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