forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 10ebd8556b7990499c896a550e3d416b444211e6
kernel/arch/arm/mach-mmp/time.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * linux/arch/arm/mach-mmp/time.c
34 *
....@@ -12,16 +13,13 @@
1213 * The timers module actually includes three timers, each timer with up to
1314 * three match comparators. Timer #0 is used here in free-running mode as
1415 * the clock source, and match comparator #1 used as clock event device.
15
- *
16
- * This program is free software; you can redistribute it and/or modify
17
- * it under the terms of the GNU General Public License version 2 as
18
- * published by the Free Software Foundation.
1916 */
2017
2118 #include <linux/init.h>
2219 #include <linux/kernel.h>
2320 #include <linux/interrupt.h>
2421 #include <linux/clockchips.h>
22
+#include <linux/clk.h>
2523
2624 #include <linux/io.h>
2725 #include <linux/irq.h>
....@@ -35,14 +33,7 @@
3533 #include "regs-timers.h"
3634 #include "regs-apbc.h"
3735 #include "irqs.h"
38
-#include "cputype.h"
39
-#include "clock.h"
40
-
41
-#ifdef CONFIG_CPU_MMP2
42
-#define MMP_CLOCK_FREQ 6500000
43
-#else
44
-#define MMP_CLOCK_FREQ 3250000
45
-#endif
36
+#include <linux/soc/mmp/cputype.h>
4637
4738 #define TIMERS_VIRT_BASE TIMERS1_VIRT_BASE
4839
....@@ -52,18 +43,21 @@
5243 static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE;
5344
5445 /*
55
- * FIXME: the timer needs some delay to stablize the counter capture
46
+ * Read the timer through the CVWR register. Delay is required after requesting
47
+ * a read. The CR register cannot be directly read due to metastability issues
48
+ * documented in the PXA168 software manual.
5649 */
5750 static inline uint32_t timer_read(void)
5851 {
59
- int delay = 100;
52
+ uint32_t val;
53
+ int delay = 3;
6054
6155 __raw_writel(1, mmp_timer_base + TMR_CVWR(1));
6256
6357 while (delay--)
64
- cpu_relax();
58
+ val = __raw_readl(mmp_timer_base + TMR_CVWR(1));
6559
66
- return __raw_readl(mmp_timer_base + TMR_CVWR(1));
60
+ return val;
6761 }
6862
6963 static u64 notrace mmp_read_sched_clock(void)
....@@ -163,7 +157,8 @@
163157
164158 __raw_writel(0x0, mmp_timer_base + TMR_CER); /* disable */
165159
166
- ccr &= (cpu_is_mmp2()) ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) :
160
+ ccr &= (cpu_is_mmp2() || cpu_is_mmp3()) ?
161
+ (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) :
167162 (TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3));
168163 __raw_writel(ccr, mmp_timer_base + TMR_CCR);
169164
....@@ -182,58 +177,50 @@
182177 __raw_writel(0x2, mmp_timer_base + TMR_CER);
183178 }
184179
185
-static struct irqaction timer_irq = {
186
- .name = "timer",
187
- .flags = IRQF_TIMER | IRQF_IRQPOLL,
188
- .handler = timer_interrupt,
189
- .dev_id = &ckevt,
190
-};
191
-
192
-void __init timer_init(int irq)
180
+void __init mmp_timer_init(int irq, unsigned long rate)
193181 {
194182 timer_config();
195183
196
- sched_clock_register(mmp_read_sched_clock, 32, MMP_CLOCK_FREQ);
184
+ sched_clock_register(mmp_read_sched_clock, 32, rate);
197185
198186 ckevt.cpumask = cpumask_of(0);
199187
200
- setup_irq(irq, &timer_irq);
188
+ if (request_irq(irq, timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
189
+ "timer", &ckevt))
190
+ pr_err("Failed to request irq %d (timer)\n", irq);
201191
202
- clocksource_register_hz(&cksrc, MMP_CLOCK_FREQ);
203
- clockevents_config_and_register(&ckevt, MMP_CLOCK_FREQ,
204
- MIN_DELTA, MAX_DELTA);
192
+ clocksource_register_hz(&cksrc, rate);
193
+ clockevents_config_and_register(&ckevt, rate, MIN_DELTA, MAX_DELTA);
205194 }
206195
207
-#ifdef CONFIG_OF
208
-static const struct of_device_id mmp_timer_dt_ids[] = {
209
- { .compatible = "mrvl,mmp-timer", },
210
- {}
211
-};
212
-
213
-void __init mmp_dt_init_timer(void)
196
+static int __init mmp_dt_init_timer(struct device_node *np)
214197 {
215
- struct device_node *np;
198
+ struct clk *clk;
216199 int irq, ret;
200
+ unsigned long rate;
217201
218
- np = of_find_matching_node(NULL, mmp_timer_dt_ids);
219
- if (!np) {
220
- ret = -ENODEV;
221
- goto out;
202
+ clk = of_clk_get(np, 0);
203
+ if (!IS_ERR(clk)) {
204
+ ret = clk_prepare_enable(clk);
205
+ if (ret)
206
+ return ret;
207
+ rate = clk_get_rate(clk);
208
+ } else if (cpu_is_pj4()) {
209
+ rate = 6500000;
210
+ } else {
211
+ rate = 3250000;
222212 }
223213
224214 irq = irq_of_parse_and_map(np, 0);
225
- if (!irq) {
226
- ret = -EINVAL;
227
- goto out;
228
- }
215
+ if (!irq)
216
+ return -EINVAL;
217
+
229218 mmp_timer_base = of_iomap(np, 0);
230
- if (!mmp_timer_base) {
231
- ret = -ENOMEM;
232
- goto out;
233
- }
234
- timer_init(irq);
235
- return;
236
-out:
237
- pr_err("Failed to get timer from device tree with error:%d\n", ret);
219
+ if (!mmp_timer_base)
220
+ return -ENOMEM;
221
+
222
+ mmp_timer_init(irq, rate);
223
+ return 0;
238224 }
239
-#endif
225
+
226
+TIMER_OF_DECLARE(mmp_timer, "mrvl,mmp-timer", mmp_dt_init_timer);