clk: renesas: rzv2h: Skip monitor checks for external clocks
For module clocks whose parent mux may select an external source, bypass the normal monitor (CLK_MON) register check when the external clock is active. Introduce a new `ext_clk_mux_index` in `struct rzv2h_mod_clk` and `struct mod_clock`, and detect the current mux index in `rzv2h_mod_clock_is_enabled()` to disable monitoring if it matches the external source index. Provide the `DEF_MOD_MUX_EXTERNAL()` macro for declaring external-source module clocks, and populate the `ext_clk_mux_index` field in `rzv2h_cpg_register_mod_clk()`. Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Link: https://lore.kernel.org/20250509160121.331073-2-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>pull/1279/head
parent
19272b37aa
commit
899e7ede4c
|
|
@ -119,6 +119,7 @@ struct pll_clk {
|
|||
* @on_bit: ON/MON bit
|
||||
* @mon_index: monitor register offset
|
||||
* @mon_bit: monitor bit
|
||||
* @ext_clk_mux_index: mux index for external clock source, or -1 if internal
|
||||
*/
|
||||
struct mod_clock {
|
||||
struct rzv2h_cpg_priv *priv;
|
||||
|
|
@ -129,6 +130,7 @@ struct mod_clock {
|
|||
u8 on_bit;
|
||||
s8 mon_index;
|
||||
u8 mon_bit;
|
||||
s8 ext_clk_mux_index;
|
||||
};
|
||||
|
||||
#define to_mod_clock(_hw) container_of(_hw, struct mod_clock, hw)
|
||||
|
|
@ -563,15 +565,38 @@ static void rzv2h_mod_clock_mstop_disable(struct rzv2h_cpg_priv *priv,
|
|||
spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||||
}
|
||||
|
||||
static int rzv2h_parent_clk_mux_to_index(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hw *parent_hw;
|
||||
struct clk *parent_clk;
|
||||
struct clk_mux *mux;
|
||||
u32 val;
|
||||
|
||||
/* This will always succeed, so no need to check for IS_ERR() */
|
||||
parent_clk = clk_get_parent(hw->clk);
|
||||
|
||||
parent_hw = __clk_get_hw(parent_clk);
|
||||
mux = to_clk_mux(parent_hw);
|
||||
|
||||
val = readl(mux->reg) >> mux->shift;
|
||||
val &= mux->mask;
|
||||
return clk_mux_val_to_index(parent_hw, mux->table, 0, val);
|
||||
}
|
||||
|
||||
static int rzv2h_mod_clock_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct mod_clock *clock = to_mod_clock(hw);
|
||||
struct rzv2h_cpg_priv *priv = clock->priv;
|
||||
int mon_index = clock->mon_index;
|
||||
u32 bitmask;
|
||||
u32 offset;
|
||||
|
||||
if (clock->mon_index >= 0) {
|
||||
offset = GET_CLK_MON_OFFSET(clock->mon_index);
|
||||
if (clock->ext_clk_mux_index >= 0 &&
|
||||
rzv2h_parent_clk_mux_to_index(hw) == clock->ext_clk_mux_index)
|
||||
mon_index = -1;
|
||||
|
||||
if (mon_index >= 0) {
|
||||
offset = GET_CLK_MON_OFFSET(mon_index);
|
||||
bitmask = BIT(clock->mon_bit);
|
||||
|
||||
if (!(readl(priv->base + offset) & bitmask))
|
||||
|
|
@ -687,6 +712,7 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod,
|
|||
clock->mon_index = mod->mon_index;
|
||||
clock->mon_bit = mod->mon_bit;
|
||||
clock->no_pm = mod->no_pm;
|
||||
clock->ext_clk_mux_index = mod->ext_clk_mux_index;
|
||||
clock->priv = priv;
|
||||
clock->hw.init = &init;
|
||||
clock->mstop_data = mod->mstop_data;
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ enum clk_types {
|
|||
* @on_bit: ON bit
|
||||
* @mon_index: monitor register index
|
||||
* @mon_bit: monitor bit
|
||||
* @ext_clk_mux_index: mux index for external clock source, or -1 if internal
|
||||
*/
|
||||
struct rzv2h_mod_clk {
|
||||
const char *name;
|
||||
|
|
@ -210,9 +211,11 @@ struct rzv2h_mod_clk {
|
|||
u8 on_bit;
|
||||
s8 mon_index;
|
||||
u8 mon_bit;
|
||||
s8 ext_clk_mux_index;
|
||||
};
|
||||
|
||||
#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, _ext_clk_mux_index) \
|
||||
{ \
|
||||
.name = (_name), \
|
||||
.mstop_data = (_mstop), \
|
||||
|
|
@ -223,16 +226,22 @@ struct rzv2h_mod_clk {
|
|||
.on_bit = (_onbit), \
|
||||
.mon_index = (_monindex), \
|
||||
.mon_bit = (_monbit), \
|
||||
.ext_clk_mux_index = (_ext_clk_mux_index), \
|
||||
}
|
||||
|
||||
#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, -1)
|
||||
|
||||
#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, -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)
|
||||
DEF_MOD_BASE(_name, _mstop, _parent, false, true, _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, \
|
||||
_ext_clk_mux_index)
|
||||
|
||||
/**
|
||||
* struct rzv2h_reset - Reset definitions
|
||||
|
|
|
|||
Loading…
Reference in New Issue