[PATCH 32/41] ddr: imx8ulp: Update the ddr init flow

Peng Fan (OSS) peng.fan at oss.nxp.com
Mon Jan 23 10:16:51 CET 2023


From: Jacky Bai <ping.bai at nxp.com>

Update the ddr init flow to support LPDDR3 and PLL bypass mode.

Reviewed-by: Ye Li <ye.li at nxp.com>
Signed-off-by: Jacky Bai <ping.bai at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/ddr/imx/imx8ulp/ddr_init.c | 55 +++++++++++++++++++++++-------
 1 file changed, 43 insertions(+), 12 deletions(-)

diff --git a/drivers/ddr/imx/imx8ulp/ddr_init.c b/drivers/ddr/imx/imx8ulp/ddr_init.c
index a5a9fd8d7c8..3f04f533825 100644
--- a/drivers/ddr/imx/imx8ulp/ddr_init.c
+++ b/drivers/ddr/imx/imx8ulp/ddr_init.c
@@ -31,6 +31,7 @@
 #define DENALI_CTL_25		(DDR_CTL_BASE_ADDR + 4 * 25)
 
 #define DENALI_PHY_1624		(DDR_PHY_BASE_ADDR + 4 * 1624)
+#define DENALI_PHY_1625		(DDR_PHY_BASE_ADDR + 4 * 1625)
 #define DENALI_PHY_1537		(DDR_PHY_BASE_ADDR + 4 * 1537)
 #define PHY_FREQ_SEL_MULTICAST_EN(X)	((X) << 8)
 #define PHY_FREQ_SEL_INDEX(X)		((X) << 16)
@@ -82,25 +83,39 @@ int ddr_calibration(unsigned int fsp_table[3])
 	u32 int_status_init, phy_freq_req, phy_freq_type;
 	u32 lock_0, lock_1, lock_2;
 	u32 freq_chg_pt, freq_chg_cnt;
+	u32 is_lpddr4 = 0;
 
 	if (IS_ENABLED(CONFIG_IMX8ULP_DRAM_PHY_PLL_BYPASS)) {
 		ddr_enable_pll_bypass();
 		freq_chg_cnt = 0;
 		freq_chg_pt = 0;
 	} else {
-		reg_val = readl(DENALI_CTL_250);
-		if (((reg_val >> 16) & 0x3) == 1)
-			freq_chg_cnt = 2;
-		else
-			freq_chg_cnt = 3;
-
-		reg_val = readl(DENALI_PI_12);
-		if (reg_val == 0x3) {
-			freq_chg_pt = 1;
-		} else if (reg_val == 0x7) {
-			freq_chg_pt = 2;
+		reg_val = (readl(DENALI_CTL_00) >> 8) & 0xf;
+		if (reg_val == 0x7) {
+			/* LPDDR3 type */
+			set_ddr_clk(fsp_table[1] >> 1);
+			freq_chg_cnt = 0;
+			freq_chg_pt = 0;
+		} else if (reg_val == 0xb) {
+			/* LPDDR4/4x type */
+			is_lpddr4 = 1;
+			reg_val = readl(DENALI_CTL_250);
+			if (((reg_val >> 16) & 0x3) == 1)
+				freq_chg_cnt = 2;
+			else
+				freq_chg_cnt = 3;
+
+			reg_val = readl(DENALI_PI_12);
+			if (reg_val == 0x3) {
+				freq_chg_pt = 1;
+			} else if (reg_val == 0x7) {
+				freq_chg_pt = 2;
+			} else {
+				printf("frequency map(0x%x) is wrong, please check!\r\n", reg_val);
+				return -1;
+			}
 		} else {
-			printf("frequency map(0x%x) is wrong, please check!\r\n", reg_val);
+			printf("Incorrect DDR type configured!\r\n");
 			return -1;
 		}
 	}
@@ -179,6 +194,22 @@ int ddr_calibration(unsigned int fsp_table[3])
 	}
 
 	debug("De-Skew PLL is locked and ready\n");
+
+	/* Change LPDDR4 FREQ1 to bypass mode if it is lower than 200MHz */
+	if (is_lpddr4 && fsp_table[1] < 400) {
+		/* Set FREQ1 to bypass mode */
+		reg_val = PHY_FREQ_SEL_MULTICAST_EN(0) | PHY_FREQ_SEL_INDEX(0);
+		writel(reg_val, DENALI_PHY_1537);
+
+		/* PHY_PLL_BYPASS=0x1 (DENALI_PHY_1624) */
+		reg_val = readl(DENALI_PHY_1624) | 0x1;
+		writel(reg_val, DENALI_PHY_1624);
+
+		/* DENALI_PHY_1625: bypass mode in PHY PLL */
+		reg_val = readl(DENALI_PHY_1625) & ~0xf;
+		writel(reg_val, DENALI_PHY_1625);
+	}
+
 	return 0;
 }
 
-- 
2.36.0



More information about the U-Boot mailing list