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_MFP_CTRL15		(AST_SCU_BASE + 0x454)
47#define AST_SCU_HW_STRAP1		(AST_SCU_BASE + 0x500)
48#define AST_SCU_HW_STRAP2		(AST_SCU_BASE + 0x510)
49#define AST_SCU_CA7_CTRL		(AST_SCU_BASE + 0x800)
50#define AST_SCU_CA7_AXI_PREFETCH_START	(AST_SCU_BASE + 0x808)
51#define AST_SCU_CA7_AXI_PREFETCH_END	(AST_SCU_BASE + 0x80C)
52#define AST_SCU_CA7_PARITY_CHK		(AST_SCU_BASE + 0x820)
53#define AST_SCU_CA7_PARITY_CLR		(AST_SCU_BASE + 0x824)
54#define AST_SCU_MMIO_DEC_SET		(AST_SCU_BASE + 0xC24)
55
56#define AST_FMC_BASE		(0x1E620000)
57#define AST_FMC_CE0_CTRL	(AST_FMC_BASE + 0x010)
58#define AST_FMC_WDT1_CTRL_MODE	(AST_FMC_BASE + 0x060)
59#define AST_FMC_WDT2_CTRL_MODE	(AST_FMC_BASE + 0x064)
60
61#define AST_GPIO_BASE		(0x1E780000)
62#define AST_GPIOYZ_DATA_VALUE	(AST_GPIO_BASE + 0x1E0)
63
64/* Revision ID */
65#define REV_ID_AST2600A0	0x05000303
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, #0xF080
80	movt	r0, #0x2FA
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	movweq 	r0, #0x32C0
89	movteq	r0, #0x4013
90	movwne	r0, #0x8C00
91	movtne	r0, #0x4786
92#endif
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, =AST_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, =AST_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, =AST_SMP_MBOX_FIELD_GOSIGN
140	ldr	r1, =AST_SMP_MBOX_FIELD_ENTRY
141
142	/* no return */
143	ldr	pc, =AST_SMP_MBOX_FIELD_POLLINSN
144
145do_primary_core_setup:
146	/* unlock system control unit */
147	scu_unlock
148
149	/* identify AST2600 A0/A1 */
150	ldr	r0, =AST_SCU_REV_ID
151	ldr	r0, [r0]
152
153	ldr	r1, =REV_ID_AST2600A0
154	cmp	r0, r1
155
156	bne	0f
157
158	/* tune up CPU clocks (A0 only) */
159	ldr	r0, =AST_SCU_HW_STRAP1
160	ldr	r1, [r0]
161	bic	r1, #0x1800
162	orr	r1, #0x1000
163	str	r1, [r0]
164
165	ldr	r0, =AST_SCU_HPLL_PARAM
166	movw	r1, #0x4080
167	movt	r1, #0x1000
168	str	r1, [r0]
169
170	ldr	r0, =AST_SCU_HPLL_PARAM_EXT
171	mov	r1, #0x47
172	str	r1, [r0]
173
174wait_lock:
175	ldr	r1, [r0]
176	tst	r1, #0x80000000
177	beq	wait_lock
178
179	/* skip A1 only area */
180	b 1f
181
1820:
183	/* enable AXI prefetch (A1 only) */
184	ldr	r0, =AST_SCU_CA7_AXI_PREFETCH_START
185	ldr r1, =ASPEED_DRAM_BASE
186	str r1, [r0]
187
188	ldr	r0, =AST_SCU_CA7_AXI_PREFETCH_END
189	ldr	r1, =0xFFFFFFFF
190	str r1, [r0]
191
192	ldr	r0, =AST_SCU_CA7_CTRL
193	ldr	r1, [r0]
194	orr	r1, #0x8000
195	str	r1, [r0]
196
197	/* LPC/eSPI mode selection (A1 only) */
198	ldr	r0, =AST_GPIOYZ_DATA_VALUE
199	ldr	r0, [r0]
200	tst	r0, #0x1000
201	beq	1f
202
203	/* switch to LPC mode if GPIOZ[4]=1 */
204	ldr	r0, =AST_SCU_HW_STRAP2
205	ldr	r1, [r0]
206	orr	r1, #0x40
207	str	r1, [r0]
208
2091:
210	/* release display port reset */
211	ldr	r0, =AST_SCU_SYSRST_CTRL_CLR
212	movw	r1, #0x0000
213	movt	r1, #0x3000
214	str	r1, [r0]
215
216	/* MMIO decode setting */
217	ldr	r0, =AST_SCU_MMIO_DEC_SET
218	mov	r1, #0x2000
219	str	r1, [r0]
220
221	/* enable cache & SRAM parity check */
222	mov	r0, #0
223	ldr	r1, =AST_SCU_CA7_PARITY_CLR
224	str	r0, [r1]
225
226	mov	r0, #0x1
227	ldr	r1, =AST_SCU_CA7_PARITY_CHK
228	str	r0, [r1]
229
230	/* disable FMC WDT for SPI address mode detection */
231	mov	r0, #0
232	ldr	r1, =AST_FMC_WDT1_CTRL_MODE
233	str	r0, [r1]
234#if 0
235	ldr	r1, =AST_FMC_WDT2_CTRL_MODE
236	str	r0, [r1]
237#endif
238	/* tune up SPI clock */
239	movw	r0, #0x0641
240	movt	r0, #0x203B
241	ldr	r1, =AST_FMC_CE0_CTRL
242	str	r0, [r1]
243
244#if 0
245	/* disable UART-based SoC Debug Interface UART5 and P2A bridge*/
246	ldr     r0, =AST_SCU_DEBUG_CTRL
247	ldr     r1, [r0]
248	orr     r1, #0x03
249	str     r1, [r0]
250
251	/* disable UART-based SoC Debug Interface UART1 and LPC2AHB bridge */
252	ldr     r0, =AST_SCU_DEBUG_CTRL2
253	ldr     r1, [r0]
254	orr     r1, #0x0A
255	str     r1, [r0]
256#endif
257
258	/* Strongest LADESPID Driving Strngth */
259	ldr	r0, =AST_SCU_MFP_CTRL15
260	ldr	r1, [r0]
261	mov r2, #0xff00
262	orr r1, r2, lsl #16
263	str	r1, [r0]
264
265	/* relocate mailbox insn. for cpuN polling SMP go signal */
266	adrl	r0, mailbox_insn
267	adrl	r1, mailbox_insn_end
268
269	ldr	r2, =#AST_SMP_MBOX_FIELD_POLLINSN
270
271relocate_mailbox_insn:
272	ldr	r3, [r0], #0x4
273	str	r3, [r2], #0x4
274	cmp	r0, r1
275	bne	relocate_mailbox_insn
276
277	/* reset SMP go sign */
278	mov	r0, #0
279	ldr	r1, =AST_SMP_MBOX_FIELD_GOSIGN
280	str	r0, [r1]
281
282	/* notify cpuN mailbox is ready */
283	movw	r0, #0xCAFE
284	movt	r0, #0xBABE
285	ldr	r1, =AST_SMP_MBOX_FIELD_READY
286	str	r0, [r1]
287	sev
288
289	/* back to arch calling code */
290	mov	pc, lr
291
292/*
293 * insn. inside mailbox to poll SMP go signal.
294 *
295 * Note that as this code will be relocated, any
296 * pc-relative assembly should NOT be used.
297 */
298mailbox_insn:
299	/*
300	 * r0 ~ r3 are parameters:
301	 *  r0 = AST_SMP_MBOX_FIELD_GOSIGN
302	 *  r1 = AST_SMP_MBOX_FIELD_ENTRY
303	 *  r2 = per-cpu go sign value
304	 *  r3 = no used now
305	 */
306poll_mailbox_smp_go:
307	wfe
308	ldr	r4, [r0]
309	cmp	r2, r4
310	bne	poll_mailbox_smp_go
311
312	/* SMP GO signal confirmed, release cpuN */
313	ldr	pc, [r1]
314
315mailbox_insn_end:
316	/* should never reach */
317	b	.
318
319#endif
320