aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/time.c')
-rw-r--r--arch/arm/mach-imx/time.c31
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}
357CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt); 378CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt);