Thread (22 messages) 22 messages, 2 authors, 2026-02-18
STALE143d
Revisions (11)
  1. v1 [diff vs current]
  2. v2 [diff vs current]
  3. v3 [diff vs current]
  4. v4 [diff vs current]
  5. v5 current
  6. v6 [diff vs current]
  7. v7 [diff vs current]
  8. v8 [diff vs current]
  9. v9 [diff vs current]
  10. v1 [diff vs current]
  11. v1 [diff vs current]

[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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help