Skip to contentSkip to conversation

sun4i support on top of Ian's patches

PATCH New Hans de Goede 4 participants 16 messages Mar 16, 2014 – May 10, 2014

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover sun4i support on top of Ian's patches

Hi All,

Here is a patch-set adding sun4i support on top of Ian's recent 1st attempt to get sun7i upstream patch-set.

Note I've had to drop the raising of the cpu core clock, without matching axp209 changes this causes issues on sun4i.

I've been thinking about how to best move forward with this patch-set, and I think it would be best to first complete the job of splitting up what we've in u-boot-sunxi now (at least most of it), keeping this based on v2014.01 so that we can easily diff. And then once we've everything split up, use the split-up patch-set as a base and start working on addressing any review comments there, which will break easy diffs against u-boot-sunxi, but at that point we no longer need them.

We can even paralellize things. I can stick with Ian's v1 patchset for now, adding patches on top adding what is missing in piecemeal patches, and Ian can start working on making his initial series ready to go upstream.

Ian, does that sound like a plan ?

Regards,

Hans

#1 lore raw

PATCH 1/4 sunxi: FIXUP: sunxi: initial generic sun7i cpu, board and start of day support

We should not be raising the cpu core frequency until we have pmic support in place.

---
 board/sunxi/board.c | 10 ----------
 1 file changed, 10 deletions(-)
board/sunxi/board.c +0 -10
index 5dbcf2a..cc3083c 100644
@@ -75,7 +75,6 @@ int board_mmc_init(bd_t *bis)
 #ifdef CONFIG_SPL_BUILD
 void sunxi_board_init(void)
 {
-	int power_failed = 0;
 	unsigned long ramsize;
 
 	printf("DRAM:");
@@ -91,14 +90,5 @@ void sunxi_board_init(void)
 	printf(" %lu MiB\n", ramsize >> 20);
 	if (!ramsize)
 		hang();
-
-	/*
-	 * Only clock up the CPU to full speed if we are reasonably
-	 * assured it's being powered with suitable core voltage
-	 */
-	if (!power_failed)
-		clock_set_pll1(912000000);
-	else
-		printf("Failed to set core voltage! Can't set CPU frequency\n");
 }
 #endif
Signature · 1 line
1.9.0
#2 lore raw

PATCH 2/4 sunxi: FIXUP: sunxi: initial sun7i dram setup support

In reply to Hans de Goede

mctl_ddr3_reset() should not be called here for sun7i, at least the u-boot-sunxi sources don't do this.

---
 arch/arm/cpu/armv7/sunxi/dram.c | 1 -
 1 file changed, 1 deletion(-)
arch/arm/cpu/armv7/sunxi/dram.c +0 -1
index 81b1f50..c34322d 100644
@@ -373,7 +373,6 @@ unsigned long dramc_init(struct dram_para *para)
 	mctl_setup_dram_clock(para->clock);
 
 	/* reset external DRAM */
-	mctl_ddr3_reset();
 	mctl_set_drive();
 
 	/* dram clock off */
Signature · 1 line
1.9.0
#3 lore raw

PATCH 2/4 sunxi: FIXUP: sunxi: initial sun7i dram setup support

Quoted 2 lines · Hans de Goede

mctl_ddr3_reset() should not be called here for sun7i, at least the u-boot-sunxi sources don't do this.

oops, I misread an ifndef. I'll fold in, thanks.

Ian.

#4 lore raw

PATCH 3/4 sunxi: Implement reset_cpu

In reply to Hans de Goede

There is no way to reset the cpu, so use the watchdog for this.

---
 arch/arm/cpu/armv7/sunxi/board.c        | 7 +++++++
 arch/arm/include/asm/arch-sunxi/timer.h | 4 ++++
 2 files changed, 11 insertions(+)
arch/arm/cpu/armv7/sunxi/board.c +7 -0
index 98cad43..2668d52 100644
@@ -70,6 +70,13 @@ int gpio_init(void)
 
 void reset_cpu(ulong addr)
 {
+	static const struct sunxi_wdog *wdog =
+		 &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
+
+	/* Set the watchdog for its shortest interval (.5s) and wait */
+	writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
+	writel(WDT_CTRL_RESTART, &wdog->ctl);
+	while (1);
 }
 
 /* do some early init */
