blob: d045df1872cf085424500f636d5953c4a0a40b45 [file] [log] [blame]
Stefan Roese42fbddd2006-09-07 11:51:23 +02001/*
2 * (C) Copyright 2006
Stefan Roese5684da02007-01-05 10:38:05 +01003 * Sylvie Gohl, AMCC/IBM, gohl.sylvie@fr.ibm.com
4 * Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com
5 * Thierry Roman, AMCC/IBM, thierry_roman@fr.ibm.com
6 * Alain Saurel, AMCC/IBM, alain.saurel@fr.ibm.com
7 * Robert Snyder, AMCC/IBM, rob.snyder@fr.ibm.com
8 *
Stefan Roese50b6c4e2007-03-06 07:47:04 +01009 * (C) Copyright 2006-2007
Stefan Roese42fbddd2006-09-07 11:51:23 +020010 * Stefan Roese, DENX Software Engineering, sr@denx.de.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 * MA 02111-1307 USA
26 */
27
Stefan Roese5684da02007-01-05 10:38:05 +010028/* define DEBUG for debug output */
29#undef DEBUG
30
Stefan Roese42fbddd2006-09-07 11:51:23 +020031#include <common.h>
32#include <asm/processor.h>
Stefan Roese5684da02007-01-05 10:38:05 +010033#include <asm/io.h>
Stefan Roese42fbddd2006-09-07 11:51:23 +020034#include <ppc440.h>
35
Stefan Roese5684da02007-01-05 10:38:05 +010036#include "sdram.h"
37
38#if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) || \
39 defined(CONFIG_DDR_DATA_EYE)
40/*-----------------------------------------------------------------------------+
41 * wait_for_dlllock.
42 +----------------------------------------------------------------------------*/
43static int wait_for_dlllock(void)
44{
45 unsigned long val;
46 int wait = 0;
47
48 /* -----------------------------------------------------------+
49 * Wait for the DCC master delay line to finish calibration
50 * ----------------------------------------------------------*/
51 mtdcr(ddrcfga, DDR0_17);
52 val = DDR0_17_DLLLOCKREG_UNLOCKED;
53
54 while (wait != 0xffff) {
55 val = mfdcr(ddrcfgd);
56 if ((val & DDR0_17_DLLLOCKREG_MASK) == DDR0_17_DLLLOCKREG_LOCKED)
57 /* dlllockreg bit on */
58 return 0;
59 else
60 wait++;
61 }
62 debug("0x%04x: DDR0_17 Value (dlllockreg bit): 0x%08x\n", wait, val);
63 debug("Waiting for dlllockreg bit to raise\n");
64
65 return -1;
66}
67#endif
68
69#if defined(CONFIG_DDR_DATA_EYE)
70/*-----------------------------------------------------------------------------+
71 * wait_for_dram_init_complete.
72 +----------------------------------------------------------------------------*/
73int wait_for_dram_init_complete(void)
74{
75 unsigned long val;
76 int wait = 0;
77
78 /* --------------------------------------------------------------+
79 * Wait for 'DRAM initialization complete' bit in status register
80 * -------------------------------------------------------------*/
81 mtdcr(ddrcfga, DDR0_00);
82
83 while (wait != 0xffff) {
84 val = mfdcr(ddrcfgd);
85 if ((val & DDR0_00_INT_STATUS_BIT6) == DDR0_00_INT_STATUS_BIT6)
86 /* 'DRAM initialization complete' bit */
87 return 0;
88 else
89 wait++;
90 }
91
92 debug("DRAM initialization complete bit in status register did not rise\n");
93
94 return -1;
95}
96
97#define NUM_TRIES 64
98#define NUM_READS 10
99
100/*-----------------------------------------------------------------------------+
101 * denali_core_search_data_eye.
102 +----------------------------------------------------------------------------*/
103void denali_core_search_data_eye(unsigned long memory_size)
104{
105 int k, j;
106 u32 val;
107 u32 wr_dqs_shift, dqs_out_shift, dll_dqs_delay_X;
108 u32 max_passing_cases = 0, wr_dqs_shift_with_max_passing_cases = 0;
109 u32 passing_cases = 0, dll_dqs_delay_X_sw_val = 0;
110 u32 dll_dqs_delay_X_start_window = 0, dll_dqs_delay_X_end_window = 0;
111 volatile u32 *ram_pointer;
112 u32 test[NUM_TRIES] = {
113 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
114 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
115 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
116 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
117 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
118 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
119 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
120 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
121 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
122 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
123 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
124 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
125 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
126 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
127 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
128 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 };
129
130 ram_pointer = (volatile u32 *)(CFG_SDRAM_BASE);
131
132 for (wr_dqs_shift = 64; wr_dqs_shift < 96; wr_dqs_shift++) {
133 /*for (wr_dqs_shift=1; wr_dqs_shift<96; wr_dqs_shift++) {*/
134
135 /* -----------------------------------------------------------+
136 * De-assert 'start' parameter.
137 * ----------------------------------------------------------*/
138 mtdcr(ddrcfga, DDR0_02);
139 val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF;
140 mtdcr(ddrcfgd, val);
141
142 /* -----------------------------------------------------------+
143 * Set 'wr_dqs_shift'
144 * ----------------------------------------------------------*/
145 mtdcr(ddrcfga, DDR0_09);
146 val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK)
147 | DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
148 mtdcr(ddrcfgd, val);
149
150 /* -----------------------------------------------------------+
151 * Set 'dqs_out_shift' = wr_dqs_shift + 32
152 * ----------------------------------------------------------*/
153 dqs_out_shift = wr_dqs_shift + 32;
154 mtdcr(ddrcfga, DDR0_22);
155 val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK)
156 | DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
157 mtdcr(ddrcfgd, val);
158
159 passing_cases = 0;
160
161 for (dll_dqs_delay_X = 1; dll_dqs_delay_X < 64; dll_dqs_delay_X++) {
162 /*for (dll_dqs_delay_X=1; dll_dqs_delay_X<128; dll_dqs_delay_X++) {*/
163 /* -----------------------------------------------------------+
164 * Set 'dll_dqs_delay_X'.
165 * ----------------------------------------------------------*/
166 /* dll_dqs_delay_0 */
167 mtdcr(ddrcfga, DDR0_17);
168 val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
169 | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
170 mtdcr(ddrcfgd, val);
171 /* dll_dqs_delay_1 to dll_dqs_delay_4 */
172 mtdcr(ddrcfga, DDR0_18);
173 val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
174 | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
175 | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
176 | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
177 | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
178 mtdcr(ddrcfgd, val);
179 /* dll_dqs_delay_5 to dll_dqs_delay_8 */
180 mtdcr(ddrcfga, DDR0_19);
181 val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
182 | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
183 | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
184 | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
185 | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
186 mtdcr(ddrcfgd, val);
187
188 ppcMsync();
189 ppcMbar();
190
191 /* -----------------------------------------------------------+
192 * Assert 'start' parameter.
193 * ----------------------------------------------------------*/
194 mtdcr(ddrcfga, DDR0_02);
195 val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_ON;
196 mtdcr(ddrcfgd, val);
197
198 ppcMsync();
199 ppcMbar();
200
201 /* -----------------------------------------------------------+
202 * Wait for the DCC master delay line to finish calibration
203 * ----------------------------------------------------------*/
204 if (wait_for_dlllock() != 0) {
205 printf("dlllock did not occur !!!\n");
206 printf("denali_core_search_data_eye!!!\n");
207 printf("wr_dqs_shift = %d - dll_dqs_delay_X = %d\n",
208 wr_dqs_shift, dll_dqs_delay_X);
209 hang();
210 }
211 ppcMsync();
212 ppcMbar();
213
214 if (wait_for_dram_init_complete() != 0) {
215 printf("dram init complete did not occur !!!\n");
216 printf("denali_core_search_data_eye!!!\n");
217 printf("wr_dqs_shift = %d - dll_dqs_delay_X = %d\n",
218 wr_dqs_shift, dll_dqs_delay_X);
219 hang();
220 }
221 udelay(100); /* wait 100us to ensure init is really completed !!! */
222
223 /* write values */
224 for (j=0; j<NUM_TRIES; j++) {
225 ram_pointer[j] = test[j];
226
227 /* clear any cache at ram location */
228 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
229 }
230
231 /* read values back */
232 for (j=0; j<NUM_TRIES; j++) {
233 for (k=0; k<NUM_READS; k++) {
234 /* clear any cache at ram location */
235 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
236
237 if (ram_pointer[j] != test[j])
238 break;
239 }
240
241 /* read error */
242 if (k != NUM_READS)
243 break;
244 }
245
246 /* See if the dll_dqs_delay_X value passed.*/
247 if (j < NUM_TRIES) {
248 /* Failed */
249 passing_cases = 0;
250 /* break; */
251 } else {
252 /* Passed */
253 if (passing_cases == 0)
254 dll_dqs_delay_X_sw_val = dll_dqs_delay_X;
255 passing_cases++;
256 if (passing_cases >= max_passing_cases) {
257 max_passing_cases = passing_cases;
258 wr_dqs_shift_with_max_passing_cases = wr_dqs_shift;
259 dll_dqs_delay_X_start_window = dll_dqs_delay_X_sw_val;
260 dll_dqs_delay_X_end_window = dll_dqs_delay_X;
261 }
262 }
263
264 /* -----------------------------------------------------------+
265 * De-assert 'start' parameter.
266 * ----------------------------------------------------------*/
267 mtdcr(ddrcfga, DDR0_02);
268 val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF;
269 mtdcr(ddrcfgd, val);
270
271 } /* for (dll_dqs_delay_X=0; dll_dqs_delay_X<128; dll_dqs_delay_X++) */
272
273 } /* for (wr_dqs_shift=0; wr_dqs_shift<96; wr_dqs_shift++) */
274
275 /* -----------------------------------------------------------+
276 * Largest passing window is now detected.
277 * ----------------------------------------------------------*/
278
279 /* Compute dll_dqs_delay_X value */
280 dll_dqs_delay_X = (dll_dqs_delay_X_end_window + dll_dqs_delay_X_start_window) / 2;
281 wr_dqs_shift = wr_dqs_shift_with_max_passing_cases;
282
283 debug("DQS calibration - Window detected:\n");
284 debug("max_passing_cases = %d\n", max_passing_cases);
285 debug("wr_dqs_shift = %d\n", wr_dqs_shift);
286 debug("dll_dqs_delay_X = %d\n", dll_dqs_delay_X);
287 debug("dll_dqs_delay_X window = %d - %d\n",
288 dll_dqs_delay_X_start_window, dll_dqs_delay_X_end_window);
289
290 /* -----------------------------------------------------------+
291 * De-assert 'start' parameter.
292 * ----------------------------------------------------------*/
293 mtdcr(ddrcfga, DDR0_02);
294 val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF;
295 mtdcr(ddrcfgd, val);
296
297 /* -----------------------------------------------------------+
298 * Set 'wr_dqs_shift'
299 * ----------------------------------------------------------*/
300 mtdcr(ddrcfga, DDR0_09);
301 val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK)
302 | DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
303 mtdcr(ddrcfgd, val);
304 debug("DDR0_09=0x%08lx\n", val);
305
306 /* -----------------------------------------------------------+
307 * Set 'dqs_out_shift' = wr_dqs_shift + 32
308 * ----------------------------------------------------------*/
309 dqs_out_shift = wr_dqs_shift + 32;
310 mtdcr(ddrcfga, DDR0_22);
311 val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK)
312 | DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
313 mtdcr(ddrcfgd, val);
314 debug("DDR0_22=0x%08lx\n", val);
315
316 /* -----------------------------------------------------------+
317 * Set 'dll_dqs_delay_X'.
318 * ----------------------------------------------------------*/
319 /* dll_dqs_delay_0 */
320 mtdcr(ddrcfga, DDR0_17);
321 val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
322 | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
323 mtdcr(ddrcfgd, val);
324 debug("DDR0_17=0x%08lx\n", val);
325
326 /* dll_dqs_delay_1 to dll_dqs_delay_4 */
327 mtdcr(ddrcfga, DDR0_18);
328 val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
329 | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
330 | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
331 | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
332 | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
333 mtdcr(ddrcfgd, val);
334 debug("DDR0_18=0x%08lx\n", val);
335
336 /* dll_dqs_delay_5 to dll_dqs_delay_8 */
337 mtdcr(ddrcfga, DDR0_19);
338 val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
339 | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
340 | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
341 | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
342 | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
343 mtdcr(ddrcfgd, val);
344 debug("DDR0_19=0x%08lx\n", val);
345
346 /* -----------------------------------------------------------+
347 * Assert 'start' parameter.
348 * ----------------------------------------------------------*/
349 mtdcr(ddrcfga, DDR0_02);
350 val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_ON;
351 mtdcr(ddrcfgd, val);
352
353 ppcMsync();
354 ppcMbar();
355
356 /* -----------------------------------------------------------+
357 * Wait for the DCC master delay line to finish calibration
358 * ----------------------------------------------------------*/
359 if (wait_for_dlllock() != 0) {
360 printf("dlllock did not occur !!!\n");
361 hang();
362 }
363 ppcMsync();
364 ppcMbar();
365
366 if (wait_for_dram_init_complete() != 0) {
367 printf("dram init complete did not occur !!!\n");
368 hang();
369 }
370 udelay(100); /* wait 100us to ensure init is really completed !!! */
371}
372#endif /* CONFIG_DDR_DATA_EYE */
373
Stefan Roese10d7d6e2007-05-05 08:29:01 +0200374#if defined(CONFIG_NAND_SPL)
375/* Using cpu/ppc4xx/speed.c to calculate the bus frequency is too big
376 * for the 4k NAND boot image so define bus_frequency to 133MHz here
377 * which is save for the refresh counter setup.
378 */
379#define get_bus_freq(val) 133000000
380#endif
381
Stefan Roese42fbddd2006-09-07 11:51:23 +0200382/*************************************************************************
383 *
384 * initdram -- 440EPx's DDR controller is a DENALI Core
385 *
386 ************************************************************************/
387long int initdram (int board_type)
388{
389#if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)
Stefan Roese50b6c4e2007-03-06 07:47:04 +0100390 ulong speed = get_bus_freq(0);
391
Stefan Roese42fbddd2006-09-07 11:51:23 +0200392 mtsdram(DDR0_02, 0x00000000);
393
Stefan Roese42fbddd2006-09-07 11:51:23 +0200394 mtsdram(DDR0_00, 0x0000190A);
395 mtsdram(DDR0_01, 0x01000000);
396 mtsdram(DDR0_03, 0x02030602);
Stefan Roese50b6c4e2007-03-06 07:47:04 +0100397 mtsdram(DDR0_04, 0x0A020200);
398 mtsdram(DDR0_05, 0x02020308);
399 mtsdram(DDR0_06, 0x0102C812);
Stefan Roese42fbddd2006-09-07 11:51:23 +0200400 mtsdram(DDR0_07, 0x000D0100);
Stefan Roese50b6c4e2007-03-06 07:47:04 +0100401 mtsdram(DDR0_08, 0x02430001);
Stefan Roese42fbddd2006-09-07 11:51:23 +0200402 mtsdram(DDR0_09, 0x00011D5F);
403 mtsdram(DDR0_10, 0x00000300);
404 mtsdram(DDR0_11, 0x0027C800);
405 mtsdram(DDR0_12, 0x00000003);
406 mtsdram(DDR0_14, 0x00000000);
407 mtsdram(DDR0_17, 0x19000000);
408 mtsdram(DDR0_18, 0x19191919);
409 mtsdram(DDR0_19, 0x19191919);
410 mtsdram(DDR0_20, 0x0B0B0B0B);
411 mtsdram(DDR0_21, 0x0B0B0B0B);
412 mtsdram(DDR0_22, 0x00267F0B);
413 mtsdram(DDR0_23, 0x00000000);
414 mtsdram(DDR0_24, 0x01010002);
Stefan Roese10d7d6e2007-05-05 08:29:01 +0200415 if (speed > 133333334)
Stefan Roese50b6c4e2007-03-06 07:47:04 +0100416 mtsdram(DDR0_26, 0x5B26050C);
417 else
418 mtsdram(DDR0_26, 0x5B260408);
Stefan Roese42fbddd2006-09-07 11:51:23 +0200419 mtsdram(DDR0_27, 0x0000682B);
420 mtsdram(DDR0_28, 0x00000000);
421 mtsdram(DDR0_31, 0x00000000);
422 mtsdram(DDR0_42, 0x01000006);
Stefan Roese50b6c4e2007-03-06 07:47:04 +0100423 mtsdram(DDR0_43, 0x030A0200);
424 mtsdram(DDR0_44, 0x00000003);
Stefan Roese42fbddd2006-09-07 11:51:23 +0200425 mtsdram(DDR0_02, 0x00000001);
426
Stefan Roese5684da02007-01-05 10:38:05 +0100427 wait_for_dlllock();
Stefan Roese42fbddd2006-09-07 11:51:23 +0200428#endif /* #ifndef CONFIG_NAND_U_BOOT */
429
Stefan Roese5684da02007-01-05 10:38:05 +0100430#ifdef CONFIG_DDR_DATA_EYE
431 /* -----------------------------------------------------------+
432 * Perform data eye search if requested.
433 * ----------------------------------------------------------*/
434 denali_core_search_data_eye(CFG_MBYTES_SDRAM << 20);
435#endif
436
Stefan Roese42fbddd2006-09-07 11:51:23 +0200437 return (CFG_MBYTES_SDRAM << 20);
438}