All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/2] sunxi: Add basic H3 support
@ 2015-11-17 14:12 Jens Kuske
  2015-11-17 14:12 ` [U-Boot] [PATCH 2/2] sunxi: Add H3 DRAM initialization support Jens Kuske
  2015-11-20 15:39 ` [U-Boot] [U-Boot,1/2] sunxi: Add basic H3 support Hans de Goede
  0 siblings, 2 replies; 3+ messages in thread
From: Jens Kuske @ 2015-11-17 14:12 UTC (permalink / raw)
  To: u-boot

Add initial sun8i H3 support, only uart + mmc are supported for now.

Signed-off-by: Jens Kuske <jenskuske@gmail.com>
---
 arch/arm/cpu/armv7/sunxi/board.c       | 4 ++++
 arch/arm/cpu/armv7/sunxi/cpu_info.c    | 2 ++
 arch/arm/include/asm/arch-sunxi/gpio.h | 1 +
 board/sunxi/Kconfig                    | 7 ++++++-
 drivers/power/Kconfig                  | 5 +++--
 include/configs/sun8i.h                | 2 ++
 6 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index 4785ac6..7615e50 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -72,6 +72,10 @@ static int gpio_init(void)
 	sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN8I_A33_GPB_UART0);
 	sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_A33_GPB_UART0);
 	sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP);
+#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_H3)
+	sunxi_gpio_set_cfgpin(SUNXI_GPA(4), SUN8I_H3_GPA_UART0);
+	sunxi_gpio_set_cfgpin(SUNXI_GPA(5), SUN8I_H3_GPA_UART0);
+	sunxi_gpio_set_pull(SUNXI_GPA(5), SUNXI_GPIO_PULL_UP);
 #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN9I)
 	sunxi_gpio_set_cfgpin(SUNXI_GPH(12), SUN9I_GPH_UART0);
 	sunxi_gpio_set_cfgpin(SUNXI_GPH(13), SUN9I_GPH_UART0);
diff --git a/arch/arm/cpu/armv7/sunxi/cpu_info.c b/arch/arm/cpu/armv7/sunxi/cpu_info.c
index 05fef32..1e73332 100644
--- a/arch/arm/cpu/armv7/sunxi/cpu_info.c
+++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c
@@ -69,6 +69,8 @@ int print_cpuinfo(void)
 	puts("CPU:   Allwinner A23 (SUN8I)\n");
 #elif defined CONFIG_MACH_SUN8I_A33
 	puts("CPU:   Allwinner A33 (SUN8I)\n");
