From: Paul Kocialkowski <[email protected]>

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/>
---
 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

Reply via email to