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