summaryrefslogtreecommitdiff
path: root/arch/mips/mach-mt7620/lowlevel_init.S
blob: aa707e0de6c409115be32b46e278813f33c7e7a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * (c) 2018 Stefan Roese <sr@denx.de>
 *
 * This code is mostly based on the code extracted from this MediaTek
 * github repository:
 *
 * https://github.com/MediaTek-Labs/linkit-smart-uboot.git
 *
 * I was not able to find a specific license or other developers
 * copyrights here, so I can't add them here.
 */

#include <config.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <asm/asm.h>
#include "mt76xx.h"

#ifndef BIT
#define BIT(nr)			(1 << (nr))
#endif

#define DELAY_USEC(us)		((us) / 100)

#define DDR_CFG1_CHIP_WIDTH_MASK (0x3 << 16)
#define DDR_CFG1_BUS_WIDTH_MASK	(0x3 << 12)

#if defined(CONFIG_ONBOARD_DDR2_SIZE_256MBIT)
#define DDR_CFG1_SIZE_VAL	0x222e2323
#define DDR_CFG4_SIZE_VAL	7
#endif
#if defined(CONFIG_ONBOARD_DDR2_SIZE_512MBIT)
#define DDR_CFG1_SIZE_VAL	0x22322323
#define DDR_CFG4_SIZE_VAL	9
#endif
#if defined(CONFIG_ONBOARD_DDR2_SIZE_1024MBIT)
#define DDR_CFG1_SIZE_VAL	0x22362323
#define DDR_CFG4_SIZE_VAL	9
#endif
#if defined(CONFIG_ONBOARD_DDR2_SIZE_2048MBIT)
#define DDR_CFG1_SIZE_VAL	0x223a2323
#define DDR_CFG4_SIZE_VAL	9
#endif

#if defined(CONFIG_ONBOARD_DDR2_CHIP_WIDTH_8BIT)
#define DDR_CFG1_CHIP_WIDTH_VAL	(0x1 << 16)
#endif
#if defined(CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT)
#define DDR_CFG1_CHIP_WIDTH_VAL	(0x2 << 16)
#endif

#if defined(CONFIG_ONBOARD_DDR2_BUS_WIDTH_16BIT)
#define DDR_CFG1_BUS_WIDTH_VAL	(0x2 << 12)
#endif
#if defined(CONFIG_ONBOARD_DDR2_BUS_WIDTH_32BIT)
#define DDR_CFG1_BUS_WIDTH_VAL	(0x3 << 12)
#endif

	.set noreorder

LEAF(lowlevel_init)

	/* Load base addresses as physical addresses for later usage */
	li	s0, CKSEG1ADDR(MT76XX_SYSCTL_BASE)
	li	s1, CKSEG1ADDR(MT76XX_MEMCTRL_BASE)
	li	s2, CKSEG1ADDR(MT76XX_RGCTRL_BASE)

	/* polling CPLL is ready */
	li	t1, DELAY_USEC(1000000)
	la	t5, MT76XX_ROM_STATUS_REG
1:
	lw	t2, 0(t5)
	andi	t2, t2, 0x1
	bnez	t2, CPLL_READY
	subu	t1, t1, 1
	bgtz	t1, 1b
	nop
	la      t0, MT76XX_CLKCFG0_REG
	lw      t3, 0(t0)
	ori	t3, t3, 0x1
	sw	t3, 0(t0)
	b	CPLL_DONE
	nop
CPLL_READY:
	la	t0, MT76XX_CLKCFG0_REG
	lw	t1, 0(t0)
	li	t2, ~0x0c
	and	t1, t1, t2
	ori	t1, t1, 0xc
	sw	t1, 0(t0)
	la	t0, MT76XX_DYN_CFG0_REG
	lw	t3, 0(t0)
	li	t5, ~((0x0f << 8) | (0x0f << 0))
	and	t3, t3, t5
	li	t5, (10 << 8) | (1 << 0)
	or	t3, t3, t5
	sw	t3, 0(t0)
	la	t0, MT76XX_CLKCFG0_REG
	lw	t3, 0(t0)
	li	t4, ~0x0F
	and     t3, t3, t4
	ori	t3, t3, 0xc
	sw	t3, 0(t0)
	lw	t3, 0(t0)
	ori	t3, t3, 0x08
	sw	t3, 0(t0)

CPLL_DONE:
	/* Reset MC */
	lw	t2, 0x34(s0)
	ori	t2, BIT(10)
	sw	t2, 0x34(s0)
	nop

	/*
	 * SDR and DDR initialization: delay 200us
	 */
	li	t0, DELAY_USEC(200 + 40)
	li	t1, 0x1
1:
	sub	t0, t0, t1
	bnez	t0, 1b
	nop

	/* set DRAM IO PAD for MT7628IC */
	/* DDR LDO Enable  */
	lw	t4, 0x100(s2)
	li	t2, BIT(31)
	or	t4, t4, t2
	sw	t4, 0x100(s2)
	lw	t4, 0x10c(s2)
	j	LDO_1P8V
	nop
LDO_1P8V:
	li	t2, ~BIT(6)
	and	t4, t4, t2
	sw	t4, 0x10c(s2)
	j	DDRLDO_SOFT_START
LDO_2P5V:
	/* suppose external DDR1 LDO 2.5V */
	li	t2, BIT(6)
	or	t4, t4, t2
	sw	t4, 0x10c(s2)

DDRLDO_SOFT_START:
	lw	t2, 0x10c(s2)
	li	t3, BIT(16)
	or	t2, t2, t3
	sw	t2, 0x10c(s2)
	li	t3, DELAY_USEC(250*50)
