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 (__riscv__)
22 __asm__
volatile("nop");
24 #error Unsupported architecture
32 sdram_dfii_control_write(DFII_CONTROL_CKE
|DFII_CONTROL_ODT
|DFII_CONTROL_RESET_N
);
33 printf("SDRAM now under software control\n");
38 sdram_dfii_control_write(DFII_CONTROL_SEL
);
39 printf("SDRAM now under hardware control\n");
42 void sdrrow(char *_row
)
48 sdram_dfii_pi0_address_write(0x0000);
49 sdram_dfii_pi0_baddress_write(0);
50 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
);
52 printf("Precharged\n");
54 row
= strtoul(_row
, &c
, 0);
56 printf("incorrect row\n");
59 sdram_dfii_pi0_address_write(row
);
60 sdram_dfii_pi0_baddress_write(0);
61 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_CS
);
63 printf("Activated row %d\n", row
);
76 first_byte
= DFII_PIX_DATA_SIZE
/2 - 1 - dq
;
77 step
= DFII_PIX_DATA_SIZE
/2;
80 for(p
=0;p
<DFII_NPHASES
;p
++)
81 for(i
=first_byte
;i
<DFII_PIX_DATA_SIZE
;i
+=step
)
82 printf("%02x", MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*i
));
86 void sdrrd(char *startaddr
, char *dq
)
93 printf("sdrrd <address>\n");
96 addr
= strtoul(startaddr
, &c
, 0);
98 printf("incorrect address\n");
104 _dq
= strtoul(dq
, &c
, 0);
106 printf("incorrect DQ\n");
111 sdram_dfii_pird_address_write(addr
);
112 sdram_dfii_pird_baddress_write(0);
113 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
118 void sdrrderr(char *count
)
124 unsigned char prev_data
[DFII_NPHASES
*DFII_PIX_DATA_SIZE
];
125 unsigned char errs
[DFII_NPHASES
*DFII_PIX_DATA_SIZE
];
128 printf("sdrrderr <count>\n");
131 _count
= strtoul(count
, &c
, 0);
133 printf("incorrect count\n");
137 for(i
=0;i
<DFII_NPHASES
*DFII_PIX_DATA_SIZE
;i
++)
139 for(addr
=0;addr
<16;addr
++) {
140 sdram_dfii_pird_address_write(addr
*8);
141 sdram_dfii_pird_baddress_write(0);
142 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
144 for(p
=0;p
<DFII_NPHASES
;p
++)
145 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
146 prev_data
[p
*DFII_PIX_DATA_SIZE
+i
] = MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*i
);
148 for(j
=0;j
<_count
;j
++) {
149 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
151 for(p
=0;p
<DFII_NPHASES
;p
++)
152 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++) {
153 unsigned char new_data
;
155 new_data
= MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*i
);
156 errs
[p
*DFII_PIX_DATA_SIZE
+i
] |= prev_data
[p
*DFII_PIX_DATA_SIZE
+i
] ^ new_data
;
157 prev_data
[p
*DFII_PIX_DATA_SIZE
+i
] = new_data
;
162 for(i
=0;i
<DFII_NPHASES
*DFII_PIX_DATA_SIZE
;i
++)
163 printf("%02x", errs
[i
]);
165 for(p
=0;p
<DFII_NPHASES
;p
++)
166 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
167 printf("%2x", DFII_PIX_DATA_SIZE
/2 - 1 - (i
% (DFII_PIX_DATA_SIZE
/2)));
171 void sdrwr(char *startaddr
)
178 if(*startaddr
== 0) {
179 printf("sdrrd <address>\n");
182 addr
= strtoul(startaddr
, &c
, 0);
184 printf("incorrect address\n");
188 for(p
=0;p
<DFII_NPHASES
;p
++)
189 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
190 MMPTR(sdram_dfii_pix_wrdata_addr
[p
]+4*i
) = 0x10*p
+ i
;
192 sdram_dfii_piwr_address_write(addr
);
193 sdram_dfii_piwr_baddress_write(0);
194 command_pwr(DFII_COMMAND_CAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
|DFII_COMMAND_WRDATA
);
197 #ifdef CSR_DDRPHY_BASE
201 sdram_dfii_pi0_address_write(DDR3_MR1
| (1 << 7));
202 sdram_dfii_pi0_baddress_write(1);
203 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_CAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
);
204 ddrphy_wlevel_en_write(1);
209 sdram_dfii_pi0_address_write(DDR3_MR1
);
210 sdram_dfii_pi0_baddress_write(1);
211 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_CAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
);
212 ddrphy_wlevel_en_write(0);
215 #define ERR_DDRPHY_DELAY 32
217 static int write_level(int *delay
, int *high_skew
)
224 printf("Write leveling: ");
228 for(i
=0;i
<DFII_PIX_DATA_SIZE
/2;i
++) {
229 dq_address
= sdram_dfii_pix_rddata_addr
[0]+4*(DFII_PIX_DATA_SIZE
/2-1-i
);
230 ddrphy_dly_sel_write(1 << i
);
231 ddrphy_wdly_dq_rst_write(1);
232 ddrphy_wdly_dqs_rst_write(1);
236 ddrphy_wlevel_strobe_write(1);
238 dq
= MMPTR(dq_address
);
241 * Assume this DQ group has between 1 and 2 bit times of skew.
242 * Bring DQS into the CK=0 zone before continuing leveling.
247 if(delay
[i
] >= ERR_DDRPHY_DELAY
)
249 ddrphy_wdly_dq_inc_write(1);
250 ddrphy_wdly_dqs_inc_write(1);
251 ddrphy_wlevel_strobe_write(1);
253 dq
= MMPTR(dq_address
);
260 if(delay
[i
] >= ERR_DDRPHY_DELAY
)
262 ddrphy_wdly_dq_inc_write(1);
263 ddrphy_wdly_dqs_inc_write(1);
265 ddrphy_wlevel_strobe_write(1);
267 dq
= MMPTR(dq_address
);
273 for(i
=DFII_PIX_DATA_SIZE
/2-1;i
>=0;i
--) {
274 printf("%2d%c ", delay
[i
], high_skew
[i
] ? '*' : ' ');
275 if(delay
[i
] >= ERR_DDRPHY_DELAY
)
280 printf("completed\n");
287 static void read_bitslip(int *delay
, int *high_skew
)
292 bitslip_thr
= 0x7fffffff;
293 for(i
=0;i
<DFII_PIX_DATA_SIZE
/2;i
++)
294 if(high_skew
[i
] && (delay
[i
] < bitslip_thr
))
295 bitslip_thr
= delay
[i
];
296 if(bitslip_thr
== 0x7fffffff)
298 bitslip_thr
= bitslip_thr
/2;
300 printf("Read bitslip: ");
301 for(i
=DFII_PIX_DATA_SIZE
/2-1;i
>=0;i
--)
302 if(delay
[i
] > bitslip_thr
) {
303 ddrphy_dly_sel_write(1 << i
);
304 /* 7-series SERDES in DDR mode needs 3 pulses for 1 bitslip */
305 ddrphy_rdly_dq_bitslip_write(1);
306 ddrphy_rdly_dq_bitslip_write(1);
307 ddrphy_rdly_dq_bitslip_write(1);
313 static void read_delays(void)
316 unsigned char prs
[DFII_NPHASES
*DFII_PIX_DATA_SIZE
];
319 int delay
, delay_min
, delay_max
;
321 printf("Read delays: ");
323 /* Generate pseudo-random sequence */
325 for(i
=0;i
<DFII_NPHASES
*DFII_PIX_DATA_SIZE
;i
++) {
326 prv
= 1664525*prv
+ 1013904223;
331 sdram_dfii_pi0_address_write(0);
332 sdram_dfii_pi0_baddress_write(0);
333 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_CS
);
336 /* Write test pattern */
337 for(p
=0;p
<DFII_NPHASES
;p
++)
338 for(i
=0;i
<DFII_PIX_DATA_SIZE
;i
++)
339 MMPTR(sdram_dfii_pix_wrdata_addr
[p
]+4*i
) = prs
[DFII_PIX_DATA_SIZE
*p
+i
];
340 sdram_dfii_piwr_address_write(0);
341 sdram_dfii_piwr_baddress_write(0);
342 command_pwr(DFII_COMMAND_CAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
|DFII_COMMAND_WRDATA
);
344 /* Calibrate each DQ in turn */
345 sdram_dfii_pird_address_write(0);
346 sdram_dfii_pird_baddress_write(0);
347 for(i
=0;i
<DFII_PIX_DATA_SIZE
/2;i
++) {
348 ddrphy_dly_sel_write(1 << (DFII_PIX_DATA_SIZE
/2-i
-1));
351 /* Find smallest working delay */
352 ddrphy_rdly_dq_rst_write(1);
354 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
357 for(p
=0;p
<DFII_NPHASES
;p
++) {
358 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*i
) != prs
[DFII_PIX_DATA_SIZE
*p
+i
])
360 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(i
+DFII_PIX_DATA_SIZE
/2)) != prs
[DFII_PIX_DATA_SIZE
*p
+i
+DFII_PIX_DATA_SIZE
/2])
366 if(delay
>= ERR_DDRPHY_DELAY
)
368 ddrphy_rdly_dq_inc_write(1);
372 /* Get a bit further into the working zone */
374 ddrphy_rdly_dq_inc_write(1);
376 /* Find largest working delay */
378 command_prd(DFII_COMMAND_CAS
|DFII_COMMAND_CS
|DFII_COMMAND_RDDATA
);
381 for(p
=0;p
<DFII_NPHASES
;p
++) {
382 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*i
) != prs
[DFII_PIX_DATA_SIZE
*p
+i
])
384 if(MMPTR(sdram_dfii_pix_rddata_addr
[p
]+4*(i
+DFII_PIX_DATA_SIZE
/2)) != prs
[DFII_PIX_DATA_SIZE
*p
+i
+DFII_PIX_DATA_SIZE
/2])
390 if(delay
>= ERR_DDRPHY_DELAY
)
392 ddrphy_rdly_dq_inc_write(1);
396 printf("%d:%02d-%02d ", DFII_PIX_DATA_SIZE
/2-i
-1, delay_min
, delay_max
);
398 /* Set delay to the middle */
399 ddrphy_rdly_dq_rst_write(1);
400 for(j
=0;j
<(delay_min
+delay_max
)/2;j
++)
401 ddrphy_rdly_dq_inc_write(1);
405 sdram_dfii_pi0_address_write(0);
406 sdram_dfii_pi0_baddress_write(0);
407 command_p0(DFII_COMMAND_RAS
|DFII_COMMAND_WE
|DFII_COMMAND_CS
);
410 printf("completed\n");
415 int delay
[DFII_PIX_DATA_SIZE
/2];
416 int high_skew
[DFII_PIX_DATA_SIZE
/2];
418 if(!write_level(delay
, high_skew
))
420 read_bitslip(delay
, high_skew
);
426 #endif /* CSR_DDRPHY_BASE */
428 static unsigned int seed_to_data_32(unsigned int seed
, int random
)
431 return 1664525*seed
+ 1013904223;
436 static unsigned short seed_to_data_16(unsigned short seed
, int random
)
439 return 25173*seed
+ 13849;
444 #define ONEZERO 0xAAAAAAAA
445 #define ZEROONE 0x55555555
447 #ifndef MEMTEST_BUS_SIZE
448 #define MEMTEST_BUS_SIZE (512)
451 static int memtest_bus(void)
453 volatile unsigned int *array
= (unsigned int *)MAIN_RAM_BASE
;
458 for(i
=0;i
<MEMTEST_BUS_SIZE
/4;i
++) {
463 for(i
=0;i
<MEMTEST_BUS_SIZE
/4;i
++) {
464 if(array
[i
] != ONEZERO
)
468 for(i
=0;i
<MEMTEST_BUS_SIZE
/4;i
++) {
473 for(i
=0;i
<MEMTEST_BUS_SIZE
/4;i
++) {
474 if(array
[i
] != ZEROONE
)
481 #ifndef MEMTEST_DATA_SIZE
482 #define MEMTEST_DATA_SIZE (2*1024*1024)
484 #define MEMTEST_DATA_RANDOM 1
486 static int memtest_data(void)
488 volatile unsigned int *array
= (unsigned int *)MAIN_RAM_BASE
;
490 unsigned int seed_32
;
495 for(i
=0;i
<MEMTEST_DATA_SIZE
/4;i
++) {
496 seed_32
= seed_to_data_32(seed_32
, MEMTEST_DATA_RANDOM
);
503 for(i
=0;i
<MEMTEST_DATA_SIZE
/4;i
++) {
504 seed_32
= seed_to_data_32(seed_32
, MEMTEST_DATA_RANDOM
);
505 if(array
[i
] != seed_32
)
511 #ifndef MEMTEST_ADDR_SIZE
512 #define MEMTEST_ADDR_SIZE (32*1024)
514 #define MEMTEST_ADDR_RANDOM 0
516 static int memtest_addr(void)
518 volatile unsigned int *array
= (unsigned int *)MAIN_RAM_BASE
;
520 unsigned short seed_16
;
525 for(i
=0;i
<MEMTEST_ADDR_SIZE
/4;i
++) {
526 seed_16
= seed_to_data_16(seed_16
, MEMTEST_ADDR_RANDOM
);
527 array
[(unsigned int) seed_16
] = i
;
533 for(i
=0;i
<MEMTEST_ADDR_SIZE
/4;i
++) {
534 seed_16
= seed_to_data_16(seed_16
, MEMTEST_ADDR_RANDOM
);
535 if(array
[(unsigned int) seed_16
] != i
)
544 int bus_errors
, data_errors
, addr_errors
;
546 bus_errors
= memtest_bus();
548 printf("Memtest bus failed: %d/%d errors\n", bus_errors
, 2*128);
550 data_errors
= memtest_data();
552 printf("Memtest data failed: %d/%d errors\n", data_errors
, MEMTEST_DATA_SIZE
/4);
554 addr_errors
= memtest_addr();
556 printf("Memtest addr failed: %d/%d errors\n", addr_errors
, MEMTEST_ADDR_SIZE
/4);
558 if(bus_errors
+ data_errors
+ addr_errors
!= 0)
561 printf("Memtest OK\n");
568 printf("Initializing SDRAM...\n");
571 #ifdef CSR_DDRPHY_BASE
575 sdram_dfii_control_write(DFII_CONTROL_SEL
);