clk: qoriq: Add ls2080a support.
authorScott Wood <scottwood@freescale.com>
Sun, 20 Sep 2015 04:29:55 +0000 (23:29 -0500)
committerScott Wood <scottwood@freescale.com>
Wed, 21 Oct 2015 23:05:55 +0000 (18:05 -0500)
LS2080A is the first implementation of the chassis 3 clockgen, which
has a different register layout than previous chips.  It is also little
endian, unlike previous chips.

Signed-off-by: Scott Wood <scottwood@freescale.com>
Acked-by: Stephen Boyd <sboyd@codeaurora.org>
drivers/clk/Kconfig
drivers/clk/clk-qoriq.c

index 42f7120ca9ceaa1b900e737efeeb67f0913ae4e4..9f1970c19690894a9c3b1427ebc4b5586c0c88c0 100644 (file)
@@ -121,7 +121,7 @@ config COMMON_CLK_AXI_CLKGEN
 
 config CLK_QORIQ
        bool "Clock driver for Freescale QorIQ platforms"
-       depends on (PPC_E500MC || ARM) && OF
+       depends on (PPC_E500MC || ARM || ARM64) && OF
        ---help---
          This adds the clock driver support for Freescale QorIQ platforms
          using common clock framework.
index 06281a36252769f963c7d34a1b362a8fb039664d..8f9c93b9ce21e85a0bc3ab7dc9bf5147a36b1a26 100644 (file)
@@ -68,7 +68,10 @@ struct clockgen;
  * If not set, cmux freq must be >= platform pll/2
  */
 #define CG_CMUX_GE_PLAT                1
+
 #define CG_PLL_8BIT            2       /* PLLCnGSR[CFG] is 8 bits, not 6 */
+#define CG_VER3                        4       /* version 3 cg: reg layout different */
+#define CG_LITTLE_ENDIAN       8
 
 struct clockgen_chipinfo {
        const char *compat, *guts_compat;
@@ -94,6 +97,26 @@ struct clockgen {
 
 static struct clockgen clockgen;
 
+static void cg_out(struct clockgen *cg, u32 val, u32 __iomem *reg)
+{
+       if (cg->info.flags & CG_LITTLE_ENDIAN)
+               iowrite32(val, reg);
+       else
+               iowrite32be(val, reg);
+}
+
+static u32 cg_in(struct clockgen *cg, u32 __iomem *reg)
+{
+       u32 val;
+
+       if (cg->info.flags & CG_LITTLE_ENDIAN)
+               val = ioread32(reg);
+       else
+               val = ioread32be(reg);
+
+       return val;
+}
+
 static const struct clockgen_muxinfo p2041_cmux_grp1 = {
        {
                [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
@@ -428,6 +451,17 @@ static const struct clockgen_chipinfo chipinfo[] = {
                },
                .pll_mask = 0x03,
        },
+       {
+               .compat = "fsl,ls2080a-clockgen",
+               .cmux_groups = {
+                       &clockgen2_cmux_cga12, &clockgen2_cmux_cgb
+               },
+               .cmux_to_group = {
+                       0, 0, 1, 1, -1
+               },
+               .pll_mask = 0x37,
+               .flags = CG_VER3 | CG_LITTLE_ENDIAN,
+       },
        {
                .compat = "fsl,p2041-clockgen",
                .guts_compat = "fsl,qoriq-device-config-1.0",
@@ -575,7 +609,7 @@ static int mux_set_parent(struct clk_hw *hw, u8 idx)
                return -EINVAL;
 
        clksel = hwc->parent_to_clksel[idx];
-       iowrite32be((clksel << CLKSEL_SHIFT) & CLKSEL_MASK, hwc->reg);
+       cg_out(hwc->cg, (clksel << CLKSEL_SHIFT) & CLKSEL_MASK, hwc->reg);
 
        return 0;
 }
@@ -586,7 +620,7 @@ static u8 mux_get_parent(struct clk_hw *hw)
        u32 clksel;
        s8 ret;
 
-       clksel = (ioread32be(hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT;
+       clksel = (cg_in(hwc->cg, hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT;
 
        ret = hwc->clksel_to_parent[clksel];
        if (ret < 0) {
@@ -705,7 +739,7 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
         * default clksel) may be inappropriately excluded on certain
         * chips.
         */
-       clksel = (ioread32be(hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT;
+       clksel = (cg_in(cg, hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT;
        div = get_pll_div(cg, hwc, clksel);
        if (!div)
                return NULL;
@@ -874,13 +908,36 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
        if (!(cg->info.pll_mask & (1 << idx)))
                return;
 
-       if (idx == PLATFORM_PLL)
-               reg = cg->regs + 0xc00;
-       else
-               reg = cg->regs + 0x800 + 0x20 * (idx - 1);
+       if (cg->info.flags & CG_VER3) {
+               switch (idx) {
+               case PLATFORM_PLL:
+                       reg = cg->regs + 0x60080;
+                       break;
+               case CGA_PLL1:
+                       reg = cg->regs + 0x80;
+                       break;
+               case CGA_PLL2:
+                       reg = cg->regs + 0xa0;
+                       break;
+               case CGB_PLL1:
+                       reg = cg->regs + 0x10080;
+                       break;
+               case CGB_PLL2:
+                       reg = cg->regs + 0x100a0;
+                       break;
+               default:
+                       WARN_ONCE(1, "index %d\n", idx);
+                       return;
+               }
+       } else {
+               if (idx == PLATFORM_PLL)
+                       reg = cg->regs + 0xc00;
+               else
+                       reg = cg->regs + 0x800 + 0x20 * (idx - 1);
+       }
 
        /* Get the multiple of PLL */
-       mult = ioread32be(reg);
+       mult = cg_in(cg, reg);
 
        /* Check if this PLL is disabled */
        if (mult & PLL_KILL) {
@@ -888,7 +945,8 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
                return;
        }
 
-       if ((cg->info.flags & CG_PLL_8BIT) && idx != PLATFORM_PLL)
+       if ((cg->info.flags & CG_VER3) ||
+           ((cg->info.flags & CG_PLL_8BIT) && idx != PLATFORM_PLL))
                mult = (mult & GENMASK(8, 1)) >> 1;
        else
                mult = (mult & GENMASK(6, 1)) >> 1;
@@ -1169,6 +1227,7 @@ err:
 CLK_OF_DECLARE(qoriq_clockgen_1, "fsl,qoriq-clockgen-1.0", clockgen_init);
 CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init);
 CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init);
+CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init);
 
 /* Legacy nodes */
 CLK_OF_DECLARE(qoriq_sysclk_1, "fsl,qoriq-sysclk-1.0", sysclk_init);