diff options
Diffstat (limited to 'arch/arm/mach-imx/time.c')
-rw-r--r-- | arch/arm/mach-imx/time.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index bf92e5a351c0..15d18e198303 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c | |||
@@ -60,17 +60,22 @@ | |||
60 | #define MX2_TSTAT_CAPT (1 << 1) | 60 | #define MX2_TSTAT_CAPT (1 << 1) |
61 | #define MX2_TSTAT_COMP (1 << 0) | 61 | #define MX2_TSTAT_COMP (1 << 0) |
62 | 62 | ||
63 | /* MX31, MX35, MX25, MX5 */ | 63 | /* MX31, MX35, MX25, MX5, MX6 */ |
64 | #define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */ | 64 | #define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */ |
65 | #define V2_TCTL_CLK_IPG (1 << 6) | 65 | #define V2_TCTL_CLK_IPG (1 << 6) |
66 | #define V2_TCTL_CLK_PER (2 << 6) | 66 | #define V2_TCTL_CLK_PER (2 << 6) |
67 | #define V2_TCTL_CLK_OSC_DIV8 (5 << 6) | ||
67 | #define V2_TCTL_FRR (1 << 9) | 68 | #define V2_TCTL_FRR (1 << 9) |
69 | #define V2_TCTL_24MEN (1 << 10) | ||
70 | #define V2_TPRER_PRE24M 12 | ||
68 | #define V2_IR 0x0c | 71 | #define V2_IR 0x0c |
69 | #define V2_TSTAT 0x08 | 72 | #define V2_TSTAT 0x08 |
70 | #define V2_TSTAT_OF1 (1 << 0) | 73 | #define V2_TSTAT_OF1 (1 << 0) |
71 | #define V2_TCN 0x24 | 74 | #define V2_TCN 0x24 |
72 | #define V2_TCMP 0x10 | 75 | #define V2_TCMP 0x10 |
73 | 76 | ||
77 | #define V2_TIMER_RATE_OSC_DIV8 3000000 | ||
78 | |||
74 | #define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) | 79 | #define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) |
75 | #define timer_is_v2() (!timer_is_v1()) | 80 | #define timer_is_v2() (!timer_is_v1()) |
76 | 81 | ||
@@ -312,10 +317,22 @@ static void __init _mxc_timer_init(int irq, | |||
312 | __raw_writel(0, timer_base + MXC_TCTL); | 317 | __raw_writel(0, timer_base + MXC_TCTL); |
313 | __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ | 318 | __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ |
314 | 319 | ||
315 | if (timer_is_v2()) | 320 | if (timer_is_v2()) { |
316 | tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; | 321 | tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; |
317 | else | 322 | if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8) { |
323 | tctl_val |= V2_TCTL_CLK_OSC_DIV8; | ||
324 | if (cpu_is_imx6dl() || cpu_is_imx6sx()) { | ||
325 | /* 24 / 8 = 3 MHz */ | ||
326 | __raw_writel(7 << V2_TPRER_PRE24M, | ||
327 | timer_base + MXC_TPRER); | ||
328 | tctl_val |= V2_TCTL_24MEN; | ||
329 | } | ||
330 | } else { | ||
331 | tctl_val |= V2_TCTL_CLK_PER; | ||
332 | } | ||
333 | } else { | ||
318 | tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; | 334 | tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; |
335 | } | ||
319 | 336 | ||
320 | __raw_writel(tctl_val, timer_base + MXC_TCTL); | 337 | __raw_writel(tctl_val, timer_base + MXC_TCTL); |
321 | 338 | ||
@@ -349,9 +366,13 @@ static void __init mxc_timer_init_dt(struct device_node *np) | |||
349 | WARN_ON(!timer_base); | 366 | WARN_ON(!timer_base); |
350 | irq = irq_of_parse_and_map(np, 0); | 367 | irq = irq_of_parse_and_map(np, 0); |
351 | 368 | ||
352 | clk_per = of_clk_get_by_name(np, "per"); | ||
353 | clk_ipg = of_clk_get_by_name(np, "ipg"); | 369 | clk_ipg = of_clk_get_by_name(np, "ipg"); |
354 | 370 | ||
371 | /* Try osc_per first, and fall back to per otherwise */ | ||
372 | clk_per = of_clk_get_by_name(np, "osc_per"); | ||
373 | if (IS_ERR(clk_per)) | ||
374 | clk_per = of_clk_get_by_name(np, "per"); | ||
375 | |||
355 | _mxc_timer_init(irq, clk_per, clk_ipg); | 376 | _mxc_timer_init(irq, clk_per, clk_ipg); |
356 | } | 377 | } |
357 | CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt); | 378 | CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt); |