]> 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
Fix for the bug in Generic platform library in RM
[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 unsigned int 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 unsigned int edma3_dma_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
144 /** Min of Link Channels */
145 unsigned int edma3_link_ch_min_val[EDMA3_MAX_EDMA3_INSTANCES];
146 /** Max of Link Channels */
147 unsigned int edma3_link_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
148 /** Min of QDMA Channels */
149 unsigned int edma3_qdma_ch_min_val[EDMA3_MAX_EDMA3_INSTANCES];
150 /** Max of QDMA Channels */
151 unsigned int edma3_qdma_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
152 /** Max of Logical Channels */
153 unsigned int 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 unsigned int 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 unsigned int 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 unsigned int 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 unsigned int 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 unsigned int 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 unsigned int 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 unsigned int 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 unsigned int 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 unsigned int 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(unsigned int arg);
281 /** EDMA3 Instance 0 CC Error Interrupt Service Routine */
282 void lisrEdma3CCErrHandler0(unsigned int 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(unsigned int arg);
288 void lisrEdma3TC1ErrHandler0(unsigned int arg);
289 void lisrEdma3TC2ErrHandler0(unsigned int arg);
290 void lisrEdma3TC3ErrHandler0(unsigned int arg);
291 void lisrEdma3TC4ErrHandler0(unsigned int arg);
292 void lisrEdma3TC5ErrHandler0(unsigned int arg);
293 void lisrEdma3TC6ErrHandler0(unsigned int arg);
294 void lisrEdma3TC7ErrHandler0(unsigned int 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, unsigned int tcNum);
305 /** Local MemZero function */
306 void edma3MemZero(void *dst, unsigned int len);
307 /** Local MemCpy function */
308 void edma3MemCpy(void *dst, const void *src, unsigned int 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 (unsigned int 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 int findBitInWord (int source, unsigned int start, unsigned short 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 int findBit (EDMA3_RM_ResType resType,
331                             unsigned int start,
332                             unsigned int end,
333                             unsigned short 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                                     unsigned int numResources,
341                                     unsigned int *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                                         unsigned int numResources);
352 /*---------------------------------------------------------------------------*/
354 EDMA3_RM_Result EDMA3_RM_create (unsigned int phyCtrllerInstId,
355                                 const EDMA3_RM_GblConfigParams *gblCfgParams,
356                                 const void *miscParam)
357     {
358     unsigned int 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 (unsigned int 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 (unsigned int phyCtrllerInstId,
591                                 const EDMA3_RM_Param *initParam,
592                                 EDMA3_RM_Result *errorCode)
593     {
594     unsigned int intState           = 0u;
595     unsigned int 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     unsigned int dmaChDwrds = 0u;
602     unsigned int paramSetDwrds = 0u;
603     unsigned int 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     unsigned int intState = 0u;
914     unsigned int resMgrIdx = 0u;
915     EDMA3_RM_Obj *rmObj             = NULL;
916     EDMA3_RM_Instance *rmInstance   = NULL;
917     unsigned int dmaChDwrds;
918     unsigned int paramSetDwrds;
919     unsigned int 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     unsigned int avlblIdx = 0u;
1022     unsigned int resIdClr = 0x0;
1023     unsigned int resIdSet = 0x0;
1024     unsigned int resId;
1025     volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1026         unsigned int mapXbarEvtToChanFlag = FALSE;
1027         unsigned int xBarEvtBeforeMap = 0;
1028         unsigned int 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 = (unsigned int)(~(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] &= (unsigned int)(~(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] &= (unsigned int)(~(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] &= (unsigned int)(~(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] &= (unsigned int)(~(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     unsigned int intState;
1627     EDMA3_RM_Instance *rmInstance = NULL;
1628     EDMA3_RM_Obj *rmObj = NULL;
1629     EDMA3_RM_Result result = EDMA3_RM_SOK;
1630     unsigned int resId;
1631     unsigned int resIdSet = 0x0;
1632     volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1633         unsigned int 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             edma3OsProtectEntry (rmObj->phyCtrllerInstId,
1671                                                                 EDMA3_OS_PROTECT_INTERRUPT,
1672                                                                 &intState);
1674             if (EDMA3_RM_SOK == result)
1675                 {
1676                 switch (resObj->type)
1677                     {
1678                     case EDMA3_RM_RES_DMA_CHANNEL :
1679                         {
1680                         if (resId < rmObj->gblCfgParams.numDmaChannels)
1681                             {
1682                             if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels [resId/32u]) & (resIdSet))!=FALSE)
1683                                 {
1684                                 if (((~(rmInstance->avlblDmaChannels[resId/32u]))&(resIdSet))!=FALSE)
1685                                     {
1686                                     /*
1687                                      * Mark the specified channel as "Available"
1688                                      * for future requests
1689                                      */
1690                                     rmInstance->avlblDmaChannels[resId/32u] |= resIdSet;
1692                                     /**
1693                                      * Check if the register modification flag is
1694                                      * set or not.
1695                                      */
1696                                     if (TRUE == rmInstance->regModificationRequired)
1697                                         {
1698                                         /**
1699                                          * DMA Channel is freed.
1700                                          * Reset the bit specific to the DMA channel
1701                                          * in the DRAE/DRAEH register also.
1702                                          */
1703                                         if (resId < 32u)
1704                                             {
1705                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1706                                                             &= (~(0x1u << resId));
1707                                             }
1708                                         else
1709                                             {
1710                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1711                                                             &= (~(0x1u << (resId-32u)));
1712                                             }
1713                                         }
1715                                     result = EDMA3_RM_SOK;
1716                                     }
1717                                 else
1718                                     {
1719                                     result = EDMA3_RM_E_RES_ALREADY_FREE;
1720                                     }
1721                                 }
1722                             else
1723                                 {
1724                                 /*
1725                                  * Specified resource is not owned by this instance
1726                                  * of the Resource Manager
1727                                  */
1728                                 result = EDMA3_RM_E_RES_NOT_OWNED;
1729                                 }
1730                             }
1731                         else
1732                             {
1733                             result = EDMA3_RM_E_INVALID_PARAM;
1734                             }
1735                         }
1736                         break;
1738                     case EDMA3_RM_RES_QDMA_CHANNEL :
1739                         {
1740                         if (resId < rmObj->gblCfgParams.numQdmaChannels)
1741                             {
1742                             if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32u]) & (resIdSet))!=FALSE)
1743                                 {
1744                                 if (((~(rmInstance->avlblQdmaChannels [resId/32u])) & (resIdSet))!=FALSE)
1745                                     {
1746                                     rmInstance->avlblQdmaChannels [resId/32u] |= resIdSet;
1748                                     /**
1749                                      * Check if the register modification flag is
1750                                      * set or not.
1751                                      */
1752                                     if (TRUE == rmInstance->regModificationRequired)
1753                                         {
1754                                         /**
1755                                          * QDMA Channel is freed.
1756                                          * Reset the bit specific to the QDMA channel
1757                                          * in the QRAE register also.
1758                                          */
1759                                         gblRegs->QRAE[rmInstance->initParam.regionId]
1760                                                         &= (~(0x1u << resId));
1761                                         }
1763                                     result = EDMA3_RM_SOK;
1764                                     }
1765                                 else
1766                                     {
1767                                     result = EDMA3_RM_E_RES_ALREADY_FREE;
1768                                     }
1769                                 }
1770                             else
1771                                 {
1772                                 /*
1773                                  * Specified resource is not owned by this instance
1774                                  * of the Resource Manager
1775                                  */
1776                                 result = EDMA3_RM_E_RES_NOT_OWNED;
1777                                 }
1778                             }
1779                         else
1780                             {
1781                             result = EDMA3_RM_E_INVALID_PARAM;
1782                             }
1783                         }
1784                         break;
1786                     case EDMA3_RM_RES_TCC :
1787                         {
1788                         if (resId < rmObj->gblCfgParams.numTccs)
1789                             {
1790                             if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32u]) & (resIdSet))!=FALSE)
1791                                 {
1792                                 if (((~(rmInstance->avlblTccs [resId/32u])) & (resIdSet))!=FALSE)
1793                                     {
1794                                     rmInstance->avlblTccs [resId/32u] |= resIdSet;
1796                                     /**
1797                                      * Check if the register modification flag is
1798                                      * set or not.
1799                                      */
1800                                     if (TRUE == rmInstance->regModificationRequired)
1801                                         {
1802                                         /**
1803                                          * Interrupt Channel is freed.
1804                                          * Reset the bit specific to the Interrupt
1805                                          * channel in the DRAE/DRAEH register also.
1806                                          * Also, if we have earlier saved this
1807                                          * TCC in allocatedTCCs[] array,
1808                                          * remove it from there too.
1809                                          */
1810                                         if (resId < 32u)
1811                                             {
1812                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1813                                                             &= (~(0x1u << resId));
1815                                             if (edma3RegionId == rmInstance->initParam.regionId)
1816                                                 {
1817                                                 allocatedTCCs[edma3Id][0u] &= (~(0x1u << resId));
1818                                                 }
1819                                             }
1820                                         else
1821                                             {
1822                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1823                                                             &= (~(0x1u << (resId-32u)));
1825                                             if (edma3RegionId == rmInstance->initParam.regionId)
1826                                                 {
1827                                                 allocatedTCCs[edma3Id][1u] &= (~(0x1u << (resId -32u)));
1828                                                 }
1829                                             }
1830                                         }
1832                                     result = EDMA3_RM_SOK;
1833                                     }
1834                                 else
1835                                     {
1836                                     result = EDMA3_RM_E_RES_ALREADY_FREE;
1837                                     }
1838                                 }
1839                             else
1840                                 {
1841                                 /*
1842                                  * Specified resource is not owned by this instance
1843                                  * of the Resource Manager
1844                                  */
1845                                 result = EDMA3_RM_E_RES_NOT_OWNED;
1846                                 }
1847                             }
1848                         else
1849                             {
1850                             result = EDMA3_RM_E_INVALID_PARAM;
1851                             }
1852                         }
1853                         break;
1855                     case EDMA3_RM_RES_PARAM_SET :
1856                         {
1857                         if (resId < rmObj->gblCfgParams.numPaRAMSets)
1858                             {
1859                             if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32u])&(resIdSet))!=FALSE)
1860                                 {
1861                                 if (((~(rmInstance->avlblPaRAMSets [resId/32u]))&(resIdSet))!=FALSE)
1862                                     {
1863                                     rmInstance->avlblPaRAMSets [resId/32u] |= resIdSet;
1865                                     result = EDMA3_RM_SOK;
1866                                     }
1867                                 else
1868                                     {
1869                                     result = EDMA3_RM_E_RES_ALREADY_FREE;
1870                                     }
1871                                 }
1872                             else
1873                                 {
1874                                 /*
1875                                  * Specified resource is not owned by this instance
1876                                  * of the Resource Manager
1877                                  */
1878                                 result = EDMA3_RM_E_RES_NOT_OWNED;
1879                                 }
1880                             }
1881                         else
1882                             {
1883                             result = EDMA3_RM_E_INVALID_PARAM;
1884                             }
1885                         }
1886                         break;
1888                     default:
1889                         result = EDMA3_RM_E_INVALID_PARAM;
1890                         break;
1891                     }
1893                 }
1895             edma3OsProtectExit (rmObj->phyCtrllerInstId,
1896                                                                 EDMA3_OS_PROTECT_INTERRUPT,
1897                                                                 intState);
1898             }
1899         }
1901 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1902     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1903                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1904                 EDMA3_DVT_dCOUNTER,
1905                 EDMA3_DVT_dNONE,
1906                 EDMA3_DVT_dNONE));
1907 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1909     return result;
1910     }
1912 EDMA3_RM_Result EDMA3_RM_allocLogicalChannel(EDMA3_RM_Handle hEdmaResMgr,
1913                             EDMA3_RM_ResDesc *lChObj,
1914                             unsigned int *pParam,
1915                             unsigned int *pTcc)
1916     {
1917     EDMA3_RM_ResDesc *chObj;
1918     EDMA3_RM_ResDesc resObj;
1919     EDMA3_RM_Result result = EDMA3_RM_SOK;
1920     EDMA3_RM_Instance *rmInstance = NULL;
1921     EDMA3_RM_Obj *rmObj = NULL;
1922     unsigned int mappedPaRAMId=0u;
1923     unsigned int mappedTcc = EDMA3_RM_CH_NO_TCC_MAP;
1924     int paRAMId = (int)EDMA3_RM_RES_ANY;
1925     volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1926     unsigned int qdmaChId = EDMA3_MAX_PARAM_SETS;
1927         unsigned int edma3Id;
1929 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1930     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1931                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1932                 EDMA3_DVT_dCOUNTER,
1933                 EDMA3_DVT_dNONE,
1934                 EDMA3_DVT_dNONE));
1935 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1937         /* If parameter checking is enabled... */
1938 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1939     if ((lChObj == NULL) || (hEdmaResMgr == NULL))
1940         {
1941         result = EDMA3_RM_E_INVALID_PARAM;
1942         }
1943 #endif
1945         /* Check if the parameters are OK. */
1946         if (EDMA3_RM_SOK == result)
1947         {
1948         chObj = lChObj;
1950         if ((chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
1951             || (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL))
1952             {
1953             /**
1954              * If the request is for a DMA or QDMA channel, check the
1955              * pParam and pTcc objects also.
1956              * For the Link channel request, they could be NULL.
1957              */
1958                         /* If parameter checking is enabled... */
1959 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1960             if ((pParam == NULL) || (pTcc == NULL))
1961                 {
1962                 result = EDMA3_RM_E_INVALID_PARAM;
1963                 }
1964 #endif
1965             }
1966         }
1968     if (result == EDMA3_RM_SOK)
1969         {
1970         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1972         if (rmInstance == NULL)
1973             {
1974             result = EDMA3_RM_E_INVALID_PARAM;
1975             }
1976         }
1978     if (result == EDMA3_RM_SOK)
1979         {
1980         rmObj = rmInstance->pResMgrObjHandle;
1982         if (rmObj == NULL)
1983             {
1984             result = EDMA3_RM_E_INVALID_PARAM;
1985             }
1986         else
1987             {
1988             if (rmObj->gblCfgParams.globalRegs == NULL)
1989                 {
1990                 result = EDMA3_RM_E_INVALID_PARAM;
1991                 }
1992             }
1993         }
1995     if (result == EDMA3_RM_SOK)
1996         {
1997         edma3Id = rmObj->phyCtrllerInstId;
1998         gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2000         switch (chObj->type)
2001             {
2002             case EDMA3_RM_RES_DMA_CHANNEL:
2003                 {
2004                 if ((chObj->resId == EDMA3_RM_DMA_CHANNEL_ANY)
2005                     || (chObj->resId == EDMA3_RM_RES_ANY))
2006                     {
2007                     /* Request for ANY DMA channel. */
2008                     resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2009                     resObj.resId = EDMA3_RM_RES_ANY;
2010                     result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2012                     if (result == EDMA3_RM_SOK)
2013                         {
2014                         /* DMA channel allocated successfully. */
2015                         chObj->resId = resObj.resId;
2017                         /**
2018                          * Check the PaRAM Set user has specified for this DMA channel.
2019                          * Two cases exist:
2020                          * a) DCHMAP exists: Any PaRAM Set can be used
2021                          * b) DCHMAP does not exist: Should not be possible
2022                          * only if the channel allocated (ANY) and PaRAM requested
2023                          * are same.
2024                          */
2025                         if ((*pParam) == EDMA3_RM_PARAM_ANY)
2026                             {
2027                             /* User specified ANY PaRAM Set; Check the mapping. */
2028                             mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2029                             if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2030                                 {
2031                                 /** If some PaRAM set is statically mapped to the returned
2032                                 * channel number, use that.
2033                                 */
2034                                 paRAMId = (int)mappedPaRAMId;
2035                                 }
2036                             }
2037                         else
2038                             {
2039                             /* User specified some PaRAM Set; check that can be used or not. */
2040                             if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2041                                 {
2042                                 paRAMId = (int)(*pParam);
2043                                 }
2044                             else
2045                                 {
2046                                 /**
2047                                  * Channel mapping does not exist. If the PaRAM Set requested
2048                                  * is the same as dma channel allocated (coincidentally), it is fine.
2049                                  * Else return error.
2050                                  */
2051                                 if ((*pParam) != (resObj.resId))
2052                                     {
2053                                     result = EDMA3_RM_E_INVALID_PARAM;
2055                                     /**
2056                                      * Free the previously allocated DMA channel also.
2057                                      */
2058                                     EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2059                                     }
2060                                 else
2061                                     {
2062                                     paRAMId = (int)(*pParam);
2063                                     }
2064                                 }
2065                             }
2067                         mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[resObj.resId];
2068                         }
2069                     }
2070                 else
2071                     {
2072                     if (chObj->resId <= edma3_dma_ch_max_val[edma3Id])
2073                         {
2074                         /* Request for a specific DMA channel */
2075                         resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2076                         resObj.resId = chObj->resId;
2077                         result = EDMA3_RM_allocResource(hEdmaResMgr,
2078                                         (EDMA3_RM_ResDesc *)&resObj);
2080                         if (result == EDMA3_RM_SOK)
2081                             {
2082                             /**
2083                              * Check the PaRAM Set user has specified for this DMA channel.
2084                              * Two cases exist:
2085                              * a) DCHMAP exists: Any PaRAM Set can be used
2086                              * b) DCHMAP does not exist: Should not be possible
2087                              * only if the channel allocated (ANY) and PaRAM requested
2088                              * are same.
2089                              */
2090                             if ((*pParam) == EDMA3_RM_PARAM_ANY)
2091                                 {
2092                                 /* User specified ANY PaRAM Set; Check the mapping. */
2093                                 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2094                                 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2095                                     {
2096                                     /** If some PaRAM set is statically mapped to the returned
2097                                     * channel number, use that.
2098                                     */
2099                                     paRAMId = (int)mappedPaRAMId;
2100                                     }
2101                                 }
2102                             else
2103                                 {
2104                                 /* User specified some PaRAM Set; check that can be used or not. */
2105                                 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2106                                     {
2107                                     paRAMId = (int)(*pParam);
2108                                     }
2109                                 else
2110                                     {
2111                                     /**
2112                                      * Channel mapping does not exist. If the PaRAM Set requested
2113                                      * is the same as dma channel allocated (coincidentally), it is fine.
2114                                      * Else return error.
2115                                      */
2116                                     if ((*pParam) != (resObj.resId))
2117                                         {
2118                                         result = EDMA3_RM_E_INVALID_PARAM;
2120                                         /**
2121                                          * Free the previously allocated DMA channel also.
2122                                          */
2123                                         EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2124                                         }
2125                                     else
2126                                         {
2127                                         paRAMId = (int)(*pParam);
2128                                         }
2129                                     }
2130                                 }
2132                             mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[chObj->resId];
2133                             }
2134                         }
2135                     else
2136                         {
2137                         result = EDMA3_RM_E_INVALID_PARAM;
2138                         }
2139                     }
2140                 }
2141                 break;
2144             case EDMA3_RM_RES_QDMA_CHANNEL:
2145                 {
2146                 if ((chObj->resId == EDMA3_RM_QDMA_CHANNEL_ANY)
2147                     || (chObj->resId == EDMA3_RM_RES_ANY))
2148                     {
2149                     /* First request for any available QDMA channel */
2150                     resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2151                     resObj.resId = EDMA3_RM_RES_ANY;
2152                     result = EDMA3_RM_allocResource(hEdmaResMgr,
2153                                     (EDMA3_RM_ResDesc *)&resObj);
2155                     if (result == EDMA3_RM_SOK)
2156                         {
2157                         /* Return the actual QDMA channel id. */
2158                         chObj->resId = resObj.resId;
2160                         /* Save the Logical-QDMA channel id for future use. */
2161                         qdmaChId = resObj.resId + edma3_qdma_ch_min_val[edma3Id];
2163                         /**
2164                          * Check the PaRAM Set user has specified for this QDMA channel.
2165                          * If he has specified any particular PaRAM Set, use that.
2166                          */
2167                         if ((*pParam) != EDMA3_RM_PARAM_ANY)
2168                             {
2169                             /* User specified ANY PaRAM Set; Check the mapping. */
2170                             paRAMId = (int)(*pParam);
2171                             }
2172                         }
2173                     }
2174                 else
2175                     {
2176                     if (chObj->resId < rmObj->gblCfgParams.numQdmaChannels)
2177                         {
2178                         /* Request for a specific QDMA channel */
2179                         resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2180                         resObj.resId = chObj->resId;
2181                         result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2183                         if (result == EDMA3_RM_SOK)
2184                             {
2185                             /* Save the Logical-QDMA channel id for future use. */
2186                             qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
2188                             /**
2189                              * Check the PaRAM Set user has specified for this QDMA channel.
2190                              * If he has specified any particular PaRAM Set, use that.
2191                              */
2192                             if ((*pParam) != EDMA3_RM_PARAM_ANY)
2193                                 {
2194                                 /* User specified ANY PaRAM Set; Check the mapping. */
2195                                 paRAMId = (int)(*pParam);
2196                                 }
2197                             }
2198                         }
2199                     else
2200                         {
2201                         result = EDMA3_RM_E_INVALID_PARAM;
2202                         }
2203                     }
2204                 }
2205                 break;
2207             case EDMA3_RM_RES_PARAM_SET:
2208                     {
2209                     /* Request for a LINK channel. */
2210                     if ((chObj->resId == EDMA3_RM_PARAM_ANY)
2211                         || (chObj->resId == EDMA3_RM_RES_ANY))
2212                         {
2213                         /* Request for ANY LINK channel. */
2214                         paRAMId = (int)EDMA3_RM_RES_ANY;
2215                         }
2216                     else
2217                         {
2218                         if (chObj->resId < edma3NumPaRAMSets)
2219                             {
2220                             /* Request for a Specific LINK channel. */
2221                             paRAMId = (int)(chObj->resId);
2222                             }
2223                         else
2224                             {
2225                             result = EDMA3_RM_E_INVALID_PARAM;
2226                             }
2227                         }
2229                     if (result == EDMA3_RM_SOK)
2230                         {
2231                         /* Try to allocate the link channel */
2232                         resObj.type = EDMA3_RM_RES_PARAM_SET;
2233                         resObj.resId = (unsigned int)paRAMId;
2234                         result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2236                         if (result == EDMA3_RM_SOK)
2237                             {
2238                             unsigned int linkCh = edma3_link_ch_min_val[edma3Id];
2240                             /* Return the actual PaRAM Id. */
2241                             chObj->resId = resObj.resId;
2243                             /*
2244                             * Search for the next Link channel place-holder available,
2245                             * starting from EDMA3_RM_LINK_CH_MIN_VAL.
2246                             * It will be used for future operations on the Link channel.
2247                             */
2248                             while ((edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId != -1)
2249                                         && (linkCh <= edma3_link_ch_max_val[edma3Id]))
2250                                 {
2251                                 /* Move to the next place-holder. */
2252                                 linkCh++;
2253                                 }
2255                             /* Verify the returned handle, it should lie in the correct range */
2256                             if (linkCh > edma3_link_ch_max_val[edma3Id])
2257                                 {
2258                                 result = EDMA3_RM_E_INVALID_PARAM;
2260                                 /* Free the PaRAM Set now. */
2261                                 resObj.type = EDMA3_RM_RES_PARAM_SET;
2262                                 resObj.resId = chObj->resId;
2263                                 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2264                                 }
2265                             else
2266                                 {
2267                                 /* Save the PaRAM Id for the Link Channel. */
2268                                 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = (int)(chObj->resId);
2270                                 /**
2271                                  * Remove any linking. Before doing that, check
2272                                  * whether it is permitted or not.
2273                                  */
2274                                 if (TRUE == rmInstance->regModificationRequired)
2275                                     {
2276                                     *((&gblRegs->PARAMENTRY[chObj->resId].OPT)
2277                                             + (unsigned int)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2278                                     }
2279                                 }
2280                             }
2281                         }
2282                     }
2283                     break;
2285             default:
2286                     result = EDMA3_RM_E_INVALID_PARAM;
2287             }
2288         }
2291     if (result == EDMA3_RM_SOK)
2292         {
2293         /**
2294          * For DMA/QDMA channels, we still have to allocate more resources like
2295          * TCC, PaRAM Set etc.
2296          * For Link channel, only the PaRAMSet is required and that has been
2297          * allocated so no further operations required.
2298          */
2300         /* Further resources' allocation for DMA channel. */
2301         if (chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
2302             {
2303             /* First allocate a PaRAM Set */
2304             resObj.type = EDMA3_RM_RES_PARAM_SET;
2305             /* Use the saved param id now. */
2306             resObj.resId = (unsigned int)paRAMId;
2307             result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2308             if (result == EDMA3_RM_SOK)
2309                 {
2310                 /**
2311                  * PaRAM Set allocation succeeded.
2312                  * Save the PaRAM Set first.
2313                  */
2314                 *pParam = resObj.resId;
2315                 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = (int)(resObj.resId);
2317                 /* Allocate the TCC now. */
2318                 resObj.type = EDMA3_RM_RES_TCC;
2319                 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2320                     {
2321                     if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2322                         {
2323                         resObj.resId = EDMA3_RM_RES_ANY;
2324                         }
2325                     else
2326                         {
2327                         resObj.resId = mappedTcc;
2328                         }
2329                     }
2330                 else
2331                     {
2332                     resObj.resId = *pTcc;
2333                     }
2335                 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2336                 if (result == EDMA3_RM_SOK)
2337                     {
2338                      /* TCC allocation succeeded. Save it first. */
2339                     *pTcc = resObj.resId;
2340                      edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].tcc = resObj.resId;
2342                     /**
2343                      * Check first whether the global registers and the allocated
2344                      * PaRAM Set can be modified or not. If yes, do the needful.
2345                      * Else leave this for the user.
2346                      */
2347                     if (TRUE == rmInstance->regModificationRequired)
2348                         {
2349                         /* Set TCC of the allocated Param Set. */
2350                         gblRegs->PARAMENTRY[*pParam].OPT  &= EDMA3_RM_OPT_TCC_CLR_MASK;
2351                         gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2353                         /**
2354                          * Do the mapping between DMA channel and PaRAM Set.
2355                          * Do this for the EDMA3 Controllers which have a register for mapping
2356                          * DMA Channel to a particular PaRAM Set.
2357                          */
2358                         if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2359                             {
2360                             gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2362                             /* Map Parameter RAM Set Number for specified channelId */
2363                             gblRegs->DCHMAP[chObj->resId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
2364                             gblRegs->DCHMAP[chObj->resId] |= EDMA3_RM_DCH_PARAM_SET_MASK(*pParam);
2365                             }
2367                         /* Remove any linking */
2368                         *((&gblRegs->PARAMENTRY[*pParam].OPT)
2369                                 + (unsigned int)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2370                         }
2371                     }
2372                 else
2373                     {
2374                     /**
2375                      * TCC allocation failed, free the previously allocated
2376                      * PaRAM Set and DMA channel.
2377                      */
2378                     resObj.type = EDMA3_RM_RES_PARAM_SET;
2379                     resObj.resId = *pParam;
2380                     EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2382                     /* Reset the book-keeping data structure also. */
2383                     edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = -1;
2385                     resObj.type = chObj->type;
2386                     resObj.resId = chObj->resId;
2387                     EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2388                     }
2389                 }
2390             else
2391                 {
2392                 /**
2393                  * PaRAM Set allocation failed, free the previously allocated
2394                  * DMA channel also.
2395                  */
2396                 resObj.type = chObj->type;
2397                 resObj.resId = chObj->resId;
2398                 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2399                 }
2400             }
2403         /* Further resources' allocation for QDMA channel. */
2404         if (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
2405             {
2406             /* First allocate a PaRAM Set */
2407             resObj.type = EDMA3_RM_RES_PARAM_SET;
2408             /* Use the saved param id now. */
2409             resObj.resId = (unsigned int)paRAMId;
2410             result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2411             if (result == EDMA3_RM_SOK)
2412                 {
2413                 /**
2414                  * PaRAM Set allocation succeeded.
2415                  * Save the PaRAM Set first.
2416                  */
2417                 *pParam = resObj.resId;
2418                 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = (int)(resObj.resId);
2420                 /* Allocate the TCC now. */
2421                 resObj.type = EDMA3_RM_RES_TCC;
2422                 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2423                     {
2424                     if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2425                         {
2426                         resObj.resId = EDMA3_RM_RES_ANY;
2427                         }
2428                     else
2429                         {
2430                         resObj.resId = mappedTcc;
2431                         }
2432                     }
2433                 else
2434                     {
2435                     resObj.resId = *pTcc;
2436                     }
2438                 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2439                 if (result == EDMA3_RM_SOK)
2440                     {
2441                      /* TCC allocation succeeded. Save it first. */
2442                     *pTcc = resObj.resId;
2443                      edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = resObj.resId;
2445                     /**
2446                      * Check first whether the global registers and the allocated
2447                      * PaRAM Set can be modified or not. If yes, do the needful.
2448                      * Else leave this for the user.
2449                      */
2450                     if (TRUE == rmInstance->regModificationRequired)
2451                         {
2452                         /* Set TCC of the allocated Param Set. */
2453                         gblRegs->PARAMENTRY[*pParam].OPT  &= EDMA3_RM_OPT_TCC_CLR_MASK;
2454                         gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2456                         /* Do the mapping between QDMA channel and PaRAM Set. */
2457                         /* Map Parameter RAM Set Number for specified channelId */
2458                         gblRegs->QCHMAP[chObj->resId]
2459                                         &= EDMA3_RM_QCH_PARAM_CLR_MASK;
2460                         gblRegs->QCHMAP[chObj->resId]
2461                                         |= EDMA3_RM_QCH_PARAM_SET_MASK(*pParam);
2463                         /* Set the Trigger Word */
2464                         gblRegs->QCHMAP[chObj->resId]
2465                                         &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
2466                         gblRegs->QCHMAP[chObj->resId]
2467                                         |= EDMA3_RM_QCH_TRWORD_SET_MASK(EDMA3_RM_QDMA_TRIG_DEFAULT);
2469                         /* Remove any linking */
2470                         *((&gblRegs->PARAMENTRY[*pParam].OPT)
2471                                 + (unsigned int)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2473                         /* Enable the transfer also. */
2474                         rmInstance->shadowRegs->QEESR = (1u << chObj->resId);
2475                         }
2476                     }
2477                 else
2478                     {
2479                     /**
2480                      * TCC allocation failed, free the previously allocated
2481                      * PaRAM Set and QDMA channel.
2482                      */
2483                     resObj.type = EDMA3_RM_RES_PARAM_SET;
2484                     resObj.resId = *pParam;
2485                     EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2487                     /* Reset the book-keeping data structure also. */
2488                     edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
2490                     resObj.type = chObj->type;
2491                     resObj.resId = chObj->resId;
2492                     EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2493                     }