diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 5b84cbee030b..4ed056b18d31 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -253,6 +253,22 @@ static void cpg_rzt2h_mstp_write(struct cpg_mssr_priv *priv, u16 offset, u32 val writel(value, base + RZT2H_MSTPCR_OFFSET(offset)); } +static void cpg_rzt2h_mstp_delay(u32 idx, bool bit_valid) +{ + unsigned int mask = bit_valid ? GENMASK(31, 0) : GENMASK(31, 5); + + if (idx == (MOD_CLK_PACK(1204) & mask)) { + /* LCDC needs 100 dummy reads, or 142us */ + udelay(142); + } else if (idx == (MOD_CLK_PACK(605) & mask)) { + /* RTC needs 300 dummy reads, or 428us */ + udelay(428); + } else { + /* default 7 dummy reads, or 10us */ + udelay(10); + } +} + static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) { struct mstp_clock *clock = to_mstp_clock(hw); @@ -312,7 +328,7 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) * register, we simply add a delay after the read operation. */ cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); - udelay(10); + cpg_rzt2h_mstp_delay(clock->index, true); return 0; } @@ -1142,7 +1158,7 @@ static int cpg_mssr_resume_noirq(struct device *dev) cpg_rzt2h_mstp_write(priv, priv->control_regs[reg], newval); /* See cpg_mstp_clock_endisable() on why this is necessary. */ cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); - udelay(10); + cpg_rzt2h_mstp_delay(reg * 32, false); continue; } else writel(newval, priv->pub.base0 + priv->control_regs[reg]);