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:
parent
e52fd71333
commit
8f32e9dd09
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user