]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/edma3_lld.git/blob - packages/ti/sdo/edma3/rm/src/edma3resmgr.c
fixed warnings in building edma libs
[keystone-rtos/edma3_lld.git] / packages / ti / sdo / edma3 / rm / src / edma3resmgr.c
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;
1029         
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)));
1125         
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                                                     }
1147         
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;
1179         
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);
1189         
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);
1200         
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                                                         }
1209         
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;
1234         
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)));
1251         
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                                                 }
1265         
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;
1288         
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                                                     }
1302         
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;
1327         
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)));
1341         
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);
1361         
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));
1378         
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                                                 }
1392         
1393         
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;
1416         
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);
1436         
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));
1453         
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                                                     }
1467         
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;
1492         
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)));
1509         
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                                                 }
1520         
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;
1543         
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                                                     }
1554         
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;
1579         
1580                             default:
1581                                     result = EDMA3_RM_E_INVALID_PARAM;
1582                                 break;
1583                             }
1584         
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;
1634         
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;
5281         
5282                     /**
5283                      * Choose interrupts coming from our allocated TCCs
5284                      * and MASK remaining ones.
5285                      */
5286                     pendingIrqs = (pendingIrqs & allocatedTCCs[edma3Id][1u]);
5287         
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);
5302         
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);
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 */