1 /*******************************************************************************
2 * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * MPFS HAL Embedded Software
7 *
8 */
9
10 /*******************************************************************************
11 * @file mss_ddr_debug.h
12 * @author Microchip FPGA Embedded Systems Solutions
13 * @brief DDR write and read test functions
14 *
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include "mpfs_hal/mss_hal.h"
21
22 /*******************************************************************************
23 * Local Defines
24 */
25 #define DDR_BASE 0x80000000u
26 #define DDR_SIZE 0x40000000u
27
28 #define PDMA_CHANNEL0_BASE_ADDRESS 0x3000000ULL
29 #define PDMA_CHANNEL1_BASE_ADDRESS 0x3001000ULL
30 #define PDMA_CHANNEL2_BASE_ADDRESS 0x3002000ULL
31 #define PDMA_CHANNEL3_BASE_ADDRESS 0x3003000ULL
32
33 const char *progress[3] = {"|\r", "/\r", "-\r"};
34 typedef void(*pattern_fct_t)(void);
35 static uint32_t g_test_buffer_cached[765];
36 static uint32_t g_test_buffer_not_cached[765];
37
38 /*******************************************************************************
39 * External Defines
40 */
41 #ifdef DEBUG_DDR_INIT
42 #ifdef SWEEP_ENABLED
43 extern uint8_t sweep_results[MAX_NUMBER_DPC_VS_GEN_SWEEPS]\
44 [MAX_NUMBER_DPC_H_GEN_SWEEPS]\
45 [MAX_NUMBER_DPC_V_GEN_SWEEPS]\
46 [MAX_NUMBER__BCLK_SCLK_OFFSET_SWEEPS]\
47 [MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS];
48 #endif
49 #endif
50 extern const uint32_t ddr_test_pattern[768];
51
52 /*******************************************************************************
53 * External function declarations
54 */
55 extern void delay(uint32_t n);
56 extern void pdma_transfer(uint64_t destination, uint64_t source, uint64_t size_in_bytes, uint64_t base_address);
57 extern void pdma_transfer_complete( uint64_t base_address);
58
59 /*******************************************************************************
60 * Local data declarations
61 */
62 #ifdef DEBUG_DDR_INIT
63 mss_uart_instance_t *g_debug_uart;
64 #endif
65
66 uint64_t ddr_test;
67
68 /*******************************************************************************
69 * Local function declarations
70 */
71 static uint32_t ddr_write ( volatile uint64_t *DDR_word_ptr,\
72 uint32_t no_of_access, uint8_t data_ptrn, DDR_ACCESS_SIZE data_size );
73 static uint32_t ddr_read ( volatile uint64_t *DDR_word_ptr,\
74 uint32_t no_of_access, uint8_t data_ptrn, DDR_ACCESS_SIZE data_size );
75
76 #ifdef HSS
rand(void)77 __attribute__((weak)) int rand(void)
78 {
79 return(0);
80 }
81 #endif
82
83 #ifdef DEBUG_DDR_INIT
84 /***************************************************************************//**
85 * Setup serial port if DDR debug required during start-up
86 * @param uart Ref to uart you want to use
87 * @return
88 */
89
90 __attribute__((weak))\
setup_ddr_debug_port(mss_uart_instance_t * uart)91 uint32_t setup_ddr_debug_port(mss_uart_instance_t * uart)
92 {
93 #ifdef DEBUG_DDR_INIT
94 /* Turn on UART0 clock */
95 SYSREG->SUBBLK_CLOCK_CR |= (SUBBLK_CLOCK_CR_MMUART0_MASK);
96 /* Remove soft reset */
97 SYSREG->SOFT_RESET_CR &= (uint32_t)(~SUBBLK_CLOCK_CR_MMUART0_MASK);
98 MSS_UART_init( uart,
99 MSS_UART_115200_BAUD,
100 MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT);
101 return(0U);
102 #endif
103 }
104
105
106 /***************************************************************************//**
107 * Print in number hex format
108 * @param uart
109 * @param b
110 */
111
dumpbyte(mss_uart_instance_t * uart,uint8_t b)112 static void dumpbyte(mss_uart_instance_t * uart, uint8_t b)
113 {
114 #ifdef DEBUG_DDR_INIT
115 const uint8_t hexchrs[] = { '0','1','2','3','4','5','6','7','8','9','A','B',\
116 'C','D','E','F' };
117 MSS_UART_polled_tx(uart, &hexchrs[b >> 4u] , 1);
118 MSS_UART_polled_tx(uart, &hexchrs[b & 0x0fu] , 1);
119 #endif
120 }
121
122 /***************************************************************************//**
123 *
124 * @param uart
125 * @param msg
126 * @param d
127 */
128 __attribute__((weak))\
uprint32(mss_uart_instance_t * uart,const char * msg,uint32_t d)129 void uprint32(mss_uart_instance_t * uart, const char* msg, uint32_t d)
130 {
131 MSS_UART_polled_tx_string(uart, (const uint8_t *)msg);
132 for (unsigned i=0; i < 4; i++)
133 {
134 dumpbyte(uart, (d >> (8*(3-i))) & 0xffu);
135 }
136 }
137
138 /***************************************************************************//**
139 *
140 * @param uart
141 * @param msg
142 * @param d
143 */
144 __attribute__((weak))\
uprint64(mss_uart_instance_t * uart,const char * msg,uint64_t d)145 void uprint64(mss_uart_instance_t * uart, const char* msg, uint64_t d)
146 {
147 MSS_UART_polled_tx_string(uart, (const uint8_t *)msg);
148 for (unsigned i=4; i < 8; i++)
149 {
150 dumpbyte(uart, (d >> (8*(3-i))) & 0xffu);
151 }
152 for (unsigned i=0; i < 4; i++)
153 {
154 dumpbyte(uart, (d >> (8*(3-i))) & 0xffu);
155 }
156 }
157
158 /***************************************************************************//**
159 *
160 * @param uart
161 * @param msg
162 */
163 __attribute__((weak))\
uprint(mss_uart_instance_t * uart,const char * msg)164 void uprint(mss_uart_instance_t * uart, const char* msg)
165 {
166 MSS_UART_polled_tx_string(uart, (const uint8_t *)msg);
167 }
168
169 /***************************************************************************//**
170 * dump a number of 32bit contiguous registers
171 * @param uart
172 * @param reg_pointer
173 * @param no_of_regs
174 */
print_reg_array(mss_uart_instance_t * uart,uint32_t * reg_pointer,uint32_t no_of_regs)175 void print_reg_array(mss_uart_instance_t * uart, uint32_t *reg_pointer,\
176 uint32_t no_of_regs)
177 {
178 #ifdef DEBUG_DDR_INIT
179 while(no_of_regs > 0U)
180 {
181 uprint64(uart, "\n\rRegister, 0x", (uint64_t)reg_pointer);
182 uprint32(uart, " ,Value, 0x", *reg_pointer);
183 reg_pointer++;
184 no_of_regs--;
185 }
186 #endif
187 }
188
189 #endif
190
191 /***************************************************************************//**
192 * Write data to DDR
193 * @param DDR_word_ptr
194 * @param no_of_access
195 * @param data_ptrn
196 * @return
197 */
ddr_write(volatile uint64_t * DDR_word_ptr,uint32_t no_of_access,uint8_t data_ptrn,DDR_ACCESS_SIZE data_size)198 static uint32_t ddr_write
199 (
200 volatile uint64_t *DDR_word_ptr,
201 uint32_t no_of_access,
202 uint8_t data_ptrn,
203 DDR_ACCESS_SIZE data_size
204 )
205 {
206 uint32_t i;
207 uint64_t DATA;
208 uint32_t error_count = 0U;
209
210 uint32_t *DDR_32_ptr = (uint32_t *)DDR_word_ptr;
211 uint16_t *DDR_16_ptr = (uint16_t *)DDR_word_ptr;
212 uint8_t *DDR_8_ptr = (uint8_t *)DDR_word_ptr;
213
214 switch (data_ptrn)
215 {
216 case PATTERN_INCREMENTAL : DATA = 0x00000000; break;
217 case PATTERN_WALKING_ONE : DATA = 0x00000001; break;
218 case PATTERN_WALKING_ZERO : DATA = 0x01;
219 DATA = ~ DATA; break;
220 case PATTERN_RANDOM :
221 DATA = (uint64_t)rand ( );
222 break;
223 case PATTERN_0xCCCCCCCC :
224 DATA = 0xCCCCCCCCCCCCCCCC;
225 break;
226 case PATTERN_0x55555555 :
227 DATA = 0x5555555555555555;
228 break;
229 case PATTERN_ZEROS :
230 DATA = 0x00000000;
231 break;
232 default :
233 DATA = 0x00000000;
234 break;
235 }
236
237 for( i = 0; i< (no_of_access); i++)
238 {
239 switch(data_size)
240 {
241 case DDR_8_BIT:
242 DATA &= 0xFFUL;
243 *DDR_8_ptr = (uint8_t)DATA;
244 DDR_8_ptr = DDR_8_ptr + 1;
245 break;
246 case DDR_16_BIT:
247 DATA &= 0xFFFFUL;
248 *DDR_16_ptr = (uint16_t)DATA;
249 DDR_16_ptr = DDR_16_ptr + 1;
250 break;
251 case DDR_32_BIT:
252 DATA &= 0xFFFFFFFFUL;
253 *DDR_32_ptr = (uint32_t)DATA;
254 DDR_32_ptr = DDR_32_ptr + 1;
255 break;
256 default:
257 case DDR_64_BIT:
258 *DDR_word_ptr = DATA;
259 DDR_word_ptr = DDR_word_ptr + 1;
260 break;
261 }
262
263 #ifdef DEBUG_DDR_INIT
264 if((i%0x1000000UL) ==0UL)
265 {
266 MSS_UART_polled_tx(g_debug_uart, (const uint8_t*)"w", (uint32_t)1UL);
267 }
268 #endif
269 switch (data_ptrn)
270 {
271 case PATTERN_INCREMENTAL : DATA = DATA + 0x00000001; break;
272 case PATTERN_WALKING_ONE :
273 if (DATA == 0x80000000)
274 DATA = 0x00000001;
275 else
276 DATA = (DATA << 1);
277 break;
278 case PATTERN_WALKING_ZERO :
279 DATA = ~DATA;
280 if (DATA == 0x80000000)
281 DATA = 0x00000001;
282 else
283 {
284 DATA = (DATA << 1);
285 }
286 DATA = ~DATA;
287 break;
288 case PATTERN_RANDOM :
289 DATA = (uint64_t)rand ( );
290 break;
291 case PATTERN_0xCCCCCCCC :
292 DATA = 0xCCCCCCCCCCCCCCCC;
293 break;
294 case PATTERN_0x55555555 :
295 DATA = 0x5555555555555555;
296 break;
297 case PATTERN_ZEROS :
298 DATA = 0x00000000;
299 break;
300 default :
301 break;
302 }
303 }
304 return error_count;
305 }
306
307 /***************************************************************************//**
308 * Reads and compares with what was written
309 * @param DDR_word_ptr
310 * @param no_of_access
311 * @param data_ptrn
312 * @return 0 => read backs all expected value, otherwise error count
313 */
ddr_read(volatile uint64_t * DDR_word_ptr,uint32_t no_of_access,uint8_t data_ptrn,DDR_ACCESS_SIZE data_size)314 uint32_t ddr_read
315 (
316 volatile uint64_t *DDR_word_ptr,
317 uint32_t no_of_access,
318 uint8_t data_ptrn,
319 DDR_ACCESS_SIZE data_size
320 )
321 {
322 uint32_t i;
323 uint64_t DATA;
324 uint32_t err_cnt;
325 volatile uint64_t ddr_data;
326 volatile uint64_t *DDR_word_pt_t, *first_DDR_word_pt_t;
327 uint32_t rand_addr_offset;
328 uint8_t *DDR_8_pt_t;
329 uint16_t *DDR_16_pt_t;
330 uint32_t *DDR_32_pt_t;
331
332 err_cnt = 0U;
333 first_DDR_word_pt_t = DDR_word_ptr;
334 DDR_8_pt_t = (uint8_t *)DDR_word_ptr;
335 DDR_16_pt_t = (uint16_t *)DDR_word_ptr;
336 DDR_32_pt_t = (uint32_t *)DDR_word_ptr;
337
338 switch (data_ptrn)
339 {
340 case PATTERN_INCREMENTAL : DATA = 0x00000000; break;
341 case PATTERN_WALKING_ONE : DATA = 0x00000001; break;
342 case PATTERN_WALKING_ZERO : DATA = 0x01;
343 DATA = ~ DATA; break;
344 case PATTERN_RANDOM :
345 DATA = (uint64_t)rand ( );
346 *DDR_word_ptr = DATA;
347 *DDR_8_pt_t = (uint8_t)DATA;
348 *DDR_16_pt_t = (uint16_t)DATA;
349 *DDR_32_pt_t = (uint32_t)DATA;
350 break;
351 case PATTERN_0xCCCCCCCC :
352 DATA = 0xCCCCCCCCCCCCCCCC;
353 break;
354 case PATTERN_0x55555555 :
355 DATA = 0x5555555555555555;
356 break;
357 case PATTERN_ZEROS :
358 DATA = 0x00000000;
359 break;
360 default :
361 DATA = 0x00000000;
362 break;
363 }
364 if (data_ptrn == '4')
365 {
366 delay(10);
367 }
368 for( i = 0; i< (no_of_access); i++)
369 {
370 switch(data_size)
371 {
372 case DDR_8_BIT:
373 DATA &= 0xFFUL;
374 ddr_data = *DDR_8_pt_t;
375 break;
376 case DDR_16_BIT:
377 DATA &= 0xFFFFUL;
378 ddr_data = *DDR_16_pt_t;
379 break;
380 case DDR_32_BIT:
381 DATA &= 0xFFFFFFFFUL;
382 ddr_data = *DDR_32_pt_t;
383 break;
384 default:
385 case DDR_64_BIT:
386 DDR_word_pt_t = DDR_word_ptr;
387 ddr_data = *DDR_word_pt_t;
388 break;
389 }
390
391 #ifdef DEBUG_DDR_INIT
392 if((i%0x1000000UL) ==0UL)
393 {
394 MSS_UART_polled_tx(g_debug_uart, (const uint8_t*)"r", (uint32_t)1UL);
395 }
396 #endif
397
398 if (ddr_data != DATA)
399 {
400 #ifdef DEBUG_DDR_INIT
401 #ifdef DEBUG_DDR_RD_RW_FAIL
402 if (err_cnt <=0xF)
403 {
404 uprint64(g_debug_uart,\
405 "\n\r READ/ WRITE ACCESS FAILED AT ADDR: 0x ",\
406 (uintptr_t)DDR_word_ptr);
407 uprint64(g_debug_uart,"\t Expected Data 0x ", DATA);
408 uprint64(g_debug_uart,"\t READ DATA: 0x ", ddr_data);
409 uprint64(g_debug_uart,"\t READ DATA: 0x ", *DDR_word_ptr);
410 uprint64(g_debug_uart,"\t READ DATA: 0x ", *DDR_word_ptr);
411 }
412 #endif
413 #endif
414 err_cnt++;
415 }
416 else
417 {
418 #ifdef DEBUG_DDR_RD_RW_PASS
419 //printf("\n\r READ/ WRITE ACCESS passED AT ADDR: 0x%x expected data = 0x%x, Data read 0x%x",DDR_word_ptr, DATA, *DDR_word_ptr);
420 uprint64(g_debug_uart, "\n\r READ/ WRITE ACCESS PASSED AT ADDR: 0x"\
421 , (uintptr_t)DDR_word_ptr);
422 uprint64(g_debug_uart,"\t READ DATA: 0x", *DDR_word_ptr);
423 #endif
424 }
425 DDR_word_ptr = DDR_word_ptr + 1U;
426 DDR_8_pt_t = DDR_8_pt_t +1U;
427 DDR_16_pt_t = DDR_16_pt_t +1U;
428 DDR_32_pt_t = DDR_32_pt_t +1U;
429 switch (data_ptrn)
430 {
431 case PATTERN_INCREMENTAL : DATA = DATA + 0x01; break;
432 case PATTERN_WALKING_ONE :
433 if (DATA == 0x80000000)
434 DATA = 0x00000001;
435 else
436 DATA = (DATA << 1);
437 break;
438 case PATTERN_WALKING_ZERO :
439 DATA = ~DATA;
440 if (DATA == 0x80000000)
441 {
442 DATA = 0x00000001;
443 }
444 else
445 {
446 DATA = (DATA << 1);
447 }
448 DATA = ~DATA;
449 break;
450 case PATTERN_RANDOM :
451 DATA = (uint64_t)rand ( );
452 rand_addr_offset = (uint32_t)(rand() & 0xFFFFCUL);
453 DDR_word_ptr = first_DDR_word_pt_t + rand_addr_offset;
454 DDR_8_pt_t = (uint8_t *)(first_DDR_word_pt_t + rand_addr_offset);
455 DDR_16_pt_t = (uint16_t *)(first_DDR_word_pt_t + rand_addr_offset);
456 DDR_32_pt_t = (uint32_t *)(first_DDR_word_pt_t + rand_addr_offset);
457 *DDR_word_ptr = DATA;
458 *DDR_8_pt_t = (uint8_t)DATA;
459 *DDR_16_pt_t = (uint16_t)DATA;
460 *DDR_32_pt_t = (uint32_t)DATA;
461 break;
462 case PATTERN_0xCCCCCCCC :
463 DATA = 0xCCCCCCCCCCCCCCCC;
464 break;
465 case PATTERN_0x55555555 :
466 DATA = 0x5555555555555555;
467 break;
468 case PATTERN_ZEROS :
469 DATA = 0x00000000;
470 break;
471 default :
472 break;
473 }
474 }
475 return (err_cnt);
476 }
477
478 /***************************************************************************//**
479 *
480 * @param DDR_word_ptr Address
481 * @param no_access Number of addresses
482 * @param pattern bit mask with patterns you want to test against
483 * @return
484 */
ddr_read_write_fn(uint64_t * DDR_word_ptr,uint32_t no_access,uint32_t pattern)485 uint32_t ddr_read_write_fn (uint64_t* DDR_word_ptr, uint32_t no_access,\
486 uint32_t pattern)
487 {
488 uint32_t error_cnt = 0U;
489 uint8_t pattern_mask;
490 for (unsigned i=0; i < 1; i++)
491 {
492 for (uint32_t pattern_shift=0U; pattern_shift < MAX_NO_PATTERNS;\
493 pattern_shift++)
494 {
495 pattern_mask = (uint8_t)(0x01U << pattern_shift);
496 if(pattern & pattern_mask)
497 {
498 #ifdef DEBUG_DDR_INIT
499 uprint32(g_debug_uart,"\n\r\t Pattern: 0x", pattern_shift);
500 #endif
501
502 #if TEST_64BIT_ACCESS == 1
503 /* write the pattern */
504 error_cnt += ddr_write ((uint64_t *)DDR_word_ptr,\
505 no_access, pattern_mask, DDR_64_BIT);
506 /* read back and verifies */
507 error_cnt += ddr_read ((uint64_t *)DDR_word_ptr, \
508 no_access, pattern_mask, DDR_64_BIT);
509 #endif
510
511 #if TEST_32BIT_ACCESS == 1
512 /* write the pattern */
513 error_cnt += ddr_write ((uint64_t *)DDR_word_ptr,\
514 no_access, pattern_mask, DDR_32_BIT);
515 /* read back and verifies */
516 error_cnt += ddr_read ((uint64_t *)DDR_word_ptr, \
517 no_access, pattern_mask, DDR_32_BIT);
518 #endif
519 }
520 }
521 DDR_word_ptr++; /* increment the address */
522 }
523 return error_cnt;
524 }
525
526
527 /***************************************************************************//**
528 *
529 * @param error
530 * @return
531 */
532 #ifdef DEBUG_DDR_INIT
error_status(mss_uart_instance_t * g_mss_uart_debug_pt,uint32_t error)533 uint32_t error_status(mss_uart_instance_t *g_mss_uart_debug_pt, uint32_t error)
534 {
535 uprint32(g_mss_uart_debug_pt, "\n\r ERROR_RESULT: ", error);
536 return (0U);
537 }
538 #endif
539
540 /***************************************************************************//**
541 * Calibration status
542 * @return
543 */
544 #ifdef DEBUG_DDR_INIT
wrcalib_status(mss_uart_instance_t * g_mss_uart_debug_pt)545 uint32_t wrcalib_status(mss_uart_instance_t *g_mss_uart_debug_pt)
546 {
547 uprint32(g_mss_uart_debug_pt, "\n\r WRCALIB_RESULT: ",\
548 CFG_DDR_SGMII_PHY->expert_wrcalib.expert_wrcalib);
549 return (0U);
550 }
551 #endif
552
553 #ifdef DEBUG_DDR_INIT
554 /***************************************************************************//**
555 * Prints out DDR status
556 * @return
557 */
tip_register_status(mss_uart_instance_t * g_mss_uart_debug_pt)558 uint32_t tip_register_status (mss_uart_instance_t *g_mss_uart_debug_pt)
559 {
560
561 uint32_t t_status = 0U;
562 uint32_t MSS_DDR_APB_ADDR;
563 uint32_t ddr_lane_sel;
564 uint32_t dq0_dly = 0U;
565 uint32_t dq1_dly = 0U;
566 uint32_t dq2_dly = 0U;
567 uint32_t dq3_dly = 0U;
568 uint32_t dq4_dly = 0U;
569 uint32_t dq5_dly = 0U;
570
571 /* MSS_UART_polled_tx_string(g_mss_uart_debug_pt, "\n\n\r TIP register status \n");
572 delay(1000);*/
573 uprint32(g_mss_uart_debug_pt, "\n\r\n\r training status = ",\
574 CFG_DDR_SGMII_PHY->training_status.training_status);
575 uprint32(g_mss_uart_debug_pt, "\n\r PCODE = ",\
576 (CFG_DDR_SGMII_PHY->IOC_REG2.IOC_REG2 & 0x7F));
577 uprint32(g_mss_uart_debug_pt, "\n\r NCODE = ",\
578 (((CFG_DDR_SGMII_PHY->IOC_REG2.IOC_REG2) >> 7) & 0x7F));
579 uprint32(g_mss_uart_debug_pt, "\n\r WRCALIB_RESULT: "\
580 , CFG_DDR_SGMII_PHY->expert_wrcalib.expert_wrcalib);
581 uprint32(g_mss_uart_debug_pt, "\n\r sro_ref_slewr = ",\
582 (((CFG_DDR_SGMII_PHY->IOC_REG5.IOC_REG5) >> 0) & 0x3F));
583 uprint32(g_mss_uart_debug_pt, "\n\r sro_ref_slewf = ",\
584 (((CFG_DDR_SGMII_PHY->IOC_REG5.IOC_REG5) >> 6) & 0xFFF));
585 uprint32(g_mss_uart_debug_pt, "\n\r sro_slewr = ",\
586 (((CFG_DDR_SGMII_PHY->IOC_REG5.IOC_REG5) >> 18) & 0x3F));
587 uprint32(g_mss_uart_debug_pt, "\n\r sro_slewf = ",\
588 (((CFG_DDR_SGMII_PHY->IOC_REG5.IOC_REG5) >> 24) & 0x3F));
589
590 MSS_UART_polled_tx_string(g_mss_uart_debug_pt, \
591 (const uint8_t*)"\n\n\r lane_select \t gt_err_comb \t gt_txdly \t gt_steps_180 \t gt_state \t wl_delay_0 \t dqdqs_err_done \t dqdqs_state \t delta0 \t delta1");
592
593 for (ddr_lane_sel=0U; ddr_lane_sel < LIBERO_SETTING_DATA_LANES_USED; ddr_lane_sel++)
594 {
595 CFG_DDR_SGMII_PHY->lane_select.lane_select = ddr_lane_sel;
596 uprint32(g_mss_uart_debug_pt, "\n\r ",\
597 CFG_DDR_SGMII_PHY->lane_select.lane_select);
598 delay(1000);
599 MSS_DDR_APB_ADDR = CFG_DDR_SGMII_PHY->gt_err_comb.gt_err_comb;
600 uprint32(g_mss_uart_debug_pt, "\t ", MSS_DDR_APB_ADDR);
601 t_status = t_status | MSS_DDR_APB_ADDR;
602
603 MSS_DDR_APB_ADDR = CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly;
604 uprint32(g_mss_uart_debug_pt, "\t ", MSS_DDR_APB_ADDR);
605
606 if((MSS_DDR_APB_ADDR & 0xFF) == 0) t_status = 1;
607 if((MSS_DDR_APB_ADDR & 0xFF00) == 0) t_status = 1;
608 if((MSS_DDR_APB_ADDR & 0xFF0000) == 0) t_status = 1;
609 if((MSS_DDR_APB_ADDR & 0xFF000000) == 0) t_status = 1;
610
611 uprint32(g_mss_uart_debug_pt, "\t ",\
612 CFG_DDR_SGMII_PHY->gt_steps_180.gt_steps_180);
613 uprint32(g_mss_uart_debug_pt, "\t ",\
614 CFG_DDR_SGMII_PHY->gt_state.gt_state);
615 uprint32(g_mss_uart_debug_pt, "\t ",\
616 CFG_DDR_SGMII_PHY->wl_delay_0.wl_delay_0);
617 uprint32(g_mss_uart_debug_pt, "\t ",\
618 CFG_DDR_SGMII_PHY->dq_dqs_err_done.dq_dqs_err_done);
619 t_status = t_status | (MSS_DDR_APB_ADDR != 8);
620
621 uprint32(g_mss_uart_debug_pt, "\t\t ",\
622 CFG_DDR_SGMII_PHY->dqdqs_state.dqdqs_state);
623 uprint32(g_mss_uart_debug_pt, "\t ",\
624 CFG_DDR_SGMII_PHY->delta0.delta0);
625 dq0_dly = (MSS_DDR_APB_ADDR & 0xFF);
626 dq1_dly = (MSS_DDR_APB_ADDR & 0xFF00) >> 8;
627 dq2_dly = (MSS_DDR_APB_ADDR & 0xFF0000) >> 16;
628 dq3_dly = (MSS_DDR_APB_ADDR & 0xFF000000) >> 24;
629 uprint32(g_mss_uart_debug_pt, "\t ",\
630 CFG_DDR_SGMII_PHY->delta1.delta1);
631 dq4_dly = (MSS_DDR_APB_ADDR & 0xFF);
632 dq5_dly = (MSS_DDR_APB_ADDR & 0xFF00) >> 8;
633 dq2_dly = (MSS_DDR_APB_ADDR & 0xFF0000) >> 16;
634 dq3_dly = (MSS_DDR_APB_ADDR & 0xFF000000) >> 24;
635 }
636
637 MSS_UART_polled_tx_string(g_mss_uart_debug_pt, (const uint8_t*)"\n\r\n\r lane_select\t rdqdqs_status2\t addcmd_status0\t addcmd_status1\t addcmd_answer1\t dqdqs_status1\n\r");
638 for (ddr_lane_sel=0U; ddr_lane_sel < LIBERO_SETTING_DATA_LANES_USED;\
639 ddr_lane_sel++)
640 {
641 CFG_DDR_SGMII_PHY->lane_select.lane_select = ddr_lane_sel;
642 uprint32(g_mss_uart_debug_pt, "\n\r ",\
643 CFG_DDR_SGMII_PHY->lane_select.lane_select);
644 delay(1000);
645
646 if(dq0_dly > 20) t_status = 1;
647 if(dq1_dly > 20) t_status = 1;
648 if(dq2_dly > 20) t_status = 1;
649 if(dq3_dly > 20) t_status = 1;
650 if(dq4_dly > 20) t_status = 1;
651 if(dq5_dly > 20) t_status = 1;
652
653 uprint32(g_mss_uart_debug_pt, "\t ",\
654 CFG_DDR_SGMII_PHY->dqdqs_status2.dqdqs_status2);
655
656 uprint32(g_mss_uart_debug_pt, "\t ",\
657 CFG_DDR_SGMII_PHY->addcmd_status0.addcmd_status0);
658 uprint32(g_mss_uart_debug_pt, "\t ",\
659 CFG_DDR_SGMII_PHY->addcmd_status1.addcmd_status1);
660 uprint32(g_mss_uart_debug_pt, "\t ",\
661 CFG_DDR_SGMII_PHY->addcmd_answer.addcmd_answer);
662 uprint32(g_mss_uart_debug_pt, "\t ",\
663 CFG_DDR_SGMII_PHY->dqdqs_status1.dqdqs_status1);
664
665 }
666 return(t_status);
667 }
668 #endif
669
670 /***************************************************************************//**
671 * display sweep results
672 *
673 * @param g_mss_uart_debug_pt
674 */
675 #ifdef DEBUG_DDR_INIT
676 #ifdef SWEEP_ENABLED
sweep_status(mss_uart_instance_t * g_mss_uart_debug_pt)677 void sweep_status (mss_uart_instance_t *g_mss_uart_debug_pt)
678 {
679
680 uint32_t t_status;
681 uint8_t cmd_index;
682 uint8_t bclk_sclk_index;
683 uint8_t dpc_vgen_index;
684 uint8_t dpc_vgen_h_index;
685 uint8_t dpc_vgen_vs_index;
686
687 MSS_UART_polled_tx_string(g_mss_uart_debug_pt,\
688 "\n\n\r dpc_vgen_vs dpc_vgen_h \t dpc_vgen_v \t bclk_sclk");
689 for (cmd_index=0U; cmd_index < MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS; \
690 cmd_index++)
691 {
692 uprint32(g_mss_uart_debug_pt, "\t ",\
693 cmd_index + LIBERO_SETTING_MIN_ADDRESS_CMD_OFFSET);
694 }
695 MSS_UART_polled_tx_string(g_mss_uart_debug_pt,\
696 "\n\r--------------------------------------------------------------------");
697
698 for (dpc_vgen_vs_index=0U; dpc_vgen_vs_index<MAX_NUMBER_DPC_VS_GEN_SWEEPS;\
699 dpc_vgen_vs_index++)
700 {
701 for (dpc_vgen_h_index=0U; dpc_vgen_h_index < \
702 MAX_NUMBER_DPC_H_GEN_SWEEPS; dpc_vgen_h_index++)
703 {
704 for (dpc_vgen_index=0U; dpc_vgen_index < \
705 MAX_NUMBER_DPC_V_GEN_SWEEPS; dpc_vgen_index++)
706 {
707 for (bclk_sclk_index=0U; bclk_sclk_index < \
708 MAX_NUMBER__BCLK_SCLK_OFFSET_SWEEPS; bclk_sclk_index++)
709 {
710 uprint32(g_mss_uart_debug_pt, "\n\r ", dpc_vgen_vs_index + \
711 LIBERO_SETTING_MIN_DPC_VS_GEN);
712 uprint32(g_mss_uart_debug_pt, "\t ", dpc_vgen_h_index + \
713 LIBERO_SETTING_MIN_DPC_H_GEN);
714 uprint32(g_mss_uart_debug_pt, "\t ", dpc_vgen_index + \
715 LIBERO_SETTING_MIN_DPC_V_GEN);
716 uprint32(g_mss_uart_debug_pt, "\t ", bclk_sclk_index + \
717 LIBERO_SETTING_MIN_ADDRESS_BCLK_SCLK_OFFSET);
718 for (cmd_index=0U; cmd_index < \
719 MAX_NUMBER_ADDR_CMD_OFFSET_SWEEPS; cmd_index++)
720 {
721 if(sweep_results[dpc_vgen_vs_index][dpc_vgen_h_index]\
722 [dpc_vgen_index][bclk_sclk_index][cmd_index] ==\
723 CALIBRATION_PASSED)
724 {
725 MSS_UART_polled_tx_string(g_mss_uart_debug_pt,\
726 "\t\t pass");
727 }
728 else
729 {
730 /*
731 * easier to see if not printed
732 * todo: may add detail to fail
733 * */
734 MSS_UART_polled_tx_string(g_mss_uart_debug_pt,\
735 "\t\t F");
736 }
737
738 }
739 }
740 }
741 }
742 }
743 }
744 #endif
745 #endif
746
747
748 /**
749 * Load a pattern to DDR
750 */
load_ddr_pattern(uint64_t base,uint32_t size,uint8_t pattern_offset)751 void load_ddr_pattern(uint64_t base, uint32_t size, uint8_t pattern_offset)
752 {
753 int alive = 0;
754
755 uint8_t *p_ddr = (uint8_t *)base;
756 uint32_t pattern_length = sizeof(ddr_test_pattern) - pattern_offset ;
757
758 #ifdef DEBUG_DDR_INIT
759 uprint(g_debug_uart, (const char*)(const uint8_t*)"\r\nLoading test pattern\r\n");
760 #endif
761
762 while(((uint64_t)p_ddr + pattern_length) < (base + size))
763 {
764
765 switch ( ((uint64_t)p_ddr)%8U )
766 {
767 case 0:
768 case 4:
769 pdma_transfer_complete(PDMA_CHANNEL0_BASE_ADDRESS);
770 pdma_transfer((uint64_t)p_ddr, (uint64_t)ddr_test_pattern, pattern_length, PDMA_CHANNEL0_BASE_ADDRESS);
771 break;
772 case 1:
773 case 5:
774 pdma_transfer_complete(PDMA_CHANNEL1_BASE_ADDRESS);
775 pdma_transfer((uint64_t)p_ddr, (uint64_t)ddr_test_pattern, pattern_length, PDMA_CHANNEL1_BASE_ADDRESS);
776 break;
777 case 2:
778 case 6:
779 pdma_transfer_complete(PDMA_CHANNEL2_BASE_ADDRESS);
780 pdma_transfer((uint64_t)p_ddr, (uint64_t)ddr_test_pattern, pattern_length, PDMA_CHANNEL2_BASE_ADDRESS);
781 break;
782 case 3:
783 case 7:
784 pdma_transfer_complete(PDMA_CHANNEL3_BASE_ADDRESS);
785 pdma_transfer((uint64_t)p_ddr, (uint64_t)ddr_test_pattern, pattern_length, PDMA_CHANNEL3_BASE_ADDRESS);
786 break;
787 }
788
789 p_ddr = p_ddr + (pattern_length);
790 alive++;
791 if (alive > 1000)
792 {
793 alive = 0;
794 #ifdef DEBUG_DDR_INIT
795 uprint(g_debug_uart, (const char*)".");
796 #endif
797 }
798 }
799 #ifdef DEBUG_DDR_INIT
800 uprint(g_debug_uart, (const char*)"\r\nFinished loading test pattern\r\n");
801 #endif
802
803 pdma_transfer_complete(PDMA_CHANNEL0_BASE_ADDRESS);
804 pdma_transfer_complete(PDMA_CHANNEL1_BASE_ADDRESS);
805 pdma_transfer_complete(PDMA_CHANNEL2_BASE_ADDRESS);
806 pdma_transfer_complete(PDMA_CHANNEL3_BASE_ADDRESS);
807
808 }
809
810 /**
811 * Run from address
812 * @param start_addr address to run from.
813 */
execute_ddr_pattern(uint64_t start_addr)814 void execute_ddr_pattern(uint64_t start_addr)
815 {
816 pattern_fct_t p_pattern_fct = (pattern_fct_t)start_addr;
817
818 (*p_pattern_fct)();
819 }
820
821 /**
822 * Loads DDR with a pattern that triggers read issues if not enough margin.
823 * Used to verify training is successful.
824 * @param p_cached_ddr
825 * @param p_not_cached_ddr
826 * @param length
827 */
load_test_buffers(uint32_t * p_cached_ddr,uint32_t * p_not_cached_ddr,uint64_t length)828 void load_test_buffers(uint32_t * p_cached_ddr, uint32_t * p_not_cached_ddr, uint64_t length)
829 {
830 (void)length;
831
832 pdma_transfer((uint64_t)g_test_buffer_cached, (uint64_t)p_cached_ddr, length, PDMA_CHANNEL0_BASE_ADDRESS);
833 pdma_transfer((uint64_t)g_test_buffer_not_cached, (uint64_t)p_not_cached_ddr, length, PDMA_CHANNEL1_BASE_ADDRESS);
834 pdma_transfer_complete(PDMA_CHANNEL0_BASE_ADDRESS);
835 pdma_transfer_complete(PDMA_CHANNEL1_BASE_ADDRESS);
836 }
837
838 /**
839 * test_ddr reads from cached and non cached DDR and compares
840 * @param no_of_iterations
841 * @param size
842 * @return returns 1 if compare fails
843 */
test_ddr(uint32_t no_of_iterations,uint32_t size)844 uint32_t test_ddr(uint32_t no_of_iterations, uint32_t size)
845 {
846 uint32_t pattern_length = sizeof(ddr_test_pattern) - (3 * sizeof(uint32_t));
847 uint32_t * p_ddr_cached = (uint32_t *)0x80000000;
848 uint32_t * p_ddr_noncached = (uint32_t *)0x1400000000;
849 uint32_t word_offset;
850 uint32_t alive = 0;
851 uint32_t alive_idx = 0U;
852 uint32_t iteration = 0U;
853 uint32_t error = 0U;
854
855
856 #ifdef DEBUG_DDR_INIT
857 uprint(g_debug_uart, (const char*)"\r\nStarting ddr test\r\n");
858 #endif
859 while(iteration < no_of_iterations)
860 {
861 int different = 0;
862
863 load_test_buffers(p_ddr_cached, p_ddr_noncached, pattern_length);
864
865 different = memcmp(g_test_buffer_cached, g_test_buffer_not_cached, pattern_length);
866
867 if(different != 0)
868 {
869 for(word_offset = 0; word_offset < (pattern_length / sizeof(uint32_t)); word_offset++)
870 {
871 if(g_test_buffer_cached[word_offset] != g_test_buffer_not_cached[word_offset])
872 {
873 #ifdef DEBUG_DDR_INIT
874 uprint64(g_debug_uart, " Mismatch, 0x", (uint64_t)p_ddr_cached);
875 uprint32(g_debug_uart, " offset:, 0x", (uint64_t)word_offset);
876 uprint32(g_debug_uart, " address: 0x", (uint64_t)(p_ddr_cached + word_offset));
877 uprint32(g_debug_uart, " expected (non-cached): 0x", g_test_buffer_not_cached[word_offset]);
878 uprint32(g_debug_uart, " found (cached): 0x", (uint64_t)g_test_buffer_cached[word_offset]);
879 uprint32(g_debug_uart, " direct cached read: 0x", (uint32_t)*(p_ddr_cached + word_offset));
880 uprint32(g_debug_uart, " direct non-cached read: 0x", (uint32_t)*(p_ddr_noncached + word_offset));
881 #endif
882 break;
883 }
884 }
885 error = 1U;
886 return error;
887 }
888
889 if (((uint64_t)p_ddr_cached + ( 2 * pattern_length)) < (LIBERO_SETTING_DDR_32_CACHE + size))
890 {
891 p_ddr_cached += (pattern_length / sizeof(uint32_t));
892 p_ddr_noncached += (pattern_length / sizeof(uint32_t));
893 }
894 else
895 {
896 p_ddr_cached = (uint32_t *)0x80000000;
897 p_ddr_noncached = (uint32_t *)0x1400000000;
898 iteration++;
899 #ifdef DEBUG_DDR_INIT
900 uprint32(g_debug_uart, " Iteration ", (uint64_t)(unsigned int)iteration);
901 #endif
902 }
903
904 alive++;
905 if(alive > 10000U)
906 {
907 alive = 0;
908 #ifdef DEBUG_DDR_INIT
909 uprint(g_debug_uart, (const char*)"\r");
910 uprint(g_debug_uart, (const char*)progress[alive_idx]);
911 #endif
912 alive_idx++;
913 if(alive_idx >= 3U)
914 {
915 alive_idx = 0;
916 }
917 if(ddr_test == 2U)
918 {
919 #ifdef DEBUG_DDR_INIT
920 uprint(g_debug_uart, (const char*)"\r\nEnding ddr test. Press 0 to display the menu\r\n");
921 #endif
922 return error;
923 }
924 }
925 }
926 return error;
927 }
928
929
930
931