
Hi,
On 03/16/2014 02:53 PM, Hans de Goede wrote:
Woops I forgot to add a commit msg here, I've jut fixed this locally:
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@allwinnertech.com Tom Cubie tangliang@allwinnertech.com
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
Regards,
Hans
arch/arm/cpu/armv7/sunxi/board.c | 2 +- arch/arm/cpu/armv7/sunxi/clock.c | 2 + arch/arm/cpu/armv7/sunxi/cpu_info.c | 7 ++ arch/arm/cpu/armv7/sunxi/dram.c | 129 ++++++++++++++++++++++++++++++++++++ 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 | 40 +++++++++++ 9 files changed, 223 insertions(+), 2 deletions(-) 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/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 2668d52..2225e31 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -82,7 +82,7 @@ void reset_cpu(ulong addr) /* do some early init */ void s_init(void) { -#if !defined CONFIG_SPL_BUILD +#if !defined CONFIG_SPL_BUILD && defined CONFIG_SUN7I /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */ asm volatile( "mrc p15, 0, r0, c1, c0, 1\n" diff --git a/arch/arm/cpu/armv7/sunxi/clock.c b/arch/arm/cpu/armv7/sunxi/clock.c index e3abaf0..f685dda 100644 --- a/arch/arm/cpu/armv7/sunxi/clock.c +++ b/arch/arm/cpu/armv7/sunxi/clock.c @@ -43,8 +43,10 @@ static void clock_init_safe(void) sdelay(200); writel(AXI_DIV_1 << 0 | AHB_DIV_2 << 4 | APB0_DIV_1 << 8 | CPU_CLK_SRC_PLL1 << 16, &ccm->cpu_ahb_apb0_cfg); +#ifdef CONFIG_SUN7I writel(0x1 << 6 | readl(&ccm->ahb_gate0), &ccm->ahb_gate0); writel(0x1 << 31 | readl(&ccm->pll6_cfg), &ccm->pll6_cfg); +#endif } #endif
diff --git a/arch/arm/cpu/armv7/sunxi/cpu_info.c b/arch/arm/cpu/armv7/sunxi/cpu_info.c index 14093dd..31c9f96 100644 --- a/arch/arm/cpu/armv7/sunxi/cpu_info.c +++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c @@ -29,7 +29,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 c34322d..08db987 100644 --- a/arch/arm/cpu/armv7/sunxi/dram.c +++ b/arch/arm/cpu/armv7/sunxi/dram.c @@ -49,6 +49,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); @@ -60,7 +75,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); } @@ -112,7 +131,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); @@ -132,6 +155,17 @@ 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, 0, 0, 0, 0, @@ -145,6 +179,7 @@ static u32 hpcr_value[32] = { * but boot0 code skips #28 and #30, and sets #29 and #31 to the * value from #28 entry (0x1031) */ +#endif };
static void mctl_configure_hostport(void) @@ -186,20 +221,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_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_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); }
@@ -209,7 +258,9 @@ static int dramc_scan_readpipe(void) u32 reg_val;
/* data training trigger */ +#ifdef CONFIG_SUN7I clrbits_le32(&dram->csr, DRAM_CSR_FAILED); +#endif setbits_le32(&dram->ccr, DRAM_CCR_DATA_TRAINING);
/* check whether data training process has completed */ @@ -336,15 +387,51 @@ fail:
static void dramc_clock_output_en(u32 on) { +#if defined(CONFIG_SUN7I) struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
if (on) setbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT); 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_SUN7I) static void dramc_set_autorefresh_cycle(u32 clk) { struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; @@ -358,6 +445,7 @@ static void dramc_set_autorefresh_cycle(u32 clk) reg_val |= 0x8 << 24; writel(reg_val, &dram->drr); } +#endif /* SUN7I */
unsigned long dramc_init(struct dram_para *para) { @@ -373,11 +461,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);
@@ -408,24 +504,35 @@ unsigned long dramc_init(struct dram_para *para) reg_val |= DRAM_DCR_MODE(DRAM_DCR_MODE_INTERLEAVE); writel(reg_val, &dram->dcr);
+#ifdef CONFIG_SUN7I setbits_le32(&dram->zqcr1, (0x1 << 24) | (0x1 << 1)); if (para->tpr4 & 0x2) clrsetbits_le32(&dram->zqcr1, (0x1 << 24), (0x1 << 1)); dramc_clock_output_en(1); +#endif
+#ifdef CONFIG_SUN7I /* 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_SUN7I /* Set CKE Delay to about 1ms */ setbits_le32(&dram->idcr, 0x1ffff); +#endif
+#ifdef CONFIG_SUN7I if ((readl(&dram->ppwrsctl) & 0x1) != 0x1) mctl_ddr3_reset(); else setbits_le32(&dram->mcr, DRAM_MCR_RESET); +#else
- /* dram clock on */
- dramc_clock_output_en(1);
+#endif
udelay(1);
@@ -433,6 +540,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);
@@ -443,7 +566,9 @@ unsigned long dramc_init(struct dram_para *para)
if (para->type == DRAM_MEMORY_TYPE_DDR3) { reg_val = DRAM_MR_BURST_LENGTH(0x0); +#if defined(CONFIG_SUN7I) reg_val |= DRAM_MR_POWER_DOWN; +#endif reg_val |= DRAM_MR_CAS_LAT(para->cas - 4); reg_val |= DRAM_MR_WRITE_RECOVERY(0x5); } else if (para->type == DRAM_MEMORY_TYPE_DDR2) { @@ -460,13 +585,16 @@ unsigned long dramc_init(struct dram_para *para) /* set DQS window mode */ clrsetbits_le32(&dram->ccr, DRAM_CCR_DQS_DRIFT_COMP, DRAM_CCR_DQS_GATE);
+#ifdef CONFIG_SUN7I /* Command rate timing mode 2T & 1T */ if (para->tpr4 & 0x1) setbits_le32(&dram->ccr, DRAM_CCR_COMMAND_RATE_1T); +#endif /* reset external DRAM */ setbits_le32(&dram->ccr, DRAM_CCR_INIT); while (readl(&dram->ccr) & DRAM_CCR_INIT);
+#ifdef CONFIG_SUN7I /* setup zq calibration manual */ reg_val = readl(&dram->ppwrsctl); if ((reg_val & 0x1) == 1) { @@ -502,6 +630,7 @@ unsigned long dramc_init(struct dram_para *para)
udelay(2);
} +#endif
/* scan read pipe value */ mctl_itm_enable(); diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile index 180adc9..2ebcd8a 100644 --- a/board/sunxi/Makefile +++ b/board/sunxi/Makefile @@ -26,4 +26,5 @@ #
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@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 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@linaro.org diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 13eba76..be5f301 100755 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -87,10 +87,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..4f37372 --- /dev/null +++ b/include/configs/sun4i.h @@ -0,0 +1,40 @@ +/*
- (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net
- Configuration settings for the Allwinner A10 (sun4i) CPU
- See file CREDITS for list of people who contributed to this
- project.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#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 */