arch/arm/include/asm/arch-sunxi/timer.h +4 -0
index f9d4f4f..1489b2e 100644
@@ -27,6 +27,10 @@
 #ifndef _SUNXI_TIMER_H_
 #define _SUNXI_TIMER_H_
 
+#define WDT_CTRL_RESTART        (0x1 << 0)
+#define WDT_MODE_EN             (0x1 << 0)
+#define WDT_MODE_RESET_EN       (0x1 << 1)
+
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
Signature · 1 line
1.9.0
#5 lore raw

PATCH 3/4 sunxi: Implement reset_cpu

Quoted 1 line · Hans de Goede

There is no way to reset the cpu, so use the watchdog for this.

The sunxi.git tree does this by calling watchdog_set(0). I think it would be better to introduce the generic watchdog support and the add this a patch to use it for reset. Unless we don't plan to upstream the watchdog stuff for some reason?

Not sure why cmd_watchdog.c is sunxi, seems like in principal it could be generic.

Ian.

Quoted 39 lines
---
 arch/arm/cpu/armv7/sunxi/board.c        | 7 +++++++
 arch/arm/include/asm/arch-sunxi/timer.h | 4 ++++
 2 files changed, 11 insertions(+)
arch/arm/cpu/armv7/sunxi/board.c +7 -0
index 98cad43..2668d52 100644
@@ -70,6 +70,13 @@ int gpio_init(void)
 
 void reset_cpu(ulong addr)
 {
+	static const struct sunxi_wdog *wdog =
+		 &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
+
+	/* Set the watchdog for its shortest interval (.5s) and wait */
+	writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
+	writel(WDT_CTRL_RESTART, &wdog->ctl);
+	while (1);
 }
 
 /* do some early init */
arch/arm/include/asm/arch-sunxi/timer.h +4 -0
index f9d4f4f..1489b2e 100644
@@ -27,6 +27,10 @@
 #ifndef _SUNXI_TIMER_H_
 #define _SUNXI_TIMER_H_
 
+#define WDT_CTRL_RESTART        (0x1 << 0)
+#define WDT_MODE_EN             (0x1 << 0)
+#define WDT_MODE_RESET_EN       (0x1 << 1)
+
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
#6 lore raw

PATCH 3/4 sunxi: Implement reset_cpu

s?n 2014-03-16 klockan 18:38 +0000 skrev Ian Campbell:

Quoted 2 lines

Not sure why cmd_watchdog.c is sunxi, seems like in principal it could be generic.

In principal it could, but there is no common API for setting the watchdog timer, and no common API for disabling the watchdog once armed.

Regards
Henrik

#7 lore raw

PATCH 3/4 sunxi: Implement reset_cpu

In reply to Hans de Goede

s?n 2014-03-16 klockan 14:53 +0100 skrev Hans de Goede:

arch/arm/cpu/armv7/sunxi/board.c int gpio_init(void) · line 79

Quoted 9 lines

void reset_cpu(ulong addr)
{

arch/arm/cpu/armv7/sunxi/board.c +7 -0
+	static const struct sunxi_wdog *wdog =
+		 &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
+
+	/* Set the watchdog for its shortest interval (.5s) and wait */
+	writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
+	writel(WDT_CTRL_RESTART, &wdog->ctl);
+	while (1);

This code is incomplete and do not reload the watchdog if already running. wdog->ctl is locked by a magic key. Should use

        writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl);

where

#define WDT_CTRL_KEY (0x0a57 << 1)

Unfortunatley Allwinner kindly omitted this little detail from the User Manual.

Found out while trying to use the watchdog as a watchdog and not only reset. Asked Tom while he still was@Allwinner and got clarification on how to use the watchdog control register.

Regards
Henrik

#8 lore raw

PATCH 3/4 sunxi: Implement reset_cpu

Hi,

Quoted 18 lines · Henrik Nordstr?m

s?n 2014-03-16 klockan 14:53 +0100 skrev Hans de Goede:

