2 * arch/powerpc/cpu/ppc4xx/denali_data_eye.c
3 * Extracted from board/amcc/sequoia/sdram.c by Larry Johnson <lrj@acm.org>.
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
12 * (C) Copyright 2006-2007
13 * Stefan Roese, DENX Software Engineering, sr@denx.de.
15 * SPDX-License-Identifier: GPL-2.0+
18 /* define DEBUG for debugging output (obviously ;-)) */
24 #include <asm/processor.h>
26 #include <asm/ppc4xx.h>
28 #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
29 /*-----------------------------------------------------------------------------+
30 * denali_wait_for_dlllock.
31 +----------------------------------------------------------------------------*/
32 int denali_wait_for_dlllock(void)
37 /* -----------------------------------------------------------+
38 * Wait for the DCC master delay line to finish calibration
39 * ----------------------------------------------------------*/
40 for (wait = 0; wait != 0xffff; ++wait) {
41 mfsdram(DDR0_17, val);
42 if (DDR0_17_DLLLOCKREG_DECODE(val)) {
43 /* dlllockreg bit on */
47 debug("0x%04x: DDR0_17 Value (dlllockreg bit): 0x%08x\n", wait, val);
48 debug("Waiting for dlllockreg bit to raise\n");
52 #if defined(CONFIG_DDR_DATA_EYE)
53 #define DDR_DCR_BASE 0x10
54 #define ddrcfga (DDR_DCR_BASE+0x0) /* DDR configuration address reg */
55 #define ddrcfgd (DDR_DCR_BASE+0x1) /* DDR configuration data reg */
57 /*-----------------------------------------------------------------------------+
58 * wait_for_dram_init_complete.
59 +----------------------------------------------------------------------------*/
60 static int wait_for_dram_init_complete(void)
65 /* --------------------------------------------------------------+
66 * Wait for 'DRAM initialization complete' bit in status register
67 * -------------------------------------------------------------*/
68 mtdcr(ddrcfga, DDR0_00);
70 while (wait != 0xffff) {
72 if ((val & DDR0_00_INT_STATUS_BIT6) == DDR0_00_INT_STATUS_BIT6)
73 /* 'DRAM initialization complete' bit */
78 debug("DRAM initialization complete bit in status register did not "
86 /*-----------------------------------------------------------------------------+
87 * denali_core_search_data_eye.
88 +----------------------------------------------------------------------------*/
89 void denali_core_search_data_eye(void)
93 u32 wr_dqs_shift, dqs_out_shift, dll_dqs_delay_X;
94 u32 max_passing_cases = 0, wr_dqs_shift_with_max_passing_cases = 0;
95 u32 passing_cases = 0, dll_dqs_delay_X_sw_val = 0;
96 u32 dll_dqs_delay_X_start_window = 0, dll_dqs_delay_X_end_window = 0;
97 volatile u32 *ram_pointer;
98 u32 test[NUM_TRIES] = {
99 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
100 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
101 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
102 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
103 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
104 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
105 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
106 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
107 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
108 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
109 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
110 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
111 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
112 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
113 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
114 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55
117 ram_pointer = (volatile u32 *)(CONFIG_SYS_SDRAM_BASE);
119 for (wr_dqs_shift = 64; wr_dqs_shift < 96; wr_dqs_shift++) {
120 /* for (wr_dqs_shift=1; wr_dqs_shift<96; wr_dqs_shift++) { */
122 /* -----------------------------------------------------------+
123 * De-assert 'start' parameter.
124 * ----------------------------------------------------------*/
125 mtdcr(ddrcfga, DDR0_02);
126 val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
130 /* -----------------------------------------------------------+
132 * ----------------------------------------------------------*/
133 mtdcr(ddrcfga, DDR0_09);
134 val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK) |
135 DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
138 /* -----------------------------------------------------------+
139 * Set 'dqs_out_shift' = wr_dqs_shift + 32
140 * ----------------------------------------------------------*/
141 dqs_out_shift = wr_dqs_shift + 32;
142 mtdcr(ddrcfga, DDR0_22);
143 val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK) |
144 DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
149 for (dll_dqs_delay_X = 1; dll_dqs_delay_X < 64;
151 /* for (dll_dqs_delay_X=1; dll_dqs_delay_X<128;
152 dll_dqs_delay_X++) { */
153 /* -----------------------------------------------------------+
154 * Set 'dll_dqs_delay_X'.
155 * ----------------------------------------------------------*/
156 /* dll_dqs_delay_0 */
157 mtdcr(ddrcfga, DDR0_17);
158 val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
159 | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
161 /* dll_dqs_delay_1 to dll_dqs_delay_4 */
162 mtdcr(ddrcfga, DDR0_18);
163 val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
164 | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
165 | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
166 | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
167 | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
169 /* dll_dqs_delay_5 to dll_dqs_delay_8 */
170 mtdcr(ddrcfga, DDR0_19);
171 val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
172 | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
173 | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
174 | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
175 | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
177 /* clear any ECC errors */
178 mtdcr(ddrcfga, DDR0_00);
180 mfdcr(ddrcfgd) | DDR0_00_INT_ACK_ENCODE(0x3C));
185 /* -----------------------------------------------------------+
186 * Assert 'start' parameter.
187 * ----------------------------------------------------------*/
188 mtdcr(ddrcfga, DDR0_02);
189 val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
196 /* -----------------------------------------------------------+
197 * Wait for the DCC master delay line to finish calibration
198 * ----------------------------------------------------------*/
199 if (denali_wait_for_dlllock() != 0) {
200 printf("dll lock did not occur !!!\n");
201 printf("denali_core_search_data_eye!!!\n");
202 printf("wr_dqs_shift = %d - dll_dqs_delay_X = "
203 "%d\n", wr_dqs_shift, dll_dqs_delay_X);
209 if (wait_for_dram_init_complete() != 0) {
210 printf("dram init complete did not occur!!!\n");
211 printf("denali_core_search_data_eye!!!\n");
212 printf("wr_dqs_shift = %d - dll_dqs_delay_X = "
213 "%d\n", wr_dqs_shift, dll_dqs_delay_X);
216 udelay(100); /* wait 100us to ensure init is really completed !!! */
219 for (j = 0; j < NUM_TRIES; j++) {
220 ram_pointer[j] = test[j];
222 /* clear any cache at ram location */
223 __asm__("dcbf 0,%0": :"r"(&ram_pointer[j]));
226 /* read values back */
227 for (j = 0; j < NUM_TRIES; j++) {
228 for (k = 0; k < NUM_READS; k++) {
229 /* clear any cache at ram location */
230 __asm__("dcbf 0,%0": :"r"(&ram_pointer
233 if (ram_pointer[j] != test[j])
242 /* See if the dll_dqs_delay_X value passed. */
243 mtdcr(ddrcfga, DDR0_00);
245 || (DDR0_00_INT_STATUS_DECODE(mfdcr(ddrcfgd)) &
252 if (passing_cases == 0)
253 dll_dqs_delay_X_sw_val =
256 if (passing_cases >= max_passing_cases) {
257 max_passing_cases = passing_cases;
258 wr_dqs_shift_with_max_passing_cases =
260 dll_dqs_delay_X_start_window =
261 dll_dqs_delay_X_sw_val;
262 dll_dqs_delay_X_end_window =
267 /* -----------------------------------------------------------+
268 * De-assert 'start' parameter.
269 * ----------------------------------------------------------*/
270 mtdcr(ddrcfga, DDR0_02);
271 val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
274 } /* for (dll_dqs_delay_X=0; dll_dqs_delay_X<128; dll_dqs_delay_X++) */
275 } /* for (wr_dqs_shift=0; wr_dqs_shift<96; wr_dqs_shift++) */
277 /* -----------------------------------------------------------+
278 * Largest passing window is now detected.
279 * ----------------------------------------------------------*/
281 /* Compute dll_dqs_delay_X value */
282 dll_dqs_delay_X = (dll_dqs_delay_X_end_window +
283 dll_dqs_delay_X_start_window) / 2;
284 wr_dqs_shift = wr_dqs_shift_with_max_passing_cases;
286 debug("DQS calibration - Window detected:\n");
287 debug("max_passing_cases = %d\n", max_passing_cases);
288 debug("wr_dqs_shift = %d\n", wr_dqs_shift);
289 debug("dll_dqs_delay_X = %d\n", dll_dqs_delay_X);
290 debug("dll_dqs_delay_X window = %d - %d\n",
291 dll_dqs_delay_X_start_window, dll_dqs_delay_X_end_window);
293 /* -----------------------------------------------------------+
294 * De-assert 'start' parameter.
295 * ----------------------------------------------------------*/
296 mtdcr(ddrcfga, DDR0_02);
297 val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF;
300 /* -----------------------------------------------------------+
302 * ----------------------------------------------------------*/
303 mtdcr(ddrcfga, DDR0_09);
304 val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK)
305 | DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
307 debug("DDR0_09=0x%08x\n", val);
309 /* -----------------------------------------------------------+
310 * Set 'dqs_out_shift' = wr_dqs_shift + 32
311 * ----------------------------------------------------------*/
312 dqs_out_shift = wr_dqs_shift + 32;
313 mtdcr(ddrcfga, DDR0_22);
314 val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK)
315 | DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
317 debug("DDR0_22=0x%08x\n", val);
319 /* -----------------------------------------------------------+
320 * Set 'dll_dqs_delay_X'.
321 * ----------------------------------------------------------*/
322 /* dll_dqs_delay_0 */
323 mtdcr(ddrcfga, DDR0_17);
324 val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
325 | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
327 debug("DDR0_17=0x%08x\n", val);
329 /* dll_dqs_delay_1 to dll_dqs_delay_4 */
330 mtdcr(ddrcfga, DDR0_18);
331 val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
332 | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
333 | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
334 | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
335 | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
337 debug("DDR0_18=0x%08x\n", val);
339 /* dll_dqs_delay_5 to dll_dqs_delay_8 */
340 mtdcr(ddrcfga, DDR0_19);
341 val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
342 | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
343 | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
344 | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
345 | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
347 debug("DDR0_19=0x%08x\n", val);
349 /* -----------------------------------------------------------+
350 * Assert 'start' parameter.
351 * ----------------------------------------------------------*/
352 mtdcr(ddrcfga, DDR0_02);
353 val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_ON;
359 /* -----------------------------------------------------------+
360 * Wait for the DCC master delay line to finish calibration
361 * ----------------------------------------------------------*/
362 if (denali_wait_for_dlllock() != 0) {
363 printf("dll lock did not occur !!!\n");
369 if (wait_for_dram_init_complete() != 0) {
370 printf("dram init complete did not occur !!!\n");
373 udelay(100); /* wait 100us to ensure init is really completed !!! */
375 #endif /* defined(CONFIG_DDR_DATA_EYE) */
376 #endif /* defined(CONFIG_440EPX) || defined(CONFIG_440GRX) */