aspeed: Add AST2600 platform support
authorChia-Wei, Wang <chiawei_wang@aspeedtech.com>
Mon, 14 Dec 2020 05:54:28 +0000 (13:54 +0800)
committerTom Rini <trini@konsulko.com>
Mon, 18 Jan 2021 20:23:06 +0000 (15:23 -0500)
Add low level platform initialization for the AST2600 SoC.
The 2-stage booting with U-Boot SPL are leveraged to support
different booting mode.

However, currently the patch supports only the booting from
memory-mapped SPI flash.

Signed-off-by: Chia-Wei, Wang <chiawei_wang@aspeedtech.com>
Reviewed-by: Ryan Chen <ryan_chen@aspeedtech.com>
14 files changed:
arch/arm/include/asm/arch-aspeed/boot0.h [new file with mode: 0644]
arch/arm/include/asm/arch-aspeed/platform.h
arch/arm/mach-aspeed/Kconfig
arch/arm/mach-aspeed/Makefile
arch/arm/mach-aspeed/ast2600/Kconfig [new file with mode: 0644]
arch/arm/mach-aspeed/ast2600/Makefile [new file with mode: 0644]
arch/arm/mach-aspeed/ast2600/board_common.c [new file with mode: 0644]
arch/arm/mach-aspeed/ast2600/lowlevel_init.S [new file with mode: 0644]
arch/arm/mach-aspeed/ast2600/spl.c [new file with mode: 0644]
board/aspeed/evb_ast2600/Kconfig [new file with mode: 0644]
board/aspeed/evb_ast2600/Makefile [new file with mode: 0644]
board/aspeed/evb_ast2600/evb_ast2600.c [new file with mode: 0644]
drivers/sysreset/sysreset_ast.c
include/configs/evb_ast2600.h [new file with mode: 0644]

diff --git a/arch/arm/include/asm/arch-aspeed/boot0.h b/arch/arm/include/asm/arch-aspeed/boot0.h
new file mode 100644 (file)
index 0000000..368becc
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) Aspeed Technology Inc.
+ */
+
+#ifndef _ASM_ARCH_BOOT0_H
+#define _ASM_ARCH_BOOT0_H
+
+_start:
+       ARM_VECTORS
+
+       .word   0x0     /* key location */
+       .word   0x0     /* start address of image */
+       .word   0xfc00  /* maximum image size: 63KB */
+       .word   0x0     /* signature address */
+       .word   0x0     /* header revision ID low */
+       .word   0x0     /* header revision ID high */
+       .word   0x0     /* reserved */
+       .word   0x0     /* checksum */
+       .word   0x0     /* BL2 secure header */
+       .word   0x0     /* public key or digest offset for BL2 */
+
+#endif
index 6cee036..d50ec5f 100644 (file)
 #define ASPEED_DRAM_BASE       0x80000000
 #define ASPEED_SRAM_BASE       0x1e720000
 #define ASPEED_SRAM_SIZE       0x9000
+#elif defined(CONFIG_ASPEED_AST2600)
+#define ASPEED_MAC_COUNT       4
+#define ASPEED_DRAM_BASE       0x80000000
+#define ASPEED_SRAM_BASE       0x10000000
+#define ASPEED_SRAM_SIZE       0x10000
 #else
 #err "Unrecognized Aspeed platform."
 #endif
index 4f021ba..9a725f1 100644 (file)
@@ -9,6 +9,11 @@ config SYS_SOC
 config SYS_TEXT_BASE
        default 0x00000000
 
+choice
+       prompt "Aspeed SoC select"
+       depends on ARCH_ASPEED
+       default ASPEED_AST2500
+
 config ASPEED_AST2500
        bool "Support Aspeed AST2500 SoC"
        depends on DM_RESET
@@ -18,6 +23,21 @@ config ASPEED_AST2500
          It is used as Board Management Controller on many server boards,
          which is enabled by support of LPC and eSPI peripherals.
 
+config ASPEED_AST2600
+       bool "Support Aspeed AST2600 SoC"
+       select CPU_V7A
+       select CPU_V7_HAS_NONSEC
+       select SYS_ARCH_TIMER
+       select SUPPORT_SPL
+       select ENABLE_ARM_SOC_BOOT0_HOOK
+       help
+         The Aspeed AST2600 is a ARM-based SoC with Cortex-A7 CPU.
+         It is used as Board Management Controller on many server boards,
+         which is enabled by support of LPC and eSPI peripherals.
+
+endchoice
+
 source "arch/arm/mach-aspeed/ast2500/Kconfig"
