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