summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-06-09 11:36:57 +0200
committerIan Campbell <ijc@hellion.org.uk>2014-07-06 20:12:44 +0100
commit745325a97d172a71dea4ec7528224ed63973d601 (patch)
treed71f3e1391a43172f40644c81518648cc437f04f
parentc7e79dec85f324565cee03f5be1d1a7765481573 (diff)
downloadblackbird-obmc-uboot-745325a97d172a71dea4ec7528224ed63973d601.tar.gz
blackbird-obmc-uboot-745325a97d172a71dea4ec7528224ed63973d601.zip
sunxi: Add sun4i support
Add support for the Allwinner A10 SoC also known as the Allwinner sun4i family, and add the Cubieboard board which uses the A10 SoC. Compared to sun7 only the DRAM controller is a bit different: -Controller reset bits are inverted, but only for Rev. A -Different hpcr values -No MBUS on sun4i -Various other initialization changes Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net> Signed-off-by: Stefan Roese <sr@denx.de> Signed-off-by: Oliver Schinagl <oliver@schinagl.nl> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Ian Campbell <ijc@hellion.org.uk>
-rw-r--r--arch/arm/cpu/armv7/sunxi/Makefile2
-rw-r--r--arch/arm/cpu/armv7/sunxi/cpu_info.c7
-rw-r--r--arch/arm/cpu/armv7/sunxi/dram.c81
-rw-r--r--board/sunxi/Makefile1
-rw-r--r--board/sunxi/dram_cubieboard.c31
-rw-r--r--boards.cfg1
-rw-r--r--include/configs/sun4i.h23
7 files changed, 143 insertions, 3 deletions
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index a64bfa18e0..856d353528 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -11,6 +11,7 @@ obj-y += timer.o
obj-y += board.o
obj-y += clock.o
obj-y += pinmux.o
+obj-$(CONFIG_SUN4I) += clock_sun4i.o
obj-$(CONFIG_SUN7I) += clock_sun4i.o
ifndef CONFIG_SPL_BUILD
@@ -18,6 +19,7 @@ obj-y += cpu_info.o
endif
ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_SUN4I) += dram.o
obj-$(CONFIG_SUN7I) += dram.o
ifdef CONFIG_SPL_FEL
obj-y += start.o
diff --git a/arch/arm/cpu/armv7/sunxi/cpu_info.c b/arch/arm/cpu/armv7/sunxi/cpu_info.c
index b4c3d5c6dd..b4b5089fec 100644
--- a/arch/arm/cpu/armv7/sunxi/cpu_info.c
+++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c
@@ -13,7 +13,14 @@
#ifdef CONFIG_DISPLAY_CPUINFO
int print_cpuinfo(void)
{
+#ifdef CONFIG_SUN4I
+ puts("CPU: Allwinner A10 (SUN4I)\n");
+#elif defined CONFIG_SUN7I
puts("CPU: Allwinner A20 (SUN7I)\n");
+#else
+#warning Please update cpu_info.c with correct CPU information
+ puts("CPU: SUNXI Family\n");
+#endif
return 0;
}
#endif
diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c
index b43c4b41d3..1de752904b 100644
--- a/arch/arm/cpu/armv7/sunxi/dram.c
+++ b/arch/arm/cpu/armv7/sunxi/dram.c
@@ -53,16 +53,37 @@ static void mctl_ddr3_reset(void)
struct sunxi_dram_reg *dram =
(struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
- clrbits_le32(&dram->mcr, DRAM_MCR_RESET);
- udelay(2);
- setbits_le32(&dram->mcr, DRAM_MCR_RESET);
+#ifdef CONFIG_SUN4I
+ struct sunxi_timer_reg *timer =
+ (struct sunxi_timer_reg *)SUNXI_TIMER_BASE;
+ u32 reg_val;
+
+ writel(0, &timer->cpu_cfg);
+ reg_val = readl(&timer->cpu_cfg);
+
+ if ((reg_val & CPU_CFG_CHIP_VER_MASK) !=
+ CPU_CFG_CHIP_VER(CPU_CFG_CHIP_REV_A)) {
+ setbits_le32(&dram->mcr, DRAM_MCR_RESET);
+ udelay(2);
+ clrbits_le32(&dram->mcr, DRAM_MCR_RESET);
+ } else
+#endif
+ {
+ clrbits_le32(&dram->mcr, DRAM_MCR_RESET);
+ udelay(2);
+ setbits_le32(&dram->mcr, DRAM_MCR_RESET);
+ }
}
static void mctl_set_drive(void)
{
struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+#ifdef CONFIG_SUN7I
clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3) | (0x3 << 28),
+#else
+ clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3),
+#endif
DRAM_MCR_MODE_EN(0x3) |
0xffc);
}
@@ -134,6 +155,16 @@ static void mctl_enable_dllx(u32 phase)
}
static u32 hpcr_value[32] = {
+#ifdef CONFIG_SUN4I
+ 0x0301, 0x0301, 0x0301, 0x0301,
+ 0x0301, 0x0301, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0x1031, 0x1031, 0x0735, 0x5031,
+ 0x1035, 0x0731, 0x1031, 0x0735,
+ 0x1035, 0x1031, 0x0731, 0x1035,
+ 0x1031, 0x0301, 0x0301, 0x0731
+#endif
#ifdef CONFIG_SUN7I
0x0301, 0x0301, 0x0301, 0x0301,
0x0301, 0x0301, 0x0301, 0x0301,
@@ -223,22 +254,32 @@ static void mctl_setup_dram_clock(u32 clk)
clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
#endif
+#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
/* setup MBUS clock */
reg_val = CCM_MBUS_CTRL_GATE |
CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL6) |
CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(2)) |
CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2));
writel(reg_val, &ccm->mbus_clk_cfg);
+#endif
/*
* open DRAMC AHB & DLL register clock
* close it first
*/
+#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
+#else
+ clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
+#endif
udelay(22);
/* then open it */
+#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
+#else
+ setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
+#endif
udelay(22);
}
@@ -385,6 +426,13 @@ static void dramc_clock_output_en(u32 on)
else
clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
#endif
+#ifdef CONFIG_SUN4I
+ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+ if (on)
+ setbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
+ else
+ clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
+#endif
}
static const u16 tRFC_table[2][6] = {
@@ -421,11 +469,19 @@ unsigned long dramc_init(struct dram_para *para)
mctl_setup_dram_clock(para->clock);
/* reset external DRAM */
+#ifndef CONFIG_SUN7I
+ mctl_ddr3_reset();
+#endif
mctl_set_drive();
/* dram clock off */
dramc_clock_output_en(0);
+#ifdef CONFIG_SUN4I
+ /* select dram controller 1 */
+ writel(DRAM_CSEL_MAGIC, &dram->csel);
+#endif
+
mctl_itm_disable();
mctl_enable_dll0(para->tpr3);
@@ -482,6 +538,9 @@ unsigned long dramc_init(struct dram_para *para)
mctl_ddr3_reset();
else
setbits_le32(&dram->mcr, DRAM_MCR_RESET);
+#else
+ /* dram clock on */
+ dramc_clock_output_en(1);
#endif
udelay(1);
@@ -490,6 +549,22 @@ unsigned long dramc_init(struct dram_para *para)
mctl_enable_dllx(para->tpr3);
+#ifdef CONFIG_SUN4I
+ /* set odt impedance divide ratio */
+ reg_val = ((para->zq) >> 8) & 0xfffff;
+ reg_val |= ((para->zq) & 0xff) << 20;
+ reg_val |= (para->zq) & 0xf0000000;
+ writel(reg_val, &dram->zqcr0);
+#endif
+
+#ifdef CONFIG_SUN4I
+ /* set I/O configure register */
+ reg_val = 0x00cc0000;
+ reg_val |= (para->odt_en) & 0x3;
+ reg_val |= ((para->odt_en) & 0x3) << 30;
+ writel(reg_val, &dram->iocr);
+#endif
+
/* set refresh period */
dramc_set_autorefresh_cycle(para->clock, para->type - 2, density);
diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index cbf8f086a9..4902d70834 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -10,4 +10,5 @@
#
obj-y += board.o
obj-$(CONFIG_SUNXI_GMAC) += gmac.o
+obj-$(CONFIG_CUBIEBOARD) += dram_cubieboard.o
obj-$(CONFIG_CUBIETRUCK) += dram_cubietruck.o
diff --git a/board/sunxi/dram_cubieboard.c b/board/sunxi/dram_cubieboard.c
new file mode 100644
index 0000000000..399028ca96
--- /dev/null
+++ b/board/sunxi/dram_cubieboard.c
@@ -0,0 +1,31 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+ .clock = 480,
+ .type = 3,
+ .rank_num = 1,
+ .density = 4096,
+ .io_width = 16,
+ .bus_width = 32,
+ .cas = 6,
+ .zq = 123,
+ .odt_en = 0,
+ .size = 1024,
+ .tpr0 = 0x30926692,
+ .tpr1 = 0x1090,
+ .tpr2 = 0x1a0c8,
+ .tpr3 = 0,
+ .tpr4 = 0,
+ .tpr5 = 0,
+ .emr1 = 0,
+ .emr2 = 0,
+ .emr3 = 0,
+};
+
+unsigned long sunxi_dram_init(void)
+{
+ return dramc_init(&dram_para);
+}
diff --git a/boards.cfg b/boards.cfg
index 6f8d168cf1..af241283c7 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -377,6 +377,7 @@ Active arm armv7 rmobile renesas lager
Active arm armv7 s5pc1xx samsung goni s5p_goni - Robert Baldyga <r.baldyga@samsung.com>
Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang <mk7.kang@samsung.com>
Active arm armv7 socfpga altera socfpga socfpga_cyclone5 - -
+Active arm armv7 sunxi - sunxi Cubieboard sun4i:CUBIEBOARD,SPL Hans de Goede <hdegoede@redhat.com>
Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII -
Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII -
Active arm armv7 u8500 st-ericsson snowball snowball - Mathieu Poirier <mathieu.poirier@linaro.org>
diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
new file mode 100644
index 0000000000..6560b65b38
--- /dev/null
+++ b/include/configs/sun4i.h
@@ -0,0 +1,23 @@
+/*
+ * (C) Copyright 2012-2013 Henrik Nordstrom <henrik@henriknordstrom.net>
+ *
+ * Configuration settings for the Allwinner A10 (sun4i) CPU
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * A10 specific configuration
+ */
+#define CONFIG_SUN4I /* sun4i SoC generation */
+
+#define CONFIG_SYS_PROMPT "sun4i# "
+
+/*
+ * Include common sunxi configuration where most the settings are
+ */
+#include <configs/sunxi-common.h>
+
+#endif /* __CONFIG_H */
OpenPOWER on IntegriCloud