]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/ppc4xx/denali_data_eye.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[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  * SPDX-License-Identifier:     GPL-2.0+
16  */
17
18 /* define DEBUG for debugging output (obviously ;-)) */
19 #if 0
20 #define DEBUG
21 #endif
22
23 #include <common.h>
24 #include <asm/processor.h>
25 #include <asm/io.h>
26 #include <asm/ppc4xx.h>
27
28 #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
29 /*-----------------------------------------------------------------------------+
30  * denali_wait_for_dlllock.
31  +----------------------------------------------------------------------------*/
32 int denali_wait_for_dlllock(void)
33 {
34         u32 val;
35         int wait;
36
37         /* -----------------------------------------------------------+
38          * Wait for the DCC master delay line to finish calibration
39          * ----------------------------------------------------------*/
40         for (wait = 0; wait != 0xffff; ++wait) {
41                 mfsdram(DDR0_17, val);
42                 if (DDR0_17_DLLLOCKREG_DECODE(val)) {
43                         /* dlllockreg bit on */
44                         return 0;
45                 }
46         }
47         debug("0x%04x: DDR0_17 Value (dlllockreg bit): 0x%08x\n", wait, val);
48         debug("Waiting for dlllockreg bit to raise\n");
49         return -1;
50 }
51
52 #if defined(CONFIG_DDR_DATA_EYE)
53 #define DDR_DCR_BASE 0x10
54 #define ddrcfga  (DDR_DCR_BASE+0x0)     /* DDR configuration address reg */
55 #define ddrcfgd  (DDR_DCR_BASE+0x1)     /* DDR configuration data reg    */
56
57 /*-----------------------------------------------------------------------------+
58  * wait_for_dram_init_complete.
59  +----------------------------------------------------------------------------*/
60 static int wait_for_dram_init_complete(void)
61 {
62         unsigned long val;
63         int wait = 0;
64
65         /* --------------------------------------------------------------+
66          * Wait for 'DRAM initialization complete' bit in status register
67          * -------------------------------------------------------------*/
68         mtdcr(ddrcfga, DDR0_00);
69
70         while (wait != 0xffff) {
71                 val = mfdcr(ddrcfgd);
72                 if ((val & DDR0_00_INT_STATUS_BIT6) == DDR0_00_INT_STATUS_BIT6)
73                         /* 'DRAM initialization complete' bit */
74                         return 0;
75                 else
76                         wait++;
77         }
78         debug("DRAM initialization complete bit in status register did not "
79               "rise\n");
80         return -1;
81 }
82
83 #define NUM_TRIES 64
84 #define NUM_READS 10
85
86 /*-----------------------------------------------------------------------------+
87  * denali_core_search_data_eye.
88  +----------------------------------------------------------------------------*/
89 void denali_core_search_data_eye(void)
90 {
91         int k, j;
92         u32 val;
93         u32 wr_dqs_shift, dqs_out_shift, dll_dqs_delay_X;
94         u32 max_passing_cases = 0, wr_dqs_shift_with_max_passing_cases = 0;
95         u32 passing_cases = 0, dll_dqs_delay_X_sw_val = 0;
96         u32 dll_dqs_delay_X_start_window = 0, dll_dqs_delay_X_end_window = 0;
97         volatile u32 *ram_pointer;
98         u32 test[NUM_TRIES] = {
99                 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
100                 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
101                 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
102                 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
103                 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
104                 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
105                 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
106                 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
107                 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
108                 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
109                 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
110                 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
111                 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
112                 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
113                 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
114                 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55
115         };
116
117         ram_pointer = (volatile u32 *)(CONFIG_SYS_SDRAM_BASE);
118
119         for (wr_dqs_shift = 64; wr_dqs_shift < 96; wr_dqs_shift++) {
120                 /* for (wr_dqs_shift=1; wr_dqs_shift<96; wr_dqs_shift++) { */
121
122                 /* -----------------------------------------------------------+
123                  * De-assert 'start' parameter.
124                  * ----------------------------------------------------------*/
125                 mtdcr(ddrcfga, DDR0_02);
126                 val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
127                     DDR0_02_START_OFF;
128                 mtdcr(ddrcfgd, val);
129
130                 /* -----------------------------------------------------------+
131                  * Set 'wr_dqs_shift'
132                  * ----------------------------------------------------------*/
133                 mtdcr(ddrcfga, DDR0_09);
134                 val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK) |
135                     DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
136                 mtdcr(ddrcfgd, val);
137
138                 /* -----------------------------------------------------------+
139                  * Set 'dqs_out_shift' = wr_dqs_shift + 32
140                  * ----------------------------------------------------------*/
141                 dqs_out_shift = wr_dqs_shift + 32;
142                 mtdcr(ddrcfga, DDR0_22);
143                 val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK) |
144                     DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
145                 mtdcr(ddrcfgd, val);
146
147                 passing_cases = 0;
148
149                 for (dll_dqs_delay_X = 1; dll_dqs_delay_X < 64;
150                      dll_dqs_delay_X++) {
151                         /* for (dll_dqs_delay_X=1; dll_dqs_delay_X<128;
152                            dll_dqs_delay_X++) { */
153                         /* -----------------------------------------------------------+
154                          * Set 'dll_dqs_delay_X'.
155                          * ----------------------------------------------------------*/
156                         /* dll_dqs_delay_0 */
157                         mtdcr(ddrcfga, DDR0_17);
158                         val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
159                             | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
160                         mtdcr(ddrcfgd, val);
161                         /* dll_dqs_delay_1 to dll_dqs_delay_4 */
162                         mtdcr(ddrcfga, DDR0_18);
163                         val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
164                             | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
165                             | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
166                             | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
167                             | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
168                         mtdcr(ddrcfgd, val);
169                         /* dll_dqs_delay_5 to dll_dqs_delay_8 */
170                         mtdcr(ddrcfga, DDR0_19);
171                         val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
172                             | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
173                             | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
174                             | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
175                             | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
176                         mtdcr(ddrcfgd, val);
177                         /* clear any ECC errors */
178                         mtdcr(ddrcfga, DDR0_00);
179                         mtdcr(ddrcfgd,
180                               mfdcr(ddrcfgd) | DDR0_00_INT_ACK_ENCODE(0x3C));
181
182                         sync();
183                         eieio();
184
185                         /* -----------------------------------------------------------+
186                          * Assert 'start' parameter.
187                          * ----------------------------------------------------------*/
188                         mtdcr(ddrcfga, DDR0_02);
189                         val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
190                             DDR0_02_START_ON;
191                         mtdcr(ddrcfgd, val);
192
193                         sync();
194                         eieio();
195
196                         /* -----------------------------------------------------------+
197                          * Wait for the DCC master delay line to finish calibration
198                          * ----------------------------------------------------------*/
199                         if (denali_wait_for_dlllock() != 0) {
200                                 printf("dll lock did not occur !!!\n");
201                                 printf("denali_core_search_data_eye!!!\n");
202                                 printf("wr_dqs_shift = %d - dll_dqs_delay_X = "
203                                        "%d\n", wr_dqs_shift, dll_dqs_delay_X);
204                                 hang();
205                         }
206                         sync();
207                         eieio();
208
209                         if (wait_for_dram_init_complete() != 0) {
210                                 printf("dram init complete did not occur!!!\n");
211                                 printf("denali_core_search_data_eye!!!\n");
212                                 printf("wr_dqs_shift = %d - dll_dqs_delay_X = "
213                                        "%d\n", wr_dqs_shift, dll_dqs_delay_X);
214                                 hang();
215                         }
216                         udelay(100); /* wait 100us to ensure init is really completed !!! */
217
218                         /* write values */
219                         for (j = 0; j < NUM_TRIES; j++) {
220                                 ram_pointer[j] = test[j];
221
222                                 /* clear any cache at ram location */
223                               __asm__("dcbf 0,%0": :"r"(&ram_pointer[j]));
224                         }
225
226                         /* read values back */
227                         for (j = 0; j < NUM_TRIES; j++) {
228                                 for (k = 0; k < NUM_READS; k++) {
229                                         /* clear any cache at ram location */
230                                       __asm__("dcbf 0,%0": :"r"(&ram_pointer
231                                             [j]));
232
233                                         if (ram_pointer[j] != test[j])
234                                                 break;
235                                 }
236
237                                 /* read error */
238                                 if (k != NUM_READS)
239                                         break;
240                         }
241
242                         /* See if the dll_dqs_delay_X value passed. */
243                         mtdcr(ddrcfga, DDR0_00);
244                         if (j < NUM_TRIES
245                             || (DDR0_00_INT_STATUS_DECODE(mfdcr(ddrcfgd)) &
246                                 0x3F)) {
247                                 /* Failed */
248                                 passing_cases = 0;
249                                 /* break; */
250                         } else {
251                                 /* Passed */
252                                 if (passing_cases == 0)
253                                         dll_dqs_delay_X_sw_val =
254                                             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 =
259                                             wr_dqs_shift;
260                                         dll_dqs_delay_X_start_window =
261                                             dll_dqs_delay_X_sw_val;
262                                         dll_dqs_delay_X_end_window =
263                                             dll_dqs_delay_X;
264                                 }
265                         }
266
267                         /* -----------------------------------------------------------+
268                          * De-assert 'start' parameter.
269                          * ----------------------------------------------------------*/
270                         mtdcr(ddrcfga, DDR0_02);
271                         val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
272                             DDR0_02_START_OFF;
273                         mtdcr(ddrcfgd, val);
274                 } /* for (dll_dqs_delay_X=0; dll_dqs_delay_X<128; dll_dqs_delay_X++) */
275         } /* for (wr_dqs_shift=0; wr_dqs_shift<96; wr_dqs_shift++) */
276
277         /* -----------------------------------------------------------+
278          * Largest passing window is now detected.
279          * ----------------------------------------------------------*/
280
281         /* Compute dll_dqs_delay_X value */
282         dll_dqs_delay_X = (dll_dqs_delay_X_end_window +
283                            dll_dqs_delay_X_start_window) / 2;
284         wr_dqs_shift = wr_dqs_shift_with_max_passing_cases;
285
286         debug("DQS calibration - Window detected:\n");
287         debug("max_passing_cases = %d\n", max_passing_cases);
288         debug("wr_dqs_shift      = %d\n", wr_dqs_shift);
289         debug("dll_dqs_delay_X   = %d\n", dll_dqs_delay_X);
290         debug("dll_dqs_delay_X window = %d - %d\n",
291               dll_dqs_delay_X_start_window, dll_dqs_delay_X_end_window);
292
293         /* -----------------------------------------------------------+
294          * De-assert 'start' parameter.
295          * ----------------------------------------------------------*/
296         mtdcr(ddrcfga, DDR0_02);
297         val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF;
298         mtdcr(ddrcfgd, val);
299
300         /* -----------------------------------------------------------+
301          * Set 'wr_dqs_shift'
302          * ----------------------------------------------------------*/
303         mtdcr(ddrcfga, DDR0_09);
304         val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK)
305             | DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
306         mtdcr(ddrcfgd, val);
307         debug("DDR0_09=0x%08x\n", val);
308
309         /* -----------------------------------------------------------+
310          * Set 'dqs_out_shift' = wr_dqs_shift + 32
311          * ----------------------------------------------------------*/
312         dqs_out_shift = wr_dqs_shift + 32;
313         mtdcr(ddrcfga, DDR0_22);
314         val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK)
315             | DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
316         mtdcr(ddrcfgd, val);
317         debug("DDR0_22=0x%08x\n", val);
318
319         /* -----------------------------------------------------------+
320          * Set 'dll_dqs_delay_X'.
321          * ----------------------------------------------------------*/
322         /* dll_dqs_delay_0 */
323         mtdcr(ddrcfga, DDR0_17);
324         val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
325             | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
326         mtdcr(ddrcfgd, val);
327         debug("DDR0_17=0x%08x\n", val);
328
329         /* dll_dqs_delay_1 to dll_dqs_delay_4 */
330         mtdcr(ddrcfga, DDR0_18);
331         val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
332             | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
333             | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
334             | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
335             | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
336         mtdcr(ddrcfgd, val);
337         debug("DDR0_18=0x%08x\n", val);
338
339         /* dll_dqs_delay_5 to dll_dqs_delay_8 */
340         mtdcr(ddrcfga, DDR0_19);
341         val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
342             | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
343             | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
344             | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
345             | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
346         mtdcr(ddrcfgd, val);
347         debug("DDR0_19=0x%08x\n", val);
348
349         /* -----------------------------------------------------------+
350          * Assert 'start' parameter.
351          * ----------------------------------------------------------*/
352         mtdcr(ddrcfga, DDR0_02);
353         val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_ON;
354         mtdcr(ddrcfgd, val);
355
356         sync();
357         eieio();
358
359         /* -----------------------------------------------------------+
360          * Wait for the DCC master delay line to finish calibration
361          * ----------------------------------------------------------*/
362         if (denali_wait_for_dlllock() != 0) {
363                 printf("dll lock did not occur !!!\n");
364                 hang();
365         }
366         sync();
367         eieio();
368
369         if (wait_for_dram_init_complete() != 0) {
370                 printf("dram init complete did not occur !!!\n");
371                 hang();
372         }
373         udelay(100); /* wait 100us to ensure init is really completed !!! */
374 }
375 #endif /* defined(CONFIG_DDR_DATA_EYE) */
376 #endif /* defined(CONFIG_440EPX) || defined(CONFIG_440GRX) */