]> 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
Misc changes in Resource Manager
[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 /**
98  * \brief Static Configuration structure for EDMA3
99  * controller, to provide Global SoC specific Information.
100  *
101  * This configuration info can also be provided by the user at run-time,
102  * while calling EDMA3_RM_create (). If not provided at run-time,
103  * this info will be taken from the config file "edma3_<PLATFORM_NAME>_cfg.c",
104  * for the specified platform.
105  */
106 extern EDMA3_RM_GblConfigParams edma3GblCfgParams [EDMA3_MAX_EDMA3_INSTANCES];
108 /**
109  * \brief Default Static Region Specific Configuration structure for
110  * EDMA3 controller, to provide region specific Information.
111  */
112 extern EDMA3_RM_InstanceInitConfig defInstInitConfig [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_REGIONS];
115 /**
116  * \brief Region Specific Configuration structure for
117  * EDMA3 controller, to provide region specific Information.
118  *
119  * This configuration info can also be provided by the user at run-time,
120  * while calling EDMA3_RM_open (). If not provided at run-time,
121  * this info will be taken from the config file "edma3_<PLATFORM_NAME>_cfg.c",
122  * for the specified platform.
123  */
124 extern EDMA3_RM_InstanceInitConfig *userInitConfig;
125 extern EDMA3_RM_InstanceInitConfig *ptrInitCfgArray;
128 /**
129  * Handles of EDMA3 Resource Manager Instances.
130  *
131  * Used to maintain information of the EDMA3 RM Instances
132  * for each HW controller.
133  * There could be a maximum of EDMA3_MAX_RM_INSTANCES instances per
134  * EDMA3 HW.
135  */
136 extern EDMA3_RM_Instance *resMgrInstance;
137 extern EDMA3_RM_Instance *ptrRMIArray;
139 /** Max of DMA Channels */
140 unsigned int edma3_dma_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
141 /** Min of Link Channels */
142 unsigned int edma3_link_ch_min_val[EDMA3_MAX_EDMA3_INSTANCES];
143 /** Max of Link Channels */
144 unsigned int edma3_link_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
145 /** Min of QDMA Channels */
146 unsigned int edma3_qdma_ch_min_val[EDMA3_MAX_EDMA3_INSTANCES];
147 /** Max of QDMA Channels */
148 unsigned int edma3_qdma_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
149 /** Max of Logical Channels */
150 unsigned int edma3_log_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
152 /* Globals */
153 /*---------------------------------------------------------------------------*/
154 /**
155  * \brief EDMA3 Resource Manager Objects, tied to each EDMA3 HW Controller.
156  *
157  * Typically one RM object will cater to one EDMA3 HW controller
158  * and will have all the global config information.
159  */
160 EDMA3_RM_Obj resMgrObj[EDMA3_MAX_EDMA3_INSTANCES];
163 /**
164  * Global Array to store the mapping between DMA channels and Interrupt
165  * channels i.e. TCCs.
166  * DMA channel X can use any TCC Y. Transfer completion
167  * interrupt will occur on the TCC Y (IPR/IPRH Register, bit Y), but error
168  * interrupt will occur on DMA channel X (EMR/EMRH register, bit X). In that
169  * scenario, this DMA channel <-> TCC mapping will be used to point to
170  * the correct callback function.
171  */
172 static unsigned int edma3DmaChTccMapping [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_DMA_CH];
175 /**
176  * Global Array to store the mapping between QDMA channels and Interrupt
177  * channels i.e. TCCs.
178  * QDMA channel X can use any TCC Y. Transfer completion
179  * interrupt will occur on the TCC Y (IPR/IPRH Register, bit Y), but error
180  * interrupt will occur on QDMA channel X (QEMR register, bit X). In that
181  * scenario, this QDMA channel <-> TCC mapping will be used to point to
182  * the correct callback function.
183  */
184 static unsigned int edma3QdmaChTccMapping [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_QDMA_CH];
187 /**
188  * Global Array to maintain the Callback details registered
189  * against a particular TCC. Used to call the callback
190  * functions linked to the particular channel.
191  */
192 static EDMA3_RM_TccCallbackParams edma3IntrParams [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_TCC];
195 /** edma3RegionId will be updated ONCE using the parameter regionId passed to
196  * the EDMA3_RM_open() function, for the Master RM instance (one who
197  * configures the Global Registers).
198  * This global variable will be used within the Interrupt handlers to know
199  * which shadow region registers to access. All other interrupts coming
200  * from other shadow regions will not be handled.
201  */
202 static EDMA3_RM_RegionId edma3RegionId = EDMA3_MAX_REGIONS;
204 /** masterExists[] will be updated when the Master RM Instance modifies the
205  * Global EDMA3 configuration registers. It is used to prevent any other
206  * Master RM Instance creation.
207  * masterExists[] is per EDMA3 hardware, hence it is created
208  * as an array.
209  */
210 static unsigned short masterExists [EDMA3_MAX_EDMA3_INSTANCES] = {FALSE,FALSE,FALSE};
212 /**
213  * Number of PaRAM Sets actually present on the SoC. This will be updated
214  * while creating the Resource Manager Object.
215  */
216 unsigned int edma3NumPaRAMSets = EDMA3_MAX_PARAM_SETS;
219 /**
220  * The list of Interrupt Channels which get allocated while requesting the
221  * TCC. It will be used while checking the IPR/IPRH bits in the RM ISR.
222  */
223 static unsigned int allocatedTCCs[EDMA3_MAX_EDMA3_INSTANCES][2u] =
224                                                                                         {
225                                                                                         {0x0u, 0x0u},
226                                                                                         {0x0u, 0x0u},
227                                                                                         {0x0u, 0x0u},
228                                                                                         };
231 /**
232  * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
233  * and stored in this array. It will be referenced in
234  * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
235  */
236 static unsigned int contiguousDmaRes[EDMA3_MAX_DMA_CHAN_DWRDS] = {0x0u, 0x0u};
238 /**
239  * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
240  * and stored in this array. It will be referenced in
241  * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
242  */
243 static unsigned int contiguousQdmaRes[EDMA3_MAX_QDMA_CHAN_DWRDS] = {0x0u};
245 /**
246  * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
247  * and stored in this array. It will be referenced in
248  * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
249  */
250 static unsigned int contiguousTccRes[EDMA3_MAX_TCC_DWRDS] = {0x0u, 0x0u};
252 /**
253  * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
254  * and stored in this array. It will be referenced in
255  * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
256  */
257 static unsigned int contiguousParamRes[EDMA3_MAX_PARAM_DWRDS];
260 /**
261  * \brief Resources bound to a Channel
262  *
263  * When a request for a channel is made, the resources PaRAM Set and TCC
264  * get bound to that channel. This information is needed internally by the
265  * resource manager, when a request is made to free the channel,
266  * to free up the channel-associated resources.
267  */
268 static EDMA3_RM_ChBoundResources edma3RmChBoundRes [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_LOGICAL_CH];
272 /*---------------------------------------------------------------------------*/
274 /* Local functions prototypes */
275 /*---------------------------------------------------------------------------*/
276 /** EDMA3 Instance 0 Completion Handler Interrupt Service Routine */
277 void lisrEdma3ComplHandler0(unsigned int arg);
278 /** EDMA3 Instance 0 CC Error Interrupt Service Routine */
279 void lisrEdma3CCErrHandler0(unsigned int arg);
280 /**
281  * EDMA3 Instance 0 TC[0-7] Error Interrupt Service Routines
282  * for a maximum of 8 TCs (Transfer Controllers).
283  */
284 void lisrEdma3TC0ErrHandler0(unsigned int arg);
285 void lisrEdma3TC1ErrHandler0(unsigned int arg);
286 void lisrEdma3TC2ErrHandler0(unsigned int arg);
287 void lisrEdma3TC3ErrHandler0(unsigned int arg);
288 void lisrEdma3TC4ErrHandler0(unsigned int arg);
289 void lisrEdma3TC5ErrHandler0(unsigned int arg);
290 void lisrEdma3TC6ErrHandler0(unsigned int arg);
291 void lisrEdma3TC7ErrHandler0(unsigned int arg);
294 /** Interrupt Handler for the Transfer Completion interrupt */
295 static void edma3ComplHandler (const EDMA3_RM_Obj *rmObj);
296 /** Interrupt Handler for the Channel Controller Error interrupt */
297 static void edma3CCErrHandler (const EDMA3_RM_Obj *rmObj);
298 /** Interrupt Handler for the Transfer Controller Error interrupt */
299 static void edma3TCErrHandler (const EDMA3_RM_Obj *rmObj, unsigned int tcNum);
302 /** Local MemZero function */
303 void edma3MemZero(void *dst, unsigned int len);
304 /** Local MemCpy function */
305 void edma3MemCpy(void *dst, const void *src, unsigned int len);
306 /* Local MemCopy function to copy Param Set ONLY */
307 void edma3ParamCpy(void *dst, const void *src);
309 /** Initialization of the Global region registers of the EDMA3 Controller */
310 static void edma3GlobalRegionInit (unsigned int phyCtrllerInstId);
311 /** Initialization of the Shadow region registers of the EDMA3 Controller */
312 static void edma3ShadowRegionInit (const EDMA3_RM_Instance *pRMInstance);
316 /* Internal functions for contiguous resource allocation */
317 /**
318  * Finds a particular bit ('0' or '1') in the particular word from 'start'.
319  * If found, returns the position, else return -1.
320  */
321 static int findBitInWord (int source, unsigned int start, unsigned short bit);
323 /**
324  * Finds a particular bit ('0' or '1') in the specified resources' array
325  * from 'start' to 'end'. If found, returns the position, else return -1.
326  */
327 static int findBit (EDMA3_RM_ResType resType,
328                             unsigned int start,
329                             unsigned int end,
330                             unsigned short bit);
332 /**
333  * If successful, this function returns EDMA3_RM_SOK and the position
334  * of first available resource in 'positionRes'. Else returns error.
335  */
336 static EDMA3_RM_Result allocAnyContigRes(EDMA3_RM_ResType resType,
337                                     unsigned int numResources,
338                                     unsigned int *positionRes);
340 /**
341  * Starting from 'firstResIdObj', this function makes the next 'numResources'
342  * Resources non-available for future. Also, it does some global resisters'
343  * setting also.
344  */
345 static EDMA3_RM_Result gblChngAllocContigRes(EDMA3_RM_Instance *rmInstance,
346                         const EDMA3_RM_ResDesc *firstResIdObj,
347                                         unsigned int numResources);
349 /*---------------------------------------------------------------------------*/
351 /**\fn      EDMA3_RM_Result EDMA3_RM_create (unsigned int phyCtrllerInstId,
352  *          const EDMA3_RM_GblConfigParams *gblCfgParams,
353  *          const void *miscParam)
354  * \brief   Create EDMA3 Resource Manager Object
355  *
356  * This API is used to create the EDMA3 Resource Manager Object. It should be
357  * called only ONCE for each EDMA3 hardware instance.
358  *
359  * Init-time Configuration structure for EDMA3 hardware is provided to pass the
360  * SoC specific information. This configuration information could be provided
361  * by the user at init-time. In case user doesn't provide it, this information
362  * could be taken from the SoC specific configuration file
363  * edma3_<SOC_NAME>_cfg.c, in case it is available.
364  *
365  * This API clears the error specific registers (EMCR/EMCRh, QEMCR, CCERRCLR)
366  * and sets the TCs priorities and Event Queues' watermark levels, if the 'miscParam'
367  * argument is NULL. User can avoid these registers' programming (in some specific
368  * use cases) by SETTING the 'isSlave' field of 'EDMA3_RM_MiscParam' configuration
369  * structure and passing this structure as the third argument (miscParam).
370  *
371  * After successful completion of this API, Resource Manager Object's state
372  * changes to EDMA3_RM_CREATED from EDMA3_RM_DELETED.
373  *
374  * \param phyCtrllerInstId  [IN]    EDMA3 Controller Instance Id
375  *                                 (Hardware instance id, starting from 0).
376  * \param gblCfgParams      [IN]    SoC specific configuration structure for the
377  *                                  EDMA3 Hardware.
378  * \param miscParam         [IN]    Misc configuration options provided in the
379  *                                  structure 'EDMA3_RM_MiscParam'.
380  *                                  For default options, user can pass NULL
381  *                                  in this argument.
382  *
383  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
384  */
385 EDMA3_RM_Result EDMA3_RM_create (unsigned int phyCtrllerInstId,
386                                 const EDMA3_RM_GblConfigParams *gblCfgParams,
387                                 const void *miscParam)
388     {
389     unsigned int count = 0u;
390     EDMA3_RM_Result result = EDMA3_RM_SOK;
391     /**
392      * Used to reset the Internal EDMA3 Resource Manager Data Structures for the first time.
393      */
394     static unsigned short rmInitDone = FALSE;
395     const EDMA3_RM_MiscParam *miscOpt = (const EDMA3_RM_MiscParam *)miscParam;
397     /**
398      * We are NOT checking 'gblCfgParams' for NULL.
399      * If user has passed NULL, default config info will be
400      * taken from config file.
401      * 'param' is also not being checked because it could be
402      * NULL also.
403      */
405     /* If parameter checking is enabled... */
406 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
407     if (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
408         {
409         result = EDMA3_RM_E_INVALID_PARAM;
410         }
411 #endif
413         /* Check if the parameters are OK. */
414     if (EDMA3_RM_SOK == result)
415         {
416         /* Initialize the global variables for the first time */
417         if (FALSE == rmInitDone)
418             {
419             edma3MemZero((void *)&(resMgrObj[count]),
420                                 sizeof(resMgrObj));
421             edma3MemZero((void *)(&(edma3IntrParams[0u])),
422                 sizeof(edma3IntrParams));
424             rmInitDone = TRUE;
425             }
427         /* Initialization has been done */
428         if (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_DELETED)
429             {
430             result = EDMA3_RM_E_OBJ_NOT_DELETED;
431             }
432         else
433             {
434             /**
435               * Check whether user has passed the Global Config Info.
436               * If yes, copy it to the driver data structures. Else, use the
437               * info from the config file edma3Cfg.c
438               */
439             if (NULL == gblCfgParams)
440                 {
441                 /* Take info from the specific config file */
442                 edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
443                                             (const void *)(&edma3GblCfgParams[phyCtrllerInstId]),
444                                             sizeof (EDMA3_RM_GblConfigParams));
445                 }
446             else
447                 {
448                 /* User passed the info, save it in the RM object first */
449                 edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
450                                             (const void *)(gblCfgParams),
451                                             sizeof (EDMA3_RM_GblConfigParams));
452                 }
455             /**
456               * Check whether DMA channel to PaRAM Set mapping exists or not.
457               * If it does not exist, set the mapping array as 1-to-1 mapped.
458               */
459             if (FALSE == resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChPaRAMMapExists)
460                 {
461                 for (count = 0u; count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels; count++)
462                     {
463                     resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChannelPaRAMMap[count] = count;
464                     }
465                 }
468             /**
469              * Update the actual number of PaRAM sets and
470              * Initialize Boundary Values for Logical Channel Ranges.
471              */
472             edma3NumPaRAMSets = resMgrObj[phyCtrllerInstId].gblCfgParams.numPaRAMSets;
473                         edma3_dma_ch_max_val[phyCtrllerInstId] = resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels - 1u;
474                         edma3_link_ch_min_val[phyCtrllerInstId] = edma3_dma_ch_max_val[phyCtrllerInstId] + 1u;
475                         edma3_link_ch_max_val[phyCtrllerInstId] = edma3_link_ch_min_val[phyCtrllerInstId] + resMgrObj[phyCtrllerInstId].gblCfgParams.numPaRAMSets - 1u;
476                         edma3_qdma_ch_min_val[phyCtrllerInstId] = edma3_link_ch_max_val[phyCtrllerInstId] + 1u;
477                         edma3_qdma_ch_max_val[phyCtrllerInstId] = edma3_qdma_ch_min_val[phyCtrllerInstId] + resMgrObj[phyCtrllerInstId].gblCfgParams.numQdmaChannels - 1u;
478                         edma3_log_ch_max_val[phyCtrllerInstId] = edma3_qdma_ch_max_val[phyCtrllerInstId];
480             resMgrObj[phyCtrllerInstId].phyCtrllerInstId = phyCtrllerInstId;
481             resMgrObj[phyCtrllerInstId].state = EDMA3_RM_CREATED;
482             resMgrObj[phyCtrllerInstId].numOpens = 0u;
484             /* Make all the RM instances for this EDMA3 HW NULL */
485             for (count = 0u; count < EDMA3_MAX_RM_INSTANCES; count++)
486                 {
487                 edma3MemZero((void *)((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
488                             sizeof(EDMA3_RM_Instance));
490                 /* Also make this data structure NULL */
491                 edma3MemZero((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
492                             sizeof(EDMA3_RM_InstanceInitConfig));
493                 }
495             /* Initialize the global edma3DmaChTccMapping array with EDMA3_MAX_TCC */
496             for (  count = 0u;
497                     count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels;
498                     count++
499                 )
500                 {
501                 edma3DmaChTccMapping[phyCtrllerInstId][count] = EDMA3_MAX_TCC;
502                 }
504             /* Initialize the global edma3QdmaChTccMapping array with EDMA3_MAX_TCC */
505             for (   count = 0u;
506                     count < resMgrObj[phyCtrllerInstId].gblCfgParams.numQdmaChannels;
507                     count++
508                 )
509                 {
510                 edma3QdmaChTccMapping[phyCtrllerInstId][count] = EDMA3_MAX_TCC;
511                 }
513             /* Reset edma3RmChBoundRes Array*/
514             for (count = 0u; count < EDMA3_MAX_LOGICAL_CH; count++)
515                 {
516                 edma3RmChBoundRes[phyCtrllerInstId][count].paRAMId = -1;
517                 edma3RmChBoundRes[phyCtrllerInstId][count].tcc = EDMA3_MAX_TCC;
518                 }
520             /* Make the contiguousParamRes array NULL */
521             edma3MemZero((void *)(&(contiguousParamRes[0u])),
522                 sizeof(contiguousParamRes));
525             /**
526              * Check the misc configuration options structure.
527              * Check whether the global registers' initialization
528              * is required or not.
529              * It is required ONLY if RM is running on the Master Processor.
530              */
531             if (NULL != miscOpt)
532                 {
533                 if (miscOpt->isSlave == FALSE)
534                     {
535                     /* It is a master. */
536                     edma3GlobalRegionInit(phyCtrllerInstId);
537                     }
538                 }
539             else
540                 {
541                 /* By default, global registers will be initialized. */
542                 edma3GlobalRegionInit(phyCtrllerInstId);
543                 }
544             }
545         }
547     return result;
548     }
552 /**\fn      EDMA3_RM_Result EDMA3_RM_delete (unsigned int phyCtrllerInstId,
553  *                               const void *param)
554  * \brief   Delete EDMA3 Resource Manager Object
555  *
556  * This API is used to delete the EDMA3 RM Object. It should be called
557  * once for each EDMA3 hardware instance, ONLY after closing all the
558  * previously opened EDMA3 RM Instances.
559  *
560  * After successful completion of this API, Resource Manager Object's state
561  * changes to EDMA3_RM_DELETED.
562  *
563  * \param phyCtrllerInstId  [IN]    EDMA3 Phy Controller Instance Id (Hardware
564  *                                  instance id, starting from 0).
565  * \param   param           [IN]    For possible future use.
566  *
567  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
568  */
569 EDMA3_RM_Result EDMA3_RM_delete (unsigned int phyCtrllerInstId,
570                                                 const void *param)
571     {
572     EDMA3_RM_Result result = EDMA3_RM_SOK;
574     /* If parameter checking is enabled... */
575 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
576     if (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
577         {
578         result = EDMA3_RM_E_INVALID_PARAM;
579         }
580 #endif
582         /* Check if the parameters are OK. */
583         if (EDMA3_RM_SOK == result)
584         {
585         /*to remove CCS remark: parameter "param" was never referenced */
586         (void)param;
588         /**
589          * If number of RM Instances is 0, then state should be
590          * EDMA3_RM_CLOSED OR EDMA3_RM_CREATED.
591          */
592         if ((NULL == resMgrObj[phyCtrllerInstId].numOpens)
593             && ((resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CLOSED)
594             && (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CREATED)))
595             {
596             result = EDMA3_RM_E_OBJ_NOT_CLOSED;
597             }
598         else
599             {
600             /**
601              * If number of RM Instances is NOT 0, then this function
602              * SHOULD NOT be called by anybody.
603              */
604             if (NULL != resMgrObj[phyCtrllerInstId].numOpens)
605                 {
606                 result = EDMA3_RM_E_INVALID_STATE;
607                 }
608             else
609                 {
610                 /** Change state to EDMA3_RM_DELETED */
611                 resMgrObj[phyCtrllerInstId].state = EDMA3_RM_DELETED;
613                 /* Reset the Allocated TCCs Array also. */
614                 allocatedTCCs[phyCtrllerInstId][0u] = 0x0u;
615                 allocatedTCCs[phyCtrllerInstId][1u] = 0x0u;
617                 /* Also, reset the RM Object Global Config Info */
618                 edma3MemZero((void *)&(resMgrObj[phyCtrllerInstId].gblCfgParams),
619                          sizeof(EDMA3_RM_GblConfigParams));
620                 }
621             }
622         }
624     return result;
625     }
628 /**\fn      EDMA3_RM_Handle EDMA3_RM_open (unsigned int phyCtrllerInstId,
629  *                                const EDMA3_RM_Param *initParam,
630  *                               EDMA3_RM_Result *errorCode)
631  * \brief   Open EDMA3 Resource Manager Instance
632  *
633  * This API is used to open an EDMA3 Resource Manager Instance. It could be
634  * called multiple times, for each possible EDMA3 shadow region. Maximum
635  * EDMA3_MAX_RM_INSTANCES instances are allowed for each EDMA3 hardware
636  * instance.
637  *
638  * Also, only ONE Master Resource Manager Instance is permitted. This master
639  * instance (and hence the region to which it belongs) will only receive the
640  * EDMA3 interrupts, if enabled.
641  *
642  * User could pass the instance specific configuration structure
643  * (initParam->rmInstInitConfig) as a part of the 'initParam' structure,
644  * during init-time. In case user doesn't provide it, this information could
645  * be taken from the SoC specific configuration file edma3_<SOC_NAME>_cfg.c,
646  * in case it is available.
647  *
648  * \param   phyCtrllerInstId    [IN]    EDMA3 Controller Instance Id (Hardware
649  *                                      instance id, starting from 0).
650  * \param   initParam           [IN]    Used to Initialize the Resource Manager
651  *                                      Instance (Master or Slave).
652  * \param   errorCode           [OUT]   Error code while opening RM instance.
653  *
654  * \return  Handle to the opened Resource Manager instance Or NULL in case of
655  *          error.
656  *
657  * \note    This function disables the global interrupts (by calling API
658  *          edma3OsProtectEntry with protection level
659  *          EDMA3_OS_PROTECT_INTERRUPT) while modifying the global RM data
660  *          structures, to make it re-entrant.
661  */
662 EDMA3_RM_Handle EDMA3_RM_open (unsigned int phyCtrllerInstId,
663                                 const EDMA3_RM_Param *initParam,
664                                 EDMA3_RM_Result *errorCode)
665     {
666     unsigned int intState           = 0u;
667     unsigned int resMgrIdx          = 0u;
668     EDMA3_RM_Result result          = EDMA3_RM_SOK;
669     EDMA3_RM_Obj *rmObj             = NULL;
670     EDMA3_RM_Instance *rmInstance   = NULL;
671     EDMA3_RM_Instance *temp_ptr_rm_inst   = NULL;
672     EDMA3_RM_Handle retVal          = NULL;
673     unsigned int dmaChDwrds = 0u;
674     unsigned int paramSetDwrds = 0u;
675     unsigned int tccDwrds = 0u;
676     volatile EDMA3_CCRL_Regs *globalRegs = NULL;
678         /* If parameter checking is enabled... */
679 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
680         if (((initParam == NULL)
681                 || (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES))
682         || (errorCode == NULL))
683         {
684         result = EDMA3_RM_E_INVALID_PARAM;
685         }
686 #endif
688         /* Check if the parameters are OK. */
689         if (EDMA3_RM_SOK == result)
690         {
691         /* Check whether the semaphore handle is null or not */
692         if (NULL == initParam->rmSemHandle)
693             {
694             result = EDMA3_RM_E_INVALID_PARAM;
695             }
696         else
697             {
698             rmObj = &resMgrObj[phyCtrllerInstId];
699             if  (
700                 (NULL == rmObj)
701                 || (initParam->regionId >=
702                         resMgrObj[phyCtrllerInstId].gblCfgParams.numRegions)
703                 )
704                 {
705                 result = EDMA3_RM_E_INVALID_PARAM;
706                 }
707             else
708                 {
709                 edma3OsProtectEntry (phyCtrllerInstId,
710                                                                         EDMA3_OS_PROTECT_INTERRUPT,
711                                                                         &intState);
713                 /** Check state of RM Object.
714                   * If no RM instance is opened and this is the first one,
715                   * then state should be created/closed.
716                   */
717                 if ((rmObj->numOpens == NULL) &&
718                     ((rmObj->state != EDMA3_RM_CREATED) &&
719                     (rmObj->state != EDMA3_RM_CLOSED)))
720                     {
721                     result = EDMA3_RM_E_INVALID_STATE;
722                     edma3OsProtectExit (phyCtrllerInstId,
723                                                                                 EDMA3_OS_PROTECT_INTERRUPT,
724                                                                                 intState);
725                     }
726                 else
727                     {
728                     /**
729                      * If num of instances opened is more than 0 and less than
730                      *  max allowed, then state should be opened.
731                      */
732                     if (((rmObj->numOpens > 0) &&
733                             (rmObj->numOpens < EDMA3_MAX_RM_INSTANCES))
734                         && (rmObj->state != EDMA3_RM_OPENED))
735                         {
736                         result = EDMA3_RM_E_INVALID_STATE;
737                             edma3OsProtectExit (phyCtrllerInstId,
738                                                                                         EDMA3_OS_PROTECT_INTERRUPT,
739                                                                                         intState);
740                         }
741                     else
742                         {
743                         /* Check if max opens have passed */
744                         if (rmObj->numOpens >= EDMA3_MAX_RM_INSTANCES)
745                             {
746                             result = EDMA3_RM_E_MAX_RM_INST_OPENED;
747                                     edma3OsProtectExit (phyCtrllerInstId,
748                                                                                                 EDMA3_OS_PROTECT_INTERRUPT,
749                                                                                                 intState);
750                             }
751                         }
752                     }
753                 }
754             }
755         }
757     if (EDMA3_RM_SOK == result)
758         {
759         /*
760         * Check whether the RM instance is Master or not.
761         * If it is master, check whether a master already exists
762         * or not. There should NOT be more than 1 master.
763         * Return error code if master already exists
764         */
765         if ((TRUE == masterExists[phyCtrllerInstId]) && (TRUE == initParam->isMaster))
766             {
767             /* No two masters should exist, return error */
768             result = EDMA3_RM_E_RM_MASTER_ALREADY_EXISTS;
769             edma3OsProtectExit (phyCtrllerInstId,
770                                                                 EDMA3_OS_PROTECT_INTERRUPT,
771                                                                 intState);
772             }
773         else
774             {
775             /* Create Res Mgr Instance */
776             for (resMgrIdx = 0u; resMgrIdx < EDMA3_MAX_RM_INSTANCES; resMgrIdx++)
777                 {
778                 temp_ptr_rm_inst = ((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
780                 if (NULL != temp_ptr_rm_inst)
781                     {
782                     if (NULL == temp_ptr_rm_inst->pResMgrObjHandle)
783                         {
784                         /* Handle to the EDMA3 HW Object */
785                         temp_ptr_rm_inst->pResMgrObjHandle = rmObj;
786                         /* Handle of the Res Mgr Instance */
787                         rmInstance = temp_ptr_rm_inst;
789                         /* Also make this data structure NULL, just for safety. */
790                         edma3MemZero((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
791                                     sizeof(EDMA3_RM_InstanceInitConfig));
793                         break;
794                         }
795                     }
796                 }
798             /* Check whether a RM instance has been created or not */
799             if (NULL == rmInstance)
800                 {
801                 result = EDMA3_RM_E_MAX_RM_INST_OPENED;
802                 edma3OsProtectExit (phyCtrllerInstId,
803                                                                         EDMA3_OS_PROTECT_INTERRUPT,
804                                                                         intState);
805                 }
806             else
807                 {
808                 /* Copy the InitPaRAM first */
809                 edma3MemCpy((void *)(&rmInstance->initParam),
810                                             (const void *)(initParam),
811                                             sizeof (EDMA3_RM_Param));
813                 if (rmObj->gblCfgParams.globalRegs != NULL)
814                     {
815                     globalRegs = (volatile EDMA3_CCRL_Regs *)
816                                             (rmObj->gblCfgParams.globalRegs);
817                     rmInstance->shadowRegs = (EDMA3_CCRL_ShadowRegs *)
818                         &(globalRegs->SHADOW[rmInstance->initParam.regionId]);
820                     /* copy the instance specific semaphore handle */
821                     rmInstance->initParam.rmSemHandle = initParam->rmSemHandle;
823                     /**
824                     * Check whether user has passed information about resources
825                     * owned and reserved by this instance. This is region specific
826                     * information. If he has not passed, dafault static config info will be taken
827                     * from the config file edma3Cfg.c, according to the regionId specified.
828                     *
829                     * resMgrIdx specifies the RM instance number created just now.
830                     * Use it to populate the userInitConfig [].
831                     */
832                     if (NULL == initParam->rmInstInitConfig)
833                         {
834                         /* Take the info from the specific config file */
835                         edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
836                                 (const void *)(&defInstInitConfig[phyCtrllerInstId][initParam->regionId]),
837                                 sizeof (EDMA3_RM_InstanceInitConfig));
838                         }
839                     else
840                         {
841                         /* User has passed the region specific info. */
842                         edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
843                                 (const void *)(initParam->rmInstInitConfig),
844                                 sizeof (EDMA3_RM_InstanceInitConfig));
845                         }
847                     rmInstance->initParam.rmInstInitConfig =
848                                 ((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
850                     dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / 32u;
851                                         if (dmaChDwrds == 0)
852                                                 {
853                                                 /* In case DMA channels are < 32 */
854                                                 dmaChDwrds = 1;
855                                                 }
857                     paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / 32u;
858                                         if (paramSetDwrds == 0)
859                                                 {
860                                                 /* In case PaRAM Sets are < 32 */
861                                                 paramSetDwrds = 1;
862                                                 }
864                     tccDwrds = rmObj->gblCfgParams.numTccs / 32u;
865                                         if (tccDwrds == 0)
866                                                 {
867                                                 /* In case TCCs are < 32 */
868                                                 tccDwrds = 1;
869                                                 }
871                     for (resMgrIdx = 0u; resMgrIdx < dmaChDwrds; ++resMgrIdx)
872                         {
873                         rmInstance->avlblDmaChannels[resMgrIdx]
874                             = rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resMgrIdx];
875                         }
877                     rmInstance->avlblQdmaChannels[0u]
878                         = rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u];
880                     for (resMgrIdx = 0u; resMgrIdx < paramSetDwrds; ++resMgrIdx)
881                         {
882                         rmInstance->avlblPaRAMSets[resMgrIdx]
883                             = rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[resMgrIdx];
884                         }
886                     for (resMgrIdx = 0u; resMgrIdx < tccDwrds; ++resMgrIdx)
887                         {
888                         rmInstance->avlblTccs [resMgrIdx]
889                             = rmInstance->initParam.rmInstInitConfig->ownTccs[resMgrIdx];
890                         }
892                     /*
893                     * If mapping exists b/w DMA channel and PaRAM set (i.e. programmable),
894                     * then mark those PaRAM sets which are mapped to some specific
895                     * DMA channels as RESERVED. If NO mapping (ie ch 0 is tied to PaRAM 0,
896                     * ch 1 is tied to PaRAM 1), mark all as RESERVED.
897                     */
898                     if (rmObj->gblCfgParams.dmaChPaRAMMapExists == TRUE)
899                         {
900                         /* Mapping Exists */
901                         for (resMgrIdx = 0u; resMgrIdx < rmObj->gblCfgParams.numDmaChannels; ++resMgrIdx)
902                             {
903                             mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resMgrIdx];
904                             if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
905                                 {
906                                 /* Channel is mapped to a particular PaRAM Set, mark it as Reserved. */
907                                 rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[mappedPaRAMId/32u] |= (1u<<(mappedPaRAMId%32u));
908                                 }
909                             }
910                         }
911                     else
912                         {
913                         /* Mapping Doesnot Exist, PaRAM Sets are 1-to-1 mapped, mark all as Reserved */
914                         for (resMgrIdx = 0u; resMgrIdx < dmaChDwrds; ++resMgrIdx)
915                             {
916                             rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[resMgrIdx] = 0xFFFFFFFFu;
917                             }
918                         }
920                     /*
921                     * If the EDMA RM instance is MASTER (ie. initParam->isMaster
922                     * is TRUE), save the region ID.
923                     * Only this shadow region will receive the
924                     * EDMA3 interrupts, if enabled.
925                     */
926                     if (TRUE == initParam->isMaster)
927                         {
928                         /* Store the region id to use it in the ISRs */
929                         edma3RegionId = rmInstance->initParam.regionId;
930                         masterExists[phyCtrllerInstId] = TRUE;
931                         }
933                     if (TRUE == initParam->regionInitEnable)
934                         {
935                         edma3ShadowRegionInit (rmInstance);
936                         }
938                     /**
939                      * By default, PaRAM Sets allocated using this RM Instance
940                      * will get cleared during their allocation.
941                      * User can stop their clearing by calling specific IOCTL
942                      * command.
943                      */
944                     rmInstance->paramInitRequired = TRUE;
947                     /**
948                      * By default, during the EDMA3_RM_allocLogicalChannel (),
949                      * global EDMA3 registers (DCHMAP/QCHMAP) and the allocated
950                      * PaRAM Set will be programmed accordingly, for users using this
951                      * RM Instance.
952                      * User can stop their pre-programming by calling
953                      * EDMA3_RM_IOCTL_SET_GBL_REG_MODIFY_OPTION
954                      * IOCTL command.
955                      */
956                     rmInstance->regModificationRequired = TRUE;
959                     if (EDMA3_RM_SOK == result)
960                         {
961                         rmObj->state = EDMA3_RM_OPENED;
962                         /* Increase the Instance count */
963                         resMgrObj[phyCtrllerInstId].numOpens++;
964                         retVal = rmInstance;
965                         }
966                     }
967                 else
968                     {
969                     result = EDMA3_RM_E_INVALID_PARAM;
970                     }
972                 edma3OsProtectExit (phyCtrllerInstId,
973                                                                         EDMA3_OS_PROTECT_INTERRUPT,
974                                                                         intState);
975                 }
976             }
977         }
979     *errorCode = result;
980     return (EDMA3_RM_Handle)retVal;
981     }
984 /**\fn      EDMA3_RM_Result EDMA3_RM_close (EDMA3_RM_Handle hEdmaResMgr,
985  *                                const void *param)
986  * \brief  Close EDMA3 Resource Manager Instance
987  *
988  * This API is used to close a previously opened EDMA3 RM Instance.
989  *
990  * \param  hEdmaResMgr         [IN]    Handle to the previously opened Resource
991  *                                     Manager Instance.
992  * \param  param               [IN]    For possible future use.
993  *
994  * \return EDMA3_RM_SOK or EDMA3_RM Error Code
995  *
996  * \note    This function disables the global interrupts (by calling API
997  *          edma3OsProtectEntry with protection level
998  *          EDMA3_OS_PROTECT_INTERRUPT) while modifying the global RM data
999  *          structures, to make it re-entrant.
1000  */
1001 EDMA3_RM_Result EDMA3_RM_close (EDMA3_RM_Handle hEdmaResMgr,
1002                                     const void *param)
1003     {
1004     EDMA3_RM_Result result = EDMA3_RM_SOK;
1005     unsigned int intState = 0u;
1006     unsigned int resMgrIdx = 0u;
1007     EDMA3_RM_Obj *rmObj             = NULL;
1008     EDMA3_RM_Instance *rmInstance   = NULL;
1009     unsigned int dmaChDwrds;
1010     unsigned int paramSetDwrds;
1011     unsigned int tccDwrds;
1013     /*to remove CCS remark: parameter "param" was never referenced */
1014     (void)param;
1016         /* If parameter checking is enabled... */
1017 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1018     if (NULL == hEdmaResMgr)
1019         {
1020         result = EDMA3_RM_E_INVALID_PARAM;
1021         }
1022 #endif
1024         /* Check if the parameters are OK. */
1025         if (EDMA3_RM_SOK == result)
1026         {
1027         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1028         rmObj = rmInstance->pResMgrObjHandle;
1030         if (rmObj == NULL)
1031             {
1032             result = (EDMA3_RM_E_INVALID_PARAM);
1033             }
1034         else
1035             {
1036             /* Check state of driver, state should be opened */
1037             if (rmObj->state != EDMA3_RM_OPENED)
1038                 {
1039                 result = (EDMA3_RM_E_OBJ_NOT_OPENED);
1040                 }
1041             else
1042                 {
1043                 dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / 32u;
1044                 paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / 32u;
1045                 tccDwrds = rmObj->gblCfgParams.numTccs / 32u;
1047                 /* Set the instance config as NULL*/
1048                 for (resMgrIdx = 0u; resMgrIdx < dmaChDwrds; ++resMgrIdx)
1049                     {
1050                     rmInstance->avlblDmaChannels[resMgrIdx] = 0x0u;
1051                     }
1052                 for (resMgrIdx = 0u; resMgrIdx < paramSetDwrds; ++resMgrIdx)
1053                     {
1054                     rmInstance->avlblPaRAMSets[resMgrIdx] = 0x0u;
1055                     }
1056                 rmInstance->avlblQdmaChannels[0u] = 0x0u;
1057                 for (resMgrIdx = 0u; resMgrIdx < tccDwrds; ++resMgrIdx)
1058                     {
1059                     rmInstance->avlblTccs[resMgrIdx] = 0x0u;
1060                     }
1062                 /**
1063                  * If this is the Master Instance, reset the static variable
1064                  * 'masterExists[]'.
1065                  */
1066                 if (TRUE == rmInstance->initParam.isMaster)
1067                     {
1068                     masterExists[rmObj->phyCtrllerInstId] = FALSE;
1069                     edma3RegionId = EDMA3_MAX_REGIONS;
1070                     }
1072                 /* Reset the Initparam for this RM Instance */
1073                 edma3MemZero((void *)&(rmInstance->initParam),
1074                                             sizeof(EDMA3_RM_Param));
1076                 /* Critical section starts */
1077                 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
1078                                                         EDMA3_OS_PROTECT_INTERRUPT,
1079                                                         &intState);
1081                 /* Decrease the Number of Opens */
1082                 --rmObj->numOpens;
1083                 if (NULL == rmObj->numOpens)
1084                     {
1085                     edma3MemZero((void *)&(edma3RmChBoundRes[rmObj->phyCtrllerInstId]),
1086                                             sizeof(edma3RmChBoundRes[rmObj->phyCtrllerInstId]));
1088                     rmObj->state = EDMA3_RM_CLOSED;
1089                     }
1091                 /* Critical section ends */
1092                 edma3OsProtectExit (rmObj->phyCtrllerInstId,
1093                                                         EDMA3_OS_PROTECT_INTERRUPT,
1094                                                         intState);
1096                 rmInstance->pResMgrObjHandle = NULL;
1097                 rmInstance->shadowRegs = NULL;
1098                 rmInstance = NULL;
1099                 }
1100             }
1101         }
1103     return result;
1104     }
1107 /**\fn      EDMA3_RM_Result EDMA3_RM_allocResource (EDMA3_RM_Handle hEdmaResMgr,
1108  *                                        EDMA3_RM_ResDesc *resObj)
1109  * \brief   This API is used to allocate specified EDMA3 Resources like
1110  * DMA/QDMA channel, PaRAM Set or TCC.
1111  *
1112  * Note: To free the resources allocated by this API, user should call
1113  * EDMA3_RM_freeResource () ONLY to de-allocate all the allocated resources.
1114  *
1115  * User can either request a specific resource by passing the resource id
1116  * in 'resObj->resId' OR request ANY available resource of the type
1117  * 'resObj->type'.
1118  *
1119  * ANY types of resources are those resources when user doesn't care about the
1120  * actual resource allocated; user just wants a resource of the type specified.
1121  * One use-case is to perform memory-to-memory data transfer operation. This
1122  * operation can be performed using any available DMA or QDMA channel.
1123  * User doesn't need any specific channel for the same.
1124  *
1125  * To allocate a specific resource, first this API checks whether that resource
1126  * is OWNED by the Resource Manager instance. Then it checks the current
1127  * availability of that resource.
1128  *
1129  * To allocate ANY available resource, this API tries to allocate a resource
1130  * from the pool of (owned && non_reserved && available_right_now) resources.
1131  *
1132  * After allocating a DMA/QDMA channel or TCC, the same resource is enabled in
1133  * the shadow region specific register (DRAE/DRAEH/QRAE).
1134  *
1135  * Allocated PaRAM Set is initialized to NULL before this API returns if user
1136  * has requested for one.
1137  *
1138  * \param  hEdmaResMgr      [IN]        Handle to the previously opened Resource
1139  *                                      Manager Instance.
1140  * \param   resObj          [IN/OUT]    Handle to the resource descriptor
1141  *                                      object, which needs to be allocated.
1142  *                                      In case user passes a specific resource
1143  *                                      Id, resObj value is left unchanged.
1144  *                                      In case user requests ANY available
1145  *                                      resource, the allocated resource id is
1146  *                                      returned in resObj.
1147  *
1148  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
1149  *
1150  * \note    This function acquires a RM Instance specific semaphore
1151  *          to prevent simultaneous access to the global pool of resources.
1152  *          It is re-entrant, but should not be called from the user callback
1153  *          function (ISR context).
1154  */
1155 EDMA3_RM_Result EDMA3_RM_allocResource(EDMA3_RM_Handle hEdmaResMgr,
1156                                         EDMA3_RM_ResDesc *resObj)
1157     {
1158     EDMA3_RM_Instance *rmInstance = NULL;
1159     EDMA3_RM_Obj *rmObj = NULL;
1160     EDMA3_RM_Result result = EDMA3_RM_SOK;
1161     EDMA3_RM_Result semResult = EDMA3_RM_SOK;
1162     unsigned int avlblIdx = 0u;
1163     unsigned int resIdClr = 0x0;
1164     unsigned int resIdSet = 0x0;
1165     unsigned int resId;
1166     volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1168 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1169     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1170                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1171                 EDMA3_DVT_dCOUNTER,
1172                 EDMA3_DVT_dNONE,
1173                 EDMA3_DVT_dNONE));
1174 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1176         /* If parameter checking is enabled... */
1177 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1178     if ((hEdmaResMgr == NULL) || (resObj == NULL))
1179         {
1180         result = (EDMA3_RM_E_INVALID_PARAM);
1181         }
1182 #endif
1184         /* Check if the parameters are OK. */
1185         if (EDMA3_RM_SOK == result)
1186         {
1187         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1188         rmObj = rmInstance->pResMgrObjHandle;
1190         if ((rmObj == NULL) ||
1191             (rmObj->gblCfgParams.globalRegs == NULL))
1192             {
1193             result = (EDMA3_RM_E_INVALID_PARAM);
1194             }
1195         else
1196             {
1197             gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1199             resId = resObj->resId;
1201             resIdClr = (unsigned int)(~(1u << (resId%32u)));
1202             resIdSet = (1u << (resId%32u));
1204             /**
1205               * Take the instance specific semaphore, to prevent simultaneous
1206               * access to the shared resources.
1207               */
1208             semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
1209                                     EDMA3_OSSEM_NO_TIMEOUT);
1210             if (EDMA3_RM_SOK == semResult)
1211                 {
1212                 switch (resObj->type)
1213                     {
1214                     case EDMA3_RM_RES_DMA_CHANNEL :
1215                             {
1216                             if (resId == EDMA3_RM_RES_ANY)
1217                                 {
1218                                 for (avlblIdx=0u;
1219                                      avlblIdx <
1220                                             rmObj->gblCfgParams.numDmaChannels;
1221                                      ++avlblIdx)
1222                                     {
1223                                     if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[avlblIdx/32u])
1224                                           &
1225                                           (rmInstance->avlblDmaChannels[avlblIdx/32u])
1226                                           &
1227                                           ~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[avlblIdx/32u])
1228                                           &
1229                                           (1u << (avlblIdx%32u))) != FALSE)
1230                                         {
1231                                         /*
1232                                          * Match found.
1233                                          * A resource which is owned by this instance of the
1234                                          * Resource Manager and which is presently available
1235                                          * and which has not been reserved - is found.
1236                                          */
1237                                         resObj->resId = avlblIdx;
1238                                         /*
1239                                          * Mark the 'match found' resource as "Not Available"
1240                                          * for future requests
1241                                          */
1242                                         rmInstance->avlblDmaChannels[avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
1244                                         /**
1245                                          * Check if the register modification flag is
1246                                          * set or not.
1247                                          */
1248                                         if (TRUE == rmInstance->regModificationRequired)
1249                                             {
1250                                             /**
1251                                              * Enable the DMA channel in the
1252                                              * DRAE/DRAEH registers also.
1253                                              */
1254                                             if (avlblIdx < 32u)
1255                                                 {
1256                                                 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1257                                                     |= (0x1u << avlblIdx);
1258                                                 }
1259                                             else
1260                                                 {
1261                                                 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1262                                                     |= (0x1u << (avlblIdx - 32u));
1263                                                 }
1264                                             }
1266                                         result = EDMA3_RM_SOK;
1267                                         break;
1268                                         }
1269                                     }
1270                                 /*
1271                                  * If none of the owned resources of this type is available
1272                                  * then report "All Resources of this type not available" error
1273                                  */
1274                                 if (avlblIdx == rmObj->gblCfgParams.numDmaChannels)
1275                                     {
1276                                     result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1277                                     }
1278                                 }
1279                             else
1280                                 {
1281                                 if (resId < rmObj->gblCfgParams.numDmaChannels)
1282                                     {
1283                                     /*
1284                                      * Check if specified resource is owned
1285                                      * by this instance of the resource manager
1286                                      */
1287                                     if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resId/32u])&(resIdSet))!=FALSE)
1288                                        {
1289                                         /* Now check if specified resource is available presently*/
1290                                         if (((rmInstance->avlblDmaChannels[resId/32u])&(resIdSet))!=FALSE)
1291                                             {
1292                                             /*
1293                                              * Mark the specified channel as "Not Available"
1294                                              * for future requests
1295                                              */
1296                                             rmInstance->avlblDmaChannels[resId/32u] &= resIdClr;
1298                                             /**
1299                                              * Check if the register modification flag is
1300                                              * set or not.
1301                                              */
1302                                             if (TRUE == rmInstance->regModificationRequired)
1303                                                 {
1304                                                 if (resId < 32u)
1305                                                     {
1306                                                     rmInstance->shadowRegs->EECR = (1UL << resId);
1308                                                     /**
1309                                                      * Enable the DMA channel in the
1310                                                      * DRAE registers also.
1311                                                      */
1312                                                     gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1313                                                         |= (0x1u << resId);
1314                                                     }
1315                                                 else
1316                                                     {
1317                                                     rmInstance->shadowRegs->EECRH = (1UL << resId);
1319                                                     /**
1320                                                      * Enable the DMA channel in the
1321                                                      * DRAEH registers also.
1322                                                      */
1323                                                     gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1324                                                         |= (0x1u << (resId - 32u));
1325                                                     }
1326                                                 }
1328                                             result = EDMA3_RM_SOK;
1329                                             }
1330                                         else
1331                                             {
1332                                             /* Specified resource is owned but is already booked */
1333                                             result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1334                                             }
1335                                         }
1336                                     else
1337                                         {
1338                                         /*
1339                                          * Specified resource is not owned by this instance
1340                                          * of the Resource Manager
1341                                          */
1342                                         result = EDMA3_RM_E_RES_NOT_OWNED;
1343                                         }
1344                                     }
1345                                 else
1346                                     {
1347                                     result = EDMA3_RM_E_INVALID_PARAM;
1348                                     }
1349                                 }
1350                         }
1351                         break;
1353                     case EDMA3_RM_RES_QDMA_CHANNEL :
1354                         {
1355                         if (resId == EDMA3_RM_RES_ANY)
1356                             {
1357                             for (avlblIdx=0u; avlblIdx<rmObj->gblCfgParams.numQdmaChannels; ++avlblIdx)
1358                                 {
1359                                 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[avlblIdx/32u])
1360                                           &
1361                                           (rmInstance->avlblQdmaChannels[avlblIdx/32u])
1362                                           &
1363                                           ~(rmInstance->initParam.rmInstInitConfig->resvdQdmaChannels[avlblIdx/32u])
1364                                           &
1365                                           (1u << (avlblIdx%32u))) != FALSE)
1366                                     {
1367                                     resObj->resId = avlblIdx;
1368                                     rmInstance->avlblQdmaChannels[avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
1370                                     /**
1371                                      * Check if the register modification flag is
1372                                      * set or not.
1373                                      */
1374                                     if (TRUE == rmInstance->regModificationRequired)
1375                                         {
1376                                         /**
1377                                          * Enable the QDMA channel in the
1378                                          * QRAE register also.
1379                                          */
1380                                         gblRegs->QRAE[rmInstance->initParam.regionId]
1381                                             |= (0x1u << avlblIdx);
1382                                         }
1384                                     result = EDMA3_RM_SOK;
1385                                     break;
1386                                     }
1387                                 }
1388                             /*
1389                              * If none of the owned resources of this type is available
1390                              * then report "All Resources of this type not available" error
1391                              */
1392                             if (avlblIdx == rmObj->gblCfgParams.numQdmaChannels)
1393                                 {
1394                                 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1395                                 }
1396                             }
1397                         else
1398                             {
1399                             if (resId < rmObj->gblCfgParams.numQdmaChannels)
1400                                 {
1401                                 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32u])&(resIdSet))!=FALSE)
1402                                     {
1403                                     if (((rmInstance->avlblQdmaChannels [resId/32u])&(resIdSet))!=FALSE)
1404                                         {
1405                                         rmInstance->avlblQdmaChannels [resId/32u] &= resIdClr;
1407                                         /**
1408                                          * Check if the register modification flag is
1409                                          * set or not.
1410                                          */
1411                                         if (TRUE == rmInstance->regModificationRequired)
1412                                             {
1413                                             /**
1414                                              * Enable the QDMA channel in the
1415                                              * QRAE register also.
1416                                              */
1417                                             gblRegs->QRAE[rmInstance->initParam.regionId]
1418                                                 |= (0x1u << resId);
1419                                             }
1421                                         result = EDMA3_RM_SOK;
1422                                         }
1423                                     else
1424                                         {
1425                                         /* Specified resource is owned but is already booked */
1426                                         result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1427                                        }
1428                                     }
1429                                 else
1430                                     {
1431                                     /*
1432                                      * Specified resource is not owned by this instance
1433                                      * of the Resource Manager
1434                                      */
1435                                     result = EDMA3_RM_E_RES_NOT_OWNED;
1436                                     }
1437                                 }
1438                             else
1439                                 {
1440                                 result = EDMA3_RM_E_INVALID_PARAM;
1441                                 }
1442                             }
1443                         }
1444                         break;
1446                     case EDMA3_RM_RES_TCC :
1447                         {
1448                         if (resId == EDMA3_RM_RES_ANY)
1449                             {
1450                             for (avlblIdx=0u; avlblIdx<rmObj->gblCfgParams.numTccs; ++avlblIdx)
1451                                 {
1452                                 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [avlblIdx/32u])
1453                                     & (rmInstance->avlblTccs [avlblIdx/32u])
1454                                     & ~(rmInstance->initParam.rmInstInitConfig->resvdTccs [avlblIdx/32u])
1455                                     & (1u << (avlblIdx%32u)))!=FALSE)
1456                                     {
1457                                     resObj->resId = avlblIdx;
1458                                     rmInstance->avlblTccs [avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
1460                                     /**
1461                                      * Check if the register modification flag is
1462                                      * set or not.
1463                                      */
1464                                     if (TRUE == rmInstance->regModificationRequired)
1465                                         {
1466                                         /**
1467                                          * Enable the Interrupt channel in the
1468                                          * DRAE/DRAEH registers also.
1469                                          * Also, If the region id coming from this
1470                                          * RM instance is same as the Master RM
1471                                          * Instance's region id, only then we will be
1472                                          * getting the interrupts on the same side.
1473                                          * So save the TCC in the allocatedTCCs[] array.
1474                                          */
1475                                         if (avlblIdx < 32u)
1476                                             {
1477                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1478                                                 |= (0x1u << avlblIdx);
1480                                             /**
1481                                              * Do not modify this global array if the register
1482                                              * modificatio flag is not set.
1483                                              * Reason being is based on this flag, the IPR/ICR
1484                                              * or error bit is cleared in the completion or
1485                                              * error handler ISR.
1486                                              */
1487                                             if (edma3RegionId == rmInstance->initParam.regionId)
1488                                                 {
1489                                                 allocatedTCCs[0u] |= (0x1u << avlblIdx);
1490                                                 }
1491                                             }
1492                                         else
1493                                             {
1494                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1495                                                 |= (0x1u << (avlblIdx - 32u));
1497                                             /**
1498                                              * Do not modify this global array if the register
1499                                              * modificatio flag is not set.
1500                                              * Reason being is based on this flag, the IPR/ICR
1501                                              * or error bit is cleared in the completion or
1502                                              * error handler ISR.
1503                                              */
1504                                             if (edma3RegionId == rmInstance->initParam.regionId)
1505                                                 {
1506                                                 allocatedTCCs[1u] |= (0x1u << (avlblIdx - 32u));
1507                                                 }
1508                                             }
1509                                         }
1512                                     result = EDMA3_RM_SOK;
1513                                     break;
1514                                     }
1515                                 }
1516                             /*
1517                              * If none of the owned resources of this type is available
1518                              * then report "All Resources of this type not available" error
1519                              */
1520                             if ( avlblIdx == rmObj->gblCfgParams.numTccs)
1521                                 {
1522                                 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1523                                 }
1524                             }
1525                         else
1526                             {
1527                             if (resId < rmObj->gblCfgParams.numTccs)
1528                                 {
1529                                 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32u])&(resIdSet))!=FALSE)
1530                                     {
1531                                     if (((rmInstance->avlblTccs [resId/32u])&(resIdSet))!=FALSE)
1532                                         {
1533                                         rmInstance->avlblTccs [resId/32u] &= resIdClr;
1535                                         /**
1536                                          * Check if the register modification flag is
1537                                          * set or not.
1538                                          */
1539                                         if (TRUE == rmInstance->regModificationRequired)
1540                                             {
1541                                             /**
1542                                              * Enable the Interrupt channel in the
1543                                              * DRAE/DRAEH registers also.
1544                                              * Also, If the region id coming from this
1545                                              * RM instance is same as the Master RM
1546                                              * Instance's region id, only then we will be
1547                                              * getting the interrupts on the same side.
1548                                              * So save the TCC in the allocatedTCCs[] array.
1549                                              */
1550                                             if (resId < 32u)
1551                                                 {
1552                                                 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1553                                                     |= (0x1u << resId);
1555                                                 /**
1556                                                  * Do not modify this global array if the register
1557                                                  * modificatio flag is not set.
1558                                                  * Reason being is based on this flag, the IPR/ICR
1559                                                  * or error bit is cleared in the completion or
1560                                                  * error handler ISR.
1561                                                  */
1562                                                 if (edma3RegionId == rmInstance->initParam.regionId)
1563                                                     {
1564                                                     allocatedTCCs[0u] |= (0x1u << resId);
1565                                                     }
1566                                                 }
1567                                             else
1568                                                 {
1569                                                 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1570                                                     |= (0x1u << (resId - 32u));
1572                                                 /**
1573                                                  * Do not modify this global array if the register
1574                                                  * modificatio flag is not set.
1575                                                  * Reason being is based on this flag, the IPR/ICR
1576                                                  * or error bit is cleared in the completion or
1577                                                  * error handler ISR.
1578                                                  */
1579                                                 if (edma3RegionId == rmInstance->initParam.regionId)
1580                                                     {
1581                                                     allocatedTCCs[1u] |= (0x1u << (resId - 32u));
1582                                                     }
1583                                                 }
1584                                             }
1586                                         result = EDMA3_RM_SOK;
1587                                         }
1588                                     else
1589                                         {
1590                                         /* Specified resource is owned but is already booked */
1591                                         result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1592                                         }
1593                                     }
1594                                 else
1595                                     {
1596                                     /*
1597                                      * Specified resource is not owned by this instance
1598                                      * of the Resource Manager
1599                                      */
1600                                     result = EDMA3_RM_E_RES_NOT_OWNED;
1601                                     }
1602                                 }
1603                             else
1604                                 {
1605                                 result = EDMA3_RM_E_INVALID_PARAM;
1606                                 }
1607                             }
1608                         }
1609                         break;
1611                     case EDMA3_RM_RES_PARAM_SET :
1612                         {
1613                         if (resId == EDMA3_RM_RES_ANY)
1614                             {
1615                             for (avlblIdx=0u; avlblIdx<rmObj->gblCfgParams.numPaRAMSets; ++avlblIdx)
1616                                 {
1617                                 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [avlblIdx/32u])
1618                                       &
1619                                       (rmInstance->avlblPaRAMSets [avlblIdx/32u])
1620                                       &
1621                                       ~(rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets [avlblIdx/32u])
1622                                       &
1623                                       (1u << (avlblIdx%32u)))!=FALSE)
1624                                     {
1625                                     resObj->resId = avlblIdx;
1626                                     rmInstance->avlblPaRAMSets [avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
1628                                     /**
1629                                      * Also, make the actual PARAM Set NULL, checking the flag
1630                                      * whether it is required or not.
1631                                      */
1632                                     if ((TRUE == rmInstance->regModificationRequired)
1633                                         && (TRUE == rmInstance->paramInitRequired))
1634                                         {
1635                                         edma3MemZero((void *)(&gblRegs->PARAMENTRY[avlblIdx]),
1636                                                     sizeof(gblRegs->PARAMENTRY[avlblIdx]));
1637                                         }
1639                                     result = EDMA3_RM_SOK;
1640                                     break;
1641                                     }
1642                                 }
1643                             /*
1644                              * If none of the owned resources of this type is available
1645                              * then report "All Resources of this type not available" error
1646                              */
1647                             if ( avlblIdx == rmObj->gblCfgParams.numPaRAMSets)
1648                                 {
1649                                 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1650                                 }
1651                             }
1652                         else
1653                             {
1654                             if (resId < rmObj->gblCfgParams.numPaRAMSets)
1655                                 {
1656                                 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32u])&(resIdSet))!=FALSE)
1657                                     {
1658                                     if (((rmInstance->avlblPaRAMSets [resId/32u])&(resIdSet)) !=FALSE)
1659                                         {
1660                                         rmInstance->avlblPaRAMSets [resId/32u] &= resIdClr;
1662                                         /**
1663                                          * Also, make the actual PARAM Set NULL, checking the flag
1664                                          * whether it is required or not.
1665                                          */
1666                                         if ((TRUE == rmInstance->regModificationRequired)
1667                                             && (TRUE == rmInstance->paramInitRequired))
1668                                             {
1669                                             edma3MemZero((void *)(&gblRegs->PARAMENTRY[resId]),
1670                                                         sizeof(gblRegs->PARAMENTRY[resId]));
1671                                             }
1673                                         result = EDMA3_RM_SOK;
1674                                         }
1675                                     else
1676                                         {
1677                                         /* Specified resource is owned but is already booked */
1678                                         result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1679                                         }
1680                                     }
1681                                 else
1682                                     {
1683                                     /*
1684                                      * Specified resource is not owned by this instance
1685                                      * of the Resource Manager
1686                                      */
1687                                     result = EDMA3_RM_E_RES_NOT_OWNED;
1688                                     }
1689                                 }
1690                             else
1691                                 {
1692                                 result = EDMA3_RM_E_INVALID_PARAM;
1693                                 }
1694                             }
1695                         }
1696                         break;
1698                     default:
1699                             result = EDMA3_RM_E_INVALID_PARAM;
1700                         break;
1701                     }
1703                 /* Return the semaphore back */
1704                 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
1705                 }
1706             }
1707         }
1709     /**
1710      * Check the Resource Allocation Result 'result' first. If Resource
1711      * Allocation has resulted in an error, return it (having more priority than
1712      * semResult.
1713      * Else, return semResult.
1714      */
1715      if (EDMA3_RM_SOK == result)
1716          {
1717          /**
1718           * Resource Allocation successful, return semResult for returning
1719           * semaphore.
1720           */
1721          result = semResult;
1722          }
1724 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1725     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1726                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1727                 EDMA3_DVT_dCOUNTER,
1728                 EDMA3_DVT_dNONE,
1729                 EDMA3_DVT_dNONE));
1730 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1732     return result;
1733     }
1737 /**\fn      EDMA3_RM_Result EDMA3_RM_freeResource(EDMA3_RM_Handle hEdmaResMgr,
1738  *                            const EDMA3_RM_ResDesc *resObj)
1739  * \brief   This API is used to free previously allocated EDMA3 Resources like
1740  * DMA/QDMA channel, PaRAM Set or TCC.
1741  *
1742  * To free a specific resource, first this API checks whether that resource is
1743  * OWNED by the Resource Manager Instance. Then it checks whether that resource
1744  * has been allocated by the Resource Manager instance or not.
1745  *
1746  * After freeing a DMA/QDMA channel or TCC, the same resource is disabled in
1747  * the shadow region specific register (DRAE/DRAEH/QRAE).
1748  *
1749  * \param  hEdmaResMgr         [IN]    Handle to the previously opened Resource
1750  *                                     Manager Instance.
1751  * \param   resObj             [IN]    Handle to the resource descriptor
1752  *                                     object, which needs to be freed.
1753  *
1754  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
1755  *
1756  * \note    This function disables the global interrupts to prevent
1757  *          simultaneous access to the global pool of resources.
1758  *          It is re-entrant.
1759  */
1760 EDMA3_RM_Result EDMA3_RM_freeResource(EDMA3_RM_Handle hEdmaResMgr,
1761                             const EDMA3_RM_ResDesc *resObj)
1762     {
1763     unsigned int intState;
1764     EDMA3_RM_Instance *rmInstance = NULL;
1765     EDMA3_RM_Obj *rmObj = NULL;
1766     EDMA3_RM_Result result = EDMA3_RM_SOK;
1767     unsigned int resId;
1768     unsigned int resIdSet = 0x0;
1769     volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1771 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1772     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1773                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1774                 EDMA3_DVT_dCOUNTER,
1775                 EDMA3_DVT_dNONE,
1776                 EDMA3_DVT_dNONE));
1777 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1779         /* If parameter checking is enabled... */
1780 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1781     if ((hEdmaResMgr == NULL) || (resObj == NULL))
1782         {
1783         result = EDMA3_RM_E_INVALID_PARAM;
1784         }
1785 #endif
1787         /* Check if the parameters are OK. */
1788         if (EDMA3_RM_SOK == result)
1789         {
1790         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1791         rmObj = rmInstance->pResMgrObjHandle;
1793         if ((rmObj == NULL) ||
1794             (rmObj->gblCfgParams.globalRegs == NULL))
1795             {
1796             result = EDMA3_RM_E_INVALID_PARAM;
1797             }
1798         else
1799             {
1800             gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1802             resId = resObj->resId;
1804             resIdSet = 1u << (resId%32u);
1806             edma3OsProtectEntry (rmObj->phyCtrllerInstId,
1807                                                                 EDMA3_OS_PROTECT_INTERRUPT,
1808                                                                 &intState);
1810             if (EDMA3_RM_SOK == result)
1811                 {
1812                 switch (resObj->type)
1813                     {
1814                     case EDMA3_RM_RES_DMA_CHANNEL :
1815                         {
1816                         if (resId < rmObj->gblCfgParams.numDmaChannels)
1817                             {
1818                             if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels [resId/32u]) & (resIdSet))!=FALSE)
1819                                 {
1820                                 if (((~(rmInstance->avlblDmaChannels[resId/32u]))&(resIdSet))!=FALSE)
1821                                     {
1822                                     /*
1823                                      * Mark the specified channel as "Available"
1824                                      * for future requests
1825                                      */
1826                                     rmInstance->avlblDmaChannels[resId/32u] |= resIdSet;
1828                                     /**
1829                                      * Check if the register modification flag is
1830                                      * set or not.
1831                                      */
1832                                     if (TRUE == rmInstance->regModificationRequired)
1833                                         {
1834                                         /**
1835                                          * DMA Channel is freed.
1836                                          * Reset the bit specific to the DMA channel
1837                                          * in the DRAE/DRAEH register also.
1838                                          */
1839                                         if (resId < 32u)
1840                                             {
1841                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1842                                                             &= (~(0x1u << resId));
1843                                             }
1844                                         else
1845                                             {
1846                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1847                                                             &= (~(0x1u << (resId-32u)));
1848                                             }
1849                                         }
1851                                     result = EDMA3_RM_SOK;
1852                                     }
1853                                 else
1854                                     {
1855                                     result = EDMA3_RM_E_RES_ALREADY_FREE;
1856                                     }
1857                                 }
1858                             else
1859                                 {
1860                                 /*
1861                                  * Specified resource is not owned by this instance
1862                                  * of the Resource Manager
1863                                  */
1864                                 result = EDMA3_RM_E_RES_NOT_OWNED;
1865                                 }
1866                             }
1867                         else
1868                             {
1869                             result = EDMA3_RM_E_INVALID_PARAM;
1870                             }
1871                         }
1872                         break;
1874                     case EDMA3_RM_RES_QDMA_CHANNEL :
1875                         {
1876                         if (resId < rmObj->gblCfgParams.numQdmaChannels)
1877                             {
1878                             if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32u]) & (resIdSet))!=FALSE)
1879                                 {
1880                                 if (((~(rmInstance->avlblQdmaChannels [resId/32u])) & (resIdSet))!=FALSE)
1881                                     {
1882                                     rmInstance->avlblQdmaChannels [resId/32u] |= resIdSet;
1884                                     /**
1885                                      * Check if the register modification flag is
1886                                      * set or not.
1887                                      */
1888                                     if (TRUE == rmInstance->regModificationRequired)
1889                                         {
1890                                         /**
1891                                          * QDMA Channel is freed.
1892                                          * Reset the bit specific to the QDMA channel
1893                                          * in the QRAE register also.
1894                                          */
1895                                         gblRegs->QRAE[rmInstance->initParam.regionId]
1896                                                         &= (~(0x1u << resId));
1897                                         }
1899                                     result = EDMA3_RM_SOK;
1900                                     }
1901                                 else
1902                                     {
1903                                     result = EDMA3_RM_E_RES_ALREADY_FREE;
1904                                     }
1905                                 }
1906                             else
1907                                 {
1908                                 /*
1909                                  * Specified resource is not owned by this instance
1910                                  * of the Resource Manager
1911                                  */
1912                                 result = EDMA3_RM_E_RES_NOT_OWNED;
1913                                 }
1914                             }
1915                         else
1916                             {
1917                             result = EDMA3_RM_E_INVALID_PARAM;
1918                             }
1919                         }
1920                         break;
1922                     case EDMA3_RM_RES_TCC :
1923                         {
1924                         if (resId < rmObj->gblCfgParams.numTccs)
1925                             {
1926                             if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32u]) & (resIdSet))!=FALSE)
1927                                 {
1928                                 if (((~(rmInstance->avlblTccs [resId/32u])) & (resIdSet))!=FALSE)
1929                                     {
1930                                     rmInstance->avlblTccs [resId/32u] |= resIdSet;
1932                                     /**
1933                                      * Check if the register modification flag is
1934                                      * set or not.
1935                                      */
1936                                     if (TRUE == rmInstance->regModificationRequired)
1937                                         {
1938                                         /**
1939                                          * Interrupt Channel is freed.
1940                                          * Reset the bit specific to the Interrupt
1941                                          * channel in the DRAE/DRAEH register also.
1942                                          * Also, if we have earlier saved this
1943                                          * TCC in allocatedTCCs[] array,
1944                                          * remove it from there too.
1945                                          */
1946                                         if (resId < 32u)
1947                                             {
1948                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1949                                                             &= (~(0x1u << resId));
1951                                             if (edma3RegionId == rmInstance->initParam.regionId)
1952                                                 {
1953                                                 allocatedTCCs[0u] &= (~(0x1u << resId));
1954                                                 }
1955                                             }
1956                                         else
1957                                             {
1958                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1959                                                             &= (~(0x1u << (resId-32u)));
1961                                             if (edma3RegionId == rmInstance->initParam.regionId)
1962                                                 {
1963                                                 allocatedTCCs[1u] &= (~(0x1u << (resId -32u)));
1964                                                 }
1965                                             }
1966                                         }
1968                                     result = EDMA3_RM_SOK;
1969                                     }
1970                                 else
1971                                     {
1972                                     result = EDMA3_RM_E_RES_ALREADY_FREE;
1973                                     }
1974                                 }
1975                             else
1976                                 {
1977                                 /*
1978                                  * Specified resource is not owned by this instance
1979                                  * of the Resource Manager
1980                                  */
1981                                 result = EDMA3_RM_E_RES_NOT_OWNED;
1982                                 }
1983                             }
1984                         else
1985                             {
1986                             result = EDMA3_RM_E_INVALID_PARAM;
1987                             }
1988                         }
1989                         break;
1991                     case EDMA3_RM_RES_PARAM_SET :
1992                         {
1993                         if (resId < rmObj->gblCfgParams.numPaRAMSets)
1994                             {
1995                             if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32u])&(resIdSet))!=FALSE)
1996                                 {
1997                                 if (((~(rmInstance->avlblPaRAMSets [resId/32u]))&(resIdSet))!=FALSE)
1998                                     {
1999                                     rmInstance->avlblPaRAMSets [resId/32u] |= resIdSet;
2001                                     result = EDMA3_RM_SOK;
2002                                     }
2003                                 else
2004                                     {
2005                                     result = EDMA3_RM_E_RES_ALREADY_FREE;
2006                                     }
2007                                 }
2008                             else
2009                                 {
2010                                 /*
2011                                  * Specified resource is not owned by this instance
2012                                  * of the Resource Manager
2013                                  */
2014                                 result = EDMA3_RM_E_RES_NOT_OWNED;
2015                                 }
2016                             }
2017                         else
2018                             {
2019                             result = EDMA3_RM_E_INVALID_PARAM;
2020                             }
2021                         }
2022                         break;
2024                     default:
2025                         result = EDMA3_RM_E_INVALID_PARAM;
2026                         break;
2027                     }
2029                 }
2031             edma3OsProtectExit (rmObj->phyCtrllerInstId,
2032                                                                 EDMA3_OS_PROTECT_INTERRUPT,
2033                                                                 intState);
2034             }
2035         }
2037 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2038     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2039                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2040                 EDMA3_DVT_dCOUNTER,
2041                 EDMA3_DVT_dNONE,
2042                 EDMA3_DVT_dNONE));
2043 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2045     return result;
2046     }
2050 /**
2051  * \fn      EDMA3_RM_Result EDMA3_RM_allocLogicalChannel(EDMA3_RM_Handle
2052  *                   hEdmaResMgr, EDMA3_RM_ResDesc *lChObj,
2053  *                   unsigned int *pParam, unsigned int *pTcc)
2054  * \brief   Request a DMA/QDMA/Link channel.
2055  *
2056  * This API is used to allocate a logical channel (DMA/QDMA/Link) along with
2057  * the associated resources. For DMA and QDMA channels, TCC and PaRAM Set are
2058  * also allocated along with the requested channel. For Link channel, ONLY a
2059  * PaRAM Set is allocated.
2060  *
2061  * Note: To free the logical channel allocated by this API, user should call
2062  * EDMA3_RM_freeLogicalChannel () ONLY to de-allocate all the allocated resources
2063  * and remove certain mappings.
2064  *
2065  * User can request a specific logical channel by passing the channel id in
2066  * 'lChObj->resId' and channel type in 'lChObj->type'. Note that the channel
2067  * id is the same as the actual resource id. For e.g. in the case of QDMA
2068  * channels, valid channel ids are from 0 to 7 only.
2069  *
2070  * User can also request ANY available logical channel of the type
2071  * 'lChObj->type' by specifying 'lChObj->resId' as:
2072  *  a)  EDMA3_RM_DMA_CHANNEL_ANY: For DMA channels
2073  *  b)  EDMA3_RM_QDMA_CHANNEL_ANY: For QDMA channels, and
2074  *  c)  EDMA3_RM_PARAM_ANY: For Link channels. Normally user should use this
2075  *      value to request link channels (PaRAM Sets used for linking purpose
2076  *      only), unless he wants to use some specific link channels (PaRAM Sets)
2077  *      which is also allowed.
2078  *
2079  * This API internally uses EDMA3_RM_allocResource () to allocate the desired
2080  * resources (DMA/QDMA channel, PaRAM Set and TCC).
2081  *
2082  * For DMA/QDMA channels, after allocating all the EDMA3 resources, this API
2083  * sets the TCC field of the OPT PaRAM Word with the allocated TCC.
2084  *
2085  * For DMA channel, it also sets the DCHMAP register, if required.
2086  *
2087  * For QDMA channel, it sets the QCHMAP register and CCNT as trigger word and
2088  * enables the QDMA channel by writing to the QEESR register.
2089  *
2090  * \param  hEdmaResMgr      [IN]        Handle to the previously opened Resource
2091  *                                      Manager Instance.
2092  * \param  lChObj           [IN/OUT]    Handle to the requested logical channel
2093  *                                      object, which needs to be allocated.
2094  *                                      It could be a specific logical channel
2095  *                                      or ANY available logical channel of the
2096  *                                      requested type.
2097  *                                      In case user passes a specific resource
2098  *                                      Id, lChObj value is left unchanged. In
2099  *                                      case user requests ANY available
2100  *                                      resource, the allocated resource id is
2101  *                                      returned in lChObj->resId.
2102  *
2103  *  \param  pParam          [IN/OUT]    PaRAM Set for a particular logical
2104  *                                      (DMA/QDMA) channel. Not used if user
2105  *                                      requested for a Link channel.
2106  *                                      In case user passes a specific PaRAM
2107  *                                      Set value, pParam value is left
2108  *                                      unchanged. In case user requests ANY
2109  *                                      available PaRAM Set, the allocated one
2110  *                                      is returned in pParam.
2111  *
2112  *  \param  pTcc            [IN/OUT]    TCC for a particular logical (DMA/QDMA)
2113  *                                      channel. Not used if user requested for
2114  *                                      a Link channel.
2115  *                                      In case user passes a specific TCC
2116  *                                      value, pTcc value is left unchanged.
2117  *                                      In case user requests ANY available TCC,
2118  *                                      the allocated one is returned in pTcc
2119  *
2120  * \return  EDMA3_RM_SOK or EDMA_RM Error Code
2121  *
2122  * \note    This function internally calls EDMA3_RM_allocResource (), which
2123  *          acquires a RM Instance specific semaphore to prevent simultaneous
2124  *          access to the global pool of resources. It is re-entrant for unique
2125  *          logical channel values, but SHOULD NOT be called from the user
2126  *          callback function (ISR context).
2127  */
2128 EDMA3_RM_Result EDMA3_RM_allocLogicalChannel(EDMA3_RM_Handle hEdmaResMgr,
2129                             EDMA3_RM_ResDesc *lChObj,
2130                             unsigned int *pParam,
2131                             unsigned int *pTcc)
2132     {
2133     EDMA3_RM_ResDesc *chObj;
2134     EDMA3_RM_ResDesc resObj;
2135     EDMA3_RM_Result result = EDMA3_RM_SOK;
2136     EDMA3_RM_Instance *rmInstance = NULL;
2137     EDMA3_RM_Obj *rmObj = NULL;
2138     unsigned int mappedPaRAMId=0u;
2139     unsigned int mappedTcc = EDMA3_RM_CH_NO_TCC_MAP;
2140     int paRAMId = (int)EDMA3_RM_RES_ANY;
2141     volatile EDMA3_CCRL_Regs *gblRegs = NULL;
2142     unsigned int qdmaChId = EDMA3_MAX_PARAM_SETS;
2143         unsigned int edma3Id;
2145 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2146     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2147                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2148                 EDMA3_DVT_dCOUNTER,
2149                 EDMA3_DVT_dNONE,
2150                 EDMA3_DVT_dNONE));
2151 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2153         /* If parameter checking is enabled... */
2154 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2155     if ((lChObj == NULL) || (hEdmaResMgr == NULL))
2156         {
2157         result = EDMA3_RM_E_INVALID_PARAM;
2158         }
2159 #endif
2161         /* Check if the parameters are OK. */
2162         if (EDMA3_RM_SOK == result)
2163         {
2164         chObj = lChObj;
2166         if ((chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
2167             || (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL))
2168             {
2169             /**
2170              * If the request is for a DMA or QDMA channel, check the
2171              * pParam and pTcc objects also.
2172              * For the Link channel request, they could be NULL.
2173              */
2174                         /* If parameter checking is enabled... */
2175 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2176             if ((pParam == NULL) || (pTcc == NULL))
2177                 {
2178                 result = EDMA3_RM_E_INVALID_PARAM;
2179                 }
2180 #endif
2181             }
2182         }
2184     if (result == EDMA3_RM_SOK)
2185         {
2186         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2188         if (rmInstance == NULL)
2189             {
2190             result = EDMA3_RM_E_INVALID_PARAM;
2191             }
2192         }
2194     if (result == EDMA3_RM_SOK)
2195         {
2196         rmObj = rmInstance->pResMgrObjHandle;
2198         if (rmObj == NULL)
2199             {
2200             result = EDMA3_RM_E_INVALID_PARAM;
2201             }
2202         else
2203             {
2204             if (rmObj->gblCfgParams.globalRegs == NULL)
2205                 {
2206                 result = EDMA3_RM_E_INVALID_PARAM;
2207                 }
2208             }
2209         }
2211     if (result == EDMA3_RM_SOK)
2212         {
2213         edma3Id = rmObj->phyCtrllerInstId;
2214         gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2216         switch (chObj->type)
2217             {
2218             case EDMA3_RM_RES_DMA_CHANNEL:
2219                 {
2220                 if ((chObj->resId == EDMA3_RM_DMA_CHANNEL_ANY)
2221                     || (chObj->resId == EDMA3_RM_RES_ANY))
2222                     {
2223                     /* Request for ANY DMA channel. */
2224                     resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2225                     resObj.resId = EDMA3_RM_RES_ANY;
2226                     result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2228                     if (result == EDMA3_RM_SOK)
2229                         {
2230                         /* DMA channel allocated successfully. */
2231                         chObj->resId = resObj.resId;
2233                         /**
2234                          * Check the PaRAM Set user has specified for this DMA channel.
2235                          * Two cases exist:
2236                          * a) DCHMAP exists: Any PaRAM Set can be used
2237                          * b) DCHMAP does not exist: Should not be possible
2238                          * only if the channel allocated (ANY) and PaRAM requested
2239                          * are same.
2240                          */
2241                         if ((*pParam) == EDMA3_RM_PARAM_ANY)
2242                             {
2243                             /* User specified ANY PaRAM Set; Check the mapping. */
2244                             mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2245                             if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2246                                 {
2247                                 /** If some PaRAM set is statically mapped to the returned
2248                                 * channel number, use that.
2249                                 */
2250                                 paRAMId = (int)mappedPaRAMId;
2251                                 }
2252                             }
2253                         else
2254                             {
2255                             /* User specified some PaRAM Set; check that can be used or not. */
2256                             if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2257                                 {
2258                                 paRAMId = (int)(*pParam);
2259                                 }
2260                             else
2261                                 {
2262                                 /**
2263                                  * Channel mapping does not exist. If the PaRAM Set requested
2264                                  * is the same as dma channel allocated (coincidentally), it is fine.
2265                                  * Else return error.
2266                                  */
2267                                 if ((*pParam) != (resObj.resId))
2268                                     {
2269                                     result = EDMA3_RM_E_INVALID_PARAM;
2271                                     /**
2272                                      * Free the previously allocated DMA channel also.
2273                                      */
2274                                     EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2275                                     }
2276                                 else
2277                                     {
2278                                     paRAMId = (int)(*pParam);
2279                                     }
2280                                 }
2281                             }
2283                         mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[resObj.resId];
2284                         }
2285                     }
2286                 else
2287                     {
2288                     if (chObj->resId <= edma3_dma_ch_max_val[edma3Id])
2289                         {
2290                         /* Request for a specific DMA channel */
2291                         resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2292                         resObj.resId = chObj->resId;
2293                         result = EDMA3_RM_allocResource(hEdmaResMgr,
2294                                         (EDMA3_RM_ResDesc *)&resObj);
2296                         if (result == EDMA3_RM_SOK)
2297                             {
2298                             /**
2299                              * Check the PaRAM Set user has specified for this DMA channel.
2300                              * Two cases exist:
2301                              * a) DCHMAP exists: Any PaRAM Set can be used
2302                              * b) DCHMAP does not exist: Should not be possible
2303                              * only if the channel allocated (ANY) and PaRAM requested
2304                              * are same.
2305                              */
2306                             if ((*pParam) == EDMA3_RM_PARAM_ANY)
2307                                 {
2308                                 /* User specified ANY PaRAM Set; Check the mapping. */
2309                                 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2310                                 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2311                                     {
2312                                     /** If some PaRAM set is statically mapped to the returned
2313                                     * channel number, use that.
2314                                     */
2315                                     paRAMId = (int)mappedPaRAMId;
2316                                     }
2317                                 }
2318                             else
2319                                 {
2320                                 /* User specified some PaRAM Set; check that can be used or not. */
2321                                 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2322                                     {
2323                                     paRAMId = (int)(*pParam);
2324                                     }
2325                                 else
2326                                     {
2327                                     /**
2328                                      * Channel mapping does not exist. If the PaRAM Set requested
2329                                      * is the same as dma channel allocated (coincidentally), it is fine.
2330                                      * Else return error.
2331                                      */
2332                                     if ((*pParam) != (resObj.resId))
2333                                         {
2334                                         result = EDMA3_RM_E_INVALID_PARAM;
2336                                         /**
2337                                          * Free the previously allocated DMA channel also.
2338                                          */
2339                                         EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2340                                         }
2341                                     else
2342                                         {
2343                                         paRAMId = (int)(*pParam);
2344                                         }
2345                                     }
2346                                 }
2348                             mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[chObj->resId];
2349                             }
2350                         }
2351                     else
2352                         {
2353                         result = EDMA3_RM_E_INVALID_PARAM;
2354                         }
2355                     }
2356                 }
2357                 break;
2360             case EDMA3_RM_RES_QDMA_CHANNEL:
2361                 {
2362                 if ((chObj->resId == EDMA3_RM_QDMA_CHANNEL_ANY)
2363                     || (chObj->resId == EDMA3_RM_RES_ANY))
2364                     {
2365                     /* First request for any available QDMA channel */
2366                     resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2367                     resObj.resId = EDMA3_RM_RES_ANY;
2368                     result = EDMA3_RM_allocResource(hEdmaResMgr,
2369                                     (EDMA3_RM_ResDesc *)&resObj);
2371                     if (result == EDMA3_RM_SOK)
2372                         {
2373                         /* Return the actual QDMA channel id. */
2374                         chObj->resId = resObj.resId;
2376                         /* Save the Logical-QDMA channel id for future use. */
2377                         qdmaChId = resObj.resId + edma3_qdma_ch_min_val[edma3Id];
2379                         /**
2380                          * Check the PaRAM Set user has specified for this QDMA channel.
2381                          * If he has specified any particular PaRAM Set, use that.
2382                          */
2383                         if ((*pParam) != EDMA3_RM_PARAM_ANY)
2384                             {
2385                             /* User specified ANY PaRAM Set; Check the mapping. */
2386                             paRAMId = (int)(*pParam);
2387                             }
2388                         }
2389                     }
2390                 else
2391                     {
2392                     if (chObj->resId < rmObj->gblCfgParams.numQdmaChannels)
2393                         {
2394                         /* Request for a specific QDMA channel */
2395                         resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2396                         resObj.resId = chObj->resId;
2397                         result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2399                         if (result == EDMA3_RM_SOK)
2400                             {
2401                             /* Save the Logical-QDMA channel id for future use. */
2402                             qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
2404                             /**
2405                              * Check the PaRAM Set user has specified for this QDMA channel.
2406                              * If he has specified any particular PaRAM Set, use that.
2407                              */
2408                             if ((*pParam) != EDMA3_RM_PARAM_ANY)
2409                                 {
2410                                 /* User specified ANY PaRAM Set; Check the mapping. */
2411                                 paRAMId = (int)(*pParam);
2412                                 }
2413                             }
2414                         }
2415                     else
2416                         {
2417                         result = EDMA3_RM_E_INVALID_PARAM;
2418                         }
2419                     }
2420                 }
2421                 break;
2423             case EDMA3_RM_RES_PARAM_SET:
2424                     {
2425                     /* Request for a LINK channel. */
2426                     if ((chObj->resId == EDMA3_RM_PARAM_ANY)
2427                         || (chObj->resId == EDMA3_RM_RES_ANY))
2428                         {
2429                         /* Request for ANY LINK channel. */
2430                         paRAMId = (int)EDMA3_RM_RES_ANY;
2431                         }
2432                     else
2433                         {
2434                         if (chObj->resId < edma3NumPaRAMSets)
2435                             {
2436                             /* Request for a Specific LINK channel. */
2437                             paRAMId = (int)(chObj->resId);
2438                             }
2439                         else
2440                             {
2441                             result = EDMA3_RM_E_INVALID_PARAM;
2442                             }
2443                         }
2445                     if (result == EDMA3_RM_SOK)
2446                         {
2447                         /* Try to allocate the link channel */
2448                         resObj.type = EDMA3_RM_RES_PARAM_SET;
2449                         resObj.resId = (unsigned int)paRAMId;
2450                         result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2452                         if (result == EDMA3_RM_SOK)
2453                             {
2454                             unsigned int linkCh = edma3_link_ch_min_val[edma3Id];
2456                             /* Return the actual PaRAM Id. */
2457                             chObj->resId = resObj.resId;
2459                             /*
2460                             * Search for the next Link channel place-holder available,
2461                             * starting from EDMA3_RM_LINK_CH_MIN_VAL.
2462                             * It will be used for future operations on the Link channel.
2463                             */
2464                             while ((edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId != -1)
2465                                         && (linkCh <= edma3_link_ch_max_val[edma3Id]))
2466                                 {
2467                                 /* Move to the next place-holder. */
2468                                 linkCh++;
2469                                 }
2471                             /* Verify the returned handle, it should lie in the correct range */
2472                             if (linkCh > edma3_link_ch_max_val[edma3Id])
2473                                 {
2474                                 result = EDMA3_RM_E_INVALID_PARAM;
2476                                 /* Free the PaRAM Set now. */
2477                                 resObj.type = EDMA3_RM_RES_PARAM_SET;
2478                                 resObj.resId = chObj->resId;
2479                                 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2480                                 }
2481                             else
2482                                 {
2483                                 /* Save the PaRAM Id for the Link Channel. */
2484                                 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = (int)(chObj->resId);
2486                                 /**
2487                                  * Remove any linking. Before doing that, check
2488                                  * whether it is permitted or not.
2489                                  */
2490                                 if (TRUE == rmInstance->regModificationRequired)
2491                                     {
2492                                     *((&gblRegs->PARAMENTRY[chObj->resId].OPT)
2493                                             + (unsigned int)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2494                                     }
2495                                 }
2496                             }
2497                         }
2498                     }
2499                     break;
2501             default:
2502                     result = EDMA3_RM_E_INVALID_PARAM;
2503             }
2504         }
2507     if (result == EDMA3_RM_SOK)
2508         {
2509         /**
2510          * For DMA/QDMA channels, we still have to allocate more resources like
2511          * TCC, PaRAM Set etc.
2512          * For Link channel, only the PaRAMSet is required and that has been
2513          * allocated so no further operations required.
2514          */
2516         /* Further resources' allocation for DMA channel. */
2517         if (chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
2518             {
2519             /* First allocate a PaRAM Set */
2520             resObj.type = EDMA3_RM_RES_PARAM_SET;
2521             /* Use the saved param id now. */
2522             resObj.resId = (unsigned int)paRAMId;
2523             result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2524             if (result == EDMA3_RM_SOK)
2525                 {
2526                 /**
2527                  * PaRAM Set allocation succeeded.
2528                  * Save the PaRAM Set first.
2529                  */
2530                 *pParam = resObj.resId;
2531                 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = (int)(resObj.resId);
2533                 /* Allocate the TCC now. */
2534                 resObj.type = EDMA3_RM_RES_TCC;
2535                 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2536                     {
2537                     if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2538                         {
2539                         resObj.resId = EDMA3_RM_RES_ANY;
2540                         }
2541                     else
2542                         {
2543                         resObj.resId = mappedTcc;
2544                         }
2545                     }
2546                 else
2547                     {
2548                     resObj.resId = *pTcc;
2549                     }
2551                 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2552                 if (result == EDMA3_RM_SOK)
2553                     {
2554                      /* TCC allocation succeeded. Save it first. */
2555                     *pTcc = resObj.resId;
2556                      edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].tcc = resObj.resId;
2558                     /**
2559                      * Check first whether the global registers and the allocated
2560                      * PaRAM Set can be modified or not. If yes, do the needful.
2561                      * Else leave this for the user.
2562                      */
2563                     if (TRUE == rmInstance->regModificationRequired)
2564                         {
2565                         /* Set TCC of the allocated Param Set. */
2566                         gblRegs->PARAMENTRY[*pParam].OPT  &= EDMA3_RM_OPT_TCC_CLR_MASK;
2567                         gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2569                         /**
2570                          * Do the mapping between DMA channel and PaRAM Set.
2571                          * Do this for the EDMA3 Controllers which have a register for mapping
2572                          * DMA Channel to a particular PaRAM Set.
2573                          */
2574                         if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2575                             {
2576                             gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2578                             /* Map Parameter RAM Set Number for specified channelId */
2579                             gblRegs->DCHMAP[chObj->resId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
2580                             gblRegs->DCHMAP[chObj->resId] |= EDMA3_RM_DCH_PARAM_SET_MASK(*pParam);
2581                             }
2583                         /* Remove any linking */
2584                         *((&gblRegs->PARAMENTRY[*pParam].OPT)
2585                                 + (unsigned int)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2586                         }
2587                     }
2588                 else
2589                     {
2590                     /**
2591                      * TCC allocation failed, free the previously allocated
2592                      * PaRAM Set and DMA channel.
2593                      */
2594                     resObj.type = EDMA3_RM_RES_PARAM_SET;
2595                     resObj.resId = *pParam;
2596                     EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2598                     /* Reset the book-keeping data structure also. */
2599                     edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = -1;
2601                     resObj.type = chObj->type;
2602                     resObj.resId = chObj->resId;
2603                     EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2604                     }
2605                 }
2606             else
2607                 {
2608                 /**
2609                  * PaRAM Set allocation failed, free the previously allocated
2610                  * DMA channel also.
2611                  */
2612                 resObj.type = chObj->type;
2613                 resObj.resId = chObj->resId;
2614                 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2615                 }
2616             }
2619         /* Further resources' allocation for QDMA channel. */
2620         if (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
2621             {
2622             /* First allocate a PaRAM Set */
2623             resObj.type = EDMA3_RM_RES_PARAM_SET;
2624             /* Use the saved param id now. */
2625             resObj.resId = (unsigned int)paRAMId;
2626             result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2627             if (result == EDMA3_RM_SOK)
2628                 {
2629                 /**
2630                  * PaRAM Set allocation succeeded.
2631                  * Save the PaRAM Set first.
2632                  */
2633                 *pParam = resObj.resId;
2634                 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = (int)(resObj.resId);
2636                 /* Allocate the TCC now. */
2637                 resObj.type = EDMA3_RM_RES_TCC;
2638                 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2639                     {
2640                     if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2641                         {
2642                         resObj.resId = EDMA3_RM_RES_ANY;
2643                         }
2644                     else
2645                         {
2646                         resObj.resId = mappedTcc;
2647                         }
2648                     }
2649                 else
2650                     {
2651                     resObj.resId = *pTcc;
2652                     }
2654                 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2655                 if (result == EDMA3_RM_SOK)
2656                     {
2657                      /* TCC allocation succeeded. Save it first. */
2658                     *pTcc = resObj.resId;
2659                      edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = resObj.resId;
2661                     /**
2662                      * Check first whether the global registers and the allocated
2663                      * PaRAM Set can be modified or not. If yes, do the needful.
2664                      * Else leave this for the user.
2665                      */
2666                     if (TRUE == rmInstance->regModificationRequired)
2667                         {
2668                         /* Set TCC of the allocated Param Set. */
2669                         gblRegs->PARAMENTRY[*pParam].OPT  &= EDMA3_RM_OPT_TCC_CLR_MASK;
2670                         gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2672                         /* Do the mapping between QDMA channel and PaRAM Set. */
2673                         /* Map Parameter RAM Set Number for specified channelId */
2674                         gblRegs->QCHMAP[chObj->resId]
2675                                         &= EDMA3_RM_QCH_PARAM_CLR_MASK;
2676                         gblRegs->QCHMAP[chObj->resId]
2677                                         |= EDMA3_RM_QCH_PARAM_SET_MASK(*pParam);
2679                         /* Set the Trigger Word */
2680                         gblRegs->QCHMAP[chObj->resId]
2681                                         &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
2682                         gblRegs->QCHMAP[chObj->resId]
2683                                         |= EDMA3_RM_QCH_TRWORD_SET_MASK(EDMA3_RM_QDMA_TRIG_DEFAULT);
2685                         /* Remove any linking */
2686                         *((&gblRegs->PARAMENTRY[*pParam].OPT)
2687                                 + (unsigned int)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2689                         /* Enable the transfer also. */
2690                         rmInstance->shadowRegs->QEESR = (1u << chObj->resId);
2691                         }
2692                     }
2693                 else
2694                     {
2695                     /**
2696                      * TCC allocation failed, free the previously allocated
2697                      * PaRAM Set and QDMA channel.
2698                      */
2699                     resObj.type = EDMA3_RM_RES_PARAM_SET;
2700                     resObj.resId = *pParam;
2701                     EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2703                     /* Reset the book-keeping data structure also. */
2704                     edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
2706                     resObj.type = chObj->type;
2707                     resObj.resId = chObj->resId;
2708                     EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2709                     }
2710                 }
2711             else
2712                 {
2713                 /**
2714                  * PaRAM Set allocation failed, free the previously allocated
2715                  * QDMA channel also.
2716                  */
2717                 resObj.type = chObj->type;
2718                 resObj.resId = chObj->resId;
2719                 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2720                 }
2721             }
2722         }
2725 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2726     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2727                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2728                 EDMA3_DVT_dCOUNTER,
2729                 EDMA3_DVT_dNONE,
2730                 EDMA3_DVT_dNONE));
2731 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2734     return result;
2735     }
2738 /** \fn     EDMA3_RM_Result EDMA3_RM_freeLogicalChannel (EDMA3_RM_Handle
2739  *                       hEdmaResMgr, EDMA3_RM_ResDesc *lChObj)
2740  *  \brief  This API is used to free the specified channel (DMA/QDMA/Link) and
2741  *          its associated resources (PaRAM Set, TCC etc).
2742  *
2743  * This API internally uses EDMA3_RM_freeResource () to free the desired
2744  * resources.
2745  *
2746  * For DMA/QDMA channels, it also clears the DCHMAP/QCHMAP registers
2747  *
2748  * \param  hEdmaResMgr      [IN]    Handle to the previously opened Resource
2749  *                                  Manager Instance.
2750  * \param  lChObj           [IN]    Handle to the logical channel object,
2751  *                                  which needs to be freed
2752  *
2753  * \return  EDMA3_RM_SOK or EDMA_RM Error Code
2754  *
2755  * \note    This is a re-entrant function which internally calls
2756  *          EDMA3_RM_freeResource () for resource de-allocation.
2757  */
2758 EDMA3_RM_Result EDMA3_RM_freeLogicalChannel (EDMA3_RM_Handle hEdmaResMgr,
2759                                                 EDMA3_RM_ResDesc *lChObj)
2760     {
2761     EDMA3_RM_ResDesc *chObj;
2762     EDMA3_RM_ResDesc resObj;
2763     EDMA3_RM_Result result = EDMA3_RM_SOK;
2764     EDMA3_RM_Instance *rmInstance = NULL;
2765     EDMA3_RM_Obj *rmObj = NULL;
2766     int paRAMId;
2767     unsigned int tcc;
2768     volatile EDMA3_CCRL_Regs *globalRegs = NULL;
2769     unsigned int qdmaChId;
2770     unsigned int dmaChId;
2771     EDMA3_RM_InstanceInitConfig *rmConfig = NULL;
2772         unsigned int edma3Id;
2774 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2775     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2776     EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2777     EDMA3_DVT_dCOUNTER,
2778     EDMA3_DVT_dNONE,
2779     EDMA3_DVT_dNONE));
2780 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2783         /* If parameter checking is enabled... */
2784 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2785     if ((lChObj == NULL) || (hEdmaResMgr == NULL))
2786         {
2787         result = (EDMA3_RM_E_INVALID_PARAM);
2788         }
2789 #endif
2791         /* Check if the parameters are OK. */
2792     if (result == EDMA3_RM_SOK)
2793         {
2794         chObj = lChObj;
2796         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2798         if (rmInstance == NULL)
2799             {
2800             result = EDMA3_RM_E_INVALID_PARAM;
2801             }
2802         }
2804     if (result == EDMA3_RM_SOK)
2805         {
2806         rmConfig = rmInstance->initParam.rmInstInitConfig;
2807         rmObj = rmInstance->pResMgrObjHandle;
2809         if (rmObj == NULL)
2810             {
2811             result = EDMA3_RM_E_INVALID_PARAM;
2812             }
2813         else
2814             {
2815             if (rmObj->gblCfgParams.globalRegs == NULL)
2816                 {
2817                 result = EDMA3_RM_E_INVALID_PARAM;
2818                 }
2819             else
2820                 {
2821                 edma3Id = rmObj->phyCtrllerInstId;
2822                 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2823                 }
2824             }
2825         }
2828     if (result == EDMA3_RM_SOK)
2829         {
2830         switch (chObj->type)
2831             {
2832             case EDMA3_RM_RES_DMA_CHANNEL:
2833                 {
2834                 /* Save the DMA channel first. */
2835                 dmaChId = chObj->resId;
2837                 /**
2838                  * Validate DMA channel id first.
2839                  * It should be a valid channel id.
2840                  */
2841                 if (dmaChId >=  EDMA3_MAX_DMA_CH)
2842                     {
2843                     result = EDMA3_RM_E_INVALID_PARAM;
2844                     }
2846                 /* It should be owned and allocated by this RM only. */
2847                 if (result == EDMA3_RM_SOK)
2848                     {
2849                     if (((rmConfig->ownDmaChannels[dmaChId/32u])
2850                           &
2851                           (~(rmInstance->avlblDmaChannels[dmaChId/32u]))
2852                           &
2853                           (1u << (dmaChId%32u))) != FALSE)
2854                         {
2855                         /** Perfectly valid channel id.
2856                          * Clear some channel specific registers, if it is permitted.
2857                          */
2858                         if (TRUE == rmInstance->regModificationRequired)
2859                             {
2860                             if (dmaChId < 32u)
2861                                 {
2862                                 if((rmInstance->shadowRegs->SER & (1u<<dmaChId))!=FALSE)
2863                                     {
2864                                     rmInstance->shadowRegs->SECR = (1u<<dmaChId);
2865                                     }
2866                                 if((globalRegs->EMR & (1u<<dmaChId))!=FALSE)
2867                                     {
2868                                     globalRegs->EMCR = (1u<<dmaChId);
2869                                     }
2870                                 }
2871                             else
2872                                 {
2873                                 if((rmInstance->shadowRegs->SERH & (1u<<(dmaChId-32u)))!=FALSE)
2874                                     {
2875                                     rmInstance->shadowRegs->SECRH = (1u<<(dmaChId-32u));
2876                                     }
2877                                 if((globalRegs->EMRH & (1u<<(dmaChId-32u)))!=FALSE)
2878                                     {
2879                                     globalRegs->EMCRH = (1u<<(dmaChId-32u));
2880                                     }
2881                                 }
2883                             /* Clear DCHMAP register also. */
2884                             if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2885                                 {
2886                                 globalRegs->DCHMAP[dmaChId] &=
2887                                                         EDMA3_RM_DCH_PARAM_CLR_MASK;
2888                                 }
2889                             }
2891                         /* Free the PaRAM Set Now. */
2892                         paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].paRAMId;
2893                         resObj.type = EDMA3_RM_RES_PARAM_SET;
2894                         resObj.resId = (unsigned int)paRAMId;
2895                         result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2896                         }
2897                     else
2898                         {
2899                         /* Channel id has some problem. */
2900                         result = EDMA3_RM_E_INVALID_PARAM;
2901                         }
2902                     }
2905                 if (result == EDMA3_RM_SOK)
2906                     {
2907                     /* PaRAM Set Freed */
2908                     edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].paRAMId = -1;
2910                     /* Free the TCC */
2911                     tcc = edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].tcc;
2912                     resObj.type = EDMA3_RM_RES_TCC;
2913                     resObj.resId = tcc;
2914                     result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2915                     }
2917                 if (result == EDMA3_RM_SOK)
2918                     {
2919                     /* TCC Freed */
2920                     edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].tcc = EDMA3_MAX_TCC;
2922                     /**
2923                      * Try to free the DMA Channel now. DMA Channel should
2924                      * be freed only in the end because while freeing, DRAE
2925                      * registers will be RESET.
2926                      * After that, no shadow region specific DMA channel
2927                      * register can be modified. So reset that DRAE register
2928                      * ONLY in the end.
2929                      */
2930                     resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2931                     resObj.resId = dmaChId;
2932                     result = EDMA3_RM_freeResource(hEdmaResMgr,
2933                                             (EDMA3_RM_ResDesc *)&resObj);
2934                     }
2935                 }
2936                 break;
2939             case EDMA3_RM_RES_QDMA_CHANNEL:
2940                 {
2941                 /**
2942                  * Calculate QDMA Logical Channel Id first.
2943                  * User has given the actual QDMA channel id.
2944                  * So we have to convert it to make the logical
2945                  * QDMA channel id first.
2946                  */
2947                 qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
2949                 /**
2950                  * Validate QDMA channel id first.
2951                  * It should be a valid channel id.
2952                  */
2953                 if (chObj->resId >=  EDMA3_MAX_QDMA_CH)
2954                     {
2955                     result = EDMA3_RM_E_INVALID_PARAM;
2956                     }
2958                 /* It should be owned and allocated by this RM only. */
2959                 if (result == EDMA3_RM_SOK)
2960                     {
2961                     if (((rmConfig->ownQdmaChannels[0u])
2962                           &
2963                           (~(rmInstance->avlblQdmaChannels[0u]))
2964                           &
2965                           (1u << chObj->resId)) != FALSE)
2966                         {
2967                         /** Perfectly valid channel id.
2968                          * Clear some channel specific registers, if
2969                          * it is permitted.
2970                          */
2971                         if (TRUE == rmInstance->regModificationRequired)
2972                             {
2973                             rmInstance->shadowRegs->QEECR = (1u<<chObj->resId);
2975                             if((globalRegs->QEMR & (1u<<chObj->resId))!=FALSE)
2976                                 {
2977                                 globalRegs->QEMCR = (1u<<chObj->resId);
2978                                 }
2980                             /* Unmap PARAM Set Number for specified channelId */
2981                             globalRegs->QCHMAP[chObj->resId] &=
2982                                                         EDMA3_RM_QCH_PARAM_CLR_MASK;
2984                             /* Reset the Trigger Word */
2985                             globalRegs->QCHMAP[chObj->resId] &=
2986                                                         EDMA3_RM_QCH_TRWORD_CLR_MASK;
2987                             }
2989                         /* Free the PaRAM Set now */
2990                         paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId;
2991                         resObj.type = EDMA3_RM_RES_PARAM_SET;
2992                         resObj.resId = (int)paRAMId;
2993                         result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2994                         }
2995                     else
2996                         {
2997                         /* Channel id has some problem. */
2998                         result = EDMA3_RM_E_INVALID_PARAM;
2999                         }
3000                     }
3003                 if (result == EDMA3_RM_SOK)
3004                     {
3005                     /* PaRAM Set Freed */
3006                     edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
3008                     /* Free the TCC */
3009                     tcc = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc;
3010                     resObj.type = EDMA3_RM_RES_TCC;
3011                     resObj.resId = tcc;
3012                     result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
3013                     }
3015                 if (result == EDMA3_RM_SOK)
3016                     {
3017                     /* TCC Freed */
3018                     edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = EDMA3_MAX_TCC;
3020                     /**
3021                      * Try to free the QDMA Channel now. QDMA Channel should
3022                      * be freed only in the end because while freeing, QRAE
3023                      * registers will be RESET.
3024                      * After that, no shadow region specific QDMA channel
3025                      * register can be modified. So reset that QDRAE register
3026                      * ONLY in the end.
3027                      */
3028                     resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
3029                     resObj.resId = chObj->resId;
3030                     result = EDMA3_RM_freeResource(hEdmaResMgr,
3031                                             (EDMA3_RM_ResDesc *)&resObj);
3032                     }
3033                 }
3034                 break;
3037             case EDMA3_RM_RES_PARAM_SET:
3038                 {
3039                 /* Link Channel */
3040                 if (chObj->resId < edma3NumPaRAMSets)
3041                     {
3042                     resObj.type = EDMA3_RM_RES_PARAM_SET;
3043                     resObj.resId = chObj->resId;
3045                     result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
3046                     if (result == EDMA3_RM_SOK)
3047                         {
3048                         /* PaRAM Set freed successfully. */
3049                         unsigned int linkCh = edma3_link_ch_min_val[edma3Id];
3051                         /* Reset the Logical-Link channel */
3052                         /* Search for the Logical-Link channel first */
3053                         for (linkCh = edma3_link_ch_min_val[edma3Id];
3054                                 linkCh < edma3_link_ch_max_val[edma3Id];
3055                                 linkCh++)
3056                             {
3057                             if (edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId == chObj->resId)
3058                                 {
3059                                 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = -1;
3060                                 break;
3061                                 }
3062                             }
3063                         }
3064                     }
3065                 else
3066                     {
3067                     result = EDMA3_RM_E_INVALID_PARAM;
3068                     }
3069                 }
3070                 break;
3072             default:
3073                 result = EDMA3_RM_E_INVALID_PARAM;
3074             }
3075         }
3078 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3079     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3080     EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3081     EDMA3_DVT_dCOUNTER,
3082     EDMA3_DVT_dNONE,
3083     EDMA3_DVT_dNONE));
3084 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3086     return result;
3087     }
3091 /**\fn      EDMA3_RM_Result EDMA3_RM_mapEdmaChannel (EDMA3_RM_Handle
3092  *                   hEdmaResMgr, unsigned int channelId, unsigned int paRAMId)
3093  * \brief   Bind the resources DMA Channel and PaRAM Set. Both the DMA channel
3094  * and the PaRAM set should be previously allocated. If they are not,
3095  * this API will result in error.
3096  *
3097  * This API sets the DCHMAP register for a specific DMA channel. This register
3098  * is used to specify the PaRAM Set associated with that particular DMA Channel.
3099  *
3100  * \param   hEdmaResMgr         [IN]    Handle to the previously opened Resource
3101  *                                      Manager Instance.
3102  * \param   channelId           [IN]    Previously allocated DMA Channel on which
3103  *                                      Transfer will occur.
3104  * \param   paRAMId             [IN]    Previously allocated PaRAM Set which
3105  *                                      needs to be associated with the dma channel.
3106  *
3107  * \return  EDMA3_RM_SOK or EDMA_RM Error Code
3108  *
3109  * \note    This API is useful only for the EDMA3 Controllers which have a
3110  *          register for mapping a DMA Channel to a particular PaRAM Set
3111  *          (DCHMAP register).
3112  *          On platforms where this feature is not supported, this API
3113  *          returns error code: EDMA3_RM_E_FEATURE_UNSUPPORTED.
3114  *          This function is re-entrant for unique channelId. It is
3115  *          non-re-entrant for same channelId values.
3116  */
3117 EDMA3_RM_Result EDMA3_RM_mapEdmaChannel (EDMA3_RM_Handle hEdmaResMgr,
3118                                  unsigned int channelId,
3119                                  unsigned int paRAMId)
3120     {
3121     EDMA3_RM_Instance *rmInstance = NULL;
3122     EDMA3_RM_Obj *rmObj = NULL;
3123     EDMA3_RM_Result result = EDMA3_RM_SOK;
3124     volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3126 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3127     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3128                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3129                 EDMA3_DVT_dCOUNTER,
3130                 EDMA3_DVT_dNONE,
3131                 EDMA3_DVT_dNONE));
3132 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3134         /* If parameter checking is enabled... */
3135 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3136     if (hEdmaResMgr == NULL)
3137         {
3138         result = EDMA3_RM_E_INVALID_PARAM;
3139         }
3140 #endif
3142     if (result == EDMA3_RM_SOK)
3143         {
3144         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3146         if (rmInstance == NULL)
3147             {
3148             result = EDMA3_RM_E_INVALID_PARAM;
3149             }
3150         }
3152     if (result == EDMA3_RM_SOK)
3153         {
3154         rmObj = rmInstance->pResMgrObjHandle;
3156         if (rmObj == NULL)
3157             {
3158             result = EDMA3_RM_E_INVALID_PARAM;
3159             }
3160         else
3161             {
3162             if (rmObj->gblCfgParams.globalRegs == NULL)
3163                 {
3164                 result = EDMA3_RM_E_INVALID_PARAM;
3165                 }
3166             }
3167         }
3169     if (result == EDMA3_RM_SOK)
3170         {
3171         gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3173                 /* If parameter checking is enabled... */
3174 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3175         if ((paRAMId >= rmObj->gblCfgParams.numPaRAMSets)
3176             || (channelId >= rmObj->gblCfgParams.numDmaChannels))
3177             {
3178             result = EDMA3_RM_E_INVALID_PARAM;
3179             }
3180 #endif
3181         }
3183     /* DMA channel and PaRAM Set should be previously allocated. */
3184     if (result == EDMA3_RM_SOK)
3185         {
3186         if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[channelId/32u])
3187                                                   &
3188                                                   (~(rmInstance->avlblDmaChannels[channelId/32u]))
3189                                                   &
3190                                                   (1u << (channelId%32u))) != FALSE)
3191             {
3192             /* DMA channel allocated, check for the PaRAM Set */
3193             if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[paRAMId/32u])
3194                                           &
3195                                           (~(rmInstance->avlblPaRAMSets[paRAMId/32u]))
3196                                           &
3197                                           (1u << (paRAMId%32u))) == FALSE)
3198                 {
3199                 /* PaRAM Set NOT allocated, return error */
3200                 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3201                 }
3202             }
3203         else
3204             {
3205             /* DMA channel NOT allocated, return error */
3206             result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3207             }
3208         }
3211     if (result == EDMA3_RM_SOK)
3212         {
3213         /* Map the Dma Channel to the PaRAM Set corresponding to paramId */
3214         /**
3215           * Do this for the EDMA3 Controllers which have a register for mapping
3216           * DMA Channel to a particular PaRAM Set. So check
3217           * dmaChPaRAMMapExists first.
3218           */
3219         if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
3220             {
3221             /* Map Parameter RAM Set Number for specified channelId */
3222             gblRegs->DCHMAP[channelId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
3223             gblRegs->DCHMAP[channelId] |= EDMA3_RM_DCH_PARAM_SET_MASK(paRAMId);
3224             }
3225         else
3226             {
3227             /* Feature NOT supported on the current platform, return error. */
3228             result = EDMA3_RM_E_FEATURE_UNSUPPORTED;
3229             }
3230         }
3232 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3233     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3234                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3235                 EDMA3_DVT_dCOUNTER,
3236                 EDMA3_DVT_dNONE,
3237                 EDMA3_DVT_dNONE));
3238 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3240     return result;
3241     }
3246 /**\fn      EDMA3_RM_Result EDMA3_RM_mapQdmaChannel (EDMA3_RM_Handle
3247  *                       hEdmaResMgr, unsigned int channelId,
3248  *                       unsigned int paRAMId,
3249  *                       EDMA3_RM_QdmaTrigWord trigWord)
3250  * \brief   Bind the resources QDMA Channel and PaRAM Set. Also, Set the
3251  * trigger word for the QDMA channel. Both the QDMA channel and the PaRAM set
3252  * should be previously allocated. If they are not, this API will result in error.
3253  *
3254  * This API sets the QCHMAP register for a specific QDMA channel. This register
3255  * is used to specify the PaRAM Set associated with that particular QDMA
3256  * Channel along with the trigger word.
3257  *
3258  * \param   hEdmaResMgr     [IN]    Handle to the previously opened Resource
3259  *                                  Manager Instance.
3260  * \param   channelId       [IN]    Previously allocated  QDMA Channel on which
3261  *                                  Transfer will occur.
3262  * \param   paRAMId         [IN]    Previously allocated PaRAM Set, which needs to
3263  *                                      be associated with channelId
3264  * \param   trigWord        [IN]    The Trigger Word for the channel.
3265  *                                  Trigger Word is the word in the PaRAM
3266  *                                  Register Set which - when written to by CPU
3267  *                                  -will start the QDMA transfer automatically
3268  *
3269  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
3270  *
3271  * \note    This function is re-entrant for unique channelId. It is non-re-entrant
3272  *          for same channelId values.
3273  */
3274 EDMA3_RM_Result EDMA3_RM_mapQdmaChannel (EDMA3_RM_Handle hEdmaResMgr,
3275                                  unsigned int channelId,
3276                                  unsigned int paRAMId,
3277                                  EDMA3_RM_QdmaTrigWord trigWord)
3278     {
3279     EDMA3_RM_Instance *rmInstance = NULL;
3280     EDMA3_RM_Obj *rmObj = NULL;
3281     EDMA3_RM_Result result = EDMA3_RM_SOK;
3282     volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3284 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3285     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3286                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3287                 EDMA3_DVT_dCOUNTER,
3288                 EDMA3_DVT_dNONE,
3289                 EDMA3_DVT_dNONE));
3290 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3292         /* If parameter checking is enabled... */
3293 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3294     if ((hEdmaResMgr == NULL)
3295         || ((trigWord < EDMA3_RM_QDMA_TRIG_OPT)
3296         || (trigWord > EDMA3_RM_QDMA_TRIG_CCNT)))
3297         {
3298         result = EDMA3_RM_E_INVALID_PARAM;
3299         }
3300 #endif
3302     if (result == EDMA3_RM_SOK)
3303         {
3304         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3306         if (rmInstance == NULL)
3307             {
3308             result = EDMA3_RM_E_INVALID_PARAM;
3309             }
3310         }
3312     if (result == EDMA3_RM_SOK)
3313         {
3314         rmObj = rmInstance->pResMgrObjHandle;
3316         if (rmObj == NULL)
3317             {
3318             result = EDMA3_RM_E_INVALID_PARAM;
3319             }
3320         else
3321             {
3322             if (rmObj->gblCfgParams.globalRegs == NULL)
3323                 {
3324                 result = EDMA3_RM_E_INVALID_PARAM;
3325                 }
3326             }
3327         }
3329     if (result == EDMA3_RM_SOK)
3330         {
3331         gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3333                 /* If parameter checking is enabled... */
3334 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3335         if ((paRAMId >= rmObj->gblCfgParams.numPaRAMSets)
3336             || (channelId >= rmObj->gblCfgParams.numQdmaChannels))
3337             {
3338             result = EDMA3_RM_E_INVALID_PARAM;
3339             }
3340 #endif
3341         }
3343     /* QDMA channel and PaRAM Set should be previously allocated. */
3344     if (result == EDMA3_RM_SOK)
3345         {
3346         if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[channelId/32u])
3347                                                   &
3348                                                   (~(rmInstance->avlblQdmaChannels[channelId/32u]))
3349                                                   &
3350                                                   (1u << (channelId%32u))) != FALSE)
3351             {
3352             /* QDMA channel allocated, check for the PaRAM Set */
3353             if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[paRAMId/32u])
3354                                           &
3355                                           (~(rmInstance->avlblPaRAMSets[paRAMId/32u]))
3356                                           &
3357                                           (1u << (paRAMId%32u))) == FALSE)
3358                 {
3359                 /* PaRAM Set NOT allocated, return error */
3360                 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3361                 }
3362             }
3363         else
3364             {
3365             /* QDMA channel NOT allocated, return error */
3366             result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3367             }
3368         }
3370     if (result == EDMA3_RM_SOK)
3371         {
3372         /* Map Parameter RAM Set Number for specified channelId */
3373         gblRegs->QCHMAP[channelId] &= EDMA3_RM_QCH_PARAM_CLR_MASK;
3374         gblRegs->QCHMAP[channelId] |= EDMA3_RM_QCH_PARAM_SET_MASK(paRAMId);
3376         /* Set the Trigger Word */
3377         gblRegs->QCHMAP[channelId] &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
3378         gblRegs->QCHMAP[channelId] |= EDMA3_RM_QCH_TRWORD_SET_MASK(trigWord);
3379         }
3382 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3383     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3384                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3385                 EDMA3_DVT_dCOUNTER,
3386                 EDMA3_DVT_dNONE,
3387                 EDMA3_DVT_dNONE));
3388 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3390     return result;
3391     }
3395 /**
3396  * \fn  EDMA3_RM_Result EDMA3_RM_registerTccCb(EDMA3_RM_Handle hEdmaResMgr,
3397  *      const EDMA3_RM_ResDesc *channelObj, unsigned int tcc,
3398  *      EDMA3_RM_TccCallback tccCb, void *cbData);
3399  * \brief   Register Interrupt / Completion Handler for a given TCC.
3400  *
3401  * This function enables the interrupts in IESR/IESRH, only if the callback
3402  * function provided by the user is NON-NULL. Moreover, if a call-back function
3403  * is already registered against that TCC, the API fails with the error code
3404  * EDMA3_RM_E_CALLBACK_ALREADY_REGISTERED. For a NULL callback function,
3405  * this API returns error.
3406  *
3407  * \param   hEdmaResMgr         [IN]    Handle to the previously opened
3408  *                                      EDMA3 Resource Manager Instance
3409  * \param   channelObj          [IN]    Channel ID and type (DMA or QDMA
3410  *                                      Channel), allocated earlier, and
3411  *                                      corresponding to which a callback
3412  *                                      function needs to be registered
3413  *                                      against the associated TCC.
3414  * \param   tcc                 [IN]    TCC against which the handler needs to
3415  *                                      be registered.
3416  * \param   tccCb               [IN]    The Callback function to be registered
3417  *                                      against the TCC.
3418  * \param   cbData              [IN]    Callback data to be passed while calling
3419  *                                      the callback function.
3420  *
3421  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
3422  *
3423  * \note    This function is re-entrant for unique tcc values. It is non-
3424  *          re-entrant for same tcc value.
3425  */
3426 EDMA3_RM_Result EDMA3_RM_registerTccCb(EDMA3_RM_Handle hEdmaResMgr,
3427                     const EDMA3_RM_ResDesc *channelObj,
3428                     unsigned int tcc,
3429                     EDMA3_RM_TccCallback tccCb,
3430                     void *cbData)
3431     {
3432     EDMA3_RM_Instance *rmInstance = NULL;
3433     EDMA3_RM_Obj *rmObj = NULL;
3434     EDMA3_RM_Result result = EDMA3_RM_SOK;
3436 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3437     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3438                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3439                 EDMA3_DVT_dCOUNTER,
3440                 EDMA3_DVT_dNONE,
3441                 EDMA3_DVT_dNONE));
3442 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3444         /* If parameter checking is enabled... */
3445 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3446     if ((NULL == hEdmaResMgr) || (NULL == channelObj))
3447         {
3448         result = EDMA3_RM_E_INVALID_PARAM;
3449         }
3451     /* Callback function should NOT be NULL */
3452     if (NULL == tccCb)
3453         {
3454         result = EDMA3_RM_E_INVALID_PARAM;
3455         }
3456 #endif
3458     if (result == EDMA3_RM_SOK)
3459         {
3460         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3461         rmObj = rmInstance->pResMgrObjHandle;
3463         if (rmObj == NULL)
3464             {
3465             result = EDMA3_RM_E_INVALID_PARAM;
3466             }
3468                 /* If parameter checking is enabled... */
3469 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3470         if ((EDMA3_RM_SOK == result) && (tcc >= rmObj->gblCfgParams.numTccs))
3471             {
3472             result = EDMA3_RM_E_INVALID_PARAM;
3473             }
3474 #endif
3476                 /* Check if the parameters are OK. */
3477                 if (EDMA3_RM_SOK == result)
3478             {
3479             /* Check whether the callback has already registered. */
3480             if (NULL != edma3IntrParams[tcc].tccCb)
3481                 {
3482                 result = EDMA3_RM_E_CALLBACK_ALREADY_REGISTERED;
3483                 }
3484             else
3485                 {
3486                 /* Store the mapping b/w DMA/QDMA channel and TCC first. */
3487                 if (channelObj->type == EDMA3_RM_RES_DMA_CHANNEL)
3488                     {
3489                     /* DMA channel */
3490                     if (channelObj->resId < rmObj->gblCfgParams.numDmaChannels)
3491                         {
3492                         /* Save the TCC */
3493                         edma3DmaChTccMapping[channelObj->resId] = tcc;
3494                         }
3495                     else
3496                         {
3497                         /* Error!!! */
3498                         result = EDMA3_RM_E_INVALID_PARAM;
3499                         }
3500                     }
3501                 else
3502                     {
3503                     if (channelObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
3504                         {
3505                         /* QDMA channel */
3506                         if (channelObj->resId < rmObj->gblCfgParams.numQdmaChannels)
3507                             {
3508                             /* Save the TCC */
3509                             edma3QdmaChTccMapping[channelObj->resId] = tcc;
3510                             }
3511                         else
3512                             {
3513                             /* Error!!! */
3514                             result = EDMA3_RM_E_INVALID_PARAM;
3515                             }
3516                         }
3517                     else
3518                         {
3519                         /* Error!!! */
3520                         result = EDMA3_RM_E_INVALID_PARAM;
3521                         }
3522                     }
3523                 }
3525             if (EDMA3_RM_SOK == result)
3526                 {
3527                 /**
3528                  * Enable the interrupts in IESR/IESRH, only if the Callback
3529                  * function is NOT NULL.
3530                  */
3531                 if (tcc < 32u)
3532                     {
3533                     rmInstance->shadowRegs->IESR = (1UL << tcc);
3534                     }
3535                 else
3536                     {
3537                     rmInstance->shadowRegs->IESRH = (1UL << (tcc-32u));
3538                     }
3540                 /* Save the callback functions also */
3541                 edma3IntrParams[tcc].cbData = cbData;
3542                 edma3IntrParams[tcc].tccCb = tccCb;
3543                 }
3544             }
3545         }
3547 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3548     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3549                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3550                 EDMA3_DVT_dCOUNTER,
3551                 EDMA3_DVT_dNONE,
3552                 EDMA3_DVT_dNONE));
3553 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3555     return result;
3556     }
3558 /**
3559  * \fn      EDMA3_RM_Result EDMA3_RM_unregisterTccCb(EDMA3_RM_Handle
3560  *          hEdmaResMgr, const EDMA3_RM_ResDesc *channelObj);
3561  * \brief   Unregister the previously registered callback function against a
3562  *          DMA/QDMA channel.
3563  *
3564  * This function unregisters the previously registered callback function against
3565  * a DMA/QDMA channel by removing any stored callback function. Moreover, it
3566  * clears the interrupt enable register (IESR/IESRH) by writing to the IECR/
3567  * IECRH register, for the TCC associated with that particular channel.
3568  *
3569  * \param   hEdmaResMgr         [IN]    Handle to the previously opened
3570  *                                      EDMA3 Resource Manager Instance
3571  * \param   channelObj          [IN]    Channel ID and type, allocated earlier
3572  *                                      (DMA or QDMA Channel ONLY), and
3573  *                                      corresponding to which a TCC is there.
3574  *                                      Against that TCC, the callback needs
3575  *                                      to be un-registered.
3576  *
3577  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code.
3578  *
3579  * \note    This function is re-entrant for unique (channelObj->type +
3580  *          channelObj->resId) combination. It is non-re-entrant for same
3581  *          channelObj Resource.
3582  */
3583 EDMA3_RM_Result EDMA3_RM_unregisterTccCb(EDMA3_RM_Handle hEdmaResMgr,
3584                     const EDMA3_RM_ResDesc *channelObj)
3585     {
3586     EDMA3_RM_Instance *rmInstance = NULL;
3587     EDMA3_RM_Obj *rmObj = NULL;
3588     EDMA3_RM_Result result = EDMA3_RM_SOK;
3589     unsigned int mappedTcc = EDMA3_MAX_TCC;
3591 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3592     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3593                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3594                 EDMA3_DVT_dCOUNTER,
3595                 EDMA3_DVT_dNONE,
3596                 EDMA3_DVT_dNONE));
3597 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3599         /* If parameter checking is enabled... */
3600 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3601     if ((NULL == hEdmaResMgr) || (NULL == channelObj))
3602         {
3603         result = EDMA3_RM_E_INVALID_PARAM;
3604         }
3605 #endif
3607         /* Check if the parameters are OK. */
3608         if (EDMA3_RM_SOK == result)
3609         {
3610         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3611         rmObj = rmInstance->pResMgrObjHandle;
3613         if (rmObj == NULL)
3614             {
3615             result = EDMA3_RM_E_INVALID_PARAM;
3616             }
3617         else
3618             {
3619             if (channelObj->type == EDMA3_RM_RES_DMA_CHANNEL)
3620                 {
3621                 /* DMA channel */
3622                 if (channelObj->resId < rmObj->gblCfgParams.numDmaChannels)
3623                     {
3624                     /* Save the mapped TCC */
3625                     mappedTcc = edma3DmaChTccMapping[channelObj->resId];
3627                     /* Remove the mapping now. */
3628                     edma3DmaChTccMapping[channelObj->resId] = EDMA3_MAX_TCC;
3629                     }
3630                 else
3631                     {
3632                     /* Error!!! */
3633                     result = EDMA3_RM_E_INVALID_PARAM;
3634                     }
3635                 }
3636             else
3637                 {
3638                 if (channelObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
3639                     {
3640                     /* QDMA channel */
3641                     if (channelObj->resId < rmObj->gblCfgParams.numQdmaChannels)
3642                         {
3643                         /* Save the mapped TCC */
3644                         mappedTcc = edma3QdmaChTccMapping[channelObj->resId];
3646                         /* Remove the mapping now. */
3647                         edma3QdmaChTccMapping[channelObj->resId] = EDMA3_MAX_TCC;
3648                         }
3649                     else
3650                         {
3651                         /* Error!!! */
3652                         result = EDMA3_RM_E_INVALID_PARAM;
3653                         }
3654                     }
3655                 else
3656                     {
3657                     /* Error!!! */
3658                     result = EDMA3_RM_E_INVALID_PARAM;
3659                     }
3660                 }
3662             if (EDMA3_RM_SOK == result)
3663                 {
3664                 /* Remove the callback function too */
3665                 if (mappedTcc < 32u)
3666                     {
3667                     rmInstance->shadowRegs->IECR = (1UL << mappedTcc);
3668                     }
3669                 else
3670                     {
3671                     rmInstance->shadowRegs->IECRH = (1UL << (mappedTcc-32u));
3672                     }
3674                 edma3IntrParams[mappedTcc].cbData = NULL;
3675                 edma3IntrParams[mappedTcc].tccCb = NULL;
3676                 }
3677             }
3678         }
3680 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3681     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3682                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3683                 EDMA3_DVT_dCOUNTER,
3684                 EDMA3_DVT_dNONE,
3685                 EDMA3_DVT_dNONE));
3686 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3688     return result;
3689     }
3692 /**\fn      EDMA3_RM_Result EDMA3_RM_allocContiguousResource(EDMA3_RM_Handle
3693  *                        hEdmaResMgr, EDMA3_RM_ResDesc *firstResIdObj,
3694  *                       unsigned int numResources)
3695  * \brief   Allocate a contiguous region of specified EDMA3 Resource
3696  * like DMA channel, QDMA channel, PaRAM Set or TCC.
3697  *
3698  * This API is used to allocate a contiguous region of specified EDMA3
3699  * Resources like DMA channel, QDMA channel, PaRAM Set or TCC.
3700  *
3701  * User can specify a particular resource Id to start with and go up to the
3702  * number of resources requested. The specific resource id to start from could
3703  * be passed in 'firstResIdObject->resId' and the number of resources requested
3704  * in 'numResources'.
3705  *
3706  * User can also request ANY available resource(s) of the type
3707  * 'firstResIdObject->type' by specifying 'firstResIdObject->resId' as
3708  * EDMA3_RM_RES_ANY.
3709  *
3710  * ANY types of resources are those resources when user doesn't care about the
3711  * actual resource allocated; user just wants a resource of the type specified.
3712  * One use-case is to perform memory-to-memory data transfer operation. This
3713  * operation can be performed using any available DMA or QDMA channel. User
3714  * doesn't need any specific channel for the same.
3715  *
3716  * To allocate specific contiguous resources, first this API checks whether
3717  * those requested resources are OWNED by the Resource Manager instance. Then
3718  * it checks the current availability of those resources.
3719  *
3720  * To allocate ANY available contiguous resources, this API tries to allocate
3721  * resources from the pool of (owned && non_reserved && available_right_now)
3722  * resources.
3723  *
3724  * After allocating DMA/QDMA channels or TCCs, the same resources are enabled in
3725  * the shadow region specific register (DRAE/DRAEH/QRAE). Allocated PaRAM Sets
3726  * are initialized to NULL before this API returns.
3727  *
3728  * \param   hEdmaResMgr         [IN]    Handle to the previously opened Resource
3729  *                                      Manager Instance.
3730  * \param   firstResIdObj       [IN]    Handle to the first resource descriptor
3731  *                                      object, which needs to be allocated.
3732  *                                      firstResIdObject->resId could be a valid
3733  *                                      resource id in case user wants to
3734  *                                      allocate specific resources OR it could
3735  *                                      be EDMA3_RM_RES_ANY in case user wants
3736  *                                      only the required number of resources
3737  *                                      and doesn't care about which resources
3738  *                                      were allocated.
3739  * \param   numResources        [IN]    Number of contiguous resources user
3740  *                                      wants to allocate.
3741  *
3742  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
3743  *
3744  * \note    This function acquires a RM Instance specific semaphore
3745  *          to prevent simultaneous access to the global pool of resources.
3746  *          It is re-entrant, but should not be called from the user callback
3747  *          function (ISR context).
3748  */
3749 EDMA3_RM_Result EDMA3_RM_allocContiguousResource(EDMA3_RM_Handle hEdmaResMgr,
3750                                             EDMA3_RM_ResDesc *firstResIdObj,
3751                                             unsigned int numResources)
3752     {
3753     EDMA3_RM_Instance *rmInstance = NULL;
3754     EDMA3_RM_Obj *rmObj = NULL;
3755     EDMA3_RM_Result result = EDMA3_RM_SOK;
3756     EDMA3_RM_ResDesc *resObj = NULL;
3757     unsigned int resAllocIdx = 0u;
3758     unsigned int firstResId;
3759     unsigned int lastResId = 0u;
3760     unsigned int maxNumResources = 0u;
3761     EDMA3_RM_Result semResult = EDMA3_RM_SOK;
3762     unsigned int resIdClr = 0x0;
3763     unsigned int resIdSet = 0x0;
3764     volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3765     unsigned int i = 0u;
3766     unsigned int position = 0u;
3767         unsigned int edma3Id;
3769 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3770     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3771     EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3772     EDMA3_DVT_dCOUNTER,
3773     EDMA3_DVT_dNONE,
3774     EDMA3_DVT_dNONE));
3775 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3778         /* If parameter checking is enabled... */
3779 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3780     if ((hEdmaResMgr == NULL) || (firstResIdObj == NULL))
3781         {
3782         result = EDMA3_RM_E_INVALID_PARAM;
3783         }
3784 #endif
3786     if (EDMA3_RM_SOK == result)
3787         {
3788         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3789         if (rmInstance == NULL)
3790             {
3791             result = EDMA3_RM_E_INVALID_PARAM;
3792             }
3793         }
3795     if (EDMA3_RM_SOK == result)
3796         {
3797         rmObj = rmInstance->pResMgrObjHandle;
3799         if (rmObj == NULL)
3800             {
3801             result = EDMA3_RM_E_INVALID_PARAM;
3802             }
3803         }
3805     if (EDMA3_RM_SOK == result)
3806         {
3807         edma3Id = rmObj->phyCtrllerInstId;
3808                 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3810         if (rmInstance->initParam.rmSemHandle == NULL)
3811             {
3812             result = EDMA3_RM_E_INVALID_PARAM;
3813             }
3814         }
3816     if (EDMA3_RM_SOK == result)
3817         {
3818         resObj = firstResIdObj;
3819         if (resObj != NULL)
3820             {
3821             firstResId = resObj->resId;
3822             }
3824         switch (resObj->type)
3825             {
3826             case EDMA3_RM_RES_DMA_CHANNEL :
3827                 maxNumResources = rmObj->gblCfgParams.numDmaChannels;
3828                 break;
3829             case EDMA3_RM_RES_QDMA_CHANNEL :
3830                 maxNumResources = rmObj->gblCfgParams.numQdmaChannels;
3831                 break;
3832             case EDMA3_RM_RES_TCC :
3833                 maxNumResources = rmObj->gblCfgParams.numTccs;
3834                 break;
3835             case EDMA3_RM_RES_PARAM_SET :
3836                 maxNumResources = rmObj->gblCfgParams.numPaRAMSets;
3837                 break;
3838             default:
3839                 result = EDMA3_RM_E_INVALID_PARAM;
3840                 break;
3841             }
3842         }
3845     if (EDMA3_RM_SOK == result)
3846         {
3847         /* First resource id (firstResId) can be a valid Resource ID as well as
3848          * 'EDMA3_RM_RES_ANY', in case user does not want to
3849          * start from a specific resource. For eg, user allocating link channels.
3850          */
3851         if (firstResId != EDMA3_RM_RES_ANY)
3852             {
3853             /* User want specific resources. */
3854             lastResId = firstResId + numResources;
3856             if (((firstResId >= maxNumResources) || (firstResId > lastResId))
3857                 || (lastResId > maxNumResources))
3858                 {
3859                 result = EDMA3_RM_E_INVALID_PARAM;
3860                 }
3861             }
3862         else
3863             {
3864             /* (firstResId == EDMA3_RM_RES_ANY)
3865              * So just check whether the number of resources
3866              * requested does not cross the limit.
3867              */
3868             if (numResources > maxNumResources)
3869                 {
3870                 result = EDMA3_RM_E_INVALID_PARAM;
3871                 }
3872             }
3873         }
3876     if (result == EDMA3_RM_SOK)
3877         {
3878         /* Now try to allocate resources for the first case */
3879         if (firstResId != EDMA3_RM_RES_ANY)
3880             {
3881             /* Request for specific resources */
3883             /**
3884               * Take the instance specific semaphore, to prevent simultaneous
3885               * access to the shared resources.
3886               */
3887             semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
3888                                     EDMA3_OSSEM_NO_TIMEOUT);
3890             if (EDMA3_RM_SOK == semResult)
3891                 {
3892                 switch (resObj->type)
3893                     {
3894                     case EDMA3_RM_RES_DMA_CHANNEL :
3895                             {
3896                             for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3897                                 {
3898                                 resIdClr = (unsigned int)(~(1u << (resAllocIdx%32u)));
3899                                 resIdSet = (1u << (resAllocIdx%32u));
3901                                 /* Check whether it is owned or not */
3902                                 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resAllocIdx/32u])&(resIdSet)) != FALSE)
3903                                    {
3904                                     /* Now check if specified resource is available presently*/
3905                                     if (((rmInstance->avlblDmaChannels[resAllocIdx/32u])&(resIdSet)) != FALSE)
3906                                         {
3907                                         /*
3908                                          * Mark the specified resource as "Not Available"
3909                                          * for future requests
3910                                          */
3911                                         rmInstance->avlblDmaChannels[resAllocIdx/32u] &= resIdClr;
3913                                         if (resAllocIdx < 32u)
3914                                             {
3915                                             rmInstance->shadowRegs->EECR = (1UL << resAllocIdx);
3917                                             /**
3918                                              * Enable the DMA channel in the
3919                                              * DRAE registers also.
3920                                              */
3921                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAE
3922                                                 |= (0x1u << resAllocIdx);
3923                                             }
3924                                         else
3925                                             {
3926                                             rmInstance->shadowRegs->EECRH = (1UL << (resAllocIdx - 32u));
3928                                             /**
3929                                              * Enable the DMA channel in the
3930                                              * DRAEH registers also.
3931                                              */
3932                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
3933                                                 |= (0x1u << (resAllocIdx - 32u));
3934                                             }
3936                                         result = EDMA3_RM_SOK;
3937                                         }
3938                                     else
3939                                         {
3940                                         /* Specified resource is owned but is already booked */
3941                                         result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3942                                         break;
3943                                         }
3944                                     }
3945                                 else
3946                                     {
3947                                     /*
3948                                      * Specified resource is not owned by this instance
3949                                      * of the Resource Manager
3950                                      */
3951                                     result = EDMA3_RM_E_RES_NOT_OWNED;
3952                                     break;
3953                                     }
3954                                 }
3956                             break;
3957                             }
3959                     case EDMA3_RM_RES_QDMA_CHANNEL:
3960                             {
3961                             for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3962                                 {
3963                                 resIdClr = (unsigned int)(~(1u << resAllocIdx));
3964                                 resIdSet = (1u << resAllocIdx);
3966                                 /* Check whether it is owned or not */
3967                                 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u])&(resIdSet))!=FALSE)
3968                                    {
3969                                     /* Now check if specified resource is available presently*/
3970                                     if (((rmInstance->avlblQdmaChannels[0u])&(resIdSet))!=FALSE)
3971                                         {
3972                                         /*
3973                                          * Mark the specified resource as "Not Available"
3974                                          * for future requests
3975                                          */
3976                                         rmInstance->avlblQdmaChannels[0u] &= resIdClr;
3978                                         /**
3979                                          * Enable the QDMA channel in the
3980                                          * QRAE register also.
3981                                          */
3982                                         gblRegs->QRAE[rmInstance->initParam.regionId]
3983                                             |= (0x1u << resAllocIdx);
3985                                         result = EDMA3_RM_SOK;
3986                                         }
3987                                     else
3988                                         {
3989                                         /* Specified resource is owned but is already booked */
3990                                         result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3991                                         break;
3992                                         }
3993                                     }
3994                                 else
3995                                     {
3996                                     /*
3997                                      * Specified resource is not owned by this instance
3998                                      * of the Resource Manager
3999                                      */
4000                                     result = EDMA3_RM_E_RES_NOT_OWNED;
4001                                     break;
4002                                     }
4003                                 }
4005                             break;
4006                             }
4008                     case EDMA3_RM_RES_TCC:
4009                             {
4010                             for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
4011                                 {
4012                                 resIdClr = (unsigned int)(~(1u << (resAllocIdx%32u)));
4013                                 resIdSet = (1u << (resAllocIdx%32u));
4015                                 /* Check whether it is owned or not */
4016                                 if (((rmInstance->initParam.rmInstInitConfig->ownTccs[resAllocIdx/32u])&(resIdSet))!=FALSE)
4017                                    {
4018                                     /* Now check if specified resource is available presently*/
4019                                     if (((rmInstance->avlblTccs[resAllocIdx/32u])&(resIdSet))!=FALSE)
4020                                         {
4021                                         /*
4022                                          * Mark the specified resource as "Not Available"
4023                                          * for future requests
4024                                          */
4025                                         rmInstance->avlblTccs[resAllocIdx/32u] &= resIdClr;
4027                                         /**
4028                                          * Enable the Interrupt channel in the
4029                                          * DRAE/DRAEH registers also.
4030                                          * Also, If the region id coming from this
4031                                          * RM instance is same as the Master RM
4032                                          * Instance's region id, only then we will be
4033                                          * getting the interrupts on the same side.
4034                                          * So save the TCC in the allocatedTCCs[] array.
4035                                          */
4036                                         if (resAllocIdx < 32u)
4037                                             {
4038                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAE
4039                                                 |= (0x1u << resAllocIdx);
4041                                             if (edma3RegionId == rmInstance->initParam.regionId)
4042                                                 {
4043                                                 allocatedTCCs[0u] |= (0x1u << resAllocIdx);
4044                                                 }
4045                                             }
4046                                         else
4047                                             {
4048                                             gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
4049                                                 |= (0x1u << (resAllocIdx - 32u));
4051                                             if (edma3RegionId == rmInstance->initParam.regionId)
4052                                                 {
4053                                                 allocatedTCCs[1u] |= (0x1u << (resAllocIdx - 32u));
4054                                                 }
4055                                             }
4057                                         result = EDMA3_RM_SOK;
4058                                         }
4059                                     else
4060                                         {
4061                                         /* Specified resource is owned but is already booked */
4062                                         result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
4063                                         break;
4064                                         }
4065                                     }
4066                                 else
4067                                     {
4068                                     /*
4069                                      * Specified resource is not owned by this instance
4070                                      * of the Resource Manager
4071                                      */
4072                                     result = EDMA3_RM_E_RES_NOT_OWNED;
4073                                     break;
4074                                     }
4075                                 }
4077                             break;
4078                             }
4080                     case EDMA3_RM_RES_PARAM_SET:
4081                             {
4082                             for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
4083                                 {
4084                                 resIdClr = (unsigned int)(~(1u << (resAllocIdx%32u)));
4085                                 resIdSet = (1u << (resAllocIdx%32u));
4087                                 /* Check whether it is owned or not */
4088                                 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[resAllocIdx/32u])&(resIdSet))!=FALSE)
4089                                    {
4090                                     /* Now check if specified resource is available presently*/
4091                                     if (((rmInstance->avlblPaRAMSets[resAllocIdx/32u])&(resIdSet))!=FALSE)
4092                                         {
4093                                         /*
4094                                          * Mark the specified resource as "Not Available"
4095                                          * for future requests
4096                                          */
4097                                         rmInstance->avlblPaRAMSets[resAllocIdx/32u] &= resIdClr;
4099                                         /**
4100                                          * Also, make the actual PARAM Set NULL, checking the flag
4101                                          * whether it is required or not.
4102                                          */
4103                                         if (TRUE == rmInstance->paramInitRequired)
4104                                             {
4105                                             edma3MemZero((void *)(&gblRegs->PARAMENTRY[resAllocIdx]),
4106                                                         sizeof(gblRegs->PARAMENTRY[resAllocIdx]));
4107                                             }
4109                                         result = EDMA3_RM_SOK;
4110                                         }
4111                                     else
4112                                         {
4113                                         /* Specified resource is owned but is already booked */
4114                                         result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
4115                                         break;
4116                                         }
4117                                     }
4118                                 else
4119                                     {
4120                                     /*
4121                                      * Specified resource is not owned by this instance
4122                                      * of the Resource Manager
4123                                      */
4124                                     result = EDMA3_RM_E_RES_NOT_OWNED;
4125                                     break;
4126                                     }
4127                                 }
4129                             break;
4130                             }
4132                     default:
4133                             {
4134                             result = EDMA3_RM_E_INVALID_PARAM;
4135                             break;
4136                             }
4137                     }
4139                 /* resource allocation completed, release the semaphore first */
4140                 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
4141                 }
4143             }
4144         else
4145             {
4146             /* (firstResId == EDMA3_RM_RES_ANY) */
4147             /**
4148             * Take the instance specific semaphore, to prevent simultaneous
4149             * access to the shared resources.
4150             */
4151             semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
4152             EDMA3_OSSEM_NO_TIMEOUT);
4154             if (EDMA3_RM_SOK == semResult)
4155                 {
4156                 /**
4157                 * We have to search three different arrays, namely ownedResoures,
4158                 * avlblResources and resvdResources, to find the 'common' contiguous
4159                 * resources. For this, take an 'AND' of all three arrays in one single
4160                 * array and use your algorithm on that array.
4161                 */
4162                 switch (resObj->type)
4163                     {
4164                     case EDMA3_RM_RES_DMA_CHANNEL:
4165                         {
4166                         /* AND all the arrays to look into */
4167                         contiguousDmaRes[0u] = ((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[0u]
4168                                                 & rmInstance->avlblDmaChannels[0u])
4169                                                 & (~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[0u]))
4170                                                 );
4171                         contiguousDmaRes[1u] = ((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[1u]
4172                                                 & rmInstance->avlblDmaChannels[1u])
4173                                                 & (~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[1u]))
4174                                                 );
4175                         }
4176                         break;
4178                     case EDMA3_RM_RES_QDMA_CHANNEL:
4179                         {
4180                         /* AND all the arrays to look into */
4181                         contiguousQdmaRes[0u] = ((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u]
4182                                                 & rmInstance->avlblQdmaChannels[0u])
4183                                                 & (~(rmInstance->initParam.rmInstInitConfig->resvdQdmaChannels[0u]))
4184                                                 );
4185                         }
4186                         break;
4188                     case EDMA3_RM_RES_TCC:
4189                         {
4190                         /* AND all the arrays to look into */
4191                         contiguousTccRes[0u] = ((rmInstance->initParam.rmInstInitConfig->ownTccs[0u]
4192                                                 & rmInstance->avlblTccs[0u])
4193                                                 & (~(rmInstance->initParam.rmInstInitConfig->resvdTccs[0u]))
4194                                                 );
4195                         contiguousTccRes[1u] = ((rmInstance->initParam.rmInstInitConfig->ownTccs[1u]
4196                                                 & rmInstance->avlblTccs[1u])
4197                                                 & (~(rmInstance->initParam.rmInstInitConfig->resvdTccs[1u]))
4198                                                 );
4199                         }
4200                         break;
4202                     case EDMA3_RM_RES_PARAM_SET:
4203                         {
4204                         /* AND all the arrays to look into */
4205                         for (i = 0u; i < (maxNumResources/32u); ++i)
4206                             {
4207                             contiguousParamRes[i] = ((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[i]
4208                                                     & rmInstance->avlblPaRAMSets[i])
4209                                                     & (~(rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[i]))
4210                                                     );
4211                             }
4212                         }
4213                         break;
4215                     default:
4216                         {
4217                         result = EDMA3_RM_E_INVALID_PARAM;
4218                         }
4219                         break;
4220                     }
4222                 if (EDMA3_RM_SOK == result)
4223                     {
4224                     /**
4225                      * Try to allocate 'numResources' contiguous resources
4226                      * of type RES_ANY.
4227                      */
4228                     result = allocAnyContigRes (resObj->type, numResources, &position);
4230                     /**
4231                     * If result != EDMA3_RM_SOK, resource allocation failed.
4232                     * Else resources successfully allocated.
4233                     */
4234                     if (result == EDMA3_RM_SOK)
4235                         {
4236                         /* Update the first resource id with the position returned. */
4237                         resObj->resId = position;
4239                         /*
4240                          * Do some further changes in the book-keeping
4241                          * data structures and global registers accordingly.
4242                          */
4243                         result = gblChngAllocContigRes(rmInstance, resObj, numResources);
4244                         }
4245                     }
4247                 /* resource allocation completed, release the semaphore first */
4248                 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
4249                 }
4250             }
4251         }
4254     /**
4255      * Check the Resource Allocation Result 'result' first. If Resource
4256      * Allocation has resulted in an error, return it (having more priority than
4257      * semResult. Else, return semResult.
4258      */
4259      if (EDMA3_RM_SOK == result)
4260          {
4261          /**
4262           * Resource Allocation successful, return semResult for returning
4263           * semaphore.
4264           */
4265          result = semResult;
4266          }
4269 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4270     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4271                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4272                 EDMA3_DVT_dCOUNTER,
4273                 EDMA3_DVT_dNONE,
4274                 EDMA3_DVT_dNONE));
4275 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4277     return result;
4278     }
4282 /**
4283  * \fn      EDMA3_RM_Result EDMA3_RM_freeContiguousResource(EDMA3_RM_Handle
4284  *                       hEdmaResMgr, EDMA3_RM_ResDesc *firstResIdObj,
4285  *                       unsigned int numResources)
4286  * \brief   Free a contiguous region of specified EDMA3 Resource
4287  * like DMA channel, QDMA channel, PaRAM Set or TCC, previously allocated.
4288  *
4289  * This API frees a contiguous region of specified EDMA3 Resources
4290  * like DMA channel, QDMA channel, PaRAM Set or TCC, which have been previously
4291  * allocated. In case of an error during the freeing of any specific resource,
4292  * user can check the 'firstResIdObj' object to know the last resource id
4293  * whose freeing has failed. In case of success, there is no need to check this
4294  * object.
4295  *
4296  * \param  hEdmaResMgr         [IN]         Handle to the previously opened
4297  *                                          Resource Manager Instance.
4298  * \param   firstResIdObj      [IN/OUT]     Handle to the first resource
4299  *                                          descriptor object, which needs to be
4300  *                                          freed. In case of an error while
4301  *                                          freeing any particular resource,
4302  *                                          the last resource id whose freeing has
4303  *                                          failed is returned in this resource
4304  *                                          descriptor object.
4305  * \param   numResources      [IN]          Number of contiguous resources allocated
4306  *                                          previously which user wants to release
4307  *
4308  * \note        This is a re-entrant function which internally calls
4309  *              EDMA3_RM_freeResource() for resource de-allocation.
4310  */
4311 EDMA3_RM_Result EDMA3_RM_freeContiguousResource(EDMA3_RM_Handle hEdmaResMgr,
4312                                            EDMA3_RM_ResDesc *firstResIdObj,
4313                                            unsigned int numResources)
4314     {
4315     EDMA3_RM_Instance *rmInstance = NULL;
4316     EDMA3_RM_Obj *rmObj = NULL;
4317     EDMA3_RM_Result result = EDMA3_RM_SOK;
4318     EDMA3_RM_ResDesc *resObj;
4319     unsigned int resFreeIdx = 0u;
4320     unsigned int firstResId;
4321     unsigned int lastResId;
4322     unsigned int maxNumResources = 0u;
4324 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4325     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4326                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4327                 EDMA3_DVT_dCOUNTER,
4328                 EDMA3_DVT_dNONE,
4329                 EDMA3_DVT_dNONE));
4330 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4332         /* If parameter checking is enabled... */
4333 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4334     if ((hEdmaResMgr == NULL) || (firstResIdObj == NULL))
4335         {
4336         result = EDMA3_RM_E_INVALID_PARAM;
4337         }
4338 #endif
4340         /* Check if the parameters are OK. */
4341         if (EDMA3_RM_SOK == result)
4342         {
4343         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4344         rmObj = rmInstance->pResMgrObjHandle;
4346         if (rmObj == NULL)
4347             {
4348             result = EDMA3_RM_E_INVALID_PARAM;
4349             }
4350         else
4351             {
4352             resObj = firstResIdObj;
4353             if (resObj != NULL)
4354                 {
4355                 firstResId = resObj->resId;
4356                 lastResId = firstResId + (numResources - 1u);
4357                 }
4359             switch (resObj->type)
4360                 {
4361                 case EDMA3_RM_RES_DMA_CHANNEL :
4362                     maxNumResources = rmObj->gblCfgParams.numDmaChannels;
4363                     break;
4364                 case EDMA3_RM_RES_QDMA_CHANNEL :
4365                     maxNumResources = rmObj->gblCfgParams.numQdmaChannels;
4366                     break;
4367                 case EDMA3_RM_RES_TCC :
4368                     maxNumResources = rmObj->gblCfgParams.numTccs;
4369                     break;
4370                 case EDMA3_RM_RES_PARAM_SET :
4371                     maxNumResources = rmObj->gblCfgParams.numPaRAMSets;
4372                     break;
4373                 default:
4374                     result = EDMA3_RM_E_INVALID_PARAM;
4375                     break;
4376                 }
4378             if (result == EDMA3_RM_SOK)
4379                 {
4380                 if ((firstResId > lastResId) || (lastResId >= maxNumResources))
4381                     {
4382                     result = EDMA3_RM_E_INVALID_PARAM;
4383                     }
4384                 else
4385                     {
4386                     for (resFreeIdx = firstResId; resFreeIdx <= lastResId; ++resFreeIdx)
4387                         {
4388                         resObj->resId = resFreeIdx;
4389                         result = EDMA3_RM_freeResource(rmInstance, resObj);
4391                         if (result != EDMA3_RM_SOK)
4392                             {
4393                             break;
4394                             }
4395                         }
4396                     }
4397                 }
4398             }
4399         }
4401 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4402     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4403                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4404                 EDMA3_DVT_dCOUNTER,
4405                 EDMA3_DVT_dNONE,
4406                 EDMA3_DVT_dNONE));
4407 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4409     return result;
4410     }
4415 /**\fn      EDMA3_RM_Result EDMA3_RM_setCCRegister (EDMA3_RM_Handle hEdmaResMgr,
4416  *                   unsigned int regOffset,
4417  *                   unsigned int newRegValue)
4418  * \brief   Set the Channel Controller (CC) Register value
4419  *
4420  * \param   hEdmaResMgr     [IN]    Handle to the previously opened Resource
4421  *                                  Manager Instance.
4422  * \param   regOffset       [IN]    CC Register offset whose value needs to be
4423  *                                  set. It should be word-aligned.
4424  * \param   newRegValue     [IN]    New CC Register Value
4425  *
4426  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
4427  *
4428  * \note    This function is non re-entrant for users using the same
4429  *          Resource Manager handle.
4430  *          Before modifying a register, it tries to acquire a semaphore
4431  *          (RM instance specific), to protect simultaneous
4432  *          modification of the same register by two different users.
4433  *          After the successful change, it releases the semaphore.
4434  *          For users using different RM handles, this function is re-entrant.
4435  */
4436 EDMA3_RM_Result EDMA3_RM_setCCRegister (EDMA3_RM_Handle hEdmaResMgr,
4437                     unsigned int regOffset,
4438                     unsigned int newRegValue)
4439     {
4440     EDMA3_RM_Result result = EDMA3_RM_SOK;
4441     EDMA3_RM_Instance *rmInstance = NULL;
4442     EDMA3_RM_Obj *rmObj = NULL;
4443     volatile unsigned int regPhyAddr = 0x0u;
4446 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4447     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4448                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4449                 EDMA3_DVT_dCOUNTER,
4450                 EDMA3_DVT_dNONE,
4451                 EDMA3_DVT_dNONE));
4452 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4455         /* If parameter checking is enabled... */
4456 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4457     if ((hEdmaResMgr == NULL) || ((regOffset % 4u) != 0))
4458         {
4459         result = (EDMA3_RM_E_INVALID_PARAM);
4460         }
4461 #endif
4463         /* Check if the parameters are OK. */
4464         if (EDMA3_RM_SOK == result)
4465         {
4466         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4467         rmObj = rmInstance->pResMgrObjHandle;
4469         if (rmObj == NULL)
4470             {
4471             result = (EDMA3_RM_E_INVALID_PARAM);
4472             }
4473         else
4474             {
4475             if (rmObj->gblCfgParams.globalRegs != NULL)
4476                 {
4477                 /**
4478                   * Take the instance specific semaphore, to prevent simultaneous
4479                   * access to the shared resources.
4480                   */
4481                 result = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
4482                                         EDMA3_OSSEM_NO_TIMEOUT);
4484                 if (EDMA3_RM_SOK == result)
4485                     {
4486                     /* Semaphore taken successfully, modify the registers. */
4487                     regPhyAddr = (unsigned int)(rmObj->gblCfgParams.globalRegs) + regOffset;
4489                     *(unsigned int *)regPhyAddr = newRegValue;
4491                     /* Return the semaphore back */
4492                     result = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
4493                     }
4494                 }
4495             }
4496         }
4499 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4500     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4501                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4502                 EDMA3_DVT_dCOUNTER,
4503                 EDMA3_DVT_dNONE,
4504                 EDMA3_DVT_dNONE));
4505 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4508     return result;
4509     }
4514 /**\fn      EDMA3_RM_Result EDMA3_RM_getCCRegister (EDMA3_RM_Handle hEdmaResMgr,
4515  *                    unsigned int regOffset,
4516  *                    unsigned int *regValue)
4517  * \brief   Get the Channel Controller (CC) Register value
4518  *
4519  * \param   hEdmaResMgr     [IN]        Handle to the previously opened Resource
4520  *                                      Manager Instance.
4521  * \param   regOffset       [IN]        CC Register offset whose value is
4522  *                                      needed. It should be word-aligned.
4523  * \param   regValue        [IN/OUT]    Fetched CC Register Value
4524  *
4525  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
4526  *
4527  * \note    This function is re-entrant.
4528  */
4529 EDMA3_RM_Result EDMA3_RM_getCCRegister (EDMA3_RM_Handle hEdmaResMgr,
4530                     unsigned int regOffset,
4531                     unsigned int *regValue)
4532     {
4533     EDMA3_RM_Result result = EDMA3_RM_SOK;
4534     EDMA3_RM_Instance *rmInstance = NULL;
4535     EDMA3_RM_Obj *rmObj = NULL;
4536     volatile unsigned int regPhyAddr = 0x0u;
4539 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4540     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4541                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4542                 EDMA3_DVT_dCOUNTER,
4543                 EDMA3_DVT_dNONE,
4544                 EDMA3_DVT_dNONE));
4545 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4548         /* If parameter checking is enabled... */
4549 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4550     if (((hEdmaResMgr == NULL) || (regValue == NULL))
4551         || ((regOffset % 4u) != 0))
4552         {
4553         result = (EDMA3_RM_E_INVALID_PARAM);
4554         }
4555 #endif
4557         /* Check if the parameters are OK. */
4558         if (EDMA3_RM_SOK == result)
4559         {
4560         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4561         rmObj = rmInstance->pResMgrObjHandle;
4563         if (rmObj == NULL)
4564             {
4565             result = (EDMA3_RM_E_INVALID_PARAM);
4566             }
4567         else
4568             {
4569             if (rmObj->gblCfgParams.globalRegs != NULL)
4570                 {
4571                 regPhyAddr = (unsigned int)(rmObj->gblCfgParams.globalRegs) + regOffset;
4573                 *regValue = *(unsigned int *)regPhyAddr;
4574                 }
4575             }
4576         }
4579 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4580     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4581                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4582                 EDMA3_DVT_dCOUNTER,
4583                 EDMA3_DVT_dNONE,
4584                 EDMA3_DVT_dNONE));
4585 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4588     return result;
4589     }
4593 /**\fn      EDMA3_RM_Result EDMA3_RM_waitAndClearTcc (EDMA3_RM_Handle
4594  *                        hEdmaResMgr, unsigned int tccNo)
4595  * \brief   Wait for a transfer completion interrupt to occur and clear it.
4596  *
4597  * This is a blocking function that returns when the IPR/IPRH bit corresponding
4598  * to the tccNo specified, is SET. It clears the corresponding bit while
4599  * returning also.
4600  *
4601  * This function waits for the specific bit indefinitely in a tight loop, with
4602  * out any delay in between. USE IT CAUTIOUSLY.
4603  *
4604  * \param   hEdmaResMgr     [IN]        Handle to the previously opened Resource
4605  *                                      Manager Instance.
4606  * \param   tccNo           [IN]        TCC, specific to which the function
4607  *                                      waits on a IPR/IPRH bit.
4608  *
4609  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
4610  *
4611  * \note    This function is re-entrant for different tccNo.
4612  *
4613  */
4614 EDMA3_RM_Result EDMA3_RM_waitAndClearTcc (EDMA3_RM_Handle hEdmaResMgr,
4615                     unsigned int tccNo)
4616     {
4617     EDMA3_RM_Result result = EDMA3_RM_SOK;
4618     EDMA3_RM_Instance *rmInstance = NULL;
4619     EDMA3_RM_Obj *rmObj = NULL;
4620     volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4621     volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
4622     unsigned int tccBitMask = 0x0u;
4625 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4626     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4627                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4628                 EDMA3_DVT_dCOUNTER,
4629                 EDMA3_DVT_dNONE,
4630                 EDMA3_DVT_dNONE));
4631 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4634         /* If parameter checking is enabled... */
4635 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4636     if (hEdmaResMgr == NULL)
4637         {
4638         result = (EDMA3_RM_E_INVALID_PARAM);
4639         }
4640 #endif
4642         /* Check if the parameters are OK. */
4643         if (EDMA3_RM_SOK == result)
4644         {
4645         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4646         rmObj = rmInstance->pResMgrObjHandle;
4648         if ((rmObj == NULL) || (rmObj->gblCfgParams.globalRegs == NULL))
4649             {
4650             result = (EDMA3_RM_E_INVALID_PARAM);
4651             }
4652         else
4653             {
4654                         /* If parameter checking is enabled... */
4655 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4656             if (tccNo >= rmObj->gblCfgParams.numTccs)
4657                 {
4658                 result = (EDMA3_RM_E_INVALID_PARAM);
4659                 }
4660 #endif
4662                         /* Check if the parameters are OK. */
4663                         if (EDMA3_RM_SOK == result)
4664                         {
4665                 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4666                 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
4667                                         (&globalRegs->SHADOW[rmInstance->initParam.regionId]);
4670                 if (shadowRegs != NULL)
4671                     {
4672                     if(tccNo < 32u)
4673                         {
4674                         tccBitMask = (1u << tccNo);
4676                         /* Check the status of the IPR[tccNo] bit. */
4677                         while (FALSE == (shadowRegs->IPR & tccBitMask))
4678                             {
4679                             /* Transfer not yet completed, bit not SET */
4680                             }
4682                         /**
4683                          * Bit found SET, transfer is completed,
4684                          * clear the pending interrupt and return.
4685                          */
4686                         shadowRegs->ICR = tccBitMask;
4687                         }
4688                     else
4689                         {
4690                         tccBitMask = (1u << (tccNo - 32u));
4692                         /* Check the status of the IPRH[tccNo-32] bit. */
4693                         while (FALSE == (shadowRegs->IPRH & tccBitMask))
4694                             {
4695                             /* Transfer not yet completed, bit not SET */
4696                             }
4698                         /**
4699                          * Bit found SET, transfer is completed,
4700                          * clear the pending interrupt and return.
4701                          */
4702                         shadowRegs->ICRH = tccBitMask;
4703                         }
4704                     }
4705                 }
4706             }
4707         }
4710 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4711     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4712                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4713                 EDMA3_DVT_dCOUNTER,
4714                 EDMA3_DVT_dNONE,
4715                 EDMA3_DVT_dNONE));
4716 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4719     return result;
4720     }
4725 /**\fn      EDMA3_RM_Result EDMA3_RM_checkAndClearTcc (EDMA3_RM_Handle
4726  *                        hEdmaResMgr, unsigned int tccNo,
4727  *                       unsigned short *tccStatus)
4728  * \brief   Returns the status of a previously initiated transfer.
4729  *
4730  * This is a non-blocking function that returns the status of a previously
4731  * initiated transfer, based on the IPR/IPRH bit. This bit corresponds to
4732  * the tccNo specified by the user. It clears the corresponding bit, if SET,
4733  * while returning also.
4734  *
4735  * \param   hEdmaResMgr     [IN]        Handle to the previously opened Resource
4736  *                                      Manager Instance.
4737  * \param   tccNo           [IN]        TCC, specific to which the function
4738  *                                      checks the status of the IPR/IPRH bit.
4739  * \param   tccStatus       [IN/OUT]    Status of the transfer is returned here.
4740  *                                      Returns "TRUE" if the transfer has
4741  *                                      completed (IPR/IPRH bit SET),
4742  *                                      "FALSE" if the transfer has not
4743  *                                      completed successfully (IPR/IPRH bit
4744  *                                      NOT SET).
4745  *
4746  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
4747  *
4748  * \note    This function is re-entrant for different tccNo.
4749  */
4750 EDMA3_RM_Result EDMA3_RM_checkAndClearTcc (EDMA3_RM_Handle hEdmaResMgr,
4751                     unsigned int tccNo,
4752                     unsigned short *tccStatus)
4753     {
4754     EDMA3_RM_Result result = EDMA3_RM_SOK;
4755     EDMA3_RM_Instance *rmInstance = NULL;
4756     EDMA3_RM_Obj *rmObj = NULL;
4757     volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4758     volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
4759     unsigned int tccBitMask = 0x0u;
4762 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4763     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4764                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4765                 EDMA3_DVT_dCOUNTER,
4766                 EDMA3_DVT_dNONE,
4767                 EDMA3_DVT_dNONE));
4768 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4771         /* If parameter checking is enabled... */
4772 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4773     if ((hEdmaResMgr == NULL) || (tccStatus == NULL))
4774         {
4775         result = (EDMA3_RM_E_INVALID_PARAM);
4776         }
4777 #endif
4779         /* Check if the parameters are OK. */
4780         if (EDMA3_RM_SOK == result)
4781         {
4782         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4783         rmObj = rmInstance->pResMgrObjHandle;
4785         if ((rmObj == NULL) || (rmObj->gblCfgParams.globalRegs == NULL))
4786             {
4787             result = (EDMA3_RM_E_INVALID_PARAM);
4788             }
4789         else
4790             {
4791                         /* If parameter checking is enabled... */
4792 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4793             if (tccNo >= rmObj->gblCfgParams.numTccs)
4794                 {
4795                 result = (EDMA3_RM_E_INVALID_PARAM);
4796                 }
4797 #endif
4799                         /* Check if the parameters are OK. */
4800                         if (EDMA3_RM_SOK == result)
4801                 {
4802                 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4803                 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
4804                                         (&globalRegs->SHADOW[rmInstance->initParam.regionId]);
4806                 /* Reset the tccStatus */
4807                 *tccStatus = FALSE;
4809                 if (shadowRegs != NULL)
4810                     {
4811                     if(tccNo < 32u)
4812                         {
4813                         tccBitMask = (1u << tccNo);
4815                         /* Check the status of the IPR[tccNo] bit. */
4816                         if ((shadowRegs->IPR & tccBitMask) != FALSE)
4817                             {
4818                             /* Transfer completed, bit found SET */
4819                             *tccStatus = TRUE;
4821                             /* Clear the pending interrupt also. */
4822                             shadowRegs->ICR = tccBitMask;
4823                             }
4824                         }
4825                     else
4826                         {
4827                         tccBitMask = (1u << (tccNo - 32u));
4829                         /* Check the status of the IPRH[tccNo-32] bit. */
4830                         if ((shadowRegs->IPRH & tccBitMask) != FALSE)
4831                             {
4832                             /* Transfer completed, bit found SET */
4833                             *tccStatus = TRUE;
4835                             /* Clear the pending interrupt also. */
4836                             shadowRegs->ICRH = tccBitMask;
4837                             }
4838                         }
4839                     }
4840                 }
4841             }
4842         }
4845 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4846     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4847                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4848                 EDMA3_DVT_dCOUNTER,
4849                 EDMA3_DVT_dNONE,
4850                 EDMA3_DVT_dNONE));
4851 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4854     return result;
4855     }
4859 /**\fn      EDMA3_RM_Result EDMA3_RM_setPaRAM (EDMA3_RM_Handle hEdmaResMgr,
4860  *                        EDMA3_RM_ResDesc *lChObj,
4861  *                       const EDMA3_RM_PaRAMRegs *newPaRAM)
4862  * \brief   Copy the user specified PaRAM Set onto the PaRAM Set
4863  *          associated with the logical channel (DMA/QDMA/Link).
4864  *
4865  * This API takes a PaRAM Set as input and copies it onto the actual PaRAM Set
4866  * associated with the logical channel. OPT field of the PaRAM Set is written
4867  * first and the CCNT field is written last.
4868  *
4869  * Caution: It should be used carefully when programming the QDMA channels whose
4870  *          trigger words are not CCNT field.
4871  *
4872  * \param   hEdmaResMgr     [IN]        Handle to the previously opened Resource
4873  *                                      Manager Instance.
4874  * \param   lChObj          [IN]        Logical Channel object for which new
4875  *                                      PaRAM set is specified. User should pass
4876  *                                      the resource type and id in this object.
4877  * \param   newPaRAM        [IN]        PaRAM set to be copied onto existing one
4878  *
4879  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
4880  *
4881  * \note    This function is re-entrant for unique lChObj values. It is non-
4882  *          re-entrant for same lChObj value.
4883  */
4884 EDMA3_RM_Result EDMA3_RM_setPaRAM (EDMA3_RM_Handle hEdmaResMgr,
4885                         EDMA3_RM_ResDesc *lChObj,
4886                         const EDMA3_RM_PaRAMRegs *newPaRAM)
4887     {
4888     EDMA3_RM_Result result = EDMA3_RM_SOK;
4889     EDMA3_RM_Instance *rmInstance = NULL;
4890     EDMA3_RM_Obj *rmObj = NULL;
4891     int paRAMId = 0u;
4892     unsigned int qdmaChId = 0u;
4893     volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4894         unsigned int edma3Id;
4896 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4897     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4898     EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4899     EDMA3_DVT_dCOUNTER,
4900     EDMA3_DVT_dNONE,
4901     EDMA3_DVT_dNONE));
4902 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4904         /* If parameter checking is enabled... */
4905 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4906     if (hEdmaResMgr == NULL)
4907         {
4908         result = EDMA3_RM_E_INVALID_PARAM;
4909         }
4911     if ((lChObj == NULL) || (newPaRAM == NULL))
4912         {
4913         result = EDMA3_RM_E_INVALID_PARAM;
4914         }
4915 #endif
4917         /* Check if the parameters are OK. */
4918     if (result == EDMA3_RM_SOK)
4919         {
4920         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4922         if (rmInstance == NULL)
4923             {
4924             result = EDMA3_RM_E_INVALID_PARAM;
4925             }
4926         }
4928     if (result == EDMA3_RM_SOK)
4929         {
4930         rmObj = rmInstance->pResMgrObjHandle;
4932         if (rmObj == NULL)
4933             {
4934             result = EDMA3_RM_E_INVALID_PARAM;
4935             }
4936         else
4937             {
4938             if (rmObj->gblCfgParams.globalRegs == NULL)
4939                 {
4940                 result = EDMA3_RM_E_INVALID_PARAM;
4941                 }
4942             }
4943         }
4945     if (result == EDMA3_RM_SOK)
4946         {
4947         edma3Id = rmObj->phyCtrllerInstId;
4948         globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4950         switch (lChObj->type)
4951             {
4952             case EDMA3_RM_RES_DMA_CHANNEL:
4953                 {
4954                 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4955                     {
4956                     paRAMId = edma3RmChBoundRes[edma3Id][lChObj->resId].paRAMId;
4957                     }
4958                 else
4959                     {
4960                     result = EDMA3_RM_E_INVALID_PARAM;
4961                     }
4962                 }
4963                 break;
4965             case EDMA3_RM_RES_QDMA_CHANNEL:
4966                 {
4967                 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4968                     {
4969                     qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4970                     paRAMId = edma3RmChBoundRes[edma3Id][qdmaChId].paRAMId;
4971                     }
4972                 else
4973                     {
4974                     result = EDMA3_RM_E_INVALID_PARAM;
4975                     }
4976                 }
4977                 break;
4979             case EDMA3_RM_RES_PARAM_SET:
4980                 {
4981                 if (lChObj->resId < edma3NumPaRAMSets)
4982                     {
4983                     /**
4984                      * User has passed the actual param set value here.
4985                      * Use this value only
4986                      */
4987                     paRAMId = (int)(lChObj->resId);
4988                     }
4989                 else
4990                     {
4991                     result = EDMA3_RM_E_INVALID_PARAM;
4992                     }
4993                 }
4994                 break;
4996             default:
4997                 result = EDMA3_RM_E_INVALID_PARAM;
4998             }
4999         }
5002     if (result == EDMA3_RM_SOK)
5003         {
5004         /* Check the param id first. */
5005         if ((paRAMId != -1) && ((unsigned int)paRAMId < edma3NumPaRAMSets))
5006             {
5007             /* Set the PaRAM Set now. */
5008             edma3ParamCpy ((void *)(&(globalRegs->PARAMENTRY[paRAMId].OPT)),
5009                                 (const void *)newPaRAM);
5010             }
5011         else
5012             {
5013             result = EDMA3_RM_E_INVALID_PARAM;
5014             }
5015         }
5018 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5019     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5020                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5021                 EDMA3_DVT_dCOUNTER,
5022                 EDMA3_DVT_dNONE,
5023                 EDMA3_DVT_dNONE));
5024 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5026     return result;
5027     }
5031 /**\fn      EDMA3_RM_Result EDMA3_RM_getPaRAM (EDMA3_RM_Handle hEdmaResMgr,
5032  *                   EDMA3_RM_ResDesc *lChObj,
5033  *                   EDMA3_RM_PaRAMRegs *currPaRAM)
5034  * \brief   Retrieve existing PaRAM set associated with specified logical
5035  *          channel (DMA/QDMA/Link).
5036  *
5037  * \param   hEdmaResMgr     [IN]        Handle to the previously opened Resource
5038  *                                      Manager Instance.
5039  * \param   lChObj          [IN]        Logical Channel object for which the
5040  *                                      PaRAM set is requested. User should pass
5041  *                                      the resource type and id in this object.
5042  * \param   currPaRAM       [IN/OUT]    User gets the existing PaRAM here.
5043  *
5044  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
5045  *
5046  * \note    This function is re-entrant.
5047  */
5048 EDMA3_RM_Result EDMA3_RM_getPaRAM (EDMA3_RM_Handle hEdmaResMgr,
5049                     EDMA3_RM_ResDesc *lChObj,
5050                     EDMA3_RM_PaRAMRegs *currPaRAM)
5051     {
5052     EDMA3_RM_Result result = EDMA3_RM_SOK;
5053     EDMA3_RM_Instance *rmInstance = NULL;
5054     EDMA3_RM_Obj *rmObj = NULL;
5055     int paRAMId = 0u;
5056     unsigned int qdmaChId = 0u;
5057     volatile EDMA3_CCRL_Regs *globalRegs = NULL;
5058         unsigned int edma3Id;
5060 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5061     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5062     EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
5063     EDMA3_DVT_dCOUNTER,
5064     EDMA3_DVT_dNONE,
5065     EDMA3_DVT_dNONE));
5066 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5068         /* If parameter checking is enabled... */
5069 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5070     if (hEdmaResMgr == NULL)
5071         {
5072         result = EDMA3_RM_E_INVALID_PARAM;
5073         }
5075     if ((lChObj == NULL) || (currPaRAM == NULL))
5076         {
5077         result = EDMA3_RM_E_INVALID_PARAM;
5078         }
5079 #endif
5081         /* Check if the parameters are OK. */
5082     if (result == EDMA3_RM_SOK)
5083         {
5084         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
5086         if (rmInstance == NULL)
5087             {
5088             result = EDMA3_RM_E_INVALID_PARAM;
5089             }
5090         }
5092     if (result == EDMA3_RM_SOK)
5093         {
5094         rmObj = rmInstance->pResMgrObjHandle;
5096         if (rmObj == NULL)
5097             {
5098             result = EDMA3_RM_E_INVALID_PARAM;
5099             }
5100         else
5101             {
5102             if (rmObj->gblCfgParams.globalRegs == NULL)
5103                 {
5104                 result = EDMA3_RM_E_INVALID_PARAM;
5105                 }
5106             }
5107         }
5109     if (result == EDMA3_RM_SOK)
5110         {
5111         edma3Id = rmObj->phyCtrllerInstId;
5112         globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
5114         switch (lChObj->type)
5115             {
5116             case EDMA3_RM_RES_DMA_CHANNEL:
5117                 {
5118                 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
5119                     {
5120                     paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][lChObj->resId].paRAMId;
5121                     }
5122                 else
5123                     {
5124                     result = EDMA3_RM_E_INVALID_PARAM;
5125                     }
5126                 }
5127                 break;
5129             case EDMA3_RM_RES_QDMA_CHANNEL:
5130                 {
5131                 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
5132                     {
5133                     qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
5134                     paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId;
5135                     }
5136                 else
5137                     {
5138                     result = EDMA3_RM_E_INVALID_PARAM;
5139                     }
5140                 }
5141                 break;
5143             case EDMA3_RM_RES_PARAM_SET:
5144                 {
5145                 if (lChObj->resId < edma3NumPaRAMSets)
5146                     {
5147                     /**
5148                      * User has passed the actual param set value here.
5149                      * Use this value only
5150                      */
5151                     paRAMId = (int)(lChObj->resId);
5152                     }
5153                 else
5154                     {
5155                     result = EDMA3_RM_E_INVALID_PARAM;
5156                     }
5157                 }
5158                 break;
5160             default:
5161                 result = EDMA3_RM_E_INVALID_PARAM;
5162             }
5163         }
5166     if (result == EDMA3_RM_SOK)
5167         {
5168         /* Check the param id first. */
5169         if ((paRAMId != -1) && (paRAMId < edma3NumPaRAMSets))
5170             {
5171             /* Get the PaRAM Set now. */
5172             edma3ParamCpy ((void *)currPaRAM ,
5173                                         (const void *)(&(globalRegs->PARAMENTRY [paRAMId].OPT)));
5174             }
5175         else
5176             {
5177             result = EDMA3_RM_E_INVALID_PARAM;
5178             }
5179         }
5182 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5183     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5184                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5185                 EDMA3_DVT_dCOUNTER,
5186                 EDMA3_DVT_dNONE,
5187                 EDMA3_DVT_dNONE));
5188 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5191     return result;
5192     }
5195 /**\fn      EDMA3_RM_Result EDMA3_RM_getPaRAMPhyAddr(EDMA3_RM_Handle
5196  *                           hEdmaResMgr, EDMA3_RM_ResDesc *lChObj,
5197  *                           unsigned int *paramPhyAddr)
5198  * \brief   Get the PaRAM Set Physical Address associated with a logical channel
5199  *
5200  * This function returns the PaRAM Set Phy Address (unsigned 32 bits).
5201  * The returned address could be used by the advanced users to program the
5202  * PaRAM Set directly without using any APIs.
5203  *
5204  * Least significant 16 bits of this address could be used to program
5205  * the LINK field in the PaRAM Set.
5206  * Users which program the LINK field directly SHOULD use this API
5207  * to get the associated PaRAM Set address with the LINK channel.
5208  *
5209  * \param   hEdmaResMgr     [IN]        Handle to the previously opened Resource
5210  *                                      Manager Instance.
5211  * \param   lChObj          [IN]        Logical Channel object for which the
5212  *                                      PaRAM set physical address is required.
5213  *                                      User should pass the resource type and
5214  *                                      id in this object.
5215  * \param   paramPhyAddr [IN/OUT]       PaRAM Set physical address is returned
5216  *                                      here.
5217  *
5218  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
5219  *
5220  * \note    This function is re-entrant.
5221  */
5222 EDMA3_RM_Result EDMA3_RM_getPaRAMPhyAddr(EDMA3_RM_Handle hEdmaResMgr,
5223                     EDMA3_RM_ResDesc *lChObj,
5224                     unsigned int *paramPhyAddr)
5225     {
5226     EDMA3_RM_Result result = EDMA3_RM_SOK;
5227     EDMA3_RM_Instance *rmInstance = NULL;
5228     EDMA3_RM_Obj *rmObj = NULL;
5229     int paRAMId = 0u;
5230     unsigned int qdmaChId = 0u;
5231     volatile EDMA3_CCRL_Regs *globalRegs = NULL;
5232         unsigned int edma3Id;
5234 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5235     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5236                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
5237                 EDMA3_DVT_dCOUNTER,
5238                 EDMA3_DVT_dNONE,
5239                 EDMA3_DVT_dNONE));
5240 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5243         /* If parameter checking is enabled... */
5244 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5245     if (hEdmaResMgr == NULL)
5246         {
5247         result = EDMA3_RM_E_INVALID_PARAM;
5248         }
5250     if ((lChObj == NULL) || (paramPhyAddr == NULL))
5251         {
5252         result = EDMA3_RM_E_INVALID_PARAM;
5253         }
5254 #endif
5256     if (result == EDMA3_RM_SOK)
5257         {
5258         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
5260         if (rmInstance == NULL)
5261             {
5262             result = EDMA3_RM_E_INVALID_PARAM;
5263             }
5264         }
5266     if (result == EDMA3_RM_SOK)
5267         {
5268         rmObj = rmInstance->pResMgrObjHandle;
5270         if (rmObj == NULL)
5271             {
5272             result = EDMA3_RM_E_INVALID_PARAM;
5273             }
5274         else
5275             {
5276             if (rmObj->gblCfgParams.globalRegs == NULL)
5277                 {
5278                 result = EDMA3_RM_E_INVALID_PARAM;
5279                 }
5280             }
5281         }
5283     if (result == EDMA3_RM_SOK)
5284         {
5285                 edma3Id = rmObj->phyCtrllerInstId;
5286                 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
5288         switch (lChObj->type)
5289             {
5290             case EDMA3_RM_RES_DMA_CHANNEL:
5291                 {
5292                 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
5293                     {
5294                     paRAMId = edma3RmChBoundRes[edma3Id][lChObj->resId].paRAMId;
5295                     }
5296                 else
5297                     {
5298                     result = EDMA3_RM_E_INVALID_PARAM;
5299                     }
5300                 }
5301                 break;
5303             case EDMA3_RM_RES_QDMA_CHANNEL:
5304                 {
5305                 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
5306                     {
5307                     qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
5308                     paRAMId = edma3RmChBoundRes[edma3Id][qdmaChId].paRAMId;
5309                     }
5310                 else
5311                     {
5312                     result = EDMA3_RM_E_INVALID_PARAM;
5313                     }
5314                 }
5315                 break;
5317             case EDMA3_RM_RES_PARAM_SET:
5318                 {
5319                 if (lChObj->resId < edma3NumPaRAMSets)
5320                     {
5321                     /**
5322                      * User has passed the actual param set value here.
5323                      * Use this value only
5324                      */
5325                     paRAMId = (int)(lChObj->resId);
5326                     }
5327                 else
5328                     {
5329                     result = EDMA3_RM_E_INVALID_PARAM;
5330                     }
5331                 }
5332                 break;
5334             default:
5335                 result = EDMA3_RM_E_INVALID_PARAM;
5336             }
5337         }
5341     if (result == EDMA3_RM_SOK)
5342         {
5343         /* Check the param id first. */
5344         if ((paRAMId != -1) && (paRAMId < edma3NumPaRAMSets))
5345             {
5346             /* Get the PaRAM Set Address now. */
5347             *paramPhyAddr = (unsigned int)(&(globalRegs->PARAMENTRY [paRAMId].OPT));
5348             }
5349         else
5350             {
5351             result = EDMA3_RM_E_INVALID_PARAM;
5352             }
5353         }
5355 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5356     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5357                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5358                 EDMA3_DVT_dCOUNTER,
5359                 EDMA3_DVT_dNONE,
5360                 EDMA3_DVT_dNONE));
5361 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5363     return result;
5364     }
5367 /**\fn      EDMA3_RM_Result EDMA3_RM_getBaseAddress (EDMA3_RM_Handle
5368  *                   hEdmaResMgr, EDMA3_RM_Cntrlr_PhyAddr controllerId,
5369  *                   unsigned int *phyAddress)
5370  * \brief   Get the Channel Controller or Transfer Controller (n) Physical
5371  *          Address.
5372  *
5373  * \param   hEdmaResMgr     [IN]        Handle to the previously opened Resource
5374  *                                      Manager Instance.
5375  * \param   controllerId    [IN]        Channel Controller or Transfer
5376  *                                      Controller (n) for which the physical
5377  *                                      address is required.
5378  * \param   phyAddress      [IN/OUT]    Physical address is returned here.
5379  *
5380  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
5381  *
5382  * \note    This function is re-entrant.
5383  */
5384 EDMA3_RM_Result EDMA3_RM_getBaseAddress (EDMA3_RM_Handle hEdmaResMgr,
5385                     EDMA3_RM_Cntrlr_PhyAddr controllerId,
5386                     unsigned int *phyAddress)
5387     {
5388     EDMA3_RM_Result result = EDMA3_RM_SOK;
5389     EDMA3_RM_Instance *rmInstance = NULL;
5390     EDMA3_RM_Obj *rmObj = NULL;
5392 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5393     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5394                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
5395                 EDMA3_DVT_dCOUNTER,
5396                 EDMA3_DVT_dNONE,
5397                 EDMA3_DVT_dNONE));
5398 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5401         /* If parameter checking is enabled... */
5402 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5403     if ((hEdmaResMgr == NULL) || (phyAddress == NULL))
5404         {
5405         result = EDMA3_RM_E_INVALID_PARAM;
5406         }
5407 #endif
5409     if (result == EDMA3_RM_SOK)
5410         {
5411         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
5413         if (rmInstance == NULL)
5414             {
5415             result = EDMA3_RM_E_INVALID_PARAM;
5416             }
5417         }
5419     if (result == EDMA3_RM_SOK)
5420         {
5421         rmObj = rmInstance->pResMgrObjHandle;
5423         if (rmObj == NULL)
5424             {
5425             result = EDMA3_RM_E_INVALID_PARAM;
5426             }
5427         }
5429     if (result == EDMA3_RM_SOK)
5430         {
5431                 /* If parameter checking is enabled... */
5432 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5433         /* Verify the 'controllerId' */
5434         if ((controllerId < ((EDMA3_RM_Cntrlr_PhyAddr)(EDMA3_RM_CC_PHY_ADDR)))
5435             || (controllerId > (EDMA3_RM_Cntrlr_PhyAddr)(rmObj->gblCfgParams.numTcs)))
5436             {
5437             /* Invalid controllerId */
5438             result = EDMA3_RM_E_INVALID_PARAM;
5439             }
5440 #endif
5442                 /* Check if the parameters are OK. */
5443                 if (EDMA3_RM_SOK == result)
5444             {
5445             if (controllerId == EDMA3_RM_CC_PHY_ADDR)
5446                 {
5447                 /* EDMA3 Channel Controller Address */
5448                 *phyAddress = (unsigned int)(rmObj->gblCfgParams.globalRegs);
5449                 }
5450             else
5451                 {
5452                 /**
5453                  * Since the TCs enum start from 1, and TCs start from 0,
5454                  * subtract 1 from the enum to get the actual address.
5455                  */
5456                 *phyAddress = (unsigned int)(rmObj->gblCfgParams.tcRegs[controllerId-1u]);
5457                 }
5458             }
5459         }
5461 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5462     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5463                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5464                 EDMA3_DVT_dCOUNTER,
5465                 EDMA3_DVT_dNONE,
5466                 EDMA3_DVT_dNONE));
5467 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5469     return result;
5470     }
5475 /**\fn      EDMA3_RM_Result EDMA3_RM_getGblConfigParams (unsigned int phyCtrllerInstId,
5476  *                                        EDMA3_RM_GblConfigParams *gblCfgParams)
5477  * \brief   Get the SoC specific configuration structure for the EDMA3 Hardware.
5478  *
5479  * This API is used to fetch the global SoC specific configuration structure
5480  * for the EDMA3 Hardware. It is useful for the user who has not passed
5481  * this information during EDMA3_RM_create() and taken the default configuration
5482  * coming along with the package.
5483  *
5484  * \param phyCtrllerInstId  [IN]    EDMA3 Controller Instance Id
5485  *                                 (Hardware instance id, starting from 0).
5486  * \param gblCfgParams      [IN/OUT]    SoC specific configuration structure for the
5487  *                                  EDMA3 Hardware will be returned here.
5488  *
5489  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
5490  *
5491  * \note    This function is re-entrant.
5492  */
5493 EDMA3_RM_Result EDMA3_RM_getGblConfigParams (
5494                                         unsigned int phyCtrllerInstId,
5495                                         EDMA3_RM_GblConfigParams *gblCfgParams)
5496     {
5497     EDMA3_RM_Result result = EDMA3_RM_SOK;
5499 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5500         EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5501         EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
5502         EDMA3_DVT_dCOUNTER,
5503         EDMA3_DVT_dNONE,
5504         EDMA3_DVT_dNONE));
5505 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5507         /* If parameter checking is enabled... */
5508 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5509     if ((phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
5510         || (NULL == gblCfgParams))
5511         {
5512         result = EDMA3_RM_E_INVALID_PARAM;
5513         }
5514 #endif
5516     if (EDMA3_RM_SOK == result)
5517         {
5518         /* Return the previously saved global config information for the EDMA3 HW */
5519         edma3MemCpy((void *)(gblCfgParams),
5520                                     (const void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
5521                                     sizeof (EDMA3_RM_GblConfigParams));
5522         }
5524 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5525         EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5526                     EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5527                     EDMA3_DVT_dCOUNTER,
5528                     EDMA3_DVT_dNONE,
5529                     EDMA3_DVT_dNONE));
5530 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5532     return result;
5533     }
5537 /**\fn      EDMA3_RM_Result EDMA3_RM_getInstanceInitCfg (EDMA3_RM_Handle hEdmaResMgr,
5538  *                                      EDMA3_RM_InstanceInitConfig *instanceInitConfig)
5539  * \brief   Get the RM Instance specific configuration structure for different
5540  *           EDMA3 resources' usage (owned resources, reserved resources etc).
5541  *
5542  * This API is used to fetch the Resource Manager Instance specific configuration
5543  * structure, for a specific shadow region. It is useful for the user who has not passed
5544  * this information during EDMA3_RM_opn() and taken the default configuration
5545  * coming along with the package. EDMA3 resources, owned and reserved by this RM
5546  * instance, will be returned from this API.
5547  *
5548  * \param   hEdmaResMgr         [IN]    Handle to the previously opened Resource
5549  *                                      Manager Instance.
5550  * \param   instanceInitConfig      [IN/OUT]    RM Instance specific configuration
5551  *                                      structure will be returned here.
5552  *
5553  * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
5554  *
5555  * \note    This function is re-entrant.
5556  */
5557 EDMA3_RM_Result EDMA3_RM_getInstanceInitCfg (
5558                                         EDMA3_RM_Handle hEdmaResMgr,
5559                                         EDMA3_RM_InstanceInitConfig *instanceInitConfig)
5560     {
5561     EDMA3_RM_Result result = EDMA3_RM_SOK;
5562     EDMA3_RM_Instance *rmInstance = NULL;
5563     EDMA3_RM_Obj *rmObj = NULL;
5564     unsigned int resMgrIdx = 0u;
5565     unsigned int hwId;
5567 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5568     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5569                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
5570                 EDMA3_DVT_dCOUNTER,
5571                 EDMA3_DVT_dNONE,
5572                 EDMA3_DVT_dNONE));
5573 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5575         /* If parameter checking is enabled... */
5576 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5577     if ((hEdmaResMgr == NULL) || (instanceInitConfig == NULL))
5578         {
5579         result = EDMA3_RM_E_INVALID_PARAM;
5580         }
5581 #endif
5583     if (result == EDMA3_RM_SOK)
5584         {
5585         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
5587         if (rmInstance == NULL)
5588             {
5589             result = EDMA3_RM_E_INVALID_PARAM;
5590             }
5591         }
5593     if (result == EDMA3_RM_SOK)
5594         {
5595         rmObj = rmInstance->pResMgrObjHandle;
5597         if (rmObj == NULL)
5598             {
5599             result = EDMA3_RM_E_INVALID_PARAM;
5600             }
5601         }
5603     if (result == EDMA3_RM_SOK)
5604         {
5605         hwId = rmObj->phyCtrllerInstId;
5607         for (resMgrIdx = 0u; resMgrIdx < EDMA3_MAX_RM_INSTANCES; resMgrIdx++)
5608             {
5609                 if (rmInstance == ((EDMA3_RM_Instance *)(ptrRMIArray) +
5610                                             (hwId*EDMA3_MAX_RM_INSTANCES) +
5611                                             resMgrIdx))
5612                 {
5613                  /* RM Id found. Return the specific config info to the user. */
5614                 edma3MemCpy((void *)(instanceInitConfig),
5615                                             (const void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) +
5616                                                                     (hwId*EDMA3_MAX_RM_INSTANCES) +
5617                                                                     resMgrIdx),
5618                                             sizeof (EDMA3_RM_InstanceInitConfig));
5619                 break;
5620                 }
5621             }
5623         if (EDMA3_MAX_RM_INSTANCES == resMgrIdx)
5624             {
5625             /* RM Id not found, report error... */
5626             result = EDMA3_RM_E_INVALID_PARAM;
5627             }
5628         }
5630 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5631     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5632                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5633                 EDMA3_DVT_dCOUNTER,
5634                 EDMA3_DVT_dNONE,
5635                 EDMA3_DVT_dNONE));
5636 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5638     return result;
5639     }
5643 /**
5644  *  \brief EDMA3 Resource Manager IOCTL
5645  *
5646  *  This function provides IOCTL functionality for EDMA3 Resource Manager
5647  *
5648  *  \param  hEdmaResMgr      [IN]       Handle to the previously opened Resource
5649  *                                      Manager Instance.
5650  *  \param  cmd             [IN]        IOCTL command to be performed
5651  *  \param  cmdArg          [IN/OUT]    IOCTL command argument (if any)
5652  *  \param  param           [IN/OUT]    Device/Cmd specific argument
5653  *
5654  *  \return EDMA3_RM_SOK or EDMA3_RM Error Code
5655  */
5656 EDMA3_RM_Result EDMA3_RM_Ioctl(
5657                       EDMA3_RM_Handle       hEdmaResMgr,
5658                       EDMA3_RM_IoctlCmd     cmd,
5659                       void                  *cmdArg,
5660                       void                  *param
5661                      )
5662     {
5663     EDMA3_RM_Result result = EDMA3_RM_SOK;
5664     EDMA3_RM_Instance *rmInstance = NULL;
5665     unsigned int paramInitRequired = 0xFFu;
5666     unsigned int regModificationRequired = 0xFFu;
5667     unsigned int *ret_val = NULL;
5669 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5670     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5671                 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
5672                 EDMA3_DVT_dCOUNTER,
5673                 EDMA3_DVT_dNONE,
5674                 EDMA3_DVT_dNONE));
5675 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5677         /* If parameter checking is enabled... */
5678 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5679     if (hEdmaResMgr == NULL)
5680         {
5681         result = EDMA3_RM_E_INVALID_PARAM;
5682         }
5684     if ((cmd <= EDMA3_RM_IOCTL_MIN_IOCTL)
5685         || (cmd >= EDMA3_RM_IOCTL_MAX_IOCTL))
5686         {
5687         result = EDMA3_RM_E_INVALID_PARAM;
5688         }
5689 #endif
5691     if (result == EDMA3_RM_SOK)
5692         {
5693         rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
5695         if (rmInstance == NULL)
5696             {
5697             result = EDMA3_RM_E_INVALID_PARAM;
5698             }
5699         }
5701     /* To remove CCS warnings */
5702     (void)param;
5704     if (result == EDMA3_RM_SOK)
5705         {
5706         switch (cmd)
5707             {
5708             case EDMA3_RM_IOCTL_SET_PARAM_CLEAR_OPTION:
5709                 {
5710                 paramInitRequired = (unsigned int)cmdArg;
5712                                 /* If parameter checking is enabled... */
5713 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5714                 if ((paramInitRequired != 0u)
5715                     && (paramInitRequired != 1u))
5716                     {
5717                         result = EDMA3_RM_E_INVALID_PARAM;
5718                     }
5719 #endif
5721                                 /* Check if the parameters are OK. */
5722                                 if (EDMA3_RM_SOK == result)
5723                                         {
5724                     /* Set/Reset the flag which is being used to do the PaRAM clearing. */
5725                     rmInstance->paramInitRequired = paramInitRequired;
5726                         }
5728                 break;
5729                 }
5731             case EDMA3_RM_IOCTL_GET_PARAM_CLEAR_OPTION:
5732                 {
5733                                 /* If parameter checking is enabled... */
5734 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5735                 if (NULL == cmdArg)
5736                     {
5737                     result = EDMA3_RM_E_INVALID_PARAM;
5738                     }
5739 #endif
5741                                 /* Check if the parameters are OK. */
5742                                 if (EDMA3_RM_SOK == result)
5743                     {
5744                     ret_val = (unsigned int *)cmdArg;
5746                     /* Get the flag which is being used to do the PaRAM clearing. */
5747                     *ret_val = rmInstance->paramInitRequired;
5748                     }
5750                 break;
5751                 }
5753             case EDMA3_RM_IOCTL_SET_GBL_REG_MODIFY_OPTION:
5754                 {
5755                 regModificationRequired = (unsigned int)cmdArg;
5757                                 /* If parameter checking is enabled... */
5758 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5759                 if ((regModificationRequired != 0u)
5760                     && (regModificationRequired != 1u))
5761                     {
5762                     /* All other values are invalid. */
5763                     result = EDMA3_RM_E_INVALID_PARAM;
5764                     }
5765 #endif
5767                                 /* Check if the parameters are OK. */
5768                                 if (EDMA3_RM_SOK == result)
5769                                         {
5770                     /**
5771                      * Set/Reset the flag which is being used to do the global
5772                      * registers and PaRAM modification.
5773                      */
5774                     rmInstance->regModificationRequired = regModificationRequired;
5775                         }
5777                 break;
5778                 }
5780             case EDMA3_RM_IOCTL_GET_GBL_REG_MODIFY_OPTION:
5781                 {
5782                                 /* If parameter checking is enabled... */
5783 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5784                 if (NULL == cmdArg)
5785                     {
5786                     result = EDMA3_RM_E_INVALID_PARAM;
5787                     }
5788 #endif
5790                                 /* Check if the parameters are OK. */
5791                                 if (EDMA3_RM_SOK == result)
5792                     {
5793                     ret_val = (unsigned int *)cmdArg;
5795                     /**
5796                      * Get the flag which is being used to do the global
5797                      * registers and PaRAM modification.
5798                      */
5799                     *ret_val = rmInstance->regModificationRequired;
5800                     }
5802                 break;
5803                 }
5805             default:
5806                 /* Hey dude! you passed invalid IOCTL cmd */
5807                 result = EDMA3_RM_E_INVALID_PARAM;
5809             }
5810         }
5813 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5814         EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5815                     EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5816                     EDMA3_DVT_dCOUNTER,
5817                     EDMA3_DVT_dNONE,
5818                     EDMA3_DVT_dNONE));
5819 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5821         return result;
5823     }
5827 /**
5828  * edma3ComplHandler
5829  * \brief   Interrupt handler for successful transfer completion.
5830  *
5831  * \note    This function first disables its own interrupt to make it non-
5832  *          entrant. Later, after calling all the callback functions, it
5833  *          re-enables its own interrupt.
5834  *
5835  * \return  None.
5836  */
5837 static void edma3ComplHandler (const EDMA3_RM_Obj *rmObj)
5838     {
5839     unsigned int Cnt;
5840     volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
5841     volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
5842     volatile unsigned int pendingIrqs;
5843     unsigned int indexl;
5844     unsigned int indexh;
5845         unsigned int edma3Id;
5847 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5848     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5849                 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5850                 EDMA3_DVT_dNONE,
5851                 EDMA3_DVT_dNONE,
5852                 EDMA3_DVT_dNONE));
5853 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5855     assert (NULL != rmObj);
5857     edma3Id = rmObj->phyCtrllerInstId;
5858     ptrEdmaccRegs =
5859             (volatile EDMA3_CCRL_Regs *)rmObj->gblCfgParams.globalRegs;
5860     if (ptrEdmaccRegs != NULL)
5861         {
5862         shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
5863                                     (&ptrEdmaccRegs->SHADOW[edma3RegionId]);
5864         }
5866     Cnt = 0u;
5867     pendingIrqs = 0u;
5868     indexl = 1u;
5869     indexh = 1u;
5871     if((shadowRegs->IPR !=0 ) || (shadowRegs->IPRH !=0 ))
5872         {
5873         /**
5874          * Since an interrupt has found, we have to make sure that this
5875          * interrupt (TCC) belongs to the TCCs allocated by us only.
5876          * It might happen that someone else, who is using EDMA3 also,
5877          * is the owner of this interrupt channel i.e. the TCC.
5878          * For this, use the allocatedTCCs[], to check which all interrupt
5879          * channels are owned by the EDMA3 RM Instances.
5880          */
5882         edma3OsProtectEntry (edma3Id,
5883                                                 EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,
5884                                                 NULL);
5886         /* Loop for EDMA3_RM_COMPL_HANDLER_RETRY_COUNT number of time,
5887                    breaks when no pending interrupt is found */
5888         while ((Cnt < EDMA3_RM_COMPL_HANDLER_RETRY_COUNT)
5889                     && ((indexl != 0u) || (indexh != 0u)))
5890             {
5891             indexl = 0u;
5892             pendingIrqs = shadowRegs->IPR;
5894             /**
5895              * Choose interrupts coming from our allocated TCCs
5896              * and MASK remaining ones.
5897              */
5898             pendingIrqs = (pendingIrqs & allocatedTCCs[edma3Id][0u]);
5900             while (pendingIrqs)
5901                 {
5902                 /*Process all the pending interrupts*/
5903                 if((pendingIrqs & 1u) == TRUE)
5904                     {
5905                     /**
5906                      * If the user has not given any callback function
5907                      * while requesting the TCC, its TCC specific bit
5908                      * in the IPR register will NOT be cleared.
5909                      */
5910                     if(edma3IntrParams[edma3Id][indexl].tccCb != NULL)
5911                         {
5912                          /* here write to ICR to clear the corresponding IPR bits*/
5913                         shadowRegs->ICR = (1u << indexl);
5915                         edma3IntrParams[edma3Id][indexl].tccCb (indexl,
5916                                     EDMA3_RM_XFER_COMPLETE,
5917                                     edma3IntrParams[edma3Id][indexl].cbData);
5918                         }
5919                     }
5920                 ++indexl;
5921                 pendingIrqs >>= 1u;
5922                 }
5924             indexh = 0u;
5925             pendingIrqs = shadowRegs->IPRH;
5927             /**
5928              * Choose interrupts coming from our allocated TCCs
5929              * and MASK remaining ones.
5930              */
5931             pendingIrqs = (pendingIrqs & allocatedTCCs[edma3Id][1u]);
5933             while (pendingIrqs)
5934                 {
5935                 /*Process all the pending interrupts*/
5936                 if((pendingIrqs & 1u)==TRUE)
5937                     {
5938                     /**
5939                      * If the user has not given any callback function
5940                      * while requesting the TCC, its TCC specific bit
5941                      * in the IPRH register will NOT be cleared.
5942                      */
5943                     if(edma3IntrParams[edma3Id][32u+indexh].tccCb!=NULL)
5944                         {
5945                          /* here write to ICR to clear the corresponding IPR bits*/
5946                         shadowRegs->ICRH = (1u << indexh);
5948                         edma3IntrParams[edma3Id][32u+indexh].tccCb(32u+indexh,
5949                                     EDMA3_RM_XFER_COMPLETE,
5950                                     edma3IntrParams[edma3Id][32u+indexh].cbData);
5951                         }
5952                     }
5953                 ++indexh;
5954                 pendingIrqs >>= 1u;
5955                 }
5957             Cnt++;
5958             }
5960         indexl = (shadowRegs->IPR & allocatedTCCs[edma3Id][0u]);
5961         indexh = (shadowRegs->IPRH & allocatedTCCs[edma3Id][1u]);
5963         if((indexl !=0 ) || (indexh !=0 ))
5964             {
5965             shadowRegs->IEVAL=0x1u;
5966             }
5968         edma3OsProtectExit (rmObj->phyCtrllerInstId,
5969                                                         EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,
5970                                                         NULL);
5971         }
5973 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5974     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5975                 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5976                 EDMA3_DVT_dNONE,
5977                 EDMA3_DVT_dNONE,
5978                 EDMA3_DVT_dNONE));
5979 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5980     }
5983 void lisrEdma3ComplHandler0(unsigned int edma3InstanceId)
5984     {
5985     /* Invoke Completion Handler ISR */
5986     edma3ComplHandler(&resMgrObj[edma3InstanceId]);
5987     }
5990 /**
5991  * \brief   Interrupt handler for Channel Controller Error.
5992  *
5993  * \note    This function first disables its own interrupt to make it non-
5994  *          entrant. Later, after calling all the callback functions, it
5995  *          re-enables its own interrupt.
5996  *
5997  * \return  None.
5998  */
5999 static void edma3CCErrHandler(const EDMA3_RM_Obj *rmObj)
6000     {
6001     unsigned int Cnt = 0u;
6002     unsigned int resMgrInstIdx = 0u;
6003     volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
6004     volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
6005     volatile unsigned int pendingIrqs;
6006     unsigned int index;
6007     unsigned int evtqueNum;
6008     EDMA3_RM_Instance *rm_instance = NULL;
6009     unsigned int edma3Id;
6010     unsigned int num_rm_instances_opened;
6011     EDMA3_RM_Instance *rmInstance   = NULL;
6012     unsigned int ownedDmaError = 0;
6013     unsigned int ownedDmaHError = 0;
6014     unsigned int ownedQdmaError = 0;
6016 #ifdef EDMA3_INSTRUMENTATION_ENABLED
6017     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_CCERR",
6018                 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
6019                 EDMA3_DVT_dNONE,
6020                 EDMA3_DVT_dNONE,
6021                 EDMA3_DVT_dNONE));
6022 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
6024     assert (rmObj != NULL);
6026     edma3Id = rmObj->phyCtrllerInstId;
6027     ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)rmObj->gblCfgParams.globalRegs;
6028     if (ptrEdmaccRegs != NULL)
6029         {
6030         shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)&ptrEdmaccRegs->SHADOW[edma3RegionId];
6031         rmInstance = ((EDMA3_RM_Instance *)(ptrRMIArray)
6032                             + (edma3Id*EDMA3_MAX_RM_INSTANCES)
6033                             + edma3RegionId);
6035         pendingIrqs = 0u;
6036         index = 1u;
6038         if(((ptrEdmaccRegs->EMR != 0 )
6039             || (ptrEdmaccRegs->EMRH != 0 ))
6040             || ((ptrEdmaccRegs->QEMR != 0)
6041             || (ptrEdmaccRegs->CCERR != 0)))
6042             {
6043             edma3OsProtectEntry (edma3Id,
6044                                                                 EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR,
6045                                                                 NULL);
6047             /* Loop for EDMA3_RM_CCERR_HANDLER_RETRY_COUNT number of time,
6048                            breaks when no pending interrupt is found */
6049             while ((Cnt < EDMA3_RM_CCERR_HANDLER_RETRY_COUNT)
6050                         && (index != 0u))
6051                 {
6052                 index = 0u;
6053                 pendingIrqs = ptrEdmaccRegs->EMR;
6055                 while (pendingIrqs)
6056                     {
6057                     /*Process all the pending interrupts*/
6058                     if((pendingIrqs & 1u)==TRUE)
6059                         {
6060                         unsigned int mappedTcc = 0u;
6062                         /**
6063                          * Using the 'index' value (basically the DMA
6064                          * channel), fetch the corresponding TCC
6065                          * value, mapped to this DMA channel.
6066                          */
6067                         mappedTcc = edma3DmaChTccMapping[edma3Id][index];
6069                         /**
6070                          * Ensure that the mapped tcc is valid and the call
6071                          * back is not NULL
6072                          */
6073                         if (mappedTcc < EDMA3_MAX_TCC)
6074                             {
6075                             /**
6076                              * TCC owned and allocated by RM.
6077                              * Write to EMCR to clear the corresponding EMR bits.
6078                              */
6079                             ptrEdmaccRegs->EMCR = (1u<<index);
6080                             /*Clear any SER*/
6081                             shadowRegs->SECR = (1u<<index);
6083                             /* Call the callback function if registered earlier. */
6084                             if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
6085                                 {
6086                                 edma3IntrParams[edma3Id][mappedTcc].tccCb (
6087                                         mappedTcc,
6088                                         EDMA3_RM_E_CC_DMA_EVT_MISS,
6089                                         edma3IntrParams[edma3Id][mappedTcc].cbData
6090                                         );
6091                                 }
6092                             }
6093                         else
6094                             {
6095                             /**
6096                              * DMA channel not owned by the RM instance.
6097                              * Check the global error interrupt clearing option.
6098                              * If it is TRUE, clear the error interupt else leave
6099                              * it like that.
6100                              */
6101 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
6102                                 /* here write to EMCR to clear the corresponding EMR bits. */
6103                                 ptrEdmaccRegs->EMCR = (1u<<index);
6104                                 /*Clear any SER*/
6105                                 ptrEdmaccRegs->SECR = (1u<<index);
6106 #endif
6107                             }
6108                         }
6109                     ++index;
6110                     pendingIrqs >>= 1u;
6111                     }
6113                 index = 0u;
6114                 pendingIrqs = ptrEdmaccRegs->EMRH;
6115                 while (pendingIrqs)
6116                     {
6117                     /*Process all the pending interrupts*/
6118                     if((pendingIrqs & 1u)==TRUE)
6119                         {
6120                         unsigned int mappedTcc = 0u;
6122                         /**
6123                          * Using the 'index' value (basically the DMA
6124                          * channel), fetch the corresponding TCC
6125                          * value, mapped to this DMA channel.
6126                          */
6127                         mappedTcc = edma3DmaChTccMapping[edma3Id][32u+index];
6129                         /**
6130                          * Ensure that the mapped tcc is valid and the call
6131                          * back is not NULL
6132                          */
6133                         if (mappedTcc < EDMA3_MAX_TCC)
6134                             {
6135                             /**
6136                              * TCC owned and allocated by RM.
6137                              * Write to EMCR to clear the corresponding EMR bits.
6138                              */
6139                             ptrEdmaccRegs->EMCRH = (1u<<index);
6140                             /*Clear any SERH*/
6141                             shadowRegs->SECRH = (1u<<index);
6143                             /* Call the callback function if registered earlier. */
6144                             if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
6145                                 {
6146                                 edma3IntrParams[edma3Id][mappedTcc].tccCb (
6147                                         mappedTcc,
6148                                         EDMA3_RM_E_CC_DMA_EVT_MISS,
6149                                         edma3IntrParams[edma3Id][mappedTcc].cbData
6150                                         );
6151                                 }
6152                             }
6153                         else
6154                             {
6155                             /**
6156                              * DMA channel not owned by the RM instance.
6157                              * Check the global error interrupt clearing option.
6158                              * If it is TRUE, clear the error interupt else leave
6159                              * it like that.
6160                              */
6161 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
6162                                 /**
6163                                  * TCC NOT owned by RM.
6164                                  * Write to EMCRH to clear the corresponding EMRH bits.
6165                                  */
6166                                 ptrEdmaccRegs->EMCRH = (1u<<index);
6167                                 /*Clear any SERH*/
6168                                 shadowRegs->SECRH = (1u<<index);
6169 #endif
6170                             }
6171                         }
6172                     ++index;
6173                     pendingIrqs >>= 1u;
6174                     }
6176                 index = 0u;
6177                 pendingIrqs = ptrEdmaccRegs->QEMR;
6178                 while (pendingIrqs)
6179                     {
6180                     /*Process all the pending interrupts*/
6181                     if((pendingIrqs & 1u)==TRUE)
6182                         {
6183                         unsigned int mappedTcc = 0u;
6185                         /**
6186                          * Using the 'index' value (basically the QDMA
6187                          * channel), fetch the corresponding TCC
6188                          * value, mapped to this QDMA channel.
6189                          */
6190                         mappedTcc = edma3QdmaChTccMapping[edma3Id][index];
6192                         if (mappedTcc < EDMA3_MAX_TCC)
6193                            {
6194                             /* here write to QEMCR to clear the corresponding QEMR bits*/
6195                             ptrEdmaccRegs->QEMCR = (1u<<index);
6196                             /*Clear any QSER*/
6197                             shadowRegs->QSECR = (1u<<index);
6199                             if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
6200                                 {
6201                                 edma3IntrParams[edma3Id][mappedTcc].tccCb (
6202                                         mappedTcc,
6203                                         EDMA3_RM_E_CC_QDMA_EVT_MISS,
6204                                         edma3IntrParams[edma3Id][mappedTcc].cbData
6205                                         );
6206                                 }
6207                             }
6208                         else
6209                             {
6210                             /**
6211                              * QDMA channel not owned by the RM instance.
6212                              * Check the global error interrupt clearing option.
6213                              * If it is TRUE, clear the error interupt else leave
6214                              * the ISR.
6215                              */
6216 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
6217                                 /* here write to QEMCR to clear the corresponding QEMR bits*/
6218                                 ptrEdmaccRegs->QEMCR = (1u<<index);
6220                                 /*Clear any QSER*/
6221                                 ptrEdmaccRegs->QSECR = (1u<<index);
6222 #endif
6223                             }
6224                         }
6225                     ++index;
6226                     pendingIrqs >>= 1u;
6227                     }
6229                 index = 0u;
6230                 pendingIrqs = ptrEdmaccRegs->CCERR;
6231                 if (pendingIrqs!=NULL)
6232                     {
6233                     /* Process all the pending CC error interrupts. */
6235                     /* Queue threshold error for different event queues.*/
6236                     for (evtqueNum = 0u; evtqueNum < rmObj->gblCfgParams.numEvtQueue; evtqueNum++)
6237                         {
6238                         if((pendingIrqs & (1u << evtqueNum)) != NULL)
6239                             {
6240                             /**
6241                              * Queue threshold error for queue 'evtqueNum' raised.
6242                              * Inform all the RM instances working on this region
6243                              * about the error by calling their global callback functions.
6244                              */
6245                             num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
6246                             for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
6247                                 {
6248                                 /* Check whether the RM instance opened working on this region */
6249                                 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
6250                                 if (NULL != rm_instance)
6251                                     {
6252                                     if (rm_instance->initParam.regionId == edma3RegionId)
6253                                         {
6254                                         /* Region id matches, call the callback function */
6255                                         if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
6256                                             {
6257                                             rm_instance->initParam.gblerrCbParams.gblerrCb(
6258                                                     EDMA3_RM_E_CC_QUE_THRES_EXCEED,
6259                                                     evtqueNum,
6260                                                     rm_instance->initParam.gblerrCbParams.gblerrData);
6261                                             }
6262                                         }
6263                                     }
6265                                 /* Check next opened instance */
6266                                 num_rm_instances_opened--;
6267                                 }
6269                             /* Clear the error interrupt. */
6270                             ptrEdmaccRegs->CCERRCLR = (1u << evtqueNum);
6271                             }
6272                         }
6275                     /* Transfer completion code error. */
6276                     if ((pendingIrqs & (1 << EDMA3_CCRL_CCERR_TCCERR_SHIFT))!=NULL)
6277                         {
6278                         /**
6279                          * Transfer completion code error raised.
6280                          * Inform all the RM instances working on this region
6281                          * about the error by calling their global callback functions.
6282                          */
6283                         num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
6284                         for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
6285                             {
6286                             /* Check whether the RM instance opened working on this region */
6287                             rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
6288                             if (NULL != rm_instance)
6289                                 {
6290                                 if (rm_instance->initParam.regionId == edma3RegionId)
6291                                     {
6292                                     /* Region id matches, call the callback function */
6293                                     if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
6294                                         {
6295                                         rm_instance->initParam.gblerrCbParams.gblerrCb(
6296                                                 EDMA3_RM_E_CC_TCC,
6297                                                 NULL,
6298                                                 rm_instance->initParam.gblerrCbParams.gblerrData);
6299                                         }
6300                                     }
6301                                 }
6303                             /* Check next opened instance */
6304                             num_rm_instances_opened--;
6305                             }
6307                         ptrEdmaccRegs->CCERRCLR = (1<<EDMA3_CCRL_CCERR_TCCERR_SHIFT);
6308                         }
6310                     ++index;
6311                     }
6313                 Cnt++;
6314                 }
6317             /**
6318              * Read the error registers again. If any interrupt is pending,
6319              * write the EEVAL register.
6320              * Moreover, according to the global error interrupt clearing
6321              * option, check either error bits associated with all the
6322              * DMA/QDMA channels (option is SET) OR check error bits
6323              * associated with owned DMA/QDMA channels.
6324              */
6325 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
6326                                 /* To remove warning. */
6327                                 rmInstance = rmInstance;
6329                 /* Check all the error bits. */
6330                 ownedDmaError = ptrEdmaccRegs->EMR;
6331                 ownedDmaHError = ptrEdmaccRegs->EMRH;
6332                 ownedQdmaError = ptrEdmaccRegs->QEMR;
6333 #else
6334                 /* Check ONLY owned error bits. */
6335                 ownedDmaError = (ptrEdmaccRegs->EMR & rmInstance->initParam.rmInstInitConfig->ownDmaChannels[0u]);
6336                 ownedDmaHError = (ptrEdmaccRegs->EMRH & rmInstance->initParam.rmInstInitConfig->ownDmaChannels[1u]);
6337                 ownedQdmaError = (ptrEdmaccRegs->QEMR & rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u]);
6338 #endif
6340             if (((ownedDmaError != 0 ) || (ownedDmaHError != 0 ))
6341                         || ((ownedQdmaError != 0) || (ptrEdmaccRegs->CCERR != 0)))
6342                 {
6343                 ptrEdmaccRegs->EEVAL=0x1u;
6344                 }
6346             edma3OsProtectExit (rmObj->phyCtrllerInstId,
6347                                                                 EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR,
6348                                                                 NULL);
6349             }
6350         }
6352 #ifdef EDMA3_INSTRUMENTATION_ENABLED
6353     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_CCERR",
6354                 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
6355                 EDMA3_DVT_dNONE,
6356                 EDMA3_DVT_dNONE,
6357                 EDMA3_DVT_dNONE));
6358 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
6359     }
6361 void lisrEdma3CCErrHandler0(unsigned int edma3InstanceId)
6362     {
6363     /* Invoke CC Error Handler ISR */
6364     edma3CCErrHandler(&resMgrObj[edma3InstanceId]);
6365     }
6369 /**
6370  * \brief   Interrupt handler for Transfer Controller Error.
6371  *
6372  * \note    This function first disables its own interrupt to make it non-
6373  *          entrant. Later, after calling all the callback functions, it
6374  *          re-enables its own interrupt.
6375  *
6376  * \return  None.
6377  */
6378 static void edma3TCErrHandler (const EDMA3_RM_Obj *rmObj, unsigned int tcNum)
6379     {
6380     volatile EDMA3_TCRL_Regs *tcRegs = NULL;
6381     unsigned int tcMemErrRdWr = 0u;
6382     unsigned int resMgrInstIdx = 0u;
6383     EDMA3_RM_Instance *rm_instance = NULL;
6384     unsigned int edma3Id;
6385     unsigned int num_rm_instances_opened;
6387 #ifdef EDMA3_INSTRUMENTATION_ENABLED
6388     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_TCERR",
6389                 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
6390                 EDMA3_DVT_dNONE,
6391                 EDMA3_DVT_dNONE,
6392                 EDMA3_DVT_dNONE));
6393 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
6395     assert ((rmObj != NULL) && (tcNum < rmObj->gblCfgParams.numTcs));
6397     if (rmObj->gblCfgParams.tcRegs[tcNum] != NULL)
6398         {
6399         tcRegs = (volatile EDMA3_TCRL_Regs *)(rmObj->gblCfgParams.tcRegs[tcNum]);
6400         edma3Id = rmObj->phyCtrllerInstId;
6401         }
6403     if (tcRegs != NULL)
6404         {
6405         if(tcRegs->ERRSTAT != 0)
6406             {
6407             edma3OsProtectEntry (rmObj->phyCtrllerInstId,
6408                                                                 EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR,
6409                                                                 &tcNum);
6411             if((tcRegs->ERRSTAT & (1 << EDMA3_TCRL_ERRSTAT_BUSERR_SHIFT))!=NULL)
6412                 {
6413                 /* Bus error event. */
6414                 /**
6415                  * EDMA3TC has detected an error at source or destination
6416                  * address. Error information can be read from the error
6417                  * details register (ERRDET).
6418                  */
6419                 tcMemErrRdWr = tcRegs->ERRDET & (EDMA3_TCRL_ERRDET_STAT_MASK);
6420                 if ((tcMemErrRdWr > 0u) && (tcMemErrRdWr < 8u))
6421                     {
6422                     /**
6423                      * Inform all the RM instances working on this region
6424                      * about the error by calling their global callback functions.
6425                      */
6426                     num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
6427                     for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
6428                         {
6429                         /* Check whether the RM instance opened working on this region */
6430                         rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
6431                         if (NULL != rm_instance)
6432                             {
6433                             if (rm_instance->initParam.regionId == edma3RegionId)
6434                                 {
6435                                 /* Region id matches, call the callback function */
6436                                 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
6437                                     {
6438                                     rm_instance->initParam.gblerrCbParams.gblerrCb(
6439                                             EDMA3_RM_E_TC_MEM_LOCATION_READ_ERROR,
6440                                             tcNum,
6441                                             rm_instance->initParam.gblerrCbParams.gblerrData);
6442                                     }
6443                                 }
6444                             }
6446                             /* Check next opened instance */
6447                             num_rm_instances_opened--;
6448                         }
6449                     }
6450                 else
6451                     {
6452                     if ((tcMemErrRdWr >= 8u) && (tcMemErrRdWr <= 0xFu))
6453                         {
6454                         /**
6455                          * Inform all the RM instances working on this region
6456                          * about the error by calling their global callback functions.
6457                          */
6458                         num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
6459                         for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
6460                             {
6461                             /* Check whether the RM instance opened working on this region */
6462                             rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
6463                             if (NULL != rm_instance)
6464                                 {
6465                                 if (rm_instance->initParam.regionId == edma3RegionId)
6466                                     {
6467                                     /* Region id matches, call the callback function */
6468                                     if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
6469                                         {
6470                                         rm_instance->initParam.gblerrCbParams.gblerrCb(
6471                                                 EDMA3_RM_E_TC_MEM_LOCATION_WRITE_ERROR,
6472                                                 tcNum,
6473                                                 rm_instance->initParam.gblerrCbParams.gblerrData);
6474                                         }
6475                                     }
6476                                 }
6478                                 /* Check next opened instance */
6479                                 num_rm_instances_opened--;
6480                             }
6481                         }
6482                     }
6483                 tcRegs->ERRCLR = (1<<EDMA3_TCRL_ERRSTAT_BUSERR_SHIFT);
6484                 }
6485             else
6486                 {
6487                 /* Transfer request (TR) error event. */
6488                 if((tcRegs->ERRSTAT & (1 << EDMA3_TCRL_ERRSTAT_TRERR_SHIFT))!=NULL)
6489                     {
6490                     num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
6491                     for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
6492                         {
6493                         /* Check whether the RM instance opened working on this region */
6494                         rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
6495                         if (NULL != rm_instance)
6496                             {
6497                             if (rm_instance->initParam.regionId == edma3RegionId)
6498                                 {
6499                                 /* Region id matches, call the callback function */
6500                                 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
6501                                     {
6502                                     rm_instance->initParam.gblerrCbParams.gblerrCb(
6503                                             EDMA3_RM_E_TC_TR_ERROR,
6504                                             tcNum,
6505                                             rm_instance->initParam.gblerrCbParams.gblerrData);
6506                                     }
6507                                 }
6508                             }
6510                             /* Check next opened instance */
6511                             num_rm_instances_opened--;
6512                         }
6514                     tcRegs->ERRCLR = (1<<EDMA3_TCRL_ERRSTAT_TRERR_SHIFT);
6515                     }
6516                 else
6517                     {
6518                     if((tcRegs->ERRSTAT & (1 << EDMA3_TCRL_ERRSTAT_MMRAERR_SHIFT))!=NULL)
6519                         {
6520                         num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
6521                         for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
6522                             {
6523                             /* Check whether the RM instance opened working on this region */
6524                             rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
6525                             if (NULL != rm_instance)
6526                                 {
6527                                 if (rm_instance->initParam.regionId == edma3RegionId)
6528                                     {
6529                                     /* Region id matches, call the callback function */
6530                                     if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
6531                                         {
6532                                         rm_instance->initParam.gblerrCbParams.gblerrCb(
6533                                                 EDMA3_RM_E_TC_INVALID_ADDR,
6534                                                 tcNum,
6535                                                 rm_instance->initParam.gblerrCbParams.gblerrData);
6536                                         }
6537                                     }
6538                                 }
6540                                 /* Check next opened instance */
6541                                 num_rm_instances_opened--;
6542                             }
6544                         tcRegs->ERRCLR = (1<<EDMA3_TCRL_ERRSTAT_MMRAERR_SHIFT);
6545                         }
6546                     }
6547                 }
6549             edma3OsProtectExit (rmObj->phyCtrllerInstId,
6550                                                                 EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR,
6551                                                                 tcNum);
6552             }
6553         }
6555 #ifdef EDMA3_INSTRUMENTATION_ENABLED
6556     EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_TCERR",
6557                 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
6558                 EDMA3_DVT_dNONE,
6559                 EDMA3_DVT_dNONE,
6560                 EDMA3_DVT_dNONE));
6561 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
6562     }
6566 /*
6567  *  ======== lisrEdma3TC0ErrHandler0 ========
6568  *  EDMA3 instance 0 TC0 Error Interrupt Service Routine
6569  */
6570 void lisrEdma3TC0ErrHandler0(unsigned int edma3InstanceId)
6571     {
6572     /* Invoke Error Handler ISR for TC0*/
6573     edma3TCErrHandler(&resMgrObj[edma3InstanceId], 0u);
6574     }
6577 /*
6578  *  ======== lisrEdma3TC1ErrHandler0 ========
6579  *  EDMA3 instance 0 TC1 Error Interrupt Service Routine
6580  */
6581 void lisrEdma3TC1ErrHandler0(unsigned int edma3InstanceId)
6582     {
6583     /* Invoke Error Handler ISR for TC1*/
6584     edma3TCErrHandler(&resMgrObj[edma3InstanceId], 1u);
6585     }
6587 /*
6588  *  ======== lisrEdma3TC2ErrHandler0 ========
6589  *  EDMA3 instance 0 TC2 Error Interrupt Service Routine
6590  */
6591 void lisrEdma3TC2ErrHandler0(unsigned int edma3InstanceId)
6592     {
6593     /* Invoke Error Handler ISR for TC2*/
6594     edma3TCErrHandler(&resMgrObj[edma3InstanceId], 2u);
6595     }
6597 /*
6598  *  ======== lisrEdma3TC3ErrHandler0 ========
6599  *  EDMA3 instance 0 TC3 Error Interrupt Service Routine
6600  */
6601 void lisrEdma3TC3ErrHandler0(unsigned int edma3InstanceId)
6602     {
6603     /* Invoke Error Handler ISR for TC3*/
6604     edma3TCErrHandler(&resMgrObj[edma3InstanceId], 3u);
6605     }
6607 /*
6608  *  ======== lisrEdma3TC4ErrHandler0 ========
6609  *  EDMA3 instance 0 TC4 Error Interrupt Service Routine
6610  */
6611 void lisrEdma3TC4ErrHandler0(unsigned int edma3InstanceId)
6612     {
6613     /* Invoke Error Handler ISR for TC4*/
6614     edma3TCErrHandler(&resMgrObj[edma3InstanceId], 4u);
6615     }
6618 /*
6619  *  ======== lisrEdma3TC5ErrHandler0 ========
6620  *  EDMA3 instance 0 TC5 Error Interrupt Service Routine
6621  */
6622 void lisrEdma3TC5ErrHandler0(unsigned int edma3InstanceId)
6623     {
6624     /* Invoke Error Handler ISR for TC5*/
6625     edma3TCErrHandler(&resMgrObj[edma3InstanceId], 5u);
6626     }
6628 /*
6629  *  ======== lisrEdma3TC6ErrHandler0 ========
6630  *  EDMA3 instance 0 TC6 Error Interrupt Service Routine
6631  */
6632 /* ARGSUSED */
6633 void lisrEdma3TC6ErrHandler0(unsigned int edma3InstanceId)
6634     {
6635     /* Invoke Error Handler ISR for TC6*/
6636     edma3TCErrHandler(&resMgrObj[edma3InstanceId], 6u);
6637     }
6639 /*
6640  *  ======== lisrEdma3TC7ErrHandler0 ========
6641  *  EDMA3 instance 0 TC7 Error Interrupt Service Routine
6642  */
6643 void lisrEdma3TC7ErrHandler0(unsigned int edma3InstanceId)
6644     {
6645     /* Invoke Error Handler ISR for TC7*/
6646     edma3TCErrHandler(&resMgrObj[edma3InstanceId], 7u);
6647     }
6651 /*  Resource Manager Internal functions - Start */
6653 /** Initialization of the Global region registers of the EDMA3 Controller */
6654 static void edma3GlobalRegionInit (unsigned int phyCtrllerInstId)
6655     {
6656     unsigned int evtQNum = 0u;
6657     volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
6659     assert (phyCtrllerInstId < EDMA3_MAX_EDMA3_INSTANCES);
6661     ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)
6662                     (resMgrObj[phyCtrllerInstId].gblCfgParams.globalRegs);
6664     if (ptrEdmaccRegs != NULL)
6665         {
6666         ptrEdmaccRegs->EMCR = EDMA3_RM_SET_ALL_BITS;
6667         ptrEdmaccRegs->EMCRH = EDMA3_RM_SET_ALL_BITS;
6668         ptrEdmaccRegs->QEMCR = EDMA3_RM_SET_ALL_BITS;
6670         /*
6671         * Set all Instance-wide EDMA3 parameters (not channel-specific)
6672         */
6674         /**
6675          * Set TC Priority among system-wide bus-masters and Queue
6676          * Watermark Level
6677          */
6678         while (evtQNum <
6679                     resMgrObj[phyCtrllerInstId].gblCfgParams.numEvtQueue)
6680             {
6681             ptrEdmaccRegs->QUEPRI &= EDMA3_RM_QUEPRI_CLR_MASK(evtQNum);
6682             ptrEdmaccRegs->QUEPRI |= EDMA3_RM_QUEPRI_SET_MASK(evtQNum,
6683                 resMgrObj[phyCtrllerInstId].gblCfgParams.evtQPri[evtQNum]);
6685             ptrEdmaccRegs->QWMTHRA |= EDMA3_RM_QUEWMTHR_SET_MASK(evtQNum,
6686                         resMgrObj[phyCtrllerInstId].gblCfgParams.evtQueueWaterMarkLvl[evtQNum]);
6688             evtQNum++;
6689             }
6691         /* Clear CCERR register */
6692         ptrEdmaccRegs ->CCERRCLR = 0xFFFFu;
6693         }
6695     return;
6696     }
6701 /** Initialization of the Shadow region registers of the EDMA3 Controller */
6702 static void edma3ShadowRegionInit (const EDMA3_RM_Instance *pRMInstance)
6703     {
6704     unsigned int  intState = 0u;
6705     volatile EDMA3_CCRL_Regs *ptrEdmaccRegs             = NULL;
6706     volatile EDMA3_CCRL_ShadowRegs *ptrEdmaShadowRegs   = NULL;
6707     unsigned int phyCtrllerInstId;
6708     unsigned int regionId;
6709     const EDMA3_RM_InstanceInitConfig *rmInstInitConfig = pRMInstance->initParam.rmInstInitConfig;
6711     assert (pRMInstance != NULL);
6713     if (rmInstInitConfig != NULL)
6714         {
6715         phyCtrllerInstId = pRMInstance->pResMgrObjHandle->phyCtrllerInstId;
6716         regionId = pRMInstance->initParam.regionId;
6718         ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)
6719                         (resMgrObj[phyCtrllerInstId].gblCfgParams.globalRegs);
6721         if (ptrEdmaccRegs != NULL)
6722             {
6723             ptrEdmaShadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
6724                                     (&ptrEdmaccRegs->SHADOW[regionId]);
6726             ptrEdmaShadowRegs->ECR      = (rmInstInitConfig->ownDmaChannels[0u]
6727                                             | rmInstInitConfig->ownTccs[0u]);
6728             ptrEdmaShadowRegs->ECRH     = (rmInstInitConfig->ownDmaChannels[1u]
6729                                             | rmInstInitConfig->ownTccs[1u]);
6730             ptrEdmaShadowRegs->EECR     = (rmInstInitConfig->ownDmaChannels[0u]
6731                                             | rmInstInitConfig->ownTccs[0u]);
6732             ptrEdmaShadowRegs->SECR     = (rmInstInitConfig->ownDmaChannels[0u]
6733                                             | rmInstInitConfig->ownTccs[0u]);
6734             ptrEdmaShadowRegs->SECRH    = (rmInstInitConfig->ownDmaChannels[1u]
6735                                             | rmInstInitConfig->ownTccs[1u]);
6736             ptrEdmaShadowRegs->EECR     = (rmInstInitConfig->ownDmaChannels[0u]
6737                                             | rmInstInitConfig->ownTccs[0u]);
6738             ptrEdmaShadowRegs->EECRH    = (rmInstInitConfig->ownDmaChannels[1u]
6739                                             | rmInstInitConfig->ownTccs[1u]);
6741             ptrEdmaShadowRegs->QEECR    = rmInstInitConfig->ownQdmaChannels[0u];
6743             ptrEdmaShadowRegs->IECR     = (rmInstInitConfig->ownDmaChannels[0u]
6744                                             | rmInstInitConfig->ownTccs[0u]);
6745             ptrEdmaShadowRegs->IECRH    = (rmInstInitConfig->ownDmaChannels[1u]
6746                                             | rmInstInitConfig->ownTccs[1u]);
6747             ptrEdmaShadowRegs->ICR      = (rmInstInitConfig->ownDmaChannels[0u]
6748                                             | rmInstInitConfig->ownTccs[0u]);
6749             ptrEdmaShadowRegs->ICRH     = (rmInstInitConfig->ownDmaChannels[1u]
6750                                             | rmInstInitConfig->ownTccs[1u]);
6752             ptrEdmaShadowRegs->QSECR    = rmInstInitConfig->ownQdmaChannels[0u];
6754             /*
6755             * Set all EDMA3 Resource<->Region mapping parameters
6756             */
6758             /* 1. Dma Channel (and TCC) <-> Region */
6759             edma3OsProtectEntry (phyCtrllerInstId,
6760                                                 EDMA3_OS_PROTECT_INTERRUPT,
6761                                                 &intState);
6762             ptrEdmaccRegs->DRA[regionId].DRAE = 0u;
6763             ptrEdmaccRegs->DRA[regionId].DRAEH = 0u;
6764             edma3OsProtectExit (phyCtrllerInstId,
6765                                                                 EDMA3_OS_PROTECT_INTERRUPT,
6766                                                                 intState);
6768             /* 2. Qdma Channel <-> Region */
6769             edma3OsProtectEntry (phyCtrllerInstId,
6770                                                 EDMA3_OS_PROTECT_INTERRUPT,
6771                                                 &intState);
6772             ptrEdmaccRegs->QRAE[regionId] = 0u;
6773             edma3OsProtectExit (phyCtrllerInstId,
6774                                                                 EDMA3_OS_PROTECT_INTERRUPT,
6775                                                                 intState);
6776             }
6777         }
6779     return;
6780     }
6784 /** Local MemZero function */
6785 void edma3MemZero(void *dst, unsigned int len)
6786     {
6787     unsigned int i = 0u;
6788     unsigned int *ds = NULL;
6790     assert (dst != NULL);
6792     ds = (unsigned int *)dst;
6794     for (i = 0 ; i < len/4 ; i++)
6795         {
6796         *ds = 0x0;
6797         ds++;
6798         }
6800     return;
6801     }
6804 /* Local MemCopy function */
6805 void edma3MemCpy(void *dst, const void *src, unsigned int len)
6806     {
6807     unsigned int i=0u;
6808     const unsigned int *sr;
6809     unsigned int *ds;
6811     assert ((src != NULL) && (dst != NULL) && ((len)%4 == 0));
6813     sr = (const unsigned int *)src;
6814     ds = (unsigned int *)dst;
6816     for (i = 0 ; i < len/4 ; i++)
6817         {
6818         *ds = *sr;
6819         ds++;
6820         sr++;
6821         }
6823     return;
6824     }
6827 /* Local MemCopy function to copy Param Set ONLY */
6828 void edma3ParamCpy(void *dst, const void *src)
6829     {
6830     unsigned int i = 0u;
6831     const unsigned int *sr;
6832     unsigned int *ds;
6834     assert ((src != NULL) && (dst != NULL));
6836     sr = (const unsigned int *)src;
6837     ds = (unsigned int *)dst;
6839     for (i = 0; i < 8; i++)
6840         {
6841         *ds = *sr;
6842         ds++;
6843         sr++;
6844         }
6846     return;
6847     }
6850 /**
6851  * Finds a particular bit ('0' or '1') in the particular word from 'start'.
6852  * If found, returns the position, else return -1.
6853  */
6854 static int findBitInWord (int source, unsigned int start, unsigned short bit)
6855     {
6856     unsigned int position = start;
6857     unsigned short found = 0;
6858     unsigned int iterations_left = 0;
6860     switch (bit)
6861         {
6862         case 1:
6863             {
6864             source >>= (start%32u);
6866             while ((found==0u) && (source!=0))
6867                 {
6868                 if ((source & 0x1) == 0x1)
6869                     {
6870                     /* 1 */
6871                     found++;
6872                     }
6873                 else
6874                     {
6875                     /* 0 */
6876                     source >>= 1;
6877                     position++;
6878                     }
6879                 }
6881             }
6882             break;
6884         case 0:
6885             {
6886             source >>= (start%32u);
6887             iterations_left = 32u - (start%32u);
6889             while ((found==0u) && (iterations_left>0u))
6890                 {
6891                 if ((source & 0x1) == 0x1)
6892                     {
6893                     /* 1 */
6894                     source >>= 1;
6895                     position++;
6896                     iterations_left--;
6897                     }
6898                 else
6899                     {
6900                     /* 0 */
6901                     found++;
6902                     }
6903                 }
6904             }
6905             break;
6907         default:
6908             break;
6909         }
6911     return (found ? (int)position : -1);
6912     }
6915 /**
6916  * Finds a particular bit ('0' or '1') in the specified resources' array
6917  * from 'start' to 'end'. If found, returns the position, else return -1.
6918  */
6919 static int findBit (EDMA3_RM_ResType resType,
6920                             unsigned int start,
6921                             unsigned int end,
6922                             unsigned short bit)
6923     {
6924     int position = -1;
6925     unsigned int start_index = start / 32u;
6926     unsigned int end_index = end / 32u;
6927     int i;
6928     unsigned int *resPtr = 0x0;
6929     int ret = -1;
6930     EDMA3_RM_Result result = EDMA3_RM_SOK;
6932     assert (start <= end);
6934     /**
6935      * job is to find 'bit' in an array[start_index:end_index]
6936      * algo used:
6937      * first search in array[start_index]
6938      * then search in array[start_index + 1 : end_index - 1]
6939      * then search in array[end_index]
6940      */
6941     switch (resType)
6942         {
6943         case EDMA3_RM_RES_DMA_CHANNEL:
6944             resPtr = &contiguousDmaRes[0];
6945             break;
6947         case EDMA3_RM_RES_QDMA_CHANNEL:
6948             resPtr = &contiguousQdmaRes[0];
6949             break;
6951         case EDMA3_RM_RES_TCC:
6952             resPtr = &contiguousTccRes[0];
6953             break;
6955         case EDMA3_RM_RES_PARAM_SET:
6956             resPtr = &contiguousParamRes[0];
6957             break;
6959         default:
6960             result = EDMA3_RM_E_INVALID_PARAM;
6961             break;
6962         }
6964     if (EDMA3_RM_SOK == result)
6965         {
6966         switch (bit)
6967             {
6968             case 1:
6969                 {
6970                 /* Find '1' in first word. */
6971                 position = findBitInWord (resPtr[start_index], start, 1u);
6973                 if (position != -1)
6974                     {
6975                     ret = position;
6976                     }
6977                 else
6978                     {
6979                     /* '1' NOT found, look into other words. */
6980                     for (i = (int)(start_index + 1u); i <= (int)(end_index - 1u); i++)
6981                         {
6982                         position = findBitInWord (resPtr[i], 0u, 1u);
6983                         if (position != -1)
6984                             {
6985                             /* '1' Found... */
6986                             ret = (position + (i*32));
6987                             break;
6988                             }
6989                         }
6991                     /* First check whether we have found '1' or not. */
6992                     if (ret == -1)
6993                         {
6994                         /* Still not found, look in the last word. */
6995                         position = findBitInWord(resPtr[end_index], 0u, 1u);
6996                         if (position != -1)
6997                             {
6998                             /* Finally got it. */
6999                             ret = (position + (end_index*32u));
7000                             }
7001                         else
7002                             {
7003                             /* Sorry, could not find it, return -1. */
7004                             ret = -1;
7005                             }
7006                         }
7007                     }
7008                 }
7009                 break;
7011             case 0:
7012                 {
7013                 /* Find '0' in first word. */
7014                 position = findBitInWord(resPtr[start_index], start, 0u);
7015                 if (position != -1)
7016                     {
7017                     ret = position;
7018                     }
7019                 else
7020                     {
7021                     /* '0' NOT found, look into other words. */
7022                     for (i = (start_index + 1u); i <= (end_index - 1u); i++)
7023                         {
7024                         position = findBitInWord(resPtr[i], 0u, 0u);
7025                         if (position != -1)
7026                             {
7027                             /* '0' found... */
7028                             ret = (position + (i*32));
7029                             break;
7030                             }
7031                         }
7033                     /* First check whether we have found '0' or not. */
7034                     if (ret == -1)
7035                         {
7036                         position = findBitInWord(resPtr[end_index], 0u, 0u);
7037                         if (position != -1)
7038                             {
7039                             /* Finally got it. */
7040                             ret = (position + (end_index*32u));
7041                             }
7042                         else
7043                             {
7044                             /* Sorry, could not find it, return -1. */
7045                             ret = -1;
7046                             }
7047                         }
7048                     }
7049                 }
7050                 break;
7052             default:
7053                 break;
7054             }
7055         }
7059     return ((ret >= start) ? ret : -1);
7064 /**
7065  * If successful, this function returns EDMA3_RM_SOK and the position
7066  * of first available resource in 'positionRes'. Else returns error.
7067  */
7068 static EDMA3_RM_Result allocAnyContigRes(EDMA3_RM_ResType resType,
7069                                     unsigned int numResources,
7070                                     unsigned int *positionRes)
7071     {
7072     unsigned short found = 0u;
7073     int first_one, next_zero;
7074     unsigned int num_available;
7075     int ret = -1;
7076     unsigned int start = 0;
7077     unsigned int end;
7078     EDMA3_RM_Result result = EDMA3_RM_SOK;
7080     assert (positionRes != NULL);
7082     switch (resType)
7083         {
7084         case EDMA3_RM_RES_DMA_CHANNEL:
7085             end = EDMA3_MAX_DMA_CH - 1u;
7086             break;
7088         case EDMA3_RM_RES_QDMA_CHANNEL:
7089             end = EDMA3_MAX_QDMA_CH - 1u;
7090             break;
7092         case EDMA3_RM_RES_TCC:
7093             end = EDMA3_MAX_TCC - 1u;
7094             break;
7096         case EDMA3_RM_RES_PARAM_SET:
7097             end = edma3NumPaRAMSets - 1u;
7098             break;
7100         default:
7101             result = EDMA3_RM_E_INVALID_PARAM;
7102             break;
7103         }
7105     if (result == EDMA3_RM_SOK)
7106         {
7107         /**
7108          * Algorithm used for finding N contiguous resources.
7109          * In the resources' array, '1' means available and '0' means
7110          * not-available.
7111          * Step a) Find first '1' starting from 'start'. If successful,
7112          * store it in first_one, else return error.
7113          * Step b) Find first '0' starting from (first_one+1) to 'end'.
7114          * If successful, store returned value in next_zero. If '0' could
7115          * not be located, it means all the resources are available.
7116          * Store 'end' (i.e. the last resource id) in next_zero.
7117          * Step c) Count the number of contiguous resources available
7118          * by subtracting first_one from next_zero.
7119          * Step d) If result < N, do the whole process again untill you
7120          * reach end. Else you have found enough resources, return success.
7121          */
7122         while((found == 0) && (((end-start)+1u) >= numResources))
7123             {
7124             /* Find first '1' starting from 'start' till 'end'. */
7125             first_one = findBit (resType, start, end, 1u);
7126             if (first_one != -1)
7127                 {
7128                 /* Got first 1, search for first '0' now. */
7129                 next_zero = findBit (resType, first_one+1, end, 0u);
7130                 if (next_zero == -1)
7131                     {
7132                     /* Unable to find next zero, all 1' are there */
7133                     next_zero = end + 1u;
7134                     }
7136                 /* check no of resources available */
7137                 num_available = next_zero - first_one;
7138                 if (num_available >= numResources)
7139                     {
7140                     /* hurrah..., we have found enough resources. */
7141                     found = 1u;
7142                     ret = first_one;
7143                     }
7144                 else
7145                     {
7146                     /* Not enough resources, try again */
7147                     start = next_zero + 1;
7148                     }
7149                 }
7150             else
7151                 {
7152                 /* do nothing, first 1 is not there, return.  */
7153                 break;
7154                 }
7155             }
7156         }
7159     if (result == EDMA3_RM_SOK)
7160         {
7161         if (found == 1u)
7162             {
7163             /* required resources found, retrun the first available res id. */
7164             *positionRes = (unsigned int)ret;
7165             }
7166         else
7167             {
7168             /* No resources allocated */
7169             result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
7170             }
7171         }
7173     return result;
7174     }
7178 /**
7179  * Starting from 'firstResIdObj', this function makes the next 'numResources'
7180  * Resources non-available for future. Also, it does some global resisters'
7181  * setting also.
7182  */
7183 static EDMA3_RM_Result gblChngAllocContigRes(EDMA3_RM_Instance *rmInstance,
7184                                         const EDMA3_RM_ResDesc *firstResIdObj,
7185                                         unsigned int numResources)
7186     {
7187     EDMA3_RM_Result result = EDMA3_RM_SOK;
7188     volatile EDMA3_CCRL_Regs *gblRegs = NULL;
7189     EDMA3_RM_Obj *rmObj = NULL;
7190     unsigned int avlblIdx = 0u;
7191     unsigned int firstResId=0u;
7192     unsigned int lastResId=0u;
7193         unsigned int edma3Id;
7195     assert ((rmInstance != NULL) && (firstResIdObj != NULL));
7197     rmObj = rmInstance->pResMgrObjHandle;
7199     if (rmObj == NULL)
7200         {
7201         result = EDMA3_RM_E_INVALID_PARAM;
7202         }
7204     if (EDMA3_RM_SOK == result)
7205         {
7206         edma3Id = rmObj->phyCtrllerInstId;
7207         gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
7209         if (gblRegs == NULL)
7210             {
7211             result = EDMA3_RM_E_INVALID_PARAM;
7212             }
7213         }
7215     if (result == EDMA3_RM_SOK)
7216         {
7217         switch (firstResIdObj->type)
7218             {
7219             case EDMA3_RM_RES_DMA_CHANNEL:
7220                 {
7221                 firstResId = firstResIdObj->resId;
7222                 lastResId = firstResId + (numResources - 1u);
7224                 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
7225                     {
7226                     rmInstance->avlblDmaChannels[avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
7228                     /**
7229                      * Enable the DMA channel in the DRAE/DRAEH registers also.
7230                      */
7231                     if (avlblIdx < 32u)
7232                         {
7233                         gblRegs->DRA[rmInstance->initParam.regionId].DRAE
7234                             |= (0x1u << avlblIdx);
7235                         }
7236                     else
7237                         {
7238                         gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
7239                             |= (0x1u << (avlblIdx - 32u));
7240                         }
7241                     }
7242                 }
7243                 break;
7245             case EDMA3_RM_RES_QDMA_CHANNEL:
7246                 {
7247                 firstResId = firstResIdObj->resId;
7248                 lastResId = firstResId + (numResources - 1u);
7250                 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
7251                     {
7252                     rmInstance->avlblQdmaChannels[avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
7254                     /**
7255                      * Enable the QDMA channel in the QRAE register also.
7256                      */
7257                     gblRegs->QRAE[rmInstance->initParam.regionId]
7258                         |= (0x1u << avlblIdx);
7259                     }
7260                 }
7261                 break;
7263             case EDMA3_RM_RES_TCC:
7264                 {
7265                 firstResId = firstResIdObj->resId;
7266                 lastResId = firstResId + (numResources - 1u);
7268                 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
7269                     {
7270                     rmInstance->avlblTccs[avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
7272                     /**
7273                      * Enable the Interrupt channel in the DRAE/DRAEH registers.
7274                      * Also, If the region id coming from this
7275                      * RM instance is same as the Master RM
7276                      * Instance's region id, only then we will be
7277                      * getting the interrupts on the same side.
7278                      * So save the TCC in the allocatedTCCs[] array.
7279                      */
7280                     if (avlblIdx < 32u)
7281                         {
7282                         gblRegs->DRA[rmInstance->initParam.regionId].DRAE
7283                             |= (0x1u << avlblIdx);
7285                         if (edma3RegionId == rmInstance->initParam.regionId)
7286                             {
7287                             allocatedTCCs[0u] |= (0x1u << avlblIdx);
7288                             }
7289                         }
7290                     else
7291                         {
7292                         gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
7293                             |= (0x1u << (avlblIdx - 32u));
7295                         if (edma3RegionId == rmInstance->initParam.regionId)
7296                             {
7297                             allocatedTCCs[1u] |= (0x1u << (avlblIdx - 32u));
7298                             }
7299                         }
7300                     }
7301                 }
7302                 break;
7304             case EDMA3_RM_RES_PARAM_SET:
7305                 {
7306                 firstResId = firstResIdObj->resId;
7307                 lastResId = firstResId + (numResources - 1u);
7309                 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
7310                     {
7311                     rmInstance->avlblPaRAMSets [avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
7313                     /**
7314                      * Also, make the actual PARAM Set NULL, checking the flag
7315                      * whether it is required or not.
7316                      */
7317                     if (TRUE == rmInstance->paramInitRequired)
7318                         {
7319                         edma3MemZero((void *)(&gblRegs->PARAMENTRY[avlblIdx]),
7320                                         sizeof(gblRegs->PARAMENTRY[avlblIdx]));
7321                         }
7322                     }
7323                 }
7324                 break;
7326             default:
7327                 result = EDMA3_RM_E_INVALID_PARAM;
7328                 break;
7329             }
7330         }
7333     return result;
7334     }
7336 /*  Resource Manager Internal functions - End */
7338 /* End of File */