diff mbox series

[3/6] clk: renesas: rzv2h-cpg: Ignore monitoring CLK_MON bits for external clocks

Message ID 20250328200105.176129-4-prabhakar.mahadev-lad.rj@bp.renesas.com (mailing list archive)
State Under Review
Headers show
Series clk: renesas: rzv2h: Add clock and reset entries for USB2 and GBETH | expand

Commit Message

Lad, Prabhakar March 28, 2025, 8:01 p.m. UTC
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>

Ignore CLK_MON bits when turning on/off module clocks that use an external
clock source, as they cannot be monitored.

Introduce the `DEF_MOD_EXTERNAL()` macro for defining module clocks that
may have an external clock source. Update `rzv2h_cpg_register_mod_clk()`
to update mon_index.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
---
 drivers/clk/renesas/rzv2h-cpg.c | 24 ++++++++++++++++++++++++
 drivers/clk/renesas/rzv2h-cpg.h | 28 ++++++++++++++++++++++++----
 2 files changed, 48 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c
index dec97f731e3a..e6a3c673879f 100644
--- a/drivers/clk/renesas/rzv2h-cpg.c
+++ b/drivers/clk/renesas/rzv2h-cpg.c
@@ -566,6 +566,25 @@  static void rzv2h_mod_clock_mstop_disable(struct rzv2h_cpg_priv *priv,
 	spin_unlock_irqrestore(&priv->rmw_lock, flags);
 }
 
+static bool rzv2h_mod_clock_is_external(struct rzv2h_cpg_priv *priv,
+					u16 ext_clk_offset,
+					u8 ext_clk_bit,
+					u8 ext_cond)
+{
+	u32 value;
+
+	if (!ext_clk_offset)
+		return false;
+
+	value = readl(priv->base + ext_clk_offset) & BIT(ext_clk_bit);
+	value >>= ext_clk_bit;
+
+	if (value == ext_cond)
+		return true;
+
+	return false;
+}
+
 static int rzv2h_mod_clock_is_enabled(struct clk_hw *hw)
 {
 	struct mod_clock *clock = to_mod_clock(hw);
@@ -688,6 +707,11 @@  rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod,
 	clock->on_index = mod->on_index;
 	clock->on_bit = mod->on_bit;
 	clock->mon_index = mod->mon_index;
+	/* If clock is coming from external source ignore the monitor bit for it */
+	if (rzv2h_mod_clock_is_external(priv, mod->external_clk_offset,
+					mod->external_clk_bit,
+					mod->external_cond))
+		clock->mon_index = -1;
 	clock->mon_bit = mod->mon_bit;
 	clock->no_pm = mod->no_pm;
 	clock->priv = priv;
diff --git a/drivers/clk/renesas/rzv2h-cpg.h b/drivers/clk/renesas/rzv2h-cpg.h
index cae807aa53ef..0277871e298b 100644
--- a/drivers/clk/renesas/rzv2h-cpg.h
+++ b/drivers/clk/renesas/rzv2h-cpg.h
@@ -180,6 +180,10 @@  enum clk_types {
  * @on_bit: ON bit
  * @mon_index: monitor register index
  * @mon_bit: monitor bit
+ * @external_clk_offset: Offset to check to determine if the clock is external
+ * @external_clk_bit: Bit to check to determine if the clock is external
+ * @external_cond: Condition to determine whether a given clock source is external;
+ *                 it can be either 0 or 1.
  */
 struct rzv2h_mod_clk {
 	const char *name;
@@ -191,9 +195,14 @@  struct rzv2h_mod_clk {
 	u8 on_bit;
 	s8 mon_index;
 	u8 mon_bit;
+	u16 external_clk_offset:10;
+	u8 external_clk_bit:5;
+	u8 external_cond:1;
 };
 
-#define DEF_MOD_BASE(_name, _mstop, _parent, _critical, _no_pm, _onindex, _onbit, _monindex, _monbit) \
+#define DEF_MOD_BASE(_name, _mstop, _parent, _critical, _no_pm, _onindex, \
+		     _onbit, _monindex, _monbit, _external_clk_offset, \
+		     _external_clk_bit, _external_cond) \
 	{ \
 		.name = (_name), \
 		.mstop_data = (_mstop), \
@@ -204,16 +213,27 @@  struct rzv2h_mod_clk {
 		.on_bit = (_onbit), \
 		.mon_index = (_monindex), \
 		.mon_bit = (_monbit), \
+		.external_clk_offset = (_external_clk_offset), \
+		.external_clk_bit = (_external_clk_bit), \
+		.external_cond = (_external_cond), \
 	}
 
 #define DEF_MOD(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop) \
-	DEF_MOD_BASE(_name, _mstop, _parent, false, false, _onindex, _onbit, _monindex, _monbit)
+	DEF_MOD_BASE(_name, _mstop, _parent, false, false, _onindex, _onbit, _monindex, _monbit, \
+		     0, 0, 0)
 
 #define DEF_MOD_CRITICAL(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop) \
-	DEF_MOD_BASE(_name, _mstop, _parent, true, false, _onindex, _onbit, _monindex, _monbit)
+	DEF_MOD_BASE(_name, _mstop, _parent, true, false, _onindex, _onbit, _monindex, _monbit, \
+		     0, 0, 0)
 
 #define DEF_MOD_NO_PM(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop) \
-	DEF_MOD_BASE(_name, _mstop, _parent, false, true, _onindex, _onbit, _monindex, _monbit)
+	DEF_MOD_BASE(_name, _mstop, _parent, false, true, _onindex, _onbit, _monindex, _monbit, \
+		     0, 0, 0)
+
+#define DEF_MOD_EXTERNAL(_name, _parent, _onindex, _onbit, _monindex, _monbit, _mstop, \
+			_external_clk_offset, _external_clk_bit, _external_cond) \
+	DEF_MOD_BASE(_name, _mstop, _parent, false, false, _onindex, _onbit, _monindex, _monbit, \
+		     _external_clk_offset, _external_clk_bit, _external_cond)
 
 /**
  * struct rzv2h_reset - Reset definitions