[PATCH v5 03/16] clk: renesas: rzv2h-cpg: Add support for init_{off|asserted} clocks/resets
From: John Madieu <john.madieu.xa@bp.renesas.com>
Date: 2026-02-10 11:32:28
Also in:
linux-clk, linux-pci, linux-renesas-soc
Subsystem:
common clk framework, renesas clock drivers, the rest · Maintainers:
Michael Turquette, Stephen Boyd, Geert Uytterhoeven, Linus Torvalds
Some peripherals may be left enabled by the bootloader but should be explicitly disabled by the kernel to ensure a known initial state. This is particularly important for PCIe which requires proper initialization sequencing. Add new macros DEF_MOD_INIT_OFF() and DEF_RST_INIT_ASSERTED() to declare module clocks that should be turned off and resets that should be asserted during CPG probe if found in the opposite state. Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com> --- Changes: v5: No changes v4: No changes v3: - Fixed potential unitialized rcdev crash - Removed duplicated message v2: - Added reset-specific assert on probe - Removed Rb tag from Geert due to previous point drivers/clk/renesas/rzv2h-cpg.c | 24 ++++++++++++++++++++++- drivers/clk/renesas/rzv2h-cpg.h | 34 +++++++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c
index 3f6299b9fec0..8e45f6f48e29 100644
--- a/drivers/clk/renesas/rzv2h-cpg.c
+++ b/drivers/clk/renesas/rzv2h-cpg.c@@ -1337,6 +1337,13 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod, spin_unlock_irqrestore(&priv->rmw_lock, flags); } + /* + * Turn off clocks marked with init_off flag if they were left + * enabled by the bootloader. This ensures a known initial state. + */ + if (mod->init_off && rzv2h_mod_clock_is_enabled(&clock->hw)) + rzv2h_mod_clock_endisable(&clock->hw, false); + return; fail:
@@ -1585,7 +1592,7 @@ static int __init rzv2h_cpg_probe(struct platform_device *pdev) struct rzv2h_cpg_priv *priv; unsigned int nclks, i; struct clk **clks; - int error; + int error, ret; info = of_device_get_match_data(dev);
@@ -1635,6 +1642,21 @@ static int __init rzv2h_cpg_probe(struct platform_device *pdev) for (i = 0; i < info->num_mod_clks; i++) rzv2h_cpg_register_mod_clk(&info->mod_clks[i], priv); + /* + * Assert resets marked with init_asserted flag if they were left + * deasserted by the bootloader. This ensures a known initial state. + */ + priv->rcdev.dev = dev; + for (i = 0; i < info->num_resets; i++) { + if (!info->resets[i].init_asserted) + continue; + + /* Check if reset is currently deasserted (status == 0) */ + ret = rzv2h_cpg_status(&priv->rcdev, i); + if (ret == 0) + rzv2h_cpg_assert(&priv->rcdev, i); + } + error = of_clk_add_provider(np, rzv2h_cpg_clk_src_twocell_get, priv); if (error) return error;
diff --git a/drivers/clk/renesas/rzv2h-cpg.h b/drivers/clk/renesas/rzv2h-cpg.h
index dc957bdaf5e9..927009431a73 100644
--- a/drivers/clk/renesas/rzv2h-cpg.h
+++ b/drivers/clk/renesas/rzv2h-cpg.h@@ -250,6 +250,7 @@ enum clk_types { * @parent: id of parent clock * @critical: flag to indicate the clock is critical * @no_pm: flag to indicate PM is not supported + * @init_off: flag to indicate the clock should be turned off during probe * @on_index: control register index * @on_bit: ON bit * @mon_index: monitor register index
@@ -262,6 +263,7 @@ struct rzv2h_mod_clk { u16 parent; bool critical; bool no_pm; + bool init_off; u8 on_index; u8 on_bit; s8 mon_index;
@@ -269,14 +271,15 @@ struct rzv2h_mod_clk { s8 ext_clk_mux_index; }; -#define DEF_MOD_BASE(_name, _mstop, _parent, _critical, _no_pm, _onindex, \ - _onbit, _monindex, _monbit, _ext_clk_mux_index) \ +#define DEF_MOD_BASE(_name, _mstop, _parent, _critical, _no_pm, _init_off, \ + _onindex, _onbit, _monindex, _monbit, _ext_clk_mux_index) \ { \ .name = (_name), \ .mstop_data = (_mstop), \ .parent = (_parent), \ .critical = (_critical), \ .no_pm = (_no_pm), \ + .init_off = (_init_off), \ .on_index = (_onindex), \ .on_bit = (_onbit), \ .mon_index = (_monindex), \
@@ -285,17 +288,20 @@ struct rzv2h_mod_clk { } #define DEF_MOD(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop) \ - DEF_MOD_BASE(_name, _mstop, _parent, false, false, _onindex, _onbit, _monindex, _monbit, -1) + DEF_MOD_BASE(_name, _mstop, _parent, false, false, false, _onindex, _onbit, _monindex, _monbit, -1) #define DEF_MOD_CRITICAL(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop) \ - DEF_MOD_BASE(_name, _mstop, _parent, true, false, _onindex, _onbit, _monindex, _monbit, -1) + DEF_MOD_BASE(_name, _mstop, _parent, true, false, false, _onindex, _onbit, _monindex, _monbit, -1) + +#define DEF_MOD_INIT_OFF(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop) \ + DEF_MOD_BASE(_name, _mstop, _parent, false, false, true, _onindex, _onbit, _monindex, _monbit, -1) #define DEF_MOD_NO_PM(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop) \ - DEF_MOD_BASE(_name, _mstop, _parent, false, true, _onindex, _onbit, _monindex, _monbit, -1) + DEF_MOD_BASE(_name, _mstop, _parent, false, true, false, _onindex, _onbit, _monindex, _monbit, -1) #define DEF_MOD_MUX_EXTERNAL(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop, \ _ext_clk_mux_index) \ - DEF_MOD_BASE(_name, _mstop, _parent, false, false, _onindex, _onbit, _monindex, _monbit, \ + DEF_MOD_BASE(_name, _mstop, _parent, false, false, false, _onindex, _onbit, _monindex, _monbit, \ _ext_clk_mux_index) /**
@@ -305,24 +311,36 @@ struct rzv2h_mod_clk { * @reset_bit: reset bit * @mon_index: monitor register index * @mon_bit: monitor bit + * @init_asserted: flag to indicate the reset should be asserted during probe */ struct rzv2h_reset { u8 reset_index; u8 reset_bit; u8 mon_index; u8 mon_bit; + bool init_asserted; }; -#define DEF_RST_BASE(_resindex, _resbit, _monindex, _monbit) \ +#define DEF_RST_BASE(_resindex, _resbit, _monindex, _monbit, _init_asserted) \ { \ .reset_index = (_resindex), \ .reset_bit = (_resbit), \ .mon_index = (_monindex), \ .mon_bit = (_monbit), \ + .init_asserted = (_init_asserted), \ } #define DEF_RST(_resindex, _resbit, _monindex, _monbit) \ - DEF_RST_BASE(_resindex, _resbit, _monindex, _monbit) + DEF_RST_BASE(_resindex, _resbit, _monindex, _monbit, false) + +/** + * DEF_RST_INIT_ASSERTED - Define a reset that should be asserted during probe + * + * Use this for peripherals that require their reset to be asserted at boot + * to ensure a known initial state before the peripheral driver takes over. + */ +#define DEF_RST_INIT_ASSERTED(_reset_index, _reset_bit, _mon_index, _mon_bit) \ + DEF_RST_BASE(_reset_index, _reset_bit, _mon_index, _mon_bit, true) /** * struct rzv2h_cpg_info - SoC-specific CPG Description
--
2.25.1