sunxi: Add support for Allwinner A64 SoCs
The Allwinner A64 SoC is used in the Pine64. This patch adds
all bits necessary to compile U-Boot for it running in AArch64
mode.
Unfortunately SPL is not ready yet due to legal problems, so
we need to boot using the binary boot0 for now.
Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
[agraf: remove SPL code, move to AArch64]
Signed-off-by: Alexander Graf <agraf@suse.de>
Acked-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index 5e72fac..464fa0f 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -77,6 +77,11 @@
select SUPPORT_SPL
select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
+config MACH_SUN50I
+ bool "sun50i (Allwinner A64)"
+ select ARM64
+ select SUNXI_GEN_SUN6I
+
config MACH_SUN8I_A83T
bool "sun8i (Allwinner A83T)"
select CPU_V7
@@ -213,6 +218,7 @@
endif
config SYS_CLK_FREQ
+ default 816000000 if MACH_SUN50I
default 912000000 if MACH_SUN7I
default 1008000000 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN8I
@@ -223,6 +229,7 @@
default "sun7i" if MACH_SUN7I
default "sun8i" if MACH_SUN8I
default "sun9i" if MACH_SUN9I
+ default "sun50i" if MACH_SUN50I
config SYS_BOARD
default "sunxi"
@@ -604,7 +611,7 @@
Set the GMAC Transmit Clock Delay Chain value.
config SPL_STACK_R_ADDR
- default 0x4fe00000 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN7I || MACH_SUN8I
+ default 0x4fe00000 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN7I || MACH_SUN8I || MACH_SUN50I
default 0x2fe00000 if MACH_SUN9I
endif
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 2271c89..ccf4129 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -21,6 +21,9 @@
#include <asm/arch/gpio.h>
#include <asm/arch/mmc.h>
#include <asm/arch/usb_phy.h>
+#ifndef CONFIG_ARM64
+#include <asm/armv7.h>
+#endif
#include <asm/gpio.h>
#include <asm/io.h>
#include <nand.h>
@@ -73,18 +76,38 @@
/* add board specific code here */
int board_init(void)
{
- int id_pfr1, ret;
+ __maybe_unused int id_pfr1, ret;
gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);
+#ifndef CONFIG_ARM64
asm volatile("mrc p15, 0, %0, c0, c1, 1" : "=r"(id_pfr1));
debug("id_pfr1: 0x%08x\n", id_pfr1);
/* Generic Timer Extension available? */
- if ((id_pfr1 >> 16) & 0xf) {
+ if ((id_pfr1 >> CPUID_ARM_GENTIMER_SHIFT) & 0xf) {
+ uint32_t freq;
+
debug("Setting CNTFRQ\n");
- /* CNTFRQ == 24 MHz */
- asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r"(24000000));
+
+ /*
+ * CNTFRQ is a secure register, so we will crash if we try to
+ * write this from the non-secure world (read is OK, though).
+ * In case some bootcode has already set the correct value,
+ * we avoid the risk of writing to it.
+ */
+ asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r"(freq));
+ if (freq != CONFIG_TIMER_CLK_FREQ) {
+ debug("arch timer frequency is %d Hz, should be %d, fixing ...\n",
+ freq, CONFIG_TIMER_CLK_FREQ);
+#ifdef CONFIG_NON_SECURE
+ printf("arch timer frequency is wrong, but cannot adjust it\n");
+#else
+ asm volatile("mcr p15, 0, %0, c14, c0, 0"
+ : : "r"(CONFIG_TIMER_CLK_FREQ));
+#endif
+ }
}
+#endif /* !CONFIG_ARM64 */
ret = axp_gpio_init();
if (ret)
@@ -264,7 +287,7 @@
sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
}
-#elif defined(CONFIG_MACH_SUN8I)
+#elif defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN50I)
/* SDC2: PC5-PC6, PC8-PC16 */
for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) {
sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
@@ -547,7 +570,7 @@
*/
static void parse_spl_header(const uint32_t spl_addr)
{
- struct boot_file_head *spl = (void *)spl_addr;
+ struct boot_file_head *spl = (void *)(ulong)spl_addr;
if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) == 0) {
uint8_t spl_header_version = spl->spl_signature[3];
if (spl_header_version == SPL_HEADER_VERSION) {