blob: f8b837ed286385c8445a9aec6b9b7430d9d4c6a6 [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 Roese42fbddd2006-09-07 11:51:23 +0200374/*************************************************************************
375 *
376 * initdram -- 440EPx's DDR controller is a DENALI Core
377 *
378 ************************************************************************/
379long int initdram (int board_type)
380{
381#if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)
Stefan Roese50b6c4e2007-03-06 07:47:04 +0100382 ulong speed = get_bus_freq(0);
383
Stefan Roese42fbddd2006-09-07 11:51:23 +0200384 mtsdram(DDR0_02, 0x00000000);
385
Stefan Roese42fbddd2006-09-07 11:51:23 +0200386 mtsdram(DDR0_00, 0x0000190A);
387 mtsdram(DDR0_01, 0x01000000);
388 mtsdram(DDR0_03, 0x02030602);
Stefan Roese50b6c4e2007-03-06 07:47:04 +0100389 mtsdram(DDR0_04, 0x0A020200);
390 mtsdram(DDR0_05, 0x02020308);
391 mtsdram(DDR0_06, 0x0102C812);
Stefan Roese42fbddd2006-09-07 11:51:23 +0200392 mtsdram(DDR0_07, 0x000D0100);
Stefan Roese50b6c4e2007-03-06 07:47:04 +0100393 mtsdram(DDR0_08, 0x02430001);
Stefan Roese42fbddd2006-09-07 11:51:23 +0200394 mtsdram(DDR0_09, 0x00011D5F);
395 mtsdram(DDR0_10, 0x00000300);
396 mtsdram(DDR0_11, 0x0027C800);
397 mtsdram(DDR0_12, 0x00000003);
398 mtsdram(DDR0_14, 0x00000000);
399 mtsdram(DDR0_17, 0x19000000);
400 mtsdram(DDR0_18, 0x19191919);
401 mtsdram(DDR0_19, 0x19191919);
402 mtsdram(DDR0_20, 0x0B0B0B0B);
403 mtsdram(DDR0_21, 0x0B0B0B0B);
404 mtsdram(DDR0_22, 0x00267F0B);
405 mtsdram(DDR0_23, 0x00000000);
406 mtsdram(DDR0_24, 0x01010002);
Stefan Roese50b6c4e2007-03-06 07:47:04 +0100407 if (speed > 133333333)
408 mtsdram(DDR0_26, 0x5B26050C);
409 else
410 mtsdram(DDR0_26, 0x5B260408);
Stefan Roese42fbddd2006-09-07 11:51:23 +0200411 mtsdram(DDR0_27, 0x0000682B);
412 mtsdram(DDR0_28, 0x00000000);
413 mtsdram(DDR0_31, 0x00000000);
414 mtsdram(DDR0_42, 0x01000006);
Stefan Roese50b6c4e2007-03-06 07:47:04 +0100415 mtsdram(DDR0_43, 0x030A0200);
416 mtsdram(DDR0_44, 0x00000003);
Stefan Roese42fbddd2006-09-07 11:51:23 +0200417 mtsdram(DDR0_02, 0x00000001);
418
Stefan Roese5684da02007-01-05 10:38:05 +0100419 wait_for_dlllock();
Stefan Roese42fbddd2006-09-07 11:51:23 +0200420#endif /* #ifndef CONFIG_NAND_U_BOOT */
421
Stefan Roese5684da02007-01-05 10:38:05 +0100422#ifdef CONFIG_DDR_DATA_EYE
423 /* -----------------------------------------------------------+
424 * Perform data eye search if requested.
425 * ----------------------------------------------------------*/
426 denali_core_search_data_eye(CFG_MBYTES_SDRAM << 20);
427#endif
428
Stefan Roese42fbddd2006-09-07 11:51:23 +0200429 return (CFG_MBYTES_SDRAM << 20);
430}