Messages in this thread Patch in this message | | | From | Rahul Tanwar <> | Subject | [PATCH RESEND 3/3] clk: mxl: Avoid disabling gate clocks from clk driver | Date | Mon, 25 Jul 2022 18:27:29 +0800 |
| |
In MxL's LGM SoC, gate clocks are supposed to be enabled or disabled from EPU (power management IP) in certain power saving modes. If gate clocks are allowed to be enabled/disabled from CGU clk driver, then there arises a conflict where in case clk driver disables a gate clk, and then EPU tries to disable the same gate clk, then it will hang polling for the clk gated successful status.
To avoid such a conflict, disable gate clocks enabling/disabling from CGU clk driver. But add a GATE_CLK_HW flag to control this in order to be backward compatible with other SoCs which share the same CGU IP but not the same EPU IP.
Signed-off-by: Rahul Tanwar <rtanwar@maxlinear.com> --- drivers/clk/x86/clk-cgu.c | 32 ++++++++++++++++++++++++-------- drivers/clk/x86/clk-cgu.h | 1 + 2 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/drivers/clk/x86/clk-cgu.c b/drivers/clk/x86/clk-cgu.c index 1f7e93de67bc..d24173cfe0b0 100644 --- a/drivers/clk/x86/clk-cgu.c +++ b/drivers/clk/x86/clk-cgu.c @@ -258,8 +258,12 @@ static int lgm_clk_gate_enable(struct clk_hw *hw) struct lgm_clk_gate *gate = to_lgm_clk_gate(hw); unsigned int reg; - reg = GATE_HW_REG_EN(gate->reg); - lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1); + if (gate->flags & GATE_CLK_HW) { + reg = GATE_HW_REG_EN(gate->reg); + lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1); + } else { + gate->reg = 1; + } return 0; } @@ -269,8 +273,12 @@ static void lgm_clk_gate_disable(struct clk_hw *hw) struct lgm_clk_gate *gate = to_lgm_clk_gate(hw); unsigned int reg; - reg = GATE_HW_REG_DIS(gate->reg); - lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1); + if (gate->flags & GATE_CLK_HW) { + reg = GATE_HW_REG_DIS(gate->reg); + lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1); + } else { + gate->reg = 0; + } } static int lgm_clk_gate_is_enabled(struct clk_hw *hw) @@ -278,8 +286,12 @@ static int lgm_clk_gate_is_enabled(struct clk_hw *hw) struct lgm_clk_gate *gate = to_lgm_clk_gate(hw); unsigned int reg, ret; - reg = GATE_HW_REG_STAT(gate->reg); - ret = lgm_get_clk_val(gate->membase, reg, gate->shift, 1); + if (gate->flags & GATE_CLK_HW) { + reg = GATE_HW_REG_STAT(gate->reg); + ret = lgm_get_clk_val(gate->membase, reg, gate->shift, 1); + } else { + ret = gate->reg; + } return ret; } @@ -315,7 +327,8 @@ lgm_clk_register_gate(struct lgm_clk_provider *ctx, init.num_parents = pname ? 1 : 0; gate->membase = ctx->membase; - gate->reg = reg; + if (cflags & GATE_CLK_HW) + gate->reg = reg; gate->shift = shift; gate->flags = cflags; gate->hw.init = &init; @@ -326,7 +339,10 @@ lgm_clk_register_gate(struct lgm_clk_provider *ctx, return ERR_PTR(ret); if (cflags & CLOCK_FLAG_VAL_INIT) { - lgm_set_clk_val(gate->membase, reg, shift, 1, list->gate_val); + if (cflags & GATE_CLK_HW) + lgm_set_clk_val(gate->membase, reg, shift, 1, list->gate_val); + else + gate->reg = 1; } return hw; diff --git a/drivers/clk/x86/clk-cgu.h b/drivers/clk/x86/clk-cgu.h index 0aa0f35d63a0..73ce84345f81 100644 --- a/drivers/clk/x86/clk-cgu.h +++ b/drivers/clk/x86/clk-cgu.h @@ -197,6 +197,7 @@ struct lgm_clk_branch { /* clock flags definition */ #define CLOCK_FLAG_VAL_INIT BIT(16) #define MUX_CLK_SW BIT(17) +#define GATE_CLK_HW BIT(18) #define LGM_MUX(_id, _name, _pdata, _f, _reg, \ _shift, _width, _cf, _v) \ -- 2.17.1
| |