Lines Matching +full:parent +full:- +full:clk
1 // SPDX-License-Identifier: GPL-2.0+
14 #include <clk-uclass.h>
20 #include <dt-bindings/clock/renesas-cpg-mssr.h>
22 #include "renesas-cpg-mssr.h"
23 #include "rcar-gen3-cpg.h"
62 *-------------------------------------------------------------------
88 static int gen3_clk_get_parent(struct gen3_clk_priv *priv, struct clk *clk, in gen3_clk_get_parent() argument
89 struct cpg_mssr_info *info, struct clk *parent) in gen3_clk_get_parent() argument
94 if (!renesas_clk_is_mod(clk)) { in gen3_clk_get_parent()
95 ret = renesas_clk_get_core(clk, info, &core); in gen3_clk_get_parent()
99 if (core->type == CLK_TYPE_GEN3_PE) { in gen3_clk_get_parent()
100 parent->dev = clk->dev; in gen3_clk_get_parent()
101 parent->id = core->parent >> (priv->sscg ? 16 : 0); in gen3_clk_get_parent()
102 parent->id &= 0xffff; in gen3_clk_get_parent()
107 return renesas_clk_get_parent(clk, info, parent); in gen3_clk_get_parent()
110 static int gen3_clk_setup_sdif_div(struct clk *clk, ulong rate) in gen3_clk_setup_sdif_div() argument
112 struct gen3_clk_priv *priv = dev_get_priv(clk->dev); in gen3_clk_setup_sdif_div()
113 struct cpg_mssr_info *info = priv->info; in gen3_clk_setup_sdif_div()
115 struct clk parent; in gen3_clk_setup_sdif_div() local
118 ret = gen3_clk_get_parent(priv, clk, info, &parent); in gen3_clk_setup_sdif_div()
120 printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret); in gen3_clk_setup_sdif_div()
124 if (renesas_clk_is_mod(&parent)) in gen3_clk_setup_sdif_div()
127 ret = renesas_clk_get_core(&parent, info, &core); in gen3_clk_setup_sdif_div()
131 if (core->type != CLK_TYPE_GEN3_SD) in gen3_clk_setup_sdif_div()
134 debug("%s[%i] SDIF offset=%x\n", __func__, __LINE__, core->offset); in gen3_clk_setup_sdif_div()
136 writel((rate == 400000000) ? 0x4 : 0x1, priv->base + core->offset); in gen3_clk_setup_sdif_div()
141 static int gen3_clk_enable(struct clk *clk) in gen3_clk_enable() argument
143 struct gen3_clk_priv *priv = dev_get_priv(clk->dev); in gen3_clk_enable()
145 return renesas_clk_endisable(clk, priv->base, true); in gen3_clk_enable()
148 static int gen3_clk_disable(struct clk *clk) in gen3_clk_disable() argument
150 struct gen3_clk_priv *priv = dev_get_priv(clk->dev); in gen3_clk_disable()
152 return renesas_clk_endisable(clk, priv->base, false); in gen3_clk_disable()
155 static u64 gen3_clk_get_rate64(struct clk *clk) in gen3_clk_get_rate64() argument
157 struct gen3_clk_priv *priv = dev_get_priv(clk->dev); in gen3_clk_get_rate64()
158 struct cpg_mssr_info *info = priv->info; in gen3_clk_get_rate64()
159 struct clk parent; in gen3_clk_get_rate64() local
162 priv->cpg_pll_config; in gen3_clk_get_rate64()
167 debug("%s[%i] Clock: id=%lu\n", __func__, __LINE__, clk->id); in gen3_clk_get_rate64()
169 ret = gen3_clk_get_parent(priv, clk, info, &parent); in gen3_clk_get_rate64()
171 printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret); in gen3_clk_get_rate64()
175 if (renesas_clk_is_mod(clk)) { in gen3_clk_get_rate64()
176 rate = gen3_clk_get_rate64(&parent); in gen3_clk_get_rate64()
177 debug("%s[%i] MOD clk: parent=%lu => rate=%llu\n", in gen3_clk_get_rate64()
178 __func__, __LINE__, parent.id, rate); in gen3_clk_get_rate64()
182 ret = renesas_clk_get_core(clk, info, &core); in gen3_clk_get_rate64()
186 switch (core->type) { in gen3_clk_get_rate64()
188 if (core->id == info->clk_extal_id) { in gen3_clk_get_rate64()
189 rate = clk_get_rate(&priv->clk_extal); in gen3_clk_get_rate64()
190 debug("%s[%i] EXTAL clk: rate=%llu\n", in gen3_clk_get_rate64()
195 if (core->id == info->clk_extalr_id) { in gen3_clk_get_rate64()
196 rate = clk_get_rate(&priv->clk_extalr); in gen3_clk_get_rate64()
197 debug("%s[%i] EXTALR clk: rate=%llu\n", in gen3_clk_get_rate64()
202 return -EINVAL; in gen3_clk_get_rate64()
205 rate = gen3_clk_get_rate64(&parent) / pll_config->extal_div; in gen3_clk_get_rate64()
206 debug("%s[%i] MAIN clk: parent=%i extal_div=%i => rate=%llu\n", in gen3_clk_get_rate64()
208 core->parent, pll_config->extal_div, rate); in gen3_clk_get_rate64()
212 value = readl(priv->base + CPG_PLL0CR); in gen3_clk_get_rate64()
214 rate = gen3_clk_get_rate64(&parent) * mult; in gen3_clk_get_rate64()
215 debug("%s[%i] PLL0 clk: parent=%i mult=%u => rate=%llu\n", in gen3_clk_get_rate64()
216 __func__, __LINE__, core->parent, mult, rate); in gen3_clk_get_rate64()
220 rate = gen3_clk_get_rate64(&parent) * pll_config->pll1_mult; in gen3_clk_get_rate64()
221 rate /= pll_config->pll1_div; in gen3_clk_get_rate64()
222 debug("%s[%i] PLL1 clk: parent=%i mul=%i div=%i => rate=%llu\n", in gen3_clk_get_rate64()
224 core->parent, pll_config->pll1_mult, in gen3_clk_get_rate64()
225 pll_config->pll1_div, rate); in gen3_clk_get_rate64()
229 value = readl(priv->base + CPG_PLL2CR); in gen3_clk_get_rate64()
231 rate = gen3_clk_get_rate64(&parent) * mult; in gen3_clk_get_rate64()
232 debug("%s[%i] PLL2 clk: parent=%i mult=%u => rate=%llu\n", in gen3_clk_get_rate64()
233 __func__, __LINE__, core->parent, mult, rate); in gen3_clk_get_rate64()
237 rate = gen3_clk_get_rate64(&parent) * pll_config->pll3_mult; in gen3_clk_get_rate64()
238 rate /= pll_config->pll3_div; in gen3_clk_get_rate64()
239 debug("%s[%i] PLL3 clk: parent=%i mul=%i div=%i => rate=%llu\n", in gen3_clk_get_rate64()
241 core->parent, pll_config->pll3_mult, in gen3_clk_get_rate64()
242 pll_config->pll3_div, rate); in gen3_clk_get_rate64()
246 value = readl(priv->base + CPG_PLL4CR); in gen3_clk_get_rate64()
248 rate = gen3_clk_get_rate64(&parent) * mult; in gen3_clk_get_rate64()
249 debug("%s[%i] PLL4 clk: parent=%i mult=%u => rate=%llu\n", in gen3_clk_get_rate64()
250 __func__, __LINE__, core->parent, mult, rate); in gen3_clk_get_rate64()
254 rate = (gen3_clk_get_rate64(&parent) * core->mult) / core->div; in gen3_clk_get_rate64()
255 debug("%s[%i] FIXED clk: parent=%i mul=%i div=%i => rate=%llu\n", in gen3_clk_get_rate64()
257 core->parent, core->mult, core->div, rate); in gen3_clk_get_rate64()
261 div = (core->div >> (priv->sscg ? 16 : 0)) & 0xffff; in gen3_clk_get_rate64()
262 rate = gen3_clk_get_rate64(&parent) / div; in gen3_clk_get_rate64()
263 debug("%s[%i] PE clk: parent=%i div=%u => rate=%llu\n", in gen3_clk_get_rate64()
265 (core->parent >> (priv->sscg ? 16 : 0)) & 0xffff, in gen3_clk_get_rate64()
270 value = readl(priv->base + core->offset); in gen3_clk_get_rate64()
277 rate = gen3_clk_get_rate64(&parent) / in gen3_clk_get_rate64()
279 debug("%s[%i] SD clk: parent=%i div=%i => rate=%llu\n", in gen3_clk_get_rate64()
281 core->parent, cpg_sd_div_table[i].div, rate); in gen3_clk_get_rate64()
286 return -EINVAL; in gen3_clk_get_rate64()
289 rate = gen3_clk_get_rate64(&parent); in gen3_clk_get_rate64()
291 value = readl(priv->base + core->offset); in gen3_clk_get_rate64()
300 return -EINVAL; in gen3_clk_get_rate64()
306 debug("%s[%i] RPC clk: parent=%i prediv=%i postdiv=%i => rate=%llu\n", in gen3_clk_get_rate64()
308 core->parent, prediv, postdiv, rate); in gen3_clk_get_rate64()
310 return -EINVAL; in gen3_clk_get_rate64()
316 return -ENOENT; in gen3_clk_get_rate64()
319 static ulong gen3_clk_get_rate(struct clk *clk) in gen3_clk_get_rate() argument
321 return gen3_clk_get_rate64(clk); in gen3_clk_get_rate()
324 static ulong gen3_clk_set_rate(struct clk *clk, ulong rate) in gen3_clk_set_rate() argument
326 /* Force correct SD-IF divider configuration if applicable */ in gen3_clk_set_rate()
327 gen3_clk_setup_sdif_div(clk, rate); in gen3_clk_set_rate()
328 return gen3_clk_get_rate64(clk); in gen3_clk_set_rate()
331 static int gen3_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args) in gen3_clk_of_xlate() argument
333 if (args->args_count != 2) { in gen3_clk_of_xlate()
334 debug("Invaild args_count: %d\n", args->args_count); in gen3_clk_of_xlate()
335 return -EINVAL; in gen3_clk_of_xlate()
338 clk->id = (args->args[0] << 16) | args->args[1]; in gen3_clk_of_xlate()
360 priv->base = (struct gen3_base *)devfdt_get_addr(dev); in gen3_clk_probe()
361 if (!priv->base) in gen3_clk_probe()
362 return -EINVAL; in gen3_clk_probe()
364 priv->info = info; in gen3_clk_probe()
365 ret = fdt_node_offset_by_compatible(gd->fdt_blob, -1, info->reset_node); in gen3_clk_probe()
369 rst_base = fdtdec_get_addr(gd->fdt_blob, ret, "reg"); in gen3_clk_probe()
371 return -EINVAL; in gen3_clk_probe()
375 priv->cpg_pll_config = in gen3_clk_probe()
376 (struct rcar_gen3_cpg_pll_config *)info->get_pll_config(cpg_mode); in gen3_clk_probe()
377 if (!priv->cpg_pll_config->extal_div) in gen3_clk_probe()
378 return -EINVAL; in gen3_clk_probe()
380 priv->sscg = !(cpg_mode & BIT(12)); in gen3_clk_probe()
382 ret = clk_get_by_name(dev, "extal", &priv->clk_extal); in gen3_clk_probe()
386 if (info->extalr_node) { in gen3_clk_probe()
387 ret = clk_get_by_name(dev, info->extalr_node, &priv->clk_extalr); in gen3_clk_probe()
399 return renesas_clk_remove(priv->base, priv->info); in gen3_clk_remove()