|
22 | 22 |
|
23 | 23 | #define TIMER_SYNC_TICKS (3) |
24 | 24 |
|
25 | | -/* cpux mcusys wrapper */ |
26 | | -#define CPUX_CON_REG 0x0 |
27 | | -#define CPUX_IDX_REG 0x4 |
28 | | - |
29 | | -/* cpux */ |
30 | | -#define CPUX_IDX_GLOBAL_CTRL 0x0 |
31 | | - #define CPUX_ENABLE BIT(0) |
32 | | - #define CPUX_CLK_DIV_MASK GENMASK(10, 8) |
33 | | - #define CPUX_CLK_DIV1 BIT(8) |
34 | | - #define CPUX_CLK_DIV2 BIT(9) |
35 | | - #define CPUX_CLK_DIV4 BIT(10) |
36 | | -#define CPUX_IDX_GLOBAL_IRQ 0x30 |
37 | | - |
38 | 25 | /* gpt */ |
39 | 26 | #define GPT_IRQ_EN_REG 0x00 |
40 | 27 | #define GPT_IRQ_ENABLE(val) BIT((val) - 1) |
|
85 | 72 |
|
86 | 73 | static void __iomem *gpt_sched_reg __read_mostly; |
87 | 74 |
|
88 | | -static u32 mtk_cpux_readl(u32 reg_idx, struct timer_of *to) |
89 | | -{ |
90 | | - writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG); |
91 | | - return readl(timer_of_base(to) + CPUX_CON_REG); |
92 | | -} |
93 | | - |
94 | | -static void mtk_cpux_writel(u32 val, u32 reg_idx, struct timer_of *to) |
95 | | -{ |
96 | | - writel(reg_idx, timer_of_base(to) + CPUX_IDX_REG); |
97 | | - writel(val, timer_of_base(to) + CPUX_CON_REG); |
98 | | -} |
99 | | - |
100 | | -static void mtk_cpux_set_irq(struct timer_of *to, bool enable) |
101 | | -{ |
102 | | - const unsigned long *irq_mask = cpumask_bits(cpu_possible_mask); |
103 | | - u32 val; |
104 | | - |
105 | | - val = mtk_cpux_readl(CPUX_IDX_GLOBAL_IRQ, to); |
106 | | - |
107 | | - if (enable) |
108 | | - val |= *irq_mask; |
109 | | - else |
110 | | - val &= ~(*irq_mask); |
111 | | - |
112 | | - mtk_cpux_writel(val, CPUX_IDX_GLOBAL_IRQ, to); |
113 | | -} |
114 | | - |
115 | | -static int mtk_cpux_clkevt_shutdown(struct clock_event_device *clkevt) |
116 | | -{ |
117 | | - /* Clear any irq */ |
118 | | - mtk_cpux_set_irq(to_timer_of(clkevt), false); |
119 | | - |
120 | | - /* |
121 | | - * Disabling CPUXGPT timer will crash the platform, especially |
122 | | - * if Trusted Firmware is using it (usually, for sleep states), |
123 | | - * so we only mask the IRQ and call it a day. |
124 | | - */ |
125 | | - return 0; |
126 | | -} |
127 | | - |
128 | | -static int mtk_cpux_clkevt_resume(struct clock_event_device *clkevt) |
129 | | -{ |
130 | | - mtk_cpux_set_irq(to_timer_of(clkevt), true); |
131 | | - return 0; |
132 | | -} |
133 | | - |
134 | 75 | static void mtk_syst_ack_irq(struct timer_of *to) |
135 | 76 | { |
136 | 77 | /* Clear and disable interrupt */ |
@@ -340,60 +281,6 @@ static struct timer_of to = { |
340 | 281 | }, |
341 | 282 | }; |
342 | 283 |
|
343 | | -static int __init mtk_cpux_init(struct device_node *node) |
344 | | -{ |
345 | | - static struct timer_of to_cpux; |
346 | | - u32 freq, val; |
347 | | - int ret; |
348 | | - |
349 | | - /* |
350 | | - * There are per-cpu interrupts for the CPUX General Purpose Timer |
351 | | - * but since this timer feeds the AArch64 System Timer we can rely |
352 | | - * on the CPU timer PPIs as well, so we don't declare TIMER_OF_IRQ. |
353 | | - */ |
354 | | - to_cpux.flags = TIMER_OF_BASE | TIMER_OF_CLOCK; |
355 | | - to_cpux.clkevt.name = "mtk-cpuxgpt"; |
356 | | - to_cpux.clkevt.rating = 10; |
357 | | - to_cpux.clkevt.cpumask = cpu_possible_mask; |
358 | | - to_cpux.clkevt.set_state_shutdown = mtk_cpux_clkevt_shutdown; |
359 | | - to_cpux.clkevt.tick_resume = mtk_cpux_clkevt_resume; |
360 | | - |
361 | | - /* If this fails, bad things are about to happen... */ |
362 | | - ret = timer_of_init(node, &to_cpux); |
363 | | - if (ret) { |
364 | | - WARN(1, "Cannot start CPUX timers.\n"); |
365 | | - return ret; |
366 | | - } |
367 | | - |
368 | | - /* |
369 | | - * Check if we're given a clock with the right frequency for this |
370 | | - * timer, otherwise warn but keep going with the setup anyway, as |
371 | | - * that makes it possible to still boot the kernel, even though |
372 | | - * it may not work correctly (random lockups, etc). |
373 | | - * The reason behind this is that having an early UART may not be |
374 | | - * possible for everyone and this gives a chance to retrieve kmsg |
375 | | - * for eventual debugging even on consumer devices. |
376 | | - */ |
377 | | - freq = timer_of_rate(&to_cpux); |
378 | | - if (freq > 13000000) |
379 | | - WARN(1, "Requested unsupported timer frequency %u\n", freq); |
380 | | - |
381 | | - /* Clock input is 26MHz, set DIV2 to achieve 13MHz clock */ |
382 | | - val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux); |
383 | | - val &= ~CPUX_CLK_DIV_MASK; |
384 | | - val |= CPUX_CLK_DIV2; |
385 | | - mtk_cpux_writel(val, CPUX_IDX_GLOBAL_CTRL, &to_cpux); |
386 | | - |
387 | | - /* Enable all CPUXGPT timers */ |
388 | | - val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to_cpux); |
389 | | - mtk_cpux_writel(val | CPUX_ENABLE, CPUX_IDX_GLOBAL_CTRL, &to_cpux); |
390 | | - |
391 | | - clockevents_config_and_register(&to_cpux.clkevt, timer_of_rate(&to_cpux), |
392 | | - TIMER_SYNC_TICKS, 0xffffffff); |
393 | | - |
394 | | - return 0; |
395 | | -} |
396 | | - |
397 | 284 | static int __init mtk_syst_init(struct device_node *node) |
398 | 285 | { |
399 | 286 | int ret; |
@@ -452,4 +339,3 @@ static int __init mtk_gpt_init(struct device_node *node) |
452 | 339 | } |
453 | 340 | TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init); |
454 | 341 | TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init); |
455 | | -TIMER_OF_DECLARE(mtk_mt6795, "mediatek,mt6795-systimer", mtk_cpux_init); |
0 commit comments