[U-Boot] [PATCH v2 6/6] sunxi: add size recalculation code for common DesignWare DRAM driver

Icenowy Zheng
2018-03-23T08:18:57Z

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, &para);
mctl_set_cr(socid, &para);

- return (1ULL << (para.row_bits + para.bank_bits)) * para.page_size *
- (para.dual_rank ? 2 : 1);
+ return sunxi_dram_recalculate_size();
}
+#endif
--
2.15.1