
The Allwinner A64 and H5 SoCs are both capable of use 3GiB capacity of 4GiB modules, and they both use the common DesignWare DRAM driver code.
Add size recalculation code for the driver.
Signed-off-by: Icenowy Zheng icenowy@aosc.io --- New patch in v2.
arch/arm/mach-sunxi/Kconfig | 1 + arch/arm/mach-sunxi/Makefile | 2 +- arch/arm/mach-sunxi/dram_sunxi_dw.c | 28 ++++++++++++++++++++++++++-- 3 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index b206472ead..0cdc34ea9a 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -108,6 +108,7 @@ config SUNXI_GEN_SUN6I
config SUNXI_DRAM_DW bool + select DRAM_CAN_RECALCULATE_SIZE ---help--- Select this for sunxi SoCs which uses a DRAM controller like the DesignWare controller used in H3, mainly SoCs after H3, which do diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index 183175340a..b403045272 100644 --- a/arch/arm/mach-sunxi/Makefile +++ b/arch/arm/mach-sunxi/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_MACH_SUN8I) += clock_sun6i.o endif obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o gtbus_sun9i.o
+obj-$(CONFIG_SUNXI_DRAM_DW) += dram_sunxi_dw.o ifdef CONFIG_SPL_BUILD obj-$(CONFIG_DRAM_SUN4I) += dram_sun4i.o obj-$(CONFIG_DRAM_SUN6I) += dram_sun6i.o @@ -40,6 +41,5 @@ obj-$(CONFIG_DRAM_SUN8I_A33) += dram_sun8i_a33.o obj-$(CONFIG_DRAM_SUN8I_A83T) += dram_sun8i_a83t.o obj-$(CONFIG_DRAM_SUN9I) += dram_sun9i.o obj-$(CONFIG_SPL_SPI_SUNXI) += spl_spi_sunxi.o -obj-$(CONFIG_SUNXI_DRAM_DW) += dram_sunxi_dw.o obj-$(CONFIG_SUNXI_DRAM_DW) += dram_timings/ endif diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c index 3bff1c46cd..f0232e63e7 100644 --- a/arch/arm/mach-sunxi/dram_sunxi_dw.c +++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c @@ -16,6 +16,30 @@ #include <asm/arch/cpu.h> #include <linux/kconfig.h>
+unsigned long long sunxi_dram_recalculate_size(void) +{ + struct sunxi_mctl_com_reg * const mctl_com = + (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE; + u32 cr_reg = readl(&mctl_com->cr); + u32 temp; + unsigned int dram_size_shift; + + temp = (cr_reg >> 8) & 0xf; /* page size code */ + dram_size_shift = (temp + 3); + + temp = (cr_reg >> 4) & 0xf; /* row width code */ + dram_size_shift += (temp + 1); + + temp = (cr_reg >> 2) & 0x3; /* bank number code */ + dram_size_shift += (temp + 2); + + temp = cr_reg & 0x3; /* rank number code */ + dram_size_shift += temp; + + return 1ULL << dram_size_shift; +} + +#ifdef CONFIG_SPL_BUILD static void mctl_phy_init(u32 val) { struct sunxi_mctl_ctl_reg * const mctl_ctl = @@ -763,6 +787,6 @@ unsigned long long sunxi_dram_init(void) mctl_auto_detect_dram_size(socid, ¶); mctl_set_cr(socid, ¶);
- return (1ULL << (para.row_bits + para.bank_bits)) * para.page_size * - (para.dual_rank ? 2 : 1); + return sunxi_dram_recalculate_size(); } +#endif