+#elif defined CONFIG_MACH_SUN8I_H3
+	puts("CPU:   Allwinner H3 (SUN8I)\n");
 #elif defined CONFIG_MACH_SUN9I
 	puts("CPU:   Allwinner A80 (SUN9I)\n");
 #else
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index 8382101..7af5e29 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -147,6 +147,7 @@ enum sunxi_gpio_number {
 #define SUN7I_GPA_GMAC		5
 #define SUN6I_GPA_SDC2		5
 #define SUN6I_GPA_SDC3		4
+#define SUN8I_H3_GPA_UART0	2
 
 #define SUN4I_GPB_TWI0		2
 #define SUN4I_GPB_TWI1		2
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index f6f2a60..e1f574f 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -68,6 +68,11 @@ config MACH_SUN8I_A33
 	select SUPPORT_SPL
 	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
 
+config MACH_SUN8I_H3
+	bool "sun8i (Allwinner H3)"
+	select CPU_V7
+	select SUNXI_GEN_SUN6I
+
 config MACH_SUN9I
 	bool "sun9i (Allwinner A80)"
 	select CPU_V7
@@ -78,7 +83,7 @@ endchoice
 # The sun8i SoCs share a lot, this helps to avoid a lot of "if A23 || A33"
 config MACH_SUN8I
 	bool
-	default y if MACH_SUN8I_A23 || MACH_SUN8I_A33
+	default y if MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_H3
 
 
 config DRAM_CLK
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 809f8f1..1936e5f 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -8,7 +8,8 @@ choice
 	prompt "Select Sunxi PMIC Variant"
 	depends on ARCH_SUNXI
 	default AXP209_POWER if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
-	default AXP221_POWER if MACH_SUN6I || MACH_SUN8I
+	default AXP221_POWER if MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33
+	default SUNXI_NO_PMIC if MACH_SUN8I_H3
 
 config SUNXI_NO_PMIC
 	boolean "board without a pmic"
@@ -31,7 +32,7 @@ config AXP209_POWER
 
 config AXP221_POWER
 	boolean "axp221 / axp223 pmic support"
-	depends on MACH_SUN6I || MACH_SUN8I
+	depends on MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33
 	---help---
 	Select this to enable support for the axp221/axp223 pmic found on most
 	A23 and A31 boards.
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h
index 4fc6365..113e320 100644
--- a/include/configs/sun8i.h
+++ b/include/configs/sun8i.h
@@ -25,6 +25,8 @@
 #define CONFIG_ARMV7_PSCI_NR_CPUS	2
 #elif defined(CONFIG_MACH_SUN8I_A33)
 #define CONFIG_ARMV7_PSCI_NR_CPUS	4
+#elif defined(CONFIG_MACH_SUN8I_H3)
+#define CONFIG_ARMV7_PSCI_NR_CPUS	4
 #else
 #error Unsupported sun8i variant
 #endif
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [U-Boot] [PATCH 2/2] sunxi: Add H3 DRAM initialization support
  2015-11-17 14:12 [U-Boot] [PATCH 1/2] sunxi: Add basic H3 support Jens Kuske
@ 2015-11-17 14:12 ` Jens Kuske
  2015-11-20 15:39 ` [U-Boot] [U-Boot,1/2] sunxi: Add basic H3 support Hans de Goede
  1 sibling, 0 replies; 3+ messages in thread
From: Jens Kuske @ 2015-11-17 14:12 UTC (permalink / raw)
  To: u-boot

Based on existing A23/A33 code and the original H3 boot0.

Signed-off-by: Jens Kuske <jenskuske@gmail.com>
---
 arch/arm/cpu/armv7/sunxi/Makefile               |   1 +
 arch/arm/cpu/armv7/sunxi/dram_sun8i_h3.c        | 469 ++++++++++++++++++++++++
 arch/arm/include/asm/arch-sunxi/clock_sun6i.h   |   3 +
 arch/arm/include/asm/arch-sunxi/dram.h          |   2 +
 arch/arm/include/asm/arch-sunxi/dram_sun8i_h3.h | 185 ++++++++++
 board/sunxi/Kconfig                             |   1 +
 6 files changed, 661 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/sunxi/dram_sun8i_h3.c
 create mode 100644 arch/arm/include/asm/arch-sunxi/dram_sun8i_h3.h

diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index 459d5d8..33c76ef 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -49,5 +49,6 @@ obj-$(CONFIG_MACH_SUN6I)	+= dram_sun6i.o
 obj-$(CONFIG_MACH_SUN7I)	+= dram_sun4i.o
 obj-$(CONFIG_MACH_SUN8I_A23)	+= dram_sun8i_a23.o
 obj-$(CONFIG_MACH_SUN8I_A33)	+= dram_sun8i_a33.o
+obj-$(CONFIG_MACH_SUN8I_H3)	+= dram_sun8i_h3.o
 obj-y	+= fel_utils.o
 endif
diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun8i_h3.c b/arch/arm/cpu/armv7/sunxi/dram_sun8i_h3.c
new file mode 100644
index 0000000..b721d60
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/dram_sun8i_h3.c
@@ -0,0 +1,469 @@
+/*
+ * sun8i H3 platform dram controller init
+ *
+ * (C) Copyright 2007-2015 Allwinner Technology Co.
+ *                         Jerry Wang <wangflord@allwinnertech.com>
+ * (C) Copyright 2015      Vishnu Patekar <vishnupatekar0510@gmail.com>
+ * (C) Copyright 2015      Hans de Goede <hdegoede@redhat.com>
+ * (C) Copyright 2015      Jens Kuske <jenskuske@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/dram.h>
+#include <linux/kconfig.h>
+
+struct dram_para {
+	u32 read_delays;
+	u32 write_delays;
+	u16 page_size;
+	u8 bus_width;
+	u8 dual_rank;
+	u8 row_bits;
+};
+
+static inline int ns_to_t(int nanoseconds)
+{
+	const unsigned int ctrl_freq = CONFIG_DRAM_CLK / 2;
+
+	return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000);
+}
+
+static u32 bin_to_mgray(int val)
+{
+	static const u8 lookup_table[32] = {
+		0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
+		0x0c, 0x0d, 0x0e, 0x0f, 0x0a, 0x0b, 0x08, 0x09,
+		0x18, 0x19, 0x1a, 0x1b, 0x1e, 0x1f, 0x1c, 0x1d,
+		0x14, 0x15, 0x16, 0x17, 0x12, 0x13, 0x10, 0x11,
+	};
+
+	return lookup_table[clamp(val, 0, 31)];
+}
+
+static int mgray_to_bin(u32 val)
+{
+	static const u8 lookup_table[32] = {
+		0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
+		0x0e, 0x0f, 0x0c, 0x0d, 0x08, 0x09, 0x0a, 0x0b,
+		0x1e, 0x1f, 0x1c, 0x1d, 0x18, 0x19, 0x1a, 0x1b,
+		0x10, 0x11, 0x12, 0x13, 0x16, 0x17, 0x14, 0x15,
+	};
+
+	return lookup_table[val & 0x1f];
+}
+
+static void mctl_phy_init(u32 val)
+{
+	struct sunxi_mctl_ctl_reg * const mctl_ctl =
+			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+	writel(val | PIR_INIT, &mctl_ctl->pir);
+	mctl_await_completion(&mctl_ctl->pgsr[0], PGSR_INIT_DONE, 0x1);
+}
+
+static void mctl_dq_delay(u32 read, u32 write)
+{
+	struct sunxi_mctl_ctl_reg * const mctl_ctl =
+			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+	int i, j;
+	u32 val;
+
+	for (i = 0; i < 4; i++) {
+		val = DATX_IOCR_WRITE_DELAY((write >> (i * 4)) & 0xf) |
+		      DATX_IOCR_READ_DELAY((read >> (i * 4)) & 0xf);
+
+		for (j = DATX_IOCR_DQ(0); j <= DATX_IOCR_DM; j++)
+			setbits_le32(&mctl_ctl->datx[i].iocr[j], val);
+	}
+
+	clrbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
+
+	for (i = 0; i < 4; i++) {
+		val = DATX_IOCR_WRITE_DELAY((write >> (16 + i * 4)) & 0xf) |
+		      DATX_IOCR_READ_DELAY((read >> (16 + i * 4)) & 0xf);
+
+		setbits_le32(&mctl_ctl->datx[i].iocr[DATX_IOCR_DQS], val);
+		setbits_le32(&mctl_ctl->datx[i].iocr[DATX_IOCR_DQSN], val);
+	}
+
+	setbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
+
+	udelay(1);
+}
+
+static void mctl_set_master_priority(void)
+{
+	struct sunxi_mctl_com_reg * const mctl_com =
+			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
+
+	/* enable bandwidth limit windows and set windows size 1us */
+	writel(0x00010190, &mctl_com->bwcr);
+
+	/* set cpu high priority */
+	writel(0x00000001, &mctl_com->mapr);
+
+	writel(0x0200000d, &mctl_com->mcr[0][0]);
+	writel(0x00800100, &mctl_com->mcr[0][1]);
+	writel(0x06000009, &mctl_com->mcr[1][0]);
+	writel(0x01000400, &mctl_com->mcr[1][1]);
+	writel(0x0200000d, &mctl_com->mcr[2][0]);
+	writel(0x00600100, &mctl_com->mcr[2][1]);
+	writel(0x0100000d, &mctl_com->mcr[3][0]);
+	writel(0x00200080, &mctl_com->mcr[3][1]);
+	writel(0x07000009, &mctl_com->mcr[4][0]);
+	writel(0x01000640, &mctl_com->mcr[4][1]);
+	writel(0x0100000d, &mctl_com->mcr[5][0]);
+	writel(0x00200080, &mctl_com->mcr[5][1]);
+	writel(0x01000009, &mctl_com->mcr[6][0]);
+	writel(0x00400080, &mctl_com->mcr[6][1]);
+	writel(0x0100000d, &mctl_com->mcr[7][0]);
+	writel(0x00400080, &mctl_com->mcr[7][1]);
+	writel(0x0100000d, &mctl_com->mcr[8][0]);
+	writel(0x00400080, &mctl_com->mcr[8][1]);
+	writel(0x04000009, &mctl_com->mcr[9][0]);
+	writel(0x00400100, &mctl_com->mcr[9][1]);
+	writel(0x2000030d, &mctl_com->mcr[10][0]);
+	writel(0x04001800, &mctl_com->mcr[10][1]);
+	writel(0x04000009, &mctl_com->mcr[11][0]);
+	writel(0x00400120, &mctl_com->mcr[11][1]);
+}
+
+static void mctl_set_timing_params(struct dram_para *para)
+{
+	struct sunxi_mctl_ctl_reg * const mctl_ctl =
+			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+	u8 tccd		= 2;
+	u8 tfaw		= ns_to_t(50);
+	u8 trrd		= max(ns_to_t(10), 4);
+	u8 trcd		= ns_to_t(15);
+	u8 trc		= ns_to_t(53);
+	u8 txp		= max(ns_to_t(8), 3);
+	u8 twtr		= max(ns_to_t(8), 4);
+	u8 trtp		= max(ns_to_t(8), 4);
+	u8 twr		= max(ns_to_t(15), 3);
+	u8 trp		= ns_to_t(15);
+	u8 tras		= ns_to_t(38);
+	u16 trefi	= ns_to_t(7800) / 32;
+	u16 trfc	= ns_to_t(350);
+
+	u8 tmrw		= 0;
+	u8 tmrd		= 4;
+	u8 tmod		= 12;
+	u8 tcke		= 3;
+	u8 tcksrx	= 5;
+	u8 tcksre	= 5;
+	u8 tckesr	= 4;
+	u8 trasmax	= 24;
+
+	u8 tcl		= 6; /* CL 12 */
+	u8 tcwl		= 4; /* CWL 8 */
+	u8 t_rdata_en	= 4;
+	u8 wr_latency	= 2;
+
+	u32 tdinit0	= (500 * CONFIG_DRAM_CLK) + 1;		/* 500us */
+	u32 tdinit1	= (360 * CONFIG_DRAM_CLK) / 1000 + 1;	/* 360ns */
+	u32 tdinit2	= (200 * CONFIG_DRAM_CLK) + 1;		/* 200us */
+	u32 tdinit3	= (1 * CONFIG_DRAM_CLK) + 1;		/* 1us */
+
+	u8 twtp		= tcwl + 2 + twr;	/* WL + BL / 2 + tWR */
+	u8 twr2rd	= tcwl + 2 + twtr;	/* WL + BL / 2 + tWTR */
+	u8 trd2wr	= tcl + 2 + 1 - tcwl;	/* RL + BL / 2 + 2 - WL */
+
+	/* set mode register */
+	writel(0x1c70, &mctl_ctl->mr[0]);	/* CL=11, WR=12 */
+	writel(0x40, &mctl_ctl->mr[1]);
+	writel(0x18, &mctl_ctl->mr[2]);		/* CWL=8 */
+	writel(0x0, &mctl_ctl->mr[3]);
+
+	/* set DRAM timing */
+	writel(DRAMTMG0_TWTP(twtp) | DRAMTMG0_TFAW(tfaw) |
+	       DRAMTMG0_TRAS_MAX(trasmax) | DRAMTMG0_TRAS(tras),
+	       &mctl_ctl->dramtmg[0]);
+	writel(DRAMTMG1_TXP(txp) | DRAMTMG1_TRTP(trtp) | DRAMTMG1_TRC(trc),
+	       &mctl_ctl->dramtmg[1]);
+	writel(DRAMTMG2_TCWL(tcwl) | DRAMTMG2_TCL(tcl) |
+	       DRAMTMG2_TRD2WR(trd2wr) | DRAMTMG2_TWR2RD(twr2rd),
+	       &mctl_ctl->dramtmg[2]);
+	writel(DRAMTMG3_TMRW(tmrw) | DRAMTMG3_TMRD(tmrd) | DRAMTMG3_TMOD(tmod),
+	       &mctl_ctl->dramtmg[3]);
+	writel(DRAMTMG4_TRCD(trcd) | DRAMTMG4_TCCD(tccd) | DRAMTMG4_TRRD(trrd) |
+	       DRAMTMG4_TRP(trp), &mctl_ctl->dramtmg[4]);
+	writel(DRAMTMG5_TCKSRX(tcksrx) | DRAMTMG5_TCKSRE(tcksre) |
+	       DRAMTMG5_TCKESR(tckesr) | DRAMTMG5_TCKE(tcke),
+	       &mctl_ctl->dramtmg[5]);
+
+	/* set two rank timing */
+	clrsetbits_le32(&mctl_ctl->dramtmg[8], (0xff << 8) | (0xff << 0),
+			(0x66 << 8) | (0x10 << 0));
+
+	/* set PHY interface timing, write latency and read latency configure */
+	writel((0x2 << 24) | (t_rdata_en << 16) | (0x1 << 8) |
+	       (wr_latency << 0), &mctl_ctl->pitmg[0]);
+
+	/* set PHY timing, PTR0-2 use default */
+	writel(PTR3_TDINIT0(tdinit0) | PTR3_TDINIT1(tdinit1), &mctl_ctl->ptr[3]);
+	writel(PTR4_TDINIT2(tdinit2) | PTR4_TDINIT3(tdinit3), &mctl_ctl->ptr[4]);
+
+	/* set refresh timing */
+	writel(RFSHTMG_TREFI(trefi) | RFSHTMG_TRFC(trfc), &mctl_ctl->rfshtmg);
+}
+
+static void mctl_zq_calibration(struct dram_para *para)
+{
+	struct sunxi_mctl_ctl_reg * const mctl_ctl =
+			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+	int i;
+	u16 zq_val[6];
+	u8 val;
+
+	writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]);
+
+	for (i = 0; i < 6; i++) {
+		u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
+
+		writel((zq << 20) | (zq << 16) | (zq << 12) |
+				(zq << 8) | (zq << 4) | (zq << 0),
+				&mctl_ctl->zqcr);
+
+		writel(PIR_CLRSR, &mctl_ctl->pir);
+		mctl_phy_init(PIR_ZCAL);
+
+		zq_val[i] = readl(&mctl_ctl->zqdr[0]) & 0xff;
+		writel(REPEAT_BYTE(zq_val[i]), &mctl_ctl->zqdr[2]);
+
+		writel(PIR_CLRSR, &mctl_ctl->pir);
+		mctl_phy_init(PIR_ZCAL);
+
+		val = readl(&mctl_ctl->zqdr[0]) >> 24;
+		zq_val[i] |= bin_to_mgray(mgray_to_bin(val) - 1) << 8;
+	}
+
+	writel((zq_val[1] << 16) | zq_val[0], &mctl_ctl->zqdr[0]);
+	writel((zq_val[3] << 16) | zq_val[2], &mctl_ctl->zqdr[1]);
+	writel((zq_val[5] << 16) | zq_val[4], &mctl_ctl->zqdr[2]);
+}
+
+static void mctl_set_cr(struct dram_para *para)
+{
+	struct sunxi_mctl_com_reg * const mctl_com =
+			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
+
+	writel(MCTL_CR_BL8 | MCTL_CR_2T | MCTL_CR_DDR3 | MCTL_CR_INTERLEAVED |
+	       MCTL_CR_EIGHT_BANKS | MCTL_CR_BUS_WIDTH(para->bus_width) |
+	       (para->dual_rank ? MCTL_CR_DUAL_RANK : MCTL_CR_SINGLE_RANK) |
+	       MCTL_CR_PAGE_SIZE(para->page_size) |
+	       MCTL_CR_ROW_BITS(para->row_bits), &mctl_com->cr);
+}
+
+static void mctl_sys_init(struct dram_para *para)
+{
+	struct sunxi_ccm_reg * const ccm =
+			(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	struct sunxi_mctl_ctl_reg * const mctl_ctl =
+			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+	clrbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
+	clrbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
+	clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
+	clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
+	clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
+	udelay(10);
+
+	clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
+	udelay(1000);
+
+	clock_set_pll5(CONFIG_DRAM_CLK * 2 * 1000000, false);
+	clrsetbits_le32(&ccm->dram_clk_cfg,
+			CCM_DRAMCLK_CFG_DIV_MASK | CCM_DRAMCLK_CFG_SRC_MASK,
+			CCM_DRAMCLK_CFG_DIV(1) | CCM_DRAMCLK_CFG_SRC_PLL5 |
+			CCM_DRAMCLK_CFG_UPD);
+	mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
+
+	setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
+	setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
+	setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
+	setbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
+
+	setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
+	udelay(10);
+
+	writel(0xc00e, &mctl_ctl->clken);
+	udelay(500);
+}
+
+static int mctl_channel_init(struct dram_para *para)
+{
+	struct sunxi_mctl_com_reg * const mctl_com =
+			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
+	struct sunxi_mctl_ctl_reg * const mctl_ctl =
+			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+	unsigned int i;
+
+	mctl_set_cr(para);
+	mctl_set_timing_params(para);
+	mctl_set_master_priority();
+
+	/* setting VTC, default disable all VT */
+	clrbits_le32(&mctl_ctl->pgcr[0], (1 << 30) | 0x3f);
+	clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26);
+
+	/* increase DFI_PHY_UPD clock */
+	writel(PROTECT_MAGIC, &mctl_com->protect);
+	udelay(100);
+	clrsetbits_le32(&mctl_ctl->upd2, 0xfff << 16, 0x50 << 16);
+	writel(0x0, &mctl_com->protect);
+	udelay(100);
+
+	/* set dramc odt */
+	for (i = 0; i < 4; i++)
+		clrsetbits_le32(&mctl_ctl->datx[i].gcr, (0x3 << 4) |
+				(0x1 << 1) | (0x3 << 2) | (0x3 << 12) |
+				(0x3 << 14),
+				IS_ENABLED(CONFIG_DRAM_ODT_EN) ? 0x0 : 0x2);
+
+	/* AC PDR should always ON */
+	setbits_le32(&mctl_ctl->aciocr, 0x1 << 1);
+
+	/* set DQS auto gating PD mode */
+	setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6);
+
+	/* dx ddr_clk & hdr_clk dynamic mode */
+	clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
+
+	/* dphy & aphy phase select 270 degree */
+	clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
+			(0x1 << 10) | (0x2 << 8));
+
+	/* set half DQ */
+	if (para->bus_width != 32) {
+		writel(0x0, &mctl_ctl->datx[2].gcr);
+		writel(0x0, &mctl_ctl->datx[3].gcr);
+	}
+
+	/* data training configuration */
+	clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24,
+			(para->dual_rank ? 0x3 : 0x1) << 24);
+
+
+	if (para->read_delays || para->write_delays) {
+		mctl_dq_delay(para->read_delays, para->write_delays);
+		udelay(50);
+	}
+
+	mctl_zq_calibration(para);
+
+	mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST | PIR_DRAMRST |
+		      PIR_DRAMINIT | PIR_QSGATE);
+
+	/* detect ranks and bus width */
+	if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20)) {
+		/* only one rank */
+		if (((readl(&mctl_ctl->datx[0].gsr[0]) >> 24) & 0x2) ||
+		    ((readl(&mctl_ctl->datx[1].gsr[0]) >> 24) & 0x2)) {
+			clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
+			para->dual_rank = 0;
+		}
+
+		/* only half DQ width */
+		if (((readl(&mctl_ctl->datx[2].gsr[0]) >> 24) & 0x1) ||
+		    ((readl(&mctl_ctl->datx[3].gsr[0]) >> 24) & 0x1)) {
+			writel(0x0, &mctl_ctl->datx[2].gcr);
+			writel(0x0, &mctl_ctl->datx[3].gcr);
+			para->bus_width = 16;
+		}
+
+		mctl_set_cr(para);
+		udelay(20);
+
+		/* re-train */
+		mctl_phy_init(PIR_QSGATE);
+		if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20))
+			return 1;
+	}
+
+	/* check the dramc status */
+	mctl_await_completion(&mctl_ctl->statr, 0x1, 0x1);
+
+	/* liuke added for refresh debug */
+	setbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
+	udelay(10);
+	clrbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
+	udelay(10);
+
+	/* set PGCR3, CKE polarity */
+	writel(0x00aa0060, &mctl_ctl->pgcr[3]);
+
+	/* power down zq calibration module for power save */
+	setbits_le32(&mctl_ctl->zqcr, ZQCR_PWRDOWN);
+
+	/* enable master access */
+	writel(0xffffffff, &mctl_com->maer);
+
+	return 0;
+}
+
+static void mctl_auto_detect_dram_size(struct dram_para *para)
+{
+	/* detect row address bits */
+	para->page_size = 512;
+	para->row_bits = 16;
+	mctl_set_cr(para);
+
+	for (para->row_bits = 11; para->row_bits < 16; para->row_bits++)
+		if (mctl_mem_matches((1 << (para->row_bits + 3)) * para->page_size))
+			break;
+
+	/* detect page size */
+	para->page_size = 8192;
+	mctl_set_cr(para);
+
+	for (para->page_size = 512; para->page_size < 8192; para->page_size *= 2)
+		if (mctl_mem_matches(para->page_size))
+			break;
+}
+
+unsigned long sunxi_dram_init(void)
+{
+	struct sunxi_mctl_com_reg * const mctl_com =
+			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
+	struct sunxi_mctl_ctl_reg * const mctl_ctl =
+			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+
+	struct dram_para para = {
+		.read_delays = 0x00007979,
+		.write_delays = 0x6aaa0000,
+		.dual_rank = 0,
+		.bus_width = 32,
+		.row_bits = 15,
+		.page_size = 4096,
+	};
+
+	mctl_sys_init(&para);
+	if (mctl_channel_init(&para))
+		return 0;
+
+	if (para.dual_rank)
+		writel(0x00000303, &mctl_ctl->odtmap);
+	else
+		writel(0x00000201, &mctl_ctl->odtmap);
+	udelay(1);
+
+	/* odt delay */
+	writel(0x0c000400, &mctl_ctl->odtcfg);
+
+	/* clear credit value */
+	setbits_le32(&mctl_com->cccr, 1 << 31);
+	udelay(10);
+
+	mctl_auto_detect_dram_size(&para);
+	mctl_set_cr(&para);
+
+	return (1 << (para.row_bits + 3)) * para.page_size *
+						(para.dual_rank ? 2 : 1);
+}
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
index 9b7b90c..584d351 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
@@ -282,6 +282,9 @@ struct sunxi_ccm_reg {
 #define CCM_DRAMCLK_CFG_DIV_MASK	(0xf << 0)
 #define CCM_DRAMCLK_CFG_DIV0(x)		((x - 1) << 8)
 #define CCM_DRAMCLK_CFG_DIV0_MASK	(0xf << 8)
+#define CCM_DRAMCLK_CFG_SRC_PLL5	(0x0 << 20)
+#define CCM_DRAMCLK_CFG_SRC_PLL6x2	(0x1 << 20)
+#define CCM_DRAMCLK_CFG_SRC_MASK	(0x3 << 20)
 #define CCM_DRAMCLK_CFG_UPD		(0x1 << 16)
 #define CCM_DRAMCLK_CFG_RST		(0x1 << 31)
 
diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h
index 273f80f..b3c1688 100644
--- a/arch/arm/include/asm/arch-sunxi/dram.h
+++ b/arch/arm/include/asm/arch-sunxi/dram.h
@@ -22,6 +22,8 @@
 #include <asm/arch/dram_sun8i_a23.h>
 #elif defined(CONFIG_MACH_SUN8I_A33)
 #include <asm/arch/dram_sun8i_a33.h>
+#elif defined(CONFIG_MACH_SUN8I_H3)
+#include <asm/arch/dram_sun8i_h3.h>
 #else
 #include <asm/arch/dram_sun4i.h>
 #endif
diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun8i_h3.h b/arch/arm/include/asm/arch-sunxi/dram_sun8i_h3.h
new file mode 100644
index 0000000..d0f2b8a
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/dram_sun8i_h3.h
@@ -0,0 +1,185 @@
+/*
+ * sun8i H3 platform dram controller register and constant defines
+ *
+ * (C) Copyright 2007-2015 Allwinner Technology Co.
+ *                         Jerry Wang <wangflord@allwinnertech.com>
+ * (C) Copyright 2015      Vishnu Patekar <vishnupatekar0510@gmail.com>
+ * (C) Copyright 2014-2015 Hans de Goede <hdegoede@redhat.com>
+ * (C) Copyright 2015      Jens Kuske <jenskuske@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _SUNXI_DRAM_SUN8I_H3_H
+#define _SUNXI_DRAM_SUN8I_H3_H
+
+struct sunxi_mctl_com_reg {
+	u32 cr;			/* 0x00 control register */
+	u8 res0[0xc];		/* 0x04 */
+	u32 mcr[16][2];		/* 0x10 */
+	u32 bwcr;		/* 0x90 bandwidth control register */
+	u32 maer;		/* 0x94 master enable register */
+	u32 mapr;		/* 0x98 master priority register */
+	u32 mcgcr;		/* 0x9c */
+	u32 cpu_bwcr;		/* 0xa0 */
+	u32 gpu_bwcr;		/* 0xa4 */
+	u32 ve_bwcr;		/* 0xa8 */
+	u32 disp_bwcr;		/* 0xac */
+	u32 other_bwcr;		/* 0xb0 */
+	u32 total_bwcr;		/* 0xb4 */
+	u8 res1[0x8];		/* 0xb8 */
+	u32 swonr;		/* 0xc0 */
+	u32 swoffr;		/* 0xc4 */
+	u8 res2[0x8];		/* 0xc8 */
+	u32 cccr;		/* 0xd0 */
+	u8 res3[0x72c];		/* 0xd4 */
+	u32 protect;		/* 0x800 */
+};
+
+#define MCTL_CR_BL8		(0x4 << 20)
+
+#define MCTL_CR_1T		(0x1 << 19)
+#define MCTL_CR_2T		(0x0 << 19)
+
+#define MCTL_CR_LPDDR3		(0x7 << 16)
+#define MCTL_CR_LPDDR2		(0x6 << 16)
+#define MCTL_CR_DDR3		(0x3 << 16)
+#define MCTL_CR_DDR2		(0x2 << 16)
+
+#define MCTL_CR_SEQUENTIAL	(0x1 << 15)
+#define MCTL_CR_INTERLEAVED	(0x0 << 15)
+
+#define MCTL_CR_32BIT		(0x1 << 12)
+#define MCTL_CR_16BIT		(0x0 << 12)
+#define MCTL_CR_BUS_WIDTH(x)	((x) == 32 ? MCTL_CR_32BIT : MCTL_CR_16BIT)
+
+#define MCTL_CR_PAGE_SIZE(x)	((fls(x) - 4) << 8)
+#define MCTL_CR_ROW_BITS(x)	(((x) - 1) << 4)
+#define MCTL_CR_EIGHT_BANKS	(0x1 << 2)
+#define MCTL_CR_FOUR_BANKS	(0x0 << 2)
+#define MCTL_CR_DUAL_RANK	(0x1 << 0)
+#define MCTL_CR_SINGLE_RANK	(0x0 << 0)
+
+#define PROTECT_MAGIC		(0x94be6fa3)
+
+struct sunxi_mctl_ctl_reg {
+	u32 pir;		/* 0x00 PHY initialization register */
+	u32 pwrctl;		/* 0x04 */
+	u32 mrctrl;		/* 0x08 */
+	u32 clken;		/* 0x0c */
+	u32 pgsr[2];		/* 0x10 PHY general status registers */
+	u32 statr;		/* 0x18 */
+	u8 res1[0x14];		/* 0x1c */
+	u32 mr[4];		/* 0x30 mode registers */
+	u32 pllgcr;		/* 0x40 */
+	u32 ptr[5];		/* 0x44 PHY timing registers */
+	u32 dramtmg[9];		/* 0x58 DRAM timing registers */
+	u32 odtcfg;		/* 0x7c */
+	u32 pitmg[2];		/* 0x80 PHY interface timing registers */
+	u8 res2[0x4];		/* 0x88 */
+	u32 rfshctl0;		/* 0x8c */
+	u32 rfshtmg;		/* 0x90 refresh timing */
+	u32 rfshctl1;		/* 0x94 */
+	u32 pwrtmg;		/* 0x98 */
+	u8  res3[0x20];		/* 0x9c */
+	u32 dqsgmr;		/* 0xbc */
+	u32 dtcr;		/* 0xc0 */
+	u32 dtar[4];		/* 0xc4 */
+	u32 dtdr[2];		/* 0xd4 */
+	u32 dtmr[2];		/* 0xdc */
+	u32 dtbmr;		/* 0xe4 */
+	u32 catr[2];		/* 0xe8 */
+	u32 dtedr[2];		/* 0xf0 */
+	u8 res4[0x8];		/* 0xf8 */
+	u32 pgcr[4];		/* 0x100 PHY general configuration registers */
+	u32 iovcr[2];		/* 0x110 */
+	u32 dqsdr;		/* 0x118 */
+	u32 dxccr;		/* 0x11c */
+	u32 odtmap;		/* 0x120 */
+	u32 zqctl[2];		/* 0x124 */
+	u8 res6[0x14];		/* 0x12c */
+	u32 zqcr;		/* 0x140 ZQ control register */
+	u32 zqsr;		/* 0x144 ZQ status register */
+	u32 zqdr[3];		/* 0x148 ZQ data registers */
+	u8 res7[0x6c];		/* 0x154 */
+	u32 sched;		/* 0x1c0 */
+	u32 perfhpr[2];		/* 0x1c4 */
+	u32 perflpr[2];		/* 0x1cc */
+	u32 perfwr[2];		/* 0x1d4 */
+	u8 res8[0x2c];		/* 0x1dc */
+	u32 aciocr;		/* 0x208 */
+	u8 res9[0xf4];		/* 0x20c */
+	struct {		/* 0x300 DATX8 modules*/
+		u32 mdlr;		/* 0x00 */
+		u32 lcdlr[3];		/* 0x04 */
+		u32 iocr[11];		/* 0x10 IO configuration register */
+		u32 bdlr6;		/* 0x3c */
+		u32 gtr;		/* 0x40 */
+		u32 gcr;		/* 0x44 */
+		u32 gsr[3];		/* 0x48 */
+		u8 res0[0x2c];		/* 0x54 */
+	} datx[4];
+	u8 res10[0x388];	/* 0x500 */
+	u32 upd2;		/* 0x888 */
+};
+
+#define PTR3_TDINIT1(x)		((x) << 20)
+#define PTR3_TDINIT0(x)		((x) <<  0)
+
+#define PTR4_TDINIT3(x)		((x) << 20)
+#define PTR4_TDINIT2(x)		((x) <<  0)
+
+#define DRAMTMG0_TWTP(x)	((x) << 24)
+#define DRAMTMG0_TFAW(x)	((x) << 16)
+#define DRAMTMG0_TRAS_MAX(x)	((x) <<  8)
+#define DRAMTMG0_TRAS(x)	((x) <<  0)
+
+#define DRAMTMG1_TXP(x)		((x) << 16)
+#define DRAMTMG1_TRTP(x)	((x) <<  8)
+#define DRAMTMG1_TRC(x)		((x) <<  0)
+
+#define DRAMTMG2_TCWL(x)	((x) << 24)
+#define DRAMTMG2_TCL(x)		((x) << 16)
+#define DRAMTMG2_TRD2WR(x)	((x) <<  8)
+#define DRAMTMG2_TWR2RD(x)	((x) <<  0)
+
+#define DRAMTMG3_TMRW(x)	((x) << 16)
+#define DRAMTMG3_TMRD(x)	((x) << 12)
+#define DRAMTMG3_TMOD(x)	((x) <<  0)
+
+#define DRAMTMG4_TRCD(x)	((x) << 24)
+#define DRAMTMG4_TCCD(x)	((x) << 16)
+#define DRAMTMG4_TRRD(x)	((x) <<  8)
+#define DRAMTMG4_TRP(x)		((x) <<  0)
+
+#define DRAMTMG5_TCKSRX(x)	((x) << 24)
+#define DRAMTMG5_TCKSRE(x)	((x) << 16)
+#define DRAMTMG5_TCKESR(x)	((x) <<  8)
+#define DRAMTMG5_TCKE(x)	((x) <<  0)
+
+#define RFSHTMG_TREFI(x)	((x) << 16)
+#define RFSHTMG_TRFC(x)		((x) <<  0)
+
+#define PIR_CLRSR	(0x1 << 27)	/* clear status registers */
+#define PIR_QSGATE	(0x1 << 10)	/* Read DQS gate training */
+#define PIR_DRAMINIT	(0x1 << 8)	/* DRAM initialization */
+#define PIR_DRAMRST	(0x1 << 7)	/* DRAM reset */
+#define PIR_PHYRST	(0x1 << 6)	/* PHY reset */
+#define PIR_DCAL	(0x1 << 5)	/* DDL calibration */
+#define PIR_PLLINIT	(0x1 << 4)	/* PLL initialization */
+#define PIR_ZCAL	(0x1 << 1)	/* ZQ calibration */
+#define PIR_INIT	(0x1 << 0)	/* PHY initialization trigger */
+
+#define PGSR_INIT_DONE	(0x1 << 0)	/* PHY init done */
+
+#define ZQCR_PWRDOWN	(0x1 << 31)	/* ZQ power down */
+
+#define DATX_IOCR_DQ(x)	(x)		/* DQ0-7 IOCR index */
+#define DATX_IOCR_DM	(8)		/* DM IOCR index */
+#define DATX_IOCR_DQS	(9)		/* DQS IOCR index */
+#define DATX_IOCR_DQSN	(10)		/* DQSN IOCR index */
+
+#define DATX_IOCR_WRITE_DELAY(x)	((x) << 8)
+#define DATX_IOCR_READ_DELAY(x)		((x) << 0)
+
+#endif /* _SUNXI_DRAM_SUN8I_H3_H */
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index e1f574f..2dd9d3b 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -72,6 +72,7 @@ config MACH_SUN8I_H3
 	bool "sun8i (Allwinner H3)"
 	select CPU_V7
 	select SUNXI_GEN_SUN6I
