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