1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net>
4 *
5 * (C) Copyright 2009
6 * Marvell Semiconductor <www.marvell.com>
7 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
8 */
9
10#include <config.h>
11#include "asm/arch/orion5x.h"
12
13/*
14 * Configuration values for SDRAM access setup
15 */
16
17#define SDRAM_CONFIG			0x3148400
18#define SDRAM_MODE			0x62
19#define SDRAM_CONTROL			0x4041000
20#define SDRAM_TIME_CTRL_LOW		0x11602220
21#define SDRAM_TIME_CTRL_HI		0x40c
22#define SDRAM_OPEN_PAGE_EN		0x0
23/* DDR 1 2x 32M NANYA NT5DS16M16CS-6K ==> 64MB */
24#define SDRAM_BANK0_SIZE		0x3ff0001
25#define SDRAM_ADDR_CTRL			0x10
26
27#define SDRAM_OP_NOP			0x05
28#define SDRAM_OP_SETMODE		0x03
29
30#define SDRAM_PAD_CTRL_WR_EN		0x80000000
31#define SDRAM_PAD_CTRL_TUNE_EN		0x00010000
32#define SDRAM_PAD_CTRL_DRVN_MASK	0x0000003f
33#define SDRAM_PAD_CTRL_DRVP_MASK	0x00000fc0
34
35/*
36 * For Guideline MEM-3 - Drive Strength value
37 */
38
39#define DDR1_PAD_STRENGTH_DEFAULT	0x00001000
40#define SDRAM_PAD_CTRL_DRV_STR_MASK	0x00003000
41
42/*
43 * For Guideline MEM-4 - DQS Reference Delay Tuning
44 */
45
46#define MSAR_ARMDDRCLCK_MASK		0x000000f0
47#define MSAR_ARMDDRCLCK_H_MASK		0x00000100
48
49#define MSAR_ARMDDRCLCK_333_167		0x00000000
50#define MSAR_ARMDDRCLCK_500_167		0x00000030
51#define MSAR_ARMDDRCLCK_667_167		0x00000060
52#define MSAR_ARMDDRCLCK_400_200_1	0x000001E0
53#define MSAR_ARMDDRCLCK_400_200		0x00000010
54#define MSAR_ARMDDRCLCK_600_200		0x00000050
55#define MSAR_ARMDDRCLCK_800_200		0x00000070
56
57#define FTDLL_DDR1_166MHZ		0x0047F001
58
59#define FTDLL_DDR1_200MHZ		0x0044D001
60
61/*
62 * Low-level init happens right after start.S has switched to SVC32,
63 * flushed and disabled caches and disabled MMU. We're still running
64 * from the boot chip select, so the first thing SPL should do is to
65 * set up the RAM to copy U-Boot into.
66 */
67
68.globl lowlevel_init
69
70lowlevel_init:
71
72#ifdef CONFIG_SPL_BUILD
73
74	/* Use 'r4 as the base for internal register accesses */
75	ldr	r4, =ORION5X_REGS_PHY_BASE
76
77	/* move internal registers from the default 0xD0000000
78	 * to their intended location, defined by SoC */
79	ldr	r3, =0xD0000000
80	add	r3, r3, #0x20000
81	str	r4, [r3, #0x80]
82
83	/* Use R3 as the base for DRAM registers */
84	add	r3, r4, #0x01000
85
86	/*DDR SDRAM Initialization Control */
87	ldr	r6, =0x00000001
88	str	r6, [r3, #0x480]
89
90	/* Use R3 as the base for PCI registers */
91	add	r3, r4, #0x31000
92
93	/* Disable arbiter */
94	ldr	r6, =0x00000030
95	str	r6, [r3, #0xd00]
96
97	/* Use R3 as the base for DRAM registers */
98	add	r3, r4, #0x01000
99
100	/* set all dram windows to 0 */
101	mov	r6, #0
102	str	r6, [r3, #0x504]
103	str	r6, [r3, #0x50C]
104	str	r6, [r3, #0x514]
105	str	r6, [r3, #0x51C]
106
107	/* 1) Configure SDRAM  */
108	ldr	r6, =SDRAM_CONFIG
109	str	r6, [r3, #0x400]
110
111	/* 2) Set SDRAM Control reg */
112	ldr	r6, =SDRAM_CONTROL
113	str	r6, [r3, #0x404]
114
115	/* 3) Write SDRAM address control register */
116	ldr	r6, =SDRAM_ADDR_CTRL
117	str	r6, [r3, #0x410]
118
119	/* 4) Write SDRAM bank 0 size register */
120	ldr	r6, =SDRAM_BANK0_SIZE
121	str	r6, [r3, #0x504]
122	/* keep other banks disabled */
123
124	/* 5) Write SDRAM open pages control register */
125	ldr	r6, =SDRAM_OPEN_PAGE_EN
126	str	r6, [r3, #0x414]
127
128	/* 6) Write SDRAM timing Low register */
129	ldr	r6, =SDRAM_TIME_CTRL_LOW
130	str	r6, [r3, #0x408]
131
132	/* 7) Write SDRAM timing High register */
133	ldr	r6, =SDRAM_TIME_CTRL_HI
134	str	r6, [r3, #0x40C]
135
136	/* 8) Write SDRAM mode register */
137	/* The CPU must not attempt to change the SDRAM Mode register setting */
138	/* prior to DRAM controller completion of the DRAM initialization     */
139	/* sequence. To guarantee this restriction, it is recommended that    */
140	/* the CPU sets the SDRAM Operation register to NOP command, performs */
141	/* read polling until the register is back in Normal operation value, */
142	/* and then sets SDRAM Mode register to its new value.		      */
143
144	/* 8.1 write 'nop' to SDRAM operation */
145	ldr	r6, =SDRAM_OP_NOP
146	str	r6, [r3, #0x418]
147
148	/* 8.2 poll SDRAM operation until back in 'normal' mode.  */
1491:
150	ldr	r6, [r3, #0x418]
151	cmp	r6, #0
152	bne	1b
153
154	/* 8.3 Now its safe to write new value to SDRAM Mode register	      */
155	ldr	r6, =SDRAM_MODE
156	str	r6, [r3, #0x41C]
157
158	/* 8.4 Set new mode */
159	ldr	r6, =SDRAM_OP_SETMODE
160	str	r6, [r3, #0x418]
161
162	/* 8.5 poll SDRAM operation until back in 'normal' mode.  */
1632:
164	ldr	r6, [r3, #0x418]
165	cmp	r6, #0
166	bne	2b
167
168	/* DDR SDRAM Address/Control Pads Calibration */
169	ldr	r6, [r3, #0x4C0]
170
171	/* Set Bit [31] to make the register writable			*/
172	orr	r6, r6, #SDRAM_PAD_CTRL_WR_EN
173	str	r6, [r3, #0x4C0]
174
175	bic	r6, r6, #SDRAM_PAD_CTRL_WR_EN
176	bic	r6, r6, #SDRAM_PAD_CTRL_TUNE_EN
177	bic	r6, r6, #SDRAM_PAD_CTRL_DRVN_MASK
178	bic	r6, r6, #SDRAM_PAD_CTRL_DRVP_MASK
179
180	/* Get the final N locked value of driving strength [22:17]	*/
181	mov	r1, r6
182	mov	r1, r1, LSL #9
183	mov	r1, r1, LSR #26	 /* r1[5:0]<DrvN>  = r3[22:17]<LockN>	*/
184	orr	r1, r1, r1, LSL #6 /* r1[11:6]<DrvP> = r1[5:0]<DrvN>	*/
185
186	/* Write to both <DrvN> bits [5:0] and <DrvP> bits [11:6]	*/
187	orr	r6, r6, r1
188	str	r6, [r3, #0x4C0]
189
190	/* DDR SDRAM Data Pads Calibration				*/
191	ldr	r6, [r3, #0x4C4]
192
193	/* Set Bit [31] to make the register writable			*/
194	orr	r6, r6, #SDRAM_PAD_CTRL_WR_EN
195	str	r6, [r3, #0x4C4]
196
197	bic	r6, r6, #SDRAM_PAD_CTRL_WR_EN
198	bic	r6, r6, #SDRAM_PAD_CTRL_TUNE_EN
199	bic	r6, r6, #SDRAM_PAD_CTRL_DRVN_MASK
200	bic	r6, r6, #SDRAM_PAD_CTRL_DRVP_MASK
201
202	/* Get the final N locked value of driving strength [22:17]	*/
203	mov	r1, r6
204	mov	r1, r1, LSL #9
205	mov	r1, r1, LSR #26
206	orr	r1, r1, r1, LSL #6 /* r1[5:0] = r3[22:17]<LockN>	*/
207
208	/* Write to both <DrvN> bits [5:0] and <DrvP> bits [11:6]	*/
209	orr	r6, r6, r1
210
211	str	r6, [r3, #0x4C4]
212
213	/* Implement Guideline (GL# MEM-3) Drive Strength Value		*/
214	/* Relevant for: 88F5181-A1/B0/B1 and 88F5281-A0/B0		*/
215
216	ldr	r1, =DDR1_PAD_STRENGTH_DEFAULT
217
218	/* Enable writes to DDR SDRAM Addr/Ctrl Pads Calibration register */
219	ldr	r6, [r3, #0x4C0]
220	orr	r6, r6, #SDRAM_PAD_CTRL_WR_EN
221	str	r6, [r3, #0x4C0]
222
223	/* Correct strength and disable writes again */
224	bic	r6, r6, #SDRAM_PAD_CTRL_WR_EN
225	bic	r6, r6, #SDRAM_PAD_CTRL_DRV_STR_MASK
226	orr	r6, r6, r1
227	str	r6, [r3, #0x4C0]
228
229	/* Enable writes to DDR SDRAM Data Pads Calibration register */
230	ldr	r6, [r3, #0x4C4]
231	orr	r6, r6, #SDRAM_PAD_CTRL_WR_EN
232	str	r6, [r3, #0x4C4]
233
234	/* Correct strength and disable writes again */
235	bic	r6, r6, #SDRAM_PAD_CTRL_DRV_STR_MASK
236	bic	r6, r6, #SDRAM_PAD_CTRL_WR_EN
237	orr	r6, r6, r1
238	str	r6, [r3, #0x4C4]
239
240	/* Implement Guideline (GL# MEM-4) DQS Reference Delay Tuning	*/
241	/* Relevant for: 88F5181-A1/B0/B1 and 88F5281-A0/B0		*/
242
243	/* Get the "sample on reset" register for the DDR frequancy	*/
244	ldr	r3, =0x10000
245	ldr	r6, [r3, #0x010]
246	ldr	r1, =MSAR_ARMDDRCLCK_MASK
247	and	r1, r6, r1
248
249	ldr	r6, =FTDLL_DDR1_166MHZ
250	cmp	r1, #MSAR_ARMDDRCLCK_333_167
251	beq	3f
252	cmp	r1, #MSAR_ARMDDRCLCK_500_167
253	beq	3f
254	cmp	r1, #MSAR_ARMDDRCLCK_667_167
255	beq	3f
256
257	ldr	r6, =FTDLL_DDR1_200MHZ
258	cmp	r1, #MSAR_ARMDDRCLCK_400_200_1
259	beq	3f
260	cmp	r1, #MSAR_ARMDDRCLCK_400_200
261	beq	3f
262	cmp	r1, #MSAR_ARMDDRCLCK_600_200
263	beq	3f
264	cmp	r1, #MSAR_ARMDDRCLCK_800_200
265	beq	3f
266
267	ldr	r6, =0
268
2693:
270	/* Use R3 as the base for DRAM registers */
271	add	r3, r4, #0x01000
272
273	ldr	r2, [r3, #0x484]
274	orr	r2, r2, r6
275	str	r2, [r3, #0x484]
276
277	/* enable for 2 GB DDR; detection should find out real amount */
278	sub	r6, r6, r6
279	str	r6, [r3, #0x500]
280	ldr	r6, =0x7fff0001
281	str	r6, [r3, #0x504]
282
283#endif /* CONFIG_SPL_BUILD */
284
285	/* Return to U-Boot via saved link register */
286	mov	pc, lr
287