[U-Boot] [PATCH 0/8] Allwinner DesignWare DRAM controller refactors and V3s SPL support

Allwinner H5/A64/V3s/R40 SoCs all feature a DRAM controller like the one in Allwinner H3, which seems from DesignWare.
They do not have properly licensed official DRAM initialization code (some have even no public readable code), but they can be supported by slightly altering the H3 code (this can be done by checking register dump).
This patchset mainly targets on Allwinner V3s support. Allwinner V3s have a co-packaged 64MiB DDR2 DRAM chip, and a DRAM controller nearly the same as the one in Allwinner H3 (the chip id of H3 is 0x1680, and V3s is 0x1681), but with only at most 16-bit bus width. Even the ZQ quirk in H3 is done in V3s (at least by stock boot0).
Patch 1 makes reusing H3 DRAM code a Kconfig option.
Patch 2 renames bus-width related macros, in order to prepare for 16-bit controllers.
Patch 3 really introduces 16-bit controllers support.
Patch 4 adds bank detection code to H3 DRAM initialization code, as some DDR2 chips have only 4 banks, not 8.
Patch 5 adds Kconfig options to select DRAM type and timing. This patch should be merged as soon as possible, as the work to adapt to Pine64 SoPine/Pinebook and Olimex TERES I needs it (these boards use A64 and LPDDR3 DRAM).
Patch 6 adds DDR2 support to the DW DRAM code.
Patch 7 adds timing for the DDR2 chip co-packaged with V3s.
Patch 8 really adds support for V3s DRAM controller -- currently only the DDR2 chip co-packaged with V3s will be used with this controller. More precise adjustments to the controller is still TODO, but current code can make it work.
Icenowy Zheng (8): sunxi: makes an invisible option for H3-like DRAM controllers sunxi: Rename bus-width related macros in H3 DRAM code sunxi: add option for 16-bit DW DRAM controller sunxi: add bank detection code to H3 DRAM initialization code sunxi: Add selective DRAM type and timing sunxi: add support for DDR2 DRAM for DesignWare-like DRAM controller sunxi: add timing info for the DDR2 in V3s SoC sunxi: add support for V3s DRAM controller
arch/arm/include/asm/arch-sunxi/dram.h | 4 +- .../{dram_sun8i_h3.h => dram_sunxi_dw.h} | 36 ++++- arch/arm/mach-sunxi/Makefile | 3 +- .../{dram_sun8i_h3.c => dram_sunxi_dw.c} | 179 +++++++-------------- arch/arm/mach-sunxi/dram_timings/Makefile | 2 + arch/arm/mach-sunxi/dram_timings/ddr2_v3s.c | 84 ++++++++++ arch/arm/mach-sunxi/dram_timings/ddr3_1333.c | 84 ++++++++++ board/sunxi/Kconfig | 60 +++++++ 8 files changed, 325 insertions(+), 127 deletions(-) rename arch/arm/include/asm/arch-sunxi/{dram_sun8i_h3.h => dram_sunxi_dw.h} (85%) rename arch/arm/mach-sunxi/{dram_sun8i_h3.c => dram_sunxi_dw.c} (79%) create mode 100644 arch/arm/mach-sunxi/dram_timings/Makefile create mode 100644 arch/arm/mach-sunxi/dram_timings/ddr2_v3s.c create mode 100644 arch/arm/mach-sunxi/dram_timings/ddr3_1333.c

