clk: renesas: rzg2l: Add support for enabling PLLs

Add support for enabling PLL clocks in the RZ/G3L CPG driver to turn off
some PLLs, if they are not in use (e.g. PLL6, PLL7).

Introduce .is_enabled() and .enable() callbacks to handle PLL state
transitions.  With the .enable() callback, the PLL will be turned ON
only when the PLL consumer device is enabled; otherwise, it will remain
off.  Define new macros for PLL standby and monitor registers to
facilitate this process.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20260326110648.29389-3-biju.das.jz@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
This commit is contained in:
Biju Das 2026-03-26 11:06:36 +00:00 committed by Geert Uytterhoeven
parent 79b5d6970b
commit 78db1faa6b
2 changed files with 71 additions and 0 deletions

View File

@ -58,6 +58,13 @@
#define RZG3S_DIV_NF GENMASK(12, 1)
#define RZG3S_SEL_PLL BIT(0)
#define RZG3L_PLL_STBY_OFFSET(x) (GET_REG_SAMPLL_CLK1(x) - 0x4)
#define RZG3L_PLL_STBY_RESETB BIT(0)
#define RZG3L_PLL_STBY_RESETB_WEN BIT(16)
#define RZG3L_PLL_MON_OFFSET(x) (GET_REG_SAMPLL_CLK1(x) + 0x8)
#define RZG3L_PLL_MON_RESETB BIT(0)
#define RZG3L_PLL_MON_LOCK BIT(4)
#define CLK_ON_R(reg) (reg)
#define CLK_MON_R(reg) (0x180 + (reg))
#define CLK_RST_R(reg) (reg)
@ -1175,6 +1182,63 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core,
return pll_clk->hw.clk;
}
static int rzg3l_cpg_pll_clk_is_enabled(struct clk_hw *hw)
{
struct pll_clk *pll_clk = to_pll(hw);
struct rzg2l_cpg_priv *priv = pll_clk->priv;
u32 val = readl(priv->base + RZG3L_PLL_MON_OFFSET(pll_clk->conf));
u32 mon_val = RZG3L_PLL_MON_RESETB | RZG3L_PLL_MON_LOCK;
/* Ensure both RESETB and LOCK bits are set */
return (mon_val == (val & mon_val));
}
static int rzg3l_cpg_pll_clk_endisable(struct clk_hw *hw, bool enable)
{
struct pll_clk *pll_clk = to_pll(hw);
struct rzg2l_cpg_priv *priv = pll_clk->priv;
u32 stby_offset, mon_offset;
u32 val, mon_val;
int ret;
stby_offset = RZG3L_PLL_STBY_OFFSET(pll_clk->conf);
mon_offset = RZG3L_PLL_MON_OFFSET(pll_clk->conf);
if (enable) {
val = RZG3L_PLL_STBY_RESETB_WEN | RZG3L_PLL_STBY_RESETB;
mon_val = RZG3L_PLL_MON_RESETB | RZG3L_PLL_MON_LOCK;
} else {
val = RZG3L_PLL_STBY_RESETB_WEN;
mon_val = 0;
}
writel(val, priv->base + stby_offset);
/* ensure PLL is in normal/standby mode */
ret = readl_poll_timeout_atomic(priv->base + mon_offset, val, mon_val ==
(val & (RZG3L_PLL_MON_RESETB | RZG3L_PLL_MON_LOCK)),
10, 100);
if (ret)
dev_err(priv->dev, "Failed to %s PLL 0x%x/%pC\n", enable ?
"enable" : "disable", stby_offset, hw->clk);
return ret;
}
static int rzg3l_cpg_pll_clk_enable(struct clk_hw *hw)
{
if (rzg3l_cpg_pll_clk_is_enabled(hw))
return 0;
return rzg3l_cpg_pll_clk_endisable(hw, true);
}
static const struct clk_ops rzg3l_cpg_pll_ops = {
.is_enabled = rzg3l_cpg_pll_clk_is_enabled,
.enable = rzg3l_cpg_pll_clk_enable,
.recalc_rate = rzg3s_cpg_pll_clk_recalc_rate,
};
static struct clk
*rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec,
void *data)
@ -1258,6 +1322,9 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
case CLK_TYPE_SAM_PLL:
clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg2l_cpg_pll_ops);
break;
case CLK_TYPE_G3L_PLL:
clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg3l_cpg_pll_ops);
break;
case CLK_TYPE_G3S_PLL:
clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg3s_cpg_pll_ops);
break;

View File

@ -123,6 +123,7 @@ enum clk_types {
CLK_TYPE_IN, /* External Clock Input */
CLK_TYPE_FF, /* Fixed Factor Clock */
CLK_TYPE_SAM_PLL,
CLK_TYPE_G3L_PLL,
CLK_TYPE_G3S_PLL,
/* Clock with divider */
@ -152,6 +153,9 @@ enum clk_types {
DEF_TYPE(_name, _id, _type, .parent = _parent)
#define DEF_SAMPLL(_name, _id, _parent, _conf) \
DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf)
#define DEF_G3L_PLL(_name, _id, _parent, _conf, _default_rate) \
DEF_TYPE(_name, _id, CLK_TYPE_G3L_PLL, .parent = _parent, .conf = _conf, \
.default_rate = _default_rate)
#define DEF_G3S_PLL(_name, _id, _parent, _conf, _default_rate) \
DEF_TYPE(_name, _id, CLK_TYPE_G3S_PLL, .parent = _parent, .conf = _conf, \
.default_rate = _default_rate)