40c2aafb7051339e850da05c47991e316962bff2
1 /*
2 * Copyright (c) Texas Instruments Incorporated 2018
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_ring.c
35 *
36 * \brief File containing the UDMA driver ring related APIs.
37 *
38 */
40 /* ========================================================================== */
41 /* Include Files */
42 /* ========================================================================== */
44 #include <ti/drv/udma/src/udma_priv.h>
46 /* ========================================================================== */
47 /* Macros & Typedefs */
48 /* ========================================================================== */
50 /** \brief Max number of door bell ring that can be performed at one go */
51 #define UDMA_RING_MAX_DB_RING_CNT (127U)
53 /* ========================================================================== */
54 /* Structure Declarations */
55 /* ========================================================================== */
57 /* None */
59 /* ========================================================================== */
60 /* Function Declarations */
61 /* ========================================================================== */
63 static inline void Udma_ringAssertFnPointers(Udma_DrvHandle drvHandle);
65 /* ========================================================================== */
66 /* Global Variables */
67 /* ========================================================================== */
69 /* None */
71 /* ========================================================================== */
72 /* Function Definitions */
73 /* ========================================================================== */
75 int32_t Udma_ringAlloc(Udma_DrvHandle drvHandle,
76 Udma_RingHandle ringHandle,
77 uint16_t ringNum,
78 const Udma_RingPrms *ringPrms)
79 {
80 int32_t retVal = UDMA_SOK;
81 uint64_t physBase;
82 uint32_t allocDone = (uint32_t) FALSE;
83 struct tisci_msg_rm_ring_cfg_req rmRingReq;
84 struct tisci_msg_rm_ring_cfg_resp rmRingResp;
86 /* Error check */
87 if((NULL_PTR == drvHandle) || (NULL_PTR == ringHandle) || (NULL_PTR == ringPrms))
88 {
89 retVal = UDMA_EBADARGS;
90 }
91 if(UDMA_SOK == retVal)
92 {
93 if(drvHandle->drvInitDone != UDMA_INIT_DONE)
94 {
95 retVal = UDMA_EFAIL;
96 }
97 }
99 if(UDMA_SOK == retVal)
100 {
101 retVal = Udma_ringCheckParams(drvHandle, ringPrms);
102 }
104 if(UDMA_SOK == retVal)
105 {
106 if(UDMA_RING_ANY == ringNum)
107 {
108 /* Alloc free ring */
109 ringHandle->ringNum = Udma_rmAllocFreeRing(drvHandle);
110 if(UDMA_RING_INVALID == ringHandle->ringNum)
111 {
112 retVal = UDMA_EALLOC;
113 }
114 else
115 {
116 allocDone = (uint32_t) TRUE;
117 }
118 }
119 else
120 {
121 if(ringNum >= drvHandle->maxRings)
122 {
123 Udma_printf(drvHandle, "[Error] Out of range ring index!!!\n");
124 retVal = UDMA_EINVALID_PARAMS;
125 }
126 else
127 {
128 ringHandle->ringNum = ringNum;
129 }
130 }
131 }
133 if(UDMA_SOK == retVal)
134 {
135 Udma_ringAssertFnPointers(drvHandle);
136 ringHandle->drvHandle = drvHandle;
137 drvHandle->ringSetCfg(drvHandle, ringHandle, ringPrms);
139 #if (UDMA_SOC_CFG_APPLY_RING_WORKAROUND == 1)
140 /* Perform ring reset */
141 retVal = Udma_ringReset(drvHandle, ringHandle);
142 if(UDMA_SOK != retVal)
143 {
144 Udma_printf(drvHandle, "[Error] Ring reset failed!!!\n");
145 }
146 #endif
147 }
149 if(UDMA_SOK == retVal)
150 {
151 /* Configure ring */
152 rmRingReq.valid_params = TISCI_MSG_VALUE_RM_RING_ADDR_LO_VALID |
153 TISCI_MSG_VALUE_RM_RING_ADDR_HI_VALID |
154 TISCI_MSG_VALUE_RM_RING_COUNT_VALID |
155 TISCI_MSG_VALUE_RM_RING_MODE_VALID |
156 TISCI_MSG_VALUE_RM_RING_SIZE_VALID |
157 TISCI_MSG_VALUE_RM_RING_ORDER_ID_VALID;
158 rmRingReq.nav_id = drvHandle->devIdRing;
159 rmRingReq.index = ringHandle->ringNum;
160 physBase = Udma_virtToPhyFxn(ringPrms->ringMem, drvHandle, (Udma_ChHandle) NULL_PTR);
161 rmRingReq.addr_lo = (uint32_t)physBase;
162 rmRingReq.addr_hi = (uint32_t)(physBase >> 32UL);
163 rmRingReq.count = ringPrms->elemCnt;
164 rmRingReq.mode = ringPrms->mode;
165 rmRingReq.size = ringPrms->elemSize;
166 rmRingReq.order_id = ringPrms->orderId;
167 retVal = Sciclient_rmRingCfg(
168 &rmRingReq, &rmRingResp, UDMA_SCICLIENT_TIMEOUT);
169 if(CSL_PASS != retVal)
170 {
171 Udma_printf(drvHandle, "[Error] Ring config failed!!!\n");
172 }
173 }
175 if(UDMA_SOK == retVal)
176 {
177 ringHandle->ringInitDone = UDMA_INIT_DONE;
178 }
179 else
180 {
181 /* Error. Free-up resource if allocated */
182 if(((uint32_t) TRUE) == allocDone)
183 {
184 Udma_rmFreeFreeRing(ringHandle->ringNum, drvHandle);
185 }
186 }
188 return (retVal);
189 }
191 int32_t Udma_ringFree(Udma_RingHandle ringHandle)
192 {
193 int32_t retVal = UDMA_SOK;
194 Udma_DrvHandle drvHandle;
196 /* Error check */
197 if(NULL_PTR == ringHandle)
198 {
199 retVal = UDMA_EBADARGS;
200 }
201 if(UDMA_SOK == retVal)
202 {
203 if(ringHandle->ringInitDone != UDMA_INIT_DONE)
204 {
205 retVal = UDMA_EFAIL;
206 }
207 }
208 if(UDMA_SOK == retVal)
209 {
210 drvHandle = ringHandle->drvHandle;
211 if((NULL_PTR == drvHandle) || (drvHandle->drvInitDone != UDMA_INIT_DONE))
212 {
213 retVal = UDMA_EFAIL;
214 }
215 }
217 if(UDMA_SOK == retVal)
218 {
219 /* Free-up event resources */
220 Udma_assert(drvHandle, ringHandle->ringNum != UDMA_RING_INVALID);
221 Udma_rmFreeFreeRing(ringHandle->ringNum, drvHandle);
222 ringHandle->ringNum = UDMA_RING_INVALID;
223 ringHandle->ringInitDone = UDMA_DEINIT_DONE;
225 drvHandle->ringHandleClearRegs(ringHandle);
227 ringHandle->drvHandle = (Udma_DrvHandle) NULL_PTR;
228 }
230 return (retVal);
231 }
233 int32_t Udma_ringAttach(Udma_DrvHandle drvHandle,
234 Udma_RingHandle ringHandle,
235 uint16_t ringNum)
236 {
237 int32_t retVal = UDMA_SOK;
239 /* Error check */
240 if((NULL_PTR == drvHandle) || (NULL_PTR == ringHandle))
241 {
242 retVal = UDMA_EBADARGS;
243 }
244 if(UDMA_SOK == retVal)
245 {
246 if(drvHandle->drvInitDone != UDMA_INIT_DONE)
247 {
248 retVal = UDMA_EFAIL;
249 }
250 }
251 if(UDMA_SOK == retVal)
252 {
253 if(ringNum >= drvHandle->maxRings)
254 {
255 Udma_printf(drvHandle, "[Error] Out of range ring index!!!\n");
256 retVal = UDMA_EINVALID_PARAMS;
257 }
258 }
260 if(UDMA_SOK == retVal)
261 {
262 ringHandle->ringNum = ringNum;
264 drvHandle->ringSetCfg(drvHandle, ringHandle, (Udma_RingPrms *) NULL_PTR);
266 ringHandle->ringInitDone = UDMA_INIT_DONE;
267 }
269 return (retVal);
270 }
272 int32_t Udma_ringDetach(Udma_RingHandle ringHandle)
273 {
274 int32_t retVal = UDMA_SOK;
275 Udma_DrvHandle drvHandle;
277 /* Error check */
278 if(NULL_PTR == ringHandle)
279 {
280 retVal = UDMA_EBADARGS;
281 }
282 if(UDMA_SOK == retVal)
283 {
284 if(ringHandle->ringInitDone != UDMA_INIT_DONE)
285 {
286 retVal = UDMA_EFAIL;
287 }
288 }
289 if(UDMA_SOK == retVal)
290 {
291 drvHandle = ringHandle->drvHandle;
292 if((NULL_PTR == drvHandle) || (drvHandle->drvInitDone != UDMA_INIT_DONE))
293 {
294 retVal = UDMA_EFAIL;
295 }
296 }
298 if(UDMA_SOK == retVal)
299 {
300 /* Clear handle object */
301 Udma_assert(drvHandle, ringHandle->ringNum != UDMA_RING_INVALID);
302 ringHandle->ringInitDone = UDMA_DEINIT_DONE;
304 drvHandle->ringHandleClearRegs(ringHandle);
306 ringHandle->drvHandle = (Udma_DrvHandle) NULL_PTR;
308 }
310 return (retVal);
311 }
313 int32_t Udma_ringQueueRaw(Udma_RingHandle ringHandle, uint64_t phyDescMem)
314 {
315 int32_t retVal = UDMA_SOK;
316 uintptr_t cookie;
317 Udma_DrvHandle drvHandle;
319 /* Error check */
320 if((NULL_PTR == ringHandle) ||
321 (ringHandle->ringInitDone != UDMA_INIT_DONE) ||
322 (ringHandle->ringNum == UDMA_RING_INVALID))
323 {
324 retVal = UDMA_EBADARGS;
325 }
326 if(UDMA_SOK == retVal)
327 {
328 drvHandle = ringHandle->drvHandle;
329 if((NULL_PTR == drvHandle) || (drvHandle->drvInitDone != UDMA_INIT_DONE))
330 {
331 retVal = UDMA_EFAIL;
332 }
333 }
335 if(UDMA_SOK == retVal)
336 {
337 cookie = drvHandle->initPrms.osalPrms.disableAllIntr();
339 retVal = drvHandle->ringQueueRaw(drvHandle,ringHandle,phyDescMem);
341 drvHandle->initPrms.osalPrms.restoreAllIntr(cookie);
342 }
344 return (retVal);
345 }
347 int32_t Udma_ringDequeueRaw(Udma_RingHandle ringHandle, uint64_t *phyDescMem)
348 {
349 int32_t retVal = UDMA_SOK;
350 uintptr_t cookie;
351 Udma_DrvHandle drvHandle;
353 /* Error check */
354 if((NULL_PTR == ringHandle) ||
355 (ringHandle->ringInitDone != UDMA_INIT_DONE) ||
356 (ringHandle->ringNum == UDMA_RING_INVALID))
357 {
358 retVal = UDMA_EBADARGS;
359 }
360 if(UDMA_SOK == retVal)
361 {
362 drvHandle = ringHandle->drvHandle;
363 if((NULL_PTR == drvHandle) || (drvHandle->drvInitDone != UDMA_INIT_DONE))
364 {
365 retVal = UDMA_EFAIL;
366 }
367 }
369 if(UDMA_SOK == retVal)
370 {
371 cookie = drvHandle->initPrms.osalPrms.disableAllIntr();
373 retVal = drvHandle->ringDequeueRaw(drvHandle,ringHandle,phyDescMem);
375 drvHandle->initPrms.osalPrms.restoreAllIntr(cookie);
376 }
378 return (retVal);
379 }
381 int32_t Udma_ringFlushRaw(Udma_RingHandle ringHandle, uint64_t *phyDescMem)
382 {
383 int32_t retVal = UDMA_SOK;
384 Udma_DrvHandle drvHandle;
386 /* Error check */
387 if((NULL_PTR == ringHandle) ||
388 (ringHandle->ringInitDone != UDMA_INIT_DONE) ||
389 (ringHandle->ringNum == UDMA_RING_INVALID))
390 {
391 retVal = UDMA_EBADARGS;
392 }
393 if(UDMA_SOK == retVal)
394 {
395 drvHandle = ringHandle->drvHandle;
396 if((NULL_PTR == drvHandle) || (drvHandle->drvInitDone != UDMA_INIT_DONE))
397 {
398 retVal = UDMA_EFAIL;
399 }
400 }
402 if(UDMA_SOK == retVal)
403 {
404 retVal = drvHandle->ringFlushRaw(drvHandle,ringHandle,phyDescMem);
405 }
407 return (retVal);
408 }
410 void Udma_ringPrime(Udma_RingHandle ringHandle, uint64_t phyDescMem)
411 {
412 Udma_DrvHandle drvHandle = ringHandle->drvHandle;
414 drvHandle->ringPrime(ringHandle,phyDescMem);
416 return;
417 }
419 void Udma_ringPrimeRead(Udma_RingHandle ringHandle, uint64_t *phyDescMem)
420 {
421 Udma_DrvHandle drvHandle = ringHandle->drvHandle;
423 drvHandle->ringPrimeRead(ringHandle,phyDescMem);
425 return;
426 }
428 void Udma_ringSetDoorBell(Udma_RingHandle ringHandle, int32_t count)
429 {
430 Udma_DrvHandle drvHandle = ringHandle->drvHandle;
432 drvHandle->ringSetDoorBell(ringHandle,count);
434 return;
435 }
437 uint16_t Udma_ringGetNum(Udma_RingHandle ringHandle)
438 {
439 uint16_t ringNum = UDMA_RING_INVALID;
441 if((NULL_PTR != ringHandle) && (UDMA_INIT_DONE == ringHandle->ringInitDone))
442 {
443 ringNum = ringHandle->ringNum;
444 }
446 return (ringNum);
447 }
449 void *Udma_ringGetMemPtr(Udma_RingHandle ringHandle)
450 {
451 void *ringMem = NULL_PTR;
452 Udma_DrvHandle drvHandle = ringHandle->drvHandle;
454 ringMem = drvHandle->ringGetMemPtr(ringHandle);
456 return (ringMem);
457 }
459 uint32_t Udma_ringGetMode(Udma_RingHandle ringHandle)
460 {
461 uint32_t ringMode = UDMA_RING_MODE_INVALID;
462 Udma_DrvHandle drvHandle = ringHandle->drvHandle;
464 ringMode = drvHandle->ringGetMode(ringHandle);
466 return (ringMode);
467 }
469 uint32_t Udma_ringGetElementCnt(Udma_RingHandle ringHandle)
470 {
471 uint32_t size = 0U;
472 Udma_DrvHandle drvHandle = ringHandle->drvHandle;
474 size = drvHandle->ringGetElementCnt(ringHandle);
476 return (size);
477 }
479 uint32_t Udma_ringGetForwardRingOcc(Udma_RingHandle ringHandle)
480 {
481 uint32_t occ = 0U;
482 Udma_DrvHandle drvHandle = ringHandle->drvHandle;
484 occ = drvHandle->ringGetForwardRingOcc(ringHandle);
486 return (occ);
487 }
489 uint32_t Udma_ringGetReverseRingOcc(Udma_RingHandle ringHandle)
490 {
491 uint32_t occ = 0U;
492 Udma_DrvHandle drvHandle = ringHandle->drvHandle;
494 occ = drvHandle->ringGetReverseRingOcc(ringHandle);
496 return (occ);
497 }
499 uint32_t Udma_ringGetWrIdx(Udma_RingHandle ringHandle)
500 {
501 uint32_t idx = 0U;
502 Udma_DrvHandle drvHandle = ringHandle->drvHandle;
504 idx = drvHandle->ringGetWrIdx(ringHandle);
506 return (idx);
507 }
509 uint32_t Udma_ringGetRdIdx(Udma_RingHandle ringHandle)
510 {
511 uint32_t idx = 0U;
512 Udma_DrvHandle drvHandle = ringHandle->drvHandle;
514 idx = drvHandle->ringGetRdIdx(ringHandle);
516 return (idx);
517 }
519 int32_t Udma_ringMonAlloc(Udma_DrvHandle drvHandle,
520 Udma_RingMonHandle monHandle,
521 uint16_t ringMonNum)
522 {
523 #if (UDMA_SOC_CFG_RING_MON_PRESENT == 1)
524 int32_t retVal = UDMA_SOK;
525 uint32_t allocDone = (uint32_t) FALSE;
527 /* Error check */
528 if((NULL_PTR == monHandle) || (NULL_PTR == drvHandle))
529 {
530 retVal = UDMA_EBADARGS;
531 }
532 if(UDMA_SOK == retVal)
533 {
534 if((NULL_PTR == drvHandle) || (drvHandle->drvInitDone != UDMA_INIT_DONE))
535 {
536 retVal = UDMA_EFAIL;
537 }
538 }
540 if(UDMA_SOK == retVal)
541 {
542 if(UDMA_RING_MON_ANY == ringMonNum)
543 {
544 /* Alloc free ring MONITOR */
545 monHandle->ringMonNum = Udma_rmAllocRingMon(drvHandle);
546 if(UDMA_RING_MON_INVALID == monHandle->ringMonNum)
547 {
548 retVal = UDMA_EALLOC;
549 }
550 else
551 {
552 allocDone = (uint32_t) TRUE;
553 }
554 }
555 else
556 {
557 if(ringMonNum >= drvHandle->maxRingMon)
558 {
559 Udma_printf(drvHandle, "[Error] Out of range ring monitor index!!!\n");
560 retVal = UDMA_EINVALID_PARAMS;
561 }
562 else
563 {
564 monHandle->ringMonNum = ringMonNum;
565 }
566 }
567 }
569 if(UDMA_SOK == retVal)
570 {
571 monHandle->drvHandle = drvHandle;
572 Udma_assert(drvHandle, drvHandle->raRegs.pMonRegs != NULL_PTR);
573 monHandle->pMonRegs =
574 &drvHandle->raRegs.pMonRegs->MON[monHandle->ringMonNum];
575 monHandle->ringMonInitDone = UDMA_INIT_DONE;
576 }
577 else
578 {
579 /* Error. Free-up resource if allocated */
580 if(((uint32_t) TRUE) == allocDone)
581 {
582 Udma_rmFreeRingMon(monHandle->ringMonNum, drvHandle);
583 }
584 }
585 #else
586 int32_t retVal = UDMA_EFAIL;
587 Udma_printf(drvHandle, "[Error] Ring Monitor not supported!!!\n");
588 #endif
590 return (retVal);
591 }
593 int32_t Udma_ringMonFree(Udma_RingMonHandle monHandle)
594 {
595 #if (UDMA_SOC_CFG_RING_MON_PRESENT == 1)
596 int32_t retVal = UDMA_SOK;
597 Udma_DrvHandle drvHandle;
599 /* Error check */
600 if((NULL_PTR == monHandle) ||
601 (monHandle->ringMonInitDone != UDMA_INIT_DONE) ||
602 (monHandle->ringMonNum == UDMA_RING_MON_INVALID))
603 {
604 retVal = UDMA_EBADARGS;
605 }
606 if(UDMA_SOK == retVal)
607 {
608 drvHandle = monHandle->drvHandle;
609 if((NULL_PTR == drvHandle) || (drvHandle->drvInitDone != UDMA_INIT_DONE))
610 {
611 retVal = UDMA_EFAIL;
612 }
613 }
615 if(UDMA_SOK == retVal)
616 {
617 /* Free-up event resources */
618 Udma_assert(drvHandle, monHandle->ringMonNum != UDMA_RING_MON_INVALID);
619 Udma_rmFreeRingMon(monHandle->ringMonNum, drvHandle);
620 monHandle->drvHandle = (Udma_DrvHandle) NULL_PTR;
621 monHandle->ringMonNum = UDMA_RING_MON_INVALID;
622 monHandle->pMonRegs = (volatile CSL_ringacc_monitorRegs_mon *) NULL_PTR;
623 monHandle->ringMonInitDone = UDMA_DEINIT_DONE;
624 }
625 #else
626 int32_t retVal = UDMA_EFAIL;
627 #endif
629 return (retVal);
630 }
632 int32_t Udma_ringMonConfig(Udma_RingMonHandle monHandle,
633 const Udma_RingMonPrms *monPrms)
634 {
635 #if (UDMA_SOC_CFG_RING_MON_PRESENT == 1)
636 int32_t retVal = UDMA_SOK;
637 Udma_DrvHandle drvHandle;
638 struct tisci_msg_rm_ring_mon_cfg_req rmRingMonReq;
639 struct tisci_msg_rm_ring_mon_cfg_resp rmRingMonResp;
641 /* Error check */
642 if((NULL_PTR == monHandle) ||
643 (NULL_PTR == monPrms) ||
644 (monHandle->ringMonInitDone != UDMA_INIT_DONE) ||
645 (monHandle->ringMonNum == UDMA_RING_MON_INVALID))
646 {
647 retVal = UDMA_EBADARGS;
648 }
649 if(UDMA_SOK == retVal)
650 {
651 drvHandle = monHandle->drvHandle;
652 if((NULL_PTR == drvHandle) || (drvHandle->drvInitDone != UDMA_INIT_DONE))
653 {
654 retVal = UDMA_EFAIL;
655 }
656 }
658 if(UDMA_SOK == retVal)
659 {
660 rmRingMonReq.valid_params = TISCI_MSG_VALUE_RM_MON_SOURCE_VALID |
661 TISCI_MSG_VALUE_RM_MON_MODE_VALID |
662 TISCI_MSG_VALUE_RM_MON_QUEUE_VALID |
663 TISCI_MSG_VALUE_RM_MON_DATA0_VAL_VALID |
664 TISCI_MSG_VALUE_RM_MON_DATA1_VAL_VALID;
665 rmRingMonReq.nav_id = drvHandle->devIdRing;
666 rmRingMonReq.index = monHandle->ringMonNum;
667 rmRingMonReq.source = monPrms->source;
668 rmRingMonReq.mode = monPrms->mode;
669 rmRingMonReq.queue = monPrms->ringNum;
670 rmRingMonReq.data0_val = monPrms->data0;
671 rmRingMonReq.data1_val = monPrms->data1;
672 retVal = Sciclient_rmRingMonCfg(
673 &rmRingMonReq, &rmRingMonResp, UDMA_SCICLIENT_TIMEOUT);
674 if(CSL_PASS != retVal)
675 {
676 Udma_printf(drvHandle, "[Error] Ring monitor config failed!!!\n");
677 }
678 }
679 #else
680 int32_t retVal = UDMA_EFAIL;
681 #endif
683 return (retVal);
684 }
686 int32_t Udma_ringMonGetData(Udma_RingMonHandle monHandle,
687 Udma_RingMonData *monData)
688 {
689 #if (UDMA_SOC_CFG_RING_MON_PRESENT == 1)
690 int32_t retVal = UDMA_SOK;
691 Udma_DrvHandle drvHandle;
693 /* Error check */
694 if((NULL_PTR == monHandle) ||
695 (NULL_PTR == monData) ||
696 (monHandle->ringMonInitDone != UDMA_INIT_DONE) ||
697 (monHandle->ringMonNum == UDMA_RING_MON_INVALID))
698 {
699 retVal = UDMA_EBADARGS;
700 }
701 if(UDMA_SOK == retVal)
702 {
703 drvHandle = monHandle->drvHandle;
704 if((NULL_PTR == drvHandle) || (drvHandle->drvInitDone != UDMA_INIT_DONE))
705 {
706 retVal = UDMA_EFAIL;
707 }
708 }
710 if(UDMA_SOK == retVal)
711 {
712 Udma_assert(drvHandle, monHandle->pMonRegs != NULL_PTR);
713 monData->data0 = CSL_REG32_RD(&monHandle->pMonRegs->DATA0);
714 monData->data1 = CSL_REG32_RD(&monHandle->pMonRegs->DATA1);
715 }
716 #else
717 int32_t retVal = UDMA_EFAIL;
718 #endif
720 return (retVal);
721 }
723 uint16_t Udma_ringMonGetNum(Udma_RingMonHandle monHandle)
724 {
725 uint16_t ringMonNum = UDMA_RING_MON_INVALID;
727 #if (UDMA_SOC_CFG_RING_MON_PRESENT == 1)
728 if((NULL_PTR != monHandle) && (UDMA_INIT_DONE == monHandle->ringMonInitDone))
729 {
730 ringMonNum = monHandle->ringMonNum;
731 }
732 #endif
734 return (ringMonNum);
735 }
737 void UdmaRingPrms_init(Udma_RingPrms *ringPrms)
738 {
739 if(NULL_PTR != ringPrms)
740 {
741 ringPrms->ringMem = NULL_PTR;
742 ringPrms->ringMemSize = UDMA_RING_SIZE_CHECK_SKIP;
743 ringPrms->mode = TISCI_MSG_VALUE_RM_RING_MODE_RING;
744 ringPrms->elemCnt = 0U;
745 ringPrms->elemSize = UDMA_RING_ES_8BYTES;
746 ringPrms->orderId = UDMA_DEFAULT_RING_ORDER_ID;
747 }
749 return;
750 }
752 void UdmaRingMonPrms_init(Udma_RingMonPrms *monPrms)
753 {
754 if(NULL_PTR != monPrms)
755 {
756 monPrms->source = TISCI_MSG_VALUE_RM_MON_SRC_ELEM_CNT;
757 monPrms->mode = TISCI_MSG_VALUE_RM_MON_MODE_DISABLED;
758 monPrms->ringNum = UDMA_RING_INVALID;
759 monPrms->data0 = 0U;
760 monPrms->data1 = 0U;
761 }
763 return;
764 }
766 int32_t Udma_ringProxyQueueRaw(Udma_RingHandle ringHandle,
767 Udma_DrvHandle drvHandle,
768 uint64_t phyDescMem)
769 {
770 #if (UDMA_SOC_CFG_PROXY_PRESENT == 1)
771 int32_t retVal = UDMA_SOK;
772 uint32_t ringHwOcc;
773 CSL_ProxyThreadCfg threadCfg;
775 /* Get ring occupancy. We should write to FIFO (through proxy) only
776 * when there is room available. Otherwise ring will overflow */
777 ringHwOcc = CSL_ringaccGetRingHwOcc(
778 &ringHandle->drvHandle->raRegs, ringHandle->ringNum);
779 if(ringHwOcc >= ringHandle->cfg.elCnt)
780 {
781 /* Ring full */
782 retVal = UDMA_EFAIL;
783 }
784 else
785 {
786 threadCfg.mode = CSL_PROXY_QUEUE_ACCESS_MODE_TAIL;
787 threadCfg.elSz = (uint32_t)sizeof(uint64_t);
788 threadCfg.queueNum = ringHandle->ringNum;
789 threadCfg.errEvtNum = UDMA_EVENT_INVALID;
790 retVal = CSL_proxyCfgThread(
791 &drvHandle->proxyCfg,
792 drvHandle->proxyTargetNumRing,
793 drvHandle->initPrms.rmInitPrms.proxyThreadNum,
794 &threadCfg);
795 if(UDMA_SOK == retVal)
796 {
797 Udma_proxyWrite64(ringHandle->proxyAddr, phyDescMem);
798 }
799 }
801 #else
802 int32_t retVal = UDMA_EFAIL;
803 Udma_printf(drvHandle, "[Error] Proxy not present!!!\n");
804 #endif
806 return (retVal);
807 }
809 int32_t Udma_ringProxyDequeueRaw(Udma_RingHandle ringHandle,
810 Udma_DrvHandle drvHandle,
811 uint64_t *phyDescMem)
812 {
813 #if (UDMA_SOC_CFG_PROXY_PRESENT == 1)
814 int32_t retVal = UDMA_SOK;
815 uint32_t ringHwOcc;
816 CSL_ProxyThreadCfg threadCfg;
818 /* Get ring occupancy. We should read from FIFO (through proxy) only
819 * when something is available. Otherwise ring will underflow */
820 ringHwOcc = CSL_ringaccGetRingHwOcc(
821 &ringHandle->drvHandle->raRegs, ringHandle->ringNum);
822 if(0U == ringHwOcc)
823 {
824 /* Nothing to flush */
825 retVal = UDMA_ETIMEOUT;
826 }
827 else
828 {
829 threadCfg.mode = CSL_PROXY_QUEUE_ACCESS_MODE_HEAD;
830 threadCfg.elSz = (uint32_t)sizeof(uint64_t);
831 threadCfg.queueNum = ringHandle->ringNum;
832 threadCfg.errEvtNum = UDMA_EVENT_INVALID;
833 retVal = CSL_proxyCfgThread(
834 &drvHandle->proxyCfg,
835 drvHandle->proxyTargetNumRing,
836 drvHandle->initPrms.rmInitPrms.proxyThreadNum,
837 &threadCfg);
838 if(UDMA_SOK == retVal)
839 {
840 Udma_proxyRead64(ringHandle->proxyAddr, phyDescMem);
841 }
842 }
844 #else
845 int32_t retVal = UDMA_EFAIL;
846 Udma_printf(drvHandle, "[Error] Proxy not present!!!\n");
847 #endif
849 return (retVal);
850 }
852 int32_t Udma_ringCheckParams(Udma_DrvHandle drvHandle,
853 const Udma_RingPrms *ringPrms)
854 {
855 int32_t retVal = UDMA_SOK;
856 uint32_t ringMemSize;
858 Udma_assert(drvHandle, ringPrms != NULL_PTR);
860 if(NULL_PTR == ringPrms->ringMem)
861 {
862 retVal = UDMA_EINVALID_PARAMS;
863 Udma_printf(drvHandle, "[Error] Ring memory should not be NULL_PTR!!!\n");
864 }
865 else
866 {
867 /* Check 128 byte alignment */
868 if(((uintptr_t)ringPrms->ringMem & (UDMA_CACHELINE_ALIGNMENT - 1U)) != 0U)
869 {
870 retVal = UDMA_EINVALID_PARAMS;
871 Udma_printf(drvHandle, "[Error] Ring memory not aligned!!!\n");
872 }
873 }
875 if(0U == ringPrms->elemCnt)
876 {
877 retVal = UDMA_EINVALID_PARAMS;
878 Udma_printf(drvHandle,
879 "[Error] Ring element count should not be zero!!!\n");
880 }
882 if(UDMA_RING_SIZE_CHECK_SKIP != ringPrms->ringMemSize)
883 {
884 /* Get ring memory size */
885 ringMemSize = UdmaUtils_getRingMemSize(
886 ringPrms->mode,
887 ringPrms->elemCnt,
888 ringPrms->elemSize);
889 if(ringPrms->ringMemSize < ringMemSize)
890 {
891 retVal = UDMA_EALLOC;
892 Udma_printf(drvHandle, "[Error] Ring memory not sufficient!!!\n");
893 }
894 }
896 if (UDMA_RING_ORDERID_MAX < ringPrms->orderId)
897 {
898 retVal = UDMA_EINVALID_PARAMS;
899 Udma_printf(drvHandle, "[Error] Ring orderId out of range (%u)!!!\n",
900 ringPrms->orderId);
901 }
903 return (retVal);
904 }
906 static inline void Udma_ringAssertFnPointers(Udma_DrvHandle drvHandle)
907 {
908 Udma_assert(drvHandle, drvHandle->ringDequeueRaw != (Udma_ringDequeueRawFxn) NULL_PTR);
909 Udma_assert(drvHandle, drvHandle->ringQueueRaw != (Udma_ringQueueRawFxn) NULL_PTR);
910 Udma_assert(drvHandle, drvHandle->ringFlushRaw != (Udma_ringFlushRawFxn) NULL_PTR);
911 Udma_assert(drvHandle, drvHandle->ringGetElementCnt != (Udma_ringGetElementCntFxn) NULL_PTR);
912 Udma_assert(drvHandle, drvHandle->ringGetMemPtr != (Udma_ringGetMemPtrFxn) NULL_PTR);
913 Udma_assert(drvHandle, drvHandle->ringGetMode != (Udma_ringGetModeFxn) NULL_PTR);
914 Udma_assert(drvHandle, drvHandle->ringGetForwardRingOcc != (Udma_ringGetForwardRingOccFxn) NULL_PTR);
915 Udma_assert(drvHandle, drvHandle->ringGetReverseRingOcc != (Udma_ringGetReverseRingOccFxn) NULL_PTR);
916 Udma_assert(drvHandle, drvHandle->ringGetWrIdx != (Udma_ringGetWrIdxFxn) NULL_PTR);
917 Udma_assert(drvHandle, drvHandle->ringGetRdIdx != (Udma_ringGetRdIdxFxn) NULL_PTR);
918 Udma_assert(drvHandle, drvHandle->ringPrime != (Udma_ringPrimeFxn) NULL_PTR);
919 Udma_assert(drvHandle, drvHandle->ringPrimeRead != (Udma_ringPrimeReadFxn) NULL_PTR);
920 Udma_assert(drvHandle, drvHandle->ringSetDoorBell != (Udma_ringSetDoorBellFxn) NULL_PTR);
921 Udma_assert(drvHandle, drvHandle->ringSetCfg != (Udma_ringSetCfgFxn) NULL_PTR);
922 Udma_assert(drvHandle, drvHandle->ringHandleClearRegs != (Udma_ringHandleClearRegsFxn) NULL_PTR);
924 Udma_assert(drvHandle, drvHandle->initPrms.osalPrms.disableAllIntr != (Udma_OsalDisableAllIntrFxn) NULL_PTR);
925 Udma_assert(drvHandle, drvHandle->initPrms.osalPrms.restoreAllIntr != (Udma_OsalRestoreAllIntrFxn) NULL_PTR);
926 }
928 #if (UDMA_SOC_CFG_APPLY_RING_WORKAROUND == 1)
929 int32_t Udma_ringReset(Udma_DrvHandle drvHandle,
930 Udma_RingHandle ringHandle)
931 {
932 int32_t retVal = UDMA_SOK;
933 uint32_t regVal;
934 uint32_t ringOcc, mode, elemSize;
935 uint32_t applyWorkaround = 0U, freeRingStart;
936 uint32_t dbRingCnt, thisDbRingCnt;
937 struct tisci_msg_rm_ring_cfg_req rmRingReq;
938 struct tisci_msg_rm_ring_cfg_resp rmRingResp;
940 Udma_assert(drvHandle, drvHandle->raRegs.pGlbRegs != NULL_PTR);
941 Udma_assert(drvHandle, ringHandle->pCfgRegs != NULL_PTR);
942 Udma_assert(drvHandle, ringHandle->pRtRegs != NULL_PTR);
944 /*-------------------------------------------------------------------------
945 * ringacc revision 1.0.19 and earlier has an issue where the UDMAP ring
946 * state (ring occupancy) will be out of sync with the ringacc ring state
947 * when a ring is reset.
948 *
949 * Perform the software workaround to correct this.
950 *-----------------------------------------------------------------------*/
951 regVal = CSL_REG32_RD(&drvHandle->raRegs.pGlbRegs->REVISION);
952 if(!((CSL_FEXT(regVal, RINGACC_GCFG_REVISION_REVMAJ) > 1U) ||
953 (CSL_FEXT(regVal, RINGACC_GCFG_REVISION_REVMIN) > 0U) ||
954 (CSL_FEXT(regVal, RINGACC_GCFG_REVISION_REVRTL) > 19U)))
955 {
956 /* Workaround required only for FQ ring */
957 freeRingStart = drvHandle->udmapRegs.txChanCnt +
958 drvHandle->udmapRegs.txExtUtcChanCnt +
959 drvHandle->udmapRegs.rxChanCnt;
960 if(ringHandle->ringNum < freeRingStart)
961 {
962 applyWorkaround = 1U;
963 }
964 }
966 if(1U == applyWorkaround)
967 {
968 /* Call SCICLIENT with dummy cfg to get read access to the ring RT
969 * By default this is is firewalled even for read access */
970 rmRingReq.valid_params = 0U;
971 rmRingReq.nav_id = drvHandle->devIdRing;
972 rmRingReq.index = ringHandle->ringNum;
973 /* Not used */
974 rmRingReq.mode = 0U;
975 rmRingReq.size = 0U;
976 rmRingReq.addr_lo = 0U;
977 rmRingReq.addr_hi = 0U;
978 rmRingReq.count = 0U;
979 rmRingReq.order_id = UDMA_DEFAULT_RING_ORDER_ID;
980 retVal = Sciclient_rmRingCfg(
981 &rmRingReq, &rmRingResp, UDMA_SCICLIENT_TIMEOUT);
982 if(CSL_PASS != retVal)
983 {
984 Udma_printf(drvHandle,
985 "[Error] Ring config for read access failed!!!\n");
986 }
987 }
989 if((1U == applyWorkaround) && (UDMA_SOK == retVal))
990 {
991 /*-------------------------------------------------------------------------
992 * 1. Read the ring occupancy.
993 *
994 * In the case of a credentials mode or qm mode ring, each ring write
995 * results in the ring occupancy increasing by 2 elements (one entry for
996 * the credentials, one entry for the data). However, the internal UDMAP
997 * ring state occupancy counter only records the number of writes, so we
998 * divide the ring occupancy by 2 to get back to the number of doorbell
999 * rings needed.
1000 *
1001 * If the ring occupancy is not 0, then we need to execute the workaround.
1002 *-----------------------------------------------------------------------*/
1003 ringOcc = CSL_REG32_FEXT(&ringHandle->pRtRegs->OCC, RINGACC_RT_RINGRT_OCC_CNT);
1004 mode = CSL_REG32_FEXT(&ringHandle->pCfgRegs->SIZE, RINGACC_CFG_RING_SIZE_QMODE);
1005 elemSize = CSL_REG32_FEXT(&ringHandle->pCfgRegs->SIZE, RINGACC_CFG_RING_SIZE_ELSIZE);
1006 if((CSL_RINGACC_RING_MODE_CREDENTIALS == mode) ||
1007 (CSL_RINGACC_RING_MODE_QM == mode))
1008 {
1009 ringOcc >>= 1U;
1010 }
1011 if(ringOcc != 0U)
1012 {
1013 /*---------------------------------------------------------------------
1014 * 2. Reset the ring by writing to size register
1015 * 3. At the same time setup the ring in ring/doorbell mode
1016 *-------------------------------------------------------------------*/
1017 rmRingReq.valid_params = TISCI_MSG_VALUE_RM_RING_MODE_VALID |
1018 TISCI_MSG_VALUE_RM_RING_SIZE_VALID;
1019 rmRingReq.nav_id = drvHandle->devIdRing;
1020 rmRingReq.index = ringHandle->ringNum;
1021 rmRingReq.mode = TISCI_MSG_VALUE_RM_RING_MODE_RING;
1022 rmRingReq.size = elemSize;
1023 /* Not used */
1024 rmRingReq.addr_lo = 0U;
1025 rmRingReq.addr_hi = 0U;
1026 rmRingReq.count = 0U;
1027 rmRingReq.order_id = UDMA_DEFAULT_RING_ORDER_ID;
1028 retVal = Sciclient_rmRingCfg(
1029 &rmRingReq, &rmRingResp, UDMA_SCICLIENT_TIMEOUT);
1030 if(CSL_PASS != retVal)
1031 {
1032 Udma_printf(drvHandle, "[Error] Ring reset failed!!!\n");
1033 }
1034 else
1035 {
1036 /*--------------------------------------------------------------
1037 * 4. Ring the doorbell 2**22 - ringOcc times. This will wrap
1038 * the internal UDMAP ring state occupancy counter
1039 * (which is 21-bits wide) to 0.
1040 *------------------------------------------------------------*/
1041 dbRingCnt = ((uint32_t)1U << 22) - ringOcc;
1042 thisDbRingCnt = UDMA_RING_MAX_DB_RING_CNT;
1043 regVal = CSL_FMK(RINGACC_RT_RINGRT_DB_CNT, thisDbRingCnt);
1044 while(dbRingCnt != 0U)
1045 {
1046 /*----------------------------------------------------------
1047 * Ring the doorbell with the maximum count each iteration
1048 * if possible to minimize the total # of writes
1049 *--------------------------------------------------------*/
1050 if(dbRingCnt < UDMA_RING_MAX_DB_RING_CNT)
1051 {
1052 thisDbRingCnt = dbRingCnt;
1053 regVal = CSL_FMK(RINGACC_RT_RINGRT_DB_CNT, thisDbRingCnt);
1054 }
1055 CSL_REG32_WR(&ringHandle->pRtRegs->DB, regVal);
1056 dbRingCnt -= thisDbRingCnt;
1057 }
1059 /*--------------------------------------------------------------
1060 * 5. Restore the original ring mode (if not ring mode)
1061 *------------------------------------------------------------*/
1062 /* Not done as we will reconfigure the ring after reset step */
1063 }
1064 }
1065 }
1067 return (retVal);
1068 }
1069 #endif