xref: /openbmc/u-boot/arch/arm/mach-aspeed/ast2600/platform.S (revision b8233483f822dc441692cc7df659e402e7edcd1b)
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_HW_STRAP1		(AST_SCU_BASE + 0x500)
47#define AST_SCU_HW_STRAP2		(AST_SCU_BASE + 0x510)
48#define AST_SCU_HW_STRAP3		(AST_SCU_BASE + 0x51C)
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_SW_RST_CTRL	(AST_FMC_BASE + 0x050)
56#define AST_FMC_WDT1_CTRL_MODE	(AST_FMC_BASE + 0x060)
57#define AST_FMC_WDT2_CTRL_MODE	(AST_FMC_BASE + 0x064)
58
59#define AST_GPIO_BASE		(0x1E780000)
60#define AST_GPIOYZ_DATA_VALUE	(AST_GPIO_BASE + 0x1E0)
61
62/* Revision ID */
63#define REV_ID_AST2600A0	0x05000303
64#define REV_ID_AST2600A1	0x05010303
65#define REV_ID_AST2620A1	0x05010203
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, #0x6c00
80	movt	r0, #0x02dc
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	beq	timer_init_a0
89
90	ldr	r1, =AST_SCU_HW_STRAP1
91	ldr	r1, [r1]
92	and	r1, #0x700
93	lsr	r1, #0x8
94
95	cmp	r1, #0x0
96	movweq	r0, #0x8c00
97	movteq	r0, #0x4786
98
99	cmp	r1, #0x1
100	movweq	r0, #0x1000
101	movteq	r0, #0x5f5e
102
103	cmp	r1, #0x2
104	movweq	r0, #0x8c00
105	movteq	r0, #0x4786
106
107	cmp	r1, #0x3
108	movweq	r0, #0x1000
109	movteq	r0, #0x5f5e
110
111	cmp	r1, #0x4
112	movwge	r0, #0x0800
113	movtge	r0, #0x2faf
114
115	b	timer_init_out
116
117timer_init_a0:
118	movweq	r0, #0x32c0
119	movteq	r0, #0x4013
120
121timer_init_out:
122#endif
123	mcr	p15, 0, r0, c14, c0, 0	@; update CNTFRQ
124.endm
125
126
127.globl lowlevel_init
128
129lowlevel_init:
130#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
131	mov	pc, lr
132#else
133	/* setup ARM arch timer frequency */
134	timer_init
135
136	/* reset SMP mailbox as early as possible */
137	mov	r0, #0x0
138	ldr	r1, =AST_SMP_MBOX_FIELD_READY
139	str	r0, [r1]
140
141	/* set ACTLR.SMP to enable cache use */
142	mrc	p15, 0, r0, c1, c0, 1
143	orr	r0, #0x40
144	mcr	p15, 0, r0, c1, c0, 1
145
146	/*
147	 * we treat cpu0 as the primary core and
148	 * put secondary core (cpuN) to sleep
149	 */
150	mrc   p15, 0, r0, c0, c0, 5	@; Read CPU ID register
151	ands  r0, #0xFF			@; Mask off, leaving the CPU ID field
152	movw  r2, #0xAB00
153	movt  r2, #0xABBA
154	orr   r2, r0
155
156	beq   do_primary_core_setup
157
158	/* hold cpuN until mailbox is ready */
159poll_mailbox_ready:
160	wfe
161	ldr	r0, =AST_SMP_MBOX_FIELD_READY
162	ldr	r0, [r0]
163	movw	r1, #0xCAFE
164	movt	r1, #0xBABE
165	cmp	r1, r0
166	bne	poll_mailbox_ready
167
168	/* parameters for relocated SMP go polling insn. */
169	ldr	r0, =AST_SMP_MBOX_FIELD_GOSIGN
170	ldr	r1, =AST_SMP_MBOX_FIELD_ENTRY
171
172	/* no return */
173	ldr	pc, =AST_SMP_MBOX_FIELD_POLLINSN
174
175do_primary_core_setup:
176	/* unlock system control unit */
177	scu_unlock
178
179	/* identify AST2600 A0/A1 */
180	ldr	r0, =AST_SCU_REV_ID
181	ldr	r0, [r0]
182
183	ldr	r1, =REV_ID_AST2600A0
184	cmp	r0, r1
185
186	bne	0f
187
188	/* tune up CPU clocks (A0 only) */
189	ldr	r0, =AST_SCU_HW_STRAP1
190	ldr	r1, [r0]
191	bic	r1, #0x1800
192	orr	r1, #0x1000
193	str	r1, [r0]
194
195	ldr	r0, =AST_SCU_HPLL_PARAM
196	movw	r1, #0x4080
197	movt	r1, #0x1000
198	str	r1, [r0]
199
200	ldr	r0, =AST_SCU_HPLL_PARAM_EXT
201	mov	r1, #0x47
202	str	r1, [r0]
203
204wait_lock:
205	ldr	r1, [r0]
206	tst	r1, #0x80000000
207	beq	wait_lock
208
209	/* skip A1 only area */
210	b 2f
211
2120:
213	/* identify AST2600/AST2620 A1 */
214	ldr	r0, =AST_SCU_REV_ID
215	ldr	r0, [r0]
216
217	ldr	r1, =REV_ID_AST2600A1
218	cmp	r0, r1
219	beq	1f
220
221	ldr	r1, =REV_ID_AST2620A1
222	cmp	r0, r1
223	bne	2f
224
2251:
226	/* LPC/eSPI mode selection by SW (AST2600/AST2620 A1 only) */
227	ldr	r0, =AST_GPIOYZ_DATA_VALUE
228	ldr	r0, [r0]
229	tst	r0, #0x1000
230	beq	2f
231
232	/* switch to LPC mode if GPIOZ[4]=1 */
233	ldr	r0, =AST_SCU_HW_STRAP2
234	ldr	r1, [r0]
235	orr	r1, #0x40
236	str	r1, [r0]
237
2382:
239	/* PCIeRC/E2M8 power-on reset comes from SCU040
240	But SCU04018 default value is 0x0.
241	It should be 0x1 to reset PCIeRC/E2M8.*/
242	ldr     r0, =AST_SCU_SYSRST_CTRL
243	movw    r1, #0x0000
244	movt    r1, #0x0004
245	str     r1, [r0]
246
247	/* Fix UART1 route problem on A3 */
248	ldr     r0, =0x1e789098
249	movw    r1, #0x0a30
250	movt    r1, #0x0000
251	str     r1, [r0]
252
253	ldr     r0, =0x1e78909c
254	movw    r1, #0x0000
255	movt    r1, #0x0000
256	str     r1, [r0]
257
258	/* MMIO decode setting */
259	ldr	r0, =AST_SCU_MMIO_DEC_SET
260	mov	r1, #0x2000
261	str	r1, [r0]
262
263	/* enable cache & SRAM parity check */
264	mov	r0, #0
265	ldr	r1, =AST_SCU_CA7_PARITY_CLR
266	str	r0, [r1]
267
268	mov	r0, #0x1
269	ldr	r1, =AST_SCU_CA7_PARITY_CHK
270	str	r0, [r1]
271
272#if 0
273	ldr	r1, =AST_FMC_WDT2_CTRL_MODE
274	str	r0, [r1]
275#endif
276
277	/* do not fill FMC50[1] if boot from eMMC */
278	ldr	r0, =AST_SCU_HW_STRAP1
279	ldr	r1, [r0]
280	ands	r1, #0x04
281	bne	skip_fill_wip_bit
282
283	/* fill FMC50[1] for waiting WIP idle */
284	mov	r0, #0x02
285	ldr	r1, =AST_FMC_SW_RST_CTRL
286	str	r0, [r1]
287skip_fill_wip_bit:
288
289	/* tune up SPI clock */
290	movw	r0, #0x0600
291	movt	r0, #0x0000
292	ldr	r1, =AST_FMC_CE0_CTRL
293	str	r0, [r1]
294
295	/* disable FMC WDT for SPI address mode detection */
296	mov	r0, #0
297	ldr	r1, =AST_FMC_WDT1_CTRL_MODE
298	str	r0, [r1]
299
300	/* disable backdoor for A1/A2 to align A3 design */
301	ldr	r0, =AST_SCU_HW_STRAP3
302	ldr	r0, [r0]
303	tst	r0, #0x1
304
305	ldr	r0, =AST_SCU_DEBUG_CTRL
306	movwne	r1, #0x0ffd
307	movweq	r1, #0x0fff
308	movt	r1, #0x0000
309	str	r1, [r0]
310
311	ldr	r0, =AST_SCU_DEBUG_CTRL2
312	movne	r1, #0xf7
313	moveq	r1, #0xff
314	str	r1, [r0]
315
316	/* relocate mailbox insn. for cpuN polling SMP go signal */
317	adrl	r0, mailbox_insn
318	adrl	r1, mailbox_insn_end
319
320	ldr	r2, =#AST_SMP_MBOX_FIELD_POLLINSN
321
322relocate_mailbox_insn:
323	ldr	r3, [r0], #0x4
324	str	r3, [r2], #0x4
325	cmp	r0, r1
326	bne	relocate_mailbox_insn
327
328	/* reset SMP go sign */
329	mov	r0, #0
330	ldr	r1, =AST_SMP_MBOX_FIELD_GOSIGN
331	str	r0, [r1]
332
333	/* notify cpuN mailbox is ready */
334	movw	r0, #0xCAFE
335	movt	r0, #0xBABE
336	ldr	r1, =AST_SMP_MBOX_FIELD_READY
337	str	r0, [r1]
338	sev
339
340	/* back to arch calling code */
341	mov	pc, lr
342
343/*
344 * insn. inside mailbox to poll SMP go signal.
345 *
346 * Note that as this code will be relocated, any
347 * pc-relative assembly should NOT be used.
348 */
349mailbox_insn:
350	/*
351	 * r0 ~ r3 are parameters:
352	 *  r0 = AST_SMP_MBOX_FIELD_GOSIGN
353	 *  r1 = AST_SMP_MBOX_FIELD_ENTRY
354	 *  r2 = per-cpu go sign value
355	 *  r3 = no used now
356	 */
357poll_mailbox_smp_go:
358	wfe
359	ldr	r4, [r0]
360	cmp	r2, r4
361	bne	poll_mailbox_smp_go
362
363	/* SMP GO signal confirmed, release cpuN */
364	ldr	pc, [r1]
365
366mailbox_insn_end:
367	/* should never reach */
368	b	.
369
370#endif
371