[PATCH v2 2/3] sunxi: a133: dram: Fix PHY dx delays offsets and add dmb

Paul Kocialkowski contact at paulk.fr
Thu Jan 29 00:57:16 CET 2026


From: Paul Kocialkowski <paulk at sys-base.io>

Some of the offsets for the DRAM PHY dx delays are wrong (as compared
to the H616 code and the reference binary) since the
mctl_phy_dx_delay0_inner function does not perform the correct
calculation for some of them.

Introduce a mctl_phy_dx_delay0_inner0 to fix the incorrect offsets and
rename the existing function to mctl_phy_dx_delay0_inner1 for the
offsets it correctly handles.

Also add memory barriers that are also present in the H616 code while
at it.

This fixes detection of 4 GiB DRAM on some boards using LPDDR4.

Signed-off-by: Paul Kocialkowski <paulk at sys-base.io>
Sponsored-by: MEC Electronics GmbH <https://www.mec.at/>
---
 arch/arm/mach-sunxi/dram_sun50i_a133.c | 61 +++++++++++++++++---------
 1 file changed, 41 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-sunxi/dram_sun50i_a133.c b/arch/arm/mach-sunxi/dram_sun50i_a133.c
index 204810aecf2a..568dc1eea2ea 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_a133.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_a133.c
@@ -931,7 +931,24 @@ static inline void mctl_phy_dx_delay1_inner(u32 *base, u32 val1, u32 val2)
 	writel_relaxed(val2, ptr + 48);
 }
 
-static inline void mctl_phy_dx_delay0_inner(u32 *base1, u32 *base2, u32 val1,
+static inline void mctl_phy_dx_delay0_inner0(u32 *base1, u32 *base2, u32 val1,
+					    u32 val2)
+{
+	u32 *ptr = base1;
+
+	for (int i = 0; i < 9; i++) {
+		writel_relaxed(val1, ptr);
+		writel_relaxed(val1, ptr + 0x30);
+		ptr += 2;
+	}
+
+	writel_relaxed(val2, base2);
+	writel_relaxed(val2, base2 + 48);
+	writel_relaxed(val2, ptr);
+	writel_relaxed(val2, base2 + 24);
+}
+
+static inline void mctl_phy_dx_delay0_inner1(u32 *base1, u32 *base2, u32 val1,
 					    u32 val2)
 {
 	u32 *ptr = base1;
@@ -975,6 +992,8 @@ static void mctl_phy_dx_delay_compensation(const struct dram_para *para)
 					 (para->tpr11 >> 24) & 0x3f,
 					 (para->para0 >> 24) & 0x3f);
 
+		dmb();
+
 		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1);
 	}
 
@@ -982,25 +1001,27 @@ static void mctl_phy_dx_delay_compensation(const struct dram_para *para)
 		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, BIT(7));
 		clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, BIT(2));
 
-		mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480),
-					 (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x528),
-					 para->tpr12 & 0x3f,
-					 para->tpr14 & 0x3f);
-
-		mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4),
-					 (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x52c),
-					 (para->tpr12 >> 8) & 0x3f,
-					 (para->tpr14 >> 8) & 0x3f);
-
-		mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600),
-					 (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x6a8),
-					 (para->tpr12 >> 16) & 0x3f,
-					 (para->tpr14 >> 16) & 0x3f);
-
-		mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x6ac),
-					 (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x528),
-					 (para->tpr12 >> 24) & 0x3f,
-					 (para->tpr14 >> 24) & 0x3f);
+		mctl_phy_dx_delay0_inner0((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480),
+					  (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x528),
+					  para->tpr12 & 0x3f,
+					  para->tpr14 & 0x3f);
+
+		mctl_phy_dx_delay0_inner1((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4),
+					  (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x52c),
+					  (para->tpr12 >> 8) & 0x3f,
+					  (para->tpr14 >> 8) & 0x3f);
+
+		mctl_phy_dx_delay0_inner0((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600),
+					  (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x6a8),
+					  (para->tpr12 >> 16) & 0x3f,
+					  (para->tpr14 >> 16) & 0x3f);
+
+		mctl_phy_dx_delay0_inner1((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x654),
+					  (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x6ac),
+					  (para->tpr12 >> 24) & 0x3f,
+					  (para->tpr14 >> 24) & 0x3f);
+
+		dmb();
 
 		setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, BIT(7));
 	}
-- 
2.52.0



More information about the U-Boot mailing list