summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S
blob: 0523bd468a114be63457312aa68d33eadc1d6ab3 (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
/*
 * Copyright (C) 2010 Albert ARIBAUD <albert.aribaud@free.fr>
 *
 * (C) Copyright 2009
 * Marvell Semiconductor <www.marvell.com>
 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA
 */

#include <config.h>
#include "asm/arch/orion5x.h"

/*
 * Configuration values for SDRAM access setup
 */

#define SDRAM_CONFIG			0x3148400
#define SDRAM_MODE			0x62
#define SDRAM_CONTROL			0x4041000
#define SDRAM_TIME_CTRL_LOW		0x11602220
#define SDRAM_TIME_CTRL_HI		0x40c
#define SDRAM_OPEN_PAGE_EN		0x0
/* DDR 1 2x 32M NANYA NT5DS16M16CS-6K ==> 64MB */
#define SDRAM_BANK0_SIZE		0x3ff0001
#define SDRAM_ADDR_CTRL			0x10

#define SDRAM_OP_NOP			0x05
#define SDRAM_OP_SETMODE		0x03

#define SDRAM_PAD_CTRL_WR_EN		0x80000000
#define SDRAM_PAD_CTRL_TUNE_EN		0x00010000
#define SDRAM_PAD_CTRL_DRVN_MASK	0x0000003f
#define SDRAM_PAD_CTRL_DRVP_MASK	0x00000fc0

/*
 * For Guideline MEM-3 - Drive Strength value
 */

#define DDR1_PAD_STRENGTH_DEFAULT	0x00001000
#define SDRAM_PAD_CTRL_DRV_STR_MASK	0x00003000

/*
 * For Guideline MEM-4 - DQS Reference Delay Tuning
 */

#define MSAR_ARMDDRCLCK_MASK		0x000000f0
#define MSAR_ARMDDRCLCK_H_MASK		0x00000100

#define MSAR_ARMDDRCLCK_333_167		0x00000000
#define MSAR_ARMDDRCLCK_500_167		0x00000030
#define MSAR_ARMDDRCLCK_667_167		0x00000060
#define MSAR_ARMDDRCLCK_400_200_1	0x000001E0
#define MSAR_ARMDDRCLCK_400_200		0x00000010
#define MSAR_ARMDDRCLCK_600_200		0x00000050
#define MSAR_ARMDDRCLCK_800_200		0x00000070

#define FTDLL_DDR1_166MHZ		0x0047F001

#define FTDLL_DDR1_200MHZ		0x0044D001

/*
 * Low-level init happens right after start.S has switched to SVC32,
 * flushed and disabled caches and disabled MMU. We're still running
 * from the boot chip select, so the first thing we should do is set
 * up RAM for us to relocate into.
 */

.globl lowlevel_init

lowlevel_init:

	/* Use 'r4 as the base for internal register accesses */
	ldr	r4, =ORION5X_REGS_PHY_BASE

	/* move internal registers from the default 0xD0000000
	 * to their intended location, defined by SoC */
	ldr	r3, =0xD0000000
	add	r3, r3, #0x20000
	str	r4, [r3, #0x80]

	/* Use R3 as the base for DRAM registers */
	add	r3, r4, #0x01000

	/*DDR SDRAM Initialization Control */
	ldr	r6, =0x00000001
	str	r6, [r3, #0x480]

	/* Use R3 as the base for PCI registers */
	add	r3, r4, #0x31000

	/* Disable arbiter */
	ldr	r6, =0x00000030
	str	r6, [r3, #0xd00]

	/* Use R3 as the base for DRAM registers */
	add	r3, r4, #0x01000

	/* set all dram windows to 0 */
	mov	r6, #0
	str	r6, [r3, #0x504]
	str	r6, [r3, #0x50C]
	str	r6, [r3, #0x514]
	str	r6, [r3, #0x51C]

	/* 1) Configure SDRAM  */
	ldr	r6, =SDRAM_CONFIG
	str	r6, [r3, #0x400]

	/* 2) Set SDRAM Control reg */
	ldr	r6, =SDRAM_CONTROL
	str	r6, [r3, #0x404]

	/* 3) Write SDRAM address control register */
	ldr	r6, =SDRAM_ADDR_CTRL
	str	r6, [r3, #0x410]

	/* 4) Write SDRAM bank 0 size register */
	ldr	r6, =SDRAM_BANK0_SIZE
	str	r6, [r3, #0x504]
	/* keep other banks disabled */

	/* 5) Write SDRAM open pages control register */
	ldr	r6, =SDRAM_OPEN_PAGE_EN
	str	r6, [r3, #0x414]

	/* 6) Write SDRAM timing Low register */
	ldr	r6, =SDRAM_TIME_CTRL_LOW
	str	r6, [r3, #0x408]

	/* 7) Write SDRAM timing High register */
	ldr	r6, =SDRAM_TIME_CTRL_HI
	str	r6, [r3, #0x40C]

	/* 8) Write SDRAM mode register */
	/* The CPU must not attempt to change the SDRAM Mode register setting */
	/* prior to DRAM controller completion of the DRAM initialization     */
	/* sequence. To guarantee this restriction, it is recommended that    */
	/* the CPU sets the SDRAM Operation register to NOP command, performs */
	/* read polling until the register is back in Normal operation value, */
	/* and then sets SDRAM Mode register to its new value.		      */

	/* 8.1 write 'nop' to SDRAM operation */
	ldr	r6, =SDRAM_OP_NOP
	str	r6, [r3, #0x418]

	/* 8.2 poll SDRAM operation until back in 'normal' mode.  */
1:
	ldr	r6, [r3, #0x418]
	cmp	r6, #0
	bne	1b

	/* 8.3 Now its safe to write new value to SDRAM Mode register	      */
	ldr	r6, =SDRAM_MODE
	str	r6, [r3, #0x41C]

	/* 8.4 Set new mode */
	ldr	r6, =SDRAM_OP_SETMODE
	str	r6, [r3, #0x418]

	/* 8.5 poll SDRAM operation until back in 'normal' mode.  */
2:
	ldr	r6, [r3, #0x418]
	cmp	r6, #0
	bne	2b

	/* DDR SDRAM Address/Control Pads Calibration */
	ldr	r6, [r3, #0x4C0]

	/* Set Bit [31] to make the register writable			*/
	orr	r6, r6, #SDRAM_PAD_CTRL_WR_EN
	str	r6, [r3, #0x4C0]

	bic	r6, r6, #SDRAM_PAD_CTRL_WR_EN
	bic	r6, r6, #SDRAM_PAD_CTRL_TUNE_EN
	bic	r6, r6, #SDRAM_PAD_CTRL_DRVN_MASK
	bic	r6, r6, #SDRAM_PAD_CTRL_DRVP_MASK

	/* Get the final N locked value of driving strength [22:17]	*/
	mov	r1, r6
	mov	r1, r1, LSL #9
	mov	r1, r1, LSR #26	 /* r1[5:0]<DrvN>  = r3[22:17]<LockN>	*/
	orr	r1, r1, r1, LSL #6 /* r1[11:6]<DrvP> = r1[5:0]<DrvN>	*/

	/* Write to both <DrvN> bits [5:0] and <DrvP> bits [11:6]	*/
	orr	r6, r6, r1
	str	r6, [r3, #0x4C0]

	/* DDR SDRAM Data Pads Calibration				*/
	ldr	r6, [r3, #0x4C4]

	/* Set Bit [31] to make the register writable			*/
	orr	r6, r6, #SDRAM_PAD_CTRL_WR_EN
	str	r6, [r3, #0x4C4]

	bic	r6, r6, #SDRAM_PAD_CTRL_WR_EN
	bic	r6, r6, #SDRAM_PAD_CTRL_TUNE_EN
	bic	r6, r6, #SDRAM_PAD_CTRL_DRVN_MASK
	bic	r6, r6, #SDRAM_PAD_CTRL_DRVP_MASK

	/* Get the final N locked value of driving strength [22:17]	*/
	mov	r1, r6
	mov	r1, r1, LSL #9
	mov	r1, r1, LSR #26
	orr	r1, r1, r1, LSL #6 /* r1[5:0] = r3[22:17]<LockN>	*/

	/* Write to both <DrvN> bits [5:0] and <DrvP> bits [11:6]	*/
	orr	r6, r6, r1

	str	r6, [r3, #0x4C4]

	/* Implement Guideline (GL# MEM-3) Drive Strength Value		*/
	/* Relevant for: 88F5181-A1/B0/B1 and 88F5281-A0/B0		*/

	ldr	r1, =DDR1_PAD_STRENGTH_DEFAULT

	/* Enable writes to DDR SDRAM Addr/Ctrl Pads Calibration register */
	ldr	r6, [r3, #0x4C0]
	orr	r6, r6, #SDRAM_PAD_CTRL_WR_EN
	str	r6, [r3, #0x4C0]

	/* Correct strength and disable writes again */
	bic	r6, r6, #SDRAM_PAD_CTRL_WR_EN
	bic	r6, r6, #SDRAM_PAD_CTRL_DRV_STR_MASK
	orr	r6, r6, r1
	str	r6, [r3, #0x4C0]

	/* Enable writes to DDR SDRAM Data Pads Calibration register */
	ldr	r6, [r3, #0x4C4]
	orr	r6, r6, #SDRAM_PAD_CTRL_WR_EN
	str	r6, [r3, #0x4C4]

	/* Correct strength and disable writes again */
	bic	r6, r6, #SDRAM_PAD_CTRL_DRV_STR_MASK
	bic	r6, r6, #SDRAM_PAD_CTRL_WR_EN
	orr	r6, r6, r1
	str	r6, [r3, #0x4C4]

	/* Implement Guideline (GL# MEM-4) DQS Reference Delay Tuning	*/
	/* Relevant for: 88F5181-A1/B0/B1 and 88F5281-A0/B0		*/

	/* Get the "sample on reset" register for the DDR frequancy	*/
	ldr	r3, =0x10000
	ldr	r6, [r3, #0x010]
	ldr	r1, =MSAR_ARMDDRCLCK_MASK
	and	r1, r6, r1

	ldr	r6, =FTDLL_DDR1_166MHZ
	cmp	r1, #MSAR_ARMDDRCLCK_333_167
	beq	3f
	cmp	r1, #MSAR_ARMDDRCLCK_500_167
	beq	3f
	cmp	r1, #MSAR_ARMDDRCLCK_667_167
	beq	3f

	ldr	r6, =FTDLL_DDR1_200MHZ
	cmp	r1, #MSAR_ARMDDRCLCK_400_200_1
	beq	3f
	cmp	r1, #MSAR_ARMDDRCLCK_400_200
	beq	3f
	cmp	r1, #MSAR_ARMDDRCLCK_600_200
	beq	3f
	cmp	r1, #MSAR_ARMDDRCLCK_800_200
	beq	3f

	ldr	r6, =0

3:
	/* Use R3 as the base for DRAM registers */
	add	r3, r4, #0x01000

	ldr	r2, [r3, #0x484]
	orr	r2, r2, r6
	str	r2, [r3, #0x484]

	/* Return to U-boot via saved link register */
	mov	pc, lr