Message ID | 1394978030-14511-5-git-send-email-hdegoede@redhat.com |
---|---|
State | RFC |
Delegated to: | Albert ARIBAUD |
Headers | show |
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 */ >
On Sun, Mar 16, 2014 at 02:53:50PM +0100, Hans de Goede wrote: > Signed-off-by: Hans de Goede <hdegoede@redhat.com> > --- > 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 Wow, nice. For tracking / merging can you split this part up into 1/2 "add SUN7I test around ..." so that Ian can pick it up into his series in the next go-round? Thanks!
Hi, On 03/17/2014 01:43 PM, Tom Rini wrote: > On Sun, Mar 16, 2014 at 02:53:50PM +0100, Hans de Goede wrote: > >> Signed-off-by: Hans de Goede <hdegoede@redhat.com> >> --- >> 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 > > Wow, nice. > > For tracking / merging can you split this part up into 1/2 "add SUN7I > test around ..." so that Ian can pick it up into his series in the next > go-round? Thanks! Done, see the next patch-set I'm about to send. Regards, Hans
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 */
Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- 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