+	select SUPPORT_SPL
 
 config MACH_SUN9I
 	bool "sun9i (Allwinner A80)"
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [U-Boot] [U-Boot,1/2] sunxi: Add basic H3 support
  2015-11-17 14:12 [U-Boot] [PATCH 1/2] sunxi: Add basic H3 support Jens Kuske
  2015-11-17 14:12 ` [U-Boot] [PATCH 2/2] sunxi: Add H3 DRAM initialization support Jens Kuske
@ 2015-11-20 15:39 ` Hans de Goede
  1 sibling, 0 replies; 3+ messages in thread
From: Hans de Goede @ 2015-11-20 15:39 UTC (permalink / raw)
  To: u-boot

Hi,

On 17-11-15 15:12, Jens Kuske wrote:
> Add initial sun8i H3 support, only uart + mmc are supported for now.
>
> Signed-off-by: Jens Kuske <jenskuske@gmail.com>

Thanks! I've applied both patches and added 2 more from
myself to bring in the latest upstream dts[i] work and
add defconfigs for the orangepi_plus and orangepi_pc.

I know that the upstream dts work is not yet fully final
due to bus_gates discussion, but the bus_gates bindings
(or any clk stuff for that matter) are not used by
u-boot. So from a u-boot pov this does not matter
(and when booting the kernel u-boot uses the dtb from
the boot medium, not its own copy).

