forked from mirrors/linux
		
	clocksource/drivers/timer-ti-dm: Simplify register writes with dmtimer_write()
We can simplify register write access by checking for the register write posted mode in the write function. This way we can combine the functions for __omap_dm_timer_write() and omap_dm_timer_write_reg() into a single function dmtimer_write(). We update the shared register access first, the timer revision specific register access will be updated in a later patch. Signed-off-by: Tony Lindgren <tony@atomide.com> Reviewed-by: Janusz Krzysztofik <jmkrzyszt@gmail.com> Link: https://lore.kernel.org/r/20220815131250.34603-4-tony@atomide.com Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
This commit is contained in:
		
							parent
							
								
									90c9aada19
								
							
						
					
					
						commit
						49cd16bb57
					
				
					 1 changed files with 43 additions and 53 deletions
				
			
		|  | @ -68,14 +68,29 @@ static inline u32 dmtimer_read(struct omap_dm_timer *timer, u32 reg) | ||||||
| 	return readl_relaxed(timer->func_base + offset); | 	return readl_relaxed(timer->func_base + offset); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline void __omap_dm_timer_write(struct omap_dm_timer *timer, | /**
 | ||||||
| 					u32 reg, u32 val, int posted) |  * dmtimer_write - write timer registers in posted and non-posted mode | ||||||
|  |  * @timer:      timer pointer over which write operation is to perform | ||||||
|  |  * @reg:        lowest byte holds the register offset | ||||||
|  |  * @value:      data to write into the register | ||||||
|  |  * | ||||||
|  |  * The posted mode bit is encoded in reg. Note that in posted mode, the write | ||||||
|  |  * pending bit must be checked. Otherwise a write on a register which has a | ||||||
|  |  * pending write will be lost. | ||||||
|  |  */ | ||||||
|  | static inline void dmtimer_write(struct omap_dm_timer *timer, u32 reg, u32 val) | ||||||
| { | { | ||||||
| 	if (posted) | 	u16 wp, offset; | ||||||
| 		while (readl_relaxed(timer->pend) & (reg >> WPSHIFT)) | 
 | ||||||
|  | 	wp = reg >> WPSHIFT; | ||||||
|  | 	offset = reg & 0xff; | ||||||
|  | 
 | ||||||
|  | 	/* Wait for a possible write pending bit in posted mode */ | ||||||
|  | 	if (wp && timer->posted) | ||||||
|  | 		while (readl_relaxed(timer->pend) & wp) | ||||||
| 			cpu_relax(); | 			cpu_relax(); | ||||||
| 
 | 
 | ||||||
| 	writel_relaxed(val, timer->func_base + (reg & 0xff)); | 	writel_relaxed(val, timer->func_base + offset); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer) | static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer) | ||||||
|  | @ -120,25 +135,24 @@ static inline void __omap_dm_timer_enable_posted(struct omap_dm_timer *timer) | ||||||
| 
 | 
 | ||||||
| 	if (timer->errata & OMAP_TIMER_ERRATA_I103_I767) { | 	if (timer->errata & OMAP_TIMER_ERRATA_I103_I767) { | ||||||
| 		timer->posted = OMAP_TIMER_NONPOSTED; | 		timer->posted = OMAP_TIMER_NONPOSTED; | ||||||
| 		__omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, 0, 0); | 		dmtimer_write(timer, OMAP_TIMER_IF_CTRL_REG, 0); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	__omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, | 	dmtimer_write(timer, OMAP_TIMER_IF_CTRL_REG, OMAP_TIMER_CTRL_POSTED); | ||||||
| 			      OMAP_TIMER_CTRL_POSTED, 0); |  | ||||||
| 	timer->context.tsicr = OMAP_TIMER_CTRL_POSTED; | 	timer->context.tsicr = OMAP_TIMER_CTRL_POSTED; | ||||||
| 	timer->posted = OMAP_TIMER_POSTED; | 	timer->posted = OMAP_TIMER_POSTED; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline void __omap_dm_timer_stop(struct omap_dm_timer *timer, | static inline void __omap_dm_timer_stop(struct omap_dm_timer *timer, | ||||||
| 					int posted, unsigned long rate) | 					unsigned long rate) | ||||||
| { | { | ||||||
| 	u32 l; | 	u32 l; | ||||||
| 
 | 
 | ||||||
| 	l = dmtimer_read(timer, OMAP_TIMER_CTRL_REG); | 	l = dmtimer_read(timer, OMAP_TIMER_CTRL_REG); | ||||||
| 	if (l & OMAP_TIMER_CTRL_ST) { | 	if (l & OMAP_TIMER_CTRL_ST) { | ||||||
| 		l &= ~0x1; | 		l &= ~0x1; | ||||||
| 		__omap_dm_timer_write(timer, OMAP_TIMER_CTRL_REG, l, posted); | 		dmtimer_write(timer, OMAP_TIMER_CTRL_REG, l); | ||||||
| #ifdef CONFIG_ARCH_OMAP2PLUS | #ifdef CONFIG_ARCH_OMAP2PLUS | ||||||
| 		/* Readback to make sure write has completed */ | 		/* Readback to make sure write has completed */ | ||||||
| 		dmtimer_read(timer, OMAP_TIMER_CTRL_REG); | 		dmtimer_read(timer, OMAP_TIMER_CTRL_REG); | ||||||
|  | @ -158,7 +172,7 @@ static inline void __omap_dm_timer_int_enable(struct omap_dm_timer *timer, | ||||||
| 						unsigned int value) | 						unsigned int value) | ||||||
| { | { | ||||||
| 	writel_relaxed(value, timer->irq_ena); | 	writel_relaxed(value, timer->irq_ena); | ||||||
| 	__omap_dm_timer_write(timer, OMAP_TIMER_WAKEUP_EN_REG, value, 0); | 	dmtimer_write(timer, OMAP_TIMER_WAKEUP_EN_REG, value); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline unsigned int | static inline unsigned int | ||||||
|  | @ -173,41 +187,17 @@ static inline void __omap_dm_timer_write_status(struct omap_dm_timer *timer, | ||||||
| 	writel_relaxed(value, timer->irq_stat); | 	writel_relaxed(value, timer->irq_stat); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 |  | ||||||
|  * omap_dm_timer_write_reg - write timer registers in posted and non-posted mode |  | ||||||
|  * @timer:      timer pointer over which write operation is to perform |  | ||||||
|  * @reg:        lowest byte holds the register offset |  | ||||||
|  * @value:      data to write into the register |  | ||||||
|  * |  | ||||||
|  * The posted mode bit is encoded in reg. Note that in posted mode the write |  | ||||||
|  * pending bit must be checked. Otherwise a write on a register which has a |  | ||||||
|  * pending write will be lost. |  | ||||||
|  */ |  | ||||||
| static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, |  | ||||||
| 						u32 value) |  | ||||||
| { |  | ||||||
| 	WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET); |  | ||||||
| 	__omap_dm_timer_write(timer, reg, value, timer->posted); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void omap_timer_restore_context(struct omap_dm_timer *timer) | static void omap_timer_restore_context(struct omap_dm_timer *timer) | ||||||
| { | { | ||||||
| 	__omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, | 	dmtimer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, timer->context.ocp_cfg); | ||||||
| 			      timer->context.ocp_cfg, 0); |  | ||||||
| 
 | 
 | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, | 	dmtimer_write(timer, OMAP_TIMER_WAKEUP_EN_REG, timer->context.twer); | ||||||
| 				timer->context.twer); | 	dmtimer_write(timer, OMAP_TIMER_COUNTER_REG, timer->context.tcrr); | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, | 	dmtimer_write(timer, OMAP_TIMER_LOAD_REG, timer->context.tldr); | ||||||
| 				timer->context.tcrr); | 	dmtimer_write(timer, OMAP_TIMER_MATCH_REG, timer->context.tmar); | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, | 	dmtimer_write(timer, OMAP_TIMER_IF_CTRL_REG, timer->context.tsicr); | ||||||
| 				timer->context.tldr); |  | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, |  | ||||||
| 				timer->context.tmar); |  | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, |  | ||||||
| 				timer->context.tsicr); |  | ||||||
| 	writel_relaxed(timer->context.tier, timer->irq_ena); | 	writel_relaxed(timer->context.tier, timer->irq_ena); | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, | 	dmtimer_write(timer, OMAP_TIMER_CTRL_REG, timer->context.tclr); | ||||||
| 				timer->context.tclr); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void omap_timer_save_context(struct omap_dm_timer *timer) | static void omap_timer_save_context(struct omap_dm_timer *timer) | ||||||
|  | @ -256,7 +246,7 @@ static int omap_dm_timer_reset(struct omap_dm_timer *timer) | ||||||
| 	if (timer->revision != 1) | 	if (timer->revision != 1) | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 
 | 
 | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); | 	dmtimer_write(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); | ||||||
