1717#include <linux/of_irq.h>
1818#include <linux/sched_clock.h>
1919
20+ #define TPM_PARAM 0x4
21+ #define TPM_PARAM_WIDTH_SHIFT 16
22+ #define TPM_PARAM_WIDTH_MASK (0xff << 16)
2023#define TPM_SC 0x10
2124#define TPM_SC_CMOD_INC_PER_CNT (0x1 << 3)
2225#define TPM_SC_CMOD_DIV_DEFAULT 0x3
26+ #define TPM_SC_CMOD_DIV_MAX 0x7
2327#define TPM_SC_TOF_MASK (0x1 << 7)
2428#define TPM_CNT 0x14
2529#define TPM_MOD 0x18
3337#define TPM_C0SC_CHF_MASK (0x1 << 7)
3438#define TPM_C0V 0x24
3539
40+ static int counter_width ;
41+ static int rating ;
3642static void __iomem * timer_base ;
3743static struct clock_event_device clockevent_tpm ;
3844
@@ -85,10 +91,11 @@ static int __init tpm_clocksource_init(unsigned long rate)
8591 tpm_delay_timer .freq = rate ;
8692 register_current_timer_delay (& tpm_delay_timer );
8793
88- sched_clock_register (tpm_read_sched_clock , 32 , rate );
94+ sched_clock_register (tpm_read_sched_clock , counter_width , rate );
8995
9096 return clocksource_mmio_init (timer_base + TPM_CNT , "imx-tpm" ,
91- rate , 200 , 32 , clocksource_mmio_readl_up );
97+ rate , rating , counter_width ,
98+ clocksource_mmio_readl_up );
9299}
93100
94101static int tpm_set_next_event (unsigned long delta ,
@@ -141,7 +148,6 @@ static struct clock_event_device clockevent_tpm = {
141148 .set_state_oneshot = tpm_set_state_oneshot ,
142149 .set_next_event = tpm_set_next_event ,
143150 .set_state_shutdown = tpm_set_state_shutdown ,
144- .rating = 200 ,
145151};
146152
147153static int __init tpm_clockevent_init (unsigned long rate , int irq )
@@ -151,10 +157,11 @@ static int __init tpm_clockevent_init(unsigned long rate, int irq)
151157 ret = request_irq (irq , tpm_timer_interrupt , IRQF_TIMER | IRQF_IRQPOLL ,
152158 "i.MX7ULP TPM Timer" , & clockevent_tpm );
153159
160+ clockevent_tpm .rating = rating ;
154161 clockevent_tpm .cpumask = cpumask_of (0 );
155162 clockevent_tpm .irq = irq ;
156- clockevents_config_and_register (& clockevent_tpm ,
157- rate , 300 , 0xfffffffe );
163+ clockevents_config_and_register (& clockevent_tpm , rate , 300 ,
164+ GENMASK ( counter_width - 1 , 1 ) );
158165
159166 return ret ;
160167}
@@ -199,6 +206,11 @@ static int __init tpm_timer_init(struct device_node *np)
199206 goto err_per_clk_enable ;
200207 }
201208
209+ counter_width = (readl (timer_base + TPM_PARAM ) & TPM_PARAM_WIDTH_MASK )
210+ >> TPM_PARAM_WIDTH_SHIFT ;
211+ /* use rating 200 for 32-bit counter and 150 for 16-bit counter */
212+ rating = counter_width == 0x20 ? 200 : 150 ;
213+
202214 /*
203215 * Initialize tpm module to a known state
204216 * 1) Counter disabled
@@ -215,12 +227,17 @@ static int __init tpm_timer_init(struct device_node *np)
215227 /* CHF is W1C */
216228 writel (TPM_C0SC_CHF_MASK , timer_base + TPM_C0SC );
217229
218- /* increase per cnt, div 8 by default */
219- writel (TPM_SC_CMOD_INC_PER_CNT | TPM_SC_CMOD_DIV_DEFAULT ,
230+ /*
231+ * increase per cnt,
232+ * div 8 for 32-bit counter and div 128 for 16-bit counter
233+ */
234+ writel (TPM_SC_CMOD_INC_PER_CNT |
235+ (counter_width == 0x20 ?
236+ TPM_SC_CMOD_DIV_DEFAULT : TPM_SC_CMOD_DIV_MAX ),
220237 timer_base + TPM_SC );
221238
222239 /* set MOD register to maximum for free running mode */
223- writel (0xffffffff , timer_base + TPM_MOD );
240+ writel (GENMASK ( counter_width - 1 , 0 ) , timer_base + TPM_MOD );
224241
225242 rate = clk_get_rate (per ) >> 3 ;
226243 ret = tpm_clocksource_init (rate );
0 commit comments