1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2022 MediaTek Inc. All rights reserved.
4 *
5 * Author: Weijie Gao <weijie.gao@mediatek.com>
6 */
7
8#include <asm-offsets.h>
9#include <config.h>
10#include <asm/asm.h>
11#include <asm/regdef.h>
12#include <asm/mipsregs.h>
13#include <asm/cacheops.h>
14#include <asm/addrspace.h>
15#include <asm/mipsmtregs.h>
16#include <asm/cm.h>
17#include "../mt7621.h"
18#include "dram.h"
19
20#ifndef CFG_SYS_INIT_SP_ADDR
21#define CFG_SYS_INIT_SP_ADDR	(CFG_SYS_SDRAM_BASE + \
22				CFG_SYS_INIT_SP_OFFSET)
23#endif
24
25#define SP_ADDR_TEMP		0xbe10dff0
26
27	.macro init_wr sel
28	MTC0	zero, CP0_WATCHLO,\sel
29	mtc0	t1, CP0_WATCHHI,\sel
30	.endm
31
32	.macro setup_stack_gd
33	li	t0, -16
34	PTR_LI	t1, CFG_SYS_INIT_SP_ADDR
35	and	sp, t1, t0		# force 16 byte alignment
36	PTR_SUBU \
37		sp, sp, GD_SIZE		# reserve space for gd
38	and	sp, sp, t0		# force 16 byte alignment
39	move	k0, sp			# save gd pointer
40#if CONFIG_IS_ENABLED(SYS_MALLOC_F) && \
41    !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
42	li	t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
43	PTR_SUBU \
44		sp, sp, t2		# reserve space for early malloc
45	and	sp, sp, t0		# force 16 byte alignment
46#endif
47	move	fp, sp
48
49	/* Clear gd */
50	move	t0, k0
511:
52	PTR_S	zero, 0(t0)
53	PTR_ADDIU t0, PTRSIZE
54	blt	t0, t1, 1b
55	 nop
56
57#if CONFIG_IS_ENABLED(SYS_MALLOC_F) && \
58    !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
59	PTR_S	sp, GD_MALLOC_BASE(k0)	# gd->malloc_base offset
60#endif
61	.endm
62
63	.set	noreorder
64
65ENTRY(_start)
66	b	1f
67	 mtc0	zero, CP0_COUNT
68
69	/* Stage header required by BootROM */
70	.org	0x8
71	.word	0		# ep, filled by mkimage
72	.word	0		# stage_size, filled by mkimage
73	.word	0		# has_stage2
74	.word	0		# next_ep
75	.word	0		# next_size
76	.word	0		# next_offset
77
781:
79	/* Init CP0 Status */
80	mfc0	t0, CP0_STATUS
81	and	t0, ST0_IMPL
82	or	t0, ST0_BEV | ST0_ERL
83	mtc0	t0, CP0_STATUS
84	ehb
85
86	/* Clear Watch Status bits and disable watch exceptions */
87	li	t1, 0x7		# Clear I, R and W conditions
88	init_wr	0
89	init_wr	1
90	init_wr	2
91	init_wr	3
92
93	/* Clear WP, IV and SW interrupts */
94	mtc0	zero, CP0_CAUSE
95
96	/* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
97	mtc0	zero, CP0_COMPARE
98
99	/* VPE1 goes to wait code directly */
100	mfc0	t0, CP0_TCBIND
101	andi	t0, TCBIND_CURVPE
102	bnez	t0, launch_vpe_entry
103	 nop
104
105	/* Core1 goes to specific launch entry */
106	PTR_LI	t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE)
107	lw	t1, GCR_Cx_ID(t0)
108	bnez	t1, launch_core_entry
109	 nop
110
111	/* MT7530 reset */
112	li	t0, KSEG1ADDR(SYSCTL_BASE)
113	lw	t1, SYSCTL_RSTCTL_REG(t0)
114	ori	t1, MCM_RST
115	sw	t1, SYSCTL_RSTCTL_REG(t0)
116
117	/* Disable DMA route for PSE SRAM set by BootROM */
118	PTR_LI	t0, KSEG1ADDR(DMA_CFG_ARB_BASE)
119	sw	zero, DMA_ROUTE_REG(t0)
120
121	/* Set CPU clock to 500MHz (Required if boot from NAND) */
122	li	t0, KSEG1ADDR(SYSCTL_BASE)
123	lw	t1, SYSCTL_CLKCFG0_REG(t0)
124	ins	t1, zero, 30, 2		# CPU_CLK_SEL
125	sw	t1, SYSCTL_CLKCFG0_REG(t0)
126
127	/* Set CPU clock divider to 1/1 */
128	li	t0, KSEG1ADDR(RBUS_BASE)
129	li	t1, 0x101
130	sw	t1, RBUS_DYN_CFG0_REG(t0)
131
132	/* (Re-)initialize the SRAM */
133	bal	mips_sram_init
134	 nop
135
136	/* Set up temporary stack */
137	li	sp, SP_ADDR_TEMP
138
139	/* Setup full CPS */
140	bal	mips_cm_map
141	 nop
142
143	bal	mt7621_cps_init
144	 nop
145
146	/* Prepare for CPU/DDR initialization binary blob */
147	bal	prepare_stage_bin
148	 nop
149
150	/* Call CPU/DDR initialization binary blob */
151	li	t9, STAGE_LOAD_ADDR
152	jalr	t9
153	 nop
154
155	/* Switch CPU PLL source */
156	li	t0, KSEG1ADDR(SYSCTL_BASE)
157	lw	t1, SYSCTL_CLKCFG0_REG(t0)
158	li	t2, 1
159	ins	t1, t2, CPU_CLK_SEL_S, 2
160	sw	t1, SYSCTL_CLKCFG0_REG(t0)
161
162	/*
163	 * Currently SPL is running on locked L2 cache (on KSEG0).
164	 * To reset the entire cache, we have to writeback SPL to DRAM first.
165	 * Cache flush won't work here. Use memcpy instead.
166	 */
167
168	la	a0, __text_start
169	move	a1, a0
170	la	a2, __image_copy_end
171	sub	a2, a2, a1
172	li	a3, 5
173	ins	a0, a3, 29, 3	# convert to KSEG1
174
175	bal	memcpy
176	 nop
177
178	/* Disable caches */
179	bal	mips_cache_disable
180	 nop
181
182	/* Reset caches */
183	bal	mips_cache_reset
184	 nop
185
186	/* Disable SRAM */
187	li	t0, KSEG1ADDR(FE_BASE)
188	li	t1, FE_PSE_RESET
189	sw	t1, FE_RST_GLO_REG(t0)
190
191	/* Clear the .bss section */
192	la	a0, __bss_start
193	la	a1, __bss_end
1941:	sw	zero, 0(a0)
195	addiu	a0, 4
196	ble	a0, a1, 1b
197	 nop
198
199	/* Set up initial stack and global data */
200	setup_stack_gd
201
202#if CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
203	/* Set malloc base */
204	li	t0, (CFG_SYS_INIT_SP_ADDR + 15) & (~15)
205	PTR_S	t0, GD_MALLOC_BASE(k0)	# gd->malloc_base offset
206#endif
207
208#if defined(CONFIG_DEBUG_UART) && defined(CONFIG_SPL_SERIAL)
209	/* Earliest point to set up debug uart */
210	bal	debug_uart_init
211	 nop
212#endif
213
214	/* Setup timer */
215	bal	set_timer_freq_simple
216	 nop
217
218	/* Bootup secondary CPUs */
219	bal	secondary_cpu_init
220	 nop
221
222	move	a0, zero		# a0 <-- boot_flags = 0
223	bal board_init_f
224	 move	ra, zero
225
226	END(_start)
227