1 #include <generated/csr.h>
7 #include <generated/sdram_phy.h>
9 #include <generated/mem.h>
15 // FIXME(hack): If we don't have main ram, just target the sram instead.
17 #define MAIN_RAM_BASE SRAM_BASE
20 static void cdelay(int i
)
23 #if defined (__lm32__)
24 __asm__
volatile("nop");
25 #elif defined (__or1k__)
26 __asm__
volatile("l.nop");
27 #elif defined (__picorv32__)
28 __asm__
volatile("nop");
29 #elif defined (__vexriscv__)
30 __asm__
volatile("nop");
31 #elif defined (__minerva__)
32 __asm__
volatile("nop");
34 #error Unsupported architecture
44 sdram_dfii_control_write(DFII_CONTROL_CKE
|DFII_CONTROL_ODT
|DFII_CONTROL_RESET_N
);
45 printf("SDRAM now under software control\n");
50 sdram_dfii_control_write(DFII_CONTROL_SEL
);
51 printf("SDRAM now under hardware control\n");
54 void sdrrow(char *_row
)
60 sdram_dfii_pi0_address_write(0x0000);
61 sdram_dfii_pi0_baddress_write(0);
62 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
);
64 printf("Precharged\n");
66 row
= strtoul(_row
, &c
, 0);
68 printf("incorrect row\n");
71 sdram_dfii_pi0_address_write(row
);
72 sdram_dfii_pi0_baddress_write(0);
73 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_CS
);
75 printf("Activated row %d\n", row
);
88 first_byte
= DFII_PIX_DATA_SIZE
/2 - 1 - dq
;
89 step
= DFII_PIX_DATA_SIZE
/2;
92 for(p
=0;p
<DFII_NPHASES
;p
++)
93 for(i
=first_byte
;i
<DFII_PIX_DATA_SIZE
;i
+=step
)
94 printf("%02x", MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*i
));
98 void sdrrd(char *startaddr
, char *dq
)
104 if(*startaddr
== 0) {
105 printf("sdrrd <address>\n");
108 addr
= strtoul(startaddr
, &c
, 0);
110 printf("incorrect address\n");
116 _dq
= strtoul(dq
, &c
, 0);
118 printf("incorrect DQ\n");
123 sdram_dfii_pird_address_write(addr
);
124 sdram_dfii_pird_baddress_write(0);
125 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
130 void sdrrderr(char *count
)
136 unsigned char prev_data
[DFII_NPHASES
*DFII_PIX_DATA_SIZE
];
137 unsigned char errs
[DFII_NPHASES
*DFII_PIX_DATA_SIZE
];
140 printf("sdrrderr <count>\n");
143 _count
= strtoul(count
, &c
, 0);
145 printf("incorrect count\n");
149 for(i
=0;i
<DFII_NPHASES
*DFII_PIX_DATA_SIZE
;i
++)
151 for(addr
=0;addr
<16;addr
++) {
152 sdram_dfii_pird_address_write(addr
*8);
153 sdram_dfii_pird_baddress_write(0);
154 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
156 for(p
=0;p
<DFII_NPHASES
;p
++)
157 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
158 prev_data
[p
*DFII_PIX_DATA_SIZE
+i
] = MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*i
);
160 for(j
=0;j
<_count
;j
++) {
161 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
163 for(p
=0;p
<DFII_NPHASES
;p
++)
164 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++) {
165 unsigned char new_data
;
167 new_data
= MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*i
);
168 errs
[p
*DFII_PIX_DATA_SIZE
+i
] |= prev_data
[p
*DFII_PIX_DATA_SIZE
+i
] ^ new_data
;
169 prev_data
[p
*DFII_PIX_DATA_SIZE
+i
] = new_data
;
174 for(i
=0;i
<DFII_NPHASES
*DFII_PIX_DATA_SIZE
;i
++)
175 printf("%02x", errs
[i
]);
177 for(p
=0;p
<DFII_NPHASES
;p
++)
178 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
179 printf("%2x", DFII_PIX_DATA_SIZE
/2 - 1 - (i
% (DFII_PIX_DATA_SIZE
/2)));
183 void sdrwr(char *startaddr
)
190 if(*startaddr
== 0) {
191 printf("sdrrd <address>\n");
194 addr
= strtoul(startaddr
, &c
, 0);
196 printf("incorrect address\n");
200 for(p
=0;p
<DFII_NPHASES
;p
++)
201 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
202 MMPTR(sdram_dfii_pix_wrdata_addr
[p
]+4*i
) = 0x10*p
+ i
;
204 sdram_dfii_piwr_address_write(addr
);
205 sdram_dfii_piwr_baddress_write(0);
206 command_pwr(DFII_COMMAND_CAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
|DFII_COMMAND_WRDATA
);
209 #ifdef CSR_DDRPHY_BASE
212 #define ERR_DDRPHY_DELAY 512
214 #define ERR_DDRPHY_DELAY 32
216 #define ERR_DDRPHY_BITSLIP 8
218 #define NBMODULES DFII_PIX_DATA_SIZE/2
220 #ifdef CSR_DDRPHY_WLEVEL_EN_ADDR
224 sdram_dfii_pi0_address_write(DDRX_MR1
| (1 << 7));
225 sdram_dfii_pi0_baddress_write(1);
226 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_CAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
);
227 ddrphy_wlevel_en_write(1);
232 sdram_dfii_pi0_address_write(DDRX_MR1
);
233 sdram_dfii_pi0_baddress_write(1);
234 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_CAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
);
235 ddrphy_wlevel_en_write(0);
238 int write_level(void)
247 unsigned char taps_scan
[ERR_DDRPHY_DELAY
];
249 int one_window_active
;
250 int one_window_start
;
252 int delays
[NBMODULES
];
256 err_ddrphy_wdly
= ERR_DDRPHY_DELAY
- ddrphy_half_sys8x_taps_read() - 1;
258 printf("Write leveling:\n");
262 for(i
=0;i
<NBMODULES
;i
++) {
264 dq_address
= sdram_dfii_pix_rddata_addr
[0]+4*(NBMODULES
-1-i
);
267 ddrphy_dly_sel_write(1 << i
);
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(j
=0; j
<ddrphy_half_sys8x_taps_read(); j
++)
272 ddrphy_wdly_dqs_inc_write(1);
275 for(j
=0;j
<err_ddrphy_wdly
;j
++) {
282 for (k
=0; k
<128; k
++) {
283 ddrphy_wlevel_strobe_write(1);
285 dq
= MMPTR(dq_address
);
291 if (one_count
> zero_count
)
296 printf("%d", taps_scan
[j
]);
297 ddrphy_wdly_dq_inc_write(1);
298 ddrphy_wdly_dqs_inc_write(1);
303 /* select last 0/1 transition */
304 one_window_active
= 0;
305 one_window_start
= 0;
307 for(j
=0;j
<err_ddrphy_wdly
;j
++) {
308 if (one_window_active
) {
309 if (taps_scan
[j
] == 0)
310 one_window_active
= 0;
313 one_window_active
= 1;
314 one_window_start
= j
;
318 delays
[i
] = one_window_start
;
320 /* configure delays */
321 ddrphy_wdly_dq_rst_write(1);
322 ddrphy_wdly_dqs_rst_write(1);
323 #ifdef USDDRPHY /* need to init manually on Ultrascale */
324 for(j
=0; j
<ddrphy_half_sys8x_taps_read(); j
++)
325 ddrphy_wdly_dqs_inc_write(1);
327 for(j
=0; j
<delays
[i
]; j
++) {
328 ddrphy_wdly_dq_inc_write(1);
329 ddrphy_wdly_dqs_inc_write(1);
332 printf(" delay: %02d\n", delays
[i
]);
338 for(i
=NBMODULES
-1;i
>=0;i
--) {
346 #endif /* CSR_DDRPHY_WLEVEL_EN_ADDR */
348 static void read_bitslip_inc(char m
)
350 ddrphy_dly_sel_write(1 << m
);
351 ddrphy_rdly_dq_bitslip_write(1);
354 static int read_level_scan(int module
, int bitslip
)
357 unsigned char prs
[DFII_NPHASES
*DFII_PIX_DATA_SIZE
];
361 /* Generate pseudo-random sequence */
363 for(i
=0;i
<DFII_NPHASES
*DFII_PIX_DATA_SIZE
;i
++) {
364 prv
= 1664525*prv
+ 1013904223;
369 sdram_dfii_pi0_address_write(0);
370 sdram_dfii_pi0_baddress_write(0);
371 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_CS
);
374 /* Write test pattern */
375 for(p
=0;p
<DFII_NPHASES
;p
++)
376 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
377 MMPTR(sdram_dfii_pix_wrdata_addr
[p
]+4*i
) = prs
[DFII_PIX_DATA_SIZE
*p
+i
];
378 sdram_dfii_piwr_address_write(0);
379 sdram_dfii_piwr_baddress_write(0);
380 command_pwr(DFII_COMMAND_CAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
|DFII_COMMAND_WRDATA
);
382 /* Calibrate each DQ in turn */
383 sdram_dfii_pird_address_write(0);
384 sdram_dfii_pird_baddress_write(0);
387 printf("m%d, b%d: |", module
, bitslip
);
388 ddrphy_dly_sel_write(1 << module
);
389 ddrphy_rdly_dq_rst_write(1);
390 for(j
=0; j
<ERR_DDRPHY_DELAY
;j
++) {
396 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
399 for(p
=0;p
<DFII_NPHASES
;p
++) {
400 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(NBMODULES
-module
-1)) != prs
[DFII_PIX_DATA_SIZE
*p
+(NBMODULES
-module
-1)])
402 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(2*NBMODULES
-module
-1)) != prs
[DFII_PIX_DATA_SIZE
*p
+2*NBMODULES
-module
-1])
406 printf("%d", working
);
408 ddrphy_rdly_dq_inc_write(1);
413 sdram_dfii_pi0_address_write(0);
414 sdram_dfii_pi0_baddress_write(0);
415 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
);
421 static void read_level(int module
)
424 unsigned char prs
[DFII_NPHASES
*DFII_PIX_DATA_SIZE
];
427 int delay
, delay_min
, delay_max
;
431 /* Generate pseudo-random sequence */
433 for(i
=0;i
<DFII_NPHASES
*DFII_PIX_DATA_SIZE
;i
++) {
434 prv
= 1664525*prv
+ 1013904223;
439 sdram_dfii_pi0_address_write(0);
440 sdram_dfii_pi0_baddress_write(0);
441 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_CS
);
444 /* Write test pattern */
445 for(p
=0;p
<DFII_NPHASES
;p
++)
446 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
447 MMPTR(sdram_dfii_pix_wrdata_addr
[p
]+4*i
) = prs
[DFII_PIX_DATA_SIZE
*p
+i
];
448 sdram_dfii_piwr_address_write(0);
449 sdram_dfii_piwr_baddress_write(0);
450 command_pwr(DFII_COMMAND_CAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
|DFII_COMMAND_WRDATA
);
452 /* Calibrate each DQ in turn */
453 sdram_dfii_pird_address_write(0);
454 sdram_dfii_pird_baddress_write(0);
456 ddrphy_dly_sel_write(1 << module
);
459 /* Find smallest working delay */
460 ddrphy_rdly_dq_rst_write(1);
462 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
465 for(p
=0;p
<DFII_NPHASES
;p
++) {
466 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(NBMODULES
-module
-1)) != prs
[DFII_PIX_DATA_SIZE
*p
+(NBMODULES
-module
-1)])
468 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(2*NBMODULES
-module
-1)) != prs
[DFII_PIX_DATA_SIZE
*p
+2*NBMODULES
-module
-1])
474 if(delay
>= ERR_DDRPHY_DELAY
)
476 ddrphy_rdly_dq_inc_write(1);
480 /* Get a bit further into the working zone */
484 ddrphy_rdly_dq_inc_write(1);
488 ddrphy_rdly_dq_inc_write(1);
491 /* Find largest working delay */
493 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
496 for(p
=0;p
<DFII_NPHASES
;p
++) {
497 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(NBMODULES
-module
-1)) != prs
[DFII_PIX_DATA_SIZE
*p
+(NBMODULES
-module
-1)])
499 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(2*NBMODULES
-module
-1)) != prs
[DFII_PIX_DATA_SIZE
*p
+2*NBMODULES
-module
-1])
505 if(delay
>= ERR_DDRPHY_DELAY
)
507 ddrphy_rdly_dq_inc_write(1);
511 printf("%02d+-%02d", (delay_min
+delay_max
)/2, (delay_max
-delay_min
)/2);
513 /* Set delay to the middle */
514 ddrphy_rdly_dq_rst_write(1);
515 for(j
=0;j
<(delay_min
+delay_max
)/2;j
++)
516 ddrphy_rdly_dq_inc_write(1);
519 sdram_dfii_pi0_address_write(0);
520 sdram_dfii_pi0_baddress_write(0);
521 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
);
524 #endif /* CSR_DDRPHY_BASE */
526 #endif /* CSR_SDRAM_BASE */
528 static unsigned int seed_to_data_32(unsigned int seed
, int random
)
531 return 1664525*seed
+ 1013904223;
536 static unsigned short seed_to_data_16(unsigned short seed
, int random
)
539 return 25173*seed
+ 13849;
544 #define ONEZERO 0xAAAAAAAA
545 #define ZEROONE 0x55555555
547 #ifndef MEMTEST_BUS_SIZE
548 #define MEMTEST_BUS_SIZE (512)
551 //#define MEMTEST_BUS_DEBUG
553 static int memtest_bus(void)
555 volatile unsigned int *array
= (unsigned int *)MAIN_RAM_BASE
;
561 for(i
=0;i
<MEMTEST_BUS_SIZE
/4;i
++) {
568 for(i
=0;i
<MEMTEST_BUS_SIZE
/4;i
++) {
570 if(rdata
!= ONEZERO
) {
572 #ifdef MEMTEST_BUS_DEBUG
573 printf("[bus: 0x%0x]: 0x%08x vs 0x%08x\n", i
, rdata
, ONEZERO
);
578 for(i
=0;i
<MEMTEST_BUS_SIZE
/4;i
++) {
585 for(i
=0;i
<MEMTEST_BUS_SIZE
/4;i
++) {
587 if(rdata
!= ZEROONE
) {
589 #ifdef MEMTEST_BUS_DEBUG
590 printf("[bus 0x%0x]: 0x%08x vs 0x%08x\n", i
, rdata
, ZEROONE
);
598 #ifndef MEMTEST_DATA_SIZE
599 #define MEMTEST_DATA_SIZE (2*1024*1024)
601 #define MEMTEST_DATA_RANDOM 1
603 //#define MEMTEST_DATA_DEBUG
605 static int memtest_data(void)
607 volatile unsigned int *array
= (unsigned int *)MAIN_RAM_BASE
;
609 unsigned int seed_32
;
615 for(i
=0;i
<MEMTEST_DATA_SIZE
/4;i
++) {
616 seed_32
= seed_to_data_32(seed_32
, MEMTEST_DATA_RANDOM
);
625 for(i
=0;i
<MEMTEST_DATA_SIZE
/4;i
++) {
626 seed_32
= seed_to_data_32(seed_32
, MEMTEST_DATA_RANDOM
);
628 if(rdata
!= seed_32
) {
630 #ifdef MEMTEST_DATA_DEBUG
631 printf("[data 0x%0x]: 0x%08x vs 0x%08x\n", i
, rdata
, seed_32
);
638 #ifndef MEMTEST_ADDR_SIZE
639 #define MEMTEST_ADDR_SIZE (32*1024)
641 #define MEMTEST_ADDR_RANDOM 0
643 //#define MEMTEST_ADDR_DEBUG
645 static int memtest_addr(void)
647 volatile unsigned int *array
= (unsigned int *)MAIN_RAM_BASE
;
649 unsigned short seed_16
;
650 unsigned short rdata
;
655 for(i
=0;i
<MEMTEST_ADDR_SIZE
/4;i
++) {
656 seed_16
= seed_to_data_16(seed_16
, MEMTEST_ADDR_RANDOM
);
657 array
[(unsigned int) seed_16
] = i
;
665 for(i
=0;i
<MEMTEST_ADDR_SIZE
/4;i
++) {
666 seed_16
= seed_to_data_16(seed_16
, MEMTEST_ADDR_RANDOM
);
667 rdata
= array
[(unsigned int) seed_16
];
670 #ifdef MEMTEST_ADDR_DEBUG
671 printf("[addr 0x%0x]: 0x%08x vs 0x%08x\n", i
, rdata
, i
);
681 int bus_errors
, data_errors
, addr_errors
;
683 bus_errors
= memtest_bus();
685 printf("Memtest bus failed: %d/%d errors\n", bus_errors
, 2*128);
687 data_errors
= memtest_data();
689 printf("Memtest data failed: %d/%d errors\n", data_errors
, MEMTEST_DATA_SIZE
/4);
691 addr_errors
= memtest_addr();
693 printf("Memtest addr failed: %d/%d errors\n", addr_errors
, MEMTEST_ADDR_SIZE
/4);
695 if(bus_errors
+ data_errors
+ addr_errors
!= 0)
698 printf("Memtest OK\n");
703 #ifdef CSR_SDRAM_BASE
705 #ifdef CSR_DDRPHY_BASE
716 for(i
=0; i
<NBMODULES
; i
++) {
717 ddrphy_dly_sel_write(1<<i
);
718 ddrphy_rdly_dq_rst_write(1);
719 ddrphy_rdly_dq_bitslip_rst_write(1);
722 #ifdef CSR_DDRPHY_WLEVEL_EN_ADDR
727 printf("Read leveling:\n");
728 for(i
=0; i
<NBMODULES
; i
++) {
729 /* scan possible read windows */
732 for(bitslip
=0; bitslip
<ERR_DDRPHY_BITSLIP
; bitslip
++) {
734 score
= read_level_scan(i
, bitslip
);
737 if (score
> best_score
) {
738 best_bitslip
= bitslip
;
742 if (bitslip
== ERR_DDRPHY_BITSLIP
-1)
744 /* increment bitslip */
748 /* select best read window */
749 printf("best: m%d, b%d ", i
, best_bitslip
);
750 ddrphy_rdly_dq_bitslip_rst_write(1);
751 for (j
=0; j
<best_bitslip
; j
++)
754 /* re-do leveling on best read window*/
765 printf("Initializing SDRAM...\n");
768 #ifdef CSR_DDRPHY_BASE
769 #if CSR_DDRPHY_EN_VTC_ADDR
770 ddrphy_en_vtc_write(0);
773 #if CSR_DDRPHY_EN_VTC_ADDR
774 ddrphy_en_vtc_write(1);