Lines Matching +full:src +full:- +full:ref +full:- +full:clk +full:- +full:mhz

1 // SPDX-License-Identifier: GPL-2.0
7 * Based on renesas-cpg-mssr.c
17 #include <linux/clk.h>
18 #include <linux/clk-provider.h>
19 #include <linux/clk/renesas.h>
31 #include <linux/reset-controller.h>
36 #include <dt-bindings/clock/renesas-cpg-mssr.h>
38 #include "rzg2l-cpg.h"
78 * struct clk_hw_data - clock hardware data
94 * struct sd_mux_hw_data - SD MUX clock hardware data
106 * struct div_hw_data - divider clock hardware data
139 * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data
148 * @num_resets: Number of Module Resets in info->resets[]
160 struct clk **clks;
181 u32 bitmask = GENMASK(GET_WIDTH(conf) - 1, 0) << GET_SHIFT(conf); in rzg2l_cpg_wait_clk_update_done()
192 struct clk_hw *hw = __clk_get_hw(cnd->clk); in rzg2l_cpg_sd_clk_mux_notifier()
194 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg2l_cpg_sd_clk_mux_notifier()
195 u32 off = GET_REG_OFFSET(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_notifier()
196 u32 shift = GET_SHIFT(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_notifier()
201 if (event != PRE_RATE_CHANGE || (cnd->new_rate / MEGA == 266)) in rzg2l_cpg_sd_clk_mux_notifier()
204 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg2l_cpg_sd_clk_mux_notifier()
207 * As per the HW manual, we should not directly switch from 533 MHz to in rzg2l_cpg_sd_clk_mux_notifier()
208 * 400 MHz and vice versa. To change the setting from 2’b01 (533 MHz) in rzg2l_cpg_sd_clk_mux_notifier()
209 * to 2’b10 (400 MHz) or vice versa, Switch to 2’b11 (266 MHz) first, in rzg2l_cpg_sd_clk_mux_notifier()
210 * and then switch to the target setting (2’b01 (533 MHz) or 2’b10 in rzg2l_cpg_sd_clk_mux_notifier()
211 * (400 MHz)). in rzg2l_cpg_sd_clk_mux_notifier()
214 * The clock mux has 3 input clocks(533 MHz, 400 MHz, and 266 MHz), and in rzg2l_cpg_sd_clk_mux_notifier()
218 writel((CPG_WEN_BIT | clk_src_266) << shift, priv->base + off); in rzg2l_cpg_sd_clk_mux_notifier()
221 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); in rzg2l_cpg_sd_clk_mux_notifier()
223 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg2l_cpg_sd_clk_mux_notifier()
226 dev_err(priv->dev, "failed to switch to safe clk source\n"); in rzg2l_cpg_sd_clk_mux_notifier()
235 struct clk_hw *hw = __clk_get_hw(cnd->clk); in rzg3s_cpg_div_clk_notifier()
238 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg3s_cpg_div_clk_notifier()
239 u32 off = GET_REG_OFFSET(clk_hw_data->conf); in rzg3s_cpg_div_clk_notifier()
240 u32 shift = GET_SHIFT(clk_hw_data->conf); in rzg3s_cpg_div_clk_notifier()
245 if (event != PRE_RATE_CHANGE || !div_hw_data->invalid_rate || in rzg3s_cpg_div_clk_notifier()
246 div_hw_data->invalid_rate % cnd->new_rate) in rzg3s_cpg_div_clk_notifier()
249 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg3s_cpg_div_clk_notifier()
251 val = readl(priv->base + off); in rzg3s_cpg_div_clk_notifier()
253 val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0); in rzg3s_cpg_div_clk_notifier()
257 * 1/ SD div cannot be 1 (val == 0) if parent rate is 800MHz in rzg3s_cpg_div_clk_notifier()
258 * 2/ OCTA / SPI div cannot be 1 (val == 0) if parent rate is 400MHz in rzg3s_cpg_div_clk_notifier()
259 * As SD can have only one parent having 800MHz and OCTA div can have in rzg3s_cpg_div_clk_notifier()
260 * only one parent having 400MHz we took into account the parent rate in rzg3s_cpg_div_clk_notifier()
265 writel((CPG_WEN_BIT | 1) << shift, priv->base + off); in rzg3s_cpg_div_clk_notifier()
267 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); in rzg3s_cpg_div_clk_notifier()
270 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg3s_cpg_div_clk_notifier()
273 dev_err(priv->dev, "Failed to downgrade the div\n"); in rzg3s_cpg_div_clk_notifier()
283 if (!core->notifier) in rzg2l_register_notifier()
286 nb = devm_kzalloc(priv->dev, sizeof(*nb), GFP_KERNEL); in rzg2l_register_notifier()
288 return -ENOMEM; in rzg2l_register_notifier()
290 nb->notifier_call = core->notifier; in rzg2l_register_notifier()
292 return clk_notifier_register(hw->clk, nb); in rzg2l_register_notifier()
300 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg3s_div_clk_recalc_rate()
303 val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf)); in rzg3s_div_clk_recalc_rate()
304 val >>= GET_SHIFT(clk_hw_data->conf); in rzg3s_div_clk_recalc_rate()
305 val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0); in rzg3s_div_clk_recalc_rate()
307 return divider_recalc_rate(hw, parent_rate, val, div_hw_data->dtable, in rzg3s_div_clk_recalc_rate()
308 CLK_DIVIDER_ROUND_CLOSEST, div_hw_data->width); in rzg3s_div_clk_recalc_rate()
316 if (div_hw_data->max_rate && req->rate > div_hw_data->max_rate) in rzg3s_div_clk_determine_rate()
317 req->rate = div_hw_data->max_rate; in rzg3s_div_clk_determine_rate()
319 return divider_determine_rate(hw, req, div_hw_data->dtable, div_hw_data->width, in rzg3s_div_clk_determine_rate()
328 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg3s_div_clk_set_rate()
329 u32 off = GET_REG_OFFSET(clk_hw_data->conf); in rzg3s_div_clk_set_rate()
330 u32 shift = GET_SHIFT(clk_hw_data->conf); in rzg3s_div_clk_set_rate()
335 val = divider_get_val(rate, parent_rate, div_hw_data->dtable, div_hw_data->width, in rzg3s_div_clk_set_rate()
338 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg3s_div_clk_set_rate()
339 writel((CPG_WEN_BIT | val) << shift, priv->base + off); in rzg3s_div_clk_set_rate()
341 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); in rzg3s_div_clk_set_rate()
342 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg3s_div_clk_set_rate()
353 static struct clk * __init
360 const struct clk *parent; in rzg3s_cpg_div_clk_register()
365 parent = priv->clks[core->parent]; in rzg3s_cpg_div_clk_register()
371 div_hw_data = devm_kzalloc(priv->dev, sizeof(*div_hw_data), GFP_KERNEL); in rzg3s_cpg_div_clk_register()
373 return ERR_PTR(-ENOMEM); in rzg3s_cpg_div_clk_register()
375 init.name = core->name; in rzg3s_cpg_div_clk_register()
376 init.flags = core->flag; in rzg3s_cpg_div_clk_register()
382 for (clkt = core->dtable; clkt->div; clkt++) { in rzg3s_cpg_div_clk_register()
383 if (max < clkt->div) in rzg3s_cpg_div_clk_register()
384 max = clkt->div; in rzg3s_cpg_div_clk_register()
387 div_hw_data->hw_data.priv = priv; in rzg3s_cpg_div_clk_register()
388 div_hw_data->hw_data.conf = core->conf; in rzg3s_cpg_div_clk_register()
389 div_hw_data->hw_data.sconf = core->sconf; in rzg3s_cpg_div_clk_register()
390 div_hw_data->dtable = core->dtable; in rzg3s_cpg_div_clk_register()
391 div_hw_data->invalid_rate = core->invalid_rate; in rzg3s_cpg_div_clk_register()
392 div_hw_data->max_rate = core->max_rate; in rzg3s_cpg_div_clk_register()
393 div_hw_data->width = fls(max) - 1; in rzg3s_cpg_div_clk_register()
395 clk_hw = &div_hw_data->hw_data.hw; in rzg3s_cpg_div_clk_register()
396 clk_hw->init = &init; in rzg3s_cpg_div_clk_register()
398 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg3s_cpg_div_clk_register()
404 dev_err(priv->dev, "Failed to register notifier for %s\n", in rzg3s_cpg_div_clk_register()
405 core->name); in rzg3s_cpg_div_clk_register()
409 return clk_hw->clk; in rzg3s_cpg_div_clk_register()
412 static struct clk * __init
416 void __iomem *base = priv->base; in rzg2l_cpg_div_clk_register()
417 struct device *dev = priv->dev; in rzg2l_cpg_div_clk_register()
418 const struct clk *parent; in rzg2l_cpg_div_clk_register()
422 parent = priv->clks[core->parent]; in rzg2l_cpg_div_clk_register()
428 if (core->dtable) in rzg2l_cpg_div_clk_register()
429 clk_hw = clk_hw_register_divider_table(dev, core->name, in rzg2l_cpg_div_clk_register()
431 base + GET_REG_OFFSET(core->conf), in rzg2l_cpg_div_clk_register()
432 GET_SHIFT(core->conf), in rzg2l_cpg_div_clk_register()
433 GET_WIDTH(core->conf), in rzg2l_cpg_div_clk_register()
434 core->flag, in rzg2l_cpg_div_clk_register()
435 core->dtable, in rzg2l_cpg_div_clk_register()
436 &priv->rmw_lock); in rzg2l_cpg_div_clk_register()
438 clk_hw = clk_hw_register_divider(dev, core->name, in rzg2l_cpg_div_clk_register()
440 base + GET_REG_OFFSET(core->conf), in rzg2l_cpg_div_clk_register()
441 GET_SHIFT(core->conf), in rzg2l_cpg_div_clk_register()
442 GET_WIDTH(core->conf), in rzg2l_cpg_div_clk_register()
443 core->flag, &priv->rmw_lock); in rzg2l_cpg_div_clk_register()
448 return clk_hw->clk; in rzg2l_cpg_div_clk_register()
451 static struct clk * __init
457 clk_hw = devm_clk_hw_register_mux(priv->dev, core->name, in rzg2l_cpg_mux_clk_register()
458 core->parent_names, core->num_parents, in rzg2l_cpg_mux_clk_register()
459 core->flag, in rzg2l_cpg_mux_clk_register()
460 priv->base + GET_REG_OFFSET(core->conf), in rzg2l_cpg_mux_clk_register()
461 GET_SHIFT(core->conf), in rzg2l_cpg_mux_clk_register()
462 GET_WIDTH(core->conf), in rzg2l_cpg_mux_clk_register()
463 core->mux_flags, &priv->rmw_lock); in rzg2l_cpg_mux_clk_register()
467 return clk_hw->clk; in rzg2l_cpg_mux_clk_register()
474 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg2l_cpg_sd_clk_mux_set_parent()
475 u32 off = GET_REG_OFFSET(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_set_parent()
476 u32 shift = GET_SHIFT(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_set_parent()
481 val = clk_mux_index_to_val(sd_mux_hw_data->mtable, CLK_MUX_ROUND_CLOSEST, index); in rzg2l_cpg_sd_clk_mux_set_parent()
483 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg2l_cpg_sd_clk_mux_set_parent()
485 writel((CPG_WEN_BIT | val) << shift, priv->base + off); in rzg2l_cpg_sd_clk_mux_set_parent()
488 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf); in rzg2l_cpg_sd_clk_mux_set_parent()
490 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg2l_cpg_sd_clk_mux_set_parent()
493 dev_err(priv->dev, "Failed to switch parent\n"); in rzg2l_cpg_sd_clk_mux_set_parent()
502 struct rzg2l_cpg_priv *priv = clk_hw_data->priv; in rzg2l_cpg_sd_clk_mux_get_parent()
505 val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf)); in rzg2l_cpg_sd_clk_mux_get_parent()
506 val >>= GET_SHIFT(clk_hw_data->conf); in rzg2l_cpg_sd_clk_mux_get_parent()
507 val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0); in rzg2l_cpg_sd_clk_mux_get_parent()
509 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()
518 static struct clk * __init
527 sd_mux_hw_data = devm_kzalloc(priv->dev, sizeof(*sd_mux_hw_data), GFP_KERNEL); in rzg2l_cpg_sd_mux_clk_register()
529 return ERR_PTR(-ENOMEM); in rzg2l_cpg_sd_mux_clk_register()
531 sd_mux_hw_data->hw_data.priv = priv; in rzg2l_cpg_sd_mux_clk_register()
532 sd_mux_hw_data->hw_data.conf = core->conf; in rzg2l_cpg_sd_mux_clk_register()
533 sd_mux_hw_data->hw_data.sconf = core->sconf; in rzg2l_cpg_sd_mux_clk_register()
534 sd_mux_hw_data->mtable = core->mtable; in rzg2l_cpg_sd_mux_clk_register()
536 init.name = core->name; in rzg2l_cpg_sd_mux_clk_register()
538 init.flags = core->flag; in rzg2l_cpg_sd_mux_clk_register()
539 init.num_parents = core->num_parents; in rzg2l_cpg_sd_mux_clk_register()
540 init.parent_names = core->parent_names; in rzg2l_cpg_sd_mux_clk_register()
542 clk_hw = &sd_mux_hw_data->hw_data.hw; in rzg2l_cpg_sd_mux_clk_register()
543 clk_hw->init = &init; in rzg2l_cpg_sd_mux_clk_register()
545 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg2l_cpg_sd_mux_clk_register()
551 dev_err(priv->dev, "Failed to register notifier for %s\n", in rzg2l_cpg_sd_mux_clk_register()
552 core->name); in rzg2l_cpg_sd_mux_clk_register()
556 return clk_hw->clk; in rzg2l_cpg_sd_mux_clk_register()
565 params->pl5_intin = rate / MEGA; in rzg2l_cpg_get_foutpostdiv_rate()
566 params->pl5_fracin = div_u64(((u64)rate % MEGA) << 24, MEGA); in rzg2l_cpg_get_foutpostdiv_rate()
567 params->pl5_refdiv = 2; in rzg2l_cpg_get_foutpostdiv_rate()
568 params->pl5_postdiv1 = 1; in rzg2l_cpg_get_foutpostdiv_rate()
569 params->pl5_postdiv2 = 1; in rzg2l_cpg_get_foutpostdiv_rate()
570 params->pl5_spread = 0x16; in rzg2l_cpg_get_foutpostdiv_rate()
573 (params->pl5_intin << 24) + params->pl5_fracin), in rzg2l_cpg_get_foutpostdiv_rate()
574 params->pl5_refdiv) >> 24; in rzg2l_cpg_get_foutpostdiv_rate()
576 params->pl5_postdiv1 * params->pl5_postdiv2); in rzg2l_cpg_get_foutpostdiv_rate()
594 unsigned long rate = dsi_div->rate; in rzg2l_cpg_dsi_div_recalc_rate()
606 struct rzg2l_cpg_priv *priv = dsi_div->priv; in rzg2l_cpg_get_vclk_parent_rate()
612 if (priv->mux_dsi_div_params.clksrc) in rzg2l_cpg_get_vclk_parent_rate()
621 if (req->rate > MAX_VCLK_FREQ) in rzg2l_cpg_dsi_div_determine_rate()
622 req->rate = MAX_VCLK_FREQ; in rzg2l_cpg_dsi_div_determine_rate()
624 req->best_parent_rate = rzg2l_cpg_get_vclk_parent_rate(hw, req->rate); in rzg2l_cpg_dsi_div_determine_rate()
634 struct rzg2l_cpg_priv *priv = dsi_div->priv; in rzg2l_cpg_dsi_div_set_rate()
637 * MUX -->DIV_DSI_{A,B} -->M3 -->VCLK in rzg2l_cpg_dsi_div_set_rate()
640 * calculates the pll parameters for generating FOUTPOSTDIV and the clk in rzg2l_cpg_dsi_div_set_rate()
645 return -EINVAL; in rzg2l_cpg_dsi_div_set_rate()
647 dsi_div->rate = rate; in rzg2l_cpg_dsi_div_set_rate()
649 (priv->mux_dsi_div_params.dsi_div_a << 0) | in rzg2l_cpg_dsi_div_set_rate()
650 (priv->mux_dsi_div_params.dsi_div_b << 8), in rzg2l_cpg_dsi_div_set_rate()
651 priv->base + CPG_PL5_SDIV); in rzg2l_cpg_dsi_div_set_rate()
662 static struct clk * __init
667 const struct clk *parent; in rzg2l_cpg_dsi_div_clk_register()
673 parent = priv->clks[core->parent]; in rzg2l_cpg_dsi_div_clk_register()
677 clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL); in rzg2l_cpg_dsi_div_clk_register()
679 return ERR_PTR(-ENOMEM); in rzg2l_cpg_dsi_div_clk_register()
681 clk_hw_data->priv = priv; in rzg2l_cpg_dsi_div_clk_register()
684 init.name = core->name; in rzg2l_cpg_dsi_div_clk_register()
690 clk_hw = &clk_hw_data->hw; in rzg2l_cpg_dsi_div_clk_register()
691 clk_hw->init = &init; in rzg2l_cpg_dsi_div_clk_register()
693 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg2l_cpg_dsi_div_clk_register()
697 return clk_hw->clk; in rzg2l_cpg_dsi_div_clk_register()
714 struct rzg2l_cpg_priv *priv = hwdata->priv; in rzg2l_cpg_pll5_4_clk_mux_determine_rate()
716 parent = clk_hw_get_parent_by_index(hw, priv->mux_dsi_div_params.clksrc); in rzg2l_cpg_pll5_4_clk_mux_determine_rate()
717 req->best_parent_hw = parent; in rzg2l_cpg_pll5_4_clk_mux_determine_rate()
718 req->best_parent_rate = req->rate; in rzg2l_cpg_pll5_4_clk_mux_determine_rate()
726 struct rzg2l_cpg_priv *priv = hwdata->priv; in rzg2l_cpg_pll5_4_clk_mux_set_parent()
729 * FOUTPOSTDIV--->| in rzg2l_cpg_pll5_4_clk_mux_set_parent()
730 * | | -->MUX -->DIV_DSIA_B -->M3 -->VCLK in rzg2l_cpg_pll5_4_clk_mux_set_parent()
731 * |--FOUT1PH0-->| in rzg2l_cpg_pll5_4_clk_mux_set_parent()
734 * rate and clk source for the MUX. It propagates that info to in rzg2l_cpg_pll5_4_clk_mux_set_parent()
739 priv->base + CPG_OTHERFUNC1_REG); in rzg2l_cpg_pll5_4_clk_mux_set_parent()
747 struct rzg2l_cpg_priv *priv = hwdata->priv; in rzg2l_cpg_pll5_4_clk_mux_get_parent()
749 return readl(priv->base + GET_REG_OFFSET(hwdata->conf)); in rzg2l_cpg_pll5_4_clk_mux_get_parent()
758 static struct clk * __init
767 clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL); in rzg2l_cpg_pll5_4_mux_clk_register()
769 return ERR_PTR(-ENOMEM); in rzg2l_cpg_pll5_4_mux_clk_register()
771 clk_hw_data->priv = priv; in rzg2l_cpg_pll5_4_mux_clk_register()
772 clk_hw_data->conf = core->conf; in rzg2l_cpg_pll5_4_mux_clk_register()
774 init.name = core->name; in rzg2l_cpg_pll5_4_mux_clk_register()
777 init.num_parents = core->num_parents; in rzg2l_cpg_pll5_4_mux_clk_register()
778 init.parent_names = core->parent_names; in rzg2l_cpg_pll5_4_mux_clk_register()
780 clk_hw = &clk_hw_data->hw; in rzg2l_cpg_pll5_4_mux_clk_register()
781 clk_hw->init = &init; in rzg2l_cpg_pll5_4_mux_clk_register()
783 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg2l_cpg_pll5_4_mux_clk_register()
787 return clk_hw->clk; in rzg2l_cpg_pll5_4_mux_clk_register()
803 struct rzg2l_cpg_priv *priv = sipll5->priv; in rzg2l_cpg_get_vclk_rate()
806 vclk = rate / ((1 << priv->mux_dsi_div_params.dsi_div_a) * in rzg2l_cpg_get_vclk_rate()
807 (priv->mux_dsi_div_params.dsi_div_b + 1)); in rzg2l_cpg_get_vclk_rate()
809 if (priv->mux_dsi_div_params.clksrc) in rzg2l_cpg_get_vclk_rate()
819 unsigned long pll5_rate = sipll5->foutpostdiv_rate; in rzg2l_cpg_sipll5_recalc_rate()
838 struct rzg2l_cpg_priv *priv = sipll5->priv; in rzg2l_cpg_sipll5_set_rate()
845 * OSC --> PLL5 --> FOUTPOSTDIV-->| in rzg2l_cpg_sipll5_set_rate()
846 * | | -->MUX -->DIV_DSIA_B -->M3 -->VCLK in rzg2l_cpg_sipll5_set_rate()
847 * |--FOUT1PH0-->| in rzg2l_cpg_sipll5_set_rate()
853 * OSC --> PLL5 --> FOUTPOSTDIV in rzg2l_cpg_sipll5_set_rate()
857 return -EINVAL; in rzg2l_cpg_sipll5_set_rate()
860 sipll5->foutpostdiv_rate = in rzg2l_cpg_sipll5_set_rate()
864 writel(CPG_SIPLL5_STBY_RESETB_WEN, priv->base + CPG_SIPLL5_STBY); in rzg2l_cpg_sipll5_set_rate()
865 ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val, in rzg2l_cpg_sipll5_set_rate()
868 dev_err(priv->dev, "failed to release pll5 lock"); in rzg2l_cpg_sipll5_set_rate()
874 (params.pl5_refdiv << 8), priv->base + CPG_SIPLL5_CLK1); in rzg2l_cpg_sipll5_set_rate()
877 writel((params.pl5_fracin << 8), priv->base + CPG_SIPLL5_CLK3); in rzg2l_cpg_sipll5_set_rate()
881 priv->base + CPG_SIPLL5_CLK4); in rzg2l_cpg_sipll5_set_rate()
884 writel(params.pl5_spread, priv->base + CPG_SIPLL5_CLK5); in rzg2l_cpg_sipll5_set_rate()
889 priv->base + CPG_SIPLL5_STBY); in rzg2l_cpg_sipll5_set_rate()
892 ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val, in rzg2l_cpg_sipll5_set_rate()
895 dev_err(priv->dev, "failed to lock pll5"); in rzg2l_cpg_sipll5_set_rate()
908 static struct clk * __init
912 const struct clk *parent; in rzg2l_cpg_sipll5_register()
919 parent = priv->clks[core->parent]; in rzg2l_cpg_sipll5_register()
923 sipll5 = devm_kzalloc(priv->dev, sizeof(*sipll5), GFP_KERNEL); in rzg2l_cpg_sipll5_register()
925 return ERR_PTR(-ENOMEM); in rzg2l_cpg_sipll5_register()
927 init.name = core->name; in rzg2l_cpg_sipll5_register()
934 sipll5->hw.init = &init; in rzg2l_cpg_sipll5_register()
935 sipll5->conf = core->conf; in rzg2l_cpg_sipll5_register()
936 sipll5->priv = priv; in rzg2l_cpg_sipll5_register()
939 CPG_SIPLL5_STBY_RESETB, priv->base + CPG_SIPLL5_STBY); in rzg2l_cpg_sipll5_register()
941 clk_hw = &sipll5->hw; in rzg2l_cpg_sipll5_register()
942 clk_hw->init = &init; in rzg2l_cpg_sipll5_register()
944 ret = devm_clk_hw_register(priv->dev, clk_hw); in rzg2l_cpg_sipll5_register()
948 priv->mux_dsi_div_params.clksrc = 1; /* Use clk src 1 for DSI */ in rzg2l_cpg_sipll5_register()
949 priv->mux_dsi_div_params.dsi_div_a = 1; /* Divided by 2 */ in rzg2l_cpg_sipll5_register()
950 priv->mux_dsi_div_params.dsi_div_b = 2; /* Divided by 3 */ in rzg2l_cpg_sipll5_register()
952 return clk_hw->clk; in rzg2l_cpg_sipll5_register()
970 struct rzg2l_cpg_priv *priv = pll_clk->priv; in rzg2l_cpg_pll_clk_recalc_rate()
974 if (pll_clk->type != CLK_TYPE_SAM_PLL) in rzg2l_cpg_pll_clk_recalc_rate()
977 val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); in rzg2l_cpg_pll_clk_recalc_rate()
978 val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf)); in rzg2l_cpg_pll_clk_recalc_rate()
994 struct rzg2l_cpg_priv *priv = pll_clk->priv; in rzg3s_cpg_pll_clk_recalc_rate()
998 if (pll_clk->type != CLK_TYPE_G3S_PLL) in rzg3s_cpg_pll_clk_recalc_rate()
1001 setting = GET_REG_SAMPLL_SETTING(pll_clk->conf); in rzg3s_cpg_pll_clk_recalc_rate()
1003 val = readl(priv->base + setting); in rzg3s_cpg_pll_clk_recalc_rate()
1005 return pll_clk->default_rate; in rzg3s_cpg_pll_clk_recalc_rate()
1008 val = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); in rzg3s_cpg_pll_clk_recalc_rate()
1028 static struct clk * __init
1033 struct device *dev = priv->dev; in rzg2l_cpg_pll_clk_register()
1034 const struct clk *parent; in rzg2l_cpg_pll_clk_register()
1040 parent = priv->clks[core->parent]; in rzg2l_cpg_pll_clk_register()
1046 return ERR_PTR(-ENOMEM); in rzg2l_cpg_pll_clk_register()
1049 init.name = core->name; in rzg2l_cpg_pll_clk_register()
1055 pll_clk->hw.init = &init; in rzg2l_cpg_pll_clk_register()
1056 pll_clk->conf = core->conf; in rzg2l_cpg_pll_clk_register()
1057 pll_clk->base = priv->base; in rzg2l_cpg_pll_clk_register()
1058 pll_clk->priv = priv; in rzg2l_cpg_pll_clk_register()
1059 pll_clk->type = core->type; in rzg2l_cpg_pll_clk_register()
1060 pll_clk->default_rate = core->default_rate; in rzg2l_cpg_pll_clk_register()
1062 ret = devm_clk_hw_register(dev, &pll_clk->hw); in rzg2l_cpg_pll_clk_register()
1066 return pll_clk->hw.clk; in rzg2l_cpg_pll_clk_register()
1069 static struct clk
1073 unsigned int clkidx = clkspec->args[1]; in rzg2l_cpg_clk_src_twocell_get()
1075 struct device *dev = priv->dev; in rzg2l_cpg_clk_src_twocell_get()
1077 struct clk *clk; in rzg2l_cpg_clk_src_twocell_get() local
1079 switch (clkspec->args[0]) { in rzg2l_cpg_clk_src_twocell_get()
1082 if (clkidx > priv->last_dt_core_clk) { in rzg2l_cpg_clk_src_twocell_get()
1084 return ERR_PTR(-EINVAL); in rzg2l_cpg_clk_src_twocell_get()
1086 clk = priv->clks[clkidx]; in rzg2l_cpg_clk_src_twocell_get()
1091 if (clkidx >= priv->num_mod_clks) { in rzg2l_cpg_clk_src_twocell_get()
1094 return ERR_PTR(-EINVAL); in rzg2l_cpg_clk_src_twocell_get()
1096 clk = priv->clks[priv->num_core_clks + clkidx]; in rzg2l_cpg_clk_src_twocell_get()
1100 dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]); in rzg2l_cpg_clk_src_twocell_get()
1101 return ERR_PTR(-EINVAL); in rzg2l_cpg_clk_src_twocell_get()
1104 if (IS_ERR(clk)) in rzg2l_cpg_clk_src_twocell_get()
1106 PTR_ERR(clk)); in rzg2l_cpg_clk_src_twocell_get()
1109 clkspec->args[0], clkspec->args[1], clk, in rzg2l_cpg_clk_src_twocell_get()
1110 clk_get_rate(clk)); in rzg2l_cpg_clk_src_twocell_get()
1111 return clk; in rzg2l_cpg_clk_src_twocell_get()
1119 struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent; in rzg2l_cpg_register_core_clk() local
1120 struct device *dev = priv->dev; in rzg2l_cpg_register_core_clk()
1121 unsigned int id = core->id, div = core->div; in rzg2l_cpg_register_core_clk()
1125 WARN_DEBUG(id >= priv->num_core_clks); in rzg2l_cpg_register_core_clk()
1126 WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); in rzg2l_cpg_register_core_clk()
1128 switch (core->type) { in rzg2l_cpg_register_core_clk()
1130 clk = of_clk_get_by_name(priv->dev->of_node, core->name); in rzg2l_cpg_register_core_clk()
1133 WARN_DEBUG(core->parent >= priv->num_core_clks); in rzg2l_cpg_register_core_clk()
1134 parent = priv->clks[core->parent]; in rzg2l_cpg_register_core_clk()
1136 clk = parent; in rzg2l_cpg_register_core_clk()
1141 clk_hw = devm_clk_hw_register_fixed_factor(dev, core->name, parent_name, in rzg2l_cpg_register_core_clk()
1143 core->mult, div); in rzg2l_cpg_register_core_clk()
1145 clk = ERR_CAST(clk_hw); in rzg2l_cpg_register_core_clk()
1147 clk = clk_hw->clk; in rzg2l_cpg_register_core_clk()
1150 clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg2l_cpg_pll_ops); in rzg2l_cpg_register_core_clk()
1153 clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg3s_cpg_pll_ops); in rzg2l_cpg_register_core_clk()
1156 clk = rzg2l_cpg_sipll5_register(core, priv); in rzg2l_cpg_register_core_clk()
1159 clk = rzg2l_cpg_div_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1162 clk = rzg3s_cpg_div_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1165 clk = rzg2l_cpg_mux_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1168 clk = rzg2l_cpg_sd_mux_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1171 clk = rzg2l_cpg_pll5_4_mux_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1174 clk = rzg2l_cpg_dsi_div_clk_register(core, priv); in rzg2l_cpg_register_core_clk()
1180 if (IS_ERR_OR_NULL(clk)) in rzg2l_cpg_register_core_clk()
1183 dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); in rzg2l_cpg_register_core_clk()
1184 priv->clks[id] = clk; in rzg2l_cpg_register_core_clk()
1189 core->name, PTR_ERR(clk)); in rzg2l_cpg_register_core_clk()
1193 * struct mstop - MSTOP specific data structure
1204 * struct mod_clock - Module clock
1206 * @hw: handle between common and hardware-specific interfaces
1231 for (unsigned int i = 0; (priv) && i < (priv)->num_mod_clks; i++) \
1232 if ((priv)->clks[(priv)->num_core_clks + i] == ERR_PTR(-ENOENT)) \
1234 else if (((hw) = __clk_get_hw((priv)->clks[(priv)->num_core_clks + i])) && \
1237 /* Need to be called with a lock held to avoid concurrent access to mstop->usecnt. */
1241 struct rzg2l_cpg_priv *priv = clock->priv; in rzg2l_mod_clock_module_set_state()
1242 struct mstop *mstop = clock->mstop; in rzg2l_mod_clock_module_set_state()
1249 value = MSTOP_MASK(mstop->conf) << 16; in rzg2l_mod_clock_module_set_state()
1254 for (unsigned int i = 0; i < clock->num_shared_mstop_clks; i++) { in rzg2l_mod_clock_module_set_state()
1255 struct mod_clock *clk = clock->shared_mstop_clks[i]; in rzg2l_mod_clock_module_set_state() local
1257 if (clk_hw_get_flags(&clk->hw) & CLK_IS_CRITICAL) in rzg2l_mod_clock_module_set_state()
1261 if (!clock->num_shared_mstop_clks && in rzg2l_mod_clock_module_set_state()
1262 clk_hw_get_flags(&clock->hw) & CLK_IS_CRITICAL) in rzg2l_mod_clock_module_set_state()
1272 * clocks and ref counted only by those critical clocks. in rzg2l_mod_clock_module_set_state()
1274 if (criticals && criticals == atomic_read(&mstop->usecnt)) in rzg2l_mod_clock_module_set_state()
1277 value |= MSTOP_MASK(mstop->conf); in rzg2l_mod_clock_module_set_state()
1280 if (!atomic_read(&mstop->usecnt)) in rzg2l_mod_clock_module_set_state()
1283 update = atomic_dec_and_test(&mstop->usecnt); in rzg2l_mod_clock_module_set_state()
1285 if (!atomic_read(&mstop->usecnt)) in rzg2l_mod_clock_module_set_state()
1287 atomic_inc(&mstop->usecnt); in rzg2l_mod_clock_module_set_state()
1291 writel(value, priv->base + MSTOP_OFF(mstop->conf)); in rzg2l_mod_clock_module_set_state()
1296 struct rzg2l_cpg_priv *priv = s->private; in rzg2l_mod_clock_mstop_show()
1297 struct mod_clock *clk; in rzg2l_mod_clock_mstop_show() local
1300 seq_printf(s, "%-20s %-5s %-10s\n", "", "", "MSTOP"); in rzg2l_mod_clock_mstop_show()
1301 seq_printf(s, "%-20s %-5s %-10s\n", "", "clk", "-------------------------"); in rzg2l_mod_clock_mstop_show()
1302 seq_printf(s, "%-20s %-5s %-5s %-5s %-6s %-6s\n", in rzg2l_mod_clock_mstop_show()
1304 seq_printf(s, "%-20s %-5s %-5s %-5s %-6s %-6s\n", in rzg2l_mod_clock_mstop_show()
1305 "--------", "-----", "-----", "-----", "------", "------"); in rzg2l_mod_clock_mstop_show()
1307 for_each_mod_clock(clk, hw, priv) { in rzg2l_mod_clock_mstop_show()
1310 if (!clk->mstop) in rzg2l_mod_clock_mstop_show()
1313 val = readl(priv->base + MSTOP_OFF(clk->mstop->conf)) & in rzg2l_mod_clock_mstop_show()
1314 MSTOP_MASK(clk->mstop->conf); in rzg2l_mod_clock_mstop_show()
1316 seq_printf(s, "%-20s %-5d %-5d 0x%-3lx 0x%-4x", clk_hw_get_name(hw), in rzg2l_mod_clock_mstop_show()
1317 __clk_get_enable_count(hw->clk), atomic_read(&clk->mstop->usecnt), in rzg2l_mod_clock_mstop_show()
1318 MSTOP_OFF(clk->mstop->conf), val); in rzg2l_mod_clock_mstop_show()
1320 for (unsigned int i = 0; i < clk->num_shared_mstop_clks; i++) in rzg2l_mod_clock_mstop_show()
1321 seq_printf(s, " %pC", clk->shared_mstop_clks[i]->hw.clk); in rzg2l_mod_clock_mstop_show()
1333 struct rzg2l_cpg_priv *priv = clock->priv; in rzg2l_mod_clock_endisable()
1334 unsigned int reg = clock->off; in rzg2l_mod_clock_endisable()
1335 struct device *dev = priv->dev; in rzg2l_mod_clock_endisable()
1336 u32 bitmask = BIT(clock->bit); in rzg2l_mod_clock_endisable()
1340 if (!clock->off) { in rzg2l_mod_clock_endisable()
1341 dev_dbg(dev, "%pC does not support ON/OFF\n", hw->clk); in rzg2l_mod_clock_endisable()
1345 dev_dbg(dev, "CLK_ON 0x%x/%pC %s\n", CLK_ON_R(reg), hw->clk, in rzg2l_mod_clock_endisable()
1352 scoped_guard(spinlock_irqsave, &priv->rmw_lock) { in rzg2l_mod_clock_endisable()
1354 writel(value, priv->base + CLK_ON_R(reg)); in rzg2l_mod_clock_endisable()
1358 writel(value, priv->base + CLK_ON_R(reg)); in rzg2l_mod_clock_endisable()
1365 if (!priv->info->has_clk_mon_regs) in rzg2l_mod_clock_endisable()
1368 error = readl_poll_timeout_atomic(priv->base + CLK_MON_R(reg), value, in rzg2l_mod_clock_endisable()
1372 CLK_ON_R(reg), hw->clk); in rzg2l_mod_clock_endisable()
1381 if (clock->sibling) { in rzg2l_mod_clock_enable()
1382 struct rzg2l_cpg_priv *priv = clock->priv; in rzg2l_mod_clock_enable()
1386 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg2l_mod_clock_enable()
1387 enabled = clock->sibling->enabled; in rzg2l_mod_clock_enable()
1388 clock->enabled = true; in rzg2l_mod_clock_enable()
1389 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg2l_mod_clock_enable()
1401 if (clock->sibling) { in rzg2l_mod_clock_disable()
1402 struct rzg2l_cpg_priv *priv = clock->priv; in rzg2l_mod_clock_disable()
1406 spin_lock_irqsave(&priv->rmw_lock, flags); in rzg2l_mod_clock_disable()
1407 enabled = clock->sibling->enabled; in rzg2l_mod_clock_disable()
1408 clock->enabled = false; in rzg2l_mod_clock_disable()
1409 spin_unlock_irqrestore(&priv->rmw_lock, flags); in rzg2l_mod_clock_disable()
1420 struct rzg2l_cpg_priv *priv = clock->priv; in rzg2l_mod_clock_is_enabled()
1421 u32 bitmask = BIT(clock->bit); in rzg2l_mod_clock_is_enabled()
1424 if (!clock->off) { in rzg2l_mod_clock_is_enabled()
1425 dev_dbg(priv->dev, "%pC does not support ON/OFF\n", hw->clk); in rzg2l_mod_clock_is_enabled()
1429 if (clock->sibling) in rzg2l_mod_clock_is_enabled()
1430 return clock->enabled; in rzg2l_mod_clock_is_enabled()
1432 if (priv->info->has_clk_mon_regs) in rzg2l_mod_clock_is_enabled()
1433 value = readl(priv->base + CLK_MON_R(clock->off)); in rzg2l_mod_clock_is_enabled()
1435 value = readl(priv->base + clock->off); in rzg2l_mod_clock_is_enabled()
1450 struct mod_clock *clk; in rzg2l_mod_clock_get_sibling() local
1453 for_each_mod_clock(clk, hw, priv) { in rzg2l_mod_clock_get_sibling()
1454 if (clock->off == clk->off && clock->bit == clk->bit) in rzg2l_mod_clock_get_sibling()
1455 return clk; in rzg2l_mod_clock_get_sibling()
1463 struct mod_clock *clk; in rzg2l_mod_clock_get_mstop() local
1466 for_each_mod_clock(clk, hw, priv) { in rzg2l_mod_clock_get_mstop()
1467 if (!clk->mstop) in rzg2l_mod_clock_get_mstop()
1470 if (clk->mstop->conf == conf) in rzg2l_mod_clock_get_mstop()
1471 return clk->mstop; in rzg2l_mod_clock_get_mstop()
1479 struct mod_clock *clk; in rzg2l_mod_clock_init_mstop() local
1482 for_each_mod_clock(clk, hw, priv) { in rzg2l_mod_clock_init_mstop()
1483 if (!clk->mstop) in rzg2l_mod_clock_init_mstop()
1491 scoped_guard(spinlock_irqsave, &priv->rmw_lock) { in rzg2l_mod_clock_init_mstop()
1492 if (!rzg2l_mod_clock_is_enabled(&clk->hw)) in rzg2l_mod_clock_init_mstop()
1493 rzg2l_mod_clock_module_set_state(clk, true); in rzg2l_mod_clock_init_mstop()
1501 struct mod_clock *clk; in rzg2l_mod_clock_update_shared_mstop_clks() local
1504 if (!clock->mstop) in rzg2l_mod_clock_update_shared_mstop_clks()
1507 for_each_mod_clock(clk, hw, priv) { in rzg2l_mod_clock_update_shared_mstop_clks()
1511 if (clk->mstop != clock->mstop) in rzg2l_mod_clock_update_shared_mstop_clks()
1514 num_shared_mstop_clks = clk->num_shared_mstop_clks; in rzg2l_mod_clock_update_shared_mstop_clks()
1518 new_clks = devm_krealloc(priv->dev, clk->shared_mstop_clks, in rzg2l_mod_clock_update_shared_mstop_clks()
1522 return -ENOMEM; in rzg2l_mod_clock_update_shared_mstop_clks()
1525 new_clks[num_shared_mstop_clks++] = clk; in rzg2l_mod_clock_update_shared_mstop_clks()
1529 new_clks[i]->shared_mstop_clks = new_clks; in rzg2l_mod_clock_update_shared_mstop_clks()
1530 new_clks[i]->num_shared_mstop_clks = num_shared_mstop_clks; in rzg2l_mod_clock_update_shared_mstop_clks()
1544 struct device *dev = priv->dev; in rzg2l_cpg_register_mod_clk()
1545 unsigned int id = mod->id; in rzg2l_cpg_register_mod_clk()
1547 struct clk *parent, *clk; in rzg2l_cpg_register_mod_clk() local
1552 WARN_DEBUG(id < priv->num_core_clks); in rzg2l_cpg_register_mod_clk()
1553 WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); in rzg2l_cpg_register_mod_clk()
1554 WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); in rzg2l_cpg_register_mod_clk()
1555 WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); in rzg2l_cpg_register_mod_clk()
1557 parent = priv->clks[mod->parent]; in rzg2l_cpg_register_mod_clk()
1559 clk = parent; in rzg2l_cpg_register_mod_clk()
1565 clk = ERR_PTR(-ENOMEM); in rzg2l_cpg_register_mod_clk()
1569 init.name = mod->name; in rzg2l_cpg_register_mod_clk()
1572 for (i = 0; i < info->num_crit_mod_clks; i++) in rzg2l_cpg_register_mod_clk()
1573 if (id == info->crit_mod_clks[i]) { in rzg2l_cpg_register_mod_clk()
1575 mod->name); in rzg2l_cpg_register_mod_clk()
1584 clock->off = mod->off; in rzg2l_cpg_register_mod_clk()
1585 clock->bit = mod->bit; in rzg2l_cpg_register_mod_clk()
1586 clock->priv = priv; in rzg2l_cpg_register_mod_clk()
1587 clock->hw.init = &init; in rzg2l_cpg_register_mod_clk()
1589 if (mod->mstop_conf) { in rzg2l_cpg_register_mod_clk()
1590 struct mstop *mstop = rzg2l_mod_clock_get_mstop(priv, mod->mstop_conf); in rzg2l_cpg_register_mod_clk()
1595 clk = ERR_PTR(-ENOMEM); in rzg2l_cpg_register_mod_clk()
1598 mstop->conf = mod->mstop_conf; in rzg2l_cpg_register_mod_clk()
1599 atomic_set(&mstop->usecnt, 0); in rzg2l_cpg_register_mod_clk()
1601 clock->mstop = mstop; in rzg2l_cpg_register_mod_clk()
1604 ret = devm_clk_hw_register(dev, &clock->hw); in rzg2l_cpg_register_mod_clk()
1606 clk = ERR_PTR(ret); in rzg2l_cpg_register_mod_clk()
1610 if (mod->is_coupled) { in rzg2l_cpg_register_mod_clk()
1613 clock->enabled = rzg2l_mod_clock_is_enabled(&clock->hw); in rzg2l_cpg_register_mod_clk()
1616 clock->sibling = sibling; in rzg2l_cpg_register_mod_clk()
1617 sibling->sibling = clock; in rzg2l_cpg_register_mod_clk()
1621 /* Keep this before priv->clks[id] is updated. */ in rzg2l_cpg_register_mod_clk()
1624 clk = ERR_PTR(ret); in rzg2l_cpg_register_mod_clk()
1628 clk = clock->hw.clk; in rzg2l_cpg_register_mod_clk()
1629 dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); in rzg2l_cpg_register_mod_clk()
1630 priv->clks[id] = clk; in rzg2l_cpg_register_mod_clk()
1636 mod->name, PTR_ERR(clk)); in rzg2l_cpg_register_mod_clk()
1645 const struct rzg2l_cpg_info *info = priv->info; in __rzg2l_cpg_assert()
1646 unsigned int reg = info->resets[id].off; in __rzg2l_cpg_assert()
1647 u32 mask = BIT(info->resets[id].bit); in __rzg2l_cpg_assert()
1648 s8 monbit = info->resets[id].monbit; in __rzg2l_cpg_assert()
1652 dev_dbg(rcdev->dev, "%s id:%ld offset:0x%x\n", in __rzg2l_cpg_assert()
1657 writel(value, priv->base + CLK_RST_R(reg)); in __rzg2l_cpg_assert()
1659 if (info->has_clk_mon_regs) { in __rzg2l_cpg_assert()
1670 ret = readl_poll_timeout_atomic(priv->base + reg, value, in __rzg2l_cpg_assert()
1674 writel(value, priv->base + CLK_RST_R(info->resets[id].off)); in __rzg2l_cpg_assert()
1708 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_status()
1709 s8 monbit = info->resets[id].monbit; in rzg2l_cpg_status()
1713 if (info->has_clk_mon_regs) { in rzg2l_cpg_status()
1714 reg = CLK_MRST_R(info->resets[id].off); in rzg2l_cpg_status()
1715 bitmask = BIT(info->resets[id].bit); in rzg2l_cpg_status()
1720 return -ENOTSUPP; in rzg2l_cpg_status()
1723 return !!(readl(priv->base + reg) & bitmask); in rzg2l_cpg_status()
1737 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_reset_xlate()
1738 unsigned int id = reset_spec->args[0]; in rzg2l_cpg_reset_xlate()
1740 if (id >= rcdev->nr_resets || !info->resets[id].off) { in rzg2l_cpg_reset_xlate()
1741 dev_err(rcdev->dev, "Invalid reset index %u\n", id); in rzg2l_cpg_reset_xlate()
1742 return -EINVAL; in rzg2l_cpg_reset_xlate()
1750 priv->rcdev.ops = &rzg2l_cpg_reset_ops; in rzg2l_cpg_reset_controller_register()
1751 priv->rcdev.of_node = priv->dev->of_node; in rzg2l_cpg_reset_controller_register()
1752 priv->rcdev.dev = priv->dev; in rzg2l_cpg_reset_controller_register()
1753 priv->rcdev.of_reset_n_cells = 1; in rzg2l_cpg_reset_controller_register()
1754 priv->rcdev.of_xlate = rzg2l_cpg_reset_xlate; in rzg2l_cpg_reset_controller_register()
1755 priv->rcdev.nr_resets = priv->num_resets; in rzg2l_cpg_reset_controller_register()
1757 return devm_reset_controller_register(priv->dev, &priv->rcdev); in rzg2l_cpg_reset_controller_register()
1763 if (clkspec->np != priv->genpd.dev.of_node || clkspec->args_count != 2) in rzg2l_cpg_is_pm_clk()
1766 switch (clkspec->args[0]) { in rzg2l_cpg_is_pm_clk()
1768 const struct rzg2l_cpg_info *info = priv->info; in rzg2l_cpg_is_pm_clk()
1769 unsigned int id = clkspec->args[1]; in rzg2l_cpg_is_pm_clk()
1771 if (id >= priv->num_mod_clks) in rzg2l_cpg_is_pm_clk()
1774 id += info->num_total_core_clks; in rzg2l_cpg_is_pm_clk()
1776 for (unsigned int i = 0; i < info->num_no_pm_mod_clks; i++) { in rzg2l_cpg_is_pm_clk()
1777 if (info->no_pm_mod_clks[i] == id) in rzg2l_cpg_is_pm_clk()
1793 struct device_node *np = dev->of_node; in rzg2l_cpg_attach_dev()
1796 struct clk *clk; in rzg2l_cpg_attach_dev() local
1800 for (i = 0; !of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, &clkspec); i++) { in rzg2l_cpg_attach_dev()
1814 clk = of_clk_get_from_provider(&clkspec); in rzg2l_cpg_attach_dev()
1816 if (IS_ERR(clk)) { in rzg2l_cpg_attach_dev()
1817 error = PTR_ERR(clk); in rzg2l_cpg_attach_dev()
1821 error = pm_clk_add_clk(dev, clk); in rzg2l_cpg_attach_dev()
1831 clk_put(clk); in rzg2l_cpg_attach_dev()
1852 struct device *dev = priv->dev; in rzg2l_cpg_add_clk_domain()
1853 struct device_node *np = dev->of_node; in rzg2l_cpg_add_clk_domain()
1854 struct generic_pm_domain *genpd = &priv->genpd; in rzg2l_cpg_add_clk_domain()
1857 genpd->name = np->name; in rzg2l_cpg_add_clk_domain()
1858 genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON | in rzg2l_cpg_add_clk_domain()
1860 genpd->attach_dev = rzg2l_cpg_attach_dev; in rzg2l_cpg_add_clk_domain()
1861 genpd->detach_dev = rzg2l_cpg_detach_dev; in rzg2l_cpg_add_clk_domain()
1875 struct device *dev = &pdev->dev; in rzg2l_cpg_probe()
1876 struct device_node *np = dev->of_node; in rzg2l_cpg_probe()
1880 struct clk **clks; in rzg2l_cpg_probe()
1887 return -ENOMEM; in rzg2l_cpg_probe()
1889 priv->dev = dev; in rzg2l_cpg_probe()
1890 priv->info = info; in rzg2l_cpg_probe()
1891 spin_lock_init(&priv->rmw_lock); in rzg2l_cpg_probe()
1893 priv->base = devm_platform_ioremap_resource(pdev, 0); in rzg2l_cpg_probe()
1894 if (IS_ERR(priv->base)) in rzg2l_cpg_probe()
1895 return PTR_ERR(priv->base); in rzg2l_cpg_probe()
1897 nclks = info->num_total_core_clks + info->num_hw_mod_clks; in rzg2l_cpg_probe()
1900 return -ENOMEM; in rzg2l_cpg_probe()
1903 priv->clks = clks; in rzg2l_cpg_probe()
1904 priv->num_core_clks = info->num_total_core_clks; in rzg2l_cpg_probe()
1905 priv->num_mod_clks = info->num_hw_mod_clks; in rzg2l_cpg_probe()
1906 priv->num_resets = info->num_resets; in rzg2l_cpg_probe()
1907 priv->last_dt_core_clk = info->last_dt_core_clk; in rzg2l_cpg_probe()
1910 clks[i] = ERR_PTR(-ENOENT); in rzg2l_cpg_probe()
1912 for (i = 0; i < info->num_core_clks; i++) in rzg2l_cpg_probe()
1913 rzg2l_cpg_register_core_clk(&info->core_clks[i], info, priv); in rzg2l_cpg_probe()
1915 for (i = 0; i < info->num_mod_clks; i++) in rzg2l_cpg_probe()
1916 rzg2l_cpg_register_mod_clk(&info->mod_clks[i], info, priv); in rzg2l_cpg_probe()
1921 * non-critical) share the same MSTOP. in rzg2l_cpg_probe()
1961 .compatible = "renesas,r9a07g043-cpg",
1967 .compatible = "renesas,r9a07g044-cpg",
1973 .compatible = "renesas,r9a07g054-cpg",
1979 .compatible = "renesas,r9a08g045-cpg",
1985 .compatible = "renesas,r9a09g011-cpg",
1994 .name = "rzg2l-cpg",