1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) ASPEED Technology Inc. 4 * 5 */ 6 7#include <config.h> 8#include <version.h> 9#include <asm/secure.h> 10#include <asm/armv7.h> 11#include <linux/linkage.h> 12 13/* 14 * SMP mailbox 15 * +----------------------+ 16 * | | 17 * | mailbox insn. for | 18 * | cpuN polling SMP go | 19 * | | 20 * +----------------------+ 0xC 21 * | mailbox ready signal | 22 * +----------------------+ 0x8 23 * | cpuN GO signal | 24 * +----------------------+ 0x4 25 * | cpuN entrypoint | 26 * +----------------------+ AST_SMP_MAILBOX_BASE 27 */ 28 29#define AST_SMP_MAILBOX_BASE 0x1E6E2180 30#define AST_SMP_MBOX_FIELD_ENTRY (AST_SMP_MAILBOX_BASE + 0x0) 31#define AST_SMP_MBOX_FIELD_GOSIGN (AST_SMP_MAILBOX_BASE + 0x4) 32#define AST_SMP_MBOX_FIELD_READY (AST_SMP_MAILBOX_BASE + 0x8) 33#define AST_SMP_MBOX_FIELD_POLLINSN (AST_SMP_MAILBOX_BASE + 0xc) 34 35/* AST2600 HW registers */ 36#define AST_SCU_BASE 0x1E6E2000 37#define AST_SCU_PROT_KEY1 (AST_SCU_BASE) 38#define AST_SCU_PROT_KEY2 (AST_SCU_BASE + 0x010) 39#define AST_SCU_REV_ID (AST_SCU_BASE + 0x014) 40#define AST_SCU_HW_STRAP1 (AST_SCU_BASE + 0x500) 41 42#define AST_FMC_BASE 0x1E620000 43#define AST_FMC_WDT1_CTRL_MODE (AST_FMC_BASE + 0x060) 44#define AST_FMC_WDT2_CTRL_MODE (AST_FMC_BASE + 0x064) 45 46/* Revision ID */ 47#define REV_ID_AST2600A0 0x05000303 48 49ENTRY(ast_bootmode) 50 ldr r1, =AST_SCU_HW_STRAP1 51 ldr r0, [r1] 52 tst r0, #0x4 53 moveq r0, #0x0 @; AST_BOOTMODE_SPI 54 movne r0, #0x1 @; AST_BOOTMODE_EMMC 55 mov pc, lr 56ENDPROC(ast_bootmode) 57 58.macro timer_init 59#ifdef CONFIG_FPGA_ASPEED 60 movw r0, #0x7840 61 movt r0, #0x17D 62#else 63 ldr r0, =AST_SCU_REV_ID 64 ldr r0, [r0] 65 66 ldr r1, =REV_ID_AST2600A0 67 cmp r0, r1 68 69 movweq r0, #0x0800 70 movteq r0, #0x2FAF @; 800MHz for A0 71 movwne r0, #0x8C00 72 movtne r0, #0x4786 @; 1.2GHz for A1 73#endif 74 mcr p15, 0, r0, c14, c0, 0 @; update CNTFRQ 75.endm 76 77.macro scu_unlock 78 movw r0, #0xA8A8 79 movt r0, #0x1688 @; magic key to unlock SCU 80 81 ldr r1, =AST_SCU_PROT_KEY1 82 str r0, [r1] 83 ldr r1, =AST_SCU_PROT_KEY2 84 str r0, [r1] 85.endm 86 87.globl lowlevel_init 88 89lowlevel_init: 90#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) 91 mov pc, lr 92#else 93 /* setup timer frequency for ARM generic timer */ 94 timer_init 95 96 /* unlock SCU */ 97 scu_unlock 98 99 /* reset SMP mailbox as early as possible */ 100 mov r0, #0x0 101 ldr r1, =AST_SMP_MBOX_FIELD_READY 102 str r0, [r1] 103 104 /* set ACTLR.SMP to enable cache use */ 105 mrc p15, 0, r0, c1, c0, 1 106 orr r0, r0, #0x40 107 mcr p15, 0, r0, c1, c0, 1 108 109 /* 110 * we treat cpu0 as the primary core and 111 * put secondary core (cpuN) to sleep 112 */ 113 mrc p15, 0, r0, c0, c0, 5 @; Read CPU ID register 114 ands r0, r0, #0xFF @; Mask off, leaving the CPU ID field 115 movw r2, #0xAB00 116 movt r2, #0xABBA 117 orr r2, r2, r0 118 119 beq do_primary_core_setup 120 121 /* hold cpuN until mailbox is ready */ 122poll_mailbox_ready: 123 wfe 124 ldr r0, =AST_SMP_MBOX_FIELD_READY 125 ldr r0, [r0] 126 movw r1, #0xCAFE 127 movt r1, #0xBABE 128 cmp r1, r0 129 bne poll_mailbox_ready 130 131 /* parameters for relocated SMP go polling insn. */ 132 ldr r0, =AST_SMP_MBOX_FIELD_GOSIGN 133 ldr r1, =AST_SMP_MBOX_FIELD_ENTRY 134 135 /* no return */ 136 ldr pc, =AST_SMP_MBOX_FIELD_POLLINSN 137 138do_primary_core_setup: 139 /* disable FMC WDT for SPI address mode detection */ 140 mov r0, #0 141 ldr r1, =AST_FMC_WDT1_CTRL_MODE 142 str r0, [r1] 143 ldr r1, =AST_FMC_WDT2_CTRL_MODE 144 str r0, [r1] 145 146 /* relocate mailbox insn. for cpuN polling SMP go signal */ 147 adrl r0, mailbox_insn 148 adrl r1, mailbox_insn_end 149 150 ldr r2, =#AST_SMP_MBOX_FIELD_POLLINSN 151 152relocate_mailbox_insn: 153 ldr r3, [r0], #0x4 154 str r3, [r2], #0x4 155 cmp r0, r1 156 bne relocate_mailbox_insn 157 158 /* reset SMP go sign */ 159 mov r0, #0 160 ldr r1, =AST_SMP_MBOX_FIELD_GOSIGN 161 str r0, [r1] 162 163 /* notify cpuN mailbox is ready */ 164 movw r0, #0xCAFE 165 movt r0, #0xBABE 166 ldr r1, =AST_SMP_MBOX_FIELD_READY 167 str r0, [r1] 168 sev 169 170 /* back to arch calling code */ 171 mov pc, lr 172 173/* 174 * insn. inside mailbox to poll SMP go signal. 175 * 176 * Note that as this code will be relocated, any 177 * pc-relative assembly should NOT be used. 178 */ 179mailbox_insn: 180 /* 181 * r0 ~ r3 are parameters: 182 * r0 = AST_SMP_MBOX_FIELD_GOSIGN 183 * r1 = AST_SMP_MBOX_FIELD_ENTRY 184 * r2 = per-cpu go sign value 185 * r3 = no used now 186 */ 187poll_mailbox_smp_go: 188 wfe 189 ldr r4, [r0] 190 cmp r2, r4 191 bne poll_mailbox_smp_go 192 193 /* SMP GO signal confirmed, release cpuN */ 194 ldr pc, [r1] 195 196mailbox_insn_end: 197 /* should never reach */ 198 b . 199 200#endif 201