aspeed: Add AST2600 platform support

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>
This commit is contained in:
Chia-Wei, Wang 2020-12-14 13:54:28 +08:00 committed by Tom Rini
parent ec55a1df39
commit 4a84cf06aa
14 changed files with 500 additions and 0 deletions

View File

@ -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

View File

@ -13,6 +13,11 @@
#define ASPEED_DRAM_BASE 0x80000000 #define ASPEED_DRAM_BASE 0x80000000
#define ASPEED_SRAM_BASE 0x1e720000 #define ASPEED_SRAM_BASE 0x1e720000
#define ASPEED_SRAM_SIZE 0x9000 #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 #else
#err "Unrecognized Aspeed platform." #err "Unrecognized Aspeed platform."
#endif #endif

View File

@ -9,6 +9,11 @@ config SYS_SOC
config SYS_TEXT_BASE config SYS_TEXT_BASE
default 0x00000000 default 0x00000000
choice
prompt "Aspeed SoC select"
depends on ARCH_ASPEED
default ASPEED_AST2500
config ASPEED_AST2500 config ASPEED_AST2500
bool "Support Aspeed AST2500 SoC" bool "Support Aspeed AST2500 SoC"
depends on DM_RESET depends on DM_RESET
@ -18,6 +23,21 @@ config ASPEED_AST2500
It is used as Board Management Controller on many server boards, It is used as Board Management Controller on many server boards,
which is enabled by support of LPC and eSPI peripherals. 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/ast2500/Kconfig"
source "arch/arm/mach-aspeed/ast2600/Kconfig"
endif endif

View File

@ -4,3 +4,4 @@
obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
obj-$(CONFIG_ASPEED_AST2500) += ast2500/ obj-$(CONFIG_ASPEED_AST2500) += ast2500/
obj-$(CONFIG_ASPEED_AST2600) += ast2600/

View File

@ -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

View File

@ -0,0 +1,2 @@
obj-y += lowlevel_init.o board_common.o
obj-$(CONFIG_SPL_BUILD) += spl.o

View File

@ -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 */
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
obj-y += evb_ast2600.o

View File

@ -0,0 +1,5 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) Aspeed Technology Inc.
*/
#include <common.h>

View File

@ -12,6 +12,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/arch/wdt.h> #include <asm/arch/wdt.h>
#include <linux/err.h> #include <linux/err.h>
#include <hang.h>
static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type) 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; return -EPROTONOSUPPORT;
} }
#if !defined(CONFIG_SPL_BUILD)
ret = wdt_expire_now(wdt, reset_mode); ret = wdt_expire_now(wdt, reset_mode);
if (ret) { if (ret) {
debug("Sysreset failed: %d", ret); debug("Sysreset failed: %d", ret);
return ret; return ret;
} }
#else
hang();
#endif
return -EINPROGRESS; return -EINPROGRESS;
} }

View File

@ -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 */