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