Lines Matching +full:core +full:- +full:clk

1 // SPDX-License-Identifier: GPL-2.0
7 * Based on renesas-cpg-mssr.c
15 #include <linux/clk.h>
16 #include <linux/clk-provider.h>
17 #include <linux/clk/renesas.h>
28 #include <linux/reset-controller.h>
32 #include <dt-bindings/clock/renesas-cpg-mssr.h>
34 #include "rzg2l-cpg.h"
69 * struct clk_hw_data - clock hardware data
85 * struct sd_mux_hw_data - SD MUX clock hardware data
97 * struct div_hw_data - divider clock hardware data
130 * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data
136 * @clks: Array containing all Core and Module Clocks
137 * @num_core_clks: Number of Core Clocks in clks[]
139 * @num_resets: Number of Module Resets in info->resets[]
140 * @last_dt_core_clk: ID of the last Core Clock exported to DT
150 struct clk **clks;
169 u32 bitmask = GENMASK(GET_WIDTH(conf) - 1, 0) << GET_SHIFT(conf); in rzg2l_cpg_wait_clk_update_done()
180 struct clk_hw *hw = __clk_get_hw(cnd->clk); in rzg2l_cpg_sd_clk_mux_notifier()
182 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg2l_cpg_sd_clk_mux_notifier()
183 u32 off = GET_REG_OFFSET(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_notifier()
184 u32 shift = GET_SHIFT(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_notifier()
189 if (event != PRE_RATE_CHANGE || (cnd->new_rate / MEGA == 266)) in rzg2l_cpg_sd_clk_mux_notifier()
192 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg2l_cpg_sd_clk_mux_notifier()
206 writel((CPG_WEN_BIT | clk_src_266) << shift, priv->base + off); in rzg2l_cpg_sd_clk_mux_notifier()
209 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); in rzg2l_cpg_sd_clk_mux_notifier()
211 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg2l_cpg_sd_clk_mux_notifier()
214 dev_err(priv->dev, "failed to switch to safe clk source\n"); in rzg2l_cpg_sd_clk_mux_notifier()
223 struct clk_hw *hw = __clk_get_hw(cnd->clk); in rzg3s_cpg_div_clk_notifier()
226 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg3s_cpg_div_clk_notifier()
227 u32 off = GET_REG_OFFSET(clk_hw_data->conf); in rzg3s_cpg_div_clk_notifier()
228 u32 shift = GET_SHIFT(clk_hw_data->conf); in rzg3s_cpg_div_clk_notifier()
233 if (event != PRE_RATE_CHANGE || !div_hw_data->invalid_rate || in rzg3s_cpg_div_clk_notifier()
234 div_hw_data->invalid_rate % cnd->new_rate) in rzg3s_cpg_div_clk_notifier()
237 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg3s_cpg_div_clk_notifier()
239 val = readl(priv->base + off); in rzg3s_cpg_div_clk_notifier()
241 val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0); in rzg3s_cpg_div_clk_notifier()
253 writel((CPG_WEN_BIT | 1) << shift, priv->base + off); in rzg3s_cpg_div_clk_notifier()
255 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); in rzg3s_cpg_div_clk_notifier()
258 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg3s_cpg_div_clk_notifier()
261 dev_err(priv->dev, "Failed to downgrade the div\n"); in rzg3s_cpg_div_clk_notifier()
266 static int rzg2l_register_notifier(struct clk_hw *hw, const struct cpg_core_clk *core, in rzg2l_register_notifier() argument
271 if (!core->notifier) in rzg2l_register_notifier()
274 nb = devm_kzalloc(priv->dev, sizeof(*nb), GFP_KERNEL); in rzg2l_register_notifier()
276 return -ENOMEM; in rzg2l_register_notifier()
278 nb->notifier_call = core->notifier; in rzg2l_register_notifier()
280 return clk_notifier_register(hw->clk, nb); in rzg2l_register_notifier()
288 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg3s_div_clk_recalc_rate()
291 val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf)); in rzg3s_div_clk_recalc_rate()
292 val >>= GET_SHIFT(clk_hw_data->conf); in rzg3s_div_clk_recalc_rate()
293 val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0); in rzg3s_div_clk_recalc_rate()
295 return divider_recalc_rate(hw, parent_rate, val, div_hw_data->dtable, in rzg3s_div_clk_recalc_rate()
296 CLK_DIVIDER_ROUND_CLOSEST, div_hw_data->width); in rzg3s_div_clk_recalc_rate()
304 if (div_hw_data->max_rate && req->rate > div_hw_data->max_rate) in rzg3s_div_clk_determine_rate()
305 req->rate = div_hw_data->max_rate; in rzg3s_div_clk_determine_rate()
307 return divider_determine_rate(hw, req, div_hw_data->dtable, div_hw_data->width, in rzg3s_div_clk_determine_rate()
316 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg3s_div_clk_set_rate()
317 u32 off = GET_REG_OFFSET(clk_hw_data->conf); in rzg3s_div_clk_set_rate()
318 u32 shift = GET_SHIFT(clk_hw_data->conf); in rzg3s_div_clk_set_rate()
323 val = divider_get_val(rate, parent_rate, div_hw_data->dtable, div_hw_data->width, in rzg3s_div_clk_set_rate()
326 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg3s_div_clk_set_rate()
327 writel((CPG_WEN_BIT | val) << shift, priv->base + off); in rzg3s_div_clk_set_rate()
329 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); in rzg3s_div_clk_set_rate()
330 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg3s_div_clk_set_rate()
341 static struct clk * __init
342 rzg3s_cpg_div_clk_register(const struct cpg_core_clk *core, struct rzg2l_cpg_priv *priv) in rzg3s_cpg_div_clk_register() argument
348 const struct clk *parent; in rzg3s_cpg_div_clk_register()
353 parent = priv->clks[core->parent]; in rzg3s_cpg_div_clk_register()
359 div_hw_data = devm_kzalloc(priv->dev, sizeof(*div_hw_data), GFP_KERNEL); in rzg3s_cpg_div_clk_register()
361 return ERR_PTR(-ENOMEM); in rzg3s_cpg_div_clk_register()
363 init.name = core->name; in rzg3s_cpg_div_clk_register()
364 init.flags = core->flag; in rzg3s_cpg_div_clk_register()
370 for (clkt = core->dtable; clkt->div; clkt++) { in rzg3s_cpg_div_clk_register()
371 if (max < clkt->div) in rzg3s_cpg_div_clk_register()
372 max = clkt->div; in rzg3s_cpg_div_clk_register()
375 div_hw_data->hw_data.priv = priv; in rzg3s_cpg_div_clk_register()
376 div_hw_data->hw_data.conf = core->conf; in rzg3s_cpg_div_clk_register()
377 div_hw_data->hw_data.sconf = core->sconf; in rzg3s_cpg_div_clk_register()
378 div_hw_data->dtable = core->dtable; in rzg3s_cpg_div_clk_register()
379 div_hw_data->invalid_rate = core->invalid_rate; in rzg3s_cpg_div_clk_register()
380 div_hw_data->max_rate = core->max_rate; in rzg3s_cpg_div_clk_register()
381 div_hw_data->width = fls(max) - 1; in rzg3s_cpg_div_clk_register()
383 clk_hw = &div_hw_data->hw_data.hw; in rzg3s_cpg_div_clk_register()
384 clk_hw->init = &init; in rzg3s_cpg_div_clk_register()
386 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg3s_cpg_div_clk_register()
390 ret = rzg2l_register_notifier(clk_hw, core, priv); in rzg3s_cpg_div_clk_register()
392 dev_err(priv->dev, "Failed to register notifier for %s\n", in rzg3s_cpg_div_clk_register()
393 core->name); in rzg3s_cpg_div_clk_register()
397 return clk_hw->clk; in rzg3s_cpg_div_clk_register()
400 static struct clk * __init
401 rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core, in rzg2l_cpg_div_clk_register() argument
404 void __iomem *base = priv->base; in rzg2l_cpg_div_clk_register()
405 struct device *dev = priv->dev; in rzg2l_cpg_div_clk_register()
406 const struct clk *parent; in rzg2l_cpg_div_clk_register()
410 parent = priv->clks[core->parent]; in rzg2l_cpg_div_clk_register()
416 if (core->dtable) in rzg2l_cpg_div_clk_register()
417 clk_hw = clk_hw_register_divider_table(dev, core->name, in rzg2l_cpg_div_clk_register()
419 base + GET_REG_OFFSET(core->conf), in rzg2l_cpg_div_clk_register()
420 GET_SHIFT(core->conf), in rzg2l_cpg_div_clk_register()
421 GET_WIDTH(core->conf), in rzg2l_cpg_div_clk_register()
422 core->flag, in rzg2l_cpg_div_clk_register()
423 core->dtable, in rzg2l_cpg_div_clk_register()
424 &priv->rmw_lock); in rzg2l_cpg_div_clk_register()
426 clk_hw = clk_hw_register_divider(dev, core->name, in rzg2l_cpg_div_clk_register()
428 base + GET_REG_OFFSET(core->conf), in rzg2l_cpg_div_clk_register()
429 GET_SHIFT(core->conf), in rzg2l_cpg_div_clk_register()
430 GET_WIDTH(core->conf), in rzg2l_cpg_div_clk_register()
431 core->flag, &priv->rmw_lock); in rzg2l_cpg_div_clk_register()
436 return clk_hw->clk; in rzg2l_cpg_div_clk_register()
439 static struct clk * __init
440 rzg2l_cpg_mux_clk_register(const struct cpg_core_clk *core, in rzg2l_cpg_mux_clk_register() argument
445 clk_hw = devm_clk_hw_register_mux(priv->dev, core->name, in rzg2l_cpg_mux_clk_register()
446 core->parent_names, core->num_parents, in rzg2l_cpg_mux_clk_register()
447 core->flag, in rzg2l_cpg_mux_clk_register()
448 priv->base + GET_REG_OFFSET(core->conf), in rzg2l_cpg_mux_clk_register()
449 GET_SHIFT(core->conf), in rzg2l_cpg_mux_clk_register()
450 GET_WIDTH(core->conf), in rzg2l_cpg_mux_clk_register()
451 core->mux_flags, &priv->rmw_lock); in rzg2l_cpg_mux_clk_register()
455 return clk_hw->clk; in rzg2l_cpg_mux_clk_register()
462 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg2l_cpg_sd_clk_mux_set_parent()
463 u32 off = GET_REG_OFFSET(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_set_parent()
464 u32 shift = GET_SHIFT(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_set_parent()
469 val = clk_mux_index_to_val(sd_mux_hw_data->mtable, CLK_MUX_ROUND_CLOSEST, index); in rzg2l_cpg_sd_clk_mux_set_parent()
471 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg2l_cpg_sd_clk_mux_set_parent()
473 writel((CPG_WEN_BIT | val) << shift, priv->base + off); in rzg2l_cpg_sd_clk_mux_set_parent()
476 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); in rzg2l_cpg_sd_clk_mux_set_parent()
478 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg2l_cpg_sd_clk_mux_set_parent()
481 dev_err(priv->dev, "Failed to switch parent\n"); in rzg2l_cpg_sd_clk_mux_set_parent()
490 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg2l_cpg_sd_clk_mux_get_parent()
493 val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf)); in rzg2l_cpg_sd_clk_mux_get_parent()
494 val >>= GET_SHIFT(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_get_parent()
495 val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0); in rzg2l_cpg_sd_clk_mux_get_parent()
497 return clk_mux_val_to_index(hw, sd_mux_hw_data->mtable, CLK_MUX_ROUND_CLOSEST, val); in rzg2l_cpg_sd_clk_mux_get_parent()
506 static struct clk * __init
507 rzg2l_cpg_sd_mux_clk_register(const struct cpg_core_clk *core, in rzg2l_cpg_sd_mux_clk_register() argument
515 sd_mux_hw_data = devm_kzalloc(priv->dev, sizeof(*sd_mux_hw_data), GFP_KERNEL); in rzg2l_cpg_sd_mux_clk_register()
517 return ERR_PTR(-ENOMEM); in rzg2l_cpg_sd_mux_clk_register()
519 sd_mux_hw_data->hw_data.priv = priv; in rzg2l_cpg_sd_mux_clk_register()
520 sd_mux_hw_data->hw_data.conf = core->conf; in rzg2l_cpg_sd_mux_clk_register()
521 sd_mux_hw_data->hw_data.sconf = core->sconf; in rzg2l_cpg_sd_mux_clk_register()
522 sd_mux_hw_data->mtable = core->mtable; in rzg2l_cpg_sd_mux_clk_register()
524 init.name = core->name; in rzg2l_cpg_sd_mux_clk_register()
526 init.flags = core->flag; in rzg2l_cpg_sd_mux_clk_register()
527 init.num_parents = core->num_parents; in rzg2l_cpg_sd_mux_clk_register()
528 init.parent_names = core->parent_names; in rzg2l_cpg_sd_mux_clk_register()
530 clk_hw = &sd_mux_hw_data->hw_data.hw; in rzg2l_cpg_sd_mux_clk_register()
531 clk_hw->init = &init; in rzg2l_cpg_sd_mux_clk_register()
533 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg2l_cpg_sd_mux_clk_register()
537 ret = rzg2l_register_notifier(clk_hw, core, priv); in rzg2l_cpg_sd_mux_clk_register()
539 dev_err(priv->dev, "Failed to register notifier for %s\n", in rzg2l_cpg_sd_mux_clk_register()
540 core->name); in rzg2l_cpg_sd_mux_clk_register()
544 return clk_hw->clk; in rzg2l_cpg_sd_mux_clk_register()
553 params->pl5_intin = rate / MEGA; in rzg2l_cpg_get_foutpostdiv_rate()
554 params->pl5_fracin = div_u64(((u64)rate % MEGA) << 24, MEGA); in rzg2l_cpg_get_foutpostdiv_rate()
555 params->pl5_refdiv = 2; in rzg2l_cpg_get_foutpostdiv_rate()
556 params->pl5_postdiv1 = 1; in rzg2l_cpg_get_foutpostdiv_rate()
557 params->pl5_postdiv2 = 1; in rzg2l_cpg_get_foutpostdiv_rate()
558 params->pl5_spread = 0x16; in rzg2l_cpg_get_foutpostdiv_rate()
561 EXTAL_FREQ_IN_MEGA_HZ * MEGA / params->pl5_refdiv * in rzg2l_cpg_get_foutpostdiv_rate()
562 ((((params->pl5_intin << 24) + params->pl5_fracin)) >> 24) / in rzg2l_cpg_get_foutpostdiv_rate()
563 (params->pl5_postdiv1 * params->pl5_postdiv2); in rzg2l_cpg_get_foutpostdiv_rate()
581 unsigned long rate = dsi_div->rate; in rzg2l_cpg_dsi_div_recalc_rate()
593 struct rzg2l_cpg_priv *priv = dsi_div->priv; in rzg2l_cpg_get_vclk_parent_rate()
599 if (priv->mux_dsi_div_params.clksrc) in rzg2l_cpg_get_vclk_parent_rate()
608 if (req->rate > MAX_VCLK_FREQ) in rzg2l_cpg_dsi_div_determine_rate()
609 req->rate = MAX_VCLK_FREQ; in rzg2l_cpg_dsi_div_determine_rate()
611 req->best_parent_rate = rzg2l_cpg_get_vclk_parent_rate(hw, req->rate); in rzg2l_cpg_dsi_div_determine_rate()
621 struct rzg2l_cpg_priv *priv = dsi_div->priv; in rzg2l_cpg_dsi_div_set_rate()
624 * MUX -->DIV_DSI_{A,B} -->M3 -->VCLK in rzg2l_cpg_dsi_div_set_rate()
627 * calculates the pll parameters for generating FOUTPOSTDIV and the clk in rzg2l_cpg_dsi_div_set_rate()
632 return -EINVAL; in rzg2l_cpg_dsi_div_set_rate()
634 dsi_div->rate = rate; in rzg2l_cpg_dsi_div_set_rate()
636 (priv->mux_dsi_div_params.dsi_div_a << 0) | in rzg2l_cpg_dsi_div_set_rate()
637 (priv->mux_dsi_div_params.dsi_div_b << 8), in rzg2l_cpg_dsi_div_set_rate()
638 priv->base + CPG_PL5_SDIV); in rzg2l_cpg_dsi_div_set_rate()
649 static struct clk * __init
650 rzg2l_cpg_dsi_div_clk_register(const struct cpg_core_clk *core, in rzg2l_cpg_dsi_div_clk_register() argument
654 const struct clk *parent; in rzg2l_cpg_dsi_div_clk_register()
660 parent = priv->clks[core->parent]; in rzg2l_cpg_dsi_div_clk_register()
664 clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL); in rzg2l_cpg_dsi_div_clk_register()
666 return ERR_PTR(-ENOMEM); in rzg2l_cpg_dsi_div_clk_register()
668 clk_hw_data->priv = priv; in rzg2l_cpg_dsi_div_clk_register()
671 init.name = core->name; in rzg2l_cpg_dsi_div_clk_register()
677 clk_hw = &clk_hw_data->hw; in rzg2l_cpg_dsi_div_clk_register()
678 clk_hw->init = &init; in rzg2l_cpg_dsi_div_clk_register()
680 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg2l_cpg_dsi_div_clk_register()
684 return clk_hw->clk; in rzg2l_cpg_dsi_div_clk_register()
701 struct rzg2l_cpg_priv *priv = hwdata->priv; in rzg2l_cpg_pll5_4_clk_mux_determine_rate()
703 parent = clk_hw_get_parent_by_index(hw, priv->mux_dsi_div_params.clksrc); in rzg2l_cpg_pll5_4_clk_mux_determine_rate()
704 req->best_parent_hw = parent; in rzg2l_cpg_pll5_4_clk_mux_determine_rate()
705 req->best_parent_rate = req->rate; in rzg2l_cpg_pll5_4_clk_mux_determine_rate()
713 struct rzg2l_cpg_priv *priv = hwdata->priv; in rzg2l_cpg_pll5_4_clk_mux_set_parent()
716 * FOUTPOSTDIV--->| in rzg2l_cpg_pll5_4_clk_mux_set_parent()
717 * | | -->MUX -->DIV_DSIA_B -->M3 -->VCLK in rzg2l_cpg_pll5_4_clk_mux_set_parent()
718 * |--FOUT1PH0-->| in rzg2l_cpg_pll5_4_clk_mux_set_parent()
721 * rate and clk source for the MUX. It propagates that info to in rzg2l_cpg_pll5_4_clk_mux_set_parent()
726 priv->base + CPG_OTHERFUNC1_REG); in rzg2l_cpg_pll5_4_clk_mux_set_parent()
734 struct rzg2l_cpg_priv *priv = hwdata->priv; in rzg2l_cpg_pll5_4_clk_mux_get_parent()
736 return readl(priv->base + GET_REG_OFFSET(hwdata->conf)); in rzg2l_cpg_pll5_4_clk_mux_get_parent()
745 static struct clk * __init
746 rzg2l_cpg_pll5_4_mux_clk_register(const struct cpg_core_clk *core, in rzg2l_cpg_pll5_4_mux_clk_register() argument
754 clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL); in rzg2l_cpg_pll5_4_mux_clk_register()
756 return ERR_PTR(-ENOMEM); in rzg2l_cpg_pll5_4_mux_clk_register()
758 clk_hw_data->priv = priv; in rzg2l_cpg_pll5_4_mux_clk_register()
759 clk_hw_data->conf = core->conf; in rzg2l_cpg_pll5_4_mux_clk_register()
761 init.name = core->name; in rzg2l_cpg_pll5_4_mux_clk_register()
764 init.num_parents = core->num_parents; in rzg2l_cpg_pll5_4_mux_clk_register()
765 init.parent_names = core->parent_names; in rzg2l_cpg_pll5_4_mux_clk_register()
767 clk_hw = &clk_hw_data->hw; in rzg2l_cpg_pll5_4_mux_clk_register()
768 clk_hw->init = &init; in rzg2l_cpg_pll5_4_mux_clk_register()
770 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg2l_cpg_pll5_4_mux_clk_register()
774 return clk_hw->clk; in rzg2l_cpg_pll5_4_mux_clk_register()
790 struct rzg2l_cpg_priv *priv = sipll5->priv; in rzg2l_cpg_get_vclk_rate()
793 vclk = rate / ((1 << priv->mux_dsi_div_params.dsi_div_a) * in rzg2l_cpg_get_vclk_rate()
794 (priv->mux_dsi_div_params.dsi_div_b + 1)); in rzg2l_cpg_get_vclk_rate()
796 if (priv->mux_dsi_div_params.clksrc) in rzg2l_cpg_get_vclk_rate()
806 unsigned long pll5_rate = sipll5->foutpostdiv_rate; in rzg2l_cpg_sipll5_recalc_rate()
826 struct rzg2l_cpg_priv *priv = sipll5->priv; in rzg2l_cpg_sipll5_set_rate()
833 * OSC --> PLL5 --> FOUTPOSTDIV-->| in rzg2l_cpg_sipll5_set_rate()
834 * | | -->MUX -->DIV_DSIA_B -->M3 -->VCLK in rzg2l_cpg_sipll5_set_rate()
835 * |--FOUT1PH0-->| in rzg2l_cpg_sipll5_set_rate()
841 * OSC --> PLL5 --> FOUTPOSTDIV in rzg2l_cpg_sipll5_set_rate()
845 return -EINVAL; in rzg2l_cpg_sipll5_set_rate()
848 sipll5->foutpostdiv_rate = in rzg2l_cpg_sipll5_set_rate()
852 writel(CPG_SIPLL5_STBY_RESETB_WEN, priv->base + CPG_SIPLL5_STBY); in rzg2l_cpg_sipll5_set_rate()
853 ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val, in rzg2l_cpg_sipll5_set_rate()
856 dev_err(priv->dev, "failed to release pll5 lock"); in rzg2l_cpg_sipll5_set_rate()
862 (params.pl5_refdiv << 8), priv->base + CPG_SIPLL5_CLK1); in rzg2l_cpg_sipll5_set_rate()
865 writel((params.pl5_fracin << 8), priv->base + CPG_SIPLL5_CLK3); in rzg2l_cpg_sipll5_set_rate()
869 priv->base + CPG_SIPLL5_CLK4); in rzg2l_cpg_sipll5_set_rate()
872 writel(params.pl5_spread, priv->base + CPG_SIPLL5_CLK5); in rzg2l_cpg_sipll5_set_rate()
877 priv->base + CPG_SIPLL5_STBY); in rzg2l_cpg_sipll5_set_rate()
880 ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val, in rzg2l_cpg_sipll5_set_rate()
883 dev_err(priv->dev, "failed to lock pll5"); in rzg2l_cpg_sipll5_set_rate()
896 static struct clk * __init
897 rzg2l_cpg_sipll5_register(const struct cpg_core_clk *core, in rzg2l_cpg_sipll5_register() argument
900 const struct clk *parent; in rzg2l_cpg_sipll5_register()
907 parent = priv->clks[core->parent]; in rzg2l_cpg_sipll5_register()
911 sipll5 = devm_kzalloc(priv->dev, sizeof(*sipll5), GFP_KERNEL); in rzg2l_cpg_sipll5_register()
913 return ERR_PTR(-ENOMEM); in rzg2l_cpg_sipll5_register()
915 init.name = core->name; in rzg2l_cpg_sipll5_register()
922 sipll5->hw.init = &init; in rzg2l_cpg_sipll5_register()
923 sipll5->conf = core->conf; in rzg2l_cpg_sipll5_register()
924 sipll5->priv = priv; in rzg2l_cpg_sipll5_register()
927 CPG_SIPLL5_STBY_RESETB, priv->base + CPG_SIPLL5_STBY); in rzg2l_cpg_sipll5_register()
929 clk_hw = &sipll5->hw; in rzg2l_cpg_sipll5_register()
930 clk_hw->init = &init; in rzg2l_cpg_sipll5_register()
932 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg2l_cpg_sipll5_register()
936 priv->mux_dsi_div_params.clksrc = 1; /* Use clk src 1 for DSI */ in rzg2l_cpg_sipll5_register()
937 priv->mux_dsi_div_params.dsi_div_a = 1; /* Divided by 2 */ in rzg2l_cpg_sipll5_register()
938 priv->mux_dsi_div_params.dsi_div_b = 2; /* Divided by 3 */ in rzg2l_cpg_sipll5_register()
940 return clk_hw->clk; in rzg2l_cpg_sipll5_register()
957 struct rzg2l_cpg_priv *priv = pll_clk->priv; in rzg2l_cpg_pll_clk_recalc_rate()
961 if (pll_clk->type != CLK_TYPE_SAM_PLL) in rzg2l_cpg_pll_clk_recalc_rate()
964 val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); in rzg2l_cpg_pll_clk_recalc_rate()
965 val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf)); in rzg2l_cpg_pll_clk_recalc_rate()
981 struct rzg2l_cpg_priv *priv = pll_clk->priv; in rzg3s_cpg_pll_clk_recalc_rate()
985 if (pll_clk->type != CLK_TYPE_G3S_PLL) in rzg3s_cpg_pll_clk_recalc_rate()
988 val = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); in rzg3s_cpg_pll_clk_recalc_rate()
1008 static struct clk * __init
1009 rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, in rzg2l_cpg_pll_clk_register() argument
1013 struct device *dev = priv->dev; in rzg2l_cpg_pll_clk_register()
1014 const struct clk *parent; in rzg2l_cpg_pll_clk_register()
1020 parent = priv->clks[core->parent]; in rzg2l_cpg_pll_clk_register()
1026 return ERR_PTR(-ENOMEM); in rzg2l_cpg_pll_clk_register()
1029 init.name = core->name; in rzg2l_cpg_pll_clk_register()
1035 pll_clk->hw.init = &init; in rzg2l_cpg_pll_clk_register()
1036 pll_clk->conf = core->conf; in rzg2l_cpg_pll_clk_register()
1037 pll_clk->base = priv->base; in rzg2l_cpg_pll_clk_register()
1038 pll_clk->priv = priv; in rzg2l_cpg_pll_clk_register()
1039 pll_clk->type = core->type; in rzg2l_cpg_pll_clk_register()
1041 ret = devm_clk_hw_register(dev, &pll_clk->hw); in rzg2l_cpg_pll_clk_register()
1045 return pll_clk->hw.clk; in rzg2l_cpg_pll_clk_register()
1048 static struct clk
1052 unsigned int clkidx = clkspec->args[1]; in rzg2l_cpg_clk_src_twocell_get()
1054 struct device *dev = priv->dev; in rzg2l_cpg_clk_src_twocell_get()
1056 struct clk *clk; in rzg2l_cpg_clk_src_twocell_get() local
1058 switch (clkspec->args[0]) { in rzg2l_cpg_clk_src_twocell_get()
1060 type = "core"; in rzg2l_cpg_clk_src_twocell_get()
1061 if (clkidx > priv->last_dt_core_clk) { in rzg2l_cpg_clk_src_twocell_get()
1063 return ERR_PTR(-EINVAL); in rzg2l_cpg_clk_src_twocell_get()
1065 clk = priv->clks[clkidx]; in rzg2l_cpg_clk_src_twocell_get()
1070 if (clkidx >= priv->num_mod_clks) { in rzg2l_cpg_clk_src_twocell_get()
1073 return ERR_PTR(-EINVAL); in rzg2l_cpg_clk_src_twocell_get()
1075 clk = priv->clks[priv->num_core_clks + clkidx]; in rzg2l_cpg_clk_src_twocell_get()
1079 dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]); in rzg2l_cpg_clk_src_twocell_get()
1080 return ERR_PTR(-EINVAL); in rzg2l_cpg_clk_src_twocell_get()
1083 if (IS_ERR(clk)) in rzg2l_cpg_clk_src_twocell_get()
1085 PTR_ERR(clk)); in rzg2l_cpg_clk_src_twocell_get()
1088 clkspec->args[0], clkspec->args[1], clk, in rzg2l_cpg_clk_src_twocell_get()
1089 clk_get_rate(clk)); in rzg2l_cpg_clk_src_twocell_get()
1090 return clk; in rzg2l_cpg_clk_src_twocell_get()
1094 rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, in rzg2l_cpg_register_core_clk() argument
1098 struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent; in rzg2l_cpg_register_core_clk() local
1099 struct device *dev = priv->dev; in rzg2l_cpg_register_core_clk()
1100 unsigned int id = core->id, div = core->div; in rzg2l_cpg_register_core_clk()
1104 WARN_DEBUG(id >= priv->num_core_clks); in rzg2l_cpg_register_core_clk()
1105 WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); in rzg2l_cpg_register_core_clk()
1107 if (!core->name) { in rzg2l_cpg_register_core_clk()
1112 switch (core->type) { in rzg2l_cpg_register_core_clk()
1114 clk = of_clk_get_by_name(priv->dev->of_node, core->name); in rzg2l_cpg_register_core_clk()
1117 WARN_DEBUG(core->parent >= priv->num_core_clks); in rzg2l_cpg_register_core_clk()
1118 parent = priv->clks[core->parent]; in rzg2l_cpg_register_core_clk()
1120 clk = parent; in rzg2l_cpg_register_core_clk()
1125 clk_hw = devm_clk_hw_register_fixed_factor(dev, core->name, parent_name, in rzg2l_cpg_register_core_clk()
1127 core->mult, div); in rzg2l_cpg_register_core_clk()
1129 clk = ERR_CAST(clk_hw); in rzg2l_cpg_register_core_clk()
1131 clk = clk_hw->clk; in rzg2l_cpg_register_core_clk()
1134 clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg2l_cpg_pll_ops); in rzg2l_cpg_register_core_clk()
1137 clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg3s_cpg_pll_ops); in rzg2l_cpg_register_core_clk()
1140 clk = rzg2l_cpg_sipll5_register(core, priv); in rzg2l_cpg_register_core_clk()
1143 clk = rzg2l_cpg_div_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1146 clk = rzg3s_cpg_div_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1149 clk = rzg2l_cpg_mux_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1152 clk = rzg2l_cpg_sd_mux_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1155 clk = rzg2l_cpg_pll5_4_mux_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1158 clk = rzg2l_cpg_dsi_div_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1164 if (IS_ERR_OR_NULL(clk)) in rzg2l_cpg_register_core_clk()
1167 dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); in rzg2l_cpg_register_core_clk()
1168 priv->clks[id] = clk; in rzg2l_cpg_register_core_clk()
1172 dev_err(dev, "Failed to register %s clock %s: %ld\n", "core", in rzg2l_cpg_register_core_clk()
1173 core->name, PTR_ERR(clk)); in rzg2l_cpg_register_core_clk()
1177 * struct mstp_clock - MSTP gating clock
1179 * @hw: handle between common and hardware-specific interfaces
1200 struct rzg2l_cpg_priv *priv = clock->priv; in rzg2l_mod_clock_endisable()
1201 unsigned int reg = clock->off; in rzg2l_mod_clock_endisable()
1202 struct device *dev = priv->dev; in rzg2l_mod_clock_endisable()
1203 u32 bitmask = BIT(clock->bit); in rzg2l_mod_clock_endisable()
1207 if (!clock->off) { in rzg2l_mod_clock_endisable()
1208 dev_dbg(dev, "%pC does not support ON/OFF\n", hw->clk); in rzg2l_mod_clock_endisable()
1212 dev_dbg(dev, "CLK_ON 0x%x/%pC %s\n", CLK_ON_R(reg), hw->clk, in rzg2l_mod_clock_endisable()
1219 writel(value, priv->base + CLK_ON_R(reg)); in rzg2l_mod_clock_endisable()
1224 if (!priv->info->has_clk_mon_regs) in rzg2l_mod_clock_endisable()
1227 error = readl_poll_timeout_atomic(priv->base + CLK_MON_R(reg), value, in rzg2l_mod_clock_endisable()
1231 priv->base + CLK_ON_R(reg)); in rzg2l_mod_clock_endisable()
1240 if (clock->sibling) { in rzg2l_mod_clock_enable()
1241 struct rzg2l_cpg_priv *priv = clock->priv; in rzg2l_mod_clock_enable()
1245 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg2l_mod_clock_enable()
1246 enabled = clock->sibling->enabled; in rzg2l_mod_clock_enable()
1247 clock->enabled = true; in rzg2l_mod_clock_enable()
1248 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg2l_mod_clock_enable()
1260 if (clock->sibling) { in rzg2l_mod_clock_disable()
1261 struct rzg2l_cpg_priv *priv = clock->priv; in rzg2l_mod_clock_disable()
1265 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg2l_mod_clock_disable()
1266 enabled = clock->sibling->enabled; in rzg2l_mod_clock_disable()
1267 clock->enabled = false; in rzg2l_mod_clock_disable()
1268 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg2l_mod_clock_disable()
1279 struct rzg2l_cpg_priv *priv = clock->priv; in rzg2l_mod_clock_is_enabled()
1280 u32 bitmask = BIT(clock->bit); in rzg2l_mod_clock_is_enabled()
1283 if (!clock->off) { in rzg2l_mod_clock_is_enabled()
1284 dev_dbg(priv->dev, "%pC does not support ON/OFF\n", hw->clk); in rzg2l_mod_clock_is_enabled()
1288 if (clock->sibling) in rzg2l_mod_clock_is_enabled()
1289 return clock->enabled; in rzg2l_mod_clock_is_enabled()
1291 if (priv->info->has_clk_mon_regs) in rzg2l_mod_clock_is_enabled()
1292 value = readl(priv->base + CLK_MON_R(clock->off)); in rzg2l_mod_clock_is_enabled()
1294 value = readl(priv->base + clock->off); in rzg2l_mod_clock_is_enabled()
1312 for (i = 0; i < priv->num_mod_clks; i++) { in rzg2l_mod_clock_get_sibling()
1313 struct mstp_clock *clk; in rzg2l_mod_clock_get_sibling() local
1315 if (priv->clks[priv->num_core_clks + i] == ERR_PTR(-ENOENT)) in rzg2l_mod_clock_get_sibling()
1318 hw = __clk_get_hw(priv->clks[priv->num_core_clks + i]); in rzg2l_mod_clock_get_sibling()
1319 clk = to_mod_clock(hw); in rzg2l_mod_clock_get_sibling()
1320 if (clock->off == clk->off && clock->bit == clk->bit) in rzg2l_mod_clock_get_sibling()
1321 return clk; in rzg2l_mod_clock_get_sibling()
1333 struct device *dev = priv->dev; in rzg2l_cpg_register_mod_clk()
1334 unsigned int id = mod->id; in rzg2l_cpg_register_mod_clk()
1336 struct clk *parent, *clk; in rzg2l_cpg_register_mod_clk() local
1341 WARN_DEBUG(id < priv->num_core_clks); in rzg2l_cpg_register_mod_clk()
1342 WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); in rzg2l_cpg_register_mod_clk()
1343 WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); in rzg2l_cpg_register_mod_clk()
1344 WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); in rzg2l_cpg_register_mod_clk()
1346 if (!mod->name) { in rzg2l_cpg_register_mod_clk()
1351 parent = priv->clks[mod->parent]; in rzg2l_cpg_register_mod_clk()
1353 clk = parent; in rzg2l_cpg_register_mod_clk()
1359 clk = ERR_PTR(-ENOMEM); in rzg2l_cpg_register_mod_clk()
1363 init.name = mod->name; in rzg2l_cpg_register_mod_clk()
1366 for (i = 0; i < info->num_crit_mod_clks; i++) in rzg2l_cpg_register_mod_clk()
1367 if (id == info->crit_mod_clks[i]) { in rzg2l_cpg_register_mod_clk()
1369 mod->name); in rzg2l_cpg_register_mod_clk()
1378 clock->off = mod->off; in rzg2l_cpg_register_mod_clk()
1379 clock->bit = mod->bit; in rzg2l_cpg_register_mod_clk()
1380 clock->priv = priv; in rzg2l_cpg_register_mod_clk()
1381 clock->hw.init = &init; in rzg2l_cpg_register_mod_clk()
1383 ret = devm_clk_hw_register(dev, &clock->hw); in rzg2l_cpg_register_mod_clk()
1385 clk = ERR_PTR(ret); in rzg2l_cpg_register_mod_clk()
1389 clk = clock->hw.clk; in rzg2l_cpg_register_mod_clk()
1390 dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); in rzg2l_cpg_register_mod_clk()
1391 priv->clks[id] = clk; in rzg2l_cpg_register_mod_clk()
1393 if (mod->is_coupled) { in rzg2l_cpg_register_mod_clk()
1396 clock->enabled = rzg2l_mod_clock_is_enabled(&clock->hw); in rzg2l_cpg_register_mod_clk()
1399 clock->sibling = sibling; in rzg2l_cpg_register_mod_clk()
1400 sibling->sibling = clock; in rzg2l_cpg_register_mod_clk()
1408 mod->name, PTR_ERR(clk)); in rzg2l_cpg_register_mod_clk()
1417 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_assert()
1418 unsigned int reg = info->resets[id].off; in rzg2l_cpg_assert()
1419 u32 mask = BIT(info->resets[id].bit); in rzg2l_cpg_assert()
1420 s8 monbit = info->resets[id].monbit; in rzg2l_cpg_assert()
1423 dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); in rzg2l_cpg_assert()
1425 writel(value, priv->base + CLK_RST_R(reg)); in rzg2l_cpg_assert()
1427 if (info->has_clk_mon_regs) { in rzg2l_cpg_assert()
1438 return readl_poll_timeout_atomic(priv->base + reg, value, in rzg2l_cpg_assert()
1446 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_deassert()
1447 unsigned int reg = info->resets[id].off; in rzg2l_cpg_deassert()
1448 u32 mask = BIT(info->resets[id].bit); in rzg2l_cpg_deassert()
1449 s8 monbit = info->resets[id].monbit; in rzg2l_cpg_deassert()
1452 dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id, in rzg2l_cpg_deassert()
1455 writel(value, priv->base + CLK_RST_R(reg)); in rzg2l_cpg_deassert()
1457 if (info->has_clk_mon_regs) { in rzg2l_cpg_deassert()
1468 return readl_poll_timeout_atomic(priv->base + reg, value, in rzg2l_cpg_deassert()
1488 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_status()
1489 s8 monbit = info->resets[id].monbit; in rzg2l_cpg_status()
1493 if (info->has_clk_mon_regs) { in rzg2l_cpg_status()
1494 reg = CLK_MRST_R(info->resets[id].off); in rzg2l_cpg_status()
1495 bitmask = BIT(info->resets[id].bit); in rzg2l_cpg_status()
1500 return -ENOTSUPP; in rzg2l_cpg_status()
1503 return !!(readl(priv->base + reg) & bitmask); in rzg2l_cpg_status()
1517 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_reset_xlate()
1518 unsigned int id = reset_spec->args[0]; in rzg2l_cpg_reset_xlate()
1520 if (id >= rcdev->nr_resets || !info->resets[id].off) { in rzg2l_cpg_reset_xlate()
1521 dev_err(rcdev->dev, "Invalid reset index %u\n", id); in rzg2l_cpg_reset_xlate()
1522 return -EINVAL; in rzg2l_cpg_reset_xlate()
1530 priv->rcdev.ops = &rzg2l_cpg_reset_ops; in rzg2l_cpg_reset_controller_register()
1531 priv->rcdev.of_node = priv->dev->of_node; in rzg2l_cpg_reset_controller_register()
1532 priv->rcdev.dev = priv->dev; in rzg2l_cpg_reset_controller_register()
1533 priv->rcdev.of_reset_n_cells = 1; in rzg2l_cpg_reset_controller_register()
1534 priv->rcdev.of_xlate = rzg2l_cpg_reset_xlate; in rzg2l_cpg_reset_controller_register()
1535 priv->rcdev.nr_resets = priv->num_resets; in rzg2l_cpg_reset_controller_register()
1537 return devm_reset_controller_register(priv->dev, &priv->rcdev); in rzg2l_cpg_reset_controller_register()
1543 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_is_pm_clk()
1547 if (clkspec->args_count != 2) in rzg2l_cpg_is_pm_clk()
1550 if (clkspec->args[0] != CPG_MOD) in rzg2l_cpg_is_pm_clk()
1553 id = clkspec->args[1] + info->num_total_core_clks; in rzg2l_cpg_is_pm_clk()
1554 for (i = 0; i < info->num_no_pm_mod_clks; i++) { in rzg2l_cpg_is_pm_clk()
1555 if (info->no_pm_mod_clks[i] == id) in rzg2l_cpg_is_pm_clk()
1563 * struct rzg2l_cpg_pm_domains - RZ/G2L PM domains data structure
1573 * struct rzg2l_cpg_pd - RZ/G2L power domain data structure
1589 struct rzg2l_cpg_priv *priv = pd->priv; in rzg2l_cpg_attach_dev()
1590 struct device_node *np = dev->of_node; in rzg2l_cpg_attach_dev()
1593 struct clk *clk; in rzg2l_cpg_attach_dev() local
1597 while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, in rzg2l_cpg_attach_dev()
1608 clk = of_clk_get_from_provider(&clkspec); in rzg2l_cpg_attach_dev()
1610 if (IS_ERR(clk)) { in rzg2l_cpg_attach_dev()
1611 error = PTR_ERR(clk); in rzg2l_cpg_attach_dev()
1615 error = pm_clk_add_clk(dev, clk); in rzg2l_cpg_attach_dev()
1630 clk_put(clk); in rzg2l_cpg_attach_dev()
1648 for (unsigned int i = 0; i < celldata->num_domains; i++) in rzg2l_cpg_genpd_remove()
1649 pm_genpd_remove(celldata->domains[i]); in rzg2l_cpg_genpd_remove()
1660 struct rzg2l_cpg_reg_conf mstop = pd->conf.mstop; in rzg2l_cpg_power_on()
1661 struct rzg2l_cpg_priv *priv = pd->priv; in rzg2l_cpg_power_on()
1665 writel(mstop.mask << 16, priv->base + mstop.off); in rzg2l_cpg_power_on()
1673 struct rzg2l_cpg_reg_conf mstop = pd->conf.mstop; in rzg2l_cpg_power_off()
1674 struct rzg2l_cpg_priv *priv = pd->priv; in rzg2l_cpg_power_off()
1678 writel(mstop.mask | (mstop.mask << 16), priv->base + mstop.off); in rzg2l_cpg_power_off()
1687 pd->genpd.flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP; in rzg2l_cpg_pd_setup()
1688 pd->genpd.attach_dev = rzg2l_cpg_attach_dev; in rzg2l_cpg_pd_setup()
1689 pd->genpd.detach_dev = rzg2l_cpg_detach_dev; in rzg2l_cpg_pd_setup()
1691 pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON; in rzg2l_cpg_pd_setup()
1694 pd->genpd.power_on = rzg2l_cpg_power_on; in rzg2l_cpg_pd_setup()
1695 pd->genpd.power_off = rzg2l_cpg_power_off; in rzg2l_cpg_pd_setup()
1699 return pm_genpd_init(&pd->genpd, governor, !always_on); in rzg2l_cpg_pd_setup()
1704 struct device *dev = priv->dev; in rzg2l_cpg_add_clk_domain()
1705 struct device_node *np = dev->of_node; in rzg2l_cpg_add_clk_domain()
1711 return -ENOMEM; in rzg2l_cpg_add_clk_domain()
1713 pd->genpd.name = np->name; in rzg2l_cpg_add_clk_domain()
1714 pd->priv = priv; in rzg2l_cpg_add_clk_domain()
1719 ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove_simple, &pd->genpd); in rzg2l_cpg_add_clk_domain()
1723 return of_genpd_add_provider_simple(np, &pd->genpd); in rzg2l_cpg_add_clk_domain()
1729 struct generic_pm_domain *domain = ERR_PTR(-ENOENT); in rzg2l_cpg_pm_domain_xlate()
1732 if (spec->args_count != 1) in rzg2l_cpg_pm_domain_xlate()
1733 return ERR_PTR(-EINVAL); in rzg2l_cpg_pm_domain_xlate()
1735 for (unsigned int i = 0; i < genpd->num_domains; i++) { in rzg2l_cpg_pm_domain_xlate()
1736 struct rzg2l_cpg_pd *pd = container_of(genpd->domains[i], struct rzg2l_cpg_pd, in rzg2l_cpg_pm_domain_xlate()
1739 if (pd->id == spec->args[0]) { in rzg2l_cpg_pm_domain_xlate()
1740 domain = &pd->genpd; in rzg2l_cpg_pm_domain_xlate()
1750 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_add_pm_domains()
1751 struct device *dev = priv->dev; in rzg2l_cpg_add_pm_domains()
1752 struct device_node *np = dev->of_node; in rzg2l_cpg_add_pm_domains()
1758 ret = of_property_read_u32(np, "#power-domain-cells", &ncells); in rzg2l_cpg_add_pm_domains()
1766 domains = devm_kzalloc(dev, struct_size(domains, domains, info->num_pm_domains), in rzg2l_cpg_add_pm_domains()
1769 return -ENOMEM; in rzg2l_cpg_add_pm_domains()
1771 domains->onecell_data.domains = domains->domains; in rzg2l_cpg_add_pm_domains()
1772 domains->onecell_data.num_domains = info->num_pm_domains; in rzg2l_cpg_add_pm_domains()
1773 domains->onecell_data.xlate = rzg2l_cpg_pm_domain_xlate; in rzg2l_cpg_add_pm_domains()
1775 ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove, &domains->onecell_data); in rzg2l_cpg_add_pm_domains()
1779 for (unsigned int i = 0; i < info->num_pm_domains; i++) { in rzg2l_cpg_add_pm_domains()
1780 bool always_on = !!(info->pm_domains[i].flags & RZG2L_PD_F_ALWAYS_ON); in rzg2l_cpg_add_pm_domains()
1785 return -ENOMEM; in rzg2l_cpg_add_pm_domains()
1787 pd->genpd.name = info->pm_domains[i].name; in rzg2l_cpg_add_pm_domains()
1788 pd->conf = info->pm_domains[i].conf; in rzg2l_cpg_add_pm_domains()
1789 pd->id = info->pm_domains[i].id; in rzg2l_cpg_add_pm_domains()
1790 pd->priv = priv; in rzg2l_cpg_add_pm_domains()
1797 ret = rzg2l_cpg_power_on(&pd->genpd); in rzg2l_cpg_add_pm_domains()
1802 domains->domains[i] = &pd->genpd; in rzg2l_cpg_add_pm_domains()
1803 /* Parent should be on the very first entry of info->pm_domains[]. */ in rzg2l_cpg_add_pm_domains()
1805 parent = &pd->genpd; in rzg2l_cpg_add_pm_domains()
1809 ret = pm_genpd_add_subdomain(parent, &pd->genpd); in rzg2l_cpg_add_pm_domains()
1814 ret = of_genpd_add_provider_onecell(np, &domains->onecell_data); in rzg2l_cpg_add_pm_domains()
1823 struct device *dev = &pdev->dev; in rzg2l_cpg_probe()
1824 struct device_node *np = dev->of_node; in rzg2l_cpg_probe()
1828 struct clk **clks; in rzg2l_cpg_probe()
1835 return -ENOMEM; in rzg2l_cpg_probe()
1837 priv->dev = dev; in rzg2l_cpg_probe()
1838 priv->info = info; in rzg2l_cpg_probe()
1839 spin_lock_init(&priv->rmw_lock); in rzg2l_cpg_probe()
1841 priv->base = devm_platform_ioremap_resource(pdev, 0); in rzg2l_cpg_probe()
1842 if (IS_ERR(priv->base)) in rzg2l_cpg_probe()
1843 return PTR_ERR(priv->base); in rzg2l_cpg_probe()
1845 nclks = info->num_total_core_clks + info->num_hw_mod_clks; in rzg2l_cpg_probe()
1848 return -ENOMEM; in rzg2l_cpg_probe()
1851 priv->clks = clks; in rzg2l_cpg_probe()
1852 priv->num_core_clks = info->num_total_core_clks; in rzg2l_cpg_probe()
1853 priv->num_mod_clks = info->num_hw_mod_clks; in rzg2l_cpg_probe()
1854 priv->num_resets = info->num_resets; in rzg2l_cpg_probe()
1855 priv->last_dt_core_clk = info->last_dt_core_clk; in rzg2l_cpg_probe()
1858 clks[i] = ERR_PTR(-ENOENT); in rzg2l_cpg_probe()
1860 for (i = 0; i < info->num_core_clks; i++) in rzg2l_cpg_probe()
1861 rzg2l_cpg_register_core_clk(&info->core_clks[i], info, priv); in rzg2l_cpg_probe()
1863 for (i = 0; i < info->num_mod_clks; i++) in rzg2l_cpg_probe()
1864 rzg2l_cpg_register_mod_clk(&info->mod_clks[i], info, priv); in rzg2l_cpg_probe()
1888 .compatible = "renesas,r9a07g043-cpg",
1894 .compatible = "renesas,r9a07g044-cpg",
1900 .compatible = "renesas,r9a07g054-cpg",
1906 .compatible = "renesas,r9a08g045-cpg",
1912 .compatible = "renesas,r9a09g011-cpg",
1921 .name = "rzg2l-cpg",