1 /*
2 * edma3resmgr.c
3 *
4 * EDMA3 Controller Resource Manager Interface Implementation
5 *
6 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
7 *
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the
19 * distribution.
20 *
21 * Neither the name of Texas Instruments Incorporated nor the names of
22 * its contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 */
39 /* Resource Manager Internal Header Files */
40 #include <ti/sdo/edma3/rm/src/edma3resmgr.h>
42 /* Instrumentation Header File */
43 #ifdef EDMA3_INSTRUMENTATION_ENABLED
44 #include <ti/sdo/edma3/rm/src/edma3_log.h>
45 #endif
47 /* For assert() */
48 /**
49 * Define NDEBUG to ignore assert().
50 * NDEBUG should be defined before including assert.h header file.
51 */
52 #include <assert.h>
55 /* Global Defines, need to re-compile if values are changed */
56 /*---------------------------------------------------------------------------*/
57 /**
58 * \brief EDMA3 Resource Manager behaviour of clearing CC ERROR interrupts.
59 * This macro controls the driver to enable/disable clearing of error
60 * status of all channels.
61 *
62 * On disabling this (with value 0x0), the channels owned by the region
63 * is cleared and its expected that some other entity is responsible for
64 * clearing the error status for channels not owned.
65 *
66 * Its recomended that this flag is a positive value, to ensure that
67 * error flags are cleared for all the channels.
68 */
69 #define EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS (TRUE)
71 /**
72 * \brief EDMA3 Resource Manager retry count to check the pending interrupts inside ISR.
73 * This macro controls the driver to check the pending interrupt for
74 * 'n' number of times.
75 * Minumum value is 1.
76 */
77 #define EDMA3_RM_COMPL_HANDLER_RETRY_COUNT (10U)
79 /**
80 * \brief EDMA3 Resource Manager retry count to check the pending CC Error Interrupt inside ISR
81 * This macro controls the driver to check the pending CC Error
82 * interrupt for 'n' number of times.
83 * Minumum value is 1.
84 */
85 #define EDMA3_RM_CCERR_HANDLER_RETRY_COUNT (10U)
89 /* Externel Variables */
90 /*---------------------------------------------------------------------------*/
91 /**
92 * Maximum Resource Manager Instances supported by the EDMA3 Package.
93 */
94 extern const uint32_t EDMA3_MAX_RM_INSTANCES;
97 #ifndef GENERIC
98 /**
99 * \brief Static Configuration structure for EDMA3
100 * controller, to provide Global SoC specific Information.
101 *
102 * This configuration info can also be provided by the user at run-time,
103 * while calling EDMA3_RM_create (). If not provided at run-time,
104 * this info will be taken from the config file "edma3_<PLATFORM_NAME>_cfg.c",
105 * for the specified platform.
106 */
107 extern EDMA3_RM_GblConfigParams edma3GblCfgParams [EDMA3_MAX_EDMA3_INSTANCES];
109 /**
110 * \brief Default Static Region Specific Configuration structure for
111 * EDMA3 controller, to provide region specific Information.
112 */
113 extern EDMA3_RM_InstanceInitConfig defInstInitConfig [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_REGIONS];
115 #endif
118 /**
119 * \brief Region Specific Configuration structure for
120 * EDMA3 controller, to provide region specific Information.
121 *
122 * This configuration info can also be provided by the user at run-time,
123 * while calling EDMA3_RM_open (). If not provided at run-time,
124 * this info will be taken from the config file "edma3_<PLATFORM_NAME>_cfg.c",
125 * for the specified platform.
126 */
127 #ifdef BUILD_C6XDSP
128 extern far EDMA3_RM_InstanceInitConfig *userInitConfig;
129 extern far EDMA3_RM_InstanceInitConfig *ptrInitCfgArray;
130 #else
131 extern EDMA3_RM_InstanceInitConfig *userInitConfig;
132 extern EDMA3_RM_InstanceInitConfig *ptrInitCfgArray;
133 #endif
135 /**
136 * Handles of EDMA3 Resource Manager Instances.
137 *
138 * Used to maintain information of the EDMA3 RM Instances
139 * for each HW controller.
140 * There could be a maximum of EDMA3_MAX_RM_INSTANCES instances per
141 * EDMA3 HW.
142 */
143 #ifdef BUILD_C6XDSP
144 extern far EDMA3_RM_Instance *resMgrInstance;
145 extern far EDMA3_RM_Instance *ptrRMIArray;
146 #else
147 extern EDMA3_RM_Instance *ptrRMIArray;
148 extern EDMA3_RM_Instance *resMgrInstance;
150 #endif
151 /** Max of DMA Channels */
152 uint32_t edma3_dma_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
153 /** Min of Link Channels */
154 uint32_t edma3_link_ch_min_val[EDMA3_MAX_EDMA3_INSTANCES];
155 /** Max of Link Channels */
156 uint32_t edma3_link_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
157 /** Min of QDMA Channels */
158 uint32_t edma3_qdma_ch_min_val[EDMA3_MAX_EDMA3_INSTANCES];
159 /** Max of QDMA Channels */
160 uint32_t edma3_qdma_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
161 /** Max of Logical Channels */
162 uint32_t edma3_log_ch_max_val[EDMA3_MAX_EDMA3_INSTANCES];
164 /* Globals */
165 /*---------------------------------------------------------------------------*/
166 /**
167 * \brief EDMA3 Resource Manager Objects, tied to each EDMA3 HW Controller.
168 *
169 * Typically one RM object will cater to one EDMA3 HW controller
170 * and will have all the global config information.
171 */
172 #ifdef BUILD_C6XDSP
173 #pragma DATA_SECTION(resMgrObj, ".fardata:.edma3Globals");
174 #endif
175 EDMA3_RM_Obj resMgrObj[EDMA3_MAX_EDMA3_INSTANCES];
178 /**
179 * Global Array to store the mapping between DMA channels and Interrupt
180 * channels i.e. TCCs.
181 * DMA 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 DMA channel X (EMR/EMRH register, bit X). In that
184 * scenario, this DMA channel <-> TCC mapping will be used to point to
185 * the correct callback function.
186 */
187 #ifdef BUILD_C6XDSP
188 #pragma DATA_SECTION(edma3DmaChTccMapping, ".fardata:.edma3Globals");
189 #endif
190 static uint32_t edma3DmaChTccMapping [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_DMA_CH];
193 /**
194 * Global Array to store the mapping between QDMA channels and Interrupt
195 * channels i.e. TCCs.
196 * QDMA channel X can use any TCC Y. Transfer completion
197 * interrupt will occur on the TCC Y (IPR/IPRH Register, bit Y), but error
198 * interrupt will occur on QDMA channel X (QEMR register, bit X). In that
199 * scenario, this QDMA channel <-> TCC mapping will be used to point to
200 * the correct callback function.
201 */
202 #ifdef BUILD_C6XDSP
203 #pragma DATA_SECTION(edma3QdmaChTccMapping, ".fardata:.edma3Globals");
204 #endif
205 static uint32_t edma3QdmaChTccMapping [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_QDMA_CH];
208 /**
209 * Global Array to maintain the Callback details registered
210 * against a particular TCC. Used to call the callback
211 * functions linked to the particular channel.
212 */
213 #ifdef BUILD_C6XDSP
214 #pragma DATA_SECTION(edma3IntrParams, ".fardata:.edma3Globals");
215 #endif
216 static EDMA3_RM_TccCallbackParams edma3IntrParams [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_TCC];
219 /** edma3RegionId will be updated ONCE using the parameter regionId passed to
220 * the EDMA3_RM_open() function, for the Master RM instance (one who
221 * configures the Global Registers).
222 * This global variable will be used within the Interrupt handlers to know
223 * which shadow region registers to access. All other interrupts coming
224 * from other shadow regions will not be handled.
225 */
226 #ifdef BUILD_C6XDSP
227 #pragma DATA_SECTION(edma3RegionId, ".fardata:.edma3Globals");
228 #endif
229 static EDMA3_RM_RegionId edma3RegionId = EDMA3_MAX_REGIONS;
231 /** masterExists[] will be updated when the Master RM Instance modifies the
232 * Global EDMA3 configuration registers. It is used to prevent any other
233 * Master RM Instance creation.
234 * masterExists[] is per EDMA3 hardware, hence it is created
235 * as an array.
236 */
237 #ifdef BUILD_C6XDSP
238 #pragma DATA_SECTION(masterExists, ".fardata:.edma3Globals");
239 #endif
240 static uint32_t masterExists [EDMA3_MAX_EDMA3_INSTANCES] = {FALSE,FALSE,FALSE,FALSE,FALSE};
242 /**
243 * Number of PaRAM Sets actually present on the SoC. This will be updated
244 * while creating the Resource Manager Object.
245 */
246 #ifdef BUILD_C6XDSP
247 #pragma DATA_SECTION(edma3NumPaRAMSets, ".fardata:.edma3Globals");
248 #endif
249 uint32_t edma3NumPaRAMSets = EDMA3_MAX_PARAM_SETS;
252 /**
253 * The list of Interrupt Channels which get allocated while requesting the
254 * TCC. It will be used while checking the IPR/IPRH bits in the RM ISR.
255 */
256 #ifdef BUILD_C6XDSP
257 #pragma DATA_SECTION(allocatedTCCs, ".fardata:.edma3Globals");
258 #endif
259 static uint32_t allocatedTCCs[EDMA3_MAX_EDMA3_INSTANCES][2U] =
260 {
261 {0x0U, 0x0U},
262 {0x0U, 0x0U},
263 {0x0U, 0x0U},
264 {0x0U, 0x0U},
265 {0x0U, 0x0U},
266 };
269 /**
270 * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
271 * and stored in this array. It will be referenced in
272 * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
273 */
274 #ifdef BUILD_C6XDSP
275 #pragma DATA_SECTION(contiguousDmaRes, ".fardata:.edma3Globals");
276 #endif
277 static uint32_t contiguousDmaRes[EDMA3_MAX_DMA_CHAN_DWRDS] = {0x0U, 0x0U};
279 /**
280 * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
281 * and stored in this array. It will be referenced in
282 * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
283 */
284 #ifdef BUILD_C6XDSP
285 #pragma DATA_SECTION(contiguousQdmaRes, ".fardata:.edma3Globals");
286 #endif
287 static uint32_t contiguousQdmaRes[EDMA3_MAX_QDMA_CHAN_DWRDS] = {0x0U};
289 /**
290 * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
291 * and stored in this array. It will be referenced in
292 * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
293 */
294 #ifdef BUILD_C6XDSP
295 #pragma DATA_SECTION(contiguousTccRes, ".fardata:.edma3Globals");
296 #endif
297 static uint32_t contiguousTccRes[EDMA3_MAX_TCC_DWRDS] = {0x0U, 0x0U};
299 /**
300 * Arrays ownDmaChannels[], resvdDmaChannels and avlblDmaChannels will be ANDed
301 * and stored in this array. It will be referenced in
302 * EDMA3_RM_allocContiguousResource () to look for contiguous resources.
303 */
304 #ifdef BUILD_C6XDSP
305 #pragma DATA_SECTION(contiguousParamRes, ".fardata:.edma3Globals");
306 #endif
307 static uint32_t contiguousParamRes[EDMA3_MAX_PARAM_DWRDS];
310 /**
311 * \brief Resources bound to a Channel
312 *
313 * When a request for a channel is made, the resources PaRAM Set and TCC
314 * get bound to that channel. This information is needed internally by the
315 * resource manager, when a request is made to free the channel,
316 * to free up the channel-associated resources.
317 */
318 #ifdef BUILD_C6XDSP
319 #pragma DATA_SECTION(edma3RmChBoundRes, ".fardata:.edma3Globals");
320 #endif
321 static EDMA3_RM_ChBoundResources edma3RmChBoundRes [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_LOGICAL_CH];
323 /**
324 * Used to reset the Internal EDMA3 Resource Manager Data Structures for the first time.
325 */
326 #ifdef BUILD_C6XDSP
327 #pragma DATA_SECTION(rmInitDone, ".fardata:.edma3Globals");
328 #endif
329 static uint16_t rmInitDone = FALSE;
331 /*---------------------------------------------------------------------------*/
333 /* Local functions prototypes */
334 /*---------------------------------------------------------------------------*/
335 /** EDMA3 Instance 0 Completion Handler Interrupt Service Routine */
336 void lisrEdma3ComplHandler0(uint32_t arg);
337 /** EDMA3 Instance 0 CC Error Interrupt Service Routine */
338 void lisrEdma3CCErrHandler0(uint32_t arg);
339 /**
340 * EDMA3 Instance 0 TC[0-7] Error Interrupt Service Routines
341 * for a maximum of 8 TCs (Transfer Controllers).
342 */
343 void lisrEdma3TC0ErrHandler0(uint32_t arg);
344 void lisrEdma3TC1ErrHandler0(uint32_t arg);
345 void lisrEdma3TC2ErrHandler0(uint32_t arg);
346 void lisrEdma3TC3ErrHandler0(uint32_t arg);
347 void lisrEdma3TC4ErrHandler0(uint32_t arg);
348 void lisrEdma3TC5ErrHandler0(uint32_t arg);
349 void lisrEdma3TC6ErrHandler0(uint32_t arg);
350 void lisrEdma3TC7ErrHandler0(uint32_t arg);
353 /** Interrupt Handler for the Transfer Completion interrupt */
354 static void edma3ComplHandler (const EDMA3_RM_Obj *rmObj);
355 /** Interrupt Handler for the Channel Controller Error interrupt */
356 static void edma3CCErrHandler (const EDMA3_RM_Obj *rmObj);
357 /** Interrupt Handler for the Transfer Controller Error interrupt */
358 static void edma3TCErrHandler (const EDMA3_RM_Obj *rmObj, uint32_t tcNum);
361 /** Local MemZero function */
362 void edma3MemZero(void *dst, uint32_t len);
363 /** Local MemCpy function */
364 void edma3MemCpy(void *dst, const void *src, uint32_t len);
365 /* Local MemCopy function to copy Param Set ONLY */
366 void edma3ParamCpy(volatile void *dst, const volatile void *src);
368 /** Initialization of the Global region registers of the EDMA3 Controller */
369 static void edma3GlobalRegionInit (uint32_t phyCtrllerInstId, uint32_t numDmaChannels);
370 /** Initialization of the Shadow region registers of the EDMA3 Controller */
371 static void edma3ShadowRegionInit (const EDMA3_RM_Instance *pRMInstance);
375 /* Internal functions for contiguous resource allocation */
376 /**
377 * Finds a particular bit ('0' or '1') in the particular word from 'start'.
378 * If found, returns the position, else return -1.
379 */
380 static int32_t findBitInWord (int32_t source, uint32_t start, uint16_t bit);
382 /**
383 * Finds a particular bit ('0' or '1') in the specified resources' array
384 * from 'start' to 'end'. If found, returns the position, else return -1.
385 */
386 static int32_t findBit (EDMA3_RM_ResType resType,
387 uint32_t start,
388 uint32_t end,
389 uint16_t bit);
391 /**
392 * If successful, this function returns EDMA3_RM_SOK and the position
393 * of first available resource in 'positionRes'. Else returns error.
394 */
395 static EDMA3_RM_Result allocAnyContigRes(EDMA3_RM_ResType resType,
396 uint32_t numResources,
397 uint32_t *positionRes);
399 /**
400 * Starting from 'firstResIdObj', this function makes the next 'numResources'
401 * Resources non-available for future. Also, it does some global resisters'
402 * setting also.
403 */
404 static EDMA3_RM_Result gblChngAllocContigRes(EDMA3_RM_Instance *rmInstance,
405 const EDMA3_RM_ResDesc *firstResIdObj,
406 uint32_t numResources);
408 /*---------------------------------------------------------------------------*/
410 EDMA3_RM_Result EDMA3_RM_create (uint32_t phyCtrllerInstId,
411 const EDMA3_RM_GblConfigParams *gblCfgParams,
412 const void *miscParam)
413 {
414 uint32_t count = 0U;
415 EDMA3_RM_Result result = EDMA3_RM_SOK;
416 const EDMA3_RM_MiscParam *miscOpt = (const EDMA3_RM_MiscParam *)miscParam;
418 #ifdef GENERIC
419 /* GENERIC libraries don't come with a default confifguration, always
420 needs to be supplied with a parameter */
421 if (gblCfgParams == NULL)
422 {
423 result = EDMA3_RM_E_INVALID_PARAM;
424 }
425 #endif
427 /**
428 * We are NOT checking 'gblCfgParams' for NULL.
429 * If user has passed NULL, default config info will be
430 * taken from config file.
431 * 'param' is also not being checked because it could be
432 * NULL also.
433 */
435 /* If parameter checking is enabled... */
436 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
437 if (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
438 {
439 result = EDMA3_RM_E_INVALID_PARAM;
440 }
441 #endif
443 /* Check if the parameters are OK. */
444 if (EDMA3_RM_SOK == result)
445 {
446 /* Initialize the global variables for the first time */
447 if (FALSE == rmInitDone)
448 {
449 edma3MemZero((void *)&(resMgrObj[count]),
450 sizeof(resMgrObj));
451 edma3MemZero((void *)(&(edma3IntrParams[0U])),
452 sizeof(edma3IntrParams));
454 rmInitDone = TRUE;
455 }
457 /* Initialization has been done */
458 if (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_DELETED)
459 {
460 result = EDMA3_RM_E_OBJ_NOT_DELETED;
461 }
462 else
463 {
464 /**
465 * Check whether user has passed the Global Config Info.
466 * If yes, copy it to the driver data structures. Else, use the
467 * info from the config file edma3Cfg.c
468 */
469 #ifndef GENERIC
470 if (NULL == gblCfgParams)
471 {
472 /* Take info from the specific config file */
473 edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
474 (const void *)(&edma3GblCfgParams[phyCtrllerInstId]),
475 sizeof (EDMA3_RM_GblConfigParams));
476 }
477 else
478 {
479 #endif
480 /* User passed the info, save it in the RM object first */
481 edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
482 (const void *)(gblCfgParams),
483 sizeof (EDMA3_RM_GblConfigParams));
484 #ifndef GENERIC
485 }
486 #endif
489 /**
490 * Check whether DMA channel to PaRAM Set mapping exists or not.
491 * If it does not exist, set the mapping array as 1-to-1 mapped.
492 */
493 if (FALSE == resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChPaRAMMapExists)
494 {
495 for (count = 0U; count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels; count++)
496 {
497 resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChannelPaRAMMap[count] = count;
498 }
499 }
502 /**
503 * Update the actual number of PaRAM sets and
504 * Initialize Boundary Values for Logical Channel Ranges.
505 */
506 edma3NumPaRAMSets = resMgrObj[phyCtrllerInstId].gblCfgParams.numPaRAMSets;
507 edma3_dma_ch_max_val[phyCtrllerInstId] = resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels - 1U;
508 edma3_link_ch_min_val[phyCtrllerInstId] = edma3_dma_ch_max_val[phyCtrllerInstId] + 1U;
509 edma3_link_ch_max_val[phyCtrllerInstId] = edma3_link_ch_min_val[phyCtrllerInstId] + (resMgrObj[phyCtrllerInstId].gblCfgParams.numPaRAMSets - 1U);
510 edma3_qdma_ch_min_val[phyCtrllerInstId] = edma3_link_ch_max_val[phyCtrllerInstId] + 1U;
511 edma3_qdma_ch_max_val[phyCtrllerInstId] = edma3_qdma_ch_min_val[phyCtrllerInstId] + (resMgrObj[phyCtrllerInstId].gblCfgParams.numQdmaChannels - 1U);
512 edma3_log_ch_max_val[phyCtrllerInstId] = edma3_qdma_ch_max_val[phyCtrllerInstId];
514 resMgrObj[phyCtrllerInstId].phyCtrllerInstId = phyCtrllerInstId;
515 resMgrObj[phyCtrllerInstId].state = EDMA3_RM_CREATED;
516 resMgrObj[phyCtrllerInstId].numOpens = 0U;
518 /* Make all the RM instances for this EDMA3 HW NULL */
519 for (count = 0U; count < EDMA3_MAX_RM_INSTANCES; count++)
520 {
521 edma3MemZero((void *)((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
522 sizeof(EDMA3_RM_Instance));
524 /* Also make this data structure NULL */
525 edma3MemZero((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
526 sizeof(EDMA3_RM_InstanceInitConfig));
527 }
529 /* Initialize the global edma3DmaChTccMapping array with EDMA3_MAX_TCC */
530 for ( count = 0U;
531 count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels;
532 count++
533 )
534 {
535 edma3DmaChTccMapping[phyCtrllerInstId][count] = EDMA3_MAX_TCC;
536 }
538 /* Initialize the global edma3QdmaChTccMapping array with EDMA3_MAX_TCC */
539 for ( count = 0U;
540 count < resMgrObj[phyCtrllerInstId].gblCfgParams.numQdmaChannels;
541 count++
542 )
543 {
544 edma3QdmaChTccMapping[phyCtrllerInstId][count] = EDMA3_MAX_TCC;
545 }
547 /* Reset edma3RmChBoundRes Array*/
548 for (count = 0U; count < EDMA3_MAX_LOGICAL_CH; count++)
549 {
550 edma3RmChBoundRes[phyCtrllerInstId][count].paRAMId = -1;
551 edma3RmChBoundRes[phyCtrllerInstId][count].tcc = EDMA3_MAX_TCC;
552 }
554 /* Make the contiguousParamRes array NULL */
555 edma3MemZero((void *)(&(contiguousParamRes[0U])),
556 sizeof(contiguousParamRes));
559 /**
560 * Check the misc configuration options structure.
561 * Check whether the global registers' initialization
562 * is required or not.
563 * It is required ONLY if RM is running on the Master Processor.
564 */
565 if (NULL != miscOpt)
566 {
567 if (miscOpt->isSlave == FALSE)
568 {
569 /* It is a master. */
570 edma3GlobalRegionInit(phyCtrllerInstId, (resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels));
571 }
572 }
573 else
574 {
575 /* By default, global registers will be initialized. */
576 edma3GlobalRegionInit(phyCtrllerInstId, (resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels));
577 }
578 }
579 }
581 return result;
582 }
584 EDMA3_RM_Result EDMA3_RM_delete (uint32_t phyCtrllerInstId,
585 const void *param)
586 {
587 EDMA3_RM_Result result = EDMA3_RM_SOK;
589 /* If parameter checking is enabled... */
590 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
591 if (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
592 {
593 result = EDMA3_RM_E_INVALID_PARAM;
594 }
595 #endif
597 /* Check if the parameters are OK. */
598 if (EDMA3_RM_SOK == result)
599 {
600 /**
601 * If number of RM Instances is 0, then state should be
602 * EDMA3_RM_CLOSED OR EDMA3_RM_CREATED.
603 */
604 if ((0 == resMgrObj[phyCtrllerInstId].numOpens)
605 && ((resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CLOSED)
606 && (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CREATED)))
607 {
608 result = EDMA3_RM_E_OBJ_NOT_CLOSED;
609 }
610 else
611 {
612 /**
613 * If number of RM Instances is NOT 0, then this function
614 * SHOULD NOT be called by anybody.
615 */
616 if (0 != resMgrObj[phyCtrllerInstId].numOpens)
617 {
618 result = EDMA3_RM_E_INVALID_STATE;
619 }
620 else
621 {
622 /** Change state to EDMA3_RM_DELETED */
623 resMgrObj[phyCtrllerInstId].state = EDMA3_RM_DELETED;
625 /* Reset the Allocated TCCs Array also. */
626 allocatedTCCs[phyCtrllerInstId][0U] = 0x0U;
627 allocatedTCCs[phyCtrllerInstId][1U] = 0x0U;
629 /* Also, reset the RM Object Global Config Info */
630 edma3MemZero((void *)&(resMgrObj[phyCtrllerInstId].gblCfgParams),
631 sizeof(EDMA3_RM_GblConfigParams));
632 }
633 }
634 }
636 return result;
637 }
639 EDMA3_RM_Handle EDMA3_RM_open (uint32_t phyCtrllerInstId,
640 const EDMA3_RM_Param *initParam,
641 EDMA3_RM_Result *errorCode)
642 {
643 uint32_t intState = 0U;
644 uint32_t resMgrIdx = 0U;
645 EDMA3_RM_Result result = EDMA3_RM_SOK;
646 EDMA3_RM_Obj *rmObj = NULL;
647 EDMA3_RM_Instance *rmInstance = NULL;
648 EDMA3_RM_Instance *temp_ptr_rm_inst = NULL;
649 EDMA3_RM_Handle retVal = NULL;
650 uint32_t dmaChDwrds = 0U;
651 uint32_t paramSetDwrds = 0U;
652 uint32_t tccDwrds = 0U;
653 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
655 #ifdef GENERIC
656 /* GENERIC libraries don't come with a default confifguration, always
657 needs to be supplied with a parameter */
658 if ((initParam == NULL) || (initParam->rmInstInitConfig == NULL))
659 {
660 result = EDMA3_RM_E_INVALID_PARAM;
661 }
662 #endif
665 /* If parameter checking is enabled... */
666 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
667 if (((initParam == NULL)
668 || (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES))
669 || (errorCode == NULL))
670 {
671 result = EDMA3_RM_E_INVALID_PARAM;
672 }
673 #endif
675 /* Check if the parameters are OK. */
676 if (EDMA3_RM_SOK == result)
677 {
678 /* Check whether the semaphore handle is null or not */
679 if (NULL == initParam->rmSemHandle)
680 {
681 result = EDMA3_RM_E_INVALID_PARAM;
682 }
683 else
684 {
685 rmObj = &resMgrObj[phyCtrllerInstId];
686 if (
687 (NULL == rmObj)
688 || (initParam->regionId >=
689 resMgrObj[phyCtrllerInstId].gblCfgParams.numRegions)
690 )
691 {
692 result = EDMA3_RM_E_INVALID_PARAM;
693 }
694 else
695 {
696 edma3OsProtectEntry (phyCtrllerInstId,
697 EDMA3_OS_PROTECT_INTERRUPT,
698 &intState);
700 /** Check state of RM Object.
701 * If no RM instance is opened and this is the first one,
702 * then state should be created/closed.
703 */
704 if ((rmObj->numOpens == 0) &&
705 ((rmObj->state != EDMA3_RM_CREATED) &&
706 (rmObj->state != EDMA3_RM_CLOSED)))
707 {
708 result = EDMA3_RM_E_INVALID_STATE;
709 edma3OsProtectExit (phyCtrllerInstId,
710 EDMA3_OS_PROTECT_INTERRUPT,
711 intState);
712 }
713 else
714 {
715 /**
716 * If num of instances opened is more than 0 and less than
717 * max allowed, then state should be opened.
718 */
719 if (((rmObj->numOpens > 0) &&
720 (rmObj->numOpens < EDMA3_MAX_RM_INSTANCES))
721 && (rmObj->state != EDMA3_RM_OPENED))
722 {
723 result = EDMA3_RM_E_INVALID_STATE;
724 edma3OsProtectExit (phyCtrllerInstId,
725 EDMA3_OS_PROTECT_INTERRUPT,
726 intState);
727 }
728 else
729 {
730 /* Check if max opens have passed */
731 if (rmObj->numOpens >= EDMA3_MAX_RM_INSTANCES)
732 {
733 result = EDMA3_RM_E_MAX_RM_INST_OPENED;
734 edma3OsProtectExit (phyCtrllerInstId,
735 EDMA3_OS_PROTECT_INTERRUPT,
736 intState);
737 }
738 }
739 }
740 }
741 }
742 }
744 if (EDMA3_RM_SOK == result)
745 {
746 /*
747 * Check whether the RM instance is Master or not.
748 * If it is master, check whether a master already exists
749 * or not. There should NOT be more than 1 master.
750 * Return error code if master already exists
751 */
752 if ((TRUE == masterExists[phyCtrllerInstId]) && (TRUE == initParam->isMaster))
753 {
754 /* No two masters should exist, return error */
755 result = EDMA3_RM_E_RM_MASTER_ALREADY_EXISTS;
756 edma3OsProtectExit (phyCtrllerInstId,
757 EDMA3_OS_PROTECT_INTERRUPT,
758 intState);
759 }
760 else
761 {
762 /* Create Res Mgr Instance */
763 for (resMgrIdx = 0U; resMgrIdx < EDMA3_MAX_RM_INSTANCES; resMgrIdx++)
764 {
765 temp_ptr_rm_inst = ((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
767 if (NULL != temp_ptr_rm_inst)
768 {
769 if (NULL == temp_ptr_rm_inst->pResMgrObjHandle)
770 {
771 /* Handle to the EDMA3 HW Object */
772 temp_ptr_rm_inst->pResMgrObjHandle = rmObj;
773 /* Handle of the Res Mgr Instance */
774 rmInstance = temp_ptr_rm_inst;
776 /* Also make this data structure NULL, just for safety. */
777 edma3MemZero((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
778 sizeof(EDMA3_RM_InstanceInitConfig));
780 break;
781 }
782 }
783 }
785 /* Check whether a RM instance has been created or not */
786 if (NULL == rmInstance)
787 {
788 result = EDMA3_RM_E_MAX_RM_INST_OPENED;
789 edma3OsProtectExit (phyCtrllerInstId,
790 EDMA3_OS_PROTECT_INTERRUPT,
791 intState);
792 }
793 else
794 {
795 /* Copy the InitPaRAM first */
796 edma3MemCpy((void *)(&rmInstance->initParam),
797 (const void *)(initParam),
798 sizeof (EDMA3_RM_Param));
800 if (rmObj->gblCfgParams.globalRegs != NULL)
801 {
802 globalRegs = (volatile EDMA3_CCRL_Regs *)
803 (rmObj->gblCfgParams.globalRegs);
804 rmInstance->shadowRegs = (EDMA3_CCRL_ShadowRegs *)
805 &(globalRegs->SHADOW[rmInstance->initParam.regionId]);
807 /* copy the instance specific semaphore handle */
808 rmInstance->initParam.rmSemHandle = initParam->rmSemHandle;
810 /**
811 * Check whether user has passed information about resources
812 * owned and reserved by this instance. This is region specific
813 * information. If he has not passed, dafault static config info will be taken
814 * from the config file edma3Cfg.c, according to the regionId specified.
815 *
816 * resMgrIdx specifies the RM instance number created just now.
817 * Use it to populate the userInitConfig [].
818 */
819 #ifndef GENERIC
820 if (NULL == initParam->rmInstInitConfig)
821 {
822 /* Take the info from the specific config file */
823 edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
824 (const void *)(&defInstInitConfig[phyCtrllerInstId][initParam->regionId]),
825 sizeof (EDMA3_RM_InstanceInitConfig));
826 }
827 else
828 {
829 #endif
830 /* User has passed the region specific info. */
831 edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
832 (const void *)(initParam->rmInstInitConfig),
833 sizeof (EDMA3_RM_InstanceInitConfig));
834 #ifndef GENERIC
835 }
836 #endif
838 rmInstance->initParam.rmInstInitConfig =
839 ((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
841 dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / 32U;
842 if (dmaChDwrds == 0)
843 {
844 /* In case DMA channels are < 32 */
845 dmaChDwrds = 1;
846 }
848 paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / 32U;
849 if (paramSetDwrds == 0)
850 {
851 /* In case PaRAM Sets are < 32 */
852 paramSetDwrds = 1;
853 }
855 tccDwrds = rmObj->gblCfgParams.numTccs / 32U;
856 if (tccDwrds == 0)
857 {
858 /* In case TCCs are < 32 */
859 tccDwrds = 1;
860 }
862 for (resMgrIdx = 0U; resMgrIdx < dmaChDwrds; ++resMgrIdx)
863 {
864 rmInstance->avlblDmaChannels[resMgrIdx]
865 = rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resMgrIdx];
866 }
868 rmInstance->avlblQdmaChannels[0U]
869 = rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0U];
871 for (resMgrIdx = 0U; resMgrIdx < paramSetDwrds; ++resMgrIdx)
872 {
873 rmInstance->avlblPaRAMSets[resMgrIdx]
874 = rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[resMgrIdx];
875 }
877 for (resMgrIdx = 0U; resMgrIdx < tccDwrds; ++resMgrIdx)
878 {
879 rmInstance->avlblTccs [resMgrIdx]
880 = rmInstance->initParam.rmInstInitConfig->ownTccs[resMgrIdx];
881 }
883 /*
884 * Mark the PaRAM Sets corresponding to DMA channels as RESERVED.
885 * For e.g. on a platform where only 32 DMA channels exist,
886 * mark the first 32 PaRAM Sets as reserved. These param sets
887 * will not be returned in case user requests for ANY link
888 * channel.
889 */
890 for (resMgrIdx = 0U; resMgrIdx < rmObj->gblCfgParams.numDmaChannels; ++resMgrIdx)
891 {
892 rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[resMgrIdx/32U] |= ((uint32_t)1U<<(resMgrIdx%32U));
893 }
895 /*
896 * If the EDMA RM instance is MASTER (ie. initParam->isMaster
897 * is TRUE), save the region ID.
898 * Only this shadow region will receive the
899 * EDMA3 interrupts, if enabled.
900 */
901 if (TRUE == initParam->isMaster)
902 {
903 /* Store the region id to use it in the ISRs */
904 edma3RegionId = rmInstance->initParam.regionId;
905 masterExists[phyCtrllerInstId] = TRUE;
906 }
908 if (TRUE == initParam->regionInitEnable)
909 {
910 edma3ShadowRegionInit (rmInstance);
911 }
913 /**
914 * By default, PaRAM Sets allocated using this RM Instance
915 * will get cleared during their allocation.
916 * User can stop their clearing by calling specific IOCTL
917 * command.
918 */
919 rmInstance->paramInitRequired = TRUE;
922 /**
923 * By default, during the EDMA3_RM_allocLogicalChannel (),
924 * global EDMA3 registers (DCHMAP/QCHMAP) and the allocated
925 * PaRAM Set will be programmed accordingly, for users using this
926 * RM Instance.
927 * User can stop their pre-programming by calling
928 * EDMA3_RM_IOCTL_SET_GBL_REG_MODIFY_OPTION
929 * IOCTL command.
930 */
931 rmInstance->regModificationRequired = TRUE;
934 if (EDMA3_RM_SOK == result)
935 {
936 rmObj->state = EDMA3_RM_OPENED;
937 /* Increase the Instance count */
938 resMgrObj[phyCtrllerInstId].numOpens++;
939 retVal = rmInstance;
940 }
941 }
942 else
943 {
944 result = EDMA3_RM_E_INVALID_PARAM;
945 }
947 edma3OsProtectExit (phyCtrllerInstId,
948 EDMA3_OS_PROTECT_INTERRUPT,
949 intState);
950 }
951 }
952 }
954 *errorCode = result;
955 return (EDMA3_RM_Handle)retVal;
956 }
958 EDMA3_RM_Result EDMA3_RM_close (EDMA3_RM_Handle hEdmaResMgr,
959 const void *param)
960 {
961 EDMA3_RM_Result result = EDMA3_RM_SOK;
962 uint32_t intState = 0U;
963 uint32_t resMgrIdx = 0U;
964 EDMA3_RM_Obj *rmObj = NULL;
965 EDMA3_RM_Instance *rmInstance = NULL;
966 uint32_t dmaChDwrds;
967 uint32_t paramSetDwrds;
968 uint32_t tccDwrds;
970 /* If parameter checking is enabled... */
971 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
972 if (NULL == hEdmaResMgr)
973 {
974 result = EDMA3_RM_E_INVALID_PARAM;
975 }
976 #endif
978 /* Check if the parameters are OK. */
979 if (EDMA3_RM_SOK == result)
980 {
981 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
982 rmObj = rmInstance->pResMgrObjHandle;
984 if (rmObj == NULL)
985 {
986 result = (EDMA3_RM_E_INVALID_PARAM);
987 }
988 else
989 {
990 /* Check state of driver, state should be opened */
991 if (rmObj->state != EDMA3_RM_OPENED)
992 {
993 result = (EDMA3_RM_E_OBJ_NOT_OPENED);
994 }
995 else
996 {
997 dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / 32U;
998 paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / 32U;
999 tccDwrds = rmObj->gblCfgParams.numTccs / 32U;
1001 /* Set the instance config as NULL*/
1002 for (resMgrIdx = 0U; resMgrIdx < dmaChDwrds; ++resMgrIdx)
1003 {
1004 rmInstance->avlblDmaChannels[resMgrIdx] = 0x0U;
1005 }
1006 for (resMgrIdx = 0U; resMgrIdx < paramSetDwrds; ++resMgrIdx)
1007 {
1008 rmInstance->avlblPaRAMSets[resMgrIdx] = 0x0U;
1009 }
1010 rmInstance->avlblQdmaChannels[0U] = 0x0U;
1011 for (resMgrIdx = 0U; resMgrIdx < tccDwrds; ++resMgrIdx)
1012 {
1013 rmInstance->avlblTccs[resMgrIdx] = 0x0U;
1014 }
1016 /**
1017 * If this is the Master Instance, reset the static variable
1018 * 'masterExists[]'.
1019 */
1020 if (TRUE == rmInstance->initParam.isMaster)
1021 {
1022 masterExists[rmObj->phyCtrllerInstId] = FALSE;
1023 edma3RegionId = EDMA3_MAX_REGIONS;
1024 }
1026 /* Reset the Initparam for this RM Instance */
1027 edma3MemZero((void *)&(rmInstance->initParam),
1028 sizeof(EDMA3_RM_Param));
1030 /* Critical section starts */
1031 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
1032 EDMA3_OS_PROTECT_INTERRUPT,
1033 &intState);
1035 /* Decrease the Number of Opens */
1036 --rmObj->numOpens;
1037 if (0 == rmObj->numOpens)
1038 {
1039 edma3MemZero((void *)&(edma3RmChBoundRes[rmObj->phyCtrllerInstId]),
1040 sizeof(edma3RmChBoundRes[rmObj->phyCtrllerInstId]));
1042 rmObj->state = EDMA3_RM_CLOSED;
1043 }
1045 /* Critical section ends */
1046 edma3OsProtectExit (rmObj->phyCtrllerInstId,
1047 EDMA3_OS_PROTECT_INTERRUPT,
1048 intState);
1050 rmInstance->pResMgrObjHandle = NULL;
1051 rmInstance->shadowRegs = NULL;
1052 rmInstance = NULL;
1053 }
1054 }
1055 }
1057 return result;
1058 }
1060 EDMA3_RM_Result EDMA3_RM_allocResource(EDMA3_RM_Handle hEdmaResMgr,
1061 EDMA3_RM_ResDesc *resObj)
1062 {
1063 EDMA3_RM_Instance *rmInstance = NULL;
1064 EDMA3_RM_Obj *rmObj = NULL;
1065 EDMA3_RM_Result result = EDMA3_RM_SOK;
1066 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
1067 uint32_t avlblIdx = 0U;
1068 uint32_t resIdClr = 0x0;
1069 uint32_t resIdSet = 0x0;
1070 uint32_t resId;
1071 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1072 uint32_t mapXbarEvtToChanFlag = FALSE;
1073 uint32_t xBarEvtBeforeMap = 0;
1074 uint32_t edma3Id;
1076 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1077 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1078 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1079 EDMA3_DVT_dCOUNTER,
1080 EDMA3_DVT_dNONE,
1081 EDMA3_DVT_dNONE));
1082 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1084 /* If parameter checking is enabled... */
1085 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1086 if ((hEdmaResMgr == NULL) || (resObj == NULL))
1087 {
1088 result = (EDMA3_RM_E_INVALID_PARAM);
1089 }
1090 #endif
1092 /* Check if the parameters are OK. */
1093 if (EDMA3_RM_SOK == result)
1094 {
1095 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1096 rmObj = rmInstance->pResMgrObjHandle;
1098 if ((rmObj == NULL) ||
1099 (rmObj->gblCfgParams.globalRegs == NULL))
1100 {
1101 result = (EDMA3_RM_E_INVALID_PARAM);
1102 }
1103 else
1104 {
1105 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1106 edma3Id = rmObj->phyCtrllerInstId;
1107 resId = resObj->resId;
1109 resIdClr = (uint32_t)(~((uint32_t)1U << (resId%32U)));
1110 resIdSet = (1U << (resId%32U));
1112 if ( rmInstance->mapXbarToChan != NULL)
1113 {
1114 xBarEvtBeforeMap = resId;
1115 if ((resId > rmObj->gblCfgParams.numDmaChannels) &&
1116 (resId != EDMA3_RM_RES_ANY) &&
1117 (resObj->type == EDMA3_RM_RES_DMA_CHANNEL))
1118 {
1119 result = rmInstance->mapXbarToChan(xBarEvtBeforeMap,
1120 &resObj->resId,
1121 &rmInstance->rmXbarToEvtMapConfig);
1122 if (EDMA3_RM_SOK == result)
1123 {
1124 resId = resObj->resId;
1125 mapXbarEvtToChanFlag = TRUE;
1126 }
1127 }
1128 }
1130 if (result == EDMA3_RM_SOK)
1131 {
1132 /**
1133 * Take the instance specific semaphore, to prevent simultaneous
1134 * access to the shared resources.
1135 */
1136 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
1137 EDMA3_OSSEM_NO_TIMEOUT);
1138 if (EDMA3_RM_SOK == semResult)
1139 {
1140 switch (resObj->type)
1141 {
1142 case EDMA3_RM_RES_DMA_CHANNEL :
1143 {
1144 if (resId == EDMA3_RM_RES_ANY)
1145 {
1146 for (avlblIdx=0U;
1147 avlblIdx <
1148 rmObj->gblCfgParams.numDmaChannels;
1149 ++avlblIdx)
1150 {
1151 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[avlblIdx/32U])
1152 &
1153 (rmInstance->avlblDmaChannels[avlblIdx/32U])
1154 &
1155 ~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[avlblIdx/32U])
1156 &
1157 ((uint32_t)1U << (avlblIdx%32U))) != FALSE)
1158 {
1159 /*
1160 * Match found.
1161 * A resource which is owned by this instance of the
1162 * Resource Manager and which is presently available
1163 * and which has not been reserved - is found.
1164 */
1165 resObj->resId = avlblIdx;
1166 /*
1167 * Mark the 'match found' resource as "Not Available"
1168 * for future requests
1169 */
1170 rmInstance->avlblDmaChannels[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
1172 /**
1173 * Check if the register modification flag is
1174 * set or not.
1175 */
1176 if (TRUE == rmInstance->regModificationRequired)
1177 {
1178 /**
1179 * Enable the DMA channel in the
1180 * DRAE/DRAEH registers also.
1181 */
1182 if (avlblIdx < 32U)
1183 {
1184 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1185 |= ((uint32_t)0x1U << avlblIdx);
1186 }
1187 else
1188 {
1189 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1190 |= ((uint32_t)0x1U << (avlblIdx - 32U));
1191 }
1192 }
1194 result = EDMA3_RM_SOK;
1195 break;
1196 }
1197 }
1198 /*
1199 * If none of the owned resources of this type is available
1200 * then report "All Resources of this type not available" error
1201 */
1202 if (avlblIdx == rmObj->gblCfgParams.numDmaChannels)
1203 {
1204 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1205 }
1206 }
1207 else
1208 {
1209 if (resId < rmObj->gblCfgParams.numDmaChannels)
1210 {
1211 /*
1212 * Check if specified resource is owned
1213 * by this instance of the resource manager
1214 */
1215 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resId/32U])&(resIdSet))!=FALSE)
1216 {
1217 /* Now check if specified resource is available presently*/
1218 if (((rmInstance->avlblDmaChannels[resId/32U])&(resIdSet))!=FALSE)
1219 {
1220 /*
1221 * Mark the specified channel as "Not Available"
1222 * for future requests
1223 */
1224 rmInstance->avlblDmaChannels[resId/32U] &= resIdClr;
1226 /**
1227 * Check if the register modification flag is
1228 * set or not.
1229 */
1230 if (TRUE == rmInstance->regModificationRequired)
1231 {
1232 if (resId < 32U)
1233 {
1234 rmInstance->shadowRegs->EECR = (1UL << resId);
1236 /**
1237 * Enable the DMA channel in the
1238 * DRAE registers also.
1239 */
1240 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1241 |= ((uint32_t)0x1U << resId);
1242 }
1243 else
1244 {
1245 rmInstance->shadowRegs->EECRH = (1UL << resId);
1247 /**
1248 * Enable the DMA channel in the
1249 * DRAEH registers also.
1250 */
1251 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1252 |= ((uint32_t)0x1U << (resId - 32U));
1253 }
1254 }
1256 result = EDMA3_RM_SOK;
1257 }
1258 else
1259 {
1260 /* Specified resource is owned but is already booked */
1261 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1262 }
1263 }
1264 else
1265 {
1266 /*
1267 * Specified resource is not owned by this instance
1268 * of the Resource Manager
1269 */
1270 result = EDMA3_RM_E_RES_NOT_OWNED;
1271 }
1272 }
1273 else
1274 {
1275 result = EDMA3_RM_E_INVALID_PARAM;
1276 }
1277 }
1278 }
1279 break;
1281 case EDMA3_RM_RES_QDMA_CHANNEL :
1282 {
1283 if (resId == EDMA3_RM_RES_ANY)
1284 {
1285 for (avlblIdx=0U; avlblIdx<rmObj->gblCfgParams.numQdmaChannels; ++avlblIdx)
1286 {
1287 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[avlblIdx/32U])
1288 &
1289 (rmInstance->avlblQdmaChannels[avlblIdx/32U])
1290 &
1291 ~(rmInstance->initParam.rmInstInitConfig->resvdQdmaChannels[avlblIdx/32U])
1292 &
1293 ((uint32_t)1U << (avlblIdx%32U))) != FALSE)
1294 {
1295 resObj->resId = avlblIdx;
1296 rmInstance->avlblQdmaChannels[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
1298 /**
1299 * Check if the register modification flag is
1300 * set or not.
1301 */
1302 if (TRUE == rmInstance->regModificationRequired)
1303 {
1304 /**
1305 * Enable the QDMA channel in the
1306 * QRAE register also.
1307 */
1308 gblRegs->QRAE[rmInstance->initParam.regionId]
1309 |= ((uint32_t)0x1U << avlblIdx);
1310 }
1312 result = EDMA3_RM_SOK;
1313 break;
1314 }
1315 }
1316 /*
1317 * If none of the owned resources of this type is available
1318 * then report "All Resources of this type not available" error
1319 */
1320 if (avlblIdx == rmObj->gblCfgParams.numQdmaChannels)
1321 {
1322 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1323 }
1324 }
1325 else
1326 {
1327 if (resId < rmObj->gblCfgParams.numQdmaChannels)
1328 {
1329 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32U])&(resIdSet))!=FALSE)
1330 {
1331 if (((rmInstance->avlblQdmaChannels [resId/32U])&(resIdSet))!=FALSE)
1332 {
1333 rmInstance->avlblQdmaChannels [resId/32U] &= resIdClr;
1335 /**
1336 * Check if the register modification flag is
1337 * set or not.
1338 */
1339 if (TRUE == rmInstance->regModificationRequired)
1340 {
1341 /**
1342 * Enable the QDMA channel in the
1343 * QRAE register also.
1344 */
1345 gblRegs->QRAE[rmInstance->initParam.regionId]
1346 |= ((uint32_t)0x1U << resId);
1347 }
1349 result = EDMA3_RM_SOK;
1350 }
1351 else
1352 {
1353 /* Specified resource is owned but is already booked */
1354 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1355 }
1356 }
1357 else
1358 {
1359 /*
1360 * Specified resource is not owned by this instance
1361 * of the Resource Manager
1362 */
1363 result = EDMA3_RM_E_RES_NOT_OWNED;
1364 }
1365 }
1366 else
1367 {
1368 result = EDMA3_RM_E_INVALID_PARAM;
1369 }
1370 }
1371 }
1372 break;
1374 case EDMA3_RM_RES_TCC :
1375 {
1376 if (resId == EDMA3_RM_RES_ANY)
1377 {
1378 for (avlblIdx=0U; avlblIdx<rmObj->gblCfgParams.numTccs; ++avlblIdx)
1379 {
1380 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [avlblIdx/32U])
1381 & (rmInstance->avlblTccs [avlblIdx/32U])
1382 & ~(rmInstance->initParam.rmInstInitConfig->resvdTccs [avlblIdx/32U])
1383 & ((uint32_t)1U << (avlblIdx%32U)))!=FALSE)
1384 {
1385 resObj->resId = avlblIdx;
1386 rmInstance->avlblTccs [avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
1388 /**
1389 * Check if the register modification flag is
1390 * set or not.
1391 */
1392 if (TRUE == rmInstance->regModificationRequired)
1393 {
1394 /**
1395 * Enable the Interrupt channel in the
1396 * DRAE/DRAEH registers also.
1397 * Also, If the region id coming from this
1398 * RM instance is same as the Master RM
1399 * Instance's region id, only then we will be
1400 * getting the interrupts on the same side.
1401 * So save the TCC in the allocatedTCCs[] array.
1402 */
1403 if (avlblIdx < 32U)
1404 {
1405 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1406 |= ((uint32_t)0x1U << avlblIdx);
1408 /**
1409 * Do not modify this global array if the register
1410 * modificatio flag is not set.
1411 * Reason being is based on this flag, the IPR/ICR
1412 * or error bit is cleared in the completion or
1413 * error handler ISR.
1414 */
1415 if (edma3RegionId == rmInstance->initParam.regionId)
1416 {
1417 allocatedTCCs[edma3Id][0U] |= ((uint32_t)0x1U << avlblIdx);
1418 }
1419 }
1420 else
1421 {
1422 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1423 |= ((uint32_t)0x1U << (avlblIdx - 32U));
1425 /**
1426 * Do not modify this global array if the register
1427 * modificatio flag is not set.
1428 * Reason being is based on this flag, the IPR/ICR
1429 * or error bit is cleared in the completion or
1430 * error handler ISR.
1431 */
1432 if (edma3RegionId == rmInstance->initParam.regionId)
1433 {
1434 allocatedTCCs[edma3Id][1U] |= ((uint32_t)0x1U << (avlblIdx - 32U));
1435 }
1436 }
1437 }
1440 result = EDMA3_RM_SOK;
1441 break;
1442 }
1443 }
1444 /*
1445 * If none of the owned resources of this type is available
1446 * then report "All Resources of this type not available" error
1447 */
1448 if ( avlblIdx == rmObj->gblCfgParams.numTccs)
1449 {
1450 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1451 }
1452 }
1453 else
1454 {
1455 if (resId < rmObj->gblCfgParams.numTccs)
1456 {
1457 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32U])&(resIdSet))!=FALSE)
1458 {
1459 if (((rmInstance->avlblTccs [resId/32U])&(resIdSet))!=FALSE)
1460 {
1461 rmInstance->avlblTccs [resId/32U] &= resIdClr;
1463 /**
1464 * Check if the register modification flag is
1465 * set or not.
1466 */
1467 if (TRUE == rmInstance->regModificationRequired)
1468 {
1469 /**
1470 * Enable the Interrupt channel in the
1471 * DRAE/DRAEH registers also.
1472 * Also, If the region id coming from this
1473 * RM instance is same as the Master RM
1474 * Instance's region id, only then we will be
1475 * getting the interrupts on the same side.
1476 * So save the TCC in the allocatedTCCs[] array.
1477 */
1478 if (resId < 32U)
1479 {
1480 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1481 |= ((uint32_t)0x1U << resId);
1483 /**
1484 * Do not modify this global array if the register
1485 * modificatio flag is not set.
1486 * Reason being is based on this flag, the IPR/ICR
1487 * or error bit is cleared in the completion or
1488 * error handler ISR.
1489 */
1490 if (edma3RegionId == rmInstance->initParam.regionId)
1491 {
1492 allocatedTCCs[edma3Id][0U] |= ((uint32_t)0x1U << resId);
1493 }
1494 }
1495 else
1496 {
1497 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1498 |= ((uint32_t)0x1U << (resId - 32U));
1500 /**
1501 * Do not modify this global array if the register
1502 * modificatio flag is not set.
1503 * Reason being is based on this flag, the IPR/ICR
1504 * or error bit is cleared in the completion or
1505 * error handler ISR.
1506 */
1507 if (edma3RegionId == rmInstance->initParam.regionId)
1508 {
1509 allocatedTCCs[edma3Id][1U] |= ((uint32_t)0x1U << (resId - 32U));
1510 }
1511 }
1512 }
1514 result = EDMA3_RM_SOK;
1515 }
1516 else
1517 {
1518 /* Specified resource is owned but is already booked */
1519 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1520 }
1521 }
1522 else
1523 {
1524 /*
1525 * Specified resource is not owned by this instance
1526 * of the Resource Manager
1527 */
1528 result = EDMA3_RM_E_RES_NOT_OWNED;
1529 }
1530 }
1531 else
1532 {
1533 result = EDMA3_RM_E_INVALID_PARAM;
1534 }
1535 }
1536 }
1537 break;
1539 case EDMA3_RM_RES_PARAM_SET :
1540 {
1541 if (resId == EDMA3_RM_RES_ANY)
1542 {
1543 for (avlblIdx=0U; avlblIdx<rmObj->gblCfgParams.numPaRAMSets; ++avlblIdx)
1544 {
1545 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [avlblIdx/32U])
1546 &
1547 (rmInstance->avlblPaRAMSets [avlblIdx/32U])
1548 &
1549 ~(rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets [avlblIdx/32U])
1550 &
1551 ((uint32_t)1U << (avlblIdx%32U)))!=FALSE)
1552 {
1553 resObj->resId = avlblIdx;
1554 rmInstance->avlblPaRAMSets [avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
1556 /**
1557 * Also, make the actual PARAM Set NULL, checking the flag
1558 * whether it is required or not.
1559 */
1560 if ((TRUE == rmInstance->regModificationRequired)
1561 && (TRUE == rmInstance->paramInitRequired))
1562 {
1563 edma3MemZero((void *)(&gblRegs->PARAMENTRY[avlblIdx]),
1564 sizeof(gblRegs->PARAMENTRY[avlblIdx]));
1565 }
1567 result = EDMA3_RM_SOK;
1568 break;
1569 }
1570 }
1571 /*
1572 * If none of the owned resources of this type is available
1573 * then report "All Resources of this type not available" error
1574 */
1575 if ( avlblIdx == rmObj->gblCfgParams.numPaRAMSets)
1576 {
1577 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1578 }
1579 }
1580 else
1581 {
1582 if (resId < rmObj->gblCfgParams.numPaRAMSets)
1583 {
1584 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32U])&(resIdSet))!=FALSE)
1585 {
1586 if (((rmInstance->avlblPaRAMSets [resId/32U])&(resIdSet)) !=FALSE)
1587 {
1588 rmInstance->avlblPaRAMSets [resId/32U] &= resIdClr;
1590 /**
1591 * Also, make the actual PARAM Set NULL, checking the flag
1592 * whether it is required or not.
1593 */
1594 if ((TRUE == rmInstance->regModificationRequired)
1595 && (TRUE == rmInstance->paramInitRequired))
1596 {
1597 edma3MemZero((void *)(&gblRegs->PARAMENTRY[resId]),
1598 sizeof(gblRegs->PARAMENTRY[resId]));
1599 }
1601 result = EDMA3_RM_SOK;
1602 }
1603 else
1604 {
1605 /* Specified resource is owned but is already booked */
1606 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1607 }
1608 }
1609 else
1610 {
1611 /*
1612 * Specified resource is not owned by this instance
1613 * of the Resource Manager
1614 */
1615 result = EDMA3_RM_E_RES_NOT_OWNED;
1616 }
1617 }
1618 else
1619 {
1620 result = EDMA3_RM_E_INVALID_PARAM;
1621 }
1622 }
1623 }
1624 break;
1626 default:
1627 result = EDMA3_RM_E_INVALID_PARAM;
1628 break;
1629 }
1631 /* Return the semaphore back */
1632 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
1633 }
1634 }
1635 }
1636 }
1638 /**
1639 * Check the Resource Allocation Result 'result' first. If Resource
1640 * Allocation has resulted in an error, return it (having more priority than
1641 * semResult.
1642 * Else, return semResult.
1643 */
1644 if (EDMA3_RM_SOK == result)
1645 {
1646 /**
1647 * Resource Allocation successful, return semResult for returning
1648 * semaphore.
1649 */
1650 result = semResult;
1651 if ((rmInstance->configScrMapXbarToEvt != NULL) &&
1652 (mapXbarEvtToChanFlag == TRUE))
1653 {
1654 rmInstance->configScrMapXbarToEvt(xBarEvtBeforeMap, resObj->resId);
1655 }
1656 }
1658 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1659 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1660 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1661 EDMA3_DVT_dCOUNTER,
1662 EDMA3_DVT_dNONE,
1663 EDMA3_DVT_dNONE));
1664 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1666 return result;
1667 }
1669 EDMA3_RM_Result EDMA3_RM_freeResource(EDMA3_RM_Handle hEdmaResMgr,
1670 const EDMA3_RM_ResDesc *resObj)
1671 {
1672 EDMA3_RM_Instance *rmInstance = NULL;
1673 EDMA3_RM_Obj *rmObj = NULL;
1674 EDMA3_RM_Result result = EDMA3_RM_SOK;
1675 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
1676 uint32_t resId;
1677 uint32_t resIdSet = 0x0;
1678 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1679 uint32_t edma3Id;
1681 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1682 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1683 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1684 EDMA3_DVT_dCOUNTER,
1685 EDMA3_DVT_dNONE,
1686 EDMA3_DVT_dNONE));
1687 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1689 /* If parameter checking is enabled... */
1690 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1691 if ((hEdmaResMgr == NULL) || (resObj == NULL))
1692 {
1693 result = EDMA3_RM_E_INVALID_PARAM;
1694 }
1695 #endif
1697 /* Check if the parameters are OK. */
1698 if (EDMA3_RM_SOK == result)
1699 {
1700 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1701 rmObj = rmInstance->pResMgrObjHandle;
1703 if ((rmObj == NULL) ||
1704 (rmObj->gblCfgParams.globalRegs == NULL))
1705 {
1706 result = EDMA3_RM_E_INVALID_PARAM;
1707 }
1708 else
1709 {
1710 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1711 edma3Id = rmObj->phyCtrllerInstId;
1712 resId = resObj->resId;
1714 resIdSet = 1U << (resId%32U);
1716 /**
1717 * Take the instance specific semaphore, to prevent simultaneous
1718 * access to the shared resources.
1719 */
1720 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
1721 EDMA3_OSSEM_NO_TIMEOUT);
1723 if (EDMA3_RM_SOK == semResult)
1724 {
1725 switch (resObj->type)
1726 {
1727 case EDMA3_RM_RES_DMA_CHANNEL :
1728 {
1729 if (resId < rmObj->gblCfgParams.numDmaChannels)
1730 {
1731 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels [resId/32U]) & (resIdSet))!=FALSE)
1732 {
1733 if (((~(rmInstance->avlblDmaChannels[resId/32U]))&(resIdSet))!=FALSE)
1734 {
1735 /*
1736 * Mark the specified channel as "Available"
1737 * for future requests
1738 */
1739 rmInstance->avlblDmaChannels[resId/32U] |= resIdSet;
1741 /**
1742 * Check if the register modification flag is
1743 * set or not.
1744 */
1745 if (TRUE == rmInstance->regModificationRequired)
1746 {
1747 /**
1748 * DMA Channel is freed.
1749 * Reset the bit specific to the DMA channel
1750 * in the DRAE/DRAEH register also.
1751 */
1752 if (resId < 32U)
1753 {
1754 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1755 &= (~((uint32_t)0x1U << resId));
1756 }
1757 else
1758 {
1759 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1760 &= (~((uint32_t)0x1U << (resId-32U)));
1761 }
1762 }
1764 result = EDMA3_RM_SOK;
1765 }
1766 else
1767 {
1768 result = EDMA3_RM_E_RES_ALREADY_FREE;
1769 }
1770 }
1771 else
1772 {
1773 /*
1774 * Specified resource is not owned by this instance
1775 * of the Resource Manager
1776 */
1777 result = EDMA3_RM_E_RES_NOT_OWNED;
1778 }
1779 }
1780 else
1781 {
1782 result = EDMA3_RM_E_INVALID_PARAM;
1783 }
1784 }
1785 break;
1787 case EDMA3_RM_RES_QDMA_CHANNEL :
1788 {
1789 if (resId < rmObj->gblCfgParams.numQdmaChannels)
1790 {
1791 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32U]) & (resIdSet))!=FALSE)
1792 {
1793 if (((~(rmInstance->avlblQdmaChannels [resId/32U])) & (resIdSet))!=FALSE)
1794 {
1795 rmInstance->avlblQdmaChannels [resId/32U] |= resIdSet;
1797 /**
1798 * Check if the register modification flag is
1799 * set or not.
1800 */
1801 if (TRUE == rmInstance->regModificationRequired)
1802 {
1803 /**
1804 * QDMA Channel is freed.
1805 * Reset the bit specific to the QDMA channel
1806 * in the QRAE register also.
1807 */
1808 gblRegs->QRAE[rmInstance->initParam.regionId]
1809 &= (~((uint32_t)0x1U << resId));
1810 }
1812 result = EDMA3_RM_SOK;
1813 }
1814 else
1815 {
1816 result = EDMA3_RM_E_RES_ALREADY_FREE;
1817 }
1818 }
1819 else
1820 {
1821 /*
1822 * Specified resource is not owned by this instance
1823 * of the Resource Manager
1824 */
1825 result = EDMA3_RM_E_RES_NOT_OWNED;
1826 }
1827 }
1828 else
1829 {
1830 result = EDMA3_RM_E_INVALID_PARAM;
1831 }
1832 }
1833 break;
1835 case EDMA3_RM_RES_TCC :
1836 {
1837 if (resId < rmObj->gblCfgParams.numTccs)
1838 {
1839 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32U]) & (resIdSet))!=FALSE)
1840 {
1841 if (((~(rmInstance->avlblTccs [resId/32U])) & (resIdSet))!=FALSE)
1842 {
1843 rmInstance->avlblTccs [resId/32U] |= resIdSet;
1845 /**
1846 * Check if the register modification flag is
1847 * set or not.
1848 */
1849 if (TRUE == rmInstance->regModificationRequired)
1850 {
1851 /**
1852 * Interrupt Channel is freed.
1853 * Reset the bit specific to the Interrupt
1854 * channel in the DRAE/DRAEH register also.
1855 * Also, if we have earlier saved this
1856 * TCC in allocatedTCCs[] array,
1857 * remove it from there too.
1858 */
1859 if (resId < 32U)
1860 {
1861 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1862 &= (~((uint32_t)0x1U << resId));
1864 if (edma3RegionId == rmInstance->initParam.regionId)
1865 {
1866 allocatedTCCs[edma3Id][0U] &= (~((uint32_t)0x1U << resId));
1867 }
1868 }
1869 else
1870 {
1871 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1872 &= (~((uint32_t)0x1U << (resId-32U)));
1874 if (edma3RegionId == rmInstance->initParam.regionId)
1875 {
1876 allocatedTCCs[edma3Id][1U] &= (~((uint32_t)0x1U << (resId -32U)));
1877 }
1878 }
1879 }
1881 result = EDMA3_RM_SOK;
1882 }
1883 else
1884 {
1885 result = EDMA3_RM_E_RES_ALREADY_FREE;
1886 }
1887 }
1888 else
1889 {
1890 /*
1891 * Specified resource is not owned by this instance
1892 * of the Resource Manager
1893 */
1894 result = EDMA3_RM_E_RES_NOT_OWNED;
1895 }
1896 }
1897 else
1898 {
1899 result = EDMA3_RM_E_INVALID_PARAM;
1900 }
1901 }
1902 break;
1904 case EDMA3_RM_RES_PARAM_SET :
1905 {
1906 if (resId < rmObj->gblCfgParams.numPaRAMSets)
1907 {
1908 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32U])&(resIdSet))!=FALSE)
1909 {
1910 if (((~(rmInstance->avlblPaRAMSets [resId/32U]))&(resIdSet))!=FALSE)
1911 {
1912 rmInstance->avlblPaRAMSets [resId/32U] |= resIdSet;
1914 result = EDMA3_RM_SOK;
1915 }
1916 else
1917 {
1918 result = EDMA3_RM_E_RES_ALREADY_FREE;
1919 }
1920 }
1921 else
1922 {
1923 /*
1924 * Specified resource is not owned by this instance
1925 * of the Resource Manager
1926 */
1927 result = EDMA3_RM_E_RES_NOT_OWNED;
1928 }
1929 }
1930 else
1931 {
1932 result = EDMA3_RM_E_INVALID_PARAM;
1933 }
1934 }
1935 break;
1937 default:
1938 result = EDMA3_RM_E_INVALID_PARAM;
1939 break;
1940 }
1941 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
1942 }
1943 }
1944 }
1946 /**
1947 * Check the Free Resource Result 'result' first. If Free Resource
1948 * has resulted in an error, return it (having more priority than
1949 * semResult.
1950 * Else, return semResult.
1951 */
1952 if (EDMA3_RM_SOK == result)
1953 {
1954 /**
1955 * Free Resource successful, return semResult for returning
1956 * semaphore.
1957 */
1958 result = semResult;
1959 }
1961 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1962 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1963 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1964 EDMA3_DVT_dCOUNTER,
1965 EDMA3_DVT_dNONE,
1966 EDMA3_DVT_dNONE));
1967 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1969 return result;
1970 }
1972 EDMA3_RM_Result EDMA3_RM_allocLogicalChannel(EDMA3_RM_Handle hEdmaResMgr,
1973 EDMA3_RM_ResDesc *lChObj,
1974 uint32_t *pParam,
1975 uint32_t *pTcc)
1976 {
1977 EDMA3_RM_ResDesc *chObj;
1978 EDMA3_RM_ResDesc resObj;
1979 EDMA3_RM_Result result = EDMA3_RM_SOK;
1980 EDMA3_RM_Instance *rmInstance = NULL;
1981 EDMA3_RM_Obj *rmObj = NULL;
1982 uint32_t mappedPaRAMId=0U;
1983 uint32_t mappedTcc = EDMA3_RM_CH_NO_TCC_MAP;
1984 int32_t paRAMId = (int32_t)EDMA3_RM_RES_ANY;
1985 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1986 uint32_t qdmaChId = EDMA3_MAX_PARAM_SETS;
1987 uint32_t edma3Id;
1989 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1990 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1991 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1992 EDMA3_DVT_dCOUNTER,
1993 EDMA3_DVT_dNONE,
1994 EDMA3_DVT_dNONE));
1995 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1997 /* If parameter checking is enabled... */
1998 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1999 if ((lChObj == NULL) || (hEdmaResMgr == NULL))
2000 {
2001 result = EDMA3_RM_E_INVALID_PARAM;
2002 }
2003 #endif
2005 /* Check if the parameters are OK. */
2006 if (EDMA3_RM_SOK == result)
2007 {
2008 chObj = lChObj;
2010 if ((chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
2011 || (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL))
2012 {
2013 /**
2014 * If the request is for a DMA or QDMA channel, check the
2015 * pParam and pTcc objects also.
2016 * For the Link channel request, they could be NULL.
2017 */
2018 /* If parameter checking is enabled... */
2019 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2020 if ((pParam == NULL) || (pTcc == NULL))
2021 {
2022 result = EDMA3_RM_E_INVALID_PARAM;
2023 }
2024 #endif
2025 }
2026 }
2028 if (result == EDMA3_RM_SOK)
2029 {
2030 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2032 if (rmInstance == NULL)
2033 {
2034 result = EDMA3_RM_E_INVALID_PARAM;
2035 }
2036 }
2038 if (result == EDMA3_RM_SOK)
2039 {
2040 rmObj = rmInstance->pResMgrObjHandle;
2042 if (rmObj == NULL)
2043 {
2044 result = EDMA3_RM_E_INVALID_PARAM;
2045 }
2046 else
2047 {
2048 if (rmObj->gblCfgParams.globalRegs == NULL)
2049 {
2050 result = EDMA3_RM_E_INVALID_PARAM;
2051 }
2052 }
2053 }
2055 if (result == EDMA3_RM_SOK)
2056 {
2057 edma3Id = rmObj->phyCtrllerInstId;
2058 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2060 switch (chObj->type)
2061 {
2062 case EDMA3_RM_RES_DMA_CHANNEL:
2063 {
2064 if ((chObj->resId == EDMA3_RM_DMA_CHANNEL_ANY)
2065 || (chObj->resId == EDMA3_RM_RES_ANY))
2066 {
2067 /* Request for ANY DMA channel. */
2068 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2069 resObj.resId = EDMA3_RM_RES_ANY;
2070 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2072 if (result == EDMA3_RM_SOK)
2073 {
2074 /* DMA channel allocated successfully. */
2075 chObj->resId = resObj.resId;
2077 /**
2078 * Check the PaRAM Set user has specified for this DMA channel.
2079 * Two cases exist:
2080 * a) DCHMAP exists: Any PaRAM Set can be used
2081 * b) DCHMAP does not exist: Should not be possible
2082 * only if the channel allocated (ANY) and PaRAM requested
2083 * are same.
2084 */
2085 if ((*pParam) == EDMA3_RM_PARAM_ANY)
2086 {
2087 /* User specified ANY PaRAM Set; Check the mapping. */
2088 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2089 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2090 {
2091 /** If some PaRAM set is statically mapped to the returned
2092 * channel number, use that.
2093 */
2094 paRAMId = (int32_t)mappedPaRAMId;
2095 }
2096 }
2097 else
2098 {
2099 /* User specified some PaRAM Set; check that can be used or not. */
2100 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2101 {
2102 paRAMId = (int32_t)(*pParam);
2103 }
2104 else
2105 {
2106 /**
2107 * Channel mapping does not exist. If the PaRAM Set requested
2108 * is the same as dma channel allocated (coincidentally), it is fine.
2109 * Else return error.
2110 */
2111 if ((*pParam) != (resObj.resId))
2112 {
2113 result = EDMA3_RM_E_INVALID_PARAM;
2115 /**
2116 * Free the previously allocated DMA channel also.
2117 */
2118 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2119 }
2120 else
2121 {
2122 paRAMId = (int32_t)(*pParam);
2123 }
2124 }
2125 }
2127 mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[resObj.resId];
2128 }
2129 }
2130 else
2131 {
2132 if (chObj->resId <= edma3_dma_ch_max_val[edma3Id])
2133 {
2134 /* Request for a specific DMA channel */
2135 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2136 resObj.resId = chObj->resId;
2137 result = EDMA3_RM_allocResource(hEdmaResMgr,
2138 (EDMA3_RM_ResDesc *)&resObj);
2140 if (result == EDMA3_RM_SOK)
2141 {
2142 /**
2143 * Check the PaRAM Set user has specified for this DMA channel.
2144 * Two cases exist:
2145 * a) DCHMAP exists: Any PaRAM Set can be used
2146 * b) DCHMAP does not exist: Should not be possible
2147 * only if the channel allocated (ANY) and PaRAM requested
2148 * are same.
2149 */
2150 if ((*pParam) == EDMA3_RM_PARAM_ANY)
2151 {
2152 /* User specified ANY PaRAM Set; Check the mapping. */
2153 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2154 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2155 {
2156 /** If some PaRAM set is statically mapped to the returned
2157 * channel number, use that.
2158 */
2159 paRAMId = (int32_t)mappedPaRAMId;
2160 }
2161 }
2162 else
2163 {
2164 /* User specified some PaRAM Set; check that can be used or not. */
2165 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2166 {
2167 paRAMId = (int32_t)(*pParam);
2168 }
2169 else
2170 {
2171 /**
2172 * Channel mapping does not exist. If the PaRAM Set requested
2173 * is the same as dma channel allocated (coincidentally), it is fine.
2174 * Else return error.
2175 */
2176 if ((*pParam) != (resObj.resId))
2177 {
2178 result = EDMA3_RM_E_INVALID_PARAM;
2180 /**
2181 * Free the previously allocated DMA channel also.
2182 */
2183 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2184 }
2185 else
2186 {
2187 paRAMId = (int32_t)(*pParam);
2188 }
2189 }
2190 }
2192 mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[chObj->resId];
2193 }
2194 }
2195 else
2196 {
2197 result = EDMA3_RM_E_INVALID_PARAM;
2198 }
2199 }
2200 }
2201 break;
2204 case EDMA3_RM_RES_QDMA_CHANNEL:
2205 {
2206 if ((chObj->resId == EDMA3_RM_QDMA_CHANNEL_ANY)
2207 || (chObj->resId == EDMA3_RM_RES_ANY))
2208 {
2209 /* First request for any available QDMA channel */
2210 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2211 resObj.resId = EDMA3_RM_RES_ANY;
2212 result = EDMA3_RM_allocResource(hEdmaResMgr,
2213 (EDMA3_RM_ResDesc *)&resObj);
2215 if (result == EDMA3_RM_SOK)
2216 {
2217 /* Return the actual QDMA channel id. */
2218 chObj->resId = resObj.resId;
2220 /* Save the Logical-QDMA channel id for future use. */
2221 qdmaChId = resObj.resId + edma3_qdma_ch_min_val[edma3Id];
2223 /**
2224 * Check the PaRAM Set user has specified for this QDMA channel.
2225 * If he has specified any particular PaRAM Set, use that.
2226 */
2227 if ((*pParam) != EDMA3_RM_PARAM_ANY)
2228 {
2229 /* User specified ANY PaRAM Set; Check the mapping. */
2230 paRAMId = (int32_t)(*pParam);
2231 }
2232 }
2233 }
2234 else
2235 {
2236 if (chObj->resId < rmObj->gblCfgParams.numQdmaChannels)
2237 {
2238 /* Request for a specific QDMA channel */
2239 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2240 resObj.resId = chObj->resId;
2241 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2243 if (result == EDMA3_RM_SOK)
2244 {
2245 /* Save the Logical-QDMA channel id for future use. */
2246 qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
2248 /**
2249 * Check the PaRAM Set user has specified for this QDMA channel.
2250 * If he has specified any particular PaRAM Set, use that.
2251 */
2252 if ((*pParam) != EDMA3_RM_PARAM_ANY)
2253 {
2254 /* User specified ANY PaRAM Set; Check the mapping. */
2255 paRAMId = (int32_t)(*pParam);
2256 }
2257 }
2258 }
2259 else
2260 {
2261 result = EDMA3_RM_E_INVALID_PARAM;
2262 }
2263 }
2264 }
2265 break;
2267 case EDMA3_RM_RES_PARAM_SET:
2268 {
2269 /* Request for a LINK channel. */
2270 if ((chObj->resId == EDMA3_RM_PARAM_ANY)
2271 || (chObj->resId == EDMA3_RM_RES_ANY))
2272 {
2273 /* Request for ANY LINK channel. */
2274 paRAMId = (int32_t)EDMA3_RM_RES_ANY;
2275 }
2276 else
2277 {
2278 if (chObj->resId < edma3NumPaRAMSets)
2279 {
2280 /* Request for a Specific LINK channel. */
2281 paRAMId = (int32_t)(chObj->resId);
2282 }
2283 else
2284 {
2285 result = EDMA3_RM_E_INVALID_PARAM;
2286 }
2287 }
2289 if (result == EDMA3_RM_SOK)
2290 {
2291 /* Try to allocate the link channel */
2292 resObj.type = EDMA3_RM_RES_PARAM_SET;
2293 resObj.resId = (uint32_t)paRAMId;
2294 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2296 if (result == EDMA3_RM_SOK)
2297 {
2298 uint32_t linkCh = edma3_link_ch_min_val[edma3Id];
2300 /* Return the actual PaRAM Id. */
2301 chObj->resId = resObj.resId;
2303 /*
2304 * Search for the next Link channel place-holder available,
2305 * starting from EDMA3_RM_LINK_CH_MIN_VAL.
2306 * It will be used for future operations on the Link channel.
2307 */
2308 while ((edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId != -1)
2309 && (linkCh <= edma3_link_ch_max_val[edma3Id]))
2310 {
2311 /* Move to the next place-holder. */
2312 linkCh++;
2313 }
2315 /* Verify the returned handle, it should lie in the correct range */
2316 if (linkCh > edma3_link_ch_max_val[edma3Id])
2317 {
2318 result = EDMA3_RM_E_INVALID_PARAM;
2320 /* Free the PaRAM Set now. */
2321 resObj.type = EDMA3_RM_RES_PARAM_SET;
2322 resObj.resId = chObj->resId;
2323 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2324 }
2325 else
2326 {
2327 /* Save the PaRAM Id for the Link Channel. */
2328 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = (int32_t)(chObj->resId);
2330 /**
2331 * Remove any linking. Before doing that, check
2332 * whether it is permitted or not.
2333 */
2334 if (TRUE == rmInstance->regModificationRequired)
2335 {
2336 *((&gblRegs->PARAMENTRY[chObj->resId].OPT)
2337 + (uint32_t)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFU;
2338 }
2339 }
2340 }
2341 }
2342 }
2343 break;
2345 default:
2346 {
2347 result = EDMA3_RM_E_INVALID_PARAM;
2348 break;
2349 }
2350 }
2351 }
2354 if (result == EDMA3_RM_SOK)
2355 {
2356 /**
2357 * For DMA/QDMA channels, we still have to allocate more resources like
2358 * TCC, PaRAM Set etc.
2359 * For Link channel, only the PaRAMSet is required and that has been
2360 * allocated so no further operations required.
2361 */
2363 /* Further resources' allocation for DMA channel. */
2364 if (chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
2365 {
2366 /* First allocate a PaRAM Set */
2367 resObj.type = EDMA3_RM_RES_PARAM_SET;
2368 /* Use the saved param id now. */
2369 resObj.resId = (uint32_t)paRAMId;
2370 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2371 if (result == EDMA3_RM_SOK)
2372 {
2373 /**
2374 * PaRAM Set allocation succeeded.
2375 * Save the PaRAM Set first.
2376 */
2377 *pParam = resObj.resId;
2378 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = (int32_t)(resObj.resId);
2380 /* Allocate the TCC now. */
2381 resObj.type = EDMA3_RM_RES_TCC;
2382 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2383 {
2384 if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2385 {
2386 resObj.resId = EDMA3_RM_RES_ANY;
2387 }
2388 else
2389 {
2390 resObj.resId = mappedTcc;
2391 }
2392 }
2393 else
2394 {
2395 resObj.resId = *pTcc;
2396 }
2398 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2399 if (result == EDMA3_RM_SOK)
2400 {
2401 /* TCC allocation succeeded. Save it first. */
2402 *pTcc = resObj.resId;
2403 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].tcc = resObj.resId;
2405 /**
2406 * Check first whether the global registers and the allocated
2407 * PaRAM Set can be modified or not. If yes, do the needful.
2408 * Else leave this for the user.
2409 */
2410 if (TRUE == rmInstance->regModificationRequired)
2411 {
2412 /* Set TCC of the allocated Param Set. */
2413 gblRegs->PARAMENTRY[*pParam].OPT &= EDMA3_RM_OPT_TCC_CLR_MASK;
2414 gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2416 /**
2417 * Do the mapping between DMA channel and PaRAM Set.
2418 * Do this for the EDMA3 Controllers which have a register for mapping
2419 * DMA Channel to a particular PaRAM Set.
2420 */
2421 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2422 {
2423 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2425 /* Map Parameter RAM Set Number for specified channelId */
2426 gblRegs->DCHMAP[chObj->resId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
2427 gblRegs->DCHMAP[chObj->resId] |= EDMA3_RM_DCH_PARAM_SET_MASK(*pParam);
2428 }
2430 /* Remove any linking */
2431 *((&gblRegs->PARAMENTRY[*pParam].OPT)
2432 + (uint32_t)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFU;
2433 }
2434 }
2435 else
2436 {
2437 /**
2438 * TCC allocation failed, free the previously allocated
2439 * PaRAM Set and DMA channel.
2440 */
2441 resObj.type = EDMA3_RM_RES_PARAM_SET;
2442 resObj.resId = *pParam;
2443 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2445 /* Reset the book-keeping data structure also. */
2446 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = -1;
2448 resObj.type = chObj->type;
2449 resObj.resId = chObj->resId;
2450 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2451 }
2452 }
2453 else
2454 {
2455 /**
2456 * PaRAM Set allocation failed, free the previously allocated
2457 * DMA channel also.
2458 */
2459 resObj.type = chObj->type;
2460 resObj.resId = chObj->resId;
2461 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2462 }
2463 }
2466 /* Further resources' allocation for QDMA channel. */
2467 if (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
2468 {
2469 /* First allocate a PaRAM Set */
2470 resObj.type = EDMA3_RM_RES_PARAM_SET;
2471 /* Use the saved param id now. */
2472 resObj.resId = (uint32_t)paRAMId;
2473 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2474 if (result == EDMA3_RM_SOK)
2475 {
2476 /**
2477 * PaRAM Set allocation succeeded.
2478 * Save the PaRAM Set first.
2479 */
2480 *pParam = resObj.resId;
2481 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = (int32_t)(resObj.resId);
2483 /* Allocate the TCC now. */
2484 resObj.type = EDMA3_RM_RES_TCC;
2485 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2486 {
2487 if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2488 {
2489 resObj.resId = EDMA3_RM_RES_ANY;
2490 }
2491 else
2492 {
2493 resObj.resId = mappedTcc;
2494 }
2495 }
2496 else
2497 {
2498 resObj.resId = *pTcc;
2499 }
2501 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2502 if (result == EDMA3_RM_SOK)
2503 {
2504 /* TCC allocation succeeded. Save it first. */
2505 *pTcc = resObj.resId;
2506 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = resObj.resId;
2508 /**
2509 * Check first whether the global registers and the allocated
2510 * PaRAM Set can be modified or not. If yes, do the needful.
2511 * Else leave this for the user.
2512 */
2513 if (TRUE == rmInstance->regModificationRequired)
2514 {
2515 /* Set TCC of the allocated Param Set. */
2516 gblRegs->PARAMENTRY[*pParam].OPT &= EDMA3_RM_OPT_TCC_CLR_MASK;
2517 gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2519 /* Do the mapping between QDMA channel and PaRAM Set. */
2520 /* Map Parameter RAM Set Number for specified channelId */
2521 gblRegs->QCHMAP[chObj->resId]
2522 &= EDMA3_RM_QCH_PARAM_CLR_MASK;
2523 gblRegs->QCHMAP[chObj->resId]
2524 |= EDMA3_RM_QCH_PARAM_SET_MASK(*pParam);
2526 /* Set the Trigger Word */
2527 gblRegs->QCHMAP[chObj->resId]
2528 &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
2529 gblRegs->QCHMAP[chObj->resId]
2530 |= EDMA3_RM_QCH_TRWORD_SET_MASK(EDMA3_RM_QDMA_TRIG_DEFAULT);
2532 /* Remove any linking */
2533 *((&gblRegs->PARAMENTRY[*pParam].OPT)
2534 + (uint32_t)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFU;
2536 /* Enable the transfer also. */
2537 rmInstance->shadowRegs->QEESR = (1U << chObj->resId);
2538 }
2539 }
2540 else
2541 {
2542 /**
2543 * TCC allocation failed, free the previously allocated
2544 * PaRAM Set and QDMA channel.
2545 */
2546 resObj.type = EDMA3_RM_RES_PARAM_SET;
2547 resObj.resId = *pParam;
2548 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2550 /* Reset the book-keeping data structure also. */
2551 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
2553 resObj.type = chObj->type;
2554 resObj.resId = chObj->resId;
2555 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2556 }
2557 }
2558 else
2559 {
2560 /**
2561 * PaRAM Set allocation failed, free the previously allocated
2562 * QDMA channel also.
2563 */
2564 resObj.type = chObj->type;
2565 resObj.resId = chObj->resId;
2566 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2567 }
2568 }
2569 }
2572 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2573 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2574 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2575 EDMA3_DVT_dCOUNTER,
2576 EDMA3_DVT_dNONE,
2577 EDMA3_DVT_dNONE));
2578 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2581 return result;
2582 }
2584 EDMA3_RM_Result EDMA3_RM_freeLogicalChannel (EDMA3_RM_Handle hEdmaResMgr,
2585 EDMA3_RM_ResDesc *lChObj)
2586 {
2587 EDMA3_RM_ResDesc *chObj;
2588 EDMA3_RM_ResDesc resObj;
2589 EDMA3_RM_Result result = EDMA3_RM_SOK;
2590 EDMA3_RM_Instance *rmInstance = NULL;
2591 EDMA3_RM_Obj *rmObj = NULL;
2592 int32_t paRAMId;
2593 uint32_t tcc;
2594 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
2595 uint32_t qdmaChId;
2596 uint32_t dmaChId;
2597 EDMA3_RM_InstanceInitConfig *rmConfig = NULL;
2598 uint32_t edma3Id;
2600 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2601 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2602 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2603 EDMA3_DVT_dCOUNTER,
2604 EDMA3_DVT_dNONE,
2605 EDMA3_DVT_dNONE));
2606 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2609 /* If parameter checking is enabled... */
2610 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2611 if ((lChObj == NULL) || (hEdmaResMgr == NULL))
2612 {
2613 result = (EDMA3_RM_E_INVALID_PARAM);
2614 }
2615 #endif
2617 /* Check if the parameters are OK. */
2618 if (result == EDMA3_RM_SOK)
2619 {
2620 chObj = lChObj;
2622 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2624 if (rmInstance == NULL)
2625 {
2626 result = EDMA3_RM_E_INVALID_PARAM;
2627 }
2628 }
2630 if (result == EDMA3_RM_SOK)
2631 {
2632 rmConfig = rmInstance->initParam.rmInstInitConfig;
2633 rmObj = rmInstance->pResMgrObjHandle;
2635 if (rmObj == NULL)
2636 {
2637 result = EDMA3_RM_E_INVALID_PARAM;
2638 }
2639 else
2640 {
2641 if (rmObj->gblCfgParams.globalRegs == NULL)
2642 {
2643 result = EDMA3_RM_E_INVALID_PARAM;
2644 }
2645 else
2646 {
2647 edma3Id = rmObj->phyCtrllerInstId;
2648 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2649 }
2650 }
2651 }
2654 if (result == EDMA3_RM_SOK)
2655 {
2656 switch (chObj->type)
2657 {
2658 case EDMA3_RM_RES_DMA_CHANNEL:
2659 {
2660 /* Save the DMA channel first. */
2661 dmaChId = chObj->resId;
2663 /**
2664 * Validate DMA channel id first.
2665 * It should be a valid channel id.
2666 */
2667 if (dmaChId >= EDMA3_MAX_DMA_CH)
2668 {
2669 result = EDMA3_RM_E_INVALID_PARAM;
2670 }
2672 /* It should be owned and allocated by this RM only. */
2673 if (result == EDMA3_RM_SOK)
2674 {
2675 if (((rmConfig->ownDmaChannels[dmaChId/32U])
2676 &
2677 (~(rmInstance->avlblDmaChannels[dmaChId/32U]))
2678 &
2679 ((uint32_t)1U << (dmaChId%32U))) != FALSE)
2680 {
2681 /** Perfectly valid channel id.
2682 * Clear some channel specific registers, if it is permitted.
2683 */
2684 if (TRUE == rmInstance->regModificationRequired)
2685 {
2686 if (dmaChId < 32U)
2687 {
2688 if((rmInstance->shadowRegs->SER & ((uint32_t)1U<<dmaChId))!=FALSE)
2689 {
2690 rmInstance->shadowRegs->SECR = (1U<<dmaChId);
2691 }
2692 if((globalRegs->EMR & ((uint32_t)1U<<dmaChId))!=FALSE)
2693 {
2694 globalRegs->EMCR = (1U<<dmaChId);
2695 }
2696 }
2697 else
2698 {
2699 if((rmInstance->shadowRegs->SERH & ((uint32_t)1U<<(dmaChId-32U)))!=FALSE)
2700 {
2701 rmInstance->shadowRegs->SECRH = (1U<<(dmaChId-32U));
2702 }
2703 if((globalRegs->EMRH & ((uint32_t)1U<<(dmaChId-32U)))!=FALSE)
2704 {
2705 globalRegs->EMCRH = (1U<<(dmaChId-32U));
2706 }
2707 }
2709 /* Clear DCHMAP register also. */
2710 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2711 {
2712 globalRegs->DCHMAP[dmaChId] &=
2713 EDMA3_RM_DCH_PARAM_CLR_MASK;
2714 }
2715 }
2717 /* Free the PaRAM Set Now. */
2718 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].paRAMId;
2719 resObj.type = EDMA3_RM_RES_PARAM_SET;
2720 resObj.resId = (uint32_t)paRAMId;
2721 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2722 }
2723 else
2724 {
2725 /* Channel id has some problem. */
2726 result = EDMA3_RM_E_INVALID_PARAM;
2727 }
2728 }
2731 if (result == EDMA3_RM_SOK)
2732 {
2733 /* PaRAM Set Freed */
2734 edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].paRAMId = -1;
2736 /* Free the TCC */
2737 tcc = edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].tcc;
2738 resObj.type = EDMA3_RM_RES_TCC;
2739 resObj.resId = tcc;
2740 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2741 }
2743 if (result == EDMA3_RM_SOK)
2744 {
2745 /* TCC Freed */
2746 edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].tcc = EDMA3_MAX_TCC;
2748 /**
2749 * Try to free the DMA Channel now. DMA Channel should
2750 * be freed only in the end because while freeing, DRAE
2751 * registers will be RESET.
2752 * After that, no shadow region specific DMA channel
2753 * register can be modified. So reset that DRAE register
2754 * ONLY in the end.
2755 */
2756 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2757 resObj.resId = dmaChId;
2758 result = EDMA3_RM_freeResource(hEdmaResMgr,
2759 (EDMA3_RM_ResDesc *)&resObj);
2760 }
2761 }
2762 break;
2765 case EDMA3_RM_RES_QDMA_CHANNEL:
2766 {
2767 /**
2768 * Calculate QDMA Logical Channel Id first.
2769 * User has given the actual QDMA channel id.
2770 * So we have to convert it to make the logical
2771 * QDMA channel id first.
2772 */
2773 qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
2775 /**
2776 * Validate QDMA channel id first.
2777 * It should be a valid channel id.
2778 */
2779 if (chObj->resId >= EDMA3_MAX_QDMA_CH)
2780 {
2781 result = EDMA3_RM_E_INVALID_PARAM;
2782 }
2784 /* It should be owned and allocated by this RM only. */
2785 if (result == EDMA3_RM_SOK)
2786 {
2787 if (((rmConfig->ownQdmaChannels[0U])
2788 &
2789 (~(rmInstance->avlblQdmaChannels[0U]))
2790 &
2791 ((uint32_t)1U << chObj->resId)) != FALSE)
2792 {
2793 /** Perfectly valid channel id.
2794 * Clear some channel specific registers, if
2795 * it is permitted.
2796 */
2797 if (TRUE == rmInstance->regModificationRequired)
2798 {
2799 rmInstance->shadowRegs->QEECR = (1U<<chObj->resId);
2801 if((globalRegs->QEMR & ((uint32_t)1U<<chObj->resId))!=FALSE)
2802 {
2803 globalRegs->QEMCR = (1U<<chObj->resId);
2804 }
2806 /* Unmap PARAM Set Number for specified channelId */
2807 globalRegs->QCHMAP[chObj->resId] &=
2808 EDMA3_RM_QCH_PARAM_CLR_MASK;
2810 /* Reset the Trigger Word */
2811 globalRegs->QCHMAP[chObj->resId] &=
2812 EDMA3_RM_QCH_TRWORD_CLR_MASK;
2813 }
2815 /* Free the PaRAM Set now */
2816 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId;
2817 resObj.type = EDMA3_RM_RES_PARAM_SET;
2818 resObj.resId = (int32_t)paRAMId;
2819 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2820 }
2821 else
2822 {
2823 /* Channel id has some problem. */
2824 result = EDMA3_RM_E_INVALID_PARAM;
2825 }
2826 }
2829 if (result == EDMA3_RM_SOK)
2830 {
2831 /* PaRAM Set Freed */
2832 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
2834 /* Free the TCC */
2835 tcc = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc;
2836 resObj.type = EDMA3_RM_RES_TCC;
2837 resObj.resId = tcc;
2838 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2839 }
2841 if (result == EDMA3_RM_SOK)
2842 {
2843 /* TCC Freed */
2844 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = EDMA3_MAX_TCC;
2846 /**
2847 * Try to free the QDMA Channel now. QDMA Channel should
2848 * be freed only in the end because while freeing, QRAE
2849 * registers will be RESET.
2850 * After that, no shadow region specific QDMA channel
2851 * register can be modified. So reset that QDRAE register
2852 * ONLY in the end.
2853 */
2854 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2855 resObj.resId = chObj->resId;
2856 result = EDMA3_RM_freeResource(hEdmaResMgr,
2857 (EDMA3_RM_ResDesc *)&resObj);
2858 }
2859 }
2860 break;
2863 case EDMA3_RM_RES_PARAM_SET:
2864 {
2865 /* Link Channel */
2866 if (chObj->resId < edma3NumPaRAMSets)
2867 {
2868 resObj.type = EDMA3_RM_RES_PARAM_SET;
2869 resObj.resId = chObj->resId;
2871 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2872 if (result == EDMA3_RM_SOK)
2873 {
2874 /* PaRAM Set freed successfully. */
2875 uint32_t linkCh = edma3_link_ch_min_val[edma3Id];
2877 /* Reset the Logical-Link channel */
2878 /* Search for the Logical-Link channel first */
2879 for (linkCh = edma3_link_ch_min_val[edma3Id];
2880 linkCh < edma3_link_ch_max_val[edma3Id];
2881 linkCh++)
2882 {
2883 if (edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId == chObj->resId)
2884 {
2885 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = -1;
2886 break;
2887 }
2888 }
2889 }
2890 }
2891 else
2892 {
2893 result = EDMA3_RM_E_INVALID_PARAM;
2894 }
2895 }
2896 break;
2898 default:
2899 {
2900 result = EDMA3_RM_E_INVALID_PARAM;
2901 break;
2902 }
2903 }
2904 }
2907 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2908 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2909 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2910 EDMA3_DVT_dCOUNTER,
2911 EDMA3_DVT_dNONE,
2912 EDMA3_DVT_dNONE));
2913 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2915 return result;
2916 }
2918 EDMA3_RM_Result EDMA3_RM_mapEdmaChannel (EDMA3_RM_Handle hEdmaResMgr,
2919 uint32_t channelId,
2920 uint32_t paRAMId)
2921 {
2922 EDMA3_RM_Instance *rmInstance = NULL;
2923 EDMA3_RM_Obj *rmObj = NULL;
2924 EDMA3_RM_Result result = EDMA3_RM_SOK;
2925 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
2927 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2928 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2929 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2930 EDMA3_DVT_dCOUNTER,
2931 EDMA3_DVT_dNONE,
2932 EDMA3_DVT_dNONE));
2933 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2935 /* If parameter checking is enabled... */
2936 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2937 if (hEdmaResMgr == NULL)
2938 {
2939 result = EDMA3_RM_E_INVALID_PARAM;
2940 }
2941 #endif
2943 if (result == EDMA3_RM_SOK)
2944 {
2945 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2947 if (rmInstance == NULL)
2948 {
2949 result = EDMA3_RM_E_INVALID_PARAM;
2950 }
2951 }
2953 if (result == EDMA3_RM_SOK)
2954 {
2955 rmObj = rmInstance->pResMgrObjHandle;
2957 if (rmObj == NULL)
2958 {
2959 result = EDMA3_RM_E_INVALID_PARAM;
2960 }
2961 else
2962 {
2963 if (rmObj->gblCfgParams.globalRegs == NULL)
2964 {
2965 result = EDMA3_RM_E_INVALID_PARAM;
2966 }
2967 }
2968 }
2970 if (result == EDMA3_RM_SOK)
2971 {
2972 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2974 /* If parameter checking is enabled... */
2975 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2976 if ((paRAMId >= rmObj->gblCfgParams.numPaRAMSets)
2977 || (channelId >= rmObj->gblCfgParams.numDmaChannels))
2978 {
2979 result = EDMA3_RM_E_INVALID_PARAM;
2980 }
2981 #endif
2982 }
2984 /* DMA channel and PaRAM Set should be previously allocated. */
2985 if (result == EDMA3_RM_SOK)
2986 {
2987 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[channelId/32U])
2988 &
2989 (~(rmInstance->avlblDmaChannels[channelId/32U]))
2990 &
2991 ((uint32_t)1U << (channelId%32U))) != FALSE)
2992 {
2993 /* DMA channel allocated, check for the PaRAM Set */
2994 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[paRAMId/32U])
2995 &
2996 (~(rmInstance->avlblPaRAMSets[paRAMId/32U]))
2997 &
2998 ((uint32_t)1U << (paRAMId%32U))) == FALSE)
2999 {
3000 /* PaRAM Set NOT allocated, return error */
3001 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3002 }
3003 }
3004 else
3005 {
3006 /* DMA channel NOT allocated, return error */
3007 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3008 }
3009 }
3012 if (result == EDMA3_RM_SOK)
3013 {
3014 /* Map the Dma Channel to the PaRAM Set corresponding to paramId */
3015 /**
3016 * Do this for the EDMA3 Controllers which have a register for mapping
3017 * DMA Channel to a particular PaRAM Set. So check
3018 * dmaChPaRAMMapExists first.
3019 */
3020 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
3021 {
3022 /* Map Parameter RAM Set Number for specified channelId */
3023 gblRegs->DCHMAP[channelId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
3024 gblRegs->DCHMAP[channelId] |= EDMA3_RM_DCH_PARAM_SET_MASK(paRAMId);
3025 }
3026 else
3027 {
3028 /* Feature NOT supported on the current platform, return error. */
3029 result = EDMA3_RM_E_FEATURE_UNSUPPORTED;
3030 }
3031 }
3033 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3034 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3035 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3036 EDMA3_DVT_dCOUNTER,
3037 EDMA3_DVT_dNONE,
3038 EDMA3_DVT_dNONE));
3039 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3041 return result;
3042 }
3044 EDMA3_RM_Result EDMA3_RM_mapQdmaChannel (EDMA3_RM_Handle hEdmaResMgr,
3045 uint32_t channelId,
3046 uint32_t paRAMId,
3047 EDMA3_RM_QdmaTrigWord trigWord)
3048 {
3049 EDMA3_RM_Instance *rmInstance = NULL;
3050 EDMA3_RM_Obj *rmObj = NULL;
3051 EDMA3_RM_Result result = EDMA3_RM_SOK;
3052 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3054 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3055 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3056 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3057 EDMA3_DVT_dCOUNTER,
3058 EDMA3_DVT_dNONE,
3059 EDMA3_DVT_dNONE));
3060 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3062 /* If parameter checking is enabled... */
3063 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3064 if ((hEdmaResMgr == NULL)
3065 || (((int32_t)trigWord < (int32_t)EDMA3_RM_QDMA_TRIG_OPT)
3066 || (trigWord > EDMA3_RM_QDMA_TRIG_CCNT)))
3067 {
3068 result = EDMA3_RM_E_INVALID_PARAM;
3069 }
3070 #endif
3072 if (result == EDMA3_RM_SOK)
3073 {
3074 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3076 if (rmInstance == NULL)
3077 {
3078 result = EDMA3_RM_E_INVALID_PARAM;
3079 }
3080 }
3082 if (result == EDMA3_RM_SOK)
3083 {
3084 rmObj = rmInstance->pResMgrObjHandle;
3086 if (rmObj == NULL)
3087 {
3088 result = EDMA3_RM_E_INVALID_PARAM;
3089 }
3090 else
3091 {
3092 if (rmObj->gblCfgParams.globalRegs == NULL)
3093 {
3094 result = EDMA3_RM_E_INVALID_PARAM;
3095 }
3096 }
3097 }
3099 if (result == EDMA3_RM_SOK)
3100 {
3101 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3103 /* If parameter checking is enabled... */
3104 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3105 if ((paRAMId >= rmObj->gblCfgParams.numPaRAMSets)
3106 || (channelId >= rmObj->gblCfgParams.numQdmaChannels))
3107 {
3108 result = EDMA3_RM_E_INVALID_PARAM;
3109 }
3110 #endif
3111 }
3113 /* QDMA channel and PaRAM Set should be previously allocated. */
3114 if (result == EDMA3_RM_SOK)
3115 {
3116 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[channelId/32U])
3117 &
3118 (~(rmInstance->avlblQdmaChannels[channelId/32U]))
3119 &
3120 ((uint32_t)1U << (channelId%32U))) != FALSE)
3121 {
3122 /* QDMA channel allocated, check for the PaRAM Set */
3123 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[paRAMId/32U])
3124 &
3125 (~(rmInstance->avlblPaRAMSets[paRAMId/32U]))
3126 &
3127 ((uint32_t)1U << (paRAMId%32U))) == FALSE)
3128 {
3129 /* PaRAM Set NOT allocated, return error */
3130 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3131 }
3132 }
3133 else
3134 {
3135 /* QDMA channel NOT allocated, return error */
3136 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3137 }
3138 }
3140 if (result == EDMA3_RM_SOK)
3141 {
3142 /* Map Parameter RAM Set Number for specified channelId */
3143 gblRegs->QCHMAP[channelId] &= EDMA3_RM_QCH_PARAM_CLR_MASK;
3144 gblRegs->QCHMAP[channelId] |= EDMA3_RM_QCH_PARAM_SET_MASK(paRAMId);
3146 /* Set the Trigger Word */
3147 gblRegs->QCHMAP[channelId] &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
3148 gblRegs->QCHMAP[channelId] |= EDMA3_RM_QCH_TRWORD_SET_MASK(trigWord);
3149 }
3152 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3153 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3154 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3155 EDMA3_DVT_dCOUNTER,
3156 EDMA3_DVT_dNONE,
3157 EDMA3_DVT_dNONE));
3158 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3160 return result;
3161 }
3163 EDMA3_RM_Result EDMA3_RM_registerTccCb(EDMA3_RM_Handle hEdmaResMgr,
3164 const EDMA3_RM_ResDesc *channelObj,
3165 uint32_t tcc,
3166 EDMA3_RM_TccCallback tccCb,
3167 void *cbData)
3168 {
3169 EDMA3_RM_Instance *rmInstance = NULL;
3170 EDMA3_RM_Obj *rmObj = NULL;
3171 EDMA3_RM_Result result = EDMA3_RM_SOK;
3172 uint32_t edma3Id;
3173 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3175 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3176 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3177 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3178 EDMA3_DVT_dCOUNTER,
3179 EDMA3_DVT_dNONE,
3180 EDMA3_DVT_dNONE));
3181 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3183 /* If parameter checking is enabled... */
3184 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3185 if ((NULL == hEdmaResMgr) || (NULL == channelObj))
3186 {
3187 result = EDMA3_RM_E_INVALID_PARAM;
3188 }
3190 /* Callback function should NOT be NULL */
3191 if (NULL == tccCb)
3192 {
3193 result = EDMA3_RM_E_INVALID_PARAM;
3194 }
3195 #endif
3197 if (result == EDMA3_RM_SOK)
3198 {
3199 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3200 rmObj = rmInstance->pResMgrObjHandle;
3202 if (rmObj == NULL)
3203 {
3204 result = EDMA3_RM_E_INVALID_PARAM;
3205 }
3206 else
3207 {
3208 edma3Id = rmObj->phyCtrllerInstId;
3209 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3210 }
3211 }
3213 if (result == EDMA3_RM_SOK)
3214 {
3215 if ((gblRegs == NULL) || (tcc >= rmObj->gblCfgParams.numTccs))
3216 {
3217 result = EDMA3_RM_E_INVALID_PARAM;
3218 }
3219 }
3221 /* Check if the parameters are OK. */
3222 if (EDMA3_RM_SOK == result)
3223 {
3224 /* Check whether the callback has already registered. */
3225 if (NULL != edma3IntrParams[edma3Id][tcc].tccCb)
3226 {
3227 result = EDMA3_RM_E_CALLBACK_ALREADY_REGISTERED;
3228 }
3229 else
3230 {
3231 /* Store the mapping b/w DMA/QDMA channel and TCC first. */
3232 if (channelObj->type == EDMA3_RM_RES_DMA_CHANNEL)
3233 {
3234 /* DMA channel */
3235 if (channelObj->resId < rmObj->gblCfgParams.numDmaChannels)
3236 {
3237 /* Save the TCC */
3238 edma3DmaChTccMapping[edma3Id][channelObj->resId] = tcc;
3239 }
3240 else
3241 {
3242 /* Error!!! */
3243 result = EDMA3_RM_E_INVALID_PARAM;
3244 }
3245 }
3246 else
3247 {
3248 if (channelObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
3249 {
3250 /* QDMA channel */
3251 if (channelObj->resId < rmObj->gblCfgParams.numQdmaChannels)
3252 {
3253 /* Save the TCC */
3254 edma3QdmaChTccMapping[edma3Id][channelObj->resId] = tcc;
3255 }
3256 else
3257 {
3258 /* Error!!! */
3259 result = EDMA3_RM_E_INVALID_PARAM;
3260 }
3261 }
3262 else
3263 {
3264 /* Error!!! */
3265 result = EDMA3_RM_E_INVALID_PARAM;
3266 }
3267 }
3268 }
3269 }
3271 if (EDMA3_RM_SOK == result)
3272 {
3274 /* Enable the interrupts in IESR/IESRH */
3275 if (tcc < 32U)
3276 {
3277 rmInstance->shadowRegs->IESR = (1UL << tcc);
3278 }
3279 else
3280 {
3281 rmInstance->shadowRegs->IESRH = (1UL << (tcc-32U));
3282 }
3284 /* Save the callback functions also */
3285 edma3IntrParams[edma3Id][tcc].cbData = cbData;
3286 edma3IntrParams[edma3Id][tcc].tccCb = tccCb;
3287 }
3289 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3290 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3291 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3292 EDMA3_DVT_dCOUNTER,
3293 EDMA3_DVT_dNONE,
3294 EDMA3_DVT_dNONE));
3295 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3297 return result;
3298 }
3300 EDMA3_RM_Result EDMA3_RM_unregisterTccCb(EDMA3_RM_Handle hEdmaResMgr,
3301 const EDMA3_RM_ResDesc *channelObj)
3302 {
3303 EDMA3_RM_Instance *rmInstance = NULL;
3304 EDMA3_RM_Obj *rmObj = NULL;
3305 EDMA3_RM_Result result = EDMA3_RM_SOK;
3306 uint32_t mappedTcc = EDMA3_MAX_TCC;
3307 uint32_t edma3Id;
3308 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3310 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3311 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3312 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3313 EDMA3_DVT_dCOUNTER,
3314 EDMA3_DVT_dNONE,
3315 EDMA3_DVT_dNONE));
3316 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3318 /* If parameter checking is enabled... */
3319 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3320 if ((NULL == hEdmaResMgr) || (NULL == channelObj))
3321 {
3322 result = EDMA3_RM_E_INVALID_PARAM;
3323 }
3324 #endif
3326 /* Check if the parameters are OK. */
3327 if (EDMA3_RM_SOK == result)
3328 {
3329 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3330 rmObj = rmInstance->pResMgrObjHandle;
3332 if (rmObj == NULL)
3333 {
3334 result = EDMA3_RM_E_INVALID_PARAM;
3335 }
3336 else
3337 {
3338 edma3Id = rmObj->phyCtrllerInstId;
3339 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3340 }
3341 }
3343 if (result == EDMA3_RM_SOK)
3344 {
3345 if (gblRegs == NULL)
3346 {
3347 result = EDMA3_RM_E_INVALID_PARAM;
3348 }
3349 else
3350 {
3351 if (channelObj->type == EDMA3_RM_RES_DMA_CHANNEL)
3352 {
3353 /* DMA channel */
3354 if (channelObj->resId < rmObj->gblCfgParams.numDmaChannels)
3355 {
3356 /* Save the mapped TCC */
3357 mappedTcc = edma3DmaChTccMapping[edma3Id][channelObj->resId];
3359 /* Remove the mapping now. */
3360 edma3DmaChTccMapping[edma3Id][channelObj->resId] = EDMA3_MAX_TCC;
3361 }
3362 else
3363 {
3364 /* Error!!! */
3365 result = EDMA3_RM_E_INVALID_PARAM;
3366 }
3367 }
3368 else
3369 {
3370 if (channelObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
3371 {
3372 /* QDMA channel */
3373 if (channelObj->resId < rmObj->gblCfgParams.numQdmaChannels)
3374 {
3375 /* Save the mapped TCC */
3376 mappedTcc = edma3QdmaChTccMapping[edma3Id][channelObj->resId];
3378 /* Remove the mapping now. */
3379 edma3QdmaChTccMapping[edma3Id][channelObj->resId] = EDMA3_MAX_TCC;
3380 }
3381 else
3382 {
3383 /* Error!!! */
3384 result = EDMA3_RM_E_INVALID_PARAM;
3385 }
3386 }
3387 else
3388 {
3389 /* Error!!! */
3390 result = EDMA3_RM_E_INVALID_PARAM;
3391 }
3392 }
3393 }
3394 }
3396 if (EDMA3_RM_SOK == result)
3397 {
3399 /* Remove the callback function too */
3400 if (mappedTcc < 32U)
3401 {
3402 rmInstance->shadowRegs->IECR = (1UL << mappedTcc);
3403 }
3404 else if(mappedTcc < 64)
3405 {
3406 rmInstance->shadowRegs->IECRH = (1UL << (mappedTcc-32U));
3407 }
3408 else
3409 {
3410 /* To Comply MISRA C warning */
3411 result = EDMA3_RM_SOK;
3412 }
3414 if(mappedTcc < EDMA3_MAX_TCC)
3415 {
3416 edma3IntrParams[edma3Id][mappedTcc].cbData = NULL;
3417 edma3IntrParams[edma3Id][mappedTcc].tccCb = NULL;
3418 }
3419 }
3421 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3422 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3423 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3424 EDMA3_DVT_dCOUNTER,
3425 EDMA3_DVT_dNONE,
3426 EDMA3_DVT_dNONE));
3427 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3429 return result;
3430 }
3432 EDMA3_RM_Result EDMA3_RM_allocContiguousResource(EDMA3_RM_Handle hEdmaResMgr,
3433 EDMA3_RM_ResDesc *firstResIdObj,
3434 uint32_t numResources)
3435 {
3436 EDMA3_RM_Instance *rmInstance = NULL;
3437 EDMA3_RM_Obj *rmObj = NULL;
3438 EDMA3_RM_Result result = EDMA3_RM_SOK;
3439 EDMA3_RM_ResDesc *resObj = NULL;
3440 uint32_t resAllocIdx = 0U;
3441 uint32_t firstResId;
3442 uint32_t lastResId = 0U;
3443 uint32_t maxNumResources = 0U;
3444 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
3445 uint32_t resIdClr = 0x0;
3446 uint32_t resIdSet = 0x0;
3447 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3448 uint32_t i = 0U;
3449 uint32_t position = 0U;
3450 uint32_t edma3Id;
3452 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3453 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3454 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3455 EDMA3_DVT_dCOUNTER,
3456 EDMA3_DVT_dNONE,
3457 EDMA3_DVT_dNONE));
3458 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3461 /* If parameter checking is enabled... */
3462 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3463 if ((hEdmaResMgr == NULL) || (firstResIdObj == NULL))
3464 {
3465 result = EDMA3_RM_E_INVALID_PARAM;
3466 }
3467 #endif
3469 if (EDMA3_RM_SOK == result)
3470 {
3471 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3472 if (rmInstance == NULL)
3473 {
3474 result = EDMA3_RM_E_INVALID_PARAM;
3475 }
3476 }
3478 if (EDMA3_RM_SOK == result)
3479 {
3480 rmObj = rmInstance->pResMgrObjHandle;
3482 if (rmObj == NULL)
3483 {
3484 result = EDMA3_RM_E_INVALID_PARAM;
3485 }
3486 }
3488 if (EDMA3_RM_SOK == result)
3489 {
3490 edma3Id = rmObj->phyCtrllerInstId;
3491 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3493 if (rmInstance->initParam.rmSemHandle == NULL)
3494 {
3495 result = EDMA3_RM_E_INVALID_PARAM;
3496 }
3497 }
3499 if (EDMA3_RM_SOK == result)
3500 {
3501 resObj = firstResIdObj;
3502 if (resObj != NULL)
3503 {
3504 firstResId = resObj->resId;
3505 }
3507 switch (resObj->type)
3508 {
3509 case EDMA3_RM_RES_DMA_CHANNEL :
3510 maxNumResources = rmObj->gblCfgParams.numDmaChannels;
3511 break;
3512 case EDMA3_RM_RES_QDMA_CHANNEL :
3513 maxNumResources = rmObj->gblCfgParams.numQdmaChannels;
3514 break;
3515 case EDMA3_RM_RES_TCC :
3516 maxNumResources = rmObj->gblCfgParams.numTccs;
3517 break;
3518 case EDMA3_RM_RES_PARAM_SET :
3519 maxNumResources = rmObj->gblCfgParams.numPaRAMSets;
3520 break;
3521 default:
3522 result = EDMA3_RM_E_INVALID_PARAM;
3523 break;
3524 }
3525 }
3528 if (EDMA3_RM_SOK == result)
3529 {
3530 /* First resource id (firstResId) can be a valid Resource ID as well as
3531 * 'EDMA3_RM_RES_ANY', in case user does not want to
3532 * start from a specific resource. For eg, user allocating link channels.
3533 */
3534 if (firstResId != EDMA3_RM_RES_ANY)
3535 {
3536 /* User want specific resources. */
3537 lastResId = firstResId + numResources;
3539 if (((firstResId >= maxNumResources) || (firstResId > lastResId))
3540 || (lastResId > maxNumResources))
3541 {
3542 result = EDMA3_RM_E_INVALID_PARAM;
3543 }
3544 }
3545 else
3546 {
3547 /* (firstResId == EDMA3_RM_RES_ANY)
3548 * So just check whether the number of resources
3549 * requested does not cross the limit.
3550 */
3551 if (numResources > maxNumResources)
3552 {
3553 result = EDMA3_RM_E_INVALID_PARAM;
3554 }
3555 }
3556 }
3559 if (result == EDMA3_RM_SOK)
3560 {
3561 /* Now try to allocate resources for the first case */
3562 if (firstResId != EDMA3_RM_RES_ANY)
3563 {
3564 /* Request for specific resources */
3566 /**
3567 * Take the instance specific semaphore, to prevent simultaneous
3568 * access to the shared resources.
3569 */
3570 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
3571 EDMA3_OSSEM_NO_TIMEOUT);
3573 if (EDMA3_RM_SOK == semResult)
3574 {
3575 switch (resObj->type)
3576 {
3577 case EDMA3_RM_RES_DMA_CHANNEL :
3578 {
3579 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3580 {
3581 resIdClr = (uint32_t)(~((uint32_t)1U << (resAllocIdx%32U)));
3582 resIdSet = (1U << (resAllocIdx%32U));
3584 /* Check whether it is owned or not */
3585 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resAllocIdx/32U])&(resIdSet)) != FALSE)
3586 {
3587 /* Now check if specified resource is available presently*/
3588 if (((rmInstance->avlblDmaChannels[resAllocIdx/32U])&(resIdSet)) != FALSE)
3589 {
3590 /*
3591 * Mark the specified resource as "Not Available"
3592 * for future requests
3593 */
3594 rmInstance->avlblDmaChannels[resAllocIdx/32U] &= resIdClr;
3596 if (resAllocIdx < 32U)
3597 {
3598 rmInstance->shadowRegs->EECR = (1UL << resAllocIdx);
3600 /**
3601 * Enable the DMA channel in the
3602 * DRAE registers also.
3603 */
3604 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
3605 |= ((uint32_t)0x1U << resAllocIdx);
3606 }
3607 else
3608 {
3609 rmInstance->shadowRegs->EECRH = (1UL << (resAllocIdx - 32U));
3611 /**
3612 * Enable the DMA channel in the
3613 * DRAEH registers also.
3614 */
3615 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
3616 |= ((uint32_t)0x1U << (resAllocIdx - 32U));
3617 }
3619 result = EDMA3_RM_SOK;
3620 }
3621 else
3622 {
3623 /* Specified resource is owned but is already booked */
3624 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3625 break;
3626 }
3627 }
3628 else
3629 {
3630 /*
3631 * Specified resource is not owned by this instance
3632 * of the Resource Manager
3633 */
3634 result = EDMA3_RM_E_RES_NOT_OWNED;
3635 break;
3636 }
3637 }
3639 break;
3640 }
3642 case EDMA3_RM_RES_QDMA_CHANNEL:
3643 {
3644 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3645 {
3646 resIdClr = (uint32_t)(~((uint32_t)1U << resAllocIdx));
3647 resIdSet = (1U << resAllocIdx);
3649 /* Check whether it is owned or not */
3650 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0U])&(resIdSet))!=FALSE)
3651 {
3652 /* Now check if specified resource is available presently*/
3653 if (((rmInstance->avlblQdmaChannels[0U])&(resIdSet))!=FALSE)
3654 {
3655 /*
3656 * Mark the specified resource as "Not Available"
3657 * for future requests
3658 */
3659 rmInstance->avlblQdmaChannels[0U] &= resIdClr;
3661 /**
3662 * Enable the QDMA channel in the
3663 * QRAE register also.
3664 */
3665 gblRegs->QRAE[rmInstance->initParam.regionId]
3666 |= ((uint32_t)0x1U << resAllocIdx);
3668 result = EDMA3_RM_SOK;
3669 }
3670 else
3671 {
3672 /* Specified resource is owned but is already booked */
3673 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3674 break;
3675 }
3676 }
3677 else
3678 {
3679 /*
3680 * Specified resource is not owned by this instance
3681 * of the Resource Manager
3682 */
3683 result = EDMA3_RM_E_RES_NOT_OWNED;
3684 break;
3685 }
3686 }
3688 break;
3689 }
3691 case EDMA3_RM_RES_TCC:
3692 {
3693 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3694 {
3695 resIdClr = (uint32_t)(~((uint32_t)1U << (resAllocIdx%32U)));
3696 resIdSet = (1U << (resAllocIdx%32U));
3698 /* Check whether it is owned or not */
3699 if (((rmInstance->initParam.rmInstInitConfig->ownTccs[resAllocIdx/32U])&(resIdSet))!=FALSE)
3700 {
3701 /* Now check if specified resource is available presently*/
3702 if (((rmInstance->avlblTccs[resAllocIdx/32U])&(resIdSet))!=FALSE)
3703 {
3704 /*
3705 * Mark the specified resource as "Not Available"
3706 * for future requests
3707 */
3708 rmInstance->avlblTccs[resAllocIdx/32U] &= resIdClr;
3710 /**
3711 * If the region id coming from this
3712 * RM instance is same as the Master RM
3713 * Instance's region id, only then we will be
3714 * getting the interrupts on the same side.
3715 * So save the TCC in the allocatedTCCs[] array.
3716 */
3717 if (edma3RegionId == rmInstance->initParam.regionId)
3718 {
3719 if (resAllocIdx < 32U)
3720 {
3721 allocatedTCCs[edma3Id][0U] |= ((uint32_t)0x1U << resAllocIdx);
3722 }
3723 else
3724 {
3725 allocatedTCCs[edma3Id][1U] |= ((uint32_t)0x1U << (resAllocIdx - 32U));
3726 }
3727 }
3728 result = EDMA3_RM_SOK;
3729 }
3730 else
3731 {
3732 /* Specified resource is owned but is already booked */
3733 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3734 break;
3735 }
3736 }
3737 else
3738 {
3739 /*
3740 * Specified resource is not owned by this instance
3741 * of the Resource Manager
3742 */
3743 result = EDMA3_RM_E_RES_NOT_OWNED;
3744 break;
3745 }
3746 }
3748 break;
3749 }
3751 case EDMA3_RM_RES_PARAM_SET:
3752 {
3753 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3754 {
3755 resIdClr = (uint32_t)(~((uint32_t)1U << (resAllocIdx%32U)));
3756 resIdSet = (1U << (resAllocIdx%32U));
3758 /* Check whether it is owned or not */
3759 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[resAllocIdx/32U])&(resIdSet))!=FALSE)
3760 {
3761 /* Now check if specified resource is available presently*/
3762 if (((rmInstance->avlblPaRAMSets[resAllocIdx/32U])&(resIdSet))!=FALSE)
3763 {
3764 /*
3765 * Mark the specified resource as "Not Available"
3766 * for future requests
3767 */
3768 rmInstance->avlblPaRAMSets[resAllocIdx/32U] &= resIdClr;
3770 /**
3771 * Also, make the actual PARAM Set NULL, checking the flag
3772 * whether it is required or not.
3773 */
3774 if (TRUE == rmInstance->paramInitRequired)
3775 {
3776 edma3MemZero((void *)(&gblRegs->PARAMENTRY[resAllocIdx]),
3777 sizeof(gblRegs->PARAMENTRY[resAllocIdx]));
3778 }
3780 result = EDMA3_RM_SOK;
3781 }
3782 else
3783 {
3784 /* Specified resource is owned but is already booked */
3785 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3786 break;
3787 }
3788 }
3789 else
3790 {
3791 /*
3792 * Specified resource is not owned by this instance
3793 * of the Resource Manager
3794 */
3795 result = EDMA3_RM_E_RES_NOT_OWNED;
3796 break;
3797 }
3798 }
3800 break;
3801 }
3803 default:
3804 {
3805 result = EDMA3_RM_E_INVALID_PARAM;
3806 break;
3807 }
3808 }
3810 /* resource allocation completed, release the semaphore first */
3811 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
3812 }
3814 }
3815 else
3816 {
3817 /* (firstResId == EDMA3_RM_RES_ANY) */
3818 /**
3819 * Take the instance specific semaphore, to prevent simultaneous
3820 * access to the shared resources.
3821 */
3822 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
3823 EDMA3_OSSEM_NO_TIMEOUT);
3825 if (EDMA3_RM_SOK == semResult)
3826 {
3827 /**
3828 * We have to search three different arrays, namely ownedResoures,
3829 * avlblResources and resvdResources, to find the 'common' contiguous
3830 * resources. For this, take an 'AND' of all three arrays in one single
3831 * array and use your algorithm on that array.
3832 */
3833 switch (resObj->type)
3834 {
3835 case EDMA3_RM_RES_DMA_CHANNEL:
3836 {
3837 /* AND all the arrays to look into */
3838 contiguousDmaRes[0U] = ((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[0U]
3839 & rmInstance->avlblDmaChannels[0U])
3840 & (~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[0U]))
3841 );
3842 contiguousDmaRes[1U] = ((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[1U]
3843 & rmInstance->avlblDmaChannels[1U])
3844 & (~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[1U]))
3845 );
3846 }
3847 break;
3849 case EDMA3_RM_RES_QDMA_CHANNEL:
3850 {
3851 /* AND all the arrays to look into */
3852 contiguousQdmaRes[0U] = ((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0U]
3853 & rmInstance->avlblQdmaChannels[0U])
3854 & (~(rmInstance->initParam.rmInstInitConfig->resvdQdmaChannels[0U]))
3855 );
3856 }
3857 break;
3859 case EDMA3_RM_RES_TCC:
3860 {
3861 /* AND all the arrays to look into */
3862 contiguousTccRes[0U] = ((rmInstance->initParam.rmInstInitConfig->ownTccs[0U]
3863 & rmInstance->avlblTccs[0U])
3864 & (~(rmInstance->initParam.rmInstInitConfig->resvdTccs[0U]))
3865 );
3866 contiguousTccRes[1U] = ((rmInstance->initParam.rmInstInitConfig->ownTccs[1U]
3867 & rmInstance->avlblTccs[1U])
3868 & (~(rmInstance->initParam.rmInstInitConfig->resvdTccs[1U]))
3869 );
3870 }
3871 break;
3873 case EDMA3_RM_RES_PARAM_SET:
3874 {
3875 /* AND all the arrays to look into */
3876 for (i = 0U; i < (maxNumResources/32U); ++i)
3877 {
3878 contiguousParamRes[i] = ((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[i]
3879 & rmInstance->avlblPaRAMSets[i])
3880 & (~(rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[i]))
3881 );
3882 }
3883 }
3884 break;
3886 default:
3887 {
3888 result = EDMA3_RM_E_INVALID_PARAM;
3889 }
3890 break;
3891 }
3893 if (EDMA3_RM_SOK == result)
3894 {
3895 /**
3896 * Try to allocate 'numResources' contiguous resources
3897 * of type RES_ANY.
3898 */
3899 result = allocAnyContigRes (resObj->type, numResources, &position);
3901 /**
3902 * If result != EDMA3_RM_SOK, resource allocation failed.
3903 * Else resources successfully allocated.
3904 */
3905 if (result == EDMA3_RM_SOK)
3906 {
3907 /* Update the first resource id with the position returned. */
3908 resObj->resId = position;
3910 /*
3911 * Do some further changes in the book-keeping
3912 * data structures and global registers accordingly.
3913 */
3914 result = gblChngAllocContigRes(rmInstance, resObj, numResources);
3915 }
3916 }
3918 /* resource allocation completed, release the semaphore first */
3919 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
3920 }
3921 }
3922 }
3925 /**
3926 * Check the Resource Allocation Result 'result' first. If Resource
3927 * Allocation has resulted in an error, return it (having more priority than
3928 * semResult. Else, return semResult.
3929 */
3930 if (EDMA3_RM_SOK == result)
3931 {
3932 /**
3933 * Resource Allocation successful, return semResult for returning
3934 * semaphore.
3935 */
3936 result = semResult;
3937 }
3940 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3941 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3942 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3943 EDMA3_DVT_dCOUNTER,
3944 EDMA3_DVT_dNONE,
3945 EDMA3_DVT_dNONE));
3946 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3948 return result;
3949 }
3951 EDMA3_RM_Result EDMA3_RM_freeContiguousResource(EDMA3_RM_Handle hEdmaResMgr,
3952 EDMA3_RM_ResDesc *firstResIdObj,
3953 uint32_t numResources)
3954 {
3955 EDMA3_RM_Instance *rmInstance = NULL;
3956 EDMA3_RM_Obj *rmObj = NULL;
3957 EDMA3_RM_Result result = EDMA3_RM_SOK;
3958 EDMA3_RM_ResDesc *resObj;
3959 uint32_t resFreeIdx = 0U;
3960 uint32_t firstResId;
3961 uint32_t lastResId;
3962 uint32_t maxNumResources = 0U;
3964 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3965 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3966 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3967 EDMA3_DVT_dCOUNTER,
3968 EDMA3_DVT_dNONE,
3969 EDMA3_DVT_dNONE));
3970 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3972 /* If parameter checking is enabled... */
3973 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3974 if ((hEdmaResMgr == NULL) || (firstResIdObj == NULL))
3975 {
3976 result = EDMA3_RM_E_INVALID_PARAM;
3977 }
3978 #endif
3980 /* Check if the parameters are OK. */
3981 if (EDMA3_RM_SOK == result)
3982 {
3983 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3984 rmObj = rmInstance->pResMgrObjHandle;
3986 if (rmObj == NULL)
3987 {
3988 result = EDMA3_RM_E_INVALID_PARAM;
3989 }
3990 else
3991 {
3992 resObj = firstResIdObj;
3993 if (resObj != NULL)
3994 {
3995 firstResId = resObj->resId;
3996 lastResId = firstResId + (numResources - 1U);
3997 }
3999 switch (resObj->type)
4000 {
4001 case EDMA3_RM_RES_DMA_CHANNEL :
4002 maxNumResources = rmObj->gblCfgParams.numDmaChannels;
4003 break;
4004 case EDMA3_RM_RES_QDMA_CHANNEL :
4005 maxNumResources = rmObj->gblCfgParams.numQdmaChannels;
4006 break;
4007 case EDMA3_RM_RES_TCC :
4008 maxNumResources = rmObj->gblCfgParams.numTccs;
4009 break;
4010 case EDMA3_RM_RES_PARAM_SET :
4011 maxNumResources = rmObj->gblCfgParams.numPaRAMSets;
4012 break;
4013 default:
4014 result = EDMA3_RM_E_INVALID_PARAM;
4015 break;
4016 }
4018 if (result == EDMA3_RM_SOK)
4019 {
4020 if ((firstResId > lastResId) || (lastResId >= maxNumResources))
4021 {
4022 result = EDMA3_RM_E_INVALID_PARAM;
4023 }
4024 else
4025 {
4026 for (resFreeIdx = firstResId; resFreeIdx <= lastResId; ++resFreeIdx)
4027 {
4028 resObj->resId = resFreeIdx;
4029 result = EDMA3_RM_freeResource(rmInstance, resObj);
4031 if (result != EDMA3_RM_SOK)
4032 {
4033 break;
4034 }
4035 }
4036 }
4037 }
4038 }
4039 }
4041 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4042 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4043 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4044 EDMA3_DVT_dCOUNTER,
4045 EDMA3_DVT_dNONE,
4046 EDMA3_DVT_dNONE));
4047 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4049 return result;
4050 }
4052 EDMA3_RM_Result EDMA3_RM_setCCRegister (EDMA3_RM_Handle hEdmaResMgr,
4053 uint32_t regOffset,
4054 uint32_t newRegValue)
4055 {
4056 uint32_t intState;
4057 EDMA3_RM_Result result = EDMA3_RM_SOK;
4058 EDMA3_RM_Instance *rmInstance = NULL;
4059 EDMA3_RM_Obj *rmObj = NULL;
4060 volatile uint32_t regPhyAddr = 0x0U;
4063 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4064 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4065 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4066 EDMA3_DVT_dCOUNTER,
4067 EDMA3_DVT_dNONE,
4068 EDMA3_DVT_dNONE));
4069 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4072 /* If parameter checking is enabled... */
4073 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4074 if ((hEdmaResMgr == NULL) || ((regOffset % 4U) != 0))
4075 {
4076 result = (EDMA3_RM_E_INVALID_PARAM);
4077 }
4078 #endif
4080 /* Check if the parameters are OK. */
4081 if (EDMA3_RM_SOK == result)
4082 {
4083 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4084 rmObj = rmInstance->pResMgrObjHandle;
4086 if (rmObj == NULL)
4087 {
4088 result = (EDMA3_RM_E_INVALID_PARAM);
4089 }
4090 else
4091 {
4092 if (rmObj->gblCfgParams.globalRegs != NULL)
4093 {
4094 /**
4095 * Take the instance specific semaphore, to prevent simultaneous
4096 * access to the shared resources.
4097 */
4098 result = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
4099 EDMA3_OSSEM_NO_TIMEOUT);
4101 if (EDMA3_RM_SOK == result)
4102 {
4103 /* Semaphore taken successfully, modify the registers. */
4104 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
4105 EDMA3_OS_PROTECT_INTERRUPT,
4106 &intState);
4107 /* Global interrupts disabled, modify the registers. */
4108 regPhyAddr = (uint32_t)(rmObj->gblCfgParams.globalRegs) + regOffset;
4110 *(uint32_t *)regPhyAddr = newRegValue;
4111 edma3OsProtectExit (rmObj->phyCtrllerInstId,
4112 EDMA3_OS_PROTECT_INTERRUPT,
4113 intState);
4115 /* Return the semaphore back */
4116 result = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
4117 }
4118 }
4119 }
4120 }
4123 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4124 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4125 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4126 EDMA3_DVT_dCOUNTER,
4127 EDMA3_DVT_dNONE,
4128 EDMA3_DVT_dNONE));
4129 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4132 return result;
4133 }
4135 EDMA3_RM_Result EDMA3_RM_getCCRegister (EDMA3_RM_Handle hEdmaResMgr,
4136 uint32_t regOffset,
4137 uint32_t *regValue)
4138 {
4139 EDMA3_RM_Result result = EDMA3_RM_SOK;
4140 EDMA3_RM_Instance *rmInstance = NULL;
4141 EDMA3_RM_Obj *rmObj = NULL;
4142 volatile uint32_t regPhyAddr = 0x0U;
4145 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4146 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4147 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4148 EDMA3_DVT_dCOUNTER,
4149 EDMA3_DVT_dNONE,
4150 EDMA3_DVT_dNONE));
4151 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4154 /* If parameter checking is enabled... */
4155 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4156 if (((hEdmaResMgr == NULL) || (regValue == NULL))
4157 || ((regOffset % 4U) != 0))
4158 {
4159 result = (EDMA3_RM_E_INVALID_PARAM);
4160 }
4161 #endif
4163 /* Check if the parameters are OK. */
4164 if (EDMA3_RM_SOK == result)
4165 {
4166 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4167 rmObj = rmInstance->pResMgrObjHandle;
4169 if (rmObj == NULL)
4170 {
4171 result = (EDMA3_RM_E_INVALID_PARAM);
4172 }
4173 else
4174 {
4175 if (rmObj->gblCfgParams.globalRegs != NULL)
4176 {
4177 regPhyAddr = (uint32_t)(rmObj->gblCfgParams.globalRegs) + regOffset;
4179 *regValue = *(uint32_t *)regPhyAddr;
4180 }
4181 }
4182 }
4185 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4186 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4187 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4188 EDMA3_DVT_dCOUNTER,
4189 EDMA3_DVT_dNONE,
4190 EDMA3_DVT_dNONE));
4191 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4194 return result;
4195 }
4197 EDMA3_RM_Result EDMA3_RM_waitAndClearTcc (EDMA3_RM_Handle hEdmaResMgr,
4198 uint32_t tccNo)
4199 {
4200 EDMA3_RM_Result result = EDMA3_RM_SOK;
4201 EDMA3_RM_Instance *rmInstance = NULL;
4202 EDMA3_RM_Obj *rmObj = NULL;
4203 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4204 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
4205 uint32_t tccBitMask = 0x0U;
4208 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4209 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4210 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4211 EDMA3_DVT_dCOUNTER,
4212 EDMA3_DVT_dNONE,
4213 EDMA3_DVT_dNONE));
4214 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4217 /* If parameter checking is enabled... */
4218 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4219 if (hEdmaResMgr == NULL)
4220 {
4221 result = (EDMA3_RM_E_INVALID_PARAM);
4222 }
4223 #endif
4225 /* Check if the parameters are OK. */
4226 if (EDMA3_RM_SOK == result)
4227 {
4228 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4229 rmObj = rmInstance->pResMgrObjHandle;
4231 if ((rmObj == NULL) || (rmObj->gblCfgParams.globalRegs == NULL))
4232 {
4233 result = (EDMA3_RM_E_INVALID_PARAM);
4234 }
4235 else
4236 {
4237 /* If parameter checking is enabled... */
4238 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4239 if (tccNo >= rmObj->gblCfgParams.numTccs)
4240 {
4241 result = (EDMA3_RM_E_INVALID_PARAM);
4242 }
4243 #endif
4245 /* Check if the parameters are OK. */
4246 if (EDMA3_RM_SOK == result)
4247 {
4248 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4249 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
4250 (&globalRegs->SHADOW[rmInstance->initParam.regionId]);
4253 if (shadowRegs != NULL)
4254 {
4255 if(tccNo < 32U)
4256 {
4257 tccBitMask = (1U << tccNo);
4259 /* Check the status of the IPR[tccNo] bit. */
4260 while (FALSE == (shadowRegs->IPR & tccBitMask))
4261 {
4262 /* Transfer not yet completed, bit not SET */
4263 }
4265 /**
4266 * Bit found SET, transfer is completed,
4267 * clear the pending interrupt and return.
4268 */
4269 shadowRegs->ICR = tccBitMask;
4270 }
4271 else
4272 {
4273 tccBitMask = (1U << (tccNo - 32U));
4275 /* Check the status of the IPRH[tccNo-32] bit. */
4276 while (FALSE == (shadowRegs->IPRH & tccBitMask))
4277 {
4278 /* Transfer not yet completed, bit not SET */
4279 }
4281 /**
4282 * Bit found SET, transfer is completed,
4283 * clear the pending interrupt and return.
4284 */
4285 shadowRegs->ICRH = tccBitMask;
4286 }
4287 }
4288 }
4289 }
4290 }
4293 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4294 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4295 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4296 EDMA3_DVT_dCOUNTER,
4297 EDMA3_DVT_dNONE,
4298 EDMA3_DVT_dNONE));
4299 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4302 return result;
4303 }
4305 EDMA3_RM_Result EDMA3_RM_checkAndClearTcc (EDMA3_RM_Handle hEdmaResMgr,
4306 uint32_t tccNo,
4307 uint16_t *tccStatus)
4308 {
4309 EDMA3_RM_Result result = EDMA3_RM_SOK;
4310 EDMA3_RM_Instance *rmInstance = NULL;
4311 EDMA3_RM_Obj *rmObj = NULL;
4312 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4313 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
4314 uint32_t tccBitMask = 0x0U;
4317 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4318 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4319 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4320 EDMA3_DVT_dCOUNTER,
4321 EDMA3_DVT_dNONE,
4322 EDMA3_DVT_dNONE));
4323 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4326 /* If parameter checking is enabled... */
4327 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4328 if ((hEdmaResMgr == NULL) || (tccStatus == NULL))
4329 {
4330 result = (EDMA3_RM_E_INVALID_PARAM);
4331 }
4332 #endif
4334 /* Check if the parameters are OK. */
4335 if (EDMA3_RM_SOK == result)
4336 {
4337 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4338 rmObj = rmInstance->pResMgrObjHandle;
4340 if ((rmObj == NULL) || (rmObj->gblCfgParams.globalRegs == NULL))
4341 {
4342 result = (EDMA3_RM_E_INVALID_PARAM);
4343 }
4344 else
4345 {
4346 /* If parameter checking is enabled... */
4347 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4348 if (tccNo >= rmObj->gblCfgParams.numTccs)
4349 {
4350 result = (EDMA3_RM_E_INVALID_PARAM);
4351 }
4352 #endif
4354 /* Check if the parameters are OK. */
4355 if (EDMA3_RM_SOK == result)
4356 {
4357 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4358 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
4359 (&globalRegs->SHADOW[rmInstance->initParam.regionId]);
4361 /* Reset the tccStatus */
4362 *tccStatus = FALSE;
4364 if (shadowRegs != NULL)
4365 {
4366 if(tccNo < 32U)
4367 {
4368 tccBitMask = (1U << tccNo);
4370 /* Check the status of the IPR[tccNo] bit. */
4371 if ((shadowRegs->IPR & tccBitMask) != FALSE)
4372 {
4373 /* Transfer completed, bit found SET */
4374 *tccStatus = TRUE;
4376 /* Clear the pending interrupt also. */
4377 shadowRegs->ICR = tccBitMask;
4378 }
4379 }
4380 else
4381 {
4382 tccBitMask = (1U << (tccNo - 32U));
4384 /* Check the status of the IPRH[tccNo-32] bit. */
4385 if ((shadowRegs->IPRH & tccBitMask) != FALSE)
4386 {
4387 /* Transfer completed, bit found SET */
4388 *tccStatus = TRUE;
4390 /* Clear the pending interrupt also. */
4391 shadowRegs->ICRH = tccBitMask;
4392 }
4393 }
4394 }
4395 }
4396 }
4397 }
4400 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4401 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4402 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4403 EDMA3_DVT_dCOUNTER,
4404 EDMA3_DVT_dNONE,
4405 EDMA3_DVT_dNONE));
4406 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4409 return result;
4410 }
4412 EDMA3_RM_Result EDMA3_RM_setPaRAM (EDMA3_RM_Handle hEdmaResMgr,
4413 EDMA3_RM_ResDesc *lChObj,
4414 const EDMA3_RM_PaRAMRegs *newPaRAM)
4415 {
4416 EDMA3_RM_Result result = EDMA3_RM_SOK;
4417 EDMA3_RM_Instance *rmInstance = NULL;
4418 EDMA3_RM_Obj *rmObj = NULL;
4419 int32_t paRAMId = 0U;
4420 uint32_t qdmaChId = 0U;
4421 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4422 uint32_t edma3Id;
4424 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4425 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4426 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4427 EDMA3_DVT_dCOUNTER,
4428 EDMA3_DVT_dNONE,
4429 EDMA3_DVT_dNONE));
4430 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4432 /* If parameter checking is enabled... */
4433 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4434 if (hEdmaResMgr == NULL)
4435 {
4436 result = EDMA3_RM_E_INVALID_PARAM;
4437 }
4439 if ((lChObj == NULL) || (newPaRAM == NULL))
4440 {
4441 result = EDMA3_RM_E_INVALID_PARAM;
4442 }
4443 #endif
4445 /* Check if the parameters are OK. */
4446 if (result == EDMA3_RM_SOK)
4447 {
4448 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4450 if (rmInstance == NULL)
4451 {
4452 result = EDMA3_RM_E_INVALID_PARAM;
4453 }
4454 }
4456 if (result == EDMA3_RM_SOK)
4457 {
4458 rmObj = rmInstance->pResMgrObjHandle;
4460 if (rmObj == NULL)
4461 {
4462 result = EDMA3_RM_E_INVALID_PARAM;
4463 }
4464 else
4465 {
4466 if (rmObj->gblCfgParams.globalRegs == NULL)
4467 {
4468 result = EDMA3_RM_E_INVALID_PARAM;
4469 }
4470 }
4471 }
4473 if (result == EDMA3_RM_SOK)
4474 {
4475 edma3Id = rmObj->phyCtrllerInstId;
4476 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4478 switch (lChObj->type)
4479 {
4480 case EDMA3_RM_RES_DMA_CHANNEL:
4481 {
4482 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4483 {
4484 paRAMId = edma3RmChBoundRes[edma3Id][lChObj->resId].paRAMId;
4485 }
4486 else
4487 {
4488 result = EDMA3_RM_E_INVALID_PARAM;
4489 }
4490 }
4491 break;
4493 case EDMA3_RM_RES_QDMA_CHANNEL:
4494 {
4495 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4496 {
4497 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4498 paRAMId = edma3RmChBoundRes[edma3Id][qdmaChId].paRAMId;
4499 }
4500 else
4501 {
4502 result = EDMA3_RM_E_INVALID_PARAM;
4503 }
4504 }
4505 break;
4507 case EDMA3_RM_RES_PARAM_SET:
4508 {
4509 if (lChObj->resId < edma3NumPaRAMSets)
4510 {
4511 /**
4512 * User has passed the actual param set value here.
4513 * Use this value only
4514 */
4515 paRAMId = (int32_t)(lChObj->resId);
4516 }
4517 else
4518 {
4519 result = EDMA3_RM_E_INVALID_PARAM;
4520 }
4521 }
4522 break;
4524 default:
4525 {
4526 result = EDMA3_RM_E_INVALID_PARAM;
4527 break;
4528 }
4529 }
4530 }
4533 if (result == EDMA3_RM_SOK)
4534 {
4535 /* Check the param id first. */
4536 if ((paRAMId != -1) && ((uint32_t)paRAMId < edma3NumPaRAMSets))
4537 {
4538 /* Set the PaRAM Set now. */
4539 edma3ParamCpy ((volatile void *)(&(globalRegs->PARAMENTRY[paRAMId].OPT)),
4540 (const void *)newPaRAM);
4541 }
4542 else
4543 {
4544 result = EDMA3_RM_E_INVALID_PARAM;
4545 }
4546 }
4549 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4550 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4551 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4552 EDMA3_DVT_dCOUNTER,
4553 EDMA3_DVT_dNONE,
4554 EDMA3_DVT_dNONE));
4555 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4557 return result;
4558 }
4560 EDMA3_RM_Result EDMA3_RM_getPaRAM (EDMA3_RM_Handle hEdmaResMgr,
4561 EDMA3_RM_ResDesc *lChObj,
4562 EDMA3_RM_PaRAMRegs *currPaRAM)
4563 {
4564 EDMA3_RM_Result result = EDMA3_RM_SOK;
4565 EDMA3_RM_Instance *rmInstance = NULL;
4566 EDMA3_RM_Obj *rmObj = NULL;
4567 int32_t paRAMId = 0U;
4568 uint32_t qdmaChId = 0U;
4569 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4570 uint32_t edma3Id;
4572 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4573 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4574 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4575 EDMA3_DVT_dCOUNTER,
4576 EDMA3_DVT_dNONE,
4577 EDMA3_DVT_dNONE));
4578 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4580 /* If parameter checking is enabled... */
4581 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4582 if (hEdmaResMgr == NULL)
4583 {
4584 result = EDMA3_RM_E_INVALID_PARAM;
4585 }
4587 if ((lChObj == NULL) || (currPaRAM == NULL))
4588 {
4589 result = EDMA3_RM_E_INVALID_PARAM;
4590 }
4591 #endif
4593 /* Check if the parameters are OK. */
4594 if (result == EDMA3_RM_SOK)
4595 {
4596 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4598 if (rmInstance == NULL)
4599 {
4600 result = EDMA3_RM_E_INVALID_PARAM;
4601 }
4602 }
4604 if (result == EDMA3_RM_SOK)
4605 {
4606 rmObj = rmInstance->pResMgrObjHandle;
4608 if (rmObj == NULL)
4609 {
4610 result = EDMA3_RM_E_INVALID_PARAM;
4611 }
4612 else
4613 {
4614 if (rmObj->gblCfgParams.globalRegs == NULL)
4615 {
4616 result = EDMA3_RM_E_INVALID_PARAM;
4617 }
4618 }
4619 }
4621 if (result == EDMA3_RM_SOK)
4622 {
4623 edma3Id = rmObj->phyCtrllerInstId;
4624 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4626 switch (lChObj->type)
4627 {
4628 case EDMA3_RM_RES_DMA_CHANNEL:
4629 {
4630 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4631 {
4632 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][lChObj->resId].paRAMId;
4633 }
4634 else
4635 {
4636 result = EDMA3_RM_E_INVALID_PARAM;
4637 }
4638 }
4639 break;
4641 case EDMA3_RM_RES_QDMA_CHANNEL:
4642 {
4643 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4644 {
4645 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4646 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId;
4647 }
4648 else
4649 {
4650 result = EDMA3_RM_E_INVALID_PARAM;
4651 }
4652 }
4653 break;
4655 case EDMA3_RM_RES_PARAM_SET:
4656 {
4657 if (lChObj->resId < edma3NumPaRAMSets)
4658 {
4659 /**
4660 * User has passed the actual param set value here.
4661 * Use this value only
4662 */
4663 paRAMId = (int32_t)(lChObj->resId);
4664 }
4665 else
4666 {
4667 result = EDMA3_RM_E_INVALID_PARAM;
4668 }
4669 }
4670 break;
4672 default:
4673 {
4674 result = EDMA3_RM_E_INVALID_PARAM;
4675 break;
4676 }
4677 }
4678 }
4681 if (result == EDMA3_RM_SOK)
4682 {
4683 /* Check the param id first. */
4684 if ((paRAMId != -1) && (paRAMId < edma3NumPaRAMSets))
4685 {
4686 /* Get the PaRAM Set now. */
4687 edma3ParamCpy ((void *)currPaRAM ,
4688 (const volatile void *)(&(globalRegs->PARAMENTRY [paRAMId].OPT)));
4689 }
4690 else
4691 {
4692 result = EDMA3_RM_E_INVALID_PARAM;
4693 }
4694 }
4697 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4698 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4699 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4700 EDMA3_DVT_dCOUNTER,
4701 EDMA3_DVT_dNONE,
4702 EDMA3_DVT_dNONE));
4703 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4706 return result;
4707 }
4709 EDMA3_RM_Result EDMA3_RM_getPaRAMPhyAddr(EDMA3_RM_Handle hEdmaResMgr,
4710 EDMA3_RM_ResDesc *lChObj,
4711 uint32_t *paramPhyAddr)
4712 {
4713 EDMA3_RM_Result result = EDMA3_RM_SOK;
4714 EDMA3_RM_Instance *rmInstance = NULL;
4715 EDMA3_RM_Obj *rmObj = NULL;
4716 int32_t paRAMId = 0U;
4717 uint32_t qdmaChId = 0U;
4718 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4719 uint32_t edma3Id;
4721 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4722 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4723 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4724 EDMA3_DVT_dCOUNTER,
4725 EDMA3_DVT_dNONE,
4726 EDMA3_DVT_dNONE));
4727 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4730 /* If parameter checking is enabled... */
4731 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4732 if (hEdmaResMgr == NULL)
4733 {
4734 result = EDMA3_RM_E_INVALID_PARAM;
4735 }
4737 if ((lChObj == NULL) || (paramPhyAddr == NULL))
4738 {
4739 result = EDMA3_RM_E_INVALID_PARAM;
4740 }
4741 #endif
4743 if (result == EDMA3_RM_SOK)
4744 {
4745 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4747 if (rmInstance == NULL)
4748 {
4749 result = EDMA3_RM_E_INVALID_PARAM;
4750 }
4751 }
4753 if (result == EDMA3_RM_SOK)
4754 {
4755 rmObj = rmInstance->pResMgrObjHandle;
4757 if (rmObj == NULL)
4758 {
4759 result = EDMA3_RM_E_INVALID_PARAM;
4760 }
4761 else
4762 {
4763 if (rmObj->gblCfgParams.globalRegs == NULL)
4764 {
4765 result = EDMA3_RM_E_INVALID_PARAM;
4766 }
4767 }
4768 }
4770 if (result == EDMA3_RM_SOK)
4771 {
4772 edma3Id = rmObj->phyCtrllerInstId;
4773 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4775 switch (lChObj->type)
4776 {
4777 case EDMA3_RM_RES_DMA_CHANNEL:
4778 {
4779 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4780 {
4781 paRAMId = edma3RmChBoundRes[edma3Id][lChObj->resId].paRAMId;
4782 }
4783 else
4784 {
4785 result = EDMA3_RM_E_INVALID_PARAM;
4786 }
4787 }
4788 break;
4790 case EDMA3_RM_RES_QDMA_CHANNEL:
4791 {
4792 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4793 {
4794 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4795 paRAMId = edma3RmChBoundRes[edma3Id][qdmaChId].paRAMId;
4796 }
4797 else
4798 {
4799 result = EDMA3_RM_E_INVALID_PARAM;
4800 }
4801 }
4802 break;
4804 case EDMA3_RM_RES_PARAM_SET:
4805 {
4806 if (lChObj->resId < edma3NumPaRAMSets)
4807 {
4808 /**
4809 * User has passed the actual param set value here.
4810 * Use this value only
4811 */
4812 paRAMId = (int32_t)(lChObj->resId);
4813 }
4814 else
4815 {
4816 result = EDMA3_RM_E_INVALID_PARAM;
4817 }
4818 }
4819 break;
4821 default:
4822 {
4823 result = EDMA3_RM_E_INVALID_PARAM;
4824 break;
4825 }
4826 }
4827 }
4829 if (result == EDMA3_RM_SOK)
4830 {
4831 /* Check the param id first. */
4832 if ((paRAMId != -1) && (paRAMId < edma3NumPaRAMSets))
4833 {
4834 /* Get the PaRAM Set Address now. */
4835 *paramPhyAddr = (uint32_t)(&(globalRegs->PARAMENTRY [paRAMId].OPT));
4836 }
4837 else
4838 {
4839 result = EDMA3_RM_E_INVALID_PARAM;
4840 }
4841 }
4843 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4844 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4845 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4846 EDMA3_DVT_dCOUNTER,
4847 EDMA3_DVT_dNONE,
4848 EDMA3_DVT_dNONE));
4849 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4851 return result;
4852 }
4854 EDMA3_RM_Result EDMA3_RM_getBaseAddress (EDMA3_RM_Handle hEdmaResMgr,
4855 EDMA3_RM_Cntrlr_PhyAddr controllerId,
4856 uint32_t *phyAddress)
4857 {
4858 EDMA3_RM_Result result = EDMA3_RM_SOK;
4859 EDMA3_RM_Instance *rmInstance = NULL;
4860 EDMA3_RM_Obj *rmObj = NULL;
4862 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4863 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4864 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4865 EDMA3_DVT_dCOUNTER,
4866 EDMA3_DVT_dNONE,
4867 EDMA3_DVT_dNONE));
4868 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4871 /* If parameter checking is enabled... */
4872 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4873 if ((hEdmaResMgr == NULL) || (phyAddress == NULL))
4874 {
4875 result = EDMA3_RM_E_INVALID_PARAM;
4876 }
4877 #endif
4879 if (result == EDMA3_RM_SOK)
4880 {
4881 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4883 if (rmInstance == NULL)
4884 {
4885 result = EDMA3_RM_E_INVALID_PARAM;
4886 }
4887 }
4889 if (result == EDMA3_RM_SOK)
4890 {
4891 rmObj = rmInstance->pResMgrObjHandle;
4893 if (rmObj == NULL)
4894 {
4895 result = EDMA3_RM_E_INVALID_PARAM;
4896 }
4897 }
4899 if (result == EDMA3_RM_SOK)
4900 {
4901 /* If parameter checking is enabled... */
4902 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4903 /* Verify the 'controllerId' */
4904 if (((int32_t)controllerId < (int32_t)((EDMA3_RM_Cntrlr_PhyAddr)(EDMA3_RM_CC_PHY_ADDR)))
4905 || (controllerId > (EDMA3_RM_Cntrlr_PhyAddr)(rmObj->gblCfgParams.numTcs)))
4906 {
4907 /* Invalid controllerId */
4908 result = EDMA3_RM_E_INVALID_PARAM;
4909 }
4910 #endif
4912 /* Check if the parameters are OK. */
4913 if (EDMA3_RM_SOK == result)
4914 {
4915 if (controllerId == EDMA3_RM_CC_PHY_ADDR)
4916 {
4917 /* EDMA3 Channel Controller Address */
4918 *phyAddress = (uint32_t)(rmObj->gblCfgParams.globalRegs);
4919 }
4920 else
4921 {
4922 /**
4923 * Since the TCs enum start from 1, and TCs start from 0,
4924 * subtract 1 from the enum to get the actual address.
4925 */
4926 *phyAddress = (uint32_t)(rmObj->gblCfgParams.tcRegs[controllerId-1U]);
4927 }
4928 }
4929 }
4931 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4932 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4933 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4934 EDMA3_DVT_dCOUNTER,
4935 EDMA3_DVT_dNONE,
4936 EDMA3_DVT_dNONE));
4937 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4939 return result;
4940 }
4942 EDMA3_RM_Result EDMA3_RM_getGblConfigParams (
4943 uint32_t phyCtrllerInstId,
4944 EDMA3_RM_GblConfigParams *gblCfgParams)
4945 {
4946 EDMA3_RM_Result result = EDMA3_RM_SOK;
4948 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4949 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4950 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4951 EDMA3_DVT_dCOUNTER,
4952 EDMA3_DVT_dNONE,
4953 EDMA3_DVT_dNONE));
4954 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4956 /* If parameter checking is enabled... */
4957 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4958 if ((phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
4959 || (NULL == gblCfgParams))
4960 {
4961 result = EDMA3_RM_E_INVALID_PARAM;
4962 }
4963 #endif
4965 if (EDMA3_RM_SOK == result)
4966 {
4967 /* Return the previously saved global config information for the EDMA3 HW */
4968 edma3MemCpy((void *)(gblCfgParams),
4969 (const void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
4970 sizeof (EDMA3_RM_GblConfigParams));
4971 }
4973 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4974 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4975 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4976 EDMA3_DVT_dCOUNTER,
4977 EDMA3_DVT_dNONE,
4978 EDMA3_DVT_dNONE));
4979 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4981 return result;
4982 }
4984 EDMA3_RM_Result EDMA3_RM_getInstanceInitCfg (
4985 EDMA3_RM_Handle hEdmaResMgr,
4986 EDMA3_RM_InstanceInitConfig *instanceInitConfig)
4987 {
4988 EDMA3_RM_Result result = EDMA3_RM_SOK;
4989 EDMA3_RM_Instance *rmInstance = NULL;
4990 EDMA3_RM_Obj *rmObj = NULL;
4991 uint32_t resMgrIdx = 0U;
4992 uint32_t hwId;
4994 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4995 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4996 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4997 EDMA3_DVT_dCOUNTER,
4998 EDMA3_DVT_dNONE,
4999 EDMA3_DVT_dNONE));
5000 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5002 /* If parameter checking is enabled... */
5003 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5004 if ((hEdmaResMgr == NULL) || (instanceInitConfig == NULL))
5005 {
5006 result = EDMA3_RM_E_INVALID_PARAM;
5007 }
5008 #endif
5010 if (result == EDMA3_RM_SOK)
5011 {
5012 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
5014 if (rmInstance == NULL)
5015 {
5016 result = EDMA3_RM_E_INVALID_PARAM;
5017 }
5018 }
5020 if (result == EDMA3_RM_SOK)
5021 {
5022 rmObj = rmInstance->pResMgrObjHandle;
5024 if (rmObj == NULL)
5025 {
5026 result = EDMA3_RM_E_INVALID_PARAM;
5027 }
5028 }
5030 if (result == EDMA3_RM_SOK)
5031 {
5032 hwId = rmObj->phyCtrllerInstId;
5034 for (resMgrIdx = 0U; resMgrIdx < EDMA3_MAX_RM_INSTANCES; resMgrIdx++)
5035 {
5036 if (rmInstance == ((EDMA3_RM_Instance *)(ptrRMIArray) +
5037 (hwId*EDMA3_MAX_RM_INSTANCES) +
5038 resMgrIdx))
5039 {
5040 /* RM Id found. Return the specific config info to the user. */
5041 edma3MemCpy((void *)(instanceInitConfig),
5042 (const void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) +
5043 (hwId*EDMA3_MAX_RM_INSTANCES) +
5044 resMgrIdx),
5045 sizeof (EDMA3_RM_InstanceInitConfig));
5046 break;
5047 }
5048 }
5050 if (EDMA3_MAX_RM_INSTANCES == resMgrIdx)
5051 {
5052 /* RM Id not found, report error... */
5053 result = EDMA3_RM_E_INVALID_PARAM;
5054 }
5055 }
5057 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5058 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5059 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5060 EDMA3_DVT_dCOUNTER,
5061 EDMA3_DVT_dNONE,
5062 EDMA3_DVT_dNONE));
5063 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5065 return result;
5066 }
5068 EDMA3_RM_Result EDMA3_RM_Ioctl(
5069 EDMA3_RM_Handle hEdmaResMgr,
5070 EDMA3_RM_IoctlCmd cmd,
5071 void *cmdArg,
5072 void *param
5073 )
5074 {
5075 EDMA3_RM_Result result = EDMA3_RM_SOK;
5076 EDMA3_RM_Instance *rmInstance = NULL;
5077 uint32_t paramInitRequired = 0xFFU;
5078 uint32_t regModificationRequired = 0xFFU;
5079 uint32_t *ret_val = NULL;
5081 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5082 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5083 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
5084 EDMA3_DVT_dCOUNTER,
5085 EDMA3_DVT_dNONE,
5086 EDMA3_DVT_dNONE));
5087 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5089 /* If parameter checking is enabled... */
5090 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5091 if (hEdmaResMgr == NULL)
5092 {
5093 result = EDMA3_RM_E_INVALID_PARAM;
5094 }
5096 if ((cmd <= EDMA3_RM_IOCTL_MIN_IOCTL)
5097 || (cmd >= EDMA3_RM_IOCTL_MAX_IOCTL))
5098 {
5099 result = EDMA3_RM_E_INVALID_PARAM;
5100 }
5101 #endif
5103 if (result == EDMA3_RM_SOK)
5104 {
5105 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
5107 if (rmInstance == NULL)
5108 {
5109 result = EDMA3_RM_E_INVALID_PARAM;
5110 }
5111 }
5113 if (result == EDMA3_RM_SOK)
5114 {
5115 switch (cmd)
5116 {
5117 case EDMA3_RM_IOCTL_SET_PARAM_CLEAR_OPTION:
5118 {
5119 paramInitRequired = (uint32_t)cmdArg;
5121 /* If parameter checking is enabled... */
5122 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5123 if ((paramInitRequired != 0U)
5124 && (paramInitRequired != 1U))
5125 {
5126 result = EDMA3_RM_E_INVALID_PARAM;
5127 }
5128 #endif
5130 /* Check if the parameters are OK. */
5131 if (EDMA3_RM_SOK == result)
5132 {
5133 /* Set/Reset the flag which is being used to do the PaRAM clearing. */
5134 rmInstance->paramInitRequired = paramInitRequired;
5135 }
5137 break;
5138 }
5140 case EDMA3_RM_IOCTL_GET_PARAM_CLEAR_OPTION:
5141 {
5142 /* If parameter checking is enabled... */
5143 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5144 if (NULL == cmdArg)
5145 {
5146 result = EDMA3_RM_E_INVALID_PARAM;
5147 }
5148 #endif
5150 /* Check if the parameters are OK. */
5151 if (EDMA3_RM_SOK == result)
5152 {
5153 ret_val = (uint32_t *)cmdArg;
5155 /* Get the flag which is being used to do the PaRAM clearing. */
5156 *ret_val = rmInstance->paramInitRequired;
5157 }
5159 break;
5160 }
5162 case EDMA3_RM_IOCTL_SET_GBL_REG_MODIFY_OPTION:
5163 {
5164 regModificationRequired = (uint32_t)cmdArg;
5166 /* If parameter checking is enabled... */
5167 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5168 if ((regModificationRequired != 0U)
5169 && (regModificationRequired != 1U))
5170 {
5171 /* All other values are invalid. */
5172 result = EDMA3_RM_E_INVALID_PARAM;
5173 }
5174 #endif
5176 /* Check if the parameters are OK. */
5177 if (EDMA3_RM_SOK == result)
5178 {
5179 /**
5180 * Set/Reset the flag which is being used to do the global
5181 * registers and PaRAM modification.
5182 */
5183 rmInstance->regModificationRequired = regModificationRequired;
5184 }
5186 break;
5187 }
5189 case EDMA3_RM_IOCTL_GET_GBL_REG_MODIFY_OPTION:
5190 {
5191 /* If parameter checking is enabled... */
5192 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5193 if (NULL == cmdArg)
5194 {
5195 result = EDMA3_RM_E_INVALID_PARAM;
5196 }
5197 #endif
5199 /* Check if the parameters are OK. */
5200 if (EDMA3_RM_SOK == result)
5201 {
5202 ret_val = (uint32_t *)cmdArg;
5204 /**
5205 * Get the flag which is being used to do the global
5206 * registers and PaRAM modification.
5207 */
5208 *ret_val = rmInstance->regModificationRequired;
5209 }
5211 break;
5212 }
5214 default:
5215 {
5216 /* Hey dude! you passed invalid IOCTL cmd */
5217 result = EDMA3_RM_E_INVALID_PARAM;
5218 break;
5219 }
5221 }
5222 }
5225 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5226 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5227 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5228 EDMA3_DVT_dCOUNTER,
5229 EDMA3_DVT_dNONE,
5230 EDMA3_DVT_dNONE));
5231 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5233 return result;
5235 }
5237 /**
5238 * edma3ComplHandler
5239 * \brief Interrupt handler for successful transfer completion.
5240 *
5241 * \note This function first disables its own interrupt to make it non-
5242 * entrant. Later, after calling all the callback functions, it
5243 * re-enables its own interrupt.
5244 *
5245 * \return None.
5246 */
5247 static void edma3ComplHandler (const EDMA3_RM_Obj *rmObj)
5248 {
5249 uint32_t Cnt;
5250 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
5251 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
5252 volatile uint32_t pendingIrqs;
5253 volatile uint32_t isIPR = 0;
5255 uint32_t indexl;
5256 uint32_t indexh;
5257 uint32_t edma3Id;
5258 uint32_t numTCCs;
5260 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5261 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5262 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5263 EDMA3_DVT_dNONE,
5264 EDMA3_DVT_dNONE,
5265 EDMA3_DVT_dNONE));
5266 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5268 assert (NULL != rmObj);
5270 edma3Id = rmObj->phyCtrllerInstId;
5271 numTCCs = rmObj->gblCfgParams.numTccs;
5272 ptrEdmaccRegs =
5273 (volatile EDMA3_CCRL_Regs *)rmObj->gblCfgParams.globalRegs;
5274 if (ptrEdmaccRegs != NULL)
5275 {
5276 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
5277 (&ptrEdmaccRegs->SHADOW[edma3RegionId]);
5278 }
5280 Cnt = 0U;
5281 pendingIrqs = 0U;
5282 indexl = 1U;
5283 indexh = 1U;
5285 if (numTCCs > 32)
5286 {
5287 isIPR = shadowRegs->IPR | shadowRegs->IPRH;
5288 }
5289 else
5290 {
5291 isIPR = shadowRegs->IPR;
5292 }
5293 if(isIPR)
5294 {
5295 /**
5296 * Since an interrupt has found, we have to make sure that this
5297 * interrupt (TCC) belongs to the TCCs allocated by us only.
5298 * It might happen that someone else, who is using EDMA3 also,
5299 * is the owner of this interrupt channel i.e. the TCC.
5300 * For this, use the allocatedTCCs[], to check which all interrupt
5301 * channels are owned by the EDMA3 RM Instances.
5302 */
5304 edma3OsProtectEntry (edma3Id,
5305 EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,
5306 NULL);
5308 /* Loop for EDMA3_RM_COMPL_HANDLER_RETRY_COUNT number of time,
5309 breaks when no pending interrupt is found */
5310 while ((Cnt < EDMA3_RM_COMPL_HANDLER_RETRY_COUNT)
5311 && ((indexl != 0U) || (indexh != 0U)))
5312 {
5313 indexl = 0U;
5314 pendingIrqs = shadowRegs->IPR;
5316 /**
5317 * Choose interrupts coming from our allocated TCCs
5318 * and MASK remaining ones.
5319 */
5320 pendingIrqs = (pendingIrqs & allocatedTCCs[edma3Id][0U]);
5322 while (pendingIrqs)
5323 {
5324 /*Process all the pending interrupts*/
5325 if((pendingIrqs & 1U) == TRUE)
5326 {
5327 /**
5328 * If the user has not given any callback function
5329 * while requesting the TCC, its TCC specific bit
5330 * in the IPR register will NOT be cleared.
5331 */
5332 if(edma3IntrParams[edma3Id][indexl].tccCb != NULL)
5333 {
5334 /* here write to ICR to clear the corresponding IPR bits*/
5335 shadowRegs->ICR = (1U << indexl);
5337 edma3IntrParams[edma3Id][indexl].tccCb (indexl,
5338 EDMA3_RM_XFER_COMPLETE,
5339 edma3IntrParams[edma3Id][indexl].cbData);
5340 }
5341 }
5342 ++indexl;
5343 pendingIrqs >>= 1U;
5344 }
5346 if(numTCCs > 32)
5347 {
5348 indexh = 0U;
5349 pendingIrqs = shadowRegs->IPRH;
5351 /**
5352 * Choose interrupts coming from our allocated TCCs
5353 * and MASK remaining ones.
5354 */
5355 pendingIrqs = (pendingIrqs & allocatedTCCs[edma3Id][1U]);
5357 while (pendingIrqs)
5358 {
5359 /*Process all the pending interrupts*/
5360 if((pendingIrqs & 1U)==TRUE)
5361 {
5362 /**
5363 * If the user has not given any callback function
5364 * while requesting the TCC, its TCC specific bit
5365 * in the IPRH register will NOT be cleared.
5366 */
5367 if(edma3IntrParams[edma3Id][32U+indexh].tccCb!=NULL)
5368 {
5369 /* here write to ICR to clear the corresponding IPR bits*/
5370 shadowRegs->ICRH = (1U << indexh);
5372 edma3IntrParams[edma3Id][32U+indexh].tccCb(32U+indexh,
5373 EDMA3_RM_XFER_COMPLETE,
5374 edma3IntrParams[edma3Id][32U+indexh].cbData);
5375 }
5376 }
5377 ++indexh;
5378 pendingIrqs >>= 1U;
5379 }
5380 }
5382 Cnt++;
5383 }
5385 indexl = (shadowRegs->IPR & allocatedTCCs[edma3Id][0U]);
5386 if (numTCCs > 32)
5387 {
5388 indexh = (shadowRegs->IPRH & allocatedTCCs[edma3Id][1U]);
5389 }
5391 if((indexl !=0 ) || (indexh !=0 ))
5392 {
5393 shadowRegs->IEVAL=0x1U;
5394 }
5396 edma3OsProtectExit (rmObj->phyCtrllerInstId,
5397 EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,
5398 0);
5399 }
5401 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5402 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5403 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5404 EDMA3_DVT_dNONE,
5405 EDMA3_DVT_dNONE,
5406 EDMA3_DVT_dNONE));
5407 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5408 }
5411 void lisrEdma3ComplHandler0(uint32_t edma3InstanceId)
5412 {
5413 /* Invoke Completion Handler ISR */
5414 edma3ComplHandler(&resMgrObj[edma3InstanceId]);
5415 }
5418 /**
5419 * \brief Interrupt handler for Channel Controller Error.
5420 *
5421 * \note This function first disables its own interrupt to make it non-
5422 * entrant. Later, after calling all the callback functions, it
5423 * re-enables its own interrupt.
5424 *
5425 * \return None.
5426 */
5427 static void edma3CCErrHandler(const EDMA3_RM_Obj *rmObj)
5428 {
5429 uint32_t Cnt = 0U;
5430 uint32_t resMgrInstIdx = 0U;
5431 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
5432 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
5433 volatile uint32_t pendingIrqs = 0;
5434 uint32_t index;
5435 uint32_t evtqueNum;
5436 EDMA3_RM_Instance *rm_instance = NULL;
5437 uint32_t edma3Id;
5438 uint32_t num_rm_instances_opened;
5439 EDMA3_RM_Instance *rmInstance = NULL;
5440 uint32_t ownedDmaError = 0;
5441 uint32_t ownedDmaHError = 0;
5442 uint32_t ownedQdmaError = 0;
5443 uint32_t numTCCs;
5445 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5446 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_CCERR",
5447 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5448 EDMA3_DVT_dNONE,
5449 EDMA3_DVT_dNONE,
5450 EDMA3_DVT_dNONE));
5451 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5453 assert (rmObj != NULL);
5455 edma3Id = rmObj->phyCtrllerInstId;
5456 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)rmObj->gblCfgParams.globalRegs;
5457 numTCCs = rmObj->gblCfgParams.numTccs;
5458 if (ptrEdmaccRegs != NULL)
5459 {
5460 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)&ptrEdmaccRegs->SHADOW[edma3RegionId];
5461 rmInstance = ((EDMA3_RM_Instance *)(ptrRMIArray)
5462 + (edma3Id*EDMA3_MAX_RM_INSTANCES)
5463 + edma3RegionId);
5465 pendingIrqs = ((ptrEdmaccRegs->EMR != 0 )
5466 || (ptrEdmaccRegs->QEMR != 0)
5467 || (ptrEdmaccRegs->CCERR != 0));
5468 if (numTCCs > 32)
5469 {
5470 pendingIrqs = pendingIrqs || (ptrEdmaccRegs->EMRH != 0 );
5471 }
5472 index = 1U;
5474 if(pendingIrqs)
5475 {
5476 edma3OsProtectEntry (edma3Id,
5477 EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR,
5478 NULL);
5480 /* Loop for EDMA3_RM_CCERR_HANDLER_RETRY_COUNT number of time,
5481 breaks when no pending interrupt is found */
5482 while ((Cnt < EDMA3_RM_CCERR_HANDLER_RETRY_COUNT)
5483 && (index != 0U))
5484 {
5485 index = 0U;
5486 pendingIrqs = ptrEdmaccRegs->EMR;
5488 while (pendingIrqs)
5489 {
5490 /*Process all the pending interrupts*/
5491 if((pendingIrqs & 1U)==TRUE)
5492 {
5493 uint32_t mappedTcc = 0U;
5495 /**
5496 * Using the 'index' value (basically the DMA
5497 * channel), fetch the corresponding TCC
5498 * value, mapped to this DMA channel.
5499 */
5500 mappedTcc = edma3DmaChTccMapping[edma3Id][index];
5502 /**
5503 * Ensure that the mapped tcc is valid and the call
5504 * back is not NULL
5505 */
5506 if (mappedTcc < EDMA3_MAX_TCC)
5507 {
5508 /**
5509 * TCC owned and allocated by RM.
5510 * Write to EMCR to clear the corresponding EMR bits.
5511 */
5512 ptrEdmaccRegs->EMCR = (1U<<index);
5513 /*Clear any SER*/
5514 shadowRegs->SECR = (1U<<index);
5516 /* Call the callback function if registered earlier. */
5517 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5518 {
5519 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5520 mappedTcc,
5521 EDMA3_RM_E_CC_DMA_EVT_MISS,
5522 edma3IntrParams[edma3Id][mappedTcc].cbData
5523 );
5524 }
5525 }
5526 else
5527 {
5528 /**
5529 * DMA channel not owned by the RM instance.
5530 * Check the global error interrupt clearing option.
5531 * If it is TRUE, clear the error interupt else leave
5532 * it like that.
5533 */
5534 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5535 /* here write to EMCR to clear the corresponding EMR bits. */
5536 ptrEdmaccRegs->EMCR = (1U<<index);
5537 /*Clear any SER*/
5538 ptrEdmaccRegs->SECR = (1U<<index);
5539 #endif
5540 }
5541 }
5542 ++index;
5543 pendingIrqs >>= 1U;
5544 }
5546 if(numTCCs > 32)
5547 {
5548 index = 0U;
5549 pendingIrqs = ptrEdmaccRegs->EMRH;
5550 while (pendingIrqs)
5551 {
5552 /*Process all the pending interrupts*/
5553 if((pendingIrqs & 1U)==TRUE)
5554 {
5555 uint32_t mappedTcc = 0U;
5557 /**
5558 * Using the 'index' value (basically the DMA
5559 * channel), fetch the corresponding TCC
5560 * value, mapped to this DMA channel.
5561 */
5562 mappedTcc = edma3DmaChTccMapping[edma3Id][32U+index];
5564 /**
5565 * Ensure that the mapped tcc is valid and the call
5566 * back is not NULL
5567 */
5568 if (mappedTcc < EDMA3_MAX_TCC)
5569 {
5570 /**
5571 * TCC owned and allocated by RM.
5572 * Write to EMCR to clear the corresponding EMR bits.
5573 */
5574 ptrEdmaccRegs->EMCRH = (1U<<index);
5575 /*Clear any SERH*/
5576 shadowRegs->SECRH = (1U<<index);
5578 /* Call the callback function if registered earlier. */
5579 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5580 {
5581 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5582 mappedTcc,
5583 EDMA3_RM_E_CC_DMA_EVT_MISS,
5584 edma3IntrParams[edma3Id][mappedTcc].cbData
5585 );
5586 }
5587 }
5588 else
5589 {
5590 /**
5591 * DMA channel not owned by the RM instance.
5592 * Check the global error interrupt clearing option.
5593 * If it is TRUE, clear the error interupt else leave
5594 * it like that.
5595 */
5596 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5597 /**
5598 * TCC NOT owned by RM.
5599 * Write to EMCRH to clear the corresponding EMRH bits.
5600 */
5601 ptrEdmaccRegs->EMCRH = (1U<<index);
5602 /*Clear any SERH*/
5603 shadowRegs->SECRH = (1U<<index);
5604 #endif
5605 }
5606 }
5607 ++index;
5608 pendingIrqs >>= 1U;
5609 }
5610 }
5612 index = 0U;
5613 pendingIrqs = ptrEdmaccRegs->QEMR;
5614 while (pendingIrqs)
5615 {
5616 /*Process all the pending interrupts*/
5617 if((pendingIrqs & 1U)==TRUE)
5618 {
5619 uint32_t mappedTcc = 0U;
5621 /**
5622 * Using the 'index' value (basically the QDMA
5623 * channel), fetch the corresponding TCC
5624 * value, mapped to this QDMA channel.
5625 */
5626 mappedTcc = edma3QdmaChTccMapping[edma3Id][index];
5628 if (mappedTcc < EDMA3_MAX_TCC)
5629 {
5630 /* here write to QEMCR to clear the corresponding QEMR bits*/
5631 ptrEdmaccRegs->QEMCR = (1U<<index);
5632 /*Clear any QSER*/
5633 shadowRegs->QSECR = (1U<<index);
5635 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5636 {
5637 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5638 mappedTcc,
5639 EDMA3_RM_E_CC_QDMA_EVT_MISS,
5640 edma3IntrParams[edma3Id][mappedTcc].cbData
5641 );
5642 }
5643 }
5644 else
5645 {
5646 /**
5647 * QDMA channel not owned by the RM instance.
5648 * Check the global error interrupt clearing option.
5649 * If it is TRUE, clear the error interupt else leave
5650 * the ISR.
5651 */
5652 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5653 /* here write to QEMCR to clear the corresponding QEMR bits*/
5654 ptrEdmaccRegs->QEMCR = (1U<<index);
5656 /*Clear any QSER*/
5657 ptrEdmaccRegs->QSECR = (1U<<index);
5658 #endif
5659 }
5660 }
5661 ++index;
5662 pendingIrqs >>= 1U;
5663 }
5665 index = 0U;
5666 pendingIrqs = ptrEdmaccRegs->CCERR;
5667 if (pendingIrqs!=0)
5668 {
5669 /* Process all the pending CC error interrupts. */
5671 /* Queue threshold error for different event queues.*/
5672 for (evtqueNum = 0U; evtqueNum < rmObj->gblCfgParams.numEvtQueue; evtqueNum++)
5673 {
5674 if((pendingIrqs & ((uint32_t)1U << evtqueNum)) != 0)
5675 {
5676 /**
5677 * Queue threshold error for queue 'evtqueNum' raised.
5678 * Inform all the RM instances working on this region
5679 * about the error by calling their global callback functions.
5680 */
5681 resMgrInstIdx = 0U;
5682 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5683 {
5684 /* Check whether the RM instance opened working on this region */
5685 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5686 if (NULL != rm_instance)
5687 {
5688 if (rm_instance->initParam.regionId == edma3RegionId)
5689 {
5690 /* Region id matches, call the callback function */
5691 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5692 {
5693 rm_instance->initParam.gblerrCbParams.gblerrCb(
5694 EDMA3_RM_E_CC_QUE_THRES_EXCEED,
5695 evtqueNum,
5696 rm_instance->initParam.gblerrCbParams.gblerrData);
5697 }
5698 }
5699 }
5701 ++resMgrInstIdx;
5702 /* Check next opened instance */
5703 }
5705 /* Clear the error interrupt. */
5706 ptrEdmaccRegs->CCERRCLR = (1U << evtqueNum);
5707 }
5708 }
5711 /* Transfer completion code error. */
5712 if ((pendingIrqs & ((uint32_t)1 << EDMA3_CCRL_CCERR_TCCERR_SHIFT))!=0)
5713 {
5714 /**
5715 * Transfer completion code error raised.
5716 * Inform all the RM instances working on this region
5717 * about the error by calling their global callback functions.
5718 */
5720 resMgrInstIdx = 0U;
5721 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5722 {
5723 /* Check whether the RM instance opened working on this region */
5724 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5725 if (NULL != rm_instance)
5726 {
5727 if (rm_instance->initParam.regionId == edma3RegionId)
5728 {
5729 /* Region id matches, call the callback function */
5730 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5731 {
5732 rm_instance->initParam.gblerrCbParams.gblerrCb(
5733 EDMA3_RM_E_CC_TCC,
5734 0,
5735 rm_instance->initParam.gblerrCbParams.gblerrData);
5736 }
5737 }
5738 }
5740 ++resMgrInstIdx;
5741 /* Check next opened instance */
5742 }
5744 ptrEdmaccRegs->CCERRCLR = ((uint32_t)1<<EDMA3_CCRL_CCERR_TCCERR_SHIFT);
5745 }
5747 ++index;
5748 }
5750 Cnt++;
5751 }
5754 /**
5755 * Read the error registers again. If any interrupt is pending,
5756 * write the EEVAL register.
5757 * Moreover, according to the global error interrupt clearing
5758 * option, check either error bits associated with all the
5759 * DMA/QDMA channels (option is SET) OR check error bits
5760 * associated with owned DMA/QDMA channels.
5761 */
5762 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5763 /* To remove warning. */
5764 rmInstance = rmInstance;
5766 /* Check all the error bits. */
5767 ownedDmaError = ptrEdmaccRegs->EMR;
5768 if (numTCCs > 32)
5769 {
5770 ownedDmaHError = ptrEdmaccRegs->EMRH;
5771 }
5772 ownedQdmaError = ptrEdmaccRegs->QEMR;
5773 #else
5774 /* Check ONLY owned error bits. */
5775 ownedDmaError = (ptrEdmaccRegs->EMR & rmInstance->initParam.rmInstInitConfig->ownDmaChannels[0U]);
5776 if (numTCCs > 32)
5777 ownedDmaHError = (ptrEdmaccRegs->EMRH & rmInstance->initParam.rmInstInitConfig->ownDmaChannels[1U]);
5778 ownedQdmaError = (ptrEdmaccRegs->QEMR & rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0U]);
5779 #endif
5781 if (((ownedDmaError != 0 ) || (ownedDmaHError != 0 ))
5782 || ((ownedQdmaError != 0) || (ptrEdmaccRegs->CCERR != 0)))
5783 {
5784 ptrEdmaccRegs->EEVAL=0x1U;
5785 }
5787 edma3OsProtectExit (rmObj->phyCtrllerInstId,
5788 EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR,
5789 0);
5790 }
5791 }
5793 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5794 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_CCERR",
5795 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5796 EDMA3_DVT_dNONE,
5797 EDMA3_DVT_dNONE,
5798 EDMA3_DVT_dNONE));
5799 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5800 }
5802 void lisrEdma3CCErrHandler0(uint32_t edma3InstanceId)
5803 {
5804 /* Invoke CC Error Handler ISR */
5805 edma3CCErrHandler(&resMgrObj[edma3InstanceId]);
5806 }
5810 /**
5811 * \brief Interrupt handler for Transfer Controller Error.
5812 *
5813 * \note This function first disables its own interrupt to make it non-
5814 * entrant. Later, after calling all the callback functions, it
5815 * re-enables its own interrupt.
5816 *
5817 * \return None.
5818 */
5819 static void edma3TCErrHandler (const EDMA3_RM_Obj *rmObj, uint32_t tcNum)
5820 {
5821 volatile EDMA3_TCRL_Regs *tcRegs = NULL;
5822 uint32_t tcMemErrRdWr = 0U;
5823 uint32_t resMgrInstIdx = 0U;
5824 EDMA3_RM_Instance *rm_instance = NULL;
5825 uint32_t edma3Id;
5826 uint32_t num_rm_instances_opened;
5828 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5829 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_TCERR",
5830 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5831 EDMA3_DVT_dNONE,
5832 EDMA3_DVT_dNONE,
5833 EDMA3_DVT_dNONE));
5834 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5836 assert ((rmObj != NULL) && (tcNum < rmObj->gblCfgParams.numTcs));
5838 if (rmObj->gblCfgParams.tcRegs[tcNum] != NULL)
5839 {
5840 tcRegs = (volatile EDMA3_TCRL_Regs *)(rmObj->gblCfgParams.tcRegs[tcNum]);
5841 edma3Id = rmObj->phyCtrllerInstId;
5842 }
5844 if (tcRegs != NULL)
5845 {
5846 if(tcRegs->ERRSTAT != 0)
5847 {
5848 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
5849 EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR,
5850 &tcNum);
5852 if((tcRegs->ERRSTAT & ((uint32_t)1 << EDMA3_TCRL_ERRSTAT_BUSERR_SHIFT))!= 0)
5853 {
5854 /* Bus error event. */
5855 /**
5856 * EDMA3TC has detected an error at source or destination
5857 * address. Error information can be read from the error
5858 * details register (ERRDET).
5859 */
5860 tcMemErrRdWr = tcRegs->ERRDET & (EDMA3_TCRL_ERRDET_STAT_MASK);
5861 if ((tcMemErrRdWr > 0U) && (tcMemErrRdWr < 8U))
5862 {
5863 /**
5864 * Inform all the RM instances working on this region
5865 * about the error by calling their global callback functions.
5866 */
5867 resMgrInstIdx = 0U;
5868 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5869 {
5870 /* Check whether the RM instance opened working on this region */
5871 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5872 if (NULL != rm_instance)
5873 {
5874 if (rm_instance->initParam.regionId == edma3RegionId)
5875 {
5876 /* Region id matches, call the callback function */
5877 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5878 {
5879 rm_instance->initParam.gblerrCbParams.gblerrCb(
5880 EDMA3_RM_E_TC_MEM_LOCATION_READ_ERROR,
5881 tcNum,
5882 rm_instance->initParam.gblerrCbParams.gblerrData);
5883 }
5884 }
5885 }
5887 ++resMgrInstIdx;
5888 /* Check next opened instance */
5889 }
5890 }
5891 else
5892 {
5893 if ((tcMemErrRdWr >= 8U) && (tcMemErrRdWr <= 0xFU))
5894 {
5895 /**
5896 * Inform all the RM instances working on this region
5897 * about the error by calling their global callback functions.
5898 */
5899 resMgrInstIdx = 0U;
5900 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5901 {
5902 /* Check whether the RM instance opened working on this region */
5903 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5904 if (NULL != rm_instance)
5905 {
5906 if (rm_instance->initParam.regionId == edma3RegionId)
5907 {
5908 /* Region id matches, call the callback function */
5909 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5910 {
5911 rm_instance->initParam.gblerrCbParams.gblerrCb(
5912 EDMA3_RM_E_TC_MEM_LOCATION_WRITE_ERROR,
5913 tcNum,
5914 rm_instance->initParam.gblerrCbParams.gblerrData);
5915 }
5916 }
5917 }
5919 ++resMgrInstIdx;
5920 /* Check next opened instance */
5921 }
5922 }
5923 }
5924 tcRegs->ERRCLR = ((uint32_t)1<<EDMA3_TCRL_ERRSTAT_BUSERR_SHIFT);
5925 }
5926 else
5927 {
5928 /* Transfer request (TR) error event. */
5929 if((tcRegs->ERRSTAT & ((uint32_t)1 << EDMA3_TCRL_ERRSTAT_TRERR_SHIFT))!= 0)
5930 {
5931 resMgrInstIdx = 0U;
5932 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5933 {
5934 /* Check whether the RM instance opened working on this region */
5935 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5936 if (NULL != rm_instance)
5937 {
5938 if (rm_instance->initParam.regionId == edma3RegionId)
5939 {
5940 /* Region id matches, call the callback function */
5941 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5942 {
5943 rm_instance->initParam.gblerrCbParams.gblerrCb(
5944 EDMA3_RM_E_TC_TR_ERROR,
5945 tcNum,
5946 rm_instance->initParam.gblerrCbParams.gblerrData);
5947 }
5948 }
5949 }
5951 ++resMgrInstIdx;
5952 /* Check next opened instance */
5953 }
5955 tcRegs->ERRCLR = ((uint32_t)1<<EDMA3_TCRL_ERRSTAT_TRERR_SHIFT);
5956 }
5957 else
5958 {
5959 if((tcRegs->ERRSTAT & ((uint32_t)1 << EDMA3_TCRL_ERRSTAT_MMRAERR_SHIFT))!= 0)
5960 {
5961 resMgrInstIdx = 0U;
5962 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5963 {
5964 /* Check whether the RM instance opened working on this region */
5965 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5966 if (NULL != rm_instance)
5967 {
5968 if (rm_instance->initParam.regionId == edma3RegionId)
5969 {
5970 /* Region id matches, call the callback function */
5971 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5972 {
5973 rm_instance->initParam.gblerrCbParams.gblerrCb(
5974 EDMA3_RM_E_TC_INVALID_ADDR,
5975 tcNum,
5976 rm_instance->initParam.gblerrCbParams.gblerrData);
5977 }
5978 }
5979 }
5981 ++resMgrInstIdx;
5982 /* Check next opened instance */
5983 }
5985 tcRegs->ERRCLR = ((uint32_t)1<<EDMA3_TCRL_ERRSTAT_MMRAERR_SHIFT);
5986 }
5987 }
5988 }
5990 edma3OsProtectExit (rmObj->phyCtrllerInstId,
5991 EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR,
5992 tcNum);
5993 }
5994 }
5996 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5997 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_TCERR",
5998 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5999 EDMA3_DVT_dNONE,
6000 EDMA3_DVT_dNONE,
6001 EDMA3_DVT_dNONE));
6002 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
6003 }
6007 /*
6008 * ======== lisrEdma3TC0ErrHandler0 ========
6009 * EDMA3 instance 0 TC0 Error Interrupt Service Routine
6010 */
6011 void lisrEdma3TC0ErrHandler0(uint32_t edma3InstanceId)
6012 {
6013 /* Invoke Error Handler ISR for TC0*/
6014 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 0U);
6015 }
6018 /*
6019 * ======== lisrEdma3TC1ErrHandler0 ========
6020 * EDMA3 instance 0 TC1 Error Interrupt Service Routine
6021 */
6022 void lisrEdma3TC1ErrHandler0(uint32_t edma3InstanceId)
6023 {
6024 /* Invoke Error Handler ISR for TC1*/
6025 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 1U);
6026 }
6028 /*
6029 * ======== lisrEdma3TC2ErrHandler0 ========
6030 * EDMA3 instance 0 TC2 Error Interrupt Service Routine
6031 */
6032 void lisrEdma3TC2ErrHandler0(uint32_t edma3InstanceId)
6033 {
6034 /* Invoke Error Handler ISR for TC2*/
6035 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 2U);
6036 }
6038 /*
6039 * ======== lisrEdma3TC3ErrHandler0 ========
6040 * EDMA3 instance 0 TC3 Error Interrupt Service Routine
6041 */
6042 void lisrEdma3TC3ErrHandler0(uint32_t edma3InstanceId)
6043 {
6044 /* Invoke Error Handler ISR for TC3*/
6045 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 3U);
6046 }
6048 /*
6049 * ======== lisrEdma3TC4ErrHandler0 ========
6050 * EDMA3 instance 0 TC4 Error Interrupt Service Routine
6051 */
6052 void lisrEdma3TC4ErrHandler0(uint32_t edma3InstanceId)
6053 {
6054 /* Invoke Error Handler ISR for TC4*/
6055 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 4U);
6056 }
6059 /*
6060 * ======== lisrEdma3TC5ErrHandler0 ========
6061 * EDMA3 instance 0 TC5 Error Interrupt Service Routine
6062 */
6063 void lisrEdma3TC5ErrHandler0(uint32_t edma3InstanceId)
6064 {
6065 /* Invoke Error Handler ISR for TC5*/
6066 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 5U);
6067 }
6069 /*
6070 * ======== lisrEdma3TC6ErrHandler0 ========
6071 * EDMA3 instance 0 TC6 Error Interrupt Service Routine
6072 */
6073 /* ARGSUSED */
6074 void lisrEdma3TC6ErrHandler0(uint32_t edma3InstanceId)
6075 {
6076 /* Invoke Error Handler ISR for TC6*/
6077 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 6U);
6078 }
6080 /*
6081 * ======== lisrEdma3TC7ErrHandler0 ========
6082 * EDMA3 instance 0 TC7 Error Interrupt Service Routine
6083 */
6084 void lisrEdma3TC7ErrHandler0(uint32_t edma3InstanceId)
6085 {
6086 /* Invoke Error Handler ISR for TC7*/
6087 edma3TCErrHandler(&resMgrObj[edma3InstanceId], 7U);
6088 }
6092 /* Resource Manager Internal functions - Start */
6094 /** Initialization of the Global region registers of the EDMA3 Controller */
6095 static void edma3GlobalRegionInit (uint32_t phyCtrllerInstId, uint32_t numDmaChannels)
6096 {
6097 uint32_t evtQNum = 0U;
6098 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
6100 assert (phyCtrllerInstId < EDMA3_MAX_EDMA3_INSTANCES);
6102 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)
6103 (resMgrObj[phyCtrllerInstId].gblCfgParams.globalRegs);
6105 if (ptrEdmaccRegs != NULL)
6106 {
6107 ptrEdmaccRegs->EMCR = EDMA3_RM_SET_ALL_BITS;
6108 if ( numDmaChannels > 32)
6109 {
6110 /* Clear the EMCRH only if available channels are more than 32 */
6111 ptrEdmaccRegs->EMCRH = EDMA3_RM_SET_ALL_BITS;
6112 }
6113 ptrEdmaccRegs->QEMCR = EDMA3_RM_SET_ALL_BITS;
6115 /*
6116 * Set all Instance-wide EDMA3 parameters (not channel-specific)
6117 */
6119 /**
6120 * Set TC Priority among system-wide bus-masters and Queue
6121 * Watermark Level
6122 */
6123 while (evtQNum <
6124 resMgrObj[phyCtrllerInstId].gblCfgParams.numEvtQueue)
6125 {
6126 ptrEdmaccRegs->QUEPRI &= EDMA3_RM_QUEPRI_CLR_MASK(evtQNum);
6127 ptrEdmaccRegs->QUEPRI |= EDMA3_RM_QUEPRI_SET_MASK(evtQNum,
6128 resMgrObj[phyCtrllerInstId].gblCfgParams.evtQPri[evtQNum]);
6130 ptrEdmaccRegs->QWMTHRA |= EDMA3_RM_QUEWMTHR_SET_MASK(evtQNum,
6131 resMgrObj[phyCtrllerInstId].gblCfgParams.evtQueueWaterMarkLvl[evtQNum]);
6133 evtQNum++;
6134 }
6136 /* Clear CCERR register */
6137 ptrEdmaccRegs ->CCERRCLR = 0xFFFFU;
6138 }
6140 return;
6141 }
6146 /** Initialization of the Shadow region registers of the EDMA3 Controller */
6147 static void edma3ShadowRegionInit (const EDMA3_RM_Instance *pRMInstance)
6148 {
6149 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
6150 volatile EDMA3_CCRL_ShadowRegs *ptrEdmaShadowRegs = NULL;
6151 uint32_t phyCtrllerInstId;
6152 uint32_t regionId;
6153 const EDMA3_RM_InstanceInitConfig *rmInstInitConfig = pRMInstance->initParam.rmInstInitConfig;
6155 assert (pRMInstance != NULL);
6157 if (rmInstInitConfig != NULL)
6158 {
6159 phyCtrllerInstId = pRMInstance->pResMgrObjHandle->phyCtrllerInstId;
6160 regionId = pRMInstance->initParam.regionId;
6162 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)
6163 (resMgrObj[phyCtrllerInstId].gblCfgParams.globalRegs);
6165 if (ptrEdmaccRegs != NULL)
6166 {
6167 ptrEdmaShadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
6168 (&ptrEdmaccRegs->SHADOW[regionId]);
6170 ptrEdmaShadowRegs->ECR = (rmInstInitConfig->ownDmaChannels[0U]
6171 | rmInstInitConfig->ownTccs[0U]);
6172 ptrEdmaShadowRegs->ECRH = (rmInstInitConfig->ownDmaChannels[1U]
6173 | rmInstInitConfig->ownTccs[1U]);
6174 ptrEdmaShadowRegs->EECR = (rmInstInitConfig->ownDmaChannels[0U]
6175 | rmInstInitConfig->ownTccs[0U]);
6176 ptrEdmaShadowRegs->SECR = (rmInstInitConfig->ownDmaChannels[0U]
6177 | rmInstInitConfig->ownTccs[0U]);
6178 ptrEdmaShadowRegs->SECRH = (rmInstInitConfig->ownDmaChannels[1U]
6179 | rmInstInitConfig->ownTccs[1U]);
6180 ptrEdmaShadowRegs->EECR = (rmInstInitConfig->ownDmaChannels[0U]
6181 | rmInstInitConfig->ownTccs[0U]);
6182 ptrEdmaShadowRegs->EECRH = (rmInstInitConfig->ownDmaChannels[1U]
6183 | rmInstInitConfig->ownTccs[1U]);
6185 ptrEdmaShadowRegs->QEECR = rmInstInitConfig->ownQdmaChannels[0U];
6187 ptrEdmaShadowRegs->IECR = (rmInstInitConfig->ownDmaChannels[0U]
6188 | rmInstInitConfig->ownTccs[0U]);
6189 ptrEdmaShadowRegs->IECRH = (rmInstInitConfig->ownDmaChannels[1U]
6190 | rmInstInitConfig->ownTccs[1U]);
6191 ptrEdmaShadowRegs->ICR = (rmInstInitConfig->ownDmaChannels[0U]
6192 | rmInstInitConfig->ownTccs[0U]);
6193 ptrEdmaShadowRegs->ICRH = (rmInstInitConfig->ownDmaChannels[1U]
6194 | rmInstInitConfig->ownTccs[1U]);
6196 ptrEdmaShadowRegs->QSECR = rmInstInitConfig->ownQdmaChannels[0U];
6198 /*
6199 * Set all EDMA3 Resource<->Region mapping parameters
6200 */
6202 /* 1. Dma Channel (and TCC) <-> Region */
6203 ptrEdmaccRegs->DRA[regionId].DRAE = 0U;
6204 ptrEdmaccRegs->DRA[regionId].DRAEH = 0U;
6206 /* 2. Qdma Channel <-> Region */
6207 ptrEdmaccRegs->QRAE[regionId] = 0U;
6208 }
6209 }
6211 return;
6212 }
6216 /** Local MemZero function */
6217 void edma3MemZero(void *dst, uint32_t len)
6218 {
6219 uint32_t i = 0U;
6220 uint32_t *ds = NULL;
6222 assert (dst != NULL);
6224 ds = (uint32_t *)dst;
6226 for (i = 0 ; i < (len/4) ; i++)
6227 {
6228 *ds = 0x0;
6229 ds++;
6230 }
6232 return;
6233 }
6236 /* Local MemCopy function */
6237 void edma3MemCpy(void *dst, const void *src, uint32_t len)
6238 {
6239 uint32_t i=0U;
6240 const uint32_t *sr;
6241 uint32_t *ds;
6243 assert ((src != NULL) && (dst != NULL) && ((len%4) == 0));
6245 sr = (const uint32_t *)src;
6246 ds = (uint32_t *)dst;
6248 for (i = 0 ; i < (len/4) ; i++)
6249 {
6250 *ds = *sr;
6251 ds++;
6252 sr++;
6253 }
6255 return;
6256 }
6259 /* Local MemCopy function to copy Param Set ONLY */
6260 void edma3ParamCpy(volatile void *dst, const volatile void *src)
6261 {
6262 uint32_t i = 0U;
6263 const volatile uint32_t *sr;
6264 volatile uint32_t *ds;
6266 assert ((src != NULL) && (dst != NULL));
6268 sr = (const volatile uint32_t *)src;
6269 ds = (volatile uint32_t *)dst;
6271 for (i = 0; i < 8; i++)
6272 {
6273 *ds = *sr;
6274 ds++;
6275 sr++;
6276 }
6278 return;
6279 }
6282 /**
6283 * Finds a particular bit ('0' or '1') in the particular word from 'start'.
6284 * If found, returns the position, else return -1.
6285 */
6286 static int32_t findBitInWord (int32_t source, uint32_t start, uint16_t bit)
6287 {
6288 uint32_t position = start;
6289 uint16_t found = 0;
6290 uint32_t iterations_left = 0;
6291 uint32_t sourceTmp=0;
6293 switch (bit)
6294 {
6295 case 1U:
6296 {
6297 sourceTmp = (uint32_t)source >> (start%32U);
6298 source = (int32_t)sourceTmp;
6300 while ((found==0U) && (source!=0))
6301 {
6302 if (((uint32_t)source & 0x1U) == 0x1U)
6303 {
6304 /* 1 */
6305 found++;
6306 }
6307 else
6308 {
6309 /* 0 */
6310 sourceTmp = (uint32_t)source >> 1;
6311 source = (int32_t)sourceTmp;
6312 position++;
6313 }
6314 }
6316 }
6317 break;
6319 case 0:
6320 {
6321 sourceTmp = (uint32_t)source >> (start%32U);
6322 source = (int32_t)sourceTmp;
6323 iterations_left = (uint32_t)32U - (start%32U);
6325 while ((found==0U) && (iterations_left>0U))
6326 {
6327 if (((uint32_t)source & 0x1U) == 0x1U)
6328 {
6329 /* 1 */
6330 sourceTmp = (uint32_t)source >> 1;
6331 source = (int32_t)sourceTmp;
6332 position++;
6333 iterations_left--;
6334 }
6335 else
6336 {
6337 /* 0 */
6338 found++;
6339 }
6340 }
6341 }
6342 break;
6344 default:
6345 break;
6346 }
6348 return (found ? (int32_t)position : -1);
6349 }
6352 /**
6353 * Finds a particular bit ('0' or '1') in the specified resources' array
6354 * from 'start' to 'end'. If found, returns the position, else return -1.
6355 */
6356 static int32_t findBit (EDMA3_RM_ResType resType,
6357 uint32_t start,
6358 uint32_t end,
6359 uint16_t bit)
6360 {
6361 int32_t position = -1;
6362 uint32_t start_index = start / 32U;
6363 uint32_t end_index = end / 32U;
6364 int32_t i;
6365 uint32_t *resPtr = 0x0;
6366 int32_t ret = -1;
6367 EDMA3_RM_Result result = EDMA3_RM_SOK;
6369 assert (start <= end);
6371 /**
6372 * job is to find 'bit' in an array[start_index:end_index]
6373 * algo used:
6374 * first search in array[start_index]
6375 * then search in array[start_index + 1 : end_index - 1]
6376 * then search in array[end_index]
6377 */
6378 switch (resType)
6379 {
6380 case EDMA3_RM_RES_DMA_CHANNEL:
6381 resPtr = &contiguousDmaRes[0];
6382 break;
6384 case EDMA3_RM_RES_QDMA_CHANNEL:
6385 resPtr = &contiguousQdmaRes[0];
6386 break;
6388 case EDMA3_RM_RES_TCC:
6389 resPtr = &contiguousTccRes[0];
6390 break;
6392 case EDMA3_RM_RES_PARAM_SET:
6393 resPtr = &contiguousParamRes[0];
6394 break;
6396 default:
6397 result = EDMA3_RM_E_INVALID_PARAM;
6398 break;
6399 }
6401 if (EDMA3_RM_SOK == result)
6402 {
6403 switch (bit)
6404 {
6405 case 1:
6406 {
6407 /* Find '1' in first word. */
6408 position = findBitInWord (resPtr[start_index], start, 1U);
6410 if (position != -1)
6411 {
6412 ret = position;
6413 }
6414 else
6415 {
6416 /* '1' NOT found, look into other words. */
6417 for (i = (int32_t)((int32_t)start_index + 1U); i <= (int32_t)((int32_t)end_index - 1U); i++)
6418 {
6419 position = findBitInWord (resPtr[i], 0U, 1U);
6420 if (position != -1)
6421 {
6422 /* '1' Found... */
6423 ret = (position + (i*32));
6424 break;
6425 }
6426 }
6428 /* First check whether we have found '1' or not. */
6429 if (ret == -1)
6430 {
6431 /* Still not found, look in the last word. */
6432 position = findBitInWord(resPtr[end_index], 0U, 1U);
6433 if (position != -1)
6434 {
6435 /* Finally got it. */
6436 ret = (position + (end_index*32U));
6437 }
6438 else
6439 {
6440 /* Sorry, could not find it, return -1. */
6441 ret = -1;
6442 }
6443 }
6444 }
6445 }
6446 break;
6448 case 0:
6449 {
6450 /* Find '0' in first word. */
6451 position = findBitInWord(resPtr[start_index], start, 0U);
6452 if (position != -1)
6453 {
6454 ret = position;
6455 }
6456 else
6457 {
6458 /* '0' NOT found, look into other words. */
6459 for (i = (start_index + 1U); i <= (end_index - 1U); i++)
6460 {
6461 position = findBitInWord(resPtr[i], 0U, 0U);
6462 if (position != -1)
6463 {
6464 /* '0' found... */
6465 ret = (position + (i*32));
6466 break;
6467 }
6468 }
6470 /* First check whether we have found '0' or not. */
6471 if (ret == -1)
6472 {
6473 position = findBitInWord(resPtr[end_index], 0U, 0U);
6474 if (position != -1)
6475 {
6476 /* Finally got it. */
6477 ret = (position + (end_index*32U));
6478 }
6479 else
6480 {
6481 /* Sorry, could not find it, return -1. */
6482 ret = -1;
6483 }
6484 }
6485 }
6486 }
6487 break;
6489 default:
6490 break;
6491 }
6492 }
6496 return ((ret >= start) ? ret : -1);
6497 }
6501 /**
6502 * If successful, this function returns EDMA3_RM_SOK and the position
6503 * of first available resource in 'positionRes'. Else returns error.
6504 */
6505 static EDMA3_RM_Result allocAnyContigRes(EDMA3_RM_ResType resType,
6506 uint32_t numResources,
6507 uint32_t *positionRes)
6508 {
6509 uint16_t found = 0U;
6510 int32_t first_one, next_zero;
6511 uint32_t num_available;
6512 int32_t ret = -1;
6513 uint32_t start = 0;
6514 uint32_t end;
6515 EDMA3_RM_Result result = EDMA3_RM_SOK;
6517 assert (positionRes != NULL);
6519 switch (resType)
6520 {
6521 case EDMA3_RM_RES_DMA_CHANNEL:
6522 end = EDMA3_MAX_DMA_CH - 1U;
6523 break;
6525 case EDMA3_RM_RES_QDMA_CHANNEL:
6526 end = EDMA3_MAX_QDMA_CH - 1U;
6527 break;
6529 case EDMA3_RM_RES_TCC:
6530 end = EDMA3_MAX_TCC - 1U;
6531 break;
6533 case EDMA3_RM_RES_PARAM_SET:
6534 end = edma3NumPaRAMSets - 1U;
6535 break;
6537 default:
6538 result = EDMA3_RM_E_INVALID_PARAM;
6539 break;
6540 }
6542 if (result == EDMA3_RM_SOK)
6543 {
6544 /**
6545 * Algorithm used for finding N contiguous resources.
6546 * In the resources' array, '1' means available and '0' means
6547 * not-available.
6548 * Step a) Find first '1' starting from 'start'. If successful,
6549 * store it in first_one, else return error.
6550 * Step b) Find first '0' starting from (first_one+1) to 'end'.
6551 * If successful, store returned value in next_zero. If '0' could
6552 * not be located, it means all the resources are available.
6553 * Store 'end' (i.e. the last resource id) in next_zero.
6554 * Step c) Count the number of contiguous resources available
6555 * by subtracting first_one from next_zero.
6556 * Step d) If result < N, do the whole process again untill you
6557 * reach end. Else you have found enough resources, return success.
6558 */
6559 while((found == 0) && (start<=end) && (((end-start)+1U) >= numResources))
6560 {
6561 /* Find first '1' starting from 'start' till 'end'. */
6562 first_one = findBit (resType, start, end, 1U);
6563 if (first_one != -1)
6564 {
6565 /* Got first 1, search for first '0' now. */
6566 next_zero = findBit (resType, first_one+1, end, 0U);
6567 if (next_zero == -1)
6568 {
6569 /* Unable to find next zero, all 1' are there */
6570 next_zero = end + 1U;
6571 }
6573 /* check no of resources available */
6574 num_available = next_zero - first_one;
6575 if (num_available >= numResources)
6576 {
6577 /* hurrah..., we have found enough resources. */
6578 found = 1U;
6579 ret = first_one;
6580 }
6581 else
6582 {
6583 /* Not enough resources, try again */
6584 start = next_zero + 1;
6585 }
6586 }
6587 else
6588 {
6589 /* do nothing, first 1 is not there, return. */
6590 break;
6591 }
6592 }
6593 }
6596 if (result == EDMA3_RM_SOK)
6597 {
6598 if (found == 1U)
6599 {
6600 /* required resources found, retrun the first available res id. */
6601 *positionRes = (uint32_t)ret;
6602 }
6603 else
6604 {
6605 /* No resources allocated */
6606 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
6607 }
6608 }
6610 return result;
6611 }
6615 /**
6616 * Starting from 'firstResIdObj', this function makes the next 'numResources'
6617 * Resources non-available for future. Also, it does some global resisters'
6618 * setting also.
6619 */
6620 static EDMA3_RM_Result gblChngAllocContigRes(EDMA3_RM_Instance *rmInstance,
6621 const EDMA3_RM_ResDesc *firstResIdObj,
6622 uint32_t numResources)
6623 {
6624 EDMA3_RM_Result result = EDMA3_RM_SOK;
6625 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
6626 EDMA3_RM_Obj *rmObj = NULL;
6627 uint32_t avlblIdx = 0U;
6628 uint32_t firstResId=0U;
6629 uint32_t lastResId=0U;
6630 uint32_t edma3Id;
6632 assert ((rmInstance != NULL) && (firstResIdObj != NULL));
6634 rmObj = rmInstance->pResMgrObjHandle;
6636 if (rmObj == NULL)
6637 {
6638 result = EDMA3_RM_E_INVALID_PARAM;
6639 }
6641 if (EDMA3_RM_SOK == result)
6642 {
6643 edma3Id = rmObj->phyCtrllerInstId;
6644 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
6646 if (gblRegs == NULL)
6647 {
6648 result = EDMA3_RM_E_INVALID_PARAM;
6649 }
6650 }
6652 if (result == EDMA3_RM_SOK)
6653 {
6654 switch (firstResIdObj->type)
6655 {
6656 case EDMA3_RM_RES_DMA_CHANNEL:
6657 {
6658 firstResId = firstResIdObj->resId;
6659 lastResId = firstResId + (numResources - 1U);
6661 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6662 {
6663 rmInstance->avlblDmaChannels[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
6665 /**
6666 * Enable the DMA channel in the DRAE/DRAEH registers also.
6667 */
6668 if (avlblIdx < 32U)
6669 {
6670 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
6671 |= ((uint32_t)0x1U << avlblIdx);
6672 }
6673 else
6674 {
6675 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
6676 |= ((uint32_t)0x1U << (avlblIdx - 32U));
6677 }
6678 }
6679 }
6680 break;
6682 case EDMA3_RM_RES_QDMA_CHANNEL:
6683 {
6684 firstResId = firstResIdObj->resId;
6685 lastResId = firstResId + (numResources - 1U);
6687 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6688 {
6689 rmInstance->avlblQdmaChannels[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
6691 /**
6692 * Enable the QDMA channel in the QRAE register also.
6693 */
6694 gblRegs->QRAE[rmInstance->initParam.regionId]
6695 |= ((uint32_t)0x1U << avlblIdx);
6696 }
6697 }
6698 break;
6700 case EDMA3_RM_RES_TCC:
6701 {
6702 firstResId = firstResIdObj->resId;
6703 lastResId = firstResId + (numResources - 1U);
6705 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6706 {
6707 rmInstance->avlblTccs[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
6709 /**
6710 * If the region id coming from this
6711 * RM instance is same as the Master RM
6712 * Instance's region id, only then we will be
6713 * getting the interrupts on the same side.
6714 * So save the TCC in the allocatedTCCs[] array.
6715 */
6716 if (edma3RegionId == rmInstance->initParam.regionId)
6717 {
6718 if (avlblIdx < 32U)
6719 {
6720 allocatedTCCs[edma3Id][0U] |= ((uint32_t)0x1U << avlblIdx);
6721 }
6722 else
6723 {
6724 allocatedTCCs[edma3Id][1U] |= ((uint32_t)0x1U << (avlblIdx - 32U));
6725 }
6726 }
6727 }
6728 }
6729 break;
6731 case EDMA3_RM_RES_PARAM_SET:
6732 {
6733 firstResId = firstResIdObj->resId;
6734 lastResId = firstResId + (numResources - 1U);
6736 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6737 {
6738 rmInstance->avlblPaRAMSets [avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
6740 /**
6741 * Also, make the actual PARAM Set NULL, checking the flag
6742 * whether it is required or not.
6743 */
6744 if (TRUE == rmInstance->paramInitRequired)
6745 {
6746 edma3MemZero((void *)(&gblRegs->PARAMENTRY[avlblIdx]),
6747 sizeof(gblRegs->PARAMENTRY[avlblIdx]));
6748 }
6749 }
6750 }
6751 break;
6753 default:
6754 result = EDMA3_RM_E_INVALID_PARAM;
6755 break;
6756 }
6757 }
6760 return result;
6761 }
6764 EDMA3_RM_Result EDMA3_RM_initXbarEventMap (EDMA3_RM_Handle hEdmaResMgr,
6765 const EDMA3_RM_GblXbarToChanConfigParams * edmaGblXbarConfig,
6766 EDMA3_RM_mapXbarEvtToChan mapXbarEvtFunc,
6767 EDMA3_RM_xbarConfigScr configXbarScr)
6768 {
6769 EDMA3_RM_Result result = EDMA3_DRV_SOK;
6770 EDMA3_RM_Instance *rmInstance = NULL;
6772 /* If parameter checking is enabled... */
6773 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
6774 if (hEdmaResMgr == NULL)
6775 {
6776 result = EDMA3_RM_E_INVALID_PARAM;
6777 }
6778 #endif
6780 /* Check if the parameters are OK. */
6781 if (EDMA3_DRV_SOK == result)
6782 {
6783 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
6785 if (mapXbarEvtFunc != NULL)
6786 {
6787 rmInstance->mapXbarToChan = mapXbarEvtFunc;
6788 }
6789 if (configXbarScr != NULL)
6790 {
6791 rmInstance->configScrMapXbarToEvt = configXbarScr;
6792 }
6793 if (edmaGblXbarConfig != NULL)
6794 {
6795 edma3MemCpy((void *)(&rmInstance->rmXbarToEvtMapConfig),
6796 (const void *)(edmaGblXbarConfig),
6797 sizeof (EDMA3_RM_GblXbarToChanConfigParams));
6798 }
6799 }
6801 return (result);
6802 }
6804 /* Resource Manager Internal functions - End */
6806 /* End of File */