Updated paramters passed in OSPI API calls
[processor-sdk/pdk.git] / packages / ti / drv / udma / examples / udma_ospi_flash_test / udma_ospi_flash_test.c
1 /*
2  *  Copyright (c) Texas Instruments Incorporated 2020
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions
6  *  are met:
7  *
8  *    Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  *    Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the
14  *    distribution.
15  *
16  *    Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
33 /**
34  *  \file udma_ospi_flash_test.c
35  *
36  *  \brief UDMA OSPI Flash sample application performs DAC DMA mode ospi write and read 
37  *  at 133MHz RCLK and 166MHz RCLK with UDMA 3D transfer using SW trigger method as below.
38  * 
39  *  Performs OSPI write of "appTestObj->numBytes" bytes:
40  *      - Loop L times (icnt1)
41  *         - SW trigger UDMA Channel -> Triggers OSPI Write of K bytes from R5 TCM to OSPI Data Buffer
42  *         - wait for transfer to complete
43  *         - wait for ospi flash to get ready for next write
44  *  > Eack inner loop writes K (inct0) bytes of data and wait for device to be ready.
45  *  > R5 TCM and OSPI Data Buffer size is L x K bytes.
46  * 
47  *  Where,
48  *      - K is icnt0 - "UDMA_TEST_WRITE_CHUNK_SIZE"
49  *      - L is icnt1 - is chunkCnt: "appTestObj->numBytes/UDMA_TEST_WRITE_CHUNK_SIZE"
50  * 
51  *  Performs OSPI read of "appTestObj->numBytes" bytes, UDMA_TEST_XFER_REPEAT_CNT no. of times
52  *     - Loop N times:
53  *          [The following performs OSPI read of icnt0 bytes]
54  *          - SW trigger UDMA Channel -> Triggers OSPI Read M bytes from OSPI Data Buffer to R5 TCM 
55  *          - Wait for transfer to complete
56  * 
57  *  > Each loop transfers M (icnt0) bytes of data
58  *  > R5 TCM and OSPI Data Buffer size is M bytes.
59  *  > For each loop the tranfer restarts from the origin address.
60  *
61  *  Where,
62  *      - M is icnt0 - "appTestObj->numBytes"  
63  *          This refers to the no. of bytes transferred per OSPI Read operation.
64  *      - N is UDMA_TEST_XFER_REPEAT_CNT
65  *         This parameters can be used to configure the the no.of times to repeat the whole transfer starting from the origin address.
66  * 
67  *  This read illustrates TR Reload Feature in which TR Reload count is set as 0x1FFU for perpetual loop.
68  *  In this example, after UDMA_TEST_XFER_REPEAT_CNT no.of read operations, we teardown the channel to exit from the loop.
69  */
71 /* ========================================================================== */
72 /*                             Include Files                                  */
73 /* ========================================================================== */
75 #include <stdio.h>
76 #include <ti/csl/soc.h>
77 #include <ti/csl/arch/csl_arch.h>
78 #include <ti/csl/hw_types.h>
79 #include <ti/drv/udma/udma.h>
80 #include <ti/drv/uart/UART.h>
81 #include <ti/drv/uart/UART_stdio.h>
82 #include <ti/drv/udma/examples/udma_apputils/udma_apputils.h>
83 #include <ti/csl/example/ospi/ospi_flash/common/ospi_flash_common.h>
85 /* ========================================================================== */
86 /*                           Macros & Typedefs                                */
87 /* ========================================================================== */
89 /*
90  * Application test config parameters
91  */
92 /** \brief Maximum Number of bytes to perform OSPI Read/Write per operation (Actual number based on test) */
93 #define UDMA_TEST_XFER_MAX_NUM_BYTES    (1024U)
94 /** \brief Number of times to repeat whole data tranfer */
95 #define UDMA_TEST_XFER_REPEAT_CNT       (10U)
96 /** \brief ChunkSize in bytes for each DMA mode OSPI Flash Write operation */
97 #define UDMA_TEST_WRITE_CHUNK_SIZE      (16U)
99 /*
100  * Application other test parameters
101  */
103 /** \brief Total number of bytes to copy and buffer allocation */
104 #define UDMA_TEST_APP_MAX_TOTAL_NUM_BYTES   (UDMA_TEST_XFER_MAX_NUM_BYTES)
105 /** \brief This ensures every channel memory is aligned */
106 #define UDMA_TEST_APP_BUF_SIZE_ALIGN        ((UDMA_TEST_APP_MAX_TOTAL_NUM_BYTES + UDMA_CACHELINE_ALIGNMENT) & ~(UDMA_CACHELINE_ALIGNMENT - 1U))
108 /*
109  * Ring parameters
110  */
111 /** \brief Number of ring entries - we can prime this much memcpy operations */
112 #define UDMA_TEST_APP_RING_ENTRIES      (1U)
113 /** \brief Size (in bytes) of each ring entry (Size of pointer - 64-bit) */
114 #define UDMA_TEST_APP_RING_ENTRY_SIZE   (sizeof(uint64_t))
115 /** \brief Total ring memory */
116 #define UDMA_TEST_APP_RING_MEM_SIZE     (UDMA_TEST_APP_RING_ENTRIES * \
117                                          UDMA_TEST_APP_RING_ENTRY_SIZE)
118 /** \brief This ensures every channel memory is aligned */
119 #define UDMA_TEST_APP_RING_MEM_SIZE_ALIGN ((UDMA_TEST_APP_RING_MEM_SIZE + UDMA_CACHELINE_ALIGNMENT) & ~(UDMA_CACHELINE_ALIGNMENT - 1U))
120 /**
121  *  \brief UDMA TR packet descriptor memory.
122  *  This contains the CSL_UdmapCppi5TRPD + Padding to sizeof(CSL_UdmapTR15) +
123  *  one Type_15 TR (CSL_UdmapTR15) + one TR response of 4 bytes.
124  *  Since CSL_UdmapCppi5TRPD is less than CSL_UdmapTR15, size is just two times
125  *  CSL_UdmapTR15 for alignment.
126  */
127 #define UDMA_TEST_APP_TRPD_SIZE         ((sizeof(CSL_UdmapTR15) * 2U) + 4U)
128 /** \brief This ensures every channel memory is aligned */
129 #define UDMA_TEST_APP_TRPD_SIZE_ALIGN   ((UDMA_TEST_APP_TRPD_SIZE + UDMA_CACHELINE_ALIGNMENT) & ~(UDMA_CACHELINE_ALIGNMENT - 1U))
131 /*
132  * UDMA OSPI Flash test ID definitions
133  */
134 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 16 Bytes */
135 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_16B     (0U)  
136 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 16 Bytes */
137 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_16B     (1U) 
138 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 32 Bytes */
139 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_32B     (2U) 
140 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 32 Bytes */
141 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_32B     (3U)  
142 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 64 Bytes */
143 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_64B     (4U)  
144 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 64 Bytes */
145 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_64B     (5U)  
146 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 128 Bytes */
147 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_128B    (6U) 
148 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 128 Bytes */
149 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_128B    (7U)  
150 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 256 Bytes */
151 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_256B    (8U)  
152 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 256 Bytes */
153 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_256B    (9U)   
154 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 512 Bytes */
155 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_512B    (10U)  
156 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 512 Bytes */
157 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_512B    (11U)  
158 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 1024 Bytes */
159 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_1024B   (12U) 
160 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 1024 Bytes */
161 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_1024B   (13U)
162     
163 /** \brief Get GTC Timer Ticks */
164 #define App_getGTCTimerTicks() (*((uint64_t *)(CSL_GTC0_GTC_CFG1_BASE + 0x8U)))
166 /* ========================================================================== */
167 /*                         Structure Declarations                             */
168 /* ========================================================================== */
170 typedef struct
172     struct Udma_EventObj    trEventObj;
174     Udma_EventHandle        trEventHandle;
175     Udma_EventPrms          trEventPrms;
177     /**< TR Reload Count */
178     uint32_t                reloadCnt;
180     uint32_t                trigger;
181     /**< Global0 or Global 1 Trigger - refer \ref CSL_UdmapTrFlagsTrigger. */
182     uint32_t                eventSize;
183     /**< Refer \ref CSL_UdmapTrFlagsEventSize. */
184     uint32_t                triggerType;
185     /**< Refer \ref CSL_UdmapTrFlagsTriggerType. */
186     uint32_t                eolType;
187     /**< Refer \ref CSL_UdmapTrFlagsEol. */
189     /**< Refer TR Address and Size Attributes */
190     uint16_t                icnt[4];    
191     uint16_t                dicnt[4];    
192     int32_t                 dim[3];
193     int32_t                 ddim[3];    
194     uint8_t                *addr;    
195     uint8_t                *daddr;    
197     Udma_DrvHandle          drvHandle;
199 } App_UdmaTrObj;
201 typedef struct
203     struct Udma_ChObj       chObj;
204     App_UdmaTrObj           appTrObj;   
206 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
207     struct Udma_EventObj    tdCqEventObj;
208     Udma_EventHandle        tdCqEventHandle;
209     Udma_EventPrms          tdCqEventPrms;
210 #endif 
212     Udma_ChHandle           chHandle;
213     Udma_DrvHandle          drvHandle;
215     uint8_t                 *txRingMem;
216 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
217     uint8_t                 *txCompRingMem;
218     uint8_t                 *txTdCompRingMem;
219 #endif
220     uint8_t                 *trpdMem;
222 } App_UdmaChObj;
224 typedef struct 
226     int32_t  (*testFunc)(void);
227     int32_t  testId;    
228     uint32_t clk;
229     uint32_t numBytes;
230     char     testDesc[80];
232 } App_UdmaTestObj;
234 typedef struct
236     /**< GTC Timer ticks at start of profiling OSPI write. */
237     volatile uint64_t       txStartTicks;
238     /**< GTC Timer ticks at stop of profiling OSPI write. */
239     volatile uint64_t       txStopTicks;
240     /**< Measured total no. of GTC Timer ticks for OSPI write. */
241     volatile uint64_t       txTotalTicks;
242     /**< Elapsed time in nsec for OSPI write.. */
243     volatile uint64_t       txElapsedTime;
245     /**< GTC Timer ticks at start of profiling OSPI read. */
246     volatile uint64_t       rxStartTicks[UDMA_TEST_XFER_REPEAT_CNT];
247     /**< GTC Timer ticks at stop of profiling OSPI read. */
248     volatile uint64_t       rxStopTicks[UDMA_TEST_XFER_REPEAT_CNT];
249     /**< Measured total no. of GTC Timer ticks for OSPI read. */
250     volatile uint64_t       rxTotalTicks[UDMA_TEST_XFER_REPEAT_CNT + 1U];
251     /**< Elapsed time in nsec for OSPI read. */
252     volatile uint64_t       rxElapsedTime[UDMA_TEST_XFER_REPEAT_CNT + 1U];
254 } App_UdmaCounterObj;
256 typedef struct
258     struct Udma_DrvObj      drvObj;
259     App_UdmaChObj           appChObj;
260     App_UdmaTestObj         appTestObj;
261     App_UdmaCounterObj      appCounterObj;    
262     uint32_t                totalNumBytes;
263 } App_UdmaObj;
266 /* ========================================================================== */
267 /*                          Function Declarations                             */
268 /* ========================================================================== */
270 static int32_t Udma_ospiFlashTestRun(void);
272 static int32_t App_ospiFlashTest(App_UdmaObj *appObj);
273 static int32_t App_udmaOspiFlash(App_UdmaObj *appObj);
274 static int32_t App_udmaOspiFlashWrite(App_UdmaObj *appObj) __attribute__((section(".udma_critical_fxns")));
275 static int32_t App_udmaOspiFlashRead(App_UdmaObj *appObj) __attribute__((section(".udma_critical_fxns")));
277 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
278 static void App_udmaEventTdCb(Udma_EventHandle eventHandle,
279                               uint32_t eventType,
280                               void *appData);
281 #endif
283 static int32_t App_init(App_UdmaObj *appObj, App_OspiObj *ospiObj);
284 static int32_t App_deinit(App_UdmaObj *appObj, App_OspiObj *ospiObj);
286 static int32_t App_create(App_UdmaObj *appObj);
287 static int32_t App_delete(App_UdmaObj *appObj);
289 static void App_udmaTrpdInit(App_UdmaTrObj *appTrObj, App_UdmaChObj  *appChObj);
290 static int32_t App_udmaTrpdSanityCheck(App_UdmaChObj *appChObj, uint64_t pDesc);
291 static inline void App_udmaTrObjInitWrite(App_UdmaTestObj *appTestObj, App_UdmaTrObj *appTrObj);
292 static inline void App_udmaTrObjInitRead(App_UdmaTestObj *appTestObj, App_UdmaTrObj *appTrObj);
294 static void App_printPerfResults(App_UdmaObj *appObj);
296 void App_print(const char *str);
297 static void App_printNum(const char *str, uint32_t num);
298 int32_t App_setGTCClk(uint32_t moduleId,
299                       uint32_t clkId,
300                       uint64_t clkRateHz);
303 static int32_t App_ospiFlashInit(App_OspiObj *ospiObj, uint32_t clk);
304 static int32_t App_ospiFlashStart(uint32_t numBytes) __attribute__((section(".udma_critical_fxns")));
306 /* ========================================================================== */
307 /*                            Global Variables                                */
308 /* ========================================================================== */
310 /*
311  * UDMA driver and channel objects
312  */
313 App_UdmaObj gUdmaAppObj;
314 App_OspiObj gOspiAppObj;
316 /*
317  * UDMA Memories
318  */
319 static uint8_t gTxRingMem[UDMA_TEST_APP_RING_MEM_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
320 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
321 static uint8_t gTxCompRingMem[UDMA_TEST_APP_RING_MEM_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
322 static uint8_t gTxTdCompRingMem[UDMA_TEST_APP_RING_MEM_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
323 #endif
324 static uint8_t gUdmaTrpdMem[UDMA_TEST_APP_TRPD_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
326 /*
327  * Application Buffers
328  */
329 static uint8_t gUdmaTestTxBuf[UDMA_TEST_APP_BUF_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
330 static uint8_t gUdmaTestRxBuf[UDMA_TEST_APP_BUF_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
331 static uint8_t * gUdmaTestOspiFlashDataAddr = (uint8_t *)(OSPI_FLASH_DATA_BASE_ADDR);
333 /* Global test pass/fail flag */
334 static volatile int32_t gUdmaTestResult = UDMA_SOK;
335 /* Global App pass/fail flag */
336 static volatile int32_t gUdmaAppResult = UDMA_SOK;
338 /* No.of ticks taken to do a GTC Reg Read operation */
339 volatile uint64_t getTicksDelay = 0; 
341 /* UDMA OSPI Flash Tests data structure */
342 App_UdmaTestObj gUdmaAppTestObj[] =
344     /* testFunc, testID, clk, numBytes, testDesc */
345     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_16B,  OSPI_MODULE_CLK_133M, 16U, "\r\n OSPI flash test at 133MHz RCLK - Read/Write 16 Bytes"},
346     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_16B,  OSPI_MODULE_CLK_166M, 16U, "\r\n OSPI flash test at 166MHz RCLK - Read/Write 16 Bytes"},
347     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_32B,  OSPI_MODULE_CLK_133M, 32U, "\r\n OSPI flash test at 133MHz RCLK - Read/Write 32 Bytes"},
348     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_32B,  OSPI_MODULE_CLK_166M, 32U, "\r\n OSPI flash test at 166MHz RCLK - Read/Write 32 Bytes"},
349     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_64B,  OSPI_MODULE_CLK_133M, 64U, "\r\n OSPI flash test at 133MHz RCLK - Read/Write 64 Bytes"},
350     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_64B,  OSPI_MODULE_CLK_166M, 64U, "\r\n OSPI flash test at 166MHz RCLK - Read/Write 64 Bytes"},
351     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_128B,  OSPI_MODULE_CLK_133M, 128U, "\r\n OSPI flash test at 133MHz RCLK - Read/Write 128 Bytes"},
352     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_128B,  OSPI_MODULE_CLK_166M, 128U, "\r\n OSPI flash test at 166MHz RCLK - Read/Write 128 Bytes"},
353     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_256B,  OSPI_MODULE_CLK_133M, 256U, "\r\n OSPI flash test at 133MHz RCLK - Read/Write 256 Bytes"},
354     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_256B,  OSPI_MODULE_CLK_166M, 256U, "\r\n OSPI flash test at 166MHz RCLK - Read/Write 256 Bytes"},
355     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_512B,  OSPI_MODULE_CLK_133M, 512U, "\r\n OSPI flash test at 133MHz RCLK - Read/Write 512 Bytes"},
356     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_512B,  OSPI_MODULE_CLK_166M, 512U, "\r\n OSPI flash test at 166MHz RCLK - Read/Write 512 Bytes"},
357     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_1024B,  OSPI_MODULE_CLK_133M, 1024U, "\r\n OSPI flash test at 133MHz RCLK - Read/Write 1024 Bytes"},
358     {Udma_ospiFlashTestRun, UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_1024B,  OSPI_MODULE_CLK_166M, 1024U, "\r\n OSPI flash test at 166MHz RCLK - Read/Write 1024 Bytes"},
359     {NULL, }
360 };
362 /* ========================================================================== */
363 /*                          Function Definitions                              */
364 /* ========================================================================== */
366 /*
367  * UDMA OSPI Flash test
368  */
369 int32_t Udma_ospiFlashTest(void)
371     int32_t          retVal;
372     uint32_t         i;
373     App_UdmaTestObj *test;
374     App_UdmaObj     *appObj = &gUdmaAppObj;
376     for (i = 0; ; i++)
377     {
378         test = &gUdmaAppTestObj[i];
379         if (test->testFunc == NULL)
380         {
381             break;
382         }
384         appObj->appTestObj = *test;
385         appObj->totalNumBytes = test->numBytes;
386         retVal = test->testFunc();
387         if((UDMA_SOK == retVal) && (UDMA_SOK == gUdmaTestResult))
388         {
389             App_print(test->testDesc);
390             App_print(" have passed\r\n");
391         }
392         else
393         {
394             App_print(test->testDesc);
395             App_print(" have failed\r\n");
396             gUdmaTestResult = UDMA_SOK;
397             gUdmaAppResult = UDMA_EFAIL;
398         }
399     }
401     if(UDMA_SOK != gUdmaAppResult)
402     {
403         App_print("\n Some tests have failed. \n");
404     }
405     else
406     {
407         App_print("\n All tests have passed. \n");
408     }
410     App_print("\n Done\n");
412     return (0);
415 /*
416  * UDMA OSPI Flash test run
417  */
418 static int32_t Udma_ospiFlashTestRun(void)
420     int32_t         retVal;
421     App_UdmaObj    *appObj = &gUdmaAppObj;
422     App_OspiObj    *ospiObj = &gOspiAppObj;
424     retVal = App_init(appObj, ospiObj);
425     if(UDMA_SOK != retVal)
426     {
427         App_print("\n [Error] UDMA App init failed!!\n");
428     }
430     App_print("UDMA OSPI Flash application started...\n");
432     if(UDMA_SOK == retVal)
433     {
434         retVal = App_create(appObj);
435         if(UDMA_SOK != retVal)
436         {
437             App_print("\n [Error] UDMA App create failed!!\n");
438         }
439     }
441     if(UDMA_SOK == retVal)
442     {
443         retVal = App_ospiFlashTest(appObj);
444         if(UDMA_SOK != retVal)
445         {
446             App_print("\n [Error] UDMA App OSPI Flash test failed!!\n");
447         }
448     }
450     retVal += App_delete(appObj);
451     if(UDMA_SOK != retVal)
452     {
453         App_print("\n [Error] UDMA App delete failed!!\n");
454     }
456     retVal += App_deinit(appObj, ospiObj);
457     if(UDMA_SOK != retVal)
458     {
459         App_print("\n [Error] UDMA App deinit failed!!\n");
460     }
462     return (retVal);
465 static int32_t App_ospiFlashTest(App_UdmaObj *appObj)
467     int32_t         retVal = UDMA_SOK;
468     uint32_t        i;
469     uint8_t        *rxBuf;
471     /* Reset RX buffer */
472     rxBuf  = &gUdmaTestRxBuf[0U];
473     for(i = 0U; i < appObj->totalNumBytes; i++)
474     {
475         rxBuf[i] = 0U;
476     }
477     /* Writeback RX buffer */
478     Udma_appUtilsCacheWb(rxBuf, appObj->totalNumBytes);
480     /* Perform UDMA memcpy */
481     retVal = App_udmaOspiFlash(appObj);
482     if(UDMA_SOK == retVal)
483     {
484         /* Print performance results for OSPI Flash in DAC DMA mode */
485         App_printPerfResults(appObj);
486     }
488     return (retVal);
491 static int32_t App_udmaOspiFlash(App_UdmaObj *appObj)
493     int32_t         retVal = UDMA_SOK;
494     uint32_t        i;
495     uint8_t        *rxBuf, *txBuf;
497     retVal = App_ospiFlashStart(appObj->totalNumBytes);
498     if(UDMA_SOK != retVal)
499     {
500         App_print("\n [Error] OSPI Start failed!!\n");
501     }
503     if(UDMA_SOK == retVal)
504     {
505         retVal = App_udmaOspiFlashWrite(appObj);
506         if(UDMA_SOK != retVal)
507         {
508             App_print("\n [Error]UDMA OSPI Write failed!!\n");
509         }
510     }
512     if(UDMA_SOK == retVal)
513     {
514         retVal = App_udmaOspiFlashRead(appObj);
515         if(UDMA_SOK != retVal)
516         {
517             App_print("\n [Error]UDMA OSPI Read failed!!\n");
518         }
519     }
521     if(UDMA_SOK == retVal)
522     {
523         rxBuf  = &gUdmaTestRxBuf[0U];
524         txBuf  = &gUdmaTestTxBuf[0U];
526         /* Compare data */
527         for(i = 0U; i < appObj->totalNumBytes; i++)
528         {
529             if(rxBuf[i] != txBuf[i])
530             {
531                 App_printNum("\n [Error] Data mismatch at idx %d", i);
532                 retVal = UDMA_EFAIL;
533                 break;
534             }
535         }
536     }
538     return (retVal);
541 static int32_t App_udmaOspiFlashWrite(App_UdmaObj *appObj)
543     int32_t              retVal = UDMA_SOK;
544     uint64_t             pDesc = 0;
545     uint32_t             i;
546     uint32_t             chunkCnt, cCnt;
547     /* Use local variables in real-time loop for optimized performance */
548     uint32_t             txStartTicks, txStopTicks;
549     volatile uint32_t   *pSwTriggerReg;
550     uint32_t             triggerMask;
551     App_UdmaTestObj     *appTestObj       = &appObj->appTestObj;
552     App_UdmaChObj       *appChObj         = &appObj->appChObj;
553     App_UdmaTrObj       *appTrObj         = &appChObj->appTrObj;
554     App_UdmaCounterObj  *appCounterObj    = &appObj->appCounterObj;
555     Udma_ChHandle        chHandle         = appChObj->chHandle;
556     uint8_t             *txBuf            = &gUdmaTestTxBuf[0U];
557     const uint16_t       size             = appTestObj->numBytes;
558     const uint16_t       totalSize        = appObj->totalNumBytes;
559     volatile uint64_t   *pintrStatusReg   = appTrObj->trEventPrms.intrStatusReg;
560     uint64_t             intrMask         = appTrObj->trEventPrms.intrMask;
561     volatile uint64_t   *intrClearReg     = appTrObj->trEventPrms.intrClearReg;
562     uint8_t             *trpdMem          = appChObj->trpdMem;
564     const CSL_ospi_flash_cfgRegs *baseAddr = (const CSL_ospi_flash_cfgRegs *)(OSPI_FLASH_CONFIG_REG_BASE_ADDR);
566     /* Init TX buffers */
567     for(i = 0U; i < totalSize; i++)
568     {
569         txBuf[i] = i;
570     }
571     
572     App_udmaTrObjInitWrite(appTestObj, appTrObj);
574     /* Get SW trigger register for easy access */
575     triggerMask = ((uint32_t)1U << (appTrObj->trigger - 1U));
576     pSwTriggerReg = (volatile uint32_t *) Udma_chGetSwTriggerRegister(chHandle);
577     if(NULL == pSwTriggerReg)
578     {
579         App_print("\n [Error] Channel trigger register get failed!!\n");
580     }
582     /* Submit TRPD to channels */
583     App_udmaTrpdInit(appTrObj, appChObj);
584     retVal = Udma_ringQueueRaw(
585                 Udma_chGetFqRingHandle(chHandle),
586                 (uint64_t) Udma_appVirtToPhyFxn(trpdMem, 0U, NULL));
587     if(UDMA_SOK != retVal)
588     {
589         App_print("\n [Error] Channel queue failed!!\n");
590     }
592     if(UDMA_SOK == retVal)
593     {
595         /*****************************************************************************
596          * OSPI Write "appTestObj->numBytes" (= appTrObj->icnt[0]* appTrObj->icnt[1] )
597          *****************************************************************************/
598         txStartTicks = App_getGTCTimerTicks();
600         /* Do Cache write-back for "appTestObj->numBytes" chunk to be tranferred */
601         CSL_armR5CacheWb(txBuf, size);
602         
603         /* Set number of times to trigger TX transfer */
604         chunkCnt = appTrObj->icnt[1];
605         for(cCnt = 0U; cCnt < chunkCnt; cCnt++)
606         {
607             /* Write UDMA_TEST_WRITE_CHUNK_SIZE(= appTrObj->icnt[0]) bytes and wait for device to be ready */
609             /* Set channel trigger and wait for completion */
610             CSL_REG32_WR(pSwTriggerReg, triggerMask);
612             /* Wait for the transfer to complete in polling mode */
613             while(1U)
614             {
615                 volatile uint64_t   intrStatusReg;
616                 intrStatusReg = CSL_REG64_RD(pintrStatusReg);
617                 /* Check whether the interrupt status Reg is set - which indicates the
618                 * tranfser completion of appTestObj->numBytes */
619                 if(intrStatusReg & intrMask)
620                 {
621                     /* Clear interrupt */
622                     CSL_REG64_WR(intrClearReg, intrMask);
623                     break;
624                 }
625             }
627             /* Wait device to be ready after write operation */
628             uint32_t timeOutVal = OSPI_FLASH_WRITE_TIMEOUT;
629             uint32_t retry = OSPI_FLASH_WRITE_TIMEOUT;
630             volatile uint32_t delay = OSPI_FLASH_CHECK_IDLE_DELAY;
631             uint8_t  status = 0xFF;
632             uint32_t regVal;
633             while (timeOutVal != 0U)
634             {
635                 (void)CSL_ospiCmdRead(baseAddr, OSPI_FLASH_CMD_RDSR, 1U);
636                 while(!CSL_ospiIsIdle(baseAddr));
637                 CSL_ospiFlashExecCmd(baseAddr);
638                 while(retry != 0U)
639                 {
640                     if(CSL_ospiFlashExecCmdComplete(baseAddr) == TRUE)
641                     {
642                         break;
643                     }
644                     while (delay > 0U)
645                     {  
646                         delay = delay - 1U;
647                     }
648                     retry--;
649                 }
650                 while(!CSL_ospiIsIdle(baseAddr));
651                 regVal = CSL_REG32_RD(&baseAddr->FLASH_RD_DATA_LOWER_REG);
652                 (void)memcpy((void *)&status, (void *)(&regVal), 1U);
653                 if ((status & 1U) == 0U)
654                 {
655                     break;
656                 }
657                 timeOutVal--;
658                 delay = OSPI_FLASH_CHECK_IDLE_DELAY;
659                 while (delay > 0U)
660                 {  
661                     delay = delay - 1U;
662                 }
663             }
664         } 
665         txStopTicks = App_getGTCTimerTicks();
667         appCounterObj->txStartTicks = txStartTicks;
668         appCounterObj->txStopTicks = txStopTicks;
669         
670     }
671     if(UDMA_SOK == retVal)
672     {
673         /* wait for response to be received in completion queue */
674         while(1)
675         {
676             retVal =
677                 Udma_ringDequeueRaw(Udma_chGetCqRingHandle(chHandle), &pDesc);
678             if(UDMA_SOK == retVal)
679             {
680                 break;
681             }
682         }
684         /* Sanity check - Check returned descriptor pointer & TR response status*/
685         retVal = App_udmaTrpdSanityCheck(appChObj, pDesc);
686     }
688     return (retVal);
691 static int32_t App_udmaOspiFlashRead(App_UdmaObj *appObj)
693     int32_t              retVal = UDMA_SOK;
694     uint32_t             triggerCnt, tCnt;
695     /* Use local variables in real-time loop for optimized performance */
696     volatile uint32_t   *pSwTriggerReg;
697     uint32_t             triggerMask;
698     uint32_t             rxStartTicks, rxStopTicks;
699     App_UdmaTestObj     *appTestObj       = &appObj->appTestObj;
700     App_UdmaChObj       *appChObj         = &appObj->appChObj;
701     App_UdmaTrObj       *appTrObj         = &appChObj->appTrObj;
702     App_UdmaCounterObj  *appCounterObj    = &appObj->appCounterObj;
703     Udma_ChHandle        chHandle         = appChObj->chHandle;
704     uint8_t             *rxBuf            = &gUdmaTestRxBuf[0U];
705     const uint16_t       size             = appTestObj->numBytes;
706     volatile uint64_t   *pintrStatusReg   = appTrObj->trEventPrms.intrStatusReg;
707     uint64_t             intrMask         = appTrObj->trEventPrms.intrMask;
708     volatile uint64_t   *intrClearReg     = appTrObj->trEventPrms.intrClearReg;
709     uint8_t             *trpdMem          = appChObj->trpdMem;
710     
711     App_udmaTrObjInitRead(appTestObj, appTrObj);
713     /* Get SW trigger register for easy access */
714     triggerMask = ((uint32_t)1U << (appTrObj->trigger - 1U));
715     pSwTriggerReg = (volatile uint32_t *) Udma_chGetSwTriggerRegister(chHandle);
716     if(NULL == pSwTriggerReg)
717     {
718         App_print("\n [Error] Channel trigger register get failed!!\n");
719     }
721     /* Submit TRPD to channels */
722     App_udmaTrpdInit(appTrObj, appChObj);
723     retVal = Udma_ringQueueRaw(
724                 Udma_chGetFqRingHandle(chHandle),
725                 (uint64_t) Udma_appVirtToPhyFxn(trpdMem, 0U, NULL));
726     if(UDMA_SOK != retVal)
727     {
728         App_print("\n [Error] Channel queue failed!!\n");
729     }
731     if(UDMA_SOK == retVal)
732     {
733         /* Set number of times to trigger RX transfer */
734         triggerCnt = UDMA_TEST_XFER_REPEAT_CNT;
735         for(tCnt = 0U; tCnt < triggerCnt; tCnt++)
736         {      
738             /********************************************************
739              * OSPI Read "appTestObj->numBytes" (= appTrObj->icnt[0])
740              ********************************************************/
742             rxStartTicks = App_getGTCTimerTicks();
744             /* Set channel trigger and wait for completion */
745             CSL_REG32_WR(pSwTriggerReg, triggerMask);
747             /* Wait for the transfer to complete in polling mode */
748             while(1U)
749             {
750                 volatile uint64_t   intrStatusReg;
751                 intrStatusReg = CSL_REG64_RD(pintrStatusReg);
752                 /* Check whether the interrupt status Reg is set - which indicates the
753                  * transfer completion of appTestObj->numBytes */
754                 if(intrStatusReg & intrMask)
755                 {
756                     /* Clear interrupt */
757                     CSL_REG64_WR(intrClearReg, intrMask);
758                     break;
759                 }
760             }
761             /* Do Cache invalidate for the received chunk */
762             CSL_armR5CacheInv(rxBuf, size);
764             rxStopTicks = App_getGTCTimerTicks();
766             appCounterObj->rxStartTicks[tCnt] = rxStartTicks;
767             appCounterObj->rxStopTicks[tCnt] = rxStopTicks;
768         }
769     }
770     /* Since TR Reload Count Set for perpetual loop, TRPD never completes and comes back to CQ.
771      * To exit, teardown the channel using Udma_chDisable */
772     retVal = Udma_chDisable(chHandle, UDMA_DEFAULT_CH_DISABLE_TIMEOUT);
773     if(UDMA_SOK != retVal)
774     {
775         App_print("\n [Error] UDMA channel disable failed!!\n");
776     }
777     return (retVal);
780 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
781 static void App_udmaEventTdCb(Udma_EventHandle eventHandle,
782                               uint32_t eventType,
783                               void *appData)
785     int32_t             retVal;
786     CSL_UdmapTdResponse tdResp;
787     App_UdmaChObj      *appChObj = (App_UdmaChObj *) appData;
789     if(appChObj != NULL)
790     {
791         if(UDMA_EVENT_TYPE_TEARDOWN_PACKET == eventType)
792         {
793             /* Response received in Teardown completion queue */
794             retVal = Udma_chDequeueTdResponse(appChObj->chHandle, &tdResp);
795             if(UDMA_SOK != retVal)
796             {
797                 /* [Error] No TD response after callback!! */
798                 gUdmaTestResult = UDMA_EFAIL;
799             }
800         }
801         else
802         {
803             gUdmaTestResult = UDMA_EFAIL;
804         }
805     }
806     else
807     {
808         gUdmaTestResult = UDMA_EFAIL;
809     }
811     return;
813 #endif
815 static int32_t App_init(App_UdmaObj *appObj, App_OspiObj *ospiObj)
817     int32_t              retVal;
818     Udma_InitPrms        initPrms;
819     uint32_t             instId;
820     App_UdmaChObj       *appChObj        = &appObj->appChObj;
821     App_UdmaTrObj       *appTrObj       = &appChObj->appTrObj;
822     App_UdmaTestObj     *appTestObj     = &appObj->appTestObj;
823     App_UdmaCounterObj  *appCounterObj  = &appObj->appCounterObj;
824     Udma_DrvHandle       drvHandle      = &appObj->drvObj;
826 #if defined (SOC_AM64X)
827     /* Use Block Copy DMA for AM64x */
828     instId = UDMA_INST_ID_BCDMA_0;
829 #else
830     /* Use MCU NAVSS for MCU domain cores. Rest all cores uses Main NAVSS */
831 #if defined (BUILD_MCU1_0) || defined (BUILD_MCU1_1)
832     instId = UDMA_INST_ID_MCU_0;
833 #else
834     instId = UDMA_INST_ID_MAIN_0;
835 #endif
836 #endif
837     /* UDMA driver init */
838     UdmaInitPrms_init(instId, &initPrms);
839     initPrms.virtToPhyFxn   = &Udma_appVirtToPhyFxn;
840     initPrms.phyToVirtFxn   = &Udma_appPhyToVirtFxn;
841     initPrms.printFxn       = &App_print;
842     retVal = Udma_init(drvHandle, &initPrms);
843     if(UDMA_SOK != retVal)
844     {
845         App_print("\n [Error] UDMA init failed!!\n");
846     }
848     /* Init channel parameters */
849     appChObj->chHandle          = &appChObj->chObj;
850     appChObj->drvHandle         = drvHandle;
851     appChObj->txRingMem         = &gTxRingMem[0U];
852 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
853     appChObj->tdCqEventHandle   = NULL;
854     appChObj->txCompRingMem     = &gTxCompRingMem[0U];
855     appChObj->txTdCompRingMem   = &gTxTdCompRingMem[0U];
856 #endif
857     appChObj->trpdMem           = &gUdmaTrpdMem[0U];
858     
859     /* Init TR parameters */
860     appTrObj->trEventHandle      = NULL;
861     appTrObj->drvHandle          = drvHandle;
863     memset((void *)&appCounterObj->txStartTicks,  0, sizeof(appCounterObj->txStartTicks));
864     memset((void *)&appCounterObj->txStopTicks,   0, sizeof(appCounterObj->txStopTicks));
865     memset((void *)&appCounterObj->txTotalTicks,  0, sizeof(appCounterObj->txTotalTicks));
866     memset((void *)&appCounterObj->txElapsedTime, 0, sizeof(appCounterObj->txElapsedTime));
867     memset((void *)&appCounterObj->rxStartTicks,  0, sizeof(appCounterObj->rxStartTicks));
868     memset((void *)&appCounterObj->rxStopTicks,   0, sizeof(appCounterObj->rxStopTicks));
869     memset((void *)&appCounterObj->rxTotalTicks,  0, sizeof(appCounterObj->rxTotalTicks));
870     memset((void *)&appCounterObj->rxElapsedTime, 0, sizeof(appCounterObj->rxElapsedTime));
872     if(UDMA_SOK == retVal)
873     {
874        retVal = App_ospiFlashInit(ospiObj, appTestObj->clk);
875     }
877     return (retVal);
881 static int32_t App_deinit(App_UdmaObj *appObj, App_OspiObj *ospiObj)
883     int32_t         retVal;
884     Udma_DrvHandle  drvHandle = &appObj->drvObj;
886     OspiFlash_ospiClose(ospiObj, FALSE);
888     retVal = Udma_deinit(drvHandle);
889     if(UDMA_SOK != retVal)
890     {
891         App_print("\n [Error] UDMA deinit failed!!\n");
892     }
894     return (retVal);
896 static int32_t App_create(App_UdmaObj *appObj)
898     int32_t             retVal = UDMA_SOK;
899     uint32_t            chType;
900     Udma_ChPrms         chPrms;
901     Udma_ChTxPrms       txPrms;
902     Udma_ChRxPrms       rxPrms;
903     Udma_EventHandle    eventHandle;
904     App_UdmaChObj      *appChObj = &appObj->appChObj;
905     App_UdmaTrObj      *appTrObj = &appChObj->appTrObj;
906     Udma_ChHandle       chHandle = appChObj->chHandle;
907     Udma_DrvHandle      drvHandle = &appObj->drvObj;
909     if(UDMA_SOK == retVal)
910     {
911         /* Init channel parameters */
912         chType = UDMA_CH_TYPE_TR_BLK_COPY;
913         UdmaChPrms_init(&chPrms, chType);
914         chPrms.fqRingPrms.ringMem       = appChObj->txRingMem;
915         chPrms.fqRingPrms.ringMemSize   = UDMA_TEST_APP_RING_MEM_SIZE;
916         chPrms.fqRingPrms.elemCnt       = UDMA_TEST_APP_RING_ENTRIES;
917 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
918         chPrms.cqRingPrms.ringMem       = appChObj->txCompRingMem;
919         chPrms.cqRingPrms.ringMemSize   = UDMA_TEST_APP_RING_MEM_SIZE;
920         chPrms.cqRingPrms.elemCnt       = UDMA_TEST_APP_RING_ENTRIES;
921         chPrms.tdCqRingPrms.ringMem     = appChObj->txTdCompRingMem;
922         chPrms.tdCqRingPrms.ringMemSize = UDMA_TEST_APP_RING_MEM_SIZE;
923         chPrms.tdCqRingPrms.elemCnt     = UDMA_TEST_APP_RING_ENTRIES;
924 #endif
926         /* Open channel for block copy */
927         retVal = Udma_chOpen(drvHandle, chHandle, chType, &chPrms);
928         if(UDMA_SOK != retVal)
929         {
930             App_print("\n [Error] UDMA channel open failed!!\n");
931         }
932     }
934     if(UDMA_SOK == retVal)
935     {
936         /* Config TX channel */
937         UdmaChTxPrms_init(&txPrms, chType);
938         retVal = Udma_chConfigTx(chHandle, &txPrms);
939         if(UDMA_SOK != retVal)
940         {
941             App_print("\n [Error] UDMA TX channel config failed!!\n");
942         }
943     }
945     if(UDMA_SOK == retVal)
946     {
947         /* Config RX channel - which is implicitly paired to TX channel in
948             * block copy mode */
949         UdmaChRxPrms_init(&rxPrms, chType);
950         retVal = Udma_chConfigRx(chHandle, &rxPrms);
951         if(UDMA_SOK != retVal)
952         {
953             App_print("\n [Error] UDMA RX channel config failed!!\n");
954         }
955     }
957     if(UDMA_SOK == retVal)
958     {
959         /* Register TR event */
960         eventHandle = &appTrObj->trEventObj;
961         UdmaEventPrms_init(&appTrObj->trEventPrms);
962         appTrObj->trEventPrms.eventType         = UDMA_EVENT_TYPE_TR;
963         appTrObj->trEventPrms.eventMode         = UDMA_EVENT_MODE_SHARED;
964         appTrObj->trEventPrms.chHandle          = chHandle;
965        /* For polling mode we can't use the existing master event as that is meant only for interrupt event - 
966         *  we can't mix interrupt and poll mode in same master handle. Set the parameter to NULL 
967         *  so that the driver creates a new master event. */
968         appTrObj->trEventPrms.masterEventHandle = NULL;
969         appTrObj->trEventPrms.eventCb           = NULL;
970         appTrObj->trEventPrms.appData           = appChObj;
971         retVal = Udma_eventRegister(drvHandle, eventHandle, &appTrObj->trEventPrms);
972         if(UDMA_SOK != retVal)
973         {
974             App_print("\n [Error] UDMA TR event register failed!!\n");
975         }
976         else
977         {
978             appTrObj->trEventHandle = eventHandle;
979         }
980     }
982 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
983     if(UDMA_SOK == retVal)
984     {
985         /* Register teardown ring completion callback */
986         eventHandle = &appChObj->tdCqEventObj;
987         UdmaEventPrms_init(&appChObj->tdCqEventPrms);
988         appChObj->tdCqEventPrms.eventType         = UDMA_EVENT_TYPE_TEARDOWN_PACKET;
989         appChObj->tdCqEventPrms.eventMode         = UDMA_EVENT_MODE_SHARED;
990         appChObj->tdCqEventPrms.chHandle          = chHandle;
991         appChObj->tdCqEventPrms.masterEventHandle = Udma_eventGetGlobalHandle(drvHandle);
992         appChObj->tdCqEventPrms.eventCb           = &App_udmaEventTdCb;
993         appChObj->tdCqEventPrms.appData           = appChObj;
994         retVal = Udma_eventRegister(drvHandle, eventHandle, &appChObj->tdCqEventPrms);
995         if(UDMA_SOK != retVal)
996         {
997             App_print("[Error] UDMA Teardown CQ event register failed!!\n");
998         }
999         else
1000         {
1001             appChObj->tdCqEventHandle = eventHandle;
1002         }
1003     }
1004 #endif 
1006     if(UDMA_SOK == retVal)
1007     {
1008         /* Channel enable */
1009         retVal = Udma_chEnable(chHandle);
1010         if(UDMA_SOK != retVal)
1011         {
1012             App_print("\n [Error] UDMA channel enable failed!!\n");
1013         }
1014     }
1016     return (retVal);
1019 static int32_t App_delete(App_UdmaObj *appObj)
1021     int32_t         retVal, tempRetVal;
1022     uint64_t        pDesc;
1023     App_UdmaChObj  *appChObj = &appObj->appChObj;
1024     App_UdmaTrObj  *appTrObj = &appChObj->appTrObj;
1025     Udma_ChHandle   chHandle = appChObj->chHandle;
1026     
1028     /* Flush any pending request from the free queue */
1029     while(1)
1030     {
1031         tempRetVal = Udma_ringFlushRaw(
1032                             Udma_chGetFqRingHandle(chHandle), &pDesc);
1033         if(UDMA_ETIMEOUT == tempRetVal)
1034         {
1035             break;
1036         }
1037     }
1039     /* Unregister all events */
1040     if(NULL != appTrObj->trEventHandle)
1041     {
1042         retVal = Udma_eventUnRegister(appTrObj->trEventHandle);
1043         if(UDMA_SOK != retVal)
1044         {
1045             App_print("\n [Error] UDMA event unregister failed!!\n");
1046         }
1047         appTrObj->trEventHandle = NULL;
1048     }
1049 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
1050     if(NULL != appChObj->tdCqEventHandle)
1051     {
1052         retVal += Udma_eventUnRegister(appChObj->tdCqEventHandle);
1053         if(UDMA_SOK != retVal)
1054         {
1055             App_print("[Error] UDMA event unregister failed!!\n");
1056         }
1057         appChObj->tdCqEventHandle = NULL;
1058     }
1059 #endif
1061     retVal += Udma_chClose(chHandle);
1062     if(UDMA_SOK != retVal)
1063     {
1064         App_print("\n [Error] UDMA channel close failed!!\n");
1065     }
1067     return (retVal);
1070 static void App_udmaTrpdInit(App_UdmaTrObj *appTrObj, App_UdmaChObj  *appChObj)
1071 {    
1072     CSL_UdmapCppi5TRPD *pTrpd = (CSL_UdmapCppi5TRPD *) appChObj->trpdMem;
1073     CSL_UdmapTR15 *pTr = (CSL_UdmapTR15 *)(appChObj->trpdMem + sizeof(CSL_UdmapTR15));
1074     uint32_t *pTrResp = (uint32_t *) (appChObj->trpdMem + (sizeof(CSL_UdmapTR15) * 2U));
1075     uint32_t cqRingNum = Udma_chGetCqRingNum(appChObj->chHandle);
1077     /* Make TRPD */
1078     UdmaUtils_makeTrpd(pTrpd, UDMA_TR_TYPE_15, 1U, cqRingNum);
1079     CSL_udmapCppi5TrSetReload((CSL_UdmapCppi5TRPD*)pTrpd, appTrObj->reloadCnt, 0U);
1081     /* Setup TR */
1082     pTr->flags  = CSL_FMK(UDMAP_TR_FLAGS_TYPE, CSL_UDMAP_TR_FLAGS_TYPE_4D_BLOCK_MOVE_REPACKING_INDIRECTION);
1083     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_STATIC, 0U);
1084     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_EOL, appTrObj->eolType);
1085     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_EVENT_SIZE, appTrObj->eventSize);
1086     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0, appTrObj->trigger);
1087     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE);
1088     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0_TYPE, appTrObj->triggerType);
1089     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1_TYPE, CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL);
1090     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_CMD_ID, 0x25U);
1091     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_SA_INDIRECT, 0U);
1092     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_DA_INDIRECT, 0U);
1093     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_EOP, 1U);
1094     
1095     pTr->icnt0    = appTrObj->icnt[0];
1096     pTr->icnt1    = appTrObj->icnt[1];
1097     pTr->icnt2    = appTrObj->icnt[2];
1098     pTr->icnt3    = appTrObj->icnt[3];
1099     pTr->addr     = (uint64_t) Udma_appVirtToPhyFxn(appTrObj->addr, 0U, NULL);
1100     pTr->fmtflags = 0x00000000U;        /* Linear addressing, 1 byte per elem.
1101                                            Replace with CSL-FL API */
1103     pTr->dicnt0   = appTrObj->dicnt[0];
1104     pTr->dicnt1   = appTrObj->dicnt[1];
1105     pTr->dicnt2   = appTrObj->dicnt[2];
1106     pTr->dicnt3   = appTrObj->dicnt[3];
1107     pTr->daddr    = (uint64_t) Udma_appVirtToPhyFxn(appTrObj->daddr, 0U, NULL);
1109     pTr->dim1     = appTrObj->dim[0]; 
1110     pTr->dim2     = appTrObj->dim[1]; 
1111     pTr->dim3     = appTrObj->dim[2]; 
1112     pTr->ddim1    = appTrObj->ddim[0]; 
1113     pTr->ddim2    = appTrObj->ddim[1]; 
1114     pTr->ddim3    = appTrObj->ddim[2];
1116     /* Clear TR response memory */
1117     *pTrResp = 0xFFFFFFFFU;
1119     /* Writeback cache */
1120     Udma_appUtilsCacheWb(appChObj->trpdMem, UDMA_TEST_APP_TRPD_SIZE_ALIGN);
1122     return;
1125 static int32_t App_udmaTrpdSanityCheck(App_UdmaChObj *appChObj, uint64_t pDesc)
1127     int32_t         retVal  = UDMA_SOK;
1128     uint32_t       *pTrResp, trRespStatus;
1129     uint8_t        *trpdMem = appChObj->trpdMem;
1131     /* Check returned descriptor pointer */
1132     if(((uint64_t) Udma_appPhyToVirtFxn(pDesc, 0U, NULL)) != ((uint64_t) trpdMem))
1133     {
1134         App_print("\n [Error] TR descriptor pointer returned doesn't "
1135                 "match the submitted address!!\n");
1136         retVal = UDMA_EFAIL;
1137     }
1139     if(UDMA_SOK == retVal)
1140     {
1141         /* Invalidate cache */
1142         Udma_appUtilsCacheInv(trpdMem, UDMA_TEST_APP_TRPD_SIZE_ALIGN);
1144         /* check TR response status */
1145         pTrResp = (uint32_t *) (trpdMem + (sizeof(CSL_UdmapTR15) * 2U));
1146         trRespStatus = CSL_FEXT(*pTrResp, UDMAP_TR_RESPONSE_STATUS_TYPE);
1147         if(trRespStatus != CSL_UDMAP_TR_RESPONSE_STATUS_COMPLETE)
1148         {
1149             App_print("\n [Error] TR Response not completed!!\n");
1150             retVal = UDMA_EFAIL;
1151         }
1152     }
1153     
1154     return (retVal);
1157 static inline void App_udmaTrObjInitRead(App_UdmaTestObj *appTestObj, App_UdmaTrObj *appTrObj)
1159     /* TR Reload Count */
1160     appTrObj->reloadCnt    = 0x1FFU; /* Set to 0x1FFU for perpetual loop */
1161     appTrObj->trigger      = CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL0;
1162     /* Set interrupt after transferring icnt0*icnt1*icnt2*icnt3 bytes - When TR is completed */
1163     appTrObj->eventSize    = CSL_UDMAP_TR_FLAGS_EVENT_SIZE_COMPLETION; 
1164     /* Transfer icnt0*icnt1*icnt2*icnt3 bytes(entire TR) after a trigger */
1165     appTrObj->triggerType  = CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL;
1166     /* EOL boundaries for each icnt0*icnt1*icnt2*icnt3 bytes */
1167     appTrObj->eolType      = CSL_UDMAP_TR_FLAGS_EOL_ICNT0_ICNT1_ICNT2_ICNT3; 
1169     /* No. of bytes to tansfer after getting interrupt (in this case)*/
1170     appTrObj->icnt[0] = appTestObj->numBytes; 
1171     /* No. of times to repeat the tansfer of inct0 bytes */
1172     appTrObj->icnt[1] = 1U;
1173     /* No. of times to repeat the tansfer of inct0*icnt1 bytes */
1174     appTrObj->icnt[2] = 1U;
1175     /* No. of times to repeat the tansfer of inct0*icnt1*inct2 bytes */
1176     appTrObj->icnt[3] = 1U;
1177     /* similar destination params */
1178     appTrObj->dicnt[0] = appTestObj->numBytes; 
1179     appTrObj->dicnt[1] = 1U;
1180     appTrObj->dicnt[2] = 1U;
1181     appTrObj->dicnt[3] = 1U;
1183     /* DIM1: Offset for source OSPI data address after transferring inct0 bytes */
1184     appTrObj->dim[0]  = appTrObj->icnt[0]; /* Use inct0 bytes so that successive triger tranfers the next icnt0 bytes */
1185     /* DIM2 - Offset for source OSPI data address after transferring inct0*inct1 bytes */
1186     appTrObj->dim[1]  = appTrObj->icnt[0]*appTrObj->icnt[1]; /* Use inct0*icnt1 bytes so that successive iteration tranfers the next icnt0*icnt1 bytes */
1187     /* DIM3 - Offset for source OSPI data address after transferring inct0*inct1*inct2 bytes */
1188     appTrObj->dim[2]  = appTrObj->icnt[0]*appTrObj->icnt[1]*appTrObj->icnt[2]; /* Use inct0*icnt1*icnt2 bytes so that successive iteration tranfers the next inct0*icnt1*icnt2 bytes */
1190     /* Similar offset for destination RX buffer address */
1191     appTrObj->ddim[0]  = appTrObj->dicnt[0]; 
1192     appTrObj->ddim[1]  = appTrObj->dicnt[0]*appTrObj->dicnt[1];
1193     appTrObj->ddim[2]  = appTrObj->dicnt[0]*appTrObj->dicnt[1]*appTrObj->dicnt[2];
1195     /* Source Address - OSPI Data address */
1196     appTrObj->addr  = gUdmaTestOspiFlashDataAddr;
1197     /* Destination Address - RX Buffer */
1198     appTrObj->daddr  = &gUdmaTestRxBuf[0U];;
1200     return;
1203 static inline void App_udmaTrObjInitWrite(App_UdmaTestObj *appTestObj, App_UdmaTrObj *appTrObj)
1205     /* TR Reload Count */
1206     appTrObj->reloadCnt    = 0U; 
1207     appTrObj->trigger      = CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL0;
1208     /* Set interrupt after transferring icnt0 bytes */
1209     appTrObj->eventSize    = CSL_UDMAP_TR_FLAGS_EVENT_SIZE_ICNT1_DEC; 
1210     /* Transfer icnt0 bytes after a trigger */
1211     appTrObj->triggerType  = CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ICNT1_DEC;
1212     /* EOL boundaries for each icnt0 bytes */
1213     appTrObj->eolType      = CSL_UDMAP_TR_FLAGS_EOL_ICNT0; 
1215     if(appTestObj->numBytes > UDMA_TEST_WRITE_CHUNK_SIZE)
1216     {
1217         /* For OSPI DMA write, write in chunks. No. of bytes to tansfer after getting interrupt(in this case) */
1218         appTrObj->icnt[0] = UDMA_TEST_WRITE_CHUNK_SIZE; 
1219         /* No. of times to repeat the tansfer of inct0 bytes (= No.of chunks in this case) */
1220         appTrObj->icnt[1] = appTestObj->numBytes/UDMA_TEST_WRITE_CHUNK_SIZE;
1222         appTrObj->dicnt[0] = UDMA_TEST_WRITE_CHUNK_SIZE; 
1223         appTrObj->dicnt[1] = appTestObj->numBytes/UDMA_TEST_WRITE_CHUNK_SIZE;
1224     }
1225     else
1226     {
1227         appTrObj->icnt[0] = appTestObj->numBytes;
1228         appTrObj->icnt[1] = 1U;
1229         
1230         appTrObj->dicnt[0] = appTestObj->numBytes;
1231         appTrObj->dicnt[1] = 1U;
1232     }
1233     
1234     appTrObj->icnt[2] = 1U;
1235     appTrObj->icnt[3] = 1U;
1236     
1237     appTrObj->dicnt[2] = 1U;
1238     appTrObj->dicnt[3] = 1U;
1240     /* DIM1- Offset for source TX Buffer address after transferring inct0 bytes */
1241     appTrObj->dim[0]  = appTrObj->icnt[0]; /* chunkSize - so that successive triger tranfers the next icnt0(chunkSize) bytes */
1242     /* DIM2 - Offset for source TX Buffer address after transferring inct0*inct1 bytes */
1243     appTrObj->dim[1]  = appTrObj->icnt[0]*appTrObj->icnt[1]; /* inct0*icnt1 bytes - so that successive iteration tranfers the next icnt0*icnt1 bytes */
1244     /* DIM3 - Offset for source TX Buffer address after transferring inct0*inct1*inct2 bytes */
1245     appTrObj->dim[2]  = appTrObj->icnt[0]*appTrObj->icnt[1]*appTrObj->icnt[2]; /* inct0*icnt1*icnt2 bytes - so that successive iteration tranfers the next inct0*icnt1*icnt2 bytes */
1247     /* DDIM1/DDIM2/DDIM3 - Similar offset for destination RX buffer address */
1248     appTrObj->ddim[0]  = appTrObj->dicnt[0]; 
1249     appTrObj->ddim[1]  = appTrObj->dicnt[0]*appTrObj->dicnt[1];
1250     appTrObj->ddim[2]  = appTrObj->dicnt[0]*appTrObj->dicnt[1]*appTrObj->dicnt[2];
1252     /* Source Address - TX Buffer */
1253     appTrObj->addr  = &gUdmaTestTxBuf[0U];
1254     /* Destination Address - OSPI Data address  */
1255     appTrObj->daddr = gUdmaTestOspiFlashDataAddr;
1257     return;
1260 static void App_printPerfResults(App_UdmaObj *appObj)
1261 {    
1262     App_UdmaCounterObj  *appCounterObj = &appObj->appCounterObj;
1263     App_UdmaTestObj     *appTestObj = &appObj->appTestObj;
1264     uint32_t             tCnt;
1265     uint32_t             triggerCnt;
1266     
1267     appCounterObj->txTotalTicks = appCounterObj->txStopTicks - appCounterObj->txStartTicks  - getTicksDelay;
1268     appCounterObj->txElapsedTime = (appCounterObj->txTotalTicks*1000000000U)/(uint64_t)OSPI_FLASH_GTC_CLK_FREQ;
1270     App_printNum("\n OSPI Write %d", appTestObj->numBytes);
1271     App_printNum(" bytes in %d", (uint32_t)appCounterObj->txElapsedTime);
1272     App_print("ns.");
1274     triggerCnt = UDMA_TEST_XFER_REPEAT_CNT;
1275     for(tCnt = 0U; tCnt < triggerCnt; tCnt++)
1276     {
1277         appCounterObj->rxTotalTicks[tCnt] = appCounterObj->rxStopTicks[tCnt] - appCounterObj->rxStartTicks[tCnt]  - getTicksDelay;
1278         appCounterObj->rxTotalTicks[triggerCnt] += appCounterObj->rxTotalTicks[tCnt];
1279         appCounterObj->rxElapsedTime[tCnt] = (appCounterObj->rxTotalTicks[tCnt]*1000000000U)/(uint64_t)OSPI_FLASH_GTC_CLK_FREQ;
1281         App_printNum("\n OSPI Read %d", appTestObj->numBytes);
1282         App_printNum(" bytes in %d", (uint32_t)appCounterObj->rxElapsedTime[tCnt]);
1283         App_print("ns.");
1284     }
1285     
1286     appCounterObj->rxTotalTicks[triggerCnt] = appCounterObj->rxTotalTicks[triggerCnt]/triggerCnt;
1287     appCounterObj->rxElapsedTime[triggerCnt] = (appCounterObj->rxTotalTicks[triggerCnt]*1000000000U)/(uint64_t)OSPI_FLASH_GTC_CLK_FREQ;
1288     App_printNum("\n\n Average time for OSPI Read %d", appTestObj->numBytes);
1289     App_printNum(" bytes = %d", (uint32_t)appCounterObj->rxElapsedTime[triggerCnt]);
1290     App_print("ns. \n\n");
1292     return;
1295 void App_print(const char *str)
1297     UART_printf("%s", str);
1298     if(TRUE == Udma_appIsPrintSupported())
1299     {
1300         printf("%s", str);
1301     }
1303     return;
1306 static void App_printNum(const char *str, uint32_t num)
1308     static char printBuf[200U];
1310     snprintf(printBuf, 200U, str, num);
1311     UART_printf("%s", printBuf);
1313     if(TRUE == Udma_appIsPrintSupported())
1314     {
1315         printf("%s", printBuf);
1316     }
1318     return;
1321 int32_t App_setGTCClk(uint32_t moduleId,
1322                       uint32_t clkId,
1323                       uint64_t clkRateHz)
1325     int32_t retVal;
1326     uint64_t currClkFreqHz;
1328     retVal = Sciclient_pmGetModuleClkFreq(moduleId,
1329                                           clkId,
1330                                           &currClkFreqHz,
1331                                           SCICLIENT_SERVICE_WAIT_FOREVER);
1332     if ((retVal == CSL_PASS) &&
1333         (currClkFreqHz != clkRateHz))
1334     {
1335         retVal = OspiFlash_ClkRateSet(moduleId, clkId, clkRateHz);
1336     }
1338     /* Enable GTC */
1339     HW_WR_REG32(CSL_GTC0_GTC_CFG1_BASE + 0x0U, 0x1);
1341     /* Measure and store the time spent to do a getTime operation */
1342     getTicksDelay = App_getGTCTimerTicks();
1343     getTicksDelay = App_getGTCTimerTicks() - getTicksDelay;
1344     App_printNum("\n Time taken to read GTC Timer ticks = %d ns ",
1345                  (uint32_t)((getTicksDelay*1000000000U)/(uint64_t)OSPI_FLASH_GTC_CLK_FREQ));
1346     App_printNum("(%d ticks) \n", (uint32_t)getTicksDelay);
1348     return (retVal);
1351 static int32_t App_ospiFlashInit(App_OspiObj *ospiObj, uint32_t clk)
1353     int32_t status = UDMA_SOK;
1355     status += OspiFlash_ospiConfigClk(clk);
1356     if(UDMA_SOK == status)
1357     {
1358         App_printNum("\n OSPI RCLK running at %d Hz. \n", clk);
1359     }
1361     status += OspiFlash_ospiOpen(ospiObj, OSPI_FLASH_WRITE_TIMEOUT, OSPI_FLASH_CHECK_IDLE_DELAY, TRUE, FALSE);
1363     status += OspiFlash_ospiEnableDDR(TRUE, FALSE);
1365     status += OspiFlash_ospiSetOpcode(TRUE);
1367     status += OspiFlash_ospiConfigPHY(clk, FALSE);
1369     return (status);    
1372 static int32_t App_ospiFlashStart(uint32_t numBytes)
1374     int32_t retVal = UDMA_SOK;
1375     const CSL_ospi_flash_cfgRegs *baseAddr = (const CSL_ospi_flash_cfgRegs *)(OSPI_FLASH_CONFIG_REG_BASE_ADDR);
1377     retVal = OspiFlash_ospiEraseBlk(numBytes, FALSE);
1379     OspiFlash_ospiXferIntrInit(FALSE);
1381     /* Enable PHY pipeline mode */
1382     CSL_ospiPipelinePhyEnable(baseAddr, TRUE);
1384     return (retVal);