]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
Merge branch 'master' of /home/wd/git/u-boot/master
[karo-tx-uboot.git] / arch / powerpc / cpu / ppc4xx / 4xx_ibm_ddr2_autocalib.c
1 /*
2  * arch/powerpc/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
3  * This SPD SDRAM detection code supports AMCC PPC44x cpu's with a
4  * DDR2 controller (non Denali Core). Those currently are:
5  *
6  * 405:         405EX
7  * 440/460:     440SP/440SPe/460EX/460GT/460SX
8  *
9  * (C) Copyright 2008 Applied Micro Circuits Corporation
10  * Adam Graham  <agraham@amcc.com>
11  *
12  * (C) Copyright 2007-2008
13  * Stefan Roese, DENX Software Engineering, sr@denx.de.
14  *
15  * COPYRIGHT   AMCC   CORPORATION 2004
16  *
17  * See file CREDITS for list of people who contributed to this
18  * project.
19  *
20  * This program is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU General Public License as
22  * published by the Free Software Foundation; either version 2 of
23  * the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28  * GNU General Public License for more details.
29  *
30  * You should have received a copy of the GNU General Public License
31  * along with this program; if not, write to the Free Software
32  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
33  * MA 02111-1307 USA
34  *
35  */
36
37 /* define DEBUG for debugging output (obviously ;-)) */
38 #undef DEBUG
39
40 #include <common.h>
41 #include <ppc4xx.h>
42 #include <asm/io.h>
43 #include <asm/processor.h>
44
45 #include "ecc.h"
46
47 #if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
48
49 /*
50  * Only compile the DDR auto-calibration code for NOR boot and
51  * not for NAND boot (NAND SPL and NAND U-Boot - NUB)
52  */
53 #if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
54
55 #define MAXBXCF                 4
56 #define SDRAM_RXBAS_SHIFT_1M    20
57
58 #if defined(CONFIG_SYS_DECREMENT_PATTERNS)
59 #define NUMMEMTESTS             24
60 #else
61 #define NUMMEMTESTS             8
62 #endif /* CONFIG_SYS_DECREMENT_PATTERNS */
63 #define NUMLOOPS                1       /* configure as you deem approporiate */
64 #define NUMMEMWORDS             16
65
66 #define SDRAM_RDCC_RDSS_VAL(n)  SDRAM_RDCC_RDSS_DECODE(ddr_rdss_opt(n))
67
68 /* Private Structure Definitions */
69
70 struct autocal_regs {
71         u32 rffd;
72         u32 rqfd;
73 };
74
75 struct ddrautocal {
76         u32 rffd;
77         u32 rffd_min;
78         u32 rffd_max;
79         u32 rffd_size;
80         u32 rqfd;
81         u32 rqfd_size;
82         u32 rdcc;
83         u32 flags;
84 };
85
86 struct sdram_timing_clks {
87         u32 wrdtr;
88         u32 clktr;
89         u32 rdcc;
90         u32 flags;
91 };
92
93 struct autocal_clks {
94         struct sdram_timing_clks clocks;
95         struct ddrautocal        autocal;
96 };
97
98 /*--------------------------------------------------------------------------+
99  * Prototypes
100  *--------------------------------------------------------------------------*/
101 #if defined(CONFIG_PPC4xx_DDR_METHOD_A)
102 static u32 DQS_calibration_methodA(struct ddrautocal *);
103 static u32 program_DQS_calibration_methodA(struct ddrautocal *);
104 #else
105 static u32 DQS_calibration_methodB(struct ddrautocal *);
106 static u32 program_DQS_calibration_methodB(struct ddrautocal *);
107 #endif
108 static int short_mem_test(u32 *);
109
110 /*
111  * To provide an interface for board specific config values in this common
112  * DDR setup code, we implement he "weak" default functions here. They return
113  * the default value back to the caller.
114  *
115  * Please see include/configs/yucca.h for an example fora board specific
116  * implementation.
117  */
118
119 #if !defined(CONFIG_SPD_EEPROM)
120 u32 __ddr_wrdtr(u32 default_val)
121 {
122         return default_val;
123 }
124 u32 ddr_wrdtr(u32) __attribute__((weak, alias("__ddr_wrdtr")));
125
126 u32 __ddr_clktr(u32 default_val)
127 {
128         return default_val;
129 }
130 u32 ddr_clktr(u32) __attribute__((weak, alias("__ddr_clktr")));
131
132 /*
133  * Board-specific Platform code can reimplement spd_ddr_init_hang () if needed
134  */
135 void __spd_ddr_init_hang(void)
136 {
137         hang();
138 }
139 void
140 spd_ddr_init_hang(void) __attribute__((weak, alias("__spd_ddr_init_hang")));
141 #endif /* defined(CONFIG_SPD_EEPROM) */
142
143 struct sdram_timing *__ddr_scan_option(struct sdram_timing *default_val)
144 {
145         return default_val;
146 }
147 struct sdram_timing *ddr_scan_option(struct sdram_timing *)
148         __attribute__((weak, alias("__ddr_scan_option")));
149
150 u32 __ddr_rdss_opt(u32 default_val)
151 {
152         return default_val;
153 }
154 u32 ddr_rdss_opt(ulong) __attribute__((weak, alias("__ddr_rdss_opt")));
155
156
157 static u32 *get_membase(int bxcr_num)
158 {
159         ulong bxcf;
160         u32 *membase;
161
162 #if defined(SDRAM_R0BAS)
163         /* BAS from Memory Queue rank reg. */
164         membase =
165             (u32 *)(SDRAM_RXBAS_SDBA_DECODE(mfdcr_any(SDRAM_R0BAS+bxcr_num)));
166         bxcf = 0;       /* just to satisfy the compiler */
167 #else
168         /* BAS from SDRAM_MBxCF mem rank reg. */
169         mfsdram(SDRAM_MB0CF + (bxcr_num<<2), bxcf);
170         membase = (u32 *)((bxcf & 0xfff80000) << 3);
171 #endif
172
173         return membase;
174 }
175
176 static inline void ecc_clear_status_reg(void)
177 {
178         mtsdram(SDRAM_ECCES, 0xffffffff);
179 #if defined(SDRAM_R0BAS)
180         mtdcr(SDRAM_ERRSTATLL, 0xffffffff);
181 #endif
182 }
183
184 /*
185  * Reset and relock memory DLL after SDRAM_CLKTR change
186  */
187 static inline void relock_memory_DLL(void)
188 {
189         u32 reg;
190
191         mtsdram(SDRAM_MCOPT2, SDRAM_MCOPT2_IPTR_EXECUTE);
192
193         do {
194                 mfsdram(SDRAM_MCSTAT, reg);
195         } while (!(reg & SDRAM_MCSTAT_MIC_COMP));
196
197         mfsdram(SDRAM_MCOPT2, reg);
198         mtsdram(SDRAM_MCOPT2, reg | SDRAM_MCOPT2_DCEN_ENABLE);
199 }
200
201 static int ecc_check_status_reg(void)
202 {
203         u32 ecc_status;
204
205         /*
206          * Compare suceeded, now check
207          * if got ecc error. If got an
208          * ecc error, then don't count
209          * this as a passing value
210          */
211         mfsdram(SDRAM_ECCES, ecc_status);
212         if (ecc_status != 0x00000000) {
213                 /* clear on error */
214                 ecc_clear_status_reg();
215                 /* ecc check failure */
216                 return 0;
217         }
218         ecc_clear_status_reg();
219         sync();
220
221         return 1;
222 }
223
224 /* return 1 if passes, 0 if fail */
225 static int short_mem_test(u32 *base_address)
226 {
227         int i, j, l;
228         u32 ecc_mode = 0;
229
230         ulong test[NUMMEMTESTS][NUMMEMWORDS] = {
231         /* 0 */ {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
232                  0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
233                  0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
234                  0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF},
235         /* 1 */ {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
236                  0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
237                  0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
238                  0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000},
239         /* 2 */ {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
240                  0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
241                  0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
242                  0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555},
243         /* 3 */ {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
244                  0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
245                  0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
246                  0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA},
247         /* 4 */ {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
248                  0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
249                  0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
250                  0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A},
251         /* 5 */ {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
252                  0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
253                  0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
254                  0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5},
255         /* 6 */ {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
256                  0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
257                  0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
258                  0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA},
259         /* 7 */ {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
260                  0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
261                  0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
262                  0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55},
263
264 #if defined(CONFIG_SYS_DECREMENT_PATTERNS)
265         /* 8 */ {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
266                  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
267                  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
268                  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
269         /* 9 */ {0xfffefffe, 0xfffefffe, 0xfffefffe, 0xfffefffe,
270                  0xfffefffe, 0xfffefffe, 0xfffefffe, 0xfffefffe,
271                  0xfffefffe, 0xfffefffe, 0xfffefffe, 0xfffefffe,
272                  0xfffefffe, 0xfffefffe, 0xfffefffe, 0xfffefffe},
273         /* 10 */{0xfffdfffd, 0xfffdfffd, 0xfffdffff, 0xfffdfffd,
274                  0xfffdfffd, 0xfffdfffd, 0xfffdffff, 0xfffdfffd,
275                  0xfffdfffd, 0xfffdfffd, 0xfffdffff, 0xfffdfffd,
276                  0xfffdfffd, 0xfffdfffd, 0xfffdffff, 0xfffdfffd},
277         /* 11 */{0xfffcfffc, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc,
278                  0xfffcfffc, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc,
279                  0xfffcfffc, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc,
280                  0xfffcfffc, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc},
281         /* 12 */{0xfffbfffb, 0xfffffffb, 0xfffffffb, 0xfffffffb,
282                  0xfffbfffb, 0xfffffffb, 0xfffffffb, 0xfffffffb,
283                  0xfffbfffb, 0xfffffffb, 0xfffffffb, 0xfffffffb,
284                  0xfffbfffb, 0xfffffffb, 0xfffffffb, 0xfffffffb},
285         /* 13 */{0xfffafffa, 0xfffafffa, 0xfffffffa, 0xfffafffa,
286                  0xfffafffa, 0xfffafffa, 0xfffafffa, 0xfffafffa,
287                  0xfffafffa, 0xfffafffa, 0xfffafffa, 0xfffafffa,
288                  0xfffafffa, 0xfffafffa, 0xfffafffa, 0xfffafffa},
289         /* 14 */{0xfff9fff9, 0xfff9fff9, 0xfff9fff9, 0xfff9fff9,
290                  0xfff9fff9, 0xfff9fff9, 0xfff9fff9, 0xfff9fff9,
291                  0xfff9fff9, 0xfff9fff9, 0xfff9fff9, 0xfff9fff9,
292                  0xfff9fff9, 0xfff9fff9, 0xfff9fff9, 0xfff9fff9},
293         /* 15 */{0xfff8fff8, 0xfff8fff8, 0xfff8fff8, 0xfff8fff8,
294                  0xfff8fff8, 0xfff8fff8, 0xfff8fff8, 0xfff8fff8,
295                  0xfff8fff8, 0xfff8fff8, 0xfff8fff8, 0xfff8fff8,
296                  0xfff8fff8, 0xfff8fff8, 0xfff8fff8, 0xfff8fff8},
297         /* 16 */{0xfff7fff7, 0xfff7ffff, 0xfff7fff7, 0xfff7fff7,
298                  0xfff7fff7, 0xfff7ffff, 0xfff7fff7, 0xfff7fff7,
299                  0xfff7fff7, 0xfff7ffff, 0xfff7fff7, 0xfff7fff7,
300                  0xfff7ffff, 0xfff7ffff, 0xfff7fff7, 0xfff7fff7},
301         /* 17 */{0xfff6fff5, 0xfff6ffff, 0xfff6fff6, 0xfff6fff7,
302                  0xfff6fff5, 0xfff6ffff, 0xfff6fff6, 0xfff6fff7,
303                  0xfff6fff5, 0xfff6ffff, 0xfff6fff6, 0xfff6fff7,
304                  0xfff6fff5, 0xfff6ffff, 0xfff6fff6, 0xfff6fff7},
305         /* 18 */{0xfff5fff4, 0xfff5ffff, 0xfff5fff5, 0xfff5fff5,
306                  0xfff5fff4, 0xfff5ffff, 0xfff5fff5, 0xfff5fff5,
307                  0xfff5fff4, 0xfff5ffff, 0xfff5fff5, 0xfff5fff5,
308                  0xfff5fff4, 0xfff5ffff, 0xfff5fff5, 0xfff5fff5},
309         /* 19 */{0xfff4fff3, 0xfff4ffff, 0xfff4fff4, 0xfff4fff4,
310                  0xfff4fff3, 0xfff4ffff, 0xfff4fff4, 0xfff4fff4,
311                  0xfff4fff3, 0xfff4ffff, 0xfff4fff4, 0xfff4fff4,
312                  0xfff4fff3, 0xfff4ffff, 0xfff4fff4, 0xfff4fff4},
313         /* 20 */{0xfff3fff2, 0xfff3ffff, 0xfff3fff3, 0xfff3fff3,
314                  0xfff3fff2, 0xfff3ffff, 0xfff3fff3, 0xfff3fff3,
315                  0xfff3fff2, 0xfff3ffff, 0xfff3fff3, 0xfff3fff3,
316                  0xfff3fff2, 0xfff3ffff, 0xfff3fff3, 0xfff3fff3},
317         /* 21 */{0xfff2ffff, 0xfff2ffff, 0xfff2fff2, 0xfff2fff2,
318                  0xfff2ffff, 0xfff2ffff, 0xfff2fff2, 0xfff2fff2,
319                  0xfff2ffff, 0xfff2ffff, 0xfff2fff2, 0xfff2fff2,
320                  0xfff2ffff, 0xfff2ffff, 0xfff2fff2, 0xfff2fff2},
321         /* 22 */{0xfff1ffff, 0xfff1ffff, 0xfff1fff1, 0xfff1fff1,
322                  0xfff1ffff, 0xfff1ffff, 0xfff1fff1, 0xfff1fff1,
323                  0xfff1ffff, 0xfff1ffff, 0xfff1fff1, 0xfff1fff1,
324                  0xfff1ffff, 0xfff1ffff, 0xfff1fff1, 0xfff1fff1},
325         /* 23 */{0xfff0fff0, 0xfff0fff0, 0xfff0fff0, 0xfff0fff0,
326                  0xfff0fff0, 0xfff0fff0, 0xfff0fff0, 0xfff0fff0,
327                  0xfff0fff0, 0xfff0fff0, 0xfff0fff0, 0xfff0fff0,
328                  0xfff0fff0, 0xfff0fffe, 0xfff0fff0, 0xfff0fff0},
329 #endif /* CONFIG_SYS_DECREMENT_PATTERNS */
330                                                                  };
331
332         mfsdram(SDRAM_MCOPT1, ecc_mode);
333         if ((ecc_mode & SDRAM_MCOPT1_MCHK_CHK_REP) ==
334                                                 SDRAM_MCOPT1_MCHK_CHK_REP) {
335                 ecc_clear_status_reg();
336                 sync();
337                 ecc_mode = 1;
338         } else {
339                 ecc_mode = 0;
340         }
341
342         /*
343          * Run the short memory test.
344          */
345         for (i = 0; i < NUMMEMTESTS; i++) {
346                 for (j = 0; j < NUMMEMWORDS; j++) {
347                         base_address[j] = test[i][j];
348                         ppcDcbf((ulong)&(base_address[j]));
349                 }
350                 sync();
351                 iobarrier_rw();
352                 for (l = 0; l < NUMLOOPS; l++) {
353                         for (j = 0; j < NUMMEMWORDS; j++) {
354                                 if (base_address[j] != test[i][j]) {
355                                         ppcDcbf((u32)&(base_address[j]));
356                                         return 0;
357                                 } else {
358                                         if (ecc_mode) {
359                                                 if (!ecc_check_status_reg())
360                                                         return 0;
361                                         }
362                                 }
363                                 ppcDcbf((u32)&(base_address[j]));
364                         } /* for (j = 0; j < NUMMEMWORDS; j++) */
365                         sync();
366                         iobarrier_rw();
367                 } /* for (l=0; l<NUMLOOPS; l++) */
368         }
369
370         return 1;
371 }
372
373 #if defined(CONFIG_PPC4xx_DDR_METHOD_A)
374 /*-----------------------------------------------------------------------------+
375 | program_DQS_calibration_methodA.
376 +-----------------------------------------------------------------------------*/
377 static u32 program_DQS_calibration_methodA(struct ddrautocal *ddrcal)
378 {
379         u32 pass_result = 0;
380
381 #ifdef DEBUG
382         ulong temp;
383
384         mfsdram(SDRAM_RDCC, temp);
385         debug("<%s>SDRAM_RDCC=0x%08x\n", __func__, temp);
386 #endif
387
388         pass_result = DQS_calibration_methodA(ddrcal);
389
390         return pass_result;
391 }
392
393 /*
394  * DQS_calibration_methodA()
395  *
396  * Autocalibration Method A
397  *
398  *  ARRAY [Entire DQS Range] DQS_Valid_Window ;    initialized to all zeros
399  *  ARRAY [Entire FDBK Range] FDBK_Valid_Window;   initialized to all zeros
400  *  MEMWRITE(addr, expected_data);
401  *  for (i = 0; i < Entire DQS Range; i++) {       RQDC.RQFD
402  *      for (j = 0; j < Entire FDBK Range; j++) {  RFDC.RFFD
403  *         MEMREAD(addr, actual_data);
404  *         if (actual_data == expected_data) {
405  *             DQS_Valid_Window[i] = 1;            RQDC.RQFD
406  *             FDBK_Valid_Window[i][j] = 1;        RFDC.RFFD
407  *         }
408  *      }
409  *  }
410  */
411 static u32 DQS_calibration_methodA(struct ddrautocal *cal)
412 {
413         ulong rfdc_reg;
414         ulong rffd;
415
416         ulong rqdc_reg;
417         ulong rqfd;
418
419         u32 *membase;
420         ulong bxcf;
421         int rqfd_average;
422         int bxcr_num;
423         int rffd_average;
424         int pass;
425         u32 passed = 0;
426
427         int in_window;
428         struct autocal_regs curr_win_min;
429         struct autocal_regs curr_win_max;
430         struct autocal_regs best_win_min;
431         struct autocal_regs best_win_max;
432         struct autocal_regs loop_win_min;
433         struct autocal_regs loop_win_max;
434
435 #ifdef DEBUG
436         ulong temp;
437 #endif
438         ulong rdcc;
439
440         char slash[] = "\\|/-\\|/-";
441         int loopi = 0;
442
443         /* start */
444         in_window = 0;
445
446         memset(&curr_win_min, 0, sizeof(curr_win_min));
447         memset(&curr_win_max, 0, sizeof(curr_win_max));
448         memset(&best_win_min, 0, sizeof(best_win_min));
449         memset(&best_win_max, 0, sizeof(best_win_max));
450         memset(&loop_win_min, 0, sizeof(loop_win_min));
451         memset(&loop_win_max, 0, sizeof(loop_win_max));
452
453         rdcc = 0;
454
455         /*
456          * Program RDCC register
457          * Read sample cycle auto-update enable
458          */
459         mtsdram(SDRAM_RDCC,
460                 ddr_rdss_opt(SDRAM_RDCC_RDSS_T2) | SDRAM_RDCC_RSAE_ENABLE);
461
462 #ifdef DEBUG
463         mfsdram(SDRAM_RDCC, temp);
464         debug("<%s>SDRAM_RDCC=0x%x\n", __func__, temp);
465         mfsdram(SDRAM_RTSR, temp);
466         debug("<%s>SDRAM_RTSR=0x%x\n", __func__, temp);
467         mfsdram(SDRAM_FCSR, temp);
468         debug("<%s>SDRAM_FCSR=0x%x\n", __func__, temp);
469 #endif
470
471         /*
472          * Program RQDC register
473          * Internal DQS delay mechanism enable
474          */
475         mtsdram(SDRAM_RQDC,
476                 SDRAM_RQDC_RQDE_ENABLE | SDRAM_RQDC_RQFD_ENCODE(0x00));
477
478 #ifdef DEBUG
479         mfsdram(SDRAM_RQDC, temp);
480         debug("<%s>SDRAM_RQDC=0x%x\n", __func__, temp);
481 #endif
482
483         /*
484          * Program RFDC register
485          * Set Feedback Fractional Oversample
486          * Auto-detect read sample cycle enable
487          */
488         mtsdram(SDRAM_RFDC, SDRAM_RFDC_ARSE_ENABLE |
489                 SDRAM_RFDC_RFOS_ENCODE(0) | SDRAM_RFDC_RFFD_ENCODE(0));
490
491 #ifdef DEBUG
492         mfsdram(SDRAM_RFDC, temp);
493         debug("<%s>SDRAM_RFDC=0x%x\n", __func__, temp);
494 #endif
495
496         putc(' ');
497         for (rqfd = 0; rqfd <= SDRAM_RQDC_RQFD_MAX; rqfd++) {
498
499                 mfsdram(SDRAM_RQDC, rqdc_reg);
500                 rqdc_reg &= ~(SDRAM_RQDC_RQFD_MASK);
501                 mtsdram(SDRAM_RQDC, rqdc_reg | SDRAM_RQDC_RQFD_ENCODE(rqfd));
502
503                 putc('\b');
504                 putc(slash[loopi++ % 8]);
505
506                 curr_win_min.rffd = 0;
507                 curr_win_max.rffd = 0;
508                 in_window = 0;
509
510                 for (rffd = 0, pass = 0; rffd <= SDRAM_RFDC_RFFD_MAX; rffd++) {
511                         mfsdram(SDRAM_RFDC, rfdc_reg);
512                         rfdc_reg &= ~(SDRAM_RFDC_RFFD_MASK);
513                         mtsdram(SDRAM_RFDC,
514                                     rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd));
515
516                         for (bxcr_num = 0; bxcr_num < MAXBXCF; bxcr_num++) {
517                                 mfsdram(SDRAM_MB0CF + (bxcr_num<<2), bxcf);
518
519                                 /* Banks enabled */
520                                 if (bxcf & SDRAM_BXCF_M_BE_MASK) {
521                                         /* Bank is enabled */
522                                         membase = get_membase(bxcr_num);
523                                         pass = short_mem_test(membase);
524                                 } /* if bank enabled */
525                         } /* for bxcr_num */
526
527                         /* If this value passed update RFFD windows */
528                         if (pass && !in_window) { /* at the start of window */
529                                 in_window = 1;
530                                 curr_win_min.rffd = curr_win_max.rffd = rffd;
531                                 curr_win_min.rqfd = curr_win_max.rqfd = rqfd;
532                                 mfsdram(SDRAM_RDCC, rdcc); /*record this value*/
533                         } else if (!pass && in_window) { /* at end of window */
534                                 in_window = 0;
535                         } else if (pass && in_window) { /* within the window */
536                                 curr_win_max.rffd = rffd;
537                                 curr_win_max.rqfd = rqfd;
538                         }
539                         /* else if (!pass && !in_window)
540                                 skip - no pass, not currently in a window */
541
542                         if (in_window) {
543                                 if ((curr_win_max.rffd - curr_win_min.rffd) >
544                                     (best_win_max.rffd - best_win_min.rffd)) {
545                                         best_win_min.rffd = curr_win_min.rffd;
546                                         best_win_max.rffd = curr_win_max.rffd;
547
548                                         best_win_min.rqfd = curr_win_min.rqfd;
549                                         best_win_max.rqfd = curr_win_max.rqfd;
550                                         cal->rdcc         = rdcc;
551                                 }
552                                 passed = 1;
553                         }
554                 } /* RFDC.RFFD */
555
556                 /*
557                  * save-off the best window results of the RFDC.RFFD
558                  * for this RQDC.RQFD setting
559                  */
560                 /*
561                  * if (just ended RFDC.RFDC loop pass window) >
562                  *      (prior RFDC.RFFD loop pass window)
563                  */
564                 if ((best_win_max.rffd - best_win_min.rffd) >
565                     (loop_win_max.rffd - loop_win_min.rffd)) {
566                         loop_win_min.rffd = best_win_min.rffd;
567                         loop_win_max.rffd = best_win_max.rffd;
568                         loop_win_min.rqfd = rqfd;
569                         loop_win_max.rqfd = rqfd;
570                         debug("RQFD.min 0x%08x, RQFD.max 0x%08x, "
571                               "RFFD.min 0x%08x, RFFD.max 0x%08x\n",
572                                         loop_win_min.rqfd, loop_win_max.rqfd,
573                                         loop_win_min.rffd, loop_win_max.rffd);
574                 }
575         } /* RQDC.RQFD */
576
577         putc('\b');
578
579         debug("\n");
580
581         if ((loop_win_min.rffd == 0) && (loop_win_max.rffd == 0) &&
582             (best_win_min.rffd == 0) && (best_win_max.rffd == 0) &&
583             (best_win_min.rqfd == 0) && (best_win_max.rqfd == 0)) {
584                 passed = 0;
585         }
586
587         /*
588          * Need to program RQDC before RFDC.
589          */
590         debug("<%s> RQFD Min: 0x%x\n", __func__, loop_win_min.rqfd);
591         debug("<%s> RQFD Max: 0x%x\n", __func__, loop_win_max.rqfd);
592         rqfd_average = loop_win_max.rqfd;
593
594         if (rqfd_average < 0)
595                 rqfd_average = 0;
596
597         if (rqfd_average > SDRAM_RQDC_RQFD_MAX)
598                 rqfd_average = SDRAM_RQDC_RQFD_MAX;
599
600         debug("<%s> RFFD average: 0x%08x\n", __func__, rqfd_average);
601         mtsdram(SDRAM_RQDC, (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |
602                                 SDRAM_RQDC_RQFD_ENCODE(rqfd_average));
603
604         debug("<%s> RFFD Min: 0x%08x\n", __func__, loop_win_min.rffd);
605         debug("<%s> RFFD Max: 0x%08x\n", __func__, loop_win_max.rffd);
606         rffd_average = ((loop_win_min.rffd + loop_win_max.rffd) / 2);
607
608         if (rffd_average < 0)
609                 rffd_average = 0;
610
611         if (rffd_average > SDRAM_RFDC_RFFD_MAX)
612                 rffd_average = SDRAM_RFDC_RFFD_MAX;
613
614         debug("<%s> RFFD average: 0x%08x\n", __func__, rffd_average);
615         mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd_average));
616
617         /* if something passed, then return the size of the largest window */
618         if (passed != 0) {
619                 passed          = loop_win_max.rffd - loop_win_min.rffd;
620                 cal->rqfd       = rqfd_average;
621                 cal->rffd       = rffd_average;
622                 cal->rffd_min   = loop_win_min.rffd;
623                 cal->rffd_max   = loop_win_max.rffd;
624         }
625
626         return (u32)passed;
627 }
628
629 #else   /* !defined(CONFIG_PPC4xx_DDR_METHOD_A) */
630
631 /*-----------------------------------------------------------------------------+
632 | program_DQS_calibration_methodB.
633 +-----------------------------------------------------------------------------*/
634 static u32 program_DQS_calibration_methodB(struct ddrautocal *ddrcal)
635 {
636         u32 pass_result = 0;
637
638 #ifdef DEBUG
639         ulong temp;
640 #endif
641
642         /*
643          * Program RDCC register
644          * Read sample cycle auto-update enable
645          */
646         mtsdram(SDRAM_RDCC,
647                 ddr_rdss_opt(SDRAM_RDCC_RDSS_T2) | SDRAM_RDCC_RSAE_ENABLE);
648
649 #ifdef DEBUG
650         mfsdram(SDRAM_RDCC, temp);
651         debug("<%s>SDRAM_RDCC=0x%08x\n", __func__, temp);
652 #endif
653
654         /*
655          * Program RQDC register
656          * Internal DQS delay mechanism enable
657          */
658         mtsdram(SDRAM_RQDC,
659 #if defined(CONFIG_DDR_RQDC_START_VAL)
660                         SDRAM_RQDC_RQDE_ENABLE |
661                             SDRAM_RQDC_RQFD_ENCODE(CONFIG_DDR_RQDC_START_VAL));
662 #else
663                         SDRAM_RQDC_RQDE_ENABLE | SDRAM_RQDC_RQFD_ENCODE(0x38));
664 #endif
665
666 #ifdef DEBUG
667         mfsdram(SDRAM_RQDC, temp);
668         debug("<%s>SDRAM_RQDC=0x%08x\n", __func__, temp);
669 #endif
670
671         /*
672          * Program RFDC register
673          * Set Feedback Fractional Oversample
674          * Auto-detect read sample cycle enable
675          */
676         mtsdram(SDRAM_RFDC,     SDRAM_RFDC_ARSE_ENABLE |
677                                 SDRAM_RFDC_RFOS_ENCODE(0) |
678                                 SDRAM_RFDC_RFFD_ENCODE(0));
679
680 #ifdef DEBUG
681         mfsdram(SDRAM_RFDC, temp);
682         debug("<%s>SDRAM_RFDC=0x%08x\n", __func__, temp);
683 #endif
684
685         pass_result = DQS_calibration_methodB(ddrcal);
686
687         return pass_result;
688 }
689
690 /*
691  * DQS_calibration_methodB()
692  *
693  * Autocalibration Method B
694  *
695  * ARRAY [Entire DQS Range] DQS_Valid_Window ;       initialized to all zeros
696  * ARRAY [Entire Feedback Range] FDBK_Valid_Window;  initialized to all zeros
697  * MEMWRITE(addr, expected_data);
698  * Initialialize the DQS delay to 80 degrees (MCIF0_RRQDC[RQFD]=0x38).
699  *
700  *  for (j = 0; j < Entire Feedback Range; j++) {
701  *      MEMREAD(addr, actual_data);
702  *       if (actual_data == expected_data) {
703  *           FDBK_Valid_Window[j] = 1;
704  *       }
705  * }
706  *
707  * Set MCIF0_RFDC[RFFD] to the middle of the FDBK_Valid_Window.
708  *
709  * for (i = 0; i < Entire DQS Range; i++) {
710  *     MEMREAD(addr, actual_data);
711  *     if (actual_data == expected_data) {
712  *         DQS_Valid_Window[i] = 1;
713  *      }
714  * }
715  *
716  * Set MCIF0_RRQDC[RQFD] to the middle of the DQS_Valid_Window.
717  */
718 /*-----------------------------------------------------------------------------+
719 | DQS_calibration_methodB.
720 +-----------------------------------------------------------------------------*/
721 static u32 DQS_calibration_methodB(struct ddrautocal *cal)
722 {
723         ulong rfdc_reg;
724         ulong rffd;
725
726         ulong rqdc_reg;
727         ulong rqfd;
728
729         ulong rdcc;
730
731         u32 *membase;
732         ulong bxcf;
733         int rqfd_average;
734         int bxcr_num;
735         int rffd_average;
736         int pass;
737         uint passed = 0;
738
739         int in_window;
740         u32 curr_win_min, curr_win_max;
741         u32 best_win_min, best_win_max;
742         u32 size = 0;
743
744         /*------------------------------------------------------------------
745          | Test to determine the best read clock delay tuning bits.
746          |
747          | Before the DDR controller can be used, the read clock delay needs to
748          | be set.  This is SDRAM_RQDC[RQFD] and SDRAM_RFDC[RFFD].
749          | This value cannot be hardcoded into the program because it changes
750          | depending on the board's setup and environment.
751          | To do this, all delay values are tested to see if they
752          | work or not.  By doing this, you get groups of fails with groups of
753          | passing values.  The idea is to find the start and end of a passing
754          | window and take the center of it to use as the read clock delay.
755          |
756          | A failure has to be seen first so that when we hit a pass, we know
757          | that it is truely the start of the window.  If we get passing values
758          | to start off with, we don't know if we are at the start of the window
759          |
760          | The code assumes that a failure will always be found.
761          | If a failure is not found, there is no easy way to get the middle
762          | of the passing window.  I guess we can pretty much pick any value
763          | but some values will be better than others.  Since the lowest speed
764          | we can clock the DDR interface at is 200 MHz (2x 100 MHz PLB speed),
765          | from experimentation it is safe to say you will always have a failure
766          +-----------------------------------------------------------------*/
767
768         debug("\n\n");
769
770 #if defined(CONFIG_DDR_RFDC_FIXED)
771         mtsdram(SDRAM_RFDC, CONFIG_DDR_RFDC_FIXED);
772         size = 512;
773         rffd_average = CONFIG_DDR_RFDC_FIXED & SDRAM_RFDC_RFFD_MASK;
774         mfsdram(SDRAM_RDCC, rdcc);      /* record this value */
775         cal->rdcc = rdcc;
776 #else /* CONFIG_DDR_RFDC_FIXED */
777         in_window = 0;
778         rdcc = 0;
779
780         curr_win_min = curr_win_max = 0;
781         best_win_min = best_win_max = 0;
782         for (rffd = 0; rffd <= SDRAM_RFDC_RFFD_MAX; rffd++) {
783                 mfsdram(SDRAM_RFDC, rfdc_reg);
784                 rfdc_reg &= ~(SDRAM_RFDC_RFFD_MASK);
785                 mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd));
786
787                 pass = 1;
788                 for (bxcr_num = 0; bxcr_num < MAXBXCF; bxcr_num++) {
789                         mfsdram(SDRAM_MB0CF + (bxcr_num<<2), bxcf);
790
791                         /* Banks enabled */
792                         if (bxcf & SDRAM_BXCF_M_BE_MASK) {
793                                 /* Bank is enabled */
794                                 membase = get_membase(bxcr_num);
795                                 pass &= short_mem_test(membase);
796                         } /* if bank enabled */
797                 } /* for bxcf_num */
798
799                 /* If this value passed */
800                 if (pass && !in_window) {       /* start of passing window */
801                         in_window = 1;
802                         curr_win_min = curr_win_max = rffd;
803                         mfsdram(SDRAM_RDCC, rdcc);      /* record this value */
804                 } else if (!pass && in_window) {        /* end passing window */
805                         in_window = 0;
806                 } else if (pass && in_window) { /* within the passing window */
807                         curr_win_max = rffd;
808                 }
809
810                 if (in_window) {
811                         if ((curr_win_max - curr_win_min) >
812                             (best_win_max - best_win_min)) {
813                                 best_win_min = curr_win_min;
814                                 best_win_max = curr_win_max;
815                                 cal->rdcc    = rdcc;
816                         }
817                         passed = 1;
818                 }
819         } /* for rffd */
820
821         if ((best_win_min == 0) && (best_win_max == 0))
822                 passed = 0;
823         else
824                 size = best_win_max - best_win_min;
825
826         debug("RFFD Min: 0x%x\n", best_win_min);
827         debug("RFFD Max: 0x%x\n", best_win_max);
828         rffd_average = ((best_win_min + best_win_max) / 2);
829
830         cal->rffd_min = best_win_min;
831         cal->rffd_max = best_win_max;
832
833         if (rffd_average < 0)
834                 rffd_average = 0;
835
836         if (rffd_average > SDRAM_RFDC_RFFD_MAX)
837                 rffd_average = SDRAM_RFDC_RFFD_MAX;
838
839         mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd_average));
840 #endif /* CONFIG_DDR_RFDC_FIXED */
841
842         rffd = rffd_average;
843         in_window = 0;
844
845         curr_win_min = curr_win_max = 0;
846         best_win_min = best_win_max = 0;
847         for (rqfd = 0; rqfd <= SDRAM_RQDC_RQFD_MAX; rqfd++) {
848                 mfsdram(SDRAM_RQDC, rqdc_reg);
849                 rqdc_reg &= ~(SDRAM_RQDC_RQFD_MASK);
850                 mtsdram(SDRAM_RQDC, rqdc_reg | SDRAM_RQDC_RQFD_ENCODE(rqfd));
851
852                 pass = 1;
853                 for (bxcr_num = 0; bxcr_num < MAXBXCF; bxcr_num++) {
854
855                         mfsdram(SDRAM_MB0CF + (bxcr_num<<2), bxcf);
856
857                         /* Banks enabled */
858                         if (bxcf & SDRAM_BXCF_M_BE_MASK) {
859                                 /* Bank is enabled */
860                                 membase = get_membase(bxcr_num);
861                                 pass &= short_mem_test(membase);
862                         } /* if bank enabled */
863                 } /* for bxcf_num */
864
865                 /* If this value passed */
866                 if (pass && !in_window) {
867                         in_window = 1;
868                         curr_win_min = curr_win_max = rqfd;
869                 } else if (!pass && in_window) {
870                         in_window = 0;
871                 } else if (pass && in_window) {
872                         curr_win_max = rqfd;
873                 }
874
875                 if (in_window) {
876                         if ((curr_win_max - curr_win_min) >
877                             (best_win_max - best_win_min)) {
878                                 best_win_min = curr_win_min;
879                                 best_win_max = curr_win_max;
880                         }
881                         passed = 1;
882                 }
883         } /* for rqfd */
884
885         if ((best_win_min == 0) && (best_win_max == 0))
886                 passed = 0;
887
888         debug("RQFD Min: 0x%x\n", best_win_min);
889         debug("RQFD Max: 0x%x\n", best_win_max);
890         rqfd_average = ((best_win_min + best_win_max) / 2);
891
892         if (rqfd_average < 0)
893                 rqfd_average = 0;
894
895         if (rqfd_average > SDRAM_RQDC_RQFD_MAX)
896                 rqfd_average = SDRAM_RQDC_RQFD_MAX;
897
898         mtsdram(SDRAM_RQDC, (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |
899                                         SDRAM_RQDC_RQFD_ENCODE(rqfd_average));
900
901         mfsdram(SDRAM_RQDC, rqdc_reg);
902         mfsdram(SDRAM_RFDC, rfdc_reg);
903
904         /*
905          * Need to program RQDC before RFDC. The value is read above.
906          * That is the reason why auto cal not work.
907          * See, comments below.
908          */
909         mtsdram(SDRAM_RQDC, rqdc_reg);
910         mtsdram(SDRAM_RFDC, rfdc_reg);
911
912         debug("RQDC: 0x%08X\n", rqdc_reg);
913         debug("RFDC: 0x%08X\n", rfdc_reg);
914
915         /* if something passed, then return the size of the largest window */
916         if (passed != 0) {
917                 passed          = size;
918                 cal->rqfd       = rqfd_average;
919                 cal->rffd       = rffd_average;
920         }
921
922         return (uint)passed;
923 }
924 #endif /* defined(CONFIG_PPC4xx_DDR_METHOD_A) */
925
926 /*
927  * Default table for DDR auto-calibration of all
928  * possible WRDTR and CLKTR values.
929  * Table format is:
930  *       {SDRAM_WRDTR.[WDTR], SDRAM_CLKTR.[CKTR]}
931  *
932  * Table is terminated with {-1, -1} value pair.
933  *
934  * Board vendors can specify their own board specific subset of
935  * known working {SDRAM_WRDTR.[WDTR], SDRAM_CLKTR.[CKTR]} value
936  * pairs via a board defined ddr_scan_option() function.
937  */
938 static struct sdram_timing full_scan_options[] = {
939         {0, 0}, {0, 1}, {0, 2}, {0, 3},
940         {1, 0}, {1, 1}, {1, 2}, {1, 3},
941         {2, 0}, {2, 1}, {2, 2}, {2, 3},
942         {3, 0}, {3, 1}, {3, 2}, {3, 3},
943         {4, 0}, {4, 1}, {4, 2}, {4, 3},
944         {5, 0}, {5, 1}, {5, 2}, {5, 3},
945         {6, 0}, {6, 1}, {6, 2}, {6, 3},
946         {-1, -1}
947 };
948
949 /*---------------------------------------------------------------------------+
950 | DQS_calibration.
951 +----------------------------------------------------------------------------*/
952 u32 DQS_autocalibration(void)
953 {
954         u32 wdtr;
955         u32 clkp;
956         u32 result = 0;
957         u32 best_result = 0;
958         u32 best_rdcc;
959         struct ddrautocal ddrcal;
960         struct autocal_clks tcal;
961         ulong rfdc_reg;
962         ulong rqdc_reg;
963         u32 val;
964         int verbose_lvl = 0;
965         char *str;
966         char slash[] = "\\|/-\\|/-";
967         int loopi = 0;
968         struct sdram_timing *scan_list;
969
970 #if defined(DEBUG_PPC4xx_DDR_AUTOCALIBRATION)
971         int i;
972         char tmp[64];   /* long enough for environment variables */
973 #endif
974
975         memset(&tcal, 0, sizeof(tcal));
976
977         scan_list = ddr_scan_option(full_scan_options);
978
979         mfsdram(SDRAM_MCOPT1, val);
980         if ((val & SDRAM_MCOPT1_MCHK_CHK_REP) == SDRAM_MCOPT1_MCHK_CHK_REP)
981                 str = "ECC Auto calibration -";
982         else
983                 str = "Auto calibration -";
984
985         puts(str);
986
987 #if defined(DEBUG_PPC4xx_DDR_AUTOCALIBRATION)
988         i = getenv_f("autocalib", tmp, sizeof(tmp));
989         if (i < 0)
990                 strcpy(tmp, CONFIG_AUTOCALIB);
991
992         if (strcmp(tmp, "final") == 0) {
993                 /* display the final autocalibration results only */
994                 verbose_lvl = 1;
995         } else if (strcmp(tmp, "loop") == 0) {
996                 /* display summary autocalibration info per iteration */
997                 verbose_lvl = 2;
998         } else if (strcmp(tmp, "display") == 0) {
999                 /* display full debug autocalibration window info. */
1000                 verbose_lvl = 3;
1001         }
1002 #endif /* (DEBUG_PPC4xx_DDR_AUTOCALIBRATION) */
1003
1004         best_rdcc = (SDRAM_RDCC_RDSS_T4 >> 30);
1005
1006         while ((scan_list->wrdtr != -1) && (scan_list->clktr != -1)) {
1007                 wdtr = scan_list->wrdtr;
1008                 clkp = scan_list->clktr;
1009
1010                 mfsdram(SDRAM_WRDTR, val);
1011                 val &= ~(SDRAM_WRDTR_LLWP_MASK | SDRAM_WRDTR_WTR_MASK);
1012                 mtsdram(SDRAM_WRDTR, (val |
1013                         ddr_wrdtr(SDRAM_WRDTR_LLWP_1_CYC | (wdtr << 25))));
1014
1015                 mtsdram(SDRAM_CLKTR, clkp << 30);
1016
1017                 relock_memory_DLL();
1018
1019                 putc('\b');
1020                 putc(slash[loopi++ % 8]);
1021
1022 #ifdef DEBUG
1023                 debug("\n");
1024                 debug("*** --------------\n");
1025                 mfsdram(SDRAM_WRDTR, val);
1026                 debug("*** SDRAM_WRDTR set to 0x%08x\n", val);
1027                 mfsdram(SDRAM_CLKTR, val);
1028                 debug("*** SDRAM_CLKTR set to 0x%08x\n", val);
1029 #endif
1030
1031                 debug("\n");
1032                 if (verbose_lvl > 2) {
1033                         printf("*** SDRAM_WRDTR (wdtr) set to %d\n", wdtr);
1034                         printf("*** SDRAM_CLKTR (clkp) set to %d\n", clkp);
1035                 }
1036
1037                 memset(&ddrcal, 0, sizeof(ddrcal));
1038
1039                 /*
1040                  * DQS calibration.
1041                  */
1042                 /*
1043                  * program_DQS_calibration_method[A|B]() returns 0 if no
1044                  * passing RFDC.[RFFD] window is found or returns the size
1045                  * of the best passing window; in the case of a found passing
1046                  * window, the ddrcal will contain the values of the best
1047                  * window RQDC.[RQFD] and RFDC.[RFFD].
1048                  */
1049
1050                 /*
1051                  * Call PPC4xx SDRAM DDR autocalibration methodA or methodB.
1052                  * Default is methodB.
1053                  * Defined the autocalibration method in the board specific
1054                  * header file.
1055                  * Please see include/configs/kilauea.h for an example for
1056                  * a board specific implementation.
1057                  */
1058 #if defined(CONFIG_PPC4xx_DDR_METHOD_A)
1059                 result = program_DQS_calibration_methodA(&ddrcal);
1060 #else
1061                 result = program_DQS_calibration_methodB(&ddrcal);
1062 #endif
1063
1064                 sync();
1065
1066                 /*
1067                  * Clear potential errors resulting from auto-calibration.
1068                  * If not done, then we could get an interrupt later on when
1069                  * exceptions are enabled.
1070                  */
1071                 set_mcsr(get_mcsr());
1072
1073                 val = ddrcal.rdcc;      /* RDCC from the best passing window */
1074
1075                 udelay(100);
1076
1077                 if (verbose_lvl > 1) {
1078                         char *tstr;
1079                         switch ((val >> 30)) {
1080                         case 0:
1081                                 if (result != 0)
1082                                         tstr = "T1";
1083                                 else
1084                                         tstr = "N/A";
1085                                 break;
1086                         case 1:
1087                                 tstr = "T2";
1088                                 break;
1089                         case 2:
1090                                 tstr = "T3";
1091                                 break;
1092                         case 3:
1093                                 tstr = "T4";
1094                                 break;
1095                         default:
1096                                 tstr = "unknown";
1097                                 break;
1098                         }
1099                         printf("** WRDTR(%d) CLKTR(%d), Wind (%d), best (%d), "
1100                                "max-min(0x%04x)(0x%04x), RDCC: %s\n",
1101                                 wdtr, clkp, result, best_result,
1102                                 ddrcal.rffd_min, ddrcal.rffd_max, tstr);
1103                 }
1104
1105                 /*
1106                  * The DQS calibration "result" is either "0"
1107                  * if no passing window was found, or is the
1108                  * size of the RFFD passing window.
1109                  */
1110                 /*
1111                  * want the lowest Read Sample Cycle Select
1112                  */
1113                 val = SDRAM_RDCC_RDSS_DECODE(val);
1114                 debug("*** (%d) (%d) current_rdcc, best_rdcc\n",
1115                         val, best_rdcc);
1116
1117                 if ((result != 0) &&
1118                     (val >= SDRAM_RDCC_RDSS_VAL(SDRAM_RDCC_RDSS_T2))) {
1119                         if (((result == best_result) && (val < best_rdcc)) ||
1120                             ((result > best_result) && (val <= best_rdcc))) {
1121                                 tcal.autocal.flags = 1;
1122                                 debug("*** (%d)(%d) result passed window "
1123                                         "size: 0x%08x, rqfd = 0x%08x, "
1124                                         "rffd = 0x%08x, rdcc = 0x%08x\n",
1125                                         wdtr, clkp, result, ddrcal.rqfd,
1126                                         ddrcal.rffd, ddrcal.rdcc);
1127
1128                                 /*
1129                                  * Save the SDRAM_WRDTR and SDRAM_CLKTR
1130                                  * settings for the largest returned
1131                                  * RFFD passing window size.
1132                                  */
1133                                 best_rdcc = val;
1134                                 tcal.clocks.wrdtr = wdtr;
1135                                 tcal.clocks.clktr = clkp;
1136                                 tcal.clocks.rdcc = SDRAM_RDCC_RDSS_ENCODE(val);
1137                                 tcal.autocal.rqfd = ddrcal.rqfd;
1138                                 tcal.autocal.rffd = ddrcal.rffd;
1139                                 best_result = result;
1140
1141                                         if (verbose_lvl > 2) {
1142                                                 printf("** (%d)(%d)  "
1143                                                        "best result: 0x%04x\n",
1144                                                         wdtr, clkp,
1145                                                         best_result);
1146                                                 printf("** (%d)(%d)  "
1147                                                        "best WRDTR: 0x%04x\n",
1148                                                         wdtr, clkp,
1149                                                         tcal.clocks.wrdtr);
1150                                                 printf("** (%d)(%d)  "
1151                                                        "best CLKTR: 0x%04x\n",
1152                                                         wdtr, clkp,
1153                                                         tcal.clocks.clktr);
1154                                                 printf("** (%d)(%d)  "
1155                                                        "best RQDC: 0x%04x\n",
1156                                                         wdtr, clkp,
1157                                                         tcal.autocal.rqfd);
1158                                                 printf("** (%d)(%d)  "
1159                                                        "best RFDC: 0x%04x\n",
1160                                                         wdtr, clkp,
1161                                                         tcal.autocal.rffd);
1162                                                 printf("** (%d)(%d)  "
1163                                                        "best RDCC: 0x%08x\n",
1164                                                         wdtr, clkp,
1165                                                         (u32)tcal.clocks.rdcc);
1166                                                 mfsdram(SDRAM_RTSR, val);
1167                                                 printf("** (%d)(%d)  best "
1168                                                        "loop RTSR: 0x%08x\n",
1169                                                         wdtr, clkp, val);
1170                                                 mfsdram(SDRAM_FCSR, val);
1171                                                 printf("** (%d)(%d)  best "
1172                                                        "loop FCSR: 0x%08x\n",
1173                                                         wdtr, clkp, val);
1174                                         }
1175                         }
1176                 } /* if ((result != 0) && (val >= (ddr_rdss_opt()))) */
1177                 scan_list++;
1178         } /* while ((scan_list->wrdtr != -1) && (scan_list->clktr != -1)) */
1179
1180         if (tcal.autocal.flags == 1) {
1181                 if (verbose_lvl > 0) {
1182                         printf("*** --------------\n");
1183                         printf("*** best_result window size: %d\n",
1184                                                         best_result);
1185                         printf("*** best_result WRDTR: 0x%04x\n",
1186                                                         tcal.clocks.wrdtr);
1187                         printf("*** best_result CLKTR: 0x%04x\n",
1188                                                         tcal.clocks.clktr);
1189                         printf("*** best_result RQFD: 0x%04x\n",
1190                                                         tcal.autocal.rqfd);
1191                         printf("*** best_result RFFD: 0x%04x\n",
1192                                                         tcal.autocal.rffd);
1193                         printf("*** best_result RDCC: 0x%04x\n",
1194                                                         tcal.clocks.rdcc);
1195                         printf("*** --------------\n");
1196                         printf("\n");
1197                 }
1198
1199                 /*
1200                  * if got best passing result window, then lock in the
1201                  * best CLKTR, WRDTR, RQFD, and RFFD values
1202                  */
1203                 mfsdram(SDRAM_WRDTR, val);
1204                 mtsdram(SDRAM_WRDTR, (val &
1205                     ~(SDRAM_WRDTR_LLWP_MASK | SDRAM_WRDTR_WTR_MASK)) |
1206                     ddr_wrdtr(SDRAM_WRDTR_LLWP_1_CYC |
1207                                         (tcal.clocks.wrdtr << 25)));
1208
1209                 mtsdram(SDRAM_CLKTR, tcal.clocks.clktr << 30);
1210
1211                 relock_memory_DLL();
1212
1213                 mfsdram(SDRAM_RQDC, rqdc_reg);
1214                 rqdc_reg &= ~(SDRAM_RQDC_RQFD_MASK);
1215                 mtsdram(SDRAM_RQDC, rqdc_reg |
1216                                 SDRAM_RQDC_RQFD_ENCODE(tcal.autocal.rqfd));
1217
1218                 mfsdram(SDRAM_RQDC, rqdc_reg);
1219                 debug("*** best_result: read value SDRAM_RQDC 0x%08x\n",
1220                                 rqdc_reg);
1221
1222 #if defined(CONFIG_DDR_RFDC_FIXED)
1223                 mtsdram(SDRAM_RFDC, CONFIG_DDR_RFDC_FIXED);
1224 #else /* CONFIG_DDR_RFDC_FIXED */
1225                 mfsdram(SDRAM_RFDC, rfdc_reg);
1226                 rfdc_reg &= ~(SDRAM_RFDC_RFFD_MASK);
1227                 mtsdram(SDRAM_RFDC, rfdc_reg |
1228                                 SDRAM_RFDC_RFFD_ENCODE(tcal.autocal.rffd));
1229 #endif /* CONFIG_DDR_RFDC_FIXED */
1230
1231                 mfsdram(SDRAM_RFDC, rfdc_reg);
1232                 debug("*** best_result: read value SDRAM_RFDC 0x%08x\n",
1233                                 rfdc_reg);
1234                 mfsdram(SDRAM_RDCC, val);
1235                 debug("***  SDRAM_RDCC 0x%08x\n", val);
1236         } else {
1237                 /*
1238                  * no valid windows were found
1239                  */
1240                 printf("DQS memory calibration window can not be determined, "
1241                        "terminating u-boot.\n");
1242                 ppc4xx_ibm_ddr2_register_dump();
1243                 spd_ddr_init_hang();
1244         }
1245
1246         blank_string(strlen(str));
1247
1248         return 0;
1249 }
1250 #else /* defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) */
1251 u32 DQS_autocalibration(void)
1252 {
1253         return 0;
1254 }
1255 #endif /* !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) */
1256 #endif /* defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION) */