diff options
| author | Paul Kocialkowski <[email protected]> | 2026-01-29 00:57:16 +0100 |
|---|---|---|
| committer | Andre Przywara <[email protected]> | 2026-03-17 23:27:24 +0100 |
| commit | 3d769809474cfb9534c317d9a6a0a8ef51a47181 (patch) | |
| tree | ffb112d8c668bd05fafd807f91f8605d58e829f0 /arch | |
| parent | 256557dd9aae376afcc3c3bc23cd739f427e9dc7 (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.c | 61 |
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)); } |
