[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 * Loop N times (int1)
40 * [This following performs OSPI write of icnt0 bytes]
41 * - SW trigger UDMA Channel -> Triggers OSPI Write 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 *
45 * > Each loop transfers M (icnt0) bytes of data
46 * > R5 TCM and OSPI Data Buffer size is M x N bytes.
47 *
48 * Loop QxPxN times (icnt3*icnt2*inct1)
49 *
50 * [The following performs OSPI read of icnt0 bytes]
51 * - SW trigger UDMA Channel -> Triggers OSPI Read from OSPI Data Buffer to R5 TCM
52 * - Wait for transfer to complete
53 *
54 * > Each loop transfers M (icnt0) bytes of data
55 * > R5 TCM and OSPI Data Buffer size is M x N bytes.
56 * > After each N no.of loops (ie, after performing MxN continous bytes tranfer),
57 * the tranfers restarts from the origin address.
58 * This happens QxP times.
59 * Memory is set to wrap around after MxN bytes of transfer.
60 * This shows how to do tranfer on circular buffer of size MxN bytes
61 *
62 * Where,
63 * - M is icnt0 - "appTestObj->numBytes"
64 * This refers to the no. of bytes transferred per OSPI Read/Write operation.
65 * - N is icnt1 - UDMA_TEST_XFER_CNT
66 * This parameter can be used to configure the no.of times the transfer operation to be carried out for continous data.
67 * - P is icnt2 = UDMA_TEST_XFER_REPEAT_CNT_0 and
68 * Q is icnt3 = UDMA_TEST_XFER_REPEAT_CNT_1
69 * This parameters can be used to configure the the no.of times to repeat the whole transfer starting from the origin address.
70 *
71 * NOTE: As per the requirments of the specific usecase, N,Q and P can be used interchangeably by making appropiate changes in the TRPD.
72 * For example UDMA_TEST_XFER_CNT can be NxP (icnt1xicnt2) with UDMA_TEST_XFER_REPEAT_CNT as Q.
73 * Or even UDMA_TEST_XFER_CNT can be NxPxQ (icnt1xicnt2xicnt3) with UDMA_TEST_XFER_REPEAT_CNT as 1.
74 * And conversly, UDMA_TEST_XFER_REPEAT_CNT can be NxPxQ (icnt1xicnt2xicnt3) with UDMA_TEST_XFER_CNT as 1.
75 */
77 /* ========================================================================== */
78 /* Include Files */
79 /* ========================================================================== */
81 #include <stdio.h>
82 #include <ti/csl/soc.h>
83 #include <ti/csl/arch/csl_arch.h>
84 #include <ti/csl/hw_types.h>
85 #include <ti/drv/udma/udma.h>
86 #include <ti/drv/uart/UART.h>
87 #include <ti/drv/uart/UART_stdio.h>
88 #include <ti/drv/udma/examples/udma_apputils/udma_apputils.h>
89 #include <ti/csl/example/ospi/ospi_flash/common/ospi_flash_common.h>
91 /* ========================================================================== */
92 /* Macros & Typedefs */
93 /* ========================================================================== */
95 /*
96 * Application test config parameters
97 */
98 /** \brief Maximum Number of bytes to perform OSPI Read/Write per operation (Actual number based on test) */
99 #define UDMA_TEST_XFER_MAX_NUM_BYTES (1024U)
100 /** \brief Number of times to do continous data tranfer */
101 #define UDMA_TEST_XFER_CNT (5U)
102 /** \brief Number of times to repeat whole data tranfer */
103 #define UDMA_TEST_XFER_REPEAT_CNT_0 (2U)
104 /** \brief Number of times to repeat whole data tranfer */
105 #define UDMA_TEST_XFER_REPEAT_CNT_1 (1U)
107 /*
108 * Application other test parameters
109 */
111 /** \brief Total number of bytes to copy and buffer allocation */
112 #define UDMA_TEST_APP_MAX_TOTAL_NUM_BYTES (UDMA_TEST_XFER_MAX_NUM_BYTES * UDMA_TEST_XFER_CNT)
113 /** \brief This ensures every channel memory is aligned */
114 #define UDMA_TEST_APP_BUF_SIZE_ALIGN ((UDMA_TEST_APP_MAX_TOTAL_NUM_BYTES + UDMA_CACHELINE_ALIGNMENT) & ~(UDMA_CACHELINE_ALIGNMENT - 1U))
115 /** \brief Number of times to perform the memcpy operation */
116 #define UDMA_TEST_APP_LOOP_CNT (1U)
118 /*
119 * Ring parameters
120 */
121 /** \brief Number of ring entries - we can prime this much memcpy operations */
122 #define UDMA_TEST_APP_RING_ENTRIES (1U)
123 /** \brief Size (in bytes) of each ring entry (Size of pointer - 64-bit) */
124 #define UDMA_TEST_APP_RING_ENTRY_SIZE (sizeof(uint64_t))
125 /** \brief Total ring memory */
126 #define UDMA_TEST_APP_RING_MEM_SIZE (UDMA_TEST_APP_RING_ENTRIES * \
127 UDMA_TEST_APP_RING_ENTRY_SIZE)
128 /** \brief This ensures every channel memory is aligned */
129 #define UDMA_TEST_APP_RING_MEM_SIZE_ALIGN ((UDMA_TEST_APP_RING_MEM_SIZE + UDMA_CACHELINE_ALIGNMENT) & ~(UDMA_CACHELINE_ALIGNMENT - 1U))
130 /**
131 * \brief UDMA TR packet descriptor memory.
132 * This contains the CSL_UdmapCppi5TRPD + Padding to sizeof(CSL_UdmapTR15) +
133 * one Type_15 TR (CSL_UdmapTR15) + one TR response of 4 bytes.
134 * Since CSL_UdmapCppi5TRPD is less than CSL_UdmapTR15, size is just two times
135 * CSL_UdmapTR15 for alignment.
136 */
137 #define UDMA_TEST_APP_TRPD_SIZE ((sizeof(CSL_UdmapTR15) * 2U) + 4U)
138 /** \brief This ensures every channel memory is aligned */
139 #define UDMA_TEST_APP_TRPD_SIZE_ALIGN ((UDMA_TEST_APP_TRPD_SIZE + UDMA_CACHELINE_ALIGNMENT) & ~(UDMA_CACHELINE_ALIGNMENT - 1U))
141 /*
142 * UDMA OSPI Flash test ID definitions
143 */
144 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 16 Bytes */
145 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_16B (0U)
146 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 16 Bytes */
147 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_16B (1U)
148 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 32 Bytes */
149 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_32B (2U)
150 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 32 Bytes */
151 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_32B (3U)
152 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 64 Bytes */
153 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_64B (4U)
154 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 64 Bytes */
155 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_64B (5U)
156 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 128 Bytes */
157 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_128B (6U)
158 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 128 Bytes */
159 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_128B (7U)
160 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 256 Bytes */
161 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_256B (8U)
162 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 256 Bytes */
163 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_256B (9U)
164 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 512 Bytes */
165 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_512B (10U)
166 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 512 Bytes */
167 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_512B (11U)
168 /** \brief OSPI flash test at 133MHz RCLK - Read/Write 1024 Bytes */
169 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_133M_1024B (12U)
170 /** \brief OSPI flash test at 166MHz RCLK - Read/Write 1024 Bytes */
171 #define UDMA_OSPI_FLASH_TEST_ID_DAC_DMA_166M_1024B (13U)
173 /** \brief Get GTC Timer Ticks */
174 #define App_getGTCTimerTicks() (*((uint64_t *)(CSL_GTC0_GTC_CFG1_BASE + 0x8U)))
176 /* ========================================================================== */
177 /* Structure Declarations */
178 /* ========================================================================== */
180 typedef struct
181 {
182 struct Udma_EventObj trEventObj;
184 Udma_EventHandle trEventHandle;
185 Udma_EventPrms trEventPrms;
187 uint32_t trigger;
188 /**< Global0 or Global 1 Trigger - refer \ref CSL_UdmapTrFlagsTrigger. */
189 uint32_t eventSize;
190 /**< Refer \ref CSL_UdmapTrFlagsEventSize. */
191 uint32_t triggerType;
192 /**< Refer \ref CSL_UdmapTrFlagsTriggerType. */
193 uint32_t eolType;
194 /**< Refer \ref CSL_UdmapTrFlagsEol. */
196 /**< Refer TR Address and Size Attributes */
197 uint16_t icnt[4];
198 uint16_t dicnt[4];
199 int32_t dim[3];
200 int32_t ddim[3];
201 uint8_t *addr;
202 uint8_t *daddr;
204 Udma_DrvHandle drvHandle;
206 } App_UdmaTrObj;
208 typedef struct
209 {
210 struct Udma_ChObj chObj;
211 App_UdmaTrObj appTrObj;
213 Udma_ChHandle chHandle;
214 Udma_DrvHandle drvHandle;
216 uint8_t *txRingMem;
217 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
218 uint8_t *txCompRingMem;
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[UDMA_TEST_XFER_CNT];
238 /**< GTC Timer ticks at stop of profiling OSPI write. */
239 volatile uint64_t txStopTicks[UDMA_TEST_XFER_CNT];
240 /**< Measured total no. of GTC Timer ticks for OSPI write. */
241 volatile uint64_t txTotalTicks[(UDMA_TEST_XFER_CNT) + 1U];
242 /**< Elapsed time in nsec for OSPI write.. */
243 volatile uint64_t txElapsedTime[(UDMA_TEST_XFER_CNT) + 1U];
245 /**< GTC Timer ticks at start of profiling OSPI read. */
246 volatile uint64_t rxStartTicks[UDMA_TEST_XFER_CNT * UDMA_TEST_XFER_REPEAT_CNT_0 * UDMA_TEST_XFER_REPEAT_CNT_1];
247 /**< GTC Timer ticks at stop of profiling OSPI read. */
248 volatile uint64_t rxStopTicks[UDMA_TEST_XFER_CNT * UDMA_TEST_XFER_REPEAT_CNT_0 * UDMA_TEST_XFER_REPEAT_CNT_1];
249 /**< Measured total no. of GTC Timer ticks for OSPI read. */
250 volatile uint64_t rxTotalTicks[(UDMA_TEST_XFER_CNT * UDMA_TEST_XFER_REPEAT_CNT_0 * UDMA_TEST_XFER_REPEAT_CNT_1) + 1U];
251 /**< Elapsed time in nsec for OSPI read. */
252 volatile uint64_t rxElapsedTime[(UDMA_TEST_XFER_CNT * UDMA_TEST_XFER_REPEAT_CNT_0 * UDMA_TEST_XFER_REPEAT_CNT_1) + 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 static int32_t App_init(App_UdmaObj *appObj);
278 static int32_t App_deinit(App_UdmaObj *appObj);
280 static int32_t App_create(App_UdmaObj *appObj);
281 static int32_t App_delete(App_UdmaObj *appObj);
283 static void App_udmaTrpdInit(App_UdmaTrObj *appTrObj, App_UdmaChObj *appChObj);
284 static int32_t App_udmaTrpdSanityCheck(App_UdmaChObj *appChObj, uint64_t pDesc);
285 static inline void App_udmaTrObjInitWrite(App_UdmaTestObj *appTestObj, App_UdmaTrObj *appTrObj);
286 static inline void App_udmaTrObjInitRead(App_UdmaTestObj *appTestObj, App_UdmaTrObj *appTrObj);
288 static void App_printPerfResults(App_UdmaObj *appObj);
290 void App_print(const char *str);
291 static void App_printNum(const char *str, uint32_t num);
292 int32_t App_setGTCClk(uint32_t moduleId,
293 uint32_t clkId,
294 uint64_t clkRateHz);
297 static int32_t App_ospiFlashInit(uint32_t clk);
298 static int32_t App_ospiFlashStart(uint32_t numBytes) __attribute__((section(".udma_critical_fxns")));
300 /* ========================================================================== */
301 /* Global Variables */
302 /* ========================================================================== */
304 /*
305 * UDMA driver and channel objects
306 */
307 App_UdmaObj gUdmaAppObj;
309 /*
310 * UDMA Memories
311 */
312 static uint8_t gTxRingMem[UDMA_TEST_APP_RING_MEM_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
313 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
314 static uint8_t gTxCompRingMem[UDMA_TEST_APP_RING_MEM_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
315 #endif
316 static uint8_t gUdmaTrpdMem[UDMA_TEST_APP_TRPD_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
318 /*
319 * Application Buffers
320 */
321 static uint8_t gUdmaTestTxBuf[UDMA_TEST_APP_BUF_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
322 static uint8_t gUdmaTestRxBuf[UDMA_TEST_APP_BUF_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT), section(".udma_buffer_r5_tcm")));
323 static uint8_t * gUdmaTestOspiFlashDataAddr = (uint8_t *)(OSPI_FLASH_DATA_BASE_ADDR);
325 /* Global test pass/fail flag */
326 static volatile int32_t gUdmaAppResult = UDMA_SOK;
328 /* No.of ticks taken to do a GTC Reg Read operation */
329 volatile uint64_t getTicksDelay = 0;
331 /* UDMA OSPI Flash Tests data structure */
332 App_UdmaTestObj gUdmaAppTestObj[] =
333 {
334 /* testFunc, testID, clk, numBytes, testDesc */
335 {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"},
336 {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"},
337 {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"},
338 {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"},
339 {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"},
340 {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"},
341 {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"},
342 {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"},
343 {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"},
344 {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"},
345 {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"},
346 {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"},
347 {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"},
348 {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"},
349 {NULL, }
350 };
352 /* ========================================================================== */
353 /* Function Definitions */
354 /* ========================================================================== */
356 /*
357 * UDMA OSPI Flash test
358 */
359 int32_t Udma_ospiFlashTest(void)
360 {
361 int32_t retVal;
362 uint32_t i;
363 App_UdmaTestObj *test;
364 App_UdmaObj *appObj = &gUdmaAppObj;
366 for (i = 0; ; i++)
367 {
368 test = &gUdmaAppTestObj[i];
369 if (test->testFunc == NULL)
370 {
371 break;
372 }
374 appObj->appTestObj = *test;
375 appObj->totalNumBytes = test->numBytes * UDMA_TEST_XFER_CNT;
376 retVal = test->testFunc();
377 if(UDMA_SOK == retVal)
378 {
379 App_print(test->testDesc);
380 App_print(" have passed\r\n");
381 }
382 else
383 {
384 App_print(test->testDesc);
385 App_print(" have failed\r\n");
386 break;
387 }
388 }
390 if(UDMA_SOK != retVal)
391 {
392 App_print("\n Some tests have failed. \n");
393 }
394 else
395 {
396 App_print("\n All tests have passed. \n");
397 }
399 App_print("\n Done\n");
401 return (0);
402 }
404 /*
405 * UDMA OSPI Flash test run
406 */
407 static int32_t Udma_ospiFlashTestRun(void)
408 {
409 int32_t retVal;
410 App_UdmaObj *appObj = &gUdmaAppObj;
412 retVal = App_init(appObj);
413 if(UDMA_SOK != retVal)
414 {
415 App_print("\n [Error] UDMA App init failed!!\n");
416 }
418 App_print("UDMA OSPI Flash application started...\n");
420 if(UDMA_SOK == retVal)
421 {
422 retVal = App_create(appObj);
423 if(UDMA_SOK != retVal)
424 {
425 App_print("\n [Error] UDMA App create failed!!\n");
426 }
427 }
429 if(UDMA_SOK == retVal)
430 {
431 retVal = App_ospiFlashTest(appObj);
432 if(UDMA_SOK != retVal)
433 {
434 App_print("\n [Error] UDMA App OSPI Flash test failed!!\n");
435 }
436 }
438 retVal += App_delete(appObj);
439 if(UDMA_SOK != retVal)
440 {
441 App_print("\n [Error] UDMA App delete failed!!\n");
442 }
444 retVal += App_deinit(appObj);
445 if(UDMA_SOK != retVal)
446 {
447 App_print("\n [Error] UDMA App deinit failed!!\n");
448 }
450 return (0);
451 }
453 static int32_t App_ospiFlashTest(App_UdmaObj *appObj)
454 {
455 int32_t retVal = UDMA_SOK;
456 uint32_t loopCnt = 0U;
457 uint32_t i;
458 uint8_t *rxBuf;
460 while(loopCnt < UDMA_TEST_APP_LOOP_CNT)
461 {
462 /* Reset RX buffer */
463 rxBuf = &gUdmaTestRxBuf[0U];
464 for(i = 0U; i < appObj->totalNumBytes; i++)
465 {
466 rxBuf[i] = 0U;
467 }
468 /* Writeback RX buffer */
469 Udma_appUtilsCacheWb(rxBuf, appObj->totalNumBytes);
471 /* Perform UDMA memcpy */
472 retVal = App_udmaOspiFlash(appObj);
473 if(UDMA_SOK != retVal)
474 {
475 break;
476 }
477 else
478 {
479 /* Print performance results for OSPI Flash in DAC DMA mode */
480 App_printPerfResults(appObj);
481 }
483 loopCnt++;
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 triggerCnt, tCnt;
545 uint8_t *txChunkAddr;
546 /* Use local variables in real-time loop for optimized performance */
547 uint32_t txStartTicks, txStopTicks;
548 volatile uint32_t *pSwTriggerReg;
549 uint32_t triggerMask;
550 App_UdmaTestObj *appTestObj = &appObj->appTestObj;
551 App_UdmaChObj *appChObj = &appObj->appChObj;
552 App_UdmaTrObj *appTrObj = &appChObj->appTrObj;
553 App_UdmaCounterObj *appCounterObj = &appObj->appCounterObj;
554 Udma_ChHandle chHandle = appChObj->chHandle;
555 uint8_t *txBuf = &gUdmaTestTxBuf[0U];
556 const uint16_t size = appTestObj->numBytes;
557 const uint16_t totalSize = appObj->totalNumBytes;
558 volatile uint64_t *pintrStatusReg = appTrObj->trEventPrms.intrStatusReg;
559 uint64_t intrMask = appTrObj->trEventPrms.intrMask;
560 volatile uint64_t *intrClearReg = appTrObj->trEventPrms.intrClearReg;
561 uint8_t *trpdMem = appChObj->trpdMem;
563 const CSL_ospi_flash_cfgRegs *baseAddr = (const CSL_ospi_flash_cfgRegs *)(OSPI_FLASH_CONFIG_REG_BASE_ADDR);
565 /* Init TX buffers */
566 for(i = 0U; i < totalSize; i++)
567 {
568 txBuf[i] = i;
569 }
571 App_udmaTrObjInitWrite(appTestObj, appTrObj);
573 /* Get SW trigger register for easy access */
574 triggerMask = ((uint32_t)1U << (appTrObj->trigger - 1U));
575 pSwTriggerReg = (volatile uint32_t *) Udma_chGetSwTriggerRegister(chHandle);
576 if(NULL == pSwTriggerReg)
577 {
578 App_print("\n [Error] Channel trigger register get failed!!\n");
579 }
581 /* Submit TRPD to channels */
582 App_udmaTrpdInit(appTrObj, appChObj);
583 retVal = Udma_ringQueueRaw(
584 Udma_chGetFqRingHandle(chHandle),
585 (uint64_t) Udma_appVirtToPhyFxn(trpdMem, 0U, NULL));
586 if(UDMA_SOK != retVal)
587 {
588 App_print("\n [Error] Channel queue failed!!\n");
589 }
591 if(UDMA_SOK == retVal)
592 {
593 /* Set number of times to trigger TX transfer */
594 triggerCnt = UDMA_TEST_XFER_CNT;
595 for(tCnt = 0U; tCnt < triggerCnt; tCnt++)
596 {
597 /* Calculate start of address to do cacheOps */
598 txChunkAddr = txBuf + (tCnt * size);
600 /**********************************
601 * OSPI Write "appTestObj->numBytes"
602 **********************************/
603 txStartTicks = App_getGTCTimerTicks();
605 /* Do Cache write-back for the chunk to be tranferred */
606 CSL_armR5CacheWb(txChunkAddr, size);
608 /* Set channel trigger and wait for completion */
609 CSL_REG32_WR(pSwTriggerReg, triggerMask);
611 /* Wait for the transfer to complete in polling mode */
612 while(1U)
613 {
614 volatile uint64_t intrStatusReg;
615 intrStatusReg = CSL_REG64_RD(pintrStatusReg);
616 /* Check whether the interrupt status Reg is set - which indicates the
617 * tranfser completion of appTestObj->numBytes */
618 if(intrStatusReg & intrMask)
619 {
620 /* Clear interrupt */
621 CSL_REG64_WR(intrClearReg, intrMask);
622 break;
623 }
624 }
626 /* Wait device to be ready after write operation */
627 uint32_t timeOutVal = OSPI_FLASH_WRITE_TIMEOUT;
628 uint32_t retry = OSPI_FLASH_WRITE_TIMEOUT;
629 volatile uint32_t delay = OSPI_FLASH_CHECK_IDLE_DELAY;
630 uint8_t status = 0xFF;
631 uint32_t regVal;
632 while (timeOutVal != 0U)
633 {
634 (void)CSL_ospiCmdRead(baseAddr, OSPI_FLASH_CMD_RDSR, 1U);
635 while(!CSL_ospiIsIdle(baseAddr));
636 CSL_ospiFlashExecCmd(baseAddr);
637 while(retry != 0U)
638 {
639 if(CSL_ospiFlashExecCmdComplete(baseAddr) == TRUE)
640 {
641 break;
642 }
643 while (delay > 0U)
644 {
645 delay = delay - 1U;
646 }
647 retry--;
648 }
649 while(!CSL_ospiIsIdle(baseAddr));
650 regVal = CSL_REG32_RD(&baseAddr->FLASH_RD_DATA_LOWER_REG);
651 (void)memcpy((void *)&status, (void *)(®Val), 1U);
652 if ((status & 1U) == 0U)
653 {
654 break;
655 }
656 timeOutVal--;
657 delay = OSPI_FLASH_CHECK_IDLE_DELAY;
658 while (delay > 0U)
659 {
660 delay = delay - 1U;
661 }
662 }
663 txStopTicks = App_getGTCTimerTicks();
665 appCounterObj->txStartTicks[tCnt] = txStartTicks;
666 appCounterObj->txStopTicks[tCnt] = 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);
687 }
689 static int32_t App_udmaOspiFlashRead(App_UdmaObj *appObj)
690 {
691 int32_t retVal = UDMA_SOK;
692 uint64_t pDesc = 0;
693 uint32_t triggerCnt, tCnt;
694 uint8_t *rxChunkAddr;
695 volatile uint32_t offset;
696 /* Use local variables in real-time loop for optimized performance */
697 volatile uint32_t *pSwTriggerReg;
698 uint32_t triggerMask;
699 uint32_t rxStartTicks, rxStopTicks;
700 App_UdmaTestObj *appTestObj = &appObj->appTestObj;
701 App_UdmaChObj *appChObj = &appObj->appChObj;
702 App_UdmaTrObj *appTrObj = &appChObj->appTrObj;
703 App_UdmaCounterObj *appCounterObj = &appObj->appCounterObj;
704 Udma_ChHandle chHandle = appChObj->chHandle;
705 uint8_t *rxBuf = &gUdmaTestRxBuf[0U];
706 const uint16_t size = appTestObj->numBytes;
707 const uint16_t totalSize = appObj->totalNumBytes;
708 volatile uint64_t *pintrStatusReg = appTrObj->trEventPrms.intrStatusReg;
709 uint64_t intrMask = appTrObj->trEventPrms.intrMask;
710 volatile uint64_t *intrClearReg = appTrObj->trEventPrms.intrClearReg;
711 uint8_t *trpdMem = appChObj->trpdMem;
713 App_udmaTrObjInitRead(appTestObj, appTrObj);
715 /* Get SW trigger register for easy access */
716 triggerMask = ((uint32_t)1U << (appTrObj->trigger - 1U));
717 pSwTriggerReg = (volatile uint32_t *) Udma_chGetSwTriggerRegister(chHandle);
718 if(NULL == pSwTriggerReg)
719 {
720 App_print("\n [Error] Channel trigger register get failed!!\n");
721 }
723 /* Submit TRPD to channels */
724 App_udmaTrpdInit(appTrObj, appChObj);
725 retVal = Udma_ringQueueRaw(
726 Udma_chGetFqRingHandle(chHandle),
727 (uint64_t) Udma_appVirtToPhyFxn(trpdMem, 0U, NULL));
728 if(UDMA_SOK != retVal)
729 {
730 App_print("\n [Error] Channel queue failed!!\n");
731 }
733 if(UDMA_SOK == retVal)
734 {
735 /* Set number of times to trigger RX transfer */
736 triggerCnt = UDMA_TEST_XFER_CNT * UDMA_TEST_XFER_REPEAT_CNT_0 * UDMA_TEST_XFER_REPEAT_CNT_1;
737 for(tCnt = 0U; tCnt < triggerCnt; tCnt++)
738 {
739 /* Calculate start of address to do cacheOps */
740 offset = tCnt * size;
741 offset = offset % totalSize;
742 rxChunkAddr = rxBuf + offset;
744 rxStartTicks = App_getGTCTimerTicks();
746 /* Set channel trigger and wait for completion */
747 CSL_REG32_WR(pSwTriggerReg, triggerMask);
749 /* Wait for the transfer to complete in polling mode */
750 while(1U)
751 {
752 volatile uint64_t intrStatusReg;
753 intrStatusReg = CSL_REG64_RD(pintrStatusReg);
754 /* Check whether the interrupt status Reg is set - which indicates the
755 * transfer completion of appTestObj->numBytes */
756 if(intrStatusReg & intrMask)
757 {
758 /* Clear interrupt */
759 CSL_REG64_WR(intrClearReg, intrMask);
760 break;
761 }
762 }
763 /* Do Cache invalidate for the received chunk */
764 CSL_armR5CacheInv(rxChunkAddr, size);
766 rxStopTicks = App_getGTCTimerTicks();
768 appCounterObj->rxStartTicks[tCnt] = rxStartTicks;
769 appCounterObj->rxStopTicks[tCnt] = rxStopTicks;
770 }
771 }
772 if(UDMA_SOK == retVal)
773 {
774 /* wait for response to be received in completion queue */
775 while(1)
776 {
777 retVal =
778 Udma_ringDequeueRaw(Udma_chGetCqRingHandle(chHandle), &pDesc);
779 if(UDMA_SOK == retVal)
780 {
781 break;
782 }
783 }
785 /* Sanity check - Check returned descriptor pointer & TR response status*/
786 retVal = App_udmaTrpdSanityCheck(appChObj, pDesc);
787 }
789 return (retVal);
790 }
792 static int32_t App_init(App_UdmaObj *appObj)
793 {
794 int32_t retVal;
795 Udma_InitPrms initPrms;
796 uint32_t instId;
797 App_UdmaChObj *appChObj = &appObj->appChObj;
798 App_UdmaTrObj *appTrObj = &appChObj->appTrObj;
799 App_UdmaTestObj *appTestObj = &appObj->appTestObj;
800 App_UdmaCounterObj *appCounterObj = &appObj->appCounterObj;
801 Udma_DrvHandle drvHandle = &appObj->drvObj;
803 #if defined (SOC_AM64X)
804 /* Use Block Copy DMA for AM64x */
805 instId = UDMA_INST_ID_BCDMA_0;
806 #else
807 /* Use MCU NAVSS for MCU domain cores. Rest all cores uses Main NAVSS */
808 #if defined (BUILD_MCU1_0) || defined (BUILD_MCU1_1)
809 instId = UDMA_INST_ID_MCU_0;
810 #else
811 instId = UDMA_INST_ID_MAIN_0;
812 #endif
813 #endif
814 /* UDMA driver init */
815 UdmaInitPrms_init(instId, &initPrms);
816 initPrms.virtToPhyFxn = &Udma_appVirtToPhyFxn;
817 initPrms.phyToVirtFxn = &Udma_appPhyToVirtFxn;
818 initPrms.printFxn = &App_print;
819 retVal = Udma_init(drvHandle, &initPrms);
820 if(UDMA_SOK != retVal)
821 {
822 App_print("\n [Error] UDMA init failed!!\n");
823 }
825 /* Init channel parameters */
826 appChObj->chHandle = &appChObj->chObj;
827 appChObj->drvHandle = drvHandle;
828 appChObj->txRingMem = &gTxRingMem[0U];
829 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
830 appChObj->txCompRingMem = &gTxCompRingMem[0U];
831 #endif
832 appChObj->trpdMem = &gUdmaTrpdMem[0U];
834 /* Init TR parameters */
835 appTrObj->trEventHandle = NULL;
836 appTrObj->drvHandle = drvHandle;
838 memset((void *)&appCounterObj->txStartTicks, 0, sizeof(appCounterObj->txStartTicks));
839 memset((void *)&appCounterObj->txStopTicks, 0, sizeof(appCounterObj->txStopTicks));
840 memset((void *)&appCounterObj->txTotalTicks, 0, sizeof(appCounterObj->txTotalTicks));
841 memset((void *)&appCounterObj->txElapsedTime, 0, sizeof(appCounterObj->txElapsedTime));
842 memset((void *)&appCounterObj->rxStartTicks, 0, sizeof(appCounterObj->rxStartTicks));
843 memset((void *)&appCounterObj->rxStopTicks, 0, sizeof(appCounterObj->rxStopTicks));
844 memset((void *)&appCounterObj->rxTotalTicks, 0, sizeof(appCounterObj->rxTotalTicks));
845 memset((void *)&appCounterObj->rxElapsedTime, 0, sizeof(appCounterObj->rxElapsedTime));
847 if(UDMA_SOK == retVal)
848 {
849 retVal = App_ospiFlashInit(appTestObj->clk);
850 }
852 return (retVal);
853 }
856 static int32_t App_deinit(App_UdmaObj *appObj)
857 {
858 int32_t retVal;
859 Udma_DrvHandle drvHandle = &appObj->drvObj;
861 OspiFlash_ospiClose(FALSE);
863 retVal = Udma_deinit(drvHandle);
864 if(UDMA_SOK != retVal)
865 {
866 App_print("\n [Error] UDMA deinit failed!!\n");
867 }
869 return (retVal);
870 }
871 static int32_t App_create(App_UdmaObj *appObj)
872 {
873 int32_t retVal = UDMA_SOK;
874 uint32_t chType;
875 Udma_ChPrms chPrms;
876 Udma_ChTxPrms txPrms;
877 Udma_ChRxPrms rxPrms;
878 Udma_EventHandle eventHandle;
879 App_UdmaChObj *appChObj = &appObj->appChObj;
880 App_UdmaTrObj *appTrObj = &appChObj->appTrObj;
881 Udma_ChHandle chHandle = appChObj->chHandle;
882 Udma_DrvHandle drvHandle = &appObj->drvObj;
884 if(UDMA_SOK == retVal)
885 {
886 /* Init channel parameters */
887 chType = UDMA_CH_TYPE_TR_BLK_COPY;
888 UdmaChPrms_init(&chPrms, chType);
889 chPrms.fqRingPrms.ringMem = appChObj->txRingMem;
890 chPrms.fqRingPrms.ringMemSize = UDMA_TEST_APP_RING_MEM_SIZE;
891 chPrms.fqRingPrms.elemCnt = UDMA_TEST_APP_RING_ENTRIES;
892 #if (UDMA_SOC_CFG_RA_NORMAL_PRESENT == 1)
893 chPrms.cqRingPrms.ringMem = appChObj->txCompRingMem;
894 chPrms.cqRingPrms.ringMemSize = UDMA_TEST_APP_RING_MEM_SIZE;
895 chPrms.cqRingPrms.elemCnt = UDMA_TEST_APP_RING_ENTRIES;
896 #endif
898 /* Open channel for block copy */
899 retVal = Udma_chOpen(drvHandle, chHandle, chType, &chPrms);
900 if(UDMA_SOK != retVal)
901 {
902 App_print("\n [Error] UDMA channel open failed!!\n");
903 }
904 }
906 if(UDMA_SOK == retVal)
907 {
908 /* Config TX channel */
909 UdmaChTxPrms_init(&txPrms, chType);
910 retVal = Udma_chConfigTx(chHandle, &txPrms);
911 if(UDMA_SOK != retVal)
912 {
913 App_print("\n [Error] UDMA TX channel config failed!!\n");
914 }
915 }
917 if(UDMA_SOK == retVal)
918 {
919 /* Config RX channel - which is implicitly paired to TX channel in
920 * block copy mode */
921 UdmaChRxPrms_init(&rxPrms, chType);
922 retVal = Udma_chConfigRx(chHandle, &rxPrms);
923 if(UDMA_SOK != retVal)
924 {
925 App_print("\n [Error] UDMA RX channel config failed!!\n");
926 }
927 }
929 if(UDMA_SOK == retVal)
930 {
931 /* Register TR event */
932 eventHandle = &appTrObj->trEventObj;
933 UdmaEventPrms_init(&appTrObj->trEventPrms);
934 appTrObj->trEventPrms.eventType = UDMA_EVENT_TYPE_TR;
935 appTrObj->trEventPrms.eventMode = UDMA_EVENT_MODE_SHARED;
936 appTrObj->trEventPrms.chHandle = chHandle;
937 appTrObj->trEventPrms.masterEventHandle = NULL;
938 appTrObj->trEventPrms.eventCb = NULL;
939 appTrObj->trEventPrms.appData = appChObj;
940 retVal = Udma_eventRegister(drvHandle, eventHandle, &appTrObj->trEventPrms);
941 if(UDMA_SOK != retVal)
942 {
943 App_print("\n [Error] UDMA TR event register failed!!\n");
944 }
945 else
946 {
947 appTrObj->trEventHandle = eventHandle;
948 }
949 }
951 if(UDMA_SOK == retVal)
952 {
953 /* Channel enable */
954 retVal = Udma_chEnable(chHandle);
955 if(UDMA_SOK != retVal)
956 {
957 App_print("\n [Error] UDMA channel enable failed!!\n");
958 }
959 }
961 return (retVal);
962 }
964 static int32_t App_delete(App_UdmaObj *appObj)
965 {
966 int32_t retVal, tempRetVal;
967 uint64_t pDesc;
968 App_UdmaChObj *appChObj = &appObj->appChObj;
969 App_UdmaTrObj *appTrObj = &appChObj->appTrObj;
970 Udma_ChHandle chHandle = appChObj->chHandle;
974 retVal = Udma_chDisable(chHandle, UDMA_DEFAULT_CH_DISABLE_TIMEOUT);
975 if(UDMA_SOK != retVal)
976 {
977 App_print("\n [Error] UDMA channel disable failed!!\n");
978 }
980 /* Flush any pending request from the free queue */
981 while(1)
982 {
983 tempRetVal = Udma_ringFlushRaw(
984 Udma_chGetFqRingHandle(chHandle), &pDesc);
985 if(UDMA_ETIMEOUT == tempRetVal)
986 {
987 break;
988 }
989 }
991 /* Unregister all events */
992 if(NULL != appTrObj->trEventHandle)
993 {
994 retVal += Udma_eventUnRegister(appTrObj->trEventHandle);
995 if(UDMA_SOK != retVal)
996 {
997 App_print("\n [Error] UDMA event unregister failed!!\n");
998 }
999 appTrObj->trEventHandle = NULL;
1000 }
1002 retVal += Udma_chClose(chHandle);
1003 if(UDMA_SOK != retVal)
1004 {
1005 App_print("\n [Error] UDMA channel close failed!!\n");
1006 }
1008 return (retVal);
1009 }
1011 static void App_udmaTrpdInit(App_UdmaTrObj *appTrObj, App_UdmaChObj *appChObj)
1012 {
1013 CSL_UdmapCppi5TRPD *pTrpd = (CSL_UdmapCppi5TRPD *) appChObj->trpdMem;
1014 CSL_UdmapTR15 *pTr = (CSL_UdmapTR15 *)(appChObj->trpdMem + sizeof(CSL_UdmapTR15));
1015 uint32_t *pTrResp = (uint32_t *) (appChObj->trpdMem + (sizeof(CSL_UdmapTR15) * 2U));
1016 uint32_t cqRingNum = Udma_chGetCqRingNum(appChObj->chHandle);
1018 /* Make TRPD */
1019 UdmaUtils_makeTrpd(pTrpd, UDMA_TR_TYPE_15, 1U, cqRingNum);
1021 /* Setup TR */
1022 pTr->flags = CSL_FMK(UDMAP_TR_FLAGS_TYPE, CSL_UDMAP_TR_FLAGS_TYPE_4D_BLOCK_MOVE_REPACKING_INDIRECTION);
1023 pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_STATIC, 0U);
1024 pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_EOL, appTrObj->eolType);
1025 pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_EVENT_SIZE, appTrObj->eventSize);
1026 pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0, appTrObj->trigger);
1027 pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE);
1028 pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0_TYPE, appTrObj->triggerType);
1029 pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1_TYPE, CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL);
1030 pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_CMD_ID, 0x25U);
1031 pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_SA_INDIRECT, 0U);
1032 pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_DA_INDIRECT, 0U);
1033 pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_EOP, 1U);
1035 pTr->icnt0 = appTrObj->icnt[0];
1036 pTr->icnt1 = appTrObj->icnt[1];
1037 pTr->icnt2 = appTrObj->icnt[2];
1038 pTr->icnt3 = appTrObj->icnt[3];
1039 pTr->addr = (uint64_t) Udma_appVirtToPhyFxn(appTrObj->addr, 0U, NULL);
1040 pTr->fmtflags = 0x00000000U; /* Linear addressing, 1 byte per elem.
1041 Replace with CSL-FL API */
1043 pTr->dicnt0 = appTrObj->dicnt[0];
1044 pTr->dicnt1 = appTrObj->dicnt[1];
1045 pTr->dicnt2 = appTrObj->dicnt[2];
1046 pTr->dicnt3 = appTrObj->dicnt[3];
1047 pTr->daddr = (uint64_t) Udma_appVirtToPhyFxn(appTrObj->daddr, 0U, NULL);
1049 pTr->dim1 = appTrObj->dim[0];
1050 pTr->dim2 = appTrObj->dim[1];
1051 pTr->dim3 = appTrObj->dim[2];
1052 pTr->ddim1 = appTrObj->ddim[0];
1053 pTr->ddim2 = appTrObj->ddim[1];
1054 pTr->ddim3 = appTrObj->ddim[2];
1056 /* Clear TR response memory */
1057 *pTrResp = 0xFFFFFFFFU;
1059 /* Writeback cache */
1060 Udma_appUtilsCacheWb(appChObj->trpdMem, UDMA_TEST_APP_TRPD_SIZE_ALIGN);
1062 return;
1063 }
1065 static int32_t App_udmaTrpdSanityCheck(App_UdmaChObj *appChObj, uint64_t pDesc)
1066 {
1067 int32_t retVal = UDMA_SOK;
1068 uint32_t *pTrResp, trRespStatus;
1069 uint8_t *trpdMem = appChObj->trpdMem;
1071 /* Check returned descriptor pointer */
1072 if(((uint64_t) Udma_appPhyToVirtFxn(pDesc, 0U, NULL)) != ((uint64_t) trpdMem))
1073 {
1074 App_print("\n [Error] TR descriptor pointer returned doesn't "
1075 "match the submitted address!!\n");
1076 retVal = UDMA_EFAIL;
1077 }
1079 if(UDMA_SOK == retVal)
1080 {
1081 /* Invalidate cache */
1082 Udma_appUtilsCacheInv(trpdMem, UDMA_TEST_APP_TRPD_SIZE_ALIGN);
1084 /* check TR response status */
1085 pTrResp = (uint32_t *) (trpdMem + (sizeof(CSL_UdmapTR15) * 2U));
1086 trRespStatus = CSL_FEXT(*pTrResp, UDMAP_TR_RESPONSE_STATUS_TYPE);
1087 if(trRespStatus != CSL_UDMAP_TR_RESPONSE_STATUS_COMPLETE)
1088 {
1089 App_print("\n [Error] TR Response not completed!!\n");
1090 retVal = UDMA_EFAIL;
1091 }
1092 }
1094 return (retVal);
1095 }
1097 static inline void App_udmaTrObjInitRead(App_UdmaTestObj *appTestObj, App_UdmaTrObj *appTrObj)
1098 {
1099 appTrObj->trigger = CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL0;
1100 /* Set interrupt after transferring icnt0 bytes */
1101 appTrObj->eventSize = CSL_UDMAP_TR_FLAGS_EVENT_SIZE_ICNT1_DEC;
1102 /* Transfer icnt0 bytes after a trigger */
1103 appTrObj->triggerType = CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ICNT1_DEC;
1104 /* EOL boundaries for each icnt0 bytes */
1105 appTrObj->eolType = CSL_UDMAP_TR_FLAGS_EOL_ICNT0;
1107 /* No. of bytes to tansfer after getting interrupt (in this case)*/
1108 appTrObj->icnt[0] = appTestObj->numBytes;
1109 /* No. of times to repeat the tansfer of inct0 bytes */
1110 appTrObj->icnt[1] = UDMA_TEST_XFER_CNT;
1111 /* No. of times to repeat the tansfer of inct0*icnt1 bytes */
1112 appTrObj->icnt[2] = UDMA_TEST_XFER_REPEAT_CNT_0;
1113 /* No. of times to repeat the tansfer of inct0*icnt1*inct2 bytes */
1114 appTrObj->icnt[3] = UDMA_TEST_XFER_REPEAT_CNT_1;
1115 /* similar destination params */
1116 appTrObj->dicnt[0] = appTestObj->numBytes;
1117 appTrObj->dicnt[1] = UDMA_TEST_XFER_CNT;
1118 appTrObj->dicnt[2] = UDMA_TEST_XFER_REPEAT_CNT_0;
1119 appTrObj->dicnt[3] = UDMA_TEST_XFER_REPEAT_CNT_1;
1121 /* DIM1: Offset for source OSPI data address after transferring inct0 bytes */
1122 appTrObj->dim[0] = appTrObj->icnt[0]; /* Use inct0 bytes so that successive triger tranfers the next icnt0 bytes */
1123 /* Offset for source OSPI data address after transferring inct0*inct1 bytes */
1124 appTrObj->dim[1] = 0U; /* To restart from the buffer origin */
1125 /* Offset for source OSPI data address after transferring inct0*inct1*inct2 bytes */
1126 appTrObj->dim[2] = 0U; /* To restart from the buffer origin */
1128 /* Similar offset for destination RX buffer address */
1129 appTrObj->ddim[0] = appTrObj->dicnt[0];
1130 appTrObj->ddim[1] = 0U;
1131 appTrObj->ddim[2] = 0U;
1133 /* Source Address - OSPI Data address */
1134 appTrObj->addr = gUdmaTestOspiFlashDataAddr;
1135 /* Destination Address - RX Buffer */
1136 appTrObj->daddr = &gUdmaTestRxBuf[0U];;
1138 return;
1139 }
1141 static inline void App_udmaTrObjInitWrite(App_UdmaTestObj *appTestObj, App_UdmaTrObj *appTrObj)
1142 {
1143 appTrObj->trigger = CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL0;
1144 /* Set interrupt after transferring icnt0 bytes */
1145 appTrObj->eventSize = CSL_UDMAP_TR_FLAGS_EVENT_SIZE_ICNT1_DEC;
1146 /* Transfer icnt0 bytes after a trigger */
1147 appTrObj->triggerType = CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ICNT1_DEC;
1148 /* EOL boundaries for each icnt0 bytes */
1149 appTrObj->eolType = CSL_UDMAP_TR_FLAGS_EOL_ICNT0;
1151 /* No. of bytes to tansfer after getting interrupt(in this case) */
1152 appTrObj->icnt[0] = appTestObj->numBytes;
1153 /* No. of times to repeat the tansfer of inct0 bytes */
1154 appTrObj->icnt[1] = UDMA_TEST_XFER_CNT;
1155 /* No. of times to repeat the tansfer of inct0*icnt1 bytes */
1156 appTrObj->icnt[2] = 1U;
1157 /* No. of times to repeat the tansfer of inct0*icnt1*inct2 bytes */
1158 appTrObj->icnt[3] = 1U;
1159 /* similar destination params */
1160 appTrObj->dicnt[0] = appTestObj->numBytes;
1161 appTrObj->dicnt[1] = UDMA_TEST_XFER_CNT;
1162 appTrObj->dicnt[2] = 1U;
1163 appTrObj->dicnt[3] = 1U;
1165 /* DIM1- Offset for source TX Buffer address after transferring inct0 bytes */
1166 appTrObj->dim[0] = appTrObj->icnt[0] ; /* inct0 bytes - so that successive triger tranfers the next icnt0 bytes */
1167 /* DIM2 - Offset for source TX Buffer address after transferring inct0*inct1 bytes */
1168 appTrObj->dim[1] = 0U; /* To restart from the buffer origin */
1169 /* DIM3 - Offset for source TX Buffer address after transferring inct0*inct1*inct2 bytes */
1170 appTrObj->dim[2] = 0U; /* To restart from the buffer origin */
1172 /* DDIM1/DDIM2/DDIM3 - Similar offset for destination RX buffer address */
1173 appTrObj->ddim[0] = appTrObj->dicnt[0];
1174 appTrObj->ddim[1] = 0U;
1175 appTrObj->ddim[2] = 0U;
1177 /* Source Address - TX Buffer */
1178 appTrObj->addr = &gUdmaTestTxBuf[0U];
1179 /* Destination Address - OSPI Data address */
1180 appTrObj->daddr = gUdmaTestOspiFlashDataAddr;
1182 return;
1183 }
1185 static void App_printPerfResults(App_UdmaObj *appObj)
1186 {
1187 App_UdmaCounterObj *appCounterObj = &appObj->appCounterObj;
1188 App_UdmaTestObj *appTestObj = &appObj->appTestObj;
1189 uint32_t tCnt;
1190 uint32_t triggerCnt;
1192 triggerCnt = UDMA_TEST_XFER_CNT;
1193 for(tCnt = 0U; tCnt < triggerCnt; tCnt++)
1194 {
1195 appCounterObj->txTotalTicks[tCnt] = appCounterObj->txStopTicks[tCnt] - appCounterObj->txStartTicks[tCnt] - getTicksDelay;
1196 appCounterObj->txTotalTicks[triggerCnt] += appCounterObj->txTotalTicks[tCnt];
1197 appCounterObj->txElapsedTime[tCnt] = (appCounterObj->txTotalTicks[tCnt]*1000000000U)/(uint64_t)OSPI_FLASH_GTC_CLK_FREQ;
1199 App_printNum("\n OSPI Write %d", appTestObj->numBytes);
1200 App_printNum(" bytes in %d", (uint32_t)appCounterObj->txElapsedTime[tCnt]);
1201 App_print("ns.");
1202 }
1204 /* Print average time */
1205 appCounterObj->txTotalTicks[triggerCnt] = appCounterObj->txTotalTicks[triggerCnt]/triggerCnt;
1206 appCounterObj->txElapsedTime[triggerCnt] = (appCounterObj->txTotalTicks[triggerCnt]*1000000000U)/(uint64_t)OSPI_FLASH_GTC_CLK_FREQ;
1207 App_printNum("\n\n Average time for OSPI Write %d", appTestObj->numBytes);
1208 App_printNum(" bytes = %d", (uint32_t)appCounterObj->txElapsedTime[triggerCnt]);
1209 App_print("ns.");
1212 triggerCnt = UDMA_TEST_XFER_CNT * UDMA_TEST_XFER_REPEAT_CNT_0 * UDMA_TEST_XFER_REPEAT_CNT_1;
1213 for(tCnt = 0U; tCnt < triggerCnt; tCnt++)
1214 {
1215 appCounterObj->rxTotalTicks[tCnt] = appCounterObj->rxStopTicks[tCnt] - appCounterObj->rxStartTicks[tCnt] - getTicksDelay;
1216 appCounterObj->rxTotalTicks[triggerCnt] += appCounterObj->rxTotalTicks[tCnt];
1217 appCounterObj->rxElapsedTime[tCnt] = (appCounterObj->rxTotalTicks[tCnt]*1000000000U)/(uint64_t)OSPI_FLASH_GTC_CLK_FREQ;
1219 App_printNum("\n OSPI Read %d", appTestObj->numBytes);
1220 App_printNum(" bytes in %d", (uint32_t)appCounterObj->rxElapsedTime[tCnt]);
1221 App_print("ns.");
1222 }
1224 appCounterObj->rxTotalTicks[triggerCnt] = appCounterObj->rxTotalTicks[triggerCnt]/triggerCnt;
1225 appCounterObj->rxElapsedTime[triggerCnt] = (appCounterObj->rxTotalTicks[triggerCnt]*1000000000U)/(uint64_t)OSPI_FLASH_GTC_CLK_FREQ;
1226 App_printNum("\n\n Average time for OSPI Read %d", appTestObj->numBytes);
1227 App_printNum(" bytes = %d", (uint32_t)appCounterObj->rxElapsedTime[triggerCnt]);
1228 App_print("ns. \n\n");
1230 return;
1231 }
1233 void App_print(const char *str)
1234 {
1235 UART_printf("%s", str);
1236 if(TRUE == Udma_appIsPrintSupported())
1237 {
1238 printf("%s", str);
1239 }
1241 return;
1242 }
1244 static void App_printNum(const char *str, uint32_t num)
1245 {
1246 static char printBuf[200U];
1248 snprintf(printBuf, 200U, str, num);
1249 UART_printf("%s", printBuf);
1251 if(TRUE == Udma_appIsPrintSupported())
1252 {
1253 printf("%s", printBuf);
1254 }
1256 return;
1257 }
1259 int32_t App_setGTCClk(uint32_t moduleId,
1260 uint32_t clkId,
1261 uint64_t clkRateHz)
1262 {
1263 int32_t retVal;
1264 uint64_t currClkFreqHz;
1266 retVal = Sciclient_pmGetModuleClkFreq(moduleId,
1267 clkId,
1268 &currClkFreqHz,
1269 SCICLIENT_SERVICE_WAIT_FOREVER);
1270 if ((retVal == CSL_PASS) &&
1271 (currClkFreqHz != clkRateHz))
1272 {
1273 retVal = OspiFlash_ClkRateSet(moduleId, clkId, clkRateHz);
1274 }
1276 /* Enable GTC */
1277 HW_WR_REG32(CSL_GTC0_GTC_CFG1_BASE + 0x0U, 0x1);
1279 /* Measure and store the time spent to do a getTime operation */
1280 getTicksDelay = App_getGTCTimerTicks();
1281 getTicksDelay = App_getGTCTimerTicks() - getTicksDelay;
1282 OSPI_FLASH_log("\n Time taken to read GTC Timer ticks = %d ns (%d ticks) ",
1283 (uint32_t)((getTicksDelay*1000000000U)/(uint64_t)OSPI_FLASH_GTC_CLK_FREQ),
1284 (uint32_t)getTicksDelay);
1286 return (retVal);
1287 }
1289 static int32_t App_ospiFlashInit(uint32_t clk)
1290 {
1291 int32_t status = UDMA_SOK;
1293 status += OspiFlash_ospiConfigClk(clk);
1295 status += OspiFlash_ospiOpen(OSPI_FLASH_WRITE_TIMEOUT, OSPI_FLASH_CHECK_IDLE_DELAY, FALSE);
1297 status += OspiFlash_ospiEnableDDR(FALSE);
1299 status += OspiFlash_ospiSetOpcode();
1301 status += OspiFlash_ospiConfigPHY(clk, FALSE);
1303 return (status);
1304 }
1306 static int32_t App_ospiFlashStart(uint32_t numBytes)
1307 {
1308 int32_t retVal = UDMA_SOK;
1309 const CSL_ospi_flash_cfgRegs *baseAddr = (const CSL_ospi_flash_cfgRegs *)(OSPI_FLASH_CONFIG_REG_BASE_ADDR);
1311 retVal = OspiFlash_ospiEraseBlk(numBytes, FALSE);
1313 OspiFlash_ospiXferIntrInit(FALSE);
1315 /* Enable PHY pipeline mode */
1316 CSL_ospiPipelinePhyEnable(baseAddr, TRUE);
1318 return (retVal);
1319 }