Allwinner SoCs after H3 (e.g. A64, H5, R40, V3s) uses a H3-like DesignWare DRAM controller, which do not have official free DRAM initialization code, but can use modified dram_sun8i_h3.c.
Add a invisible option for easier DRAM initialization code reuse.
Signed-off-by: Icenowy Zheng icenowy@aosc.xyz Acked-by: Maxime Ripard maxime.ripard@free-electrons.com --- arch/arm/include/asm/arch-sunxi/dram.h | 4 ++-- .../include/asm/arch-sunxi/{dram_sun8i_h3.h => dram_sunxi_dw.h} | 0 arch/arm/mach-sunxi/Makefile | 2 +- arch/arm/mach-sunxi/{dram_sun8i_h3.c => dram_sunxi_dw.c} | 0 board/sunxi/Kconfig | 9 +++++++++ 5 files changed, 12 insertions(+), 3 deletions(-) rename arch/arm/include/asm/arch-sunxi/{dram_sun8i_h3.h => dram_sunxi_dw.h} (100%) rename arch/arm/mach-sunxi/{dram_sun8i_h3.c => dram_sunxi_dw.c} (100%)
diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 53e6d471d2..80abac95b8 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -24,8 +24,8 @@ #include <asm/arch/dram_sun8i_a33.h> #elif defined(CONFIG_MACH_SUN8I_A83T) #include <asm/arch/dram_sun8i_a83t.h> -#elif defined(CONFIG_MACH_SUN8I_H3) || defined(CONFIG_MACH_SUN50I) -#include <asm/arch/dram_sun8i_h3.h> +#elif defined(CONFIG_SUNXI_DRAM_DW) +#include <asm/arch/dram_sunxi_dw.h> #elif defined(CONFIG_MACH_SUN9I) #include <asm/arch/dram_sun9i.h> #else diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun8i_h3.h b/arch/arm/include/asm/arch-sunxi/dram_sunxi_dw.h similarity index 100% rename from arch/arm/include/asm/arch-sunxi/dram_sun8i_h3.h rename to arch/arm/include/asm/arch-sunxi/dram_sunxi_dw.h diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index 7daba1169c..b8f01e3b61 100644 --- a/arch/arm/mach-sunxi/Makefile +++ b/arch/arm/mach-sunxi/Makefile @@ -48,7 +48,7 @@ obj-$(CONFIG_MACH_SUN7I) += dram_sun4i.o obj-$(CONFIG_MACH_SUN8I_A23) += dram_sun8i_a23.o obj-$(CONFIG_MACH_SUN8I_A33) += dram_sun8i_a33.o obj-$(CONFIG_MACH_SUN8I_A83T) += dram_sun8i_a83t.o -obj-$(CONFIG_MACH_SUN8I_H3) += dram_sun8i_h3.o +obj-$(CONFIG_SUNXI_DRAM_DW) += dram_sunxi_dw.o obj-$(CONFIG_MACH_SUN9I) += dram_sun9i.o obj-$(CONFIG_MACH_SUN50I) += dram_sun8i_h3.o endif diff --git a/arch/arm/mach-sunxi/dram_sun8i_h3.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c similarity index 100% rename from arch/arm/mach-sunxi/dram_sun8i_h3.c rename to arch/arm/mach-sunxi/dram_sunxi_dw.c diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 56b7513fe3..e71fdaee86 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -42,6 +42,13 @@ config SUNXI_GEN_SUN6I separate ahb reset control registers, custom pmic bus, new style watchdog, etc.
+config SUNXI_DRAM_DW + bool + ---help--- + Select this for sunxi SoCs which uses a DRAM controller like the + DesignWare controller used in H3, mainly SoCs after H3, which do + not have official open-source DRAM initialization code, but can + use modified H3 DRAM initialization code.
choice prompt "Sunxi SoC Variant" @@ -113,6 +120,7 @@ config MACH_SUN8I_H3 select ARCH_SUPPORT_PSCI select SUNXI_GEN_SUN6I select SUPPORT_SPL + select SUNXI_DRAM_DW select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
config MACH_SUN8I_V3S @@ -135,6 +143,7 @@ config MACH_SUN50I select ARM64 select SUNXI_GEN_SUN6I select SUPPORT_SPL + select SUNXI_DRAM_DW
endchoice

