Some Allwinner SoCs features a DesignWare-like controller with only 16
bit bus width.

Add support for them.

Signed-off-by: Icenowy Zheng <icen...@aosc.xyz>
---
 arch/arm/mach-sunxi/dram_sunxi_dw.c | 34 +++++++++++++++++++++++++++++-----
 board/sunxi/Kconfig                 | 16 ++++++++++++++++
 2 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c 
b/arch/arm/mach-sunxi/dram_sunxi_dw.c
index 0c73a43075..b08998c0d1 100644
--- a/arch/arm/mach-sunxi/dram_sunxi_dw.c
+++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c
@@ -298,6 +298,13 @@ static void mctl_h3_zq_calibration_quirk(struct dram_para 
*para)
 {
        struct sunxi_mctl_ctl_reg * const mctl_ctl =
                        (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+       int zq_count;
+
+#if defined CONFIG_SUNXI_DRAM_DW_16BIT
+       zq_count = 4;
+#else
+       zq_count = 6;
+#endif
 
        if ((readl(SUNXI_SRAMC_BASE + 0x24) & 0xff) == 0 &&
            (readl(SUNXI_SRAMC_BASE + 0xf0) & 0x1) == 0) {
@@ -326,7 +333,7 @@ static void mctl_h3_zq_calibration_quirk(struct dram_para 
*para)
 
                writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]);
 
-               for (i = 0; i < 6; i++) {
+               for (i = 0; i < zq_count; i++) {
                        u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
 
                        writel((zq << 20) | (zq << 16) | (zq << 12) |
@@ -348,7 +355,9 @@ static void mctl_h3_zq_calibration_quirk(struct dram_para 
*para)
 
                writel((zq_val[1] << 16) | zq_val[0], &mctl_ctl->zqdr[0]);
                writel((zq_val[3] << 16) | zq_val[2], &mctl_ctl->zqdr[1]);
-               writel((zq_val[5] << 16) | zq_val[4], &mctl_ctl->zqdr[2]);
+               if (zq_count > 4)
+                       writel((zq_val[5] << 16) | zq_val[4],
+                              &mctl_ctl->zqdr[2]);
        }
 }
 
@@ -473,8 +482,14 @@ static int mctl_channel_init(uint16_t socid, struct 
dram_para *para)
 
        /* set half DQ */
        if (!para->bus_full_width) {
+#if defined CONFIG_SUNXI_DRAM_DW_32BIT
                writel(0x0, &mctl_ctl->dx[2].gcr);
                writel(0x0, &mctl_ctl->dx[3].gcr);
+#elif defined CONFIG_SUNXI_DRAM_DW_16BIT
+               writel(0x0, &mctl_ctl->dx[1].gcr);
+#else
+#error Unsupported DRAM bus width!
+#endif
        }
 
        /* data training configuration */
@@ -499,20 +514,29 @@ static int mctl_channel_init(uint16_t socid, struct 
dram_para *para)
        /* detect ranks and bus width */
        if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20)) {
                /* only one rank */
-               if (((readl(&mctl_ctl->dx[0].gsr[0]) >> 24) & 0x2) ||
-                   ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x2)) {
+               if (((readl(&mctl_ctl->dx[0].gsr[0]) >> 24) & 0x2)
+#if defined CONFIG_SUNXI_DRAM_DW_32BIT
+                   || ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x2)
+#endif
+                   ) {
                        clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
                        para->dual_rank = 0;
                }
 
                /* only half DQ width */
+#if defined CONFIG_SUNXI_DRAM_DW_32BIT
                if (((readl(&mctl_ctl->dx[2].gsr[0]) >> 24) & 0x1) ||
                    ((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_full_width = 0;
                }
-
+#elif defined CONFIG_SUNXI_DRAM_DW_16BIT
+               if ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x1) {
+                       writel(0x0, &mctl_ctl->dx[1].gcr);
+                       para->bus_full_width = 0;
+               }
+#endif
                mctl_set_cr(para);
                udelay(20);
 
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index e71fdaee86..d8a1e341e8 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -50,6 +50,20 @@ config SUNXI_DRAM_DW
        not have official open-source DRAM initialization code, but can
        use modified H3 DRAM initialization code.
 
+if SUNXI_DRAM_DW
+config SUNXI_DRAM_DW_16BIT
+       bool
+       ---help---
+       Select this for sunxi SoCs with DesignWare DRAM controller and
+       have only 16-bit memory buswidth.
+
+config SUNXI_DRAM_DW_32BIT
+       bool
+       ---help---
+       Select this for sunxi SoCs with DesignWare DRAM controller with
+       32-bit memory buswidth.
+endif
+
 choice
        prompt "Sunxi SoC Variant"
        optional
@@ -121,6 +135,7 @@ config MACH_SUN8I_H3
        select SUNXI_GEN_SUN6I
        select SUPPORT_SPL
        select SUNXI_DRAM_DW
+       select SUNXI_DRAM_DW_32BIT
        select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
 
 config MACH_SUN8I_V3S
@@ -144,6 +159,7 @@ config MACH_SUN50I
        select SUNXI_GEN_SUN6I
        select SUPPORT_SPL
        select SUNXI_DRAM_DW
+       select SUNXI_DRAM_DW_32BIT
 
 endchoice
 
-- 
2.12.0

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to