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_MFP_CTRL15 (AST_SCU_BASE + 0x454) 47#define AST_SCU_HW_STRAP1 (AST_SCU_BASE + 0x500) 48#define AST_SCU_HW_STRAP2 (AST_SCU_BASE + 0x510) 49#define AST_SCU_CA7_CTRL (AST_SCU_BASE + 0x800) 50#define AST_SCU_CA7_AXI_PREFETCH_START (AST_SCU_BASE + 0x808) 51#define AST_SCU_CA7_AXI_PREFETCH_END (AST_SCU_BASE + 0x80C) 52#define AST_SCU_CA7_PARITY_CHK (AST_SCU_BASE + 0x820) 53#define AST_SCU_CA7_PARITY_CLR (AST_SCU_BASE + 0x824) 54#define AST_SCU_MMIO_DEC_SET (AST_SCU_BASE + 0xC24) 55 56#define AST_FMC_BASE (0x1E620000) 57#define AST_FMC_CE0_CTRL (AST_FMC_BASE + 0x010) 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 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, #0xF080 80 movt r0, #0x2FA 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 movweq r0, #0x32C0 89 movteq r0, #0x4013 90 movwne r0, #0x8C00 91 movtne r0, #0x4786 92#endif 93 mcr p15, 0, r0, c14, c0, 0 @; update CNTFRQ 94.endm 95 96 97.globl lowlevel_init 98 99lowlevel_init: 100#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) 101 mov pc, lr 102#else 103 /* setup ARM arch timer frequency */ 104 timer_init 105 106 /* reset SMP mailbox as early as possible */ 107 mov r0, #0x0 108 ldr r1, =AST_SMP_MBOX_FIELD_READY 109 str r0, [r1] 110 111 /* set ACTLR.SMP to enable cache use */ 112 mrc p15, 0, r0, c1, c0, 1 113 orr r0, #0x40 114 mcr p15, 0, r0, c1, c0, 1 115 116 /* 117 * we treat cpu0 as the primary core and 118 * put secondary core (cpuN) to sleep 119 */ 120 mrc p15, 0, r0, c0, c0, 5 @; Read CPU ID register 121 ands r0, #0xFF @; Mask off, leaving the CPU ID field 122 movw r2, #0xAB00 123 movt r2, #0xABBA 124 orr r2, r0 125 126 beq do_primary_core_setup 127 128 /* hold cpuN until mailbox is ready */ 129poll_mailbox_ready: 130 wfe 131 ldr r0, =AST_SMP_MBOX_FIELD_READY 132 ldr r0, [r0] 133 movw r1, #0xCAFE 134 movt r1, #0xBABE 135 cmp r1, r0 136 bne poll_mailbox_ready 137 138 /* parameters for relocated SMP go polling insn. */ 139 ldr r0, =AST_SMP_MBOX_FIELD_GOSIGN 140 ldr r1, =AST_SMP_MBOX_FIELD_ENTRY 141 142 /* no return */ 143 ldr pc, =AST_SMP_MBOX_FIELD_POLLINSN 144 145do_primary_core_setup: 146 /* unlock system control unit */ 147 scu_unlock 148 149 /* identify AST2600 A0/A1 */ 150 ldr r0, =AST_SCU_REV_ID 151 ldr r0, [r0] 152 153 ldr r1, =REV_ID_AST2600A0 154 cmp r0, r1 155 156 bne 0f 157 158 /* tune up CPU clocks (A0 only) */ 159 ldr r0, =AST_SCU_HW_STRAP1 160 ldr r1, [r0] 161 bic r1, #0x1800 162 orr r1, #0x1000 163 str r1, [r0] 164 165 ldr r0, =AST_SCU_HPLL_PARAM 166 movw r1, #0x4080 167 movt r1, #0x1000 168 str r1, [r0] 169 170 ldr r0, =AST_SCU_HPLL_PARAM_EXT 171 mov r1, #0x47 172 str r1, [r0] 173 174wait_lock: 175 ldr r1, [r0] 176 tst r1, #0x80000000 177 beq wait_lock 178 179 /* skip A1 only area */ 180 b 1f 181 1820: 183 /* enable AXI prefetch (A1 only) */ 184 ldr r0, =AST_SCU_CA7_AXI_PREFETCH_START 185 ldr r1, =ASPEED_DRAM_BASE 186 str r1, [r0] 187 188 ldr r0, =AST_SCU_CA7_AXI_PREFETCH_END 189 ldr r1, =0xFFFFFFFF 190 str r1, [r0] 191 192 ldr r0, =AST_SCU_CA7_CTRL 193 ldr r1, [r0] 194 orr r1, #0x8000 195 str r1, [r0] 196 197 /* LPC/eSPI mode selection (A1 only) */ 198 ldr r0, =AST_GPIOYZ_DATA_VALUE 199 ldr r0, [r0] 200 tst r0, #0x1000 201 beq 1f 202 203 /* switch to LPC mode if GPIOZ[4]=1 */ 204 ldr r0, =AST_SCU_HW_STRAP2 205 ldr r1, [r0] 206 orr r1, #0x40 207 str r1, [r0] 208 2091: 210 /* release display port reset */ 211 ldr r0, =AST_SCU_SYSRST_CTRL_CLR 212 movw r1, #0x0000 213 movt r1, #0x3000 214 str r1, [r0] 215 216 /* MMIO decode setting */ 217 ldr r0, =AST_SCU_MMIO_DEC_SET 218 mov r1, #0x2000 219 str r1, [r0] 220 221 /* enable cache & SRAM parity check */ 222 mov r0, #0 223 ldr r1, =AST_SCU_CA7_PARITY_CLR 224 str r0, [r1] 225 226 mov r0, #0x1 227 ldr r1, =AST_SCU_CA7_PARITY_CHK 228 str r0, [r1] 229 230 /* disable FMC WDT for SPI address mode detection */ 231 mov r0, #0 232 ldr r1, =AST_FMC_WDT1_CTRL_MODE 233 str r0, [r1] 234#if 0 235 ldr r1, =AST_FMC_WDT2_CTRL_MODE 236 str r0, [r1] 237#endif 238 /* tune up SPI clock */ 239 movw r0, #0x0641 240 movt r0, #0x203B 241 ldr r1, =AST_FMC_CE0_CTRL 242 str r0, [r1] 243 244#if 0 245 /* disable UART-based SoC Debug Interface UART5 and P2A bridge*/ 246 ldr r0, =AST_SCU_DEBUG_CTRL 247 ldr r1, [r0] 248 orr r1, #0x03 249 str r1, [r0] 250 251 /* disable UART-based SoC Debug Interface UART1 and LPC2AHB bridge */ 252 ldr r0, =AST_SCU_DEBUG_CTRL2 253 ldr r1, [r0] 254 orr r1, #0x0A 255 str r1, [r0] 256#endif 257 258 /* Strongest LADESPID Driving Strngth */ 259 ldr r0, =AST_SCU_MFP_CTRL15 260 ldr r1, [r0] 261 mov r2, #0xff00 262 orr r1, r2, lsl #16 263 str r1, [r0] 264 265 /* relocate mailbox insn. for cpuN polling SMP go signal */ 266 adrl r0, mailbox_insn 267 adrl r1, mailbox_insn_end 268 269 ldr r2, =#AST_SMP_MBOX_FIELD_POLLINSN 270 271relocate_mailbox_insn: 272 ldr r3, [r0], #0x4 273 str r3, [r2], #0x4 274 cmp r0, r1 275 bne relocate_mailbox_insn 276 277 /* reset SMP go sign */ 278 mov r0, #0 279 ldr r1, =AST_SMP_MBOX_FIELD_GOSIGN 280 str r0, [r1] 281 282 /* notify cpuN mailbox is ready */ 283 movw r0, #0xCAFE 284 movt r0, #0xBABE 285 ldr r1, =AST_SMP_MBOX_FIELD_READY 286 str r0, [r1] 287 sev 288 289 /* back to arch calling code */ 290 mov pc, lr 291 292/* 293 * insn. inside mailbox to poll SMP go signal. 294 * 295 * Note that as this code will be relocated, any 296 * pc-relative assembly should NOT be used. 297 */ 298mailbox_insn: 299 /* 300 * r0 ~ r3 are parameters: 301 * r0 = AST_SMP_MBOX_FIELD_GOSIGN 302 * r1 = AST_SMP_MBOX_FIELD_ENTRY 303 * r2 = per-cpu go sign value 304 * r3 = no used now 305 */ 306poll_mailbox_smp_go: 307 wfe 308 ldr r4, [r0] 309 cmp r2, r4 310 bne poll_mailbox_smp_go 311 312 /* SMP GO signal confirmed, release cpuN */ 313 ldr pc, [r1] 314 315mailbox_insn_end: 316 /* should never reach */ 317 b . 318 319#endif 320