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