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

51 views
Skip to first unread message

Icenowy Zheng

unread,
Mar 11, 2017, 10:03:01 AM3/11/17
to Jagan Teki, Maxime Ripard, Andre Przywara, Jens Kuske, Chen-Yu Tsai, linux...@googlegroups.com, u-b...@lists.denx.de, Icenowy Zheng
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

--
2.12.0

Icenowy Zheng

unread,
Mar 11, 2017, 10:04:25 AM3/11/17
to Jagan Teki, Maxime Ripard, Andre Przywara, Jens Kuske, Chen-Yu Tsai, linux...@googlegroups.com, u-b...@lists.denx.de, Icenowy Zheng
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 <ice...@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,

--
2.12.0

Icenowy Zheng

unread,
Mar 11, 2017, 10:04:29 AM3/11/17
to Jagan Teki, Maxime Ripard, Andre Przywara, Jens Kuske, Chen-Yu Tsai, linux...@googlegroups.com, u-b...@lists.denx.de, Icenowy Zheng
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 <ice...@aosc.xyz>
Acked-by: Maxime Ripard <maxime...@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

--
2.12.0

Reply all
Reply to author
Forward
0 new messages