]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/drv/udma/examples/udma_ospi_flash_test/udma_ospi_flash_test.c
f7e598519267f683fbda553778c9b525a80fa5ee
[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);
284 static int32_t App_deinit(App_UdmaObj *appObj);
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(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;
315 /*
316  * UDMA Memories
317  */
318 static uint8_t gTxRingMem[UDMA_TEST_APP_RING_MEM_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
319 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
320 static uint8_t gTxCompRingMem[UDMA_TEST_APP_RING_MEM_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
321 static uint8_t gTxTdCompRingMem[UDMA_TEST_APP_RING_MEM_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
322 #endif
323 static uint8_t gUdmaTrpdMem[UDMA_TEST_APP_TRPD_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
325 /*
326  * Application Buffers
327  */
328 static uint8_t gUdmaTestTxBuf[UDMA_TEST_APP_BUF_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
329 static uint8_t gUdmaTestRxBuf[UDMA_TEST_APP_BUF_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
330 static uint8_t * gUdmaTestOspiFlashDataAddr = (uint8_t *)(OSPI_FLASH_DATA_BASE_ADDR);
332 /* Global test pass/fail flag */
333 static volatile int32_t gUdmaTestResult = UDMA_SOK;
334 /* Global App pass/fail flag */
335 static volatile int32_t gUdmaAppResult = UDMA_SOK;
337 /* No.of ticks taken to do a GTC Reg Read operation */
338 volatile uint64_t getTicksDelay = 0; 
340 /* UDMA OSPI Flash Tests data structure */
341 App_UdmaTestObj gUdmaAppTestObj[] =
343     /* testFunc, testID, clk, numBytes, testDesc */
344     {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"},
345     {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"},
346     {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"},
347     {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"},
348     {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"},
349     {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"},
350     {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"},
351     {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"},
352     {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"},
353     {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"},
354     {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"},
355     {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"},
356     {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"},
357     {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"},
358     {NULL, }
359 };
361 /* ========================================================================== */
362 /*                          Function Definitions                              */
363 /* ========================================================================== */
365 /*
366  * UDMA OSPI Flash test
367  */
368 int32_t Udma_ospiFlashTest(void)
370     int32_t          retVal;
371     uint32_t         i;
372     App_UdmaTestObj *test;
373     App_UdmaObj     *appObj = &gUdmaAppObj;
375     for (i = 0; ; i++)
376     {
377         test = &gUdmaAppTestObj[i];
378         if (test->testFunc == NULL)
379         {
380             break;
381         }
383         appObj->appTestObj = *test;
384         appObj->totalNumBytes = test->numBytes;
385         retVal = test->testFunc();
386         if((UDMA_SOK == retVal) && (UDMA_SOK == gUdmaTestResult))
387         {
388             App_print(test->testDesc);
389             App_print(" have passed\r\n");
390         }
391         else
392         {
393             App_print(test->testDesc);
394             App_print(" have failed\r\n");
395             gUdmaTestResult = UDMA_SOK;
396             gUdmaAppResult = UDMA_EFAIL;
397         }
398     }
400     if(UDMA_SOK != gUdmaAppResult)
401     {
402         App_print("\n Some tests have failed. \n");
403     }
404     else
405     {
406         App_print("\n All tests have passed. \n");
407     }
409     App_print("\n Done\n");
411     return (0);
414 /*
415  * UDMA OSPI Flash test run
416  */
417 static int32_t Udma_ospiFlashTestRun(void)
419     int32_t         retVal;
420     App_UdmaObj    *appObj = &gUdmaAppObj;
422     retVal = App_init(appObj);
423     if(UDMA_SOK != retVal)
424     {
425         App_print("\n [Error] UDMA App init failed!!\n");
426     }
428     App_print("UDMA OSPI Flash application started...\n");
430     if(UDMA_SOK == retVal)
431     {
432         retVal = App_create(appObj);
433         if(UDMA_SOK != retVal)
434         {
435             App_print("\n [Error] UDMA App create failed!!\n");
436         }
437     }
439     if(UDMA_SOK == retVal)
440     {
441         retVal = App_ospiFlashTest(appObj);
442         if(UDMA_SOK != retVal)
443         {
444             App_print("\n [Error] UDMA App OSPI Flash test failed!!\n");
445         }
446     }
448     retVal += App_delete(appObj);
449     if(UDMA_SOK != retVal)
450     {
451         App_print("\n [Error] UDMA App delete failed!!\n");
452     }
454     retVal += App_deinit(appObj);
455     if(UDMA_SOK != retVal)
456     {
457         App_print("\n [Error] UDMA App deinit failed!!\n");
458     }
460     return (retVal);
463 static int32_t App_ospiFlashTest(App_UdmaObj *appObj)
465     int32_t         retVal = UDMA_SOK;
466     uint32_t        i;
467     uint8_t        *rxBuf;
469     /* Reset RX buffer */
470     rxBuf  = &gUdmaTestRxBuf[0U];
471     for(i = 0U; i < appObj->totalNumBytes; i++)
472     {
473         rxBuf[i] = 0U;
474     }
475     /* Writeback RX buffer */
476     Udma_appUtilsCacheWb(rxBuf, appObj->totalNumBytes);
478     /* Perform UDMA memcpy */
479     retVal = App_udmaOspiFlash(appObj);
480     if(UDMA_SOK == retVal)
481     {
482         /* Print performance results for OSPI Flash in DAC DMA mode */
483         App_printPerfResults(appObj);
484     }
486     return (retVal);
489 static int32_t App_udmaOspiFlash(App_UdmaObj *appObj)
491     int32_t         retVal = UDMA_SOK;
492     uint32_t        i;
493     uint8_t        *rxBuf, *txBuf;
495     retVal = App_ospiFlashStart(appObj->totalNumBytes);
496     if(UDMA_SOK != retVal)
497     {
498         App_print("\n [Error] OSPI Start failed!!\n");
499     }
501     if(UDMA_SOK == retVal)
502     {
503         retVal = App_udmaOspiFlashWrite(appObj);
504         if(UDMA_SOK != retVal)
505         {
506             App_print("\n [Error]UDMA OSPI Write failed!!\n");
507         }
508     }
510     if(UDMA_SOK == retVal)
511     {
512         retVal = App_udmaOspiFlashRead(appObj);
513         if(UDMA_SOK != retVal)
514         {
515             App_print("\n [Error]UDMA OSPI Read failed!!\n");
516         }
517     }
519     if(UDMA_SOK == retVal)
520     {
521         rxBuf  = &gUdmaTestRxBuf[0U];
522         txBuf  = &gUdmaTestTxBuf[0U];
524         /* Compare data */
525         for(i = 0U; i < appObj->totalNumBytes; i++)
526         {
527             if(rxBuf[i] != txBuf[i])
528             {
529                 App_printNum("\n [Error] Data mismatch at idx %d", i);
530                 retVal = UDMA_EFAIL;
531                 break;
532             }
533         }
534     }
536     return (retVal);
539 static int32_t App_udmaOspiFlashWrite(App_UdmaObj *appObj)
541     int32_t              retVal = UDMA_SOK;
542     uint64_t             pDesc = 0;
543     uint32_t             i;
544     uint32_t             chunkCnt, cCnt;
545     /* Use local variables in real-time loop for optimized performance */
546     uint32_t             txStartTicks, txStopTicks;
547     volatile uint32_t   *pSwTriggerReg;
548     uint32_t             triggerMask;
549     App_UdmaTestObj     *appTestObj       = &appObj->appTestObj;
550     App_UdmaChObj       *appChObj         = &appObj->appChObj;
551     App_UdmaTrObj       *appTrObj         = &appChObj->appTrObj;
552     App_UdmaCounterObj  *appCounterObj    = &appObj->appCounterObj;
553     Udma_ChHandle        chHandle         = appChObj->chHandle;
554     uint8_t             *txBuf            = &gUdmaTestTxBuf[0U];
555     const uint16_t       size             = appTestObj->numBytes;
556     const uint16_t       totalSize        = appObj->totalNumBytes;
557     volatile uint64_t   *pintrStatusReg   = appTrObj->trEventPrms.intrStatusReg;
558     uint64_t             intrMask         = appTrObj->trEventPrms.intrMask;
559     volatile uint64_t   *intrClearReg     = appTrObj->trEventPrms.intrClearReg;
560     uint8_t             *trpdMem          = appChObj->trpdMem;
562     const CSL_ospi_flash_cfgRegs *baseAddr = (const CSL_ospi_flash_cfgRegs *)(OSPI_FLASH_CONFIG_REG_BASE_ADDR);
564     /* Init TX buffers */
565     for(i = 0U; i < totalSize; i++)
566     {
567         txBuf[i] = i;
568     }
569     
570     App_udmaTrObjInitWrite(appTestObj, appTrObj);
572     /* Get SW trigger register for easy access */
573     triggerMask = ((uint32_t)1U << (appTrObj->trigger - 1U));
574     pSwTriggerReg = (volatile uint32_t *) Udma_chGetSwTriggerRegister(chHandle);
575     if(NULL == pSwTriggerReg)
576     {
577         App_print("\n [Error] Channel trigger register get failed!!\n");
578     }
580     /* Submit TRPD to channels */
581     App_udmaTrpdInit(appTrObj, appChObj);
582     retVal = Udma_ringQueueRaw(
583                 Udma_chGetFqRingHandle(chHandle),
584                 (uint64_t) Udma_appVirtToPhyFxn(trpdMem, 0U, NULL));
585     if(UDMA_SOK != retVal)
586     {
587         App_print("\n [Error] Channel queue failed!!\n");
588     }
590     if(UDMA_SOK == retVal)
591     {
593         /*****************************************************************************
594          * OSPI Write "appTestObj->numBytes" (= appTrObj->icnt[0]* appTrObj->icnt[1] )
595          *****************************************************************************/
596         txStartTicks = App_getGTCTimerTicks();
598         /* Do Cache write-back for "appTestObj->numBytes" chunk to be tranferred */
599         CSL_armR5CacheWb(txBuf, size);
600         
601         /* Set number of times to trigger TX transfer */
602         chunkCnt = appTrObj->icnt[1];
603         for(cCnt = 0U; cCnt < chunkCnt; cCnt++)
604         {
605             /* Write UDMA_TEST_WRITE_CHUNK_SIZE(= appTrObj->icnt[0]) bytes and wait for device to be ready */
607             /* Set channel trigger and wait for completion */
608             CSL_REG32_WR(pSwTriggerReg, triggerMask);
610             /* Wait for the transfer to complete in polling mode */
611             while(1U)
612             {
613                 volatile uint64_t   intrStatusReg;
614                 intrStatusReg = CSL_REG64_RD(pintrStatusReg);
615                 /* Check whether the interrupt status Reg is set - which indicates the
616                 * tranfser completion of appTestObj->numBytes */
617                 if(intrStatusReg & intrMask)
618                 {
619                     /* Clear interrupt */
620                     CSL_REG64_WR(intrClearReg, intrMask);
621                     break;
622                 }
623             }
625             /* Wait device to be ready after write operation */
626             uint32_t timeOutVal = OSPI_FLASH_WRITE_TIMEOUT;
627             uint32_t retry = OSPI_FLASH_WRITE_TIMEOUT;
628             volatile uint32_t delay = OSPI_FLASH_CHECK_IDLE_DELAY;
629             uint8_t  status = 0xFF;
630             uint32_t regVal;
631             while (timeOutVal != 0U)
632             {
633                 (void)CSL_ospiCmdRead(baseAddr, OSPI_FLASH_CMD_RDSR, 1U);
634                 while(!CSL_ospiIsIdle(baseAddr));
635                 CSL_ospiFlashExecCmd(baseAddr);
636                 while(retry != 0U)
637                 {
638                     if(CSL_ospiFlashExecCmdComplete(baseAddr) == TRUE)
639                     {
640                         break;
641                     }
642                     while (delay > 0U)
643                     {  
644                         delay = delay - 1U;
645                     }
646                     retry--;
647                 }
648                 while(!CSL_ospiIsIdle(baseAddr));
649                 regVal = CSL_REG32_RD(&baseAddr->FLASH_RD_DATA_LOWER_REG);
650                 (void)memcpy((void *)&status, (void *)(&regVal), 1U);
651                 if ((status & 1U) == 0U)
652                 {
653                     break;
654                 }
655                 timeOutVal--;
656                 delay = OSPI_FLASH_CHECK_IDLE_DELAY;
657                 while (delay > 0U)
658                 {  
659                     delay = delay - 1U;
660                 }
661             }
662         } 
663         txStopTicks = App_getGTCTimerTicks();
665         appCounterObj->txStartTicks = txStartTicks;
666         appCounterObj->txStopTicks = txStopTicks;
667         
668     }
669     if(UDMA_SOK == retVal)
670     {
671         /* wait for response to be received in completion queue */
672         while(1)
673         {
674             retVal =
675                 Udma_ringDequeueRaw(Udma_chGetCqRingHandle(chHandle), &pDesc);
676             if(UDMA_SOK == retVal)
677             {
678                 break;
679             }
680         }
682         /* Sanity check - Check returned descriptor pointer & TR response status*/
683         retVal = App_udmaTrpdSanityCheck(appChObj, pDesc);
684     }
686     return (retVal);
689 static int32_t App_udmaOspiFlashRead(App_UdmaObj *appObj)
691     int32_t              retVal = UDMA_SOK;
692     uint32_t             triggerCnt, tCnt;
693     /* Use local variables in real-time loop for optimized performance */
694     volatile uint32_t   *pSwTriggerReg;
695     uint32_t             triggerMask;
696     uint32_t             rxStartTicks, rxStopTicks;
697     App_UdmaTestObj     *appTestObj       = &appObj->appTestObj;
698     App_UdmaChObj       *appChObj         = &appObj->appChObj;
699     App_UdmaTrObj       *appTrObj         = &appChObj->appTrObj;
700     App_UdmaCounterObj  *appCounterObj    = &appObj->appCounterObj;
701     Udma_ChHandle        chHandle         = appChObj->chHandle;
702     uint8_t             *rxBuf            = &gUdmaTestRxBuf[0U];
703     const uint16_t       size             = appTestObj->numBytes;
704     volatile uint64_t   *pintrStatusReg   = appTrObj->trEventPrms.intrStatusReg;
705     uint64_t             intrMask         = appTrObj->trEventPrms.intrMask;
706     volatile uint64_t   *intrClearReg     = appTrObj->trEventPrms.intrClearReg;
707     uint8_t             *trpdMem          = appChObj->trpdMem;
708     
709     App_udmaTrObjInitRead(appTestObj, appTrObj);
711     /* Get SW trigger register for easy access */
712     triggerMask = ((uint32_t)1U << (appTrObj->trigger - 1U));
713     pSwTriggerReg = (volatile uint32_t *) Udma_chGetSwTriggerRegister(chHandle);
714     if(NULL == pSwTriggerReg)
715     {
716         App_print("\n [Error] Channel trigger register get failed!!\n");
717     }
719     /* Submit TRPD to channels */
720     App_udmaTrpdInit(appTrObj, appChObj);
721     retVal = Udma_ringQueueRaw(
722                 Udma_chGetFqRingHandle(chHandle),
723                 (uint64_t) Udma_appVirtToPhyFxn(trpdMem, 0U, NULL));
724     if(UDMA_SOK != retVal)
725     {
726         App_print("\n [Error] Channel queue failed!!\n");
727     }
729     if(UDMA_SOK == retVal)
730     {
731         /* Set number of times to trigger RX transfer */
732         triggerCnt = UDMA_TEST_XFER_REPEAT_CNT;
733         for(tCnt = 0U; tCnt < triggerCnt; tCnt++)
734         {      
736             /********************************************************
737              * OSPI Read "appTestObj->numBytes" (= appTrObj->icnt[0])
738              ********************************************************/
740             rxStartTicks = App_getGTCTimerTicks();
742             /* Set channel trigger and wait for completion */
743             CSL_REG32_WR(pSwTriggerReg, triggerMask);
745             /* Wait for the transfer to complete in polling mode */
746             while(1U)
747             {
748                 volatile uint64_t   intrStatusReg;
749                 intrStatusReg = CSL_REG64_RD(pintrStatusReg);
750                 /* Check whether the interrupt status Reg is set - which indicates the
751                  * transfer completion of appTestObj->numBytes */
752                 if(intrStatusReg & intrMask)
753                 {
754                     /* Clear interrupt */
755                     CSL_REG64_WR(intrClearReg, intrMask);
756                     break;
757                 }
758             }
759             /* Do Cache invalidate for the received chunk */
760             CSL_armR5CacheInv(rxBuf, size);
762             rxStopTicks = App_getGTCTimerTicks();
764             appCounterObj->rxStartTicks[tCnt] = rxStartTicks;
765             appCounterObj->rxStopTicks[tCnt] = rxStopTicks;
766         }
767     }
768     /* Since TR Reload Count Set for perpetual loop, TRPD never completes and comes back to CQ.
769      * To exit, teardown the channel using Udma_chDisable */
770     retVal = Udma_chDisable(chHandle, UDMA_DEFAULT_CH_DISABLE_TIMEOUT);
771     if(UDMA_SOK != retVal)
772     {
773         App_print("\n [Error] UDMA channel disable failed!!\n");
774     }
775     return (retVal);
778 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
779 static void App_udmaEventTdCb(Udma_EventHandle eventHandle,
780                               uint32_t eventType,
781                               void *appData)
783     int32_t             retVal;
784     CSL_UdmapTdResponse tdResp;
785     App_UdmaChObj      *appChObj = (App_UdmaChObj *) appData;
787     if(appChObj != NULL)
788     {
789         if(UDMA_EVENT_TYPE_TEARDOWN_PACKET == eventType)
790         {
791             /* Response received in Teardown completion queue */
792             retVal = Udma_chDequeueTdResponse(appChObj->chHandle, &tdResp);
793             if(UDMA_SOK != retVal)
794             {
795                 /* [Error] No TD response after callback!! */
796                 gUdmaTestResult = UDMA_EFAIL;
797             }
798         }
799         else
800         {
801             gUdmaTestResult = UDMA_EFAIL;
802         }
803     }
804     else
805     {
806         gUdmaTestResult = UDMA_EFAIL;
807     }
809     return;
811 #endif
813 static int32_t App_init(App_UdmaObj *appObj)
815     int32_t              retVal;
816     Udma_InitPrms        initPrms;
817     uint32_t             instId;
818     App_UdmaChObj       *appChObj        = &appObj->appChObj;
819     App_UdmaTrObj       *appTrObj       = &appChObj->appTrObj;
820     App_UdmaTestObj     *appTestObj     = &appObj->appTestObj;
821     App_UdmaCounterObj  *appCounterObj  = &appObj->appCounterObj;
822     Udma_DrvHandle       drvHandle      = &appObj->drvObj;
824 #if defined (SOC_AM64X)
825     /* Use Block Copy DMA for AM64x */
826     instId = UDMA_INST_ID_BCDMA_0;
827 #else
828     /* Use MCU NAVSS for MCU domain cores. Rest all cores uses Main NAVSS */
829 #if defined (BUILD_MCU1_0) || defined (BUILD_MCU1_1)
830     instId = UDMA_INST_ID_MCU_0;
831 #else
832     instId = UDMA_INST_ID_MAIN_0;
833 #endif
834 #endif
835     /* UDMA driver init */
836     UdmaInitPrms_init(instId, &initPrms);
837     initPrms.virtToPhyFxn   = &Udma_appVirtToPhyFxn;
838     initPrms.phyToVirtFxn   = &Udma_appPhyToVirtFxn;
839     initPrms.printFxn       = &App_print;
840     retVal = Udma_init(drvHandle, &initPrms);
841     if(UDMA_SOK != retVal)
842     {
843         App_print("\n [Error] UDMA init failed!!\n");
844     }
846     /* Init channel parameters */
847     appChObj->chHandle          = &appChObj->chObj;
848     appChObj->drvHandle         = drvHandle;
849     appChObj->txRingMem         = &gTxRingMem[0U];
850 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
851     appChObj->tdCqEventHandle   = NULL;
852     appChObj->txCompRingMem     = &gTxCompRingMem[0U];
853     appChObj->txTdCompRingMem   = &gTxTdCompRingMem[0U];
854 #endif
855     appChObj->trpdMem           = &gUdmaTrpdMem[0U];
856     
857     /* Init TR parameters */
858     appTrObj->trEventHandle      = NULL;
859     appTrObj->drvHandle          = drvHandle;
861     memset((void *)&appCounterObj->txStartTicks,  0, sizeof(appCounterObj->txStartTicks));
862     memset((void *)&appCounterObj->txStopTicks,   0, sizeof(appCounterObj->txStopTicks));
863     memset((void *)&appCounterObj->txTotalTicks,  0, sizeof(appCounterObj->txTotalTicks));
864     memset((void *)&appCounterObj->txElapsedTime, 0, sizeof(appCounterObj->txElapsedTime));
865     memset((void *)&appCounterObj->rxStartTicks,  0, sizeof(appCounterObj->rxStartTicks));
866     memset((void *)&appCounterObj->rxStopTicks,   0, sizeof(appCounterObj->rxStopTicks));
867     memset((void *)&appCounterObj->rxTotalTicks,  0, sizeof(appCounterObj->rxTotalTicks));
868     memset((void *)&appCounterObj->rxElapsedTime, 0, sizeof(appCounterObj->rxElapsedTime));
870     if(UDMA_SOK == retVal)
871     {
872        retVal = App_ospiFlashInit(appTestObj->clk);
873     }
875     return (retVal);
879 static int32_t App_deinit(App_UdmaObj *appObj)
881     int32_t         retVal;
882     Udma_DrvHandle  drvHandle = &appObj->drvObj;
884     OspiFlash_ospiClose(FALSE);
886     retVal = Udma_deinit(drvHandle);
887     if(UDMA_SOK != retVal)
888     {
889         App_print("\n [Error] UDMA deinit failed!!\n");
890     }
892     return (retVal);
894 static int32_t App_create(App_UdmaObj *appObj)
896     int32_t             retVal = UDMA_SOK;
897     uint32_t            chType;
898     Udma_ChPrms         chPrms;
899     Udma_ChTxPrms       txPrms;
900     Udma_ChRxPrms       rxPrms;
901     Udma_EventHandle    eventHandle;
902     App_UdmaChObj      *appChObj = &appObj->appChObj;
903     App_UdmaTrObj      *appTrObj = &appChObj->appTrObj;
904     Udma_ChHandle       chHandle = appChObj->chHandle;
905     Udma_DrvHandle      drvHandle = &appObj->drvObj;
907     if(UDMA_SOK == retVal)
908     {
909         /* Init channel parameters */
910         chType = UDMA_CH_TYPE_TR_BLK_COPY;
911         UdmaChPrms_init(&chPrms, chType);
912         chPrms.fqRingPrms.ringMem       = appChObj->txRingMem;
913         chPrms.fqRingPrms.ringMemSize   = UDMA_TEST_APP_RING_MEM_SIZE;
914         chPrms.fqRingPrms.elemCnt       = UDMA_TEST_APP_RING_ENTRIES;
915 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
916         chPrms.cqRingPrms.ringMem       = appChObj->txCompRingMem;
917         chPrms.cqRingPrms.ringMemSize   = UDMA_TEST_APP_RING_MEM_SIZE;
918         chPrms.cqRingPrms.elemCnt       = UDMA_TEST_APP_RING_ENTRIES;
919         chPrms.tdCqRingPrms.ringMem     = appChObj->txTdCompRingMem;
920         chPrms.tdCqRingPrms.ringMemSize = UDMA_TEST_APP_RING_MEM_SIZE;
921         chPrms.tdCqRingPrms.elemCnt     = UDMA_TEST_APP_RING_ENTRIES;
922 #endif
924         /* Open channel for block copy */
925         retVal = Udma_chOpen(drvHandle, chHandle, chType, &chPrms);
926         if(UDMA_SOK != retVal)
927         {
928             App_print("\n [Error] UDMA channel open failed!!\n");
929         }
930     }
932     if(UDMA_SOK == retVal)
933     {
934         /* Config TX channel */
935         UdmaChTxPrms_init(&txPrms, chType);
936         retVal = Udma_chConfigTx(chHandle, &txPrms);
937         if(UDMA_SOK != retVal)
938         {
939             App_print("\n [Error] UDMA TX channel config failed!!\n");
940         }
941     }
943     if(UDMA_SOK == retVal)
944     {
945         /* Config RX channel - which is implicitly paired to TX channel in
946             * block copy mode */
947         UdmaChRxPrms_init(&rxPrms, chType);
948         retVal = Udma_chConfigRx(chHandle, &rxPrms);
949         if(UDMA_SOK != retVal)
950         {
951             App_print("\n [Error] UDMA RX channel config failed!!\n");
952         }
953     }
955     if(UDMA_SOK == retVal)
956     {
957         /* Register TR event */
958         eventHandle = &appTrObj->trEventObj;
959         UdmaEventPrms_init(&appTrObj->trEventPrms);
960         appTrObj->trEventPrms.eventType         = UDMA_EVENT_TYPE_TR;
961         appTrObj->trEventPrms.eventMode         = UDMA_EVENT_MODE_SHARED;
962         appTrObj->trEventPrms.chHandle          = chHandle;
963        /* For polling mode we can't use the existing master event as that is meant only for interrupt event - 
964         *  we can't mix interrupt and poll mode in same master handle. Set the parameter to NULL 
965         *  so that the driver creates a new master event. */
966         appTrObj->trEventPrms.masterEventHandle = NULL;
967         appTrObj->trEventPrms.eventCb           = NULL;
968         appTrObj->trEventPrms.appData           = appChObj;
969         retVal = Udma_eventRegister(drvHandle, eventHandle, &appTrObj->trEventPrms);
970         if(UDMA_SOK != retVal)
971         {
972             App_print("\n [Error] UDMA TR event register failed!!\n");
973         }
974         else
975         {
976             appTrObj->trEventHandle = eventHandle;
977         }
978     }
980 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
981     if(UDMA_SOK == retVal)
982     {
983         /* Register teardown ring completion callback */
984         eventHandle = &appChObj->tdCqEventObj;
985         UdmaEventPrms_init(&appChObj->tdCqEventPrms);
986         appChObj->tdCqEventPrms.eventType         = UDMA_EVENT_TYPE_TEARDOWN_PACKET;
987         appChObj->tdCqEventPrms.eventMode         = UDMA_EVENT_MODE_SHARED;
988         appChObj->tdCqEventPrms.chHandle          = chHandle;
989         appChObj->tdCqEventPrms.masterEventHandle = Udma_eventGetGlobalHandle(drvHandle);
990         appChObj->tdCqEventPrms.eventCb           = &App_udmaEventTdCb;
991         appChObj->tdCqEventPrms.appData           = appChObj;
992         retVal = Udma_eventRegister(drvHandle, eventHandle, &appChObj->tdCqEventPrms);
993         if(UDMA_SOK != retVal)
994         {
995             App_print("[Error] UDMA Teardown CQ event register failed!!\n");
996         }
997         else
998         {
999             appChObj->tdCqEventHandle = eventHandle;
1000         }
1001     }
1002 #endif 
1004     if(UDMA_SOK == retVal)
1005     {
1006         /* Channel enable */
1007         retVal = Udma_chEnable(chHandle);
1008         if(UDMA_SOK != retVal)
1009         {
1010             App_print("\n [Error] UDMA channel enable failed!!\n");
1011         }
1012     }
1014     return (retVal);
1017 static int32_t App_delete(App_UdmaObj *appObj)
1019     int32_t         retVal, tempRetVal;
1020     uint64_t        pDesc;
1021     App_UdmaChObj  *appChObj = &appObj->appChObj;
1022     App_UdmaTrObj  *appTrObj = &appChObj->appTrObj;
1023     Udma_ChHandle   chHandle = appChObj->chHandle;
1024     
1026     /* Flush any pending request from the free queue */
1027     while(1)
1028     {
1029         tempRetVal = Udma_ringFlushRaw(
1030                             Udma_chGetFqRingHandle(chHandle), &pDesc);
1031         if(UDMA_ETIMEOUT == tempRetVal)
1032         {
1033             break;
1034         }
1035     }
1037     /* Unregister all events */
1038     if(NULL != appTrObj->trEventHandle)
1039     {
1040         retVal = Udma_eventUnRegister(appTrObj->trEventHandle);
1041         if(UDMA_SOK != retVal)
1042         {
1043             App_print("\n [Error] UDMA event unregister failed!!\n");
1044         }
1045         appTrObj->trEventHandle = NULL;
1046     }
1047 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
1048     if(NULL != appChObj->tdCqEventHandle)
1049     {
1050         retVal += Udma_eventUnRegister(appChObj->tdCqEventHandle);
1051         if(UDMA_SOK != retVal)
1052         {
1053             App_print("[Error] UDMA event unregister failed!!\n");
1054         }
1055         appChObj->tdCqEventHandle = NULL;
1056     }
1057 #endif
1059     retVal += Udma_chClose(chHandle);
1060     if(UDMA_SOK != retVal)
1061     {
1062         App_print("\n [Error] UDMA channel close failed!!\n");
1063     }
1065     return (retVal);
1068 static void App_udmaTrpdInit(App_UdmaTrObj *appTrObj, App_UdmaChObj  *appChObj)
1069 {    
1070     CSL_UdmapCppi5TRPD *pTrpd = (CSL_UdmapCppi5TRPD *) appChObj->trpdMem;
1071     CSL_UdmapTR15 *pTr = (CSL_UdmapTR15 *)(appChObj->trpdMem + sizeof(CSL_UdmapTR15));
1072     uint32_t *pTrResp = (uint32_t *) (appChObj->trpdMem + (sizeof(CSL_UdmapTR15) * 2U));
1073     uint32_t cqRingNum = Udma_chGetCqRingNum(appChObj->chHandle);
1075     /* Make TRPD */
1076     UdmaUtils_makeTrpd(pTrpd, UDMA_TR_TYPE_15, 1U, cqRingNum);
1077     CSL_udmapCppi5TrSetReload((CSL_UdmapCppi5TRPD*)pTrpd, appTrObj->reloadCnt, 0U);
1079     /* Setup TR */
1080     pTr->flags  = CSL_FMK(UDMAP_TR_FLAGS_TYPE, CSL_UDMAP_TR_FLAGS_TYPE_4D_BLOCK_MOVE_REPACKING_INDIRECTION);
1081     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_STATIC, 0U);
1082     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_EOL, appTrObj->eolType);
1083     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_EVENT_SIZE, appTrObj->eventSize);
1084     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0, appTrObj->trigger);
1085     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE);
1086     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0_TYPE, appTrObj->triggerType);
1087     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1_TYPE, CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL);
1088     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_CMD_ID, 0x25U);
1089     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_SA_INDIRECT, 0U);
1090     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_DA_INDIRECT, 0U);
1091     pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_EOP, 1U);
1092     
1093     pTr->icnt0    = appTrObj->icnt[0];
1094     pTr->icnt1    = appTrObj->icnt[1];
1095     pTr->icnt2    = appTrObj->icnt[2];
1096     pTr->icnt3    = appTrObj->icnt[3];
1097     pTr->addr     = (uint64_t) Udma_appVirtToPhyFxn(appTrObj->addr, 0U, NULL);
1098     pTr->fmtflags = 0x00000000U;        /* Linear addressing, 1 byte per elem.
1099                                            Replace with CSL-FL API */
1101     pTr->dicnt0   = appTrObj->dicnt[0];
1102     pTr->dicnt1   = appTrObj->dicnt[1];
1103     pTr->dicnt2   = appTrObj->dicnt[2];
1104     pTr->dicnt3   = appTrObj->dicnt[3];
1105     pTr->daddr    = (uint64_t) Udma_appVirtToPhyFxn(appTrObj->daddr, 0U, NULL);
1107     pTr->dim1     = appTrObj->dim[0]; 
1108     pTr->dim2     = appTrObj->dim[1]; 
1109     pTr->dim3     = appTrObj->dim[2]; 
1110     pTr->ddim1    = appTrObj->ddim[0]; 
1111     pTr->ddim2    = appTrObj->ddim[1]; 
1112     pTr->ddim3    = appTrObj->ddim[2];
1114     /* Clear TR response memory */
1115     *pTrResp = 0xFFFFFFFFU;
1117     /* Writeback cache */
1118     Udma_appUtilsCacheWb(appChObj->trpdMem, UDMA_TEST_APP_TRPD_SIZE_ALIGN);
1120     return;
1123 static int32_t App_udmaTrpdSanityCheck(App_UdmaChObj *appChObj, uint64_t pDesc)
1125     int32_t         retVal  = UDMA_SOK;
1126     uint32_t       *pTrResp, trRespStatus;
1127     uint8_t        *trpdMem = appChObj->trpdMem;
1129     /* Check returned descriptor pointer */
1130     if(((uint64_t) Udma_appPhyToVirtFxn(pDesc, 0U, NULL)) != ((uint64_t) trpdMem))
1131     {
1132         App_print("\n [Error] TR descriptor pointer returned doesn't "
1133                 "match the submitted address!!\n");
1134         retVal = UDMA_EFAIL;
1135     }
1137     if(UDMA_SOK == retVal)
1138     {
1139         /* Invalidate cache */
1140         Udma_appUtilsCacheInv(trpdMem, UDMA_TEST_APP_TRPD_SIZE_ALIGN);
1142         /* check TR response status */
1143         pTrResp = (uint32_t *) (trpdMem + (sizeof(CSL_UdmapTR15) * 2U));
1144         trRespStatus = CSL_FEXT(*pTrResp, UDMAP_TR_RESPONSE_STATUS_TYPE);
1145         if(trRespStatus != CSL_UDMAP_TR_RESPONSE_STATUS_COMPLETE)
1146         {
1147             App_print("\n [Error] TR Response not completed!!\n");
1148             retVal = UDMA_EFAIL;
1149         }
1150     }
1151     
1152     return (retVal);
1155 static inline void App_udmaTrObjInitRead(App_UdmaTestObj *appTestObj, App_UdmaTrObj *appTrObj)
1157     /* TR Reload Count */
1158     appTrObj->reloadCnt    = 0x1FFU; /* Set to 0x1FFU for perpetual loop */
1159     appTrObj->trigger      = CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL0;
1160     /* Set interrupt after transferring icnt0*icnt1*icnt2*icnt3 bytes - When TR is completed */
1161     appTrObj->eventSize    = CSL_UDMAP_TR_FLAGS_EVENT_SIZE_COMPLETION; 
1162     /* Transfer icnt0*icnt1*icnt2*icnt3 bytes(entire TR) after a trigger */
1163     appTrObj->triggerType  = CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL;
1164     /* EOL boundaries for each icnt0*icnt1*icnt2*icnt3 bytes */
1165     appTrObj->eolType      = CSL_UDMAP_TR_FLAGS_EOL_ICNT0_ICNT1_ICNT2_ICNT3; 
1167     /* No. of bytes to tansfer after getting interrupt (in this case)*/
1168     appTrObj->icnt[0] = appTestObj->numBytes; 
1169     /* No. of times to repeat the tansfer of inct0 bytes */
1170     appTrObj->icnt[1] = 1U;
1171     /* No. of times to repeat the tansfer of inct0*icnt1 bytes */
1172     appTrObj->icnt[2] = 1U;
1173     /* No. of times to repeat the tansfer of inct0*icnt1*inct2 bytes */
1174     appTrObj->icnt[3] = 1U;
1175     /* similar destination params */
1176     appTrObj->dicnt[0] = appTestObj->numBytes; 
1177     appTrObj->dicnt[1] = 1U;
1178     appTrObj->dicnt[2] = 1U;
1179     appTrObj->dicnt[3] = 1U;
1181     /* DIM1: Offset for source OSPI data address after transferring inct0 bytes */
1182     appTrObj->dim[0]  = appTrObj->icnt[0]; /* Use inct0 bytes so that successive triger tranfers the next icnt0 bytes */
1183     /* DIM2 - Offset for source OSPI data address after transferring inct0*inct1 bytes */
1184     appTrObj->dim[1]  = appTrObj->icnt[0]*appTrObj->icnt[1]; /* Use inct0*icnt1 bytes so that successive iteration tranfers the next icnt0*icnt1 bytes */
1185     /* DIM3 - Offset for source OSPI data address after transferring inct0*inct1*inct2 bytes */
1186     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 */
1188     /* Similar offset for destination RX buffer address */
1189     appTrObj->ddim[0]  = appTrObj->dicnt[0]; 
1190     appTrObj->ddim[1]  = appTrObj->dicnt[0]*appTrObj->dicnt[1];
1191     appTrObj->ddim[2]  = appTrObj->dicnt[0]*appTrObj->dicnt[1]*appTrObj->dicnt[2];
1193     /* Source Address - OSPI Data address */
1194     appTrObj->addr  = gUdmaTestOspiFlashDataAddr;
1195     /* Destination Address - RX Buffer */
1196     appTrObj->daddr  = &gUdmaTestRxBuf[0U];;
1198     return;
1201 static inline void App_udmaTrObjInitWrite(App_UdmaTestObj *appTestObj, App_UdmaTrObj *appTrObj)
1203     /* TR Reload Count */
1204     appTrObj->reloadCnt    = 0U; 
1205     appTrObj->trigger      = CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL0;
1206     /* Set interrupt after transferring icnt0 bytes */
1207     appTrObj->eventSize    = CSL_UDMAP_TR_FLAGS_EVENT_SIZE_ICNT1_DEC; 
1208     /* Transfer icnt0 bytes after a trigger */
1209     appTrObj->triggerType  = CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ICNT1_DEC;
1210     /* EOL boundaries for each icnt0 bytes */
1211     appTrObj->eolType      = CSL_UDMAP_TR_FLAGS_EOL_ICNT0; 
1213     if(appTestObj->numBytes > UDMA_TEST_WRITE_CHUNK_SIZE)
1214     {
1215         /* For OSPI DMA write, write in chunks. No. of bytes to tansfer after getting interrupt(in this case) */
1216         appTrObj->icnt[0] = UDMA_TEST_WRITE_CHUNK_SIZE; 
1217         /* No. of times to repeat the tansfer of inct0 bytes (= No.of chunks in this case) */
1218         appTrObj->icnt[1] = appTestObj->numBytes/UDMA_TEST_WRITE_CHUNK_SIZE;
1220         appTrObj->dicnt[0] = UDMA_TEST_WRITE_CHUNK_SIZE; 
1221         appTrObj->dicnt[1] = appTestObj->numBytes/UDMA_TEST_WRITE_CHUNK_SIZE;
1222     }
1223     else
1224     {
1225         appTrObj->icnt[0] = appTestObj->numBytes;
1226         appTrObj->icnt[1] = 1U;
1227         
1228         appTrObj->dicnt[0] = appTestObj->numBytes;
1229         appTrObj->dicnt[1] = 1U;
1230     }
1231     
1232     appTrObj->icnt[2] = 1U;
1233     appTrObj->icnt[3] = 1U;
1234     
1235     appTrObj->dicnt[2] = 1U;
1236     appTrObj->dicnt[3] = 1U;
1238     /* DIM1- Offset for source TX Buffer address after transferring inct0 bytes */
1239     appTrObj->dim[0]  = appTrObj->icnt[0]; /* chunkSize - so that successive triger tranfers the next icnt0(chunkSize) bytes */
1240     /* DIM2 - Offset for source TX Buffer address after transferring inct0*inct1 bytes */
1241     appTrObj->dim[1]  = appTrObj->icnt[0]*appTrObj->icnt[1]; /* inct0*icnt1 bytes - so that successive iteration tranfers the next icnt0*icnt1 bytes */
1242     /* DIM3 - Offset for source TX Buffer address after transferring inct0*inct1*inct2 bytes */
1243     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 */
1245     /* DDIM1/DDIM2/DDIM3 - Similar offset for destination RX buffer address */
1246     appTrObj->ddim[0]  = appTrObj->dicnt[0]; 
1247     appTrObj->ddim[1]  = appTrObj->dicnt[0]*appTrObj->dicnt[1];
1248     appTrObj->ddim[2]  = appTrObj->dicnt[0]*appTrObj->dicnt[1]*appTrObj->dicnt[2];
1250     /* Source Address - TX Buffer */
1251     appTrObj->addr  = &gUdmaTestTxBuf[0U];
1252     /* Destination Address - OSPI Data address  */
1253     appTrObj->daddr = gUdmaTestOspiFlashDataAddr;
1255     return;
1258 static void App_printPerfResults(App_UdmaObj *appObj)
1259 {    
1260     App_UdmaCounterObj  *appCounterObj = &appObj->appCounterObj;
1261     App_UdmaTestObj     *appTestObj = &appObj->appTestObj;
1262     uint32_t             tCnt;
1263     uint32_t             triggerCnt;
1264     
1265     appCounterObj->txTotalTicks = appCounterObj->txStopTicks - appCounterObj->txStartTicks  - getTicksDelay;
1266     appCounterObj->txElapsedTime = (appCounterObj->txTotalTicks*1000000000U)/(uint64_t)OSPI_FLASH_GTC_CLK_FREQ;
1268     App_printNum("\n OSPI Write %d", appTestObj->numBytes);
1269     App_printNum(" bytes in %d", (uint32_t)appCounterObj->txElapsedTime);
1270     App_print("ns.");
1272     triggerCnt = UDMA_TEST_XFER_REPEAT_CNT;
1273     for(tCnt = 0U; tCnt < triggerCnt; tCnt++)
1274     {
1275         appCounterObj->rxTotalTicks[tCnt] = appCounterObj->rxStopTicks[tCnt] - appCounterObj->rxStartTicks[tCnt]  - getTicksDelay;
1276         appCounterObj->rxTotalTicks[triggerCnt] += appCounterObj->rxTotalTicks[tCnt];
1277         appCounterObj->rxElapsedTime[tCnt] = (appCounterObj->rxTotalTicks[tCnt]*1000000000U)/(uint64_t)OSPI_FLASH_GTC_CLK_FREQ;
1279         App_printNum("\n OSPI Read %d", appTestObj->numBytes);
1280         App_printNum(" bytes in %d", (uint32_t)appCounterObj->rxElapsedTime[tCnt]);
1281         App_print("ns.");
1282     }
1283     
1284     appCounterObj->rxTotalTicks[triggerCnt] = appCounterObj->rxTotalTicks[triggerCnt]/triggerCnt;
1285     appCounterObj->rxElapsedTime[triggerCnt] = (appCounterObj->rxTotalTicks[triggerCnt]*1000000000U)/(uint64_t)OSPI_FLASH_GTC_CLK_FREQ;
1286     App_printNum("\n\n Average time for OSPI Read %d", appTestObj->numBytes);
1287     App_printNum(" bytes = %d", (uint32_t)appCounterObj->rxElapsedTime[triggerCnt]);
1288     App_print("ns. \n\n");
1290     return;
1293 void App_print(const char *str)
1295     UART_printf("%s", str);
1296     if(TRUE == Udma_appIsPrintSupported())
1297     {
1298         printf("%s", str);
1299     }
1301     return;
1304 static void App_printNum(const char *str, uint32_t num)
1306     static char printBuf[200U];
1308     snprintf(printBuf, 200U, str, num);
1309     UART_printf("%s", printBuf);
1311     if(TRUE == Udma_appIsPrintSupported())
1312     {
1313         printf("%s", printBuf);
1314     }
1316     return;
1319 int32_t App_setGTCClk(uint32_t moduleId,
1320                       uint32_t clkId,
1321                       uint64_t clkRateHz)
1323     int32_t retVal;
1324     uint64_t currClkFreqHz;
1326     retVal = Sciclient_pmGetModuleClkFreq(moduleId,
1327                                           clkId,
1328                                           &currClkFreqHz,
1329                                           SCICLIENT_SERVICE_WAIT_FOREVER);
1330     if ((retVal == CSL_PASS) &&
1331         (currClkFreqHz != clkRateHz))
1332     {
1333         retVal = OspiFlash_ClkRateSet(moduleId, clkId, clkRateHz);
1334     }
1336     /* Enable GTC */
1337     HW_WR_REG32(CSL_GTC0_GTC_CFG1_BASE + 0x0U, 0x1);
1339     /* Measure and store the time spent to do a getTime operation */
1340     getTicksDelay = App_getGTCTimerTicks();
1341     getTicksDelay = App_getGTCTimerTicks() - getTicksDelay;
1342     App_printNum("\n Time taken to read GTC Timer ticks = %d ns ",
1343                  (uint32_t)((getTicksDelay*1000000000U)/(uint64_t)OSPI_FLASH_GTC_CLK_FREQ));
1344     App_printNum("(%d ticks) \n", (uint32_t)getTicksDelay);
1346     return (retVal);
1349 static int32_t App_ospiFlashInit(uint32_t clk)
1351     int32_t status = UDMA_SOK;
1353     status += OspiFlash_ospiConfigClk(clk);
1354     if(UDMA_SOK == status)
1355     {
1356         App_printNum("\n OSPI RCLK running at %d Hz. \n", clk);
1357     }
1359     status += OspiFlash_ospiOpen(OSPI_FLASH_WRITE_TIMEOUT, OSPI_FLASH_CHECK_IDLE_DELAY, FALSE);
1361     status += OspiFlash_ospiEnableDDR(FALSE);
1363     status += OspiFlash_ospiSetOpcode();
1365     status += OspiFlash_ospiConfigPHY(clk, FALSE);
1367     return (status);    
1370 static int32_t App_ospiFlashStart(uint32_t numBytes)
1372     int32_t retVal = UDMA_SOK;
1373     const CSL_ospi_flash_cfgRegs *baseAddr = (const CSL_ospi_flash_cfgRegs *)(OSPI_FLASH_CONFIG_REG_BASE_ADDR);
1375     retVal = OspiFlash_ospiEraseBlk(numBytes, FALSE);
1377     OspiFlash_ospiXferIntrInit(FALSE);
1379     /* Enable PHY pipeline mode */
1380     CSL_ospiPipelinePhyEnable(baseAddr, TRUE);
1382     return (retVal);