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