Given the popularity of H3 boards I believe that it is
important to get basic support in place now. Esp. to
keep the contributions from various people working
on H3 support flowing. I'm very happy to see that various
people are contributing to this and I do not want to
discourage them by taking for-ever to merge this :)

Regards,

Hans

p.s.

I've listed myself as maintainer for the orangepi_plus
for now but I do not actually have one, feel free to
submit a follow-up patch updating board/sunxi/MAINTAINERS
to make you the maintainer for that one.

> ---
>   arch/arm/cpu/armv7/sunxi/board.c       | 4 ++++
>   arch/arm/cpu/armv7/sunxi/cpu_info.c    | 2 ++
>   arch/arm/include/asm/arch-sunxi/gpio.h | 1 +
>   board/sunxi/Kconfig                    | 7 ++++++-
>   drivers/power/Kconfig                  | 5 +++--
>   include/configs/sun8i.h                | 2 ++
>   6 files changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
> index 4785ac6..7615e50 100644
> --- a/arch/arm/cpu/armv7/sunxi/board.c
> +++ b/arch/arm/cpu/armv7/sunxi/board.c
> @@ -72,6 +72,10 @@ static int gpio_init(void)
>   	sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN8I_A33_GPB_UART0);
>   	sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_A33_GPB_UART0);
>   	sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP);
> +#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_H3)
> +	sunxi_gpio_set_cfgpin(SUNXI_GPA(4), SUN8I_H3_GPA_UART0);
> +	sunxi_gpio_set_cfgpin(SUNXI_GPA(5), SUN8I_H3_GPA_UART0);
> +	sunxi_gpio_set_pull(SUNXI_GPA(5), SUNXI_GPIO_PULL_UP);
>   #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN9I)
>   	sunxi_gpio_set_cfgpin(SUNXI_GPH(12), SUN9I_GPH_UART0);
>   	sunxi_gpio_set_cfgpin(SUNXI_GPH(13), SUN9I_GPH_UART0);
> diff --git a/arch/arm/cpu/armv7/sunxi/cpu_info.c b/arch/arm/cpu/armv7/sunxi/cpu_info.c
> index 05fef32..1e73332 100644
> --- a/arch/arm/cpu/armv7/sunxi/cpu_info.c
> +++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c
> @@ -69,6 +69,8 @@ int print_cpuinfo(void)
>   	puts("CPU:   Allwinner A23 (SUN8I)\n");
>   #elif defined CONFIG_MACH_SUN8I_A33
>   	puts("CPU:   Allwinner A33 (SUN8I)\n");
> +#elif defined CONFIG_MACH_SUN8I_H3
> +	puts("CPU:   Allwinner H3 (SUN8I)\n");
>   #elif defined CONFIG_MACH_SUN9I
>   	puts("CPU:   Allwinner A80 (SUN9I)\n");
>   #else
> diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
> index 8382101..7af5e29 100644
> --- a/arch/arm/include/asm/arch-sunxi/gpio.h
> +++ b/arch/arm/include/asm/arch-sunxi/gpio.h
> @@ -147,6 +147,7 @@ enum sunxi_gpio_number {
>   #define SUN7I_GPA_GMAC		5
>   #define SUN6I_GPA_SDC2		5
>   #define SUN6I_GPA_SDC3		4
> +#define SUN8I_H3_GPA_UART0	2
>
>   #define SUN4I_GPB_TWI0		2
>   #define SUN4I_GPB_TWI1		2
> diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
> index f6f2a60..e1f574f 100644
> --- a/board/sunxi/Kconfig
> +++ b/board/sunxi/Kconfig
> @@ -68,6 +68,11 @@ config MACH_SUN8I_A33
>   	select SUPPORT_SPL
>   	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
>
> +config MACH_SUN8I_H3
> +	bool "sun8i (Allwinner H3)"
> +	select CPU_V7
> +	select SUNXI_GEN_SUN6I
> +
>   config MACH_SUN9I
>   	bool "sun9i (Allwinner A80)"
>   	select CPU_V7
> @@ -78,7 +83,7 @@ endchoice
>   # The sun8i SoCs share a lot, this helps to avoid a lot of "if A23 || A33"
>   config MACH_SUN8I
>   	bool
> -	default y if MACH_SUN8I_A23 || MACH_SUN8I_A33
> +	default y if MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_H3
>
>
>   config DRAM_CLK
> diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
> index 809f8f1..1936e5f 100644
> --- a/drivers/power/Kconfig
> +++ b/drivers/power/Kconfig
> @@ -8,7 +8,8 @@ choice
>   	prompt "Select Sunxi PMIC Variant"
>   	depends on ARCH_SUNXI
>   	default AXP209_POWER if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
> -	default AXP221_POWER if MACH_SUN6I || MACH_SUN8I
> +	default AXP221_POWER if MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33
> +	default SUNXI_NO_PMIC if MACH_SUN8I_H3
>
>   config SUNXI_NO_PMIC
>   	boolean "board without a pmic"
> @@ -31,7 +32,7 @@ config AXP209_POWER
>
>   config AXP221_POWER
>   	boolean "axp221 / axp223 pmic support"
> -	depends on MACH_SUN6I || MACH_SUN8I
> +	depends on MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33
>   	---help---
>   	Select this to enable support for the axp221/axp223 pmic found on most
>   	A23 and A31 boards.
> diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h
> index 4fc6365..113e320 100644
> --- a/include/configs/sun8i.h
> +++ b/include/configs/sun8i.h
> @@ -25,6 +25,8 @@
>   #define CONFIG_ARMV7_PSCI_NR_CPUS	2
>   #elif defined(CONFIG_MACH_SUN8I_A33)
>   #define CONFIG_ARMV7_PSCI_NR_CPUS	4
> +#elif defined(CONFIG_MACH_SUN8I_H3)
> +#define CONFIG_ARMV7_PSCI_NR_CPUS	4
>   #else
>   #error Unsupported sun8i variant
>   #endif
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-11-20 15:39 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-17 14:12 [U-Boot] [PATCH 1/2] sunxi: Add basic H3 support Jens Kuske
2015-11-17 14:12 ` [U-Boot] [PATCH 2/2] sunxi: Add H3 DRAM initialization support Jens Kuske
2015-11-20 15:39 ` [U-Boot] [U-Boot,1/2] sunxi: Add basic H3 support Hans de Goede

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.