From: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxx> --- drivers/clk/renesas/rzv2h-cpg.c | 24 ++++++++++++++++++++++++ drivers/clk/renesas/rzv2h-cpg.h | 28 ++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) 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 -- 2.49.0