f0c12edfe7188eb643440b961da6fb97cf37b3ce
[litex.git] / litex / soc / software / bios / sdram.c
1 // This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq <sb@m-labs.hk>
2 // This file is Copyright (c) 2013-2019 Florent Kermarrec <florent@enjoy-digital.fr>
3 // This file is Copyright (c) 2018 Chris Ballance <chris.ballance@physics.ox.ac.uk>
4 // This file is Copyright (c) 2018 Dolu1990 <charles.papon.90@gmail.com>
5 // This file is Copyright (c) 2019 Gabriel L. Somlo <gsomlo@gmail.com>
6 // This file is Copyright (c) 2018 Jean-François Nguyen <jf@lambdaconcept.fr>
7 // This file is Copyright (c) 2018 Sergiusz Bazanski <q3k@q3k.org>
8 // This file is Copyright (c) 2018 Tim 'mithro' Ansell <me@mith.ro>
9 // License: BSD
10
11 #include <generated/csr.h>
12
13 #include <stdio.h>
14 #include <stdlib.h>
15
16 #ifdef CSR_SDRAM_BASE
17 #include <generated/sdram_phy.h>
18 #endif
19 #include <generated/mem.h>
20 #include <hw/flags.h>
21 #include <system.h>
22
23 #include "sdram.h"
24
25 // FIXME(hack): If we don't have main ram, just target the sram instead.
26 #ifndef MAIN_RAM_BASE
27 #define MAIN_RAM_BASE SRAM_BASE
28 #endif
29
30 __attribute__((unused)) static void cdelay(int i)
31 {
32 while(i > 0) {
33 #if defined (__lm32__)
34 __asm__ volatile("nop");
35 #elif defined (__or1k__)
36 __asm__ volatile("l.nop");
37 #elif defined (__picorv32__)
38 __asm__ volatile("nop");
39 #elif defined (__vexriscv__)
40 __asm__ volatile("nop");
41 #elif defined (__minerva__)
42 __asm__ volatile("nop");
43 #elif defined (__rocket__)
44 __asm__ volatile("nop");
45 #elif defined (__powerpc__)
46 __asm__ volatile("nop");
47 #else
48 #error Unsupported architecture
49 #endif
50 i--;
51 }
52 }
53
54 #ifdef CSR_SDRAM_BASE
55
56 #define DFII_ADDR_SHIFT CONFIG_CSR_ALIGNMENT/8
57
58 void sdrsw(void)
59 {
60 sdram_dfii_control_write(DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N);
61 printf("SDRAM now under software control\n");
62 }
63
64 void sdrhw(void)
65 {
66 sdram_dfii_control_write(DFII_CONTROL_SEL);
67 printf("SDRAM now under hardware control\n");
68 }
69
70 void sdrrow(char *_row)
71 {
72 char *c;
73 unsigned int row;
74
75 if(*_row == 0) {
76 sdram_dfii_pi0_address_write(0x0000);
77 sdram_dfii_pi0_baddress_write(0);
78 command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
79 cdelay(15);
80 printf("Precharged\n");
81 } else {
82 row = strtoul(_row, &c, 0);
83 if(*c != 0) {
84 printf("incorrect row\n");
85 return;
86 }
87 sdram_dfii_pi0_address_write(row);
88 sdram_dfii_pi0_baddress_write(0);
89 command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CS);
90 cdelay(15);
91 printf("Activated row %d\n", row);
92 }
93 }
94
95 void sdrrdbuf(int dq)
96 {
97 int i, p;
98 int first_byte, step;
99
100 if(dq < 0) {
101 first_byte = 0;
102 step = 1;
103 } else {
104 first_byte = DFII_PIX_DATA_SIZE/2 - 1 - dq;
105 step = DFII_PIX_DATA_SIZE/2;
106 }
107
108 for(p=0;p<DFII_NPHASES;p++)
109 for(i=first_byte;i<DFII_PIX_DATA_SIZE;i+=step)
110 printf("%02x", MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*i));
111 printf("\n");
112 }
113
114 void sdrrd(char *startaddr, char *dq)
115 {
116 char *c;
117 unsigned int addr;
118 int _dq;
119
120 if(*startaddr == 0) {
121 printf("sdrrd <address>\n");
122 return;
123 }
124 addr = strtoul(startaddr, &c, 0);
125 if(*c != 0) {
126 printf("incorrect address\n");
127 return;
128 }
129 if(*dq == 0)
130 _dq = -1;
131 else {
132 _dq = strtoul(dq, &c, 0);
133 if(*c != 0) {
134 printf("incorrect DQ\n");
135 return;
136 }
137 }
138
139 sdram_dfii_pird_address_write(addr);
140 sdram_dfii_pird_baddress_write(0);
141 command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
142 cdelay(15);
143 sdrrdbuf(_dq);
144 }
145
146 void sdrrderr(char *count)
147 {
148 int addr;
149 char *c;
150 int _count;
151 int i, j, p;
152 unsigned char prev_data[DFII_NPHASES*DFII_PIX_DATA_SIZE];
153 unsigned char errs[DFII_NPHASES*DFII_PIX_DATA_SIZE];
154
155 if(*count == 0) {
156 printf("sdrrderr <count>\n");
157 return;
158 }
159 _count = strtoul(count, &c, 0);
160 if(*c != 0) {
161 printf("incorrect count\n");
162 return;
163 }
164
165 for(i=0;i<DFII_NPHASES*DFII_PIX_DATA_SIZE;i++)
166 errs[i] = 0;
167 for(addr=0;addr<16;addr++) {
168 sdram_dfii_pird_address_write(addr*8);
169 sdram_dfii_pird_baddress_write(0);
170 command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
171 cdelay(15);
172 for(p=0;p<DFII_NPHASES;p++)
173 for(i=0;i<DFII_PIX_DATA_SIZE;i++)
174 prev_data[p*DFII_PIX_DATA_SIZE+i] = MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*i);
175
176 for(j=0;j<_count;j++) {
177 command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
178 cdelay(15);
179 for(p=0;p<DFII_NPHASES;p++)
180 for(i=0;i<DFII_PIX_DATA_SIZE;i++) {
181 unsigned char new_data;
182
183 new_data = MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*i);
184 errs[p*DFII_PIX_DATA_SIZE+i] |= prev_data[p*DFII_PIX_DATA_SIZE+i] ^ new_data;
185 prev_data[p*DFII_PIX_DATA_SIZE+i] = new_data;
186 }
187 }
188 }
189
190 for(i=0;i<DFII_NPHASES*DFII_PIX_DATA_SIZE;i++)
191 printf("%02x", errs[i]);
192 printf("\n");
193 for(p=0;p<DFII_NPHASES;p++)
194 for(i=0;i<DFII_PIX_DATA_SIZE;i++)
195 printf("%2x", DFII_PIX_DATA_SIZE/2 - 1 - (i % (DFII_PIX_DATA_SIZE/2)));
196 printf("\n");
197 }
198
199 void sdrwr(char *startaddr)
200 {
201 char *c;
202 unsigned int addr;
203 int i;
204 int p;
205
206 if(*startaddr == 0) {
207 printf("sdrrd <address>\n");
208 return;
209 }
210 addr = strtoul(startaddr, &c, 0);
211 if(*c != 0) {
212 printf("incorrect address\n");
213 return;
214 }
215
216 for(p=0;p<DFII_NPHASES;p++)
217 for(i=0;i<DFII_PIX_DATA_SIZE;i++)
218 MMPTR(sdram_dfii_pix_wrdata_addr[p]+DFII_ADDR_SHIFT*i) = 0x10*p + i;
219
220 sdram_dfii_piwr_address_write(addr);
221 sdram_dfii_piwr_baddress_write(0);
222 command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA);
223 }
224
225 #ifdef CSR_DDRPHY_BASE
226
227 #if defined (USDDRPHY)
228 #define ERR_DDRPHY_DELAY 512
229 #define ERR_DDRPHY_BITSLIP 8
230 #define NBMODULES DFII_PIX_DATA_SIZE/2
231 #elif defined (ECP5DDRPHY)
232 #define ERR_DDRPHY_DELAY 8
233 #define ERR_DDRPHY_BITSLIP 1
234 #define NBMODULES DFII_PIX_DATA_SIZE/4
235 #else
236 #define ERR_DDRPHY_DELAY 32
237 #define ERR_DDRPHY_BITSLIP 8
238 #define NBMODULES DFII_PIX_DATA_SIZE/2
239 #endif
240
241 #ifdef CSR_DDRPHY_WLEVEL_EN_ADDR
242
243 void sdrwlon(void)
244 {
245 sdram_dfii_pi0_address_write(DDRX_MR1 | (1 << 7));
246 sdram_dfii_pi0_baddress_write(1);
247 command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
248 ddrphy_wlevel_en_write(1);
249 }
250
251 void sdrwloff(void)
252 {
253 sdram_dfii_pi0_address_write(DDRX_MR1);
254 sdram_dfii_pi0_baddress_write(1);
255 command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
256 ddrphy_wlevel_en_write(0);
257 }
258
259 static void write_delay_rst(int module) {
260 #ifdef USDDRPHY
261 int i;
262 #endif
263
264 /* sel module */
265 ddrphy_dly_sel_write(1 << module);
266
267 /* rst delay */
268 ddrphy_wdly_dq_rst_write(1);
269 ddrphy_wdly_dqs_rst_write(1);
270 #ifdef USDDRPHY /* need to init manually on Ultrascale */
271 for(i=0; i<ddrphy_half_sys8x_taps_read(); i++)
272 ddrphy_wdly_dqs_inc_write(1);
273 #endif
274
275 /* unsel module */
276 ddrphy_dly_sel_write(0);
277 }
278
279 static void write_delay_inc(int module) {
280 /* sel module */
281 ddrphy_dly_sel_write(1 << module);
282
283 /* inc delay */
284 ddrphy_wdly_dq_inc_write(1);
285 ddrphy_wdly_dqs_inc_write(1);
286
287 /* unsel module */
288 ddrphy_dly_sel_write(0);
289 }
290
291 int write_level(void)
292 {
293 int i, j, k;
294
295 int dq_address;
296 unsigned char dq;
297
298 int err_ddrphy_wdly;
299
300 unsigned char taps_scan[ERR_DDRPHY_DELAY];
301
302 int one_window_active;
303 int one_window_start, one_window_best_start;
304 int one_window_count, one_window_best_count;
305
306 int delays[NBMODULES];
307
308 int ok;
309
310 err_ddrphy_wdly = ERR_DDRPHY_DELAY - ddrphy_half_sys8x_taps_read();
311
312 printf("Write leveling:\n");
313
314 sdrwlon();
315 cdelay(100);
316 for(i=0;i<NBMODULES;i++) {
317 printf("m%d: |", i);
318 dq_address = sdram_dfii_pix_rddata_addr[0]+DFII_ADDR_SHIFT*(NBMODULES-1-i);
319
320 /* rst delay */
321 write_delay_rst(i);
322
323 /* scan write delay taps */
324 for(j=0;j<err_ddrphy_wdly;j++) {
325 int zero_count = 0;
326 int one_count = 0;
327 int show = 1;
328 #ifdef USDDRPHY
329 show = (j%16 == 0);
330 #endif
331 for (k=0; k<128; k++) {
332 ddrphy_wlevel_strobe_write(1);
333 cdelay(10);
334 dq = MMPTR(dq_address);
335 if (dq != 0)
336 one_count++;
337 else
338 zero_count++;
339 }
340 if (one_count > zero_count)
341 taps_scan[j] = 1;
342 else
343 taps_scan[j] = 0;
344 if (show)
345 printf("%d", taps_scan[j]);
346 write_delay_inc(i);
347 cdelay(10);
348 }
349 printf("|");
350
351 /* find longer 1 window and set delay at the 0/1 transition */
352 one_window_active = 0;
353 one_window_start = 0;
354 one_window_count = 0;
355 one_window_best_start = 0;
356 one_window_best_count = 0;
357 delays[i] = -1;
358 for(j=0;j<err_ddrphy_wdly;j++) {
359 if (one_window_active) {
360 if ((taps_scan[j] == 0) | (j == err_ddrphy_wdly - 1)) {
361 one_window_active = 0;
362 one_window_count = j - one_window_start;
363 if (one_window_count > one_window_best_count) {
364 one_window_best_start = one_window_start;
365 one_window_best_count = one_window_count;
366 }
367 }
368 } else {
369 if (taps_scan[j]) {
370 one_window_active = 1;
371 one_window_start = j;
372 }
373 }
374 }
375 delays[i] = one_window_best_start;
376
377 /* configure write delay */
378 write_delay_rst(i);
379 for(j=0; j<delays[i]; j++)
380 write_delay_inc(i);
381 printf(" delay: %02d\n", delays[i]);
382 }
383
384 sdrwloff();
385
386 ok = 1;
387 for(i=NBMODULES-1;i>=0;i--) {
388 if(delays[i] < 0)
389 ok = 0;
390 }
391
392 return ok;
393 }
394
395 #endif /* CSR_DDRPHY_WLEVEL_EN_ADDR */
396
397 static void read_delay_rst(int module) {
398 /* sel module */
399 ddrphy_dly_sel_write(1 << module);
400
401 /* rst delay */
402 ddrphy_rdly_dq_rst_write(1);
403
404 /* unsel module */
405 ddrphy_dly_sel_write(0);
406 }
407
408 static void read_delay_inc(int module) {
409 /* sel module */
410 ddrphy_dly_sel_write(1 << module);
411
412 /* inc delay */
413 ddrphy_rdly_dq_inc_write(1);
414
415 /* unsel module */
416 ddrphy_dly_sel_write(0);
417 }
418
419 static void read_bitslip_rst(char m)
420 {
421 /* sel module */
422 ddrphy_dly_sel_write(1 << m);
423
424 /* inc delay */
425 ddrphy_rdly_dq_bitslip_rst_write(1);
426
427 /* unsel module */
428 ddrphy_dly_sel_write(0);
429 }
430
431
432 static void read_bitslip_inc(char m)
433 {
434 /* sel module */
435 ddrphy_dly_sel_write(1 << m);
436
437 /* inc delay */
438 ddrphy_rdly_dq_bitslip_write(1);
439
440 /* unsel module */
441 ddrphy_dly_sel_write(0);
442 }
443
444 static int read_level_scan(int module, int bitslip)
445 {
446 unsigned int prv;
447 unsigned char prs[DFII_NPHASES*DFII_PIX_DATA_SIZE];
448 int p, i, j;
449 int score;
450
451 /* Generate pseudo-random sequence */
452 prv = 42;
453 for(i=0;i<DFII_NPHASES*DFII_PIX_DATA_SIZE;i++) {
454 prv = 1664525*prv + 1013904223;
455 prs[i] = prv;
456 }
457
458 /* Activate */
459 sdram_dfii_pi0_address_write(0);
460 sdram_dfii_pi0_baddress_write(0);
461 command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CS);
462 cdelay(15);
463
464 /* Write test pattern */
465 for(p=0;p<DFII_NPHASES;p++)
466 for(i=0;i<DFII_PIX_DATA_SIZE;i++)
467 MMPTR(sdram_dfii_pix_wrdata_addr[p]+DFII_ADDR_SHIFT*i) = prs[DFII_PIX_DATA_SIZE*p+i];
468 sdram_dfii_piwr_address_write(0);
469 sdram_dfii_piwr_baddress_write(0);
470 command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA);
471
472 /* Calibrate each DQ in turn */
473 sdram_dfii_pird_address_write(0);
474 sdram_dfii_pird_baddress_write(0);
475 score = 0;
476
477 printf("m%d, b%d: |", module, bitslip);
478 read_delay_rst(module);
479 for(j=0; j<ERR_DDRPHY_DELAY;j++) {
480 int working;
481 int show = 1;
482 #ifdef USDDRPHY
483 show = (j%16 == 0);
484 #endif
485 #ifdef ECP5DDRPHY
486 ddrphy_burstdet_clr_write(1);
487 #endif
488 command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
489 cdelay(15);
490 working = 1;
491 for(p=0;p<DFII_NPHASES;p++) {
492 if(MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*(NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+(NBMODULES-module-1)])
493 working = 0;
494 if(MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*(2*NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+2*NBMODULES-module-1])
495 working = 0;
496 }
497 #ifdef ECP5DDRPHY
498 if (((ddrphy_burstdet_seen_read() >> module) & 0x1) != 1)
499 working = 0;
500 #endif
501 if (show)
502 printf("%d", working);
503 score += working;
504 read_delay_inc(module);
505 }
506 printf("| ");
507
508 /* Precharge */
509 sdram_dfii_pi0_address_write(0);
510 sdram_dfii_pi0_baddress_write(0);
511 command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
512 cdelay(15);
513
514 return score;
515 }
516
517 static void read_level(int module)
518 {
519 unsigned int prv;
520 unsigned char prs[DFII_NPHASES*DFII_PIX_DATA_SIZE];
521 int p, i, j;
522 int working;
523 int delay, delay_min, delay_max;
524
525 printf("delays: ");
526
527 /* Generate pseudo-random sequence */
528 prv = 42;
529 for(i=0;i<DFII_NPHASES*DFII_PIX_DATA_SIZE;i++) {
530 prv = 1664525*prv + 1013904223;
531 prs[i] = prv;
532 }
533
534 /* Activate */
535 sdram_dfii_pi0_address_write(0);
536 sdram_dfii_pi0_baddress_write(0);
537 command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CS);
538 cdelay(15);
539
540 /* Write test pattern */
541 for(p=0;p<DFII_NPHASES;p++)
542 for(i=0;i<DFII_PIX_DATA_SIZE;i++)
543 MMPTR(sdram_dfii_pix_wrdata_addr[p]+DFII_ADDR_SHIFT*i) = prs[DFII_PIX_DATA_SIZE*p+i];
544 sdram_dfii_piwr_address_write(0);
545 sdram_dfii_piwr_baddress_write(0);
546 command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA);
547
548 /* Calibrate each DQ in turn */
549 sdram_dfii_pird_address_write(0);
550 sdram_dfii_pird_baddress_write(0);
551
552 /* Find smallest working delay */
553 delay = 0;
554 read_delay_rst(module);
555 while(1) {
556 #ifdef ECP5DDRPHY
557 ddrphy_burstdet_clr_write(1);
558 #endif
559 command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
560 cdelay(15);
561 working = 1;
562 for(p=0;p<DFII_NPHASES;p++) {
563 if(MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*(NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+(NBMODULES-module-1)])
564 working = 0;
565 if(MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*(2*NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+2*NBMODULES-module-1])
566 working = 0;
567 }
568 #ifdef ECP5DDRPHY
569 if (((ddrphy_burstdet_seen_read() >> module) & 0x1) != 1)
570 working = 0;
571 #endif
572 if(working)
573 break;
574 delay++;
575 if(delay >= ERR_DDRPHY_DELAY)
576 break;
577 read_delay_inc(module);
578 }
579 delay_min = delay;
580
581 /* Get a bit further into the working zone */
582 #ifdef USDDRPHY
583 for(j=0;j<16;j++) {
584 delay += 1;
585 read_delay_inc(module);
586 }
587 #else
588 delay++;
589 read_delay_inc(module);
590 #endif
591
592 /* Find largest working delay */
593 while(1) {
594 #ifdef ECP5DDRPHY
595 ddrphy_burstdet_clr_write(1);
596 #endif
597 command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
598 cdelay(15);
599 working = 1;
600 for(p=0;p<DFII_NPHASES;p++) {
601 if(MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*(NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+(NBMODULES-module-1)])
602 working = 0;
603 if(MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*(2*NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+2*NBMODULES-module-1])
604 working = 0;
605 }
606 #ifdef ECP5DDRPHY
607 if (((ddrphy_burstdet_seen_read() >> module) & 0x1) != 1)
608 working = 0;
609 #endif
610 if(!working)
611 break;
612 delay++;
613 if(delay >= ERR_DDRPHY_DELAY)
614 break;
615 read_delay_inc(module);
616 }
617 delay_max = delay;
618
619 if (delay_min >= ERR_DDRPHY_DELAY)
620 printf("-");
621 else
622 printf("%02d+-%02d", (delay_min+delay_max)/2, (delay_max-delay_min)/2);
623
624 /* Set delay to the middle */
625 read_delay_rst(module);
626 for(j=0;j<(delay_min+delay_max)/2;j++)
627 read_delay_inc(module);
628
629 /* Precharge */
630 sdram_dfii_pi0_address_write(0);
631 sdram_dfii_pi0_baddress_write(0);
632 command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
633 cdelay(15);
634 }
635 #endif /* CSR_DDRPHY_BASE */
636
637 #endif /* CSR_SDRAM_BASE */
638
639 static unsigned int seed_to_data_32(unsigned int seed, int random)
640 {
641 if (random)
642 return 1664525*seed + 1013904223;
643 else
644 return seed + 1;
645 }
646
647 static unsigned short seed_to_data_16(unsigned short seed, int random)
648 {
649 if (random)
650 return 25173*seed + 13849;
651 else
652 return seed + 1;
653 }
654
655 #define ONEZERO 0xAAAAAAAA
656 #define ZEROONE 0x55555555
657
658 #ifndef MEMTEST_BUS_SIZE
659 #define MEMTEST_BUS_SIZE (512)
660 #endif
661
662 //#define MEMTEST_BUS_DEBUG
663
664 static int memtest_bus(void)
665 {
666 volatile unsigned int *array = (unsigned int *)MAIN_RAM_BASE;
667 int i, errors;
668 unsigned int rdata;
669
670 errors = 0;
671
672 for(i=0;i<MEMTEST_BUS_SIZE/4;i++) {
673 array[i] = ONEZERO;
674 }
675 flush_cpu_dcache();
676 #ifdef CONFIG_L2_SIZE
677 flush_l2_cache();
678 #endif
679 for(i=0;i<MEMTEST_BUS_SIZE/4;i++) {
680 rdata = array[i];
681 if(rdata != ONEZERO) {
682 errors++;
683 #ifdef MEMTEST_BUS_DEBUG
684 printf("[bus: 0x%0x]: 0x%08x vs 0x%08x\n", i, rdata, ONEZERO);
685 #endif
686 }
687 }
688
689 for(i=0;i<MEMTEST_BUS_SIZE/4;i++) {
690 array[i] = ZEROONE;
691 }
692 flush_cpu_dcache();
693 #ifdef CONFIG_L2_SIZE
694 flush_l2_cache();
695 #endif
696 for(i=0;i<MEMTEST_BUS_SIZE/4;i++) {
697 rdata = array[i];
698 if(rdata != ZEROONE) {
699 errors++;
700 #ifdef MEMTEST_BUS_DEBUG
701 printf("[bus 0x%0x]: 0x%08x vs 0x%08x\n", i, rdata, ZEROONE);
702 #endif
703 }
704 }
705
706 return errors;
707 }
708
709 #ifndef MEMTEST_DATA_SIZE
710 #define MEMTEST_DATA_SIZE (2*1024*1024)
711 #endif
712 #define MEMTEST_DATA_RANDOM 1
713
714 //#define MEMTEST_DATA_DEBUG
715
716 static int memtest_data(void)
717 {
718 volatile unsigned int *array = (unsigned int *)MAIN_RAM_BASE;
719 int i, errors;
720 unsigned int seed_32;
721 unsigned int rdata;
722
723 errors = 0;
724 seed_32 = 0;
725
726 for(i=0;i<MEMTEST_DATA_SIZE/4;i++) {
727 seed_32 = seed_to_data_32(seed_32, MEMTEST_DATA_RANDOM);
728 array[i] = seed_32;
729 }
730
731 seed_32 = 0;
732 flush_cpu_dcache();
733 #ifdef CONFIG_L2_SIZE
734 flush_l2_cache();
735 #endif
736 for(i=0;i<MEMTEST_DATA_SIZE/4;i++) {
737 seed_32 = seed_to_data_32(seed_32, MEMTEST_DATA_RANDOM);
738 rdata = array[i];
739 if(rdata != seed_32) {
740 errors++;
741 #ifdef MEMTEST_DATA_DEBUG
742 printf("[data 0x%0x]: 0x%08x vs 0x%08x\n", i, rdata, seed_32);
743 #endif
744 }
745 }
746
747 return errors;
748 }
749 #ifndef MEMTEST_ADDR_SIZE
750 #define MEMTEST_ADDR_SIZE (32*1024)
751 #endif
752 #define MEMTEST_ADDR_RANDOM 0
753
754 //#define MEMTEST_ADDR_DEBUG
755
756 static int memtest_addr(void)
757 {
758 volatile unsigned int *array = (unsigned int *)MAIN_RAM_BASE;
759 int i, errors;
760 unsigned short seed_16;
761 unsigned short rdata;
762
763 errors = 0;
764 seed_16 = 0;
765
766 for(i=0;i<MEMTEST_ADDR_SIZE/4;i++) {
767 seed_16 = seed_to_data_16(seed_16, MEMTEST_ADDR_RANDOM);
768 array[(unsigned int) seed_16] = i;
769 }
770
771 seed_16 = 0;
772 flush_cpu_dcache();
773 #ifdef CONFIG_L2_SIZE
774 flush_l2_cache();
775 #endif
776 for(i=0;i<MEMTEST_ADDR_SIZE/4;i++) {
777 seed_16 = seed_to_data_16(seed_16, MEMTEST_ADDR_RANDOM);
778 rdata = array[(unsigned int) seed_16];
779 if(rdata != i) {
780 errors++;
781 #ifdef MEMTEST_ADDR_DEBUG
782 printf("[addr 0x%0x]: 0x%08x vs 0x%08x\n", i, rdata, i);
783 #endif
784 }
785 }
786
787 return errors;
788 }
789
790 int memtest(void)
791 {
792 int bus_errors, data_errors, addr_errors;
793
794 bus_errors = memtest_bus();
795 if(bus_errors != 0)
796 printf("Memtest bus failed: %d/%d errors\n", bus_errors, 2*128);
797
798 data_errors = memtest_data();
799 if(data_errors != 0)
800 printf("Memtest data failed: %d/%d errors\n", data_errors, MEMTEST_DATA_SIZE/4);
801
802 addr_errors = memtest_addr();
803 if(addr_errors != 0)
804 printf("Memtest addr failed: %d/%d errors\n", addr_errors, MEMTEST_ADDR_SIZE/4);
805
806 if(bus_errors + data_errors + addr_errors != 0)
807 return 0;
808 else {
809 printf("Memtest OK\n");
810 return 1;
811 }
812 }
813
814 #ifdef CSR_SDRAM_BASE
815
816 #ifdef CSR_DDRPHY_BASE
817 int sdrlevel(void)
818 {
819 int module;
820 int bitslip;
821 int score;
822 int best_score;
823 int best_bitslip;
824
825 sdrsw();
826
827 for(module=0; module<NBMODULES; module++) {
828 #ifdef CSR_DDRPHY_WLEVEL_EN_ADDR
829 write_delay_rst(module);
830 #endif
831 read_delay_rst(module);
832 read_bitslip_rst(module);
833 }
834
835 #ifdef CSR_DDRPHY_WLEVEL_EN_ADDR
836 if(!write_level())
837 return 0;
838 #endif
839
840 printf("Read leveling:\n");
841 for(module=0; module<NBMODULES; module++) {
842 /* scan possible read windows */
843 best_score = 0;
844 best_bitslip = 0;
845 for(bitslip=0; bitslip<ERR_DDRPHY_BITSLIP; bitslip++) {
846 /* compute score */
847 score = read_level_scan(module, bitslip);
848 read_level(module);
849 printf("\n");
850 if (score > best_score) {
851 best_bitslip = bitslip;
852 best_score = score;
853 }
854 /* exit */
855 if (bitslip == ERR_DDRPHY_BITSLIP-1)
856 break;
857 /* increment bitslip */
858 read_bitslip_inc(module);
859 }
860
861 /* select best read window */
862 printf("best: m%d, b%d ", module, best_bitslip);
863 read_bitslip_rst(module);
864 for (bitslip=0; bitslip<best_bitslip; bitslip++)
865 read_bitslip_inc(module);
866
867 /* re-do leveling on best read window*/
868 read_level(module);
869 printf("\n");
870 }
871
872 return 1;
873 }
874 #endif
875
876 int sdrinit(void)
877 {
878 printf("Initializing SDRAM...\n");
879
880 #ifdef CSR_DDRCTRL_BASE
881 ddrctrl_init_done_write(0);
882 ddrctrl_init_error_write(0);
883 #endif
884
885 init_sequence();
886 #ifdef CSR_DDRPHY_BASE
887 #if CSR_DDRPHY_EN_VTC_ADDR
888 ddrphy_en_vtc_write(0);
889 #endif
890 sdrlevel();
891 #if CSR_DDRPHY_EN_VTC_ADDR
892 ddrphy_en_vtc_write(1);
893 #endif
894 #endif
895 sdrhw();
896 if(!memtest()) {
897 #ifdef CSR_DDRCTRL_BASE
898 ddrctrl_init_done_write(1);
899 ddrctrl_init_error_write(1);
900 #endif
901 return 0;
902 }
903 #ifdef CSR_DDRCTRL_BASE
904 ddrctrl_init_done_write(1);
905 #endif
906
907 return 1;
908 }
909
910 #endif