1

clk: imx: composite-8m: Enable gate clk with mcore_booted

Bootloader might disable some CCM ROOT Slices. So if mcore_booted set with
display CCM ROOT disabled by Bootloader, kernel display BLK CTRL driver
imx8m_blk_ctrl_driver_init may hang the system because the BUS clk is
disabled.

Add back gate ops, but with disable doing nothing, then the CCM ROOT
will be enabled when used.

Fixes: bb7e897b00 ("clk: imx8m: check mcore_booted before register clk")
Reviewed-by: Ye Li <ye.li@nxp.com>
Reviewed-by: Jacky Bai <ping.bai@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
Link: https://lore.kernel.org/r/20240607133347.3291040-2-peng.fan@oss.nxp.com
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
This commit is contained in:
Peng Fan 2024-06-07 21:33:33 +08:00 committed by Abel Vesa
parent e52fd71333
commit 8f32e9dd09

View File

@ -204,6 +204,34 @@ static const struct clk_ops imx8m_clk_composite_mux_ops = {
.determine_rate = imx8m_clk_composite_mux_determine_rate, .determine_rate = imx8m_clk_composite_mux_determine_rate,
}; };
static int imx8m_clk_composite_gate_enable(struct clk_hw *hw)
{
struct clk_gate *gate = to_clk_gate(hw);
unsigned long flags;
u32 val;
spin_lock_irqsave(gate->lock, flags);
val = readl(gate->reg);
val |= BIT(gate->bit_idx);
writel(val, gate->reg);
spin_unlock_irqrestore(gate->lock, flags);
return 0;
}
static void imx8m_clk_composite_gate_disable(struct clk_hw *hw)
{
/* composite clk requires the disable hook */
}
static const struct clk_ops imx8m_clk_composite_gate_ops = {
.enable = imx8m_clk_composite_gate_enable,
.disable = imx8m_clk_composite_gate_disable,
.is_enabled = clk_gate_is_enabled,
};
struct clk_hw *__imx8m_clk_hw_composite(const char *name, struct clk_hw *__imx8m_clk_hw_composite(const char *name,
const char * const *parent_names, const char * const *parent_names,
int num_parents, void __iomem *reg, int num_parents, void __iomem *reg,
@ -217,6 +245,7 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
struct clk_mux *mux; struct clk_mux *mux;
const struct clk_ops *divider_ops; const struct clk_ops *divider_ops;
const struct clk_ops *mux_ops; const struct clk_ops *mux_ops;
const struct clk_ops *gate_ops;
mux = kzalloc(sizeof(*mux), GFP_KERNEL); mux = kzalloc(sizeof(*mux), GFP_KERNEL);
if (!mux) if (!mux)
@ -257,20 +286,22 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
div->flags = CLK_DIVIDER_ROUND_CLOSEST; div->flags = CLK_DIVIDER_ROUND_CLOSEST;
/* skip registering the gate ops if M4 is enabled */ /* skip registering the gate ops if M4 is enabled */
if (!mcore_booted) { gate = kzalloc(sizeof(*gate), GFP_KERNEL);
gate = kzalloc(sizeof(*gate), GFP_KERNEL); if (!gate)
if (!gate) goto free_div;
goto free_div;
gate_hw = &gate->hw; gate_hw = &gate->hw;
gate->reg = reg; gate->reg = reg;
gate->bit_idx = PCG_CGC_SHIFT; gate->bit_idx = PCG_CGC_SHIFT;
gate->lock = &imx_ccm_lock; gate->lock = &imx_ccm_lock;
} if (!mcore_booted)
gate_ops = &clk_gate_ops;
else
gate_ops = &imx8m_clk_composite_gate_ops;
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
mux_hw, mux_ops, div_hw, mux_hw, mux_ops, div_hw,
divider_ops, gate_hw, &clk_gate_ops, flags); divider_ops, gate_hw, gate_ops, flags);
if (IS_ERR(hw)) if (IS_ERR(hw))
goto free_gate; goto free_gate;