ccu: fix mux clk update childs by old freq when clk_set_rate

Change-Id: Ifebf947d73f25aaa74f700b7fe59506cf525b9ea
This commit is contained in:
weijinmei
2025-04-14 19:33:25 +08:00
committed by 张猛
parent c9b1a8ba29
commit d5d5da121b
4 changed files with 19 additions and 7 deletions

View File

@@ -1640,7 +1640,6 @@ void spacemit_clocks_init_rate(struct clk_hw_table *tbl, int tbl_size)
clk = clk_hw_get_clk(spacemit_k1x_hw_clks.hws[tbl[i].clk_hw_id], tbl[i].name);
if (!IS_ERR_OR_NULL(clk)) {
clk_set_rate(clk, tbl[i].rate);
clk_get_rate(clk);
}
else
pr_err("%s : can't find clk %s\n", __func__, tbl[i].name);

View File

@@ -50,6 +50,7 @@ struct ccu_common {
unsigned long flags;
spinlock_t *lock;
struct clk_hw hw;
unsigned long rate;
};
struct spacemit_k1x_clk {

View File

@@ -58,7 +58,8 @@ struct ccu_ddn {
.ddn = _SPACEMIT_CCU_DDN_CONFIG(_info, _table, _size), \
.common = { \
.reg_ctrl = _reg_ctrl, \
.base_type = _base_type, \
.base_type = _base_type, \
.name = _name, \
.hw.init = CLK_HW_INIT(_name, \
_parent, \
&ccu_ddn_ops, \
@@ -75,7 +76,8 @@ struct ccu_ddn {
.common = { \
.reg_ctrl = _reg_ddn, \
.reg_sel = __reg_gate, \
.base_type = _base_type, \
.base_type = _base_type, \
.name = _name, \
.hw.init = CLK_HW_INIT(_name, \
_parent, \
&ccu_ddn_ops, \

View File

@@ -194,16 +194,22 @@ static unsigned long ccu_mix_recalc_rate(struct clk_hw *hw,
struct ccu_mix *mix = hw_to_ccu_mix(hw);
struct ccu_common * common = &mix->common;
struct ccu_div_config *div = mix->div;
struct ccu_mux_config *mux = mix->mux ? mix->mux : NULL;
unsigned long val;
u32 reg;
if (!div){
if (!div) {
if (mux && common->rate && common->rate != parent_rate)
parent_rate = common->rate;
if (mix->factor)
return parent_rate * mix->factor->mul / mix->factor->div;
val = parent_rate * mix->factor->mul / mix->factor->div;
else
return parent_rate;
val = parent_rate;
goto end;
}
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3
|| common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
reg = readl(common->base + common->reg_sel);
else
@@ -215,6 +221,8 @@ static unsigned long ccu_mix_recalc_rate(struct clk_hw *hw,
val = divider_recalc_rate(hw, parent_rate, val, div->table,
div->flags, div->width);
end:
common->rate = val;
return val;
}
@@ -338,6 +346,8 @@ static int ccu_mix_set_rate(struct clk_hw *hw, unsigned long rate,
}
best_rate = ccu_mix_calc_best_rate(hw, rate, &mux_val, &div_val);
common->rate = best_rate;
if (!strcmp(common->name, tswi8_clk_name)){
if(mux){
cur_mux = twsi8_reg_val >> mux->shift;