]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00173586-1 [MX6] Add support to source GPT from 24MHz
authorRanjani Vaidyanathan <ra5478@freescale.com>
Thu, 2 Feb 2012 11:31:52 +0000 (05:31 -0600)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:33:54 +0000 (08:33 +0200)
On MX6Q TO1.1, MX6DL/S and MX6Solo, GPT can be sourced
from a constant source (better for frequency scaling).
Currently we set the GPT clock to 3MHz (24MHz div by 8).

Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
arch/arm/plat-mxc/include/mach/common.h
arch/arm/plat-mxc/time.c

index 9a340ccf8dac25175192b76e4ea5b7a3f8e203bf..a8d1982b1b08cc9c3f866633d20c55ec8711fb79 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -86,4 +86,5 @@ extern void mx51_efikamx_reset(void);
 extern int mx53_revision(void);
 extern int mx50_revision(void);
 extern int mx53_display_revision(void);
+extern unsigned long mx6_timer_rate(void);
 #endif
index dd6b74e378c1e2d13c9d18db1e8fbd700ce35037..437921fdd2c2b1ba30b1df90cfba9e41fff509a8 100644 (file)
 #define V2_TCTL_WAITEN         (1 << 3) /* Wait enable mode */
 #define V2_TCTL_CLK_IPG                (1 << 6)
 #define V2_TCTL_CLK_PER                (2 << 6)
-#define V2_TCTL_FRR            (1 << 9)
+#define V2_TCTL_CLK_OSC_DIV8    (5 << 6)
+#define V2_TCTL_CLK_OSC                (7 << 6)
+#define V2_TCTL_FRR                    (1 << 9)
+#define V2_TCTL_ENABLE24M      (1 << 10)
+#define V2_TPRER_PRE24M_DIV8   7
+#define V2_TPRER_PRE24M_MASK   0xF
+#define V2_TPRER_PRE24M_OFFSET 12
 #define V2_IR                  0x0c
 #define V2_TSTAT               0x08
 #define V2_TSTAT_OF1           (1 << 0)
@@ -73,6 +79,10 @@ static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
 
 static void __iomem *timer_base;
 
+#ifdef CONFIG_ARCH_MX6
+extern int mx6q_revision(void);
+#endif
+
 static inline void gpt_irq_disable(void)
 {
        unsigned int tmp;
@@ -289,9 +299,38 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
        return 0;
 }
 
+#ifdef CONFIG_ARCH_MX6
+unsigned long mx6_timer_rate()
+{
+       struct clk *osc_clk = clk_get(NULL, "osc");
+       u32 parent_rate = clk_get_rate(osc_clk);
+
+       u32 reg = __raw_readl(timer_base + MXC_TCTL);
+       u32 div;
+
+       clk_put(osc_clk);
+
+       if ((reg & V2_TCTL_CLK_OSC_DIV8) == V2_TCTL_CLK_OSC_DIV8) {
+               if (cpu_is_mx6q())
+                       /* For MX6Q, only options are 24MHz or 24MHz/8*/
+                       return parent_rate / 8;
+               else {
+                       /* For MX6DLS and MX6Solo, the rate is based on the
+                         * divider value set in prescalar register. */
+                       div = __raw_readl(timer_base + MXC_TPRER);
+                       div = (div >> V2_TPRER_PRE24M_OFFSET) &
+                                       V2_TPRER_PRE24M_MASK;
+                       return parent_rate / (div + 1);
+               }
+       }
+       return 0;
+}
+#endif
+
 void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
 {
        uint32_t tctl_val;
+       u32 reg;
 
        clk_enable(timer_clk);
 
@@ -304,9 +343,24 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
        __raw_writel(0, timer_base + MXC_TCTL);
        __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
 
-       if (timer_is_v2())
-               tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
-       else
+       if (timer_is_v2()) {
+               if (cpu_is_mx5() ||
+                       mx6q_revision() == IMX_CHIP_REVISION_1_0)
+                       tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR |
+                                               V2_TCTL_WAITEN | MXC_TCTL_TEN;
+               else {
+                       tctl_val = V2_TCTL_CLK_OSC_DIV8 | V2_TCTL_FRR |
+                                               V2_TCTL_WAITEN | MXC_TCTL_TEN;
+                       if (!cpu_is_mx6q()) {
+                               reg = __raw_readl(timer_base + MXC_TPRER);
+                               reg |= (V2_TPRER_PRE24M_DIV8 <<
+                                                       V2_TPRER_PRE24M_OFFSET);
+                               __raw_writel(reg, timer_base + MXC_TPRER);
+                               /* Enable the 24MHz input clock. */
+                               tctl_val |= V2_TCTL_ENABLE24M;
+                       }
+               }
+       } else
                tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
 
        __raw_writel(tctl_val, timer_base + MXC_TCTL);