1 /*
2 * edma3resmgr.c
3 *
4 * EDMA3 Controller Resource Manager Interface Implementation
5 *
6 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
7 *
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the
19 * distribution.
20 *
21 * Neither the name of Texas Instruments Incorporated nor the names of
22 * its contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 */
39 /* Resource Manager Internal Header Files */
40 #include <ti/sdo/edma3/rm/src/edma3resmgr.h>
42 /* Instrumentation Header File */
43 #ifdef EDMA3_INSTRUMENTATION_ENABLED
44 #include <ti/sdo/edma3/rm/src/edma3_log.h>
45 #endif
47 /* For assert() */
48 /**
49 * Define NDEBUG to ignore assert().
50 * NDEBUG should be defined before including assert.h header file.
51 */
52 #include <assert.h>
55 /* Global Defines, need to re-compile if values are changed */
56 /*---------------------------------------------------------------------------*/
57 /**
58 * \brief EDMA3 Resource Manager behaviour of clearing CC ERROR interrupts.
59 * This macro controls the driver to enable/disable clearing of error
60 * status of all channels.
61 *
62 * On disabling this (with value 0x0), the channels owned by the region
63 * is cleared and its expected that some other entity is responsible for
64 * clearing the error status for channels not owned.
65 *
66 * Its recomended that this flag is a positive value, to ensure that
67 * error flags are cleared for all the channels.
68 */
69 #define EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS (TRUE)
71 /**
72 * \brief EDMA3 Resource Manager retry count to check the pending interrupts inside ISR.
73 * This macro controls the driver to check the pending interrupt for
74 * 'n' number of times.
75 * Minumum value is 1.
76 */
77 #define EDMA3_RM_COMPL_HANDLER_RETRY_COUNT (10u)
79 /**
80 * \brief EDMA3 Resource Manager retry count to check the pending CC Error Interrupt inside ISR
81 * This macro controls the driver to check the pending CC Error
82 * interrupt for 'n' number of times.
83 * Minumum value is 1.
84 */
85 #define EDMA3_RM_CCERR_HANDLER_RETRY_COUNT (10u)
89 /* Externel Variables */
90 /*---------------------------------------------------------------------------*/
91 /**
92 * Maximum Resource Manager Instances supported by the EDMA3 Package.
93 */
94 extern const unsigned int EDMA3_MAX_RM_INSTANCES;
97 #ifndef GENERIC
98 /**
99 * \brief Static Configuration structure for EDMA3
100 * controller, to provide Global SoC specific Information.
101 *
102 * This configuration info can also be provided by the user at run-time,
103 * while calling EDMA3_RM_create (). If not provided at run-time,
104 * this info will be taken from the config file "edma3_<PLATFORM_NAME>_cfg.c",
105 * for the specified platform.
106 */
107 extern EDMA3_RM_GblConfigParams edma3GblCfgParams [EDMA3_MAX_EDMA3_INSTANCES];
109 /**
110 * \brief Default Static Region Specific Configuration structure for
111 * EDMA3 controller, to provide region specific Information.
112 */
113 extern EDMA3_RM_InstanceInitConfig defInstInitConfig [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_REGIONS];
115 #endif
118 /**
119 * \brief Region Specific Configuration structure for
120 * EDMA3 controller, to provide region specific Information.
121 *
122 * This configuration info can also be provided by the user at run-time,
123 * while calling EDMA3_RM_open (). If not provided at run-time,
124 * this info will be taken from the config file "edma3_<PLATFORM_NAME>_cfg.c",
125 * for the specified platform.
126 */
127 extern EDMA3_RM_InstanceInitConfig *userInitConfig;
128 extern EDMA3_RM_InstanceInitConfig *ptrInitCfgArray;
131 /**
132 * Handles of EDMA3 Resource Manager Instances.
133 *
134 * Used to maintain information of the EDMA3 RM Instances
135 * for each HW controller.
136 * There could be a maximum of EDMA3_MAX_RM_INSTANCES instances per
137 * EDMA3 HW.
138 */
139 extern EDMA3_RM_Instance *resMgrInstance;
140 extern EDMA3_RM_Instance *ptrRMIArray;
142 /** Max of DMA Channels */
143 unsigned int edma3_dma_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
144 /** Min of Link Channels */
145 unsigned int edma3_link_ch_min_val[EDMA3_MAX_EDMA3_INSTANCES];
146 /** Max of Link Channels */
147 unsigned int edma3_link_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
148 /** Min of QDMA Channels */
149 unsigned int edma3_qdma_ch_min_val[EDMA3_MAX_EDMA3_INSTANCES];
150 /** Max of QDMA Channels */
151 unsigned int edma3_qdma_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
152 /** Max of Logical Channels */
153 unsigned int edma3_log_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
155 /* Globals */
156 /*---------------------------------------------------------------------------*/
157 /**
158 * \brief EDMA3 Resource Manager Objects, tied to each EDMA3 HW Controller.
159 *
160 * Typically one RM object will cater to one EDMA3 HW controller
161 * and will have all the global config information.
162 */
163 EDMA3_RM_Obj resMgrObj[EDMA3_MAX_EDMA3_INSTANCES];
166 /**
167 * Global Array to store the mapping between DMA channels and Interrupt
168 * channels i.e. TCCs.
169 * DMA channel X can use any TCC Y. Transfer completion
170 * interrupt will occur on the TCC Y (IPR/IPRH Register, bit Y), but error
171 * interrupt will occur on DMA channel X (EMR/EMRH register, bit X). In that
172 * scenario, this DMA channel <-> TCC mapping will be used to point to
173 * the correct callback function.
174 */
175 static unsigned int edma3DmaChTccMapping [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_DMA_CH];
178 /**
179 * Global Array to store the mapping between QDMA channels and Interrupt
180 * channels i.e. TCCs.
181 * QDMA channel X can use any TCC Y. Transfer completion
182 * interrupt will occur on the TCC Y (IPR/IPRH Register, bit Y), but error
183 * interrupt will occur on QDMA channel X (QEMR register, bit X). In that
184 * scenario, this QDMA channel <-> TCC mapping will be used to point to
185 * the correct callback function.
186 */
187 static unsigned int edma3QdmaChTccMapping [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_QDMA_CH];
190 /**
191 * Global Array to maintain the Callback details registered
192 * against a particular TCC. Used to call the callback
193 * functions linked to the particular channel.
194 */
195 static EDMA3_RM_TccCallbackParams edma3IntrParams [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_TCC];
198 /** edma3RegionId will be updated ONCE using the parameter regionId passed to
199 * the EDMA3_RM_open() function, for the Master RM instance (one who
200 * configures the Global Registers).
201 * This global variable will be used within the Interrupt handlers to know
202 * which shadow region registers to access. All other interrupts coming
203 * from other shadow regions will not be handled.
204 */
205 static EDMA3_RM_RegionId edma3RegionId = EDMA3_MAX_REGIONS;
207 /** masterExists[] will be updated when the Master RM Instance modifies the
208 * Global EDMA3 configuration registers. It is used to prevent any other
209 * Master RM Instance creation.
210 * masterExists[] is per EDMA3 hardware, hence it is created
211 * as an array.
212 */
213 static unsigned int masterExists [EDMA3_MAX_EDMA3_INSTANCES] = {FALSE,FALSE,FALSE};
215 /**
216 * Number of PaRAM Sets actually present on the SoC. This will be updated
217 * while creating the Resource Manager Object.
218 */
219 unsigned int edma3NumPaRAMSets = EDMA3_MAX_PARAM_SETS;
222 /**
223 * The list of Interrupt Channels which get allocated while requesting the
224 * TCC. It will be used while checking the IPR/IPRH bits in the RM ISR.
225 */
226 static unsigned int allocatedTCCs[EDMA3_MAX_EDMA3_INSTANCES][2u] =
227 {
228 {0x0u, 0x0u},
229 {0x0u, 0x0u},
230 {0x0u, 0x0u},
231 };
234 /**
235 * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
236 * and stored in this array. It will be referenced in
237 * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
238 */
239 static unsigned int contiguousDmaRes[EDMA3_MAX_DMA_CHAN_DWRDS] = {0x0u, 0x0u};
241 /**
242 * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
243 * and stored in this array. It will be referenced in
244 * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
245 */
246 static unsigned int contiguousQdmaRes[EDMA3_MAX_QDMA_CHAN_DWRDS] = {0x0u};
248 /**
249 * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
250 * and stored in this array. It will be referenced in
251 * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
252 */
253 static unsigned int contiguousTccRes[EDMA3_MAX_TCC_DWRDS] = {0x0u, 0x0u};
255 /**
256 * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
257 * and stored in this array. It will be referenced in
258 * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
259 */
260 static unsigned int contiguousParamRes[EDMA3_MAX_PARAM_DWRDS];
263 /**
264 * \brief Resources bound to a Channel
265 *
266 * When a request for a channel is made, the resources PaRAM Set and TCC
267 * get bound to that channel. This information is needed internally by the
268 * resource manager, when a request is made to free the channel,
269 * to free up the channel-associated resources.
270 */
271 static EDMA3_RM_ChBoundResources edma3RmChBoundRes [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_LOGICAL_CH];
275 /*---------------------------------------------------------------------------*/
277 /* Local functions prototypes */
278 /*---------------------------------------------------------------------------*/
279 /** EDMA3 Instance 0 Completion Handler Interrupt Service Routine */
280 void lisrEdma3ComplHandler0(unsigned int arg);
281 /** EDMA3 Instance 0 CC Error Interrupt Service Routine */
282 void lisrEdma3CCErrHandler0(unsigned int arg);
283 /**
284 * EDMA3 Instance 0 TC[0-7] Error Interrupt Service Routines
285 * for a maximum of 8 TCs (Transfer Controllers).
286 */
287 void lisrEdma3TC0ErrHandler0(unsigned int arg);
288 void lisrEdma3TC1ErrHandler0(unsigned int arg);
289 void lisrEdma3TC2ErrHandler0(unsigned int arg);
290 void lisrEdma3TC3ErrHandler0(unsigned int arg);
291 void lisrEdma3TC4ErrHandler0(unsigned int arg);
292 void lisrEdma3TC5ErrHandler0(unsigned int arg);
293 void lisrEdma3TC6ErrHandler0(unsigned int arg);
294 void lisrEdma3TC7ErrHandler0(unsigned int arg);
297 /** Interrupt Handler for the Transfer Completion interrupt */
298 static void edma3ComplHandler (const EDMA3_RM_Obj *rmObj);
299 /** Interrupt Handler for the Channel Controller Error interrupt */
300 static void edma3CCErrHandler (const EDMA3_RM_Obj *rmObj);
301 /** Interrupt Handler for the Transfer Controller Error interrupt */
302 static void edma3TCErrHandler (const EDMA3_RM_Obj *rmObj, unsigned int tcNum);
305 /** Local MemZero function */
306 void edma3MemZero(void *dst, unsigned int len);
307 /** Local MemCpy function */
308 void edma3MemCpy(void *dst, const void *src, unsigned int len);
309 /* Local MemCopy function to copy Param Set ONLY */
310 void edma3ParamCpy(void *dst, const void *src);
312 /** Initialization of the Global region registers of the EDMA3 Controller */
313 static void edma3GlobalRegionInit (unsigned int phyCtrllerInstId);
314 /** Initialization of the Shadow region registers of the EDMA3 Controller */
315 static void edma3ShadowRegionInit (const EDMA3_RM_Instance *pRMInstance);
319 /* Internal functions for contiguous resource allocation */
320 /**
321 * Finds a particular bit ('0' or '1') in the particular word from 'start'.
322 * If found, returns the position, else return -1.
323 */
324 static int findBitInWord (int source, unsigned int start, unsigned short bit);
326 /**
327 * Finds a particular bit ('0' or '1') in the specified resources' array
328 * from 'start' to 'end'. If found, returns the position, else return -1.
329 */
330 static int findBit (EDMA3_RM_ResType resType,
331 unsigned int start,
332 unsigned int end,
333 unsigned short bit);
335 /**
336 * If successful, this function returns EDMA3_RM_SOK and the position
337 * of first available resource in 'positionRes'. Else returns error.
338 */
339 static EDMA3_RM_Result allocAnyContigRes(EDMA3_RM_ResType resType,
340 unsigned int numResources,
341 unsigned int *positionRes);
343 /**
344 * Starting from 'firstResIdObj', this function makes the next 'numResources'
345 * Resources non-available for future. Also, it does some global resisters'
346 * setting also.
347 */
348 static EDMA3_RM_Result gblChngAllocContigRes(EDMA3_RM_Instance *rmInstance,
349 const EDMA3_RM_ResDesc *firstResIdObj,
350 unsigned int numResources);
352 /*---------------------------------------------------------------------------*/
354 EDMA3_RM_Result EDMA3_RM_create (unsigned int phyCtrllerInstId,
355 const EDMA3_RM_GblConfigParams *gblCfgParams,
356 const void *miscParam)
357 {
358 unsigned int count = 0u;
359 EDMA3_RM_Result result = EDMA3_RM_SOK;
360 /**
361 * Used to reset the Internal EDMA3 Resource Manager Data Structures for the first time.
362 */
363 static unsigned short rmInitDone = FALSE;
364 const EDMA3_RM_MiscParam *miscOpt = (const EDMA3_RM_MiscParam *)miscParam;
366 #ifdef GENERIC
367 /* GENERIC libraries don't come with a default confifguration, always
368 needs to be supplied with a parameter */
369 if (gblCfgParams == NULL)
370 {
371 result = EDMA3_RM_E_INVALID_PARAM;
372 }
373 #endif
375 /**
376 * We are NOT checking 'gblCfgParams' for NULL.
377 * If user has passed NULL, default config info will be
378 * taken from config file.
379 * 'param' is also not being checked because it could be
380 * NULL also.
381 */
383 /* If parameter checking is enabled... */
384 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
385 if (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
386 {
387 result = EDMA3_RM_E_INVALID_PARAM;
388 }
389 #endif
391 /* Check if the parameters are OK. */
392 if (EDMA3_RM_SOK == result)
393 {
394 /* Initialize the global variables for the first time */
395 if (FALSE == rmInitDone)
396 {
397 edma3MemZero((void *)&(resMgrObj[count]),
398 sizeof(resMgrObj));
399 edma3MemZero((void *)(&(edma3IntrParams[0u])),
400 sizeof(edma3IntrParams));
402 rmInitDone = TRUE;
403 }
405 /* Initialization has been done */
406 if (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_DELETED)
407 {
408 result = EDMA3_RM_E_OBJ_NOT_DELETED;
409 }
410 else
411 {
412 /**
413 * Check whether user has passed the Global Config Info.
414 * If yes, copy it to the driver data structures. Else, use the
415 * info from the config file edma3Cfg.c
416 */
417 #ifndef GENERIC
418 if (NULL == gblCfgParams)
419 {
420 /* Take info from the specific config file */
421 edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
422 (const void *)(&edma3GblCfgParams[phyCtrllerInstId]),
423 sizeof (EDMA3_RM_GblConfigParams));
424 }
425 else
426 {
427 #endif
428 /* User passed the info, save it in the RM object first */
429 edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
430 (const void *)(gblCfgParams),
431 sizeof (EDMA3_RM_GblConfigParams));
432 #ifndef GENERIC
433 }
434 #endif
437 /**
438 * Check whether DMA channel to PaRAM Set mapping exists or not.
439 * If it does not exist, set the mapping array as 1-to-1 mapped.
440 */
441 if (FALSE == resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChPaRAMMapExists)
442 {
443 for (count = 0u; count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels; count++)
444 {
445 resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChannelPaRAMMap[count] = count;
446 }
447 }
450 /**
451 * Update the actual number of PaRAM sets and
452 * Initialize Boundary Values for Logical Channel Ranges.
453 */
454 edma3NumPaRAMSets = resMgrObj[phyCtrllerInstId].gblCfgParams.numPaRAMSets;
455 edma3_dma_ch_max_val[phyCtrllerInstId] = resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels - 1u;
456 edma3_link_ch_min_val[phyCtrllerInstId] = edma3_dma_ch_max_val[phyCtrllerInstId] + 1u;
457 edma3_link_ch_max_val[phyCtrllerInstId] = edma3_link_ch_min_val[phyCtrllerInstId] + resMgrObj[phyCtrllerInstId].gblCfgParams.numPaRAMSets - 1u;
458 edma3_qdma_ch_min_val[phyCtrllerInstId] = edma3_link_ch_max_val[phyCtrllerInstId] + 1u;
459 edma3_qdma_ch_max_val[phyCtrllerInstId] = edma3_qdma_ch_min_val[phyCtrllerInstId] + resMgrObj[phyCtrllerInstId].gblCfgParams.numQdmaChannels - 1u;
460 edma3_log_ch_max_val[phyCtrllerInstId] = edma3_qdma_ch_max_val[phyCtrllerInstId];
462 resMgrObj[phyCtrllerInstId].phyCtrllerInstId = phyCtrllerInstId;
463 resMgrObj[phyCtrllerInstId].state = EDMA3_RM_CREATED;
464 resMgrObj[phyCtrllerInstId].numOpens = 0u;
466 /* Make all the RM instances for this EDMA3 HW NULL */
467 for (count = 0u; count < EDMA3_MAX_RM_INSTANCES; count++)
468 {
469 edma3MemZero((void *)((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
470 sizeof(EDMA3_RM_Instance));
472 /* Also make this data structure NULL */
473 edma3MemZero((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
474 sizeof(EDMA3_RM_InstanceInitConfig));
475 }
477 /* Initialize the global edma3DmaChTccMapping array with EDMA3_MAX_TCC */
478 for ( count = 0u;
479 count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels;
480 count++
481 )
482 {
483 edma3DmaChTccMapping[phyCtrllerInstId][count] = EDMA3_MAX_TCC;
484 }
486 /* Initialize the global edma3QdmaChTccMapping array with EDMA3_MAX_TCC */
487 for ( count = 0u;
488 count < resMgrObj[phyCtrllerInstId].gblCfgParams.numQdmaChannels;
489 count++
490 )
491 {
492 edma3QdmaChTccMapping[phyCtrllerInstId][count] = EDMA3_MAX_TCC;
493 }
495 /* Reset edma3RmChBoundRes Array*/
496 for (count = 0u; count < EDMA3_MAX_LOGICAL_CH; count++)
497 {
498 edma3RmChBoundRes[phyCtrllerInstId][count].paRAMId = -1;
499 edma3RmChBoundRes[phyCtrllerInstId][count].tcc = EDMA3_MAX_TCC;
500 }
502 /* Make the contiguousParamRes array NULL */
503 edma3MemZero((void *)(&(contiguousParamRes[0u])),
504 sizeof(contiguousParamRes));
507 /**
508 * Check the misc configuration options structure.
509 * Check whether the global registers' initialization
510 * is required or not.
511 * It is required ONLY if RM is running on the Master Processor.
512 */
513 if (NULL != miscOpt)
514 {
515 if (miscOpt->isSlave == FALSE)
516 {
517 /* It is a master. */
518 edma3GlobalRegionInit(phyCtrllerInstId);
519 }
520 }
521 else
522 {
523 /* By default, global registers will be initialized. */
524 edma3GlobalRegionInit(phyCtrllerInstId);
525 }
526 }
527 }
529 return result;
530 }
532 EDMA3_RM_Result EDMA3_RM_delete (unsigned int phyCtrllerInstId,
533 const void *param)
534 {
535 EDMA3_RM_Result result = EDMA3_RM_SOK;
537 /* If parameter checking is enabled... */
538 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
539 if (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
540 {
541 result = EDMA3_RM_E_INVALID_PARAM;
542 }
543 #endif
545 /* Check if the parameters are OK. */
546 if (EDMA3_RM_SOK == result)
547 {
548 /*to remove CCS remark: parameter "param" was never referenced */
549 (void)param;
551 /**
552 * If number of RM Instances is 0, then state should be
553 * EDMA3_RM_CLOSED OR EDMA3_RM_CREATED.
554 */
555 if ((NULL == resMgrObj[phyCtrllerInstId].numOpens)
556 && ((resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CLOSED)
557 && (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CREATED)))
558 {
559 result = EDMA3_RM_E_OBJ_NOT_CLOSED;
560 }
561 else
562 {
563 /**
564 * If number of RM Instances is NOT 0, then this function
565 * SHOULD NOT be called by anybody.
566 */
567 if (NULL != resMgrObj[phyCtrllerInstId].numOpens)
568 {
569 result = EDMA3_RM_E_INVALID_STATE;
570 }
571 else
572 {
573 /** Change state to EDMA3_RM_DELETED */
574 resMgrObj[phyCtrllerInstId].state = EDMA3_RM_DELETED;
576 /* Reset the Allocated TCCs Array also. */
577 allocatedTCCs[phyCtrllerInstId][0u] = 0x0u;
578 allocatedTCCs[phyCtrllerInstId][1u] = 0x0u;
580 /* Also, reset the RM Object Global Config Info */
581 edma3MemZero((void *)&(resMgrObj[phyCtrllerInstId].gblCfgParams),
582 sizeof(EDMA3_RM_GblConfigParams));
583 }
584 }
585 }
587 return result;
588 }
590 EDMA3_RM_Handle EDMA3_RM_open (unsigned int phyCtrllerInstId,
591 const EDMA3_RM_Param *initParam,
592 EDMA3_RM_Result *errorCode)
593 {
594 unsigned int intState = 0u;
595 unsigned int resMgrIdx = 0u;
596 EDMA3_RM_Result result = EDMA3_RM_SOK;
597 EDMA3_RM_Obj *rmObj = NULL;
598 EDMA3_RM_Instance *rmInstance = NULL;
599 EDMA3_RM_Instance *temp_ptr_rm_inst = NULL;
600 EDMA3_RM_Handle retVal = NULL;
601 unsigned int dmaChDwrds = 0u;
602 unsigned int paramSetDwrds = 0u;
603 unsigned int tccDwrds = 0u;
604 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
606 #ifdef GENERIC
607 /* GENERIC libraries don't come with a default confifguration, always
608 needs to be supplied with a parameter */
609 if ((initParam == NULL) || (initParam->rmInstInitConfig == NULL))
610 {
611 result = EDMA3_RM_E_INVALID_PARAM;
612 }
613 #endif
616 /* If parameter checking is enabled... */
617 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
618 if (((initParam == NULL)
619 || (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES))
620 || (errorCode == NULL))
621 {
622 result = EDMA3_RM_E_INVALID_PARAM;
623 }
624 #endif
626 /* Check if the parameters are OK. */
627 if (EDMA3_RM_SOK == result)
628 {
629 /* Check whether the semaphore handle is null or not */
630 if (NULL == initParam->rmSemHandle)
631 {
632 result = EDMA3_RM_E_INVALID_PARAM;
633 }
634 else
635 {
636 rmObj = &resMgrObj[phyCtrllerInstId];
637 if (
638 (NULL == rmObj)
639 || (initParam->regionId >=
640 resMgrObj[phyCtrllerInstId].gblCfgParams.numRegions)
641 )
642 {
643 result = EDMA3_RM_E_INVALID_PARAM;
644 }
645 else
646 {
647 edma3OsProtectEntry (phyCtrllerInstId,
648 EDMA3_OS_PROTECT_INTERRUPT,
649 &intState);
651 /** Check state of RM Object.
652 * If no RM instance is opened and this is the first one,
653 * then state should be created/closed.
654 */
655 if ((rmObj->numOpens == NULL) &&
656 ((rmObj->state != EDMA3_RM_CREATED) &&
657 (rmObj->state != EDMA3_RM_CLOSED)))
658 {
659 result = EDMA3_RM_E_INVALID_STATE;
660 edma3OsProtectExit (phyCtrllerInstId,
661 EDMA3_OS_PROTECT_INTERRUPT,
662 intState);
663 }
664 else
665 {
666 /**
667 * If num of instances opened is more than 0 and less than
668 * max allowed, then state should be opened.
669 */
670 if (((rmObj->numOpens > 0) &&
671 (rmObj->numOpens < EDMA3_MAX_RM_INSTANCES))
672 && (rmObj->state != EDMA3_RM_OPENED))
673 {
674 result = EDMA3_RM_E_INVALID_STATE;
675 edma3OsProtectExit (phyCtrllerInstId,
676 EDMA3_OS_PROTECT_INTERRUPT,
677 intState);
678 }
679 else
680 {
681 /* Check if max opens have passed */
682 if (rmObj->numOpens >= EDMA3_MAX_RM_INSTANCES)
683 {
684 result = EDMA3_RM_E_MAX_RM_INST_OPENED;
685 edma3OsProtectExit (phyCtrllerInstId,
686 EDMA3_OS_PROTECT_INTERRUPT,
687 intState);
688 }
689 }
690 }
691 }
692 }
693 }
695 if (EDMA3_RM_SOK == result)
696 {
697 /*
698 * Check whether the RM instance is Master or not.
699 * If it is master, check whether a master already exists
700 * or not. There should NOT be more than 1 master.
701 * Return error code if master already exists
702 */
703 if ((TRUE == masterExists[phyCtrllerInstId]) && (TRUE == initParam->isMaster))
704 {
705 /* No two masters should exist, return error */
706 result = EDMA3_RM_E_RM_MASTER_ALREADY_EXISTS;
707 edma3OsProtectExit (phyCtrllerInstId,
708 EDMA3_OS_PROTECT_INTERRUPT,
709 intState);
710 }
711 else
712 {
713 /* Create Res Mgr Instance */
714 for (resMgrIdx = 0u; resMgrIdx < EDMA3_MAX_RM_INSTANCES; resMgrIdx++)
715 {
716 temp_ptr_rm_inst = ((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
718 if (NULL != temp_ptr_rm_inst)
719 {
720 if (NULL == temp_ptr_rm_inst->pResMgrObjHandle)
721 {
722 /* Handle to the EDMA3 HW Object */
723 temp_ptr_rm_inst->pResMgrObjHandle = rmObj;
724 /* Handle of the Res Mgr Instance */
725 rmInstance = temp_ptr_rm_inst;
727 /* Also make this data structure NULL, just for safety. */
728 edma3MemZero((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
729 sizeof(EDMA3_RM_InstanceInitConfig));
731 break;
732 }
733 }
734 }
736 /* Check whether a RM instance has been created or not */
737 if (NULL == rmInstance)
738 {
739 result = EDMA3_RM_E_MAX_RM_INST_OPENED;
740 edma3OsProtectExit (phyCtrllerInstId,
741 EDMA3_OS_PROTECT_INTERRUPT,
742 intState);
743 }
744 else
745 {
746 /* Copy the InitPaRAM first */
747 edma3MemCpy((void *)(&rmInstance->initParam),
748 (const void *)(initParam),
749 sizeof (EDMA3_RM_Param));
751 if (rmObj->gblCfgParams.globalRegs != NULL)
752 {
753 globalRegs = (volatile EDMA3_CCRL_Regs *)
754 (rmObj->gblCfgParams.globalRegs);
755 rmInstance->shadowRegs = (EDMA3_CCRL_ShadowRegs *)
756 &(globalRegs->SHADOW[rmInstance->initParam.regionId]);
758 /* copy the instance specific semaphore handle */
759 rmInstance->initParam.rmSemHandle = initParam->rmSemHandle;
761 /**
762 * Check whether user has passed information about resources
763 * owned and reserved by this instance. This is region specific
764 * information. If he has not passed, dafault static config info will be taken
765 * from the config file edma3Cfg.c, according to the regionId specified.
766 *
767 * resMgrIdx specifies the RM instance number created just now.
768 * Use it to populate the userInitConfig [].
769 */
770 #ifndef GENERIC
771 if (NULL == initParam->rmInstInitConfig)
772 {
773 /* Take the info from the specific config file */
774 edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
775 (const void *)(&defInstInitConfig[phyCtrllerInstId][initParam->regionId]),
776 sizeof (EDMA3_RM_InstanceInitConfig));
777 }
778 else
779 {
780 #endif
781 /* User has passed the region specific info. */
782 edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
783 (const void *)(initParam->rmInstInitConfig),
784 sizeof (EDMA3_RM_InstanceInitConfig));
785 #ifndef GENERIC
786 }
787 #endif
789 rmInstance->initParam.rmInstInitConfig =
790 ((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
792 dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / 32u;
793 if (dmaChDwrds == 0)
794 {
795 /* In case DMA channels are < 32 */
796 dmaChDwrds = 1;
797 }
799 paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / 32u;
800 if (paramSetDwrds == 0)
801 {
802 /* In case PaRAM Sets are < 32 */
803 paramSetDwrds = 1;
804 }
806 tccDwrds = rmObj->gblCfgParams.numTccs / 32u;
807 if (tccDwrds == 0)
808 {
809 /* In case TCCs are < 32 */
810 tccDwrds = 1;
811 }
813 for (resMgrIdx = 0u; resMgrIdx < dmaChDwrds; ++resMgrIdx)
814 {
815 rmInstance->avlblDmaChannels[resMgrIdx]
816 = rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resMgrIdx];
817 }
819 rmInstance->avlblQdmaChannels[0u]
820 = rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u];
822 for (resMgrIdx = 0u; resMgrIdx < paramSetDwrds; ++resMgrIdx)
823 {
824 rmInstance->avlblPaRAMSets[resMgrIdx]
825 = rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[resMgrIdx];
826 }
828 for (resMgrIdx = 0u; resMgrIdx < tccDwrds; ++resMgrIdx)
829 {
830 rmInstance->avlblTccs [resMgrIdx]
831 = rmInstance->initParam.rmInstInitConfig->ownTccs[resMgrIdx];
832 }
834 /*
835 * Mark the PaRAM Sets corresponding to DMA channels as RESERVED.
836 * For e.g. on a platform where only 32 DMA channels exist,
837 * mark the first 32 PaRAM Sets as reserved. These param sets
838 * will not be returned in case user requests for ANY link
839 * channel.
840 */
841 for (resMgrIdx = 0u; resMgrIdx < rmObj->gblCfgParams.numDmaChannels; ++resMgrIdx)
842 {
843 rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[resMgrIdx/32u] |= (1u<<(resMgrIdx%32u));
844 }
846 /*
847 * If the EDMA RM instance is MASTER (ie. initParam->isMaster
848 * is TRUE), save the region ID.
849 * Only this shadow region will receive the
850 * EDMA3 interrupts, if enabled.
851 */
852 if (TRUE == initParam->isMaster)
853 {
854 /* Store the region id to use it in the ISRs */
855 edma3RegionId = rmInstance->initParam.regionId;
856 masterExists[phyCtrllerInstId] = TRUE;
857 }
859 if (TRUE == initParam->regionInitEnable)
860 {
861 edma3ShadowRegionInit (rmInstance);
862 }
864 /**
865 * By default, PaRAM Sets allocated using this RM Instance
866 * will get cleared during their allocation.
867 * User can stop their clearing by calling specific IOCTL
868 * command.
869 */
870 rmInstance->paramInitRequired = TRUE;
873 /**
874 * By default, during the EDMA3_RM_allocLogicalChannel (),
875 * global EDMA3 registers (DCHMAP/QCHMAP) and the allocated
876 * PaRAM Set will be programmed accordingly, for users using this
877 * RM Instance.
878 * User can stop their pre-programming by calling
879 * EDMA3_RM_IOCTL_SET_GBL_REG_MODIFY_OPTION
880 * IOCTL command.
881 */
882 rmInstance->regModificationRequired = TRUE;
885 if (EDMA3_RM_SOK == result)
886 {
887 rmObj->state = EDMA3_RM_OPENED;
888 /* Increase the Instance count */
889 resMgrObj[phyCtrllerInstId].numOpens++;
890 retVal = rmInstance;
891 }
892 }
893 else
894 {
895 result = EDMA3_RM_E_INVALID_PARAM;
896 }
898 edma3OsProtectExit (phyCtrllerInstId,
899 EDMA3_OS_PROTECT_INTERRUPT,
900 intState);
901 }
902 }
903 }
905 *errorCode = result;
906 return (EDMA3_RM_Handle)retVal;
907 }
909 EDMA3_RM_Result EDMA3_RM_close (EDMA3_RM_Handle hEdmaResMgr,
910 const void *param)
911 {
912 EDMA3_RM_Result result = EDMA3_RM_SOK;
913 unsigned int intState = 0u;
914 unsigned int resMgrIdx = 0u;
915 EDMA3_RM_Obj *rmObj = NULL;
916 EDMA3_RM_Instance *rmInstance = NULL;
917 unsigned int dmaChDwrds;
918 unsigned int paramSetDwrds;
919 unsigned int tccDwrds;
921 /*to remove CCS remark: parameter "param" was never referenced */
922 (void)param;
924 /* If parameter checking is enabled... */
925 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
926 if (NULL == hEdmaResMgr)
927 {
928 result = EDMA3_RM_E_INVALID_PARAM;
929 }
930 #endif
932 /* Check if the parameters are OK. */
933 if (EDMA3_RM_SOK == result)
934 {
935 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
936 rmObj = rmInstance->pResMgrObjHandle;
938 if (rmObj == NULL)
939 {
940 result = (EDMA3_RM_E_INVALID_PARAM);
941 }
942 else
943 {
944 /* Check state of driver, state should be opened */
945 if (rmObj->state != EDMA3_RM_OPENED)
946 {
947 result = (EDMA3_RM_E_OBJ_NOT_OPENED);
948 }
949 else
950 {
951 dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / 32u;
952 paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / 32u;
953 tccDwrds = rmObj->gblCfgParams.numTccs / 32u;
955 /* Set the instance config as NULL*/
956 for (resMgrIdx = 0u; resMgrIdx < dmaChDwrds; ++resMgrIdx)
957 {
958 rmInstance->avlblDmaChannels[resMgrIdx] = 0x0u;
959 }
960 for (resMgrIdx = 0u; resMgrIdx < paramSetDwrds; ++resMgrIdx)
961 {
962 rmInstance->avlblPaRAMSets[resMgrIdx] = 0x0u;
963 }
964 rmInstance->avlblQdmaChannels[0u] = 0x0u;
965 for (resMgrIdx = 0u; resMgrIdx < tccDwrds; ++resMgrIdx)
966 {
967 rmInstance->avlblTccs[resMgrIdx] = 0x0u;
968 }
970 /**
971 * If this is the Master Instance, reset the static variable
972 * 'masterExists[]'.
973 */
974 if (TRUE == rmInstance->initParam.isMaster)
975 {
976 masterExists[rmObj->phyCtrllerInstId] = FALSE;
977 edma3RegionId = EDMA3_MAX_REGIONS;
978 }
980 /* Reset the Initparam for this RM Instance */
981 edma3MemZero((void *)&(rmInstance->initParam),
982 sizeof(EDMA3_RM_Param));
984 /* Critical section starts */
985 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
986 EDMA3_OS_PROTECT_INTERRUPT,
987 &intState);
989 /* Decrease the Number of Opens */
990 --rmObj->numOpens;
991 if (NULL == rmObj->numOpens)
992 {
993 edma3MemZero((void *)&(edma3RmChBoundRes[rmObj->phyCtrllerInstId]),
994 sizeof(edma3RmChBoundRes[rmObj->phyCtrllerInstId]));
996 rmObj->state = EDMA3_RM_CLOSED;
997 }
999 /* Critical section ends */
1000 edma3OsProtectExit (rmObj->phyCtrllerInstId,
1001 EDMA3_OS_PROTECT_INTERRUPT,
1002 intState);
1004 rmInstance->pResMgrObjHandle = NULL;
1005 rmInstance->shadowRegs = NULL;
1006 rmInstance = NULL;
1007 }
1008 }
1009 }
1011 return result;
1012 }
1014 EDMA3_RM_Result EDMA3_RM_allocResource(EDMA3_RM_Handle hEdmaResMgr,
1015 EDMA3_RM_ResDesc *resObj)
1016 {
1017 EDMA3_RM_Instance *rmInstance = NULL;
1018 EDMA3_RM_Obj *rmObj = NULL;
1019 EDMA3_RM_Result result = EDMA3_RM_SOK;
1020 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
1021 unsigned int avlblIdx = 0u;
1022 unsigned int resIdClr = 0x0;
1023 unsigned int resIdSet = 0x0;
1024 unsigned int resId;
1025 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1026 unsigned int mapXbarEvtToChanFlag = FALSE;
1027 unsigned int xBarEvtBeforeMap = 0;
1028 unsigned int edma3Id;
1030 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1031 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1032 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1033 EDMA3_DVT_dCOUNTER,
1034 EDMA3_DVT_dNONE,
1035 EDMA3_DVT_dNONE));
1036 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1038 /* If parameter checking is enabled... */
1039 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1040 if ((hEdmaResMgr == NULL) || (resObj == NULL))
1041 {
1042 result = (EDMA3_RM_E_INVALID_PARAM);
1043 }
1044 #endif
1046 /* Check if the parameters are OK. */
1047 if (EDMA3_RM_SOK == result)
1048 {
1049 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1050 rmObj = rmInstance->pResMgrObjHandle;
1052 if ((rmObj == NULL) ||
1053 (rmObj->gblCfgParams.globalRegs == NULL))
1054 {
1055 result = (EDMA3_RM_E_INVALID_PARAM);
1056 }
1057 else
1058 {
1059 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1060 edma3Id = rmObj->phyCtrllerInstId;
1061 resId = resObj->resId;
1063 resIdClr = (unsigned int)(~(1u << (resId%32u)));
1064 resIdSet = (1u << (resId%32u));
1066 if ( rmInstance->mapXbarToChan != NULL)
1067 {
1068 xBarEvtBeforeMap = resId;
1069 if ((resId > rmObj->gblCfgParams.numDmaChannels) &&
1070 (resId != EDMA3_RM_RES_ANY) &&
1071 (resObj->type == EDMA3_RM_RES_DMA_CHANNEL))
1072 {
1073 result = rmInstance->mapXbarToChan(xBarEvtBeforeMap,
1074 &resObj->resId,
1075 &rmInstance->rmXbarToEvtMapConfig);
1076 if (EDMA3_RM_SOK == result)
1077 {
1078 resId = resObj->resId;
1079 mapXbarEvtToChanFlag = TRUE;
1080 }
1081 }
1082 }
1084 if (result == EDMA3_RM_SOK)
1085 {
1086 /**
1087 * Take the instance specific semaphore, to prevent simultaneous
1088 * access to the shared resources.
1089 */
1090 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
1091 EDMA3_OSSEM_NO_TIMEOUT);
1092 if (EDMA3_RM_SOK == semResult)
1093 {
1094 switch (resObj->type)
1095 {
1096 case EDMA3_RM_RES_DMA_CHANNEL :
1097 {
1098 if (resId == EDMA3_RM_RES_ANY)
1099 {
1100 for (avlblIdx=0u;
1101 avlblIdx <
1102 rmObj->gblCfgParams.numDmaChannels;
1103 ++avlblIdx)
1104 {
1105 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[avlblIdx/32u])
1106 &
1107 (rmInstance->avlblDmaChannels[avlblIdx/32u])
1108 &
1109 ~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[avlblIdx/32u])
1110 &
1111 (1u << (avlblIdx%32u))) != FALSE)
1112 {
1113 /*
1114 * Match found.
1115 * A resource which is owned by this instance of the
1116 * Resource Manager and which is presently available
1117 * and which has not been reserved - is found.
1118 */
1119 resObj->resId = avlblIdx;
1120 /*
1121 * Mark the 'match found' resource as "Not Available"
1122 * for future requests
1123 */
1124 rmInstance->avlblDmaChannels[avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
1126 /**
1127 * Check if the register modification flag is
1128 * set or not.
1129 */
1130 if (TRUE == rmInstance->regModificationRequired)
1131 {
1132 /**
1133 * Enable the DMA channel in the
1134 * DRAE/DRAEH registers also.
1135 */
1136 if (avlblIdx < 32u)
1137 {
1138 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1139 |= (0x1u << avlblIdx);
1140 }
1141 else
1142 {
1143 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1144 |= (0x1u << (avlblIdx - 32u));
1145 }
1146 }
1148 result = EDMA3_RM_SOK;
1149 break;
1150 }
1151 }
1152 /*
1153 * If none of the owned resources of this type is available
1154 * then report "All Resources of this type not available" error
1155 */
1156 if (avlblIdx == rmObj->gblCfgParams.numDmaChannels)
1157 {
1158 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1159 }
1160 }
1161 else
1162 {
1163 if (resId < rmObj->gblCfgParams.numDmaChannels)
1164 {
1165 /*
1166 * Check if specified resource is owned
1167 * by this instance of the resource manager
1168 */
1169 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resId/32u])&(resIdSet))!=FALSE)
1170 {
1171 /* Now check if specified resource is available presently*/
1172 if (((rmInstance->avlblDmaChannels[resId/32u])&(resIdSet))!=FALSE)
1173 {
1174 /*
1175 * Mark the specified channel as "Not Available"
1176 * for future requests
1177 */
1178 rmInstance->avlblDmaChannels[resId/32u] &= resIdClr;
1180 /**
1181 * Check if the register modification flag is
1182 * set or not.
1183 */
1184 if (TRUE == rmInstance->regModificationRequired)
1185 {
1186 if (resId < 32u)
1187 {
1188 rmInstance->shadowRegs->EECR = (1UL << resId);
1190 /**
1191 * Enable the DMA channel in the
1192 * DRAE registers also.
1193 */
1194 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1195 |= (0x1u << resId);
1196 }
1197 else
1198 {
1199 rmInstance->shadowRegs->EECRH = (1UL << resId);
1201 /**
1202 * Enable the DMA channel in the
1203 * DRAEH registers also.
1204 */
1205 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1206 |= (0x1u << (resId - 32u));
1207 }
1208 }
1210 result = EDMA3_RM_SOK;
1211 }
1212 else
1213 {
1214 /* Specified resource is owned but is already booked */
1215 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1216 }
1217 }
1218 else
1219 {
1220 /*
1221 * Specified resource is not owned by this instance
1222 * of the Resource Manager
1223 */
1224 result = EDMA3_RM_E_RES_NOT_OWNED;
1225 }
1226 }
1227 else
1228 {
1229 result = EDMA3_RM_E_INVALID_PARAM;
1230 }
1231 }
1232 }
1233 break;
1235 case EDMA3_RM_RES_QDMA_CHANNEL :
1236 {
1237 if (resId == EDMA3_RM_RES_ANY)
1238 {
1239 for (avlblIdx=0u; avlblIdx<rmObj->gblCfgParams.numQdmaChannels; ++avlblIdx)
1240 {
1241 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[avlblIdx/32u])
1242 &
1243 (rmInstance->avlblQdmaChannels[avlblIdx/32u])
1244 &
1245 ~(rmInstance->initParam.rmInstInitConfig->resvdQdmaChannels[avlblIdx/32u])
1246 &
1247 (1u << (avlblIdx%32u))) != FALSE)
1248 {
1249 resObj->resId = avlblIdx;
1250 rmInstance->avlblQdmaChannels[avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
1252 /**
1253 * Check if the register modification flag is
1254 * set or not.
1255 */
1256 if (TRUE == rmInstance->regModificationRequired)
1257 {
1258 /**
1259 * Enable the QDMA channel in the
1260 * QRAE register also.
1261 */
1262 gblRegs->QRAE[rmInstance->initParam.regionId]
1263 |= (0x1u << avlblIdx);
1264 }
1266 result = EDMA3_RM_SOK;
1267 break;
1268 }
1269 }
1270 /*
1271 * If none of the owned resources of this type is available
1272 * then report "All Resources of this type not available" error
1273 */
1274 if (avlblIdx == rmObj->gblCfgParams.numQdmaChannels)
1275 {
1276 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1277 }
1278 }
1279 else
1280 {
1281 if (resId < rmObj->gblCfgParams.numQdmaChannels)
1282 {
1283 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32u])&(resIdSet))!=FALSE)
1284 {
1285 if (((rmInstance->avlblQdmaChannels [resId/32u])&(resIdSet))!=FALSE)
1286 {
1287 rmInstance->avlblQdmaChannels [resId/32u] &= resIdClr;
1289 /**
1290 * Check if the register modification flag is
1291 * set or not.
1292 */
1293 if (TRUE == rmInstance->regModificationRequired)
1294 {
1295 /**
1296 * Enable the QDMA channel in the
1297 * QRAE register also.
1298 */
1299 gblRegs->QRAE[rmInstance->initParam.regionId]
1300 |= (0x1u << resId);
1301 }
1303 result = EDMA3_RM_SOK;
1304 }
1305 else
1306 {
1307 /* Specified resource is owned but is already booked */
1308 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1309 }
1310 }
1311 else
1312 {
1313 /*
1314 * Specified resource is not owned by this instance
1315 * of the Resource Manager
1316 */
1317 result = EDMA3_RM_E_RES_NOT_OWNED;
1318 }
1319 }
1320 else
1321 {
1322 result = EDMA3_RM_E_INVALID_PARAM;
1323 }
1324 }
1325 }
1326 break;
1328 case EDMA3_RM_RES_TCC :
1329 {
1330 if (resId == EDMA3_RM_RES_ANY)
1331 {
1332 for (avlblIdx=0u; avlblIdx<rmObj->gblCfgParams.numTccs; ++avlblIdx)
1333 {
1334 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [avlblIdx/32u])
1335 & (rmInstance->avlblTccs [avlblIdx/32u])
1336 & ~(rmInstance->initParam.rmInstInitConfig->resvdTccs [avlblIdx/32u])
1337 & (1u << (avlblIdx%32u)))!=FALSE)
1338 {
1339 resObj->resId = avlblIdx;
1340 rmInstance->avlblTccs [avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
1342 /**
1343 * Check if the register modification flag is
1344 * set or not.
1345 */
1346 if (TRUE == rmInstance->regModificationRequired)
1347 {
1348 /**
1349 * Enable the Interrupt channel in the
1350 * DRAE/DRAEH registers also.
1351 * Also, If the region id coming from this
1352 * RM instance is same as the Master RM
1353 * Instance's region id, only then we will be
1354 * getting the interrupts on the same side.
1355 * So save the TCC in the allocatedTCCs[] array.
1356 */
1357 if (avlblIdx < 32u)
1358 {
1359 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1360 |= (0x1u << avlblIdx);
1362 /**
1363 * Do not modify this global array if the register
1364 * modificatio flag is not set.
1365 * Reason being is based on this flag, the IPR/ICR
1366 * or error bit is cleared in the completion or
1367 * error handler ISR.
1368 */
1369 if (edma3RegionId == rmInstance->initParam.regionId)
1370 {
1371 allocatedTCCs[edma3Id][0u] |= (0x1u << avlblIdx);
1372 }
1373 }
1374 else
1375 {
1376 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1377 |= (0x1u << (avlblIdx - 32u));
1379 /**
1380 * Do not modify this global array if the register
1381 * modificatio flag is not set.
1382 * Reason being is based on this flag, the IPR/ICR
1383 * or error bit is cleared in the completion or
1384 * error handler ISR.
1385 */
1386 if (edma3RegionId == rmInstance->initParam.regionId)
1387 {
1388 allocatedTCCs[edma3Id][1u] |= (0x1u << (avlblIdx - 32u));
1389 }
1390 }
1391 }
1394 result = EDMA3_RM_SOK;
1395 break;
1396 }
1397 }
1398 /*
1399 * If none of the owned resources of this type is available
1400 * then report "All Resources of this type not available" error
1401 */
1402 if ( avlblIdx == rmObj->gblCfgParams.numTccs)
1403 {
1404 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1405 }
1406 }
1407 else
1408 {
1409 if (resId < rmObj->gblCfgParams.numTccs)
1410 {
1411 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32u])&(resIdSet))!=FALSE)
1412 {
1413 if (((rmInstance->avlblTccs [resId/32u])&(resIdSet))!=FALSE)
1414 {
1415 rmInstance->avlblTccs [resId/32u] &= resIdClr;
1417 /**
1418 * Check if the register modification flag is
1419 * set or not.
1420 */
1421 if (TRUE == rmInstance->regModificationRequired)
1422 {
1423 /**
1424 * Enable the Interrupt channel in the
1425 * DRAE/DRAEH registers also.
1426 * Also, If the region id coming from this
1427 * RM instance is same as the Master RM
1428 * Instance's region id, only then we will be
1429 * getting the interrupts on the same side.
1430 * So save the TCC in the allocatedTCCs[] array.
1431 */
1432 if (resId < 32u)
1433 {
1434 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1435 |= (0x1u << resId);
1437 /**
1438 * Do not modify this global array if the register
1439 * modificatio flag is not set.
1440 * Reason being is based on this flag, the IPR/ICR
1441 * or error bit is cleared in the completion or
1442 * error handler ISR.
1443 */
1444 if (edma3RegionId == rmInstance->initParam.regionId)
1445 {
1446 allocatedTCCs[edma3Id][0u] |= (0x1u << resId);
1447 }
1448 }
1449 else
1450 {
1451 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1452 |= (0x1u << (resId - 32u));
1454 /**
1455 * Do not modify this global array if the register
1456 * modificatio flag is not set.
1457 * Reason being is based on this flag, the IPR/ICR
1458 * or error bit is cleared in the completion or
1459 * error handler ISR.
1460 */
1461 if (edma3RegionId == rmInstance->initParam.regionId)
1462 {
1463 allocatedTCCs[edma3Id][1u] |= (0x1u << (resId - 32u));
1464 }
1465 }
1466 }
1468 result = EDMA3_RM_SOK;
1469 }
1470 else
1471 {
1472 /* Specified resource is owned but is already booked */
1473 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1474 }
1475 }
1476 else
1477 {
1478 /*
1479 * Specified resource is not owned by this instance
1480 * of the Resource Manager
1481 */
1482 result = EDMA3_RM_E_RES_NOT_OWNED;
1483 }
1484 }
1485 else
1486 {
1487 result = EDMA3_RM_E_INVALID_PARAM;
1488 }
1489 }
1490 }
1491 break;
1493 case EDMA3_RM_RES_PARAM_SET :
1494 {
1495 if (resId == EDMA3_RM_RES_ANY)
1496 {
1497 for (avlblIdx=0u; avlblIdx<rmObj->gblCfgParams.numPaRAMSets; ++avlblIdx)
1498 {
1499 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [avlblIdx/32u])
1500 &
1501 (rmInstance->avlblPaRAMSets [avlblIdx/32u])
1502 &
1503 ~(rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets [avlblIdx/32u])
1504 &
1505 (1u << (avlblIdx%32u)))!=FALSE)
1506 {
1507 resObj->resId = avlblIdx;
1508 rmInstance->avlblPaRAMSets [avlblIdx/32u] &= (unsigned int)(~(1u << (avlblIdx%32u)));
1510 /**
1511 * Also, make the actual PARAM Set NULL, checking the flag
1512 * whether it is required or not.
1513 */
1514 if ((TRUE == rmInstance->regModificationRequired)
1515 && (TRUE == rmInstance->paramInitRequired))
1516 {
1517 edma3MemZero((void *)(&gblRegs->PARAMENTRY[avlblIdx]),
1518 sizeof(gblRegs->PARAMENTRY[avlblIdx]));
1519 }
1521 result = EDMA3_RM_SOK;
1522 break;
1523 }
1524 }
1525 /*
1526 * If none of the owned resources of this type is available
1527 * then report "All Resources of this type not available" error
1528 */
1529 if ( avlblIdx == rmObj->gblCfgParams.numPaRAMSets)
1530 {
1531 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1532 }
1533 }
1534 else
1535 {
1536 if (resId < rmObj->gblCfgParams.numPaRAMSets)
1537 {
1538 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32u])&(resIdSet))!=FALSE)
1539 {
1540 if (((rmInstance->avlblPaRAMSets [resId/32u])&(resIdSet)) !=FALSE)
1541 {
1542 rmInstance->avlblPaRAMSets [resId/32u] &= resIdClr;
1544 /**
1545 * Also, make the actual PARAM Set NULL, checking the flag
1546 * whether it is required or not.
1547 */
1548 if ((TRUE == rmInstance->regModificationRequired)
1549 && (TRUE == rmInstance->paramInitRequired))
1550 {
1551 edma3MemZero((void *)(&gblRegs->PARAMENTRY[resId]),
1552 sizeof(gblRegs->PARAMENTRY[resId]));
1553 }
1555 result = EDMA3_RM_SOK;
1556 }
1557 else
1558 {
1559 /* Specified resource is owned but is already booked */
1560 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1561 }
1562 }
1563 else
1564 {
1565 /*
1566 * Specified resource is not owned by this instance
1567 * of the Resource Manager
1568 */
1569 result = EDMA3_RM_E_RES_NOT_OWNED;
1570 }
1571 }
1572 else
1573 {
1574 result = EDMA3_RM_E_INVALID_PARAM;
1575 }
1576 }
1577 }
1578 break;
1580 default:
1581 result = EDMA3_RM_E_INVALID_PARAM;
1582 break;
1583 }
1585 /* Return the semaphore back */
1586 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
1587 }
1588 }
1589 }
1590 }
1592 /**
1593 * Check the Resource Allocation Result 'result' first. If Resource
1594 * Allocation has resulted in an error, return it (having more priority than
1595 * semResult.
1596 * Else, return semResult.
1597 */
1598 if (EDMA3_RM_SOK == result)
1599 {
1600 /**
1601 * Resource Allocation successful, return semResult for returning
1602 * semaphore.
1603 */
1604 result = semResult;
1605 if ((rmInstance->configScrMapXbarToEvt != NULL) &&
1606 (mapXbarEvtToChanFlag == TRUE))
1607 {
1608 rmInstance->configScrMapXbarToEvt(xBarEvtBeforeMap, resObj->resId);
1609 }
1610 }
1612 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1613 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1614 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1615 EDMA3_DVT_dCOUNTER,
1616 EDMA3_DVT_dNONE,
1617 EDMA3_DVT_dNONE));
1618 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1620 return result;
1621 }
1623 EDMA3_RM_Result EDMA3_RM_freeResource(EDMA3_RM_Handle hEdmaResMgr,
1624 const EDMA3_RM_ResDesc *resObj)
1625 {
1626 unsigned int intState;
1627 EDMA3_RM_Instance *rmInstance = NULL;
1628 EDMA3_RM_Obj *rmObj = NULL;
1629 EDMA3_RM_Result result = EDMA3_RM_SOK;
1630 unsigned int resId;
1631 unsigned int resIdSet = 0x0;
1632 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1633 unsigned int edma3Id;
1635 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1636 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1637 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1638 EDMA3_DVT_dCOUNTER,
1639 EDMA3_DVT_dNONE,
1640 EDMA3_DVT_dNONE));
1641 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1643 /* If parameter checking is enabled... */
1644 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1645 if ((hEdmaResMgr == NULL) || (resObj == NULL))
1646 {
1647 result = EDMA3_RM_E_INVALID_PARAM;
1648 }
1649 #endif
1651 /* Check if the parameters are OK. */
1652 if (EDMA3_RM_SOK == result)
1653 {
1654 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1655 rmObj = rmInstance->pResMgrObjHandle;
1657 if ((rmObj == NULL) ||
1658 (rmObj->gblCfgParams.globalRegs == NULL))
1659 {
1660 result = EDMA3_RM_E_INVALID_PARAM;
1661 }
1662 else
1663 {
1664 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1665 edma3Id = rmObj->phyCtrllerInstId;
1666 resId = resObj->resId;
1668 resIdSet = 1u << (resId%32u);
1670 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
1671 EDMA3_OS_PROTECT_INTERRUPT,
1672 &intState);
1674 if (EDMA3_RM_SOK == result)
1675 {
1676 switch (resObj->type)
1677 {
1678 case EDMA3_RM_RES_DMA_CHANNEL :
1679 {
1680 if (resId < rmObj->gblCfgParams.numDmaChannels)
1681 {
1682 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels [resId/32u]) & (resIdSet))!=FALSE)
1683 {
1684 if (((~(rmInstance->avlblDmaChannels[resId/32u]))&(resIdSet))!=FALSE)
1685 {
1686 /*
1687 * Mark the specified channel as "Available"
1688 * for future requests
1689 */
1690 rmInstance->avlblDmaChannels[resId/32u] |= resIdSet;
1692 /**
1693 * Check if the register modification flag is
1694 * set or not.
1695 */
1696 if (TRUE == rmInstance->regModificationRequired)
1697 {
1698 /**
1699 * DMA Channel is freed.
1700 * Reset the bit specific to the DMA channel
1701 * in the DRAE/DRAEH register also.
1702 */
1703 if (resId < 32u)
1704 {
1705 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1706 &= (~(0x1u << resId));
1707 }
1708 else
1709 {
1710 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1711 &= (~(0x1u << (resId-32u)));
1712 }
1713 }
1715 result = EDMA3_RM_SOK;
1716 }
1717 else
1718 {
1719 result = EDMA3_RM_E_RES_ALREADY_FREE;
1720 }
1721 }
1722 else
1723 {
1724 /*
1725 * Specified resource is not owned by this instance
1726 * of the Resource Manager
1727 */
1728 result = EDMA3_RM_E_RES_NOT_OWNED;
1729 }
1730 }
1731 else
1732 {
1733 result = EDMA3_RM_E_INVALID_PARAM;
1734 }
1735 }
1736 break;
1738 case EDMA3_RM_RES_QDMA_CHANNEL :
1739 {
1740 if (resId < rmObj->gblCfgParams.numQdmaChannels)
1741 {
1742 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32u]) & (resIdSet))!=FALSE)
1743 {
1744 if (((~(rmInstance->avlblQdmaChannels [resId/32u])) & (resIdSet))!=FALSE)
1745 {
1746 rmInstance->avlblQdmaChannels [resId/32u] |= resIdSet;
1748 /**
1749 * Check if the register modification flag is
1750 * set or not.
1751 */
1752 if (TRUE == rmInstance->regModificationRequired)
1753 {
1754 /**
1755 * QDMA Channel is freed.
1756 * Reset the bit specific to the QDMA channel
1757 * in the QRAE register also.
1758 */
1759 gblRegs->QRAE[rmInstance->initParam.regionId]
1760 &= (~(0x1u << resId));
1761 }
1763 result = EDMA3_RM_SOK;
1764 }
1765 else
1766 {
1767 result = EDMA3_RM_E_RES_ALREADY_FREE;
1768 }
1769 }
1770 else
1771 {
1772 /*
1773 * Specified resource is not owned by this instance
1774 * of the Resource Manager
1775 */
1776 result = EDMA3_RM_E_RES_NOT_OWNED;
1777 }
1778 }
1779 else
1780 {
1781 result = EDMA3_RM_E_INVALID_PARAM;
1782 }
1783 }
1784 break;
1786 case EDMA3_RM_RES_TCC :
1787 {
1788 if (resId < rmObj->gblCfgParams.numTccs)
1789 {
1790 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32u]) & (resIdSet))!=FALSE)
1791 {
1792 if (((~(rmInstance->avlblTccs [resId/32u])) & (resIdSet))!=FALSE)
1793 {
1794 rmInstance->avlblTccs [resId/32u] |= resIdSet;
1796 /**
1797 * Check if the register modification flag is
1798 * set or not.
1799 */
1800 if (TRUE == rmInstance->regModificationRequired)
1801 {
1802 /**
1803 * Interrupt Channel is freed.
1804 * Reset the bit specific to the Interrupt
1805 * channel in the DRAE/DRAEH register also.
1806 * Also, if we have earlier saved this
1807 * TCC in allocatedTCCs[] array,
1808 * remove it from there too.
1809 */
1810 if (resId < 32u)
1811 {
1812 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1813 &= (~(0x1u << resId));
1815 if (edma3RegionId == rmInstance->initParam.regionId)
1816 {
1817 allocatedTCCs[edma3Id][0u] &= (~(0x1u << resId));
1818 }
1819 }
1820 else
1821 {
1822 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1823 &= (~(0x1u << (resId-32u)));
1825 if (edma3RegionId == rmInstance->initParam.regionId)
1826 {
1827 allocatedTCCs[edma3Id][1u] &= (~(0x1u << (resId -32u)));
1828 }
1829 }
1830 }
1832 result = EDMA3_RM_SOK;
1833 }
1834 else
1835 {
1836 result = EDMA3_RM_E_RES_ALREADY_FREE;
1837 }
1838 }
1839 else
1840 {
1841 /*
1842 * Specified resource is not owned by this instance
1843 * of the Resource Manager
1844 */
1845 result = EDMA3_RM_E_RES_NOT_OWNED;
1846 }
1847 }
1848 else
1849 {
1850 result = EDMA3_RM_E_INVALID_PARAM;
1851 }
1852 }
1853 break;
1855 case EDMA3_RM_RES_PARAM_SET :
1856 {
1857 if (resId < rmObj->gblCfgParams.numPaRAMSets)
1858 {
1859 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32u])&(resIdSet))!=FALSE)
1860 {
1861 if (((~(rmInstance->avlblPaRAMSets [resId/32u]))&(resIdSet))!=FALSE)
1862 {
1863 rmInstance->avlblPaRAMSets [resId/32u] |= resIdSet;
1865 result = EDMA3_RM_SOK;
1866 }
1867 else
1868 {
1869 result = EDMA3_RM_E_RES_ALREADY_FREE;
1870 }
1871 }
1872 else
1873 {
1874 /*
1875 * Specified resource is not owned by this instance
1876 * of the Resource Manager
1877 */
1878 result = EDMA3_RM_E_RES_NOT_OWNED;
1879 }
1880 }
1881 else
1882 {
1883 result = EDMA3_RM_E_INVALID_PARAM;
1884 }
1885 }
1886 break;
1888 default:
1889 result = EDMA3_RM_E_INVALID_PARAM;
1890 break;
1891 }
1893 }
1895 edma3OsProtectExit (rmObj->phyCtrllerInstId,
1896 EDMA3_OS_PROTECT_INTERRUPT,
1897 intState);
1898 }
1899 }
1901 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1902 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1903 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1904 EDMA3_DVT_dCOUNTER,
1905 EDMA3_DVT_dNONE,
1906 EDMA3_DVT_dNONE));
1907 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1909 return result;
1910 }
1912 EDMA3_RM_Result EDMA3_RM_allocLogicalChannel(EDMA3_RM_Handle hEdmaResMgr,
1913 EDMA3_RM_ResDesc *lChObj,
1914 unsigned int *pParam,
1915 unsigned int *pTcc)
1916 {
1917 EDMA3_RM_ResDesc *chObj;
1918 EDMA3_RM_ResDesc resObj;
1919 EDMA3_RM_Result result = EDMA3_RM_SOK;
1920 EDMA3_RM_Instance *rmInstance = NULL;
1921 EDMA3_RM_Obj *rmObj = NULL;
1922 unsigned int mappedPaRAMId=0u;
1923 unsigned int mappedTcc = EDMA3_RM_CH_NO_TCC_MAP;
1924 int paRAMId = (int)EDMA3_RM_RES_ANY;
1925 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1926 unsigned int qdmaChId = EDMA3_MAX_PARAM_SETS;
1927 unsigned int edma3Id;
1929 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1930 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1931 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1932 EDMA3_DVT_dCOUNTER,
1933 EDMA3_DVT_dNONE,
1934 EDMA3_DVT_dNONE));
1935 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1937 /* If parameter checking is enabled... */
1938 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1939 if ((lChObj == NULL) || (hEdmaResMgr == NULL))
1940 {
1941 result = EDMA3_RM_E_INVALID_PARAM;
1942 }
1943 #endif
1945 /* Check if the parameters are OK. */
1946 if (EDMA3_RM_SOK == result)
1947 {
1948 chObj = lChObj;
1950 if ((chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
1951 || (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL))
1952 {
1953 /**
1954 * If the request is for a DMA or QDMA channel, check the
1955 * pParam and pTcc objects also.
1956 * For the Link channel request, they could be NULL.
1957 */
1958 /* If parameter checking is enabled... */
1959 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1960 if ((pParam == NULL) || (pTcc == NULL))
1961 {
1962 result = EDMA3_RM_E_INVALID_PARAM;
1963 }
1964 #endif
1965 }
1966 }
1968 if (result == EDMA3_RM_SOK)
1969 {
1970 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1972 if (rmInstance == NULL)
1973 {
1974 result = EDMA3_RM_E_INVALID_PARAM;
1975 }
1976 }
1978 if (result == EDMA3_RM_SOK)
1979 {
1980 rmObj = rmInstance->pResMgrObjHandle;
1982 if (rmObj == NULL)
1983 {
1984 result = EDMA3_RM_E_INVALID_PARAM;
1985 }
1986 else
1987 {
1988 if (rmObj->gblCfgParams.globalRegs == NULL)
1989 {
1990 result = EDMA3_RM_E_INVALID_PARAM;
1991 }
1992 }
1993 }
1995 if (result == EDMA3_RM_SOK)
1996 {
1997 edma3Id = rmObj->phyCtrllerInstId;
1998 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2000 switch (chObj->type)
2001 {
2002 case EDMA3_RM_RES_DMA_CHANNEL:
2003 {
2004 if ((chObj->resId == EDMA3_RM_DMA_CHANNEL_ANY)
2005 || (chObj->resId == EDMA3_RM_RES_ANY))
2006 {
2007 /* Request for ANY DMA channel. */
2008 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2009 resObj.resId = EDMA3_RM_RES_ANY;
2010 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2012 if (result == EDMA3_RM_SOK)
2013 {
2014 /* DMA channel allocated successfully. */
2015 chObj->resId = resObj.resId;
2017 /**
2018 * Check the PaRAM Set user has specified for this DMA channel.
2019 * Two cases exist:
2020 * a) DCHMAP exists: Any PaRAM Set can be used
2021 * b) DCHMAP does not exist: Should not be possible
2022 * only if the channel allocated (ANY) and PaRAM requested
2023 * are same.
2024 */
2025 if ((*pParam) == EDMA3_RM_PARAM_ANY)
2026 {
2027 /* User specified ANY PaRAM Set; Check the mapping. */
2028 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2029 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2030 {
2031 /** If some PaRAM set is statically mapped to the returned
2032 * channel number, use that.
2033 */
2034 paRAMId = (int)mappedPaRAMId;
2035 }
2036 }
2037 else
2038 {
2039 /* User specified some PaRAM Set; check that can be used or not. */
2040 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2041 {
2042 paRAMId = (int)(*pParam);
2043 }
2044 else
2045 {
2046 /**
2047 * Channel mapping does not exist. If the PaRAM Set requested
2048 * is the same as dma channel allocated (coincidentally), it is fine.
2049 * Else return error.
2050 */
2051 if ((*pParam) != (resObj.resId))
2052 {
2053 result = EDMA3_RM_E_INVALID_PARAM;
2055 /**
2056 * Free the previously allocated DMA channel also.
2057 */
2058 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2059 }
2060 else
2061 {
2062 paRAMId = (int)(*pParam);
2063 }
2064 }
2065 }
2067 mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[resObj.resId];
2068 }
2069 }
2070 else
2071 {
2072 if (chObj->resId <= edma3_dma_ch_max_val[edma3Id])
2073 {
2074 /* Request for a specific DMA channel */
2075 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2076 resObj.resId = chObj->resId;
2077 result = EDMA3_RM_allocResource(hEdmaResMgr,
2078 (EDMA3_RM_ResDesc *)&resObj);
2080 if (result == EDMA3_RM_SOK)
2081 {
2082 /**
2083 * Check the PaRAM Set user has specified for this DMA channel.
2084 * Two cases exist:
2085 * a) DCHMAP exists: Any PaRAM Set can be used
2086 * b) DCHMAP does not exist: Should not be possible
2087 * only if the channel allocated (ANY) and PaRAM requested
2088 * are same.
2089 */
2090 if ((*pParam) == EDMA3_RM_PARAM_ANY)
2091 {
2092 /* User specified ANY PaRAM Set; Check the mapping. */
2093 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2094 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2095 {
2096 /** If some PaRAM set is statically mapped to the returned
2097 * channel number, use that.
2098 */
2099 paRAMId = (int)mappedPaRAMId;
2100 }
2101 }
2102 else
2103 {
2104 /* User specified some PaRAM Set; check that can be used or not. */
2105 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2106 {
2107 paRAMId = (int)(*pParam);
2108 }
2109 else
2110 {
2111 /**
2112 * Channel mapping does not exist. If the PaRAM Set requested
2113 * is the same as dma channel allocated (coincidentally), it is fine.
2114 * Else return error.
2115 */
2116 if ((*pParam) != (resObj.resId))
2117 {
2118 result = EDMA3_RM_E_INVALID_PARAM;
2120 /**
2121 * Free the previously allocated DMA channel also.
2122 */
2123 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2124 }
2125 else
2126 {
2127 paRAMId = (int)(*pParam);
2128 }
2129 }
2130 }
2132 mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[chObj->resId];
2133 }
2134 }
2135 else
2136 {
2137 result = EDMA3_RM_E_INVALID_PARAM;
2138 }
2139 }
2140 }
2141 break;
2144 case EDMA3_RM_RES_QDMA_CHANNEL:
2145 {
2146 if ((chObj->resId == EDMA3_RM_QDMA_CHANNEL_ANY)
2147 || (chObj->resId == EDMA3_RM_RES_ANY))
2148 {
2149 /* First request for any available QDMA channel */
2150 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2151 resObj.resId = EDMA3_RM_RES_ANY;
2152 result = EDMA3_RM_allocResource(hEdmaResMgr,
2153 (EDMA3_RM_ResDesc *)&resObj);
2155 if (result == EDMA3_RM_SOK)
2156 {
2157 /* Return the actual QDMA channel id. */
2158 chObj->resId = resObj.resId;
2160 /* Save the Logical-QDMA channel id for future use. */
2161 qdmaChId = resObj.resId + edma3_qdma_ch_min_val[edma3Id];
2163 /**
2164 * Check the PaRAM Set user has specified for this QDMA channel.
2165 * If he has specified any particular PaRAM Set, use that.
2166 */
2167 if ((*pParam) != EDMA3_RM_PARAM_ANY)
2168 {
2169 /* User specified ANY PaRAM Set; Check the mapping. */
2170 paRAMId = (int)(*pParam);
2171 }
2172 }
2173 }
2174 else
2175 {
2176 if (chObj->resId < rmObj->gblCfgParams.numQdmaChannels)
2177 {
2178 /* Request for a specific QDMA channel */
2179 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2180 resObj.resId = chObj->resId;
2181 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2183 if (result == EDMA3_RM_SOK)
2184 {
2185 /* Save the Logical-QDMA channel id for future use. */
2186 qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
2188 /**
2189 * Check the PaRAM Set user has specified for this QDMA channel.
2190 * If he has specified any particular PaRAM Set, use that.
2191 */
2192 if ((*pParam) != EDMA3_RM_PARAM_ANY)
2193 {
2194 /* User specified ANY PaRAM Set; Check the mapping. */
2195 paRAMId = (int)(*pParam);
2196 }
2197 }
2198 }
2199 else
2200 {
2201 result = EDMA3_RM_E_INVALID_PARAM;
2202 }
2203 }
2204 }
2205 break;
2207 case EDMA3_RM_RES_PARAM_SET:
2208 {
2209 /* Request for a LINK channel. */
2210 if ((chObj->resId == EDMA3_RM_PARAM_ANY)
2211 || (chObj->resId == EDMA3_RM_RES_ANY))
2212 {
2213 /* Request for ANY LINK channel. */
2214 paRAMId = (int)EDMA3_RM_RES_ANY;
2215 }
2216 else
2217 {
2218 if (chObj->resId < edma3NumPaRAMSets)
2219 {
2220 /* Request for a Specific LINK channel. */
2221 paRAMId = (int)(chObj->resId);
2222 }
2223 else
2224 {
2225 result = EDMA3_RM_E_INVALID_PARAM;
2226 }
2227 }
2229 if (result == EDMA3_RM_SOK)
2230 {
2231 /* Try to allocate the link channel */
2232 resObj.type = EDMA3_RM_RES_PARAM_SET;
2233 resObj.resId = (unsigned int)paRAMId;
2234 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2236 if (result == EDMA3_RM_SOK)
2237 {
2238 unsigned int linkCh = edma3_link_ch_min_val[edma3Id];
2240 /* Return the actual PaRAM Id. */
2241 chObj->resId = resObj.resId;
2243 /*
2244 * Search for the next Link channel place-holder available,
2245 * starting from EDMA3_RM_LINK_CH_MIN_VAL.
2246 * It will be used for future operations on the Link channel.
2247 */
2248 while ((edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId != -1)
2249 && (linkCh <= edma3_link_ch_max_val[edma3Id]))
2250 {
2251 /* Move to the next place-holder. */
2252 linkCh++;
2253 }
2255 /* Verify the returned handle, it should lie in the correct range */
2256 if (linkCh > edma3_link_ch_max_val[edma3Id])
2257 {
2258 result = EDMA3_RM_E_INVALID_PARAM;
2260 /* Free the PaRAM Set now. */
2261 resObj.type = EDMA3_RM_RES_PARAM_SET;
2262 resObj.resId = chObj->resId;
2263 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2264 }
2265 else
2266 {
2267 /* Save the PaRAM Id for the Link Channel. */
2268 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = (int)(chObj->resId);
2270 /**
2271 * Remove any linking. Before doing that, check
2272 * whether it is permitted or not.
2273 */
2274 if (TRUE == rmInstance->regModificationRequired)
2275 {
2276 *((&gblRegs->PARAMENTRY[chObj->resId].OPT)
2277 + (unsigned int)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2278 }
2279 }
2280 }
2281 }
2282 }
2283 break;
2285 default:
2286 result = EDMA3_RM_E_INVALID_PARAM;
2287 }
2288 }
2291 if (result == EDMA3_RM_SOK)
2292 {
2293 /**
2294 * For DMA/QDMA channels, we still have to allocate more resources like
2295 * TCC, PaRAM Set etc.
2296 * For Link channel, only the PaRAMSet is required and that has been
2297 * allocated so no further operations required.
2298 */
2300 /* Further resources' allocation for DMA channel. */
2301 if (chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
2302 {
2303 /* First allocate a PaRAM Set */
2304 resObj.type = EDMA3_RM_RES_PARAM_SET;
2305 /* Use the saved param id now. */
2306 resObj.resId = (unsigned int)paRAMId;
2307 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2308 if (result == EDMA3_RM_SOK)
2309 {
2310 /**
2311 * PaRAM Set allocation succeeded.
2312 * Save the PaRAM Set first.
2313 */
2314 *pParam = resObj.resId;
2315 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = (int)(resObj.resId);
2317 /* Allocate the TCC now. */
2318 resObj.type = EDMA3_RM_RES_TCC;
2319 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2320 {
2321 if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2322 {
2323 resObj.resId = EDMA3_RM_RES_ANY;
2324 }
2325 else
2326 {
2327 resObj.resId = mappedTcc;
2328 }
2329 }
2330 else
2331 {
2332 resObj.resId = *pTcc;
2333 }
2335 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2336 if (result == EDMA3_RM_SOK)
2337 {
2338 /* TCC allocation succeeded. Save it first. */
2339 *pTcc = resObj.resId;
2340 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].tcc = resObj.resId;
2342 /**
2343 * Check first whether the global registers and the allocated
2344 * PaRAM Set can be modified or not. If yes, do the needful.
2345 * Else leave this for the user.
2346 */
2347 if (TRUE == rmInstance->regModificationRequired)
2348 {
2349 /* Set TCC of the allocated Param Set. */
2350 gblRegs->PARAMENTRY[*pParam].OPT &= EDMA3_RM_OPT_TCC_CLR_MASK;
2351 gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2353 /**
2354 * Do the mapping between DMA channel and PaRAM Set.
2355 * Do this for the EDMA3 Controllers which have a register for mapping
2356 * DMA Channel to a particular PaRAM Set.
2357 */
2358 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2359 {
2360 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2362 /* Map Parameter RAM Set Number for specified channelId */
2363 gblRegs->DCHMAP[chObj->resId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
2364 gblRegs->DCHMAP[chObj->resId] |= EDMA3_RM_DCH_PARAM_SET_MASK(*pParam);
2365 }
2367 /* Remove any linking */
2368 *((&gblRegs->PARAMENTRY[*pParam].OPT)
2369 + (unsigned int)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2370 }
2371 }
2372 else
2373 {
2374 /**
2375 * TCC allocation failed, free the previously allocated
2376 * PaRAM Set and DMA channel.
2377 */
2378 resObj.type = EDMA3_RM_RES_PARAM_SET;
2379 resObj.resId = *pParam;
2380 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2382 /* Reset the book-keeping data structure also. */
2383 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = -1;
2385 resObj.type = chObj->type;
2386 resObj.resId = chObj->resId;
2387 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2388 }
2389 }
2390 else
2391 {
2392 /**
2393 * PaRAM Set allocation failed, free the previously allocated
2394 * DMA channel also.
2395 */
2396 resObj.type = chObj->type;
2397 resObj.resId = chObj->resId;
2398 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2399 }
2400 }
2403 /* Further resources' allocation for QDMA channel. */
2404 if (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
2405 {
2406 /* First allocate a PaRAM Set */
2407 resObj.type = EDMA3_RM_RES_PARAM_SET;
2408 /* Use the saved param id now. */
2409 resObj.resId = (unsigned int)paRAMId;
2410 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2411 if (result == EDMA3_RM_SOK)
2412 {
2413 /**
2414 * PaRAM Set allocation succeeded.
2415 * Save the PaRAM Set first.
2416 */
2417 *pParam = resObj.resId;
2418 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = (int)(resObj.resId);
2420 /* Allocate the TCC now. */
2421 resObj.type = EDMA3_RM_RES_TCC;
2422 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2423 {
2424 if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2425 {
2426 resObj.resId = EDMA3_RM_RES_ANY;
2427 }
2428 else
2429 {
2430 resObj.resId = mappedTcc;
2431 }
2432 }
2433 else
2434 {
2435 resObj.resId = *pTcc;
2436 }
2438 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2439 if (result == EDMA3_RM_SOK)
2440 {
2441 /* TCC allocation succeeded. Save it first. */
2442 *pTcc = resObj.resId;
2443 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = resObj.resId;
2445 /**
2446 * Check first whether the global registers and the allocated
2447 * PaRAM Set can be modified or not. If yes, do the needful.
2448 * Else leave this for the user.
2449 */
2450 if (TRUE == rmInstance->regModificationRequired)
2451 {
2452 /* Set TCC of the allocated Param Set. */
2453 gblRegs->PARAMENTRY[*pParam].OPT &= EDMA3_RM_OPT_TCC_CLR_MASK;
2454 gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2456 /* Do the mapping between QDMA channel and PaRAM Set. */
2457 /* Map Parameter RAM Set Number for specified channelId */
2458 gblRegs->QCHMAP[chObj->resId]
2459 &= EDMA3_RM_QCH_PARAM_CLR_MASK;
2460 gblRegs->QCHMAP[chObj->resId]
2461 |= EDMA3_RM_QCH_PARAM_SET_MASK(*pParam);
2463 /* Set the Trigger Word */
2464 gblRegs->QCHMAP[chObj->resId]
2465 &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
2466 gblRegs->QCHMAP[chObj->resId]
2467 |= EDMA3_RM_QCH_TRWORD_SET_MASK(EDMA3_RM_QDMA_TRIG_DEFAULT);
2469 /* Remove any linking */
2470 *((&gblRegs->PARAMENTRY[*pParam].OPT)
2471 + (unsigned int)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFu;
2473 /* Enable the transfer also. */
2474 rmInstance->shadowRegs->QEESR = (1u << chObj->resId);
2475 }
2476 }
2477 else
2478 {
2479 /**
2480 * TCC allocation failed, free the previously allocated
2481 * PaRAM Set and QDMA channel.
2482 */
2483 resObj.type = EDMA3_RM_RES_PARAM_SET;
2484 resObj.resId = *pParam;
2485 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2487 /* Reset the book-keeping data structure also. */
2488 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
2490 resObj.type = chObj->type;
2491 resObj.resId = chObj->resId;
2492 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2493 }