| 
 | 
 | ||||||
| 	do { | 	do { | ||||||
| 		l = dmtimer_read(timer, OMAP_TIMER_V1_SYS_STAT_OFFSET); | 		l = dmtimer_read(timer, OMAP_TIMER_V1_SYS_STAT_OFFSET); | ||||||
|  | @ -270,7 +260,7 @@ static int omap_dm_timer_reset(struct omap_dm_timer *timer) | ||||||
| 	/* Configure timer for smart-idle mode */ | 	/* Configure timer for smart-idle mode */ | ||||||
| 	l = dmtimer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET); | 	l = dmtimer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET); | ||||||
| 	l |= 0x2 << 0x3; | 	l |= 0x2 << 0x3; | ||||||
| 	__omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0); | 	dmtimer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l); | ||||||
| 
 | 
 | ||||||
| 	timer->posted = 0; | 	timer->posted = 0; | ||||||
| 
 | 
 | ||||||
|  | @ -586,7 +576,7 @@ static int omap_dm_timer_start(struct omap_dm_timer *timer) | ||||||
| 	l = dmtimer_read(timer, OMAP_TIMER_CTRL_REG); | 	l = dmtimer_read(timer, OMAP_TIMER_CTRL_REG); | ||||||
| 	if (!(l & OMAP_TIMER_CTRL_ST)) { | 	if (!(l & OMAP_TIMER_CTRL_ST)) { | ||||||
| 		l |= OMAP_TIMER_CTRL_ST; | 		l |= OMAP_TIMER_CTRL_ST; | ||||||
| 		omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); | 		dmtimer_write(timer, OMAP_TIMER_CTRL_REG, l); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
|  | @ -602,7 +592,7 @@ static int omap_dm_timer_stop(struct omap_dm_timer *timer) | ||||||
| 	if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) | 	if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) | ||||||
| 		rate = clk_get_rate(timer->fclk); | 		rate = clk_get_rate(timer->fclk); | ||||||
| 
 | 
 | ||||||
