blob: 594963d039d0140ded4d9677528bc129685aa7dc [file] [log] [blame]
Chia-Wei, Wang8f7f4902020-12-14 13:54:28 +08001/* 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