+source "arch/arm/mach-aspeed/ast2600/Kconfig"
 
 endif
index 33f65b5..42599c1 100644 (file)
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
 obj-$(CONFIG_ASPEED_AST2500) += ast2500/
+obj-$(CONFIG_ASPEED_AST2600) += ast2600/
diff --git a/arch/arm/mach-aspeed/ast2600/Kconfig b/arch/arm/mach-aspeed/ast2600/Kconfig
new file mode 100644 (file)
index 0000000..f3a5338
--- /dev/null
@@ -0,0 +1,17 @@
+if ASPEED_AST2600
+
+config SYS_CPU
+       default "armv7"
+
+config TARGET_EVB_AST2600
+       bool "EVB-AST2600"
+       depends on ASPEED_AST2600
+       help
+         EVB-AST2600 is Aspeed evaluation board for AST2600A0 chip.
+         It has 512M of RAM, 32M of SPI flash, two Ethernet ports,
+         4 Serial ports, 4 USB ports, VGA port, PCIe, SD card slot,
+         20 pin JTAG, pinouts for 14 I2Cs, 3 SPIs and eSPI, 8 PWMs.
+
+source "board/aspeed/evb_ast2600/Kconfig"
+
+endif
diff --git a/arch/arm/mach-aspeed/ast2600/Makefile b/arch/arm/mach-aspeed/ast2600/Makefile
new file mode 100644 (file)
index 0000000..448d320
--- /dev/null
@@ -0,0 +1,2 @@
+obj-y   += lowlevel_init.o board_common.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
diff --git a/arch/arm/mach-aspeed/ast2600/board_common.c b/arch/arm/mach-aspeed/ast2600/board_common.c
new file mode 100644 (file)
index 0000000..a53e163
--- /dev/null
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) Aspeed Technology Inc.
+ */
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <timer.h>
+#include <asm/io.h>
+#include <asm/arch/timer.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <dm/uclass.h>
+#include <asm/arch/scu_ast2600.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Memory Control registers */
+#define MCR_BASE                       0x1e6e0000
+#define MCR_CONF                       (MCR_BASE + 0x004)
+
+/* bit fields of MCR_CONF */
+#define MCR_CONF_ECC_EN                        BIT(7)
+#define MCR_CONF_VGA_MEMSZ_MASK                GENMASK(3, 2)
+#define MCR_CONF_VGA_MEMSZ_SHIFT       2
+#define MCR_CONF_MEMSZ_MASK            GENMASK(1, 0)
+#define MCR_CONF_MEMSZ_SHIFT           0
+
+int dram_init(void)
+{
+       int ret;
+       struct udevice *dev;
+       struct ram_info ram;
+
+       ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+       if (ret) {
+               debug("cannot get DRAM driver\n");
+               return ret;
+       }
+
+       ret = ram_get_info(dev, &ram);
+       if (ret) {
+               debug("cannot get DRAM information\n");
+               return ret;
+       }
+
+       gd->ram_size = ram.size;
+       return 0;
+}
+
+int board_init(void)
+{
+       int i = 0, rc;
+       struct udevice *dev;
+
+       gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+       while (1) {
+               rc = uclass_get_device(UCLASS_MISC, i++, &dev);
+               if (rc)
+                       break;
+       }
+
+       return 0;
+}
+
+void board_add_ram_info(int use_default)
+{
+       int rc;
+       uint32_t conf;
+       uint32_t ecc, act_size, vga_rsvd;
+       struct udevice *scu_dev;
+       struct ast2600_scu *scu;
+
+       rc = uclass_get_device_by_driver(UCLASS_CLK,
+                                        DM_DRIVER_GET(aspeed_ast2600_scu), &scu_dev);
+       if (rc) {
+               debug("%s: cannot find SCU device, rc=%d\n", __func__, rc);
+               return;
+       }
+
+       scu = devfdt_get_addr_ptr(scu_dev);
+       if (IS_ERR_OR_NULL(scu)) {
+               debug("%s: cannot get SCU address pointer\n", __func__);
+               return;
+       }
+
+       conf = readl(MCR_CONF);
+
+       ecc = conf & MCR_CONF_ECC_EN;
+       act_size = 0x100 << ((conf & MCR_CONF_MEMSZ_MASK) >> MCR_CONF_MEMSZ_SHIFT);
+       vga_rsvd = 0x8 << ((conf & MCR_CONF_VGA_MEMSZ_MASK) >> MCR_CONF_VGA_MEMSZ_SHIFT);
+
+       /* no VGA reservation if efuse VGA disable bit is set */
+       if (readl(scu->efuse) & SCU_EFUSE_DIS_VGA)
+               vga_rsvd = 0;
+
+       printf(" (capacity:%d MiB, VGA:%d MiB), ECC %s", act_size,
+              vga_rsvd, (ecc) ? "on" : "off");
+}
+
+void enable_caches(void)
+{
+       /* get rid of the warning message */
+}
diff --git a/arch/arm/mach-aspeed/ast2600/lowlevel_init.S b/arch/arm/mach-aspeed/ast2600/lowlevel_init.S
new file mode 100644 (file)
index 0000000..594963d
--- /dev/null
@@ -0,0 +1,233 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) ASPEED Technology Inc.
+ */
+#include <config.h>
+#include <asm/armv7.h>
+#include <linux/linkage.h>
+#include <asm/arch/scu_ast2600.h>
+
+/* SCU register offsets */
+#define SCU_BASE               0x1e6e2000
+#define SCU_PROT_KEY1          (SCU_BASE + 0x000)
+#define SCU_PROT_KEY2          (SCU_BASE + 0x010)
+#define SCU_SMP_BOOT           (SCU_BASE + 0x180)
+#define SCU_HWSTRAP1           (SCU_BASE + 0x510)
+#define SCU_CA7_PARITY_CHK     (SCU_BASE + 0x820)
+#define SCU_CA7_PARITY_CLR     (SCU_BASE + 0x824)
+#define SCU_MMIO_DEC           (SCU_BASE + 0xc24)
+
+/* FMC SPI register offsets */
+#define FMC_BASE               0x1e620000
+#define FMC_CE0_CTRL           (FMC_BASE + 0x010)
+#define FMC_SW_RST_CTRL                (FMC_BASE + 0x050)
+#define FMC_WDT1_CTRL_MODE     (FMC_BASE + 0x060)
+#define FMC_WDT2_CTRL_MODE     (FMC_BASE + 0x064)
+
+/*
+ * The SMP mailbox provides a space with few instructions in it
+ * for secondary cores to execute on and wait for the signal of
+ * SMP core bring up.
+ *
+ *       SMP mailbox
+ * +----------------------+
+ * |                      |
+ * | mailbox insn. for    |
+ * | cpuN polling SMP go  |
+ * |                      |
+ * +----------------------+ 0xC
+ * | mailbox ready signal |
+ * +----------------------+ 0x8
+ * | cpuN GO signal       |
+ * +----------------------+ 0x4
+ * | cpuN entrypoint      |
+ * +----------------------+ SMP_MAILBOX_BASE
+ */
+#define SMP_MBOX_BASE          (SCU_SMP_BOOT)
+#define SMP_MBOX_FIELD_ENTRY   (SMP_MBOX_BASE + 0x0)
+#define SMP_MBOX_FIELD_GOSIGN  (SMP_MBOX_BASE + 0x4)
+#define SMP_MBOX_FIELD_READY   (SMP_MBOX_BASE + 0x8)
+#define SMP_MBOX_FIELD_POLLINSN        (SMP_MBOX_BASE + 0xc)
+
+.macro scu_unlock
+       movw    r0, #(SCU_UNLOCK_KEY & 0xffff)
+       movt    r0, #(SCU_UNLOCK_KEY >> 16)
+
+       ldr     r1, =SCU_PROT_KEY1
+       str     r0, [r1]
+       ldr     r1, =SCU_PROT_KEY2
+       str     r0, [r1]
+.endm
+
+.macro timer_init
+       ldr     r1, =SCU_HWSTRAP1
+       ldr     r1, [r1]
+       and     r1, #0x700
+       lsr     r1, #0x8
+
+       /* 1.2GHz */
+       cmp     r1, #0x0
+       movweq  r0, #0x8c00
+       movteq  r0, #0x4786
+
+       /* 1.6GHz */
+       cmp     r1, #0x1
+       movweq  r0, #0x1000
+       movteq  r0, #0x5f5e
+
+       /* 1.2GHz */
+       cmp     r1, #0x2
+       movweq  r0, #0x8c00
+       movteq  r0, #0x4786
+
+       /* 1.6GHz */
+       cmp     r1, #0x3
+       movweq  r0, #0x1000
+       movteq  r0, #0x5f5e
+
+       /* 800MHz */
+       cmp     r1, #0x4
+       movwge  r0, #0x0800
+       movtge  r0, #0x2faf
+
+       mcr     p15, 0, r0, c14, c0, 0  @; update CNTFRQ
+.endm
+
+
+.globl lowlevel_init
+
+lowlevel_init:
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+       mov     pc, lr
+#else
+       /* setup ARM arch timer frequency */
+       timer_init
+
+       /* reset SMP mailbox as early as possible */
+       mov     r0, #0x0
+       ldr     r1, =SMP_MBOX_FIELD_READY
+       str     r0, [r1]
+
+       /* set ACTLR.SMP to enable cache use */
+       mrc     p15, 0, r0, c1, c0, 1
+       orr     r0, #0x40
+       mcr     p15, 0, r0, c1, c0, 1
+
+       /*
+        * we treat cpu0 as the primary core and
+        * put secondary core (cpuN) to sleep
+        */
+       mrc   p15, 0, r0, c0, c0, 5     @; Read CPU ID register
+       ands  r0, #0xff                 @; Mask off, leaving the CPU ID field
+       movw  r2, #0xab00
+       movt  r2, #0xabba
+       orr   r2, r0
+
+       beq   do_primary_core_setup
+
+       /* hold cpuN until mailbox is ready */
+poll_mailbox_ready:
+       wfe
+       ldr     r0, =SMP_MBOX_FIELD_READY
+       ldr     r0, [r0]
+       movw    r1, #0xcafe
+       movt    r1, #0xbabe
+       cmp     r1, r0
+       bne     poll_mailbox_ready
+
+       /* parameters for relocated SMP go polling insn. */
+       ldr     r0, =SMP_MBOX_FIELD_GOSIGN
+       ldr     r1, =SMP_MBOX_FIELD_ENTRY
+
+       /* no return */
+       ldr     pc, =SMP_MBOX_FIELD_POLLINSN
+
+do_primary_core_setup:
+       scu_unlock
+
+       /* MMIO decode setting */
+       ldr     r0, =SCU_MMIO_DEC
+       mov     r1, #0x2000
+       str     r1, [r0]
+
+       /* enable CA7 cache parity check */
+       mov     r0, #0
+       ldr     r1, =SCU_CA7_PARITY_CLR
+       str     r0, [r1]
+
+       mov     r0, #0x1
+       ldr     r1, =SCU_CA7_PARITY_CHK
+       str     r0, [r1]
+
+       /* do not fill FMC50[1] if boot from eMMC */
+       ldr     r0, =SCU_HWSTRAP1
+       ldr     r1, [r0]
+       ands    r1, #0x04
+       bne     skip_fill_wip_bit
+
+       /* fill FMC50[1] for waiting WIP idle */
+       mov     r0, #0x02
+       ldr     r1, =FMC_SW_RST_CTRL
+       str     r0, [r1]
+
+skip_fill_wip_bit:
+       /* disable FMC WDT for SPI address mode detection */
+       mov     r0, #0
+       ldr     r1, =FMC_WDT1_CTRL_MODE
+       str     r0, [r1]
+
+       /* relocate mailbox insn. for cpuN polling SMP go signal */
+       adrl    r0, mailbox_insn
+       adrl    r1, mailbox_insn_end
+
+       ldr     r2, =#SMP_MBOX_FIELD_POLLINSN
+
+relocate_mailbox_insn:
+       ldr     r3, [r0], #0x4
+       str     r3, [r2], #0x4
+       cmp     r0, r1
+       bne     relocate_mailbox_insn
+
+       /* reset SMP go sign */
+       mov     r0, #0
+       ldr     r1, =SMP_MBOX_FIELD_GOSIGN
+       str     r0, [r1]
+
+       /* notify cpuN mailbox is ready */
+       movw    r0, #0xCAFE
+       movt    r0, #0xBABE
+       ldr     r1, =SMP_MBOX_FIELD_READY
+       str     r0, [r1]
+       sev
+
+       /* back to arch calling code */
+       mov     pc, lr
+
+/*
+ * insn. inside mailbox to poll SMP go signal.
+ *
+ * Note that as this code will be relocated, any
+ * pc-relative assembly should NOT be used.
+ */
+mailbox_insn:
+       /*
+        * r0 ~ r3 are parameters:
+        *  r0 = SMP_MBOX_FIELD_GOSIGN
+        *  r1 = SMP_MBOX_FIELD_ENTRY
+        *  r2 = per-cpu go sign value
+        *  r3 = no used now
+        */
+poll_mailbox_smp_go:
+       wfe
+       ldr     r4, [r0]
+       cmp     r2, r4
+       bne     poll_mailbox_smp_go
+
+       /* SMP GO signal confirmed, release cpuN */
+       ldr     pc, [r1]
+
+mailbox_insn_end:
+       /* should never reach */
+       b       .
+
+#endif
diff --git a/arch/arm/mach-aspeed/ast2600/spl.c b/arch/arm/mach-aspeed/ast2600/spl.c
new file mode 100644 (file)
index 0000000..9201d4a
--- /dev/null
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) Aspeed Technology Inc.
+ */
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <spl.h>
+#include <init.h>
+#include <asm/io.h>
+#include <asm/arch/scu_ast2600.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void board_init_f(ulong dummy)
+{
+       spl_early_init();
+       preloader_console_init();
+       timer_init();
+       dram_init();
+}
+
+u32 spl_boot_device(void)
+{
+       return BOOT_DEVICE_RAM;
+}
+
+struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
+{
+       /*
+        * When boot from SPI, AST2600 already remap 0x00000000 ~ 0x0fffffff
+        * to BMC SPI memory space 0x20000000 ~ 0x2fffffff. The next stage BL
+        * has been located in SPI for XIP. In this case, the load buffer for
+        * SPL image loading will be set to the remapped address of the next
+        * BL instead of the DRAM space CONFIG_SYS_LOAD_ADDR
+        */
+       return (struct image_header *)(CONFIG_SYS_TEXT_BASE);
+}
+
+#ifdef CONFIG_SPL_OS_BOOT
+int spl_start_uboot(void)
+{
+       /* boot linux */
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_SPL_LOAD_FIT
+int board_fit_config_name_match(const char *name)
+{
+       /* just empty function now - can't decide what to choose */
+       debug("%s: %s\n", __func__, name);
+       return 0;
+}
+#endif
diff --git a/board/aspeed/evb_ast2600/Kconfig b/board/aspeed/evb_ast2600/Kconfig
new file mode 100644 (file)
index 0000000..42008cd
--- /dev/null
@@ -0,0 +1,12 @@
+if TARGET_EVB_AST2600
+
+config SYS_BOARD
+       default "evb_ast2600"
+
+config SYS_VENDOR
+       default "aspeed"
+
+config SYS_CONFIG_NAME
+       default "evb_ast2600"
+
+endif
diff --git a/board/aspeed/evb_ast2600/Makefile b/board/aspeed/evb_ast2600/Makefile
new file mode 100644 (file)
index 0000000..9291db6
--- /dev/null
@@ -0,0 +1 @@
+obj-y += evb_ast2600.o
diff --git a/board/aspeed/evb_ast2600/evb_ast2600.c b/board/aspeed/evb_ast2600/evb_ast2600.c
new file mode 100644 (file)
index 0000000..e6dc8c7
--- /dev/null
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) Aspeed Technology Inc.
+ */
+#include <common.h>
index ee941c7..d747ed0 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/io.h>
 #include <asm/arch/wdt.h>
 #include <linux/err.h>
+#include <hang.h>
 
 static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type)
 {
@@ -33,11 +34,15 @@ static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type)
                return -EPROTONOSUPPORT;
        }
 
+#if !defined(CONFIG_SPL_BUILD)
        ret = wdt_expire_now(wdt, reset_mode);
        if (ret) {
                debug("Sysreset failed: %d", ret);
                return ret;
        }
+#else
+       hang();
+#endif
 
        return -EINPROGRESS;
 }
diff --git a/include/configs/evb_ast2600.h b/include/configs/evb_ast2600.h
new file mode 100644 (file)
index 0000000..e7975bf
--- /dev/null
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) Aspeed Technology Inc.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/aspeed-common.h>
+
+#define CONFIG_SYS_UBOOT_BASE          CONFIG_SYS_TEXT_BASE
+
+/* Memory Info */
+#define CONFIG_SYS_LOAD_ADDR           0x83000000
+
+#endif /* __CONFIG_H */