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