diff options
Diffstat (limited to 'roms/u-boot/arch/arm/mach-aspeed/ast2600/lowlevel_init.S')
-rw-r--r-- | roms/u-boot/arch/arm/mach-aspeed/ast2600/lowlevel_init.S | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/roms/u-boot/arch/arm/mach-aspeed/ast2600/lowlevel_init.S b/roms/u-boot/arch/arm/mach-aspeed/ast2600/lowlevel_init.S new file mode 100644 index 000000000..594963d03 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-aspeed/ast2600/lowlevel_init.S @@ -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 |