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) */