[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