| 	__omap_dm_timer_stop(timer, timer->posted, rate); | 	__omap_dm_timer_stop(timer, rate); | ||||||
| 
 | 
 | ||||||
| 	omap_dm_timer_disable(timer); | 	omap_dm_timer_disable(timer); | ||||||
| 	return 0; | 	return 0; | ||||||
|  | @ -615,7 +605,7 @@ static int omap_dm_timer_set_load(struct omap_dm_timer *timer, | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 
 | 
 | ||||||
| 	omap_dm_timer_enable(timer); | 	omap_dm_timer_enable(timer); | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); | 	dmtimer_write(timer, OMAP_TIMER_LOAD_REG, load); | ||||||
| 
 | 
 | ||||||
| 	omap_dm_timer_disable(timer); | 	omap_dm_timer_disable(timer); | ||||||
| 	return 0; | 	return 0; | ||||||
|  | @ -635,8 +625,8 @@ static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, | ||||||
| 		l |= OMAP_TIMER_CTRL_CE; | 		l |= OMAP_TIMER_CTRL_CE; | ||||||
| 	else | 	else | ||||||
| 		l &= ~OMAP_TIMER_CTRL_CE; | 		l &= ~OMAP_TIMER_CTRL_CE; | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match); | 	dmtimer_write(timer, OMAP_TIMER_MATCH_REG, match); | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); | 	dmtimer_write(timer, OMAP_TIMER_CTRL_REG, l); | ||||||
| 
 | 
 | ||||||
| 	omap_dm_timer_disable(timer); | 	omap_dm_timer_disable(timer); | ||||||
| 	return 0; | 	return 0; | ||||||
|  | @ -661,7 +651,7 @@ static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, | ||||||
| 	l |= trigger << 10; | 	l |= trigger << 10; | ||||||
| 	if (autoreload) | 	if (autoreload) | ||||||
| 		l |= OMAP_TIMER_CTRL_AR; | 		l |= OMAP_TIMER_CTRL_AR; | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); | 	dmtimer_write(timer, OMAP_TIMER_CTRL_REG, l); | ||||||
| 
 | 
 | ||||||
| 	omap_dm_timer_disable(timer); | 	omap_dm_timer_disable(timer); | ||||||
| 	return 0; | 	return 0; | ||||||
|  | @ -696,7 +686,7 @@ static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, | ||||||
| 		l |= OMAP_TIMER_CTRL_PRE; | 		l |= OMAP_TIMER_CTRL_PRE; | ||||||
| 		l |= prescaler << 2; | 		l |= prescaler << 2; | ||||||
| 	} | 	} | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); | 	dmtimer_write(timer, OMAP_TIMER_CTRL_REG, l); | ||||||
| 
 | 
 | ||||||
| 	omap_dm_timer_disable(timer); | 	omap_dm_timer_disable(timer); | ||||||
| 	return 0; | 	return 0; | ||||||
|  | @ -736,7 +726,7 @@ static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask) | ||||||
| 
 | 
 | ||||||
| 	writel_relaxed(l, timer->irq_dis); | 	writel_relaxed(l, timer->irq_dis); | ||||||
| 	l = dmtimer_read(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask; | 	l = dmtimer_read(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask; | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l); | 	dmtimer_write(timer, OMAP_TIMER_WAKEUP_EN_REG, l); | ||||||
| 
 | 
 | ||||||
| 	omap_dm_timer_disable(timer); | 	omap_dm_timer_disable(timer); | ||||||
| 	return 0; | 	return 0; | ||||||
|  | @ -783,7 +773,7 @@ static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); | 	dmtimer_write(timer, OMAP_TIMER_COUNTER_REG, value); | ||||||
| 
 | 
 | ||||||
| 	/* Save the context */ | 	/* Save the context */ | ||||||
| 	timer->context.tcrr = value; | 	timer->context.tcrr = value; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Tony Lindgren
						Tony Lindgren