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_HPLL_PARAM	(AST_SCU_BASE + 0x200)
43#define AST_SCU_HPLL_PARAM_EXT	(AST_SCU_BASE + 0x204)
44#define AST_SCU_HW_STRAP1	(AST_SCU_BASE + 0x500)
45#define AST_SCU_CA7_PARITY_CHK	(AST_SCU_BASE + 0x820)
46#define AST_SCU_CA7_PARITY_CLR	(AST_SCU_BASE + 0x824)
47
48#define AST_FMC_BASE		(0x1E620000)
49#define AST_FMC_CE0_CTRL	(AST_FMC_BASE + 0x010)
50#define AST_FMC_WDT1_CTRL_MODE	(AST_FMC_BASE + 0x060)
51#define AST_FMC_WDT2_CTRL_MODE	(AST_FMC_BASE + 0x064)
52
53/* Revision ID */
54#define REV_ID_AST2600A0	0x05000303
55
56.macro scu_unlock
57	movw	r0, #0xA8A8
58	movt	r0, #0x1688	@; magic key to unlock SCU
59
60	ldr	r1, =AST_SCU_PROT_KEY1
61	str	r0, [r1]
62	ldr	r1, =AST_SCU_PROT_KEY2
63	str	r0, [r1]
64.endm
65
66.macro timer_init
67#ifdef CONFIG_FPGA_ASPEED
68	movw	r0, #0xF080
69	movt	r0, #0x2FA
70#else
71	movw 	r0, #0x32c0
72	movt	r0, #0x4013
73#endif
74	mcr	p15, 0, r0, c14, c0, 0	@; update CNTFRQ
75.endm
76
77
78.globl lowlevel_init
79
80lowlevel_init:
81#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
82	mov	pc, lr
83#else
84	/* setup ARM arch timer frequency */
85	timer_init
86
87	/* reset SMP mailbox as early as possible */
88	mov	r0, #0x0
89	ldr	r1, =AST_SMP_MBOX_FIELD_READY
90	str	r0, [r1]
91
92	/* set ACTLR.SMP to enable cache use */
93	mrc	p15, 0, r0, c1, c0, 1
94	orr	r0, #0x40
95	mcr	p15, 0, r0, c1, c0, 1
96
97	/*
98	 * we treat cpu0 as the primary core and
99	 * put secondary core (cpuN) to sleep
100	 */
101	mrc   p15, 0, r0, c0, c0, 5	@; Read CPU ID register
102	ands  r0, #0xFF			@; Mask off, leaving the CPU ID field
103	movw  r2, #0xAB00
104	movt  r2, #0xABBA
105	orr   r2, r0
106
107	beq   do_primary_core_setup
108
109	/* hold cpuN until mailbox is ready */
110poll_mailbox_ready:
111	wfe
112	ldr	r0, =AST_SMP_MBOX_FIELD_READY
113	ldr	r0, [r0]
114	movw	r1, #0xCAFE
115	movt	r1, #0xBABE
116	cmp	r1, r0
117	bne	poll_mailbox_ready
118
119	/* parameters for relocated SMP go polling insn. */
120	ldr	r0, =AST_SMP_MBOX_FIELD_GOSIGN
121	ldr	r1, =AST_SMP_MBOX_FIELD_ENTRY
122
123	/* no return */
124	ldr	pc, =AST_SMP_MBOX_FIELD_POLLINSN
125
126do_primary_core_setup:
127	/* unlock system control unit */
128	scu_unlock
129
130	/* tune-up CPU clock for AST2600 A0 */
131	ldr	r0, =AST_SCU_REV_ID
132	ldr	r0, [r0]
133
134	ldr	r1, =REV_ID_AST2600A0
135	cmp	r0, r1
136
137	bne	0f
138
139	/* setup CPU clocks */
140	ldr	r0, =AST_SCU_HW_STRAP1
141	ldr	r1, [r0]
142	bic	r1, #0x1800
143	orr	r1, #0x1000
144	str	r1, [r0]
145
146	ldr	r0, =AST_SCU_HPLL_PARAM
147	movw	r1, #0x4080
148	movt	r1, #0x1000
149	str	r1, [r0]
150
151	ldr	r0, =AST_SCU_HPLL_PARAM_EXT
152	mov	r1, #0x47
153	str	r1, [r0]
154
155wait_lock:
156	ldr	r1, [r0]
157	tst	r1, #0x80000000
158	beq	wait_lock
159
1600:
161	/* enable cache & SRAM parity check */
162	mov	r0, #0
163	ldr	r1, =AST_SCU_CA7_PARITY_CLR
164	str	r0, [r1]
165
166	mov	r0, #0x11
167	ldr	r1, =AST_SCU_CA7_PARITY_CHK
168	str	r0, [r1]
169
170	/* disable FMC WDT for SPI address mode detection */
171	mov	r0, #0
172	ldr	r1, =AST_FMC_WDT1_CTRL_MODE
173	str	r0, [r1]
174#if 0
175	ldr	r1, =AST_FMC_WDT2_CTRL_MODE
176	str	r0, [r1]
177#endif
178	/* tune up SPI clock */
179	movw	r0, #0x0641
180	movt	r0, #0x000B
181	ldr	r1, =AST_FMC_CE0_CTRL
182	str	r0, [r1]
183
184	/* release display port reset */
185	ldr	r0, =AST_SCU_SYSRST_CTRL_CLR
186	movw	r1, #0x0000
187	movt	r1, #0x3000
188	str	r1, [r0]
189
190	/* relocate mailbox insn. for cpuN polling SMP go signal */
191	adrl	r0, mailbox_insn
192	adrl	r1, mailbox_insn_end
193
194	ldr	r2, =#AST_SMP_MBOX_FIELD_POLLINSN
195
196relocate_mailbox_insn:
197	ldr	r3, [r0], #0x4
198	str	r3, [r2], #0x4
199	cmp	r0, r1
200	bne	relocate_mailbox_insn
201
202	/* reset SMP go sign */
203	mov	r0, #0
204	ldr	r1, =AST_SMP_MBOX_FIELD_GOSIGN
205	str	r0, [r1]
206
207	/* notify cpuN mailbox is ready */
208	movw	r0, #0xCAFE
209	movt	r0, #0xBABE
210	ldr	r1, =AST_SMP_MBOX_FIELD_READY
211	str	r0, [r1]
212	sev
213
214	/* back to arch calling code */
215	mov	pc, lr
216
217/*
218 * insn. inside mailbox to poll SMP go signal.
219 *
220 * Note that as this code will be relocated, any
221 * pc-relative assembly should NOT be used.
222 */
223mailbox_insn:
224	/*
225	 * r0 ~ r3 are parameters:
226	 *  r0 = AST_SMP_MBOX_FIELD_GOSIGN
227	 *  r1 = AST_SMP_MBOX_FIELD_ENTRY
228	 *  r2 = per-cpu go sign value
229	 *  r3 = no used now
230	 */
231poll_mailbox_smp_go:
232	wfe
233	ldr	r4, [r0]
234	cmp	r2, r4
235	bne	poll_mailbox_smp_go
236
237	/* SMP GO signal confirmed, release cpuN */
238	ldr	pc, [r1]
239
240mailbox_insn_end:
241	/* should never reach */
242	b	.
243
244#endif
245