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