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