[coreboot-gerrit] New patch to review for coreboot: cpu/allwinner: add A20 code to coreboot

Iru Cai (mytbk920423@gmail.com) gerrit at coreboot.org
Mon Jun 20 16:53:05 CEST 2016


Iru Cai (mytbk920423 at gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15263

-gerrit

commit 08050d949e4e9aa2e62330d95ea47ea876ef7c25
Author: Iru Cai <mytbk920423 at gmail.com>
Date:   Mon Jun 20 10:36:54 2016 +0800

    cpu/allwinner: add A20 code to coreboot
    
    I ported coreboot to A20-Cubietruck last year based on mrnuke's branch
    and U-Boot source code, and now I'm trying to port mainline coreboot
    to it: https://github.com/mytbk/coreboot/tree/cubie_mmc_ct
    
    Tested on A20 Cubietruck, not tested on A10 Cubieboard.
    
    Change-Id: Id4146c4f151ef4c0a0febd8cb70db9bf65ee2b29
    Signed-off-by: Iru Cai <mytbk920423 at gmail.com>
---
 src/cpu/allwinner/Makefile.inc  |  1 +
 src/cpu/allwinner/a10/Kconfig   |  8 +++--
 src/cpu/allwinner/a10/clock.c   | 16 ++++++++--
 src/cpu/allwinner/a10/clock.h   | 15 +++++++--
 src/cpu/allwinner/a10/raminit.c | 67 +++++++++++++++++++++++++++++++++--------
 5 files changed, 89 insertions(+), 18 deletions(-)

diff --git a/src/cpu/allwinner/Makefile.inc b/src/cpu/allwinner/Makefile.inc
index e52a12e..997f4df 100644
--- a/src/cpu/allwinner/Makefile.inc
+++ b/src/cpu/allwinner/Makefile.inc
@@ -1 +1,2 @@
 subdirs-$(CONFIG_CPU_ALLWINNER_A10) += a10
+subdirs-$(CONFIG_CPU_ALLWINNER_A20) += a10
diff --git a/src/cpu/allwinner/a10/Kconfig b/src/cpu/allwinner/a10/Kconfig
index 0e5aba9..165c554 100644
--- a/src/cpu/allwinner/a10/Kconfig
+++ b/src/cpu/allwinner/a10/Kconfig
@@ -2,7 +2,11 @@ config CPU_ALLWINNER_A10
 	bool
 	default n
 
-if CPU_ALLWINNER_A10
+config CPU_ALLWINNER_A20
+	bool
+	default n
+
+if CPU_ALLWINNER_A10 || CPU_ALLWINNER_A20
 
 config CPU_SPECIFIC_OPTIONS
 	def_bool y
@@ -15,4 +19,4 @@ config CPU_SPECIFIC_OPTIONS
 	select BOOTBLOCK_CONSOLE
 	select UART_OVERRIDE_REFCLK
 
-endif # if CPU_ALLWINNER_A10
+endif # if CPU_ALLWINNER_A10 || CPU_ALLWINNER_A20
diff --git a/src/cpu/allwinner/a10/clock.c b/src/cpu/allwinner/a10/clock.c
index ae50e06..a05b344 100644
--- a/src/cpu/allwinner/a10/clock.c
+++ b/src/cpu/allwinner/a10/clock.c
@@ -17,6 +17,7 @@
  */
 
 #include "clock.h"
+#include "dramc.h"
 
 #include <arch/io.h>
 #include <console/console.h>
@@ -25,6 +26,7 @@
 #include <stdlib.h>
 
 static struct a10_ccm *const ccm = (void *)A1X_CCM_BASE;
+static struct a1x_dramc *const dram = (void*)A1X_DRAMC_BASE;
 
 /**
  * \brief Enable the clock source for the peripheral
@@ -123,7 +125,12 @@ void a1x_pll5_enable_dram_clock_output(void)
  */
 void a1x_ungate_dram_clock_output(void)
 {
-	setbits_le32(&ccm->dram_clk_cfg, DRAM_CTRL_DCLK_OUT);
+	if (IS_ENABLED(CONFIG_CPU_ALLWINNER_A10)) {
+		setbits_le32(&ccm->dram_clk_cfg, DRAM_CTRL_DCLK_OUT);
+	}
+	if (IS_ENABLED(CONFIG_CPU_ALLWINNER_A20)) {
+		setbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
+	}
 }
 
 /**
@@ -134,7 +141,12 @@ void a1x_ungate_dram_clock_output(void)
  */
 void a1x_gate_dram_clock_output(void)
 {
-	clrbits_le32(&ccm->dram_clk_cfg, DRAM_CTRL_DCLK_OUT);
+	if (IS_ENABLED(CONFIG_CPU_ALLWINNER_A10)) {
+		clrbits_le32(&ccm->dram_clk_cfg, DRAM_CTRL_DCLK_OUT);
+	}
+	if (IS_ENABLED(CONFIG_CPU_ALLWINNER_A20)) {
+		clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
+	}
 }
 
 /*
diff --git a/src/cpu/allwinner/a10/clock.h b/src/cpu/allwinner/a10/clock.h
index d1729a3..2da20e3 100644
--- a/src/cpu/allwinner/a10/clock.h
+++ b/src/cpu/allwinner/a10/clock.h
@@ -44,6 +44,14 @@
 #define  AXI_DIV_3			(2 << 0)
 #define  AXI_DIV_4			(3 << 0)
 
+/* AHB_CLK_GATE values */
+#define AHB_GATE_DMA			(1 << 6)
+#define AHB_GATE_SDRAM			(1 << 14)
+/* AHB_GATE_DLL undocumented in A20 */
+#define AHB_GATE_DLL			(1 << 15)
+#define AHB_GATE_ACE			(1 << 16)
+#define AHB_GATE_SATA			(1 << 25)
+
 /* APB1_CLK_DIV values */
 #define APB1_CLK_SRC_MASK		(3 << 24)
 #define  APB1_CLK_SRC_OSC24M		(0 << 24)
@@ -51,7 +59,7 @@
 #define  APB1_CLK_SRC_32K		(2 << 24)
 #define APB1_RAT_N_MASK			(3 << 16)
 #define  APB1_RAT_N(m)			(((m) & 0x3) << 16)
-#define APB1_RAT_M_MASK			0x1f << 0)
+#define APB1_RAT_M_MASK			(0x1f << 0)
 #define  APB1_RAT_M(n)			(((n) & 0x1f) << 0)
 
 /* PLL5_CFG values */
@@ -74,6 +82,9 @@
 #define PLL5_FACTOR_M_MASK		(0x3 << 0)
 #define PLL5_FACTOR_M(m)		((((m) - 1) << 0) & PLL5_FACTOR_M_MASK)
 
+/* PLL6_CFG values */
+#define PLL6_SATA_CLK_EN			(1 << 14)
+
 /* DRAM_CLK values*/
 #define DRAM_CTRL_DCLK_OUT		(1 << 15)
 
@@ -119,7 +130,7 @@ enum a1x_clken {
 	A1X_CLKEN_NC,
 	A1X_CLKEN_NAND,
 	A1X_CLKEN_SDRAM,
-	RSVD_0x60_15,
+	A1X_CLKEN_DLL,
 	A1X_CLKEN_ACE,
 	A1X_CLKEN_EMAC,
 	A1X_CLKEN_TS,
diff --git a/src/cpu/allwinner/a10/raminit.c b/src/cpu/allwinner/a10/raminit.c
index f3b39cb..98b1f28 100644
--- a/src/cpu/allwinner/a10/raminit.c
+++ b/src/cpu/allwinner/a10/raminit.c
@@ -33,14 +33,23 @@
 #include <console/console.h>
 #include <delay.h>
 
+static struct a10_ccm *const ccm = (void *)A1X_CCM_BASE;
 static struct a1x_dramc *const dram = (void *)A1X_DRAMC_BASE;
 
 static void mctl_ddr3_reset(void)
 {
-	if (a1x_get_cpu_chip_revision() != A1X_CHIP_REV_A) {
-		setbits_le32(&dram->mcr, DRAM_MCR_RESET);
-		udelay(2);
-		clrbits_le32(&dram->mcr, DRAM_MCR_RESET);
+	if (IS_ENABLED(CONFIG_CPU_ALLWINNER_A10)) {
+		struct a1x_timer_module *timer =
+			(struct a1x_timer_module*)A1X_TIMER_BASE;
+		u32 reg;
+
+		write32(&timer->cpu_cfg, 0);
+		reg = read32(&timer->cpu_cfg);
+		if (reg && a1x_get_cpu_chip_revision() != A1X_CHIP_REV_A) {
+			setbits_le32(&dram->mcr, DRAM_MCR_RESET);
+			udelay(2);
+			clrbits_le32(&dram->mcr, DRAM_MCR_RESET);
+		}
 	} else {
 		clrbits_le32(&dram->mcr, DRAM_MCR_RESET);
 		udelay(2);
@@ -50,7 +59,11 @@ static void mctl_ddr3_reset(void)
 
 static void mctl_set_drive(void)
 {
+#if (IS_ENABLED(CONFIG_CPU_ALLWINNER_A20))
+	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);
 }
 
@@ -114,6 +127,7 @@ static void mctl_enable_dllx(u32 phase)
 }
 
 static u32 hpcr_value[32] = {
+#if IS_ENABLED(CONFIG_CPU_ALLWINNER_A10)
 	0x0301, 0x0301, 0x0301, 0x0301,
 	0x0301, 0x0301, 0, 0,
 	0, 0, 0, 0,
@@ -122,6 +136,22 @@ static u32 hpcr_value[32] = {
 	0x1035, 0x0731, 0x1031, 0x0735,
 	0x1035, 0x1031, 0x0731, 0x1035,
 	0x1031, 0x0301, 0x0301, 0x0731
+#endif
+#if IS_ENABLED(CONFIG_CPU_ALLWINNER_A20)
+	0x0301, 0x0301, 0x0301, 0x0301,
+	0x0301, 0x0301, 0x0301, 0x0301,
+	0, 0, 0, 0,
+	0, 0, 0, 0,
+	0x1031, 0x1031, 0x0735, 0x1035,
+	0x1035, 0x0731, 0x1031, 0x0735,
+	0x1035, 0x1031, 0x0731, 0x1035,
+	0x0001, 0x1031, 0, 0x1031
+	/* last row differs from boot0 source table
+	 * 0x1031, 0x0301, 0x0301, 0x0731
+	 * 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)
@@ -188,12 +218,19 @@ static void mctl_setup_dram_clock(u32 clk)
 	 * open DRAMC AHB & DLL register clock
 	 * close it first
 	 */
-	a1x_periph_clock_disable(A1X_CLKEN_SDRAM);
-
+	if (IS_ENABLED(CONFIG_CPU_ALLWINNER_A20)) {
+		clrbits_le32(&ccm->ahb_gate0, AHB_GATE_SDRAM | AHB_GATE_DLL);
+	} else {
+		a1x_periph_clock_disable(A1X_CLKEN_SDRAM);
+	}
 	udelay(22);
 
 	/* then open it */
-	a1x_periph_clock_enable(A1X_CLKEN_SDRAM);
+	if (IS_ENABLED(CONFIG_CPU_ALLWINNER_A20)) {
+		setbits_le32(&ccm->ahb_gate0, AHB_GATE_SDRAM | AHB_GATE_DLL);
+	} else {
+		a1x_periph_clock_enable(A1X_CLKEN_SDRAM);
+	}
 	udelay(22);
 }
 
@@ -202,6 +239,7 @@ static int dramc_scan_readpipe(void)
 	u32 reg32;
 
 	/* data training trigger */
+	clrbits_le32(&dram->csr, DRAM_CSR_FAILED);
 	setbits_le32(&dram->ccr, DRAM_CCR_DATA_TRAINING);
 
 	/* check whether data training process has completed */
@@ -362,16 +400,15 @@ unsigned long dramc_init(struct dram_para *para)
 	/* setup DRAM relative clock */
 	mctl_setup_dram_clock(para->clock);
 
-	/* reset external DRAM */
-	mctl_ddr3_reset();
-
 	mctl_set_drive();
 
 	/* dram clock off */
 	a1x_gate_dram_clock_output();
 
-	/* select dram controller 1 */
-	write32(&dram->csel, DRAM_CSEL_MAGIC);
+	if (IS_ENABLED(CONFIG_CPU_ALLWINNER_A10)) {
+		/* select dram controller 1 */
+		write32(&dram->csel, DRAM_CSEL_MAGIC);
+	}
 
 	mctl_itm_disable();
 	mctl_enable_dll0(para->tpr3);
@@ -406,6 +443,9 @@ unsigned long dramc_init(struct dram_para *para)
 	/* dram clock on */
 	a1x_ungate_dram_clock_output();
 
+	/* reset external DRAM */
+	mctl_ddr3_reset();
+
 	udelay(1);
 
 	while (read32(&dram->ccr) & DRAM_CCR_INIT) ;
@@ -434,6 +474,9 @@ unsigned long dramc_init(struct dram_para *para)
 
 	if (para->type == DRAM_MEMORY_TYPE_DDR3) {
 		reg32 = DRAM_MR_BURST_LENGTH(0x0);
+		if (IS_ENABLED(CONFIG_CPU_ALLWINNER_A20)) {
+			reg32 |= DRAM_MR_POWER_DOWN;
+		}
 		reg32 |= DRAM_MR_CAS_LAT(para->cas - 4);
 		reg32 |= DRAM_MR_WRITE_RECOVERY(0x5);
 	} else if (para->type == DRAM_MEMORY_TYPE_DDR2) {



More information about the coreboot-gerrit mailing list