[PATCH 16/20] imx8ulp: clock: Handle the DDRLOCKED when setting DDR clock

Peng Fan (OSS) peng.fan at oss.nxp.com
Fri Oct 29 03:46:30 CEST 2021


From: Ye Li <ye.li at nxp.com>

The DDRLOCKED bit in CGC2 DDRCLK will auto lock up and down by HW
according to DDR DIV updating or DDR CLK halt status change. So DDR
PCC disable/enable will trigger the lock up/down flow. We
need wait until unlock to ensure clock is ready.

And before configuring the DDRCLK DIV, we need polling the DDRLOCKED
until it is unlocked. Otherwise writing ti DIV bits will not set.

Reviewed-by: Peng Fan <peng.fan at nxp.com>
Signed-off-by: Ye Li <ye.li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm/include/asm/arch-imx8ulp/cgc.h |  1 +
 arch/arm/mach-imx/imx8ulp/cgc.c         | 11 +++++++++++
 arch/arm/mach-imx/imx8ulp/clock.c       |  6 ++++++
 3 files changed, 18 insertions(+)

diff --git a/arch/arm/include/asm/arch-imx8ulp/cgc.h b/arch/arm/include/asm/arch-imx8ulp/cgc.h
index e15ef1d6c1..ad3edc85ad 100644
--- a/arch/arm/include/asm/arch-imx8ulp/cgc.h
+++ b/arch/arm/include/asm/arch-imx8ulp/cgc.h
@@ -152,6 +152,7 @@ void cgc1_soscdiv_init(void);
 void cgc1_init_core_clk(void);
 void cgc2_pll4_init(void);
 void cgc2_ddrclk_config(u32 src, u32 div);
+void cgc2_ddrclk_wait_unlock(void);
 u32 cgc1_sosc_div(enum cgc_clk clk);
 void cgc1_enet_stamp_sel(u32 clk_src);
 void cgc2_pll4_pfd_config(enum cgc_clk pllpfd, u32 pfd);
diff --git a/arch/arm/mach-imx/imx8ulp/cgc.c b/arch/arm/mach-imx/imx8ulp/cgc.c
index fc84f3f293..38bcbb91e6 100644
--- a/arch/arm/mach-imx/imx8ulp/cgc.c
+++ b/arch/arm/mach-imx/imx8ulp/cgc.c
@@ -269,12 +269,23 @@ void cgc2_pll4_pfddiv_config(enum cgc_clk pllpfddiv, u32 div)
 
 void cgc2_ddrclk_config(u32 src, u32 div)
 {
+	/* If reg lock is set, wait until unlock by HW */
+	/* This lock is triggered by div updating and ddrclk halt status change, */
+	while ((readl(&cgc2_regs->ddrclk) & BIT(31)))
+		;
+
 	writel((src << 28) | (div << 21), &cgc2_regs->ddrclk);
 	/* wait for DDRCLK switching done */
 	while (!(readl(&cgc2_regs->ddrclk) & BIT(27)))
 		;
 }
 
+void cgc2_ddrclk_wait_unlock(void)
+{
+	while ((readl(&cgc2_regs->ddrclk) & BIT(31)))
+		;
+}
+
 void cgc2_lpav_init(enum cgc_clk clk)
 {
 	u32 i, scs, reg;
diff --git a/arch/arm/mach-imx/imx8ulp/clock.c b/arch/arm/mach-imx/imx8ulp/clock.c
index 961702310c..91580b2c29 100644
--- a/arch/arm/mach-imx/imx8ulp/clock.c
+++ b/arch/arm/mach-imx/imx8ulp/clock.c
@@ -107,6 +107,9 @@ void init_clk_ddr(void)
 	/* enable ddr pcc */
 	writel(0xd0000000, PCC5_LPDDR4_ADDR);
 
+	/* Wait until ddrclk reg lock bit is cleared, so that the div update is finished */
+	cgc2_ddrclk_wait_unlock();
+
 	/* for debug */
 	/* setclkout_ddr(); */
 }
@@ -144,6 +147,9 @@ int set_ddr_clk(u32 phy_freq_mhz)
 		return -EINVAL;
 	}
 
+	/* Wait until ddrclk reg lock bit is cleared, so that the div update is finished */
+	cgc2_ddrclk_wait_unlock();
+
 	return 0;
 }
 
-- 
2.30.0



More information about the U-Boot mailing list