LDO_DELAY:
	subu	t3, t3, 1
	bnez	t3, LDO_DELAY
	nop

	lw	t2, 0x10c(s2)
	li	t3, BIT(18)
	or	t2, t2, t3
	sw	t2, 0x10c(s2)

SET_RG_BUCK_FPWM:
	lw	t2, 0x104(s2)
	ori	t2, t2, BIT(10)
	sw	t2, 0x104(s2)

DDR_PAD_CFG:
	/* clean CLK PAD */
	lw	t2, 0x704(s2)
	li	t8, 0xfffff0f0
	and	t2, t2, t8
	/* clean CMD PAD */
	lw	t3, 0x70c(s2)
	li	t8, 0xfffff0f0
	and	t3, t3, t8
	/* clean DQ IPAD */
	lw	t4, 0x710(s2)
	li	t8, 0xfffff8ff
	and	t4, t4, t8
	/* clean DQ OPAD */
	lw	t5, 0x714(s2)
	li	t8, 0xfffff0f0
	and	t5, t5, t8
	/* clean DQS IPAD */
	lw	t6, 0x718(s2)
	li	t8, 0xfffff8ff
	and	t6, t6, t8
	/* clean DQS OPAD */
	lw	t7, 0x71c(s2)
	li	t8, 0xfffff0f0
	and	t7, t7, t8

	lw	t9, 0xc(s0)
	srl	t9, t9, 16
	andi	t9, t9, 0x1
	bnez	t9, MT7628_AN_DDR1_PAD
MT7628_KN_PAD:
	li	t8, 0x00000303
	or	t2, t2, t8
	or	t3, t3, t8
	or	t5, t5, t8
	or	t7, t7, t8
	li	t8, 0x00000000
	or	t4, t4, t8
	or	t6, t6, t8
	j	SET_PAD_CFG
MT7628_AN_DDR1_PAD:
	lw	t1, 0x10(s0)
	andi	t1, t1, 0x1
	beqz	t1, MT7628_AN_DDR2_PAD
	li	t8, 0x00000c0c
	or	t2, t2, t8
	li	t8, 0x00000202
	or	t3, t3, t8
	li	t8, 0x00000707
	or	t5, t5, t8
	li	t8, 0x00000c0c
	or	t7, t7, t8
	li	t8, 0x00000000
	or	t4, t4, t8
	or	t6, t6, t8
	j	SET_PAD_CFG
MT7628_AN_DDR2_PAD:
	li	t8, 0x00000c0c
	or	t2, t2, t8
	li	t8, 0x00000202
	or	t3, t3, t8
	li	t8, 0x00000404
	or	t5, t5, t8
	li	t8, 0x00000c0c
	or	t7, t7, t8
	li	t8, 0x00000000		/* ODT off */
	or	t4, t4, t8
	or	t6, t6, t8

SET_PAD_CFG:
	sw	t2, 0x704(s2)
	sw	t3, 0x70c(s2)
	sw	t4, 0x710(s2)
	sw	t5, 0x714(s2)
	sw	t6, 0x718(s2)
	sw	t7, 0x71c(s2)

	/*
	 * DDR initialization: reset pin to 0
	 */
	lw	t2, 0x34(s0)
	and	t2, ~BIT(10)
	sw	t2, 0x34(s0)
	nop

	/*
	 * DDR initialization: wait til reg DDR_CFG1 bit 21 equal to 1 (ready)
	 */
DDR_READY:
	li	t1, DDR_CFG1_REG
	lw	t0, 0(t1)
	nop
	and	t2, t0, BIT(21)
	beqz	t2, DDR_READY
	nop

	/*
	 * DDR initialization
	 *
	 * Only DDR2 supported right now. DDR2 support can be added, once
	 * boards using it will get added to mainline U-Boot.
	 */
	li	t1, DDR_CFG2_REG
	lw	t0, 0(t1)
	nop
	and	t0, ~BIT(30)
	and	t0, ~(7 << 4)
	or	t0, (4 << 4)
	or	t0, BIT(30)
	or	t0, BIT(11)
	sw	t0, 0(t1)
	nop

	li	t1, DDR_CFG3_REG
	lw	t2, 0(t1)
	/* Disable ODT; reference board ok, ev board fail */
	and	t2, ~BIT(6)
	or	t2, BIT(2)
	li	t0, DDR_CFG4_REG
	lw	t1, 0(t0)
	li	t2, ~(0x01f | 0x0f0)
	and	t1, t1, t2
	ori	t1, t1, DDR_CFG4_SIZE_VAL
	sw	t1, 0(t0)
	nop

	/*
	 * DDR initialization: config size and width on reg DDR_CFG1
	 */
	li	t6, DDR_CFG1_SIZE_VAL

	and	t6, ~DDR_CFG1_CHIP_WIDTH_MASK
	or	t6, DDR_CFG1_CHIP_WIDTH_VAL

	/* CONFIG DDR_CFG1[13:12] about TOTAL WIDTH */
	and	t6, ~DDR_CFG1_BUS_WIDTH_MASK
	or	t6, DDR_CFG1_BUS_WIDTH_VAL

	li	t5, DDR_CFG1_REG
	sw	t6, 0(t5)
	nop

	/*
	 * DDR: enable self auto refresh for power saving
	 * enable it by default for both RAM and ROM version (for CoC)
	 */
	lw	t1, 0x14(s1)
	nop
	and	t1, 0xff000000
	or	t1, 0x01
	sw	t1, 0x14(s1)
	nop
	lw	t1, 0x10(s1)
	nop
	or	t1, 0x10
	sw	t1, 0x10(s1)
	nop

	jr	ra
	nop
	END(lowlevel_init)