1 #include <generated/csr.h>
7 #include <generated/sdram_phy.h>
8 #include <generated/mem.h>
14 static void cdelay(int i
)
17 #if defined (__lm32__)
18 __asm__
volatile("nop");
19 #elif defined (__or1k__)
20 __asm__
volatile("l.nop");
21 #elif defined (__picorv32__)
22 __asm__
volatile("nop");
23 #elif defined (__vexriscv__)
24 __asm__
volatile("nop");
25 #elif defined (__minerva__)
26 __asm__
volatile("nop");
28 #error Unsupported architecture
36 sdram_dfii_control_write(DFII_CONTROL_CKE
|DFII_CONTROL_ODT
|DFII_CONTROL_RESET_N
);
37 printf("SDRAM now under software control\n");
42 sdram_dfii_control_write(DFII_CONTROL_SEL
);
43 printf("SDRAM now under hardware control\n");
46 void sdrrow(char *_row
)
52 sdram_dfii_pi0_address_write(0x0000);
53 sdram_dfii_pi0_baddress_write(0);
54 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
);
56 printf("Precharged\n");
58 row
= strtoul(_row
, &c
, 0);
60 printf("incorrect row\n");
63 sdram_dfii_pi0_address_write(row
);
64 sdram_dfii_pi0_baddress_write(0);
65 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_CS
);
67 printf("Activated row %d\n", row
);
80 first_byte
= DFII_PIX_DATA_SIZE
/2 - 1 - dq
;
81 step
= DFII_PIX_DATA_SIZE
/2;
84 for(p
=0;p
<DFII_NPHASES
;p
++)
85 for(i
=first_byte
;i
<DFII_PIX_DATA_SIZE
;i
+=step
)
86 printf("%02x", MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*i
));
90 void sdrrd(char *startaddr
, char *dq
)
97 printf("sdrrd <address>\n");
100 addr
= strtoul(startaddr
, &c
, 0);
102 printf("incorrect address\n");
108 _dq
= strtoul(dq
, &c
, 0);
110 printf("incorrect DQ\n");
115 sdram_dfii_pird_address_write(addr
);
116 sdram_dfii_pird_baddress_write(0);
117 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
122 void sdrrderr(char *count
)
128 unsigned char prev_data
[DFII_NPHASES
*DFII_PIX_DATA_SIZE
];
129 unsigned char errs
[DFII_NPHASES
*DFII_PIX_DATA_SIZE
];
132 printf("sdrrderr <count>\n");
135 _count
= strtoul(count
, &c
, 0);
137 printf("incorrect count\n");
141 for(i
=0;i
<DFII_NPHASES
*DFII_PIX_DATA_SIZE
;i
++)
143 for(addr
=0;addr
<16;addr
++) {
144 sdram_dfii_pird_address_write(addr
*8);
145 sdram_dfii_pird_baddress_write(0);
146 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
148 for(p
=0;p
<DFII_NPHASES
;p
++)
149 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
150 prev_data
[p
*DFII_PIX_DATA_SIZE
+i
] = MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*i
);
152 for(j
=0;j
<_count
;j
++) {
153 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
155 for(p
=0;p
<DFII_NPHASES
;p
++)
156 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++) {
157 unsigned char new_data
;
159 new_data
= MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*i
);
160 errs
[p
*DFII_PIX_DATA_SIZE
+i
] |= prev_data
[p
*DFII_PIX_DATA_SIZE
+i
] ^ new_data
;
161 prev_data
[p
*DFII_PIX_DATA_SIZE
+i
] = new_data
;
166 for(i
=0;i
<DFII_NPHASES
*DFII_PIX_DATA_SIZE
;i
++)
167 printf("%02x", errs
[i
]);
169 for(p
=0;p
<DFII_NPHASES
;p
++)
170 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
171 printf("%2x", DFII_PIX_DATA_SIZE
/2 - 1 - (i
% (DFII_PIX_DATA_SIZE
/2)));
175 void sdrwr(char *startaddr
)
182 if(*startaddr
== 0) {
183 printf("sdrrd <address>\n");
186 addr
= strtoul(startaddr
, &c
, 0);
188 printf("incorrect address\n");
192 for(p
=0;p
<DFII_NPHASES
;p
++)
193 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
194 MMPTR(sdram_dfii_pix_wrdata_addr
[p
]+4*i
) = 0x10*p
+ i
;
196 sdram_dfii_piwr_address_write(addr
);
197 sdram_dfii_piwr_baddress_write(0);
198 command_pwr(DFII_COMMAND_CAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
|DFII_COMMAND_WRDATA
);
201 #ifdef CSR_DDRPHY_BASE
204 #define ERR_DDRPHY_DELAY 512
206 #define ERR_DDRPHY_DELAY 32
208 #define ERR_DDRPHY_BITSLIP 8
210 #define NBMODULES DFII_PIX_DATA_SIZE/2
212 #ifdef CSR_DDRPHY_WLEVEL_EN_ADDR
216 sdram_dfii_pi0_address_write(DDRX_MR1
| (1 << 7));
217 sdram_dfii_pi0_baddress_write(1);
218 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_CAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
);
219 ddrphy_wlevel_en_write(1);
224 sdram_dfii_pi0_address_write(DDRX_MR1
);
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(0);
230 int write_level(void)
239 unsigned char taps_scan
[ERR_DDRPHY_DELAY
];
241 int one_window_active
;
242 int one_window_start
;
244 int delays
[NBMODULES
];
249 err_ddrphy_wdly
= ERR_DDRPHY_DELAY
; /* FIXME */
251 err_ddrphy_wdly
= ERR_DDRPHY_DELAY
- ddrphy_half_sys8x_taps_read() - 1;
254 printf("Write leveling:\n");
258 for(i
=0;i
<NBMODULES
;i
++) {
260 dq_address
= sdram_dfii_pix_rddata_addr
[0]+4*(NBMODULES
-1-i
);
263 ddrphy_dly_sel_write(1 << i
);
264 ddrphy_wdly_dq_rst_write(1);
265 ddrphy_wdly_dqs_rst_write(1);
266 #ifdef KUSDDRPHY /* need to init manually on Ultrascale */
267 for(j
=0; j
<ddrphy_wdly_dqs_taps_read(); j
++)
268 ddrphy_wdly_dqs_inc_write(1);
271 for(j
=0;j
<err_ddrphy_wdly
;j
++) {
274 for (k
=0; k
<128; k
++) {
275 ddrphy_wlevel_strobe_write(1);
277 dq
= MMPTR(dq_address
);
283 if (one_count
> zero_count
)
287 printf("%d", taps_scan
[j
]);
288 ddrphy_wdly_dq_inc_write(1);
289 ddrphy_wdly_dqs_inc_write(1);
294 /* select last 0/1 transition */
295 one_window_active
= 0;
296 one_window_start
= 0;
298 for(j
=0;j
<err_ddrphy_wdly
;j
++) {
299 if (one_window_active
) {
300 if (taps_scan
[j
] == 0)
301 one_window_active
= 0;
304 one_window_active
= 1;
305 one_window_start
= j
;
309 delays
[i
] = one_window_start
;
311 /* configure delays */
312 ddrphy_wdly_dq_rst_write(1);
313 ddrphy_wdly_dqs_rst_write(1);
314 #ifdef KUSDDRPHY /* need to init manually on Ultrascale */
315 for(j
=0; j
<ddrphy_wdly_dqs_taps_read(); j
++)
316 ddrphy_wdly_dqs_inc_write(1);
318 for(j
=0; j
<delays
[i
]; j
++) {
319 ddrphy_wdly_dq_inc_write(1);
320 ddrphy_wdly_dqs_inc_write(1);
323 printf(" delay: %02d\n", delays
[i
]);
329 for(i
=NBMODULES
-1;i
>=0;i
--) {
337 #endif /* CSR_DDRPHY_WLEVEL_EN_ADDR */
339 static void read_bitslip_inc(char m
)
341 ddrphy_dly_sel_write(1 << m
);
342 ddrphy_rdly_dq_bitslip_write(1);
345 static int read_level_scan(int module
, int bitslip
)
348 unsigned char prs
[DFII_NPHASES
*DFII_PIX_DATA_SIZE
];
352 /* Generate pseudo-random sequence */
354 for(i
=0;i
<DFII_NPHASES
*DFII_PIX_DATA_SIZE
;i
++) {
355 prv
= 1664525*prv
+ 1013904223;
360 sdram_dfii_pi0_address_write(0);
361 sdram_dfii_pi0_baddress_write(0);
362 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_CS
);
365 /* Write test pattern */
366 for(p
=0;p
<DFII_NPHASES
;p
++)
367 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
368 MMPTR(sdram_dfii_pix_wrdata_addr
[p
]+4*i
) = prs
[DFII_PIX_DATA_SIZE
*p
+i
];
369 sdram_dfii_piwr_address_write(0);
370 sdram_dfii_piwr_baddress_write(0);
371 command_pwr(DFII_COMMAND_CAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
|DFII_COMMAND_WRDATA
);
373 /* Calibrate each DQ in turn */
374 sdram_dfii_pird_address_write(0);
375 sdram_dfii_pird_baddress_write(0);
378 printf("m%d, b%d: |", module
, bitslip
);
379 ddrphy_dly_sel_write(1 << module
);
380 ddrphy_rdly_dq_rst_write(1);
381 for(j
=0; j
<ERR_DDRPHY_DELAY
;j
++) {
383 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
386 for(p
=0;p
<DFII_NPHASES
;p
++) {
387 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(NBMODULES
-module
-1)) != prs
[DFII_PIX_DATA_SIZE
*p
+(NBMODULES
-module
-1)])
389 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(2*NBMODULES
-module
-1)) != prs
[DFII_PIX_DATA_SIZE
*p
+2*NBMODULES
-module
-1])
392 printf("%d", working
);
394 ddrphy_rdly_dq_inc_write(1);
399 sdram_dfii_pi0_address_write(0);
400 sdram_dfii_pi0_baddress_write(0);
401 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
);
407 static void read_level(int module
)
410 unsigned char prs
[DFII_NPHASES
*DFII_PIX_DATA_SIZE
];
413 int delay
, delay_min
, delay_max
;
417 /* Generate pseudo-random sequence */
419 for(i
=0;i
<DFII_NPHASES
*DFII_PIX_DATA_SIZE
;i
++) {
420 prv
= 1664525*prv
+ 1013904223;
425 sdram_dfii_pi0_address_write(0);
426 sdram_dfii_pi0_baddress_write(0);
427 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_CS
);
430 /* Write test pattern */
431 for(p
=0;p
<DFII_NPHASES
;p
++)
432 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
433 MMPTR(sdram_dfii_pix_wrdata_addr
[p
]+4*i
) = prs
[DFII_PIX_DATA_SIZE
*p
+i
];
434 sdram_dfii_piwr_address_write(0);
435 sdram_dfii_piwr_baddress_write(0);
436 command_pwr(DFII_COMMAND_CAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
|DFII_COMMAND_WRDATA
);
438 /* Calibrate each DQ in turn */
439 sdram_dfii_pird_address_write(0);
440 sdram_dfii_pird_baddress_write(0);
442 ddrphy_dly_sel_write(1 << module
);
445 /* Find smallest working delay */
446 ddrphy_rdly_dq_rst_write(1);
448 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
451 for(p
=0;p
<DFII_NPHASES
;p
++) {
452 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(NBMODULES
-module
-1)) != prs
[DFII_PIX_DATA_SIZE
*p
+(NBMODULES
-module
-1)])
454 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(2*NBMODULES
-module
-1)) != prs
[DFII_PIX_DATA_SIZE
*p
+2*NBMODULES
-module
-1])
460 if(delay
>= ERR_DDRPHY_DELAY
)
462 ddrphy_rdly_dq_inc_write(1);
466 /* Get a bit further into the working zone */
470 ddrphy_rdly_dq_inc_write(1);
474 ddrphy_rdly_dq_inc_write(1);
477 /* Find largest working delay */
479 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
482 for(p
=0;p
<DFII_NPHASES
;p
++) {
483 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(NBMODULES
-module
-1)) != prs
[DFII_PIX_DATA_SIZE
*p
+(NBMODULES
-module
-1)])
485 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(2*NBMODULES
-module
-1)) != prs
[DFII_PIX_DATA_SIZE
*p
+2*NBMODULES
-module
-1])
491 if(delay
>= ERR_DDRPHY_DELAY
)
493 ddrphy_rdly_dq_inc_write(1);
497 printf("%02d+-%02d", (delay_min
+delay_max
)/2, (delay_max
-delay_min
)/2);
499 /* Set delay to the middle */
500 ddrphy_rdly_dq_rst_write(1);
501 for(j
=0;j
<(delay_min
+delay_max
)/2;j
++)
502 ddrphy_rdly_dq_inc_write(1);
505 sdram_dfii_pi0_address_write(0);
506 sdram_dfii_pi0_baddress_write(0);
507 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
);
510 #endif /* CSR_DDRPHY_BASE */
512 static unsigned int seed_to_data_32(unsigned int seed
, int random
)
515 return 1664525*seed
+ 1013904223;
520 static unsigned short seed_to_data_16(unsigned short seed
, int random
)
523 return 25173*seed
+ 13849;
528 #define ONEZERO 0xAAAAAAAA
529 #define ZEROONE 0x55555555
531 #ifndef MEMTEST_BUS_SIZE
532 #define MEMTEST_BUS_SIZE (512)
535 //#define MEMTEST_BUS_DEBUG
537 static int memtest_bus(void)
539 volatile unsigned int *array
= (unsigned int *)MAIN_RAM_BASE
;
545 for(i
=0;i
<MEMTEST_BUS_SIZE
/4;i
++) {
550 for(i
=0;i
<MEMTEST_BUS_SIZE
/4;i
++) {
552 if(rdata
!= ONEZERO
) {
554 #ifdef MEMTEST_BUS_DEBUG
555 printf("[bus: 0x%0x]: 0x%08x vs 0x%08x\n", i
, rdata
, ONEZERO
);
560 for(i
=0;i
<MEMTEST_BUS_SIZE
/4;i
++) {
565 for(i
=0;i
<MEMTEST_BUS_SIZE
/4;i
++) {
567 if(rdata
!= ZEROONE
) {
569 #ifdef MEMTEST_BUS_DEBUG
570 printf("[bus 0x%0x]: 0x%08x vs 0x%08x\n", i
, rdata
, ZEROONE
);
578 #ifndef MEMTEST_DATA_SIZE
579 #define MEMTEST_DATA_SIZE (2*1024*1024)
581 #define MEMTEST_DATA_RANDOM 1
583 //#define MEMTEST_DATA_DEBUG
585 static int memtest_data(void)
587 volatile unsigned int *array
= (unsigned int *)MAIN_RAM_BASE
;
589 unsigned int seed_32
;
595 for(i
=0;i
<MEMTEST_DATA_SIZE
/4;i
++) {
596 seed_32
= seed_to_data_32(seed_32
, MEMTEST_DATA_RANDOM
);
603 for(i
=0;i
<MEMTEST_DATA_SIZE
/4;i
++) {
604 seed_32
= seed_to_data_32(seed_32
, MEMTEST_DATA_RANDOM
);
606 if(rdata
!= seed_32
) {
608 #ifdef MEMTEST_DATA_DEBUG
609 printf("[data 0x%0x]: 0x%08x vs 0x%08x\n", i
, rdata
, seed_32
);
616 #ifndef MEMTEST_ADDR_SIZE
617 #define MEMTEST_ADDR_SIZE (32*1024)
619 #define MEMTEST_ADDR_RANDOM 0
621 //#define MEMTEST_ADDR_DEBUG
623 static int memtest_addr(void)
625 volatile unsigned int *array
= (unsigned int *)MAIN_RAM_BASE
;
627 unsigned short seed_16
;
628 unsigned short rdata
;
633 for(i
=0;i
<MEMTEST_ADDR_SIZE
/4;i
++) {
634 seed_16
= seed_to_data_16(seed_16
, MEMTEST_ADDR_RANDOM
);
635 array
[(unsigned int) seed_16
] = i
;
641 for(i
=0;i
<MEMTEST_ADDR_SIZE
/4;i
++) {
642 seed_16
= seed_to_data_16(seed_16
, MEMTEST_ADDR_RANDOM
);
643 rdata
= array
[(unsigned int) seed_16
];
646 #ifdef MEMTEST_ADDR_DEBUG
647 printf("[addr 0x%0x]: 0x%08x vs 0x%08x\n", i
, rdata
, i
);
657 int bus_errors
, data_errors
, addr_errors
;
659 bus_errors
= memtest_bus();
661 printf("Memtest bus failed: %d/%d errors\n", bus_errors
, 2*128);
663 data_errors
= memtest_data();
665 printf("Memtest data failed: %d/%d errors\n", data_errors
, MEMTEST_DATA_SIZE
/4);
667 addr_errors
= memtest_addr();
669 printf("Memtest addr failed: %d/%d errors\n", addr_errors
, MEMTEST_ADDR_SIZE
/4);
671 if(bus_errors
+ data_errors
+ addr_errors
!= 0)
674 printf("Memtest OK\n");
679 #ifdef CSR_DDRPHY_BASE
690 for(i
=0; i
<NBMODULES
; i
++) {
691 ddrphy_dly_sel_write(1<<i
);
692 ddrphy_rdly_dq_rst_write(1);
693 ddrphy_rdly_dq_bitslip_rst_write(1);
696 #ifdef CSR_DDRPHY_WLEVEL_EN_ADDR
701 printf("Read leveling:\n");
702 for(i
=0; i
<NBMODULES
; i
++) {
703 /* scan possible read windows */
706 for(bitslip
=0; bitslip
<ERR_DDRPHY_BITSLIP
; bitslip
++) {
708 score
= read_level_scan(i
, bitslip
);
711 if (score
> best_score
) {
712 best_bitslip
= bitslip
;
716 if (bitslip
== ERR_DDRPHY_BITSLIP
-1)
718 /* increment bitslip */
722 /* select best read window */
723 printf("best: m%d, b%d ", i
, best_bitslip
);
724 ddrphy_rdly_dq_bitslip_rst_write(1);
725 for (j
=0; j
<best_bitslip
; j
++)
728 /* re-do leveling on best read window*/
739 printf("Initializing SDRAM...\n");
742 #ifdef CSR_DDRPHY_BASE
743 #if CSR_DDRPHY_EN_VTC_ADDR
744 ddrphy_en_vtc_write(0);
747 #if CSR_DDRPHY_EN_VTC_ADDR
748 ddrphy_en_vtc_write(1);