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 int 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 EDMA3_RM_Result EDMA3_RM_create (unsigned int phyCtrllerInstId,
352 const EDMA3_RM_GblConfigParams *gblCfgParams,
353 const void *miscParam)
354 {
355 unsigned int count = 0u;
356 EDMA3_RM_Result result = EDMA3_RM_SOK;
357 /**
358 * Used to reset the Internal EDMA3 Resource Manager Data Structures for the first time.
359 */
360 static unsigned short rmInitDone = FALSE;
361 const EDMA3_RM_MiscParam *miscOpt = (const EDMA3_RM_MiscParam *)miscParam;
363 /**
364 * We are NOT checking 'gblCfgParams' for NULL.
365 * If user has passed NULL, default config info will be
366 * taken from config file.
367 * 'param' is also not being checked because it could be
368 * NULL also.
369 */
371 /* If parameter checking is enabled... */
372 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
373 if (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
374 {
375 result = EDMA3_RM_E_INVALID_PARAM;
376 }
377 #endif
379 /* Check if the parameters are OK. */
380 if (EDMA3_RM_SOK == result)
381 {
382 /* Initialize the global variables for the first time */
383 if (FALSE == rmInitDone)
384 {
385 edma3MemZero((void *)&(resMgrObj[count]),
386 sizeof(resMgrObj));
387 edma3MemZero((void *)(&(edma3IntrParams[0u])),
388 sizeof(edma3IntrParams));
390 rmInitDone = TRUE;
391 }
393 /* Initialization has been done */
394 if (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_DELETED)
395 {
396 result = EDMA3_RM_E_OBJ_NOT_DELETED;
397 }
398 else
399 {
400 /**
401 * Check whether user has passed the Global Config Info.
402 * If yes, copy it to the driver data structures. Else, use the
403 * info from the config file edma3Cfg.c
404 */
405 if (NULL == gblCfgParams)
406 {
407 /* Take info from the specific config file */
408 edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
409 (const void *)(&edma3GblCfgParams[phyCtrllerInstId]),
410 sizeof (EDMA3_RM_GblConfigParams));
411 }
412 else
413 {
414 /* User passed the info, save it in the RM object first */
415 edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
416 (const void *)(gblCfgParams),
417 sizeof (EDMA3_RM_GblConfigParams));
418 }
421 /**
422 * Check whether DMA channel to PaRAM Set mapping exists or not.
423 * If it does not exist, set the mapping array as 1-to-1 mapped.
424 */
425 if (FALSE == resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChPaRAMMapExists)
426 {
427 for (count = 0u; count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels; count++)
428 {
429 resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChannelPaRAMMap[count] = count;
430 }
431 }
434 /**
435 * Update the actual number of PaRAM sets and
436 * Initialize Boundary Values for Logical Channel Ranges.
437 */
438 edma3NumPaRAMSets = resMgrObj[phyCtrllerInstId].gblCfgParams.numPaRAMSets;
439 edma3_dma_ch_max_val[phyCtrllerInstId] = resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels - 1u;
440 edma3_link_ch_min_val[phyCtrllerInstId] = edma3_dma_ch_max_val[phyCtrllerInstId] + 1u;
441 edma3_link_ch_max_val[phyCtrllerInstId] = edma3_link_ch_min_val[phyCtrllerInstId] + resMgrObj[phyCtrllerInstId].gblCfgParams.numPaRAMSets - 1u;
442 edma3_qdma_ch_min_val[phyCtrllerInstId] = edma3_link_ch_max_val[phyCtrllerInstId] + 1u;
443 edma3_qdma_ch_max_val[phyCtrllerInstId] = edma3_qdma_ch_min_val[phyCtrllerInstId] + resMgrObj[phyCtrllerInstId].gblCfgParams.numQdmaChannels - 1u;
444 edma3_log_ch_max_val[phyCtrllerInstId] = edma3_qdma_ch_max_val[phyCtrllerInstId];
446 resMgrObj[phyCtrllerInstId].phyCtrllerInstId = phyCtrllerInstId;
447 resMgrObj[phyCtrllerInstId].state = EDMA3_RM_CREATED;
448 resMgrObj[phyCtrllerInstId].numOpens = 0u;
450 /* Make all the RM instances for this EDMA3 HW NULL */
451 for (count = 0u; count < EDMA3_MAX_RM_INSTANCES; count++)
452 {
453 edma3MemZero((void *)((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
454 sizeof(EDMA3_RM_Instance));
456 /* Also make this data structure NULL */
457 edma3MemZero((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
458 sizeof(EDMA3_RM_InstanceInitConfig));
459 }
461 /* Initialize the global edma3DmaChTccMapping array with EDMA3_MAX_TCC */
462 for ( count = 0u;
463 count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels;
464 count++
465 )
466 {
467 edma3DmaChTccMapping[phyCtrllerInstId][count] = EDMA3_MAX_TCC;
468 }
470 /* Initialize the global edma3QdmaChTccMapping array with EDMA3_MAX_TCC */
471 for ( count = 0u;
472 count < resMgrObj[phyCtrllerInstId].gblCfgParams.numQdmaChannels;
473 count++
474 )
475 {
476 edma3QdmaChTccMapping[phyCtrllerInstId][count] = EDMA3_MAX_TCC;
477 }
479 /* Reset edma3RmChBoundRes Array*/
480 for (count = 0u; count < EDMA3_MAX_LOGICAL_CH; count++)
481 {
482 edma3RmChBoundRes[phyCtrllerInstId][count].paRAMId = -1;
483 edma3RmChBoundRes[phyCtrllerInstId][count].tcc = EDMA3_MAX_TCC;
484 }
486 /* Make the contiguousParamRes array NULL */
487 edma3MemZero((void *)(&(contiguousParamRes[0u])),
488 sizeof(contiguousParamRes));
491 /**
492 * Check the misc configuration options structure.
493 * Check whether the global registers' initialization
494 * is required or not.
495 * It is required ONLY if RM is running on the Master Processor.
496 */
497 if (NULL != miscOpt)
498 {
499 if (miscOpt->isSlave == FALSE)
500 {
501 /* It is a master. */
502 edma3GlobalRegionInit(phyCtrllerInstId);
503 }
504 }
505 else
506 {
507 /* By default, global registers will be initialized. */
508 edma3GlobalRegionInit(phyCtrllerInstId);
509 }
510 }
511 }
513 return result;
514 }
516 EDMA3_RM_Result EDMA3_RM_delete (unsigned int phyCtrllerInstId,
517 const void *param)
518 {
519 EDMA3_RM_Result result = EDMA3_RM_SOK;
521 /* If parameter checking is enabled... */
522 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
523 if (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
524 {
525 result = EDMA3_RM_E_INVALID_PARAM;
526 }
527 #endif
529 /* Check if the parameters are OK. */
530 if (EDMA3_RM_SOK == result)
531 {
532 /*to remove CCS remark: parameter "param" was never referenced */
533 (void)param;
535 /**
536 * If number of RM Instances is 0, then state should be
537 * EDMA3_RM_CLOSED OR EDMA3_RM_CREATED.
538 */
539 if ((NULL == resMgrObj[phyCtrllerInstId].numOpens)
540 && ((resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CLOSED)
541 && (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CREATED)))
542 {
543 result = EDMA3_RM_E_OBJ_NOT_CLOSED;
544 }
545 else
546 {
547 /**
548 * If number of RM Instances is NOT 0, then this function
549 * SHOULD NOT be called by anybody.
550 */
551 if (NULL != resMgrObj[phyCtrllerInstId].numOpens)
552 {
553 result = EDMA3_RM_E_INVALID_STATE;
554 }
555 else
556 {
557 /** Change state to EDMA3_RM_DELETED */
558 resMgrObj[phyCtrllerInstId].state = EDMA3_RM_DELETED;
560 /* Reset the Allocated TCCs Array also. */
561 allocatedTCCs[phyCtrllerInstId][0u] = 0x0u;
562 allocatedTCCs[phyCtrllerInstId][1u] = 0x0u;
564 /* Also, reset the RM Object Global Config Info */
565 edma3MemZero((void *)&(resMgrObj[phyCtrllerInstId].gblCfgParams),
566 sizeof(EDMA3_RM_GblConfigParams));
567 }
568 }
569 }
571 return result;
572 }
574 EDMA3_RM_Handle EDMA3_RM_open (unsigned int phyCtrllerInstId,
575 const EDMA3_RM_Param *initParam,
576 EDMA3_RM_Result *errorCode)
577 {
578 unsigned int intState = 0u;
579 unsigned int resMgrIdx = 0u;
580 EDMA3_RM_Result result = EDMA3_RM_SOK;
581 EDMA3_RM_Obj *rmObj = NULL;
582 EDMA3_RM_Instance *rmInstance = NULL;
583 EDMA3_RM_Instance *temp_ptr_rm_inst = NULL;
584 EDMA3_RM_Handle retVal = NULL;
585 unsigned int dmaChDwrds = 0u;
586 unsigned int paramSetDwrds = 0u;
587 unsigned int tccDwrds = 0u;
588 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
590 /* If parameter checking is enabled... */
591 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
592 if (((initParam == NULL)
593 || (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES))
594 || (errorCode == NULL))
595 {
596 result = EDMA3_RM_E_INVALID_PARAM;
597 }
598 #endif
600 /* Check if the parameters are OK. */
601 if (EDMA3_RM_SOK == result)
602 {
603 /* Check whether the semaphore handle is null or not */
604 if (NULL == initParam->rmSemHandle)
605 {
606 result = EDMA3_RM_E_INVALID_PARAM;
607 }
608 else
609 {
610 rmObj = &resMgrObj[phyCtrllerInstId];
611 if (
612 (NULL == rmObj)
613 || (initParam->regionId >=
614 resMgrObj[phyCtrllerInstId].gblCfgParams.numRegions)
615 )
616 {
617 result = EDMA3_RM_E_INVALID_PARAM;
618 }
619 else
620 {
621 edma3OsProtectEntry (phyCtrllerInstId,
622 EDMA3_OS_PROTECT_INTERRUPT,
623 &intState);
625 /** Check state of RM Object.
626 * If no RM instance is opened and this is the first one,
627 * then state should be created/closed.
628 */
629 if ((rmObj->numOpens == NULL) &&
630 ((rmObj->state != EDMA3_RM_CREATED) &&
631 (rmObj->state != EDMA3_RM_CLOSED)))
632 {
633 result = EDMA3_RM_E_INVALID_STATE;
634 edma3OsProtectExit (phyCtrllerInstId,
635 EDMA3_OS_PROTECT_INTERRUPT,
636 intState);
637 }
638 else
639 {
640 /**
641 * If num of instances opened is more than 0 and less than
642 * max allowed, then state should be opened.
643 */
644 if (((rmObj->numOpens > 0) &&
645 (rmObj->numOpens < EDMA3_MAX_RM_INSTANCES))
646 && (rmObj->state != EDMA3_RM_OPENED))
647 {
648 result = EDMA3_RM_E_INVALID_STATE;
649 edma3OsProtectExit (phyCtrllerInstId,
650 EDMA3_OS_PROTECT_INTERRUPT,
651 intState);
652 }
653 else
654 {
655 /* Check if max opens have passed */
656 if (rmObj->numOpens >= EDMA3_MAX_RM_INSTANCES)
657 {
658 result = EDMA3_RM_E_MAX_RM_INST_OPENED;
659 edma3OsProtectExit (phyCtrllerInstId,
660 EDMA3_OS_PROTECT_INTERRUPT,
661 intState);
662 }
663 }
664 }
665 }
666 }
667 }
669 if (EDMA3_RM_SOK == result)
670 {
671 /*
672 * Check whether the RM instance is Master or not.
673 * If it is master, check whether a master already exists
674 * or not. There should NOT be more than 1 master.
675 * Return error code if master already exists
676 */
677 if ((TRUE == masterExists[phyCtrllerInstId]) && (TRUE == initParam->isMaster))
678 {
679 /* No two masters should exist, return error */
680 result = EDMA3_RM_E_RM_MASTER_ALREADY_EXISTS;
681 edma3OsProtectExit (phyCtrllerInstId,
682 EDMA3_OS_PROTECT_INTERRUPT,
683 intState);
684 }
685 else
686 {
687 /* Create Res Mgr Instance */
688 for (resMgrIdx = 0u; resMgrIdx < EDMA3_MAX_RM_INSTANCES; resMgrIdx++)
689 {
690 temp_ptr_rm_inst = ((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
692 if (NULL != temp_ptr_rm_inst)
693 {
694 if (NULL == temp_ptr_rm_inst->pResMgrObjHandle)
695 {
696 /* Handle to the EDMA3 HW Object */
697 temp_ptr_rm_inst->pResMgrObjHandle = rmObj;
698 /* Handle of the Res Mgr Instance */
699 rmInstance = temp_ptr_rm_inst;
701 /* Also make this data structure NULL, just for safety. */
702 edma3MemZero((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
703 sizeof(EDMA3_RM_InstanceInitConfig));
705 break;
706 }
707 }
708 }
710 /* Check whether a RM instance has been created or not */
711 if (NULL == rmInstance)
712 {
713 result = EDMA3_RM_E_MAX_RM_INST_OPENED;
714 edma3OsProtectExit (phyCtrllerInstId,
715 EDMA3_OS_PROTECT_INTERRUPT,
716 intState);
717 }
718 else
719 {
720 /* Copy the InitPaRAM first */
721 edma3MemCpy((void *)(&rmInstance->initParam),
722 (const void *)(initParam),
723 sizeof (EDMA3_RM_Param));
725 if (rmObj->gblCfgParams.globalRegs != NULL)
726 {
727 globalRegs = (volatile EDMA3_CCRL_Regs *)
728 (rmObj->gblCfgParams.globalRegs);
729 rmInstance->shadowRegs = (EDMA3_CCRL_ShadowRegs *)
730 &(globalRegs->SHADOW[rmInstance->initParam.regionId]);
732 /* copy the instance specific semaphore handle */
733 rmInstance->initParam.rmSemHandle = initParam->rmSemHandle;
735 /**
736 * Check whether user has passed information about resources
737 * owned and reserved by this instance. This is region specific
738 * information. If he has not passed, dafault static config info will be taken
739 * from the config file edma3Cfg.c, according to the regionId specified.
740 *
741 * resMgrIdx specifies the RM instance number created just now.
742 * Use it to populate the userInitConfig [].
743 */
744 if (NULL == initParam->rmInstInitConfig)
745 {
746 /* Take the info from the specific config file */
747 edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
748 (const void *)(&defInstInitConfig[phyCtrllerInstId][initParam->regionId]),
749 sizeof (EDMA3_RM_InstanceInitConfig));
750 }
751 else
752 {
753 /* User has passed the region specific info. */
754 edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
755 (const void *)(initParam->rmInstInitConfig),
756 sizeof (EDMA3_RM_InstanceInitConfig));
757 }
759 rmInstance->initParam.rmInstInitConfig =
760 ((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
762 dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / 32u;
763 if (dmaChDwrds == 0)
764 {
765 /* In case DMA channels are < 32 */
766 dmaChDwrds = 1;
767 }
769 paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / 32u;
770 if (paramSetDwrds == 0)
771 {
772 /* In case PaRAM Sets are < 32 */
773 paramSetDwrds = 1;
774 }
776 tccDwrds = rmObj->gblCfgParams.numTccs / 32u;
777 if (tccDwrds == 0)
778 {
779 /* In case TCCs are < 32 */
780 tccDwrds = 1;
781 }
783 for (resMgrIdx = 0u; resMgrIdx < dmaChDwrds; ++resMgrIdx)
784 {
785 rmInstance->avlblDmaChannels[resMgrIdx]
786 = rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resMgrIdx];
787 }
789 rmInstance->avlblQdmaChannels[0u]
790 = rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u];
792 for (resMgrIdx = 0u; resMgrIdx < paramSetDwrds; ++resMgrIdx)
793 {
794 rmInstance->avlblPaRAMSets[resMgrIdx]
795 = rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[resMgrIdx];
796 }
798 for (resMgrIdx = 0u; resMgrIdx < tccDwrds; ++resMgrIdx)
799 {
800 rmInstance->avlblTccs [resMgrIdx]
801 = rmInstance->initParam.rmInstInitConfig->ownTccs[resMgrIdx];
802 }
804 /*
805 * Mark the PaRAM Sets corresponding to DMA channels as RESERVED.
806 * For e.g. on a platform where only 32 DMA channels exist,
807 * mark the first 32 PaRAM Sets as reserved. These param sets
808 * will not be returned in case user requests for ANY link
809 * channel.
810 */
811 for (resMgrIdx = 0u; resMgrIdx < rmObj->gblCfgParams.numDmaChannels; ++resMgrIdx)
812 {
813 rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[resMgrIdx/32u] |= (1u<<(resMgrIdx%32u));
814 }
816 /*
817 * If the EDMA RM instance is MASTER (ie. initParam->isMaster
818 * is TRUE), save the region ID.
819 * Only this shadow region will receive the
820 * EDMA3 interrupts, if enabled.
821 */
822 if (TRUE == initParam->isMaster)
823 {
824 /* Store the region id to use it in the ISRs */
825 edma3RegionId = rmInstance->initParam.regionId;
826 masterExists[phyCtrllerInstId] = TRUE;
827 }
829 if (TRUE == initParam->regionInitEnable)
830 {
831 edma3ShadowRegionInit (rmInstance);
832 }
834 /**
835 * By default, PaRAM Sets allocated using this RM Instance
836 * will get cleared during their allocation.
837 * User can stop their clearing by calling specific IOCTL
838 * command.
839 */
840 rmInstance->paramInitRequired = TRUE;
843 /**
844 * By default, during the EDMA3_RM_allocLogicalChannel (),
845 * global EDMA3 registers (DCHMAP/QCHMAP) and the allocated
846 * PaRAM Set will be programmed accordingly, for users using this
847 * RM Instance.
848 * User can stop their pre-programming by calling
849 * EDMA3_RM_IOCTL_SET_GBL_REG_MODIFY_OPTION
850 * IOCTL command.
851 */
852 rmInstance->regModificationRequired = TRUE;
855 if (EDMA3_RM_SOK == result)
856 {
857 rmObj->state = EDMA3_RM_OPENED;
858 /* Increase the Instance count */
859 resMgrObj[phyCtrllerInstId].numOpens++;
860 retVal = rmInstance;
861 }
862 }
863 else
864 {
865 result = EDMA3_RM_E_INVALID_PARAM;
866 }
868 edma3OsProtectExit (phyCtrllerInstId,
869 EDMA3_OS_PROTECT_INTERRUPT,
870 intState);
871 }
872 }
873 }
875 *errorCode = result;
876 return (EDMA3_RM_Handle)retVal;
877 }
879 EDMA3_RM_Result EDMA3_RM_close (EDMA3_RM_Handle hEdmaResMgr,
880 const void *param)
881 {
882 EDMA3_RM_Result result = EDMA3_RM_SOK;
883 unsigned int intState = 0u;
884 unsigned int resMgrIdx = 0u;
885 EDMA3_RM_Obj *rmObj = NULL;
886 EDMA3_RM_Instance *rmInstance = NULL;
887 unsigned int dmaChDwrds;
888 unsigned int paramSetDwrds;
889 unsigned int tccDwrds;
891 /*to remove CCS remark: parameter "param" was never referenced */
892 (void)param;
894 /* If parameter checking is enabled... */
895 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
896 if (NULL == hEdmaResMgr)
897 {
898 result = EDMA3_RM_E_INVALID_PARAM;
899 }
900 #endif
902 /* Check if the parameters are OK. */
903 if (EDMA3_RM_SOK == result)
904 {
905 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
906 rmObj = rmInstance->pResMgrObjHandle;
908 if (rmObj == NULL)
909 {
910 result = (EDMA3_RM_E_INVALID_PARAM);
911 }
912 else
913 {
914 /* Check state of driver, state should be opened */
915 if (rmObj->state != EDMA3_RM_OPENED)
916 {
917 result = (EDMA3_RM_E_OBJ_NOT_OPENED);
918 }
919 else
920 {
921 dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / 32u;
922 paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / 32u;
923 tccDwrds = rmObj->gblCfgParams.numTccs / 32u;
925 /* Set the instance config as NULL*/
926 for (resMgrIdx = 0u; resMgrIdx < dmaChDwrds; ++resMgrIdx)
927 {
928 rmInstance->avlblDmaChannels[resMgrIdx] = 0x0u;
929 }
930 for (resMgrIdx = 0u; resMgrIdx < paramSetDwrds; ++resMgrIdx)
931 {
932 rmInstance->avlblPaRAMSets[resMgrIdx] = 0x0u;
933 }
934 rmInstance->avlblQdmaChannels[0u] = 0x0u;
935 for (resMgrIdx = 0u; resMgrIdx < tccDwrds; ++resMgrIdx)
936 {
937 rmInstance->avlblTccs[resMgrIdx] = 0x0u;
938 }
940 /**
941 * If this is the Master Instance, reset the static variable
942 * 'masterExists[]'.
943 */
944 if (TRUE == rmInstance->initParam.isMaster)
945 {
946 masterExists[rmObj->phyCtrllerInstId] = FALSE;
947 edma3RegionId = EDMA3_MAX_REGIONS;
948 }
950 /* Reset the Initparam for this RM Instance */
951 edma3MemZero((void *)&(rmInstance->initParam),
952 sizeof(EDMA3_RM_Param));
954 /* Critical section starts */
955 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
956 EDMA3_OS_PROTECT_INTERRUPT,
957 &intState);
959 /* Decrease the Number of Opens */
960 --rmObj->numOpens;
961 if (NULL == rmObj->numOpens)
962 {
963 edma3MemZero((void *)&(edma3RmChBoundRes[rmObj->phyCtrllerInstId]),
964 sizeof(edma3RmChBoundRes[rmObj->phyCtrllerInstId]));
966 rmObj->state = EDMA3_RM_CLOSED;
967 }
969 /* Critical section ends */
970 edma3OsProtectExit (rmObj->phyCtrllerInstId,
971 EDMA3_OS_PROTECT_INTERRUPT,
972 intState);
974 rmInstance->pResMgrObjHandle = NULL;
975 rmInstance->shadowRegs = NULL;
976 rmInstance = NULL;
977 }
978 }
979 }
981 return result;
982 }
984 EDMA3_RM_Result EDMA3_RM_allocResource(EDMA3_RM_Handle hEdmaResMgr,
985 EDMA3_RM_ResDesc *resObj)
986 {
987 EDMA3_RM_Instance *rmInstance = NULL;
988 EDMA3_RM_Obj *rmObj = NULL;
989 EDMA3_RM_Result result = EDMA3_RM_SOK;
990 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
991 unsigned int avlblIdx = 0u;
992 unsigned int resIdClr = 0x0;
993 unsigned int resIdSet = 0x0;
994 unsigned int resId;
995 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
997 #ifdef EDMA3_INSTRUMENTATION_ENABLED
998 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
999 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1000 EDMA3_DVT_dCOUNTER,
1001 EDMA3_DVT_dNONE,
1002 EDMA3_DVT_dNONE));
1003 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1005 /* If parameter checking is enabled... */
1006 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1007 if ((hEdmaResMgr == NULL) || (resObj == NULL))
1008 {
1009 result = (EDMA3_RM_E_INVALID_PARAM);
1010 }
1011 #endif
1013 /* Check if the parameters are OK. */
1014 if (EDMA3_RM_SOK == result)
1015 {
1016 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1017 rmObj = rmInstance->pResMgrObjHandle;
1019 if ((rmObj == NULL) ||
1020 (rmObj->gblCfgParams.globalRegs == NULL))
1021 {
1022 result = (EDMA3_RM_E_INVALID_PARAM);
1023 }
1024 else
1025 {
1026 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1028 resId = resObj->resId;
1030 resIdClr = (unsigned int)(~(1u << (resId%32u)));
1031 resIdSet = (1u << (resId%32u));
1033 /**
1034 * Take the instance specific semaphore, to prevent simultaneous
1035 * access to the shared resources.
1036 */
1037 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
1038 EDMA3_OSSEM_NO_TIMEOUT);
1039 if (EDMA3_RM_SOK == semResult)
1040 {
1041 switch (resObj->type)
1042 {
1043 case EDMA3_RM_RES_DMA_CHANNEL :
1044 {
1045 if (resId == EDMA3_RM_RES_ANY)
1046 {
1047 for (avlblIdx=0u;
1048 avlblIdx <
1049 rmObj->gblCfgParams.numDmaChannels;
1050 ++avlblIdx)
1051 {
1052 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[avlblIdx/32u])
1053 &
1054 (rmInstance->avlblDmaChannels[avlblIdx/32u])
1055 &
1056 ~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[avlblIdx/32u])
1057 &
1058 (1u << (avlblIdx%32u))) != FALSE)
1059 {
1060 /*
1061 * Match found.
1062 * A resource which is owned by this instance of the
1063 * Resource Manager and which is presently available
1064 * and which has not been reserved - is found.
1065 */
1066 resObj->resId = avlblIdx;
1067 /*
1068 * Mark the 'match found' resource as "Not Available"
1069 * for future requests
1070 */
1071 rmInstance->avlblDmaChannels[avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
1073 /**
1074 * Check if the register modification flag is
1075 * set or not.
1076 */
1077 if (TRUE == rmInstance->regModificationRequired)
1078 {
1079 /**
1080 * Enable the DMA channel in the
1081 * DRAE/DRAEH registers also.
1082 */
1083 if (avlblIdx < 32u)
1084 {
1085 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1086 |= (0x1u << avlblIdx);
1087 }
1088 else
1089 {
1090 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1091 |= (0x1u << (avlblIdx - 32u));
1092 }
1093 }
1095 result = EDMA3_RM_SOK;
1096 break;
1097 }
1098 }
1099 /*
1100 * If none of the owned resources of this type is available
1101 * then report "All Resources of this type not available" error
1102 */
1103 if (avlblIdx == rmObj->gblCfgParams.numDmaChannels)
1104 {
1105 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1106 }
1107 }
1108 else
1109 {
1110 if (resId < rmObj->gblCfgParams.numDmaChannels)
1111 {
1112 /*
1113 * Check if specified resource is owned
1114 * by this instance of the resource manager
1115 */
1116 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resId/32u])&(resIdSet))!=FALSE)
1117 {
1118 /* Now check if specified resource is available presently*/
1119 if (((rmInstance->avlblDmaChannels[resId/32u])&(resIdSet))!=FALSE)
1120 {
1121 /*
1122 * Mark the specified channel as "Not Available"
1123 * for future requests
1124 */
1125 rmInstance->avlblDmaChannels[resId/32u] &= resIdClr;
1127 /**
1128 * Check if the register modification flag is
1129 * set or not.
1130 */
1131 if (TRUE == rmInstance->regModificationRequired)
1132 {
1133 if (resId < 32u)
1134 {
1135 rmInstance->shadowRegs->EECR = (1UL << resId);
1137 /**
1138 * Enable the DMA channel in the
1139 * DRAE registers also.
1140 */
1141 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1142 |= (0x1u << resId);
1143 }
1144 else
1145 {
1146 rmInstance->shadowRegs->EECRH = (1UL << resId);
1148 /**
1149 * Enable the DMA channel in the
1150 * DRAEH registers also.
1151 */
1152 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1153 |= (0x1u << (resId - 32u));
1154 }
1155 }
1157 result = EDMA3_RM_SOK;
1158 }
1159 else
1160 {
1161 /* Specified resource is owned but is already booked */
1162 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1163 }
1164 }
1165 else
1166 {
1167 /*
1168 * Specified resource is not owned by this instance
1169 * of the Resource Manager
1170 */
1171 result = EDMA3_RM_E_RES_NOT_OWNED;
1172 }
1173 }
1174 else
1175 {
1176 result = EDMA3_RM_E_INVALID_PARAM;
1177 }
1178 }
1179 }
1180 break;
1182 case EDMA3_RM_RES_QDMA_CHANNEL :
1183 {
1184 if (resId == EDMA3_RM_RES_ANY)
1185 {
1186 for (avlblIdx=0u; avlblIdx<rmObj->gblCfgParams.numQdmaChannels; ++avlblIdx)
1187 {
1188 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[avlblIdx/32u])
1189 &
1190 (rmInstance->avlblQdmaChannels[avlblIdx/32u])
1191 &
1192 ~(rmInstance->initParam.rmInstInitConfig->resvdQdmaChannels[avlblIdx/32u])
1193 &
1194 (1u << (avlblIdx%32u))) != FALSE)
1195 {
1196 resObj->resId = avlblIdx;
1197 rmInstance->avlblQdmaChannels[avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
1199 /**
1200 * Check if the register modification flag is
1201 * set or not.
1202 */
1203 if (TRUE == rmInstance->regModificationRequired)
1204 {
1205 /**
1206 * Enable the QDMA channel in the
1207 * QRAE register also.
1208 */
1209 gblRegs->QRAE[rmInstance->initParam.regionId]
1210 |= (0x1u << avlblIdx);
1211 }
1213 result = EDMA3_RM_SOK;
1214 break;
1215 }
1216 }
1217 /*
1218 * If none of the owned resources of this type is available
1219 * then report "All Resources of this type not available" error
1220 */
1221 if (avlblIdx == rmObj->gblCfgParams.numQdmaChannels)
1222 {
1223 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1224 }
1225 }
1226 else
1227 {
1228 if (resId < rmObj->gblCfgParams.numQdmaChannels)
1229 {
1230 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32u])&(resIdSet))!=FALSE)
1231 {
1232 if (((rmInstance->avlblQdmaChannels [resId/32u])&(resIdSet))!=FALSE)
1233 {
1234 rmInstance->avlblQdmaChannels [resId/32u] &= resIdClr;
1236 /**
1237 * Check if the register modification flag is
1238 * set or not.
1239 */
1240 if (TRUE == rmInstance->regModificationRequired)
1241 {
1242 /**
1243 * Enable the QDMA channel in the
1244 * QRAE register also.
1245 */
1246 gblRegs->QRAE[rmInstance->initParam.regionId]
1247 |= (0x1u << resId);
1248 }
1250 result = EDMA3_RM_SOK;
1251 }
1252 else
1253 {
1254 /* Specified resource is owned but is already booked */
1255 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1256 }
1257 }
1258 else
1259 {
1260 /*
1261 * Specified resource is not owned by this instance
1262 * of the Resource Manager
1263 */
1264 result = EDMA3_RM_E_RES_NOT_OWNED;
1265 }
1266 }
1267 else
1268 {
1269 result = EDMA3_RM_E_INVALID_PARAM;
1270 }
1271 }
1272 }
1273 break;
1275 case EDMA3_RM_RES_TCC :
1276 {
1277 if (resId == EDMA3_RM_RES_ANY)
1278 {
1279 for (avlblIdx=0u; avlblIdx<rmObj->gblCfgParams.numTccs; ++avlblIdx)
1280 {
1281 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [avlblIdx/32u])
1282 & (rmInstance->avlblTccs [avlblIdx/32u])
1283 & ~(rmInstance->initParam.rmInstInitConfig->resvdTccs [avlblIdx/32u])
1284 & (1u << (avlblIdx%32u)))!=FALSE)
1285 {
1286 resObj->resId = avlblIdx;
1287 rmInstance->avlblTccs [avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
1288 result = EDMA3_RM_SOK;
1289 break;
1290 }
1291 }
1292 /*
1293 * If none of the owned resources of this type is available
1294 * then report "All Resources of this type not available" error
1295 */
1296 if ( avlblIdx == rmObj->gblCfgParams.numTccs)
1297 {
1298 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1299 }
1300 }
1301 else
1302 {
1303 if (resId < rmObj->gblCfgParams.numTccs)
1304 {
1305 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32u])&(resIdSet))!=FALSE)
1306 {
1307 if (((rmInstance->avlblTccs [resId/32u])&(resIdSet))!=FALSE)
1308 {
1309 rmInstance->avlblTccs [resId/32u] &= resIdClr;
1310 result = EDMA3_RM_SOK;
1311 }
1312 else
1313 {
1314 /* Specified resource is owned but is already booked */
1315 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1316 }
1317 }
1318 else
1319 {
1320 /*
1321 * Specified resource is not owned by this instance
1322 * of the Resource Manager
1323 */
1324 result = EDMA3_RM_E_RES_NOT_OWNED;
1325 }
1326 }
1327 else
1328 {
1329 result = EDMA3_RM_E_INVALID_PARAM;
1330 }
1331 }
1332 }
1333 break;
1335 case EDMA3_RM_RES_PARAM_SET :
1336 {
1337 if (resId == EDMA3_RM_RES_ANY)
1338 {
1339 for (avlblIdx=0u; avlblIdx<rmObj->gblCfgParams.numPaRAMSets; ++avlblIdx)
1340 {
1341 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [avlblIdx/32u])
1342 &
1343 (rmInstance->avlblPaRAMSets [avlblIdx/32u])
1344 &
1345 ~(rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets [avlblIdx/32u])
1346 &
1347 (1u << (avlblIdx%32u)))!=FALSE)
1348 {
1349 resObj->resId = avlblIdx;
1350 rmInstance->avlblPaRAMSets [avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
1352 /**
1353 * Also, make the actual PARAM Set NULL, checking the flag
1354 * whether it is required or not.
1355 */
1356 if ((TRUE == rmInstance->regModificationRequired)
1357 && (TRUE == rmInstance->paramInitRequired))
1358 {
1359 edma3MemZero((void *)(&gblRegs->PARAMENTRY[avlblIdx]),
1360 sizeof(gblRegs->PARAMENTRY[avlblIdx]));
1361 }
1363 result = EDMA3_RM_SOK;
1364 break;
1365 }
1366 }
1367 /*
1368 * If none of the owned resources of this type is available
1369 * then report "All Resources of this type not available" error
1370 */
1371 if ( avlblIdx == rmObj->gblCfgParams.numPaRAMSets)
1372 {
1373 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1374 }
1375 }
1376 else
1377 {
1378 if (resId < rmObj->gblCfgParams.numPaRAMSets)
1379 {
1380 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32u])&(resIdSet))!=FALSE)
1381 {
1382 if (((rmInstance->avlblPaRAMSets [resId/32u])&(resIdSet)) !=FALSE)
1383 {
1384 rmInstance->avlblPaRAMSets [resId/32u] &= resIdClr;
1386 /**
1387 * Also, make the actual PARAM Set NULL, checking the flag
1388 * whether it is required or not.
1389 */
1390 if ((TRUE == rmInstance->regModificationRequired)
1391 && (TRUE == rmInstance->paramInitRequired))
1392 {
1393 edma3MemZero((void *)(&gblRegs->PARAMENTRY[resId]),
1394 sizeof(gblRegs->PARAMENTRY[resId]));
1395 }
1397 result = EDMA3_RM_SOK;
1398 }
1399 else
1400 {
1401 /* Specified resource is owned but is already booked */
1402 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1403 }
1404 }
1405 else
1406 {
1407 /*
1408 * Specified resource is not owned by this instance
1409 * of the Resource Manager
1410 */
1411 result = EDMA3_RM_E_RES_NOT_OWNED;
1412 }
1413 }
1414 else
1415 {
1416 result = EDMA3_RM_E_INVALID_PARAM;
1417 }
1418 }
1419 }
1420 break;
1422 default:
1423 result = EDMA3_RM_E_INVALID_PARAM;
1424 break;
1425 }
1427 /* Return the semaphore back */
1428 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
1429 }
1430 }
1431 }
1433 /**
1434 * Check the Resource Allocation Result 'result' first. If Resource
1435 * Allocation has resulted in an error, return it (having more priority than
1436 * semResult.
1437 * Else, return semResult.
1438 */
1439 if (EDMA3_RM_SOK == result)
1440 {
1441 /**
1442 * Resource Allocation successful, return semResult for returning
1443 * semaphore.
1444 */
1445 result = semResult;
1446 }
1448 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1449 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1450 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1451 EDMA3_DVT_dCOUNTER,
1452 EDMA3_DVT_dNONE,
1453 EDMA3_DVT_dNONE));
1454 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1456 return result;
1457 }
1459 EDMA3_RM_Result EDMA3_RM_freeResource(EDMA3_RM_Handle hEdmaResMgr,
1460 const EDMA3_RM_ResDesc *resObj)
1461 {
1462 unsigned int intState;
1463 EDMA3_RM_Instance *rmInstance = NULL;
1464 EDMA3_RM_Obj *rmObj = NULL;
1465 EDMA3_RM_Result result = EDMA3_RM_SOK;
1466 unsigned int resId;
1467 unsigned int resIdSet = 0x0;
1468 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1470 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1471 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1472 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1473 EDMA3_DVT_dCOUNTER,
1474 EDMA3_DVT_dNONE,
1475 EDMA3_DVT_dNONE));
1476 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1478 /* If parameter checking is enabled... */
1479 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1480 if ((hEdmaResMgr == NULL) || (resObj == NULL))
1481 {
1482 result = EDMA3_RM_E_INVALID_PARAM;
1483 }
1484 #endif
1486 /* Check if the parameters are OK. */
1487 if (EDMA3_RM_SOK == result)
1488 {
1489 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1490 rmObj = rmInstance->pResMgrObjHandle;
1492 if ((rmObj == NULL) ||
1493 (rmObj->gblCfgParams.globalRegs == NULL))
1494 {
1495 result = EDMA3_RM_E_INVALID_PARAM;
1496 }
1497 else
1498 {
1499 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1501 resId = resObj->resId;
1503 resIdSet = 1u << (resId%32u);
1505 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
1506 EDMA3_OS_PROTECT_INTERRUPT,
1507 &intState);
1509 if (EDMA3_RM_SOK == result)
1510 {
1511 switch (resObj->type)
1512 {
1513 case EDMA3_RM_RES_DMA_CHANNEL :
1514 {
1515 if (resId < rmObj->gblCfgParams.numDmaChannels)
1516 {
1517 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels [resId/32u]) & (resIdSet))!=FALSE)
1518 {
1519 if (((~(rmInstance->avlblDmaChannels[resId/32u]))&(resIdSet))!=FALSE)
1520 {
1521 /*
1522 * Mark the specified channel as "Available"
1523 * for future requests
1524 */
1525 rmInstance->avlblDmaChannels[resId/32u] |= resIdSet;
1527 /**
1528 * Check if the register modification flag is
1529 * set or not.
1530 */
1531 if (TRUE == rmInstance->regModificationRequired)
1532 {
1533 /**
1534 * DMA Channel is freed.
1535 * Reset the bit specific to the DMA channel
1536 * in the DRAE/DRAEH register also.
1537 */
1538 if (resId < 32u)
1539 {
1540 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1541 &= (~(0x1u << resId));
1542 }
1543 else
1544 {
1545 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1546 &= (~(0x1u << (resId-32u)));
1547 }
1548 }
1550 result = EDMA3_RM_SOK;
1551 }
1552 else
1553 {
1554 result = EDMA3_RM_E_RES_ALREADY_FREE;
1555 }
1556 }
1557 else
1558 {
1559 /*
1560 * Specified resource is not owned by this instance
1561 * of the Resource Manager
1562 */
1563 result = EDMA3_RM_E_RES_NOT_OWNED;
1564 }
1565 }
1566 else
1567 {
1568 result = EDMA3_RM_E_INVALID_PARAM;
1569 }
1570 }
1571 break;
1573 case EDMA3_RM_RES_QDMA_CHANNEL :
1574 {
1575 if (resId < rmObj->gblCfgParams.numQdmaChannels)
1576 {
1577 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32u]) & (resIdSet))!=FALSE)
1578 {
1579 if (((~(rmInstance->avlblQdmaChannels [resId/32u])) & (resIdSet))!=FALSE)
1580 {
1581 rmInstance->avlblQdmaChannels [resId/32u] |= resIdSet;
1583 /**
1584 * Check if the register modification flag is
1585 * set or not.
1586 */
1587 if (TRUE == rmInstance->regModificationRequired)
1588 {
1589 /**
1590 * QDMA Channel is freed.
1591 * Reset the bit specific to the QDMA channel
1592 * in the QRAE register also.
1593 */
1594 gblRegs->QRAE[rmInstance->initParam.regionId]
1595 &= (~(0x1u << resId));
1596 }
1598 result = EDMA3_RM_SOK;
1599 }
1600 else
1601 {
1602 result = EDMA3_RM_E_RES_ALREADY_FREE;
1603 }
1604 }
1605 else
1606 {
1607 /*
1608 * Specified resource is not owned by this instance
1609 * of the Resource Manager
1610 */
1611 result = EDMA3_RM_E_RES_NOT_OWNED;
1612 }
1613 }
1614 else
1615 {
1616 result = EDMA3_RM_E_INVALID_PARAM;
1617 }
1618 }
1619 break;
1621 case EDMA3_RM_RES_TCC :
1622 {
1623 if (resId < rmObj->gblCfgParams.numTccs)
1624 {
1625 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32u]) & (resIdSet))!=FALSE)
1626 {
1627 if (((~(rmInstance->avlblTccs [resId/32u])) & (resIdSet))!=FALSE)
1628 {
1629 rmInstance->avlblTccs [resId/32u] |= resIdSet;
1631 result = EDMA3_RM_SOK;
1632 }
1633 else
1634 {
1635 result = EDMA3_RM_E_RES_ALREADY_FREE;
1636 }
1637 }
1638 else
1639 {
1640 /*
1641 * Specified resource is not owned by this instance
1642 * of the Resource Manager
1643 */
1644 result = EDMA3_RM_E_RES_NOT_OWNED;
1645 }
1646 }
1647 else
1648 {
1649 result = EDMA3_RM_E_INVALID_PARAM;
1650 }
1651 }
1652 break;
1654 case EDMA3_RM_RES_PARAM_SET :
1655 {
1656 if (resId < rmObj->gblCfgParams.numPaRAMSets)
1657 {
1658 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32u])&(resIdSet))!=FALSE)
1659 {
1660 if (((~(rmInstance->avlblPaRAMSets [resId/32u]))&(resIdSet))!=FALSE)
1661 {
1662 rmInstance->avlblPaRAMSets [resId/32u] |= resIdSet;
1664 result = EDMA3_RM_SOK;
1665 }
1666 else
1667 {
1668 result = EDMA3_RM_E_RES_ALREADY_FREE;
1669 }
1670 }
1671 else
1672 {
1673 /*
1674 * Specified resource is not owned by this instance
1675 * of the Resource Manager
1676 */
1677 result = EDMA3_RM_E_RES_NOT_OWNED;
1678 }
1679 }
1680 else
1681 {
1682 result = EDMA3_RM_E_INVALID_PARAM;
1683 }
1684 }
1685 break;
1687 default:
1688 result = EDMA3_RM_E_INVALID_PARAM;
1689 break;
1690 }
1692 }
1694 edma3OsProtectExit (rmObj->phyCtrllerInstId,
1695 EDMA3_OS_PROTECT_INTERRUPT,
1696 intState);
1697 }
1698 }
1700 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1701 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1702 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1703 EDMA3_DVT_dCOUNTER,
1704 EDMA3_DVT_dNONE,
1705 EDMA3_DVT_dNONE));
1706 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1708 return result;
1709 }
1711 EDMA3_RM_Result EDMA3_RM_allocLogicalChannel(EDMA3_RM_Handle hEdmaResMgr,
1712 EDMA3_RM_ResDesc *lChObj,
1713 unsigned int *pParam,
1714 unsigned int *pTcc)
1715 {
1716 EDMA3_RM_ResDesc *chObj;
1717 EDMA3_RM_ResDesc resObj;
1718 EDMA3_RM_Result result = EDMA3_RM_SOK;
1719 EDMA3_RM_Instance *rmInstance = NULL;
1720 EDMA3_RM_Obj *rmObj = NULL;
1721 unsigned int mappedPaRAMId=0u;
1722 unsigned int mappedTcc = EDMA3_RM_CH_NO_TCC_MAP;
1723 int paRAMId = (int)EDMA3_RM_RES_ANY;
1724 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1725 unsigned int qdmaChId = EDMA3_MAX_PARAM_SETS;
1726 unsigned int edma3Id;
1728 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1729 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1730 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1731 EDMA3_DVT_dCOUNTER,
1732 EDMA3_DVT_dNONE,
1733 EDMA3_DVT_dNONE));
1734 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1736 /* If parameter checking is enabled... */
1737 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1738 if ((lChObj == NULL) || (hEdmaResMgr == NULL))
1739 {
1740 result = EDMA3_RM_E_INVALID_PARAM;
1741 }
1742 #endif
1744 /* Check if the parameters are OK. */
1745 if (EDMA3_RM_SOK == result)
1746 {
1747 chObj = lChObj;
1749 if ((chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
1750 || (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL))
1751 {
1752 /**
1753 * If the request is for a DMA or QDMA channel, check the
1754 * pParam and pTcc objects also.
1755 * For the Link channel request, they could be NULL.
1756 */
1757 /* If parameter checking is enabled... */
1758 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1759 if ((pParam == NULL) || (pTcc == NULL))
1760 {
1761 result = EDMA3_RM_E_INVALID_PARAM;
1762 }
1763 #endif
1764 }
1765 }
1767 if (result == EDMA3_RM_SOK)
1768 {
1769 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1771 if (rmInstance == NULL)
1772 {
1773 result = EDMA3_RM_E_INVALID_PARAM;
1774 }
1775 }
1777 if (result == EDMA3_RM_SOK)
1778 {
1779 rmObj = rmInstance->pResMgrObjHandle;
1781 if (rmObj == NULL)
1782 {
1783 result = EDMA3_RM_E_INVALID_PARAM;
1784 }
1785 else
1786 {
1787 if (rmObj->gblCfgParams.globalRegs == NULL)
1788 {
1789 result = EDMA3_RM_E_INVALID_PARAM;
1790 }
1791 }
1792 }
1794 if (result == EDMA3_RM_SOK)
1795 {
1796 edma3Id = rmObj->phyCtrllerInstId;
1797 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1799 switch (chObj->type)
1800 {
1801 case EDMA3_RM_RES_DMA_CHANNEL:
1802 {
1803 if ((chObj->resId == EDMA3_RM_DMA_CHANNEL_ANY)
1804 || (chObj->resId == EDMA3_RM_RES_ANY))
1805 {
1806 /* Request for ANY DMA channel. */
1807 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
1808 resObj.resId = EDMA3_RM_RES_ANY;
1809 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
1811 if (result == EDMA3_RM_SOK)
1812 {
1813 /* DMA channel allocated successfully. */
1814 chObj->resId = resObj.resId;
1816 /**
1817 * Check the PaRAM Set user has specified for this DMA channel.
1818 * Two cases exist:
1819 * a) DCHMAP exists: Any PaRAM Set can be used
1820 * b) DCHMAP does not exist: Should not be possible
1821 * only if the channel allocated (ANY) and PaRAM requested
1822 * are same.
1823 */
1824 if ((*pParam) == EDMA3_RM_PARAM_ANY)
1825 {
1826 /* User specified ANY PaRAM Set; Check the mapping. */
1827 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
1828 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
1829 {
1830 /** If some PaRAM set is statically mapped to the returned
1831 * channel number, use that.
1832 */
1833 paRAMId = (int)mappedPaRAMId;
1834 }
1835 }
1836 else
1837 {
1838 /* User specified some PaRAM Set; check that can be used or not. */
1839 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
1840 {
1841 paRAMId = (int)(*pParam);
1842 }
1843 else
1844 {
1845 /**
1846 * Channel mapping does not exist. If the PaRAM Set requested
1847 * is the same as dma channel allocated (coincidentally), it is fine.
1848 * Else return error.
1849 */
1850 if ((*pParam) != (resObj.resId))
1851 {
1852 result = EDMA3_RM_E_INVALID_PARAM;
1854 /**
1855 * Free the previously allocated DMA channel also.
1856 */
1857 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
1858 }
1859 else
1860 {
1861 paRAMId = (int)(*pParam);
1862 }
1863 }
1864 }
1866 mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[resObj.resId];
1867 }
1868 }
1869 else
1870 {
1871 if (chObj->resId <= edma3_dma_ch_max_val[edma3Id])
1872 {
1873 /* Request for a specific DMA channel */
1874 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
1875 resObj.resId = chObj->resId;
1876 result = EDMA3_RM_allocResource(hEdmaResMgr,
1877 (EDMA3_RM_ResDesc *)&resObj);
1879 if (result == EDMA3_RM_SOK)
1880 {
1881 /**
1882 * Check the PaRAM Set user has specified for this DMA channel.
1883 * Two cases exist:
1884 * a) DCHMAP exists: Any PaRAM Set can be used
1885 * b) DCHMAP does not exist: Should not be possible
1886 * only if the channel allocated (ANY) and PaRAM requested
1887 * are same.
1888 */
1889 if ((*pParam) == EDMA3_RM_PARAM_ANY)
1890 {
1891 /* User specified ANY PaRAM Set; Check the mapping. */
1892 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
1893 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
1894 {
1895 /** If some PaRAM set is statically mapped to the returned
1896 * channel number, use that.
1897 */
1898 paRAMId = (int)mappedPaRAMId;
1899 }
1900 }
1901 else
1902 {
1903 /* User specified some PaRAM Set; check that can be used or not. */
1904 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
1905 {
1906 paRAMId = (int)(*pParam);
1907 }
1908 else
1909 {
1910 /**
1911 * Channel mapping does not exist. If the PaRAM Set requested
1912 * is the same as dma channel allocated (coincidentally), it is fine.
1913 * Else return error.
1914 */
1915 if ((*pParam) != (resObj.resId))
1916 {
1917 result = EDMA3_RM_E_INVALID_PARAM;
1919 /**
1920 * Free the previously allocated DMA channel also.
1921 */
1922 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
1923 }
1924 else
1925 {
1926 paRAMId = (int)(*pParam);
1927 }
1928 }
1929 }
1931 mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[chObj->resId];
1932 }
1933 }
1934 else
1935 {
1936 result = EDMA3_RM_E_INVALID_PARAM;
1937 }
1938 }
1939 }
1940 break;
1943 case EDMA3_RM_RES_QDMA_CHANNEL:
1944 {
1945 if ((chObj->resId == EDMA3_RM_QDMA_CHANNEL_ANY)
1946 || (chObj->resId == EDMA3_RM_RES_ANY))
1947 {
1948 /* First request for any available QDMA channel */
1949 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
1950 resObj.resId = EDMA3_RM_RES_ANY;
1951 result = EDMA3_RM_allocResource(hEdmaResMgr,
1952 (EDMA3_RM_ResDesc *)&resObj);
1954 if (result == EDMA3_RM_SOK)
1955 {
1956 /* Return the actual QDMA channel id. */
1957 chObj->resId = resObj.resId;
1959 /* Save the Logical-QDMA channel id for future use. */
1960 qdmaChId = resObj.resId + edma3_qdma_ch_min_val[edma3Id];
1962 /**
1963 * Check the PaRAM Set user has specified for this QDMA channel.
1964 * If he has specified any particular PaRAM Set, use that.
1965 */
1966 if ((*pParam) != EDMA3_RM_PARAM_ANY)
1967 {
1968 /* User specified ANY PaRAM Set; Check the mapping. */
1969 paRAMId = (int)(*pParam);
1970 }
1971 }
1972 }
1973 else
1974 {
1975 if (chObj->resId < rmObj->gblCfgParams.numQdmaChannels)
1976 {
1977 /* Request for a specific QDMA channel */
1978 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
1979 resObj.resId = chObj->resId;
1980 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
1982 if (result == EDMA3_RM_SOK)
1983 {
1984 /* Save the Logical-QDMA channel id for future use. */
1985 qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
1987 /**
1988 * Check the PaRAM Set user has specified for this QDMA channel.
1989 * If he has specified any particular PaRAM Set, use that.
1990 */
1991 if ((*pParam) != EDMA3_RM_PARAM_ANY)
1992 {
1993 /* User specified ANY PaRAM Set; Check the mapping. */
1994 paRAMId = (int)(*pParam);
1995 }
1996 }
1997 }
1998 else
1999 {
2000 result = EDMA3_RM_E_INVALID_PARAM;
2001 }
2002 }
2003 }
2004 break;
2006 case EDMA3_RM_RES_PARAM_SET:
2007 {
2008 /* Request for a LINK channel. */
2009 if ((chObj->resId == EDMA3_RM_PARAM_ANY)
2010 || (chObj->resId == EDMA3_RM_RES_ANY))
2011 {
2012 /* Request for ANY LINK channel. */
2013 paRAMId = (int)EDMA3_RM_RES_ANY;
2014 }
2015 else
2016 {
2017 if (chObj->resId < edma3NumPaRAMSets)
2018 {
2019 /* Request for a Specific LINK channel. */
2020 paRAMId = (int)(chObj->resId);
2021 }
2022 else
2023 {
2024 result = EDMA3_RM_E_INVALID_PARAM;
2025 }
2026 }
2028 if (result == EDMA3_RM_SOK)
2029 {
2030 /* Try to allocate the link channel */
2031 resObj.type = EDMA3_RM_RES_PARAM_SET;
2032 resObj.resId = (unsigned int)paRAMId;
2033 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2035 if (result == EDMA3_RM_SOK)
2036 {
2037 unsigned int linkCh = edma3_link_ch_min_val[edma3Id];
2039 /* Return the actual PaRAM Id. */
2040 chObj->resId = resObj.resId;
2042 /*
2043 * Search for the next Link channel place-holder available,
2044 * starting from EDMA3_RM_LINK_CH_MIN_VAL.
2045 * It will be used for future operations on the Link channel.
2046 */
2047 while ((edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId != -1)
2048 && (linkCh <= edma3_link_ch_max_val[edma3Id]))
2049 {
2050 /* Move to the next place-holder. */
2051 linkCh++;
2052 }
2054 /* Verify the returned handle, it should lie in the correct range */
2055 if (linkCh > edma3_link_ch_max_val[edma3Id])
2056 {
2057 result = EDMA3_RM_E_INVALID_PARAM;
2059 /* Free the PaRAM Set now. */
2060 resObj.type = EDMA3_RM_RES_PARAM_SET;
2061 resObj.resId = chObj->resId;
2062 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2063 }
2064 else
2065 {
2066 /* Save the PaRAM Id for the Link Channel. */
2067 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = (int)(chObj->resId);
2069 /**
2070 * Remove any linking. Before doing that, check
2071 * whether it is permitted or not.
2072 */
2073 if (TRUE == rmInstance->regModificationRequired)
2074 {
2075 *((&gblRegs->PARAMENTRY[chObj->resId].OPT)
2076 + (unsigned int)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2077 }
2078 }
2079 }
2080 }
2081 }
2082 break;
2084 default:
2085 result = EDMA3_RM_E_INVALID_PARAM;
2086 }
2087 }
2090 if (result == EDMA3_RM_SOK)
2091 {
2092 /**
2093 * For DMA/QDMA channels, we still have to allocate more resources like
2094 * TCC, PaRAM Set etc.
2095 * For Link channel, only the PaRAMSet is required and that has been
2096 * allocated so no further operations required.
2097 */
2099 /* Further resources' allocation for DMA channel. */
2100 if (chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
2101 {
2102 /* First allocate a PaRAM Set */
2103 resObj.type = EDMA3_RM_RES_PARAM_SET;
2104 /* Use the saved param id now. */
2105 resObj.resId = (unsigned int)paRAMId;
2106 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2107 if (result == EDMA3_RM_SOK)
2108 {
2109 /**
2110 * PaRAM Set allocation succeeded.
2111 * Save the PaRAM Set first.
2112 */
2113 *pParam = resObj.resId;
2114 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = (int)(resObj.resId);
2116 /* Allocate the TCC now. */
2117 resObj.type = EDMA3_RM_RES_TCC;
2118 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2119 {
2120 if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2121 {
2122 resObj.resId = EDMA3_RM_RES_ANY;
2123 }
2124 else
2125 {
2126 resObj.resId = mappedTcc;
2127 }
2128 }
2129 else
2130 {
2131 resObj.resId = *pTcc;
2132 }
2134 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2135 if (result == EDMA3_RM_SOK)
2136 {
2137 /* TCC allocation succeeded. Save it first. */
2138 *pTcc = resObj.resId;
2139 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].tcc = resObj.resId;
2141 /**
2142 * Check first whether the global registers and the allocated
2143 * PaRAM Set can be modified or not. If yes, do the needful.
2144 * Else leave this for the user.
2145 */
2146 if (TRUE == rmInstance->regModificationRequired)
2147 {
2148 /* Set TCC of the allocated Param Set. */
2149 gblRegs->PARAMENTRY[*pParam].OPT &= EDMA3_RM_OPT_TCC_CLR_MASK;
2150 gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2152 /**
2153 * Do the mapping between DMA channel and PaRAM Set.
2154 * Do this for the EDMA3 Controllers which have a register for mapping
2155 * DMA Channel to a particular PaRAM Set.
2156 */
2157 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2158 {
2159 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2161 /* Map Parameter RAM Set Number for specified channelId */
2162 gblRegs->DCHMAP[chObj->resId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
2163 gblRegs->DCHMAP[chObj->resId] |= EDMA3_RM_DCH_PARAM_SET_MASK(*pParam);
2164 }
2166 /* Remove any linking */
2167 *((&gblRegs->PARAMENTRY[*pParam].OPT)
2168 + (unsigned int)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2169 }
2170 }
2171 else
2172 {
2173 /**
2174 * TCC allocation failed, free the previously allocated
2175 * PaRAM Set and DMA channel.
2176 */
2177 resObj.type = EDMA3_RM_RES_PARAM_SET;
2178 resObj.resId = *pParam;
2179 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2181 /* Reset the book-keeping data structure also. */
2182 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = -1;
2184 resObj.type = chObj->type;
2185 resObj.resId = chObj->resId;
2186 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2187 }
2188 }
2189 else
2190 {
2191 /**
2192 * PaRAM Set allocation failed, free the previously allocated
2193 * DMA channel also.
2194 */
2195 resObj.type = chObj->type;
2196 resObj.resId = chObj->resId;
2197 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2198 }
2199 }
2202 /* Further resources' allocation for QDMA channel. */
2203 if (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
2204 {
2205 /* First allocate a PaRAM Set */
2206 resObj.type = EDMA3_RM_RES_PARAM_SET;
2207 /* Use the saved param id now. */
2208 resObj.resId = (unsigned int)paRAMId;
2209 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2210 if (result == EDMA3_RM_SOK)
2211 {
2212 /**
2213 * PaRAM Set allocation succeeded.
2214 * Save the PaRAM Set first.
2215 */
2216 *pParam = resObj.resId;
2217 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = (int)(resObj.resId);
2219 /* Allocate the TCC now. */
2220 resObj.type = EDMA3_RM_RES_TCC;
2221 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2222 {
2223 if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2224 {
2225 resObj.resId = EDMA3_RM_RES_ANY;
2226 }
2227 else
2228 {
2229 resObj.resId = mappedTcc;
2230 }
2231 }
2232 else
2233 {
2234 resObj.resId = *pTcc;
2235 }
2237 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2238 if (result == EDMA3_RM_SOK)
2239 {
2240 /* TCC allocation succeeded. Save it first. */
2241 *pTcc = resObj.resId;
2242 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = resObj.resId;
2244 /**
2245 * Check first whether the global registers and the allocated
2246 * PaRAM Set can be modified or not. If yes, do the needful.
2247 * Else leave this for the user.
2248 */
2249 if (TRUE == rmInstance->regModificationRequired)
2250 {
2251 /* Set TCC of the allocated Param Set. */
2252 gblRegs->PARAMENTRY[*pParam].OPT &= EDMA3_RM_OPT_TCC_CLR_MASK;
2253 gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2255 /* Do the mapping between QDMA channel and PaRAM Set. */
2256 /* Map Parameter RAM Set Number for specified channelId */
2257 gblRegs->QCHMAP[chObj->resId]
2258 &= EDMA3_RM_QCH_PARAM_CLR_MASK;
2259 gblRegs->QCHMAP[chObj->resId]
2260 |= EDMA3_RM_QCH_PARAM_SET_MASK(*pParam);
2262 /* Set the Trigger Word */
2263 gblRegs->QCHMAP[chObj->resId]
2264 &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
2265 gblRegs->QCHMAP[chObj->resId]
2266 |= EDMA3_RM_QCH_TRWORD_SET_MASK(EDMA3_RM_QDMA_TRIG_DEFAULT);
2268 /* Remove any linking */
2269 *((&gblRegs->PARAMENTRY[*pParam].OPT)
2270 + (unsigned int)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2272 /* Enable the transfer also. */
2273 rmInstance->shadowRegs->QEESR = (1u << chObj->resId);
2274 }
2275 }
2276 else
2277 {
2278 /**
2279 * TCC allocation failed, free the previously allocated
2280 * PaRAM Set and QDMA channel.
2281 */
2282 resObj.type = EDMA3_RM_RES_PARAM_SET;
2283 resObj.resId = *pParam;
2284 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2286 /* Reset the book-keeping data structure also. */
2287 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
2289 resObj.type = chObj->type;
2290 resObj.resId = chObj->resId;
2291 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2292 }
2293 }
2294 else
2295 {
2296 /**
2297 * PaRAM Set allocation failed, free the previously allocated
2298 * QDMA channel also.
2299 */
2300 resObj.type = chObj->type;
2301 resObj.resId = chObj->resId;
2302 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2303 }
2304 }
2305 }
2308 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2309 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2310 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2311 EDMA3_DVT_dCOUNTER,
2312 EDMA3_DVT_dNONE,
2313 EDMA3_DVT_dNONE));
2314 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2317 return result;
2318 }
2320 EDMA3_RM_Result EDMA3_RM_freeLogicalChannel (EDMA3_RM_Handle hEdmaResMgr,
2321 EDMA3_RM_ResDesc *lChObj)
2322 {
2323 EDMA3_RM_ResDesc *chObj;
2324 EDMA3_RM_ResDesc resObj;
2325 EDMA3_RM_Result result = EDMA3_RM_SOK;
2326 EDMA3_RM_Instance *rmInstance = NULL;
2327 EDMA3_RM_Obj *rmObj = NULL;
2328 int paRAMId;
2329 unsigned int tcc;
2330 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
2331 unsigned int qdmaChId;
2332 unsigned int dmaChId;
2333 EDMA3_RM_InstanceInitConfig *rmConfig = NULL;
2334 unsigned int edma3Id;
2336 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2337 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2338 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2339 EDMA3_DVT_dCOUNTER,
2340 EDMA3_DVT_dNONE,
2341 EDMA3_DVT_dNONE));
2342 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2345 /* If parameter checking is enabled... */
2346 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2347 if ((lChObj == NULL) || (hEdmaResMgr == NULL))
2348 {
2349 result = (EDMA3_RM_E_INVALID_PARAM);
2350 }
2351 #endif
2353 /* Check if the parameters are OK. */
2354 if (result == EDMA3_RM_SOK)
2355 {
2356 chObj = lChObj;
2358 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2360 if (rmInstance == NULL)
2361 {
2362 result = EDMA3_RM_E_INVALID_PARAM;
2363 }
2364 }
2366 if (result == EDMA3_RM_SOK)
2367 {
2368 rmConfig = rmInstance->initParam.rmInstInitConfig;
2369 rmObj = rmInstance->pResMgrObjHandle;
2371 if (rmObj == NULL)
2372 {
2373 result = EDMA3_RM_E_INVALID_PARAM;
2374 }
2375 else
2376 {
2377 if (rmObj->gblCfgParams.globalRegs == NULL)
2378 {
2379 result = EDMA3_RM_E_INVALID_PARAM;
2380 }
2381 else
2382 {
2383 edma3Id = rmObj->phyCtrllerInstId;
2384 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2385 }
2386 }
2387 }
2390 if (result == EDMA3_RM_SOK)
2391 {
2392 switch (chObj->type)
2393 {
2394 case EDMA3_RM_RES_DMA_CHANNEL:
2395 {
2396 /* Save the DMA channel first. */
2397 dmaChId = chObj->resId;
2399 /**
2400 * Validate DMA channel id first.
2401 * It should be a valid channel id.
2402 */
2403 if (dmaChId >= EDMA3_MAX_DMA_CH)
2404 {
2405 result = EDMA3_RM_E_INVALID_PARAM;
2406 }
2408 /* It should be owned and allocated by this RM only. */
2409 if (result == EDMA3_RM_SOK)
2410 {
2411 if (((rmConfig->ownDmaChannels[dmaChId/32u])
2412 &
2413 (~(rmInstance->avlblDmaChannels[dmaChId/32u]))
2414 &
2415 (1u << (dmaChId%32u))) != FALSE)
2416 {
2417 /** Perfectly valid channel id.
2418 * Clear some channel specific registers, if it is permitted.
2419 */
2420 if (TRUE == rmInstance->regModificationRequired)
2421 {
2422 if (dmaChId < 32u)
2423 {
2424 if((rmInstance->shadowRegs->SER & (1u<<dmaChId))!=FALSE)
2425 {
2426 rmInstance->shadowRegs->SECR = (1u<<dmaChId);
2427 }
2428 if((globalRegs->EMR & (1u<<dmaChId))!=FALSE)
2429 {
2430 globalRegs->EMCR = (1u<<dmaChId);
2431 }
2432 }
2433 else
2434 {
2435 if((rmInstance->shadowRegs->SERH & (1u<<(dmaChId-32u)))!=FALSE)
2436 {
2437 rmInstance->shadowRegs->SECRH = (1u<<(dmaChId-32u));
2438 }
2439 if((globalRegs->EMRH & (1u<<(dmaChId-32u)))!=FALSE)
2440 {
2441 globalRegs->EMCRH = (1u<<(dmaChId-32u));
2442 }
2443 }
2445 /* Clear DCHMAP register also. */
2446 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2447 {
2448 globalRegs->DCHMAP[dmaChId] &=
2449 EDMA3_RM_DCH_PARAM_CLR_MASK;
2450 }
2451 }
2453 /* Free the PaRAM Set Now. */
2454 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].paRAMId;
2455 resObj.type = EDMA3_RM_RES_PARAM_SET;
2456 resObj.resId = (unsigned int)paRAMId;
2457 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2458 }
2459 else
2460 {
2461 /* Channel id has some problem. */
2462 result = EDMA3_RM_E_INVALID_PARAM;
2463 }
2464 }
2467 if (result == EDMA3_RM_SOK)
2468 {
2469 /* PaRAM Set Freed */
2470 edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].paRAMId = -1;
2472 /* Free the TCC */
2473 tcc = edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].tcc;
2474 resObj.type = EDMA3_RM_RES_TCC;
2475 resObj.resId = tcc;
2476 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2477 }
2479 if (result == EDMA3_RM_SOK)
2480 {
2481 /* TCC Freed */
2482 edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].tcc = EDMA3_MAX_TCC;
2484 /**
2485 * Try to free the DMA Channel now. DMA Channel should
2486 * be freed only in the end because while freeing, DRAE
2487 * registers will be RESET.
2488 * After that, no shadow region specific DMA channel
2489 * register can be modified. So reset that DRAE register
2490 * ONLY in the end.
2491 */
2492 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2493 resObj.resId = dmaChId;
2494 result = EDMA3_RM_freeResource(hEdmaResMgr,
2495 (EDMA3_RM_ResDesc *)&resObj);
2496 }
2497 }
2498 break;
2501 case EDMA3_RM_RES_QDMA_CHANNEL:
2502 {
2503 /**
2504 * Calculate QDMA Logical Channel Id first.
2505 * User has given the actual QDMA channel id.
2506 * So we have to convert it to make the logical
2507 * QDMA channel id first.
2508 */
2509 qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
2511 /**
2512 * Validate QDMA channel id first.
2513 * It should be a valid channel id.
2514 */
2515 if (chObj->resId >= EDMA3_MAX_QDMA_CH)
2516 {
2517 result = EDMA3_RM_E_INVALID_PARAM;
2518 }
2520 /* It should be owned and allocated by this RM only. */
2521 if (result == EDMA3_RM_SOK)
2522 {
2523 if (((rmConfig->ownQdmaChannels[0u])
2524 &
2525 (~(rmInstance->avlblQdmaChannels[0u]))
2526 &
2527 (1u << chObj->resId)) != FALSE)
2528 {
2529 /** Perfectly valid channel id.
2530 * Clear some channel specific registers, if
2531 * it is permitted.
2532 */
2533 if (TRUE == rmInstance->regModificationRequired)
2534 {
2535 rmInstance->shadowRegs->QEECR = (1u<<chObj->resId);
2537 if((globalRegs->QEMR & (1u<<chObj->resId))!=FALSE)
2538 {
2539 globalRegs->QEMCR = (1u<<chObj->resId);
2540 }
2542 /* Unmap PARAM Set Number for specified channelId */
2543 globalRegs->QCHMAP[chObj->resId] &=
2544 EDMA3_RM_QCH_PARAM_CLR_MASK;
2546 /* Reset the Trigger Word */
2547 globalRegs->QCHMAP[chObj->resId] &=
2548 EDMA3_RM_QCH_TRWORD_CLR_MASK;
2549 }
2551 /* Free the PaRAM Set now */
2552 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId;
2553 resObj.type = EDMA3_RM_RES_PARAM_SET;
2554 resObj.resId = (int)paRAMId;
2555 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2556 }
2557 else
2558 {
2559 /* Channel id has some problem. */
2560 result = EDMA3_RM_E_INVALID_PARAM;
2561 }
2562 }
2565 if (result == EDMA3_RM_SOK)
2566 {
2567 /* PaRAM Set Freed */
2568 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
2570 /* Free the TCC */
2571 tcc = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc;
2572 resObj.type = EDMA3_RM_RES_TCC;
2573 resObj.resId = tcc;
2574 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2575 }
2577 if (result == EDMA3_RM_SOK)
2578 {
2579 /* TCC Freed */
2580 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = EDMA3_MAX_TCC;
2582 /**
2583 * Try to free the QDMA Channel now. QDMA Channel should
2584 * be freed only in the end because while freeing, QRAE
2585 * registers will be RESET.
2586 * After that, no shadow region specific QDMA channel
2587 * register can be modified. So reset that QDRAE register
2588 * ONLY in the end.
2589 */
2590 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2591 resObj.resId = chObj->resId;
2592 result = EDMA3_RM_freeResource(hEdmaResMgr,
2593 (EDMA3_RM_ResDesc *)&resObj);
2594 }
2595 }
2596 break;
2599 case EDMA3_RM_RES_PARAM_SET:
2600 {
2601 /* Link Channel */
2602 if (chObj->resId < edma3NumPaRAMSets)
2603 {
2604 resObj.type = EDMA3_RM_RES_PARAM_SET;
2605 resObj.resId = chObj->resId;
2607 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2608 if (result == EDMA3_RM_SOK)
2609 {
2610 /* PaRAM Set freed successfully. */
2611 unsigned int linkCh = edma3_link_ch_min_val[edma3Id];
2613 /* Reset the Logical-Link channel */
2614 /* Search for the Logical-Link channel first */
2615 for (linkCh = edma3_link_ch_min_val[edma3Id];
2616 linkCh < edma3_link_ch_max_val[edma3Id];
2617 linkCh++)
2618 {
2619 if (edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId == chObj->resId)
2620 {
2621 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = -1;
2622 break;
2623 }
2624 }
2625 }
2626 }
2627 else
2628 {
2629 result = EDMA3_RM_E_INVALID_PARAM;
2630 }
2631 }
2632 break;
2634 default:
2635 result = EDMA3_RM_E_INVALID_PARAM;
2636 }
2637 }
2640 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2641 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2642 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2643 EDMA3_DVT_dCOUNTER,
2644 EDMA3_DVT_dNONE,
2645 EDMA3_DVT_dNONE));
2646 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2648 return result;
2649 }
2651 EDMA3_RM_Result EDMA3_RM_mapEdmaChannel (EDMA3_RM_Handle hEdmaResMgr,
2652 unsigned int channelId,
2653 unsigned int paRAMId)
2654 {
2655 EDMA3_RM_Instance *rmInstance = NULL;
2656 EDMA3_RM_Obj *rmObj = NULL;
2657 EDMA3_RM_Result result = EDMA3_RM_SOK;
2658 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
2660 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2661 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2662 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2663 EDMA3_DVT_dCOUNTER,
2664 EDMA3_DVT_dNONE,
2665 EDMA3_DVT_dNONE));
2666 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2668 /* If parameter checking is enabled... */
2669 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2670 if (hEdmaResMgr == NULL)
2671 {
2672 result = EDMA3_RM_E_INVALID_PARAM;
2673 }
2674 #endif
2676 if (result == EDMA3_RM_SOK)
2677 {
2678 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2680 if (rmInstance == NULL)
2681 {
2682 result = EDMA3_RM_E_INVALID_PARAM;
2683 }
2684 }
2686 if (result == EDMA3_RM_SOK)
2687 {
2688 rmObj = rmInstance->pResMgrObjHandle;
2690 if (rmObj == NULL)
2691 {
2692 result = EDMA3_RM_E_INVALID_PARAM;
2693 }
2694 else
2695 {
2696 if (rmObj->gblCfgParams.globalRegs == NULL)
2697 {
2698 result = EDMA3_RM_E_INVALID_PARAM;
2699 }
2700 }
2701 }
2703 if (result == EDMA3_RM_SOK)
2704 {
2705 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2707 /* If parameter checking is enabled... */
2708 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2709 if ((paRAMId >= rmObj->gblCfgParams.numPaRAMSets)
2710 || (channelId >= rmObj->gblCfgParams.numDmaChannels))
2711 {
2712 result = EDMA3_RM_E_INVALID_PARAM;
2713 }
2714 #endif
2715 }
2717 /* DMA channel and PaRAM Set should be previously allocated. */
2718 if (result == EDMA3_RM_SOK)
2719 {
2720 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[channelId/32u])
2721 &
2722 (~(rmInstance->avlblDmaChannels[channelId/32u]))
2723 &
2724 (1u << (channelId%32u))) != FALSE)
2725 {
2726 /* DMA channel allocated, check for the PaRAM Set */
2727 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[paRAMId/32u])
2728 &
2729 (~(rmInstance->avlblPaRAMSets[paRAMId/32u]))
2730 &
2731 (1u << (paRAMId%32u))) == FALSE)
2732 {
2733 /* PaRAM Set NOT allocated, return error */
2734 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
2735 }
2736 }
2737 else
2738 {
2739 /* DMA channel NOT allocated, return error */
2740 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
2741 }
2742 }
2745 if (result == EDMA3_RM_SOK)
2746 {
2747 /* Map the Dma Channel to the PaRAM Set corresponding to paramId */
2748 /**
2749 * Do this for the EDMA3 Controllers which have a register for mapping
2750 * DMA Channel to a particular PaRAM Set. So check
2751 * dmaChPaRAMMapExists first.
2752 */
2753 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2754 {
2755 /* Map Parameter RAM Set Number for specified channelId */
2756 gblRegs->DCHMAP[channelId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
2757 gblRegs->DCHMAP[channelId] |= EDMA3_RM_DCH_PARAM_SET_MASK(paRAMId);
2758 }
2759 else
2760 {
2761 /* Feature NOT supported on the current platform, return error. */
2762 result = EDMA3_RM_E_FEATURE_UNSUPPORTED;
2763 }
2764 }
2766 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2767 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2768 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2769 EDMA3_DVT_dCOUNTER,
2770 EDMA3_DVT_dNONE,
2771 EDMA3_DVT_dNONE));
2772 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2774 return result;
2775 }
2777 EDMA3_RM_Result EDMA3_RM_mapQdmaChannel (EDMA3_RM_Handle hEdmaResMgr,
2778 unsigned int channelId,
2779 unsigned int paRAMId,
2780 EDMA3_RM_QdmaTrigWord trigWord)
2781 {
2782 EDMA3_RM_Instance *rmInstance = NULL;
2783 EDMA3_RM_Obj *rmObj = NULL;
2784 EDMA3_RM_Result result = EDMA3_RM_SOK;
2785 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
2787 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2788 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2789 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2790 EDMA3_DVT_dCOUNTER,
2791 EDMA3_DVT_dNONE,
2792 EDMA3_DVT_dNONE));
2793 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2795 /* If parameter checking is enabled... */
2796 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2797 if ((hEdmaResMgr == NULL)
2798 || ((trigWord < EDMA3_RM_QDMA_TRIG_OPT)
2799 || (trigWord > EDMA3_RM_QDMA_TRIG_CCNT)))
2800 {
2801 result = EDMA3_RM_E_INVALID_PARAM;
2802 }
2803 #endif
2805 if (result == EDMA3_RM_SOK)
2806 {
2807 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2809 if (rmInstance == NULL)
2810 {
2811 result = EDMA3_RM_E_INVALID_PARAM;
2812 }
2813 }
2815 if (result == EDMA3_RM_SOK)
2816 {
2817 rmObj = rmInstance->pResMgrObjHandle;
2819 if (rmObj == NULL)
2820 {
2821 result = EDMA3_RM_E_INVALID_PARAM;
2822 }
2823 else
2824 {
2825 if (rmObj->gblCfgParams.globalRegs == NULL)
2826 {
2827 result = EDMA3_RM_E_INVALID_PARAM;
2828 }
2829 }
2830 }
2832 if (result == EDMA3_RM_SOK)
2833 {
2834 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2836 /* If parameter checking is enabled... */
2837 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2838 if ((paRAMId >= rmObj->gblCfgParams.numPaRAMSets)
2839 || (channelId >= rmObj->gblCfgParams.numQdmaChannels))
2840 {
2841 result = EDMA3_RM_E_INVALID_PARAM;
2842 }
2843 #endif
2844 }
2846 /* QDMA channel and PaRAM Set should be previously allocated. */
2847 if (result == EDMA3_RM_SOK)
2848 {
2849 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[channelId/32u])
2850 &
2851 (~(rmInstance->avlblQdmaChannels[channelId/32u]))
2852 &
2853 (1u << (channelId%32u))) != FALSE)
2854 {
2855 /* QDMA channel allocated, check for the PaRAM Set */
2856 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[paRAMId/32u])
2857 &
2858 (~(rmInstance->avlblPaRAMSets[paRAMId/32u]))
2859 &
2860 (1u << (paRAMId%32u))) == FALSE)
2861 {
2862 /* PaRAM Set NOT allocated, return error */
2863 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
2864 }
2865 }
2866 else
2867 {
2868 /* QDMA channel NOT allocated, return error */
2869 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
2870 }
2871 }
2873 if (result == EDMA3_RM_SOK)
2874 {
2875 /* Map Parameter RAM Set Number for specified channelId */
2876 gblRegs->QCHMAP[channelId] &= EDMA3_RM_QCH_PARAM_CLR_MASK;
2877 gblRegs->QCHMAP[channelId] |= EDMA3_RM_QCH_PARAM_SET_MASK(paRAMId);
2879 /* Set the Trigger Word */
2880 gblRegs->QCHMAP[channelId] &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
2881 gblRegs->QCHMAP[channelId] |= EDMA3_RM_QCH_TRWORD_SET_MASK(trigWord);
2882 }
2885 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2886 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2887 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2888 EDMA3_DVT_dCOUNTER,
2889 EDMA3_DVT_dNONE,
2890 EDMA3_DVT_dNONE));
2891 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2893 return result;
2894 }
2896 EDMA3_RM_Result EDMA3_RM_registerTccCb(EDMA3_RM_Handle hEdmaResMgr,
2897 const EDMA3_RM_ResDesc *channelObj,
2898 unsigned int tcc,
2899 EDMA3_RM_TccCallback tccCb,
2900 void *cbData)
2901 {
2902 EDMA3_RM_Instance *rmInstance = NULL;
2903 EDMA3_RM_Obj *rmObj = NULL;
2904 EDMA3_RM_Result result = EDMA3_RM_SOK;
2905 unsigned int edma3Id;
2906 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
2908 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2909 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2910 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2911 EDMA3_DVT_dCOUNTER,
2912 EDMA3_DVT_dNONE,
2913 EDMA3_DVT_dNONE));
2914 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2916 /* If parameter checking is enabled... */
2917 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2918 if ((NULL == hEdmaResMgr) || (NULL == channelObj))
2919 {
2920 result = EDMA3_RM_E_INVALID_PARAM;
2921 }
2923 /* Callback function should NOT be NULL */
2924 if (NULL == tccCb)
2925 {
2926 result = EDMA3_RM_E_INVALID_PARAM;
2927 }
2928 #endif
2930 if (result == EDMA3_RM_SOK)
2931 {
2932 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2933 rmObj = rmInstance->pResMgrObjHandle;
2935 if (rmObj == NULL)
2936 {
2937 result = EDMA3_RM_E_INVALID_PARAM;
2938 }
2939 else
2940 {
2941 edma3Id = rmObj->phyCtrllerInstId;
2942 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2943 }
2944 }
2946 if (result == EDMA3_RM_SOK)
2947 {
2948 if ((gblRegs == NULL) || (tcc >= rmObj->gblCfgParams.numTccs))
2949 {
2950 result = EDMA3_RM_E_INVALID_PARAM;
2951 }
2952 }
2954 /* Check if the parameters are OK. */
2955 if (EDMA3_RM_SOK == result)
2956 {
2957 /* Check whether the callback has already registered. */
2958 if (NULL != edma3IntrParams[edma3Id][tcc].tccCb)
2959 {
2960 result = EDMA3_RM_E_CALLBACK_ALREADY_REGISTERED;
2961 }
2962 else
2963 {
2964 /* Store the mapping b/w DMA/QDMA channel and TCC first. */
2965 if (channelObj->type == EDMA3_RM_RES_DMA_CHANNEL)
2966 {
2967 /* DMA channel */
2968 if (channelObj->resId < rmObj->gblCfgParams.numDmaChannels)
2969 {
2970 /* Save the TCC */
2971 edma3DmaChTccMapping[edma3Id][channelObj->resId] = tcc;
2972 }
2973 else
2974 {
2975 /* Error!!! */
2976 result = EDMA3_RM_E_INVALID_PARAM;
2977 }
2978 }
2979 else
2980 {
2981 if (channelObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
2982 {
2983 /* QDMA channel */
2984 if (channelObj->resId < rmObj->gblCfgParams.numQdmaChannels)
2985 {
2986 /* Save the TCC */
2987 edma3QdmaChTccMapping[edma3Id][channelObj->resId] = tcc;
2988 }
2989 else
2990 {
2991 /* Error!!! */
2992 result = EDMA3_RM_E_INVALID_PARAM;
2993 }
2994 }
2995 else
2996 {
2997 /* Error!!! */
2998 result = EDMA3_RM_E_INVALID_PARAM;
2999 }
3000 }
3001 }
3002 }
3004 if (EDMA3_RM_SOK == result)
3005 {
3006 /**
3007 * Enable the Interrupt channel in the DRAE/DRAEH registers also.
3008 * Also, If the region id coming from this RM instance is same as the
3009 * Master RM Instance's region id, only then we will be getting the
3010 * interrupts on the same side.
3011 * So save the TCC in the allocatedTCCs[] array.
3012 */
3013 if (TRUE == rmInstance->regModificationRequired)
3014 {
3015 if (tcc < 32u)
3016 {
3017 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
3018 |= (0x1u << tcc);
3020 if (edma3RegionId == rmInstance->initParam.regionId)
3021 {
3022 allocatedTCCs[edma3Id][0u] |= (0x1u << tcc);
3023 }
3024 }
3025 else
3026 {
3027 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
3028 |= (0x1u << (tcc - 32u));
3030 if (edma3RegionId == rmInstance->initParam.regionId)
3031 {
3032 allocatedTCCs[edma3Id][1u] |= (0x1u << (tcc - 32u));
3033 }
3034 }
3035 }
3037 /* Enable the interrupts in IESR/IESRH */
3038 if (tcc < 32u)
3039 {
3040 rmInstance->shadowRegs->IESR = (1UL << tcc);
3041 }
3042 else
3043 {
3044 rmInstance->shadowRegs->IESRH = (1UL << (tcc-32u));
3045 }
3047 /* Save the callback functions also */
3048 edma3IntrParams[edma3Id][tcc].cbData = cbData;
3049 edma3IntrParams[edma3Id][tcc].tccCb = tccCb;
3050 }
3052 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3053 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3054 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3055 EDMA3_DVT_dCOUNTER,
3056 EDMA3_DVT_dNONE,
3057 EDMA3_DVT_dNONE));
3058 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3060 return result;
3061 }
3063 EDMA3_RM_Result EDMA3_RM_unregisterTccCb(EDMA3_RM_Handle hEdmaResMgr,
3064 const EDMA3_RM_ResDesc *channelObj)
3065 {
3066 EDMA3_RM_Instance *rmInstance = NULL;
3067 EDMA3_RM_Obj *rmObj = NULL;
3068 EDMA3_RM_Result result = EDMA3_RM_SOK;
3069 unsigned int mappedTcc = EDMA3_MAX_TCC;
3070 unsigned int edma3Id;
3071 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3073 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3074 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3075 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3076 EDMA3_DVT_dCOUNTER,
3077 EDMA3_DVT_dNONE,
3078 EDMA3_DVT_dNONE));
3079 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3081 /* If parameter checking is enabled... */
3082 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3083 if ((NULL == hEdmaResMgr) || (NULL == channelObj))
3084 {
3085 result = EDMA3_RM_E_INVALID_PARAM;
3086 }
3087 #endif
3089 /* Check if the parameters are OK. */
3090 if (EDMA3_RM_SOK == result)
3091 {
3092 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3093 rmObj = rmInstance->pResMgrObjHandle;
3095 if (rmObj == NULL)
3096 {
3097 result = EDMA3_RM_E_INVALID_PARAM;
3098 }
3099 else
3100 {
3101 edma3Id = rmObj->phyCtrllerInstId;
3102 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3103 }
3104 }
3106 if (result == EDMA3_RM_SOK)
3107 {
3108 if (gblRegs == NULL)
3109 {
3110 result = EDMA3_RM_E_INVALID_PARAM;
3111 }
3112 else
3113 {
3114 if (channelObj->type == EDMA3_RM_RES_DMA_CHANNEL)
3115 {
3116 /* DMA channel */
3117 if (channelObj->resId < rmObj->gblCfgParams.numDmaChannels)
3118 {
3119 /* Save the mapped TCC */
3120 mappedTcc = edma3DmaChTccMapping[edma3Id][channelObj->resId];
3122 /* Remove the mapping now. */
3123 edma3DmaChTccMapping[edma3Id][channelObj->resId] = EDMA3_MAX_TCC;
3124 }
3125 else
3126 {
3127 /* Error!!! */
3128 result = EDMA3_RM_E_INVALID_PARAM;
3129 }
3130 }
3131 else
3132 {
3133 if (channelObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
3134 {
3135 /* QDMA channel */
3136 if (channelObj->resId < rmObj->gblCfgParams.numQdmaChannels)
3137 {
3138 /* Save the mapped TCC */
3139 mappedTcc = edma3QdmaChTccMapping[edma3Id][channelObj->resId];
3141 /* Remove the mapping now. */
3142 edma3QdmaChTccMapping[edma3Id][channelObj->resId] = EDMA3_MAX_TCC;
3143 }
3144 else
3145 {
3146 /* Error!!! */
3147 result = EDMA3_RM_E_INVALID_PARAM;
3148 }
3149 }
3150 else
3151 {
3152 /* Error!!! */
3153 result = EDMA3_RM_E_INVALID_PARAM;
3154 }
3155 }
3156 }
3157 }
3159 if (EDMA3_RM_SOK == result)
3160 {
3161 if (TRUE == rmInstance->regModificationRequired)
3162 {
3163 /**
3164 * Interrupt Channel is freed. Reset the bit specific to the Interrupt
3165 * channel in the DRAE/DRAEH register also. Also, if we have earlier
3166 * saved this TCC in allocatedTCCs[] array, remove it from there too.
3167 */
3168 if (mappedTcc < 32u)
3169 {
3170 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
3171 &= (~(0x1u << mappedTcc));
3172 if (edma3RegionId == rmInstance->initParam.regionId)
3173 {
3174 allocatedTCCs[edma3Id][0u] &= (~(0x1u << mappedTcc));
3175 }
3176 }
3177 else
3178 {
3179 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
3180 &= (~(0x1u << (mappedTcc-32u)));
3181 if (edma3RegionId == rmInstance->initParam.regionId)
3182 {
3183 allocatedTCCs[edma3Id][1u] &= (~(0x1u << (mappedTcc-32u)));
3184 }
3185 }
3186 }
3188 /* Remove the callback function too */
3189 if (mappedTcc < 32u)
3190 {
3191 rmInstance->shadowRegs->IECR = (1UL << mappedTcc);
3192 }
3193 else
3194 {
3195 rmInstance->shadowRegs->IECRH = (1UL << (mappedTcc-32u));
3196 }
3198 edma3IntrParams[edma3Id][mappedTcc].cbData = NULL;
3199 edma3IntrParams[edma3Id][mappedTcc].tccCb = NULL;
3200 }
3202 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3203 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3204 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3205 EDMA3_DVT_dCOUNTER,
3206 EDMA3_DVT_dNONE,
3207 EDMA3_DVT_dNONE));
3208 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3210 return result;
3211 }
3213 EDMA3_RM_Result EDMA3_RM_allocContiguousResource(EDMA3_RM_Handle hEdmaResMgr,
3214 EDMA3_RM_ResDesc *firstResIdObj,
3215 unsigned int numResources)
3216 {
3217 EDMA3_RM_Instance *rmInstance = NULL;
3218 EDMA3_RM_Obj *rmObj = NULL;
3219 EDMA3_RM_Result result = EDMA3_RM_SOK;
3220 EDMA3_RM_ResDesc *resObj = NULL;
3221 unsigned int resAllocIdx = 0u;
3222 unsigned int firstResId;
3223 unsigned int lastResId = 0u;
3224 unsigned int maxNumResources = 0u;
3225 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
3226 unsigned int resIdClr = 0x0;
3227 unsigned int resIdSet = 0x0;
3228 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3229 unsigned int i = 0u;
3230 unsigned int position = 0u;
3231 unsigned int edma3Id;
3233 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3234 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3235 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3236 EDMA3_DVT_dCOUNTER,
3237 EDMA3_DVT_dNONE,
3238 EDMA3_DVT_dNONE));
3239 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3242 /* If parameter checking is enabled... */
3243 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3244 if ((hEdmaResMgr == NULL) || (firstResIdObj == NULL))
3245 {
3246 result = EDMA3_RM_E_INVALID_PARAM;
3247 }
3248 #endif
3250 if (EDMA3_RM_SOK == result)
3251 {
3252 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3253 if (rmInstance == NULL)
3254 {
3255 result = EDMA3_RM_E_INVALID_PARAM;
3256 }
3257 }
3259 if (EDMA3_RM_SOK == result)
3260 {
3261 rmObj = rmInstance->pResMgrObjHandle;
3263 if (rmObj == NULL)
3264 {
3265 result = EDMA3_RM_E_INVALID_PARAM;
3266 }
3267 }
3269 if (EDMA3_RM_SOK == result)
3270 {
3271 edma3Id = rmObj->phyCtrllerInstId;
3272 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3274 if (rmInstance->initParam.rmSemHandle == NULL)
3275 {
3276 result = EDMA3_RM_E_INVALID_PARAM;
3277 }
3278 }
3280 if (EDMA3_RM_SOK == result)
3281 {
3282 resObj = firstResIdObj;
3283 if (resObj != NULL)
3284 {
3285 firstResId = resObj->resId;
3286 }
3288 switch (resObj->type)
3289 {
3290 case EDMA3_RM_RES_DMA_CHANNEL :
3291 maxNumResources = rmObj->gblCfgParams.numDmaChannels;
3292 break;
3293 case EDMA3_RM_RES_QDMA_CHANNEL :
3294 maxNumResources = rmObj->gblCfgParams.numQdmaChannels;
3295 break;
3296 case EDMA3_RM_RES_TCC :
3297 maxNumResources = rmObj->gblCfgParams.numTccs;
3298 break;
3299 case EDMA3_RM_RES_PARAM_SET :
3300 maxNumResources = rmObj->gblCfgParams.numPaRAMSets;
3301 break;
3302 default:
3303 result = EDMA3_RM_E_INVALID_PARAM;
3304 break;
3305 }
3306 }
3309 if (EDMA3_RM_SOK == result)
3310 {
3311 /* First resource id (firstResId) can be a valid Resource ID as well as
3312 * 'EDMA3_RM_RES_ANY', in case user does not want to
3313 * start from a specific resource. For eg, user allocating link channels.
3314 */
3315 if (firstResId != EDMA3_RM_RES_ANY)
3316 {
3317 /* User want specific resources. */
3318 lastResId = firstResId + numResources;
3320 if (((firstResId >= maxNumResources) || (firstResId > lastResId))
3321 || (lastResId > maxNumResources))
3322 {
3323 result = EDMA3_RM_E_INVALID_PARAM;
3324 }
3325 }
3326 else
3327 {
3328 /* (firstResId == EDMA3_RM_RES_ANY)
3329 * So just check whether the number of resources
3330 * requested does not cross the limit.
3331 */
3332 if (numResources > maxNumResources)
3333 {
3334 result = EDMA3_RM_E_INVALID_PARAM;
3335 }
3336 }
3337 }
3340 if (result == EDMA3_RM_SOK)
3341 {
3342 /* Now try to allocate resources for the first case */
3343 if (firstResId != EDMA3_RM_RES_ANY)
3344 {
3345 /* Request for specific resources */
3347 /**
3348 * Take the instance specific semaphore, to prevent simultaneous
3349 * access to the shared resources.
3350 */
3351 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
3352 EDMA3_OSSEM_NO_TIMEOUT);
3354 if (EDMA3_RM_SOK == semResult)
3355 {
3356 switch (resObj->type)
3357 {
3358 case EDMA3_RM_RES_DMA_CHANNEL :
3359 {
3360 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3361 {
3362 resIdClr = (unsigned int)(~(1u << (resAllocIdx%32u)));
3363 resIdSet = (1u << (resAllocIdx%32u));
3365 /* Check whether it is owned or not */
3366 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resAllocIdx/32u])&(resIdSet)) != FALSE)
3367 {
3368 /* Now check if specified resource is available presently*/
3369 if (((rmInstance->avlblDmaChannels[resAllocIdx/32u])&(resIdSet)) != FALSE)
3370 {
3371 /*
3372 * Mark the specified resource as "Not Available"
3373 * for future requests
3374 */
3375 rmInstance->avlblDmaChannels[resAllocIdx/32u] &= resIdClr;
3377 if (resAllocIdx < 32u)
3378 {
3379 rmInstance->shadowRegs->EECR = (1UL << resAllocIdx);
3381 /**
3382 * Enable the DMA channel in the
3383 * DRAE registers also.
3384 */
3385 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
3386 |= (0x1u << resAllocIdx);
3387 }
3388 else
3389 {
3390 rmInstance->shadowRegs->EECRH = (1UL << (resAllocIdx - 32u));
3392 /**
3393 * Enable the DMA channel in the
3394 * DRAEH registers also.
3395 */
3396 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
3397 |= (0x1u << (resAllocIdx - 32u));
3398 }
3400 result = EDMA3_RM_SOK;
3401 }
3402 else
3403 {
3404 /* Specified resource is owned but is already booked */
3405 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3406 break;
3407 }
3408 }
3409 else
3410 {
3411 /*
3412 * Specified resource is not owned by this instance
3413 * of the Resource Manager
3414 */
3415 result = EDMA3_RM_E_RES_NOT_OWNED;
3416 break;
3417 }
3418 }
3420 break;
3421 }
3423 case EDMA3_RM_RES_QDMA_CHANNEL:
3424 {
3425 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3426 {
3427 resIdClr = (unsigned int)(~(1u << resAllocIdx));
3428 resIdSet = (1u << resAllocIdx);
3430 /* Check whether it is owned or not */
3431 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u])&(resIdSet))!=FALSE)
3432 {
3433 /* Now check if specified resource is available presently*/
3434 if (((rmInstance->avlblQdmaChannels[0u])&(resIdSet))!=FALSE)
3435 {
3436 /*
3437 * Mark the specified resource as "Not Available"
3438 * for future requests
3439 */
3440 rmInstance->avlblQdmaChannels[0u] &= resIdClr;
3442 /**
3443 * Enable the QDMA channel in the
3444 * QRAE register also.
3445 */
3446 gblRegs->QRAE[rmInstance->initParam.regionId]
3447 |= (0x1u << resAllocIdx);
3449 result = EDMA3_RM_SOK;
3450 }
3451 else
3452 {
3453 /* Specified resource is owned but is already booked */
3454 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3455 break;
3456 }
3457 }
3458 else
3459 {
3460 /*
3461 * Specified resource is not owned by this instance
3462 * of the Resource Manager
3463 */
3464 result = EDMA3_RM_E_RES_NOT_OWNED;
3465 break;
3466 }
3467 }
3469 break;
3470 }
3472 case EDMA3_RM_RES_TCC:
3473 {
3474 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3475 {
3476 resIdClr = (unsigned int)(~(1u << (resAllocIdx%32u)));
3477 resIdSet = (1u << (resAllocIdx%32u));
3479 /* Check whether it is owned or not */
3480 if (((rmInstance->initParam.rmInstInitConfig->ownTccs[resAllocIdx/32u])&(resIdSet))!=FALSE)
3481 {
3482 /* Now check if specified resource is available presently*/
3483 if (((rmInstance->avlblTccs[resAllocIdx/32u])&(resIdSet))!=FALSE)
3484 {
3485 /*
3486 * Mark the specified resource as "Not Available"
3487 * for future requests
3488 */
3489 rmInstance->avlblTccs[resAllocIdx/32u] &= resIdClr;
3491 /**
3492 * If the region id coming from this
3493 * RM instance is same as the Master RM
3494 * Instance's region id, only then we will be
3495 * getting the interrupts on the same side.
3496 * So save the TCC in the allocatedTCCs[] array.
3497 */
3498 if (edma3RegionId == rmInstance->initParam.regionId)
3499 {
3500 if (resAllocIdx < 32u)
3501 {
3502 allocatedTCCs[edma3Id][0u] |= (0x1u << resAllocIdx);
3503 }
3504 else
3505 {
3506 allocatedTCCs[edma3Id][1u] |= (0x1u << (resAllocIdx - 32u));
3507 }
3508 }
3509 result = EDMA3_RM_SOK;
3510 }
3511 else
3512 {
3513 /* Specified resource is owned but is already booked */
3514 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3515 break;
3516 }
3517 }
3518 else
3519 {
3520 /*
3521 * Specified resource is not owned by this instance
3522 * of the Resource Manager
3523 */
3524 result = EDMA3_RM_E_RES_NOT_OWNED;
3525 break;
3526 }
3527 }
3529 break;
3530 }
3532 case EDMA3_RM_RES_PARAM_SET:
3533 {
3534 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3535 {
3536 resIdClr = (unsigned int)(~(1u << (resAllocIdx%32u)));
3537 resIdSet = (1u << (resAllocIdx%32u));
3539 /* Check whether it is owned or not */
3540 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[resAllocIdx/32u])&(resIdSet))!=FALSE)
3541 {
3542 /* Now check if specified resource is available presently*/
3543 if (((rmInstance->avlblPaRAMSets[resAllocIdx/32u])&(resIdSet))!=FALSE)
3544 {
3545 /*
3546 * Mark the specified resource as "Not Available"
3547 * for future requests
3548 */
3549 rmInstance->avlblPaRAMSets[resAllocIdx/32u] &= resIdClr;
3551 /**
3552 * Also, make the actual PARAM Set NULL, checking the flag
3553 * whether it is required or not.
3554 */
3555 if (TRUE == rmInstance->paramInitRequired)
3556 {
3557 edma3MemZero((void *)(&gblRegs->PARAMENTRY[resAllocIdx]),
3558 sizeof(gblRegs->PARAMENTRY[resAllocIdx]));
3559 }
3561 result = EDMA3_RM_SOK;
3562 }
3563 else
3564 {
3565 /* Specified resource is owned but is already booked */
3566 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3567 break;
3568 }
3569 }
3570 else
3571 {
3572 /*
3573 * Specified resource is not owned by this instance
3574 * of the Resource Manager
3575 */
3576 result = EDMA3_RM_E_RES_NOT_OWNED;
3577 break;
3578 }
3579 }
3581 break;
3582 }
3584 default:
3585 {
3586 result = EDMA3_RM_E_INVALID_PARAM;
3587 break;
3588 }
3589 }
3591 /* resource allocation completed, release the semaphore first */
3592 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
3593 }
3595 }
3596 else
3597 {
3598 /* (firstResId == EDMA3_RM_RES_ANY) */
3599 /**
3600 * Take the instance specific semaphore, to prevent simultaneous
3601 * access to the shared resources.
3602 */
3603 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
3604 EDMA3_OSSEM_NO_TIMEOUT);
3606 if (EDMA3_RM_SOK == semResult)
3607 {
3608 /**
3609 * We have to search three different arrays, namely ownedResoures,
3610 * avlblResources and resvdResources, to find the 'common' contiguous
3611 * resources. For this, take an 'AND' of all three arrays in one single
3612 * array and use your algorithm on that array.
3613 */
3614 switch (resObj->type)
3615 {
3616 case EDMA3_RM_RES_DMA_CHANNEL:
3617 {
3618 /* AND all the arrays to look into */
3619 contiguousDmaRes[0u] = ((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[0u]
3620 & rmInstance->avlblDmaChannels[0u])
3621 & (~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[0u]))
3622 );
3623 contiguousDmaRes[1u] = ((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[1u]
3624 & rmInstance->avlblDmaChannels[1u])
3625 & (~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[1u]))
3626 );
3627 }
3628 break;
3630 case EDMA3_RM_RES_QDMA_CHANNEL:
3631 {
3632 /* AND all the arrays to look into */
3633 contiguousQdmaRes[0u] = ((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u]
3634 & rmInstance->avlblQdmaChannels[0u])
3635 & (~(rmInstance->initParam.rmInstInitConfig->resvdQdmaChannels[0u]))
3636 );
3637 }
3638 break;
3640 case EDMA3_RM_RES_TCC:
3641 {
3642 /* AND all the arrays to look into */
3643 contiguousTccRes[0u] = ((rmInstance->initParam.rmInstInitConfig->ownTccs[0u]
3644 & rmInstance->avlblTccs[0u])
3645 & (~(rmInstance->initParam.rmInstInitConfig->resvdTccs[0u]))
3646 );
3647 contiguousTccRes[1u] = ((rmInstance->initParam.rmInstInitConfig->ownTccs[1u]
3648 & rmInstance->avlblTccs[1u])
3649 & (~(rmInstance->initParam.rmInstInitConfig->resvdTccs[1u]))
3650 );
3651 }
3652 break;
3654 case EDMA3_RM_RES_PARAM_SET:
3655 {
3656 /* AND all the arrays to look into */
3657 for (i = 0u; i < (maxNumResources/32u); ++i)
3658 {
3659 contiguousParamRes[i] = ((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[i]
3660 & rmInstance->avlblPaRAMSets[i])
3661 & (~(rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[i]))
3662 );
3663 }
3664 }
3665 break;
3667 default:
3668 {
3669 result = EDMA3_RM_E_INVALID_PARAM;
3670 }
3671 break;
3672 }
3674 if (EDMA3_RM_SOK == result)
3675 {
3676 /**
3677 * Try to allocate 'numResources' contiguous resources
3678 * of type RES_ANY.
3679 */
3680 result = allocAnyContigRes (resObj->type, numResources, &position);
3682 /**
3683 * If result != EDMA3_RM_SOK, resource allocation failed.
3684 * Else resources successfully allocated.
3685 */
3686 if (result == EDMA3_RM_SOK)
3687 {
3688 /* Update the first resource id with the position returned. */
3689 resObj->resId = position;
3691 /*
3692 * Do some further changes in the book-keeping
3693 * data structures and global registers accordingly.
3694 */
3695 result = gblChngAllocContigRes(rmInstance, resObj, numResources);
3696 }
3697 }
3699 /* resource allocation completed, release the semaphore first */
3700 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
3701 }
3702 }
3703 }
3706 /**
3707 * Check the Resource Allocation Result 'result' first. If Resource
3708 * Allocation has resulted in an error, return it (having more priority than
3709 * semResult. Else, return semResult.
3710 */
3711 if (EDMA3_RM_SOK == result)
3712 {
3713 /**
3714 * Resource Allocation successful, return semResult for returning
3715 * semaphore.
3716 */
3717 result = semResult;
3718 }
3721 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3722 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3723 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3724 EDMA3_DVT_dCOUNTER,
3725 EDMA3_DVT_dNONE,
3726 EDMA3_DVT_dNONE));
3727 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3729 return result;
3730 }
3732 EDMA3_RM_Result EDMA3_RM_freeContiguousResource(EDMA3_RM_Handle hEdmaResMgr,
3733 EDMA3_RM_ResDesc *firstResIdObj,
3734 unsigned int numResources)
3735 {
3736 EDMA3_RM_Instance *rmInstance = NULL;
3737 EDMA3_RM_Obj *rmObj = NULL;
3738 EDMA3_RM_Result result = EDMA3_RM_SOK;
3739 EDMA3_RM_ResDesc *resObj;
3740 unsigned int resFreeIdx = 0u;
3741 unsigned int firstResId;
3742 unsigned int lastResId;
3743 unsigned int maxNumResources = 0u;
3745 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3746 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3747 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3748 EDMA3_DVT_dCOUNTER,
3749 EDMA3_DVT_dNONE,
3750 EDMA3_DVT_dNONE));
3751 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3753 /* If parameter checking is enabled... */
3754 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3755 if ((hEdmaResMgr == NULL) || (firstResIdObj == NULL))
3756 {
3757 result = EDMA3_RM_E_INVALID_PARAM;
3758 }
3759 #endif
3761 /* Check if the parameters are OK. */
3762 if (EDMA3_RM_SOK == result)
3763 {
3764 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3765 rmObj = rmInstance->pResMgrObjHandle;
3767 if (rmObj == NULL)
3768 {
3769 result = EDMA3_RM_E_INVALID_PARAM;
3770 }
3771 else
3772 {
3773 resObj = firstResIdObj;
3774 if (resObj != NULL)
3775 {
3776 firstResId = resObj->resId;
3777 lastResId = firstResId + (numResources - 1u);
3778 }
3780 switch (resObj->type)
3781 {
3782 case EDMA3_RM_RES_DMA_CHANNEL :
3783 maxNumResources = rmObj->gblCfgParams.numDmaChannels;
3784 break;
3785 case EDMA3_RM_RES_QDMA_CHANNEL :
3786 maxNumResources = rmObj->gblCfgParams.numQdmaChannels;
3787 break;
3788 case EDMA3_RM_RES_TCC :
3789 maxNumResources = rmObj->gblCfgParams.numTccs;
3790 break;
3791 case EDMA3_RM_RES_PARAM_SET :
3792 maxNumResources = rmObj->gblCfgParams.numPaRAMSets;
3793 break;
3794 default:
3795 result = EDMA3_RM_E_INVALID_PARAM;
3796 break;
3797 }
3799 if (result == EDMA3_RM_SOK)
3800 {
3801 if ((firstResId > lastResId) || (lastResId >= maxNumResources))
3802 {
3803 result = EDMA3_RM_E_INVALID_PARAM;
3804 }
3805 else
3806 {
3807 for (resFreeIdx = firstResId; resFreeIdx <= lastResId; ++resFreeIdx)
3808 {
3809 resObj->resId = resFreeIdx;
3810 result = EDMA3_RM_freeResource(rmInstance, resObj);
3812 if (result != EDMA3_RM_SOK)
3813 {
3814 break;
3815 }
3816 }
3817 }
3818 }
3819 }
3820 }
3822 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3823 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3824 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3825 EDMA3_DVT_dCOUNTER,
3826 EDMA3_DVT_dNONE,
3827 EDMA3_DVT_dNONE));
3828 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3830 return result;
3831 }
3833 EDMA3_RM_Result EDMA3_RM_setCCRegister (EDMA3_RM_Handle hEdmaResMgr,
3834 unsigned int regOffset,
3835 unsigned int newRegValue)
3836 {
3837 EDMA3_RM_Result result = EDMA3_RM_SOK;
3838 EDMA3_RM_Instance *rmInstance = NULL;
3839 EDMA3_RM_Obj *rmObj = NULL;
3840 volatile unsigned int regPhyAddr = 0x0u;
3843 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3844 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3845 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3846 EDMA3_DVT_dCOUNTER,
3847 EDMA3_DVT_dNONE,
3848 EDMA3_DVT_dNONE));
3849 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3852 /* If parameter checking is enabled... */
3853 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3854 if ((hEdmaResMgr == NULL) || ((regOffset % 4u) != 0))
3855 {
3856 result = (EDMA3_RM_E_INVALID_PARAM);
3857 }
3858 #endif
3860 /* Check if the parameters are OK. */
3861 if (EDMA3_RM_SOK == result)
3862 {
3863 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3864 rmObj = rmInstance->pResMgrObjHandle;
3866 if (rmObj == NULL)
3867 {
3868 result = (EDMA3_RM_E_INVALID_PARAM);
3869 }
3870 else
3871 {
3872 if (rmObj->gblCfgParams.globalRegs != NULL)
3873 {
3874 /**
3875 * Take the instance specific semaphore, to prevent simultaneous
3876 * access to the shared resources.
3877 */
3878 result = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
3879 EDMA3_OSSEM_NO_TIMEOUT);
3881 if (EDMA3_RM_SOK == result)
3882 {
3883 /* Semaphore taken successfully, modify the registers. */
3884 regPhyAddr = (unsigned int)(rmObj->gblCfgParams.globalRegs) + regOffset;
3886 *(unsigned int *)regPhyAddr = newRegValue;
3888 /* Return the semaphore back */
3889 result = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
3890 }
3891 }
3892 }
3893 }
3896 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3897 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3898 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3899 EDMA3_DVT_dCOUNTER,
3900 EDMA3_DVT_dNONE,
3901 EDMA3_DVT_dNONE));
3902 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3905 return result;
3906 }
3908 EDMA3_RM_Result EDMA3_RM_getCCRegister (EDMA3_RM_Handle hEdmaResMgr,
3909 unsigned int regOffset,
3910 unsigned int *regValue)
3911 {
3912 EDMA3_RM_Result result = EDMA3_RM_SOK;
3913 EDMA3_RM_Instance *rmInstance = NULL;
3914 EDMA3_RM_Obj *rmObj = NULL;
3915 volatile unsigned int regPhyAddr = 0x0u;
3918 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3919 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3920 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3921 EDMA3_DVT_dCOUNTER,
3922 EDMA3_DVT_dNONE,
3923 EDMA3_DVT_dNONE));
3924 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3927 /* If parameter checking is enabled... */
3928 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3929 if (((hEdmaResMgr == NULL) || (regValue == NULL))
3930 || ((regOffset % 4u) != 0))
3931 {
3932 result = (EDMA3_RM_E_INVALID_PARAM);
3933 }
3934 #endif
3936 /* Check if the parameters are OK. */
3937 if (EDMA3_RM_SOK == result)
3938 {
3939 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3940 rmObj = rmInstance->pResMgrObjHandle;
3942 if (rmObj == NULL)
3943 {
3944 result = (EDMA3_RM_E_INVALID_PARAM);
3945 }
3946 else
3947 {
3948 if (rmObj->gblCfgParams.globalRegs != NULL)
3949 {
3950 regPhyAddr = (unsigned int)(rmObj->gblCfgParams.globalRegs) + regOffset;
3952 *regValue = *(unsigned int *)regPhyAddr;
3953 }
3954 }
3955 }
3958 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3959 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3960 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3961 EDMA3_DVT_dCOUNTER,
3962 EDMA3_DVT_dNONE,
3963 EDMA3_DVT_dNONE));
3964 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3967 return result;
3968 }
3970 EDMA3_RM_Result EDMA3_RM_waitAndClearTcc (EDMA3_RM_Handle hEdmaResMgr,
3971 unsigned int tccNo)
3972 {
3973 EDMA3_RM_Result result = EDMA3_RM_SOK;
3974 EDMA3_RM_Instance *rmInstance = NULL;
3975 EDMA3_RM_Obj *rmObj = NULL;
3976 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
3977 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
3978 unsigned int tccBitMask = 0x0u;
3981 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3982 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3983 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3984 EDMA3_DVT_dCOUNTER,
3985 EDMA3_DVT_dNONE,
3986 EDMA3_DVT_dNONE));
3987 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3990 /* If parameter checking is enabled... */
3991 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3992 if (hEdmaResMgr == NULL)
3993 {
3994 result = (EDMA3_RM_E_INVALID_PARAM);
3995 }
3996 #endif
3998 /* Check if the parameters are OK. */
3999 if (EDMA3_RM_SOK == result)
4000 {
4001 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4002 rmObj = rmInstance->pResMgrObjHandle;
4004 if ((rmObj == NULL) || (rmObj->gblCfgParams.globalRegs == NULL))
4005 {
4006 result = (EDMA3_RM_E_INVALID_PARAM);
4007 }
4008 else
4009 {
4010 /* If parameter checking is enabled... */
4011 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4012 if (tccNo >= rmObj->gblCfgParams.numTccs)
4013 {
4014 result = (EDMA3_RM_E_INVALID_PARAM);
4015 }
4016 #endif
4018 /* Check if the parameters are OK. */
4019 if (EDMA3_RM_SOK == result)
4020 {
4021 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4022 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
4023 (&globalRegs->SHADOW[rmInstance->initParam.regionId]);
4026 if (shadowRegs != NULL)
4027 {
4028 if(tccNo < 32u)
4029 {
4030 tccBitMask = (1u << tccNo);
4032 /* Check the status of the IPR[tccNo] bit. */
4033 while (FALSE == (shadowRegs->IPR & tccBitMask))
4034 {
4035 /* Transfer not yet completed, bit not SET */
4036 }
4038 /**
4039 * Bit found SET, transfer is completed,
4040 * clear the pending interrupt and return.
4041 */
4042 shadowRegs->ICR = tccBitMask;
4043 }
4044 else
4045 {
4046 tccBitMask = (1u << (tccNo - 32u));
4048 /* Check the status of the IPRH[tccNo-32] bit. */
4049 while (FALSE == (shadowRegs->IPRH & tccBitMask))
4050 {
4051 /* Transfer not yet completed, bit not SET */
4052 }
4054 /**
4055 * Bit found SET, transfer is completed,
4056 * clear the pending interrupt and return.
4057 */
4058 shadowRegs->ICRH = tccBitMask;
4059 }
4060 }
4061 }
4062 }
4063 }
4066 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4067 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4068 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4069 EDMA3_DVT_dCOUNTER,
4070 EDMA3_DVT_dNONE,
4071 EDMA3_DVT_dNONE));
4072 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4075 return result;
4076 }
4078 EDMA3_RM_Result EDMA3_RM_checkAndClearTcc (EDMA3_RM_Handle hEdmaResMgr,
4079 unsigned int tccNo,
4080 unsigned short *tccStatus)
4081 {
4082 EDMA3_RM_Result result = EDMA3_RM_SOK;
4083 EDMA3_RM_Instance *rmInstance = NULL;
4084 EDMA3_RM_Obj *rmObj = NULL;
4085 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4086 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
4087 unsigned int tccBitMask = 0x0u;
4090 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4091 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4092 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4093 EDMA3_DVT_dCOUNTER,
4094 EDMA3_DVT_dNONE,
4095 EDMA3_DVT_dNONE));
4096 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4099 /* If parameter checking is enabled... */
4100 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4101 if ((hEdmaResMgr == NULL) || (tccStatus == NULL))
4102 {
4103 result = (EDMA3_RM_E_INVALID_PARAM);
4104 }
4105 #endif
4107 /* Check if the parameters are OK. */
4108 if (EDMA3_RM_SOK == result)
4109 {
4110 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4111 rmObj = rmInstance->pResMgrObjHandle;
4113 if ((rmObj == NULL) || (rmObj->gblCfgParams.globalRegs == NULL))
4114 {
4115 result = (EDMA3_RM_E_INVALID_PARAM);
4116 }
4117 else
4118 {
4119 /* If parameter checking is enabled... */
4120 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4121 if (tccNo >= rmObj->gblCfgParams.numTccs)
4122 {
4123 result = (EDMA3_RM_E_INVALID_PARAM);
4124 }
4125 #endif
4127 /* Check if the parameters are OK. */
4128 if (EDMA3_RM_SOK == result)
4129 {
4130 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4131 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
4132 (&globalRegs->SHADOW[rmInstance->initParam.regionId]);
4134 /* Reset the tccStatus */
4135 *tccStatus = FALSE;
4137 if (shadowRegs != NULL)
4138 {
4139 if(tccNo < 32u)
4140 {
4141 tccBitMask = (1u << tccNo);
4143 /* Check the status of the IPR[tccNo] bit. */
4144 if ((shadowRegs->IPR & tccBitMask) != FALSE)
4145 {
4146 /* Transfer completed, bit found SET */
4147 *tccStatus = TRUE;
4149 /* Clear the pending interrupt also. */
4150 shadowRegs->ICR = tccBitMask;
4151 }
4152 }
4153 else
4154 {
4155 tccBitMask = (1u << (tccNo - 32u));
4157 /* Check the status of the IPRH[tccNo-32] bit. */
4158 if ((shadowRegs->IPRH & tccBitMask) != FALSE)
4159 {
4160 /* Transfer completed, bit found SET */
4161 *tccStatus = TRUE;
4163 /* Clear the pending interrupt also. */
4164 shadowRegs->ICRH = tccBitMask;
4165 }
4166 }
4167 }
4168 }
4169 }
4170 }
4173 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4174 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4175 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4176 EDMA3_DVT_dCOUNTER,
4177 EDMA3_DVT_dNONE,
4178 EDMA3_DVT_dNONE));
4179 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4182 return result;
4183 }
4185 EDMA3_RM_Result EDMA3_RM_setPaRAM (EDMA3_RM_Handle hEdmaResMgr,
4186 EDMA3_RM_ResDesc *lChObj,
4187 const EDMA3_RM_PaRAMRegs *newPaRAM)
4188 {
4189 EDMA3_RM_Result result = EDMA3_RM_SOK;
4190 EDMA3_RM_Instance *rmInstance = NULL;
4191 EDMA3_RM_Obj *rmObj = NULL;
4192 int paRAMId = 0u;
4193 unsigned int qdmaChId = 0u;
4194 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4195 unsigned int edma3Id;
4197 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4198 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4199 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4200 EDMA3_DVT_dCOUNTER,
4201 EDMA3_DVT_dNONE,
4202 EDMA3_DVT_dNONE));
4203 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4205 /* If parameter checking is enabled... */
4206 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4207 if (hEdmaResMgr == NULL)
4208 {
4209 result = EDMA3_RM_E_INVALID_PARAM;
4210 }
4212 if ((lChObj == NULL) || (newPaRAM == NULL))
4213 {
4214 result = EDMA3_RM_E_INVALID_PARAM;
4215 }
4216 #endif
4218 /* Check if the parameters are OK. */
4219 if (result == EDMA3_RM_SOK)
4220 {
4221 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4223 if (rmInstance == NULL)
4224 {
4225 result = EDMA3_RM_E_INVALID_PARAM;
4226 }
4227 }
4229 if (result == EDMA3_RM_SOK)
4230 {
4231 rmObj = rmInstance->pResMgrObjHandle;
4233 if (rmObj == NULL)
4234 {
4235 result = EDMA3_RM_E_INVALID_PARAM;
4236 }
4237 else
4238 {
4239 if (rmObj->gblCfgParams.globalRegs == NULL)
4240 {
4241 result = EDMA3_RM_E_INVALID_PARAM;
4242 }
4243 }
4244 }
4246 if (result == EDMA3_RM_SOK)
4247 {
4248 edma3Id = rmObj->phyCtrllerInstId;
4249 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4251 switch (lChObj->type)
4252 {
4253 case EDMA3_RM_RES_DMA_CHANNEL:
4254 {
4255 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4256 {
4257 paRAMId = edma3RmChBoundRes[edma3Id][lChObj->resId].paRAMId;
4258 }
4259 else
4260 {
4261 result = EDMA3_RM_E_INVALID_PARAM;
4262 }
4263 }
4264 break;
4266 case EDMA3_RM_RES_QDMA_CHANNEL:
4267 {
4268 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4269 {
4270 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4271 paRAMId = edma3RmChBoundRes[edma3Id][qdmaChId].paRAMId;
4272 }
4273 else
4274 {
4275 result = EDMA3_RM_E_INVALID_PARAM;
4276 }
4277 }
4278 break;
4280 case EDMA3_RM_RES_PARAM_SET:
4281 {
4282 if (lChObj->resId < edma3NumPaRAMSets)
4283 {
4284 /**
4285 * User has passed the actual param set value here.
4286 * Use this value only
4287 */
4288 paRAMId = (int)(lChObj->resId);
4289 }
4290 else
4291 {
4292 result = EDMA3_RM_E_INVALID_PARAM;
4293 }
4294 }
4295 break;
4297 default:
4298 result = EDMA3_RM_E_INVALID_PARAM;
4299 }
4300 }
4303 if (result == EDMA3_RM_SOK)
4304 {
4305 /* Check the param id first. */
4306 if ((paRAMId != -1) && ((unsigned int)paRAMId < edma3NumPaRAMSets))
4307 {
4308 /* Set the PaRAM Set now. */
4309 edma3ParamCpy ((void *)(&(globalRegs->PARAMENTRY[paRAMId].OPT)),
4310 (const void *)newPaRAM);
4311 }
4312 else
4313 {
4314 result = EDMA3_RM_E_INVALID_PARAM;
4315 }
4316 }
4319 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4320 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4321 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4322 EDMA3_DVT_dCOUNTER,
4323 EDMA3_DVT_dNONE,
4324 EDMA3_DVT_dNONE));
4325 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4327 return result;
4328 }
4330 EDMA3_RM_Result EDMA3_RM_getPaRAM (EDMA3_RM_Handle hEdmaResMgr,
4331 EDMA3_RM_ResDesc *lChObj,
4332 EDMA3_RM_PaRAMRegs *currPaRAM)
4333 {
4334 EDMA3_RM_Result result = EDMA3_RM_SOK;
4335 EDMA3_RM_Instance *rmInstance = NULL;
4336 EDMA3_RM_Obj *rmObj = NULL;
4337 int paRAMId = 0u;
4338 unsigned int qdmaChId = 0u;
4339 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4340 unsigned int edma3Id;
4342 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4343 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4344 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4345 EDMA3_DVT_dCOUNTER,
4346 EDMA3_DVT_dNONE,
4347 EDMA3_DVT_dNONE));
4348 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4350 /* If parameter checking is enabled... */
4351 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4352 if (hEdmaResMgr == NULL)
4353 {
4354 result = EDMA3_RM_E_INVALID_PARAM;
4355 }
4357 if ((lChObj == NULL) || (currPaRAM == NULL))
4358 {
4359 result = EDMA3_RM_E_INVALID_PARAM;
4360 }
4361 #endif
4363 /* Check if the parameters are OK. */
4364 if (result == EDMA3_RM_SOK)
4365 {
4366 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4368 if (rmInstance == NULL)
4369 {
4370 result = EDMA3_RM_E_INVALID_PARAM;
4371 }
4372 }
4374 if (result == EDMA3_RM_SOK)
4375 {
4376 rmObj = rmInstance->pResMgrObjHandle;
4378 if (rmObj == NULL)
4379 {
4380 result = EDMA3_RM_E_INVALID_PARAM;
4381 }
4382 else
4383 {
4384 if (rmObj->gblCfgParams.globalRegs == NULL)
4385 {
4386 result = EDMA3_RM_E_INVALID_PARAM;
4387 }
4388 }
4389 }
4391 if (result == EDMA3_RM_SOK)
4392 {
4393 edma3Id = rmObj->phyCtrllerInstId;
4394 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4396 switch (lChObj->type)
4397 {
4398 case EDMA3_RM_RES_DMA_CHANNEL:
4399 {
4400 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4401 {
4402 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][lChObj->resId].paRAMId;
4403 }
4404 else
4405 {
4406 result = EDMA3_RM_E_INVALID_PARAM;
4407 }
4408 }
4409 break;
4411 case EDMA3_RM_RES_QDMA_CHANNEL:
4412 {
4413 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4414 {
4415 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4416 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId;
4417 }
4418 else
4419 {
4420 result = EDMA3_RM_E_INVALID_PARAM;
4421 }
4422 }
4423 break;
4425 case EDMA3_RM_RES_PARAM_SET:
4426 {
4427 if (lChObj->resId < edma3NumPaRAMSets)
4428 {
4429 /**
4430 * User has passed the actual param set value here.
4431 * Use this value only
4432 */
4433 paRAMId = (int)(lChObj->resId);
4434 }
4435 else
4436 {
4437 result = EDMA3_RM_E_INVALID_PARAM;
4438 }
4439 }
4440 break;
4442 default:
4443 result = EDMA3_RM_E_INVALID_PARAM;
4444 }
4445 }
4448 if (result == EDMA3_RM_SOK)
4449 {
4450 /* Check the param id first. */
4451 if ((paRAMId != -1) && (paRAMId < edma3NumPaRAMSets))
4452 {
4453 /* Get the PaRAM Set now. */
4454 edma3ParamCpy ((void *)currPaRAM ,
4455 (const void *)(&(globalRegs->PARAMENTRY [paRAMId].OPT)));
4456 }
4457 else
4458 {
4459 result = EDMA3_RM_E_INVALID_PARAM;
4460 }
4461 }
4464 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4465 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4466 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4467 EDMA3_DVT_dCOUNTER,
4468 EDMA3_DVT_dNONE,
4469 EDMA3_DVT_dNONE));
4470 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4473 return result;
4474 }
4476 EDMA3_RM_Result EDMA3_RM_getPaRAMPhyAddr(EDMA3_RM_Handle hEdmaResMgr,
4477 EDMA3_RM_ResDesc *lChObj,
4478 unsigned int *paramPhyAddr)
4479 {
4480 EDMA3_RM_Result result = EDMA3_RM_SOK;
4481 EDMA3_RM_Instance *rmInstance = NULL;
4482 EDMA3_RM_Obj *rmObj = NULL;
4483 int paRAMId = 0u;
4484 unsigned int qdmaChId = 0u;
4485 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4486 unsigned int edma3Id;
4488 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4489 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4490 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4491 EDMA3_DVT_dCOUNTER,
4492 EDMA3_DVT_dNONE,
4493 EDMA3_DVT_dNONE));
4494 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4497 /* If parameter checking is enabled... */
4498 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4499 if (hEdmaResMgr == NULL)
4500 {
4501 result = EDMA3_RM_E_INVALID_PARAM;
4502 }
4504 if ((lChObj == NULL) || (paramPhyAddr == NULL))
4505 {
4506 result = EDMA3_RM_E_INVALID_PARAM;
4507 }
4508 #endif
4510 if (result == EDMA3_RM_SOK)
4511 {
4512 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4514 if (rmInstance == NULL)
4515 {
4516 result = EDMA3_RM_E_INVALID_PARAM;
4517 }
4518 }
4520 if (result == EDMA3_RM_SOK)
4521 {
4522 rmObj = rmInstance->pResMgrObjHandle;
4524 if (rmObj == NULL)
4525 {
4526 result = EDMA3_RM_E_INVALID_PARAM;
4527 }
4528 else
4529 {
4530 if (rmObj->gblCfgParams.globalRegs == NULL)
4531 {
4532 result = EDMA3_RM_E_INVALID_PARAM;
4533 }
4534 }
4535 }
4537 if (result == EDMA3_RM_SOK)
4538 {
4539 edma3Id = rmObj->phyCtrllerInstId;
4540 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4542 switch (lChObj->type)
4543 {
4544 case EDMA3_RM_RES_DMA_CHANNEL:
4545 {
4546 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4547 {
4548 paRAMId = edma3RmChBoundRes[edma3Id][lChObj->resId].paRAMId;
4549 }
4550 else
4551 {
4552 result = EDMA3_RM_E_INVALID_PARAM;
4553 }
4554 }
4555 break;
4557 case EDMA3_RM_RES_QDMA_CHANNEL:
4558 {
4559 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4560 {
4561 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4562 paRAMId = edma3RmChBoundRes[edma3Id][qdmaChId].paRAMId;
4563 }
4564 else
4565 {
4566 result = EDMA3_RM_E_INVALID_PARAM;
4567 }
4568 }
4569 break;
4571 case EDMA3_RM_RES_PARAM_SET:
4572 {
4573 if (lChObj->resId < edma3NumPaRAMSets)
4574 {
4575 /**
4576 * User has passed the actual param set value here.
4577 * Use this value only
4578 */
4579 paRAMId = (int)(lChObj->resId);
4580 }
4581 else
4582 {
4583 result = EDMA3_RM_E_INVALID_PARAM;
4584 }
4585 }
4586 break;
4588 default:
4589 result = EDMA3_RM_E_INVALID_PARAM;
4590 }
4591 }
4593 if (result == EDMA3_RM_SOK)
4594 {
4595 /* Check the param id first. */
4596 if ((paRAMId != -1) && (paRAMId < edma3NumPaRAMSets))
4597 {
4598 /* Get the PaRAM Set Address now. */
4599 *paramPhyAddr = (unsigned int)(&(globalRegs->PARAMENTRY [paRAMId].OPT));
4600 }
4601 else
4602 {
4603 result = EDMA3_RM_E_INVALID_PARAM;
4604 }
4605 }
4607 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4608 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4609 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4610 EDMA3_DVT_dCOUNTER,
4611 EDMA3_DVT_dNONE,
4612 EDMA3_DVT_dNONE));
4613 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4615 return result;
4616 }
4618 EDMA3_RM_Result EDMA3_RM_getBaseAddress (EDMA3_RM_Handle hEdmaResMgr,
4619 EDMA3_RM_Cntrlr_PhyAddr controllerId,
4620 unsigned int *phyAddress)
4621 {
4622 EDMA3_RM_Result result = EDMA3_RM_SOK;
4623 EDMA3_RM_Instance *rmInstance = NULL;
4624 EDMA3_RM_Obj *rmObj = NULL;
4626 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4627 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4628 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4629 EDMA3_DVT_dCOUNTER,
4630 EDMA3_DVT_dNONE,
4631 EDMA3_DVT_dNONE));
4632 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4635 /* If parameter checking is enabled... */
4636 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4637 if ((hEdmaResMgr == NULL) || (phyAddress == NULL))
4638 {
4639 result = EDMA3_RM_E_INVALID_PARAM;
4640 }
4641 #endif
4643 if (result == EDMA3_RM_SOK)
4644 {
4645 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4647 if (rmInstance == NULL)
4648 {
4649 result = EDMA3_RM_E_INVALID_PARAM;
4650 }
4651 }
4653 if (result == EDMA3_RM_SOK)
4654 {
4655 rmObj = rmInstance->pResMgrObjHandle;
4657 if (rmObj == NULL)
4658 {
4659 result = EDMA3_RM_E_INVALID_PARAM;
4660 }
4661 }
4663 if (result == EDMA3_RM_SOK)
4664 {
4665 /* If parameter checking is enabled... */
4666 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4667 /* Verify the 'controllerId' */
4668 if ((controllerId < ((EDMA3_RM_Cntrlr_PhyAddr)(EDMA3_RM_CC_PHY_ADDR)))
4669 || (controllerId > (EDMA3_RM_Cntrlr_PhyAddr)(rmObj->gblCfgParams.numTcs)))
4670 {
4671 /* Invalid controllerId */
4672 result = EDMA3_RM_E_INVALID_PARAM;
4673 }
4674 #endif
4676 /* Check if the parameters are OK. */
4677 if (EDMA3_RM_SOK == result)
4678 {
4679 if (controllerId == EDMA3_RM_CC_PHY_ADDR)
4680 {
4681 /* EDMA3 Channel Controller Address */
4682 *phyAddress = (unsigned int)(rmObj->gblCfgParams.globalRegs);
4683 }
4684 else
4685 {
4686 /**
4687 * Since the TCs enum start from 1, and TCs start from 0,
4688 * subtract 1 from the enum to get the actual address.
4689 */
4690 *phyAddress = (unsigned int)(rmObj->gblCfgParams.tcRegs[controllerId-1u]);
4691 }
4692 }
4693 }
4695 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4696 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4697 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4698 EDMA3_DVT_dCOUNTER,
4699 EDMA3_DVT_dNONE,
4700 EDMA3_DVT_dNONE));
4701 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4703 return result;
4704 }
4706 EDMA3_RM_Result EDMA3_RM_getGblConfigParams (
4707 unsigned int phyCtrllerInstId,
4708 EDMA3_RM_GblConfigParams *gblCfgParams)
4709 {
4710 EDMA3_RM_Result result = EDMA3_RM_SOK;
4712 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4713 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4714 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4715 EDMA3_DVT_dCOUNTER,
4716 EDMA3_DVT_dNONE,
4717 EDMA3_DVT_dNONE));
4718 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4720 /* If parameter checking is enabled... */
4721 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4722 if ((phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
4723 || (NULL == gblCfgParams))
4724 {
4725 result = EDMA3_RM_E_INVALID_PARAM;
4726 }
4727 #endif
4729 if (EDMA3_RM_SOK == result)
4730 {
4731 /* Return the previously saved global config information for the EDMA3 HW */
4732 edma3MemCpy((void *)(gblCfgParams),
4733 (const void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
4734 sizeof (EDMA3_RM_GblConfigParams));
4735 }
4737 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4738 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4739 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4740 EDMA3_DVT_dCOUNTER,
4741 EDMA3_DVT_dNONE,
4742 EDMA3_DVT_dNONE));
4743 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4745 return result;
4746 }
4748 EDMA3_RM_Result EDMA3_RM_getInstanceInitCfg (
4749 EDMA3_RM_Handle hEdmaResMgr,
4750 EDMA3_RM_InstanceInitConfig *instanceInitConfig)
4751 {
4752 EDMA3_RM_Result result = EDMA3_RM_SOK;
4753 EDMA3_RM_Instance *rmInstance = NULL;
4754 EDMA3_RM_Obj *rmObj = NULL;
4755 unsigned int resMgrIdx = 0u;
4756 unsigned int hwId;
4758 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4759 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4760 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4761 EDMA3_DVT_dCOUNTER,
4762 EDMA3_DVT_dNONE,
4763 EDMA3_DVT_dNONE));
4764 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4766 /* If parameter checking is enabled... */
4767 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4768 if ((hEdmaResMgr == NULL) || (instanceInitConfig == NULL))
4769 {
4770 result = EDMA3_RM_E_INVALID_PARAM;
4771 }
4772 #endif
4774 if (result == EDMA3_RM_SOK)
4775 {
4776 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4778 if (rmInstance == NULL)
4779 {
4780 result = EDMA3_RM_E_INVALID_PARAM;
4781 }
4782 }
4784 if (result == EDMA3_RM_SOK)
4785 {
4786 rmObj = rmInstance->pResMgrObjHandle;
4788 if (rmObj == NULL)
4789 {
4790 result = EDMA3_RM_E_INVALID_PARAM;
4791 }
4792 }
4794 if (result == EDMA3_RM_SOK)
4795 {
4796 hwId = rmObj->phyCtrllerInstId;
4798 for (resMgrIdx = 0u; resMgrIdx < EDMA3_MAX_RM_INSTANCES; resMgrIdx++)
4799 {
4800 if (rmInstance == ((EDMA3_RM_Instance *)(ptrRMIArray) +
4801 (hwId*EDMA3_MAX_RM_INSTANCES) +
4802 resMgrIdx))
4803 {
4804 /* RM Id found. Return the specific config info to the user. */
4805 edma3MemCpy((void *)(instanceInitConfig),
4806 (const void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) +
4807 (hwId*EDMA3_MAX_RM_INSTANCES) +
4808 resMgrIdx),
4809 sizeof (EDMA3_RM_InstanceInitConfig));
4810 break;
4811 }
4812 }
4814 if (EDMA3_MAX_RM_INSTANCES == resMgrIdx)
4815 {
4816 /* RM Id not found, report error... */
4817 result = EDMA3_RM_E_INVALID_PARAM;
4818 }
4819 }
4821 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4822 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4823 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4824 EDMA3_DVT_dCOUNTER,
4825 EDMA3_DVT_dNONE,
4826 EDMA3_DVT_dNONE));
4827 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4829 return result;
4830 }
4832 EDMA3_RM_Result EDMA3_RM_Ioctl(
4833 EDMA3_RM_Handle hEdmaResMgr,
4834 EDMA3_RM_IoctlCmd cmd,
4835 void *cmdArg,
4836 void *param
4837 )
4838 {
4839 EDMA3_RM_Result result = EDMA3_RM_SOK;
4840 EDMA3_RM_Instance *rmInstance = NULL;
4841 unsigned int paramInitRequired = 0xFFu;
4842 unsigned int regModificationRequired = 0xFFu;
4843 unsigned int *ret_val = NULL;
4845 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4846 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4847 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4848 EDMA3_DVT_dCOUNTER,
4849 EDMA3_DVT_dNONE,
4850 EDMA3_DVT_dNONE));
4851 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4853 /* If parameter checking is enabled... */
4854 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4855 if (hEdmaResMgr == NULL)
4856 {
4857 result = EDMA3_RM_E_INVALID_PARAM;
4858 }
4860 if ((cmd <= EDMA3_RM_IOCTL_MIN_IOCTL)
4861 || (cmd >= EDMA3_RM_IOCTL_MAX_IOCTL))
4862 {
4863 result = EDMA3_RM_E_INVALID_PARAM;
4864 }
4865 #endif
4867 if (result == EDMA3_RM_SOK)
4868 {
4869 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4871 if (rmInstance == NULL)
4872 {
4873 result = EDMA3_RM_E_INVALID_PARAM;
4874 }
4875 }
4877 /* To remove CCS warnings */
4878 (void)param;
4880 if (result == EDMA3_RM_SOK)
4881 {
4882 switch (cmd)
4883 {
4884 case EDMA3_RM_IOCTL_SET_PARAM_CLEAR_OPTION:
4885 {
4886 paramInitRequired = (unsigned int)cmdArg;
4888 /* If parameter checking is enabled... */
4889 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4890 if ((paramInitRequired != 0u)
4891 && (paramInitRequired != 1u))
4892 {
4893 result = EDMA3_RM_E_INVALID_PARAM;
4894 }
4895 #endif
4897 /* Check if the parameters are OK. */
4898 if (EDMA3_RM_SOK == result)
4899 {
4900 /* Set/Reset the flag which is being used to do the PaRAM clearing. */
4901 rmInstance->paramInitRequired = paramInitRequired;
4902 }
4904 break;
4905 }
4907 case EDMA3_RM_IOCTL_GET_PARAM_CLEAR_OPTION:
4908 {
4909 /* If parameter checking is enabled... */
4910 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4911 if (NULL == cmdArg)
4912 {
4913 result = EDMA3_RM_E_INVALID_PARAM;
4914 }
4915 #endif
4917 /* Check if the parameters are OK. */
4918 if (EDMA3_RM_SOK == result)
4919 {
4920 ret_val = (unsigned int *)cmdArg;
4922 /* Get the flag which is being used to do the PaRAM clearing. */
4923 *ret_val = rmInstance->paramInitRequired;
4924 }
4926 break;
4927 }
4929 case EDMA3_RM_IOCTL_SET_GBL_REG_MODIFY_OPTION:
4930 {
4931 regModificationRequired = (unsigned int)cmdArg;
4933 /* If parameter checking is enabled... */
4934 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4935 if ((regModificationRequired != 0u)
4936 && (regModificationRequired != 1u))
4937 {
4938 /* All other values are invalid. */
4939 result = EDMA3_RM_E_INVALID_PARAM;
4940 }
4941 #endif
4943 /* Check if the parameters are OK. */
4944 if (EDMA3_RM_SOK == result)
4945 {
4946 /**
4947 * Set/Reset the flag which is being used to do the global
4948 * registers and PaRAM modification.
4949 */
4950 rmInstance->regModificationRequired = regModificationRequired;
4951 }
4953 break;
4954 }
4956 case EDMA3_RM_IOCTL_GET_GBL_REG_MODIFY_OPTION:
4957 {
4958 /* If parameter checking is enabled... */
4959 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4960 if (NULL == cmdArg)
4961 {
4962 result = EDMA3_RM_E_INVALID_PARAM;
4963 }
4964 #endif
4966 /* Check if the parameters are OK. */
4967 if (EDMA3_RM_SOK == result)
4968 {
4969 ret_val = (unsigned int *)cmdArg;
4971 /**
4972 * Get the flag which is being used to do the global
4973 * registers and PaRAM modification.
4974 */
4975 *ret_val = rmInstance->regModificationRequired;
4976 }
4978 break;
4979 }
4981 default:
4982 /* Hey dude! you passed invalid IOCTL cmd */
4983 result = EDMA3_RM_E_INVALID_PARAM;
4985 }
4986 }
4989 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4990 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4991 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4992 EDMA3_DVT_dCOUNTER,
4993 EDMA3_DVT_dNONE,
4994 EDMA3_DVT_dNONE));
4995 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4997 return result;
4999 }
5001 /**
5002 * edma3ComplHandler
5003 * \brief Interrupt handler for successful transfer completion.
5004 *
5005 * \note This function first disables its own interrupt to make it non-
5006 * entrant. Later, after calling all the callback functions, it
5007 * re-enables its own interrupt.
5008 *
5009 * \return None.
5010 */
5011 static void edma3ComplHandler (const EDMA3_RM_Obj *rmObj)
5012 {
5013 unsigned int Cnt;
5014 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
5015 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
5016 volatile unsigned int pendingIrqs;
5017 unsigned int indexl;
5018 unsigned int indexh;
5019 unsigned int edma3Id;
5021 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5022 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5023 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5024 EDMA3_DVT_dNONE,
5025 EDMA3_DVT_dNONE,
5026 EDMA3_DVT_dNONE));
5027 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5029 assert (NULL != rmObj);
5031 edma3Id = rmObj->phyCtrllerInstId;
5032 ptrEdmaccRegs =
5033 (volatile EDMA3_CCRL_Regs *)rmObj->gblCfgParams.globalRegs;
5034 if (ptrEdmaccRegs != NULL)
5035 {
5036 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
5037 (&ptrEdmaccRegs->SHADOW[edma3RegionId]);
5038 }
5040 Cnt = 0u;
5041 pendingIrqs = 0u;
5042 indexl = 1u;
5043 indexh = 1u;
5045 if((shadowRegs->IPR !=0 ) || (shadowRegs->IPRH !=0 ))
5046 {
5047 /**
5048 * Since an interrupt has found, we have to make sure that this
5049 * interrupt (TCC) belongs to the TCCs allocated by us only.
5050 * It might happen that someone else, who is using EDMA3 also,
5051 * is the owner of this interrupt channel i.e. the TCC.
5052 * For this, use the allocatedTCCs[], to check which all interrupt
5053 * channels are owned by the EDMA3 RM Instances.
5054 */
5056 edma3OsProtectEntry (edma3Id,
5057 EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,
5058 NULL);
5060 /* Loop for EDMA3_RM_COMPL_HANDLER_RETRY_COUNT number of time,
5061 breaks when no pending interrupt is found */
5062 while ((Cnt < EDMA3_RM_COMPL_HANDLER_RETRY_COUNT)
5063 && ((indexl != 0u) || (indexh != 0u)))
5064 {
5065 indexl = 0u;
5066 pendingIrqs = shadowRegs->IPR;
5068 /**
5069 * Choose interrupts coming from our allocated TCCs
5070 * and MASK remaining ones.
5071 */
5072 pendingIrqs = (pendingIrqs & allocatedTCCs[edma3Id][0u]);
5074 while (pendingIrqs)
5075 {
5076 /*Process all the pending interrupts*/
5077 if((pendingIrqs & 1u) == TRUE)
5078 {
5079 /**
5080 * If the user has not given any callback function
5081 * while requesting the TCC, its TCC specific bit
5082 * in the IPR register will NOT be cleared.
5083 */
5084 if(edma3IntrParams[edma3Id][indexl].tccCb != NULL)
5085 {
5086 /* here write to ICR to clear the corresponding IPR bits*/
5087 shadowRegs->ICR = (1u << indexl);
5089 edma3IntrParams[edma3Id][indexl].tccCb (indexl,
5090 EDMA3_RM_XFER_COMPLETE,
5091 edma3IntrParams[edma3Id][indexl].cbData);
5092 }
5093 }
5094 ++indexl;
5095 pendingIrqs >>= 1u;
5096 }
5098 indexh = 0u;
5099 pendingIrqs = shadowRegs->IPRH;
5101 /**
5102 * Choose interrupts coming from our allocated TCCs
5103 * and MASK remaining ones.
5104 */
5105 pendingIrqs = (pendingIrqs & allocatedTCCs[edma3Id][1u]);
5107 while (pendingIrqs)
5108 {
5109 /*Process all the pending interrupts*/
5110 if((pendingIrqs & 1u)==TRUE)
5111 {
5112 /**
5113 * If the user has not given any callback function
5114 * while requesting the TCC, its TCC specific bit
5115 * in the IPRH register will NOT be cleared.
5116 */
5117 if(edma3IntrParams[edma3Id][32u+indexh].tccCb!=NULL)
5118 {
5119 /* here write to ICR to clear the corresponding IPR bits*/
5120 shadowRegs->ICRH = (1u << indexh);
5122 edma3IntrParams[edma3Id][32u+indexh].tccCb(32u+indexh,
5123 EDMA3_RM_XFER_COMPLETE,
5124 edma3IntrParams[edma3Id][32u+indexh].cbData);
5125 }
5126 }
5127 ++indexh;
5128 pendingIrqs >>= 1u;
5129 }
5131 Cnt++;
5132 }
5134 indexl = (shadowRegs->IPR & allocatedTCCs[edma3Id][0u]);
5135 indexh = (shadowRegs->IPRH & allocatedTCCs[edma3Id][1u]);
5137 if((indexl !=0 ) || (indexh !=0 ))
5138 {
5139 shadowRegs->IEVAL=0x1u;
5140 }
5142 edma3OsProtectExit (rmObj->phyCtrllerInstId,
5143 EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,
5144 NULL);
5145 }
5147 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5148 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5149 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5150 EDMA3_DVT_dNONE,
5151 EDMA3_DVT_dNONE,
5152 EDMA3_DVT_dNONE));
5153 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5154 }
5157 void lisrEdma3ComplHandler0(unsigned int edma3InstanceId)
5158 {
5159 /* Invoke Completion Handler ISR */
5160 edma3ComplHandler(&resMgrObj[edma3InstanceId]);
5161 }
5164 /**
5165 * \brief Interrupt handler for Channel Controller Error.
5166 *
5167 * \note This function first disables its own interrupt to make it non-
5168 * entrant. Later, after calling all the callback functions, it
5169 * re-enables its own interrupt.
5170 *
5171 * \return None.
5172 */
5173 static void edma3CCErrHandler(const EDMA3_RM_Obj *rmObj)
5174 {
5175 unsigned int Cnt = 0u;
5176 unsigned int resMgrInstIdx = 0u;
5177 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
5178 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
5179 volatile unsigned int pendingIrqs;
5180 unsigned int index;
5181 unsigned int evtqueNum;
5182 EDMA3_RM_Instance *rm_instance = NULL;
5183 unsigned int edma3Id;
5184 unsigned int num_rm_instances_opened;
5185 EDMA3_RM_Instance *rmInstance = NULL;
5186 unsigned int ownedDmaError = 0;
5187 unsigned int ownedDmaHError = 0;
5188 unsigned int ownedQdmaError = 0;
5190 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5191 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_CCERR",
5192 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5193 EDMA3_DVT_dNONE,
5194 EDMA3_DVT_dNONE,
5195 EDMA3_DVT_dNONE));
5196 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5198 assert (rmObj != NULL);
5200 edma3Id = rmObj->phyCtrllerInstId;
5201 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)rmObj->gblCfgParams.globalRegs;
5202 if (ptrEdmaccRegs != NULL)
5203 {
5204 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)&ptrEdmaccRegs->SHADOW[edma3RegionId];
5205 rmInstance = ((EDMA3_RM_Instance *)(ptrRMIArray)
5206 + (edma3Id*EDMA3_MAX_RM_INSTANCES)
5207 + edma3RegionId);
5209 pendingIrqs = 0u;
5210 index = 1u;
5212 if(((ptrEdmaccRegs->EMR != 0 )
5213 || (ptrEdmaccRegs->EMRH != 0 ))
5214 || ((ptrEdmaccRegs->QEMR != 0)
5215 || (ptrEdmaccRegs->CCERR != 0)))
5216 {
5217 edma3OsProtectEntry (edma3Id,
5218 EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR,
5219 NULL);
5221 /* Loop for EDMA3_RM_CCERR_HANDLER_RETRY_COUNT number of time,
5222 breaks when no pending interrupt is found */
5223 while ((Cnt < EDMA3_RM_CCERR_HANDLER_RETRY_COUNT)
5224 && (index != 0u))
5225 {
5226 index = 0u;
5227 pendingIrqs = ptrEdmaccRegs->EMR;
5229 while (pendingIrqs)
5230 {
5231 /*Process all the pending interrupts*/
5232 if((pendingIrqs & 1u)==TRUE)
5233 {
5234 unsigned int mappedTcc = 0u;
5236 /**
5237 * Using the 'index' value (basically the DMA
5238 * channel), fetch the corresponding TCC
5239 * value, mapped to this DMA channel.
5240 */
5241 mappedTcc = edma3DmaChTccMapping[edma3Id][index];
5243 /**
5244 * Ensure that the mapped tcc is valid and the call
5245 * back is not NULL
5246 */
5247 if (mappedTcc < EDMA3_MAX_TCC)
5248 {
5249 /**
5250 * TCC owned and allocated by RM.
5251 * Write to EMCR to clear the corresponding EMR bits.
5252 */
5253 ptrEdmaccRegs->EMCR = (1u<<index);
5254 /*Clear any SER*/
5255 shadowRegs->SECR = (1u<<index);
5257 /* Call the callback function if registered earlier. */
5258 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5259 {
5260 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5261 mappedTcc,
5262 EDMA3_RM_E_CC_DMA_EVT_MISS,
5263 edma3IntrParams[edma3Id][mappedTcc].cbData
5264 );
5265 }
5266 }
5267 else
5268 {
5269 /**
5270 * DMA channel not owned by the RM instance.
5271 * Check the global error interrupt clearing option.
5272 * If it is TRUE, clear the error interupt else leave
5273 * it like that.
5274 */
5275 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5276 /* here write to EMCR to clear the corresponding EMR bits. */
5277 ptrEdmaccRegs->EMCR = (1u<<index);
5278 /*Clear any SER*/
5279 ptrEdmaccRegs->SECR = (1u<<index);
5280 #endif
5281 }
5282 }
5283 ++index;
5284 pendingIrqs >>= 1u;
5285 }
5287 index = 0u;
5288 pendingIrqs = ptrEdmaccRegs->EMRH;
5289 while (pendingIrqs)
5290 {
5291 /*Process all the pending interrupts*/
5292 if((pendingIrqs & 1u)==TRUE)
5293 {
5294 unsigned int mappedTcc = 0u;
5296 /**
5297 * Using the 'index' value (basically the DMA
5298 * channel), fetch the corresponding TCC
5299 * value, mapped to this DMA channel.
5300 */
5301 mappedTcc = edma3DmaChTccMapping[edma3Id][32u+index];
5303 /**
5304 * Ensure that the mapped tcc is valid and the call
5305 * back is not NULL
5306 */
5307 if (mappedTcc < EDMA3_MAX_TCC)
5308 {
5309 /**
5310 * TCC owned and allocated by RM.
5311 * Write to EMCR to clear the corresponding EMR bits.
5312 */
5313 ptrEdmaccRegs->EMCRH = (1u<<index);
5314 /*Clear any SERH*/
5315 shadowRegs->SECRH = (1u<<index);
5317 /* Call the callback function if registered earlier. */
5318 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5319 {
5320 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5321 mappedTcc,
5322 EDMA3_RM_E_CC_DMA_EVT_MISS,
5323 edma3IntrParams[edma3Id][mappedTcc].cbData
5324 );
5325 }
5326 }
5327 else
5328 {
5329 /**
5330 * DMA channel not owned by the RM instance.
5331 * Check the global error interrupt clearing option.
5332 * If it is TRUE, clear the error interupt else leave
5333 * it like that.
5334 */
5335 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5336 /**
5337 * TCC NOT owned by RM.
5338 * Write to EMCRH to clear the corresponding EMRH bits.
5339 */
5340 ptrEdmaccRegs->EMCRH = (1u<<index);
5341 /*Clear any SERH*/
5342 shadowRegs->SECRH = (1u<<index);
5343 #endif
5344 }
5345 }
5346 ++index;
5347 pendingIrqs >>= 1u;
5348 }
5350 index = 0u;
5351 pendingIrqs = ptrEdmaccRegs->QEMR;
5352 while (pendingIrqs)
5353 {
5354 /*Process all the pending interrupts*/
5355 if((pendingIrqs & 1u)==TRUE)
5356 {
5357 unsigned int mappedTcc = 0u;
5359 /**
5360 * Using the 'index' value (basically the QDMA
5361 * channel), fetch the corresponding TCC
5362 * value, mapped to this QDMA channel.
5363 */
5364 mappedTcc = edma3QdmaChTccMapping[edma3Id][index];
5366 if (mappedTcc < EDMA3_MAX_TCC)
5367 {
5368 /* here write to QEMCR to clear the corresponding QEMR bits*/
5369 ptrEdmaccRegs->QEMCR = (1u<<index);
5370 /*Clear any QSER*/
5371 shadowRegs->QSECR = (1u<<index);
5373 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5374 {
5375 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5376 mappedTcc,
5377 EDMA3_RM_E_CC_QDMA_EVT_MISS,
5378 edma3IntrParams[edma3Id][mappedTcc].cbData
5379 );
5380 }
5381 }
5382 else
5383 {
5384 /**
5385 * QDMA channel not owned by the RM instance.
5386 * Check the global error interrupt clearing option.
5387 * If it is TRUE, clear the error interupt else leave
5388 * the ISR.
5389 */
5390 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5391 /* here write to QEMCR to clear the corresponding QEMR bits*/
5392 ptrEdmaccRegs->QEMCR = (1u<<index);
5394 /*Clear any QSER*/
5395 ptrEdmaccRegs->QSECR = (1u<<index);
5396 #endif
5397 }
5398 }
5399 ++index;
5400 pendingIrqs >>= 1u;
5401 }
5403 index = 0u;
5404 pendingIrqs = ptrEdmaccRegs->CCERR;
5405 if (pendingIrqs!=NULL)
5406 {
5407 /* Process all the pending CC error interrupts. */
5409 /* Queue threshold error for different event queues.*/
5410 for (evtqueNum = 0u; evtqueNum < rmObj->gblCfgParams.numEvtQueue; evtqueNum++)
5411 {
5412 if((pendingIrqs & (1u << evtqueNum)) != NULL)
5413 {
5414 /**
5415 * Queue threshold error for queue 'evtqueNum' raised.
5416 * Inform all the RM instances working on this region
5417 * about the error by calling their global callback functions.
5418 */
5419 num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
5420 for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
5421 {
5422 /* Check whether the RM instance opened working on this region */
5423 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5424 if (NULL != rm_instance)
5425 {
5426 if (rm_instance->initParam.regionId == edma3RegionId)
5427 {
5428 /* Region id matches, call the callback function */
5429 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5430 {
5431 rm_instance->initParam.gblerrCbParams.gblerrCb(
5432 EDMA3_RM_E_CC_QUE_THRES_EXCEED,
5433 evtqueNum,
5434 rm_instance->initParam.gblerrCbParams.gblerrData);
5435 }
5436 }
5437 }
5439 /* Check next opened instance */
5440 num_rm_instances_opened--;
5441 }
5443 /* Clear the error interrupt. */
5444 ptrEdmaccRegs->CCERRCLR = (1u << evtqueNum);
5445 }
5446 }
5449 /* Transfer completion code error. */
5450 if ((pendingIrqs & (1 << EDMA3_CCRL_CCERR_TCCERR_SHIFT))!=NULL)
5451 {
5452 /**
5453 * Transfer completion code error raised.
5454 * Inform all the RM instances working on this region
5455 * about the error by calling their global callback functions.
5456 */
5457 num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
5458 for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
5459 {
5460 /* Check whether the RM instance opened working on this region */
5461 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5462 if (NULL != rm_instance)
5463 {
5464 if (rm_instance->initParam.regionId == edma3RegionId)
5465 {
5466 /* Region id matches, call the callback function */
5467 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5468 {
5469 rm_instance->initParam.gblerrCbParams.gblerrCb(
5470 EDMA3_RM_E_CC_TCC,
5471 NULL,
5472 rm_instance->initParam.gblerrCbParams.gblerrData);
5473 }
5474 }
5475 }
5477 /* Check next opened instance */
5478 num_rm_instances_opened--;
5479 }
5481 ptrEdmaccRegs->CCERRCLR = (1<<EDMA3_CCRL_CCERR_TCCERR_SHIFT);
5482 }
5484 ++index;
5485 }
5487 Cnt++;
5488 }
5491 /**
5492 * Read the error registers again. If any interrupt is pending,
5493 * write the EEVAL register.
5494 * Moreover, according to the global error interrupt clearing
5495 * option, check either error bits associated with all the
5496 * DMA/QDMA channels (option is SET) OR check error bits
5497 * associated with owned DMA/QDMA channels.
5498 */
5499 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5500 /* To remove warning. */
5501 rmInstance = rmInstance;
5503 /* Check all the error bits. */
5504 ownedDmaError = ptrEdmaccRegs->EMR;
5505 ownedDmaHError = ptrEdmaccRegs->EMRH;
5506 ownedQdmaError = ptrEdmaccRegs->QEMR;
5507 #else
5508 /* Check ONLY owned error bits. */
5509 ownedDmaError = (ptrEdmaccRegs->EMR & rmInstance->initParam.rmInstInitConfig->ownDmaChannels[0u]);
5510 ownedDmaHError = (ptrEdmaccRegs->EMRH & rmInstance->initParam.rmInstInitConfig->ownDmaChannels[1u]);
5511 ownedQdmaError = (ptrEdmaccRegs->QEMR & rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u]);
5512 #endif
5514 if (((ownedDmaError != 0 ) || (ownedDmaHError != 0 ))
5515 || ((ownedQdmaError != 0) || (ptrEdmaccRegs->CCERR != 0)))
5516 {
5517 ptrEdmaccRegs->EEVAL=0x1u;
5518 }
5520 edma3OsProtectExit (rmObj->phyCtrllerInstId,
5521 EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR,
5522 NULL);
5523 }
5524 }
5526 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5527 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_CCERR",
5528 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5529 EDMA3_DVT_dNONE,
5530 EDMA3_DVT_dNONE,
5531 EDMA3_DVT_dNONE));
5532 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5533 }
5535 void lisrEdma3CCErrHandler0(unsigned int edma3InstanceId)
5536 {
5537 /* Invoke CC Error Handler ISR */
5538 edma3CCErrHandler(&resMgrObj[edma3InstanceId]);
5539 }
5543 /**
5544 * \brief Interrupt handler for Transfer Controller Error.
5545 *
5546 * \note This function first disables its own interrupt to make it non-
5547 * entrant. Later, after calling all the callback functions, it
5548 * re-enables its own interrupt.
5549 *
5550 * \return None.
5551 */
5552 static void edma3TCErrHandler (const EDMA3_RM_Obj *rmObj, unsigned int tcNum)
5553 {
5554 volatile EDMA3_TCRL_Regs *tcRegs = NULL;
5555 unsigned int tcMemErrRdWr = 0u;
5556 unsigned int resMgrInstIdx = 0u;
5557 EDMA3_RM_Instance *rm_instance = NULL;
5558 unsigned int edma3Id;
5559 unsigned int num_rm_instances_opened;
5561 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5562 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_TCERR",
5563 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5564 EDMA3_DVT_dNONE,
5565 EDMA3_DVT_dNONE,
5566 EDMA3_DVT_dNONE));
5567 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5569 assert ((rmObj != NULL) && (tcNum < rmObj->gblCfgParams.numTcs));
5571 if (rmObj->gblCfgParams.tcRegs[tcNum] != NULL)
5572 {
5573 tcRegs = (volatile EDMA3_TCRL_Regs *)(rmObj->gblCfgParams.tcRegs[tcNum]);
5574 edma3Id = rmObj->phyCtrllerInstId;
5575 }
5577 if (tcRegs != NULL)
5578 {
5579 if(tcRegs->ERRSTAT != 0)
5580 {
5581 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
5582 EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR,
5583 &tcNum);
5585 if((tcRegs->ERRSTAT & (1 << EDMA3_TCRL_ERRSTAT_BUSERR_SHIFT))!=NULL)
5586 {
5587 /* Bus error event. */
5588 /**
5589 * EDMA3TC has detected an error at source or destination
5590 * address. Error information can be read from the error
5591 * details register (ERRDET).
5592 */
5593 tcMemErrRdWr = tcRegs->ERRDET & (EDMA3_TCRL_ERRDET_STAT_MASK);
5594 if ((tcMemErrRdWr > 0u) && (tcMemErrRdWr < 8u))
5595 {
5596 /**
5597 * Inform all the RM instances working on this region
5598 * about the error by calling their global callback functions.
5599 */
5600 num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
5601 for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
5602 {
5603 /* Check whether the RM instance opened working on this region */
5604 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5605 if (NULL != rm_instance)
5606 {
5607 if (rm_instance->initParam.regionId == edma3RegionId)
5608 {
5609 /* Region id matches, call the callback function */
5610 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5611 {
5612 rm_instance->initParam.gblerrCbParams.gblerrCb(
5613 EDMA3_RM_E_TC_MEM_LOCATION_READ_ERROR,
5614 tcNum,
5615 rm_instance->initParam.gblerrCbParams.gblerrData);
5616 }
5617 }
5618 }
5620 /* Check next opened instance */
5621 num_rm_instances_opened--;
5622 }
5623 }
5624 else
5625 {
5626 if ((tcMemErrRdWr >= 8u) && (tcMemErrRdWr <= 0xFu))
5627 {
5628 /**
5629 * Inform all the RM instances working on this region
5630 * about the error by calling their global callback functions.
5631 */
5632 num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
5633 for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
5634 {
5635 /* Check whether the RM instance opened working on this region */
5636 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5637 if (NULL != rm_instance)
5638 {
5639 if (rm_instance->initParam.regionId == edma3RegionId)
5640 {
5641 /* Region id matches, call the callback function */
5642 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5643 {
5644 rm_instance->initParam.gblerrCbParams.gblerrCb(
5645 EDMA3_RM_E_TC_MEM_LOCATION_WRITE_ERROR,
5646 tcNum,
5647 rm_instance->initParam.gblerrCbParams.gblerrData);
5648 }
5649 }
5650 }
5652 /* Check next opened instance */
5653 num_rm_instances_opened--;
5654 }
5655 }
5656 }
5657 tcRegs->ERRCLR = (1<<EDMA3_TCRL_ERRSTAT_BUSERR_SHIFT);
5658 }
5659 else
5660 {
5661 /* Transfer request (TR) error event. */
5662 if((tcRegs->ERRSTAT & (1 << EDMA3_TCRL_ERRSTAT_TRERR_SHIFT))!=NULL)
5663 {
5664 num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
5665 for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
5666 {
5667 /* Check whether the RM instance opened working on this region */
5668 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5669 if (NULL != rm_instance)
5670 {
5671 if (rm_instance->initParam.regionId == edma3RegionId)
5672 {
5673 /* Region id matches, call the callback function */
5674 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5675 {
5676 rm_instance->initParam.gblerrCbParams.gblerrCb(
5677 EDMA3_RM_E_TC_TR_ERROR,
5678 tcNum,
5679 rm_instance->initParam.gblerrCbParams.gblerrData);
5680 }
5681 }
5682 }
5684 /* Check next opened instance */
5685 num_rm_instances_opened--;
5686 }
5688 tcRegs->ERRCLR = (1<<EDMA3_TCRL_ERRSTAT_TRERR_SHIFT);
5689 }
5690 else
5691 {
5692 if((tcRegs->ERRSTAT & (1 << EDMA3_TCRL_ERRSTAT_MMRAERR_SHIFT))!=NULL)
5693 {
5694 num_rm_instances_opened = resMgrObj[edma3Id].numOpens;
5695 for (resMgrInstIdx = 0u; num_rm_instances_opened; ++resMgrInstIdx)
5696 {
5697 /* Check whether the RM instance opened working on this region */
5698 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5699 if (NULL != rm_instance)
5700 {
5701 if (rm_instance->initParam.regionId == edma3RegionId)
5702 {
5703 /* Region id matches, call the callback function */
5704 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5705 {
5706 rm_instance->initParam.gblerrCbParams.gblerrCb(
5707 EDMA3_RM_E_TC_INVALID_ADDR,
5708 tcNum,
5709 rm_instance->initParam.gblerrCbParams.gblerrData);
5710 }
5711 }
5712 }
5714 /* Check next opened instance */
5715 num_rm_instances_opened--;
5716 }
5718 tcRegs->ERRCLR = (1<<EDMA3_TCRL_ERRSTAT_MMRAERR_SHIFT);
5719 }
5720 }
5721 }
5723 edma3OsProtectExit (rmObj->phyCtrllerInstId,
5724 EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR,
5725 tcNum);
5726 }
5727 }
5729 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5730 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_TCERR",
5731 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5732 EDMA3_DVT_dNONE,
5733 EDMA3_DVT_dNONE,
5734 EDMA3_DVT_dNONE));
5735 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5736 }
5740 /*
5741 * ======== lisrEdma3TC0ErrHandler0 ========
5742 * EDMA3 instance 0 TC0 Error Interrupt Service Routine
5743 */
5744 void lisrEdma3TC0ErrHandler0(unsigned int edma3InstanceId)
5745 {
5746 /* Invoke Error Handler ISR for TC0*/
5747 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 0u);
5748 }
5751 /*
5752 * ======== lisrEdma3TC1ErrHandler0 ========
5753 * EDMA3 instance 0 TC1 Error Interrupt Service Routine
5754 */
5755 void lisrEdma3TC1ErrHandler0(unsigned int edma3InstanceId)
5756 {
5757 /* Invoke Error Handler ISR for TC1*/
5758 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 1u);
5759 }
5761 /*
5762 * ======== lisrEdma3TC2ErrHandler0 ========
5763 * EDMA3 instance 0 TC2 Error Interrupt Service Routine
5764 */
5765 void lisrEdma3TC2ErrHandler0(unsigned int edma3InstanceId)
5766 {
5767 /* Invoke Error Handler ISR for TC2*/
5768 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 2u);
5769 }
5771 /*
5772 * ======== lisrEdma3TC3ErrHandler0 ========
5773 * EDMA3 instance 0 TC3 Error Interrupt Service Routine
5774 */
5775 void lisrEdma3TC3ErrHandler0(unsigned int edma3InstanceId)
5776 {
5777 /* Invoke Error Handler ISR for TC3*/
5778 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 3u);
5779 }
5781 /*
5782 * ======== lisrEdma3TC4ErrHandler0 ========
5783 * EDMA3 instance 0 TC4 Error Interrupt Service Routine
5784 */
5785 void lisrEdma3TC4ErrHandler0(unsigned int edma3InstanceId)
5786 {
5787 /* Invoke Error Handler ISR for TC4*/
5788 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 4u);
5789 }
5792 /*
5793 * ======== lisrEdma3TC5ErrHandler0 ========
5794 * EDMA3 instance 0 TC5 Error Interrupt Service Routine
5795 */
5796 void lisrEdma3TC5ErrHandler0(unsigned int edma3InstanceId)
5797 {
5798 /* Invoke Error Handler ISR for TC5*/
5799 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 5u);
5800 }
5802 /*
5803 * ======== lisrEdma3TC6ErrHandler0 ========
5804 * EDMA3 instance 0 TC6 Error Interrupt Service Routine
5805 */
5806 /* ARGSUSED */
5807 void lisrEdma3TC6ErrHandler0(unsigned int edma3InstanceId)
5808 {
5809 /* Invoke Error Handler ISR for TC6*/
5810 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 6u);
5811 }
5813 /*
5814 * ======== lisrEdma3TC7ErrHandler0 ========
5815 * EDMA3 instance 0 TC7 Error Interrupt Service Routine
5816 */
5817 void lisrEdma3TC7ErrHandler0(unsigned int edma3InstanceId)
5818 {
5819 /* Invoke Error Handler ISR for TC7*/
5820 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 7u);
5821 }
5825 /* Resource Manager Internal functions - Start */
5827 /** Initialization of the Global region registers of the EDMA3 Controller */
5828 static void edma3GlobalRegionInit (unsigned int phyCtrllerInstId)
5829 {
5830 unsigned int evtQNum = 0u;
5831 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
5833 assert (phyCtrllerInstId < EDMA3_MAX_EDMA3_INSTANCES);
5835 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)
5836 (resMgrObj[phyCtrllerInstId].gblCfgParams.globalRegs);
5838 if (ptrEdmaccRegs != NULL)
5839 {
5840 ptrEdmaccRegs->EMCR = EDMA3_RM_SET_ALL_BITS;
5841 ptrEdmaccRegs->EMCRH = EDMA3_RM_SET_ALL_BITS;
5842 ptrEdmaccRegs->QEMCR = EDMA3_RM_SET_ALL_BITS;
5844 /*
5845 * Set all Instance-wide EDMA3 parameters (not channel-specific)
5846 */
5848 /**
5849 * Set TC Priority among system-wide bus-masters and Queue
5850 * Watermark Level
5851 */
5852 while (evtQNum <
5853 resMgrObj[phyCtrllerInstId].gblCfgParams.numEvtQueue)
5854 {
5855 ptrEdmaccRegs->QUEPRI &= EDMA3_RM_QUEPRI_CLR_MASK(evtQNum);
5856 ptrEdmaccRegs->QUEPRI |= EDMA3_RM_QUEPRI_SET_MASK(evtQNum,
5857 resMgrObj[phyCtrllerInstId].gblCfgParams.evtQPri[evtQNum]);
5859 ptrEdmaccRegs->QWMTHRA |= EDMA3_RM_QUEWMTHR_SET_MASK(evtQNum,
5860 resMgrObj[phyCtrllerInstId].gblCfgParams.evtQueueWaterMarkLvl[evtQNum]);
5862 evtQNum++;
5863 }
5865 /* Clear CCERR register */
5866 ptrEdmaccRegs ->CCERRCLR = 0xFFFFu;
5867 }
5869 return;
5870 }
5875 /** Initialization of the Shadow region registers of the EDMA3 Controller */
5876 static void edma3ShadowRegionInit (const EDMA3_RM_Instance *pRMInstance)
5877 {
5878 unsigned int intState = 0u;
5879 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
5880 volatile EDMA3_CCRL_ShadowRegs *ptrEdmaShadowRegs = NULL;
5881 unsigned int phyCtrllerInstId;
5882 unsigned int regionId;
5883 const EDMA3_RM_InstanceInitConfig *rmInstInitConfig = pRMInstance->initParam.rmInstInitConfig;
5885 assert (pRMInstance != NULL);
5887 if (rmInstInitConfig != NULL)
5888 {
5889 phyCtrllerInstId = pRMInstance->pResMgrObjHandle->phyCtrllerInstId;
5890 regionId = pRMInstance->initParam.regionId;
5892 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)
5893 (resMgrObj[phyCtrllerInstId].gblCfgParams.globalRegs);
5895 if (ptrEdmaccRegs != NULL)
5896 {
5897 ptrEdmaShadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
5898 (&ptrEdmaccRegs->SHADOW[regionId]);
5900 ptrEdmaShadowRegs->ECR = (rmInstInitConfig->ownDmaChannels[0u]
5901 | rmInstInitConfig->ownTccs[0u]);
5902 ptrEdmaShadowRegs->ECRH = (rmInstInitConfig->ownDmaChannels[1u]
5903 | rmInstInitConfig->ownTccs[1u]);
5904 ptrEdmaShadowRegs->EECR = (rmInstInitConfig->ownDmaChannels[0u]
5905 | rmInstInitConfig->ownTccs[0u]);
5906 ptrEdmaShadowRegs->SECR = (rmInstInitConfig->ownDmaChannels[0u]
5907 | rmInstInitConfig->ownTccs[0u]);
5908 ptrEdmaShadowRegs->SECRH = (rmInstInitConfig->ownDmaChannels[1u]
5909 | rmInstInitConfig->ownTccs[1u]);
5910 ptrEdmaShadowRegs->EECR = (rmInstInitConfig->ownDmaChannels[0u]
5911 | rmInstInitConfig->ownTccs[0u]);
5912 ptrEdmaShadowRegs->EECRH = (rmInstInitConfig->ownDmaChannels[1u]
5913 | rmInstInitConfig->ownTccs[1u]);
5915 ptrEdmaShadowRegs->QEECR = rmInstInitConfig->ownQdmaChannels[0u];
5917 ptrEdmaShadowRegs->IECR = (rmInstInitConfig->ownDmaChannels[0u]
5918 | rmInstInitConfig->ownTccs[0u]);
5919 ptrEdmaShadowRegs->IECRH = (rmInstInitConfig->ownDmaChannels[1u]
5920 | rmInstInitConfig->ownTccs[1u]);
5921 ptrEdmaShadowRegs->ICR = (rmInstInitConfig->ownDmaChannels[0u]
5922 | rmInstInitConfig->ownTccs[0u]);
5923 ptrEdmaShadowRegs->ICRH = (rmInstInitConfig->ownDmaChannels[1u]
5924 | rmInstInitConfig->ownTccs[1u]);
5926 ptrEdmaShadowRegs->QSECR = rmInstInitConfig->ownQdmaChannels[0u];
5928 /*
5929 * Set all EDMA3 Resource<->Region mapping parameters
5930 */
5932 /* 1. Dma Channel (and TCC) <-> Region */
5933 edma3OsProtectEntry (phyCtrllerInstId,
5934 EDMA3_OS_PROTECT_INTERRUPT,
5935 &intState);
5936 ptrEdmaccRegs->DRA[regionId].DRAE = 0u;
5937 ptrEdmaccRegs->DRA[regionId].DRAEH = 0u;
5938 edma3OsProtectExit (phyCtrllerInstId,
5939 EDMA3_OS_PROTECT_INTERRUPT,
5940 intState);
5942 /* 2. Qdma Channel <-> Region */
5943 edma3OsProtectEntry (phyCtrllerInstId,
5944 EDMA3_OS_PROTECT_INTERRUPT,
5945 &intState);
5946 ptrEdmaccRegs->QRAE[regionId] = 0u;
5947 edma3OsProtectExit (phyCtrllerInstId,
5948 EDMA3_OS_PROTECT_INTERRUPT,
5949 intState);
5950 }
5951 }
5953 return;
5954 }
5958 /** Local MemZero function */
5959 void edma3MemZero(void *dst, unsigned int len)
5960 {
5961 unsigned int i = 0u;
5962 unsigned int *ds = NULL;
5964 assert (dst != NULL);
5966 ds = (unsigned int *)dst;
5968 for (i = 0 ; i < len/4 ; i++)
5969 {
5970 *ds = 0x0;
5971 ds++;
5972 }
5974 return;
5975 }
5978 /* Local MemCopy function */
5979 void edma3MemCpy(void *dst, const void *src, unsigned int len)
5980 {
5981 unsigned int i=0u;
5982 const unsigned int *sr;
5983 unsigned int *ds;
5985 assert ((src != NULL) && (dst != NULL) && ((len)%4 == 0));
5987 sr = (const unsigned int *)src;
5988 ds = (unsigned int *)dst;
5990 for (i = 0 ; i < len/4 ; i++)
5991 {
5992 *ds = *sr;
5993 ds++;
5994 sr++;
5995 }
5997 return;
5998 }
6001 /* Local MemCopy function to copy Param Set ONLY */
6002 void edma3ParamCpy(void *dst, const void *src)
6003 {
6004 unsigned int i = 0u;
6005 const unsigned int *sr;
6006 unsigned int *ds;
6008 assert ((src != NULL) && (dst != NULL));
6010 sr = (const unsigned int *)src;
6011 ds = (unsigned int *)dst;
6013 for (i = 0; i < 8; i++)
6014 {
6015 *ds = *sr;
6016 ds++;
6017 sr++;
6018 }
6020 return;
6021 }
6024 /**
6025 * Finds a particular bit ('0' or '1') in the particular word from 'start'.
6026 * If found, returns the position, else return -1.
6027 */
6028 static int findBitInWord (int source, unsigned int start, unsigned short bit)
6029 {
6030 unsigned int position = start;
6031 unsigned short found = 0;
6032 unsigned int iterations_left = 0;
6034 switch (bit)
6035 {
6036 case 1:
6037 {
6038 source >>= (start%32u);
6040 while ((found==0u) && (source!=0))
6041 {
6042 if ((source & 0x1) == 0x1)
6043 {
6044 /* 1 */
6045 found++;
6046 }
6047 else
6048 {
6049 /* 0 */
6050 source >>= 1;
6051 position++;
6052 }
6053 }
6055 }
6056 break;
6058 case 0:
6059 {
6060 source >>= (start%32u);
6061 iterations_left = 32u - (start%32u);
6063 while ((found==0u) && (iterations_left>0u))
6064 {
6065 if ((source & 0x1) == 0x1)
6066 {
6067 /* 1 */
6068 source >>= 1;
6069 position++;
6070 iterations_left--;
6071 }
6072 else
6073 {
6074 /* 0 */
6075 found++;
6076 }
6077 }
6078 }
6079 break;
6081 default:
6082 break;
6083 }
6085 return (found ? (int)position : -1);
6086 }
6089 /**
6090 * Finds a particular bit ('0' or '1') in the specified resources' array
6091 * from 'start' to 'end'. If found, returns the position, else return -1.
6092 */
6093 static int findBit (EDMA3_RM_ResType resType,
6094 unsigned int start,
6095 unsigned int end,
6096 unsigned short bit)
6097 {
6098 int position = -1;
6099 unsigned int start_index = start / 32u;
6100 unsigned int end_index = end / 32u;
6101 int i;
6102 unsigned int *resPtr = 0x0;
6103 int ret = -1;
6104 EDMA3_RM_Result result = EDMA3_RM_SOK;
6106 assert (start <= end);
6108 /**
6109 * job is to find 'bit' in an array[start_index:end_index]
6110 * algo used:
6111 * first search in array[start_index]
6112 * then search in array[start_index + 1 : end_index - 1]
6113 * then search in array[end_index]
6114 */
6115 switch (resType)
6116 {
6117 case EDMA3_RM_RES_DMA_CHANNEL:
6118 resPtr = &contiguousDmaRes[0];
6119 break;
6121 case EDMA3_RM_RES_QDMA_CHANNEL:
6122 resPtr = &contiguousQdmaRes[0];
6123 break;
6125 case EDMA3_RM_RES_TCC:
6126 resPtr = &contiguousTccRes[0];
6127 break;
6129 case EDMA3_RM_RES_PARAM_SET:
6130 resPtr = &contiguousParamRes[0];
6131 break;
6133 default:
6134 result = EDMA3_RM_E_INVALID_PARAM;
6135 break;
6136 }
6138 if (EDMA3_RM_SOK == result)
6139 {
6140 switch (bit)
6141 {
6142 case 1:
6143 {
6144 /* Find '1' in first word. */
6145 position = findBitInWord (resPtr[start_index], start, 1u);
6147 if (position != -1)
6148 {
6149 ret = position;
6150 }
6151 else
6152 {
6153 /* '1' NOT found, look into other words. */
6154 for (i = (int)(start_index + 1u); i <= (int)(end_index - 1u); i++)
6155 {
6156 position = findBitInWord (resPtr[i], 0u, 1u);
6157 if (position != -1)
6158 {
6159 /* '1' Found... */
6160 ret = (position + (i*32));
6161 break;
6162 }
6163 }
6165 /* First check whether we have found '1' or not. */
6166 if (ret == -1)
6167 {
6168 /* Still not found, look in the last word. */
6169 position = findBitInWord(resPtr[end_index], 0u, 1u);
6170 if (position != -1)
6171 {
6172 /* Finally got it. */
6173 ret = (position + (end_index*32u));
6174 }
6175 else
6176 {
6177 /* Sorry, could not find it, return -1. */
6178 ret = -1;
6179 }
6180 }
6181 }
6182 }
6183 break;
6185 case 0:
6186 {
6187 /* Find '0' in first word. */
6188 position = findBitInWord(resPtr[start_index], start, 0u);
6189 if (position != -1)
6190 {
6191 ret = position;
6192 }
6193 else
6194 {
6195 /* '0' NOT found, look into other words. */
6196 for (i = (start_index + 1u); i <= (end_index - 1u); i++)
6197 {
6198 position = findBitInWord(resPtr[i], 0u, 0u);
6199 if (position != -1)
6200 {
6201 /* '0' found... */
6202 ret = (position + (i*32));
6203 break;
6204 }
6205 }
6207 /* First check whether we have found '0' or not. */
6208 if (ret == -1)
6209 {
6210 position = findBitInWord(resPtr[end_index], 0u, 0u);
6211 if (position != -1)
6212 {
6213 /* Finally got it. */
6214 ret = (position + (end_index*32u));
6215 }
6216 else
6217 {
6218 /* Sorry, could not find it, return -1. */
6219 ret = -1;
6220 }
6221 }
6222 }
6223 }
6224 break;
6226 default:
6227 break;
6228 }
6229 }
6233 return ((ret >= start) ? ret : -1);
6234 }
6238 /**
6239 * If successful, this function returns EDMA3_RM_SOK and the position
6240 * of first available resource in 'positionRes'. Else returns error.
6241 */
6242 static EDMA3_RM_Result allocAnyContigRes(EDMA3_RM_ResType resType,
6243 unsigned int numResources,
6244 unsigned int *positionRes)
6245 {
6246 unsigned short found = 0u;
6247 int first_one, next_zero;
6248 unsigned int num_available;
6249 int ret = -1;
6250 unsigned int start = 0;
6251 unsigned int end;
6252 EDMA3_RM_Result result = EDMA3_RM_SOK;
6254 assert (positionRes != NULL);
6256 switch (resType)
6257 {
6258 case EDMA3_RM_RES_DMA_CHANNEL:
6259 end = EDMA3_MAX_DMA_CH - 1u;
6260 break;
6262 case EDMA3_RM_RES_QDMA_CHANNEL:
6263 end = EDMA3_MAX_QDMA_CH - 1u;
6264 break;
6266 case EDMA3_RM_RES_TCC:
6267 end = EDMA3_MAX_TCC - 1u;
6268 break;
6270 case EDMA3_RM_RES_PARAM_SET:
6271 end = edma3NumPaRAMSets - 1u;
6272 break;
6274 default:
6275 result = EDMA3_RM_E_INVALID_PARAM;
6276 break;
6277 }
6279 if (result == EDMA3_RM_SOK)
6280 {
6281 /**
6282 * Algorithm used for finding N contiguous resources.
6283 * In the resources' array, '1' means available and '0' means
6284 * not-available.
6285 * Step a) Find first '1' starting from 'start'. If successful,
6286 * store it in first_one, else return error.
6287 * Step b) Find first '0' starting from (first_one+1) to 'end'.
6288 * If successful, store returned value in next_zero. If '0' could
6289 * not be located, it means all the resources are available.
6290 * Store 'end' (i.e. the last resource id) in next_zero.
6291 * Step c) Count the number of contiguous resources available
6292 * by subtracting first_one from next_zero.
6293 * Step d) If result < N, do the whole process again untill you
6294 * reach end. Else you have found enough resources, return success.
6295 */
6296 while((found == 0) && (((end-start)+1u) >= numResources))
6297 {
6298 /* Find first '1' starting from 'start' till 'end'. */
6299 first_one = findBit (resType, start, end, 1u);
6300 if (first_one != -1)
6301 {
6302 /* Got first 1, search for first '0' now. */
6303 next_zero = findBit (resType, first_one+1, end, 0u);
6304 if (next_zero == -1)
6305 {
6306 /* Unable to find next zero, all 1' are there */
6307 next_zero = end + 1u;
6308 }
6310 /* check no of resources available */
6311 num_available = next_zero - first_one;
6312 if (num_available >= numResources)
6313 {
6314 /* hurrah..., we have found enough resources. */
6315 found = 1u;
6316 ret = first_one;
6317 }
6318 else
6319 {
6320 /* Not enough resources, try again */
6321 start = next_zero + 1;
6322 }
6323 }
6324 else
6325 {
6326 /* do nothing, first 1 is not there, return. */
6327 break;
6328 }
6329 }
6330 }
6333 if (result == EDMA3_RM_SOK)
6334 {
6335 if (found == 1u)
6336 {
6337 /* required resources found, retrun the first available res id. */
6338 *positionRes = (unsigned int)ret;
6339 }
6340 else
6341 {
6342 /* No resources allocated */
6343 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
6344 }
6345 }
6347 return result;
6348 }
6352 /**
6353 * Starting from 'firstResIdObj', this function makes the next 'numResources'
6354 * Resources non-available for future. Also, it does some global resisters'
6355 * setting also.
6356 */
6357 static EDMA3_RM_Result gblChngAllocContigRes(EDMA3_RM_Instance *rmInstance,
6358 const EDMA3_RM_ResDesc *firstResIdObj,
6359 unsigned int numResources)
6360 {
6361 EDMA3_RM_Result result = EDMA3_RM_SOK;
6362 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
6363 EDMA3_RM_Obj *rmObj = NULL;
6364 unsigned int avlblIdx = 0u;
6365 unsigned int firstResId=0u;
6366 unsigned int lastResId=0u;
6367 unsigned int edma3Id;
6369 assert ((rmInstance != NULL) && (firstResIdObj != NULL));
6371 rmObj = rmInstance->pResMgrObjHandle;
6373 if (rmObj == NULL)
6374 {
6375 result = EDMA3_RM_E_INVALID_PARAM;
6376 }
6378 if (EDMA3_RM_SOK == result)
6379 {
6380 edma3Id = rmObj->phyCtrllerInstId;
6381 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
6383 if (gblRegs == NULL)
6384 {
6385 result = EDMA3_RM_E_INVALID_PARAM;
6386 }
6387 }
6389 if (result == EDMA3_RM_SOK)
6390 {
6391 switch (firstResIdObj->type)
6392 {
6393 case EDMA3_RM_RES_DMA_CHANNEL:
6394 {
6395 firstResId = firstResIdObj->resId;
6396 lastResId = firstResId + (numResources - 1u);
6398 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6399 {
6400 rmInstance->avlblDmaChannels[avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
6402 /**
6403 * Enable the DMA channel in the DRAE/DRAEH registers also.
6404 */
6405 if (avlblIdx < 32u)
6406 {
6407 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
6408 |= (0x1u << avlblIdx);
6409 }
6410 else
6411 {
6412 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
6413 |= (0x1u << (avlblIdx - 32u));
6414 }
6415 }
6416 }
6417 break;
6419 case EDMA3_RM_RES_QDMA_CHANNEL:
6420 {
6421 firstResId = firstResIdObj->resId;
6422 lastResId = firstResId + (numResources - 1u);
6424 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6425 {
6426 rmInstance->avlblQdmaChannels[avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
6428 /**
6429 * Enable the QDMA channel in the QRAE register also.
6430 */
6431 gblRegs->QRAE[rmInstance->initParam.regionId]
6432 |= (0x1u << avlblIdx);
6433 }
6434 }
6435 break;
6437 case EDMA3_RM_RES_TCC:
6438 {
6439 firstResId = firstResIdObj->resId;
6440 lastResId = firstResId + (numResources - 1u);
6442 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6443 {
6444 rmInstance->avlblTccs[avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
6446 /**
6447 * If the region id coming from this
6448 * RM instance is same as the Master RM
6449 * Instance's region id, only then we will be
6450 * getting the interrupts on the same side.
6451 * So save the TCC in the allocatedTCCs[] array.
6452 */
6453 if (edma3RegionId == rmInstance->initParam.regionId)
6454 {
6455 if (avlblIdx < 32u)
6456 {
6457 allocatedTCCs[edma3Id][0u] |= (0x1u << avlblIdx);
6458 }
6459 else
6460 {
6461 allocatedTCCs[edma3Id][1u] |= (0x1u << (avlblIdx - 32u));
6462 }
6463 }
6464 }
6465 }
6466 break;
6468 case EDMA3_RM_RES_PARAM_SET:
6469 {
6470 firstResId = firstResIdObj->resId;
6471 lastResId = firstResId + (numResources - 1u);
6473 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6474 {
6475 rmInstance->avlblPaRAMSets [avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
6477 /**
6478 * Also, make the actual PARAM Set NULL, checking the flag
6479 * whether it is required or not.
6480 */
6481 if (TRUE == rmInstance->paramInitRequired)
6482 {
6483 edma3MemZero((void *)(&gblRegs->PARAMENTRY[avlblIdx]),
6484 sizeof(gblRegs->PARAMENTRY[avlblIdx]));
6485 }
6486 }
6487 }
6488 break;
6490 default:
6491 result = EDMA3_RM_E_INVALID_PARAM;
6492 break;
6493 }
6494 }
6497 return result;
6498 }
6500 /* Resource Manager Internal functions - End */
6502 /* End of File */