1 /*
2 * edma3resmgr.c
3 *
4 * EDMA3 Controller Resource Manager Interface Implementation
5 *
6 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
7 *
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the
19 * distribution.
20 *
21 * Neither the name of Texas Instruments Incorporated nor the names of
22 * its contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 */
39 /* Resource Manager Internal Header Files */
40 #include <ti/sdo/edma3/rm/src/edma3resmgr.h>
42 /* Instrumentation Header File */
43 #ifdef EDMA3_INSTRUMENTATION_ENABLED
44 #include <ti/sdo/edma3/rm/src/edma3_log.h>
45 #endif
47 /* For assert() */
48 /**
49 * Define NDEBUG to ignore assert().
50 * NDEBUG should be defined before including assert.h header file.
51 */
52 #include <assert.h>
55 /* Global Defines, need to re-compile if values are changed */
56 /*---------------------------------------------------------------------------*/
57 /**
58 * \brief EDMA3 Resource Manager behaviour of clearing CC ERROR interrupts.
59 * This macro controls the driver to enable/disable clearing of error
60 * status of all channels.
61 *
62 * On disabling this (with value 0x0), the channels owned by the region
63 * is cleared and its expected that some other entity is responsible for
64 * clearing the error status for channels not owned.
65 *
66 * Its recomended that this flag is a positive value, to ensure that
67 * error flags are cleared for all the channels.
68 */
69 #define EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS (TRUE)
71 /**
72 * \brief EDMA3 Resource Manager retry count to check the pending interrupts inside ISR.
73 * This macro controls the driver to check the pending interrupt for
74 * 'n' number of times.
75 * Minumum value is 1.
76 */
77 #define EDMA3_RM_COMPL_HANDLER_RETRY_COUNT (10u)
79 /**
80 * \brief EDMA3 Resource Manager retry count to check the pending CC Error Interrupt inside ISR
81 * This macro controls the driver to check the pending CC Error
82 * interrupt for 'n' number of times.
83 * Minumum value is 1.
84 */
85 #define EDMA3_RM_CCERR_HANDLER_RETRY_COUNT (10u)
89 /* Externel Variables */
90 /*---------------------------------------------------------------------------*/
91 /**
92 * Maximum Resource Manager Instances supported by the EDMA3 Package.
93 */
94 extern const uint32_t EDMA3_MAX_RM_INSTANCES;
97 #ifndef GENERIC
98 /**
99 * \brief Static Configuration structure for EDMA3
100 * controller, to provide Global SoC specific Information.
101 *
102 * This configuration info can also be provided by the user at run-time,
103 * while calling EDMA3_RM_create (). If not provided at run-time,
104 * this info will be taken from the config file "edma3_<PLATFORM_NAME>_cfg.c",
105 * for the specified platform.
106 */
107 extern EDMA3_RM_GblConfigParams edma3GblCfgParams [EDMA3_MAX_EDMA3_INSTANCES];
109 /**
110 * \brief Default Static Region Specific Configuration structure for
111 * EDMA3 controller, to provide region specific Information.
112 */
113 extern EDMA3_RM_InstanceInitConfig defInstInitConfig [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_REGIONS];
115 #endif
118 /**
119 * \brief Region Specific Configuration structure for
120 * EDMA3 controller, to provide region specific Information.
121 *
122 * This configuration info can also be provided by the user at run-time,
123 * while calling EDMA3_RM_open (). If not provided at run-time,
124 * this info will be taken from the config file "edma3_<PLATFORM_NAME>_cfg.c",
125 * for the specified platform.
126 */
127 extern EDMA3_RM_InstanceInitConfig *userInitConfig;
128 extern EDMA3_RM_InstanceInitConfig *ptrInitCfgArray;
131 /**
132 * Handles of EDMA3 Resource Manager Instances.
133 *
134 * Used to maintain information of the EDMA3 RM Instances
135 * for each HW controller.
136 * There could be a maximum of EDMA3_MAX_RM_INSTANCES instances per
137 * EDMA3 HW.
138 */
139 extern EDMA3_RM_Instance *resMgrInstance;
140 extern EDMA3_RM_Instance *ptrRMIArray;
142 /** Max of DMA Channels */
143 uint32_t edma3_dma_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
144 /** Min of Link Channels */
145 uint32_t edma3_link_ch_min_val[EDMA3_MAX_EDMA3_INSTANCES];
146 /** Max of Link Channels */
147 uint32_t edma3_link_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
148 /** Min of QDMA Channels */
149 uint32_t edma3_qdma_ch_min_val[EDMA3_MAX_EDMA3_INSTANCES];
150 /** Max of QDMA Channels */
151 uint32_t edma3_qdma_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
152 /** Max of Logical Channels */
153 uint32_t edma3_log_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
155 /* Globals */
156 /*---------------------------------------------------------------------------*/
157 /**
158 * \brief EDMA3 Resource Manager Objects, tied to each EDMA3 HW Controller.
159 *
160 * Typically one RM object will cater to one EDMA3 HW controller
161 * and will have all the global config information.
162 */
163 EDMA3_RM_Obj resMgrObj[EDMA3_MAX_EDMA3_INSTANCES];
166 /**
167 * Global Array to store the mapping between DMA channels and Interrupt
168 * channels i.e. TCCs.
169 * DMA channel X can use any TCC Y. Transfer completion
170 * interrupt will occur on the TCC Y (IPR/IPRH Register, bit Y), but error
171 * interrupt will occur on DMA channel X (EMR/EMRH register, bit X). In that
172 * scenario, this DMA channel <-> TCC mapping will be used to point to
173 * the correct callback function.
174 */
175 static uint32_t edma3DmaChTccMapping [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_DMA_CH];
178 /**
179 * Global Array to store the mapping between QDMA channels and Interrupt
180 * channels i.e. TCCs.
181 * QDMA channel X can use any TCC Y. Transfer completion
182 * interrupt will occur on the TCC Y (IPR/IPRH Register, bit Y), but error
183 * interrupt will occur on QDMA channel X (QEMR register, bit X). In that
184 * scenario, this QDMA channel <-> TCC mapping will be used to point to
185 * the correct callback function.
186 */
187 static uint32_t edma3QdmaChTccMapping [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_QDMA_CH];
190 /**
191 * Global Array to maintain the Callback details registered
192 * against a particular TCC. Used to call the callback
193 * functions linked to the particular channel.
194 */
195 static EDMA3_RM_TccCallbackParams edma3IntrParams [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_TCC];
198 /** edma3RegionId will be updated ONCE using the parameter regionId passed to
199 * the EDMA3_RM_open() function, for the Master RM instance (one who
200 * configures the Global Registers).
201 * This global variable will be used within the Interrupt handlers to know
202 * which shadow region registers to access. All other interrupts coming
203 * from other shadow regions will not be handled.
204 */
205 static EDMA3_RM_RegionId edma3RegionId = EDMA3_MAX_REGIONS;
207 /** masterExists[] will be updated when the Master RM Instance modifies the
208 * Global EDMA3 configuration registers. It is used to prevent any other
209 * Master RM Instance creation.
210 * masterExists[] is per EDMA3 hardware, hence it is created
211 * as an array.
212 */
213 static uint32_t masterExists [EDMA3_MAX_EDMA3_INSTANCES] = {FALSE,FALSE,FALSE};
215 /**
216 * Number of PaRAM Sets actually present on the SoC. This will be updated
217 * while creating the Resource Manager Object.
218 */
219 uint32_t edma3NumPaRAMSets = EDMA3_MAX_PARAM_SETS;
222 /**
223 * The list of Interrupt Channels which get allocated while requesting the
224 * TCC. It will be used while checking the IPR/IPRH bits in the RM ISR.
225 */
226 static uint32_t allocatedTCCs[EDMA3_MAX_EDMA3_INSTANCES][2u] =
227 {
228 {0x0u, 0x0u},
229 {0x0u, 0x0u},
230 {0x0u, 0x0u},
231 };
234 /**
235 * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
236 * and stored in this array. It will be referenced in
237 * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
238 */
239 static uint32_t contiguousDmaRes[EDMA3_MAX_DMA_CHAN_DWRDS] = {0x0u, 0x0u};
241 /**
242 * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
243 * and stored in this array. It will be referenced in
244 * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
245 */
246 static uint32_t contiguousQdmaRes[EDMA3_MAX_QDMA_CHAN_DWRDS] = {0x0u};
248 /**
249 * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
250 * and stored in this array. It will be referenced in
251 * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
252 */
253 static uint32_t contiguousTccRes[EDMA3_MAX_TCC_DWRDS] = {0x0u, 0x0u};
255 /**
256 * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
257 * and stored in this array. It will be referenced in
258 * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
259 */
260 static uint32_t contiguousParamRes[EDMA3_MAX_PARAM_DWRDS];
263 /**
264 * \brief Resources bound to a Channel
265 *
266 * When a request for a channel is made, the resources PaRAM Set and TCC
267 * get bound to that channel. This information is needed internally by the
268 * resource manager, when a request is made to free the channel,
269 * to free up the channel-associated resources.
270 */
271 static EDMA3_RM_ChBoundResources edma3RmChBoundRes [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_LOGICAL_CH];
275 /*---------------------------------------------------------------------------*/
277 /* Local functions prototypes */
278 /*---------------------------------------------------------------------------*/
279 /** EDMA3 Instance 0 Completion Handler Interrupt Service Routine */
280 void lisrEdma3ComplHandler0(uint32_t arg);
281 /** EDMA3 Instance 0 CC Error Interrupt Service Routine */
282 void lisrEdma3CCErrHandler0(uint32_t arg);
283 /**
284 * EDMA3 Instance 0 TC[0-7] Error Interrupt Service Routines
285 * for a maximum of 8 TCs (Transfer Controllers).
286 */
287 void lisrEdma3TC0ErrHandler0(uint32_t arg);
288 void lisrEdma3TC1ErrHandler0(uint32_t arg);
289 void lisrEdma3TC2ErrHandler0(uint32_t arg);
290 void lisrEdma3TC3ErrHandler0(uint32_t arg);
291 void lisrEdma3TC4ErrHandler0(uint32_t arg);
292 void lisrEdma3TC5ErrHandler0(uint32_t arg);
293 void lisrEdma3TC6ErrHandler0(uint32_t arg);
294 void lisrEdma3TC7ErrHandler0(uint32_t arg);
297 /** Interrupt Handler for the Transfer Completion interrupt */
298 static void edma3ComplHandler (const EDMA3_RM_Obj *rmObj);
299 /** Interrupt Handler for the Channel Controller Error interrupt */
300 static void edma3CCErrHandler (const EDMA3_RM_Obj *rmObj);
301 /** Interrupt Handler for the Transfer Controller Error interrupt */
302 static void edma3TCErrHandler (const EDMA3_RM_Obj *rmObj, uint32_t tcNum);
305 /** Local MemZero function */
306 void edma3MemZero(void *dst, uint32_t len);
307 /** Local MemCpy function */
308 void edma3MemCpy(void *dst, const void *src, uint32_t len);
309 /* Local MemCopy function to copy Param Set ONLY */
310 void edma3ParamCpy(void *dst, const void *src);
312 /** Initialization of the Global region registers of the EDMA3 Controller */
313 static void edma3GlobalRegionInit (uint32_t phyCtrllerInstId);
314 /** Initialization of the Shadow region registers of the EDMA3 Controller */
315 static void edma3ShadowRegionInit (const EDMA3_RM_Instance *pRMInstance);
319 /* Internal functions for contiguous resource allocation */
320 /**
321 * Finds a particular bit ('0' or '1') in the particular word from 'start'.
322 * If found, returns the position, else return -1.
323 */
324 static int32_t findBitInWord (int32_t source, uint32_t start, uint16_t bit);
326 /**
327 * Finds a particular bit ('0' or '1') in the specified resources' array
328 * from 'start' to 'end'. If found, returns the position, else return -1.
329 */
330 static int32_t findBit (EDMA3_RM_ResType resType,
331 uint32_t start,
332 uint32_t end,
333 uint16_t bit);
335 /**
336 * If successful, this function returns EDMA3_RM_SOK and the position
337 * of first available resource in 'positionRes'. Else returns error.
338 */
339 static EDMA3_RM_Result allocAnyContigRes(EDMA3_RM_ResType resType,
340 uint32_t numResources,
341 uint32_t *positionRes);
343 /**
344 * Starting from 'firstResIdObj', this function makes the next 'numResources'
345 * Resources non-available for future. Also, it does some global resisters'
346 * setting also.
347 */
348 static EDMA3_RM_Result gblChngAllocContigRes(EDMA3_RM_Instance *rmInstance,
349 const EDMA3_RM_ResDesc *firstResIdObj,
350 uint32_t numResources);
352 /*---------------------------------------------------------------------------*/
354 EDMA3_RM_Result EDMA3_RM_create (uint32_t phyCtrllerInstId,
355 const EDMA3_RM_GblConfigParams *gblCfgParams,
356 const void *miscParam)
357 {
358 uint32_t count = 0u;
359 EDMA3_RM_Result result = EDMA3_RM_SOK;
360 /**
361 * Used to reset the Internal EDMA3 Resource Manager Data Structures for the first time.
362 */
363 static unsigned short rmInitDone = FALSE;
364 const EDMA3_RM_MiscParam *miscOpt = (const EDMA3_RM_MiscParam *)miscParam;
366 #ifdef GENERIC
367 /* GENERIC libraries don't come with a default confifguration, always
368 needs to be supplied with a parameter */
369 if (gblCfgParams == NULL)
370 {
371 result = EDMA3_RM_E_INVALID_PARAM;
372 }
373 #endif
375 /**
376 * We are NOT checking 'gblCfgParams' for NULL.
377 * If user has passed NULL, default config info will be
378 * taken from config file.
379 * 'param' is also not being checked because it could be
380 * NULL also.
381 */
383 /* If parameter checking is enabled... */
384 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
385 if (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
386 {
387 result = EDMA3_RM_E_INVALID_PARAM;
388 }
389 #endif
391 /* Check if the parameters are OK. */
392 if (EDMA3_RM_SOK == result)
393 {
394 /* Initialize the global variables for the first time */
395 if (FALSE == rmInitDone)
396 {
397 edma3MemZero((void *)&(resMgrObj[count]),
398 sizeof(resMgrObj));
399 edma3MemZero((void *)(&(edma3IntrParams[0u])),
400 sizeof(edma3IntrParams));
402 rmInitDone = TRUE;
403 }
405 /* Initialization has been done */
406 if (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_DELETED)
407 {
408 result = EDMA3_RM_E_OBJ_NOT_DELETED;
409 }
410 else
411 {
412 /**
413 * Check whether user has passed the Global Config Info.
414 * If yes, copy it to the driver data structures. Else, use the
415 * info from the config file edma3Cfg.c
416 */
417 #ifndef GENERIC
418 if (NULL == gblCfgParams)
419 {
420 /* Take info from the specific config file */
421 edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
422 (const void *)(&edma3GblCfgParams[phyCtrllerInstId]),
423 sizeof (EDMA3_RM_GblConfigParams));
424 }
425 else
426 {
427 #endif
428 /* User passed the info, save it in the RM object first */
429 edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
430 (const void *)(gblCfgParams),
431 sizeof (EDMA3_RM_GblConfigParams));
432 #ifndef GENERIC
433 }
434 #endif
437 /**
438 * Check whether DMA channel to PaRAM Set mapping exists or not.
439 * If it does not exist, set the mapping array as 1-to-1 mapped.
440 */
441 if (FALSE == resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChPaRAMMapExists)
442 {
443 for (count = 0u; count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels; count++)
444 {
445 resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChannelPaRAMMap[count] = count;
446 }
447 }
450 /**
451 * Update the actual number of PaRAM sets and
452 * Initialize Boundary Values for Logical Channel Ranges.
453 */
454 edma3NumPaRAMSets = resMgrObj[phyCtrllerInstId].gblCfgParams.numPaRAMSets;
455 edma3_dma_ch_max_val[phyCtrllerInstId] = resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels - 1u;
456 edma3_link_ch_min_val[phyCtrllerInstId] = edma3_dma_ch_max_val[phyCtrllerInstId] + 1u;
457 edma3_link_ch_max_val[phyCtrllerInstId] = edma3_link_ch_min_val[phyCtrllerInstId] + resMgrObj[phyCtrllerInstId].gblCfgParams.numPaRAMSets - 1u;
458 edma3_qdma_ch_min_val[phyCtrllerInstId] = edma3_link_ch_max_val[phyCtrllerInstId] + 1u;
459 edma3_qdma_ch_max_val[phyCtrllerInstId] = edma3_qdma_ch_min_val[phyCtrllerInstId] + resMgrObj[phyCtrllerInstId].gblCfgParams.numQdmaChannels - 1u;
460 edma3_log_ch_max_val[phyCtrllerInstId] = edma3_qdma_ch_max_val[phyCtrllerInstId];
462 resMgrObj[phyCtrllerInstId].phyCtrllerInstId = phyCtrllerInstId;
463 resMgrObj[phyCtrllerInstId].state = EDMA3_RM_CREATED;
464 resMgrObj[phyCtrllerInstId].numOpens = 0u;
466 /* Make all the RM instances for this EDMA3 HW NULL */
467 for (count = 0u; count < EDMA3_MAX_RM_INSTANCES; count++)
468 {
469 edma3MemZero((void *)((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
470 sizeof(EDMA3_RM_Instance));
472 /* Also make this data structure NULL */
473 edma3MemZero((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
474 sizeof(EDMA3_RM_InstanceInitConfig));
475 }
477 /* Initialize the global edma3DmaChTccMapping array with EDMA3_MAX_TCC */
478 for ( count = 0u;
479 count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels;
480 count++
481 )
482 {
483 edma3DmaChTccMapping[phyCtrllerInstId][count] = EDMA3_MAX_TCC;
484 }
486 /* Initialize the global edma3QdmaChTccMapping array with EDMA3_MAX_TCC */
487 for ( count = 0u;
488 count < resMgrObj[phyCtrllerInstId].gblCfgParams.numQdmaChannels;
489 count++
490 )
491 {
492 edma3QdmaChTccMapping[phyCtrllerInstId][count] = EDMA3_MAX_TCC;
493 }
495 /* Reset edma3RmChBoundRes Array*/
496 for (count = 0u; count < EDMA3_MAX_LOGICAL_CH; count++)
497 {
498 edma3RmChBoundRes[phyCtrllerInstId][count].paRAMId = -1;
499 edma3RmChBoundRes[phyCtrllerInstId][count].tcc = EDMA3_MAX_TCC;
500 }
502 /* Make the contiguousParamRes array NULL */
503 edma3MemZero((void *)(&(contiguousParamRes[0u])),
504 sizeof(contiguousParamRes));
507 /**
508 * Check the misc configuration options structure.
509 * Check whether the global registers' initialization
510 * is required or not.
511 * It is required ONLY if RM is running on the Master Processor.
512 */
513 if (NULL != miscOpt)
514 {
515 if (miscOpt->isSlave == FALSE)
516 {
517 /* It is a master. */
518 edma3GlobalRegionInit(phyCtrllerInstId);
519 }
520 }
521 else
522 {
523 /* By default, global registers will be initialized. */
524 edma3GlobalRegionInit(phyCtrllerInstId);
525 }
526 }
527 }
529 return result;
530 }
532 EDMA3_RM_Result EDMA3_RM_delete (uint32_t phyCtrllerInstId,
533 const void *param)
534 {
535 EDMA3_RM_Result result = EDMA3_RM_SOK;
537 /* If parameter checking is enabled... */
538 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
539 if (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
540 {
541 result = EDMA3_RM_E_INVALID_PARAM;
542 }
543 #endif
545 /* Check if the parameters are OK. */
546 if (EDMA3_RM_SOK == result)
547 {
548 /*to remove CCS remark: parameter "param" was never referenced */
549 (void)param;
551 /**
552 * If number of RM Instances is 0, then state should be
553 * EDMA3_RM_CLOSED OR EDMA3_RM_CREATED.
554 */
555 if ((NULL == resMgrObj[phyCtrllerInstId].numOpens)
556 && ((resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CLOSED)
557 && (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CREATED)))
558 {
559 result = EDMA3_RM_E_OBJ_NOT_CLOSED;
560 }
561 else
562 {
563 /**
564 * If number of RM Instances is NOT 0, then this function
565 * SHOULD NOT be called by anybody.
566 */
567 if (NULL != resMgrObj[phyCtrllerInstId].numOpens)
568 {
569 result = EDMA3_RM_E_INVALID_STATE;
570 }
571 else
572 {
573 /** Change state to EDMA3_RM_DELETED */
574 resMgrObj[phyCtrllerInstId].state = EDMA3_RM_DELETED;
576 /* Reset the Allocated TCCs Array also. */
577 allocatedTCCs[phyCtrllerInstId][0u] = 0x0u;
578 allocatedTCCs[phyCtrllerInstId][1u] = 0x0u;
580 /* Also, reset the RM Object Global Config Info */
581 edma3MemZero((void *)&(resMgrObj[phyCtrllerInstId].gblCfgParams),
582 sizeof(EDMA3_RM_GblConfigParams));
583 }
584 }
585 }
587 return result;
588 }
590 EDMA3_RM_Handle EDMA3_RM_open (uint32_t phyCtrllerInstId,
591 const EDMA3_RM_Param *initParam,
592 EDMA3_RM_Result *errorCode)
593 {
594 uint32_t intState = 0u;
595 uint32_t resMgrIdx = 0u;
596 EDMA3_RM_Result result = EDMA3_RM_SOK;
597 EDMA3_RM_Obj *rmObj = NULL;
598 EDMA3_RM_Instance *rmInstance = NULL;
599 EDMA3_RM_Instance *temp_ptr_rm_inst = NULL;
600 EDMA3_RM_Handle retVal = NULL;
601 uint32_t dmaChDwrds = 0u;
602 uint32_t paramSetDwrds = 0u;
603 uint32_t tccDwrds = 0u;
604 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
606 #ifdef GENERIC
607 /* GENERIC libraries don't come with a default confifguration, always
608 needs to be supplied with a parameter */
609 if ((initParam == NULL) || (initParam->rmInstInitConfig == NULL))
610 {
611 result = EDMA3_RM_E_INVALID_PARAM;
612 }
613 #endif
616 /* If parameter checking is enabled... */
617 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
618 if (((initParam == NULL)
619 || (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES))
620 || (errorCode == NULL))
621 {
622 result = EDMA3_RM_E_INVALID_PARAM;
623 }
624 #endif
626 /* Check if the parameters are OK. */
627 if (EDMA3_RM_SOK == result)
628 {
629 /* Check whether the semaphore handle is null or not */
630 if (NULL == initParam->rmSemHandle)
631 {
632 result = EDMA3_RM_E_INVALID_PARAM;
633 }
634 else
635 {
636 rmObj = &resMgrObj[phyCtrllerInstId];
637 if (
638 (NULL == rmObj)
639 || (initParam->regionId >=
640 resMgrObj[phyCtrllerInstId].gblCfgParams.numRegions)
641 )
642 {
643 result = EDMA3_RM_E_INVALID_PARAM;
644 }
645 else
646 {
647 edma3OsProtectEntry (phyCtrllerInstId,
648 EDMA3_OS_PROTECT_INTERRUPT,
649 &intState);
651 /** Check state of RM Object.
652 * If no RM instance is opened and this is the first one,
653 * then state should be created/closed.
654 */
655 if ((rmObj->numOpens == NULL) &&
656 ((rmObj->state != EDMA3_RM_CREATED) &&
657 (rmObj->state != EDMA3_RM_CLOSED)))
658 {
659 result = EDMA3_RM_E_INVALID_STATE;
660 edma3OsProtectExit (phyCtrllerInstId,
661 EDMA3_OS_PROTECT_INTERRUPT,
662 intState);
663 }
664 else
665 {
666 /**
667 * If num of instances opened is more than 0 and less than
668 * max allowed, then state should be opened.
669 */
670 if (((rmObj->numOpens > 0) &&
671 (rmObj->numOpens < EDMA3_MAX_RM_INSTANCES))
672 && (rmObj->state != EDMA3_RM_OPENED))
673 {
674 result = EDMA3_RM_E_INVALID_STATE;
675 edma3OsProtectExit (phyCtrllerInstId,
676 EDMA3_OS_PROTECT_INTERRUPT,
677 intState);
678 }
679 else
680 {
681 /* Check if max opens have passed */
682 if (rmObj->numOpens >= EDMA3_MAX_RM_INSTANCES)
683 {
684 result = EDMA3_RM_E_MAX_RM_INST_OPENED;
685 edma3OsProtectExit (phyCtrllerInstId,
686 EDMA3_OS_PROTECT_INTERRUPT,
687 intState);
688 }
689 }
690 }
691 }
692 }
693 }
695 if (EDMA3_RM_SOK == result)
696 {
697 /*
698 * Check whether the RM instance is Master or not.
699 * If it is master, check whether a master already exists
700 * or not. There should NOT be more than 1 master.
701 * Return error code if master already exists
702 */
703 if ((TRUE == masterExists[phyCtrllerInstId]) && (TRUE == initParam->isMaster))
704 {
705 /* No two masters should exist, return error */
706 result = EDMA3_RM_E_RM_MASTER_ALREADY_EXISTS;
707 edma3OsProtectExit (phyCtrllerInstId,
708 EDMA3_OS_PROTECT_INTERRUPT,
709 intState);
710 }
711 else
712 {
713 /* Create Res Mgr Instance */
714 for (resMgrIdx = 0u; resMgrIdx < EDMA3_MAX_RM_INSTANCES; resMgrIdx++)
715 {
716 temp_ptr_rm_inst = ((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
718 if (NULL != temp_ptr_rm_inst)
719 {
720 if (NULL == temp_ptr_rm_inst->pResMgrObjHandle)
721 {
722 /* Handle to the EDMA3 HW Object */
723 temp_ptr_rm_inst->pResMgrObjHandle = rmObj;
724 /* Handle of the Res Mgr Instance */
725 rmInstance = temp_ptr_rm_inst;
727 /* Also make this data structure NULL, just for safety. */
728 edma3MemZero((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
729 sizeof(EDMA3_RM_InstanceInitConfig));
731 break;
732 }
733 }
734 }
736 /* Check whether a RM instance has been created or not */
737 if (NULL == rmInstance)
738 {
739 result = EDMA3_RM_E_MAX_RM_INST_OPENED;
740 edma3OsProtectExit (phyCtrllerInstId,
741 EDMA3_OS_PROTECT_INTERRUPT,
742 intState);
743 }
744 else
745 {
746 /* Copy the InitPaRAM first */
747 edma3MemCpy((void *)(&rmInstance->initParam),
748 (const void *)(initParam),
749 sizeof (EDMA3_RM_Param));
751 if (rmObj->gblCfgParams.globalRegs != NULL)
752 {
753 globalRegs = (volatile EDMA3_CCRL_Regs *)
754 (rmObj->gblCfgParams.globalRegs);
755 rmInstance->shadowRegs = (EDMA3_CCRL_ShadowRegs *)
756 &(globalRegs->SHADOW[rmInstance->initParam.regionId]);
758 /* copy the instance specific semaphore handle */
759 rmInstance->initParam.rmSemHandle = initParam->rmSemHandle;
761 /**
762 * Check whether user has passed information about resources
763 * owned and reserved by this instance. This is region specific
764 * information. If he has not passed, dafault static config info will be taken
765 * from the config file edma3Cfg.c, according to the regionId specified.
766 *
767 * resMgrIdx specifies the RM instance number created just now.
768 * Use it to populate the userInitConfig [].
769 */
770 #ifndef GENERIC
771 if (NULL == initParam->rmInstInitConfig)
772 {
773 /* Take the info from the specific config file */
774 edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
775 (const void *)(&defInstInitConfig[phyCtrllerInstId][initParam->regionId]),
776 sizeof (EDMA3_RM_InstanceInitConfig));
777 }
778 else
779 {
780 #endif
781 /* User has passed the region specific info. */
782 edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
783 (const void *)(initParam->rmInstInitConfig),
784 sizeof (EDMA3_RM_InstanceInitConfig));
785 #ifndef GENERIC
786 }
787 #endif
789 rmInstance->initParam.rmInstInitConfig =
790 ((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
792 dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / 32u;
793 if (dmaChDwrds == 0)
794 {
795 /* In case DMA channels are < 32 */
796 dmaChDwrds = 1;
797 }
799 paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / 32u;
800 if (paramSetDwrds == 0)
801 {
802 /* In case PaRAM Sets are < 32 */
803 paramSetDwrds = 1;
804 }
806 tccDwrds = rmObj->gblCfgParams.numTccs / 32u;
807 if (tccDwrds == 0)
808 {
809 /* In case TCCs are < 32 */
810 tccDwrds = 1;
811 }
813 for (resMgrIdx = 0u; resMgrIdx < dmaChDwrds; ++resMgrIdx)
814 {
815 rmInstance->avlblDmaChannels[resMgrIdx]
816 = rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resMgrIdx];
817 }
819 rmInstance->avlblQdmaChannels[0u]
820 = rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u];
822 for (resMgrIdx = 0u; resMgrIdx < paramSetDwrds; ++resMgrIdx)
823 {
824 rmInstance->avlblPaRAMSets[resMgrIdx]
825 = rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[resMgrIdx];
826 }
828 for (resMgrIdx = 0u; resMgrIdx < tccDwrds; ++resMgrIdx)
829 {
830 rmInstance->avlblTccs [resMgrIdx]
831 = rmInstance->initParam.rmInstInitConfig->ownTccs[resMgrIdx];
832 }
834 /*
835 * Mark the PaRAM Sets corresponding to DMA channels as RESERVED.
836 * For e.g. on a platform where only 32 DMA channels exist,
837 * mark the first 32 PaRAM Sets as reserved. These param sets
838 * will not be returned in case user requests for ANY link
839 * channel.
840 */
841 for (resMgrIdx = 0u; resMgrIdx < rmObj->gblCfgParams.numDmaChannels; ++resMgrIdx)
842 {
843 rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[resMgrIdx/32u] |= (1u<<(resMgrIdx%32u));
844 }
846 /*
847 * If the EDMA RM instance is MASTER (ie. initParam->isMaster
848 * is TRUE), save the region ID.
849 * Only this shadow region will receive the
850 * EDMA3 interrupts, if enabled.
851 */
852 if (TRUE == initParam->isMaster)
853 {
854 /* Store the region id to use it in the ISRs */
855 edma3RegionId = rmInstance->initParam.regionId;
856 masterExists[phyCtrllerInstId] = TRUE;
857 }
859 if (TRUE == initParam->regionInitEnable)
860 {
861 edma3ShadowRegionInit (rmInstance);
862 }
864 /**
865 * By default, PaRAM Sets allocated using this RM Instance
866 * will get cleared during their allocation.
867 * User can stop their clearing by calling specific IOCTL
868 * command.
869 */
870 rmInstance->paramInitRequired = TRUE;
873 /**
874 * By default, during the EDMA3_RM_allocLogicalChannel (),
875 * global EDMA3 registers (DCHMAP/QCHMAP) and the allocated
876 * PaRAM Set will be programmed accordingly, for users using this
877 * RM Instance.
878 * User can stop their pre-programming by calling
879 * EDMA3_RM_IOCTL_SET_GBL_REG_MODIFY_OPTION
880 * IOCTL command.
881 */
882 rmInstance->regModificationRequired = TRUE;
885 if (EDMA3_RM_SOK == result)
886 {
887 rmObj->state = EDMA3_RM_OPENED;
888 /* Increase the Instance count */
889 resMgrObj[phyCtrllerInstId].numOpens++;
890 retVal = rmInstance;
891 }
892 }
893 else
894 {
895 result = EDMA3_RM_E_INVALID_PARAM;
896 }
898 edma3OsProtectExit (phyCtrllerInstId,
899 EDMA3_OS_PROTECT_INTERRUPT,
900 intState);
901 }
902 }
903 }
905 *errorCode = result;
906 return (EDMA3_RM_Handle)retVal;
907 }
909 EDMA3_RM_Result EDMA3_RM_close (EDMA3_RM_Handle hEdmaResMgr,
910 const void *param)
911 {
912 EDMA3_RM_Result result = EDMA3_RM_SOK;
913 uint32_t intState = 0u;
914 uint32_t resMgrIdx = 0u;
915 EDMA3_RM_Obj *rmObj = NULL;
916 EDMA3_RM_Instance *rmInstance = NULL;
917 uint32_t dmaChDwrds;
918 uint32_t paramSetDwrds;
919 uint32_t tccDwrds;
921 /*to remove CCS remark: parameter "param" was never referenced */
922 (void)param;
924 /* If parameter checking is enabled... */
925 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
926 if (NULL == hEdmaResMgr)
927 {
928 result = EDMA3_RM_E_INVALID_PARAM;
929 }
930 #endif
932 /* Check if the parameters are OK. */
933 if (EDMA3_RM_SOK == result)
934 {
935 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
936 rmObj = rmInstance->pResMgrObjHandle;
938 if (rmObj == NULL)
939 {
940 result = (EDMA3_RM_E_INVALID_PARAM);
941 }
942 else
943 {
944 /* Check state of driver, state should be opened */
945 if (rmObj->state != EDMA3_RM_OPENED)
946 {
947 result = (EDMA3_RM_E_OBJ_NOT_OPENED);
948 }
949 else
950 {
951 dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / 32u;
952 paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / 32u;
953 tccDwrds = rmObj->gblCfgParams.numTccs / 32u;
955 /* Set the instance config as NULL*/
956 for (resMgrIdx = 0u; resMgrIdx < dmaChDwrds; ++resMgrIdx)
957 {
958 rmInstance->avlblDmaChannels[resMgrIdx] = 0x0u;
959 }
960 for (resMgrIdx = 0u; resMgrIdx < paramSetDwrds; ++resMgrIdx)
961 {
962 rmInstance->avlblPaRAMSets[resMgrIdx] = 0x0u;
963 }
964 rmInstance->avlblQdmaChannels[0u] = 0x0u;
965 for (resMgrIdx = 0u; resMgrIdx < tccDwrds; ++resMgrIdx)
966 {
967 rmInstance->avlblTccs[resMgrIdx] = 0x0u;
968 }
970 /**
971 * If this is the Master Instance, reset the static variable
972 * 'masterExists[]'.
973 */
974 if (TRUE == rmInstance->initParam.isMaster)
975 {
976 masterExists[rmObj->phyCtrllerInstId] = FALSE;
977 edma3RegionId = EDMA3_MAX_REGIONS;
978 }
980 /* Reset the Initparam for this RM Instance */
981 edma3MemZero((void *)&(rmInstance->initParam),
982 sizeof(EDMA3_RM_Param));
984 /* Critical section starts */
985 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
986 EDMA3_OS_PROTECT_INTERRUPT,
987 &intState);
989 /* Decrease the Number of Opens */
990 --rmObj->numOpens;
991 if (NULL == rmObj->numOpens)
992 {
993 edma3MemZero((void *)&(edma3RmChBoundRes[rmObj->phyCtrllerInstId]),
994 sizeof(edma3RmChBoundRes[rmObj->phyCtrllerInstId]));
996 rmObj->state = EDMA3_RM_CLOSED;
997 }
999 /* Critical section ends */
1000 edma3OsProtectExit (rmObj->phyCtrllerInstId,
1001 EDMA3_OS_PROTECT_INTERRUPT,
1002 intState);
1004 rmInstance->pResMgrObjHandle = NULL;
1005 rmInstance->shadowRegs = NULL;
1006 rmInstance = NULL;
1007 }
1008 }
1009 }
1011 return result;
1012 }
1014 EDMA3_RM_Result EDMA3_RM_allocResource(EDMA3_RM_Handle hEdmaResMgr,
1015 EDMA3_RM_ResDesc *resObj)
1016 {
1017 EDMA3_RM_Instance *rmInstance = NULL;
1018 EDMA3_RM_Obj *rmObj = NULL;
1019 EDMA3_RM_Result result = EDMA3_RM_SOK;
1020 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
1021 uint32_t avlblIdx = 0u;
1022 uint32_t resIdClr = 0x0;
1023 uint32_t resIdSet = 0x0;
1024 uint32_t resId;
1025 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1026 uint32_t mapXbarEvtToChanFlag = FALSE;
1027 uint32_t xBarEvtBeforeMap = 0;
1028 uint32_t edma3Id;
1030 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1031 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1032 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1033 EDMA3_DVT_dCOUNTER,
1034 EDMA3_DVT_dNONE,
1035 EDMA3_DVT_dNONE));
1036 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1038 /* If parameter checking is enabled... */
1039 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1040 if ((hEdmaResMgr == NULL) || (resObj == NULL))
1041 {
1042 result = (EDMA3_RM_E_INVALID_PARAM);
1043 }
1044 #endif
1046 /* Check if the parameters are OK. */
1047 if (EDMA3_RM_SOK == result)
1048 {
1049 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1050 rmObj = rmInstance->pResMgrObjHandle;
1052 if ((rmObj == NULL) ||
1053 (rmObj->gblCfgParams.globalRegs == NULL))
1054 {
1055 result = (EDMA3_RM_E_INVALID_PARAM);
1056 }
1057 else
1058 {
1059 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1060 edma3Id = rmObj->phyCtrllerInstId;
1061 resId = resObj->resId;
1063 resIdClr = (uint32_t)(~(1u << (resId%32u)));
1064 resIdSet = (1u << (resId%32u));
1066 if ( rmInstance->mapXbarToChan != NULL)
1067 {
1068 xBarEvtBeforeMap = resId;
1069 if ((resId > rmObj->gblCfgParams.numDmaChannels) &&
1070 (resId != EDMA3_RM_RES_ANY) &&
1071 (resObj->type == EDMA3_RM_RES_DMA_CHANNEL))
1072 {
1073 result = rmInstance->mapXbarToChan(xBarEvtBeforeMap,
1074 &resObj->resId,
1075 &rmInstance->rmXbarToEvtMapConfig);
1076 if (EDMA3_RM_SOK == result)
1077 {
1078 resId = resObj->resId;
1079 mapXbarEvtToChanFlag = TRUE;
1080 }
1081 }
1082 }
1084 if (result == EDMA3_RM_SOK)
1085 {
1086 /**
1087 * Take the instance specific semaphore, to prevent simultaneous
1088 * access to the shared resources.
1089 */
1090 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
1091 EDMA3_OSSEM_NO_TIMEOUT);
1092 if (EDMA3_RM_SOK == semResult)
1093 {
1094 switch (resObj->type)
1095 {
1096 case EDMA3_RM_RES_DMA_CHANNEL :
1097 {
1098 if (resId == EDMA3_RM_RES_ANY)
1099 {
1100 for (avlblIdx=0u;
1101 avlblIdx <
1102 rmObj->gblCfgParams.numDmaChannels;
1103 ++avlblIdx)
1104 {
1105 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[avlblIdx/32u])
1106 &
1107 (rmInstance->avlblDmaChannels[avlblIdx/32u])
1108 &
1109 ~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[avlblIdx/32u])
1110 &
1111 (1u << (avlblIdx%32u))) != FALSE)
1112 {
1113 /*
1114 * Match found.
1115 * A resource which is owned by this instance of the
1116 * Resource Manager and which is presently available
1117 * and which has not been reserved - is found.
1118 */
1119 resObj->resId = avlblIdx;
1120 /*
1121 * Mark the 'match found' resource as "Not Available"
1122 * for future requests
1123 */
1124 rmInstance->avlblDmaChannels[avlblIdx/32u] &= (uint32_t)(~(1u << (avlblIdx%32u)));
1126 /**
1127 * Check if the register modification flag is
1128 * set or not.
1129 */
1130 if (TRUE == rmInstance->regModificationRequired)
1131 {
1132 /**
1133 * Enable the DMA channel in the
1134 * DRAE/DRAEH registers also.
1135 */
1136 if (avlblIdx < 32u)
1137 {
1138 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1139 |= (0x1u << avlblIdx);
1140 }
1141 else
1142 {
1143 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1144 |= (0x1u << (avlblIdx - 32u));
1145 }
1146 }
1148 result = EDMA3_RM_SOK;
1149 break;
1150 }
1151 }
1152 /*
1153 * If none of the owned resources of this type is available
1154 * then report "All Resources of this type not available" error
1155 */
1156 if (avlblIdx == rmObj->gblCfgParams.numDmaChannels)
1157 {
1158 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1159 }
1160 }
1161 else
1162 {
1163 if (resId < rmObj->gblCfgParams.numDmaChannels)
1164 {
1165 /*
1166 * Check if specified resource is owned
1167 * by this instance of the resource manager
1168 */
1169 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resId/32u])&(resIdSet))!=FALSE)
1170 {
1171 /* Now check if specified resource is available presently*/
1172 if (((rmInstance->avlblDmaChannels[resId/32u])&(resIdSet))!=FALSE)
1173 {
1174 /*
1175 * Mark the specified channel as "Not Available"
1176 * for future requests
1177 */
1178 rmInstance->avlblDmaChannels[resId/32u] &= resIdClr;
1180 /**
1181 * Check if the register modification flag is
1182 * set or not.
1183 */
1184 if (TRUE == rmInstance->regModificationRequired)
1185 {
1186 if (resId < 32u)
1187 {
1188 rmInstance->shadowRegs->EECR = (1UL << resId);
1190 /**
1191 * Enable the DMA channel in the
1192 * DRAE registers also.
1193 */
1194 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1195 |= (0x1u << resId);
1196 }
1197 else
1198 {
1199 rmInstance->shadowRegs->EECRH = (1UL << resId);
1201 /**
1202 * Enable the DMA channel in the
1203 * DRAEH registers also.
1204 */
1205 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1206 |= (0x1u << (resId - 32u));
1207 }
1208 }
1210 result = EDMA3_RM_SOK;
1211 }
1212 else
1213 {
1214 /* Specified resource is owned but is already booked */
1215 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1216 }
1217 }
1218 else
1219 {
1220 /*
1221 * Specified resource is not owned by this instance
1222 * of the Resource Manager
1223 */
1224 result = EDMA3_RM_E_RES_NOT_OWNED;
1225 }
1226 }
1227 else
1228 {
1229 result = EDMA3_RM_E_INVALID_PARAM;
1230 }
1231 }
1232 }
1233 break;
1235 case EDMA3_RM_RES_QDMA_CHANNEL :
1236 {
1237 if (resId == EDMA3_RM_RES_ANY)
1238 {
1239 for (avlblIdx=0u; avlblIdx<rmObj->gblCfgParams.numQdmaChannels; ++avlblIdx)
1240 {
1241 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[avlblIdx/32u])
1242 &
1243 (rmInstance->avlblQdmaChannels[avlblIdx/32u])
1244 &
1245 ~(rmInstance->initParam.rmInstInitConfig->resvdQdmaChannels[avlblIdx/32u])
1246 &
1247 (1u << (avlblIdx%32u))) != FALSE)
1248 {
1249 resObj->resId = avlblIdx;
1250 rmInstance->avlblQdmaChannels[avlblIdx/32u] &= (uint32_t)(~(1u << (avlblIdx%32u)));
1252 /**
1253 * Check if the register modification flag is
1254 * set or not.
1255 */
1256 if (TRUE == rmInstance->regModificationRequired)
1257 {
1258 /**
1259 * Enable the QDMA channel in the
1260 * QRAE register also.
1261 */
1262 gblRegs->QRAE[rmInstance->initParam.regionId]
1263 |= (0x1u << avlblIdx);
1264 }
1266 result = EDMA3_RM_SOK;
1267 break;
1268 }
1269 }
1270 /*
1271 * If none of the owned resources of this type is available
1272 * then report "All Resources of this type not available" error
1273 */
1274 if (avlblIdx == rmObj->gblCfgParams.numQdmaChannels)
1275 {
1276 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1277 }
1278 }
1279 else
1280 {
1281 if (resId < rmObj->gblCfgParams.numQdmaChannels)
1282 {
1283 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32u])&(resIdSet))!=FALSE)
1284 {
1285 if (((rmInstance->avlblQdmaChannels [resId/32u])&(resIdSet))!=FALSE)
1286 {
1287 rmInstance->avlblQdmaChannels [resId/32u] &= resIdClr;
1289 /**
1290 * Check if the register modification flag is
1291 * set or not.
1292 */
1293 if (TRUE == rmInstance->regModificationRequired)
1294 {
1295 /**
1296 * Enable the QDMA channel in the
1297 * QRAE register also.
1298 */
1299 gblRegs->QRAE[rmInstance->initParam.regionId]
1300 |= (0x1u << resId);
1301 }
1303 result = EDMA3_RM_SOK;
1304 }
1305 else
1306 {
1307 /* Specified resource is owned but is already booked */
1308 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1309 }
1310 }
1311 else
1312 {
1313 /*
1314 * Specified resource is not owned by this instance
1315 * of the Resource Manager
1316 */
1317 result = EDMA3_RM_E_RES_NOT_OWNED;
1318 }
1319 }
1320 else
1321 {
1322 result = EDMA3_RM_E_INVALID_PARAM;
1323 }
1324 }
1325 }
1326 break;
1328 case EDMA3_RM_RES_TCC :
1329 {
1330 if (resId == EDMA3_RM_RES_ANY)
1331 {
1332 for (avlblIdx=0u; avlblIdx<rmObj->gblCfgParams.numTccs; ++avlblIdx)
1333 {
1334 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [avlblIdx/32u])
1335 & (rmInstance->avlblTccs [avlblIdx/32u])
1336 & ~(rmInstance->initParam.rmInstInitConfig->resvdTccs [avlblIdx/32u])
1337 & (1u << (avlblIdx%32u)))!=FALSE)
1338 {
1339 resObj->resId = avlblIdx;
1340 rmInstance->avlblTccs [avlblIdx/32u] &= (uint32_t)(~(1u << (avlblIdx%32u)));
1342 /**
1343 * Check if the register modification flag is
1344 * set or not.
1345 */
1346 if (TRUE == rmInstance->regModificationRequired)
1347 {
1348 /**
1349 * Enable the Interrupt channel in the
1350 * DRAE/DRAEH registers also.
1351 * Also, If the region id coming from this
1352 * RM instance is same as the Master RM
1353 * Instance's region id, only then we will be
1354 * getting the interrupts on the same side.
1355 * So save the TCC in the allocatedTCCs[] array.
1356 */
1357 if (avlblIdx < 32u)
1358 {
1359 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1360 |= (0x1u << avlblIdx);
1362 /**
1363 * Do not modify this global array if the register
1364 * modificatio flag is not set.
1365 * Reason being is based on this flag, the IPR/ICR
1366 * or error bit is cleared in the completion or
1367 * error handler ISR.
1368 */
1369 if (edma3RegionId == rmInstance->initParam.regionId)
1370 {
1371 allocatedTCCs[edma3Id][0u] |= (0x1u << avlblIdx);
1372 }
1373 }
1374 else
1375 {
1376 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1377 |= (0x1u << (avlblIdx - 32u));
1379 /**
1380 * Do not modify this global array if the register
1381 * modificatio flag is not set.
1382 * Reason being is based on this flag, the IPR/ICR
1383 * or error bit is cleared in the completion or
1384 * error handler ISR.
1385 */
1386 if (edma3RegionId == rmInstance->initParam.regionId)
1387 {
1388 allocatedTCCs[edma3Id][1u] |= (0x1u << (avlblIdx - 32u));
1389 }
1390 }
1391 }
1394 result = EDMA3_RM_SOK;
1395 break;
1396 }
1397 }
1398 /*
1399 * If none of the owned resources of this type is available
1400 * then report "All Resources of this type not available" error
1401 */
1402 if ( avlblIdx == rmObj->gblCfgParams.numTccs)
1403 {
1404 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1405 }
1406 }
1407 else
1408 {
1409 if (resId < rmObj->gblCfgParams.numTccs)
1410 {
1411 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32u])&(resIdSet))!=FALSE)
1412 {
1413 if (((rmInstance->avlblTccs [resId/32u])&(resIdSet))!=FALSE)
1414 {
1415 rmInstance->avlblTccs [resId/32u] &= resIdClr;
1417 /**
1418 * Check if the register modification flag is
1419 * set or not.
1420 */
1421 if (TRUE == rmInstance->regModificationRequired)
1422 {
1423 /**
1424 * Enable the Interrupt channel in the
1425 * DRAE/DRAEH registers also.
1426 * Also, If the region id coming from this
1427 * RM instance is same as the Master RM
1428 * Instance's region id, only then we will be
1429 * getting the interrupts on the same side.
1430 * So save the TCC in the allocatedTCCs[] array.
1431 */
1432 if (resId < 32u)
1433 {
1434 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1435 |= (0x1u << resId);
1437 /**
1438 * Do not modify this global array if the register
1439 * modificatio flag is not set.
1440 * Reason being is based on this flag, the IPR/ICR
1441 * or error bit is cleared in the completion or
1442 * error handler ISR.
1443 */
1444 if (edma3RegionId == rmInstance->initParam.regionId)
1445 {
1446 allocatedTCCs[edma3Id][0u] |= (0x1u << resId);
1447 }
1448 }
1449 else
1450 {
1451 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1452 |= (0x1u << (resId - 32u));
1454 /**
1455 * Do not modify this global array if the register
1456 * modificatio flag is not set.
1457 * Reason being is based on this flag, the IPR/ICR
1458 * or error bit is cleared in the completion or
1459 * error handler ISR.
1460 */
1461 if (edma3RegionId == rmInstance->initParam.regionId)
1462 {
1463 allocatedTCCs[edma3Id][1u] |= (0x1u << (resId - 32u));
1464 }
1465 }
1466 }
1468 result = EDMA3_RM_SOK;
1469 }
1470 else
1471 {
1472 /* Specified resource is owned but is already booked */
1473 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1474 }
1475 }
1476 else
1477 {
1478 /*
1479 * Specified resource is not owned by this instance
1480 * of the Resource Manager
1481 */
1482 result = EDMA3_RM_E_RES_NOT_OWNED;
1483 }
1484 }
1485 else
1486 {
1487 result = EDMA3_RM_E_INVALID_PARAM;
1488 }
1489 }
1490 }
1491 break;
1493 case EDMA3_RM_RES_PARAM_SET :
1494 {
1495 if (resId == EDMA3_RM_RES_ANY)
1496 {
1497 for (avlblIdx=0u; avlblIdx<rmObj->gblCfgParams.numPaRAMSets; ++avlblIdx)
1498 {
1499 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [avlblIdx/32u])
1500 &
1501 (rmInstance->avlblPaRAMSets [avlblIdx/32u])
1502 &
1503 ~(rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets [avlblIdx/32u])
1504 &
1505 (1u << (avlblIdx%32u)))!=FALSE)
1506 {
1507 resObj->resId = avlblIdx;
1508 rmInstance->avlblPaRAMSets [avlblIdx/32u] &= (uint32_t)(~(1u << (avlblIdx%32u)));
1510 /**
1511 * Also, make the actual PARAM Set NULL, checking the flag
1512 * whether it is required or not.
1513 */
1514 if ((TRUE == rmInstance->regModificationRequired)
1515 && (TRUE == rmInstance->paramInitRequired))
1516 {
1517 edma3MemZero((void *)(&gblRegs->PARAMENTRY[avlblIdx]),
1518 sizeof(gblRegs->PARAMENTRY[avlblIdx]));
1519 }
1521 result = EDMA3_RM_SOK;
1522 break;
1523 }
1524 }
1525 /*
1526 * If none of the owned resources of this type is available
1527 * then report "All Resources of this type not available" error
1528 */
1529 if ( avlblIdx == rmObj->gblCfgParams.numPaRAMSets)
1530 {
1531 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1532 }
1533 }
1534 else
1535 {
1536 if (resId < rmObj->gblCfgParams.numPaRAMSets)
1537 {
1538 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32u])&(resIdSet))!=FALSE)
1539 {
1540 if (((rmInstance->avlblPaRAMSets [resId/32u])&(resIdSet)) !=FALSE)
1541 {
1542 rmInstance->avlblPaRAMSets [resId/32u] &= resIdClr;
1544 /**
1545 * Also, make the actual PARAM Set NULL, checking the flag
1546 * whether it is required or not.
1547 */
1548 if ((TRUE == rmInstance->regModificationRequired)
1549 && (TRUE == rmInstance->paramInitRequired))
1550 {
1551 edma3MemZero((void *)(&gblRegs->PARAMENTRY[resId]),
1552 sizeof(gblRegs->PARAMENTRY[resId]));
1553 }
1555 result = EDMA3_RM_SOK;
1556 }
1557 else
1558 {
1559 /* Specified resource is owned but is already booked */
1560 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1561 }
1562 }
1563 else
1564 {
1565 /*
1566 * Specified resource is not owned by this instance
1567 * of the Resource Manager
1568 */
1569 result = EDMA3_RM_E_RES_NOT_OWNED;
1570 }
1571 }
1572 else
1573 {
1574 result = EDMA3_RM_E_INVALID_PARAM;
1575 }
1576 }
1577 }
1578 break;
1580 default:
1581 result = EDMA3_RM_E_INVALID_PARAM;
1582 break;
1583 }
1585 /* Return the semaphore back */
1586 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
1587 }
1588 }
1589 }
1590 }
1592 /**
1593 * Check the Resource Allocation Result 'result' first. If Resource
1594 * Allocation has resulted in an error, return it (having more priority than
1595 * semResult.
1596 * Else, return semResult.
1597 */
1598 if (EDMA3_RM_SOK == result)
1599 {
1600 /**
1601 * Resource Allocation successful, return semResult for returning
1602 * semaphore.
1603 */
1604 result = semResult;
1605 if ((rmInstance->configScrMapXbarToEvt != NULL) &&
1606 (mapXbarEvtToChanFlag == TRUE))
1607 {
1608 rmInstance->configScrMapXbarToEvt(xBarEvtBeforeMap, resObj->resId);
1609 }
1610 }
1612 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1613 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1614 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1615 EDMA3_DVT_dCOUNTER,
1616 EDMA3_DVT_dNONE,
1617 EDMA3_DVT_dNONE));
1618 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1620 return result;
1621 }
1623 EDMA3_RM_Result EDMA3_RM_freeResource(EDMA3_RM_Handle hEdmaResMgr,
1624 const EDMA3_RM_ResDesc *resObj)
1625 {
1626 EDMA3_RM_Instance *rmInstance = NULL;
1627 EDMA3_RM_Obj *rmObj = NULL;
1628 EDMA3_RM_Result result = EDMA3_RM_SOK;
1629 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
1630 uint32_t resId;
1631 uint32_t resIdSet = 0x0;
1632 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1633 uint32_t edma3Id;
1635 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1636 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1637 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1638 EDMA3_DVT_dCOUNTER,
1639 EDMA3_DVT_dNONE,
1640 EDMA3_DVT_dNONE));
1641 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1643 /* If parameter checking is enabled... */
1644 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1645 if ((hEdmaResMgr == NULL) || (resObj == NULL))
1646 {
1647 result = EDMA3_RM_E_INVALID_PARAM;
1648 }
1649 #endif
1651 /* Check if the parameters are OK. */
1652 if (EDMA3_RM_SOK == result)
1653 {
1654 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1655 rmObj = rmInstance->pResMgrObjHandle;
1657 if ((rmObj == NULL) ||
1658 (rmObj->gblCfgParams.globalRegs == NULL))
1659 {
1660 result = EDMA3_RM_E_INVALID_PARAM;
1661 }
1662 else
1663 {
1664 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1665 edma3Id = rmObj->phyCtrllerInstId;
1666 resId = resObj->resId;
1668 resIdSet = 1u << (resId%32u);
1670 /**
1671 * Take the instance specific semaphore, to prevent simultaneous
1672 * access to the shared resources.
1673 */
1674 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
1675 EDMA3_OSSEM_NO_TIMEOUT);
1677 if (EDMA3_RM_SOK == semResult)
1678 {
1679 switch (resObj->type)
1680 {
1681 case EDMA3_RM_RES_DMA_CHANNEL :
1682 {
1683 if (resId < rmObj->gblCfgParams.numDmaChannels)
1684 {
1685 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels [resId/32u]) & (resIdSet))!=FALSE)
1686 {
1687 if (((~(rmInstance->avlblDmaChannels[resId/32u]))&(resIdSet))!=FALSE)
1688 {
1689 /*
1690 * Mark the specified channel as "Available"
1691 * for future requests
1692 */
1693 rmInstance->avlblDmaChannels[resId/32u] |= resIdSet;
1695 /**
1696 * Check if the register modification flag is
1697 * set or not.
1698 */
1699 if (TRUE == rmInstance->regModificationRequired)
1700 {
1701 /**
1702 * DMA Channel is freed.
1703 * Reset the bit specific to the DMA channel
1704 * in the DRAE/DRAEH register also.
1705 */
1706 if (resId < 32u)
1707 {
1708 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1709 &= (~(0x1u << resId));
1710 }
1711 else
1712 {
1713 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1714 &= (~(0x1u << (resId-32u)));
1715 }
1716 }
1718 result = EDMA3_RM_SOK;
1719 }
1720 else
1721 {
1722 result = EDMA3_RM_E_RES_ALREADY_FREE;
1723 }
1724 }
1725 else
1726 {
1727 /*
1728 * Specified resource is not owned by this instance
1729 * of the Resource Manager
1730 */
1731 result = EDMA3_RM_E_RES_NOT_OWNED;
1732 }
1733 }
1734 else
1735 {
1736 result = EDMA3_RM_E_INVALID_PARAM;
1737 }
1738 }
1739 break;
1741 case EDMA3_RM_RES_QDMA_CHANNEL :
1742 {
1743 if (resId < rmObj->gblCfgParams.numQdmaChannels)
1744 {
1745 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32u]) & (resIdSet))!=FALSE)
1746 {
1747 if (((~(rmInstance->avlblQdmaChannels [resId/32u])) & (resIdSet))!=FALSE)
1748 {
1749 rmInstance->avlblQdmaChannels [resId/32u] |= resIdSet;
1751 /**
1752 * Check if the register modification flag is
1753 * set or not.
1754 */
1755 if (TRUE == rmInstance->regModificationRequired)
1756 {
1757 /**
1758 * QDMA Channel is freed.
1759 * Reset the bit specific to the QDMA channel
1760 * in the QRAE register also.
1761 */
1762 gblRegs->QRAE[rmInstance->initParam.regionId]
1763 &= (~(0x1u << resId));
1764 }
1766 result = EDMA3_RM_SOK;
1767 }
1768 else
1769 {
1770 result = EDMA3_RM_E_RES_ALREADY_FREE;
1771 }
1772 }
1773 else
1774 {
1775 /*
1776 * Specified resource is not owned by this instance
1777 * of the Resource Manager
1778 */
1779 result = EDMA3_RM_E_RES_NOT_OWNED;
1780 }
1781 }
1782 else
1783 {
1784 result = EDMA3_RM_E_INVALID_PARAM;
1785 }
1786 }
1787 break;
1789 case EDMA3_RM_RES_TCC :
1790 {
1791 if (resId < rmObj->gblCfgParams.numTccs)
1792 {
1793 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32u]) & (resIdSet))!=FALSE)
1794 {
1795 if (((~(rmInstance->avlblTccs [resId/32u])) & (resIdSet))!=FALSE)
1796 {
1797 rmInstance->avlblTccs [resId/32u] |= resIdSet;
1799 /**
1800 * Check if the register modification flag is
1801 * set or not.
1802 */
1803 if (TRUE == rmInstance->regModificationRequired)
1804 {
1805 /**
1806 * Interrupt Channel is freed.
1807 * Reset the bit specific to the Interrupt
1808 * channel in the DRAE/DRAEH register also.
1809 * Also, if we have earlier saved this
1810 * TCC in allocatedTCCs[] array,
1811 * remove it from there too.
1812 */
1813 if (resId < 32u)
1814 {
1815 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1816 &= (~(0x1u << resId));
1818 if (edma3RegionId == rmInstance->initParam.regionId)
1819 {
1820 allocatedTCCs[edma3Id][0u] &= (~(0x1u << resId));
1821 }
1822 }
1823 else
1824 {
1825 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1826 &= (~(0x1u << (resId-32u)));
1828 if (edma3RegionId == rmInstance->initParam.regionId)
1829 {
1830 allocatedTCCs[edma3Id][1u] &= (~(0x1u << (resId -32u)));
1831 }
1832 }
1833 }
1835 result = EDMA3_RM_SOK;
1836 }
1837 else
1838 {
1839 result = EDMA3_RM_E_RES_ALREADY_FREE;
1840 }
1841 }
1842 else
1843 {
1844 /*
1845 * Specified resource is not owned by this instance
1846 * of the Resource Manager
1847 */
1848 result = EDMA3_RM_E_RES_NOT_OWNED;
1849 }
1850 }
1851 else
1852 {
1853 result = EDMA3_RM_E_INVALID_PARAM;
1854 }
1855 }
1856 break;
1858 case EDMA3_RM_RES_PARAM_SET :
1859 {
1860 if (resId < rmObj->gblCfgParams.numPaRAMSets)
1861 {
1862 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32u])&(resIdSet))!=FALSE)
1863 {
1864 if (((~(rmInstance->avlblPaRAMSets [resId/32u]))&(resIdSet))!=FALSE)
1865 {
1866 rmInstance->avlblPaRAMSets [resId/32u] |= resIdSet;
1868 result = EDMA3_RM_SOK;
1869 }
1870 else
1871 {
1872 result = EDMA3_RM_E_RES_ALREADY_FREE;
1873 }
1874 }
1875 else
1876 {
1877 /*
1878 * Specified resource is not owned by this instance
1879 * of the Resource Manager
1880 */
1881 result = EDMA3_RM_E_RES_NOT_OWNED;
1882 }
1883 }
1884 else
1885 {
1886 result = EDMA3_RM_E_INVALID_PARAM;
1887 }
1888 }
1889 break;
1891 default:
1892 result = EDMA3_RM_E_INVALID_PARAM;
1893 break;
1894 }
1895 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
1896 }
1897 }
1898 }
1900 /**
1901 * Check the Free Resource Result 'result' first. If Free Resource
1902 * has resulted in an error, return it (having more priority than
1903 * semResult.
1904 * Else, return semResult.
1905 */
1906 if (EDMA3_RM_SOK == result)
1907 {
1908 /**
1909 * Free Resource successful, return semResult for returning
1910 * semaphore.
1911 */
1912 result = semResult;
1913 }
1915 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1916 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1917 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1918 EDMA3_DVT_dCOUNTER,
1919 EDMA3_DVT_dNONE,
1920 EDMA3_DVT_dNONE));
1921 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1923 return result;
1924 }
1926 EDMA3_RM_Result EDMA3_RM_allocLogicalChannel(EDMA3_RM_Handle hEdmaResMgr,
1927 EDMA3_RM_ResDesc *lChObj,
1928 uint32_t *pParam,
1929 uint32_t *pTcc)
1930 {
1931 EDMA3_RM_ResDesc *chObj;
1932 EDMA3_RM_ResDesc resObj;
1933 EDMA3_RM_Result result = EDMA3_RM_SOK;
1934 EDMA3_RM_Instance *rmInstance = NULL;
1935 EDMA3_RM_Obj *rmObj = NULL;
1936 uint32_t mappedPaRAMId=0u;
1937 uint32_t mappedTcc = EDMA3_RM_CH_NO_TCC_MAP;
1938 int32_t paRAMId = (int32_t)EDMA3_RM_RES_ANY;
1939 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1940 uint32_t qdmaChId = EDMA3_MAX_PARAM_SETS;
1941 uint32_t edma3Id;
1943 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1944 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1945 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1946 EDMA3_DVT_dCOUNTER,
1947 EDMA3_DVT_dNONE,
1948 EDMA3_DVT_dNONE));
1949 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1951 /* If parameter checking is enabled... */
1952 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1953 if ((lChObj == NULL) || (hEdmaResMgr == NULL))
1954 {
1955 result = EDMA3_RM_E_INVALID_PARAM;
1956 }
1957 #endif
1959 /* Check if the parameters are OK. */
1960 if (EDMA3_RM_SOK == result)
1961 {
1962 chObj = lChObj;
1964 if ((chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
1965 || (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL))
1966 {
1967 /**
1968 * If the request is for a DMA or QDMA channel, check the
1969 * pParam and pTcc objects also.
1970 * For the Link channel request, they could be NULL.
1971 */
1972 /* If parameter checking is enabled... */
1973 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1974 if ((pParam == NULL) || (pTcc == NULL))
1975 {
1976 result = EDMA3_RM_E_INVALID_PARAM;
1977 }
1978 #endif
1979 }
1980 }
1982 if (result == EDMA3_RM_SOK)
1983 {
1984 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1986 if (rmInstance == NULL)
1987 {
1988 result = EDMA3_RM_E_INVALID_PARAM;
1989 }
1990 }
1992 if (result == EDMA3_RM_SOK)
1993 {
1994 rmObj = rmInstance->pResMgrObjHandle;
1996 if (rmObj == NULL)
1997 {
1998 result = EDMA3_RM_E_INVALID_PARAM;
1999 }
2000 else
2001 {
2002 if (rmObj->gblCfgParams.globalRegs == NULL)
2003 {
2004 result = EDMA3_RM_E_INVALID_PARAM;
2005 }
2006 }
2007 }
2009 if (result == EDMA3_RM_SOK)
2010 {
2011 edma3Id = rmObj->phyCtrllerInstId;
2012 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2014 switch (chObj->type)
2015 {
2016 case EDMA3_RM_RES_DMA_CHANNEL:
2017 {
2018 if ((chObj->resId == EDMA3_RM_DMA_CHANNEL_ANY)
2019 || (chObj->resId == EDMA3_RM_RES_ANY))
2020 {
2021 /* Request for ANY DMA channel. */
2022 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2023 resObj.resId = EDMA3_RM_RES_ANY;
2024 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2026 if (result == EDMA3_RM_SOK)
2027 {
2028 /* DMA channel allocated successfully. */
2029 chObj->resId = resObj.resId;
2031 /**
2032 * Check the PaRAM Set user has specified for this DMA channel.
2033 * Two cases exist:
2034 * a) DCHMAP exists: Any PaRAM Set can be used
2035 * b) DCHMAP does not exist: Should not be possible
2036 * only if the channel allocated (ANY) and PaRAM requested
2037 * are same.
2038 */
2039 if ((*pParam) == EDMA3_RM_PARAM_ANY)
2040 {
2041 /* User specified ANY PaRAM Set; Check the mapping. */
2042 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2043 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2044 {
2045 /** If some PaRAM set is statically mapped to the returned
2046 * channel number, use that.
2047 */
2048 paRAMId = (int32_t)mappedPaRAMId;
2049 }
2050 }
2051 else
2052 {
2053 /* User specified some PaRAM Set; check that can be used or not. */
2054 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2055 {
2056 paRAMId = (int32_t)(*pParam);
2057 }
2058 else
2059 {
2060 /**
2061 * Channel mapping does not exist. If the PaRAM Set requested
2062 * is the same as dma channel allocated (coincidentally), it is fine.
2063 * Else return error.
2064 */
2065 if ((*pParam) != (resObj.resId))
2066 {
2067 result = EDMA3_RM_E_INVALID_PARAM;
2069 /**
2070 * Free the previously allocated DMA channel also.
2071 */
2072 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2073 }
2074 else
2075 {
2076 paRAMId = (int32_t)(*pParam);
2077 }
2078 }
2079 }
2081 mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[resObj.resId];
2082 }
2083 }
2084 else
2085 {
2086 if (chObj->resId <= edma3_dma_ch_max_val[edma3Id])
2087 {
2088 /* Request for a specific DMA channel */
2089 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2090 resObj.resId = chObj->resId;
2091 result = EDMA3_RM_allocResource(hEdmaResMgr,
2092 (EDMA3_RM_ResDesc *)&resObj);
2094 if (result == EDMA3_RM_SOK)
2095 {
2096 /**
2097 * Check the PaRAM Set user has specified for this DMA channel.
2098 * Two cases exist:
2099 * a) DCHMAP exists: Any PaRAM Set can be used
2100 * b) DCHMAP does not exist: Should not be possible
2101 * only if the channel allocated (ANY) and PaRAM requested
2102 * are same.
2103 */
2104 if ((*pParam) == EDMA3_RM_PARAM_ANY)
2105 {
2106 /* User specified ANY PaRAM Set; Check the mapping. */
2107 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2108 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2109 {
2110 /** If some PaRAM set is statically mapped to the returned
2111 * channel number, use that.
2112 */
2113 paRAMId = (int32_t)mappedPaRAMId;
2114 }
2115 }
2116 else
2117 {
2118 /* User specified some PaRAM Set; check that can be used or not. */
2119 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2120 {
2121 paRAMId = (int32_t)(*pParam);
2122 }
2123 else
2124 {
2125 /**
2126 * Channel mapping does not exist. If the PaRAM Set requested
2127 * is the same as dma channel allocated (coincidentally), it is fine.
2128 * Else return error.
2129 */
2130 if ((*pParam) != (resObj.resId))
2131 {
2132 result = EDMA3_RM_E_INVALID_PARAM;
2134 /**
2135 * Free the previously allocated DMA channel also.
2136 */
2137 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2138 }
2139 else
2140 {
2141 paRAMId = (int32_t)(*pParam);
2142 }
2143 }
2144 }
2146 mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[chObj->resId];
2147 }
2148 }
2149 else
2150 {
2151 result = EDMA3_RM_E_INVALID_PARAM;
2152 }
2153 }
2154 }
2155 break;
2158 case EDMA3_RM_RES_QDMA_CHANNEL:
2159 {
2160 if ((chObj->resId == EDMA3_RM_QDMA_CHANNEL_ANY)
2161 || (chObj->resId == EDMA3_RM_RES_ANY))
2162 {
2163 /* First request for any available QDMA channel */
2164 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2165 resObj.resId = EDMA3_RM_RES_ANY;
2166 result = EDMA3_RM_allocResource(hEdmaResMgr,
2167 (EDMA3_RM_ResDesc *)&resObj);
2169 if (result == EDMA3_RM_SOK)
2170 {
2171 /* Return the actual QDMA channel id. */
2172 chObj->resId = resObj.resId;
2174 /* Save the Logical-QDMA channel id for future use. */
2175 qdmaChId = resObj.resId + edma3_qdma_ch_min_val[edma3Id];
2177 /**
2178 * Check the PaRAM Set user has specified for this QDMA channel.
2179 * If he has specified any particular PaRAM Set, use that.
2180 */
2181 if ((*pParam) != EDMA3_RM_PARAM_ANY)
2182 {
2183 /* User specified ANY PaRAM Set; Check the mapping. */
2184 paRAMId = (int32_t)(*pParam);
2185 }
2186 }
2187 }
2188 else
2189 {
2190 if (chObj->resId < rmObj->gblCfgParams.numQdmaChannels)
2191 {
2192 /* Request for a specific QDMA channel */
2193 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2194 resObj.resId = chObj->resId;
2195 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2197 if (result == EDMA3_RM_SOK)
2198 {
2199 /* Save the Logical-QDMA channel id for future use. */
2200 qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
2202 /**
2203 * Check the PaRAM Set user has specified for this QDMA channel.
2204 * If he has specified any particular PaRAM Set, use that.
2205 */
2206 if ((*pParam) != EDMA3_RM_PARAM_ANY)
2207 {
2208 /* User specified ANY PaRAM Set; Check the mapping. */
2209 paRAMId = (int32_t)(*pParam);
2210 }
2211 }
2212 }
2213 else
2214 {
2215 result = EDMA3_RM_E_INVALID_PARAM;
2216 }
2217 }
2218 }
2219 break;
2221 case EDMA3_RM_RES_PARAM_SET:
2222 {
2223 /* Request for a LINK channel. */
2224 if ((chObj->resId == EDMA3_RM_PARAM_ANY)
2225 || (chObj->resId == EDMA3_RM_RES_ANY))
2226 {
2227 /* Request for ANY LINK channel. */
2228 paRAMId = (int32_t)EDMA3_RM_RES_ANY;
2229 }
2230 else
2231 {
2232 if (chObj->resId < edma3NumPaRAMSets)
2233 {
2234 /* Request for a Specific LINK channel. */
2235 paRAMId = (int32_t)(chObj->resId);
2236 }
2237 else
2238 {
2239 result = EDMA3_RM_E_INVALID_PARAM;
2240 }
2241 }
2243 if (result == EDMA3_RM_SOK)
2244 {
2245 /* Try to allocate the link channel */
2246 resObj.type = EDMA3_RM_RES_PARAM_SET;
2247 resObj.resId = (uint32_t)paRAMId;
2248 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2250 if (result == EDMA3_RM_SOK)
2251 {
2252 uint32_t linkCh = edma3_link_ch_min_val[edma3Id];
2254 /* Return the actual PaRAM Id. */
2255 chObj->resId = resObj.resId;
2257 /*
2258 * Search for the next Link channel place-holder available,
2259 * starting from EDMA3_RM_LINK_CH_MIN_VAL.
2260 * It will be used for future operations on the Link channel.
2261 */
2262 while ((edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId != -1)
2263 && (linkCh <= edma3_link_ch_max_val[edma3Id]))
2264 {
2265 /* Move to the next place-holder. */
2266 linkCh++;
2267 }
2269 /* Verify the returned handle, it should lie in the correct range */
2270 if (linkCh > edma3_link_ch_max_val[edma3Id])
2271 {
2272 result = EDMA3_RM_E_INVALID_PARAM;
2274 /* Free the PaRAM Set now. */
2275 resObj.type = EDMA3_RM_RES_PARAM_SET;
2276 resObj.resId = chObj->resId;
2277 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2278 }
2279 else
2280 {
2281 /* Save the PaRAM Id for the Link Channel. */
2282 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = (int32_t)(chObj->resId);
2284 /**
2285 * Remove any linking. Before doing that, check
2286 * whether it is permitted or not.
2287 */
2288 if (TRUE == rmInstance->regModificationRequired)
2289 {
2290 *((&gblRegs->PARAMENTRY[chObj->resId].OPT)
2291 + (uint32_t)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2292 }
2293 }
2294 }
2295 }
2296 }
2297 break;
2299 default:
2300 result = EDMA3_RM_E_INVALID_PARAM;
2301 }
2302 }
2305 if (result == EDMA3_RM_SOK)
2306 {
2307 /**
2308 * For DMA/QDMA channels, we still have to allocate more resources like
2309 * TCC, PaRAM Set etc.
2310 * For Link channel, only the PaRAMSet is required and that has been
2311 * allocated so no further operations required.
2312 */
2314 /* Further resources' allocation for DMA channel. */
2315 if (chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
2316 {
2317 /* First allocate a PaRAM Set */
2318 resObj.type = EDMA3_RM_RES_PARAM_SET;
2319 /* Use the saved param id now. */
2320 resObj.resId = (uint32_t)paRAMId;
2321 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2322 if (result == EDMA3_RM_SOK)
2323 {
2324 /**
2325 * PaRAM Set allocation succeeded.
2326 * Save the PaRAM Set first.
2327 */
2328 *pParam = resObj.resId;
2329 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = (int32_t)(resObj.resId);
2331 /* Allocate the TCC now. */
2332 resObj.type = EDMA3_RM_RES_TCC;
2333 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2334 {
2335 if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2336 {
2337 resObj.resId = EDMA3_RM_RES_ANY;
2338 }
2339 else
2340 {
2341 resObj.resId = mappedTcc;
2342 }
2343 }
2344 else
2345 {
2346 resObj.resId = *pTcc;
2347 }
2349 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2350 if (result == EDMA3_RM_SOK)
2351 {
2352 /* TCC allocation succeeded. Save it first. */
2353 *pTcc = resObj.resId;
2354 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].tcc = resObj.resId;
2356 /**
2357 * Check first whether the global registers and the allocated
2358 * PaRAM Set can be modified or not. If yes, do the needful.
2359 * Else leave this for the user.
2360 */
2361 if (TRUE == rmInstance->regModificationRequired)
2362 {
2363 /* Set TCC of the allocated Param Set. */
2364 gblRegs->PARAMENTRY[*pParam].OPT &= EDMA3_RM_OPT_TCC_CLR_MASK;
2365 gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2367 /**
2368 * Do the mapping between DMA channel and PaRAM Set.
2369 * Do this for the EDMA3 Controllers which have a register for mapping
2370 * DMA Channel to a particular PaRAM Set.
2371 */
2372 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2373 {
2374 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2376 /* Map Parameter RAM Set Number for specified channelId */
2377 gblRegs->DCHMAP[chObj->resId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
2378 gblRegs->DCHMAP[chObj->resId] |= EDMA3_RM_DCH_PARAM_SET_MASK(*pParam);
2379 }
2381 /* Remove any linking */
2382 *((&gblRegs->PARAMENTRY[*pParam].OPT)
2383 + (uint32_t)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2384 }
2385 }
2386 else
2387 {
2388 /**
2389 * TCC allocation failed, free the previously allocated
2390 * PaRAM Set and DMA channel.
2391 */
2392 resObj.type = EDMA3_RM_RES_PARAM_SET;
2393 resObj.resId = *pParam;
2394 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2396 /* Reset the book-keeping data structure also. */
2397 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = -1;
2399 resObj.type = chObj->type;
2400 resObj.resId = chObj->resId;
2401 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2402 }
2403 }
2404 else
2405 {
2406 /**
2407 * PaRAM Set allocation failed, free the previously allocated
2408 * DMA channel also.
2409 */
2410 resObj.type = chObj->type;
2411 resObj.resId = chObj->resId;
2412 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2413 }
2414 }
2417 /* Further resources' allocation for QDMA channel. */
2418 if (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
2419 {
2420 /* First allocate a PaRAM Set */
2421 resObj.type = EDMA3_RM_RES_PARAM_SET;
2422 /* Use the saved param id now. */
2423 resObj.resId = (uint32_t)paRAMId;
2424 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2425 if (result == EDMA3_RM_SOK)
2426 {
2427 /**
2428 * PaRAM Set allocation succeeded.
2429 * Save the PaRAM Set first.
2430 */
2431 *pParam = resObj.resId;
2432 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = (int32_t)(resObj.resId);
2434 /* Allocate the TCC now. */
2435 resObj.type = EDMA3_RM_RES_TCC;
2436 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2437 {
2438 if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2439 {
2440 resObj.resId = EDMA3_RM_RES_ANY;
2441 }
2442 else
2443 {
2444 resObj.resId = mappedTcc;
2445 }
2446 }
2447 else
2448 {
2449 resObj.resId = *pTcc;
2450 }
2452 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2453 if (result == EDMA3_RM_SOK)
2454 {
2455 /* TCC allocation succeeded. Save it first. */
2456 *pTcc = resObj.resId;
2457 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = resObj.resId;
2459 /**
2460 * Check first whether the global registers and the allocated
2461 * PaRAM Set can be modified or not. If yes, do the needful.
2462 * Else leave this for the user.
2463 */
2464 if (TRUE == rmInstance->regModificationRequired)
2465 {
2466 /* Set TCC of the allocated Param Set. */
2467 gblRegs->PARAMENTRY[*pParam].OPT &= EDMA3_RM_OPT_TCC_CLR_MASK;
2468 gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2470 /* Do the mapping between QDMA channel and PaRAM Set. */
2471 /* Map Parameter RAM Set Number for specified channelId */
2472 gblRegs->QCHMAP[chObj->resId]
2473 &= EDMA3_RM_QCH_PARAM_CLR_MASK;
2474 gblRegs->QCHMAP[chObj->resId]
2475 |= EDMA3_RM_QCH_PARAM_SET_MASK(*pParam);
2477 /* Set the Trigger Word */
2478 gblRegs->QCHMAP[chObj->resId]
2479 &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
2480 gblRegs->QCHMAP[chObj->resId]
2481 |= EDMA3_RM_QCH_TRWORD_SET_MASK(EDMA3_RM_QDMA_TRIG_DEFAULT);
2483 /* Remove any linking */
2484 *((&gblRegs->PARAMENTRY[*pParam].OPT)
2485 + (uint32_t)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2487 /* Enable the transfer also. */
2488 rmInstance->shadowRegs->QEESR = (1u << chObj->resId);
2489 }
2490 }
2491 else
2492 {
2493 /**
2494 * TCC allocation failed, free the previously allocated
2495 * PaRAM Set and QDMA channel.
2496 */
2497 resObj.type = EDMA3_RM_RES_PARAM_SET;
2498 resObj.resId = *pParam;
2499 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2501 /* Reset the book-keeping data structure also. */
2502 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
2504 resObj.type = chObj->type;
2505 resObj.resId = chObj->resId;
2506 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2507 }
2508 }
2509 else
2510 {
2511 /**
2512 * PaRAM Set allocation failed, free the previously allocated
2513 * QDMA channel also.
2514 */
2515 resObj.type = chObj->type;
2516 resObj.resId = chObj->resId;
2517 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2518 }
2519 }
2520 }
2523 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2524 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2525 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2526 EDMA3_DVT_dCOUNTER,
2527 EDMA3_DVT_dNONE,
2528 EDMA3_DVT_dNONE));
2529 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2532 return result;
2533 }
2535 EDMA3_RM_Result EDMA3_RM_freeLogicalChannel (EDMA3_RM_Handle hEdmaResMgr,
2536 EDMA3_RM_ResDesc *lChObj)
2537 {
2538 EDMA3_RM_ResDesc *chObj;
2539 EDMA3_RM_ResDesc resObj;
2540 EDMA3_RM_Result result = EDMA3_RM_SOK;
2541 EDMA3_RM_Instance *rmInstance = NULL;
2542 EDMA3_RM_Obj *rmObj = NULL;
2543 int32_t paRAMId;
2544 uint32_t tcc;
2545 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
2546 uint32_t qdmaChId;
2547 uint32_t dmaChId;
2548 EDMA3_RM_InstanceInitConfig *rmConfig = NULL;
2549 uint32_t edma3Id;
2551 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2552 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2553 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2554 EDMA3_DVT_dCOUNTER,
2555 EDMA3_DVT_dNONE,
2556 EDMA3_DVT_dNONE));
2557 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2560 /* If parameter checking is enabled... */
2561 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2562 if ((lChObj == NULL) || (hEdmaResMgr == NULL))
2563 {
2564 result = (EDMA3_RM_E_INVALID_PARAM);
2565 }
2566 #endif
2568 /* Check if the parameters are OK. */
2569 if (result == EDMA3_RM_SOK)
2570 {
2571 chObj = lChObj;
2573 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2575 if (rmInstance == NULL)
2576 {
2577 result = EDMA3_RM_E_INVALID_PARAM;
2578 }
2579 }
2581 if (result == EDMA3_RM_SOK)
2582 {
2583 rmConfig = rmInstance->initParam.rmInstInitConfig;
2584 rmObj = rmInstance->pResMgrObjHandle;
2586 if (rmObj == NULL)
2587 {
2588 result = EDMA3_RM_E_INVALID_PARAM;
2589 }
2590 else
2591 {
2592 if (rmObj->gblCfgParams.globalRegs == NULL)
2593 {
2594 result = EDMA3_RM_E_INVALID_PARAM;
2595 }
2596 else
2597 {
2598 edma3Id = rmObj->phyCtrllerInstId;
2599 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2600 }
2601 }
2602 }
2605 if (result == EDMA3_RM_SOK)
2606 {
2607 switch (chObj->type)
2608 {
2609 case EDMA3_RM_RES_DMA_CHANNEL:
2610 {
2611 /* Save the DMA channel first. */
2612 dmaChId = chObj->resId;
2614 /**
2615 * Validate DMA channel id first.
2616 * It should be a valid channel id.
2617 */
2618 if (dmaChId >= EDMA3_MAX_DMA_CH)
2619 {
2620 result = EDMA3_RM_E_INVALID_PARAM;
2621 }
2623 /* It should be owned and allocated by this RM only. */
2624 if (result == EDMA3_RM_SOK)
2625 {
2626 if (((rmConfig->ownDmaChannels[dmaChId/32u])
2627 &
2628 (~(rmInstance->avlblDmaChannels[dmaChId/32u]))
2629 &
2630 (1u << (dmaChId%32u))) != FALSE)
2631 {
2632 /** Perfectly valid channel id.
2633 * Clear some channel specific registers, if it is permitted.
2634 */
2635 if (TRUE == rmInstance->regModificationRequired)
2636 {
2637 if (dmaChId < 32u)
2638 {
2639 if((rmInstance->shadowRegs->SER & (1u<<dmaChId))!=FALSE)
2640 {
2641 rmInstance->shadowRegs->SECR = (1u<<dmaChId);
2642 }
2643 if((globalRegs->EMR & (1u<<dmaChId))!=FALSE)
2644 {
2645 globalRegs->EMCR = (1u<<dmaChId);
2646 }
2647 }
2648 else
2649 {
2650 if((rmInstance->shadowRegs->SERH & (1u<<(dmaChId-32u)))!=FALSE)
2651 {
2652 rmInstance->shadowRegs->SECRH = (1u<<(dmaChId-32u));
2653 }
2654 if((globalRegs->EMRH & (1u<<(dmaChId-32u)))!=FALSE)
2655 {
2656 globalRegs->EMCRH = (1u<<(dmaChId-32u));
2657 }
2658 }
2660 /* Clear DCHMAP register also. */
2661 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2662 {
2663 globalRegs->DCHMAP[dmaChId] &=
2664 EDMA3_RM_DCH_PARAM_CLR_MASK;
2665 }
2666 }
2668 /* Free the PaRAM Set Now. */
2669 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].paRAMId;
2670 resObj.type = EDMA3_RM_RES_PARAM_SET;
2671 resObj.resId = (uint32_t)paRAMId;
2672 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2673 }
2674 else
2675 {
2676 /* Channel id has some problem. */
2677 result = EDMA3_RM_E_INVALID_PARAM;
2678 }
2679 }
2682 if (result == EDMA3_RM_SOK)
2683 {
2684 /* PaRAM Set Freed */
2685 edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].paRAMId = -1;
2687 /* Free the TCC */
2688 tcc = edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].tcc;
2689 resObj.type = EDMA3_RM_RES_TCC;
2690 resObj.resId = tcc;
2691 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2692 }
2694 if (result == EDMA3_RM_SOK)
2695 {
2696 /* TCC Freed */
2697 edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].tcc = EDMA3_MAX_TCC;
2699 /**
2700 * Try to free the DMA Channel now. DMA Channel should
2701 * be freed only in the end because while freeing, DRAE
2702 * registers will be RESET.
2703 * After that, no shadow region specific DMA channel
2704 * register can be modified. So reset that DRAE register
2705 * ONLY in the end.
2706 */
2707 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2708 resObj.resId = dmaChId;
2709 result = EDMA3_RM_freeResource(hEdmaResMgr,
2710 (EDMA3_RM_ResDesc *)&resObj);
2711 }
2712 }
2713 break;
2716 case EDMA3_RM_RES_QDMA_CHANNEL:
2717 {
2718 /**
2719 * Calculate QDMA Logical Channel Id first.
2720 * User has given the actual QDMA channel id.
2721 * So we have to convert it to make the logical
2722 * QDMA channel id first.
2723 */
2724 qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
2726 /**
2727 * Validate QDMA channel id first.
2728 * It should be a valid channel id.
2729 */
2730 if (chObj->resId >= EDMA3_MAX_QDMA_CH)
2731 {
2732 result = EDMA3_RM_E_INVALID_PARAM;
2733 }
2735 /* It should be owned and allocated by this RM only. */
2736 if (result == EDMA3_RM_SOK)
2737 {
2738 if (((rmConfig->ownQdmaChannels[0u])
2739 &
2740 (~(rmInstance->avlblQdmaChannels[0u]))
2741 &
2742 (1u << chObj->resId)) != FALSE)
2743 {
2744 /** Perfectly valid channel id.
2745 * Clear some channel specific registers, if
2746 * it is permitted.
2747 */
2748 if (TRUE == rmInstance->regModificationRequired)
2749 {
2750 rmInstance->shadowRegs->QEECR = (1u<<chObj->resId);
2752 if((globalRegs->QEMR & (1u<<chObj->resId))!=FALSE)
2753 {
2754 globalRegs->QEMCR = (1u<<chObj->resId);
2755 }
2757 /* Unmap PARAM Set Number for specified channelId */
2758 globalRegs->QCHMAP[chObj->resId] &=
2759 EDMA3_RM_QCH_PARAM_CLR_MASK;
2761 /* Reset the Trigger Word */
2762 globalRegs->QCHMAP[chObj->resId] &=
2763 EDMA3_RM_QCH_TRWORD_CLR_MASK;
2764 }
2766 /* Free the PaRAM Set now */
2767 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId;
2768 resObj.type = EDMA3_RM_RES_PARAM_SET;
2769 resObj.resId = (int32_t)paRAMId;
2770 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2771 }
2772 else
2773 {
2774 /* Channel id has some problem. */
2775 result = EDMA3_RM_E_INVALID_PARAM;
2776 }
2777 }
2780 if (result == EDMA3_RM_SOK)
2781 {
2782 /* PaRAM Set Freed */
2783 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
2785 /* Free the TCC */
2786 tcc = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc;
2787 resObj.type = EDMA3_RM_RES_TCC;
2788 resObj.resId = tcc;
2789 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2790 }
2792 if (result == EDMA3_RM_SOK)
2793 {
2794 /* TCC Freed */
2795 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = EDMA3_MAX_TCC;
2797 /**
2798 * Try to free the QDMA Channel now. QDMA Channel should
2799 * be freed only in the end because while freeing, QRAE
2800 * registers will be RESET.
2801 * After that, no shadow region specific QDMA channel
2802 * register can be modified. So reset that QDRAE register
2803 * ONLY in the end.
2804 */
2805 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2806 resObj.resId = chObj->resId;
2807 result = EDMA3_RM_freeResource(hEdmaResMgr,
2808 (EDMA3_RM_ResDesc *)&resObj);
2809 }
2810 }
2811 break;
2814 case EDMA3_RM_RES_PARAM_SET:
2815 {
2816 /* Link Channel */
2817 if (chObj->resId < edma3NumPaRAMSets)
2818 {
2819 resObj.type = EDMA3_RM_RES_PARAM_SET;
2820 resObj.resId = chObj->resId;
2822 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2823 if (result == EDMA3_RM_SOK)
2824 {
2825 /* PaRAM Set freed successfully. */
2826 uint32_t linkCh = edma3_link_ch_min_val[edma3Id];
2828 /* Reset the Logical-Link channel */
2829 /* Search for the Logical-Link channel first */
2830 for (linkCh = edma3_link_ch_min_val[edma3Id];
2831 linkCh < edma3_link_ch_max_val[edma3Id];
2832 linkCh++)
2833 {
2834 if (edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId == chObj->resId)
2835 {
2836 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = -1;
2837 break;
2838 }
2839 }
2840 }
2841 }
2842 else
2843 {
2844 result = EDMA3_RM_E_INVALID_PARAM;
2845 }
2846 }
2847 break;
2849 default:
2850 result = EDMA3_RM_E_INVALID_PARAM;
2851 }
2852 }
2855 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2856 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2857 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2858 EDMA3_DVT_dCOUNTER,
2859 EDMA3_DVT_dNONE,
2860 EDMA3_DVT_dNONE));
2861 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2863 return result;
2864 }
2866 EDMA3_RM_Result EDMA3_RM_mapEdmaChannel (EDMA3_RM_Handle hEdmaResMgr,
2867 uint32_t channelId,
2868 uint32_t paRAMId)
2869 {
2870 EDMA3_RM_Instance *rmInstance = NULL;
2871 EDMA3_RM_Obj *rmObj = NULL;
2872 EDMA3_RM_Result result = EDMA3_RM_SOK;
2873 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
2875 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2876 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2877 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2878 EDMA3_DVT_dCOUNTER,
2879 EDMA3_DVT_dNONE,
2880 EDMA3_DVT_dNONE));
2881 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2883 /* If parameter checking is enabled... */
2884 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2885 if (hEdmaResMgr == NULL)
2886 {
2887 result = EDMA3_RM_E_INVALID_PARAM;
2888 }
2889 #endif
2891 if (result == EDMA3_RM_SOK)
2892 {
2893 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2895 if (rmInstance == NULL)
2896 {
2897 result = EDMA3_RM_E_INVALID_PARAM;
2898 }
2899 }
2901 if (result == EDMA3_RM_SOK)
2902 {
2903 rmObj = rmInstance->pResMgrObjHandle;
2905 if (rmObj == NULL)
2906 {
2907 result = EDMA3_RM_E_INVALID_PARAM;
2908 }
2909 else
2910 {
2911 if (rmObj->gblCfgParams.globalRegs == NULL)
2912 {
2913 result = EDMA3_RM_E_INVALID_PARAM;
2914 }
2915 }
2916 }
2918 if (result == EDMA3_RM_SOK)
2919 {
2920 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2922 /* If parameter checking is enabled... */
2923 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2924 if ((paRAMId >= rmObj->gblCfgParams.numPaRAMSets)
2925 || (channelId >= rmObj->gblCfgParams.numDmaChannels))
2926 {
2927 result = EDMA3_RM_E_INVALID_PARAM;
2928 }
2929 #endif
2930 }
2932 /* DMA channel and PaRAM Set should be previously allocated. */
2933 if (result == EDMA3_RM_SOK)
2934 {
2935 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[channelId/32u])
2936 &
2937 (~(rmInstance->avlblDmaChannels[channelId/32u]))
2938 &
2939 (1u << (channelId%32u))) != FALSE)
2940 {
2941 /* DMA channel allocated, check for the PaRAM Set */
2942 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[paRAMId/32u])
2943 &
2944 (~(rmInstance->avlblPaRAMSets[paRAMId/32u]))
2945 &
2946 (1u << (paRAMId%32u))) == FALSE)
2947 {
2948 /* PaRAM Set NOT allocated, return error */
2949 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
2950 }
2951 }
2952 else
2953 {
2954 /* DMA channel NOT allocated, return error */
2955 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
2956 }
2957 }
2960 if (result == EDMA3_RM_SOK)
2961 {
2962 /* Map the Dma Channel to the PaRAM Set corresponding to paramId */
2963 /**
2964 * Do this for the EDMA3 Controllers which have a register for mapping
2965 * DMA Channel to a particular PaRAM Set. So check
2966 * dmaChPaRAMMapExists first.
2967 */
2968 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2969 {
2970 /* Map Parameter RAM Set Number for specified channelId */
2971 gblRegs->DCHMAP[channelId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
2972 gblRegs->DCHMAP[channelId] |= EDMA3_RM_DCH_PARAM_SET_MASK(paRAMId);
2973 }
2974 else
2975 {
2976 /* Feature NOT supported on the current platform, return error. */
2977 result = EDMA3_RM_E_FEATURE_UNSUPPORTED;
2978 }
2979 }
2981 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2982 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2983 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2984 EDMA3_DVT_dCOUNTER,
2985 EDMA3_DVT_dNONE,
2986 EDMA3_DVT_dNONE));
2987 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2989 return result;
2990 }
2992 EDMA3_RM_Result EDMA3_RM_mapQdmaChannel (EDMA3_RM_Handle hEdmaResMgr,
2993 uint32_t channelId,
2994 uint32_t paRAMId,
2995 EDMA3_RM_QdmaTrigWord trigWord)
2996 {
2997 EDMA3_RM_Instance *rmInstance = NULL;
2998 EDMA3_RM_Obj *rmObj = NULL;
2999 EDMA3_RM_Result result = EDMA3_RM_SOK;
3000 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3002 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3003 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3004 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3005 EDMA3_DVT_dCOUNTER,
3006 EDMA3_DVT_dNONE,
3007 EDMA3_DVT_dNONE));
3008 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3010 /* If parameter checking is enabled... */
3011 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3012 if ((hEdmaResMgr == NULL)
3013 || (((int32_t)trigWord < (int32_t)EDMA3_RM_QDMA_TRIG_OPT)
3014 || (trigWord > EDMA3_RM_QDMA_TRIG_CCNT)))
3015 {
3016 result = EDMA3_RM_E_INVALID_PARAM;
3017 }
3018 #endif
3020 if (result == EDMA3_RM_SOK)
3021 {
3022 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3024 if (rmInstance == NULL)
3025 {
3026 result = EDMA3_RM_E_INVALID_PARAM;
3027 }
3028 }
3030 if (result == EDMA3_RM_SOK)
3031 {
3032 rmObj = rmInstance->pResMgrObjHandle;
3034 if (rmObj == NULL)
3035 {
3036 result = EDMA3_RM_E_INVALID_PARAM;
3037 }
3038 else
3039 {
3040 if (rmObj->gblCfgParams.globalRegs == NULL)
3041 {
3042 result = EDMA3_RM_E_INVALID_PARAM;
3043 }
3044 }
3045 }
3047 if (result == EDMA3_RM_SOK)
3048 {
3049 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3051 /* If parameter checking is enabled... */
3052 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3053 if ((paRAMId >= rmObj->gblCfgParams.numPaRAMSets)
3054 || (channelId >= rmObj->gblCfgParams.numQdmaChannels))
3055 {
3056 result = EDMA3_RM_E_INVALID_PARAM;
3057 }
3058 #endif
3059 }
3061 /* QDMA channel and PaRAM Set should be previously allocated. */
3062 if (result == EDMA3_RM_SOK)
3063 {
3064 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[channelId/32u])
3065 &
3066 (~(rmInstance->avlblQdmaChannels[channelId/32u]))
3067 &
3068 (1u << (channelId%32u))) != FALSE)
3069 {
3070 /* QDMA channel allocated, check for the PaRAM Set */
3071 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[paRAMId/32u])
3072 &
3073 (~(rmInstance->avlblPaRAMSets[paRAMId/32u]))
3074 &
3075 (1u << (paRAMId%32u))) == FALSE)
3076 {
3077 /* PaRAM Set NOT allocated, return error */
3078 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3079 }
3080 }
3081 else
3082 {
3083 /* QDMA channel NOT allocated, return error */
3084 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3085 }
3086 }
3088 if (result == EDMA3_RM_SOK)
3089 {
3090 /* Map Parameter RAM Set Number for specified channelId */
3091 gblRegs->QCHMAP[channelId] &= EDMA3_RM_QCH_PARAM_CLR_MASK;
3092 gblRegs->QCHMAP[channelId] |= EDMA3_RM_QCH_PARAM_SET_MASK(paRAMId);
3094 /* Set the Trigger Word */
3095 gblRegs->QCHMAP[channelId] &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
3096 gblRegs->QCHMAP[channelId] |= EDMA3_RM_QCH_TRWORD_SET_MASK(trigWord);
3097 }
3100 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3101 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3102 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3103 EDMA3_DVT_dCOUNTER,
3104 EDMA3_DVT_dNONE,
3105 EDMA3_DVT_dNONE));
3106 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3108 return result;
3109 }
3111 EDMA3_RM_Result EDMA3_RM_registerTccCb(EDMA3_RM_Handle hEdmaResMgr,
3112 const EDMA3_RM_ResDesc *channelObj,
3113 uint32_t tcc,
3114 EDMA3_RM_TccCallback tccCb,
3115 void *cbData)
3116 {
3117 EDMA3_RM_Instance *rmInstance = NULL;
3118 EDMA3_RM_Obj *rmObj = NULL;
3119 EDMA3_RM_Result result = EDMA3_RM_SOK;
3120 uint32_t edma3Id;
3121 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3123 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3124 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3125 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3126 EDMA3_DVT_dCOUNTER,
3127 EDMA3_DVT_dNONE,
3128 EDMA3_DVT_dNONE));
3129 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3131 /* If parameter checking is enabled... */
3132 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3133 if ((NULL == hEdmaResMgr) || (NULL == channelObj))
3134 {
3135 result = EDMA3_RM_E_INVALID_PARAM;
3136 }
3138 /* Callback function should NOT be NULL */
3139 if (NULL == tccCb)
3140 {
3141 result = EDMA3_RM_E_INVALID_PARAM;
3142 }
3143 #endif
3145 if (result == EDMA3_RM_SOK)
3146 {
3147 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3148 rmObj = rmInstance->pResMgrObjHandle;
3150 if (rmObj == NULL)
3151 {
3152 result = EDMA3_RM_E_INVALID_PARAM;
3153 }
3154 else
3155 {
3156 edma3Id = rmObj->phyCtrllerInstId;
3157 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3158 }
3159 }
3161 if (result == EDMA3_RM_SOK)
3162 {
3163 if ((gblRegs == NULL) || (tcc >= rmObj->gblCfgParams.numTccs))
3164 {
3165 result = EDMA3_RM_E_INVALID_PARAM;
3166 }
3167 }
3169 /* Check if the parameters are OK. */
3170 if (EDMA3_RM_SOK == result)
3171 {
3172 /* Check whether the callback has already registered. */
3173 if (NULL != edma3IntrParams[edma3Id][tcc].tccCb)
3174 {
3175 result = EDMA3_RM_E_CALLBACK_ALREADY_REGISTERED;
3176 }
3177 else
3178 {
3179 /* Store the mapping b/w DMA/QDMA channel and TCC first. */
3180 if (channelObj->type == EDMA3_RM_RES_DMA_CHANNEL)
3181 {
3182 /* DMA channel */
3183 if (channelObj->resId < rmObj->gblCfgParams.numDmaChannels)
3184 {
3185 /* Save the TCC */
3186 edma3DmaChTccMapping[edma3Id][channelObj->resId] = tcc;
3187 }
3188 else
3189 {
3190 /* Error!!! */
3191 result = EDMA3_RM_E_INVALID_PARAM;
3192 }
3193 }
3194 else
3195 {
3196 if (channelObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
3197 {
3198 /* QDMA channel */
3199 if (channelObj->resId < rmObj->gblCfgParams.numQdmaChannels)
3200 {
3201 /* Save the TCC */
3202 edma3QdmaChTccMapping[edma3Id][channelObj->resId] = tcc;
3203 }
3204 else
3205 {
3206 /* Error!!! */
3207 result = EDMA3_RM_E_INVALID_PARAM;
3208 }
3209 }
3210 else
3211 {
3212 /* Error!!! */
3213 result = EDMA3_RM_E_INVALID_PARAM;
3214 }
3215 }
3216 }
3217 }
3219 if (EDMA3_RM_SOK == result)
3220 {
3222 /* Enable the interrupts in IESR/IESRH */
3223 if (tcc < 32u)
3224 {
3225 rmInstance->shadowRegs->IESR = (1UL << tcc);
3226 }
3227 else
3228 {
3229 rmInstance->shadowRegs->IESRH = (1UL << (tcc-32u));
3230 }
3232 /* Save the callback functions also */
3233 edma3IntrParams[edma3Id][tcc].cbData = cbData;
3234 edma3IntrParams[edma3Id][tcc].tccCb = tccCb;
3235 }
3237 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3238 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3239 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3240 EDMA3_DVT_dCOUNTER,
3241 EDMA3_DVT_dNONE,
3242 EDMA3_DVT_dNONE));
3243 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3245 return result;
3246 }
3248 EDMA3_RM_Result EDMA3_RM_unregisterTccCb(EDMA3_RM_Handle hEdmaResMgr,
3249 const EDMA3_RM_ResDesc *channelObj)
3250 {
3251 EDMA3_RM_Instance *rmInstance = NULL;
3252 EDMA3_RM_Obj *rmObj = NULL;
3253 EDMA3_RM_Result result = EDMA3_RM_SOK;
3254 uint32_t mappedTcc = EDMA3_MAX_TCC;
3255 uint32_t edma3Id;
3256 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3258 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3259 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3260 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3261 EDMA3_DVT_dCOUNTER,
3262 EDMA3_DVT_dNONE,
3263 EDMA3_DVT_dNONE));
3264 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3266 /* If parameter checking is enabled... */
3267 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3268 if ((NULL == hEdmaResMgr) || (NULL == channelObj))
3269 {
3270 result = EDMA3_RM_E_INVALID_PARAM;
3271 }
3272 #endif
3274 /* Check if the parameters are OK. */
3275 if (EDMA3_RM_SOK == result)
3276 {
3277 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3278 rmObj = rmInstance->pResMgrObjHandle;
3280 if (rmObj == NULL)
3281 {
3282 result = EDMA3_RM_E_INVALID_PARAM;
3283 }
3284 else
3285 {
3286 edma3Id = rmObj->phyCtrllerInstId;
3287 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3288 }
3289 }
3291 if (result == EDMA3_RM_SOK)
3292 {
3293 if (gblRegs == NULL)
3294 {
3295 result = EDMA3_RM_E_INVALID_PARAM;
3296 }
3297 else
3298 {
3299 if (channelObj->type == EDMA3_RM_RES_DMA_CHANNEL)
3300 {
3301 /* DMA channel */
3302 if (channelObj->resId < rmObj->gblCfgParams.numDmaChannels)
3303 {
3304 /* Save the mapped TCC */
3305 mappedTcc = edma3DmaChTccMapping[edma3Id][channelObj->resId];
3307 /* Remove the mapping now. */
3308 edma3DmaChTccMapping[edma3Id][channelObj->resId] = EDMA3_MAX_TCC;
3309 }
3310 else
3311 {
3312 /* Error!!! */
3313 result = EDMA3_RM_E_INVALID_PARAM;
3314 }
3315 }
3316 else
3317 {
3318 if (channelObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
3319 {
3320 /* QDMA channel */
3321 if (channelObj->resId < rmObj->gblCfgParams.numQdmaChannels)
3322 {
3323 /* Save the mapped TCC */
3324 mappedTcc = edma3QdmaChTccMapping[edma3Id][channelObj->resId];
3326 /* Remove the mapping now. */
3327 edma3QdmaChTccMapping[edma3Id][channelObj->resId] = EDMA3_MAX_TCC;
3328 }
3329 else
3330 {
3331 /* Error!!! */
3332 result = EDMA3_RM_E_INVALID_PARAM;
3333 }
3334 }
3335 else
3336 {
3337 /* Error!!! */
3338 result = EDMA3_RM_E_INVALID_PARAM;
3339 }
3340 }
3341 }
3342 }
3344 if (EDMA3_RM_SOK == result)
3345 {
3347 /* Remove the callback function too */
3348 if (mappedTcc < 32u)
3349 {
3350 rmInstance->shadowRegs->IECR = (1UL << mappedTcc);
3351 }
3352 else if(mappedTcc < 64)
3353 {
3354 rmInstance->shadowRegs->IECRH = (1UL << (mappedTcc-32u));
3355 }
3357 if(mappedTcc < EDMA3_MAX_TCC)
3358 {
3359 edma3IntrParams[edma3Id][mappedTcc].cbData = NULL;
3360 edma3IntrParams[edma3Id][mappedTcc].tccCb = NULL;
3361 }
3362 }
3364 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3365 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3366 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3367 EDMA3_DVT_dCOUNTER,
3368 EDMA3_DVT_dNONE,
3369 EDMA3_DVT_dNONE));
3370 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3372 return result;
3373 }
3375 EDMA3_RM_Result EDMA3_RM_allocContiguousResource(EDMA3_RM_Handle hEdmaResMgr,
3376 EDMA3_RM_ResDesc *firstResIdObj,
3377 uint32_t numResources)
3378 {
3379 EDMA3_RM_Instance *rmInstance = NULL;
3380 EDMA3_RM_Obj *rmObj = NULL;
3381 EDMA3_RM_Result result = EDMA3_RM_SOK;
3382 EDMA3_RM_ResDesc *resObj = NULL;
3383 uint32_t resAllocIdx = 0u;
3384 uint32_t firstResId;
3385 uint32_t lastResId = 0u;
3386 uint32_t maxNumResources = 0u;
3387 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
3388 uint32_t resIdClr = 0x0;
3389 uint32_t resIdSet = 0x0;
3390 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3391 uint32_t i = 0u;
3392 uint32_t position = 0u;
3393 uint32_t edma3Id;
3395 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3396 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3397 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3398 EDMA3_DVT_dCOUNTER,
3399 EDMA3_DVT_dNONE,
3400 EDMA3_DVT_dNONE));
3401 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3404 /* If parameter checking is enabled... */
3405 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3406 if ((hEdmaResMgr == NULL) || (firstResIdObj == NULL))
3407 {
3408 result = EDMA3_RM_E_INVALID_PARAM;
3409 }
3410 #endif
3412 if (EDMA3_RM_SOK == result)
3413 {
3414 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3415 if (rmInstance == NULL)
3416 {
3417 result = EDMA3_RM_E_INVALID_PARAM;
3418 }
3419 }
3421 if (EDMA3_RM_SOK == result)
3422 {
3423 rmObj = rmInstance->pResMgrObjHandle;
3425 if (rmObj == NULL)
3426 {
3427 result = EDMA3_RM_E_INVALID_PARAM;
3428 }
3429 }
3431 if (EDMA3_RM_SOK == result)
3432 {
3433 edma3Id = rmObj->phyCtrllerInstId;
3434 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3436 if (rmInstance->initParam.rmSemHandle == NULL)
3437 {
3438 result = EDMA3_RM_E_INVALID_PARAM;
3439 }
3440 }
3442 if (EDMA3_RM_SOK == result)
3443 {
3444 resObj = firstResIdObj;
3445 if (resObj != NULL)
3446 {
3447 firstResId = resObj->resId;
3448 }
3450 switch (resObj->type)
3451 {
3452 case EDMA3_RM_RES_DMA_CHANNEL :
3453 maxNumResources = rmObj->gblCfgParams.numDmaChannels;
3454 break;
3455 case EDMA3_RM_RES_QDMA_CHANNEL :
3456 maxNumResources = rmObj->gblCfgParams.numQdmaChannels;
3457 break;
3458 case EDMA3_RM_RES_TCC :
3459 maxNumResources = rmObj->gblCfgParams.numTccs;
3460 break;
3461 case EDMA3_RM_RES_PARAM_SET :
3462 maxNumResources = rmObj->gblCfgParams.numPaRAMSets;
3463 break;
3464 default:
3465 result = EDMA3_RM_E_INVALID_PARAM;
3466 break;
3467 }
3468 }
3471 if (EDMA3_RM_SOK == result)
3472 {
3473 /* First resource id (firstResId) can be a valid Resource ID as well as
3474 * 'EDMA3_RM_RES_ANY', in case user does not want to
3475 * start from a specific resource. For eg, user allocating link channels.
3476 */
3477 if (firstResId != EDMA3_RM_RES_ANY)
3478 {
3479 /* User want specific resources. */
3480 lastResId = firstResId + numResources;
3482 if (((firstResId >= maxNumResources) || (firstResId > lastResId))
3483 || (lastResId > maxNumResources))
3484 {
3485 result = EDMA3_RM_E_INVALID_PARAM;
3486 }
3487 }
3488 else
3489 {
3490 /* (firstResId == EDMA3_RM_RES_ANY)
3491 * So just check whether the number of resources
3492 * requested does not cross the limit.
3493 */
3494 if (numResources > maxNumResources)
3495 {
3496 result = EDMA3_RM_E_INVALID_PARAM;
3497 }
3498 }
3499 }
3502 if (result == EDMA3_RM_SOK)
3503 {
3504 /* Now try to allocate resources for the first case */
3505 if (firstResId != EDMA3_RM_RES_ANY)
3506 {
3507 /* Request for specific resources */
3509 /**
3510 * Take the instance specific semaphore, to prevent simultaneous
3511 * access to the shared resources.
3512 */
3513 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
3514 EDMA3_OSSEM_NO_TIMEOUT);
3516 if (EDMA3_RM_SOK == semResult)
3517 {
3518 switch (resObj->type)
3519 {
3520 case EDMA3_RM_RES_DMA_CHANNEL :
3521 {
3522 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3523 {
3524 resIdClr = (uint32_t)(~(1u << (resAllocIdx%32u)));
3525 resIdSet = (1u << (resAllocIdx%32u));
3527 /* Check whether it is owned or not */
3528 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resAllocIdx/32u])&(resIdSet)) != FALSE)
3529 {
3530 /* Now check if specified resource is available presently*/
3531 if (((rmInstance->avlblDmaChannels[resAllocIdx/32u])&(resIdSet)) != FALSE)
3532 {
3533 /*
3534 * Mark the specified resource as "Not Available"
3535 * for future requests
3536 */
3537 rmInstance->avlblDmaChannels[resAllocIdx/32u] &= resIdClr;
3539 if (resAllocIdx < 32u)
3540 {
3541 rmInstance->shadowRegs->EECR = (1UL << resAllocIdx);
3543 /**
3544 * Enable the DMA channel in the
3545 * DRAE registers also.
3546 */
3547 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
3548 |= (0x1u << resAllocIdx);
3549 }
3550 else
3551 {
3552 rmInstance->shadowRegs->EECRH = (1UL << (resAllocIdx - 32u));
3554 /**
3555 * Enable the DMA channel in the
3556 * DRAEH registers also.
3557 */
3558 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
3559 |= (0x1u << (resAllocIdx - 32u));
3560 }
3562 result = EDMA3_RM_SOK;
3563 }
3564 else
3565 {
3566 /* Specified resource is owned but is already booked */
3567 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3568 break;
3569 }
3570 }
3571 else
3572 {
3573 /*
3574 * Specified resource is not owned by this instance
3575 * of the Resource Manager
3576 */
3577 result = EDMA3_RM_E_RES_NOT_OWNED;
3578 break;
3579 }
3580 }
3582 break;
3583 }
3585 case EDMA3_RM_RES_QDMA_CHANNEL:
3586 {
3587 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3588 {
3589 resIdClr = (uint32_t)(~(1u << resAllocIdx));
3590 resIdSet = (1u << resAllocIdx);
3592 /* Check whether it is owned or not */
3593 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u])&(resIdSet))!=FALSE)
3594 {
3595 /* Now check if specified resource is available presently*/
3596 if (((rmInstance->avlblQdmaChannels[0u])&(resIdSet))!=FALSE)
3597 {
3598 /*
3599 * Mark the specified resource as "Not Available"
3600 * for future requests
3601 */
3602 rmInstance->avlblQdmaChannels[0u] &= resIdClr;
3604 /**
3605 * Enable the QDMA channel in the
3606 * QRAE register also.
3607 */
3608 gblRegs->QRAE[rmInstance->initParam.regionId]
3609 |= (0x1u << resAllocIdx);
3611 result = EDMA3_RM_SOK;
3612 }
3613 else
3614 {
3615 /* Specified resource is owned but is already booked */
3616 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3617 break;
3618 }
3619 }
3620 else
3621 {
3622 /*
3623 * Specified resource is not owned by this instance
3624 * of the Resource Manager
3625 */
3626 result = EDMA3_RM_E_RES_NOT_OWNED;
3627 break;
3628 }
3629 }
3631 break;
3632 }
3634 case EDMA3_RM_RES_TCC:
3635 {
3636 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3637 {
3638 resIdClr = (uint32_t)(~(1u << (resAllocIdx%32u)));
3639 resIdSet = (1u << (resAllocIdx%32u));
3641 /* Check whether it is owned or not */
3642 if (((rmInstance->initParam.rmInstInitConfig->ownTccs[resAllocIdx/32u])&(resIdSet))!=FALSE)
3643 {
3644 /* Now check if specified resource is available presently*/
3645 if (((rmInstance->avlblTccs[resAllocIdx/32u])&(resIdSet))!=FALSE)
3646 {
3647 /*
3648 * Mark the specified resource as "Not Available"
3649 * for future requests
3650 */
3651 rmInstance->avlblTccs[resAllocIdx/32u] &= resIdClr;
3653 /**
3654 * If the region id coming from this
3655 * RM instance is same as the Master RM
3656 * Instance's region id, only then we will be
3657 * getting the interrupts on the same side.
3658 * So save the TCC in the allocatedTCCs[] array.
3659 */
3660 if (edma3RegionId == rmInstance->initParam.regionId)
3661 {
3662 if (resAllocIdx < 32u)
3663 {
3664 allocatedTCCs[edma3Id][0u] |= (0x1u << resAllocIdx);
3665 }
3666 else
3667 {
3668 allocatedTCCs[edma3Id][1u] |= (0x1u << (resAllocIdx - 32u));
3669 }
3670 }
3671 result = EDMA3_RM_SOK;
3672 }
3673 else
3674 {
3675 /* Specified resource is owned but is already booked */
3676 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3677 break;
3678 }
3679 }
3680 else
3681 {
3682 /*
3683 * Specified resource is not owned by this instance
3684 * of the Resource Manager
3685 */
3686 result = EDMA3_RM_E_RES_NOT_OWNED;
3687 break;
3688 }
3689 }
3691 break;
3692 }
3694 case EDMA3_RM_RES_PARAM_SET:
3695 {
3696 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3697 {
3698 resIdClr = (uint32_t)(~(1u << (resAllocIdx%32u)));
3699 resIdSet = (1u << (resAllocIdx%32u));
3701 /* Check whether it is owned or not */
3702 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[resAllocIdx/32u])&(resIdSet))!=FALSE)
3703 {
3704 /* Now check if specified resource is available presently*/
3705 if (((rmInstance->avlblPaRAMSets[resAllocIdx/32u])&(resIdSet))!=FALSE)
3706 {
3707 /*
3708 * Mark the specified resource as "Not Available"
3709 * for future requests
3710 */
3711 rmInstance->avlblPaRAMSets[resAllocIdx/32u] &= resIdClr;
3713 /**
3714 * Also, make the actual PARAM Set NULL, checking the flag
3715 * whether it is required or not.
3716 */
3717 if (TRUE == rmInstance->paramInitRequired)
3718 {
3719 edma3MemZero((void *)(&gblRegs->PARAMENTRY[resAllocIdx]),
3720 sizeof(gblRegs->PARAMENTRY[resAllocIdx]));
3721 }
3723 result = EDMA3_RM_SOK;
3724 }
3725 else
3726 {
3727 /* Specified resource is owned but is already booked */
3728 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3729 break;
3730 }
3731 }
3732 else
3733 {
3734 /*
3735 * Specified resource is not owned by this instance
3736 * of the Resource Manager
3737 */
3738 result = EDMA3_RM_E_RES_NOT_OWNED;
3739 break;
3740 }
3741 }
3743 break;
3744 }
3746 default:
3747 {
3748 result = EDMA3_RM_E_INVALID_PARAM;
3749 break;
3750 }
3751 }
3753 /* resource allocation completed, release the semaphore first */
3754 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
3755 }
3757 }
3758 else
3759 {
3760 /* (firstResId == EDMA3_RM_RES_ANY) */
3761 /**
3762 * Take the instance specific semaphore, to prevent simultaneous
3763 * access to the shared resources.
3764 */
3765 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
3766 EDMA3_OSSEM_NO_TIMEOUT);
3768 if (EDMA3_RM_SOK == semResult)
3769 {
3770 /**
3771 * We have to search three different arrays, namely ownedResoures,
3772 * avlblResources and resvdResources, to find the 'common' contiguous
3773 * resources. For this, take an 'AND' of all three arrays in one single
3774 * array and use your algorithm on that array.
3775 */
3776 switch (resObj->type)
3777 {
3778 case EDMA3_RM_RES_DMA_CHANNEL:
3779 {
3780 /* AND all the arrays to look into */
3781 contiguousDmaRes[0u] = ((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[0u]
3782 & rmInstance->avlblDmaChannels[0u])
3783 & (~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[0u]))
3784 );
3785 contiguousDmaRes[1u] = ((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[1u]
3786 & rmInstance->avlblDmaChannels[1u])
3787 & (~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[1u]))
3788 );
3789 }
3790 break;
3792 case EDMA3_RM_RES_QDMA_CHANNEL:
3793 {
3794 /* AND all the arrays to look into */
3795 contiguousQdmaRes[0u] = ((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u]
3796 & rmInstance->avlblQdmaChannels[0u])
3797 & (~(rmInstance->initParam.rmInstInitConfig->resvdQdmaChannels[0u]))
3798 );
3799 }
3800 break;
3802 case EDMA3_RM_RES_TCC:
3803 {
3804 /* AND all the arrays to look into */
3805 contiguousTccRes[0u] = ((rmInstance->initParam.rmInstInitConfig->ownTccs[0u]
3806 & rmInstance->avlblTccs[0u])
3807 & (~(rmInstance->initParam.rmInstInitConfig->resvdTccs[0u]))
3808 );
3809 contiguousTccRes[1u] = ((rmInstance->initParam.rmInstInitConfig->ownTccs[1u]
3810 & rmInstance->avlblTccs[1u])
3811 & (~(rmInstance->initParam.rmInstInitConfig->resvdTccs[1u]))
3812 );
3813 }
3814 break;
3816 case EDMA3_RM_RES_PARAM_SET:
3817 {
3818 /* AND all the arrays to look into */
3819 for (i = 0u; i < (maxNumResources/32u); ++i)
3820 {
3821 contiguousParamRes[i] = ((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[i]
3822 & rmInstance->avlblPaRAMSets[i])
3823 & (~(rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[i]))
3824 );
3825 }
3826 }
3827 break;
3829 default:
3830 {
3831 result = EDMA3_RM_E_INVALID_PARAM;
3832 }
3833 break;
3834 }
3836 if (EDMA3_RM_SOK == result)
3837 {
3838 /**
3839 * Try to allocate 'numResources' contiguous resources
3840 * of type RES_ANY.
3841 */
3842 result = allocAnyContigRes (resObj->type, numResources, &position);
3844 /**
3845 * If result != EDMA3_RM_SOK, resource allocation failed.
3846 * Else resources successfully allocated.
3847 */
3848 if (result == EDMA3_RM_SOK)
3849 {
3850 /* Update the first resource id with the position returned. */
3851 resObj->resId = position;
3853 /*
3854 * Do some further changes in the book-keeping
3855 * data structures and global registers accordingly.
3856 */
3857 result = gblChngAllocContigRes(rmInstance, resObj, numResources);
3858 }
3859 }
3861 /* resource allocation completed, release the semaphore first */
3862 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
3863 }
3864 }
3865 }
3868 /**
3869 * Check the Resource Allocation Result 'result' first. If Resource
3870 * Allocation has resulted in an error, return it (having more priority than
3871 * semResult. Else, return semResult.
3872 */
3873 if (EDMA3_RM_SOK == result)
3874 {
3875 /**
3876 * Resource Allocation successful, return semResult for returning
3877 * semaphore.
3878 */
3879 result = semResult;
3880 }
3883 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3884 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3885 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3886 EDMA3_DVT_dCOUNTER,
3887 EDMA3_DVT_dNONE,
3888 EDMA3_DVT_dNONE));
3889 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3891 return result;
3892 }
3894 EDMA3_RM_Result EDMA3_RM_freeContiguousResource(EDMA3_RM_Handle hEdmaResMgr,
3895 EDMA3_RM_ResDesc *firstResIdObj,
3896 uint32_t numResources)
3897 {
3898 EDMA3_RM_Instance *rmInstance = NULL;
3899 EDMA3_RM_Obj *rmObj = NULL;
3900 EDMA3_RM_Result result = EDMA3_RM_SOK;
3901 EDMA3_RM_ResDesc *resObj;
3902 uint32_t resFreeIdx = 0u;
3903 uint32_t firstResId;
3904 uint32_t lastResId;
3905 uint32_t maxNumResources = 0u;
3907 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3908 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3909 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3910 EDMA3_DVT_dCOUNTER,
3911 EDMA3_DVT_dNONE,
3912 EDMA3_DVT_dNONE));
3913 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3915 /* If parameter checking is enabled... */
3916 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3917 if ((hEdmaResMgr == NULL) || (firstResIdObj == NULL))
3918 {
3919 result = EDMA3_RM_E_INVALID_PARAM;
3920 }
3921 #endif
3923 /* Check if the parameters are OK. */
3924 if (EDMA3_RM_SOK == result)
3925 {
3926 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3927 rmObj = rmInstance->pResMgrObjHandle;
3929 if (rmObj == NULL)
3930 {
3931 result = EDMA3_RM_E_INVALID_PARAM;
3932 }
3933 else
3934 {
3935 resObj = firstResIdObj;
3936 if (resObj != NULL)
3937 {
3938 firstResId = resObj->resId;
3939 lastResId = firstResId + (numResources - 1u);
3940 }
3942 switch (resObj->type)
3943 {
3944 case EDMA3_RM_RES_DMA_CHANNEL :
3945 maxNumResources = rmObj->gblCfgParams.numDmaChannels;
3946 break;
3947 case EDMA3_RM_RES_QDMA_CHANNEL :
3948 maxNumResources = rmObj->gblCfgParams.numQdmaChannels;
3949 break;
3950 case EDMA3_RM_RES_TCC :
3951 maxNumResources = rmObj->gblCfgParams.numTccs;
3952 break;
3953 case EDMA3_RM_RES_PARAM_SET :
3954 maxNumResources = rmObj->gblCfgParams.numPaRAMSets;
3955 break;
3956 default:
3957 result = EDMA3_RM_E_INVALID_PARAM;
3958 break;
3959 }
3961 if (result == EDMA3_RM_SOK)
3962 {
3963 if ((firstResId > lastResId) || (lastResId >= maxNumResources))
3964 {
3965 result = EDMA3_RM_E_INVALID_PARAM;
3966 }
3967 else
3968 {
3969 for (resFreeIdx = firstResId; resFreeIdx <= lastResId; ++resFreeIdx)
3970 {
3971 resObj->resId = resFreeIdx;
3972 result = EDMA3_RM_freeResource(rmInstance, resObj);
3974 if (result != EDMA3_RM_SOK)
3975 {
3976 break;
3977 }
3978 }
3979 }
3980 }
3981 }
3982 }
3984 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3985 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3986 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3987 EDMA3_DVT_dCOUNTER,
3988 EDMA3_DVT_dNONE,
3989 EDMA3_DVT_dNONE));
3990 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3992 return result;
3993 }
3995 EDMA3_RM_Result EDMA3_RM_setCCRegister (EDMA3_RM_Handle hEdmaResMgr,
3996 uint32_t regOffset,
3997 uint32_t newRegValue)
3998 {
3999 uint32_t intState;
4000 EDMA3_RM_Result result = EDMA3_RM_SOK;
4001 EDMA3_RM_Instance *rmInstance = NULL;
4002 EDMA3_RM_Obj *rmObj = NULL;
4003 volatile uint32_t regPhyAddr = 0x0u;
4006 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4007 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4008 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4009 EDMA3_DVT_dCOUNTER,
4010 EDMA3_DVT_dNONE,
4011 EDMA3_DVT_dNONE));
4012 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4015 /* If parameter checking is enabled... */
4016 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4017 if ((hEdmaResMgr == NULL) || ((regOffset % 4u) != 0))
4018 {
4019 result = (EDMA3_RM_E_INVALID_PARAM);
4020 }
4021 #endif
4023 /* Check if the parameters are OK. */
4024 if (EDMA3_RM_SOK == result)
4025 {
4026 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4027 rmObj = rmInstance->pResMgrObjHandle;
4029 if (rmObj == NULL)
4030 {
4031 result = (EDMA3_RM_E_INVALID_PARAM);
4032 }
4033 else
4034 {
4035 if (rmObj->gblCfgParams.globalRegs != NULL)
4036 {
4037 /**
4038 * Take the instance specific semaphore, to prevent simultaneous
4039 * access to the shared resources.
4040 */
4041 result = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
4042 EDMA3_OSSEM_NO_TIMEOUT);
4044 if (EDMA3_RM_SOK == result)
4045 {
4046 /* Semaphore taken successfully, modify the registers. */
4047 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
4048 EDMA3_OS_PROTECT_INTERRUPT,
4049 &intState);
4050 /* Global interrupts disabled, modify the registers. */
4051 regPhyAddr = (uint32_t)(rmObj->gblCfgParams.globalRegs) + regOffset;
4053 *(uint32_t *)regPhyAddr = newRegValue;
4054 edma3OsProtectExit (rmObj->phyCtrllerInstId,
4055 EDMA3_OS_PROTECT_INTERRUPT,
4056 intState);
4058 /* Return the semaphore back */
4059 result = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
4060 }
4061 }
4062 }
4063 }
4066 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4067 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4068 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4069 EDMA3_DVT_dCOUNTER,
4070 EDMA3_DVT_dNONE,
4071 EDMA3_DVT_dNONE));
4072 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4075 return result;
4076 }
4078 EDMA3_RM_Result EDMA3_RM_getCCRegister (EDMA3_RM_Handle hEdmaResMgr,
4079 uint32_t regOffset,
4080 uint32_t *regValue)
4081 {
4082 EDMA3_RM_Result result = EDMA3_RM_SOK;
4083 EDMA3_RM_Instance *rmInstance = NULL;
4084 EDMA3_RM_Obj *rmObj = NULL;
4085 volatile uint32_t regPhyAddr = 0x0u;
4088 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4089 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4090 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4091 EDMA3_DVT_dCOUNTER,
4092 EDMA3_DVT_dNONE,
4093 EDMA3_DVT_dNONE));
4094 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4097 /* If parameter checking is enabled... */
4098 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4099 if (((hEdmaResMgr == NULL) || (regValue == NULL))
4100 || ((regOffset % 4u) != 0))
4101 {
4102 result = (EDMA3_RM_E_INVALID_PARAM);
4103 }
4104 #endif
4106 /* Check if the parameters are OK. */
4107 if (EDMA3_RM_SOK == result)
4108 {
4109 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4110 rmObj = rmInstance->pResMgrObjHandle;
4112 if (rmObj == NULL)
4113 {
4114 result = (EDMA3_RM_E_INVALID_PARAM);
4115 }
4116 else
4117 {
4118 if (rmObj->gblCfgParams.globalRegs != NULL)
4119 {
4120 regPhyAddr = (uint32_t)(rmObj->gblCfgParams.globalRegs) + regOffset;
4122 *regValue = *(uint32_t *)regPhyAddr;
4123 }
4124 }
4125 }
4128 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4129 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4130 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4131 EDMA3_DVT_dCOUNTER,
4132 EDMA3_DVT_dNONE,
4133 EDMA3_DVT_dNONE));
4134 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4137 return result;
4138 }
4140 EDMA3_RM_Result EDMA3_RM_waitAndClearTcc (EDMA3_RM_Handle hEdmaResMgr,
4141 uint32_t tccNo)
4142 {
4143 EDMA3_RM_Result result = EDMA3_RM_SOK;
4144 EDMA3_RM_Instance *rmInstance = NULL;
4145 EDMA3_RM_Obj *rmObj = NULL;
4146 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4147 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
4148 uint32_t tccBitMask = 0x0u;
4151 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4152 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4153 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4154 EDMA3_DVT_dCOUNTER,
4155 EDMA3_DVT_dNONE,
4156 EDMA3_DVT_dNONE));
4157 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4160 /* If parameter checking is enabled... */
4161 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4162 if (hEdmaResMgr == NULL)
4163 {
4164 result = (EDMA3_RM_E_INVALID_PARAM);
4165 }
4166 #endif
4168 /* Check if the parameters are OK. */
4169 if (EDMA3_RM_SOK == result)
4170 {
4171 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4172 rmObj = rmInstance->pResMgrObjHandle;
4174 if ((rmObj == NULL) || (rmObj->gblCfgParams.globalRegs == NULL))
4175 {
4176 result = (EDMA3_RM_E_INVALID_PARAM);
4177 }
4178 else
4179 {
4180 /* If parameter checking is enabled... */
4181 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4182 if (tccNo >= rmObj->gblCfgParams.numTccs)
4183 {
4184 result = (EDMA3_RM_E_INVALID_PARAM);
4185 }
4186 #endif
4188 /* Check if the parameters are OK. */
4189 if (EDMA3_RM_SOK == result)
4190 {
4191 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4192 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
4193 (&globalRegs->SHADOW[rmInstance->initParam.regionId]);
4196 if (shadowRegs != NULL)
4197 {
4198 if(tccNo < 32u)
4199 {
4200 tccBitMask = (1u << tccNo);
4202 /* Check the status of the IPR[tccNo] bit. */
4203 while (FALSE == (shadowRegs->IPR & tccBitMask))
4204 {
4205 /* Transfer not yet completed, bit not SET */
4206 }
4208 /**
4209 * Bit found SET, transfer is completed,
4210 * clear the pending interrupt and return.
4211 */
4212 shadowRegs->ICR = tccBitMask;
4213 }
4214 else
4215 {
4216 tccBitMask = (1u << (tccNo - 32u));
4218 /* Check the status of the IPRH[tccNo-32] bit. */
4219 while (FALSE == (shadowRegs->IPRH & tccBitMask))
4220 {
4221 /* Transfer not yet completed, bit not SET */
4222 }
4224 /**
4225 * Bit found SET, transfer is completed,
4226 * clear the pending interrupt and return.
4227 */
4228 shadowRegs->ICRH = tccBitMask;
4229 }
4230 }
4231 }
4232 }
4233 }
4236 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4237 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4238 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4239 EDMA3_DVT_dCOUNTER,
4240 EDMA3_DVT_dNONE,
4241 EDMA3_DVT_dNONE));
4242 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4245 return result;
4246 }
4248 EDMA3_RM_Result EDMA3_RM_checkAndClearTcc (EDMA3_RM_Handle hEdmaResMgr,
4249 uint32_t tccNo,
4250 uint16_t *tccStatus)
4251 {
4252 EDMA3_RM_Result result = EDMA3_RM_SOK;
4253 EDMA3_RM_Instance *rmInstance = NULL;
4254 EDMA3_RM_Obj *rmObj = NULL;
4255 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4256 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
4257 uint32_t tccBitMask = 0x0u;
4260 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4261 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4262 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4263 EDMA3_DVT_dCOUNTER,
4264 EDMA3_DVT_dNONE,
4265 EDMA3_DVT_dNONE));
4266 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4269 /* If parameter checking is enabled... */
4270 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4271 if ((hEdmaResMgr == NULL) || (tccStatus == NULL))
4272 {
4273 result = (EDMA3_RM_E_INVALID_PARAM);
4274 }
4275 #endif
4277 /* Check if the parameters are OK. */
4278 if (EDMA3_RM_SOK == result)
4279 {
4280 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4281 rmObj = rmInstance->pResMgrObjHandle;
4283 if ((rmObj == NULL) || (rmObj->gblCfgParams.globalRegs == NULL))
4284 {
4285 result = (EDMA3_RM_E_INVALID_PARAM);
4286 }
4287 else
4288 {
4289 /* If parameter checking is enabled... */
4290 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4291 if (tccNo >= rmObj->gblCfgParams.numTccs)
4292 {
4293 result = (EDMA3_RM_E_INVALID_PARAM);
4294 }
4295 #endif
4297 /* Check if the parameters are OK. */
4298 if (EDMA3_RM_SOK == result)
4299 {
4300 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4301 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
4302 (&globalRegs->SHADOW[rmInstance->initParam.regionId]);
4304 /* Reset the tccStatus */
4305 *tccStatus = FALSE;
4307 if (shadowRegs != NULL)
4308 {
4309 if(tccNo < 32u)
4310 {
4311 tccBitMask = (1u << tccNo);
4313 /* Check the status of the IPR[tccNo] bit. */
4314 if ((shadowRegs->IPR & tccBitMask) != FALSE)
4315 {
4316 /* Transfer completed, bit found SET */
4317 *tccStatus = TRUE;
4319 /* Clear the pending interrupt also. */
4320 shadowRegs->ICR = tccBitMask;
4321 }
4322 }
4323 else
4324 {
4325 tccBitMask = (1u << (tccNo - 32u));
4327 /* Check the status of the IPRH[tccNo-32] bit. */
4328 if ((shadowRegs->IPRH & tccBitMask) != FALSE)
4329 {
4330 /* Transfer completed, bit found SET */
4331 *tccStatus = TRUE;
4333 /* Clear the pending interrupt also. */
4334 shadowRegs->ICRH = tccBitMask;
4335 }
4336 }
4337 }
4338 }
4339 }
4340 }
4343 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4344 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4345 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4346 EDMA3_DVT_dCOUNTER,
4347 EDMA3_DVT_dNONE,
4348 EDMA3_DVT_dNONE));
4349 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4352 return result;
4353 }
4355 EDMA3_RM_Result EDMA3_RM_setPaRAM (EDMA3_RM_Handle hEdmaResMgr,
4356 EDMA3_RM_ResDesc *lChObj,
4357 const EDMA3_RM_PaRAMRegs *newPaRAM)
4358 {
4359 EDMA3_RM_Result result = EDMA3_RM_SOK;
4360 EDMA3_RM_Instance *rmInstance = NULL;
4361 EDMA3_RM_Obj *rmObj = NULL;
4362 int32_t paRAMId = 0u;
4363 uint32_t qdmaChId = 0u;
4364 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4365 uint32_t edma3Id;
4367 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4368 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4369 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4370 EDMA3_DVT_dCOUNTER,
4371 EDMA3_DVT_dNONE,
4372 EDMA3_DVT_dNONE));
4373 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4375 /* If parameter checking is enabled... */
4376 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4377 if (hEdmaResMgr == NULL)
4378 {
4379 result = EDMA3_RM_E_INVALID_PARAM;
4380 }
4382 if ((lChObj == NULL) || (newPaRAM == NULL))
4383 {
4384 result = EDMA3_RM_E_INVALID_PARAM;
4385 }
4386 #endif
4388 /* Check if the parameters are OK. */
4389 if (result == EDMA3_RM_SOK)
4390 {
4391 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4393 if (rmInstance == NULL)
4394 {
4395 result = EDMA3_RM_E_INVALID_PARAM;
4396 }
4397 }
4399 if (result == EDMA3_RM_SOK)
4400 {
4401 rmObj = rmInstance->pResMgrObjHandle;
4403 if (rmObj == NULL)
4404 {
4405 result = EDMA3_RM_E_INVALID_PARAM;
4406 }
4407 else
4408 {
4409 if (rmObj->gblCfgParams.globalRegs == NULL)
4410 {
4411 result = EDMA3_RM_E_INVALID_PARAM;
4412 }
4413 }
4414 }
4416 if (result == EDMA3_RM_SOK)
4417 {
4418 edma3Id = rmObj->phyCtrllerInstId;
4419 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4421 switch (lChObj->type)
4422 {
4423 case EDMA3_RM_RES_DMA_CHANNEL:
4424 {
4425 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4426 {
4427 paRAMId = edma3RmChBoundRes[edma3Id][lChObj->resId].paRAMId;
4428 }
4429 else
4430 {
4431 result = EDMA3_RM_E_INVALID_PARAM;
4432 }
4433 }
4434 break;
4436 case EDMA3_RM_RES_QDMA_CHANNEL:
4437 {
4438 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4439 {
4440 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4441 paRAMId = edma3RmChBoundRes[edma3Id][qdmaChId].paRAMId;
4442 }
4443 else
4444 {
4445 result = EDMA3_RM_E_INVALID_PARAM;
4446 }
4447 }
4448 break;
4450 case EDMA3_RM_RES_PARAM_SET:
4451 {
4452 if (lChObj->resId < edma3NumPaRAMSets)
4453 {
4454 /**
4455 * User has passed the actual param set value here.
4456 * Use this value only
4457 */
4458 paRAMId = (int32_t)(lChObj->resId);
4459 }
4460 else
4461 {
4462 result = EDMA3_RM_E_INVALID_PARAM;
4463 }
4464 }
4465 break;
4467 default:
4468 result = EDMA3_RM_E_INVALID_PARAM;
4469 }
4470 }
4473 if (result == EDMA3_RM_SOK)
4474 {
4475 /* Check the param id first. */
4476 if ((paRAMId != -1) && ((uint32_t)paRAMId < edma3NumPaRAMSets))
4477 {
4478 /* Set the PaRAM Set now. */
4479 edma3ParamCpy ((void *)(&(globalRegs->PARAMENTRY[paRAMId].OPT)),
4480 (const void *)newPaRAM);
4481 }
4482 else
4483 {
4484 result = EDMA3_RM_E_INVALID_PARAM;
4485 }
4486 }
4489 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4490 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4491 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4492 EDMA3_DVT_dCOUNTER,
4493 EDMA3_DVT_dNONE,
4494 EDMA3_DVT_dNONE));
4495 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4497 return result;
4498 }
4500 EDMA3_RM_Result EDMA3_RM_getPaRAM (EDMA3_RM_Handle hEdmaResMgr,
4501 EDMA3_RM_ResDesc *lChObj,
4502 EDMA3_RM_PaRAMRegs *currPaRAM)
4503 {
4504 EDMA3_RM_Result result = EDMA3_RM_SOK;
4505 EDMA3_RM_Instance *rmInstance = NULL;
4506 EDMA3_RM_Obj *rmObj = NULL;
4507 int32_t paRAMId = 0u;
4508 uint32_t qdmaChId = 0u;
4509 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4510 uint32_t edma3Id;
4512 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4513 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4514 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4515 EDMA3_DVT_dCOUNTER,
4516 EDMA3_DVT_dNONE,
4517 EDMA3_DVT_dNONE));
4518 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4520 /* If parameter checking is enabled... */
4521 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4522 if (hEdmaResMgr == NULL)
4523 {
4524 result = EDMA3_RM_E_INVALID_PARAM;
4525 }
4527 if ((lChObj == NULL) || (currPaRAM == NULL))
4528 {
4529 result = EDMA3_RM_E_INVALID_PARAM;
4530 }
4531 #endif
4533 /* Check if the parameters are OK. */
4534 if (result == EDMA3_RM_SOK)
4535 {
4536 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4538 if (rmInstance == NULL)
4539 {
4540 result = EDMA3_RM_E_INVALID_PARAM;
4541 }
4542 }
4544 if (result == EDMA3_RM_SOK)
4545 {
4546 rmObj = rmInstance->pResMgrObjHandle;
4548 if (rmObj == NULL)
4549 {
4550 result = EDMA3_RM_E_INVALID_PARAM;
4551 }
4552 else
4553 {
4554 if (rmObj->gblCfgParams.globalRegs == NULL)
4555 {
4556 result = EDMA3_RM_E_INVALID_PARAM;
4557 }
4558 }
4559 }
4561 if (result == EDMA3_RM_SOK)
4562 {
4563 edma3Id = rmObj->phyCtrllerInstId;
4564 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4566 switch (lChObj->type)
4567 {
4568 case EDMA3_RM_RES_DMA_CHANNEL:
4569 {
4570 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4571 {
4572 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][lChObj->resId].paRAMId;
4573 }
4574 else
4575 {
4576 result = EDMA3_RM_E_INVALID_PARAM;
4577 }
4578 }
4579 break;
4581 case EDMA3_RM_RES_QDMA_CHANNEL:
4582 {
4583 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4584 {
4585 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4586 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId;
4587 }
4588 else
4589 {
4590 result = EDMA3_RM_E_INVALID_PARAM;
4591 }
4592 }
4593 break;
4595 case EDMA3_RM_RES_PARAM_SET:
4596 {
4597 if (lChObj->resId < edma3NumPaRAMSets)
4598 {
4599 /**
4600 * User has passed the actual param set value here.
4601 * Use this value only
4602 */
4603 paRAMId = (int32_t)(lChObj->resId);
4604 }
4605 else
4606 {
4607 result = EDMA3_RM_E_INVALID_PARAM;
4608 }
4609 }
4610 break;
4612 default:
4613 result = EDMA3_RM_E_INVALID_PARAM;
4614 }
4615 }
4618 if (result == EDMA3_RM_SOK)
4619 {
4620 /* Check the param id first. */
4621 if ((paRAMId != -1) && (paRAMId < edma3NumPaRAMSets))
4622 {
4623 /* Get the PaRAM Set now. */
4624 edma3ParamCpy ((void *)currPaRAM ,
4625 (const void *)(&(globalRegs->PARAMENTRY [paRAMId].OPT)));
4626 }
4627 else
4628 {
4629 result = EDMA3_RM_E_INVALID_PARAM;
4630 }
4631 }
4634 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4635 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4636 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4637 EDMA3_DVT_dCOUNTER,
4638 EDMA3_DVT_dNONE,
4639 EDMA3_DVT_dNONE));
4640 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4643 return result;
4644 }
4646 EDMA3_RM_Result EDMA3_RM_getPaRAMPhyAddr(EDMA3_RM_Handle hEdmaResMgr,
4647 EDMA3_RM_ResDesc *lChObj,
4648 uint32_t *paramPhyAddr)
4649 {
4650 EDMA3_RM_Result result = EDMA3_RM_SOK;
4651 EDMA3_RM_Instance *rmInstance = NULL;
4652 EDMA3_RM_Obj *rmObj = NULL;
4653 int32_t paRAMId = 0u;
4654 uint32_t qdmaChId = 0u;
4655 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4656 uint32_t edma3Id;
4658 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4659 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4660 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4661 EDMA3_DVT_dCOUNTER,
4662 EDMA3_DVT_dNONE,
4663 EDMA3_DVT_dNONE));
4664 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4667 /* If parameter checking is enabled... */
4668 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4669 if (hEdmaResMgr == NULL)
4670 {
4671 result = EDMA3_RM_E_INVALID_PARAM;
4672 }
4674 if ((lChObj == NULL) || (paramPhyAddr == NULL))
4675 {
4676 result = EDMA3_RM_E_INVALID_PARAM;
4677 }
4678 #endif
4680 if (result == EDMA3_RM_SOK)
4681 {
4682 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4684 if (rmInstance == NULL)
4685 {
4686 result = EDMA3_RM_E_INVALID_PARAM;
4687 }
4688 }
4690 if (result == EDMA3_RM_SOK)
4691 {
4692 rmObj = rmInstance->pResMgrObjHandle;
4694 if (rmObj == NULL)
4695 {
4696 result = EDMA3_RM_E_INVALID_PARAM;
4697 }
4698 else
4699 {
4700 if (rmObj->gblCfgParams.globalRegs == NULL)
4701 {
4702 result = EDMA3_RM_E_INVALID_PARAM;
4703 }
4704 }
4705 }
4707 if (result == EDMA3_RM_SOK)
4708 {
4709 edma3Id = rmObj->phyCtrllerInstId;
4710 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4712 switch (lChObj->type)
4713 {
4714 case EDMA3_RM_RES_DMA_CHANNEL:
4715 {
4716 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4717 {
4718 paRAMId = edma3RmChBoundRes[edma3Id][lChObj->resId].paRAMId;
4719 }
4720 else
4721 {
4722 result = EDMA3_RM_E_INVALID_PARAM;
4723 }
4724 }
4725 break;
4727 case EDMA3_RM_RES_QDMA_CHANNEL:
4728 {
4729 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4730 {
4731 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4732 paRAMId = edma3RmChBoundRes[edma3Id][qdmaChId].paRAMId;
4733 }
4734 else
4735 {
4736 result = EDMA3_RM_E_INVALID_PARAM;
4737 }
4738 }
4739 break;
4741 case EDMA3_RM_RES_PARAM_SET:
4742 {
4743 if (lChObj->resId < edma3NumPaRAMSets)
4744 {
4745 /**
4746 * User has passed the actual param set value here.
4747 * Use this value only
4748 */
4749 paRAMId = (int32_t)(lChObj->resId);
4750 }
4751 else
4752 {
4753 result = EDMA3_RM_E_INVALID_PARAM;
4754 }
4755 }
4756 break;
4758 default:
4759 result = EDMA3_RM_E_INVALID_PARAM;
4760 }
4761 }
4763 if (result == EDMA3_RM_SOK)
4764 {
4765 /* Check the param id first. */
4766 if ((paRAMId != -1) && (paRAMId < edma3NumPaRAMSets))
4767 {
4768 /* Get the PaRAM Set Address now. */
4769 *paramPhyAddr = (uint32_t)(&(globalRegs->PARAMENTRY [paRAMId].OPT));
4770 }
4771 else
4772 {
4773 result = EDMA3_RM_E_INVALID_PARAM;
4774 }
4775 }
4777 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4778 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4779 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4780 EDMA3_DVT_dCOUNTER,
4781 EDMA3_DVT_dNONE,
4782 EDMA3_DVT_dNONE));
4783 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4785 return result;
4786 }
4788 EDMA3_RM_Result EDMA3_RM_getBaseAddress (EDMA3_RM_Handle hEdmaResMgr,
4789 EDMA3_RM_Cntrlr_PhyAddr controllerId,
4790 uint32_t *phyAddress)
4791 {
4792 EDMA3_RM_Result result = EDMA3_RM_SOK;
4793 EDMA3_RM_Instance *rmInstance = NULL;
4794 EDMA3_RM_Obj *rmObj = NULL;
4796 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4797 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4798 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4799 EDMA3_DVT_dCOUNTER,
4800 EDMA3_DVT_dNONE,
4801 EDMA3_DVT_dNONE));
4802 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4805 /* If parameter checking is enabled... */
4806 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4807 if ((hEdmaResMgr == NULL) || (phyAddress == NULL))
4808 {
4809 result = EDMA3_RM_E_INVALID_PARAM;
4810 }
4811 #endif
4813 if (result == EDMA3_RM_SOK)
4814 {
4815 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4817 if (rmInstance == NULL)
4818 {
4819 result = EDMA3_RM_E_INVALID_PARAM;
4820 }
4821 }
4823 if (result == EDMA3_RM_SOK)
4824 {
4825 rmObj = rmInstance->pResMgrObjHandle;
4827 if (rmObj == NULL)
4828 {
4829 result = EDMA3_RM_E_INVALID_PARAM;
4830 }
4831 }
4833 if (result == EDMA3_RM_SOK)
4834 {
4835 /* If parameter checking is enabled... */
4836 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4837 /* Verify the 'controllerId' */
4838 if (((int32_t)controllerId < (int32_t)((EDMA3_RM_Cntrlr_PhyAddr)(EDMA3_RM_CC_PHY_ADDR)))
4839 || (controllerId > (EDMA3_RM_Cntrlr_PhyAddr)(rmObj->gblCfgParams.numTcs)))
4840 {
4841 /* Invalid controllerId */
4842 result = EDMA3_RM_E_INVALID_PARAM;
4843 }
4844 #endif
4846 /* Check if the parameters are OK. */
4847 if (EDMA3_RM_SOK == result)
4848 {
4849 if (controllerId == EDMA3_RM_CC_PHY_ADDR)
4850 {
4851 /* EDMA3 Channel Controller Address */
4852 *phyAddress = (uint32_t)(rmObj->gblCfgParams.globalRegs);
4853 }
4854 else
4855 {
4856 /**
4857 * Since the TCs enum start from 1, and TCs start from 0,
4858 * subtract 1 from the enum to get the actual address.
4859 */
4860 *phyAddress = (uint32_t)(rmObj->gblCfgParams.tcRegs[controllerId-1u]);
4861 }
4862 }
4863 }
4865 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4866 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4867 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4868 EDMA3_DVT_dCOUNTER,
4869 EDMA3_DVT_dNONE,
4870 EDMA3_DVT_dNONE));
4871 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4873 return result;
4874 }
4876 EDMA3_RM_Result EDMA3_RM_getGblConfigParams (
4877 uint32_t phyCtrllerInstId,
4878 EDMA3_RM_GblConfigParams *gblCfgParams)
4879 {
4880 EDMA3_RM_Result result = EDMA3_RM_SOK;
4882 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4883 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4884 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4885 EDMA3_DVT_dCOUNTER,
4886 EDMA3_DVT_dNONE,
4887 EDMA3_DVT_dNONE));
4888 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4890 /* If parameter checking is enabled... */
4891 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4892 if ((phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
4893 || (NULL == gblCfgParams))
4894 {
4895 result = EDMA3_RM_E_INVALID_PARAM;
4896 }
4897 #endif
4899 if (EDMA3_RM_SOK == result)
4900 {
4901 /* Return the previously saved global config information for the EDMA3 HW */
4902 edma3MemCpy((void *)(gblCfgParams),
4903 (const void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
4904 sizeof (EDMA3_RM_GblConfigParams));
4905 }
4907 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4908 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4909 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4910 EDMA3_DVT_dCOUNTER,
4911 EDMA3_DVT_dNONE,
4912 EDMA3_DVT_dNONE));
4913 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4915 return result;
4916 }
4918 EDMA3_RM_Result EDMA3_RM_getInstanceInitCfg (
4919 EDMA3_RM_Handle hEdmaResMgr,
4920 EDMA3_RM_InstanceInitConfig *instanceInitConfig)
4921 {
4922 EDMA3_RM_Result result = EDMA3_RM_SOK;
4923 EDMA3_RM_Instance *rmInstance = NULL;
4924 EDMA3_RM_Obj *rmObj = NULL;
4925 uint32_t resMgrIdx = 0u;
4926 uint32_t hwId;
4928 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4929 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4930 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4931 EDMA3_DVT_dCOUNTER,
4932 EDMA3_DVT_dNONE,
4933 EDMA3_DVT_dNONE));
4934 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4936 /* If parameter checking is enabled... */
4937 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4938 if ((hEdmaResMgr == NULL) || (instanceInitConfig == NULL))
4939 {
4940 result = EDMA3_RM_E_INVALID_PARAM;
4941 }
4942 #endif
4944 if (result == EDMA3_RM_SOK)
4945 {
4946 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4948 if (rmInstance == NULL)
4949 {
4950 result = EDMA3_RM_E_INVALID_PARAM;
4951 }
4952 }
4954 if (result == EDMA3_RM_SOK)
4955 {
4956 rmObj = rmInstance->pResMgrObjHandle;
4958 if (rmObj == NULL)
4959 {
4960 result = EDMA3_RM_E_INVALID_PARAM;
4961 }
4962 }
4964 if (result == EDMA3_RM_SOK)
4965 {
4966 hwId = rmObj->phyCtrllerInstId;
4968 for (resMgrIdx = 0u; resMgrIdx < EDMA3_MAX_RM_INSTANCES; resMgrIdx++)
4969 {
4970 if (rmInstance == ((EDMA3_RM_Instance *)(ptrRMIArray) +
4971 (hwId*EDMA3_MAX_RM_INSTANCES) +
4972 resMgrIdx))
4973 {
4974 /* RM Id found. Return the specific config info to the user. */
4975 edma3MemCpy((void *)(instanceInitConfig),
4976 (const void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) +
4977 (hwId*EDMA3_MAX_RM_INSTANCES) +
4978 resMgrIdx),
4979 sizeof (EDMA3_RM_InstanceInitConfig));
4980 break;
4981 }
4982 }
4984 if (EDMA3_MAX_RM_INSTANCES == resMgrIdx)
4985 {
4986 /* RM Id not found, report error... */
4987 result = EDMA3_RM_E_INVALID_PARAM;
4988 }
4989 }
4991 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4992 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4993 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4994 EDMA3_DVT_dCOUNTER,
4995 EDMA3_DVT_dNONE,
4996 EDMA3_DVT_dNONE));
4997 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4999 return result;
5000 }
5002 EDMA3_RM_Result EDMA3_RM_Ioctl(
5003 EDMA3_RM_Handle hEdmaResMgr,
5004 EDMA3_RM_IoctlCmd cmd,
5005 void *cmdArg,
5006 void *param
5007 )
5008 {
5009 EDMA3_RM_Result result = EDMA3_RM_SOK;
5010 EDMA3_RM_Instance *rmInstance = NULL;
5011 uint32_t paramInitRequired = 0xFFu;
5012 uint32_t regModificationRequired = 0xFFu;
5013 uint32_t *ret_val = NULL;
5015 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5016 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5017 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
5018 EDMA3_DVT_dCOUNTER,
5019 EDMA3_DVT_dNONE,
5020 EDMA3_DVT_dNONE));
5021 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5023 /* If parameter checking is enabled... */
5024 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5025 if (hEdmaResMgr == NULL)
5026 {
5027 result = EDMA3_RM_E_INVALID_PARAM;
5028 }
5030 if ((cmd <= EDMA3_RM_IOCTL_MIN_IOCTL)
5031 || (cmd >= EDMA3_RM_IOCTL_MAX_IOCTL))
5032 {
5033 result = EDMA3_RM_E_INVALID_PARAM;
5034 }
5035 #endif
5037 if (result == EDMA3_RM_SOK)
5038 {
5039 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
5041 if (rmInstance == NULL)
5042 {
5043 result = EDMA3_RM_E_INVALID_PARAM;
5044 }
5045 }
5047 /* To remove CCS warnings */
5048 (void)param;
5050 if (result == EDMA3_RM_SOK)
5051 {
5052 switch (cmd)
5053 {
5054 case EDMA3_RM_IOCTL_SET_PARAM_CLEAR_OPTION:
5055 {
5056 paramInitRequired = (uint32_t)cmdArg;
5058 /* If parameter checking is enabled... */
5059 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5060 if ((paramInitRequired != 0u)
5061 && (paramInitRequired != 1u))
5062 {
5063 result = EDMA3_RM_E_INVALID_PARAM;
5064 }
5065 #endif
5067 /* Check if the parameters are OK. */
5068 if (EDMA3_RM_SOK == result)
5069 {
5070 /* Set/Reset the flag which is being used to do the PaRAM clearing. */
5071 rmInstance->paramInitRequired = paramInitRequired;
5072 }
5074 break;
5075 }
5077 case EDMA3_RM_IOCTL_GET_PARAM_CLEAR_OPTION:
5078 {
5079 /* If parameter checking is enabled... */
5080 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5081 if (NULL == cmdArg)
5082 {
5083 result = EDMA3_RM_E_INVALID_PARAM;
5084 }
5085 #endif
5087 /* Check if the parameters are OK. */
5088 if (EDMA3_RM_SOK == result)
5089 {
5090 ret_val = (uint32_t *)cmdArg;
5092 /* Get the flag which is being used to do the PaRAM clearing. */
5093 *ret_val = rmInstance->paramInitRequired;
5094 }
5096 break;
5097 }
5099 case EDMA3_RM_IOCTL_SET_GBL_REG_MODIFY_OPTION:
5100 {
5101 regModificationRequired = (uint32_t)cmdArg;
5103 /* If parameter checking is enabled... */
5104 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5105 if ((regModificationRequired != 0u)
5106 && (regModificationRequired != 1u))
5107 {
5108 /* All other values are invalid. */
5109 result = EDMA3_RM_E_INVALID_PARAM;
5110 }
5111 #endif
5113 /* Check if the parameters are OK. */
5114 if (EDMA3_RM_SOK == result)
5115 {
5116 /**
5117 * Set/Reset the flag which is being used to do the global
5118 * registers and PaRAM modification.
5119 */
5120 rmInstance->regModificationRequired = regModificationRequired;
5121 }
5123 break;
5124 }
5126 case EDMA3_RM_IOCTL_GET_GBL_REG_MODIFY_OPTION:
5127 {
5128 /* If parameter checking is enabled... */
5129 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5130 if (NULL == cmdArg)
5131 {
5132 result = EDMA3_RM_E_INVALID_PARAM;
5133 }
5134 #endif
5136 /* Check if the parameters are OK. */
5137 if (EDMA3_RM_SOK == result)
5138 {
5139 ret_val = (uint32_t *)cmdArg;
5141 /**
5142 * Get the flag which is being used to do the global
5143 * registers and PaRAM modification.
5144 */
5145 *ret_val = rmInstance->regModificationRequired;
5146 }
5148 break;
5149 }
5151 default:
5152 /* Hey dude! you passed invalid IOCTL cmd */
5153 result = EDMA3_RM_E_INVALID_PARAM;
5155 }
5156 }
5159 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5160 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5161 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5162 EDMA3_DVT_dCOUNTER,
5163 EDMA3_DVT_dNONE,
5164 EDMA3_DVT_dNONE));
5165 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5167 return result;
5169 }
5171 /**
5172 * edma3ComplHandler
5173 * \brief Interrupt handler for successful transfer completion.
5174 *
5175 * \note This function first disables its own interrupt to make it non-
5176 * entrant. Later, after calling all the callback functions, it
5177 * re-enables its own interrupt.
5178 *
5179 * \return None.
5180 */
5181 static void edma3ComplHandler (const EDMA3_RM_Obj *rmObj)
5182 {
5183 uint32_t Cnt;
5184 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
5185 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
5186 volatile uint32_t pendingIrqs;
5187 volatile uint32_t isIPR = 0;
5189 uint32_t indexl;
5190 uint32_t indexh;
5191 uint32_t edma3Id;
5192 uint32_t numTCCs;
5194 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5195 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5196 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5197 EDMA3_DVT_dNONE,
5198 EDMA3_DVT_dNONE,
5199 EDMA3_DVT_dNONE));
5200 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5202 assert (NULL != rmObj);
5204 edma3Id = rmObj->phyCtrllerInstId;
5205 numTCCs = rmObj->gblCfgParams.numTccs;
5206 ptrEdmaccRegs =
5207 (volatile EDMA3_CCRL_Regs *)rmObj->gblCfgParams.globalRegs;
5208 if (ptrEdmaccRegs != NULL)
5209 {
5210 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
5211 (&ptrEdmaccRegs->SHADOW[edma3RegionId]);
5212 }
5214 Cnt = 0u;
5215 pendingIrqs = 0u;
5216 indexl = 1u;
5217 indexh = 1u;
5219 if (numTCCs > 32)
5220 isIPR = shadowRegs->IPR | shadowRegs->IPRH;
5221 else
5222 isIPR = shadowRegs->IPR;
5224 if(isIPR)
5225 {
5226 /**
5227 * Since an interrupt has found, we have to make sure that this
5228 * interrupt (TCC) belongs to the TCCs allocated by us only.
5229 * It might happen that someone else, who is using EDMA3 also,
5230 * is the owner of this interrupt channel i.e. the TCC.
5231 * For this, use the allocatedTCCs[], to check which all interrupt
5232 * channels are owned by the EDMA3 RM Instances.
5233 */
5235 edma3OsProtectEntry (edma3Id,
5236 EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,
5237 NULL);
5239 /* Loop for EDMA3_RM_COMPL_HANDLER_RETRY_COUNT number of time,
5240 breaks when no pending interrupt is found */
5241 while ((Cnt < EDMA3_RM_COMPL_HANDLER_RETRY_COUNT)
5242 && ((indexl != 0u) || (indexh != 0u)))
5243 {
5244 indexl = 0u;
5245 pendingIrqs = shadowRegs->IPR;
5247 /**
5248 * Choose interrupts coming from our allocated TCCs
5249 * and MASK remaining ones.
5250 */
5251 pendingIrqs = (pendingIrqs & allocatedTCCs[edma3Id][0u]);
5253 while (pendingIrqs)
5254 {
5255 /*Process all the pending interrupts*/
5256 if((pendingIrqs & 1u) == TRUE)
5257 {
5258 /**
5259 * If the user has not given any callback function
5260 * while requesting the TCC, its TCC specific bit
5261 * in the IPR register will NOT be cleared.
5262 */
5263 if(edma3IntrParams[edma3Id][indexl].tccCb != NULL)
5264 {
5265 /* here write to ICR to clear the corresponding IPR bits*/
5266 shadowRegs->ICR = (1u << indexl);
5268 edma3IntrParams[edma3Id][indexl].tccCb (indexl,
5269 EDMA3_RM_XFER_COMPLETE,
5270 edma3IntrParams[edma3Id][indexl].cbData);
5271 }
5272 }
5273 ++indexl;
5274 pendingIrqs >>= 1u;
5275 }
5277 if(numTCCs > 32)
5278 {
5279 indexh = 0u;
5280 pendingIrqs = shadowRegs->IPRH;
5282 /**
5283 * Choose interrupts coming from our allocated TCCs
5284 * and MASK remaining ones.
5285 */
5286 pendingIrqs = (pendingIrqs & allocatedTCCs[edma3Id][1u]);
5288 while (pendingIrqs)
5289 {
5290 /*Process all the pending interrupts*/
5291 if((pendingIrqs & 1u)==TRUE)
5292 {
5293 /**
5294 * If the user has not given any callback function
5295 * while requesting the TCC, its TCC specific bit
5296 * in the IPRH register will NOT be cleared.
5297 */
5298 if(edma3IntrParams[edma3Id][32u+indexh].tccCb!=NULL)
5299 {
5300 /* here write to ICR to clear the corresponding IPR bits*/
5301 shadowRegs->ICRH = (1u << indexh);
5303 edma3IntrParams[edma3Id][32u+indexh].tccCb(32u+indexh,
5304 EDMA3_RM_XFER_COMPLETE,
5305 edma3IntrParams[edma3Id][32u+indexh].cbData);
5306 }
5307 }
5308 ++indexh;
5309 pendingIrqs >>= 1u;
5310 }
5311 }
5313 Cnt++;
5314 }
5316 indexl = (shadowRegs->IPR & allocatedTCCs[edma3Id][0u]);
5317 if (numTCCs > 32)
5318 indexh = (shadowRegs->IPRH & allocatedTCCs[edma3Id][1u]);
5320 if((indexl !=0 ) || (indexh !=0 ))
5321 {
5322 shadowRegs->IEVAL=0x1u;
5323 }
5325 edma3OsProtectExit (rmObj->phyCtrllerInstId,
5326 EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,
5327 NULL);
5328 }
5330 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5331 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5332 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5333 EDMA3_DVT_dNONE,
5334 EDMA3_DVT_dNONE,
5335 EDMA3_DVT_dNONE));
5336 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5337 }
5340 void lisrEdma3ComplHandler0(uint32_t edma3InstanceId)
5341 {
5342 /* Invoke Completion Handler ISR */
5343 edma3ComplHandler(&resMgrObj[edma3InstanceId]);
5344 }
5347 /**
5348 * \brief Interrupt handler for Channel Controller Error.
5349 *
5350 * \note This function first disables its own interrupt to make it non-
5351 * entrant. Later, after calling all the callback functions, it
5352 * re-enables its own interrupt.
5353 *
5354 * \return None.
5355 */
5356 static void edma3CCErrHandler(const EDMA3_RM_Obj *rmObj)
5357 {
5358 uint32_t Cnt = 0u;
5359 uint32_t resMgrInstIdx = 0u;
5360 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
5361 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
5362 volatile uint32_t pendingIrqs = 0;
5363 uint32_t index;
5364 uint32_t evtqueNum;
5365 EDMA3_RM_Instance *rm_instance = NULL;
5366 uint32_t edma3Id;
5367 uint32_t num_rm_instances_opened;
5368 EDMA3_RM_Instance *rmInstance = NULL;
5369 uint32_t ownedDmaError = 0;
5370 uint32_t ownedDmaHError = 0;
5371 uint32_t ownedQdmaError = 0;
5372 uint32_t numTCCs;
5374 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5375 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_CCERR",
5376 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5377 EDMA3_DVT_dNONE,
5378 EDMA3_DVT_dNONE,
5379 EDMA3_DVT_dNONE));
5380 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5382 assert (rmObj != NULL);
5384 edma3Id = rmObj->phyCtrllerInstId;
5385 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)rmObj->gblCfgParams.globalRegs;
5386 numTCCs = rmObj->gblCfgParams.numTccs;
5387 if (ptrEdmaccRegs != NULL)
5388 {
5389 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)&ptrEdmaccRegs->SHADOW[edma3RegionId];
5390 rmInstance = ((EDMA3_RM_Instance *)(ptrRMIArray)
5391 + (edma3Id*EDMA3_MAX_RM_INSTANCES)
5392 + edma3RegionId);
5394 pendingIrqs = ((ptrEdmaccRegs->EMR != 0 )
5395 || (ptrEdmaccRegs->QEMR != 0)
5396 || (ptrEdmaccRegs->CCERR != 0));
5397 if (numTCCs > 32)
5398 {
5399 pendingIrqs = pendingIrqs || (ptrEdmaccRegs->EMRH != 0 );
5400 }
5401 index = 1u;
5403 if(pendingIrqs)
5404 {
5405 edma3OsProtectEntry (edma3Id,
5406 EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR,
5407 NULL);
5409 /* Loop for EDMA3_RM_CCERR_HANDLER_RETRY_COUNT number of time,
5410 breaks when no pending interrupt is found */
5411 while ((Cnt < EDMA3_RM_CCERR_HANDLER_RETRY_COUNT)
5412 && (index != 0u))
5413 {
5414 index = 0u;
5415 pendingIrqs = ptrEdmaccRegs->EMR;
5417 while (pendingIrqs)
5418 {
5419 /*Process all the pending interrupts*/
5420 if((pendingIrqs & 1u)==TRUE)
5421 {
5422 uint32_t mappedTcc = 0u;
5424 /**
5425 * Using the 'index' value (basically the DMA
5426 * channel), fetch the corresponding TCC
5427 * value, mapped to this DMA channel.
5428 */
5429 mappedTcc = edma3DmaChTccMapping[edma3Id][index];
5431 /**
5432 * Ensure that the mapped tcc is valid and the call
5433 * back is not NULL
5434 */
5435 if (mappedTcc < EDMA3_MAX_TCC)
5436 {
5437 /**
5438 * TCC owned and allocated by RM.
5439 * Write to EMCR to clear the corresponding EMR bits.
5440 */
5441 ptrEdmaccRegs->EMCR = (1u<<index);
5442 /*Clear any SER*/
5443 shadowRegs->SECR = (1u<<index);
5445 /* Call the callback function if registered earlier. */
5446 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5447 {
5448 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5449 mappedTcc,
5450 EDMA3_RM_E_CC_DMA_EVT_MISS,
5451 edma3IntrParams[edma3Id][mappedTcc].cbData
5452 );
5453 }
5454 }
5455 else
5456 {
5457 /**
5458 * DMA channel not owned by the RM instance.
5459 * Check the global error interrupt clearing option.
5460 * If it is TRUE, clear the error interupt else leave
5461 * it like that.
5462 */
5463 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5464 /* here write to EMCR to clear the corresponding EMR bits. */
5465 ptrEdmaccRegs->EMCR = (1u<<index);
5466 /*Clear any SER*/
5467 ptrEdmaccRegs->SECR = (1u<<index);
5468 #endif
5469 }
5470 }
5471 ++index;
5472 pendingIrqs >>= 1u;
5473 }
5475 if(numTCCs > 32)
5476 {
5477 index = 0u;
5478 pendingIrqs = ptrEdmaccRegs->EMRH;
5479 while (pendingIrqs)
5480 {
5481 /*Process all the pending interrupts*/
5482 if((pendingIrqs & 1u)==TRUE)
5483 {
5484 uint32_t mappedTcc = 0u;
5486 /**
5487 * Using the 'index' value (basically the DMA
5488 * channel), fetch the corresponding TCC
5489 * value, mapped to this DMA channel.
5490 */
5491 mappedTcc = edma3DmaChTccMapping[edma3Id][32u+index];
5493 /**
5494 * Ensure that the mapped tcc is valid and the call
5495 * back is not NULL
5496 */
5497 if (mappedTcc < EDMA3_MAX_TCC)
5498 {
5499 /**
5500 * TCC owned and allocated by RM.
5501 * Write to EMCR to clear the corresponding EMR bits.
5502 */
5503 ptrEdmaccRegs->EMCRH = (1u<<index);
5504 /*Clear any SERH*/
5505 shadowRegs->SECRH = (1u<<index);
5507 /* Call the callback function if registered earlier. */
5508 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5509 {
5510 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5511 mappedTcc,
5512 EDMA3_RM_E_CC_DMA_EVT_MISS,
5513 edma3IntrParams[edma3Id][mappedTcc].cbData
5514 );
5515 }
5516 }
5517 else
5518 {
5519 /**
5520 * DMA channel not owned by the RM instance.
5521 * Check the global error interrupt clearing option.
5522 * If it is TRUE, clear the error interupt else leave
5523 * it like that.
5524 */
5525 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5526 /**
5527 * TCC NOT owned by RM.
5528 * Write to EMCRH to clear the corresponding EMRH bits.
5529 */
5530 ptrEdmaccRegs->EMCRH = (1u<<index);
5531 /*Clear any SERH*/
5532 shadowRegs->SECRH = (1u<<index);
5533 #endif
5534 }
5535 }
5536 ++index;
5537 pendingIrqs >>= 1u;
5538 }
5539 }
5541 index = 0u;
5542 pendingIrqs = ptrEdmaccRegs->QEMR;
5543 while (pendingIrqs)
5544 {
5545 /*Process all the pending interrupts*/
5546 if((pendingIrqs & 1u)==TRUE)
5547 {
5548 uint32_t mappedTcc = 0u;
5550 /**
5551 * Using the 'index' value (basically the QDMA
5552 * channel), fetch the corresponding TCC
5553 * value, mapped to this QDMA channel.
5554 */
5555 mappedTcc = edma3QdmaChTccMapping[edma3Id][index];
5557 if (mappedTcc < EDMA3_MAX_TCC)
5558 {
5559 /* here write to QEMCR to clear the corresponding QEMR bits*/
5560 ptrEdmaccRegs->QEMCR = (1u<<index);
5561 /*Clear any QSER*/
5562 shadowRegs->QSECR = (1u<<index);
5564 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5565 {
5566 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5567 mappedTcc,
5568 EDMA3_RM_E_CC_QDMA_EVT_MISS,
5569 edma3IntrParams[edma3Id][mappedTcc].cbData
5570 );
5571 }
5572 }
5573 else
5574 {
5575 /**
5576 * QDMA channel not owned by the RM instance.
5577 * Check the global error interrupt clearing option.
5578 * If it is TRUE, clear the error interupt else leave
5579 * the ISR.
5580 */
5581 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5582 /* here write to QEMCR to clear the corresponding QEMR bits*/
5583 ptrEdmaccRegs->QEMCR = (1u<<index);
5585 /*Clear any QSER*/
5586 ptrEdmaccRegs->QSECR = (1u<<index);
5587 #endif
5588 }
5589 }
5590 ++index;
5591 pendingIrqs >>= 1u;
5592 }
5594 index = 0u;
5595 pendingIrqs = ptrEdmaccRegs->CCERR;
5596 if (pendingIrqs!=NULL)
5597 {
5598 /* Process all the pending CC error interrupts. */
5600 /* Queue threshold error for different event queues.*/
5601 for (evtqueNum = 0u; evtqueNum < rmObj->gblCfgParams.numEvtQueue; evtqueNum++)
5602 {
5603 if((pendingIrqs & (1u << evtqueNum)) != NULL)
5604 {
5605 /**
5606 * Queue threshold error for queue 'evtqueNum' raised.
5607 * Inform all the RM instances working on this region
5608 * about the error by calling their global callback functions.
5609 */
5610 num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
5611 for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
5612 {
5613 /* Check whether the RM instance opened working on this region */
5614 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5615 if (NULL != rm_instance)
5616 {
5617 if (rm_instance->initParam.regionId == edma3RegionId)
5618 {
5619 /* Region id matches, call the callback function */
5620 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5621 {
5622 rm_instance->initParam.gblerrCbParams.gblerrCb(
5623 EDMA3_RM_E_CC_QUE_THRES_EXCEED,
5624 evtqueNum,
5625 rm_instance->initParam.gblerrCbParams.gblerrData);
5626 }
5627 }
5628 }
5630 /* Check next opened instance */
5631 num_rm_instances_opened--;
5632 }
5634 /* Clear the error interrupt. */
5635 ptrEdmaccRegs->CCERRCLR = (1u << evtqueNum);
5636 }
5637 }
5640 /* Transfer completion code error. */
5641 if ((pendingIrqs & (1 << EDMA3_CCRL_CCERR_TCCERR_SHIFT))!=NULL)
5642 {
5643 /**
5644 * Transfer completion code error raised.
5645 * Inform all the RM instances working on this region
5646 * about the error by calling their global callback functions.
5647 */
5648 num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
5649 for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
5650 {
5651 /* Check whether the RM instance opened working on this region */
5652 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5653 if (NULL != rm_instance)
5654 {
5655 if (rm_instance->initParam.regionId == edma3RegionId)
5656 {
5657 /* Region id matches, call the callback function */
5658 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5659 {
5660 rm_instance->initParam.gblerrCbParams.gblerrCb(
5661 EDMA3_RM_E_CC_TCC,
5662 NULL,
5663 rm_instance->initParam.gblerrCbParams.gblerrData);
5664 }
5665 }
5666 }
5668 /* Check next opened instance */
5669 num_rm_instances_opened--;
5670 }
5672 ptrEdmaccRegs->CCERRCLR = (1<<EDMA3_CCRL_CCERR_TCCERR_SHIFT);
5673 }
5675 ++index;
5676 }
5678 Cnt++;
5679 }
5682 /**
5683 * Read the error registers again. If any interrupt is pending,
5684 * write the EEVAL register.
5685 * Moreover, according to the global error interrupt clearing
5686 * option, check either error bits associated with all the
5687 * DMA/QDMA channels (option is SET) OR check error bits
5688 * associated with owned DMA/QDMA channels.
5689 */
5690 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5691 /* To remove warning. */
5692 rmInstance = rmInstance;
5694 /* Check all the error bits. */
5695 ownedDmaError = ptrEdmaccRegs->EMR;
5696 if (numTCCs > 32)
5697 ownedDmaHError = ptrEdmaccRegs->EMRH;
5698 ownedQdmaError = ptrEdmaccRegs->QEMR;
5699 #else
5700 /* Check ONLY owned error bits. */
5701 ownedDmaError = (ptrEdmaccRegs->EMR & rmInstance->initParam.rmInstInitConfig->ownDmaChannels[0u]);
5702 if (numTCCs > 32)
5703 ownedDmaHError = (ptrEdmaccRegs->EMRH & rmInstance->initParam.rmInstInitConfig->ownDmaChannels[1u]);
5704 ownedQdmaError = (ptrEdmaccRegs->QEMR & rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u]);
5705 #endif
5707 if (((ownedDmaError != 0 ) || (ownedDmaHError != 0 ))
5708 || ((ownedQdmaError != 0) || (ptrEdmaccRegs->CCERR != 0)))
5709 {
5710 ptrEdmaccRegs->EEVAL=0x1u;
5711 }
5713 edma3OsProtectExit (rmObj->phyCtrllerInstId,
5714 EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR,
5715 NULL);
5716 }
5717 }
5719 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5720 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_CCERR",
5721 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5722 EDMA3_DVT_dNONE,
5723 EDMA3_DVT_dNONE,
5724 EDMA3_DVT_dNONE));
5725 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5726 }
5728 void lisrEdma3CCErrHandler0(uint32_t edma3InstanceId)
5729 {
5730 /* Invoke CC Error Handler ISR */
5731 edma3CCErrHandler(&resMgrObj[edma3InstanceId]);
5732 }
5736 /**
5737 * \brief Interrupt handler for Transfer Controller Error.
5738 *
5739 * \note This function first disables its own interrupt to make it non-
5740 * entrant. Later, after calling all the callback functions, it
5741 * re-enables its own interrupt.
5742 *
5743 * \return None.
5744 */
5745 static void edma3TCErrHandler (const EDMA3_RM_Obj *rmObj, uint32_t tcNum)
5746 {
5747 volatile EDMA3_TCRL_Regs *tcRegs = NULL;
5748 uint32_t tcMemErrRdWr = 0u;
5749 uint32_t resMgrInstIdx = 0u;
5750 EDMA3_RM_Instance *rm_instance = NULL;
5751 uint32_t edma3Id;
5752 uint32_t num_rm_instances_opened;
5754 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5755 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_TCERR",
5756 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5757 EDMA3_DVT_dNONE,
5758 EDMA3_DVT_dNONE,
5759 EDMA3_DVT_dNONE));
5760 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5762 assert ((rmObj != NULL) && (tcNum < rmObj->gblCfgParams.numTcs));
5764 if (rmObj->gblCfgParams.tcRegs[tcNum] != NULL)
5765 {
5766 tcRegs = (volatile EDMA3_TCRL_Regs *)(rmObj->gblCfgParams.tcRegs[tcNum]);
5767 edma3Id = rmObj->phyCtrllerInstId;
5768 }
5770 if (tcRegs != NULL)
5771 {
5772 if(tcRegs->ERRSTAT != 0)
5773 {
5774 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
5775 EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR,
5776 &tcNum);
5778 if((tcRegs->ERRSTAT & (1 << EDMA3_TCRL_ERRSTAT_BUSERR_SHIFT))!=NULL)
5779 {
5780 /* Bus error event. */
5781 /**
5782 * EDMA3TC has detected an error at source or destination
5783 * address. Error information can be read from the error
5784 * details register (ERRDET).
5785 */
5786 tcMemErrRdWr = tcRegs->ERRDET & (EDMA3_TCRL_ERRDET_STAT_MASK);
5787 if ((tcMemErrRdWr > 0u) && (tcMemErrRdWr < 8u))
5788 {
5789 /**
5790 * Inform all the RM instances working on this region
5791 * about the error by calling their global callback functions.
5792 */
5793 num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
5794 for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
5795 {
5796 /* Check whether the RM instance opened working on this region */
5797 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5798 if (NULL != rm_instance)
5799 {
5800 if (rm_instance->initParam.regionId == edma3RegionId)
5801 {
5802 /* Region id matches, call the callback function */
5803 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5804 {
5805 rm_instance->initParam.gblerrCbParams.gblerrCb(
5806 EDMA3_RM_E_TC_MEM_LOCATION_READ_ERROR,
5807 tcNum,
5808 rm_instance->initParam.gblerrCbParams.gblerrData);
5809 }
5810 }
5811 }
5813 /* Check next opened instance */
5814 num_rm_instances_opened--;
5815 }
5816 }
5817 else
5818 {
5819 if ((tcMemErrRdWr >= 8u) && (tcMemErrRdWr <= 0xFu))
5820 {
5821 /**
5822 * Inform all the RM instances working on this region
5823 * about the error by calling their global callback functions.
5824 */
5825 num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
5826 for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
5827 {
5828 /* Check whether the RM instance opened working on this region */
5829 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5830 if (NULL != rm_instance)
5831 {
5832 if (rm_instance->initParam.regionId == edma3RegionId)
5833 {
5834 /* Region id matches, call the callback function */
5835 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5836 {
5837 rm_instance->initParam.gblerrCbParams.gblerrCb(
5838 EDMA3_RM_E_TC_MEM_LOCATION_WRITE_ERROR,
5839 tcNum,
5840 rm_instance->initParam.gblerrCbParams.gblerrData);
5841 }
5842 }
5843 }
5845 /* Check next opened instance */
5846 num_rm_instances_opened--;
5847 }
5848 }
5849 }
5850 tcRegs->ERRCLR = (1<<EDMA3_TCRL_ERRSTAT_BUSERR_SHIFT);
5851 }
5852 else
5853 {
5854 /* Transfer request (TR) error event. */
5855 if((tcRegs->ERRSTAT & (1 << EDMA3_TCRL_ERRSTAT_TRERR_SHIFT))!=NULL)
5856 {
5857 num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
5858 for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
5859 {
5860 /* Check whether the RM instance opened working on this region */
5861 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5862 if (NULL != rm_instance)
5863 {
5864 if (rm_instance->initParam.regionId == edma3RegionId)
5865 {
5866 /* Region id matches, call the callback function */
5867 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5868 {
5869 rm_instance->initParam.gblerrCbParams.gblerrCb(
5870 EDMA3_RM_E_TC_TR_ERROR,
5871 tcNum,
5872 rm_instance->initParam.gblerrCbParams.gblerrData);
5873 }
5874 }
5875 }
5877 /* Check next opened instance */
5878 num_rm_instances_opened--;
5879 }
5881 tcRegs->ERRCLR = (1<<EDMA3_TCRL_ERRSTAT_TRERR_SHIFT);
5882 }
5883 else
5884 {
5885 if((tcRegs->ERRSTAT & (1 << EDMA3_TCRL_ERRSTAT_MMRAERR_SHIFT))!=NULL)
5886 {
5887 num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
5888 for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
5889 {
5890 /* Check whether the RM instance opened working on this region */
5891 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5892 if (NULL != rm_instance)
5893 {
5894 if (rm_instance->initParam.regionId == edma3RegionId)
5895 {
5896 /* Region id matches, call the callback function */
5897 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5898 {
5899 rm_instance->initParam.gblerrCbParams.gblerrCb(
5900 EDMA3_RM_E_TC_INVALID_ADDR,
5901 tcNum,
5902 rm_instance->initParam.gblerrCbParams.gblerrData);
5903 }
5904 }
5905 }
5907 /* Check next opened instance */
5908 num_rm_instances_opened--;
5909 }
5911 tcRegs->ERRCLR = (1<<EDMA3_TCRL_ERRSTAT_MMRAERR_SHIFT);
5912 }
5913 }
5914 }
5916 edma3OsProtectExit (rmObj->phyCtrllerInstId,
5917 EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR,
5918 tcNum);
5919 }
5920 }
5922 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5923 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_TCERR",
5924 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5925 EDMA3_DVT_dNONE,
5926 EDMA3_DVT_dNONE,
5927 EDMA3_DVT_dNONE));
5928 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5929 }
5933 /*
5934 * ======== lisrEdma3TC0ErrHandler0 ========
5935 * EDMA3 instance 0 TC0 Error Interrupt Service Routine
5936 */
5937 void lisrEdma3TC0ErrHandler0(uint32_t edma3InstanceId)
5938 {
5939 /* Invoke Error Handler ISR for TC0*/
5940 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 0u);
5941 }
5944 /*
5945 * ======== lisrEdma3TC1ErrHandler0 ========
5946 * EDMA3 instance 0 TC1 Error Interrupt Service Routine
5947 */
5948 void lisrEdma3TC1ErrHandler0(uint32_t edma3InstanceId)
5949 {
5950 /* Invoke Error Handler ISR for TC1*/
5951 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 1u);
5952 }
5954 /*
5955 * ======== lisrEdma3TC2ErrHandler0 ========
5956 * EDMA3 instance 0 TC2 Error Interrupt Service Routine
5957 */
5958 void lisrEdma3TC2ErrHandler0(uint32_t edma3InstanceId)
5959 {
5960 /* Invoke Error Handler ISR for TC2*/
5961 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 2u);
5962 }
5964 /*
5965 * ======== lisrEdma3TC3ErrHandler0 ========
5966 * EDMA3 instance 0 TC3 Error Interrupt Service Routine
5967 */
5968 void lisrEdma3TC3ErrHandler0(uint32_t edma3InstanceId)
5969 {
5970 /* Invoke Error Handler ISR for TC3*/
5971 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 3u);
5972 }
5974 /*
5975 * ======== lisrEdma3TC4ErrHandler0 ========
5976 * EDMA3 instance 0 TC4 Error Interrupt Service Routine
5977 */
5978 void lisrEdma3TC4ErrHandler0(uint32_t edma3InstanceId)
5979 {
5980 /* Invoke Error Handler ISR for TC4*/
5981 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 4u);
5982 }
5985 /*
5986 * ======== lisrEdma3TC5ErrHandler0 ========
5987 * EDMA3 instance 0 TC5 Error Interrupt Service Routine
5988 */
5989 void lisrEdma3TC5ErrHandler0(uint32_t edma3InstanceId)
5990 {
5991 /* Invoke Error Handler ISR for TC5*/
5992 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 5u);
5993 }
5995 /*
5996 * ======== lisrEdma3TC6ErrHandler0 ========
5997 * EDMA3 instance 0 TC6 Error Interrupt Service Routine
5998 */
5999 /* ARGSUSED */
6000 void lisrEdma3TC6ErrHandler0(uint32_t edma3InstanceId)
6001 {
6002 /* Invoke Error Handler ISR for TC6*/
6003 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 6u);
6004 }
6006 /*
6007 * ======== lisrEdma3TC7ErrHandler0 ========
6008 * EDMA3 instance 0 TC7 Error Interrupt Service Routine
6009 */
6010 void lisrEdma3TC7ErrHandler0(uint32_t edma3InstanceId)
6011 {
6012 /* Invoke Error Handler ISR for TC7*/
6013 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 7u);
6014 }
6018 /* Resource Manager Internal functions - Start */
6020 /** Initialization of the Global region registers of the EDMA3 Controller */
6021 static void edma3GlobalRegionInit (uint32_t phyCtrllerInstId)
6022 {
6023 uint32_t evtQNum = 0u;
6024 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
6026 assert (phyCtrllerInstId < EDMA3_MAX_EDMA3_INSTANCES);
6028 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)
6029 (resMgrObj[phyCtrllerInstId].gblCfgParams.globalRegs);
6031 if (ptrEdmaccRegs != NULL)
6032 {
6033 ptrEdmaccRegs->EMCR = EDMA3_RM_SET_ALL_BITS;
6034 ptrEdmaccRegs->EMCRH = EDMA3_RM_SET_ALL_BITS;
6035 ptrEdmaccRegs->QEMCR = EDMA3_RM_SET_ALL_BITS;
6037 /*
6038 * Set all Instance-wide EDMA3 parameters (not channel-specific)
6039 */
6041 /**
6042 * Set TC Priority among system-wide bus-masters and Queue
6043 * Watermark Level
6044 */
6045 while (evtQNum <
6046 resMgrObj[phyCtrllerInstId].gblCfgParams.numEvtQueue)
6047 {
6048 ptrEdmaccRegs->QUEPRI &= EDMA3_RM_QUEPRI_CLR_MASK(evtQNum);
6049 ptrEdmaccRegs->QUEPRI |= EDMA3_RM_QUEPRI_SET_MASK(evtQNum,
6050 resMgrObj[phyCtrllerInstId].gblCfgParams.evtQPri[evtQNum]);
6052 ptrEdmaccRegs->QWMTHRA |= EDMA3_RM_QUEWMTHR_SET_MASK(evtQNum,
6053 resMgrObj[phyCtrllerInstId].gblCfgParams.evtQueueWaterMarkLvl[evtQNum]);
6055 evtQNum++;
6056 }
6058 /* Clear CCERR register */
6059 ptrEdmaccRegs ->CCERRCLR = 0xFFFFu;
6060 }
6062 return;
6063 }
6068 /** Initialization of the Shadow region registers of the EDMA3 Controller */
6069 static void edma3ShadowRegionInit (const EDMA3_RM_Instance *pRMInstance)
6070 {
6071 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
6072 volatile EDMA3_CCRL_ShadowRegs *ptrEdmaShadowRegs = NULL;
6073 uint32_t phyCtrllerInstId;
6074 uint32_t regionId;
6075 const EDMA3_RM_InstanceInitConfig *rmInstInitConfig = pRMInstance->initParam.rmInstInitConfig;
6077 assert (pRMInstance != NULL);
6079 if (rmInstInitConfig != NULL)
6080 {
6081 phyCtrllerInstId = pRMInstance->pResMgrObjHandle->phyCtrllerInstId;
6082 regionId = pRMInstance->initParam.regionId;
6084 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)
6085 (resMgrObj[phyCtrllerInstId].gblCfgParams.globalRegs);
6087 if (ptrEdmaccRegs != NULL)
6088 {
6089 ptrEdmaShadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
6090 (&ptrEdmaccRegs->SHADOW[regionId]);
6092 ptrEdmaShadowRegs->ECR = (rmInstInitConfig->ownDmaChannels[0u]
6093 | rmInstInitConfig->ownTccs[0u]);
6094 ptrEdmaShadowRegs->ECRH = (rmInstInitConfig->ownDmaChannels[1u]
6095 | rmInstInitConfig->ownTccs[1u]);
6096 ptrEdmaShadowRegs->EECR = (rmInstInitConfig->ownDmaChannels[0u]
6097 | rmInstInitConfig->ownTccs[0u]);
6098 ptrEdmaShadowRegs->SECR = (rmInstInitConfig->ownDmaChannels[0u]
6099 | rmInstInitConfig->ownTccs[0u]);
6100 ptrEdmaShadowRegs->SECRH = (rmInstInitConfig->ownDmaChannels[1u]
6101 | rmInstInitConfig->ownTccs[1u]);
6102 ptrEdmaShadowRegs->EECR = (rmInstInitConfig->ownDmaChannels[0u]
6103 | rmInstInitConfig->ownTccs[0u]);
6104 ptrEdmaShadowRegs->EECRH = (rmInstInitConfig->ownDmaChannels[1u]
6105 | rmInstInitConfig->ownTccs[1u]);
6107 ptrEdmaShadowRegs->QEECR = rmInstInitConfig->ownQdmaChannels[0u];
6109 ptrEdmaShadowRegs->IECR = (rmInstInitConfig->ownDmaChannels[0u]
6110 | rmInstInitConfig->ownTccs[0u]);
6111 ptrEdmaShadowRegs->IECRH = (rmInstInitConfig->ownDmaChannels[1u]
6112 | rmInstInitConfig->ownTccs[1u]);
6113 ptrEdmaShadowRegs->ICR = (rmInstInitConfig->ownDmaChannels[0u]
6114 | rmInstInitConfig->ownTccs[0u]);
6115 ptrEdmaShadowRegs->ICRH = (rmInstInitConfig->ownDmaChannels[1u]
6116 | rmInstInitConfig->ownTccs[1u]);
6118 ptrEdmaShadowRegs->QSECR = rmInstInitConfig->ownQdmaChannels[0u];
6120 /*
6121 * Set all EDMA3 Resource<->Region mapping parameters
6122 */
6124 /* 1. Dma Channel (and TCC) <-> Region */
6125 ptrEdmaccRegs->DRA[regionId].DRAE = 0u;
6126 ptrEdmaccRegs->DRA[regionId].DRAEH = 0u;
6128 /* 2. Qdma Channel <-> Region */
6129 ptrEdmaccRegs->QRAE[regionId] = 0u;
6130 }
6131 }
6133 return;
6134 }
6138 /** Local MemZero function */
6139 void edma3MemZero(void *dst, uint32_t len)
6140 {
6141 uint32_t i = 0u;
6142 uint32_t *ds = NULL;
6144 assert (dst != NULL);
6146 ds = (uint32_t *)dst;
6148 for (i = 0 ; i < len/4 ; i++)
6149 {
6150 *ds = 0x0;
6151 ds++;
6152 }
6154 return;
6155 }
6158 /* Local MemCopy function */
6159 void edma3MemCpy(void *dst, const void *src, uint32_t len)
6160 {
6161 uint32_t i=0u;
6162 const uint32_t *sr;
6163 uint32_t *ds;
6165 assert ((src != NULL) && (dst != NULL) && ((len)%4 == 0));
6167 sr = (const uint32_t *)src;
6168 ds = (uint32_t *)dst;
6170 for (i = 0 ; i < len/4 ; i++)
6171 {
6172 *ds = *sr;
6173 ds++;
6174 sr++;
6175 }
6177 return;
6178 }
6181 /* Local MemCopy function to copy Param Set ONLY */
6182 void edma3ParamCpy(void *dst, const void *src)
6183 {
6184 uint32_t i = 0u;
6185 const uint32_t *sr;
6186 uint32_t *ds;
6188 assert ((src != NULL) && (dst != NULL));
6190 sr = (const uint32_t *)src;
6191 ds = (uint32_t *)dst;
6193 for (i = 0; i < 8; i++)
6194 {
6195 *ds = *sr;
6196 ds++;
6197 sr++;
6198 }
6200 return;
6201 }
6204 /**
6205 * Finds a particular bit ('0' or '1') in the particular word from 'start'.
6206 * If found, returns the position, else return -1.
6207 */
6208 static int32_t findBitInWord (int32_t source, uint32_t start, uint16_t bit)
6209 {
6210 uint32_t position = start;
6211 uint16_t found = 0;
6212 uint32_t iterations_left = 0;
6214 switch (bit)
6215 {
6216 case 1:
6217 {
6218 source >>= (start%32u);
6220 while ((found==0u) && (source!=0))
6221 {
6222 if ((source & 0x1) == 0x1)
6223 {
6224 /* 1 */
6225 found++;
6226 }
6227 else
6228 {
6229 /* 0 */
6230 source >>= 1;
6231 position++;
6232 }
6233 }
6235 }
6236 break;
6238 case 0:
6239 {
6240 source >>= (start%32u);
6241 iterations_left = 32u - (start%32u);
6243 while ((found==0u) && (iterations_left>0u))
6244 {
6245 if ((source & 0x1) == 0x1)
6246 {
6247 /* 1 */
6248 source >>= 1;
6249 position++;
6250 iterations_left--;
6251 }
6252 else
6253 {
6254 /* 0 */
6255 found++;
6256 }
6257 }
6258 }
6259 break;
6261 default:
6262 break;
6263 }
6265 return (found ? (int32_t)position : -1);
6266 }
6269 /**
6270 * Finds a particular bit ('0' or '1') in the specified resources' array
6271 * from 'start' to 'end'. If found, returns the position, else return -1.
6272 */
6273 static int32_t findBit (EDMA3_RM_ResType resType,
6274 uint32_t start,
6275 uint32_t end,
6276 uint16_t bit)
6277 {
6278 int32_t position = -1;
6279 uint32_t start_index = start / 32u;
6280 uint32_t end_index = end / 32u;
6281 int32_t i;
6282 uint32_t *resPtr = 0x0;
6283 int32_t ret = -1;
6284 EDMA3_RM_Result result = EDMA3_RM_SOK;
6286 assert (start <= end);
6288 /**
6289 * job is to find 'bit' in an array[start_index:end_index]
6290 * algo used:
6291 * first search in array[start_index]
6292 * then search in array[start_index + 1 : end_index - 1]
6293 * then search in array[end_index]
6294 */
6295 switch (resType)
6296 {
6297 case EDMA3_RM_RES_DMA_CHANNEL:
6298 resPtr = &contiguousDmaRes[0];
6299 break;
6301 case EDMA3_RM_RES_QDMA_CHANNEL:
6302 resPtr = &contiguousQdmaRes[0];
6303 break;
6305 case EDMA3_RM_RES_TCC:
6306 resPtr = &contiguousTccRes[0];
6307 break;
6309 case EDMA3_RM_RES_PARAM_SET:
6310 resPtr = &contiguousParamRes[0];
6311 break;
6313 default:
6314 result = EDMA3_RM_E_INVALID_PARAM;
6315 break;
6316 }
6318 if (EDMA3_RM_SOK == result)
6319 {
6320 switch (bit)
6321 {
6322 case 1:
6323 {
6324 /* Find '1' in first word. */
6325 position = findBitInWord (resPtr[start_index], start, 1u);
6327 if (position != -1)
6328 {
6329 ret = position;
6330 }
6331 else
6332 {
6333 /* '1' NOT found, look into other words. */
6334 for (i = (int32_t)(start_index + 1u); i <= (int32_t)(end_index - 1u); i++)
6335 {
6336 position = findBitInWord (resPtr[i], 0u, 1u);
6337 if (position != -1)
6338 {
6339 /* '1' Found... */
6340 ret = (position + (i*32));
6341 break;
6342 }
6343 }
6345 /* First check whether we have found '1' or not. */
6346 if (ret == -1)
6347 {
6348 /* Still not found, look in the last word. */
6349 position = findBitInWord(resPtr[end_index], 0u, 1u);
6350 if (position != -1)
6351 {
6352 /* Finally got it. */
6353 ret = (position + (end_index*32u));
6354 }
6355 else
6356 {
6357 /* Sorry, could not find it, return -1. */
6358 ret = -1;
6359 }
6360 }
6361 }
6362 }
6363 break;
6365 case 0:
6366 {
6367 /* Find '0' in first word. */
6368 position = findBitInWord(resPtr[start_index], start, 0u);
6369 if (position != -1)
6370 {
6371 ret = position;
6372 }
6373 else
6374 {
6375 /* '0' NOT found, look into other words. */
6376 for (i = (start_index + 1u); i <= (end_index - 1u); i++)
6377 {
6378 position = findBitInWord(resPtr[i], 0u, 0u);
6379 if (position != -1)
6380 {
6381 /* '0' found... */
6382 ret = (position + (i*32));
6383 break;
6384 }
6385 }
6387 /* First check whether we have found '0' or not. */
6388 if (ret == -1)
6389 {
6390 position = findBitInWord(resPtr[end_index], 0u, 0u);
6391 if (position != -1)
6392 {
6393 /* Finally got it. */
6394 ret = (position + (end_index*32u));
6395 }
6396 else
6397 {
6398 /* Sorry, could not find it, return -1. */
6399 ret = -1;
6400 }
6401 }
6402 }
6403 }
6404 break;
6406 default:
6407 break;
6408 }
6409 }
6413 return ((ret >= start) ? ret : -1);
6414 }
6418 /**
6419 * If successful, this function returns EDMA3_RM_SOK and the position
6420 * of first available resource in 'positionRes'. Else returns error.
6421 */
6422 static EDMA3_RM_Result allocAnyContigRes(EDMA3_RM_ResType resType,
6423 uint32_t numResources,
6424 uint32_t *positionRes)
6425 {
6426 uint16_t found = 0u;
6427 int32_t first_one, next_zero;
6428 uint32_t num_available;
6429 int32_t ret = -1;
6430 uint32_t start = 0;
6431 uint32_t end;
6432 EDMA3_RM_Result result = EDMA3_RM_SOK;
6434 assert (positionRes != NULL);
6436 switch (resType)
6437 {
6438 case EDMA3_RM_RES_DMA_CHANNEL:
6439 end = EDMA3_MAX_DMA_CH - 1u;
6440 break;
6442 case EDMA3_RM_RES_QDMA_CHANNEL:
6443 end = EDMA3_MAX_QDMA_CH - 1u;
6444 break;
6446 case EDMA3_RM_RES_TCC:
6447 end = EDMA3_MAX_TCC - 1u;
6448 break;
6450 case EDMA3_RM_RES_PARAM_SET:
6451 end = edma3NumPaRAMSets - 1u;
6452 break;
6454 default:
6455 result = EDMA3_RM_E_INVALID_PARAM;
6456 break;
6457 }
6459 if (result == EDMA3_RM_SOK)
6460 {
6461 /**
6462 * Algorithm used for finding N contiguous resources.
6463 * In the resources' array, '1' means available and '0' means
6464 * not-available.
6465 * Step a) Find first '1' starting from 'start'. If successful,
6466 * store it in first_one, else return error.
6467 * Step b) Find first '0' starting from (first_one+1) to 'end'.
6468 * If successful, store returned value in next_zero. If '0' could
6469 * not be located, it means all the resources are available.
6470 * Store 'end' (i.e. the last resource id) in next_zero.
6471 * Step c) Count the number of contiguous resources available
6472 * by subtracting first_one from next_zero.
6473 * Step d) If result < N, do the whole process again untill you
6474 * reach end. Else you have found enough resources, return success.
6475 */
6476 while((found == 0) && (start<=end) && (((end-start)+1u) >= numResources))
6477 {
6478 /* Find first '1' starting from 'start' till 'end'. */
6479 first_one = findBit (resType, start, end, 1u);
6480 if (first_one != -1)
6481 {
6482 /* Got first 1, search for first '0' now. */
6483 next_zero = findBit (resType, first_one+1, end, 0u);
6484 if (next_zero == -1)
6485 {
6486 /* Unable to find next zero, all 1' are there */
6487 next_zero = end + 1u;
6488 }
6490 /* check no of resources available */
6491 num_available = next_zero - first_one;
6492 if (num_available >= numResources)
6493 {
6494 /* hurrah..., we have found enough resources. */
6495 found = 1u;
6496 ret = first_one;
6497 }
6498 else
6499 {
6500 /* Not enough resources, try again */
6501 start = next_zero + 1;
6502 }
6503 }
6504 else
6505 {
6506 /* do nothing, first 1 is not there, return. */
6507 break;
6508 }
6509 }
6510 }
6513 if (result == EDMA3_RM_SOK)
6514 {
6515 if (found == 1u)
6516 {
6517 /* required resources found, retrun the first available res id. */
6518 *positionRes = (uint32_t)ret;
6519 }
6520 else
6521 {
6522 /* No resources allocated */
6523 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
6524 }
6525 }
6527 return result;
6528 }
6532 /**
6533 * Starting from 'firstResIdObj', this function makes the next 'numResources'
6534 * Resources non-available for future. Also, it does some global resisters'
6535 * setting also.
6536 */
6537 static EDMA3_RM_Result gblChngAllocContigRes(EDMA3_RM_Instance *rmInstance,
6538 const EDMA3_RM_ResDesc *firstResIdObj,
6539 uint32_t numResources)
6540 {
6541 EDMA3_RM_Result result = EDMA3_RM_SOK;
6542 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
6543 EDMA3_RM_Obj *rmObj = NULL;
6544 uint32_t avlblIdx = 0u;
6545 uint32_t firstResId=0u;
6546 uint32_t lastResId=0u;
6547 uint32_t edma3Id;
6549 assert ((rmInstance != NULL) && (firstResIdObj != NULL));
6551 rmObj = rmInstance->pResMgrObjHandle;
6553 if (rmObj == NULL)
6554 {
6555 result = EDMA3_RM_E_INVALID_PARAM;
6556 }
6558 if (EDMA3_RM_SOK == result)
6559 {
6560 edma3Id = rmObj->phyCtrllerInstId;
6561 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
6563 if (gblRegs == NULL)
6564 {
6565 result = EDMA3_RM_E_INVALID_PARAM;
6566 }
6567 }
6569 if (result == EDMA3_RM_SOK)
6570 {
6571 switch (firstResIdObj->type)
6572 {
6573 case EDMA3_RM_RES_DMA_CHANNEL:
6574 {
6575 firstResId = firstResIdObj->resId;
6576 lastResId = firstResId + (numResources - 1u);
6578 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6579 {
6580 rmInstance->avlblDmaChannels[avlblIdx/32u] &= (uint32_t)(~(1u << (avlblIdx%32u)));
6582 /**
6583 * Enable the DMA channel in the DRAE/DRAEH registers also.
6584 */
6585 if (avlblIdx < 32u)
6586 {
6587 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
6588 |= (0x1u << avlblIdx);
6589 }
6590 else
6591 {
6592 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
6593 |= (0x1u << (avlblIdx - 32u));
6594 }
6595 }
6596 }
6597 break;
6599 case EDMA3_RM_RES_QDMA_CHANNEL:
6600 {
6601 firstResId = firstResIdObj->resId;
6602 lastResId = firstResId + (numResources - 1u);
6604 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6605 {
6606 rmInstance->avlblQdmaChannels[avlblIdx/32u] &= (uint32_t)(~(1u << (avlblIdx%32u)));
6608 /**
6609 * Enable the QDMA channel in the QRAE register also.
6610 */
6611 gblRegs->QRAE[rmInstance->initParam.regionId]
6612 |= (0x1u << avlblIdx);
6613 }
6614 }
6615 break;
6617 case EDMA3_RM_RES_TCC:
6618 {
6619 firstResId = firstResIdObj->resId;
6620 lastResId = firstResId + (numResources - 1u);
6622 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6623 {
6624 rmInstance->avlblTccs[avlblIdx/32u] &= (uint32_t)(~(1u << (avlblIdx%32u)));
6626 /**
6627 * If the region id coming from this
6628 * RM instance is same as the Master RM
6629 * Instance's region id, only then we will be
6630 * getting the interrupts on the same side.
6631 * So save the TCC in the allocatedTCCs[] array.
6632 */
6633 if (edma3RegionId == rmInstance->initParam.regionId)
6634 {
6635 if (avlblIdx < 32u)
6636 {
6637 allocatedTCCs[edma3Id][0u] |= (0x1u << avlblIdx);
6638 }
6639 else
6640 {
6641 allocatedTCCs[edma3Id][1u] |= (0x1u << (avlblIdx - 32u));
6642 }
6643 }
6644 }
6645 }
6646 break;
6648 case EDMA3_RM_RES_PARAM_SET:
6649 {
6650 firstResId = firstResIdObj->resId;
6651 lastResId = firstResId + (numResources - 1u);
6653 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6654 {
6655 rmInstance->avlblPaRAMSets [avlblIdx/32u] &= (uint32_t)(~(1u << (avlblIdx%32u)));
6657 /**
6658 * Also, make the actual PARAM Set NULL, checking the flag
6659 * whether it is required or not.
6660 */
6661 if (TRUE == rmInstance->paramInitRequired)
6662 {
6663 edma3MemZero((void *)(&gblRegs->PARAMENTRY[avlblIdx]),
6664 sizeof(gblRegs->PARAMENTRY[avlblIdx]));
6665 }
6666 }
6667 }
6668 break;
6670 default:
6671 result = EDMA3_RM_E_INVALID_PARAM;
6672 break;
6673 }
6674 }
6677 return result;
6678 }
6681 EDMA3_RM_Result EDMA3_RM_initXbarEventMap (EDMA3_RM_Handle hEdmaResMgr,
6682 const EDMA3_RM_GblXbarToChanConfigParams * edmaGblXbarConfig,
6683 EDMA3_RM_mapXbarEvtToChan mapXbarEvtFunc,
6684 EDMA3_RM_xbarConfigScr configXbarScr)
6685 {
6686 EDMA3_RM_Result result = EDMA3_DRV_SOK;
6687 EDMA3_RM_Instance *rmInstance = NULL;
6689 /* If parameter checking is enabled... */
6690 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
6691 if (hEdmaResMgr == NULL)
6692 {
6693 result = EDMA3_RM_E_INVALID_PARAM;
6694 }
6695 #endif
6697 /* Check if the parameters are OK. */
6698 if (EDMA3_DRV_SOK == result)
6699 {
6700 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
6702 if (mapXbarEvtFunc != NULL)
6703 {
6704 rmInstance->mapXbarToChan = mapXbarEvtFunc;
6705 }
6706 if (configXbarScr != NULL)
6707 {
6708 rmInstance->configScrMapXbarToEvt = configXbarScr;
6709 }
6710 if (edmaGblXbarConfig != NULL)
6711 {
6712 edma3MemCpy((void *)(&rmInstance->rmXbarToEvtMapConfig),
6713 (const void *)(edmaGblXbarConfig),
6714 sizeof (EDMA3_RM_GblXbarToChanConfigParams));
6715 }
6716 }
6718 return (result);
6719 }
6721 /* Resource Manager Internal functions - End */
6723 /* End of File */