Commit 8f32e9dd authored by Peng Fan's avatar Peng Fan Committed by Abel Vesa
Browse files

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: bb7e897b ("clk: imx8m: check mcore_booted before register clk")
Reviewed-by: default avatarYe Li <ye.li@nxp.com>
Reviewed-by: default avatarJacky Bai <ping.bai@nxp.com>
Signed-off-by: default avatarPeng Fan <peng.fan@nxp.com>
Reviewed-by: default avatarAbel Vesa <abel.vesa@linaro.org>
Link: https://lore.kernel.org/r/20240607133347.3291040-2-peng.fan@oss.nxp.com


Signed-off-by: default avatarAbel Vesa <abel.vesa@linaro.org>
parent e52fd713
Loading
Loading
Loading
Loading
+42 −11
Original line number Diff line number Diff line
@@ -204,6 +204,34 @@ static const struct clk_ops imx8m_clk_composite_mux_ops = {
	.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,
					const char * const *parent_names,
					int num_parents, void __iomem *reg,
@@ -217,6 +245,7 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
	struct clk_mux *mux;
	const struct clk_ops *divider_ops;
	const struct clk_ops *mux_ops;
	const struct clk_ops *gate_ops;

	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
	if (!mux)
@@ -257,7 +286,6 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
	div->flags = CLK_DIVIDER_ROUND_CLOSEST;

	/* skip registering the gate ops if M4 is enabled */
	if (!mcore_booted) {
	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
	if (!gate)
		goto free_div;
@@ -266,11 +294,14 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
	gate->reg = reg;
	gate->bit_idx = PCG_CGC_SHIFT;
	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,
			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))
		goto free_gate;