Skip to content

Commit 0136c74

Browse files
Anson-Huangdlezcano
authored andcommitted
clocksource/drivers/imx-tpm: Add different counter width support
Different TPM modules have different width counters which is 16-bit or 32-bit, the counter width can be read from TPM_PARAM register bit[23:16], this patch adds dynamic check for counter width to support both 16-bit and 32-bit TPM modules. Signed-off-by: Anson Huang <[email protected]> Signed-off-by: Daniel Lezcano <[email protected]>
1 parent 506a7be commit 0136c74

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

drivers/clocksource/timer-imx-tpm.c

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@
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
@@ -33,6 +37,8 @@
3337
#define TPM_C0SC_CHF_MASK (0x1 << 7)
3438
#define TPM_C0V 0x24
3539

40+
static int counter_width;
41+
static int rating;
3642
static void __iomem *timer_base;
3743
static 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

94101
static 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

147153
static 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

Comments
 (0)