The DesignWare DRAM controller used by H3 and newer SoCs use a bit to identify whether the DRAM is half-width.
As H3 itself come with 32-bit DRAM, the two modes of the bit used to be named "MCTL_CR_32BIT" and "MCTL_CR_16BIT", but for SoCs with 16-bit DRAM they're really 8-bit and 16-bit.
Rename the bit's macro, and also rename the variable name in dram_sun8i_h3.c.
This commit do not add 16-bit DRAM controller support, but the support will be introduced in next commit.
Signed-off-by: Icenowy Zheng icenowy@aosc.xyz --- arch/arm/include/asm/arch-sunxi/dram_sunxi_dw.h | 6 +++--- arch/arm/mach-sunxi/dram_sunxi_dw.c | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/dram_sunxi_dw.h b/arch/arm/include/asm/arch-sunxi/dram_sunxi_dw.h index 25d07d9863..48bd6f7c0f 100644 --- a/arch/arm/include/asm/arch-sunxi/dram_sunxi_dw.h +++ b/arch/arm/include/asm/arch-sunxi/dram_sunxi_dw.h @@ -52,9 +52,9 @@ struct sunxi_mctl_com_reg { #define MCTL_CR_SEQUENTIAL (0x1 << 15) #define MCTL_CR_INTERLEAVED (0x0 << 15)
-#define MCTL_CR_32BIT (0x1 << 12) -#define MCTL_CR_16BIT (0x0 << 12) -#define MCTL_CR_BUS_WIDTH(x) ((x) == 32 ? MCTL_CR_32BIT : MCTL_CR_16BIT) +#define MCTL_CR_FULL_WIDTH (0x1 << 12) +#define MCTL_CR_HALF_WIDTH (0x0 << 12) +#define MCTL_CR_BUS_FULL_WIDTH(x) ((x) << 12)
#define MCTL_CR_PAGE_SIZE(x) ((fls(x) - 4) << 8) #define MCTL_CR_ROW_BITS(x) (((x) - 1) << 4) diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c index 9f7cc7fd4c..0c73a43075 100644 --- a/arch/arm/mach-sunxi/dram_sunxi_dw.c +++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c @@ -28,7 +28,7 @@ #define LINES_PER_BYTE_LANE (BITS_PER_BYTE + 3) struct dram_para { u16 page_size; - u8 bus_width; + u8 bus_full_width; u8 dual_rank; u8 row_bits; const u8 dx_read_delays[NR_OF_BYTE_LANES][LINES_PER_BYTE_LANE]; @@ -358,7 +358,8 @@ static void mctl_set_cr(struct dram_para *para) (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
writel(MCTL_CR_BL8 | MCTL_CR_2T | MCTL_CR_DDR3 | MCTL_CR_INTERLEAVED | - MCTL_CR_EIGHT_BANKS | MCTL_CR_BUS_WIDTH(para->bus_width) | + MCTL_CR_EIGHT_BANKS | + MCTL_CR_BUS_FULL_WIDTH(para->bus_full_width) | (para->dual_rank ? MCTL_CR_DUAL_RANK : MCTL_CR_SINGLE_RANK) | MCTL_CR_PAGE_SIZE(para->page_size) | MCTL_CR_ROW_BITS(para->row_bits), &mctl_com->cr); @@ -471,7 +472,7 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para) }
/* set half DQ */ - if (para->bus_width != 32) { + if (!para->bus_full_width) { writel(0x0, &mctl_ctl->dx[2].gcr); writel(0x0, &mctl_ctl->dx[3].gcr); } @@ -509,7 +510,7 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para) ((readl(&mctl_ctl->dx[3].gsr[0]) >> 24) & 0x1)) { writel(0x0, &mctl_ctl->dx[2].gcr); writel(0x0, &mctl_ctl->dx[3].gcr); - para->bus_width = 16; + para->bus_full_width = 0; }
mctl_set_cr(para); @@ -613,7 +614,7 @@ unsigned long sunxi_dram_init(void)
struct dram_para para = { .dual_rank = 0, - .bus_width = 32, + .bus_full_width = 1, .row_bits = 15, .page_size = 4096,
participants (1)
-
Icenowy Zheng