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