1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2020 MediaTek Inc.
4 *
5 * Author:  Weijie Gao <weijie.gao@mediatek.com>
6 */
7
8#include <config.h>
9#include <asm-offsets.h>
10#include <asm/cacheops.h>
11#include <asm/regdef.h>
12#include <asm/mipsregs.h>
13#include <asm/addrspace.h>
14#include <asm/asm.h>
15#include <system-constants.h>
16#include "mt7628.h"
17
18#define CACHE_STACK_SIZE	0x4000
19#define CACHE_STACK_BASE	(SYS_INIT_SP_ADDR - CACHE_STACK_SIZE)
20
21#define DELAY_USEC(us)		((58 * (us)) / 3)
22
23	.set noreorder
24
25LEAF(mips_sram_init)
26#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
27	/* Setup CPU PLL */
28	li	t0, DELAY_USEC(1000000)
29	li	t1, KSEG1ADDR(SYSCTL_BASE + SYSCTL_ROM_STATUS_REG)
30	li	t2, KSEG1ADDR(SYSCTL_BASE + SYSCTL_CLKCFG0_REG)
31
32_check_rom_status:
33	lw	t3, 0(t1)
34	andi	t3, t3, 1
35	bnez	t3, _rom_normal
36	subu	t0, t0, 1
37	bnez	t0, _check_rom_status
38	 nop
39
40	lw	t3, 0(t2)
41	ori	t3, (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL)
42	xori	t3, CPU_PLL_FROM_BBP
43	b	_cpu_pll_done
44	 nop
45
46_rom_normal:
47	lw	t3, 0(t2)
48	ori	t3, (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL | \
49		    DIS_BBP_SLEEP | EN_BBP_CLK)
50	xori	t3, (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL)
51
52_cpu_pll_done:
53	sw	t3, 0(t2)
54
55	li	t2, KSEG1ADDR(RBUSCTL_BASE + RBUSCTL_DYN_CFG0_REG)
56	lw	t3, 0(t2)
57	ori	t3, t3, (CPU_FDIV_M | CPU_FFRAC_M)
58	xori	t3, t3, (CPU_FDIV_M | CPU_FFRAC_M)
59	ori	t3, t3, ((1 << CPU_FDIV_S) | (1 << CPU_FFRAC_S))
60	sw	t3, 0(t2)
61
62	/* Clear WST & SPR bits in ErrCtl */
63	mfc0	t0, CP0_ECC
64	ins	t0, zero, 30, 2
65	mtc0	t0, CP0_ECC
66	ehb
67
68	/* Simply initialize I-Cache */
69	li	a0, 0
70	li	a1, CONFIG_SYS_ICACHE_SIZE
71
72	mtc0	zero, CP0_TAGLO		/* Zero to DDataLo */
73
741:	cache	INDEX_STORE_TAG_I, 0(a0)
75	addiu	a0, CONFIG_SYS_ICACHE_LINE_SIZE
76	bne	a0, a1, 1b
77	 nop
78
79	/* Simply initialize D-Cache */
80	li	a0, 0
81	li	a1, CONFIG_SYS_DCACHE_SIZE
82
83	mtc0	zero, CP0_TAGLO, 2
84
852:	cache	INDEX_STORE_TAG_D, 0(a0)
86	addiu	a0, CONFIG_SYS_DCACHE_LINE_SIZE
87	bne	a0, a1, 2b
88	 nop
89
90	/* Set KSEG0 Cachable */
91	mfc0	t0, CP0_CONFIG
92	and	t0, t0, MIPS_CONF_IMPL
93	or	t0, t0, CONF_CM_CACHABLE_NONCOHERENT
94	mtc0	t0, CP0_CONFIG
95	ehb
96
97	/* Lock D-Cache */
98	PTR_LI	a0, CACHE_STACK_BASE		/* D-Cache lock base */
99	li	a1, CACHE_STACK_SIZE		/* D-Cache lock size */
100	li	a2, 0x1ffff800			/* Mask of DTagLo[PTagLo] */
101
1023:
103	/* Lock one cacheline */
104	and	t0, a0, a2
105	ori	t0, 0xe0			/* Valid & Dirty & Lock bits */
106	mtc0	t0, CP0_TAGLO, 2		/* Write to DTagLo */
107	ehb
108	cache	INDEX_STORE_TAG_D, 0(a0)
109
110	addiu	a0, CONFIG_SYS_DCACHE_LINE_SIZE
111	sub	a1, CONFIG_SYS_DCACHE_LINE_SIZE
112	bnez	a1, 3b
113	 nop
114#endif /* CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT) */
115
116	jr	ra
117	 nop
118	END(mips_sram_init)
119
120NESTED(lowlevel_init, 0, ra)
121	/* Save ra and do real lowlevel initialization */
122	move	s0, ra
123
124	PTR_LA	t9, mt7628_init
125	jalr	t9
126	 nop
127
128	move	ra, s0
129
130#if CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
131	/* Set malloc base */
132	li	t0, (SYS_INIT_SP_ADDR + 15) & (~15)
133	PTR_S	t0, GD_MALLOC_BASE(k0)	# gd->malloc_base offset
134#endif
135
136	/* Write back data in locked cache to DRAM */
137	PTR_LI	a0, CACHE_STACK_BASE		/* D-Cache unlock base */
138	li	a1, CACHE_STACK_SIZE		/* D-Cache unlock size */
139
1401:
141	cache	HIT_WRITEBACK_INV_D, 0(a0)
142	addiu	a0, CONFIG_SYS_DCACHE_LINE_SIZE
143	sub	a1, CONFIG_SYS_DCACHE_LINE_SIZE
144	bnez	a1, 1b
145	 nop
146
147	/* Set KSEG0 Uncached */
148	mfc0	t0, CP0_CONFIG
149	and	t0, t0, MIPS_CONF_IMPL
150	or	t0, t0, CONF_CM_UNCACHED
151	mtc0	t0, CP0_CONFIG
152	ehb
153
154	jr	ra
155	 nop
156	END(lowlevel_init)
157