diff options
Diffstat (limited to 'drivers/clk/renesas')
-rw-r--r-- | drivers/clk/renesas/r9a07g043-cpg.c | 7 | ||||
-rw-r--r-- | drivers/clk/renesas/r9a08g045-cpg.c | 5 | ||||
-rw-r--r-- | drivers/clk/renesas/renesas-cpg-mssr.c | 2 | ||||
-rw-r--r-- | drivers/clk/renesas/rzg2l-cpg.c | 123 | ||||
-rw-r--r-- | drivers/clk/renesas/rzg2l-cpg.h | 10 | ||||
-rw-r--r-- | drivers/clk/renesas/rzv2h-cpg.c | 1 |
6 files changed, 89 insertions, 59 deletions
diff --git a/drivers/clk/renesas/r9a07g043-cpg.c b/drivers/clk/renesas/r9a07g043-cpg.c index c3c2b0c43983..fce2eecfa8c0 100644 --- a/drivers/clk/renesas/r9a07g043-cpg.c +++ b/drivers/clk/renesas/r9a07g043-cpg.c @@ -89,7 +89,9 @@ static const struct clk_div_table dtable_1_32[] = { /* Mux clock tables */ static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" }; +#ifdef CONFIG_ARM64 static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" }; +#endif static const char * const sel_sdhi[] = { ".clk_533", ".clk_400", ".clk_266" }; static const u32 mtable_sdhi[] = { 1, 2, 3 }; @@ -137,7 +139,12 @@ static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = { DEF_DIV("P2", R9A07G043_CLK_P2, CLK_PLL3_DIV2_4_2, DIVPL3A, dtable_1_32), DEF_FIXED("M0", R9A07G043_CLK_M0, CLK_PLL3_DIV2_4, 1, 1), DEF_FIXED("ZT", R9A07G043_CLK_ZT, CLK_PLL3_DIV2_4_2, 1, 1), +#ifdef CONFIG_ARM64 DEF_MUX("HP", R9A07G043_CLK_HP, SEL_PLL6_2, sel_pll6_2), +#endif +#ifdef CONFIG_RISCV + DEF_FIXED("HP", R9A07G043_CLK_HP, CLK_PLL6_250, 1, 1), +#endif DEF_FIXED("SPI0", R9A07G043_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2), DEF_FIXED("SPI1", R9A07G043_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4), DEF_SD_MUX("SD0", R9A07G043_CLK_SD0, SEL_SDHI0, SEL_SDHI0_STS, sel_sdhi, diff --git a/drivers/clk/renesas/r9a08g045-cpg.c b/drivers/clk/renesas/r9a08g045-cpg.c index 1ce40fb51f13..a1f961d5b856 100644 --- a/drivers/clk/renesas/r9a08g045-cpg.c +++ b/drivers/clk/renesas/r9a08g045-cpg.c @@ -50,7 +50,7 @@ #define G3S_SEL_SDHI2 SEL_PLL_PACK(G3S_CPG_SDHI_DSEL, 8, 2) /* PLL 1/4/6 configuration registers macro. */ -#define G3S_PLL146_CONF(clk1, clk2) ((clk1) << 22 | (clk2) << 12) +#define G3S_PLL146_CONF(clk1, clk2, setting) ((clk1) << 22 | (clk2) << 12 | (setting)) #define DEF_G3S_MUX(_name, _id, _conf, _parent_names, _mux_flags, _clk_flags) \ DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = (_conf), \ @@ -133,7 +133,8 @@ static const struct cpg_core_clk r9a08g045_core_clks[] __initconst = { /* Internal Core Clocks */ DEF_FIXED(".osc_div1000", CLK_OSC_DIV1000, CLK_EXTAL, 1, 1000), - DEF_G3S_PLL(".pll1", CLK_PLL1, CLK_EXTAL, G3S_PLL146_CONF(0x4, 0x8)), + DEF_G3S_PLL(".pll1", CLK_PLL1, CLK_EXTAL, G3S_PLL146_CONF(0x4, 0x8, 0x100), + 1100000000UL), DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 200, 3), DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 200, 3), DEF_FIXED(".pll4", CLK_PLL4, CLK_EXTAL, 100, 3), diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 1b421b809796..0f27c33192e1 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -981,7 +981,7 @@ static void __init cpg_mssr_reserved_exit(struct cpg_mssr_priv *priv) static int __init cpg_mssr_reserved_init(struct cpg_mssr_priv *priv, const struct cpg_mssr_info *info) { - struct device_node *soc = of_find_node_by_path("/soc"); + struct device_node *soc __free(device_node) = of_find_node_by_path("/soc"); struct device_node *node; uint32_t args[MAX_PHANDLE_ARGS]; unsigned int *ids = NULL; diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index b43b763dfe18..e2ecc9d36e05 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -51,6 +51,7 @@ #define RZG3S_DIV_M GENMASK(25, 22) #define RZG3S_DIV_NI GENMASK(21, 13) #define RZG3S_DIV_NF GENMASK(12, 1) +#define RZG3S_SEL_PLL BIT(0) #define CLK_ON_R(reg) (reg) #define CLK_MON_R(reg) (0x180 + (reg)) @@ -60,6 +61,7 @@ #define GET_REG_OFFSET(val) ((val >> 20) & 0xfff) #define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff) #define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff) +#define GET_REG_SAMPLL_SETTING(val) ((val) & 0xfff) #define CPG_WEN_BIT BIT(16) @@ -943,6 +945,7 @@ rzg2l_cpg_sipll5_register(const struct cpg_core_clk *core, struct pll_clk { struct clk_hw hw; + unsigned long default_rate; unsigned int conf; unsigned int type; void __iomem *base; @@ -980,12 +983,19 @@ static unsigned long rzg3s_cpg_pll_clk_recalc_rate(struct clk_hw *hw, { struct pll_clk *pll_clk = to_pll(hw); struct rzg2l_cpg_priv *priv = pll_clk->priv; - u32 nir, nfr, mr, pr, val; + u32 nir, nfr, mr, pr, val, setting; u64 rate; if (pll_clk->type != CLK_TYPE_G3S_PLL) return parent_rate; + setting = GET_REG_SAMPLL_SETTING(pll_clk->conf); + if (setting) { + val = readl(priv->base + setting); + if (val & RZG3S_SEL_PLL) + return pll_clk->default_rate; + } + val = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); pr = 1 << FIELD_GET(RZG3S_DIV_P, val); @@ -1038,6 +1048,7 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, pll_clk->base = priv->base; pll_clk->priv = priv; pll_clk->type = core->type; + pll_clk->default_rate = core->default_rate; ret = devm_clk_hw_register(dev, &pll_clk->hw); if (ret) @@ -1387,10 +1398,6 @@ rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, goto fail; } - clk = clock->hw.clk; - dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); - priv->clks[id] = clk; - if (mod->is_coupled) { struct mstp_clock *sibling; @@ -1402,6 +1409,10 @@ rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, } } + clk = clock->hw.clk; + dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); + priv->clks[id] = clk; + return; fail: @@ -1538,28 +1549,6 @@ static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv) return devm_reset_controller_register(priv->dev, &priv->rcdev); } -static bool rzg2l_cpg_is_pm_clk(struct rzg2l_cpg_priv *priv, - const struct of_phandle_args *clkspec) -{ - const struct rzg2l_cpg_info *info = priv->info; - unsigned int id; - unsigned int i; - - if (clkspec->args_count != 2) - return false; - - if (clkspec->args[0] != CPG_MOD) - return false; - - id = clkspec->args[1] + info->num_total_core_clks; - for (i = 0; i < info->num_no_pm_mod_clks; i++) { - if (info->no_pm_mod_clks[i] == id) - return false; - } - - return true; -} - /** * struct rzg2l_cpg_pm_domains - RZ/G2L PM domains data structure * @onecell_data: cell data @@ -1584,45 +1573,73 @@ struct rzg2l_cpg_pd { u16 id; }; +static bool rzg2l_cpg_is_pm_clk(struct rzg2l_cpg_pd *pd, + const struct of_phandle_args *clkspec) +{ + if (clkspec->np != pd->genpd.dev.of_node || clkspec->args_count != 2) + return false; + + switch (clkspec->args[0]) { + case CPG_MOD: { + struct rzg2l_cpg_priv *priv = pd->priv; + const struct rzg2l_cpg_info *info = priv->info; + unsigned int id = clkspec->args[1]; + + if (id >= priv->num_mod_clks) + return false; + + id += info->num_total_core_clks; + + for (unsigned int i = 0; i < info->num_no_pm_mod_clks; i++) { + if (info->no_pm_mod_clks[i] == id) + return false; + } + + return true; + } + + case CPG_CORE: + default: + return false; + } +} + static int rzg2l_cpg_attach_dev(struct generic_pm_domain *domain, struct device *dev) { struct rzg2l_cpg_pd *pd = container_of(domain, struct rzg2l_cpg_pd, genpd); - struct rzg2l_cpg_priv *priv = pd->priv; struct device_node *np = dev->of_node; struct of_phandle_args clkspec; bool once = true; struct clk *clk; + unsigned int i; int error; - int i = 0; - - while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, - &clkspec)) { - if (rzg2l_cpg_is_pm_clk(priv, &clkspec)) { - if (once) { - once = false; - error = pm_clk_create(dev); - if (error) { - of_node_put(clkspec.np); - goto err; - } - } - clk = of_clk_get_from_provider(&clkspec); + + for (i = 0; !of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, &clkspec); i++) { + if (!rzg2l_cpg_is_pm_clk(pd, &clkspec)) { of_node_put(clkspec.np); - if (IS_ERR(clk)) { - error = PTR_ERR(clk); - goto fail_destroy; - } + continue; + } - error = pm_clk_add_clk(dev, clk); + if (once) { + once = false; + error = pm_clk_create(dev); if (error) { - dev_err(dev, "pm_clk_add_clk failed %d\n", - error); - goto fail_put; + of_node_put(clkspec.np); + goto err; } - } else { - of_node_put(clkspec.np); } - i++; + clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); + if (IS_ERR(clk)) { + error = PTR_ERR(clk); + goto fail_destroy; + } + + error = pm_clk_add_clk(dev, clk); + if (error) { + dev_err(dev, "pm_clk_add_clk failed %d\n", error); + goto fail_put; + } } return 0; diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h index ecfe7e7ea8a1..019efe00ffd9 100644 --- a/drivers/clk/renesas/rzg2l-cpg.h +++ b/drivers/clk/renesas/rzg2l-cpg.h @@ -102,7 +102,10 @@ struct cpg_core_clk { const struct clk_div_table *dtable; const u32 *mtable; const unsigned long invalid_rate; - const unsigned long max_rate; + union { + const unsigned long max_rate; + const unsigned long default_rate; + }; const char * const *parent_names; notifier_fn_t notifier; u32 flag; @@ -144,8 +147,9 @@ enum clk_types { DEF_TYPE(_name, _id, _type, .parent = _parent) #define DEF_SAMPLL(_name, _id, _parent, _conf) \ DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf) -#define DEF_G3S_PLL(_name, _id, _parent, _conf) \ - DEF_TYPE(_name, _id, CLK_TYPE_G3S_PLL, .parent = _parent, .conf = _conf) +#define DEF_G3S_PLL(_name, _id, _parent, _conf, _default_rate) \ + DEF_TYPE(_name, _id, CLK_TYPE_G3S_PLL, .parent = _parent, .conf = _conf, \ + .default_rate = _default_rate) #define DEF_INPUT(_name, _id) \ DEF_TYPE(_name, _id, CLK_TYPE_IN) #define DEF_FIXED(_name, _id, _parent, _mult, _div) \ diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index b524a9d33610..5f8116e39e22 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -312,6 +312,7 @@ rzv2h_cpg_ddiv_clk_register(const struct cpg_core_clk *core, init.ops = &rzv2h_ddiv_clk_divider_ops; init.parent_names = &parent_name; init.num_parents = 1; + init.flags = CLK_SET_RATE_PARENT; ddiv->priv = priv; ddiv->mon = cfg_ddiv.monbit; |