xref: /openbmc/linux/drivers/counter/rz-mtu3-cnt.c (revision 39266b64)
10be89073SBiju Das // SPDX-License-Identifier: GPL-2.0
20be89073SBiju Das /*
30be89073SBiju Das  * Renesas RZ/G2L MTU3a Counter driver
40be89073SBiju Das  *
50be89073SBiju Das  * Copyright (C) 2022 Renesas Electronics Corporation
60be89073SBiju Das  */
70be89073SBiju Das 
80be89073SBiju Das #include <linux/clk.h>
90be89073SBiju Das #include <linux/counter.h>
100be89073SBiju Das #include <linux/mfd/rz-mtu3.h>
110be89073SBiju Das #include <linux/module.h>
120be89073SBiju Das #include <linux/platform_device.h>
130be89073SBiju Das #include <linux/pm_runtime.h>
140be89073SBiju Das #include <linux/types.h>
150be89073SBiju Das 
160be89073SBiju Das /*
170be89073SBiju Das  * Register descriptions
180be89073SBiju Das  *   TSR: Timer Status Register
190be89073SBiju Das  *   TMDR1: Timer Mode Register 1
200be89073SBiju Das  *   TMDR3: Timer Mode Register 3
210be89073SBiju Das  *   TIOR: Timer I/O Control Register
220be89073SBiju Das  *   TCR: Timer Control Register
230be89073SBiju Das  *   TCNT: Timer Counter
240be89073SBiju Das  *   TGRA: Timer general register A
250be89073SBiju Das  *   TCNTLW: Timer Longword Counter
260be89073SBiju Das  *   TGRALW: Timer longword general register A
270be89073SBiju Das  */
280be89073SBiju Das 
290be89073SBiju Das #define RZ_MTU3_TSR_TCFD	BIT(7) /* Count Direction Flag */
300be89073SBiju Das 
310be89073SBiju Das #define RZ_MTU3_TMDR1_PH_CNT_MODE_1	(4) /* Phase counting mode 1 */
320be89073SBiju Das #define RZ_MTU3_TMDR1_PH_CNT_MODE_2	(5) /* Phase counting mode 2 */
330be89073SBiju Das #define RZ_MTU3_TMDR1_PH_CNT_MODE_3	(6) /* Phase counting mode 3 */
340be89073SBiju Das #define RZ_MTU3_TMDR1_PH_CNT_MODE_4	(7) /* Phase counting mode 4 */
350be89073SBiju Das #define RZ_MTU3_TMDR1_PH_CNT_MODE_5	(9) /* Phase counting mode 5 */
360be89073SBiju Das #define RZ_MTU3_TMDR1_PH_CNT_MODE_MASK	(0xf)
370be89073SBiju Das 
380be89073SBiju Das /*
390be89073SBiju Das  * LWA: MTU1/MTU2 Combination Longword Access Control
400be89073SBiju Das  * 0: 16-bit, 1: 32-bit
410be89073SBiju Das  */
420be89073SBiju Das #define RZ_MTU3_TMDR3_LWA	(0)
430be89073SBiju Das 
440be89073SBiju Das /*
450be89073SBiju Das  * PHCKSEL: External Input Phase Clock Select
460be89073SBiju Das  * 0: MTCLKA and MTCLKB, 1: MTCLKC and MTCLKD
470be89073SBiju Das  */
480be89073SBiju Das #define RZ_MTU3_TMDR3_PHCKSEL	(1)
490be89073SBiju Das 
500be89073SBiju Das #define RZ_MTU3_16_BIT_MTU1_CH	(0)
510be89073SBiju Das #define RZ_MTU3_16_BIT_MTU2_CH	(1)
520be89073SBiju Das #define RZ_MTU3_32_BIT_CH	(2)
530be89073SBiju Das 
540be89073SBiju Das #define RZ_MTU3_TIOR_NO_OUTPUT	(0) /* Output prohibited */
550be89073SBiju Das #define RZ_MTU3_TIOR_IC_BOTH	(10) /* Input capture at both edges */
560be89073SBiju Das 
570be89073SBiju Das #define SIGNAL_A_ID	(0)
580be89073SBiju Das #define SIGNAL_B_ID	(1)
590be89073SBiju Das #define SIGNAL_C_ID	(2)
600be89073SBiju Das #define SIGNAL_D_ID	(3)
610be89073SBiju Das 
620be89073SBiju Das #define RZ_MTU3_MAX_HW_CNTR_CHANNELS	(2)
630be89073SBiju Das #define RZ_MTU3_MAX_LOGICAL_CNTR_CHANNELS	(3)
640be89073SBiju Das 
650be89073SBiju Das /**
660be89073SBiju Das  * struct rz_mtu3_cnt - MTU3 counter private data
670be89073SBiju Das  *
680be89073SBiju Das  * @clk: MTU3 module clock
690be89073SBiju Das  * @lock: Lock to prevent concurrent access for ceiling and count
700be89073SBiju Das  * @ch: HW channels for the counters
710be89073SBiju Das  * @count_is_enabled: Enabled state of Counter value channel
720be89073SBiju Das  * @mtu_16bit_max: Cache for 16-bit counters
730be89073SBiju Das  * @mtu_32bit_max: Cache for 32-bit counters
740be89073SBiju Das  */
750be89073SBiju Das struct rz_mtu3_cnt {
760be89073SBiju Das 	struct clk *clk;
770be89073SBiju Das 	struct mutex lock;
780be89073SBiju Das 	struct rz_mtu3_channel *ch;
790be89073SBiju Das 	bool count_is_enabled[RZ_MTU3_MAX_LOGICAL_CNTR_CHANNELS];
800be89073SBiju Das 	union {
810be89073SBiju Das 		u16 mtu_16bit_max[RZ_MTU3_MAX_HW_CNTR_CHANNELS];
820be89073SBiju Das 		u32 mtu_32bit_max;
830be89073SBiju Das 	};
840be89073SBiju Das };
850be89073SBiju Das 
860be89073SBiju Das static const enum counter_function rz_mtu3_count_functions[] = {
870be89073SBiju Das 	COUNTER_FUNCTION_QUADRATURE_X4,
880be89073SBiju Das 	COUNTER_FUNCTION_PULSE_DIRECTION,
890be89073SBiju Das 	COUNTER_FUNCTION_QUADRATURE_X2_B,
900be89073SBiju Das };
910be89073SBiju Das 
rz_mtu3_get_hw_ch(const size_t id)920be89073SBiju Das static inline size_t rz_mtu3_get_hw_ch(const size_t id)
930be89073SBiju Das {
940be89073SBiju Das 	return (id == RZ_MTU3_32_BIT_CH) ? 0 : id;
950be89073SBiju Das }
960be89073SBiju Das 
rz_mtu3_get_ch(struct counter_device * counter,int id)970be89073SBiju Das static inline struct rz_mtu3_channel *rz_mtu3_get_ch(struct counter_device *counter, int id)
980be89073SBiju Das {
990be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
1000be89073SBiju Das 	const size_t ch_id = rz_mtu3_get_hw_ch(id);
1010be89073SBiju Das 
1020be89073SBiju Das 	return &priv->ch[ch_id];
1030be89073SBiju Das }
1040be89073SBiju Das 
rz_mtu3_is_counter_invalid(struct counter_device * counter,int id)1050be89073SBiju Das static bool rz_mtu3_is_counter_invalid(struct counter_device *counter, int id)
1060be89073SBiju Das {
1070be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
1080be89073SBiju Das 	unsigned long tmdr;
1090be89073SBiju Das 
1100be89073SBiju Das 	pm_runtime_get_sync(priv->ch->dev);
1110be89073SBiju Das 	tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
1120be89073SBiju Das 	pm_runtime_put(priv->ch->dev);
1130be89073SBiju Das 
1140be89073SBiju Das 	if (id == RZ_MTU3_32_BIT_CH && test_bit(RZ_MTU3_TMDR3_LWA, &tmdr))
1150be89073SBiju Das 		return false;
1160be89073SBiju Das 
1170be89073SBiju Das 	if (id != RZ_MTU3_32_BIT_CH && !test_bit(RZ_MTU3_TMDR3_LWA, &tmdr))
1180be89073SBiju Das 		return false;
1190be89073SBiju Das 
1200be89073SBiju Das 	return true;
1210be89073SBiju Das }
1220be89073SBiju Das 
rz_mtu3_lock_if_counter_is_valid(struct counter_device * counter,struct rz_mtu3_channel * const ch,struct rz_mtu3_cnt * const priv,int id)1230be89073SBiju Das static int rz_mtu3_lock_if_counter_is_valid(struct counter_device *counter,
1240be89073SBiju Das 					    struct rz_mtu3_channel *const ch,
1250be89073SBiju Das 					    struct rz_mtu3_cnt *const priv,
1260be89073SBiju Das 					    int id)
1270be89073SBiju Das {
1280be89073SBiju Das 	mutex_lock(&priv->lock);
1290be89073SBiju Das 
1300be89073SBiju Das 	if (ch->is_busy && !priv->count_is_enabled[id]) {
1310be89073SBiju Das 		mutex_unlock(&priv->lock);
1320be89073SBiju Das 		return -EINVAL;
1330be89073SBiju Das 	}
1340be89073SBiju Das 
1350be89073SBiju Das 	if (rz_mtu3_is_counter_invalid(counter, id)) {
1360be89073SBiju Das 		mutex_unlock(&priv->lock);
1370be89073SBiju Das 		return -EBUSY;
1380be89073SBiju Das 	}
1390be89073SBiju Das 
1400be89073SBiju Das 	return 0;
1410be89073SBiju Das }
1420be89073SBiju Das 
rz_mtu3_lock_if_count_is_enabled(struct rz_mtu3_channel * const ch,struct rz_mtu3_cnt * const priv,int id)1430be89073SBiju Das static int rz_mtu3_lock_if_count_is_enabled(struct rz_mtu3_channel *const ch,
1440be89073SBiju Das 					    struct rz_mtu3_cnt *const priv,
1450be89073SBiju Das 					    int id)
1460be89073SBiju Das {
1470be89073SBiju Das 	mutex_lock(&priv->lock);
1480be89073SBiju Das 
1490be89073SBiju Das 	if (ch->is_busy && !priv->count_is_enabled[id]) {
1500be89073SBiju Das 		mutex_unlock(&priv->lock);
1510be89073SBiju Das 		return -EINVAL;
1520be89073SBiju Das 	}
1530be89073SBiju Das 
1540be89073SBiju Das 	return 0;
1550be89073SBiju Das }
1560be89073SBiju Das 
rz_mtu3_count_read(struct counter_device * counter,struct counter_count * count,u64 * val)1570be89073SBiju Das static int rz_mtu3_count_read(struct counter_device *counter,
1580be89073SBiju Das 			      struct counter_count *count, u64 *val)
1590be89073SBiju Das {
1600be89073SBiju Das 	struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
1610be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
1620be89073SBiju Das 	int ret;
1630be89073SBiju Das 
1640be89073SBiju Das 	ret = rz_mtu3_lock_if_counter_is_valid(counter, ch, priv, count->id);
1650be89073SBiju Das 	if (ret)
1660be89073SBiju Das 		return ret;
1670be89073SBiju Das 
1680be89073SBiju Das 	pm_runtime_get_sync(ch->dev);
1690be89073SBiju Das 	if (count->id == RZ_MTU3_32_BIT_CH)
1700be89073SBiju Das 		*val = rz_mtu3_32bit_ch_read(ch, RZ_MTU3_TCNTLW);
1710be89073SBiju Das 	else
1720be89073SBiju Das 		*val = rz_mtu3_16bit_ch_read(ch, RZ_MTU3_TCNT);
1730be89073SBiju Das 	pm_runtime_put(ch->dev);
1740be89073SBiju Das 	mutex_unlock(&priv->lock);
1750be89073SBiju Das 
1760be89073SBiju Das 	return 0;
1770be89073SBiju Das }
1780be89073SBiju Das 
rz_mtu3_count_write(struct counter_device * counter,struct counter_count * count,const u64 val)1790be89073SBiju Das static int rz_mtu3_count_write(struct counter_device *counter,
1800be89073SBiju Das 			       struct counter_count *count, const u64 val)
1810be89073SBiju Das {
1820be89073SBiju Das 	struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
1830be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
1840be89073SBiju Das 	int ret;
1850be89073SBiju Das 
1860be89073SBiju Das 	ret = rz_mtu3_lock_if_counter_is_valid(counter, ch, priv, count->id);
1870be89073SBiju Das 	if (ret)
1880be89073SBiju Das 		return ret;
1890be89073SBiju Das 
1900be89073SBiju Das 	pm_runtime_get_sync(ch->dev);
1910be89073SBiju Das 	if (count->id == RZ_MTU3_32_BIT_CH)
1920be89073SBiju Das 		rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TCNTLW, val);
1930be89073SBiju Das 	else
1940be89073SBiju Das 		rz_mtu3_16bit_ch_write(ch, RZ_MTU3_TCNT, val);
1950be89073SBiju Das 	pm_runtime_put(ch->dev);
1960be89073SBiju Das 	mutex_unlock(&priv->lock);
1970be89073SBiju Das 
1980be89073SBiju Das 	return 0;
1990be89073SBiju Das }
2000be89073SBiju Das 
rz_mtu3_count_function_read_helper(struct rz_mtu3_channel * const ch,struct rz_mtu3_cnt * const priv,enum counter_function * function)2010be89073SBiju Das static int rz_mtu3_count_function_read_helper(struct rz_mtu3_channel *const ch,
2020be89073SBiju Das 					      struct rz_mtu3_cnt *const priv,
2030be89073SBiju Das 					      enum counter_function *function)
2040be89073SBiju Das {
2050be89073SBiju Das 	u8 timer_mode;
2060be89073SBiju Das 
2070be89073SBiju Das 	pm_runtime_get_sync(ch->dev);
2080be89073SBiju Das 	timer_mode = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TMDR1);
2090be89073SBiju Das 	pm_runtime_put(ch->dev);
2100be89073SBiju Das 
2110be89073SBiju Das 	switch (timer_mode & RZ_MTU3_TMDR1_PH_CNT_MODE_MASK) {
2120be89073SBiju Das 	case RZ_MTU3_TMDR1_PH_CNT_MODE_1:
2130be89073SBiju Das 		*function = COUNTER_FUNCTION_QUADRATURE_X4;
2140be89073SBiju Das 		return 0;
2150be89073SBiju Das 	case RZ_MTU3_TMDR1_PH_CNT_MODE_2:
2160be89073SBiju Das 		*function = COUNTER_FUNCTION_PULSE_DIRECTION;
2170be89073SBiju Das 		return 0;
2180be89073SBiju Das 	case RZ_MTU3_TMDR1_PH_CNT_MODE_4:
2190be89073SBiju Das 		*function = COUNTER_FUNCTION_QUADRATURE_X2_B;
2200be89073SBiju Das 		return 0;
2210be89073SBiju Das 	default:
2220be89073SBiju Das 		/*
2230be89073SBiju Das 		 * TODO:
2240be89073SBiju Das 		 *  - need to add RZ_MTU3_TMDR1_PH_CNT_MODE_3
2250be89073SBiju Das 		 *  - need to add RZ_MTU3_TMDR1_PH_CNT_MODE_5
2260be89073SBiju Das 		 */
2270be89073SBiju Das 		return -EINVAL;
2280be89073SBiju Das 	}
2290be89073SBiju Das }
2300be89073SBiju Das 
rz_mtu3_count_function_read(struct counter_device * counter,struct counter_count * count,enum counter_function * function)2310be89073SBiju Das static int rz_mtu3_count_function_read(struct counter_device *counter,
2320be89073SBiju Das 				       struct counter_count *count,
2330be89073SBiju Das 				       enum counter_function *function)
2340be89073SBiju Das {
2350be89073SBiju Das 	struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
2360be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
2370be89073SBiju Das 	int ret;
2380be89073SBiju Das 
2390be89073SBiju Das 	ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, count->id);
2400be89073SBiju Das 	if (ret)
2410be89073SBiju Das 		return ret;
2420be89073SBiju Das 
2430be89073SBiju Das 	ret = rz_mtu3_count_function_read_helper(ch, priv, function);
2440be89073SBiju Das 	mutex_unlock(&priv->lock);
2450be89073SBiju Das 
2460be89073SBiju Das 	return ret;
2470be89073SBiju Das }
2480be89073SBiju Das 
rz_mtu3_count_function_write(struct counter_device * counter,struct counter_count * count,enum counter_function function)2490be89073SBiju Das static int rz_mtu3_count_function_write(struct counter_device *counter,
2500be89073SBiju Das 					struct counter_count *count,
2510be89073SBiju Das 					enum counter_function function)
2520be89073SBiju Das {
2530be89073SBiju Das 	struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
2540be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
2550be89073SBiju Das 	u8 timer_mode;
2560be89073SBiju Das 	int ret;
2570be89073SBiju Das 
2580be89073SBiju Das 	ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, count->id);
2590be89073SBiju Das 	if (ret)
2600be89073SBiju Das 		return ret;
2610be89073SBiju Das 
2620be89073SBiju Das 	switch (function) {
2630be89073SBiju Das 	case COUNTER_FUNCTION_QUADRATURE_X4:
2640be89073SBiju Das 		timer_mode = RZ_MTU3_TMDR1_PH_CNT_MODE_1;
2650be89073SBiju Das 		break;
2660be89073SBiju Das 	case COUNTER_FUNCTION_PULSE_DIRECTION:
2670be89073SBiju Das 		timer_mode = RZ_MTU3_TMDR1_PH_CNT_MODE_2;
2680be89073SBiju Das 		break;
2690be89073SBiju Das 	case COUNTER_FUNCTION_QUADRATURE_X2_B:
2700be89073SBiju Das 		timer_mode = RZ_MTU3_TMDR1_PH_CNT_MODE_4;
2710be89073SBiju Das 		break;
2720be89073SBiju Das 	default:
2730be89073SBiju Das 		/*
2740be89073SBiju Das 		 * TODO:
2750be89073SBiju Das 		 *  - need to add RZ_MTU3_TMDR1_PH_CNT_MODE_3
2760be89073SBiju Das 		 *  - need to add RZ_MTU3_TMDR1_PH_CNT_MODE_5
2770be89073SBiju Das 		 */
2780be89073SBiju Das 		mutex_unlock(&priv->lock);
2790be89073SBiju Das 		return -EINVAL;
2800be89073SBiju Das 	}
2810be89073SBiju Das 
2820be89073SBiju Das 	pm_runtime_get_sync(ch->dev);
2830be89073SBiju Das 	rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TMDR1, timer_mode);
2840be89073SBiju Das 	pm_runtime_put(ch->dev);
2850be89073SBiju Das 	mutex_unlock(&priv->lock);
2860be89073SBiju Das 
2870be89073SBiju Das 	return 0;
2880be89073SBiju Das }
2890be89073SBiju Das 
rz_mtu3_count_direction_read(struct counter_device * counter,struct counter_count * count,enum counter_count_direction * direction)2900be89073SBiju Das static int rz_mtu3_count_direction_read(struct counter_device *counter,
2910be89073SBiju Das 					struct counter_count *count,
2920be89073SBiju Das 					enum counter_count_direction *direction)
2930be89073SBiju Das {
2940be89073SBiju Das 	struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
2950be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
2960be89073SBiju Das 	int ret;
2970be89073SBiju Das 	u8 tsr;
2980be89073SBiju Das 
2990be89073SBiju Das 	ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, count->id);
3000be89073SBiju Das 	if (ret)
3010be89073SBiju Das 		return ret;
3020be89073SBiju Das 
3030be89073SBiju Das 	pm_runtime_get_sync(ch->dev);
3040be89073SBiju Das 	tsr = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TSR);
3050be89073SBiju Das 	pm_runtime_put(ch->dev);
3060be89073SBiju Das 
3070be89073SBiju Das 	*direction = (tsr & RZ_MTU3_TSR_TCFD) ?
3080be89073SBiju Das 		COUNTER_COUNT_DIRECTION_FORWARD : COUNTER_COUNT_DIRECTION_BACKWARD;
3090be89073SBiju Das 	mutex_unlock(&priv->lock);
3100be89073SBiju Das 
3110be89073SBiju Das 	return 0;
3120be89073SBiju Das }
3130be89073SBiju Das 
rz_mtu3_count_ceiling_read(struct counter_device * counter,struct counter_count * count,u64 * ceiling)3140be89073SBiju Das static int rz_mtu3_count_ceiling_read(struct counter_device *counter,
3150be89073SBiju Das 				      struct counter_count *count,
3160be89073SBiju Das 				      u64 *ceiling)
3170be89073SBiju Das {
3180be89073SBiju Das 	struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
3190be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
3200be89073SBiju Das 	const size_t ch_id = rz_mtu3_get_hw_ch(count->id);
3210be89073SBiju Das 	int ret;
3220be89073SBiju Das 
3230be89073SBiju Das 	ret = rz_mtu3_lock_if_counter_is_valid(counter, ch, priv, count->id);
3240be89073SBiju Das 	if (ret)
3250be89073SBiju Das 		return ret;
3260be89073SBiju Das 
3270be89073SBiju Das 	switch (count->id) {
3280be89073SBiju Das 	case RZ_MTU3_16_BIT_MTU1_CH:
3290be89073SBiju Das 	case RZ_MTU3_16_BIT_MTU2_CH:
3300be89073SBiju Das 		*ceiling = priv->mtu_16bit_max[ch_id];
3310be89073SBiju Das 		break;
3320be89073SBiju Das 	case RZ_MTU3_32_BIT_CH:
3330be89073SBiju Das 		*ceiling = priv->mtu_32bit_max;
3340be89073SBiju Das 		break;
3350be89073SBiju Das 	default:
3360be89073SBiju Das 		/* should never reach this path */
3370be89073SBiju Das 		mutex_unlock(&priv->lock);
3380be89073SBiju Das 		return -EINVAL;
3390be89073SBiju Das 	}
3400be89073SBiju Das 
3410be89073SBiju Das 	mutex_unlock(&priv->lock);
3420be89073SBiju Das 	return 0;
3430be89073SBiju Das }
3440be89073SBiju Das 
rz_mtu3_count_ceiling_write(struct counter_device * counter,struct counter_count * count,u64 ceiling)3450be89073SBiju Das static int rz_mtu3_count_ceiling_write(struct counter_device *counter,
3460be89073SBiju Das 				       struct counter_count *count,
3470be89073SBiju Das 				       u64 ceiling)
3480be89073SBiju Das {
3490be89073SBiju Das 	struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
3500be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
3510be89073SBiju Das 	const size_t ch_id = rz_mtu3_get_hw_ch(count->id);
3520be89073SBiju Das 	int ret;
3530be89073SBiju Das 
3540be89073SBiju Das 	ret = rz_mtu3_lock_if_counter_is_valid(counter, ch, priv, count->id);
3550be89073SBiju Das 	if (ret)
3560be89073SBiju Das 		return ret;
3570be89073SBiju Das 
3580be89073SBiju Das 	switch (count->id) {
3590be89073SBiju Das 	case RZ_MTU3_16_BIT_MTU1_CH:
3600be89073SBiju Das 	case RZ_MTU3_16_BIT_MTU2_CH:
3611e28dfdfSDan Carpenter 		if (ceiling > U16_MAX) {
3621e28dfdfSDan Carpenter 			mutex_unlock(&priv->lock);
3630be89073SBiju Das 			return -ERANGE;
3641e28dfdfSDan Carpenter 		}
3650be89073SBiju Das 		priv->mtu_16bit_max[ch_id] = ceiling;
3660be89073SBiju Das 		break;
3670be89073SBiju Das 	case RZ_MTU3_32_BIT_CH:
3681e28dfdfSDan Carpenter 		if (ceiling > U32_MAX) {
3691e28dfdfSDan Carpenter 			mutex_unlock(&priv->lock);
3700be89073SBiju Das 			return -ERANGE;
3711e28dfdfSDan Carpenter 		}
3720be89073SBiju Das 		priv->mtu_32bit_max = ceiling;
3730be89073SBiju Das 		break;
3740be89073SBiju Das 	default:
3750be89073SBiju Das 		/* should never reach this path */
3760be89073SBiju Das 		mutex_unlock(&priv->lock);
3770be89073SBiju Das 		return -EINVAL;
3780be89073SBiju Das 	}
3790be89073SBiju Das 
3800be89073SBiju Das 	pm_runtime_get_sync(ch->dev);
3810be89073SBiju Das 	if (count->id == RZ_MTU3_32_BIT_CH)
3820be89073SBiju Das 		rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TGRALW, ceiling);
3830be89073SBiju Das 	else
3840be89073SBiju Das 		rz_mtu3_16bit_ch_write(ch, RZ_MTU3_TGRA, ceiling);
3850be89073SBiju Das 
3860be89073SBiju Das 	rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TCR, RZ_MTU3_TCR_CCLR_TGRA);
3870be89073SBiju Das 	pm_runtime_put(ch->dev);
3880be89073SBiju Das 	mutex_unlock(&priv->lock);
3890be89073SBiju Das 
3900be89073SBiju Das 	return 0;
3910be89073SBiju Das }
3920be89073SBiju Das 
rz_mtu3_32bit_cnt_setting(struct counter_device * counter)3930be89073SBiju Das static void rz_mtu3_32bit_cnt_setting(struct counter_device *counter)
3940be89073SBiju Das {
3950be89073SBiju Das 	struct rz_mtu3_channel *const ch1 = rz_mtu3_get_ch(counter, 0);
3960be89073SBiju Das 	struct rz_mtu3_channel *const ch2 = rz_mtu3_get_ch(counter, 1);
3970be89073SBiju Das 
3980be89073SBiju Das 	/* Phase counting mode 1 is used as default in initialization. */
3990be89073SBiju Das 	rz_mtu3_8bit_ch_write(ch1, RZ_MTU3_TMDR1, RZ_MTU3_TMDR1_PH_CNT_MODE_1);
4000be89073SBiju Das 
4010be89073SBiju Das 	rz_mtu3_8bit_ch_write(ch1, RZ_MTU3_TCR, RZ_MTU3_TCR_CCLR_TGRA);
4020be89073SBiju Das 	rz_mtu3_8bit_ch_write(ch1, RZ_MTU3_TIOR, RZ_MTU3_TIOR_IC_BOTH);
4030be89073SBiju Das 
4040be89073SBiju Das 	rz_mtu3_enable(ch1);
4050be89073SBiju Das 	rz_mtu3_enable(ch2);
4060be89073SBiju Das }
4070be89073SBiju Das 
rz_mtu3_16bit_cnt_setting(struct counter_device * counter,int id)4080be89073SBiju Das static void rz_mtu3_16bit_cnt_setting(struct counter_device *counter, int id)
4090be89073SBiju Das {
4100be89073SBiju Das 	struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id);
4110be89073SBiju Das 
4120be89073SBiju Das 	/* Phase counting mode 1 is used as default in initialization. */
4130be89073SBiju Das 	rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TMDR1, RZ_MTU3_TMDR1_PH_CNT_MODE_1);
4140be89073SBiju Das 
4150be89073SBiju Das 	rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TCR, RZ_MTU3_TCR_CCLR_TGRA);
4160be89073SBiju Das 	rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TIOR, RZ_MTU3_TIOR_NO_OUTPUT);
4170be89073SBiju Das 	rz_mtu3_enable(ch);
4180be89073SBiju Das }
4190be89073SBiju Das 
rz_mtu3_initialize_counter(struct counter_device * counter,int id)4200be89073SBiju Das static int rz_mtu3_initialize_counter(struct counter_device *counter, int id)
4210be89073SBiju Das {
4220be89073SBiju Das 	struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id);
4230be89073SBiju Das 	struct rz_mtu3_channel *const ch1 = rz_mtu3_get_ch(counter, 0);
4240be89073SBiju Das 	struct rz_mtu3_channel *const ch2 = rz_mtu3_get_ch(counter, 1);
4250be89073SBiju Das 
4260be89073SBiju Das 	switch (id) {
4270be89073SBiju Das 	case RZ_MTU3_16_BIT_MTU1_CH:
4280be89073SBiju Das 	case RZ_MTU3_16_BIT_MTU2_CH:
4290be89073SBiju Das 		if (!rz_mtu3_request_channel(ch))
4300be89073SBiju Das 			return -EBUSY;
4310be89073SBiju Das 
4320be89073SBiju Das 		rz_mtu3_16bit_cnt_setting(counter, id);
4330be89073SBiju Das 		return 0;
4340be89073SBiju Das 	case RZ_MTU3_32_BIT_CH:
4350be89073SBiju Das 		/*
4360be89073SBiju Das 		 * 32-bit phase counting need MTU1 and MTU2 to create 32-bit
4370be89073SBiju Das 		 * cascade counter.
4380be89073SBiju Das 		 */
4390be89073SBiju Das 		if (!rz_mtu3_request_channel(ch1))
4400be89073SBiju Das 			return -EBUSY;
4410be89073SBiju Das 
4420be89073SBiju Das 		if (!rz_mtu3_request_channel(ch2)) {
4430be89073SBiju Das 			rz_mtu3_release_channel(ch1);
4440be89073SBiju Das 			return -EBUSY;
4450be89073SBiju Das 		}
4460be89073SBiju Das 
4470be89073SBiju Das 		rz_mtu3_32bit_cnt_setting(counter);
4480be89073SBiju Das 		return 0;
4490be89073SBiju Das 	default:
4500be89073SBiju Das 		/* should never reach this path */
4510be89073SBiju Das 		return -EINVAL;
4520be89073SBiju Das 	}
4530be89073SBiju Das }
4540be89073SBiju Das 
rz_mtu3_terminate_counter(struct counter_device * counter,int id)4550be89073SBiju Das static void rz_mtu3_terminate_counter(struct counter_device *counter, int id)
4560be89073SBiju Das {
4570be89073SBiju Das 	struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id);
4580be89073SBiju Das 	struct rz_mtu3_channel *const ch1 = rz_mtu3_get_ch(counter, 0);
4590be89073SBiju Das 	struct rz_mtu3_channel *const ch2 = rz_mtu3_get_ch(counter, 1);
4600be89073SBiju Das 
4610be89073SBiju Das 	if (id == RZ_MTU3_32_BIT_CH) {
4620be89073SBiju Das 		rz_mtu3_release_channel(ch2);
4630be89073SBiju Das 		rz_mtu3_release_channel(ch1);
4640be89073SBiju Das 		rz_mtu3_disable(ch2);
4650be89073SBiju Das 		rz_mtu3_disable(ch1);
4660be89073SBiju Das 	} else {
4670be89073SBiju Das 		rz_mtu3_release_channel(ch);
4680be89073SBiju Das 		rz_mtu3_disable(ch);
4690be89073SBiju Das 	}
4700be89073SBiju Das }
4710be89073SBiju Das 
rz_mtu3_count_enable_read(struct counter_device * counter,struct counter_count * count,u8 * enable)4720be89073SBiju Das static int rz_mtu3_count_enable_read(struct counter_device *counter,
4730be89073SBiju Das 				     struct counter_count *count, u8 *enable)
4740be89073SBiju Das {
4750be89073SBiju Das 	struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
4760be89073SBiju Das 	struct rz_mtu3_channel *const ch1 = rz_mtu3_get_ch(counter, 0);
4770be89073SBiju Das 	struct rz_mtu3_channel *const ch2 = rz_mtu3_get_ch(counter, 1);
4780be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
4790be89073SBiju Das 	int ret;
4800be89073SBiju Das 
4810be89073SBiju Das 	ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, count->id);
4820be89073SBiju Das 	if (ret)
4830be89073SBiju Das 		return ret;
4840be89073SBiju Das 
4850be89073SBiju Das 	if (count->id == RZ_MTU3_32_BIT_CH)
4860be89073SBiju Das 		*enable = rz_mtu3_is_enabled(ch1) && rz_mtu3_is_enabled(ch2);
4870be89073SBiju Das 	else
4880be89073SBiju Das 		*enable = rz_mtu3_is_enabled(ch);
4890be89073SBiju Das 
4900be89073SBiju Das 	mutex_unlock(&priv->lock);
4910be89073SBiju Das 
4920be89073SBiju Das 	return 0;
4930be89073SBiju Das }
4940be89073SBiju Das 
rz_mtu3_count_enable_write(struct counter_device * counter,struct counter_count * count,u8 enable)4950be89073SBiju Das static int rz_mtu3_count_enable_write(struct counter_device *counter,
4960be89073SBiju Das 				      struct counter_count *count, u8 enable)
4970be89073SBiju Das {
4980be89073SBiju Das 	struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
4990be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
5000be89073SBiju Das 	int ret = 0;
5010be89073SBiju Das 
5020be89073SBiju Das 	if (enable) {
5030be89073SBiju Das 		mutex_lock(&priv->lock);
504*39266b64SBiju Das 		pm_runtime_get_sync(ch->dev);
5050be89073SBiju Das 		ret = rz_mtu3_initialize_counter(counter, count->id);
5060be89073SBiju Das 		if (ret == 0)
5070be89073SBiju Das 			priv->count_is_enabled[count->id] = true;
5080be89073SBiju Das 		mutex_unlock(&priv->lock);
5090be89073SBiju Das 	} else {
5100be89073SBiju Das 		mutex_lock(&priv->lock);
5110be89073SBiju Das 		rz_mtu3_terminate_counter(counter, count->id);
5120be89073SBiju Das 		priv->count_is_enabled[count->id] = false;
5130be89073SBiju Das 		pm_runtime_put(ch->dev);
514*39266b64SBiju Das 		mutex_unlock(&priv->lock);
5150be89073SBiju Das 	}
5160be89073SBiju Das 
5170be89073SBiju Das 	return ret;
5180be89073SBiju Das }
5190be89073SBiju Das 
rz_mtu3_lock_if_ch0_is_enabled(struct rz_mtu3_cnt * const priv)5200be89073SBiju Das static int rz_mtu3_lock_if_ch0_is_enabled(struct rz_mtu3_cnt *const priv)
5210be89073SBiju Das {
5220be89073SBiju Das 	mutex_lock(&priv->lock);
5230be89073SBiju Das 	if (priv->ch->is_busy && !(priv->count_is_enabled[RZ_MTU3_16_BIT_MTU1_CH] ||
5240be89073SBiju Das 				   priv->count_is_enabled[RZ_MTU3_32_BIT_CH])) {
5250be89073SBiju Das 		mutex_unlock(&priv->lock);
5260be89073SBiju Das 		return -EINVAL;
5270be89073SBiju Das 	}
5280be89073SBiju Das 
5290be89073SBiju Das 	return 0;
5300be89073SBiju Das }
5310be89073SBiju Das 
rz_mtu3_cascade_counts_enable_get(struct counter_device * counter,u8 * cascade_enable)5320be89073SBiju Das static int rz_mtu3_cascade_counts_enable_get(struct counter_device *counter,
5330be89073SBiju Das 					     u8 *cascade_enable)
5340be89073SBiju Das {
5350be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
5360be89073SBiju Das 	unsigned long tmdr;
5370be89073SBiju Das 	int ret;
5380be89073SBiju Das 
5390be89073SBiju Das 	ret = rz_mtu3_lock_if_ch0_is_enabled(priv);
5400be89073SBiju Das 	if (ret)
5410be89073SBiju Das 		return ret;
5420be89073SBiju Das 
5430be89073SBiju Das 	pm_runtime_get_sync(priv->ch->dev);
5440be89073SBiju Das 	tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
5450be89073SBiju Das 	pm_runtime_put(priv->ch->dev);
5460be89073SBiju Das 	*cascade_enable = test_bit(RZ_MTU3_TMDR3_LWA, &tmdr);
5470be89073SBiju Das 	mutex_unlock(&priv->lock);
5480be89073SBiju Das 
5490be89073SBiju Das 	return 0;
5500be89073SBiju Das }
5510be89073SBiju Das 
rz_mtu3_cascade_counts_enable_set(struct counter_device * counter,u8 cascade_enable)5520be89073SBiju Das static int rz_mtu3_cascade_counts_enable_set(struct counter_device *counter,
5530be89073SBiju Das 					     u8 cascade_enable)
5540be89073SBiju Das {
5550be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
5560be89073SBiju Das 	int ret;
5570be89073SBiju Das 
5580be89073SBiju Das 	ret = rz_mtu3_lock_if_ch0_is_enabled(priv);
5590be89073SBiju Das 	if (ret)
5600be89073SBiju Das 		return ret;
5610be89073SBiju Das 
5620be89073SBiju Das 	pm_runtime_get_sync(priv->ch->dev);
5630be89073SBiju Das 	rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3,
5640be89073SBiju Das 				      RZ_MTU3_TMDR3_LWA, cascade_enable);
5650be89073SBiju Das 	pm_runtime_put(priv->ch->dev);
5660be89073SBiju Das 	mutex_unlock(&priv->lock);
5670be89073SBiju Das 
5680be89073SBiju Das 	return 0;
5690be89073SBiju Das }
5700be89073SBiju Das 
rz_mtu3_ext_input_phase_clock_select_get(struct counter_device * counter,u32 * ext_input_phase_clock_select)5710be89073SBiju Das static int rz_mtu3_ext_input_phase_clock_select_get(struct counter_device *counter,
5720be89073SBiju Das 						    u32 *ext_input_phase_clock_select)
5730be89073SBiju Das {
5740be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
5750be89073SBiju Das 	unsigned long tmdr;
5760be89073SBiju Das 	int ret;
5770be89073SBiju Das 
5780be89073SBiju Das 	ret = rz_mtu3_lock_if_ch0_is_enabled(priv);
5790be89073SBiju Das 	if (ret)
5800be89073SBiju Das 		return ret;
5810be89073SBiju Das 
5820be89073SBiju Das 	pm_runtime_get_sync(priv->ch->dev);
5830be89073SBiju Das 	tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
5840be89073SBiju Das 	pm_runtime_put(priv->ch->dev);
5850be89073SBiju Das 	*ext_input_phase_clock_select = test_bit(RZ_MTU3_TMDR3_PHCKSEL, &tmdr);
5860be89073SBiju Das 	mutex_unlock(&priv->lock);
5870be89073SBiju Das 
5880be89073SBiju Das 	return 0;
5890be89073SBiju Das }
5900be89073SBiju Das 
rz_mtu3_ext_input_phase_clock_select_set(struct counter_device * counter,u32 ext_input_phase_clock_select)5910be89073SBiju Das static int rz_mtu3_ext_input_phase_clock_select_set(struct counter_device *counter,
5920be89073SBiju Das 						    u32 ext_input_phase_clock_select)
5930be89073SBiju Das {
5940be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
5950be89073SBiju Das 	int ret;
5960be89073SBiju Das 
5970be89073SBiju Das 	ret = rz_mtu3_lock_if_ch0_is_enabled(priv);
5980be89073SBiju Das 	if (ret)
5990be89073SBiju Das 		return ret;
6000be89073SBiju Das 
6010be89073SBiju Das 	pm_runtime_get_sync(priv->ch->dev);
6020be89073SBiju Das 	rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3,
6030be89073SBiju Das 				      RZ_MTU3_TMDR3_PHCKSEL,
6040be89073SBiju Das 				      ext_input_phase_clock_select);
6050be89073SBiju Das 	pm_runtime_put(priv->ch->dev);
6060be89073SBiju Das 	mutex_unlock(&priv->lock);
6070be89073SBiju Das 
6080be89073SBiju Das 	return 0;
6090be89073SBiju Das }
6100be89073SBiju Das 
6110be89073SBiju Das static struct counter_comp rz_mtu3_count_ext[] = {
6120be89073SBiju Das 	COUNTER_COMP_DIRECTION(rz_mtu3_count_direction_read),
6130be89073SBiju Das 	COUNTER_COMP_ENABLE(rz_mtu3_count_enable_read,
6140be89073SBiju Das 			    rz_mtu3_count_enable_write),
6150be89073SBiju Das 	COUNTER_COMP_CEILING(rz_mtu3_count_ceiling_read,
6160be89073SBiju Das 			     rz_mtu3_count_ceiling_write),
6170be89073SBiju Das };
6180be89073SBiju Das 
6190be89073SBiju Das static const enum counter_synapse_action rz_mtu3_synapse_actions[] = {
6200be89073SBiju Das 	COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
6210be89073SBiju Das 	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
6220be89073SBiju Das 	COUNTER_SYNAPSE_ACTION_NONE,
6230be89073SBiju Das };
6240be89073SBiju Das 
rz_mtu3_action_read(struct counter_device * counter,struct counter_count * count,struct counter_synapse * synapse,enum counter_synapse_action * action)6250be89073SBiju Das static int rz_mtu3_action_read(struct counter_device *counter,
6260be89073SBiju Das 			       struct counter_count *count,
6270be89073SBiju Das 			       struct counter_synapse *synapse,
6280be89073SBiju Das 			       enum counter_synapse_action *action)
6290be89073SBiju Das {
6300be89073SBiju Das 	const bool is_signal_ab = (synapse->signal->id == SIGNAL_A_ID) ||
6310be89073SBiju Das 				  (synapse->signal->id == SIGNAL_B_ID);
6320be89073SBiju Das 	struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
6330be89073SBiju Das 	struct rz_mtu3_cnt *const priv = counter_priv(counter);
6340be89073SBiju Das 	enum counter_function function;
6350be89073SBiju Das 	bool mtclkc_mtclkd;
6360be89073SBiju Das 	unsigned long tmdr;
6370be89073SBiju Das 	int ret;
6380be89073SBiju Das 
6390be89073SBiju Das 	ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, count->id);
6400be89073SBiju Das 	if (ret)
6410be89073SBiju Das 		return ret;
6420be89073SBiju Das 
6430be89073SBiju Das 	ret = rz_mtu3_count_function_read_helper(ch, priv, &function);
6440be89073SBiju Das 	if (ret) {
6450be89073SBiju Das 		mutex_unlock(&priv->lock);
6460be89073SBiju Das 		return ret;
6470be89073SBiju Das 	}
6480be89073SBiju Das 
6490be89073SBiju Das 	/* Default action mode */
6500be89073SBiju Das 	*action = COUNTER_SYNAPSE_ACTION_NONE;
6510be89073SBiju Das 
6520be89073SBiju Das 	if (count->id != RZ_MTU3_16_BIT_MTU1_CH) {
6530be89073SBiju Das 		tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
6540be89073SBiju Das 		mtclkc_mtclkd = test_bit(RZ_MTU3_TMDR3_PHCKSEL, &tmdr);
6550be89073SBiju Das 		if ((mtclkc_mtclkd && is_signal_ab) ||
6560be89073SBiju Das 		    (!mtclkc_mtclkd && !is_signal_ab)) {
6570be89073SBiju Das 			mutex_unlock(&priv->lock);
6580be89073SBiju Das 			return 0;
6590be89073SBiju Das 		}
6600be89073SBiju Das 	}
6610be89073SBiju Das 
6620be89073SBiju Das 	switch (function) {
6630be89073SBiju Das 	case COUNTER_FUNCTION_PULSE_DIRECTION:
6640be89073SBiju Das 		/*
6650be89073SBiju Das 		 * Rising edges on signal A (signal C) updates the respective
6660be89073SBiju Das 		 * count. The input level of signal B (signal D) determines
6670be89073SBiju Das 		 * direction.
6680be89073SBiju Das 		 */
6690be89073SBiju Das 		if (synapse->signal->id == SIGNAL_A_ID ||
6700be89073SBiju Das 		    synapse->signal->id == SIGNAL_C_ID)
6710be89073SBiju Das 			*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
6720be89073SBiju Das 		break;
6730be89073SBiju Das 	case COUNTER_FUNCTION_QUADRATURE_X2_B:
6740be89073SBiju Das 		/*
6750be89073SBiju Das 		 * Any state transition on quadrature pair signal B (signal D)
6760be89073SBiju Das 		 * updates the respective count.
6770be89073SBiju Das 		 */
6780be89073SBiju Das 		if (synapse->signal->id == SIGNAL_B_ID ||
6790be89073SBiju Das 		    synapse->signal->id == SIGNAL_D_ID)
6800be89073SBiju Das 			*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
6810be89073SBiju Das 		break;
6820be89073SBiju Das 	case COUNTER_FUNCTION_QUADRATURE_X4:
6830be89073SBiju Das 		/* counts up/down on both edges of A (C)  and B (D) signal */
6840be89073SBiju Das 		*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
6850be89073SBiju Das 		break;
6860be89073SBiju Das 	default:
6870be89073SBiju Das 		/* should never reach this path */
6880be89073SBiju Das 		mutex_unlock(&priv->lock);
6890be89073SBiju Das 		return -EINVAL;
6900be89073SBiju Das 	}
6910be89073SBiju Das 
6920be89073SBiju Das 	mutex_unlock(&priv->lock);
6930be89073SBiju Das 
6940be89073SBiju Das 	return 0;
6950be89073SBiju Das }
6960be89073SBiju Das 
6970be89073SBiju Das static const struct counter_ops rz_mtu3_cnt_ops = {
6980be89073SBiju Das 	.count_read = rz_mtu3_count_read,
6990be89073SBiju Das 	.count_write = rz_mtu3_count_write,
7000be89073SBiju Das 	.function_read = rz_mtu3_count_function_read,
7010be89073SBiju Das 	.function_write = rz_mtu3_count_function_write,
7020be89073SBiju Das 	.action_read = rz_mtu3_action_read,
7030be89073SBiju Das };
7040be89073SBiju Das 
7050be89073SBiju Das #define RZ_MTU3_PHASE_SIGNAL(_id, _name) {		\
7060be89073SBiju Das 	.id = (_id),				\
7070be89073SBiju Das 	.name = (_name),			\
7080be89073SBiju Das }
7090be89073SBiju Das 
7100be89073SBiju Das static struct counter_signal rz_mtu3_signals[] = {
7110be89073SBiju Das 	RZ_MTU3_PHASE_SIGNAL(SIGNAL_A_ID, "MTU1 MTCLKA"),
7120be89073SBiju Das 	RZ_MTU3_PHASE_SIGNAL(SIGNAL_B_ID, "MTU1 MTCLKB"),
7130be89073SBiju Das 	RZ_MTU3_PHASE_SIGNAL(SIGNAL_C_ID, "MTU2 MTCLKC"),
7140be89073SBiju Das 	RZ_MTU3_PHASE_SIGNAL(SIGNAL_D_ID, "MTU2 MTCLKD"),
7150be89073SBiju Das };
7160be89073SBiju Das 
7170be89073SBiju Das static struct counter_synapse rz_mtu3_mtu1_count_synapses[] = {
7180be89073SBiju Das 	{
7190be89073SBiju Das 		.actions_list = rz_mtu3_synapse_actions,
7200be89073SBiju Das 		.num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions),
7210be89073SBiju Das 		.signal = rz_mtu3_signals,
7220be89073SBiju Das 	},
7230be89073SBiju Das 	{
7240be89073SBiju Das 		.actions_list = rz_mtu3_synapse_actions,
7250be89073SBiju Das 		.num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions),
7260be89073SBiju Das 		.signal = rz_mtu3_signals + 1,
7270be89073SBiju Das 	}
7280be89073SBiju Das };
7290be89073SBiju Das 
7300be89073SBiju Das static struct counter_synapse rz_mtu3_mtu2_count_synapses[] = {
7310be89073SBiju Das 	{
7320be89073SBiju Das 		.actions_list = rz_mtu3_synapse_actions,
7330be89073SBiju Das 		.num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions),
7340be89073SBiju Das 		.signal = rz_mtu3_signals,
7350be89073SBiju Das 	},
7360be89073SBiju Das 	{
7370be89073SBiju Das 		.actions_list = rz_mtu3_synapse_actions,
7380be89073SBiju Das 		.num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions),
7390be89073SBiju Das 		.signal = rz_mtu3_signals + 1,
7400be89073SBiju Das 	},
7410be89073SBiju Das 	{
7420be89073SBiju Das 		.actions_list = rz_mtu3_synapse_actions,
7430be89073SBiju Das 		.num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions),
7440be89073SBiju Das 		.signal = rz_mtu3_signals + 2,
7450be89073SBiju Das 	},
7460be89073SBiju Das 	{
7470be89073SBiju Das 		.actions_list = rz_mtu3_synapse_actions,
7480be89073SBiju Das 		.num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions),
7490be89073SBiju Das 		.signal = rz_mtu3_signals + 3,
7500be89073SBiju Das 	}
7510be89073SBiju Das };
7520be89073SBiju Das 
7530be89073SBiju Das static struct counter_count rz_mtu3_counts[] = {
7540be89073SBiju Das 	{
7550be89073SBiju Das 		.id = RZ_MTU3_16_BIT_MTU1_CH,
7560be89073SBiju Das 		.name = "Channel 1 Count",
7570be89073SBiju Das 		.functions_list = rz_mtu3_count_functions,
7580be89073SBiju Das 		.num_functions = ARRAY_SIZE(rz_mtu3_count_functions),
7590be89073SBiju Das 		.synapses = rz_mtu3_mtu1_count_synapses,
7600be89073SBiju Das 		.num_synapses = ARRAY_SIZE(rz_mtu3_mtu1_count_synapses),
7610be89073SBiju Das 		.ext = rz_mtu3_count_ext,
7620be89073SBiju Das 		.num_ext = ARRAY_SIZE(rz_mtu3_count_ext),
7630be89073SBiju Das 	},
7640be89073SBiju Das 	{
7650be89073SBiju Das 		.id = RZ_MTU3_16_BIT_MTU2_CH,
7660be89073SBiju Das 		.name = "Channel 2 Count",
7670be89073SBiju Das 		.functions_list = rz_mtu3_count_functions,
7680be89073SBiju Das 		.num_functions = ARRAY_SIZE(rz_mtu3_count_functions),
7690be89073SBiju Das 		.synapses = rz_mtu3_mtu2_count_synapses,
7700be89073SBiju Das 		.num_synapses = ARRAY_SIZE(rz_mtu3_mtu2_count_synapses),
7710be89073SBiju Das 		.ext = rz_mtu3_count_ext,
7720be89073SBiju Das 		.num_ext = ARRAY_SIZE(rz_mtu3_count_ext),
7730be89073SBiju Das 	},
7740be89073SBiju Das 	{
7750be89073SBiju Das 		.id = RZ_MTU3_32_BIT_CH,
7760be89073SBiju Das 		.name = "Channel 1 and 2 (cascaded) Count",
7770be89073SBiju Das 		.functions_list = rz_mtu3_count_functions,
7780be89073SBiju Das 		.num_functions = ARRAY_SIZE(rz_mtu3_count_functions),
7790be89073SBiju Das 		.synapses = rz_mtu3_mtu2_count_synapses,
7800be89073SBiju Das 		.num_synapses = ARRAY_SIZE(rz_mtu3_mtu2_count_synapses),
7810be89073SBiju Das 		.ext = rz_mtu3_count_ext,
7820be89073SBiju Das 		.num_ext = ARRAY_SIZE(rz_mtu3_count_ext),
7830be89073SBiju Das 	}
7840be89073SBiju Das };
7850be89073SBiju Das 
7860be89073SBiju Das static const char *const rz_mtu3_ext_input_phase_clock_select[] = {
7870be89073SBiju Das 	"MTCLKA-MTCLKB",
7880be89073SBiju Das 	"MTCLKC-MTCLKD",
7890be89073SBiju Das };
7900be89073SBiju Das 
7910be89073SBiju Das static DEFINE_COUNTER_ENUM(rz_mtu3_ext_input_phase_clock_select_enum,
7920be89073SBiju Das 			   rz_mtu3_ext_input_phase_clock_select);
7930be89073SBiju Das 
7940be89073SBiju Das static struct counter_comp rz_mtu3_device_ext[] = {
7950be89073SBiju Das 	COUNTER_COMP_DEVICE_BOOL("cascade_counts_enable",
7960be89073SBiju Das 				 rz_mtu3_cascade_counts_enable_get,
7970be89073SBiju Das 				 rz_mtu3_cascade_counts_enable_set),
7980be89073SBiju Das 	COUNTER_COMP_DEVICE_ENUM("external_input_phase_clock_select",
7990be89073SBiju Das 				 rz_mtu3_ext_input_phase_clock_select_get,
8000be89073SBiju Das 				 rz_mtu3_ext_input_phase_clock_select_set,
8010be89073SBiju Das 				 rz_mtu3_ext_input_phase_clock_select_enum),
8020be89073SBiju Das };
8030be89073SBiju Das 
rz_mtu3_cnt_pm_runtime_suspend(struct device * dev)8040be89073SBiju Das static int rz_mtu3_cnt_pm_runtime_suspend(struct device *dev)
8050be89073SBiju Das {
8060be89073SBiju Das 	struct clk *const clk = dev_get_drvdata(dev);
8070be89073SBiju Das 
8080be89073SBiju Das 	clk_disable_unprepare(clk);
8090be89073SBiju Das 
8100be89073SBiju Das 	return 0;
8110be89073SBiju Das }
8120be89073SBiju Das 
rz_mtu3_cnt_pm_runtime_resume(struct device * dev)8130be89073SBiju Das static int rz_mtu3_cnt_pm_runtime_resume(struct device *dev)
8140be89073SBiju Das {
8150be89073SBiju Das 	struct clk *const clk = dev_get_drvdata(dev);
8160be89073SBiju Das 
8170be89073SBiju Das 	clk_prepare_enable(clk);
8180be89073SBiju Das 
8190be89073SBiju Das 	return 0;
8200be89073SBiju Das }
8210be89073SBiju Das 
8220be89073SBiju Das static DEFINE_RUNTIME_DEV_PM_OPS(rz_mtu3_cnt_pm_ops,
8230be89073SBiju Das 				 rz_mtu3_cnt_pm_runtime_suspend,
8240be89073SBiju Das 				 rz_mtu3_cnt_pm_runtime_resume, NULL);
8250be89073SBiju Das 
rz_mtu3_cnt_pm_disable(void * data)8260be89073SBiju Das static void rz_mtu3_cnt_pm_disable(void *data)
8270be89073SBiju Das {
8280be89073SBiju Das 	struct device *dev = data;
8290be89073SBiju Das 
8300be89073SBiju Das 	pm_runtime_disable(dev);
8310be89073SBiju Das 	pm_runtime_set_suspended(dev);
8320be89073SBiju Das }
8330be89073SBiju Das 
rz_mtu3_cnt_probe(struct platform_device * pdev)8340be89073SBiju Das static int rz_mtu3_cnt_probe(struct platform_device *pdev)
8350be89073SBiju Das {
8360be89073SBiju Das 	struct rz_mtu3 *ddata = dev_get_drvdata(pdev->dev.parent);
8370be89073SBiju Das 	struct device *dev = &pdev->dev;
8380be89073SBiju Das 	struct counter_device *counter;
8390be89073SBiju Das 	struct rz_mtu3_channel *ch;
8400be89073SBiju Das 	struct rz_mtu3_cnt *priv;
8410be89073SBiju Das 	unsigned int i;
8420be89073SBiju Das 	int ret;
8430be89073SBiju Das 
8440be89073SBiju Das 	counter = devm_counter_alloc(dev, sizeof(*priv));
8450be89073SBiju Das 	if (!counter)
8460be89073SBiju Das 		return -ENOMEM;
8470be89073SBiju Das 
8480be89073SBiju Das 	priv = counter_priv(counter);
8490be89073SBiju Das 	priv->clk = ddata->clk;
8500be89073SBiju Das 	priv->mtu_32bit_max = U32_MAX;
8510be89073SBiju Das 	priv->ch = &ddata->channels[RZ_MTU3_CHAN_1];
8520be89073SBiju Das 	ch = &priv->ch[0];
8530be89073SBiju Das 	for (i = 0; i < RZ_MTU3_MAX_HW_CNTR_CHANNELS; i++) {
8540be89073SBiju Das 		ch->dev = dev;
8550be89073SBiju Das 		priv->mtu_16bit_max[i] = U16_MAX;
8560be89073SBiju Das 		ch++;
8570be89073SBiju Das 	}
8580be89073SBiju Das 
8590be89073SBiju Das 	mutex_init(&priv->lock);
8600be89073SBiju Das 	platform_set_drvdata(pdev, priv->clk);
8610be89073SBiju Das 	clk_prepare_enable(priv->clk);
8620be89073SBiju Das 	pm_runtime_set_active(&pdev->dev);
8630be89073SBiju Das 	pm_runtime_enable(&pdev->dev);
8640be89073SBiju Das 	ret = devm_add_action_or_reset(&pdev->dev, rz_mtu3_cnt_pm_disable, dev);
8650be89073SBiju Das 	if (ret < 0)
8660be89073SBiju Das 		goto disable_clock;
8670be89073SBiju Das 
8680be89073SBiju Das 	counter->name = dev_name(dev);
8690be89073SBiju Das 	counter->parent = dev;
8700be89073SBiju Das 	counter->ops = &rz_mtu3_cnt_ops;
8710be89073SBiju Das 	counter->counts = rz_mtu3_counts;
8720be89073SBiju Das 	counter->num_counts = ARRAY_SIZE(rz_mtu3_counts);
8730be89073SBiju Das 	counter->signals = rz_mtu3_signals;
8740be89073SBiju Das 	counter->num_signals = ARRAY_SIZE(rz_mtu3_signals);
8750be89073SBiju Das 	counter->ext = rz_mtu3_device_ext;
8760be89073SBiju Das 	counter->num_ext = ARRAY_SIZE(rz_mtu3_device_ext);
8770be89073SBiju Das 
8780be89073SBiju Das 	/* Register Counter device */
8790be89073SBiju Das 	ret = devm_counter_add(dev, counter);
8800be89073SBiju Das 	if (ret < 0) {
8810be89073SBiju Das 		dev_err_probe(dev, ret, "Failed to add counter\n");
8820be89073SBiju Das 		goto disable_clock;
8830be89073SBiju Das 	}
8840be89073SBiju Das 
8850be89073SBiju Das 	return 0;
8860be89073SBiju Das 
8870be89073SBiju Das disable_clock:
8880be89073SBiju Das 	clk_disable_unprepare(priv->clk);
8890be89073SBiju Das 
8900be89073SBiju Das 	return ret;
8910be89073SBiju Das }
8920be89073SBiju Das 
8930be89073SBiju Das static struct platform_driver rz_mtu3_cnt_driver = {
8940be89073SBiju Das 	.probe = rz_mtu3_cnt_probe,
8950be89073SBiju Das 	.driver = {
8960be89073SBiju Das 		.name = "rz-mtu3-counter",
8970be89073SBiju Das 		.pm = pm_ptr(&rz_mtu3_cnt_pm_ops),
8980be89073SBiju Das 	},
8990be89073SBiju Das };
9000be89073SBiju Das module_platform_driver(rz_mtu3_cnt_driver);
9010be89073SBiju Das 
9020be89073SBiju Das MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
9030be89073SBiju Das MODULE_ALIAS("platform:rz-mtu3-counter");
9040be89073SBiju Das MODULE_DESCRIPTION("Renesas RZ/G2L MTU3a counter driver");
9050be89073SBiju Das MODULE_LICENSE("GPL");
9060be89073SBiju Das MODULE_IMPORT_NS(COUNTER);
907