]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/ppc4xx/denali_data_eye.c
Move arch/ppc to arch/powerpc
[karo-tx-uboot.git] / arch / powerpc / cpu / ppc4xx / denali_data_eye.c
1 /*
2  * arch/powerpc/cpu/ppc4xx/denali_data_eye.c
3  * Extracted from board/amcc/sequoia/sdram.c by Larry Johnson <lrj@acm.org>.
4  *
5  * (C) Copyright 2006
6  * Sylvie Gohl,             AMCC/IBM, gohl.sylvie@fr.ibm.com
7  * Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com
8  * Thierry Roman,           AMCC/IBM, thierry_roman@fr.ibm.com
9  * Alain Saurel,            AMCC/IBM, alain.saurel@fr.ibm.com
10  * Robert Snyder,           AMCC/IBM, rob.snyder@fr.ibm.com
11  *
12  * (C) Copyright 2006-2007
13  * Stefan Roese, DENX Software Engineering, sr@denx.de.
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License as
17  * published by the Free Software Foundation; either version 2 of
18  * the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28  * MA 02111-1307 USA
29  */
30
31 /* define DEBUG for debugging output (obviously ;-)) */
32 #if 0
33 #define DEBUG
34 #endif
35
36 #include <common.h>
37 #include <asm/processor.h>
38 #include <asm/io.h>
39 #include <ppc4xx.h>
40
41 #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
42 /*-----------------------------------------------------------------------------+
43  * denali_wait_for_dlllock.
44  +----------------------------------------------------------------------------*/
45 int denali_wait_for_dlllock(void)
46 {
47         u32 val;
48         int wait;
49
50         /* -----------------------------------------------------------+
51          * Wait for the DCC master delay line to finish calibration
52          * ----------------------------------------------------------*/
53         for (wait = 0; wait != 0xffff; ++wait) {
54                 mfsdram(DDR0_17, val);
55                 if (DDR0_17_DLLLOCKREG_DECODE(val)) {
56                         /* dlllockreg bit on */
57                         return 0;
58                 }
59         }
60         debug("0x%04x: DDR0_17 Value (dlllockreg bit): 0x%08x\n", wait, val);
61         debug("Waiting for dlllockreg bit to raise\n");
62         return -1;
63 }
64
65 #if defined(CONFIG_DDR_DATA_EYE)
66 #define DDR_DCR_BASE 0x10
67 #define ddrcfga  (DDR_DCR_BASE+0x0)     /* DDR configuration address reg */
68 #define ddrcfgd  (DDR_DCR_BASE+0x1)     /* DDR configuration data reg    */
69
70 /*-----------------------------------------------------------------------------+
71  * wait_for_dram_init_complete.
72  +----------------------------------------------------------------------------*/
73 static int 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         debug("DRAM initialization complete bit in status register did not "
92               "rise\n");
93         return -1;
94 }
95
96 #define NUM_TRIES 64
97 #define NUM_READS 10
98
99 /*-----------------------------------------------------------------------------+
100  * denali_core_search_data_eye.
101  +----------------------------------------------------------------------------*/
102 void denali_core_search_data_eye(void)
103 {
104         int k, j;
105         u32 val;
106         u32 wr_dqs_shift, dqs_out_shift, dll_dqs_delay_X;
107         u32 max_passing_cases = 0, wr_dqs_shift_with_max_passing_cases = 0;
108         u32 passing_cases = 0, dll_dqs_delay_X_sw_val = 0;
109         u32 dll_dqs_delay_X_start_window = 0, dll_dqs_delay_X_end_window = 0;
110         volatile u32 *ram_pointer;
111         u32 test[NUM_TRIES] = {
112                 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
113                 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
114                 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
115                 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
116                 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
117                 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
118                 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
119                 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
120                 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
121                 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
122                 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
123                 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
124                 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
125                 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
126                 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
127                 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55
128         };
129
130         ram_pointer = (volatile u32 *)(CONFIG_SYS_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) |
140                     DDR0_02_START_OFF;
141                 mtdcr(ddrcfgd, val);
142
143                 /* -----------------------------------------------------------+
144                  * Set 'wr_dqs_shift'
145                  * ----------------------------------------------------------*/
146                 mtdcr(ddrcfga, DDR0_09);
147                 val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK) |
148                     DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
149                 mtdcr(ddrcfgd, val);
150
151                 /* -----------------------------------------------------------+
152                  * Set 'dqs_out_shift' = wr_dqs_shift + 32
153                  * ----------------------------------------------------------*/
154                 dqs_out_shift = wr_dqs_shift + 32;
155                 mtdcr(ddrcfga, DDR0_22);
156                 val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK) |
157                     DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
158                 mtdcr(ddrcfgd, val);
159
160                 passing_cases = 0;
161
162                 for (dll_dqs_delay_X = 1; dll_dqs_delay_X < 64;
163                      dll_dqs_delay_X++) {
164                         /* for (dll_dqs_delay_X=1; dll_dqs_delay_X<128;
165                            dll_dqs_delay_X++) { */
166                         /* -----------------------------------------------------------+
167                          * Set 'dll_dqs_delay_X'.
168                          * ----------------------------------------------------------*/
169                         /* dll_dqs_delay_0 */
170                         mtdcr(ddrcfga, DDR0_17);
171                         val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
172                             | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
173                         mtdcr(ddrcfgd, val);
174                         /* dll_dqs_delay_1 to dll_dqs_delay_4 */
175                         mtdcr(ddrcfga, DDR0_18);
176                         val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
177                             | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
178                             | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
179                             | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
180                             | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
181                         mtdcr(ddrcfgd, val);
182                         /* dll_dqs_delay_5 to dll_dqs_delay_8 */
183                         mtdcr(ddrcfga, DDR0_19);
184                         val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
185                             | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
186                             | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
187                             | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
188                             | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
189                         mtdcr(ddrcfgd, val);
190                         /* clear any ECC errors */
191                         mtdcr(ddrcfga, DDR0_00);
192                         mtdcr(ddrcfgd,
193                               mfdcr(ddrcfgd) | DDR0_00_INT_ACK_ENCODE(0x3C));
194
195                         sync();
196                         eieio();
197
198                         /* -----------------------------------------------------------+
199                          * Assert 'start' parameter.
200                          * ----------------------------------------------------------*/
201                         mtdcr(ddrcfga, DDR0_02);
202                         val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
203                             DDR0_02_START_ON;
204                         mtdcr(ddrcfgd, val);
205
206                         sync();
207                         eieio();
208
209                         /* -----------------------------------------------------------+
210                          * Wait for the DCC master delay line to finish calibration
211                          * ----------------------------------------------------------*/
212                         if (denali_wait_for_dlllock() != 0) {
213                                 printf("dll lock did not occur !!!\n");
214                                 printf("denali_core_search_data_eye!!!\n");
215                                 printf("wr_dqs_shift = %d - dll_dqs_delay_X = "
216                                        "%d\n", wr_dqs_shift, dll_dqs_delay_X);
217                                 hang();
218                         }
219                         sync();
220                         eieio();
221
222                         if (wait_for_dram_init_complete() != 0) {
223                                 printf("dram init complete did not occur!!!\n");
224                                 printf("denali_core_search_data_eye!!!\n");
225                                 printf("wr_dqs_shift = %d - dll_dqs_delay_X = "
226                                        "%d\n", wr_dqs_shift, dll_dqs_delay_X);
227                                 hang();
228                         }
229                         udelay(100); /* wait 100us to ensure init is really completed !!! */
230
231                         /* write values */
232                         for (j = 0; j < NUM_TRIES; j++) {
233                                 ram_pointer[j] = test[j];
234
235                                 /* clear any cache at ram location */
236                               __asm__("dcbf 0,%0": :"r"(&ram_pointer[j]));
237                         }
238
239                         /* read values back */
240                         for (j = 0; j < NUM_TRIES; j++) {
241                                 for (k = 0; k < NUM_READS; k++) {
242                                         /* clear any cache at ram location */
243                                       __asm__("dcbf 0,%0": :"r"(&ram_pointer
244                                             [j]));
245
246                                         if (ram_pointer[j] != test[j])
247                                                 break;
248                                 }
249
250                                 /* read error */
251                                 if (k != NUM_READS)
252                                         break;
253                         }
254
255                         /* See if the dll_dqs_delay_X value passed. */
256                         mtdcr(ddrcfga, DDR0_00);
257                         if (j < NUM_TRIES
258                             || (DDR0_00_INT_STATUS_DECODE(mfdcr(ddrcfgd)) &
259                                 0x3F)) {
260                                 /* Failed */
261                                 passing_cases = 0;
262                                 /* break; */
263                         } else {
264                                 /* Passed */
265                                 if (passing_cases == 0)
266                                         dll_dqs_delay_X_sw_val =
267                                             dll_dqs_delay_X;
268                                 passing_cases++;
269                                 if (passing_cases >= max_passing_cases) {
270                                         max_passing_cases = passing_cases;
271                                         wr_dqs_shift_with_max_passing_cases =
272                                             wr_dqs_shift;
273                                         dll_dqs_delay_X_start_window =
274                                             dll_dqs_delay_X_sw_val;
275                                         dll_dqs_delay_X_end_window =
276                                             dll_dqs_delay_X;
277                                 }
278                         }
279
280                         /* -----------------------------------------------------------+
281                          * De-assert 'start' parameter.
282                          * ----------------------------------------------------------*/
283                         mtdcr(ddrcfga, DDR0_02);
284                         val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
285                             DDR0_02_START_OFF;
286                         mtdcr(ddrcfgd, val);
287                 } /* for (dll_dqs_delay_X=0; dll_dqs_delay_X<128; dll_dqs_delay_X++) */
288         } /* for (wr_dqs_shift=0; wr_dqs_shift<96; wr_dqs_shift++) */
289
290         /* -----------------------------------------------------------+
291          * Largest passing window is now detected.
292          * ----------------------------------------------------------*/
293
294         /* Compute dll_dqs_delay_X value */
295         dll_dqs_delay_X = (dll_dqs_delay_X_end_window +
296                            dll_dqs_delay_X_start_window) / 2;
297         wr_dqs_shift = wr_dqs_shift_with_max_passing_cases;
298
299         debug("DQS calibration - Window detected:\n");
300         debug("max_passing_cases = %d\n", max_passing_cases);
301         debug("wr_dqs_shift      = %d\n", wr_dqs_shift);
302         debug("dll_dqs_delay_X   = %d\n", dll_dqs_delay_X);
303         debug("dll_dqs_delay_X window = %d - %d\n",
304               dll_dqs_delay_X_start_window, dll_dqs_delay_X_end_window);
305
306         /* -----------------------------------------------------------+
307          * De-assert 'start' parameter.
308          * ----------------------------------------------------------*/
309         mtdcr(ddrcfga, DDR0_02);
310         val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF;
311         mtdcr(ddrcfgd, val);
312
313         /* -----------------------------------------------------------+
314          * Set 'wr_dqs_shift'
315          * ----------------------------------------------------------*/
316         mtdcr(ddrcfga, DDR0_09);
317         val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK)
318             | DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
319         mtdcr(ddrcfgd, val);
320         debug("DDR0_09=0x%08lx\n", val);
321
322         /* -----------------------------------------------------------+
323          * Set 'dqs_out_shift' = wr_dqs_shift + 32
324          * ----------------------------------------------------------*/
325         dqs_out_shift = wr_dqs_shift + 32;
326         mtdcr(ddrcfga, DDR0_22);
327         val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK)
328             | DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
329         mtdcr(ddrcfgd, val);
330         debug("DDR0_22=0x%08lx\n", val);
331
332         /* -----------------------------------------------------------+
333          * Set 'dll_dqs_delay_X'.
334          * ----------------------------------------------------------*/
335         /* dll_dqs_delay_0 */
336         mtdcr(ddrcfga, DDR0_17);
337         val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
338             | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
339         mtdcr(ddrcfgd, val);
340         debug("DDR0_17=0x%08lx\n", val);
341
342         /* dll_dqs_delay_1 to dll_dqs_delay_4 */
343         mtdcr(ddrcfga, DDR0_18);
344         val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
345             | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
346             | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
347             | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
348             | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
349         mtdcr(ddrcfgd, val);
350         debug("DDR0_18=0x%08lx\n", val);
351
352         /* dll_dqs_delay_5 to dll_dqs_delay_8 */
353         mtdcr(ddrcfga, DDR0_19);
354         val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
355             | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
356             | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
357             | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
358             | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
359         mtdcr(ddrcfgd, val);
360         debug("DDR0_19=0x%08lx\n", val);
361
362         /* -----------------------------------------------------------+
363          * Assert 'start' parameter.
364          * ----------------------------------------------------------*/
365         mtdcr(ddrcfga, DDR0_02);
366         val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_ON;
367         mtdcr(ddrcfgd, val);
368
369         sync();
370         eieio();
371
372         /* -----------------------------------------------------------+
373          * Wait for the DCC master delay line to finish calibration
374          * ----------------------------------------------------------*/
375         if (denali_wait_for_dlllock() != 0) {
376                 printf("dll lock did not occur !!!\n");
377                 hang();
378         }
379         sync();
380         eieio();
381
382         if (wait_for_dram_init_complete() != 0) {
383                 printf("dram init complete did not occur !!!\n");
384                 hang();
385         }
386         udelay(100); /* wait 100us to ensure init is really completed !!! */
387 }
388 #endif /* defined(CONFIG_DDR_DATA_EYE) */
389 #endif /* defined(CONFIG_440EPX) || defined(CONFIG_440GRX) */