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)
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
171 {
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
202 {
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
225 {
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
235 {
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
257 {
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[] =
342 {
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)
369 {
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);
412 }
414 /*
415 * UDMA OSPI Flash test run
416 */
417 static int32_t Udma_ospiFlashTestRun(void)
418 {
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);
461 }
463 static int32_t App_ospiFlashTest(App_UdmaObj *appObj)
464 {
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);
487 }
489 static int32_t App_udmaOspiFlash(App_UdmaObj *appObj)
490 {
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);
537 }
539 static int32_t App_udmaOspiFlashWrite(App_UdmaObj *appObj)
540 {
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 }
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);
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 *)(®Val), 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;
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);
687 }
689 static int32_t App_udmaOspiFlashRead(App_UdmaObj *appObj)
690 {
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;
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);
776 }
778 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
779 static void App_udmaEventTdCb(Udma_EventHandle eventHandle,
780 uint32_t eventType,
781 void *appData)
782 {
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;
810 }
811 #endif
813 static int32_t App_init(App_UdmaObj *appObj)
814 {
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];
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);
876 }
879 static int32_t App_deinit(App_UdmaObj *appObj)
880 {
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);
893 }
894 static int32_t App_create(App_UdmaObj *appObj)
895 {
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);
1015 }
1017 static int32_t App_delete(App_UdmaObj *appObj)
1018 {
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;
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);
1066 }
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);
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;
1121 }
1123 static int32_t App_udmaTrpdSanityCheck(App_UdmaChObj *appChObj, uint64_t pDesc)
1124 {
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 }
1152 return (retVal);
1153 }
1155 static inline void App_udmaTrObjInitRead(App_UdmaTestObj *appTestObj, App_UdmaTrObj *appTrObj)
1156 {
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;
1199 }
1201 static inline void App_udmaTrObjInitWrite(App_UdmaTestObj *appTestObj, App_UdmaTrObj *appTrObj)
1202 {
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;
1228 appTrObj->dicnt[0] = appTestObj->numBytes;
1229 appTrObj->dicnt[1] = 1U;
1230 }
1232 appTrObj->icnt[2] = 1U;
1233 appTrObj->icnt[3] = 1U;
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;
1256 }
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;
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 }
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;
1291 }
1293 void App_print(const char *str)
1294 {
1295 UART_printf("%s", str);
1296 if(TRUE == Udma_appIsPrintSupported())
1297 {
1298 printf("%s", str);
1299 }
1301 return;
1302 }
1304 static void App_printNum(const char *str, uint32_t num)
1305 {
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;
1317 }
1319 int32_t App_setGTCClk(uint32_t moduleId,
1320 uint32_t clkId,
1321 uint64_t clkRateHz)
1322 {
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);
1347 }
1349 static int32_t App_ospiFlashInit(uint32_t clk)
1350 {
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);
1368 }
1370 static int32_t App_ospiFlashStart(uint32_t numBytes)
1371 {
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);
1383 }