Skip to content

Commit fea942b

Browse files
prabhakarladgeertu
authored andcommitted
clk: renesas: rzv2h: Add support for enabling PLLs
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 <[email protected]> Reviewed-by: Geert Uytterhoeven <[email protected]> Link: https://lore.kernel.org/[email protected] Signed-off-by: Geert Uytterhoeven <[email protected]>
1 parent 18510fd commit fea942b

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

drivers/clk/renesas/rzv2h-cpg.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,18 @@
4444
#define CPG_BUS_1_MSTOP (0xd00)
4545
#define CPG_BUS_MSTOP(m) (CPG_BUS_1_MSTOP + ((m) - 1) * 4)
4646

47+
#define CPG_PLL_STBY(x) ((x))
48+
#define CPG_PLL_STBY_RESETB BIT(0)
49+
#define CPG_PLL_STBY_RESETB_WEN BIT(16)
4750
#define CPG_PLL_CLK1(x) ((x) + 0x004)
4851
#define KDIV(val) ((s16)FIELD_GET(GENMASK(31, 16), (val)))
4952
#define MDIV(val) FIELD_GET(GENMASK(15, 6), (val))
5053
#define PDIV(val) FIELD_GET(GENMASK(5, 0), (val))
5154
#define CPG_PLL_CLK2(x) ((x) + 0x008)
5255
#define SDIV(val) FIELD_GET(GENMASK(2, 0), (val))
56+
#define CPG_PLL_MON(x) ((x) + 0x010)
57+
#define CPG_PLL_MON_RESETB BIT(0)
58+
#define CPG_PLL_MON_LOCK BIT(4)
5359

5460
#define DDIV_DIVCTL_WEN(shift) BIT((shift) + 16)
5561

@@ -141,6 +147,54 @@ struct ddiv_clk {
141147

142148
#define to_ddiv_clock(_div) container_of(_div, struct ddiv_clk, div)
143149

150+
static int rzv2h_cpg_pll_clk_is_enabled(struct clk_hw *hw)
151+
{
152+
struct pll_clk *pll_clk = to_pll(hw);
153+
struct rzv2h_cpg_priv *priv = pll_clk->priv;
154+
u32 val = readl(priv->base + CPG_PLL_MON(pll_clk->pll.offset));
155+
156+
/* Ensure both RESETB and LOCK bits are set */
157+
return (val & (CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK)) ==
158+
(CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK);
159+
}
160+
161+
static int rzv2h_cpg_pll_clk_enable(struct clk_hw *hw)
162+
{
163+
struct pll_clk *pll_clk = to_pll(hw);
164+
struct rzv2h_cpg_priv *priv = pll_clk->priv;
165+
struct pll pll = pll_clk->pll;
166+
u32 stby_offset;
167+
u32 mon_offset;
168+
u32 val;
169+
int ret;
170+
171+
if (rzv2h_cpg_pll_clk_is_enabled(hw))
172+
return 0;
173+
174+
stby_offset = CPG_PLL_STBY(pll.offset);
175+
mon_offset = CPG_PLL_MON(pll.offset);
176+
177+
writel(CPG_PLL_STBY_RESETB_WEN | CPG_PLL_STBY_RESETB,
178+
priv->base + stby_offset);
179+
180+
/*
181+
* Ensure PLL enters into normal mode
182+
*
183+
* Note: There is no HW information about the worst case latency.
184+
*
185+
* Since this latency might depend on external crystal or PLL rate,
186+
* use a "super" safe timeout value.
187+
*/
188+
ret = readl_poll_timeout_atomic(priv->base + mon_offset, val,
189+
(val & (CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK)) ==
190+
(CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK), 200, 2000);
191+
if (ret)
192+
dev_err(priv->dev, "Failed to enable PLL 0x%x/%pC\n",
193+
stby_offset, hw->clk);
194+
195+
return ret;
196+
}
197+
144198
static unsigned long rzv2h_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
145199
unsigned long parent_rate)
146200
{
@@ -163,6 +217,8 @@ static unsigned long rzv2h_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
163217
}
164218

165219
static const struct clk_ops rzv2h_cpg_pll_ops = {
220+
.is_enabled = rzv2h_cpg_pll_clk_is_enabled,
221+
.enable = rzv2h_cpg_pll_clk_enable,
166222
.recalc_rate = rzv2h_cpg_pll_clk_recalc_rate,
167223
};
168224

0 commit comments

Comments
 (0)