[Letux-kernel] [PATCH 3/5] [WIP] clocksource/drivers/ingenic: Add support for JZ4730

H. Nikolaus Schaller hns at goldelico.com
Fri Nov 27 14:04:12 CET 2020


This patch does not apply to my tree.

Do you have a git repo where it is already applied somewhere?

BR,
Nikolaus


> Am 27.11.2020 um 04:15 schrieb Lubomir Rintel <lkundrak at v3.sk>:
> 
> Before JZ4740 the register layout was quite different. There were not
> separate set/clear registers and the registers pertaining to a
> particular channel were grouped together.
> 
> Signed-off-by: Lubomir Rintel <lkundrak at v3.sk>
> ---
> drivers/clocksource/ingenic-timer.c | 69 +++++++++++++++++++++++------
> 1 file changed, 55 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/clocksource/ingenic-timer.c b/drivers/clocksource/ingenic-timer.c
> index 09850a38566a9..63a6f02c52300 100644
> --- a/drivers/clocksource/ingenic-timer.c
> +++ b/drivers/clocksource/ingenic-timer.c
> @@ -27,6 +27,7 @@ static DEFINE_PER_CPU(call_single_data_t, ingenic_cevt_csd);
> 
> struct ingenic_soc_info {
> 	unsigned int num_channels;
> +	bool jz4740_regs;
> };
> 
> struct ingenic_tcu_timer {
> @@ -38,6 +39,7 @@ struct ingenic_tcu_timer {
> };
> 
> struct ingenic_tcu {
> +	const struct ingenic_soc_info *soc_info;
> 	struct regmap *map;
> 	struct device_node *np;
> 	struct clk *cs_clk;
> @@ -52,9 +54,16 @@ static struct ingenic_tcu *ingenic_tcu;
> static u64 notrace ingenic_tcu_timer_read(void)
> {
> 	struct ingenic_tcu *tcu = ingenic_tcu;
> +	unsigned int reload;
> 	unsigned int count;
> 
> -	regmap_read(tcu->map, TCU_REG_TCNTc(tcu->cs_channel), &count);
> +	if (tcu->soc_info->jz4740_regs) {
> +		regmap_read(tcu->map, TCU_REG_TCNTc(tcu->cs_channel), &count);
> +	} else {
> +		regmap_read(tcu->map, TCU_JZ4730_REG_TCNTc(tcu->cs_channel), &count);
> +		regmap_read(tcu->map, TCU_JZ4730_REG_TRDRc(tcu->cs_channel), &reload);
> +		count = (u16)reload - (u16)count;
> +	}
> 
> 	return count;
> }
> @@ -81,7 +90,11 @@ static int ingenic_tcu_cevt_set_state_shutdown(struct clock_event_device *evt)
> 	struct ingenic_tcu_timer *timer = to_ingenic_tcu_timer(evt);
> 	struct ingenic_tcu *tcu = to_ingenic_tcu(timer);
> 
> -	regmap_write(tcu->map, TCU_REG_TECR, BIT(timer->channel));
> +	if (tcu->soc_info->jz4740_regs) {
> +		regmap_write(tcu->map, TCU_REG_TECR, BIT(timer->channel));
> +	} else {
> +		regmap_clear_bits(tcu->map, TCU_JZ4730_REG_TER, BIT(timer->channel));
> +	}
> 
> 	return 0;
> }
> @@ -95,9 +108,15 @@ static int ingenic_tcu_cevt_set_next(unsigned long next,
> 	if (next > 0xffff)
> 		return -EINVAL;
> 
> -	regmap_write(tcu->map, TCU_REG_TDFRc(timer->channel), next);
> -	regmap_write(tcu->map, TCU_REG_TCNTc(timer->channel), 0);
> -	regmap_write(tcu->map, TCU_REG_TESR, BIT(timer->channel));
> +	if (tcu->soc_info->jz4740_regs) {
> +		regmap_write(tcu->map, TCU_REG_TDFRc(timer->channel), next);
> +		regmap_write(tcu->map, TCU_REG_TCNTc(timer->channel), 0);
> +		regmap_write(tcu->map, TCU_REG_TESR, BIT(timer->channel));
> +	} else {
> +		regmap_write(tcu->map, TCU_JZ4730_REG_TRDRc(timer->channel), next);
> +		regmap_write(tcu->map, TCU_JZ4730_REG_TCNTc(timer->channel), 0xffff);
> +		regmap_set_bits(tcu->map, TCU_JZ4730_REG_TER, BIT(timer->channel));
> +	}
> 
> 	return 0;
> }
> @@ -115,7 +134,11 @@ static irqreturn_t ingenic_tcu_cevt_cb(int irq, void *dev_id)
> 	struct ingenic_tcu *tcu = to_ingenic_tcu(timer);
> 	call_single_data_t *csd;
> 
> -	regmap_write(tcu->map, TCU_REG_TECR, BIT(timer->channel));
> +	if (tcu->soc_info->jz4740_regs) {
> +		regmap_write(tcu->map, TCU_REG_TECR, BIT(timer->channel));
> +	} else {
> +		regmap_clear_bits(tcu->map, TCU_JZ4730_REG_TER, BIT(timer->channel));
> +	}
> 
> 	if (timer->cevt.event_handler) {
> 		csd = &per_cpu(ingenic_cevt_csd, timer->cpu);
> @@ -223,16 +246,30 @@ static int __init ingenic_tcu_clocksource_init(struct device_node *np,
> 		goto err_clk_disable;
> 	}
> 
> -	/* Reset channel */
> -	regmap_update_bits(tcu->map, TCU_REG_TCSRc(channel),
> -			   0xffff & ~TCU_TCSR_RESERVED_BITS, 0);
> 
> -	/* Reset counter */
> -	regmap_write(tcu->map, TCU_REG_TDFRc(channel), 0xffff);
> -	regmap_write(tcu->map, TCU_REG_TCNTc(channel), 0);
> +	if (tcu->soc_info->jz4740_regs) {
> +		/* Reset channel */
> +		regmap_update_bits(tcu->map, TCU_REG_TCSRc(channel),
> +				   0xffff & ~TCU_TCSR_RESERVED_BITS, 0);
> 
> -	/* Enable channel */
> -	regmap_write(tcu->map, TCU_REG_TESR, BIT(channel));
> +		/* Reset counter */
> +		regmap_write(tcu->map, TCU_REG_TDFRc(channel), 0xffff);
> +		regmap_write(tcu->map, TCU_REG_TCNTc(channel), 0);
> +
> +		/* Enable channel */
> +		regmap_write(tcu->map, TCU_REG_TESR, BIT(channel));
> +	} else {
> +		/* Reset channel */
> +		regmap_update_bits(tcu->map, TCU_JZ4730_REG_TCSRc(channel),
> +				   0xffff & ~TCU_JZ4730_TCSR_PARENT_CLOCK_MASK, 0);
> +
> +		/* Reset counter */
> +		regmap_write(tcu->map, TCU_JZ4730_REG_TRDRc(channel), 0xffff);
> +		regmap_write(tcu->map, TCU_JZ4730_REG_TCNTc(channel), 0);
> +
> +		/* Enable channel */
> +		regmap_set_bits(tcu->map, TCU_JZ4730_REG_TER, BIT(channel));
> +	}
> 
> 	cs->name = "ingenic-timer";
> 	cs->rating = 200;
> @@ -255,14 +292,17 @@ static int __init ingenic_tcu_clocksource_init(struct device_node *np,
> 
> static const struct ingenic_soc_info jz4740_soc_info = {
> 	.num_channels = 8,
> +	.jz4740_regs = true,
> };
> 
> static const struct ingenic_soc_info jz4725b_soc_info = {
> 	.num_channels = 6,
> +	.jz4740_regs = true,
> };
> 
> static const struct ingenic_soc_info jz4730_soc_info = {
> 	.num_channels = 3,
> +	.jz4740_regs = false,
> };
> 
> static const struct of_device_id ingenic_tcu_of_match[] = {
> @@ -314,6 +354,7 @@ static int __init ingenic_tcu_init(struct device_node *np)
> 		goto err_free_ingenic_tcu;
> 	}
> 
> +	tcu->soc_info = soc_info;
> 	tcu->map = map;
> 	tcu->np = np;
> 	ingenic_tcu = tcu;
> -- 
> 2.28.0
> 



More information about the Letux-kernel mailing list