[U-Boot] [PATCH 05/12] sunxi: Add sun4i support

Hans de Goede hdegoede at redhat.com
Fri May 30 11:06:05 CEST 2014


Add support for the Allwinner A10 SoC also know as the Allwinner sun4i family.

Signed-off-by: Henrik Nordstrom <henrik at henriknordstrom.net>
Signed-off-by: Stefan Roese <sr at denx.de>
Signed-off-by: Oliver Schinagl <oliver at schinagl.nl>
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/cpu/armv7/sunxi/Makefile   |  2 +
 arch/arm/cpu/armv7/sunxi/cpu_info.c |  7 ++++
 arch/arm/cpu/armv7/sunxi/dram.c     | 81 +++++++++++++++++++++++++++++++++++--
 board/sunxi/Makefile                |  1 +
 board/sunxi/dram_cubieboard.c       | 31 ++++++++++++++
 boards.cfg                          |  1 +
 include/configs/sun4i.h             | 23 +++++++++++
 7 files changed, 143 insertions(+), 3 deletions(-)
 create mode 100644 board/sunxi/dram_cubieboard.c
 create mode 100644 include/configs/sun4i.h

diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index a64bfa1..856d353 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 b4c3d5c..b4b5089 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 b43c4b4..76753d7 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 impendance 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 cbf8f08..4902d70 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 0000000..399028c
--- /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 79105f5..177f680 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -380,6 +380,7 @@ Active  arm         armv7          rmobile     renesas         lager
 Active  arm         armv7          s5pc1xx     samsung         goni                s5p_goni                              -                                                                                                                                 Przemyslaw Marczak <p.marczak at samsung.com>
 Active  arm         armv7          s5pc1xx     samsung         smdkc100            smdkc100                              -                                                                                                                                 Minkyu Kang <mk7.kang at samsung.com>
 Active  arm         armv7          socfpga     altera          socfpga             socfpga_cyclone5                      -                                                                                                                                 -
+Active  arm         armv7          sunxi       -               sunxi               Cubieboard                            sun4i:CUBIEBOARD,SPL                                                                                                              Hans de Goede <hdegoede at 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 at linaro.org>
diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
new file mode 100644
index 0000000..6560b65
--- /dev/null
+++ b/include/configs/sun4i.h
@@ -0,0 +1,23 @@
+/*
+ * (C) Copyright 2012-2013 Henrik Nordstrom <henrik at 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 */
-- 
1.9.3



More information about the U-Boot mailing list