summaryrefslogtreecommitdiff
path: root/arch/arm/mach-sunxi
diff options
context:
space:
mode:
authorIcenowy Zheng <icenowy@aosc.xyz>2017-06-03 09:10:16 (GMT)
committerJagan Teki <jagan@amarulasolutions.com>2017-06-08 17:07:55 (GMT)
commit87098d701da77f264c9cbed67a5d6fb27fbaaf3f (patch)
treed4321481b59e6f2969efd57b810f91737c28c4a5 /arch/arm/mach-sunxi
parentf43a009959e6c1f1ace8b76ef525651ac4729c9d (diff)
downloadu-boot-87098d701da77f264c9cbed67a5d6fb27fbaaf3f.tar.xz
sunxi: add option for 16-bit DW DRAM controller
Some Allwinner SoCs features a DesignWare-like controller with only 16 bit bus width. Add support for them. Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz> Reviewed-by: Jagan Teki <jagan@amarulasolutions.com> Tested-by: Jagan Teki <jagan@amarulasolutions.com>
Diffstat (limited to 'arch/arm/mach-sunxi')
-rw-r--r--arch/arm/mach-sunxi/Kconfig17
-rw-r--r--arch/arm/mach-sunxi/dram_sunxi_dw.c33
2 files changed, 46 insertions, 4 deletions
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 11da1ab..8b8fc20 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -37,11 +37,26 @@ 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
+
config MACH_SUNXI_H3_H5
bool
select DM_I2C
select SUNXI_DE2
select SUNXI_DRAM_DW
+ select SUNXI_DRAM_DW_32BIT
select SUNXI_GEN_SUN6I
select SUPPORT_SPL
@@ -127,6 +142,7 @@ config MACH_SUN8I_R40
select SUNXI_GEN_SUN6I
select SUPPORT_SPL
select SUNXI_DRAM_DW
+ select SUNXI_DRAM_DW_32BIT
config MACH_SUN8I_V3S
bool "sun8i (Allwinner V3s)"
@@ -153,6 +169,7 @@ config MACH_SUN50I
select SUNXI_HIGH_SRAM
select SUPPORT_SPL
select SUNXI_DRAM_DW
+ select SUNXI_DRAM_DW_32BIT
select FIT
select SPL_LOAD_FIT
diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c
index 77fa6c2..de683a1 100644
--- a/arch/arm/mach-sunxi/dram_sunxi_dw.c
+++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c
@@ -380,6 +380,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) {
@@ -408,7 +415,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) |
@@ -430,7 +437,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]);
}
}
@@ -580,8 +589,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 */
@@ -612,19 +627,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(socid, para);
udelay(20);