arch/arm/cpu/armv7/sunxi/board.c int gpio_init(void) · line 79

Quoted 9 lines

void reset_cpu(ulong addr)
{

arch/arm/cpu/armv7/sunxi/board.c +7 -0
+	static const struct sunxi_wdog *wdog =
+		 &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
+
+	/* Set the watchdog for its shortest interval (.5s) and wait */
+	writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
+	writel(WDT_CTRL_RESTART, &wdog->ctl);
+	while (1);

This code is incomplete and do not reload the watchdog if already running. wdog->ctl is locked by a magic key. Should use

        writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl);

where

Quoted 8 lines

#define WDT_CTRL_KEY (0x0a57 << 1)

Unfortunatley Allwinner kindly omitted this little detail from the User Manual.

Found out while trying to use the watchdog as a watchdog and not only reset. Asked Tom while he still was at Allwinner and got clarification on how to use the watchdog control register.

Thanks, I'm currently working on v2 of this series and I've included this fix.

Regards,

Hans

#9 lore raw

PATCH 4/4 sunxi: Add sun4i support

In reply to Hans de Goede
---
 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
arch/arm/cpu/armv7/sunxi/board.c +1 -1
index 2668d52..2225e31 100644
@@ -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"
arch/arm/cpu/armv7/sunxi/clock.c +2 -0
index e3abaf0..f685dda 100644
@@ -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
 
arch/arm/cpu/armv7/sunxi/cpu_info.c +7 -0
index 14093dd..31c9f96 100644
@@ -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
arch/arm/cpu/armv7/sunxi/dram.c +129 -0

276 lines not on this page · raw message

board/sunxi/Makefile +2 -1
index 180adc9..2ebcd8a 100644
@@ -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
board/sunxi/dram_a10_olinuxino_l.c new file +31 -0
new file mode 100644
index 0000000..24a1bd9
@@ -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);
+}
boards.cfg +1 -0
index a513376..07dd65a 100644
@@ -353,6 +353,7 @@ Active  arm         armv7          rmobile     renesas         koelsch
 Active  arm         armv7          s5pc1xx     samsung         goni                s5p_goni                             -                                                                                                                                 Mateusz Zalega <[email protected]>
 Active  arm         armv7          s5pc1xx     samsung         smdkc100            smdkc100                             -                                                                                                                                 Minkyu Kang <[email protected]>
 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 <[email protected]>
drivers/mmc/sunxi_mmc.c +10 -0
index 13eba76..be5f301 100755
@@ -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;
 };
include/configs/sun4i.h new file +40 -0
new file mode 100644
index 0000000..4f37372
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2012-2013 Henrik Nordstrom <[email protected]>
+ *
+ * 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 */
Signature · 1 line
1.9.0
#10 lore raw

PATCH 4/4 sunxi: Add sun4i support

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 <[email protected]>
Tom Cubie <[email protected]>

Regards,

Hans

Quoted 488 lines
---
 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
arch/arm/cpu/armv7/sunxi/board.c +1 -1
index 2668d52..2225e31 100644
@@ -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"
arch/arm/cpu/armv7/sunxi/clock.c +2 -0
index e3abaf0..f685dda 100644
@@ -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
 
arch/arm/cpu/armv7/sunxi/cpu_info.c +7 -0
index 14093dd..31c9f96 100644
@@ -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
arch/arm/cpu/armv7/sunxi/dram.c +129 -0
index c34322d..08db987 100644
@@ -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();
board/sunxi/Makefile +2 -1
index 180adc9..2ebcd8a 100644
@@ -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
board/sunxi/dram_a10_olinuxino_l.c new file +31 -0
new file mode 100644
index 0000000..24a1bd9
@@ -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);
+}
boards.cfg +1 -0
index a513376..07dd65a 100644
@@ -353,6 +353,7 @@ Active  arm         armv7          rmobile     renesas         koelsch
 Active  arm         armv7          s5pc1xx     samsung         goni                s5p_goni                             -                                                                                                                                 Mateusz Zalega <[email protected]>
 Active  arm         armv7          s5pc1xx     samsung         smdkc100            smdkc100                             -                                                                                                                                 Minkyu Kang <[email protected]>
 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 <[email protected]>
