summaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk-qoric.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/clk-qoric.c')
-rw-r--r--drivers/clk/clk-qoric.c137
1 files changed, 102 insertions, 35 deletions
diff --git a/drivers/clk/clk-qoric.c b/drivers/clk/clk-qoric.c
index c40c6e90d9..44155692a8 100644
--- a/drivers/clk/clk-qoric.c
+++ b/drivers/clk/clk-qoric.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright 2013 Freescale Semiconductor, Inc.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
* clock driver for Freescale QorIQ SoCs.
*/
@@ -16,7 +13,7 @@
#include <linux/kernel.h>
#include <of_address.h>
#include <of.h>
-#include <asm-generic/div64.h>
+#include <linux/math64.h>
#define PLL_DIV1 0
#define PLL_DIV2 1
@@ -30,14 +27,15 @@
#define CGA_PLL4 4 /* only on clockgen-1.0, which lacks CGB */
#define CGB_PLL1 4
#define CGB_PLL2 5
+#define MAX_PLL_DIV 32
struct clockgen_pll_div {
- struct clk *clk;
+ struct clk_hw *hw;
char name[32];
};
struct clockgen_pll {
- struct clockgen_pll_div div[8];
+ struct clockgen_pll_div div[MAX_PLL_DIV];
};
#define CLKSEL_VALID 1
@@ -146,6 +144,58 @@ static const struct clockgen_muxinfo clockgen2_cmux_cgb = {
},
};
+static const struct clockgen_muxinfo ls1028a_hwa1 = {
+ {
+ { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
+ {},
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
+ },
+};
+
+static const struct clockgen_muxinfo ls1028a_hwa2 = {
+ {
+ { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
+ {},
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
+ },
+};
+
+static const struct clockgen_muxinfo ls1028a_hwa3 = {
+ {
+ { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
+ {},
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
+ },
+};
+
+static const struct clockgen_muxinfo ls1028a_hwa4 = {
+ {
+ { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
+ {},
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
+ },
+};
+
static const struct clockgen_muxinfo ls1043a_hwa1 = {
{
{},
@@ -206,6 +256,13 @@ static void __init t2080_init_periph(struct clockgen *cg)
cg->fman[0] = cg->hwaccel[0];
}
+static const struct clockgen_chipinfo chipinfo_ls1012a = {
+ .compat = "fsl,ls1012a-clockgen",
+ .cmux_groups = { &ls1012a_cmux },
+ .cmux_to_group = { 0, -1 },
+ .pll_mask = 0x03,
+};
+
static const struct clockgen_chipinfo chipinfo_ls1021a = {
.compat = "fsl,ls1021a-clockgen",
.cmux_groups = { &t1023_cmux },
@@ -213,6 +270,15 @@ static const struct clockgen_chipinfo chipinfo_ls1021a = {
.pll_mask = 0x03,
};
+static const struct clockgen_chipinfo chipinfo_ls1028a = {
+ .compat = "fsl,ls1028a-clockgen",
+ .cmux_groups = { &clockgen2_cmux_cga12 },
+ .hwaccel = { &ls1028a_hwa1, &ls1028a_hwa2, &ls1028a_hwa3, &ls1028a_hwa4 },
+ .cmux_to_group = { 0, 0, 0, 0, -1 },
+ .pll_mask = 0x07,
+ .flags = CG_VER3 | CG_LITTLE_ENDIAN,
+};
+
static const struct clockgen_chipinfo chipinfo_ls1043a = {
.compat = "fsl,ls1043a-clockgen",
.init_periph = t2080_init_periph,
@@ -241,13 +307,6 @@ static const struct clockgen_chipinfo chipinfo_ls1088a = {
.flags = CG_VER3 | CG_LITTLE_ENDIAN,
};
-static const struct clockgen_chipinfo chipinfo_ls1012a = {
- .compat = "fsl,ls1012a-clockgen",
- .cmux_groups = { &ls1012a_cmux },
- .cmux_to_group = { 0, -1 },
- .pll_mask = 0x03,
-};
-
static const struct clockgen_chipinfo chipinfo_ls2080a = {
.compat = "fsl,ls2080a-clockgen",
.cmux_groups = { &clockgen2_cmux_cga12, &clockgen2_cmux_cgb },
@@ -257,20 +316,20 @@ static const struct clockgen_chipinfo chipinfo_ls2080a = {
};
struct mux_hwclock {
- struct clk clk;
+ struct clk_hw hw;
struct clockgen *cg;
const struct clockgen_muxinfo *info;
u32 __iomem *reg;
int num_parents;
};
-#define to_mux_hwclock(p) container_of(p, struct mux_hwclock, clk)
+#define to_mux_hwclock(p) container_of(p, struct mux_hwclock, hw)
#define CLKSEL_MASK 0x78000000
#define CLKSEL_SHIFT 27
-static int mux_set_parent(struct clk *clk, u8 idx)
+static int mux_set_parent(struct clk_hw *hw, u8 idx)
{
- struct mux_hwclock *hwc = to_mux_hwclock(clk);
+ struct mux_hwclock *hwc = to_mux_hwclock(hw);
if (idx >= hwc->num_parents)
return -EINVAL;
@@ -280,9 +339,9 @@ static int mux_set_parent(struct clk *clk, u8 idx)
return 0;
}
-static int mux_get_parent(struct clk *clk)
+static int mux_get_parent(struct clk_hw *hw)
{
- struct mux_hwclock *hwc = to_mux_hwclock(clk);
+ struct mux_hwclock *hwc = to_mux_hwclock(hw);
return (cg_in(hwc->cg, hwc->reg) & CLKSEL_MASK) >> CLKSEL_SHIFT;
}
@@ -321,7 +380,7 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
const struct clk_ops *ops,
const char *fmt, int idx)
{
- struct clk *clk = &hwc->clk;
+ struct clk_hw *hw = &hwc->hw;
const struct clockgen_pll_div *div;
const char **parent_names;
int i, ret;
@@ -336,20 +395,20 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
parent_names[i] = div->name;
}
- clk->name = xasprintf(fmt, idx);;
- clk->ops = ops;
- clk->parent_names = parent_names;
- clk->num_parents = hwc->num_parents = i;
+ hw->clk.name = xasprintf(fmt, idx);;
+ hw->clk.ops = ops;
+ hw->clk.parent_names = parent_names;
+ hw->clk.num_parents = hwc->num_parents = i;
hwc->cg = cg;
- ret = clk_register(clk);
+ ret = bclk_register(&hw->clk);
if (ret) {
- pr_err("%s: Couldn't register %s: %d\n", __func__, clk->name, ret);
+ pr_err("%s: Couldn't register %s: %d\n", __func__, clk_hw_get_name(hw), ret);
kfree(hwc);
return NULL;
}
- return clk;
+ return &hw->clk;
}
static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
@@ -502,7 +561,7 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
continue;
}
- pll->div[i].clk = clk;
+ pll->div[i].hw = clk_to_clk_hw(clk);
}
}
@@ -554,7 +613,7 @@ static struct clk *clockgen_clk_get(struct of_phandle_args *clkspec, void *data)
pll = &cg->pll[PLATFORM_PLL];
if (idx >= ARRAY_SIZE(pll->div))
goto bad_args;
- clk = pll->div[idx].clk;
+ clk = clk_hw_to_clk(pll->div[idx].hw);
break;
case 5:
if (idx != 0)
@@ -584,7 +643,7 @@ static void __init clockgen_init(struct device_node *np,
clockgen.node = np;
clockgen.regs = of_iomap(np, 0);
if (!clockgen.regs) {
- pr_err("of_iomap failed for %s\n", np->full_name);
+ pr_err("of_iomap failed for %pOF\n", np);
return;
}
@@ -592,10 +651,10 @@ static void __init clockgen_init(struct device_node *np,
clockgen.sysclk = of_clk_get(clockgen.node, 0);
if (IS_ERR(clockgen.sysclk)) {
- pr_err("sysclk not found: %s\n", strerrorp(clockgen.sysclk));
+ pr_err("sysclk not found: %pe\n", clockgen.sysclk);
return;
}
-
+
clockgen.coreclk = of_clk_get(clockgen.node, 1);
if (IS_ERR(clockgen.coreclk))
clockgen.coreclk = NULL;
@@ -608,8 +667,8 @@ static void __init clockgen_init(struct device_node *np,
ret = of_clk_add_provider(np, clockgen_clk_get, &clockgen);
if (ret) {
- pr_err("Couldn't register clk provider for node %s: %d\n",
- np->full_name, ret);
+ pr_err("Couldn't register clk provider for node %pOF: %d\n",
+ np, ret);
}
return;
@@ -625,6 +684,11 @@ static void __maybe_unused clockgen_init_ls1021a(struct device_node *np)
clockgen_init(np, &chipinfo_ls1021a);
}
+static void __maybe_unused clockgen_init_ls1028a(struct device_node *np)
+{
+ clockgen_init(np, &chipinfo_ls1028a);
+}
+
static void __maybe_unused clockgen_init_ls1043a(struct device_node *np)
{
clockgen_init(np, &chipinfo_ls1043a);
@@ -651,6 +715,9 @@ CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init_ls1
#ifdef CONFIG_ARCH_LS1021
CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init_ls1021a);
#endif
+#ifdef CONFIG_ARCH_LS1028
+CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1028a-clockgen", clockgen_init_ls1028a);
+#endif
#ifdef CONFIG_ARCH_LS1043
CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init_ls1043a);
#endif