]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00160615 Clock updates to enable support clko
authorMahesh Mahadevan <r9aadq@freescale.com>
Fri, 21 Oct 2011 15:50:25 +0000 (10:50 -0500)
committerOliver Wendt <ow@karo-electronics.de>
Mon, 30 Sep 2013 12:09:46 +0000 (14:09 +0200)
Enable support for clko clock used for the audio codec
on MX6 Sabre-lite board

Signed-off-by: Mahesh Mahadevan <r9aadq@freescale.com>
arch/arm/mach-mx6/clock.c
arch/arm/mach-mx6/crm_regs.h

index fe9dba23cc989e8eab4bcb982a5d7d4f62f89c15..7ca3b884c0cb0fec24bcbe200e73c283d508414e 100644 (file)
@@ -4408,6 +4408,123 @@ static struct clk usboh3_clk[] = {
        },
 };
 
+static int _clk_enable1(struct clk *clk)
+{
+       u32 reg;
+       reg = __raw_readl(clk->enable_reg);
+       reg |= 1 << clk->enable_shift;
+       __raw_writel(reg, clk->enable_reg);
+
+       return 0;
+}
+
+static void _clk_disable1(struct clk *clk)
+{
+       u32 reg;
+       reg = __raw_readl(clk->enable_reg);
+       reg &= ~(1 << clk->enable_shift);
+       __raw_writel(reg, clk->enable_reg);
+}
+
+static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
+{
+       u32 sel, reg;
+
+       if (parent == &pll3_usb_otg_main_clk)
+               sel = 0;
+       else if (parent == &pll2_528_bus_main_clk)
+               sel = 1;
+       else if (parent == &pll1_sys_main_clk)
+               sel = 2;
+       else if (parent == &pll5_video_main_clk)
+               sel = 3;
+       else if (parent == &axi_clk)
+               sel = 5;
+       else if (parent == &enfc_clk)
+               sel = 6;
+       else if (parent == &ipu1_di_clk[0])
+               sel = 7;
+       else if (parent == &ipu1_di_clk[1])
+               sel = 8;
+       else if (parent == &ipu2_di_clk[0])
+               sel = 9;
+       else if (parent == &ipu2_di_clk[1])
+               sel = 10;
+       else if (parent == &ahb_clk)
+               sel = 11;
+       else if (parent == &ipg_clk)
+               sel = 12;
+       else if (parent == &ipg_perclk)
+               sel = 13;
+       else if (parent == &ckil_clk)
+               sel = 14;
+       else if (parent == &pll4_audio_main_clk)
+               sel = 15;
+       else
+               return -EINVAL;
+
+       reg = __raw_readl(MXC_CCM_CCOSR);
+       reg &= ~MXC_CCM_CCOSR_CKOL_SEL_MASK;
+       reg |= sel << MXC_CCM_CCOSR_CKOL_SEL_OFFSET;
+       __raw_writel(reg, MXC_CCM_CCOSR);
+       return 0;
+}
+
+static unsigned long _clk_clko_get_rate(struct clk *clk)
+{
+       u32 reg = __raw_readl(MXC_CCM_CCOSR);
+       u32 div = ((reg & MXC_CCM_CCOSR_CKOL_DIV_MASK) >>
+                       MXC_CCM_CCOSR_CKOL_DIV_OFFSET) + 1;
+       return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
+{
+       u32 reg;
+       u32 parent_rate = clk_get_rate(clk->parent);
+       u32 div = parent_rate / rate;
+
+       if (div == 0)
+               div++;
+       if (((parent_rate / div) != rate) || (div > 8))
+               return -EINVAL;
+
+       reg = __raw_readl(MXC_CCM_CCOSR);
+       reg &= ~MXC_CCM_CCOSR_CKOL_DIV_MASK;
+       reg |= (div - 1) << MXC_CCM_CCOSR_CKOL_DIV_OFFSET;
+       __raw_writel(reg, MXC_CCM_CCOSR);
+       return 0;
+}
+
+static unsigned long _clk_clko_round_rate(struct clk *clk,
+                                               unsigned long rate)
+{
+       u32 parent_rate = clk_get_rate(clk->parent);
+       u32 div = parent_rate / rate;
+
+       /* Make sure rate is not greater than the maximum value for the clock.
+        * Also prevent a div of 0.
+        */
+       if (div == 0)
+               div++;
+       if (div > 8)
+               div = 8;
+       return parent_rate / div;
+}
+
+static struct clk clko_clk = {
+       __INIT_CLK_DEBUG(clko_clk)
+       .parent = &pll2_528_bus_main_clk,
+       .enable = _clk_enable1,
+       .enable_reg = MXC_CCM_CCOSR,
+       .enable_shift = MXC_CCM_CCOSR_CKOL_EN_OFFSET,
+       .disable = _clk_disable1,
+       .set_parent = _clk_clko_set_parent,
+       .set_rate = _clk_clko_set_rate,
+       .get_rate = _clk_clko_get_rate,
+       .round_rate = _clk_clko_round_rate,
+};
+
 static struct clk dummy_clk = {
        .id = 0,
 };
@@ -4525,6 +4642,7 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK(NULL, NULL, vdoa_clk),
        _REGISTER_CLOCK(NULL, NULL, aips_tz2_clk),
        _REGISTER_CLOCK(NULL, NULL, aips_tz1_clk),
+       _REGISTER_CLOCK(NULL, "clko_clk", clko_clk),
 };
 
 
index 273e8d238caab6b792c12b8db36a45f19cddce64..c17f8bb23ee2482d483a0629aaa57ed1309c1afb 100644 (file)
 #define MXC_CCM_CCOSR_CKO2_DIV_OFFSET          (21)
 #define MXC_CCM_CCOSR_CKO2_SEL_OFFSET          (16)
 #define MXC_CCM_CCOSR_CKO2_SEL_MASK            (0x1F << 16)
+#define MXC_CCM_CCOSR_CKOL_MIRROR_CKO2_MASK    (1 << 8)
+#define MXC_CCM_CCOSR_CKOL_EN_OFFSET           7
 #define MXC_CCM_CCOSR_CKOL_EN                  (0x1 << 7)
 #define MXC_CCM_CCOSR_CKOL_DIV_MASK            (0x7 << 4)
 #define MXC_CCM_CCOSR_CKOL_DIV_OFFSET          (4)