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_SYSRST_EVENT (AST_SCU_BASE + 0x064) 43#define AST_SCU_CLK_STOP_CTRL_CLR (AST_SCU_BASE + 0x084) 44#define AST_SCU_DEBUG_CTRL (AST_SCU_BASE + 0x0C8) 45#define AST_SCU_DEBUG_CTRL2 (AST_SCU_BASE + 0x0D8) 46#define AST_SCU_HPLL_PARAM (AST_SCU_BASE + 0x200) 47#define AST_SCU_HPLL_PARAM_EXT (AST_SCU_BASE + 0x204) 48#define AST_SCU_USB_MULTI_FUNC (AST_SCU_BASE + 0x440) 49#define AST_SCU_HW_STRAP1 (AST_SCU_BASE + 0x500) 50#define AST_SCU_HW_STRAP2 (AST_SCU_BASE + 0x510) 51#define AST_SCU_HW_STRAP3 (AST_SCU_BASE + 0x51C) 52#define AST_SCU_CA7_PARITY_CHK (AST_SCU_BASE + 0x820) 53#define AST_SCU_CA7_PARITY_CLR (AST_SCU_BASE + 0x824) 54#define AST_SCU_MMIO_DEC_SET (AST_SCU_BASE + 0xC24) 55 56#define AST_FMC_BASE (0x1E620000) 57#define AST_FMC_CE0_CTRL (AST_FMC_BASE + 0x010) 58#define AST_FMC_SW_RST_CTRL (AST_FMC_BASE + 0x050) 59#define AST_FMC_WDT1_CTRL_MODE (AST_FMC_BASE + 0x060) 60#define AST_FMC_WDT2_CTRL_MODE (AST_FMC_BASE + 0x064) 61 62#define AST_GPIO_BASE (0x1E780000) 63#define AST_GPIOYZ_DATA_VALUE (AST_GPIO_BASE + 0x1E0) 64 65#define AST_SEC_BASE (0x1E6F2000) 66#define AST_SEC_VAULT_KEY_CTRL (AST_SEC_BASE + 0x80C) 67 68/* Revision ID */ 69#define REV_ID_AST2600A0 0x05000303 70#define REV_ID_AST2600A1 0x05010303 71#define REV_ID_AST2620A1 0x05010203 72 73.macro scu_unlock 74 movw r0, #0xA8A8 75 movt r0, #0x1688 @; magic key to unlock SCU 76 77 ldr r1, =AST_SCU_PROT_KEY1 78 str r0, [r1] 79 ldr r1, =AST_SCU_PROT_KEY2 80 str r0, [r1] 81.endm 82 83.macro timer_init 84#ifdef CONFIG_FPGA_ASPEED 85 movw r0, #0x6c00 86 movt r0, #0x02dc 87#else 88 ldr r0, =AST_SCU_REV_ID 89 ldr r0, [r0] 90 91 ldr r1, =REV_ID_AST2600A0 92 cmp r0, r1 93 94 beq timer_init_a0 95 96 ldr r1, =AST_SCU_HW_STRAP1 97 ldr r1, [r1] 98 and r1, #0x700 99 lsr r1, #0x8 100 101 cmp r1, #0x0 102 movweq r0, #0x8c00 103 movteq r0, #0x4786 104 105 cmp r1, #0x1 106 movweq r0, #0x1000 107 movteq r0, #0x5f5e 108 109 cmp r1, #0x2 110 movweq r0, #0x8c00 111 movteq r0, #0x4786 112 113 cmp r1, #0x3 114 movweq r0, #0x1000 115 movteq r0, #0x5f5e 116 117 cmp r1, #0x4 118 movwge r0, #0x0800 119 movtge r0, #0x2faf 120 121 b timer_init_out 122 123timer_init_a0: 124 movweq r0, #0x32c0 125 movteq r0, #0x4013 126 127timer_init_out: 128#endif 129 mcr p15, 0, r0, c14, c0, 0 @; update CNTFRQ 130.endm 131 132 133.globl lowlevel_init 134 135lowlevel_init: 136#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) 137 mov pc, lr 138#else 139 /* setup ARM arch timer frequency */ 140 timer_init 141 142 /* reset SMP mailbox as early as possible */ 143 mov r0, #0x0 144 ldr r1, =AST_SMP_MBOX_FIELD_READY 145 str r0, [r1] 146 147 /* set ACTLR.SMP to enable cache use */ 148 mrc p15, 0, r0, c1, c0, 1 149 orr r0, #0x40 150 mcr p15, 0, r0, c1, c0, 1 151 152 /* 153 * we treat cpu0 as the primary core and 154 * put secondary core (cpuN) to sleep 155 */ 156 mrc p15, 0, r0, c0, c0, 5 @; Read CPU ID register 157 ands r0, #0xFF @; Mask off, leaving the CPU ID field 158 movw r2, #0xAB00 159 movt r2, #0xABBA 160 orr r2, r0 161 162 beq do_primary_core_setup 163 164 /* hold cpuN until mailbox is ready */ 165poll_mailbox_ready: 166 wfe 167 ldr r0, =AST_SMP_MBOX_FIELD_READY 168 ldr r0, [r0] 169 movw r1, #0xCAFE 170 movt r1, #0xBABE 171 cmp r1, r0 172 bne poll_mailbox_ready 173 174 /* parameters for relocated SMP go polling insn. */ 175 ldr r0, =AST_SMP_MBOX_FIELD_GOSIGN 176 ldr r1, =AST_SMP_MBOX_FIELD_ENTRY 177 178 /* no return */ 179 ldr pc, =AST_SMP_MBOX_FIELD_POLLINSN 180 181do_primary_core_setup: 182 /* unlock system control unit */ 183 scu_unlock 184 185 /* identify AST2600 A0/A1 */ 186 ldr r0, =AST_SCU_REV_ID 187 ldr r0, [r0] 188 189 ldr r1, =REV_ID_AST2600A0 190 cmp r0, r1 191 192 bne 0f 193 194 /* tune up CPU clocks (A0 only) */ 195 ldr r0, =AST_SCU_HW_STRAP1 196 ldr r1, [r0] 197 bic r1, #0x1800 198 orr r1, #0x1000 199 str r1, [r0] 200 201 ldr r0, =AST_SCU_HPLL_PARAM 202 movw r1, #0x4080 203 movt r1, #0x1000 204 str r1, [r0] 205 206 ldr r0, =AST_SCU_HPLL_PARAM_EXT 207 mov r1, #0x47 208 str r1, [r0] 209 210wait_lock: 211 ldr r1, [r0] 212 tst r1, #0x80000000 213 beq wait_lock 214 215 /* skip A1 only area */ 216 b 2f 217 2180: 219 /* identify AST2600/AST2620 A1 */ 220 ldr r0, =AST_SCU_REV_ID 221 ldr r0, [r0] 222 223 ldr r1, =REV_ID_AST2600A1 224 cmp r0, r1 225 beq 1f 226 227 ldr r1, =REV_ID_AST2620A1 228 cmp r0, r1 229 bne 2f 230 2311: 232 /* LPC/eSPI mode selection by SW (AST2600/AST2620 A1 only) */ 233 ldr r0, =AST_GPIOYZ_DATA_VALUE 234 ldr r0, [r0] 235 tst r0, #0x1000 236 beq 2f 237 238 /* switch to LPC mode if GPIOZ[4]=1 */ 239 ldr r0, =AST_SCU_HW_STRAP2 240 ldr r1, [r0] 241 orr r1, #0x40 242 str r1, [r0] 243 2442: 245 /* Enable Vault Key Write Protection */ 246 mov r0, #0x2 247 ldr r1, =AST_SEC_VAULT_KEY_CTRL 248 str r0, [r1] 249 250 /* PCIeRC/E2M8 power-on reset comes from SCU040 251 It need set SCU040[18] high to reset PCIeRC/E2M 252 when AC power-on */ 253 ldr r0, =AST_SCU_SYSRST_EVENT 254 ldr r1, [r0] 255 tst r1, #0x1 256 beq 3f 257 ldr r0, =AST_SCU_SYSRST_CTRL 258 movw r1, #0x0000 259 movt r1, #0x0004 260 str r1, [r0] 2613: 262 /* Fix UART1 route problem on A3 */ 263 ldr r0, =0x1e789098 264 movw r1, #0x0a30 265 movt r1, #0x0000 266 str r1, [r0] 267 268 ldr r0, =0x1e78909c 269 movw r1, #0x0000 270 movt r1, #0x0000 271 str r1, [r0] 272 273 /* MMIO decode setting */ 274 ldr r0, =AST_SCU_MMIO_DEC_SET 275 mov r1, #0x2000 276 str r1, [r0] 277 278 /* enable cache & SRAM parity check */ 279 mov r0, #0 280 ldr r1, =AST_SCU_CA7_PARITY_CLR 281 str r0, [r1] 282 283 mov r0, #0x1 284 ldr r1, =AST_SCU_CA7_PARITY_CHK 285 str r0, [r1] 286 287 /* Select USB2.0 Device mode as USB port B */ 288 ldr r0, =0x10000000 289 ldr r1, =AST_SCU_USB_MULTI_FUNC 290 str r0, [r1] 291 292 /* enable USB port B PHY clk */ 293 mov r0, #0x80 294 ldr r1, =AST_SCU_CLK_STOP_CTRL_CLR 295 str r0, [r1] 296 297#if 0 298 ldr r1, =AST_FMC_WDT2_CTRL_MODE 299 str r0, [r1] 300#endif 301 302 /* do not fill FMC50[1] if boot from eMMC */ 303 ldr r0, =AST_SCU_HW_STRAP1 304 ldr r1, [r0] 305 ands r1, #0x04 306 bne skip_fill_wip_bit 307 308 /* fill FMC50[1] for waiting WIP idle */ 309 mov r0, #0x02 310 ldr r1, =AST_FMC_SW_RST_CTRL 311 str r0, [r1] 312skip_fill_wip_bit: 313 314#if !defined(CONFIG_ASPEED_DEFAULT_SPI_FREQUENCY) 315 /* tune up SPI clock */ 316 movw r0, #0x0600 317 movt r0, #0x0000 318 ldr r1, =AST_FMC_CE0_CTRL 319 str r0, [r1] 320#endif 321 322 /* disable FMC WDT for SPI address mode detection */ 323 mov r0, #0 324 ldr r1, =AST_FMC_WDT1_CTRL_MODE 325 str r0, [r1] 326 327 /* disable backdoor for A1/A2 to align A3 design */ 328 ldr r0, =AST_SCU_HW_STRAP3 329 ldr r0, [r0] 330 tst r0, #0x1 331 332 ldr r0, =AST_SCU_DEBUG_CTRL 333 movwne r1, #0x0ffd 334 movweq r1, #0x0fff 335 movt r1, #0x0000 336 str r1, [r0] 337 338 ldr r0, =AST_SCU_DEBUG_CTRL2 339 movne r1, #0xf7 340 moveq r1, #0xff 341 str r1, [r0] 342 343 /* relocate mailbox insn. for cpuN polling SMP go signal */ 344 adrl r0, mailbox_insn 345 adrl r1, mailbox_insn_end 346 347 ldr r2, =#AST_SMP_MBOX_FIELD_POLLINSN 348 349relocate_mailbox_insn: 350 ldr r3, [r0], #0x4 351 str r3, [r2], #0x4 352 cmp r0, r1 353 bne relocate_mailbox_insn 354 355 /* reset SMP go sign */ 356 mov r0, #0 357 ldr r1, =AST_SMP_MBOX_FIELD_GOSIGN 358 str r0, [r1] 359 360 /* notify cpuN mailbox is ready */ 361 movw r0, #0xCAFE 362 movt r0, #0xBABE 363 ldr r1, =AST_SMP_MBOX_FIELD_READY 364 str r0, [r1] 365 sev 366 367 /* back to arch calling code */ 368 mov pc, lr 369 370/* 371 * insn. inside mailbox to poll SMP go signal. 372 * 373 * Note that as this code will be relocated, any 374 * pc-relative assembly should NOT be used. 375 */ 376mailbox_insn: 377 /* 378 * r0 ~ r3 are parameters: 379 * r0 = AST_SMP_MBOX_FIELD_GOSIGN 380 * r1 = AST_SMP_MBOX_FIELD_ENTRY 381 * r2 = per-cpu go sign value 382 * r3 = no used now 383 */ 384poll_mailbox_smp_go: 385 wfe 386 ldr r4, [r0] 387 cmp r2, r4 388 bne poll_mailbox_smp_go 389 390 /* SMP GO signal confirmed, release cpuN */ 391 ldr pc, [r1] 392 393mailbox_insn_end: 394 /* should never reach */ 395 b . 396 397#endif 398