1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Copyright (c) ASPEED Technology Inc. 4 */ 5#include <config.h> 6#include <asm/armv7.h> 7#include <linux/linkage.h> 8#include <asm/arch/scu_ast2600.h> 9 10/* SCU register offsets */ 11#define SCU_BASE 0x1e6e2000 12#define SCU_PROT_KEY1 (SCU_BASE + 0x000) 13#define SCU_PROT_KEY2 (SCU_BASE + 0x010) 14#define SCU_SMP_BOOT (SCU_BASE + 0x180) 15#define SCU_HWSTRAP1 (SCU_BASE + 0x510) 16#define SCU_CA7_PARITY_CHK (SCU_BASE + 0x820) 17#define SCU_CA7_PARITY_CLR (SCU_BASE + 0x824) 18#define SCU_MMIO_DEC (SCU_BASE + 0xc24) 19 20/* FMC SPI register offsets */ 21#define FMC_BASE 0x1e620000 22#define FMC_CE0_CTRL (FMC_BASE + 0x010) 23#define FMC_SW_RST_CTRL (FMC_BASE + 0x050) 24#define FMC_WDT1_CTRL_MODE (FMC_BASE + 0x060) 25#define FMC_WDT2_CTRL_MODE (FMC_BASE + 0x064) 26 27/* 28 * The SMP mailbox provides a space with few instructions in it 29 * for secondary cores to execute on and wait for the signal of 30 * SMP core bring up. 31 * 32 * SMP mailbox 33 * +----------------------+ 34 * | | 35 * | mailbox insn. for | 36 * | cpuN polling SMP go | 37 * | | 38 * +----------------------+ 0xC 39 * | mailbox ready signal | 40 * +----------------------+ 0x8 41 * | cpuN GO signal | 42 * +----------------------+ 0x4 43 * | cpuN entrypoint | 44 * +----------------------+ SMP_MAILBOX_BASE 45 */ 46#define SMP_MBOX_BASE (SCU_SMP_BOOT) 47#define SMP_MBOX_FIELD_ENTRY (SMP_MBOX_BASE + 0x0) 48#define SMP_MBOX_FIELD_GOSIGN (SMP_MBOX_BASE + 0x4) 49#define SMP_MBOX_FIELD_READY (SMP_MBOX_BASE + 0x8) 50#define SMP_MBOX_FIELD_POLLINSN (SMP_MBOX_BASE + 0xc) 51 52.macro scu_unlock 53 movw r0, #(SCU_UNLOCK_KEY & 0xffff) 54 movt r0, #(SCU_UNLOCK_KEY >> 16) 55 56 ldr r1, =SCU_PROT_KEY1 57 str r0, [r1] 58 ldr r1, =SCU_PROT_KEY2 59 str r0, [r1] 60.endm 61 62.macro timer_init 63 ldr r1, =SCU_HWSTRAP1 64 ldr r1, [r1] 65 and r1, #0x700 66 lsr r1, #0x8 67 68 /* 1.2GHz */ 69 cmp r1, #0x0 70 movweq r0, #0x8c00 71 movteq r0, #0x4786 72 73 /* 1.6GHz */ 74 cmp r1, #0x1 75 movweq r0, #0x1000 76 movteq r0, #0x5f5e 77 78 /* 1.2GHz */ 79 cmp r1, #0x2 80 movweq r0, #0x8c00 81 movteq r0, #0x4786 82 83 /* 1.6GHz */ 84 cmp r1, #0x3 85 movweq r0, #0x1000 86 movteq r0, #0x5f5e 87 88 /* 800MHz */ 89 cmp r1, #0x4 90 movwge r0, #0x0800 91 movtge r0, #0x2faf 92 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, =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, =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, =SMP_MBOX_FIELD_GOSIGN 140 ldr r1, =SMP_MBOX_FIELD_ENTRY 141 142 /* no return */ 143 ldr pc, =SMP_MBOX_FIELD_POLLINSN 144 145do_primary_core_setup: 146 scu_unlock 147 148 /* MMIO decode setting */ 149 ldr r0, =SCU_MMIO_DEC 150 mov r1, #0x2000 151 str r1, [r0] 152 153 /* enable CA7 cache parity check */ 154 mov r0, #0 155 ldr r1, =SCU_CA7_PARITY_CLR 156 str r0, [r1] 157 158 mov r0, #0x1 159 ldr r1, =SCU_CA7_PARITY_CHK 160 str r0, [r1] 161 162 /* do not fill FMC50[1] if boot from eMMC */ 163 ldr r0, =SCU_HWSTRAP1 164 ldr r1, [r0] 165 ands r1, #0x04 166 bne skip_fill_wip_bit 167 168 /* fill FMC50[1] for waiting WIP idle */ 169 mov r0, #0x02 170 ldr r1, =FMC_SW_RST_CTRL 171 str r0, [r1] 172 173skip_fill_wip_bit: 174 /* disable FMC WDT for SPI address mode detection */ 175 mov r0, #0 176 ldr r1, =FMC_WDT1_CTRL_MODE 177 str r0, [r1] 178 179 /* relocate mailbox insn. for cpuN polling SMP go signal */ 180 adrl r0, mailbox_insn 181 adrl r1, mailbox_insn_end 182 183 ldr r2, =#SMP_MBOX_FIELD_POLLINSN 184 185relocate_mailbox_insn: 186 ldr r3, [r0], #0x4 187 str r3, [r2], #0x4 188 cmp r0, r1 189 bne relocate_mailbox_insn 190 191 /* reset SMP go sign */ 192 mov r0, #0 193 ldr r1, =SMP_MBOX_FIELD_GOSIGN 194 str r0, [r1] 195 196 /* notify cpuN mailbox is ready */ 197 movw r0, #0xCAFE 198 movt r0, #0xBABE 199 ldr r1, =SMP_MBOX_FIELD_READY 200 str r0, [r1] 201 sev 202 203 /* back to arch calling code */ 204 mov pc, lr 205 206/* 207 * insn. inside mailbox to poll SMP go signal. 208 * 209 * Note that as this code will be relocated, any 210 * pc-relative assembly should NOT be used. 211 */ 212mailbox_insn: 213 /* 214 * r0 ~ r3 are parameters: 215 * r0 = SMP_MBOX_FIELD_GOSIGN 216 * r1 = SMP_MBOX_FIELD_ENTRY 217 * r2 = per-cpu go sign value 218 * r3 = no used now 219 */ 220poll_mailbox_smp_go: 221 wfe 222 ldr r4, [r0] 223 cmp r2, r4 224 bne poll_mailbox_smp_go 225 226 /* SMP GO signal confirmed, release cpuN */ 227 ldr pc, [r1] 228 229mailbox_insn_end: 230 /* should never reach */ 231 b . 232 233#endif 234