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