1 /*
2 * Copyright (c) Texas Instruments Incorporated 2018-2019
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 pcie_udma.c
35 *
36 * \brief UDMA memory copy sample application performing block copy using
37 * Type 15 Transfer Record (TR15) using Transfer Record Packet
38 * Descriptor (TRPD).
39 *
40 * Requirement: DOX_REQ_TAG(PRSDK-3851)
41 */
43 /* ========================================================================== */
44 /* Include Files */
45 /* ========================================================================== */
46 #ifdef QOS
47 #include "pcie_qos_sample.h"
48 #else
49 #include "pcie_sample.h"
50 #endif
51 #include "pcie_udma.h"
53 #include <stdio.h>
54 #include <ti/drv/udma/udma.h>
55 #include <ti/drv/sciclient/sciclient.h>
57 /* ========================================================================== */
58 /* Macros & Typedefs */
59 /* ========================================================================== */
61 /*
62 * Application test parameters
63 */
64 /** \brief Number of times to perform the memcpy operation */
65 #ifdef QOS
66 #define PCIE_TEST_APP_UDMA_LOOPS (10U)
67 #else
68 #define PCIE_TEST_APP_UDMA_LOOPS (1U)
69 #endif
70 /*
71 * Ring parameters
72 */
73 /** \brief Number of ring entries - we can prime this much memcpy operations */
74 #define PCIE_TEST_APP_RING_ENTRIES (1U)
75 /** \brief Size (in bytes) of each ring entry (Size of pointer - 64-bit) */
76 #define PCIE_TEST_APP_RING_ENTRY_SIZE (sizeof(uint64_t))
77 /** \brief Total ring memory */
78 #define PCIE_TEST_APP_RING_MEM_SIZE (PCIE_TEST_APP_RING_ENTRIES * \
79 PCIE_TEST_APP_RING_ENTRY_SIZE)
80 /**
81 * \brief UDMA TR packet descriptor memory.
82 * This contains the CSL_UdmapCppi5TRPD + Padding to sizeof(CSL_UdmapTR15) +
83 * one Type_15 TR (CSL_UdmapTR15) + one TR response of 4 bytes.
84 * Since CSL_UdmapCppi5TRPD is less than CSL_UdmapTR15, size is just two times
85 * CSL_UdmapTR15 for alignment.
86 */
87 #define PCIE_TEST_APP_TRPD_SIZE ((sizeof(CSL_UdmapTR15) * 2U) + 4U)
89 #if defined (__aarch64__)
90 // Timestamp for A53 core
91 #if defined (PCIE_SMP_ENABLE)
92 #include <ti/sysbios/timers/dmtimer/TimestampProvider.h>
93 #else
94 #include <ti/sysbios/family/arm/v8a/TimestampProvider.h>
95 #endif
96 #define TIMESTAMP_GETFREQ(x) TimestampProvider_getFreq(x)
97 #define TIMESTAMP_GET32() TimestampProvider_get32()
98 #else
99 // Timestamp for R5F core
100 #include <xdc/runtime/Timestamp.h>
101 #define TIMESTAMP_GETFREQ(x) Timestamp_getFreq(x)
102 #define TIMESTAMP_GET32() Timestamp_get32()
103 #endif
105 #ifdef QOS
106 #define LOGSIZE 4096
107 uint32_t readLatency[LOGSIZE] __attribute__ ((aligned (64)));
108 #ifdef __TI_ARM_V7R4__
109 #pragma DATA_SECTION(readLatency, ".statBuf")
110 #endif
111 extern unsigned int lowPriAddr[3];
112 #endif
113 uint32_t loop_counter = 0;
114 uint32_t t_overhead;
116 /* ========================================================================== */
117 /* Structure Declarations */
118 /* ========================================================================== */
120 struct QosSetup {
121 uint8_t priority;
122 uint8_t qosLevel;
123 uint8_t orderId;
124 uint8_t dmaPriority;
125 };
126 /* ========================================================================== */
127 /* Function Declarations */
128 /* ========================================================================== */
130 static int32_t pcieUdmaLoop (Udma_ChHandle chHandle,
131 void *src,
132 void *dst,
133 uint32_t length);
135 static int32_t pcieUdmaOneCopy (Udma_ChHandle chHandle,
136 void *destBuf,
137 void *srcBuf,
138 uint32_t length);
140 static void pcieUdmaEventDmaCb(Udma_EventHandle eventHandle,
141 uint32_t eventType,
142 void *appData);
143 static void pcieUdmaEventTdCb(Udma_EventHandle eventHandle,
144 uint32_t eventType,
145 void *appData);
147 static int32_t pcieUdmaInit(Udma_DrvHandle drvHandle);
148 static int32_t pcieUdmaDeinit(Udma_DrvHandle drvHandle);
150 static int32_t pcieUdmaCreate(Udma_DrvHandle drvHandle, Udma_ChHandle chHandle, struct QosSetup tx, struct QosSetup rx);
151 static int32_t pcieUdmaDelete(Udma_DrvHandle drvHandle, Udma_ChHandle chHandle);
153 static void pcieUdmaTrpdInit(Udma_ChHandle chHandle,
154 uint8_t *pTrpdMem,
155 const void *destBuf,
156 const void *srcBuf,
157 uint32_t length);
159 extern uint32_t get_clock(void);
161 #ifdef QOS
162 extern void printQosResults(uint32_t iteration, uint32_t dataArray[], uint32_t size);
163 #endif
164 /* ========================================================================== */
165 /* Global Variables */
166 /* ========================================================================== */
168 /*
169 * UDMA driver objects
170 */
171 struct Udma_DrvObj gUdmaDrvObj;
172 struct Udma_ChObj gUdmaChObj;
173 struct Udma_EventObj gUdmaCqEventObj;
174 struct Udma_EventObj gUdmaTdCqEventObj;
176 /*
177 * UDMA Memories
178 */
179 static uint8_t gTxRingMem[PCIE_TEST_APP_RING_MEM_SIZE] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
180 static uint8_t gTxCompRingMem[PCIE_TEST_APP_RING_MEM_SIZE] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
181 static uint8_t gTxTdCompRingMem[PCIE_TEST_APP_RING_MEM_SIZE] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
182 static uint8_t gUdmaTprdMem[PCIE_TEST_APP_TRPD_SIZE] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
184 #ifndef QOS
185 /* Source buffer */
186 static uint32_t gSrcBuf[PCIE_EXAMPLE_LINE_SIZE];
187 #endif
189 /* Semaphore to indicate transfer completion */
190 static SemaphoreP_Handle gUdmaAppDoneSem = NULL;
192 /* Global test pass/fail flag */
193 static volatile int32_t gUdmaAppResult = UDMA_SOK;
195 static struct QosSetup txQosSetup = {5, 2, 7, 3};
196 static struct QosSetup rxQosSetup = {6, 7, 9, 3};
198 #ifdef __aarch64__
199 #define CPU_FREQ (800000000u)
200 #else
201 /* R5 */
202 #define CPU_FREQ (400000000u)
203 #endif
205 /* ========================================================================== */
206 /* Function Definitions */
207 /* ========================================================================== */
209 /*
210 * UDMA memcpy test
211 */
212 int32_t pcieUdmaTest (void *pcieWindow, uint32_t windowSize)
213 {
214 int32_t retVal;
215 Sciclient_ConfigPrms_t sciClientCfg;
216 Udma_DrvHandle drvHandle = &gUdmaDrvObj;
217 Udma_ChHandle chHandle = &gUdmaChObj;
219 Sciclient_configPrmsInit(&sciClientCfg);
220 Sciclient_init(&sciClientCfg);
222 t_overhead = TIMESTAMP_GET32();
223 t_overhead = TIMESTAMP_GET32() - t_overhead;
225 retVal = pcieUdmaInit(drvHandle);
226 if(UDMA_SOK != retVal)
227 {
228 PCIE_logPrintf("[Error] UDMA App init failed!!\n");
229 }
231 PCIE_logPrintf("UDMA memcpy application started...\n");
233 if(UDMA_SOK == retVal)
234 {
235 retVal = pcieUdmaCreate(drvHandle, chHandle, txQosSetup, rxQosSetup);
236 if(UDMA_SOK != retVal)
237 {
238 PCIE_logPrintf("[Error] UDMA App create failed!!\n");
239 }
240 }
242 if(UDMA_SOK == retVal)
243 {
244 #ifndef QOS
245 retVal = pcieUdmaLoop(chHandle, gSrcBuf, pcieWindow, windowSize);
246 #else
247 /* PCIE VC0 read */
248 retVal = pcieUdmaLoop(chHandle, pcieWindow, (void *)lowPriAddr[0], windowSize);
249 #endif
250 if(UDMA_SOK != retVal)
251 {
252 PCIE_logPrintf("[Error] UDMA App memcpy test failed!!\n");
253 }
254 }
256 retVal += pcieUdmaDelete(drvHandle, chHandle);
257 if(UDMA_SOK != retVal)
258 {
259 PCIE_logPrintf("[Error] UDMA App delete failed!!\n");
260 }
262 retVal += pcieUdmaDeinit (drvHandle);
263 if(UDMA_SOK != retVal)
264 {
265 PCIE_logPrintf("[Error] UDMA App deinit failed!!\n");
266 }
268 if((UDMA_SOK == retVal) && (UDMA_SOK == gUdmaAppResult))
269 {
270 PCIE_logPrintf("UDMA memcpy using TR15 block copy Passed!!\n");
271 }
272 else
273 {
274 PCIE_logPrintf("UDMA memcpy using TR15 block copy Failed!!\n");
275 }
277 Sciclient_deinit();
279 return (retVal);
280 }
282 static int32_t pcieUdmaLoop (Udma_ChHandle chHandle, void *src, void *dst, uint32_t size)
283 {
284 int32_t retVal = UDMA_SOK;
285 uint32_t i;
286 uint8_t *srcBuf = (void *)src;
287 uint8_t *destBuf = (void *)dst;
289 /* Init buffers */
290 for(i = 0U; i < size; i++)
291 {
292 srcBuf[i] = i;
293 destBuf[i] = 0U;
294 }
295 /* Writeback source and destination buffer if not PCIE data space */
296 if ((uint32_t)src >= 0x20000000) {
297 CacheP_wb((void *)src, size);
298 }
299 if ((uint32_t)dst >= 0x20000000) {
300 CacheP_wb((void *)dst, size);
301 }
303 /* Perform UDMA memcpy */
304 for (i = 0; i < PCIE_TEST_APP_UDMA_LOOPS; i++)
305 {
306 retVal = pcieUdmaOneCopy (
307 chHandle,
308 destBuf,
309 srcBuf,
310 size);
311 if(UDMA_SOK != retVal)
312 {
313 break;
314 }
315 #ifdef QOS
316 printQosResults(i, readLatency, LOGSIZE);
317 #endif
318 }
319 #ifdef QOS
320 PCIE_logPrintf("Checking RC side readLatency buffer for the last iteration log if needed\n");
321 #endif
322 return (retVal);
323 }
325 static int32_t pcieUdmaOneCopy (Udma_ChHandle chHandle,
326 void *destBuf,
327 void *srcBuf,
328 uint32_t length)
329 {
330 int32_t retVal = UDMA_SOK;
331 uint32_t *pTrResp, trRespStatus;
332 uint64_t pDesc = 0;
333 uint8_t *tprdMem = &gUdmaTprdMem[0U];
334 uint32_t t_read;
335 #ifndef QOS
336 float speed;
337 #else
338 uint32_t loop = 0;
339 #endif
340 /* Update TR packet descriptor */
341 pcieUdmaTrpdInit(chHandle, tprdMem, destBuf, srcBuf, length);
343 /* Submit TRPD to channel */
344 t_read = TIMESTAMP_GET32();
345 retVal = Udma_ringQueueRaw(
346 Udma_chGetFqRingHandle(chHandle), (uint64_t) tprdMem);
347 if(UDMA_SOK != retVal)
348 {
349 PCIE_logPrintf("[Error] Channel queue failed!!\n");
350 }
352 #ifndef QOS
353 if(UDMA_SOK == retVal)
354 {
355 /* Wait for return descriptor in completion ring - this marks the
356 * transfer completion */
357 SemaphoreP_pend(gUdmaAppDoneSem, SemaphoreP_WAIT_FOREVER);
358 t_read = TIMESTAMP_GET32() - t_read - t_overhead;
359 /* Response received in completion queue */
360 speed = (float)length;
361 speed *= 8;
362 speed /= (((float)t_read)/CPU_FREQ);
363 speed /= 1000000;
364 PCIE_logPrintf("Speed: %d Mbps\n", (int)speed);
365 retVal = Udma_ringDequeueRaw(Udma_chGetCqRingHandle(chHandle), &pDesc);
366 if(UDMA_SOK != retVal)
367 {
368 PCIE_logPrintf("[Error] No descriptor after callback!!\n");
369 retVal = UDMA_EFAIL;
370 }
371 }
372 #else
373 if(UDMA_SOK == retVal)
374 {
375 #if defined (__TI_ARM_V7R4__)
376 asm (" cpsid if ");
377 #endif
378 /* The PCIE VC3 read with CPU is performed in the gap of UDMA transfer
379 The total read duration needs to be shorter than the gap */
380 while(loop < LOGSIZE) {
381 t_read = TIMESTAMP_GET32();
382 BARRIER
383 (void)*(unsigned volatile int*)(uintptr_t)(PCIE_WINDOW_MEM_BASE_VC3);
384 BARRIER
385 t_read = TIMESTAMP_GET32() - t_read - t_overhead;
386 readLatency[loop++] = t_read;
387 }
388 #if defined (__TI_ARM_V7R4__)
389 asm (" cpsie if ");
390 #endif
391 /* Wait for return descriptor in completion ring - this marks the
392 * transfer completion */
394 SemaphoreP_pend(gUdmaAppDoneSem, SemaphoreP_WAIT_FOREVER);
396 /* Response received in completion queue */
397 retVal = Udma_ringDequeueRaw(Udma_chGetCqRingHandle(chHandle), &pDesc);
398 if(UDMA_SOK != retVal)
399 {
400 PCIE_logPrintf("[Error] No descriptor after callback!!\n");
401 retVal = UDMA_EFAIL;
402 }
403 }
404 #endif
405 if(UDMA_SOK == retVal)
406 {
407 /*
408 * Sanity check
409 */
410 /* Check returned descriptor pointer */
411 if(pDesc != ((uint64_t) tprdMem))
412 {
413 PCIE_logPrintf("[Error] TR descriptor pointer returned doesn't "
414 "match the submitted address!!\n");
415 retVal = UDMA_EFAIL;
416 }
417 }
419 if(UDMA_SOK == retVal)
420 {
421 /* Invalidate cache */
422 CacheP_Inv(&gUdmaTprdMem[0U], PCIE_TEST_APP_TRPD_SIZE);
424 /* check TR response status */
425 pTrResp = (uint32_t *) (tprdMem + (sizeof(CSL_UdmapTR15) * 2U));
426 trRespStatus = CSL_FEXT(*pTrResp, UDMAP_TR_RESPONSE_STATUS_TYPE);
427 if(trRespStatus != CSL_UDMAP_TR_RESPONSE_STATUS_COMPLETE)
428 {
429 PCIE_logPrintf("[Error] TR Response not completed!!\n");
430 retVal = UDMA_EFAIL;
431 }
432 }
434 return (retVal);
435 }
437 static void pcieUdmaEventDmaCb(Udma_EventHandle eventHandle,
438 uint32_t eventType,
439 void *appData)
440 {
441 if(UDMA_EVENT_TYPE_DMA_COMPLETION == eventType)
442 {
443 SemaphoreP_post(gUdmaAppDoneSem);
444 }
445 else
446 {
447 gUdmaAppResult = UDMA_EFAIL;
448 }
450 return;
451 }
453 static void pcieUdmaEventTdCb(Udma_EventHandle eventHandle,
454 uint32_t eventType,
455 void *appData)
456 {
457 int32_t retVal;
458 CSL_UdmapTdResponse tdResp;
460 if(UDMA_EVENT_TYPE_TEARDOWN_PACKET == eventType)
461 {
462 /* Response received in Teardown completion queue */
463 retVal = Udma_chDequeueTdResponse(&gUdmaChObj, &tdResp);
464 if(UDMA_SOK != retVal)
465 {
466 /* [Error] No TD response after callback!! */
467 gUdmaAppResult = UDMA_EFAIL;
468 }
469 }
470 else
471 {
472 gUdmaAppResult = UDMA_EFAIL;
473 }
475 return;
476 }
478 static int32_t pcieUdmaInit(Udma_DrvHandle drvHandle)
479 {
480 int32_t retVal;
481 Udma_InitPrms initPrms;
482 uint32_t instId;
484 /* UDMA driver init */
485 #if defined (__aarch64__)
486 instId = UDMA_INST_ID_MAIN_0;
487 #else
488 #ifdef QOS
489 instId = UDMA_INST_ID_MAIN_0;
490 #else
491 instId = UDMA_INST_ID_MCU_0;
492 #endif
493 #endif
494 UdmaInitPrms_init(instId, &initPrms);
495 initPrms.printFxn = (Udma_PrintFxn)&PCIE_logPrintf;
496 retVal = Udma_init(drvHandle, &initPrms);
497 if(UDMA_SOK != retVal)
498 {
499 PCIE_logPrintf("[Error] UDMA init failed!!\n");
500 }
502 return (retVal);
503 }
505 static int32_t pcieUdmaDeinit (Udma_DrvHandle drvHandle)
506 {
507 int32_t retVal;
509 retVal = Udma_deinit(drvHandle);
510 if(UDMA_SOK != retVal)
511 {
512 PCIE_logPrintf("[Error] UDMA deinit failed!!\n");
513 }
515 return (retVal);
516 }
518 static int32_t pcieUdmaCreate(Udma_DrvHandle drvHandle, Udma_ChHandle chHandle, struct QosSetup txQosSetup, struct QosSetup rxQosSetup)
519 {
520 int32_t retVal = UDMA_SOK;
521 uint32_t chType;
522 Udma_ChPrms chPrms;
523 Udma_ChTxPrms txPrms;
524 Udma_ChRxPrms rxPrms;
525 Udma_EventHandle eventHandle;
526 Udma_EventPrms eventPrms;
527 SemaphoreP_Params semPrms;
529 SemaphoreP_Params_init(&semPrms);
530 gUdmaAppDoneSem = SemaphoreP_create(0, &semPrms);
531 if(NULL == gUdmaAppDoneSem)
532 {
533 PCIE_logPrintf("[Error] Sem create failed!!\n");
534 retVal = UDMA_EFAIL;
535 }
537 if(UDMA_SOK == retVal)
538 {
539 /* Init channel parameters */
540 chType = UDMA_CH_TYPE_TR_BLK_COPY;
541 UdmaChPrms_init(&chPrms, chType);
542 chPrms.fqRingPrms.ringMem = &gTxRingMem[0U];
543 chPrms.cqRingPrms.ringMem = &gTxCompRingMem[0U];
544 chPrms.tdCqRingPrms.ringMem = &gTxTdCompRingMem[0U];
545 chPrms.fqRingPrms.elemCnt = PCIE_TEST_APP_RING_ENTRIES;
546 chPrms.cqRingPrms.elemCnt = PCIE_TEST_APP_RING_ENTRIES;
547 chPrms.tdCqRingPrms.elemCnt = PCIE_TEST_APP_RING_ENTRIES;
549 /* Open channel for block copy */
550 retVal = Udma_chOpen(drvHandle, chHandle, chType, &chPrms);
551 if(UDMA_SOK != retVal)
552 {
553 PCIE_logPrintf("[Error] UDMA channel open failed!!\n");
554 }
555 }
557 if(UDMA_SOK == retVal)
558 {
559 /* Config TX channel */
560 UdmaChTxPrms_init(&txPrms, chType);
561 txPrms.busPriority = txQosSetup.priority;
562 txPrms.busQos = txQosSetup.qosLevel;
563 txPrms.busOrderId = txQosSetup.orderId;
564 txPrms.dmaPriority = txQosSetup.dmaPriority;
565 retVal = Udma_chConfigTx(chHandle, &txPrms);
566 if(UDMA_SOK != retVal)
567 {
568 PCIE_logPrintf("[Error] UDMA TX channel config failed!!\n");
569 }
570 }
572 if(UDMA_SOK == retVal)
573 {
574 /* Config RX channel - which is implicitly paired to TX channel in
575 * block copy mode */
576 UdmaChRxPrms_init(&rxPrms, chType);
577 rxPrms.busPriority = rxQosSetup.priority;
578 rxPrms.busQos = rxQosSetup.qosLevel;
579 rxPrms.busOrderId = rxQosSetup.orderId;
580 rxPrms.dmaPriority = rxQosSetup.dmaPriority;
581 retVal = Udma_chConfigRx(chHandle, &rxPrms);
582 if(UDMA_SOK != retVal)
583 {
584 PCIE_logPrintf("[Error] UDMA RX channel config failed!!\n");
585 }
586 }
588 if(UDMA_SOK == retVal)
589 {
590 /* Register ring completion callback */
591 eventHandle = &gUdmaCqEventObj;
592 UdmaEventPrms_init(&eventPrms);
593 eventPrms.eventType = UDMA_EVENT_TYPE_DMA_COMPLETION;
594 eventPrms.eventMode = UDMA_EVENT_MODE_SHARED;
595 eventPrms.chHandle = chHandle;
596 eventPrms.masterEventHandle = NULL;
597 eventPrms.eventCb = &pcieUdmaEventDmaCb;
598 retVal = Udma_eventRegister(drvHandle, eventHandle, &eventPrms);
599 if(UDMA_SOK != retVal)
600 {
601 PCIE_logPrintf("[Error] UDMA CQ event register failed!!\n");
602 }
603 }
605 if(UDMA_SOK == retVal)
606 {
607 /* Register teardown ring completion callback */
608 eventHandle = &gUdmaTdCqEventObj;
609 UdmaEventPrms_init(&eventPrms);
610 eventPrms.eventType = UDMA_EVENT_TYPE_TEARDOWN_PACKET;
611 eventPrms.eventMode = UDMA_EVENT_MODE_SHARED;
612 eventPrms.chHandle = chHandle;
613 eventPrms.masterEventHandle = &gUdmaCqEventObj;
614 eventPrms.eventCb = &pcieUdmaEventTdCb;
615 retVal = Udma_eventRegister(drvHandle, eventHandle, &eventPrms);
616 if(UDMA_SOK != retVal)
617 {
618 PCIE_logPrintf("[Error] UDMA Teardown CQ event register failed!!\n");
619 }
620 }
622 if(UDMA_SOK == retVal)
623 {
624 /* Channel enable */
625 retVal = Udma_chEnable(chHandle);
626 if(UDMA_SOK != retVal)
627 {
628 PCIE_logPrintf("[Error] UDMA channel enable failed!!\n");
629 }
630 }
632 return (retVal);
633 }
635 static int32_t pcieUdmaDelete(Udma_DrvHandle drvHandle, Udma_ChHandle chHandle)
636 {
637 int32_t retVal, tempRetVal;
638 uint64_t pDesc;
639 Udma_EventHandle eventHandle;
641 retVal = Udma_chDisable(chHandle, UDMA_DEFAULT_CH_DISABLE_TIMEOUT);
642 if(UDMA_SOK != retVal)
643 {
644 PCIE_logPrintf("[Error] UDMA channel disable failed!!\n");
645 }
647 /* Unregister master event at the end */
648 eventHandle = &gUdmaTdCqEventObj;
649 retVal += Udma_eventUnRegister(eventHandle);
650 eventHandle = &gUdmaCqEventObj;
651 retVal += Udma_eventUnRegister(eventHandle);
652 if(UDMA_SOK != retVal)
653 {
654 PCIE_logPrintf("[Error] UDMA event unregister failed!!\n");
655 }
657 /* Flush any pending request from the free queue */
658 while(1)
659 {
660 tempRetVal = Udma_ringFlushRaw(
661 Udma_chGetFqRingHandle(chHandle), &pDesc);
662 if(UDMA_ETIMEOUT == tempRetVal)
663 {
664 break;
665 }
666 }
668 retVal += Udma_chClose(chHandle);
669 if(UDMA_SOK != retVal)
670 {
671 PCIE_logPrintf("[Error] UDMA channel close failed!!\n");
672 }
674 if(gUdmaAppDoneSem != NULL)
675 {
676 SemaphoreP_delete(gUdmaAppDoneSem);
677 gUdmaAppDoneSem = NULL;
678 }
680 return (retVal);
681 }
683 static void pcieUdmaTrpdInit(Udma_ChHandle chHandle,
684 uint8_t *pTrpdMem,
685 const void *destBuf,
686 const void *srcBuf,
687 uint32_t length)
688 {
689 CSL_UdmapCppi5TRPD *pTrpd = (CSL_UdmapCppi5TRPD *) pTrpdMem;
690 CSL_UdmapTR15 *pTr = (CSL_UdmapTR15 *)(pTrpdMem + sizeof(CSL_UdmapTR15));
691 uint32_t *pTrResp = (uint32_t *) (pTrpdMem + (sizeof(CSL_UdmapTR15) * 2U));
692 uint32_t cqRingNum = Udma_chGetCqRingNum(chHandle);
693 uint32_t descType = CSL_UDMAP_CPPI5_PD_DESCINFO_DTYPE_VAL_TR;
695 /* Setup descriptor */
696 CSL_udmapCppi5SetDescType(pTrpd, descType);
697 CSL_udmapCppi5TrSetReload(pTrpd, 0U, 0U);
698 CSL_udmapCppi5SetPktLen(pTrpd, descType, 1U); /* Only one TR in TRPD */
699 CSL_udmapCppi5SetIds(pTrpd, descType, 0U, UDMA_DEFAULT_FLOW_ID); /* Flow ID and Packet ID */
700 CSL_udmapCppi5SetSrcTag(pTrpd, 0x0000); /* Not used */
701 CSL_udmapCppi5SetDstTag(pTrpd, 0x0000); /* Not used */
702 CSL_udmapCppi5TrSetEntryStride(
703 pTrpd, CSL_UDMAP_CPPI5_TRPD_PKTINFO_RECSIZE_VAL_64B);
704 CSL_udmapCppi5SetReturnPolicy(
705 pTrpd,
706 descType,
707 CSL_UDMAP_CPPI5_PD_PKTINFO2_RETPOLICY_VAL_ENTIRE_PKT, /* Don't care for TR */
708 CSL_UDMAP_CPPI5_PD_PKTINFO2_EARLYRET_VAL_NO,
709 CSL_UDMAP_CPPI5_PD_PKTINFO2_RETPUSHPOLICY_VAL_TO_TAIL,
710 cqRingNum);
712 /* Setup TR */
713 pTr->flags = CSL_FMK(UDMAP_TR_FLAGS_TYPE, 15) |
714 CSL_FMK(UDMAP_TR_FLAGS_STATIC, 0U) |
715 CSL_FMK(UDMAP_TR_FLAGS_EOL, 0U) | /* NA */
716 CSL_FMK(UDMAP_TR_FLAGS_EVENT_SIZE, CSL_UDMAP_TR_FLAGS_EVENT_SIZE_COMPLETION)|
717 CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE) |
718 CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0_TYPE, CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL) |
719 CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE) |
720 CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1_TYPE, CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL) |
721 CSL_FMK(UDMAP_TR_FLAGS_CMD_ID, 0x25U) | /* This will come back in TR response */
722 CSL_FMK(UDMAP_TR_FLAGS_SA_INDIRECT, 0U) |
723 CSL_FMK(UDMAP_TR_FLAGS_DA_INDIRECT, 0U) |
724 CSL_FMK(UDMAP_TR_FLAGS_EOP, 1U);
726 /* Assume length is multiple of 32KB*/
727 if (length <= 32768) {
728 pTr->icnt0 = length;
729 pTr->icnt1 = 1U;
730 } else {
731 pTr->icnt0 = 32768;
732 pTr->icnt1 = length/32768U;
733 }
734 pTr->icnt2 = 1U;
735 pTr->icnt3 = 1U;
736 pTr->dim1 = pTr->icnt0;
737 pTr->dim2 = (pTr->icnt0 * pTr->icnt1);
738 pTr->dim3 = (pTr->icnt0 * pTr->icnt1 * pTr->icnt2);
739 pTr->addr = (uint64_t) srcBuf;
740 pTr->fmtflags = 0x00000000U; /* Linear addressing, 1 byte per elem.
741 Replace with CSL-FL API */
742 /* Assume length is multiple of 32KB*/
743 if (length <= 32768) {
744 pTr->dicnt0 = length;
745 pTr->dicnt1 = 1U;
746 } else {
747 pTr->dicnt0 = 32768;
748 pTr->dicnt1 = length/32768U;
749 }
750 pTr->dicnt2 = 1U;
751 pTr->dicnt3 = 1U;
752 pTr->ddim1 = pTr->dicnt0;
753 pTr->ddim2 = (pTr->dicnt0 * pTr->dicnt1);
754 pTr->ddim3 = (pTr->dicnt0 * pTr->dicnt1 * pTr->dicnt2);
755 pTr->daddr = (uint64_t) destBuf;
757 /* Clear TR response memory */
758 *pTrResp = 0xFFFFFFFFU;
760 /* Writeback cache */
761 CacheP_wb(pTrpdMem, PCIE_TEST_APP_TRPD_SIZE);
763 return;
764 }