drivers/mmc/sunxi_mmc.c +10 -0
index 13eba76..be5f301 100755
@@ -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;
 };
include/configs/sun4i.h new file +40 -0
new file mode 100644
index 0000000..4f37372
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2012-2013 Henrik Nordstrom <[email protected]>
+ *
+ * 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 */
#11 lore raw

PATCH 4/4 sunxi: Add sun4i support

In reply to Hans de Goede
Quoted 14 lines · Hans de Goede
---
 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!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140317/a89f57a7/attachment.pgp>
#12 lore raw

[U-Boot] [linux-sunxi] Re: [PATCH u-boot sunxi 4/4] sunxi: Add sun4i support

Hi,

Quoted 17 lines · Tom Rini
Quoted 14 lines · Hans de Goede
---
 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
Quoted 5 lines

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

#13 lore raw

cover sun4i support on top of Ian's patches

In reply to Hans de Goede
Quoted 7 lines · Hans de Goede

Hi All,

Here is a patch-set adding sun4i support on top of Ian's recent 1st attempt to get sun7i upstream patch-set.

Note I've had to drop the raising of the cpu core clock, without matching axp209 changes this causes issues on sun4i.

Yes, I was going to drop this from the base series based on the feedback so far.

Quoted 4 lines

I've been thinking about how to best move forward with this patch-set, and I think it would be best to first complete the job of splitting up what we've in u-boot-sunxi now (at least most of it), keeping this based on v2014.01 so that we can easily diff.

I was actually planning to ask if we could merge up to at least v2014.04-rc2, in general it is easier to upstream the closer we are starting from.

In particular between v2014.01 and v2014.04.rc the following are going to be relevant for upstreaming:
* Switch to Kbuild has made the Makefile stuff very different
* Based on Wens' feedback it looked like there are changes to the designware stuff upstream which will need integrating
* The generic distro stuff which Dennis asked for isn't in v2014.01 AFAIK.

The merge up doesn't seem too bad, I've got it mostly done locally. Not sure what the best way to send it out is -- probably as a git pull request?

I've also got a small series which addresses the initial upstream review feedback in sunxi.git which I hope to send out soon.

Quoted 3 lines

We can even paralellize things. I can stick with Ian's v1 patchset for now, adding patches on top adding what is missing in piecemeal patches, and Ian can start working on making his initial series ready to go upstream.

I'd prefer this approach to tacking your patches onto the end of my series and managing them myself.

Ian.

#14 lore raw

cover sun4i support on top of Ian's patches

Hi,

Quoted 11 lines · Ian Campbell
Quoted 7 lines · Hans de Goede

Hi All,

Here is a patch-set adding sun4i support on top of Ian's recent 1st attempt to get sun7i upstream patch-set.

Note I've had to drop the raising of the cpu core clock, without matching axp209 changes this causes issues on sun4i.

Yes, I was going to drop this from the base series based on the feedback so far.

Ack, the "FIXUP" marked patched in my series are intented to get squashed into your patches.

Quoted 8 lines
Quoted 4 lines

I've been thinking about how to best move forward with this patch-set, and I think it would be best to first complete the job of splitting up what we've in u-boot-sunxi now (at least most of it), keeping this based on v2014.01 so that we can easily diff.

I was actually planning to ask if we could merge up to at least v2014.04-rc2, in general it is easier to upstream the closer we are starting from.

You mean merging u-boot-sunxi's sunxi branch to v2014.04-rc2 right? That sounds fine to me. Ultimately its HNO call to make though. HNO if you're ok with this I can test Ian's merge on sun4i and sun5i and then push it to u-boot-sunxi's sunxi branch.

Quoted 11 lines

In particular between v2014.01 and v2014.04.rc the following are going to be relevant for upstreaming:
* Switch to Kbuild has made the Makefile stuff very different
* Based on Wens' feedback it looked like there are changes to the designware stuff upstream which will need integrating
* The generic distro stuff which Dennis asked for isn't in v2014.01 AFAIK.

The merge up doesn't seem too bad, I've got it mostly done locally. Not sure what the best way to send it out is -- probably as a git pull request?

