diff options
| -rw-r--r-- | drivers/clk/renesas/rzv2h-cpg.c | 30 | ||||
| -rw-r--r-- | drivers/clk/renesas/rzv2h-cpg.h | 17 | 
2 files changed, 41 insertions, 6 deletions
| diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index bcc496e8cbcd..2f045acc5080 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -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; diff --git a/drivers/clk/renesas/rzv2h-cpg.h b/drivers/clk/renesas/rzv2h-cpg.h index 9104b1cd276c..68c223373916 100644 --- a/drivers/clk/renesas/rzv2h-cpg.h +++ b/drivers/clk/renesas/rzv2h-cpg.h @@ -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 | 
