Lines Matching +full:max +full:- +full:clk +full:- +full:rate +full:- +full:hz

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"
71 * struct clk_hw_data - clock hardware data
87 * struct sd_mux_hw_data - SD MUX clock hardware data
99 * struct div_hw_data - divider clock hardware data
102 * @invalid_rate: invalid rate for divider
103 * @max_rate: maximum rate for divider
132 * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data
141 * @num_resets: Number of Module Resets in info->resets[]
152 struct clk **clks;
171 u32 bitmask = GENMASK(GET_WIDTH(conf) - 1, 0) << GET_SHIFT(conf); in rzg2l_cpg_wait_clk_update_done()
182 struct clk_hw *hw = __clk_get_hw(cnd->clk); in rzg2l_cpg_sd_clk_mux_notifier()
184 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg2l_cpg_sd_clk_mux_notifier()
185 u32 off = GET_REG_OFFSET(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_notifier()
186 u32 shift = GET_SHIFT(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_notifier()
191 if (event != PRE_RATE_CHANGE || (cnd->new_rate / MEGA == 266)) in rzg2l_cpg_sd_clk_mux_notifier()
194 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg2l_cpg_sd_clk_mux_notifier()
208 writel((CPG_WEN_BIT | clk_src_266) << shift, priv->base + off); in rzg2l_cpg_sd_clk_mux_notifier()
211 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); in rzg2l_cpg_sd_clk_mux_notifier()
213 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg2l_cpg_sd_clk_mux_notifier()
216 dev_err(priv->dev, "failed to switch to safe clk source\n"); in rzg2l_cpg_sd_clk_mux_notifier()
225 struct clk_hw *hw = __clk_get_hw(cnd->clk); in rzg3s_cpg_div_clk_notifier()
228 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg3s_cpg_div_clk_notifier()
229 u32 off = GET_REG_OFFSET(clk_hw_data->conf); in rzg3s_cpg_div_clk_notifier()
230 u32 shift = GET_SHIFT(clk_hw_data->conf); in rzg3s_cpg_div_clk_notifier()
235 if (event != PRE_RATE_CHANGE || !div_hw_data->invalid_rate || in rzg3s_cpg_div_clk_notifier()
236 div_hw_data->invalid_rate % cnd->new_rate) in rzg3s_cpg_div_clk_notifier()
239 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg3s_cpg_div_clk_notifier()
241 val = readl(priv->base + off); in rzg3s_cpg_div_clk_notifier()
243 val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0); in rzg3s_cpg_div_clk_notifier()
247 * 1/ SD div cannot be 1 (val == 0) if parent rate is 800MHz in rzg3s_cpg_div_clk_notifier()
248 * 2/ OCTA / SPI div cannot be 1 (val == 0) if parent rate is 400MHz in rzg3s_cpg_div_clk_notifier()
250 * only one parent having 400MHz we took into account the parent rate in rzg3s_cpg_div_clk_notifier()
255 writel((CPG_WEN_BIT | 1) << shift, priv->base + off); in rzg3s_cpg_div_clk_notifier()
257 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); in rzg3s_cpg_div_clk_notifier()
260 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg3s_cpg_div_clk_notifier()
263 dev_err(priv->dev, "Failed to downgrade the div\n"); in rzg3s_cpg_div_clk_notifier()
273 if (!core->notifier) in rzg2l_register_notifier()
276 nb = devm_kzalloc(priv->dev, sizeof(*nb), GFP_KERNEL); in rzg2l_register_notifier()
278 return -ENOMEM; in rzg2l_register_notifier()
280 nb->notifier_call = core->notifier; in rzg2l_register_notifier()
282 return clk_notifier_register(hw->clk, nb); in rzg2l_register_notifier()
290 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg3s_div_clk_recalc_rate()
293 val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf)); in rzg3s_div_clk_recalc_rate()
294 val >>= GET_SHIFT(clk_hw_data->conf); in rzg3s_div_clk_recalc_rate()
295 val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0); in rzg3s_div_clk_recalc_rate()
297 return divider_recalc_rate(hw, parent_rate, val, div_hw_data->dtable, in rzg3s_div_clk_recalc_rate()
298 CLK_DIVIDER_ROUND_CLOSEST, div_hw_data->width); in rzg3s_div_clk_recalc_rate()
306 if (div_hw_data->max_rate && req->rate > div_hw_data->max_rate) in rzg3s_div_clk_determine_rate()
307 req->rate = div_hw_data->max_rate; in rzg3s_div_clk_determine_rate()
309 return divider_determine_rate(hw, req, div_hw_data->dtable, div_hw_data->width, in rzg3s_div_clk_determine_rate()
313 static int rzg3s_div_clk_set_rate(struct clk_hw *hw, unsigned long rate, in rzg3s_div_clk_set_rate() argument
318 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg3s_div_clk_set_rate()
319 u32 off = GET_REG_OFFSET(clk_hw_data->conf); in rzg3s_div_clk_set_rate()
320 u32 shift = GET_SHIFT(clk_hw_data->conf); in rzg3s_div_clk_set_rate()
325 val = divider_get_val(rate, parent_rate, div_hw_data->dtable, div_hw_data->width, in rzg3s_div_clk_set_rate()
328 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg3s_div_clk_set_rate()
329 writel((CPG_WEN_BIT | val) << shift, priv->base + off); in rzg3s_div_clk_set_rate()
331 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); in rzg3s_div_clk_set_rate()
332 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg3s_div_clk_set_rate()
343 static struct clk * __init
350 const struct clk *parent; in rzg3s_cpg_div_clk_register()
352 u32 max = 0; in rzg3s_cpg_div_clk_register() local
355 parent = priv->clks[core->parent]; in rzg3s_cpg_div_clk_register()
361 div_hw_data = devm_kzalloc(priv->dev, sizeof(*div_hw_data), GFP_KERNEL); in rzg3s_cpg_div_clk_register()
363 return ERR_PTR(-ENOMEM); in rzg3s_cpg_div_clk_register()
365 init.name = core->name; in rzg3s_cpg_div_clk_register()
366 init.flags = core->flag; in rzg3s_cpg_div_clk_register()
372 for (clkt = core->dtable; clkt->div; clkt++) { in rzg3s_cpg_div_clk_register()
373 if (max < clkt->div) in rzg3s_cpg_div_clk_register()
374 max = clkt->div; in rzg3s_cpg_div_clk_register()
377 div_hw_data->hw_data.priv = priv; in rzg3s_cpg_div_clk_register()
378 div_hw_data->hw_data.conf = core->conf; in rzg3s_cpg_div_clk_register()
379 div_hw_data->hw_data.sconf = core->sconf; in rzg3s_cpg_div_clk_register()
380 div_hw_data->dtable = core->dtable; in rzg3s_cpg_div_clk_register()
381 div_hw_data->invalid_rate = core->invalid_rate; in rzg3s_cpg_div_clk_register()
382 div_hw_data->max_rate = core->max_rate; in rzg3s_cpg_div_clk_register()
383 div_hw_data->width = fls(max) - 1; in rzg3s_cpg_div_clk_register()
385 clk_hw = &div_hw_data->hw_data.hw; in rzg3s_cpg_div_clk_register()
386 clk_hw->init = &init; in rzg3s_cpg_div_clk_register()
388 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg3s_cpg_div_clk_register()
394 dev_err(priv->dev, "Failed to register notifier for %s\n", in rzg3s_cpg_div_clk_register()
395 core->name); in rzg3s_cpg_div_clk_register()
399 return clk_hw->clk; in rzg3s_cpg_div_clk_register()
402 static struct clk * __init
406 void __iomem *base = priv->base; in rzg2l_cpg_div_clk_register()
407 struct device *dev = priv->dev; in rzg2l_cpg_div_clk_register()
408 const struct clk *parent; in rzg2l_cpg_div_clk_register()
412 parent = priv->clks[core->parent]; in rzg2l_cpg_div_clk_register()
418 if (core->dtable) in rzg2l_cpg_div_clk_register()
419 clk_hw = clk_hw_register_divider_table(dev, core->name, in rzg2l_cpg_div_clk_register()
421 base + GET_REG_OFFSET(core->conf), in rzg2l_cpg_div_clk_register()
422 GET_SHIFT(core->conf), in rzg2l_cpg_div_clk_register()
423 GET_WIDTH(core->conf), in rzg2l_cpg_div_clk_register()
424 core->flag, in rzg2l_cpg_div_clk_register()
425 core->dtable, in rzg2l_cpg_div_clk_register()
426 &priv->rmw_lock); in rzg2l_cpg_div_clk_register()
428 clk_hw = clk_hw_register_divider(dev, core->name, in rzg2l_cpg_div_clk_register()
430 base + GET_REG_OFFSET(core->conf), in rzg2l_cpg_div_clk_register()
431 GET_SHIFT(core->conf), in rzg2l_cpg_div_clk_register()
432 GET_WIDTH(core->conf), in rzg2l_cpg_div_clk_register()
433 core->flag, &priv->rmw_lock); in rzg2l_cpg_div_clk_register()
438 return clk_hw->clk; in rzg2l_cpg_div_clk_register()
441 static struct clk * __init
447 clk_hw = devm_clk_hw_register_mux(priv->dev, core->name, in rzg2l_cpg_mux_clk_register()
448 core->parent_names, core->num_parents, in rzg2l_cpg_mux_clk_register()
449 core->flag, in rzg2l_cpg_mux_clk_register()
450 priv->base + GET_REG_OFFSET(core->conf), in rzg2l_cpg_mux_clk_register()
451 GET_SHIFT(core->conf), in rzg2l_cpg_mux_clk_register()
452 GET_WIDTH(core->conf), in rzg2l_cpg_mux_clk_register()
453 core->mux_flags, &priv->rmw_lock); in rzg2l_cpg_mux_clk_register()
457 return clk_hw->clk; in rzg2l_cpg_mux_clk_register()
464 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg2l_cpg_sd_clk_mux_set_parent()
465 u32 off = GET_REG_OFFSET(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_set_parent()
466 u32 shift = GET_SHIFT(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_set_parent()
471 val = clk_mux_index_to_val(sd_mux_hw_data->mtable, CLK_MUX_ROUND_CLOSEST, index); in rzg2l_cpg_sd_clk_mux_set_parent()
473 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg2l_cpg_sd_clk_mux_set_parent()
475 writel((CPG_WEN_BIT | val) << shift, priv->base + off); in rzg2l_cpg_sd_clk_mux_set_parent()
478 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); in rzg2l_cpg_sd_clk_mux_set_parent()
480 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg2l_cpg_sd_clk_mux_set_parent()
483 dev_err(priv->dev, "Failed to switch parent\n"); in rzg2l_cpg_sd_clk_mux_set_parent()
492 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg2l_cpg_sd_clk_mux_get_parent()
495 val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf)); in rzg2l_cpg_sd_clk_mux_get_parent()
496 val >>= GET_SHIFT(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_get_parent()
497 val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0); in rzg2l_cpg_sd_clk_mux_get_parent()
499 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()
508 static struct clk * __init
517 sd_mux_hw_data = devm_kzalloc(priv->dev, sizeof(*sd_mux_hw_data), GFP_KERNEL); in rzg2l_cpg_sd_mux_clk_register()
519 return ERR_PTR(-ENOMEM); in rzg2l_cpg_sd_mux_clk_register()
521 sd_mux_hw_data->hw_data.priv = priv; in rzg2l_cpg_sd_mux_clk_register()
522 sd_mux_hw_data->hw_data.conf = core->conf; in rzg2l_cpg_sd_mux_clk_register()
523 sd_mux_hw_data->hw_data.sconf = core->sconf; in rzg2l_cpg_sd_mux_clk_register()
524 sd_mux_hw_data->mtable = core->mtable; in rzg2l_cpg_sd_mux_clk_register()
526 init.name = core->name; in rzg2l_cpg_sd_mux_clk_register()
528 init.flags = core->flag; in rzg2l_cpg_sd_mux_clk_register()
529 init.num_parents = core->num_parents; in rzg2l_cpg_sd_mux_clk_register()
530 init.parent_names = core->parent_names; in rzg2l_cpg_sd_mux_clk_register()
532 clk_hw = &sd_mux_hw_data->hw_data.hw; in rzg2l_cpg_sd_mux_clk_register()
533 clk_hw->init = &init; in rzg2l_cpg_sd_mux_clk_register()
535 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg2l_cpg_sd_mux_clk_register()
541 dev_err(priv->dev, "Failed to register notifier for %s\n", in rzg2l_cpg_sd_mux_clk_register()
542 core->name); in rzg2l_cpg_sd_mux_clk_register()
546 return clk_hw->clk; in rzg2l_cpg_sd_mux_clk_register()
551 unsigned long rate) in rzg2l_cpg_get_foutpostdiv_rate() argument
555 params->pl5_intin = rate / MEGA; in rzg2l_cpg_get_foutpostdiv_rate()
556 params->pl5_fracin = div_u64(((u64)rate % MEGA) << 24, MEGA); in rzg2l_cpg_get_foutpostdiv_rate()
557 params->pl5_refdiv = 2; in rzg2l_cpg_get_foutpostdiv_rate()
558 params->pl5_postdiv1 = 1; in rzg2l_cpg_get_foutpostdiv_rate()
559 params->pl5_postdiv2 = 1; in rzg2l_cpg_get_foutpostdiv_rate()
560 params->pl5_spread = 0x16; in rzg2l_cpg_get_foutpostdiv_rate()
563 (params->pl5_intin << 24) + params->pl5_fracin), in rzg2l_cpg_get_foutpostdiv_rate()
564 params->pl5_refdiv) >> 24; in rzg2l_cpg_get_foutpostdiv_rate()
566 params->pl5_postdiv1 * params->pl5_postdiv2); in rzg2l_cpg_get_foutpostdiv_rate()
574 unsigned long rate; member
584 unsigned long rate = dsi_div->rate; in rzg2l_cpg_dsi_div_recalc_rate() local
586 if (!rate) in rzg2l_cpg_dsi_div_recalc_rate()
587 rate = parent_rate; in rzg2l_cpg_dsi_div_recalc_rate()
589 return rate; in rzg2l_cpg_dsi_div_recalc_rate()
593 unsigned long rate) in rzg2l_cpg_get_vclk_parent_rate() argument
596 struct rzg2l_cpg_priv *priv = dsi_div->priv; in rzg2l_cpg_get_vclk_parent_rate()
600 parent_rate = rzg2l_cpg_get_foutpostdiv_rate(&params, rate); in rzg2l_cpg_get_vclk_parent_rate()
602 if (priv->mux_dsi_div_params.clksrc) in rzg2l_cpg_get_vclk_parent_rate()
611 if (req->rate > MAX_VCLK_FREQ) in rzg2l_cpg_dsi_div_determine_rate()
612 req->rate = MAX_VCLK_FREQ; in rzg2l_cpg_dsi_div_determine_rate()
614 req->best_parent_rate = rzg2l_cpg_get_vclk_parent_rate(hw, req->rate); in rzg2l_cpg_dsi_div_determine_rate()
620 unsigned long rate, in rzg2l_cpg_dsi_div_set_rate() argument
624 struct rzg2l_cpg_priv *priv = dsi_div->priv; in rzg2l_cpg_dsi_div_set_rate()
627 * MUX -->DIV_DSI_{A,B} -->M3 -->VCLK in rzg2l_cpg_dsi_div_set_rate()
630 * calculates the pll parameters for generating FOUTPOSTDIV and the clk in rzg2l_cpg_dsi_div_set_rate()
634 if (!rate || rate > MAX_VCLK_FREQ) in rzg2l_cpg_dsi_div_set_rate()
635 return -EINVAL; in rzg2l_cpg_dsi_div_set_rate()
637 dsi_div->rate = rate; in rzg2l_cpg_dsi_div_set_rate()
639 (priv->mux_dsi_div_params.dsi_div_a << 0) | in rzg2l_cpg_dsi_div_set_rate()
640 (priv->mux_dsi_div_params.dsi_div_b << 8), in rzg2l_cpg_dsi_div_set_rate()
641 priv->base + CPG_PL5_SDIV); in rzg2l_cpg_dsi_div_set_rate()
652 static struct clk * __init
657 const struct clk *parent; in rzg2l_cpg_dsi_div_clk_register()
663 parent = priv->clks[core->parent]; in rzg2l_cpg_dsi_div_clk_register()
667 clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL); in rzg2l_cpg_dsi_div_clk_register()
669 return ERR_PTR(-ENOMEM); in rzg2l_cpg_dsi_div_clk_register()
671 clk_hw_data->priv = priv; in rzg2l_cpg_dsi_div_clk_register()
674 init.name = core->name; in rzg2l_cpg_dsi_div_clk_register()
680 clk_hw = &clk_hw_data->hw; in rzg2l_cpg_dsi_div_clk_register()
681 clk_hw->init = &init; in rzg2l_cpg_dsi_div_clk_register()
683 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg2l_cpg_dsi_div_clk_register()
687 return clk_hw->clk; in rzg2l_cpg_dsi_div_clk_register()
693 unsigned long rate; member
704 struct rzg2l_cpg_priv *priv = hwdata->priv; in rzg2l_cpg_pll5_4_clk_mux_determine_rate()
706 parent = clk_hw_get_parent_by_index(hw, priv->mux_dsi_div_params.clksrc); in rzg2l_cpg_pll5_4_clk_mux_determine_rate()
707 req->best_parent_hw = parent; in rzg2l_cpg_pll5_4_clk_mux_determine_rate()
708 req->best_parent_rate = req->rate; in rzg2l_cpg_pll5_4_clk_mux_determine_rate()
716 struct rzg2l_cpg_priv *priv = hwdata->priv; in rzg2l_cpg_pll5_4_clk_mux_set_parent()
719 * FOUTPOSTDIV--->| in rzg2l_cpg_pll5_4_clk_mux_set_parent()
720 * | | -->MUX -->DIV_DSIA_B -->M3 -->VCLK in rzg2l_cpg_pll5_4_clk_mux_set_parent()
721 * |--FOUT1PH0-->| in rzg2l_cpg_pll5_4_clk_mux_set_parent()
724 * rate and clk source for the MUX. It propagates that info to in rzg2l_cpg_pll5_4_clk_mux_set_parent()
729 priv->base + CPG_OTHERFUNC1_REG); in rzg2l_cpg_pll5_4_clk_mux_set_parent()
737 struct rzg2l_cpg_priv *priv = hwdata->priv; in rzg2l_cpg_pll5_4_clk_mux_get_parent()
739 return readl(priv->base + GET_REG_OFFSET(hwdata->conf)); in rzg2l_cpg_pll5_4_clk_mux_get_parent()
748 static struct clk * __init
757 clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL); in rzg2l_cpg_pll5_4_mux_clk_register()
759 return ERR_PTR(-ENOMEM); in rzg2l_cpg_pll5_4_mux_clk_register()
761 clk_hw_data->priv = priv; in rzg2l_cpg_pll5_4_mux_clk_register()
762 clk_hw_data->conf = core->conf; in rzg2l_cpg_pll5_4_mux_clk_register()
764 init.name = core->name; in rzg2l_cpg_pll5_4_mux_clk_register()
767 init.num_parents = core->num_parents; in rzg2l_cpg_pll5_4_mux_clk_register()
768 init.parent_names = core->parent_names; in rzg2l_cpg_pll5_4_mux_clk_register()
770 clk_hw = &clk_hw_data->hw; in rzg2l_cpg_pll5_4_mux_clk_register()
771 clk_hw->init = &init; in rzg2l_cpg_pll5_4_mux_clk_register()
773 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg2l_cpg_pll5_4_mux_clk_register()
777 return clk_hw->clk; in rzg2l_cpg_pll5_4_mux_clk_register()
790 unsigned long rate) in rzg2l_cpg_get_vclk_rate() argument
793 struct rzg2l_cpg_priv *priv = sipll5->priv; in rzg2l_cpg_get_vclk_rate()
796 vclk = rate / ((1 << priv->mux_dsi_div_params.dsi_div_a) * in rzg2l_cpg_get_vclk_rate()
797 (priv->mux_dsi_div_params.dsi_div_b + 1)); in rzg2l_cpg_get_vclk_rate()
799 if (priv->mux_dsi_div_params.clksrc) in rzg2l_cpg_get_vclk_rate()
809 unsigned long pll5_rate = sipll5->foutpostdiv_rate; in rzg2l_cpg_sipll5_recalc_rate()
818 unsigned long rate, in rzg2l_cpg_sipll5_round_rate() argument
821 return rate; in rzg2l_cpg_sipll5_round_rate()
825 unsigned long rate, in rzg2l_cpg_sipll5_set_rate() argument
829 struct rzg2l_cpg_priv *priv = sipll5->priv; in rzg2l_cpg_sipll5_set_rate()
836 * OSC --> PLL5 --> FOUTPOSTDIV-->| in rzg2l_cpg_sipll5_set_rate()
837 * | | -->MUX -->DIV_DSIA_B -->M3 -->VCLK in rzg2l_cpg_sipll5_set_rate()
838 * |--FOUT1PH0-->| in rzg2l_cpg_sipll5_set_rate()
841 * rate and the pll5 parameters for generating FOUTPOSTDIV. It propagates in rzg2l_cpg_sipll5_set_rate()
844 * OSC --> PLL5 --> FOUTPOSTDIV in rzg2l_cpg_sipll5_set_rate()
847 if (!rate) in rzg2l_cpg_sipll5_set_rate()
848 return -EINVAL; in rzg2l_cpg_sipll5_set_rate()
850 vclk_rate = rzg2l_cpg_get_vclk_rate(hw, rate); in rzg2l_cpg_sipll5_set_rate()
851 sipll5->foutpostdiv_rate = in rzg2l_cpg_sipll5_set_rate()
855 writel(CPG_SIPLL5_STBY_RESETB_WEN, priv->base + CPG_SIPLL5_STBY); in rzg2l_cpg_sipll5_set_rate()
856 ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val, in rzg2l_cpg_sipll5_set_rate()
859 dev_err(priv->dev, "failed to release pll5 lock"); in rzg2l_cpg_sipll5_set_rate()
865 (params.pl5_refdiv << 8), priv->base + CPG_SIPLL5_CLK1); in rzg2l_cpg_sipll5_set_rate()
868 writel((params.pl5_fracin << 8), priv->base + CPG_SIPLL5_CLK3); in rzg2l_cpg_sipll5_set_rate()
872 priv->base + CPG_SIPLL5_CLK4); in rzg2l_cpg_sipll5_set_rate()
875 writel(params.pl5_spread, priv->base + CPG_SIPLL5_CLK5); in rzg2l_cpg_sipll5_set_rate()
880 priv->base + CPG_SIPLL5_STBY); in rzg2l_cpg_sipll5_set_rate()
883 ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val, in rzg2l_cpg_sipll5_set_rate()
886 dev_err(priv->dev, "failed to lock pll5"); in rzg2l_cpg_sipll5_set_rate()
899 static struct clk * __init
903 const struct clk *parent; in rzg2l_cpg_sipll5_register()
910 parent = priv->clks[core->parent]; in rzg2l_cpg_sipll5_register()
914 sipll5 = devm_kzalloc(priv->dev, sizeof(*sipll5), GFP_KERNEL); in rzg2l_cpg_sipll5_register()
916 return ERR_PTR(-ENOMEM); in rzg2l_cpg_sipll5_register()
918 init.name = core->name; in rzg2l_cpg_sipll5_register()
925 sipll5->hw.init = &init; in rzg2l_cpg_sipll5_register()
926 sipll5->conf = core->conf; in rzg2l_cpg_sipll5_register()
927 sipll5->priv = priv; in rzg2l_cpg_sipll5_register()
930 CPG_SIPLL5_STBY_RESETB, priv->base + CPG_SIPLL5_STBY); in rzg2l_cpg_sipll5_register()
932 clk_hw = &sipll5->hw; in rzg2l_cpg_sipll5_register()
933 clk_hw->init = &init; in rzg2l_cpg_sipll5_register()
935 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg2l_cpg_sipll5_register()
939 priv->mux_dsi_div_params.clksrc = 1; /* Use clk src 1 for DSI */ in rzg2l_cpg_sipll5_register()
940 priv->mux_dsi_div_params.dsi_div_a = 1; /* Divided by 2 */ in rzg2l_cpg_sipll5_register()
941 priv->mux_dsi_div_params.dsi_div_b = 2; /* Divided by 3 */ in rzg2l_cpg_sipll5_register()
943 return clk_hw->clk; in rzg2l_cpg_sipll5_register()
961 struct rzg2l_cpg_priv *priv = pll_clk->priv; in rzg2l_cpg_pll_clk_recalc_rate()
963 u64 rate; in rzg2l_cpg_pll_clk_recalc_rate() local
965 if (pll_clk->type != CLK_TYPE_SAM_PLL) in rzg2l_cpg_pll_clk_recalc_rate()
968 val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); in rzg2l_cpg_pll_clk_recalc_rate()
969 val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf)); in rzg2l_cpg_pll_clk_recalc_rate()
971 rate = mul_u64_u32_shr(parent_rate, (MDIV(val1) << 16) + KDIV(val1), in rzg2l_cpg_pll_clk_recalc_rate()
974 return DIV_ROUND_CLOSEST_ULL(rate, PDIV(val1)); in rzg2l_cpg_pll_clk_recalc_rate()
985 struct rzg2l_cpg_priv *priv = pll_clk->priv; in rzg3s_cpg_pll_clk_recalc_rate()
987 u64 rate; in rzg3s_cpg_pll_clk_recalc_rate() local
989 if (pll_clk->type != CLK_TYPE_G3S_PLL) in rzg3s_cpg_pll_clk_recalc_rate()
992 setting = GET_REG_SAMPLL_SETTING(pll_clk->conf); in rzg3s_cpg_pll_clk_recalc_rate()
994 val = readl(priv->base + setting); in rzg3s_cpg_pll_clk_recalc_rate()
996 return pll_clk->default_rate; in rzg3s_cpg_pll_clk_recalc_rate()
999 val = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); in rzg3s_cpg_pll_clk_recalc_rate()
1010 rate = mul_u64_u32_shr(parent_rate, 4096 * nir + nfr, 12); in rzg3s_cpg_pll_clk_recalc_rate()
1012 return DIV_ROUND_CLOSEST_ULL(rate, (mr * pr)); in rzg3s_cpg_pll_clk_recalc_rate()
1019 static struct clk * __init
1024 struct device *dev = priv->dev; in rzg2l_cpg_pll_clk_register()
1025 const struct clk *parent; in rzg2l_cpg_pll_clk_register()
1031 parent = priv->clks[core->parent]; in rzg2l_cpg_pll_clk_register()
1037 return ERR_PTR(-ENOMEM); in rzg2l_cpg_pll_clk_register()
1040 init.name = core->name; in rzg2l_cpg_pll_clk_register()
1046 pll_clk->hw.init = &init; in rzg2l_cpg_pll_clk_register()
1047 pll_clk->conf = core->conf; in rzg2l_cpg_pll_clk_register()
1048 pll_clk->base = priv->base; in rzg2l_cpg_pll_clk_register()
1049 pll_clk->priv = priv; in rzg2l_cpg_pll_clk_register()
1050 pll_clk->type = core->type; in rzg2l_cpg_pll_clk_register()
1051 pll_clk->default_rate = core->default_rate; in rzg2l_cpg_pll_clk_register()
1053 ret = devm_clk_hw_register(dev, &pll_clk->hw); in rzg2l_cpg_pll_clk_register()
1057 return pll_clk->hw.clk; in rzg2l_cpg_pll_clk_register()
1060 static struct clk
1064 unsigned int clkidx = clkspec->args[1]; in rzg2l_cpg_clk_src_twocell_get()
1066 struct device *dev = priv->dev; in rzg2l_cpg_clk_src_twocell_get()
1068 struct clk *clk; in rzg2l_cpg_clk_src_twocell_get() local
1070 switch (clkspec->args[0]) { in rzg2l_cpg_clk_src_twocell_get()
1073 if (clkidx > priv->last_dt_core_clk) { in rzg2l_cpg_clk_src_twocell_get()
1075 return ERR_PTR(-EINVAL); in rzg2l_cpg_clk_src_twocell_get()
1077 clk = priv->clks[clkidx]; in rzg2l_cpg_clk_src_twocell_get()
1082 if (clkidx >= priv->num_mod_clks) { in rzg2l_cpg_clk_src_twocell_get()
1085 return ERR_PTR(-EINVAL); in rzg2l_cpg_clk_src_twocell_get()
1087 clk = priv->clks[priv->num_core_clks + clkidx]; in rzg2l_cpg_clk_src_twocell_get()
1091 dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]); in rzg2l_cpg_clk_src_twocell_get()
1092 return ERR_PTR(-EINVAL); in rzg2l_cpg_clk_src_twocell_get()
1095 if (IS_ERR(clk)) in rzg2l_cpg_clk_src_twocell_get()
1097 PTR_ERR(clk)); in rzg2l_cpg_clk_src_twocell_get()
1099 dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n", in rzg2l_cpg_clk_src_twocell_get()
1100 clkspec->args[0], clkspec->args[1], clk, in rzg2l_cpg_clk_src_twocell_get()
1101 clk_get_rate(clk)); in rzg2l_cpg_clk_src_twocell_get()
1102 return clk; in rzg2l_cpg_clk_src_twocell_get()
1110 struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent; in rzg2l_cpg_register_core_clk() local
1111 struct device *dev = priv->dev; in rzg2l_cpg_register_core_clk()
1112 unsigned int id = core->id, div = core->div; in rzg2l_cpg_register_core_clk()
1116 WARN_DEBUG(id >= priv->num_core_clks); in rzg2l_cpg_register_core_clk()
1117 WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); in rzg2l_cpg_register_core_clk()
1119 if (!core->name) { in rzg2l_cpg_register_core_clk()
1124 switch (core->type) { in rzg2l_cpg_register_core_clk()
1126 clk = of_clk_get_by_name(priv->dev->of_node, core->name); in rzg2l_cpg_register_core_clk()
1129 WARN_DEBUG(core->parent >= priv->num_core_clks); in rzg2l_cpg_register_core_clk()
1130 parent = priv->clks[core->parent]; in rzg2l_cpg_register_core_clk()
1132 clk = parent; in rzg2l_cpg_register_core_clk()
1137 clk_hw = devm_clk_hw_register_fixed_factor(dev, core->name, parent_name, in rzg2l_cpg_register_core_clk()
1139 core->mult, div); in rzg2l_cpg_register_core_clk()
1141 clk = ERR_CAST(clk_hw); in rzg2l_cpg_register_core_clk()
1143 clk = clk_hw->clk; in rzg2l_cpg_register_core_clk()
1146 clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg2l_cpg_pll_ops); in rzg2l_cpg_register_core_clk()
1149 clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg3s_cpg_pll_ops); in rzg2l_cpg_register_core_clk()
1152 clk = rzg2l_cpg_sipll5_register(core, priv); in rzg2l_cpg_register_core_clk()
1155 clk = rzg2l_cpg_div_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1158 clk = rzg3s_cpg_div_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1161 clk = rzg2l_cpg_mux_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1164 clk = rzg2l_cpg_sd_mux_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1167 clk = rzg2l_cpg_pll5_4_mux_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1170 clk = rzg2l_cpg_dsi_div_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1176 if (IS_ERR_OR_NULL(clk)) in rzg2l_cpg_register_core_clk()
1179 dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); in rzg2l_cpg_register_core_clk()
1180 priv->clks[id] = clk; in rzg2l_cpg_register_core_clk()
1185 core->name, PTR_ERR(clk)); in rzg2l_cpg_register_core_clk()
1189 * struct mstp_clock - MSTP gating clock
1191 * @hw: handle between common and hardware-specific interfaces
1212 struct rzg2l_cpg_priv *priv = clock->priv; in rzg2l_mod_clock_endisable()
1213 unsigned int reg = clock->off; in rzg2l_mod_clock_endisable()
1214 struct device *dev = priv->dev; in rzg2l_mod_clock_endisable()
1215 u32 bitmask = BIT(clock->bit); in rzg2l_mod_clock_endisable()
1219 if (!clock->off) { in rzg2l_mod_clock_endisable()
1220 dev_dbg(dev, "%pC does not support ON/OFF\n", hw->clk); in rzg2l_mod_clock_endisable()
1224 dev_dbg(dev, "CLK_ON 0x%x/%pC %s\n", CLK_ON_R(reg), hw->clk, in rzg2l_mod_clock_endisable()
1231 writel(value, priv->base + CLK_ON_R(reg)); in rzg2l_mod_clock_endisable()
1236 if (!priv->info->has_clk_mon_regs) in rzg2l_mod_clock_endisable()
1239 error = readl_poll_timeout_atomic(priv->base + CLK_MON_R(reg), value, in rzg2l_mod_clock_endisable()
1243 priv->base + CLK_ON_R(reg)); in rzg2l_mod_clock_endisable()
1252 if (clock->sibling) { in rzg2l_mod_clock_enable()
1253 struct rzg2l_cpg_priv *priv = clock->priv; in rzg2l_mod_clock_enable()
1257 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg2l_mod_clock_enable()
1258 enabled = clock->sibling->enabled; in rzg2l_mod_clock_enable()
1259 clock->enabled = true; in rzg2l_mod_clock_enable()
1260 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg2l_mod_clock_enable()
1272 if (clock->sibling) { in rzg2l_mod_clock_disable()
1273 struct rzg2l_cpg_priv *priv = clock->priv; in rzg2l_mod_clock_disable()
1277 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg2l_mod_clock_disable()
1278 enabled = clock->sibling->enabled; in rzg2l_mod_clock_disable()
1279 clock->enabled = false; in rzg2l_mod_clock_disable()
1280 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg2l_mod_clock_disable()
1291 struct rzg2l_cpg_priv *priv = clock->priv; in rzg2l_mod_clock_is_enabled()
1292 u32 bitmask = BIT(clock->bit); in rzg2l_mod_clock_is_enabled()
1295 if (!clock->off) { in rzg2l_mod_clock_is_enabled()
1296 dev_dbg(priv->dev, "%pC does not support ON/OFF\n", hw->clk); in rzg2l_mod_clock_is_enabled()
1300 if (clock->sibling) in rzg2l_mod_clock_is_enabled()
1301 return clock->enabled; in rzg2l_mod_clock_is_enabled()
1303 if (priv->info->has_clk_mon_regs) in rzg2l_mod_clock_is_enabled()
1304 value = readl(priv->base + CLK_MON_R(clock->off)); in rzg2l_mod_clock_is_enabled()
1306 value = readl(priv->base + clock->off); in rzg2l_mod_clock_is_enabled()
1324 for (i = 0; i < priv->num_mod_clks; i++) { in rzg2l_mod_clock_get_sibling()
1325 struct mstp_clock *clk; in rzg2l_mod_clock_get_sibling() local
1327 if (priv->clks[priv->num_core_clks + i] == ERR_PTR(-ENOENT)) in rzg2l_mod_clock_get_sibling()
1330 hw = __clk_get_hw(priv->clks[priv->num_core_clks + i]); in rzg2l_mod_clock_get_sibling()
1331 clk = to_mod_clock(hw); in rzg2l_mod_clock_get_sibling()
1332 if (clock->off == clk->off && clock->bit == clk->bit) in rzg2l_mod_clock_get_sibling()
1333 return clk; in rzg2l_mod_clock_get_sibling()
1345 struct device *dev = priv->dev; in rzg2l_cpg_register_mod_clk()
1346 unsigned int id = mod->id; in rzg2l_cpg_register_mod_clk()
1348 struct clk *parent, *clk; in rzg2l_cpg_register_mod_clk() local
1353 WARN_DEBUG(id < priv->num_core_clks); in rzg2l_cpg_register_mod_clk()
1354 WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); in rzg2l_cpg_register_mod_clk()
1355 WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); in rzg2l_cpg_register_mod_clk()
1356 WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); in rzg2l_cpg_register_mod_clk()
1358 if (!mod->name) { in rzg2l_cpg_register_mod_clk()
1363 parent = priv->clks[mod->parent]; in rzg2l_cpg_register_mod_clk()
1365 clk = parent; in rzg2l_cpg_register_mod_clk()
1371 clk = ERR_PTR(-ENOMEM); in rzg2l_cpg_register_mod_clk()
1375 init.name = mod->name; in rzg2l_cpg_register_mod_clk()
1378 for (i = 0; i < info->num_crit_mod_clks; i++) in rzg2l_cpg_register_mod_clk()
1379 if (id == info->crit_mod_clks[i]) { in rzg2l_cpg_register_mod_clk()
1381 mod->name); in rzg2l_cpg_register_mod_clk()
1390 clock->off = mod->off; in rzg2l_cpg_register_mod_clk()
1391 clock->bit = mod->bit; in rzg2l_cpg_register_mod_clk()
1392 clock->priv = priv; in rzg2l_cpg_register_mod_clk()
1393 clock->hw.init = &init; in rzg2l_cpg_register_mod_clk()
1395 ret = devm_clk_hw_register(dev, &clock->hw); in rzg2l_cpg_register_mod_clk()
1397 clk = ERR_PTR(ret); in rzg2l_cpg_register_mod_clk()
1401 clk = clock->hw.clk; in rzg2l_cpg_register_mod_clk()
1402 dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); in rzg2l_cpg_register_mod_clk()
1403 priv->clks[id] = clk; in rzg2l_cpg_register_mod_clk()
1405 if (mod->is_coupled) { in rzg2l_cpg_register_mod_clk()
1408 clock->enabled = rzg2l_mod_clock_is_enabled(&clock->hw); in rzg2l_cpg_register_mod_clk()
1411 clock->sibling = sibling; in rzg2l_cpg_register_mod_clk()
1412 sibling->sibling = clock; in rzg2l_cpg_register_mod_clk()
1420 mod->name, PTR_ERR(clk)); in rzg2l_cpg_register_mod_clk()
1429 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_assert()
1430 unsigned int reg = info->resets[id].off; in rzg2l_cpg_assert()
1431 u32 mask = BIT(info->resets[id].bit); in rzg2l_cpg_assert()
1432 s8 monbit = info->resets[id].monbit; in rzg2l_cpg_assert()
1435 dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); in rzg2l_cpg_assert()
1437 writel(value, priv->base + CLK_RST_R(reg)); in rzg2l_cpg_assert()
1439 if (info->has_clk_mon_regs) { in rzg2l_cpg_assert()
1450 return readl_poll_timeout_atomic(priv->base + reg, value, in rzg2l_cpg_assert()
1458 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_deassert()
1459 unsigned int reg = info->resets[id].off; in rzg2l_cpg_deassert()
1460 u32 mask = BIT(info->resets[id].bit); in rzg2l_cpg_deassert()
1461 s8 monbit = info->resets[id].monbit; in rzg2l_cpg_deassert()
1464 dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id, in rzg2l_cpg_deassert()
1467 writel(value, priv->base + CLK_RST_R(reg)); in rzg2l_cpg_deassert()
1469 if (info->has_clk_mon_regs) { in rzg2l_cpg_deassert()
1480 return readl_poll_timeout_atomic(priv->base + reg, value, in rzg2l_cpg_deassert()
1500 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_status()
1501 s8 monbit = info->resets[id].monbit; in rzg2l_cpg_status()
1505 if (info->has_clk_mon_regs) { in rzg2l_cpg_status()
1506 reg = CLK_MRST_R(info->resets[id].off); in rzg2l_cpg_status()
1507 bitmask = BIT(info->resets[id].bit); in rzg2l_cpg_status()
1512 return -ENOTSUPP; in rzg2l_cpg_status()
1515 return !!(readl(priv->base + reg) & bitmask); in rzg2l_cpg_status()
1529 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_reset_xlate()
1530 unsigned int id = reset_spec->args[0]; in rzg2l_cpg_reset_xlate()
1532 if (id >= rcdev->nr_resets || !info->resets[id].off) { in rzg2l_cpg_reset_xlate()
1533 dev_err(rcdev->dev, "Invalid reset index %u\n", id); in rzg2l_cpg_reset_xlate()
1534 return -EINVAL; in rzg2l_cpg_reset_xlate()
1542 priv->rcdev.ops = &rzg2l_cpg_reset_ops; in rzg2l_cpg_reset_controller_register()
1543 priv->rcdev.of_node = priv->dev->of_node; in rzg2l_cpg_reset_controller_register()
1544 priv->rcdev.dev = priv->dev; in rzg2l_cpg_reset_controller_register()
1545 priv->rcdev.of_reset_n_cells = 1; in rzg2l_cpg_reset_controller_register()
1546 priv->rcdev.of_xlate = rzg2l_cpg_reset_xlate; in rzg2l_cpg_reset_controller_register()
1547 priv->rcdev.nr_resets = priv->num_resets; in rzg2l_cpg_reset_controller_register()
1549 return devm_reset_controller_register(priv->dev, &priv->rcdev); in rzg2l_cpg_reset_controller_register()
1555 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_is_pm_clk()
1559 if (clkspec->args_count != 2) in rzg2l_cpg_is_pm_clk()
1562 if (clkspec->args[0] != CPG_MOD) in rzg2l_cpg_is_pm_clk()
1565 id = clkspec->args[1] + info->num_total_core_clks; in rzg2l_cpg_is_pm_clk()
1566 for (i = 0; i < info->num_no_pm_mod_clks; i++) { in rzg2l_cpg_is_pm_clk()
1567 if (info->no_pm_mod_clks[i] == id) in rzg2l_cpg_is_pm_clk()
1575 * struct rzg2l_cpg_pm_domains - RZ/G2L PM domains data structure
1585 * struct rzg2l_cpg_pd - RZ/G2L power domain data structure
1601 struct rzg2l_cpg_priv *priv = pd->priv; in rzg2l_cpg_attach_dev()
1602 struct device_node *np = dev->of_node; in rzg2l_cpg_attach_dev()
1605 struct clk *clk; in rzg2l_cpg_attach_dev() local
1609 while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, in rzg2l_cpg_attach_dev()
1620 clk = of_clk_get_from_provider(&clkspec); in rzg2l_cpg_attach_dev()
1622 if (IS_ERR(clk)) { in rzg2l_cpg_attach_dev()
1623 error = PTR_ERR(clk); in rzg2l_cpg_attach_dev()
1627 error = pm_clk_add_clk(dev, clk); in rzg2l_cpg_attach_dev()
1642 clk_put(clk); in rzg2l_cpg_attach_dev()
1660 for (unsigned int i = 0; i < celldata->num_domains; i++) in rzg2l_cpg_genpd_remove()
1661 pm_genpd_remove(celldata->domains[i]); in rzg2l_cpg_genpd_remove()
1672 struct rzg2l_cpg_reg_conf mstop = pd->conf.mstop; in rzg2l_cpg_power_on()
1673 struct rzg2l_cpg_priv *priv = pd->priv; in rzg2l_cpg_power_on()
1677 writel(mstop.mask << 16, priv->base + mstop.off); in rzg2l_cpg_power_on()
1685 struct rzg2l_cpg_reg_conf mstop = pd->conf.mstop; in rzg2l_cpg_power_off()
1686 struct rzg2l_cpg_priv *priv = pd->priv; in rzg2l_cpg_power_off()
1690 writel(mstop.mask | (mstop.mask << 16), priv->base + mstop.off); in rzg2l_cpg_power_off()
1697 bool always_on = !!(pd->genpd.flags & GENPD_FLAG_ALWAYS_ON); in rzg2l_cpg_pd_setup()
1706 pd->genpd.flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP; in rzg2l_cpg_pd_setup()
1707 pd->genpd.attach_dev = rzg2l_cpg_attach_dev; in rzg2l_cpg_pd_setup()
1708 pd->genpd.detach_dev = rzg2l_cpg_detach_dev; in rzg2l_cpg_pd_setup()
1709 pd->genpd.power_on = rzg2l_cpg_power_on; in rzg2l_cpg_pd_setup()
1710 pd->genpd.power_off = rzg2l_cpg_power_off; in rzg2l_cpg_pd_setup()
1712 ret = pm_genpd_init(&pd->genpd, governor, !always_on); in rzg2l_cpg_pd_setup()
1717 ret = rzg2l_cpg_power_on(&pd->genpd); in rzg2l_cpg_pd_setup()
1724 struct device *dev = priv->dev; in rzg2l_cpg_add_clk_domain()
1725 struct device_node *np = dev->of_node; in rzg2l_cpg_add_clk_domain()
1731 return -ENOMEM; in rzg2l_cpg_add_clk_domain()
1733 pd->genpd.name = np->name; in rzg2l_cpg_add_clk_domain()
1734 pd->genpd.flags = GENPD_FLAG_ALWAYS_ON; in rzg2l_cpg_add_clk_domain()
1735 pd->priv = priv; in rzg2l_cpg_add_clk_domain()
1740 ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove_simple, &pd->genpd); in rzg2l_cpg_add_clk_domain()
1744 return of_genpd_add_provider_simple(np, &pd->genpd); in rzg2l_cpg_add_clk_domain()
1750 struct generic_pm_domain *domain = ERR_PTR(-ENOENT); in rzg2l_cpg_pm_domain_xlate()
1753 if (spec->args_count != 1) in rzg2l_cpg_pm_domain_xlate()
1754 return ERR_PTR(-EINVAL); in rzg2l_cpg_pm_domain_xlate()
1756 for (unsigned int i = 0; i < genpd->num_domains; i++) { in rzg2l_cpg_pm_domain_xlate()
1757 struct rzg2l_cpg_pd *pd = container_of(genpd->domains[i], struct rzg2l_cpg_pd, in rzg2l_cpg_pm_domain_xlate()
1760 if (pd->id == spec->args[0]) { in rzg2l_cpg_pm_domain_xlate()
1761 domain = &pd->genpd; in rzg2l_cpg_pm_domain_xlate()
1771 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_add_pm_domains()
1772 struct device *dev = priv->dev; in rzg2l_cpg_add_pm_domains()
1773 struct device_node *np = dev->of_node; in rzg2l_cpg_add_pm_domains()
1779 ret = of_property_read_u32(np, "#power-domain-cells", &ncells); in rzg2l_cpg_add_pm_domains()
1787 domains = devm_kzalloc(dev, struct_size(domains, domains, info->num_pm_domains), in rzg2l_cpg_add_pm_domains()
1790 return -ENOMEM; in rzg2l_cpg_add_pm_domains()
1792 domains->onecell_data.domains = domains->domains; in rzg2l_cpg_add_pm_domains()
1793 domains->onecell_data.num_domains = info->num_pm_domains; in rzg2l_cpg_add_pm_domains()
1794 domains->onecell_data.xlate = rzg2l_cpg_pm_domain_xlate; in rzg2l_cpg_add_pm_domains()
1796 ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove, &domains->onecell_data); in rzg2l_cpg_add_pm_domains()
1800 for (unsigned int i = 0; i < info->num_pm_domains; i++) { in rzg2l_cpg_add_pm_domains()
1805 return -ENOMEM; in rzg2l_cpg_add_pm_domains()
1807 pd->genpd.name = info->pm_domains[i].name; in rzg2l_cpg_add_pm_domains()
1808 pd->genpd.flags = info->pm_domains[i].genpd_flags; in rzg2l_cpg_add_pm_domains()
1809 pd->conf = info->pm_domains[i].conf; in rzg2l_cpg_add_pm_domains()
1810 pd->id = info->pm_domains[i].id; in rzg2l_cpg_add_pm_domains()
1811 pd->priv = priv; in rzg2l_cpg_add_pm_domains()
1817 domains->domains[i] = &pd->genpd; in rzg2l_cpg_add_pm_domains()
1818 /* Parent should be on the very first entry of info->pm_domains[]. */ in rzg2l_cpg_add_pm_domains()
1820 parent = &pd->genpd; in rzg2l_cpg_add_pm_domains()
1824 ret = pm_genpd_add_subdomain(parent, &pd->genpd); in rzg2l_cpg_add_pm_domains()
1829 ret = of_genpd_add_provider_onecell(np, &domains->onecell_data); in rzg2l_cpg_add_pm_domains()
1838 struct device *dev = &pdev->dev; in rzg2l_cpg_probe()
1839 struct device_node *np = dev->of_node; in rzg2l_cpg_probe()
1843 struct clk **clks; in rzg2l_cpg_probe()
1850 return -ENOMEM; in rzg2l_cpg_probe()
1852 priv->dev = dev; in rzg2l_cpg_probe()
1853 priv->info = info; in rzg2l_cpg_probe()
1854 spin_lock_init(&priv->rmw_lock); in rzg2l_cpg_probe()
1856 priv->base = devm_platform_ioremap_resource(pdev, 0); in rzg2l_cpg_probe()
1857 if (IS_ERR(priv->base)) in rzg2l_cpg_probe()
1858 return PTR_ERR(priv->base); in rzg2l_cpg_probe()
1860 nclks = info->num_total_core_clks + info->num_hw_mod_clks; in rzg2l_cpg_probe()
1863 return -ENOMEM; in rzg2l_cpg_probe()
1866 priv->clks = clks; in rzg2l_cpg_probe()
1867 priv->num_core_clks = info->num_total_core_clks; in rzg2l_cpg_probe()
1868 priv->num_mod_clks = info->num_hw_mod_clks; in rzg2l_cpg_probe()
1869 priv->num_resets = info->num_resets; in rzg2l_cpg_probe()
1870 priv->last_dt_core_clk = info->last_dt_core_clk; in rzg2l_cpg_probe()
1873 clks[i] = ERR_PTR(-ENOENT); in rzg2l_cpg_probe()
1875 for (i = 0; i < info->num_core_clks; i++) in rzg2l_cpg_probe()
1876 rzg2l_cpg_register_core_clk(&info->core_clks[i], info, priv); in rzg2l_cpg_probe()
1878 for (i = 0; i < info->num_mod_clks; i++) in rzg2l_cpg_probe()
1879 rzg2l_cpg_register_mod_clk(&info->mod_clks[i], info, priv); in rzg2l_cpg_probe()
1903 .compatible = "renesas,r9a07g043-cpg",
1909 .compatible = "renesas,r9a07g044-cpg",
1915 .compatible = "renesas,r9a07g054-cpg",
1921 .compatible = "renesas,r9a08g045-cpg",
1927 .compatible = "renesas,r9a09g011-cpg",
1936 .name = "rzg2l-cpg",