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

