[PATCH v2 1/5] clk: renesas: rzv2h-cpg: Use per-SoC PLL reference frequency for calculations

From: Prabhakar

Date: Tue Jun 09 2026 - 07:14:39 EST


From: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>

Introduce a per-SoC PLL reference input frequency parameter to avoid
relying on a hardcoded 24MHz constant during PLL configuration math.

Add an input_fref member to struct rzv2h_pll_limits. In the core
calculation helper rzv2h_get_pll_pars(), derive the base input clock
rate from limits->input_fref, utilizing the conditional ternary operator
to fall back to 24MHz if the struct field is left uninitialized (0), and
drop the obsolete macro RZ_V2H_OSC_CLK_IN_MEGA.

This abstraction permits the reuse of the common PLL divider logic on
newer SoC platforms like the RZ/T2H, which feature a 48 MHz PLL reference
clock input instead of the 24 MHz signal used by RZ/V2H(P), without
disrupting existing platforms.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>
---
v1->v2:
- Dropped RZ_V2H_OSC_CLK_IN_MEGA macro in favor of direct use of the
input_fref field with a fallback.
- Updated the doc to specify the default value of input_freq when it is 0.
- Updated commit message
---
drivers/clk/renesas/rzv2h-cpg.c | 8 ++++----
include/linux/clk/renesas.h | 5 +++++
2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c
index e271c04cee34..fff89f2bdc0b 100644
--- a/drivers/clk/renesas/rzv2h-cpg.c
+++ b/drivers/clk/renesas/rzv2h-cpg.c
@@ -218,7 +218,6 @@ struct rzv2h_plldsi_div_clk {
#define to_plldsi_div_clk(_hw) \
container_of(_hw, struct rzv2h_plldsi_div_clk, hw)

-#define RZ_V2H_OSC_CLK_IN_MEGA (24 * MEGA)
#define RZV2H_MAX_DIV_TABLES (16)

/**
@@ -242,6 +241,7 @@ struct rzv2h_plldsi_div_clk {
bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits,
struct rzv2h_pll_pars *pars, u64 freq_millihz)
{
+ unsigned long input_fref = limits->input_fref ?: (24 * MEGA);
u64 fout_min_millihz = mul_u32_u32(limits->fout.min, MILLI);
u64 fout_max_millihz = mul_u32_u32(limits->fout.max, MILLI);
struct rzv2h_pll_pars p, best;
@@ -254,7 +254,7 @@ bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits,
best.error_millihz = S64_MAX;

for (p.p = limits->p.min; p.p <= limits->p.max; p.p++) {
- u32 fref = RZ_V2H_OSC_CLK_IN_MEGA / p.p;
+ u32 fref = input_fref / p.p;
u16 divider;

for (divider = 1 << limits->s.min, p.s = limits->s.min;
@@ -335,9 +335,9 @@ bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits,
continue;

/* PLL_M component of (output * 65536 * PLL_P) */
- output = mul_u32_u32(p.m * 65536, RZ_V2H_OSC_CLK_IN_MEGA);
+ output = mul_u32_u32(p.m * 65536, input_fref);
/* PLL_K component of (output * 65536 * PLL_P) */
- output += p.k * RZ_V2H_OSC_CLK_IN_MEGA;
+ output += p.k * input_fref;
/* Make it in mHz */
output *= MILLI;
output = DIV_U64_ROUND_CLOSEST(output, 65536 * p.p * divider);
diff --git a/include/linux/clk/renesas.h b/include/linux/clk/renesas.h
index 0949400f44de..2aeff01150c3 100644
--- a/include/linux/clk/renesas.h
+++ b/include/linux/clk/renesas.h
@@ -53,6 +53,9 @@ static inline void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target) { }
* various parameters used to configure a PLL. These limits ensure
* the PLL operates within valid and stable ranges.
*
+ * @input_fref: Reference input frequency to the PLL (in MHz). If set
+ * to 0, a default value of 24MHz is used.
+ *
* @fout: Output frequency range (in MHz)
* @fout.min: Minimum allowed output frequency
* @fout.max: Maximum allowed output frequency
@@ -78,6 +81,8 @@ static inline void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target) { }
* @k.max: Maximum delta-sigma value
*/
struct rzv2h_pll_limits {
+ u32 input_fref;
+
struct {
u32 min;
u32 max;
--
2.54.0