@@ -650,6 +650,9 @@ config TARGET_SUN5I
config TARGET_SUN7I
bool "Support sun7i"
+config TARGET_SUN4I_SUN5I_SUN7I
+ bool "Support sun4i/sun5i/sun7i"
+
config TARGET_SNOWBALL
bool "Support snowball"
@@ -14,6 +14,7 @@ obj-y += pinmux.o
obj-$(CONFIG_SUN4I) += clock_sun4i.o
obj-$(CONFIG_SUN5I) += clock_sun4i.o
obj-$(CONFIG_SUN7I) += clock_sun4i.o
+obj-$(CONFIG_SUN4I_SUN5I_SUN7I) += clock_sun4i.o
ifndef CONFIG_SPL_BUILD
obj-y += cpu_info.o
@@ -26,6 +27,7 @@ ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_SUN4I) += dram.o
obj-$(CONFIG_SUN5I) += dram.o
obj-$(CONFIG_SUN7I) += dram.o
+obj-$(CONFIG_SUN4I_SUN5I_SUN7I) += dram.o
ifdef CONFIG_SPL_FEL
obj-y += start.o
endif
@@ -48,17 +48,62 @@ u32 spl_boot_mode(void)
}
#endif
+static void sunxi_soc_detect_init(void)
+{
+ /* Enable VER_REG (set the VER_R_EN bit) */
+ setbits_le32((u32 *)(SUNXI_SRAMC_BASE + 0x24), 1 << 15);
+}
+
+int soc_is_sun4i(void)
+{
+ return (readl((u32 *)(SUNXI_SRAMC_BASE + 0x24)) >> 16) == 0x1623;
+}
+
+int soc_is_sun5i(void)
+{
+ return (readl((u32 *)(SUNXI_SRAMC_BASE + 0x24)) >> 16) == 0x1625;
+}
+
+int soc_is_sun7i(void)
+{
+ return (readl((u32 *)(SUNXI_SRAMC_BASE + 0x24)) >> 16) == 0x1651;
+}
+
+int sunxi_cons_index(void)
+{
+ int cons_index = CONFIG_CONS_INDEX;
+
+ if (cons_index == 1 && SOC_IS_SUN5I()) {
+ u32 val = readl(SUNXI_SID_BASE + 0x08);
+ if (((val >> 12) & 0xf) == 3) {
+ /* Allwinner A13 */
+ cons_index = 2;
+ }
+ }
+ return cons_index;
+}
+
+struct serial_device *default_serial_console(void)
+{
+ if (sunxi_cons_index() == 1)
+ return &eserial1_device;
+ else
+ return &eserial2_device;
+}
+
int gpio_init(void)
{
- if (CONFIG_CONS_INDEX == 1 && (SOC_IS_SUN4I() || SOC_IS_SUN7I())) {
+ int cons_index = sunxi_cons_index();
+
+ if (cons_index == 1 && (SOC_IS_SUN4I() || SOC_IS_SUN7I())) {
sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB22_UART0_TX);
sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB23_UART0_RX);
sunxi_gpio_set_pull(SUNXI_GPB(23), 1);
- } else if (CONFIG_CONS_INDEX == 1 && SOC_IS_SUN5I()) {
+ } else if (cons_index == 1 && SOC_IS_SUN5I()) {
sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN5I_GPB19_UART0_TX);
sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN5I_GPB20_UART0_RX);
sunxi_gpio_set_pull(SUNXI_GPB(20), 1);
- } else if (CONFIG_CONS_INDEX == 2 && SOC_IS_SUN5I()) {
+ } else if (cons_index == 2 && SOC_IS_SUN5I()) {
sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG3_UART1_TX);
sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG4_UART1_RX);
sunxi_gpio_set_pull(SUNXI_GPG(4), 1);
@@ -88,6 +133,7 @@ void reset_cpu(ulong addr)
/* do some early init */
void s_init(void)
{
+ sunxi_soc_detect_init();
#if !defined CONFIG_SPL_BUILD
int soc_is_sun6i = 0;
#ifdef CONFIG_SUN6I
@@ -51,6 +51,7 @@ void clock_init_uart(void)
{
struct sunxi_ccm_reg *const ccm =
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+ int cons_index = sunxi_cons_index();
/* uart clock source is apb1 */
writel(APB1_CLK_SRC_OSC24M|
@@ -60,7 +61,7 @@ void clock_init_uart(void)
/* open the clock for uart */
setbits_le32(&ccm->apb1_gate,
- CLK_GATE_OPEN << (APB1_GATE_UART_SHIFT+CONFIG_CONS_INDEX-1));
+ CLK_GATE_OPEN << (APB1_GATE_UART_SHIFT + cons_index - 1));
}
int clock_twi_onoff(int port, int state)
@@ -9,6 +9,7 @@
#include <common.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
+#include <asm/arch/sys_proto.h>
#ifdef CONFIG_DISPLAY_CPUINFO
int print_cpuinfo(void)
@@ -13,4 +13,9 @@
void sdelay(unsigned long);
+int sunxi_cons_index(void);
+int soc_is_sun4i(void);
+int soc_is_sun5i(void);
+int soc_is_sun7i(void);
+
#endif
@@ -57,3 +57,23 @@ config SYS_CONFIG_NAME
default "sun7i"
endif
+
+if TARGET_SUN4I_SUN5I_SUN7I
+
+config SYS_CPU
+ string
+ default "armv7"
+
+config SYS_BOARD
+ string
+ default "sunxi"
+
+config SYS_SOC
+ string
+ default "sunxi"
+
+config SYS_CONFIG_NAME
+ string
+ default "sun4i_sun5i_sun7i"
+
+endif
@@ -32,3 +32,10 @@ F: configs/Cubieboard2_defconfig
F: configs/Cubieboard2_FEL_defconfig
F: configs/Cubietruck_defconfig
F: configs/Cubietruck_FEL_defconfig
+
+SUNXI GENERIC
+M: Siarhei Siamashka <siarhei.siamashka@gmail.com>
+S: Maintained
+F: include/configs/sun4i_sun5i_sun7i.h
+F: configs/sunxi-generic-a10-a13-a20_defconfig
+F: configs/sunxi-generic-a10-a13-a20_FEL_defconfig
@@ -11,6 +11,7 @@
obj-y += board.o
obj-$(CONFIG_SUNXI_GMAC) += gmac.o
obj-$(CONFIG_SUNXI_AHCI) += ahci.o
+obj-$(CONFIG_SUNXI_GENERIC_A10_A13_A20) += dram_sunxi_ddr3_failsafe.o
obj-$(CONFIG_A10_OLINUXINO_L) += dram_a10_olinuxino_l.o
obj-$(CONFIG_A10S_OLINUXINO_M) += dram_a10s_olinuxino_m.o
obj-$(CONFIG_A13_OLINUXINO) += dram_a13_olinuxino.o
@@ -23,6 +23,7 @@
#include <asm/arch/dram.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mmc.h>
+#include <asm/arch/sys_proto.h>
#include <asm/io.h>
#include <net.h>
new file mode 100644
@@ -0,0 +1,28 @@
+/* this file is generated, don't edit it yourself */
+
+#include "common.h"
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = { /* DRAM timings: 6-5-5-13 (360 MHz) */
+ .clock = 360,
+ .type = 3,
+ .rank_num = 1,
+ .cas = 6,
+ .zq = 0x7b,
+ .odt_en = 0,
+ .tpr0 = 0x248d5590,
+ .tpr1 = 0xa088,
+ .tpr2 = 0x22a00,
+ .tpr3 = 0x0,
+ .tpr4 = 0x0,
+ .tpr5 = 0x0,
+ .emr1 = 0x0,
+ .emr2 = 0x0,
+ .emr3 = 0x0,
+ .active_windowing = 1,
+};
+
+unsigned long sunxi_dram_init(void)
+{
+ return dramc_init(&dram_para);
+}
new file mode 100644
@@ -0,0 +1,4 @@
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GENERIC_A10_A13_A20,SPL_FEL"
++S:CONFIG_ARM=y
++S:CONFIG_TARGET_SUN4I_SUN5I_SUN7I=y
new file mode 100644
@@ -0,0 +1,4 @@
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GENERIC_A10_A13_A20,SPL"
++S:CONFIG_ARM=y
++S:CONFIG_TARGET_SUN4I_SUN5I_SUN7I=y
new file mode 100644
@@ -0,0 +1,38 @@
+/*
+ * (C) Copyright 2012-2013 Henrik Nordstrom <henrik@henriknordstrom.net>
+ *
+ * Configuration settings for the Allwinner A10 (sun4i) CPU
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define SOC_IS_SUN4I() (soc_is_sun4i())
+#define SOC_IS_SUN5I() (soc_is_sun5i())
+#define SOC_IS_SUN7I() (soc_is_sun7i())
+
+#define CONFIG_SUN4I_SUN5I_SUN7I
+#define CONFIG_CLK_FULL_SPEED (SOC_IS_SUN7I() ? 912000000 : \
+ 1008000000)
+
+#define CONFIG_SYS_PROMPT "sunxi# "
+
+/* The Cortex-A8 CPU in sun4i/sun5i is going to fail runtime
+ * check and will fallback to booting the kernel in secure mode */
+#define CONFIG_ARMV7_ALLOW_SECURE_MODE_FALLBACK 1
+
+/* This is going to be used for sun7i */
+#define CONFIG_ARMV7_VIRT 1
+#define CONFIG_ARMV7_NONSEC 1
+#define CONFIG_ARMV7_PSCI 1
+#define CONFIG_ARMV7_PSCI_NR_CPUS 2
+#define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE
+#define CONFIG_SYS_CLK_FREQ 24000000
+
+/*
+ * Include common sunxi configuration where most the settings are
+ */
+#include <configs/sunxi-common.h>
+
+#endif /* __CONFIG_H */
Two new defconfigs ('sunxi-generic-a10-a13-a20_defconfig' and 'sunxi-generic-a10-a13-a20_FEL_defconfig') can be used to build universal u-boot binaries, suitable for all Allwinner A10/A13/A20 devices. The supported peripherals are just UART and MMC (the lowest common denominator approach). MMC support is completely problem free for runtime detection, because it must be supported by BROM and no strange pin muxing configurations are expected. UART is a bit more difficult, but in practice very few configurations exist. And they can be successfully detected at runtime. CONFIG_CONS_INDEX=1 is used on almost all devices. And CONFIG_CONS_INDEX=2 is only used on Allwinner A13, where the SoC just does not have the B19/B20 pins on the package, which are normally used for CONFIG_CONS_INDEX=1 UART on Allwiner A10S. So it is a matter of necessity and not a random choice. The universal u-boot binary should be sufficient for booting the system from SD card and/or getting the u-boot command prompt on the serial console. Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com> --- arch/arm/Kconfig | 3 ++ arch/arm/cpu/armv7/sunxi/Makefile | 2 + arch/arm/cpu/armv7/sunxi/board.c | 52 +++++++++++++++++++++++-- arch/arm/cpu/armv7/sunxi/clock_sun4i.c | 3 +- arch/arm/cpu/armv7/sunxi/cpu_info.c | 1 + arch/arm/include/asm/arch-sunxi/sys_proto.h | 5 +++ board/sunxi/Kconfig | 20 ++++++++++ board/sunxi/MAINTAINERS | 7 ++++ board/sunxi/Makefile | 1 + board/sunxi/board.c | 1 + board/sunxi/dram_sunxi_ddr3_failsafe.c | 28 +++++++++++++ configs/sunxi-generic-a10-a13-a20_FEL_defconfig | 4 ++ configs/sunxi-generic-a10-a13-a20_defconfig | 4 ++ include/configs/sun4i_sun5i_sun7i.h | 38 ++++++++++++++++++ 14 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 board/sunxi/dram_sunxi_ddr3_failsafe.c create mode 100644 configs/sunxi-generic-a10-a13-a20_FEL_defconfig create mode 100644 configs/sunxi-generic-a10-a13-a20_defconfig create mode 100644 include/configs/sun4i_sun5i_sun7i.h