[PATCH v3 3/4] clk: mxl: Add option to override gate clks enable/disable

From: Rahul Tanwar
Date: Wed Oct 05 2022 - 05:37:05 EST


In MxL's LGM SoC, gate clocks can be controlled either from CGU clk driver
i.e. this driver or directly from power management driver/daemon. It is
dependent on the power policy/profile requirements of the end product.

To support such use cases, provide option to override gate clks enable/disable
by adding a flag GATE_CLK_HW which controls if these gate clks are controlled
by HW i.e. this driver or overridden in order to allow it to be controlled
by power profiles instead.

Signed-off-by: Rahul Tanwar <rtanwar@xxxxxxxxxxxxx>
---
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