[U-Boot] [PATCH u-boot sunxi 05/12] sunxi: Add sun4i support
Hans de Goede
hdegoede at redhat.com
Tue Mar 18 00:00:49 CET 2014
Based linux-sunxi#sunxi commit d854c4de2f57 "arm: Handle .gnu.hash section in
ldscripts" vs v2014.01.
As well as the following signed-off-by the sunxi branch shows commits to
the new sun4i dram bits by:
Berg Xing <bergxing at allwinnertech.com>
Tom Cubie <tangliang at allwinnertech.com>
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/cpu_info.c | 7 +++
arch/arm/cpu/armv7/sunxi/dram.c | 108 ++++++++++++++++++++++++++++++++++++
board/sunxi/Makefile | 3 +-
board/sunxi/dram_a10_olinuxino_l.c | 31 +++++++++++
boards.cfg | 1 +
drivers/mmc/sunxi_mmc.c | 10 ++++
include/configs/sun4i.h | 23 ++++++++
7 files changed, 182 insertions(+), 1 deletion(-)
create mode 100644 board/sunxi/dram_a10_olinuxino_l.c
create mode 100644 include/configs/sun4i.h
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 555b75d..37edede 100644
--- a/arch/arm/cpu/armv7/sunxi/dram.c
+++ b/arch/arm/cpu/armv7/sunxi/dram.c
@@ -33,6 +33,21 @@ static void mctl_ddr3_reset(void)
struct sunxi_dram_reg *dram =
(struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+#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);
@@ -44,7 +59,11 @@ 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);
}
@@ -96,7 +115,11 @@ static void mctl_enable_dllx(u32 phase)
n = DRAM_DCR_NR_DLLCR_16BIT;
for (i = 1; i < n; i++) {
+#ifdef CONFIG_SUN7I
clrsetbits_le32(&dram->dllcr[i], 0xf << 14,
+#else
+ clrsetbits_le32(&dram->dllcr[i], 0x4 << 14,
+#endif
(phase & 0xf) << 14);
clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET,
DRAM_DLLCR_DISABLE);
@@ -116,6 +139,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, 0x1035,
+ 0x1035, 0x0731, 0x1031, 0x0735,
+ 0x1035, 0x1031, 0x0731, 0x1035,
+ 0x1031, 0x0301, 0x0301, 0x0731
+#endif
#ifdef CONFIG_SUN7I
0x0301, 0x0301, 0x0301, 0x0301,
0x0301, 0x0301, 0x0301, 0x0301,
@@ -174,20 +207,34 @@ static void mctl_setup_dram_clock(u32 clk)
/* setup MBUS clock */
reg_val = CCM_MBUS_CTRL_GATE |
+#if defined(CONFIG_SUN7I)
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));
+#else /* defined(CONFIG_SUN7I) */
+ CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL5) |
+ CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(1)) |
+ CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2));
+#endif
writel(reg_val, &ccm->mbus_clk_cfg);
/*
* 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);
}
@@ -334,8 +381,42 @@ 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
}
+#ifdef CONFIG_SUN4I
+static void dramc_set_autorefresh_cycle(u32 clk)
+{
+ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+ u32 reg_val;
+ u32 tmp_val;
+ u32 reg_dcr;
+
+ if (clk < 600) {
+ reg_dcr = readl(&dram->dcr);
+ if ((reg_dcr & DRAM_DCR_CHIP_DENSITY_MASK) <=
+ DRAM_DCR_CHIP_DENSITY(DRAM_DCR_CHIP_DENSITY_1024M))
+ reg_val = (131 * clk) >> 10;
+ else
+ reg_val = (336 * clk) >> 10;
+
+ tmp_val = (7987 * clk) >> 10;
+ tmp_val = tmp_val * 9 - 200;
+ reg_val |= tmp_val << 8;
+ reg_val |= 0x8 << 24;
+ writel(reg_val, &dram->drr);
+ } else {
+ writel(0x0, &dram->drr);
+ }
+}
+#endif /* SUN4I */
+
#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
static void dramc_set_autorefresh_cycle(u32 clk)
{
@@ -366,11 +447,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);
@@ -426,6 +515,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);
@@ -434,6 +526,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);
diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index 6483bf4..590ca42 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -9,4 +9,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += board.o
-obj-y += dram_cubietruck.o
+obj-$(CONFIG_A10_OLINUXINO_L) += dram_a10_olinuxino_l.o
+obj-$(CONFIG_CUBIETRUCK) += dram_cubietruck.o
diff --git a/board/sunxi/dram_a10_olinuxino_l.c b/board/sunxi/dram_a10_olinuxino_l.c
new file mode 100644
index 0000000..24a1bd9
--- /dev/null
+++ b/board/sunxi/dram_a10_olinuxino_l.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 = 16,
+ .cas = 6,
+ .zq = 123,
+ .odt_en = 0,
+ .size = 512,
+ .tpr0 = 0x30926692,
+ .tpr1 = 0x1090,
+ .tpr2 = 0x1a0c8,
+ .tpr3 = 0,
+ .tpr4 = 0,
+ .tpr5 = 0,
+ .emr1 = 0x4,
+ .emr2 = 0,
+ .emr3 = 0,
+};
+
+unsigned long sunxi_dram_init(void)
+{
+ return dramc_init(&dram_para);
+}
diff --git a/boards.cfg b/boards.cfg
index a513376..07dd65a 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -353,6 +353,7 @@ Active arm armv7 rmobile renesas koelsch
Active arm armv7 s5pc1xx samsung goni s5p_goni - Mateusz Zalega <m.zalega 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 A10-OLinuXino-Lime sun4i:A10_OLINUXINO_L,SPL -
Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL -
Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL -
Active arm armv7 u8500 st-ericsson snowball snowball - Mathieu Poirier <mathieu.poirier at linaro.org>
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index e052af5..80e4369 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -71,10 +71,20 @@ struct sunxi_mmc_des {
u32 reserved1_2:24;
u32 card_err_sum:1; /* transfer error flag */
u32 own:1; /* des owner:1-idma owns it, 0-host owns it */
+#ifdef CONFIG_SUN4I
+#define SDXC_DES_NUM_SHIFT 13
+#define SDXC_DES_BUFFER_MAX_LEN (1 << SDXC_DES_NUM_SHIFT)
+ u32 data_buf1_sz:13;
+ u32 data_buf2_sz:13;
+ u32 reserverd2_1:6;
+#elif defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
#define SDXC_DES_NUM_SHIFT 16
#define SDXC_DES_BUFFER_MAX_LEN (1 << SDXC_DES_NUM_SHIFT)
u32 data_buf1_sz:16;
u32 data_buf2_sz:16;
+#else
+#error ">>>> Wrong Platform for MMC <<<<"
+#endif
u32 buf_addr_ptr1;
u32 buf_addr_ptr2;
};
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.0
More information about the U-Boot
mailing list