Hi Geert, On Sun, Mar 9, 2025 at 9:14 PM Prabhakar <prabhakar.csengg@xxxxxxxxx> wrote: > > From: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx> > > Some RZ/V2H(P) SoC variants do not have a GPU, resulting in PLLGPU being > disabled by default in TF-A. Add support for enabling PLL clocks in the > RZ/V2H(P) CPG driver to manage this. > > Introduce `is_enabled` and `enable` callbacks to handle PLL state > transitions. With the `enable` callback, PLLGPU will be turned ON only > when the GPU node is enabled; otherwise, it will remain off. Define new > macros for PLL standby and monitor registers to facilitate this process. > > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx> > --- > v1->v2 > - Updated macros to get PLL offsets > - Switched to readl_poll_timeout_atomic() and updated the timeout > --- > drivers/clk/renesas/rzv2h-cpg.c | 49 +++++++++++++++++++++++++++++++++ > 1 file changed, 49 insertions(+) > > diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c > index e489ce28ae63..76ad037b4361 100644 > --- a/drivers/clk/renesas/rzv2h-cpg.c > +++ b/drivers/clk/renesas/rzv2h-cpg.c > @@ -44,12 +44,18 @@ > #define CPG_BUS_1_MSTOP (0xd00) > #define CPG_BUS_MSTOP(m) (CPG_BUS_1_MSTOP + ((m) - 1) * 4) > > +#define CPG_PLL_STBY(x) ((x)) > +#define CPG_PLL_STBY_RESETB BIT(0) > +#define CPG_PLL_STBY_RESETB_WEN BIT(16) > #define CPG_PLL_CLK1(x) ((x) + 0x004) > #define KDIV(val) ((s16)FIELD_GET(GENMASK(31, 16), (val))) > #define MDIV(val) FIELD_GET(GENMASK(15, 6), (val)) > #define PDIV(val) FIELD_GET(GENMASK(5, 0), (val)) > #define CPG_PLL_CLK2(x) ((x) + 0x008) > #define SDIV(val) FIELD_GET(GENMASK(2, 0), (val)) > +#define CPG_PLL_MON(x) ((x) + 0x010) > +#define CPG_PLL_MON_RESETB BIT(0) > +#define CPG_PLL_MON_LOCK BIT(4) > > #define DDIV_DIVCTL_WEN(shift) BIT((shift) + 16) > > @@ -141,6 +147,47 @@ struct ddiv_clk { > > #define to_ddiv_clock(_div) container_of(_div, struct ddiv_clk, div) > > +static int rzv2h_cpg_pll_clk_is_enabled(struct clk_hw *hw) > +{ > + struct pll_clk *pll_clk = to_pll(hw); > + struct rzv2h_cpg_priv *priv = pll_clk->priv; > + u32 val = readl(priv->base + CPG_PLL_MON(pll_clk->pll.offset)); > + > + /* Ensure both RESETB and LOCK bits are set */ > + return (val & (CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK)) == > + (CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK); > +} > + > +static int rzv2h_cpg_pll_clk_enable(struct clk_hw *hw) > +{ > + struct pll_clk *pll_clk = to_pll(hw); > + struct rzv2h_cpg_priv *priv = pll_clk->priv; > + struct pll pll = pll_clk->pll; > + u32 stby_offset; > + u32 mon_offset; > + u32 val; > + int ret; > + > + if (rzv2h_cpg_pll_clk_is_enabled(hw)) > + return 0; > + > + stby_offset = CPG_PLL_STBY(pll.offset); > + mon_offset = CPG_PLL_MON(pll.offset); > + > + writel(CPG_PLL_STBY_RESETB_WEN | CPG_PLL_STBY_RESETB, > + priv->base + stby_offset); > + > + /* ensure PLL is in normal mode */ > + ret = readl_poll_timeout_atomic(priv->base + mon_offset, val, > + (val & (CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK)) == > + (CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK), 10, 100); This timeout didnt work when I power cycled after a complete shutdown overnight. I will update the timeout as below, this Ive made sure the below delay works OK after complete shutdown. /* * Ensure PLL enters into normal mode * * Note: There is no HW information about the worst case latency. * * Since this value might be dependent on external xtal rate, pll * rate or even the other emulation clocks rate, use 2000 as a * "super" safe value. */ ret = readl_poll_timeout_atomic(priv->base + mon_offset, val, (val & (CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK)) == (CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK), 200, 2000); Please let me know shall I send v3 with this change or wait for your review. Cheers, Prabhakar