diff options
Diffstat (limited to 'drivers/clk/clk-qoric.c')
-rw-r--r-- | drivers/clk/clk-qoric.c | 137 |
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 |