Yes a git pull is probably best. You can use either github's pull-req interface or just send one to the linux-sunxi list.

Quoted 2 lines

I've also got a small series which addresses the initial upstream review feedback in sunxi.git which I hope to send out soon.

Sounds good.

Quoted 6 lines
Quoted 3 lines

We can even paralellize things. I can stick with Ian's v1 patchset for now, adding patches on top adding what is missing in piecemeal patches, and Ian can start working on making his initial series ready to go upstream.

I'd prefer this approach to tacking your patches onto the end of my series and managing them myself.

Ok, so lets split up our efforts for now then, you work on getting the basic sun7i support upstream and I'll work on adding missing bits, like sun4i, sun5i and axp support.

Regards,

Hans

p.s.

For those reading along, I've just finished adding sun5i support, testing that is next on my todo list, then adding axp support. I'll send a second patch-set with what I've tonight to avoid others doing double work. In general my latest work on this can be found here:
https://github.com/jwrdegoede/u-boot-sunxi/tree/v2014.01-sunxi

#15 lore raw

cover sun4i support on top of Ian's patches

Quoted 9 lines · Hans de Goede

Hi,

Quoted 6 lines · Ian Campbell
Quoted 5 lines · Hans de Goede

Hi All,

Here is a patch-set adding sun4i support on top of Ian's recent 1st attempt to get sun7i upstream patch-set.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Note I've had to drop the raising of the cpu core clock, without matching axp209 changes this causes issues on sun4i.

Yes, I was going to drop this from the base series based on the feedback so far.

Ack, the "FIXUP" marked patched in my series are intented to get squashed into your patches.

Thanks, will do.

Quoted 10 lines
Quoted 8 lines
Quoted 4 lines

I've been thinking about how to best move forward with this patch-set, and I think it would be best to first complete the job of splitting up what we've in u-boot-sunxi now (at least most of it), keeping this based on v2014.01 so that we can easily diff.

I was actually planning to ask if we could merge up to at least v2014.04-rc2, in general it is easier to upstream the closer we are starting from.

You mean merging u-boot-sunxi's sunxi branch to v2014.04-rc2 right?

Correct.

Quoted 13 lines

That sounds
fine to me. Ultimately its HNO call to make though. HNO if you're ok with this I can test Ian's merge on sun4i and sun5i and then push it to u-boot-sunxi's sunxi branch.

Quoted 8 lines

In particular between v2014.01 and v2014.04.rc the following are going to be relevant for upstreaming:
* Switch to Kbuild has made the Makefile stuff very different
* Based on Wens' feedback it looked like there are changes to the designware stuff upstream which will need integrating
* The generic distro stuff which Dennis asked for isn't in v2014.01 AFAIK.

Quoted 6 lines
Quoted 3 lines

The merge up doesn't seem too bad, I've got it mostly done locally. Not sure what the best way to send it out is -- probably as a git pull request?

Yes a git pull is probably best. You can use either github's pull-req interface or just send one to the linux-sunxi list.

I've been trying to avoid registering with github so I'll send a request to the list.

Quoted 9 lines
Quoted 2 lines

I've also got a small series which addresses the initial upstream review feedback in sunxi.git which I hope to send out soon.

Sounds good.

Quoted 4 lines
Quoted 3 lines

We can even paralellize things. I can stick with Ian's v1 patchset for now, adding patches on top adding what is missing in piecemeal patches, and Ian can start working on making his initial series ready to go upstream.

Quoted 6 lines
Quoted 2 lines

I'd prefer this approach to tacking your patches onto the end of my series and managing them myself.

Ok, so lets split up our efforts for now then, you work on getting the basic sun7i support upstream and I'll work on adding missing bits, like sun4i, sun5i and axp support.

Agreed.

Quoted 5 lines

For those reading along, I've just finished adding sun5i support, testing that is next on my todo list, then adding axp support. I'll send a second patch-set with what I've tonight to avoid others doing double work. In general my latest work on this can be found here:
https://github.com/jwrdegoede/u-boot-sunxi/tree/v2014.01-sunxi

Great!

Ian.