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 * +----------------------+ 0x40 16 * | cpuN sec_entrypoint | 17 * +----------------------+ 0x3c 18 * | | 19 * | mailbox insn. for | 20 * | cpuN GO sign polling | 21 * | | 22 * +----------------------+ 0x10 23 * | mailbox ready | 24 * +----------------------+ 0x0c 25 * | reserved | 26 * +----------------------+ 0x08 27 * | cpuN GO signal | 28 * +----------------------+ 0x04 29 * | cpuN ns_entrypoint | 30 * +----------------------+ SCU180 31 */ 32 33#define SCU_BASE 0x1e6e2000 34#define SCU_PROT_KEY1 (SCU_BASE) 35#define SCU_PROT_KEY2 (SCU_BASE + 0x010) 36#define SCU_REV_ID (SCU_BASE + 0x014) 37#define SCU_SYSRST_CTRL (SCU_BASE + 0x040) 38#define SCU_SYSRST_CTRL_CLR (SCU_BASE + 0x044) 39#define SCU_SYSRST_EVENT (SCU_BASE + 0x064) 40#define SCU_CLK_STOP_CTRL_CLR (SCU_BASE + 0x084) 41#define SCU_DEBUG_CTRL (SCU_BASE + 0x0c8) 42#define SCU_DEBUG_CTRL2 (SCU_BASE + 0x0d8) 43#define SCU_SMP_NS_EP (SCU_BASE + 0x180) 44#define SCU_SMP_GO (SCU_BASE + 0x184) 45#define SCU_SMP_READY (SCU_BASE + 0x18c) 46#define SCU_SMP_POLLINSN (SCU_BASE + 0x190) 47#define SCU_SMP_S_EP (SCU_BASE + 0x1bc) 48#define SCU_HPLL_PARAM (SCU_BASE + 0x200) 49#define SCU_HPLL_PARAM_EXT (SCU_BASE + 0x204) 50#define SCU_USB_MULTI_FUNC (SCU_BASE + 0x440) 51#define SCU_HW_STRAP1 (SCU_BASE + 0x500) 52#define SCU_HW_STRAP2 (SCU_BASE + 0x510) 53#define SCU_HW_STRAP3 (SCU_BASE + 0x51c) 54#define SCU_CA7_PARITY_CHK (SCU_BASE + 0x820) 55#define SCU_CA7_PARITY_CLR (SCU_BASE + 0x824) 56#define SCU_MMIO_DEC_SET (SCU_BASE + 0xc24) 57 58#define FMC_BASE 0x1e620000 59#define FMC_CE0_CTRL (FMC_BASE + 0x010) 60#define FMC_SW_RST_CTRL (FMC_BASE + 0x050) 61#define FMC_WDT1_CTRL_MODE (FMC_BASE + 0x060) 62#define FMC_WDT2_CTRL_MODE (FMC_BASE + 0x064) 63 64#define GPIO_BASE 0x1e780000 65#define GPIOYZ_DATA_VALUE (GPIO_BASE + 0x1e0) 66 67#define SEC_BASE 0x1e6f2000 68#define SEC_VAULT_KEY_CTRL (SEC_BASE + 0x80c) 69 70#define REV_ID_AST2600A0 0x05000303 71#define REV_ID_AST2600A1 0x05010303 72#define REV_ID_AST2620A1 0x05010203 73 74.macro scu_unlock 75 movw r0, #0xa8a8 76 movt r0, #0x1688 @; magic key to unlock SCU 77 78 ldr r1, =SCU_PROT_KEY1 79 str r0, [r1] 80 ldr r1, =SCU_PROT_KEY2 81 str r0, [r1] 82.endm 83 84.macro timer_init 85#ifdef CONFIG_FPGA_ASPEED 86 movw r0, #0x6c00 87 movt r0, #0x02dc 88#else 89 ldr r0, =SCU_REV_ID 90 ldr r0, [r0] 91 92 ldr r1, =REV_ID_AST2600A0 93 cmp r0, r1 94 95 beq timer_init_a0 96 97 ldr r1, =SCU_HW_STRAP1 98 ldr r1, [r1] 99 and r1, #0x700 100 lsr r1, #0x8 101 102 cmp r1, #0x0 103 movweq r0, #0x8c00 104 movteq r0, #0x4786 105 106 cmp r1, #0x1 107 movweq r0, #0x1000 108 movteq r0, #0x5f5e 109 110 cmp r1, #0x2 111 movweq r0, #0x8c00 112 movteq r0, #0x4786 113 114 cmp r1, #0x3 115 movweq r0, #0x1000 116 movteq r0, #0x5f5e 117 118 cmp r1, #0x4 119 movwge r0, #0x0800 120 movtge r0, #0x2faf 121 122 b timer_init_out 123 124timer_init_a0: 125 movweq r0, #0x32c0 126 movteq r0, #0x4013 127 128timer_init_out: 129#endif 130 mcr p15, 0, r0, c14, c0, 0 @; update CNTFRQ 131.endm 132 133 134.globl lowlevel_init 135 136lowlevel_init: 137#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) 138 mov pc, lr 139#else 140 /* setup ARM arch timer frequency */ 141 timer_init 142 143 /* reset SMP mailbox as early as possible */ 144 mov r0, #0x0 145 ldr r1, =SCU_SMP_READY 146 str r0, [r1] 147 148 /* set ACTLR.SMP to enable cache use */ 149 mrc p15, 0, r0, c1, c0, 1 150 orr r0, #0x40 151 mcr p15, 0, r0, c1, c0, 1 152 153 /* 154 * we treat cpu0 as the primary core and 155 * put secondary core (cpuN) to sleep 156 */ 157 mrc p15, 0, r0, c0, c0, 5 @; Read CPU ID register 158 ands r0, #0xff @; Mask off, leaving the CPU ID field 159 movw r4, #0xab00 160 movt r4, #0xabba 161 orr r4, r0 162 163 beq do_primary_core_setup 164 165 /* hold cpuN until SMP mailbox is ready */ 166poll_smp_mbox_ready: 167 wfe 168 ldr r0, =SCU_SMP_READY 169 ldr r0, [r0] 170 movw r1, #0xcafe 171 movt r1, #0xbabe 172 cmp r1, r0 173 bne poll_smp_mbox_ready 174 175 /* 176 * for relocated SMP mailbox insn. use 177 * r4 = per-cpu go sign value 178 * r5 = SCU_SMP_GO 179 * r6 = SCU_SMP_NS_EP 180 * r7 = SCU_SMP_S_EP 181 */ 182 ldr r5, =SCU_SMP_GO 183 ldr r6, =SCU_SMP_NS_EP 184 ldr r7, =SCU_SMP_S_EP 185 186 /* no return */ 187 ldr pc, =SCU_SMP_POLLINSN 188 189do_primary_core_setup: 190 /* unlock system control unit */ 191 scu_unlock 192 193 /* identify AST2600 A0/A1 */ 194 ldr r0, =SCU_REV_ID 195 ldr r0, [r0] 196 197 ldr r1, =REV_ID_AST2600A0 198 cmp r0, r1 199 200 bne 0f 201 202 /* tune up CPU clocks (A0 only) */ 203 ldr r0, =SCU_HW_STRAP1 204 ldr r1, [r0] 205 bic r1, #0x1800 206 orr r1, #0x1000 207 str r1, [r0] 208 209 ldr r0, =SCU_HPLL_PARAM 210 movw r1, #0x4080 211 movt r1, #0x1000 212 str r1, [r0] 213 214 ldr r0, =SCU_HPLL_PARAM_EXT 215 mov r1, #0x47 216 str r1, [r0] 217 218wait_lock: 219 ldr r1, [r0] 220 tst r1, #0x80000000 221 beq wait_lock 222 223 /* skip A1 only area */ 224 b 2f 225 2260: 227 /* identify AST2600/AST2620 A1 */ 228 ldr r0, =SCU_REV_ID 229 ldr r0, [r0] 230 231 ldr r1, =REV_ID_AST2600A1 232 cmp r0, r1 233 beq 1f 234 235 ldr r1, =REV_ID_AST2620A1 236 cmp r0, r1 237 bne 2f 238 2391: 240 /* LPC/eSPI mode selection by SW (AST2600/AST2620 A1 only) */ 241 ldr r0, =GPIOYZ_DATA_VALUE 242 ldr r0, [r0] 243 tst r0, #0x1000 244 beq 2f 245 246 /* switch to LPC mode if GPIOZ[4]=1 */ 247 ldr r0, =SCU_HW_STRAP2 248 ldr r1, [r0] 249 orr r1, #0x40 250 str r1, [r0] 251 2522: 253 /* Enable Vault Key Write Protection */ 254 mov r0, #0x2 255 ldr r1, =SEC_VAULT_KEY_CTRL 256 str r0, [r1] 257 258 /* PCIeRC/E2M8 power-on reset comes from SCU040 259 It need set SCU040[18] high to reset PCIeRC/E2M 260 when AC power-on */ 261 ldr r0, =SCU_SYSRST_EVENT 262 ldr r1, [r0] 263 tst r1, #0x1 264 beq 3f 265 ldr r0, =SCU_SYSRST_CTRL 266 movw r1, #0x0000 267 movt r1, #0x0004 268 str r1, [r0] 2693: 270 /* Fix UART1 route problem on A3 */ 271 ldr r0, =0x1e789098 272 movw r1, #0x0a30 273 movt r1, #0x0000 274 str r1, [r0] 275 276 ldr r0, =0x1e78909c 277 movw r1, #0x0000 278 movt r1, #0x0000 279 str r1, [r0] 280 281 /* MMIO decode setting */ 282 ldr r0, =SCU_MMIO_DEC_SET 283 mov r1, #0x2000 284 str r1, [r0] 285 286 /* enable cache & SRAM parity check */ 287 mov r0, #0 288 ldr r1, =SCU_CA7_PARITY_CLR 289 str r0, [r1] 290 291 mov r0, #0x1 292 ldr r1, =SCU_CA7_PARITY_CHK 293 str r0, [r1] 294 295 /* Select USB2.0 Device mode as USB port B */ 296 ldr r0, =0x10000000 297 ldr r1, =SCU_USB_MULTI_FUNC 298 str r0, [r1] 299 300 /* enable USB port B PHY clk */ 301 mov r0, #0x80 302 ldr r1, =SCU_CLK_STOP_CTRL_CLR 303 str r0, [r1] 304 305#if 0 306 ldr r1, =FMC_WDT2_CTRL_MODE 307 str r0, [r1] 308#endif 309 310 /* do not fill FMC50[1] if boot from eMMC */ 311 ldr r0, =SCU_HW_STRAP1 312 ldr r1, [r0] 313 ands r1, #0x04 314 bne skip_fill_wip_bit 315 316 /* fill FMC50[1] for waiting WIP idle */ 317 mov r0, #0x02 318 ldr r1, =FMC_SW_RST_CTRL 319 str r0, [r1] 320skip_fill_wip_bit: 321 322#if !defined(CONFIG_ASPEED_DEFAULT_SPI_FREQUENCY) 323 /* tune up SPI clock */ 324 movw r0, #0x0600 325 movt r0, #0x0000 326 ldr r1, =FMC_CE0_CTRL 327 str r0, [r1] 328#endif 329 330 /* disable FMC WDT for SPI address mode detection */ 331 mov r0, #0 332 ldr r1, =FMC_WDT1_CTRL_MODE 333 str r0, [r1] 334 335 /* disable backdoor for A1/A2 to align A3 design */ 336 ldr r0, =SCU_HW_STRAP3 337 ldr r0, [r0] 338 tst r0, #0x1 339 340 ldr r0, =SCU_DEBUG_CTRL 341 movwne r1, #0x0ffd 342 movweq r1, #0x0fff 343 movt r1, #0x0000 344 str r1, [r0] 345 346 ldr r0, =SCU_DEBUG_CTRL2 347 movne r1, #0xf7 348 moveq r1, #0xff 349 str r1, [r0] 350 351relocate_smp_mbox_start: 352 /* relocate SMP mailbox insn. for cpuN to poll for go signal */ 353 adrl r0, smp_mbox_insn 354 adrl r1, smp_mbox_insn_end 355 ldr r2, =SCU_SMP_POLLINSN 356 357relocate_smp_mbox_insn: 358 ldr r3, [r0], #0x4 359 str r3, [r2], #0x4 360 cmp r0, r1 361 bne relocate_smp_mbox_insn 362 363 /* reset SMP go sign and entrypoints */ 364 mov r0, #0 365 ldr r1, =SCU_SMP_GO 366 str r0, [r1] 367 ldr r1, =SCU_SMP_NS_EP 368 str r0, [r1] 369 ldr r1, =SCU_SMP_S_EP 370 str r0, [r1] 371 372 /* notify cpuN mailbox is ready */ 373 movw r0, #0xcafe 374 movt r0, #0xbabe 375 ldr r1, =SCU_SMP_READY 376 str r0, [r1] 377 sev 378 379 /* back to arch calling code */ 380 mov pc, lr 381 382/* 383 * insn. inside mailbox to poll SMP go signal. 384 * 385 * Note that as this code will be relocated, any 386 * pc-relative assembly should NOT be used. 387 */ 388smp_mbox_insn: 389 /* 390 * r4 = per-cpu go sign value 391 * r5 = SCU_SMP_GO 392 * r6 = SCU_SMP_NS_EP 393 * r7 = SCU_SMP_S_EP 394 */ 395poll_smp_mbox_go: 396 wfe 397 ldr r0, [r5] 398 cmp r0, r4 399 bne poll_smp_mbox_go 400 401 /* go to secure world if secure entrypoint is specified */ 402 ldr r3, [r7] 403 cmp r3, #0 404 beq 1f 405 406 ldr lr, [r6] 407 mov pc, r3 4081: 409 ldr pc, [r6] 410 411smp_mbox_insn_end: 412 /* should never reach */ 413 b . 414 415#endif 416