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