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