summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorPaul Kocialkowski <[email protected]>2026-01-29 00:57:16 +0100
committerAndre Przywara <[email protected]>2026-03-17 23:27:24 +0100
commit3d769809474cfb9534c317d9a6a0a8ef51a47181 (patch)
treeffb112d8c668bd05fafd807f91f8605d58e829f0 /arch
parent256557dd9aae376afcc3c3bc23cd739f427e9dc7 (diff)
sunxi: a133: dram: Fix PHY dx delays offsets and add dmb
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 <[email protected]> Sponsored-by: MEC Electronics GmbH <https://www.mec.at/> Acked-by: Jernej Skrabec <[email protected]>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-sunxi/dram_sun50i_a133.c61
1 files 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 1496f99624d..e5c46e036cb 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_a133.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_a133.c
@@ -871,7 +871,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;
@@ -915,6 +932,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);
}
@@ -922,25 +941,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));
}