1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) ASPEED Technology Inc. 4 * Chia-Wei Wang <chiawei_wang@aspeedtech.com> 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_SYSRST_CTRL (AST_SCU_BASE + 0x040) 41#define AST_SCU_SYSRST_CTRL_CLR (AST_SCU_BASE + 0x044) 42#define AST_SCU_DEBUG_CTRL (AST_SCU_BASE + 0x0C8) 43#define AST_SCU_DEBUG_CTRL2 (AST_SCU_BASE + 0x0D8) 44#define AST_SCU_HPLL_PARAM (AST_SCU_BASE + 0x200) 45#define AST_SCU_HPLL_PARAM_EXT (AST_SCU_BASE + 0x204) 46#define AST_SCU_HW_STRAP1 (AST_SCU_BASE + 0x500) 47#define AST_SCU_HW_STRAP2 (AST_SCU_BASE + 0x510) 48#define AST_SCU_CA7_CTRL (AST_SCU_BASE + 0x800) 49#define AST_SCU_CA7_AXI_PREFETCH_START (AST_SCU_BASE + 0x808) 50#define AST_SCU_CA7_AXI_PREFETCH_END (AST_SCU_BASE + 0x80C) 51#define AST_SCU_CA7_PARITY_CHK (AST_SCU_BASE + 0x820) 52#define AST_SCU_CA7_PARITY_CLR (AST_SCU_BASE + 0x824) 53#define AST_SCU_MMIO_DEC_SET (AST_SCU_BASE + 0xC24) 54 55#define AST_FMC_BASE (0x1E620000) 56#define AST_FMC_CE0_CTRL (AST_FMC_BASE + 0x010) 57#define AST_FMC_WDT1_CTRL_MODE (AST_FMC_BASE + 0x060) 58#define AST_FMC_WDT2_CTRL_MODE (AST_FMC_BASE + 0x064) 59 60#define AST_GPIO_BASE (0x1E780000) 61#define AST_GPIOYZ_DATA_VALUE (AST_GPIO_BASE + 0x1E0) 62 63/* Revision ID */ 64#define REV_ID_AST2600A0 0x05000303 65 66.macro scu_unlock 67 movw r0, #0xA8A8 68 movt r0, #0x1688 @; magic key to unlock SCU 69 70 ldr r1, =AST_SCU_PROT_KEY1 71 str r0, [r1] 72 ldr r1, =AST_SCU_PROT_KEY2 73 str r0, [r1] 74.endm 75 76.macro timer_init 77#ifdef CONFIG_FPGA_ASPEED 78 movw r0, #0xF080 79 movt r0, #0x2FA 80#else 81 ldr r0, =AST_SCU_REV_ID 82 ldr r0, [r0] 83 84 ldr r1, =REV_ID_AST2600A0 85 cmp r0, r1 86 87 movweq r0, #0x32C0 88 movteq r0, #0x4013 89 movwne r0, #0x8C00 90 movtne r0, #0x4786 91#endif 92 mcr p15, 0, r0, c14, c0, 0 @; update CNTFRQ 93.endm 94 95 96.globl lowlevel_init 97 98lowlevel_init: 99#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) 100 mov pc, lr 101#else 102 /* setup ARM arch timer frequency */ 103 timer_init 104 105 /* reset SMP mailbox as early as possible */ 106 mov r0, #0x0 107 ldr r1, =AST_SMP_MBOX_FIELD_READY 108 str r0, [r1] 109 110 /* set ACTLR.SMP to enable cache use */ 111 mrc p15, 0, r0, c1, c0, 1 112 orr r0, #0x40 113 mcr p15, 0, r0, c1, c0, 1 114 115 /* 116 * we treat cpu0 as the primary core and 117 * put secondary core (cpuN) to sleep 118 */ 119 mrc p15, 0, r0, c0, c0, 5 @; Read CPU ID register 120 ands r0, #0xFF @; Mask off, leaving the CPU ID field 121 movw r2, #0xAB00 122 movt r2, #0xABBA 123 orr r2, r0 124 125 beq do_primary_core_setup 126 127 /* hold cpuN until mailbox is ready */ 128poll_mailbox_ready: 129 wfe 130 ldr r0, =AST_SMP_MBOX_FIELD_READY 131 ldr r0, [r0] 132 movw r1, #0xCAFE 133 movt r1, #0xBABE 134 cmp r1, r0 135 bne poll_mailbox_ready 136 137 /* parameters for relocated SMP go polling insn. */ 138 ldr r0, =AST_SMP_MBOX_FIELD_GOSIGN 139 ldr r1, =AST_SMP_MBOX_FIELD_ENTRY 140 141 /* no return */ 142 ldr pc, =AST_SMP_MBOX_FIELD_POLLINSN 143 144do_primary_core_setup: 145 /* unlock system control unit */ 146 scu_unlock 147 148 /* identify AST2600 A0/A1 */ 149 ldr r0, =AST_SCU_REV_ID 150 ldr r0, [r0] 151 152 ldr r1, =REV_ID_AST2600A0 153 cmp r0, r1 154 155 bne 0f 156 157 /* tune up CPU clocks (A0 only) */ 158 ldr r0, =AST_SCU_HW_STRAP1 159 ldr r1, [r0] 160 bic r1, #0x1800 161 orr r1, #0x1000 162 str r1, [r0] 163 164 ldr r0, =AST_SCU_HPLL_PARAM 165 movw r1, #0x4080 166 movt r1, #0x1000 167 str r1, [r0] 168 169 ldr r0, =AST_SCU_HPLL_PARAM_EXT 170 mov r1, #0x47 171 str r1, [r0] 172 173wait_lock: 174 ldr r1, [r0] 175 tst r1, #0x80000000 176 beq wait_lock 177 178 /* skip A1 only area */ 179 b 1f 180 1810: 182 /* enable AXI prefetch (A1 only) */ 183 ldr r0, =AST_SCU_CA7_AXI_PREFETCH_START 184 ldr r1, =ASPEED_DRAM_BASE 185 str r1, [r0] 186 187 ldr r0, =AST_SCU_CA7_AXI_PREFETCH_END 188 ldr r1, =0xFFFFFFFF 189 str r1, [r0] 190 191 ldr r0, =AST_SCU_CA7_CTRL 192 ldr r1, [r0] 193 orr r1, #0x8000 194 str r1, [r0] 195 196 /* LPC/eSPI mode selection (A1 only) */ 197 ldr r0, =AST_GPIOYZ_DATA_VALUE 198 ldr r0, [r0] 199 tst r0, #0x1000 200 beq 1f 201 202 /* switch to LPC mode if GPIOZ[4]=1 */ 203 ldr r0, =AST_SCU_HW_STRAP2 204 ldr r1, [r0] 205 orr r1, #0x40 206 str r1, [r0] 207 2081: 209 /* release display port reset */ 210 ldr r0, =AST_SCU_SYSRST_CTRL_CLR 211 movw r1, #0x0000 212 movt r1, #0x3000 213 str r1, [r0] 214 215 /* MMIO decode setting */ 216 ldr r0, =AST_SCU_MMIO_DEC_SET 217 mov r1, #0x2000 218 str r1, [r0] 219 220 /* enable cache & SRAM parity check */ 221 mov r0, #0 222 ldr r1, =AST_SCU_CA7_PARITY_CLR 223 str r0, [r1] 224 225 mov r0, #0x1 226 ldr r1, =AST_SCU_CA7_PARITY_CHK 227 str r0, [r1] 228 229 /* disable FMC WDT for SPI address mode detection */ 230 mov r0, #0 231 ldr r1, =AST_FMC_WDT1_CTRL_MODE 232 str r0, [r1] 233#if 0 234 ldr r1, =AST_FMC_WDT2_CTRL_MODE 235 str r0, [r1] 236#endif 237 /* tune up SPI clock */ 238 movw r0, #0x0641 239 movt r0, #0x203B 240 ldr r1, =AST_FMC_CE0_CTRL 241 str r0, [r1] 242 243#if 0 244 /* disable UART-based SoC Debug Interface UART5 and P2A bridge*/ 245 ldr r0, =AST_SCU_DEBUG_CTRL 246 ldr r1, [r0] 247 orr r1, #0x03 248 str r1, [r0] 249 250 /* disable UART-based SoC Debug Interface UART1 and LPC2AHB bridge */ 251 ldr r0, =AST_SCU_DEBUG_CTRL2 252 ldr r1, [r0] 253 orr r1, #0x0A 254 str r1, [r0] 255#endif 256 257 /* relocate mailbox insn. for cpuN polling SMP go signal */ 258 adrl r0, mailbox_insn 259 adrl r1, mailbox_insn_end 260 261 ldr r2, =#AST_SMP_MBOX_FIELD_POLLINSN 262 263relocate_mailbox_insn: 264 ldr r3, [r0], #0x4 265 str r3, [r2], #0x4 266 cmp r0, r1 267 bne relocate_mailbox_insn 268 269 /* reset SMP go sign */ 270 mov r0, #0 271 ldr r1, =AST_SMP_MBOX_FIELD_GOSIGN 272 str r0, [r1] 273 274 /* notify cpuN mailbox is ready */ 275 movw r0, #0xCAFE 276 movt r0, #0xBABE 277 ldr r1, =AST_SMP_MBOX_FIELD_READY 278 str r0, [r1] 279 sev 280 281 /* back to arch calling code */ 282 mov pc, lr 283 284/* 285 * insn. inside mailbox to poll SMP go signal. 286 * 287 * Note that as this code will be relocated, any 288 * pc-relative assembly should NOT be used. 289 */ 290mailbox_insn: 291 /* 292 * r0 ~ r3 are parameters: 293 * r0 = AST_SMP_MBOX_FIELD_GOSIGN 294 * r1 = AST_SMP_MBOX_FIELD_ENTRY 295 * r2 = per-cpu go sign value 296 * r3 = no used now 297 */ 298poll_mailbox_smp_go: 299 wfe 300 ldr r4, [r0] 301 cmp r2, r4 302 bne poll_mailbox_smp_go 303 304 /* SMP GO signal confirmed, release cpuN */ 305 ldr pc, [r1] 306 307mailbox_insn_end: 308 /* should never reach */ 309 b . 310 311#endif 312