d31b4ff37210148dbe16be9df37c4b403f3dfec3
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 edma3InstanceId);
337 /** EDMA3 Instance 0 CC Error Interrupt Service Routine */
338 void lisrEdma3CCErrHandler0(uint32_t edma3InstanceId);
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 edma3InstanceId);
344 void lisrEdma3TC1ErrHandler0(uint32_t edma3InstanceId);
345 void lisrEdma3TC2ErrHandler0(uint32_t edma3InstanceId);
346 void lisrEdma3TC3ErrHandler0(uint32_t edma3InstanceId);
347 void lisrEdma3TC4ErrHandler0(uint32_t edma3InstanceId);
348 void lisrEdma3TC5ErrHandler0(uint32_t edma3InstanceId);
349 void lisrEdma3TC6ErrHandler0(uint32_t edma3InstanceId);
350 void lisrEdma3TC7ErrHandler0(uint32_t edma3InstanceId);
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 (int32_t)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 (int32_t)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 (int32_t)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 (int32_t)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 (int32_t)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 (int32_t)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 / (uint32_t)32U;
842 if (dmaChDwrds == 0)
843 {
844 /* In case DMA channels are < 32 */
845 dmaChDwrds = 1U;
846 }
848 paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / (uint32_t)32U;
849 if (paramSetDwrds == 0)
850 {
851 /* In case PaRAM Sets are < 32 */
852 paramSetDwrds = 1U;
853 }
855 tccDwrds = rmObj->gblCfgParams.numTccs / (uint32_t)32U;
856 if (tccDwrds == 0)
857 {
858 /* In case TCCs are < 32 */
859 tccDwrds = 1U;
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 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
949 intState);
950 }
951 }
952 }
954 if(errorCode != NULL)
955 {
956 *errorCode = result;
957 }
958 return (EDMA3_RM_Handle)retVal;
959 }
961 EDMA3_RM_Result EDMA3_RM_close (EDMA3_RM_Handle hEdmaResMgr,
962 const void *param)
963 {
964 EDMA3_RM_Result result = EDMA3_RM_SOK;
965 uint32_t intState = 0U;
966 uint32_t resMgrIdx = 0U;
967 EDMA3_RM_Obj *rmObj = NULL;
968 EDMA3_RM_Instance *rmInstance = NULL;
969 uint32_t dmaChDwrds;
970 uint32_t paramSetDwrds;
971 uint32_t tccDwrds;
973 /* If parameter checking is enabled... */
974 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
975 if (NULL == hEdmaResMgr)
976 {
977 result = EDMA3_RM_E_INVALID_PARAM;
978 }
979 #endif
981 /* Check if the parameters are OK. */
982 if (EDMA3_RM_SOK == result)
983 {
984 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
985 rmObj = rmInstance->pResMgrObjHandle;
987 if (rmObj == NULL)
988 {
989 result = (EDMA3_RM_E_INVALID_PARAM);
990 }
991 else
992 {
993 /* Check state of driver, state should be opened */
994 if (rmObj->state != EDMA3_RM_OPENED)
995 {
996 result = (EDMA3_RM_E_OBJ_NOT_OPENED);
997 }
998 else
999 {
1000 dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / (uint32_t)32U;
1001 paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / (uint32_t)32U;
1002 tccDwrds = rmObj->gblCfgParams.numTccs / (uint32_t)32U;
1004 /* Set the instance config as NULL*/
1005 for (resMgrIdx = 0U; resMgrIdx < dmaChDwrds; ++resMgrIdx)
1006 {
1007 rmInstance->avlblDmaChannels[resMgrIdx] = 0x0U;
1008 }
1009 for (resMgrIdx = 0U; resMgrIdx < paramSetDwrds; ++resMgrIdx)
1010 {
1011 rmInstance->avlblPaRAMSets[resMgrIdx] = 0x0U;
1012 }
1013 rmInstance->avlblQdmaChannels[0U] = 0x0U;
1014 for (resMgrIdx = 0U; resMgrIdx < tccDwrds; ++resMgrIdx)
1015 {
1016 rmInstance->avlblTccs[resMgrIdx] = 0x0U;
1017 }
1019 /**
1020 * If this is the Master Instance, reset the static variable
1021 * 'masterExists[]'.
1022 */
1023 if (TRUE == rmInstance->initParam.isMaster)
1024 {
1025 masterExists[rmObj->phyCtrllerInstId] = FALSE;
1026 edma3RegionId = EDMA3_MAX_REGIONS;
1027 }
1029 /* Reset the Initparam for this RM Instance */
1030 edma3MemZero((void *)&(rmInstance->initParam),
1031 sizeof(EDMA3_RM_Param));
1033 /* Critical section starts */
1034 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
1035 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
1036 &intState);
1038 /* Decrease the Number of Opens */
1039 --rmObj->numOpens;
1040 if (0 == rmObj->numOpens)
1041 {
1042 edma3MemZero((void *)&(edma3RmChBoundRes[rmObj->phyCtrllerInstId]),
1043 sizeof(edma3RmChBoundRes[rmObj->phyCtrllerInstId]));
1045 rmObj->state = EDMA3_RM_CLOSED;
1046 }
1048 /* Critical section ends */
1049 edma3OsProtectExit (rmObj->phyCtrllerInstId,
1050 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
1051 intState);
1053 rmInstance->pResMgrObjHandle = NULL;
1054 rmInstance->shadowRegs = NULL;
1055 rmInstance = NULL;
1056 }
1057 }
1058 }
1060 return result;
1061 }
1063 EDMA3_RM_Result EDMA3_RM_allocResource(EDMA3_RM_Handle hEdmaResMgr,
1064 EDMA3_RM_ResDesc *resObj)
1065 {
1066 EDMA3_RM_Instance *rmInstance = NULL;
1067 EDMA3_RM_Obj *rmObj = NULL;
1068 EDMA3_RM_Result result = EDMA3_RM_SOK;
1069 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
1070 uint32_t avlblIdx = 0U;
1071 uint32_t resIdClr = 0x0;
1072 uint32_t resIdSet = 0x0;
1073 uint32_t resId;
1074 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1075 uint32_t mapXbarEvtToChanFlag = FALSE;
1076 uint32_t xBarEvtBeforeMap = 0;
1077 uint32_t edma3Id;
1079 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1080 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1081 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1082 EDMA3_DVT_dCOUNTER,
1083 EDMA3_DVT_dNONE,
1084 EDMA3_DVT_dNONE));
1085 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1087 /* If parameter checking is enabled... */
1088 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1089 if ((hEdmaResMgr == NULL) || (resObj == NULL))
1090 {
1091 result = (EDMA3_RM_E_INVALID_PARAM);
1092 }
1093 #endif
1095 /* Check if the parameters are OK. */
1096 if (EDMA3_RM_SOK == result)
1097 {
1098 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1099 rmObj = rmInstance->pResMgrObjHandle;
1101 if ((rmObj == NULL) ||
1102 (rmObj->gblCfgParams.globalRegs == NULL))
1103 {
1104 result = (EDMA3_RM_E_INVALID_PARAM);
1105 }
1106 else
1107 {
1108 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1109 edma3Id = rmObj->phyCtrllerInstId;
1110 resId = resObj->resId;
1112 resIdClr = (uint32_t)(~((uint32_t)1U << (resId%32U)));
1113 resIdSet = (1U << (resId%32U));
1115 if ( rmInstance->mapXbarToChan != NULL)
1116 {
1117 xBarEvtBeforeMap = resId;
1118 if ((resId > rmObj->gblCfgParams.numDmaChannels) &&
1119 (resId != EDMA3_RM_RES_ANY) &&
1120 (resObj->type == EDMA3_RM_RES_DMA_CHANNEL))
1121 {
1122 result = rmInstance->mapXbarToChan(xBarEvtBeforeMap,
1123 &resObj->resId,
1124 &rmInstance->rmXbarToEvtMapConfig);
1125 if (EDMA3_RM_SOK == result)
1126 {
1127 resId = resObj->resId;
1128 mapXbarEvtToChanFlag = TRUE;
1129 }
1130 }
1131 }
1133 if (result == EDMA3_RM_SOK)
1134 {
1135 /**
1136 * Take the instance specific semaphore, to prevent simultaneous
1137 * access to the shared resources.
1138 */
1139 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
1140 EDMA3_OSSEM_NO_TIMEOUT);
1141 if (EDMA3_RM_SOK == semResult)
1142 {
1143 switch (resObj->type)
1144 {
1145 case EDMA3_RM_RES_DMA_CHANNEL :
1146 {
1147 if (resId == EDMA3_RM_RES_ANY)
1148 {
1149 for (avlblIdx=0U;
1150 avlblIdx <
1151 rmObj->gblCfgParams.numDmaChannels;
1152 ++avlblIdx)
1153 {
1154 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[avlblIdx/32U])
1155 &
1156 (rmInstance->avlblDmaChannels[avlblIdx/32U])
1157 &
1158 ~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[avlblIdx/32U])
1159 &
1160 ((uint32_t)1U << (avlblIdx%32U))) != FALSE)
1161 {
1162 /*
1163 * Match found.
1164 * A resource which is owned by this instance of the
1165 * Resource Manager and which is presently available
1166 * and which has not been reserved - is found.
1167 */
1168 resObj->resId = avlblIdx;
1169 /*
1170 * Mark the 'match found' resource as "Not Available"
1171 * for future requests
1172 */
1173 rmInstance->avlblDmaChannels[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
1175 /**
1176 * Check if the register modification flag is
1177 * set or not.
1178 */
1179 if (TRUE == rmInstance->regModificationRequired)
1180 {
1181 /**
1182 * Enable the DMA channel in the
1183 * DRAE/DRAEH registers also.
1184 */
1185 if (avlblIdx < 32U)
1186 {
1187 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1188 |= ((uint32_t)0x1U << avlblIdx);
1189 }
1190 else
1191 {
1192 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1193 |= ((uint32_t)0x1U << (avlblIdx - 32U));
1194 }
1195 }
1197 result = EDMA3_RM_SOK;
1198 break;
1199 }
1200 }
1201 /*
1202 * If none of the owned resources of this type is available
1203 * then report "All Resources of this type not available" error
1204 */
1205 if (avlblIdx == rmObj->gblCfgParams.numDmaChannels)
1206 {
1207 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1208 }
1209 }
1210 else
1211 {
1212 if (resId < rmObj->gblCfgParams.numDmaChannels)
1213 {
1214 /*
1215 * Check if specified resource is owned
1216 * by this instance of the resource manager
1217 */
1218 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resId/32U])&(resIdSet))!=FALSE)
1219 {
1220 /* Now check if specified resource is available presently*/
1221 if (((rmInstance->avlblDmaChannels[resId/32U])&(resIdSet))!=FALSE)
1222 {
1223 /*
1224 * Mark the specified channel as "Not Available"
1225 * for future requests
1226 */
1227 rmInstance->avlblDmaChannels[resId/32U] &= resIdClr;
1229 /**
1230 * Check if the register modification flag is
1231 * set or not.
1232 */
1233 if (TRUE == rmInstance->regModificationRequired)
1234 {
1235 if (resId < 32U)
1236 {
1237 rmInstance->shadowRegs->EECR = (1UL << resId);
1239 /**
1240 * Enable the DMA channel in the
1241 * DRAE registers also.
1242 */
1243 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1244 |= ((uint32_t)0x1U << resId);
1245 }
1246 else
1247 {
1248 rmInstance->shadowRegs->EECRH = (1UL << resId);
1250 /**
1251 * Enable the DMA channel in the
1252 * DRAEH registers also.
1253 */
1254 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1255 |= ((uint32_t)0x1U << (resId - 32U));
1256 }
1257 }
1259 result = EDMA3_RM_SOK;
1260 }
1261 else
1262 {
1263 /* Specified resource is owned but is already booked */
1264 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1265 }
1266 }
1267 else
1268 {
1269 /*
1270 * Specified resource is not owned by this instance
1271 * of the Resource Manager
1272 */
1273 result = EDMA3_RM_E_RES_NOT_OWNED;
1274 }
1275 }
1276 else
1277 {
1278 result = EDMA3_RM_E_INVALID_PARAM;
1279 }
1280 }
1281 }
1282 break;
1284 case EDMA3_RM_RES_QDMA_CHANNEL :
1285 {
1286 if (resId == EDMA3_RM_RES_ANY)
1287 {
1288 for (avlblIdx=0U; avlblIdx<rmObj->gblCfgParams.numQdmaChannels; ++avlblIdx)
1289 {
1290 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[avlblIdx/32U])
1291 &
1292 (rmInstance->avlblQdmaChannels[avlblIdx/32U])
1293 &
1294 ~(rmInstance->initParam.rmInstInitConfig->resvdQdmaChannels[avlblIdx/32U])
1295 &
1296 ((uint32_t)1U << (avlblIdx%32U))) != FALSE)
1297 {
1298 resObj->resId = avlblIdx;
1299 rmInstance->avlblQdmaChannels[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
1301 /**
1302 * Check if the register modification flag is
1303 * set or not.
1304 */
1305 if (TRUE == rmInstance->regModificationRequired)
1306 {
1307 /**
1308 * Enable the QDMA channel in the
1309 * QRAE register also.
1310 */
1311 gblRegs->QRAE[rmInstance->initParam.regionId]
1312 |= ((uint32_t)0x1U << avlblIdx);
1313 }
1315 result = EDMA3_RM_SOK;
1316 break;
1317 }
1318 }
1319 /*
1320 * If none of the owned resources of this type is available
1321 * then report "All Resources of this type not available" error
1322 */
1323 if (avlblIdx == rmObj->gblCfgParams.numQdmaChannels)
1324 {
1325 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1326 }
1327 }
1328 else
1329 {
1330 if (resId < rmObj->gblCfgParams.numQdmaChannels)
1331 {
1332 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32U])&(resIdSet))!=FALSE)
1333 {
1334 if (((rmInstance->avlblQdmaChannels [resId/32U])&(resIdSet))!=FALSE)
1335 {
1336 rmInstance->avlblQdmaChannels [resId/32U] &= resIdClr;
1338 /**
1339 * Check if the register modification flag is
1340 * set or not.
1341 */
1342 if (TRUE == rmInstance->regModificationRequired)
1343 {
1344 /**
1345 * Enable the QDMA channel in the
1346 * QRAE register also.
1347 */
1348 gblRegs->QRAE[rmInstance->initParam.regionId]
1349 |= ((uint32_t)0x1U << resId);
1350 }
1352 result = EDMA3_RM_SOK;
1353 }
1354 else
1355 {
1356 /* Specified resource is owned but is already booked */
1357 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1358 }
1359 }
1360 else
1361 {
1362 /*
1363 * Specified resource is not owned by this instance
1364 * of the Resource Manager
1365 */
1366 result = EDMA3_RM_E_RES_NOT_OWNED;
1367 }
1368 }
1369 else
1370 {
1371 result = EDMA3_RM_E_INVALID_PARAM;
1372 }
1373 }
1374 }
1375 break;
1377 case EDMA3_RM_RES_TCC :
1378 {
1379 if (resId == EDMA3_RM_RES_ANY)
1380 {
1381 for (avlblIdx=0U; avlblIdx<rmObj->gblCfgParams.numTccs; ++avlblIdx)
1382 {
1383 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [avlblIdx/32U])
1384 & (rmInstance->avlblTccs [avlblIdx/32U])
1385 & ~(rmInstance->initParam.rmInstInitConfig->resvdTccs [avlblIdx/32U])
1386 & ((uint32_t)1U << (avlblIdx%32U)))!=FALSE)
1387 {
1388 resObj->resId = avlblIdx;
1389 rmInstance->avlblTccs [avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
1391 /**
1392 * Check if the register modification flag is
1393 * set or not.
1394 */
1395 if (TRUE == rmInstance->regModificationRequired)
1396 {
1397 /**
1398 * Enable the Interrupt channel in the
1399 * DRAE/DRAEH registers also.
1400 * Also, If the region id coming from this
1401 * RM instance is same as the Master RM
1402 * Instance's region id, only then we will be
1403 * getting the interrupts on the same side.
1404 * So save the TCC in the allocatedTCCs[] array.
1405 */
1406 if (avlblIdx < 32U)
1407 {
1408 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1409 |= ((uint32_t)0x1U << avlblIdx);
1411 /**
1412 * Do not modify this global array if the register
1413 * modificatio flag is not set.
1414 * Reason being is based on this flag, the IPR/ICR
1415 * or error bit is cleared in the completion or
1416 * error handler ISR.
1417 */
1418 if (edma3RegionId == rmInstance->initParam.regionId)
1419 {
1420 allocatedTCCs[edma3Id][0U] |= ((uint32_t)0x1U << avlblIdx);
1421 }
1422 }
1423 else
1424 {
1425 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1426 |= ((uint32_t)0x1U << (avlblIdx - 32U));
1428 /**
1429 * Do not modify this global array if the register
1430 * modificatio flag is not set.
1431 * Reason being is based on this flag, the IPR/ICR
1432 * or error bit is cleared in the completion or
1433 * error handler ISR.
1434 */
1435 if (edma3RegionId == rmInstance->initParam.regionId)
1436 {
1437 allocatedTCCs[edma3Id][1U] |= ((uint32_t)0x1U << (avlblIdx - 32U));
1438 }
1439 }
1440 }
1443 result = EDMA3_RM_SOK;
1444 break;
1445 }
1446 }
1447 /*
1448 * If none of the owned resources of this type is available
1449 * then report "All Resources of this type not available" error
1450 */
1451 if ( avlblIdx == rmObj->gblCfgParams.numTccs)
1452 {
1453 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1454 }
1455 }
1456 else
1457 {
1458 if (resId < rmObj->gblCfgParams.numTccs)
1459 {
1460 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32U])&(resIdSet))!=FALSE)
1461 {
1462 if (((rmInstance->avlblTccs [resId/32U])&(resIdSet))!=FALSE)
1463 {
1464 rmInstance->avlblTccs [resId/32U] &= resIdClr;
1466 /**
1467 * Check if the register modification flag is
1468 * set or not.
1469 */
1470 if (TRUE == rmInstance->regModificationRequired)
1471 {
1472 /**
1473 * Enable the Interrupt channel in the
1474 * DRAE/DRAEH registers also.
1475 * Also, If the region id coming from this
1476 * RM instance is same as the Master RM
1477 * Instance's region id, only then we will be
1478 * getting the interrupts on the same side.
1479 * So save the TCC in the allocatedTCCs[] array.
1480 */
1481 if (resId < 32U)
1482 {
1483 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1484 |= ((uint32_t)0x1U << resId);
1486 /**
1487 * Do not modify this global array if the register
1488 * modificatio flag is not set.
1489 * Reason being is based on this flag, the IPR/ICR
1490 * or error bit is cleared in the completion or
1491 * error handler ISR.
1492 */
1493 if (edma3RegionId == rmInstance->initParam.regionId)
1494 {
1495 allocatedTCCs[edma3Id][0U] |= ((uint32_t)0x1U << resId);
1496 }
1497 }
1498 else
1499 {
1500 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1501 |= ((uint32_t)0x1U << (resId - 32U));
1503 /**
1504 * Do not modify this global array if the register
1505 * modificatio flag is not set.
1506 * Reason being is based on this flag, the IPR/ICR
1507 * or error bit is cleared in the completion or
1508 * error handler ISR.
1509 */
1510 if (edma3RegionId == rmInstance->initParam.regionId)
1511 {
1512 allocatedTCCs[edma3Id][1U] |= ((uint32_t)0x1U << (resId - 32U));
1513 }
1514 }
1515 }
1517 result = EDMA3_RM_SOK;
1518 }
1519 else
1520 {
1521 /* Specified resource is owned but is already booked */
1522 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1523 }
1524 }
1525 else
1526 {
1527 /*
1528 * Specified resource is not owned by this instance
1529 * of the Resource Manager
1530 */
1531 result = EDMA3_RM_E_RES_NOT_OWNED;
1532 }
1533 }
1534 else
1535 {
1536 result = EDMA3_RM_E_INVALID_PARAM;
1537 }
1538 }
1539 }
1540 break;
1542 case EDMA3_RM_RES_PARAM_SET :
1543 {
1544 if (resId == EDMA3_RM_RES_ANY)
1545 {
1546 for (avlblIdx=0U; avlblIdx<rmObj->gblCfgParams.numPaRAMSets; ++avlblIdx)
1547 {
1548 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [avlblIdx/32U])
1549 &
1550 (rmInstance->avlblPaRAMSets [avlblIdx/32U])
1551 &
1552 ~(rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets [avlblIdx/32U])
1553 &
1554 ((uint32_t)1U << (avlblIdx%32U)))!=FALSE)
1555 {
1556 resObj->resId = avlblIdx;
1557 rmInstance->avlblPaRAMSets [avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
1559 /**
1560 * Also, make the actual PARAM Set NULL, checking the flag
1561 * whether it is required or not.
1562 */
1563 if ((TRUE == rmInstance->regModificationRequired)
1564 && (TRUE == rmInstance->paramInitRequired))
1565 {
1566 edma3MemZero((void *)(&gblRegs->PARAMENTRY[avlblIdx]),
1567 sizeof(gblRegs->PARAMENTRY[avlblIdx]));
1568 }
1570 result = EDMA3_RM_SOK;
1571 break;
1572 }
1573 }
1574 /*
1575 * If none of the owned resources of this type is available
1576 * then report "All Resources of this type not available" error
1577 */
1578 if ( avlblIdx == rmObj->gblCfgParams.numPaRAMSets)
1579 {
1580 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1581 }
1582 }
1583 else
1584 {
1585 if (resId < rmObj->gblCfgParams.numPaRAMSets)
1586 {
1587 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32U])&(resIdSet))!=FALSE)
1588 {
1589 if (((rmInstance->avlblPaRAMSets [resId/32U])&(resIdSet)) !=FALSE)
1590 {
1591 rmInstance->avlblPaRAMSets [resId/32U] &= resIdClr;
1593 /**
1594 * Also, make the actual PARAM Set NULL, checking the flag
1595 * whether it is required or not.
1596 */
1597 if ((TRUE == rmInstance->regModificationRequired)
1598 && (TRUE == rmInstance->paramInitRequired))
1599 {
1600 edma3MemZero((void *)(&gblRegs->PARAMENTRY[resId]),
1601 sizeof(gblRegs->PARAMENTRY[resId]));
1602 }
1604 result = EDMA3_RM_SOK;
1605 }
1606 else
1607 {
1608 /* Specified resource is owned but is already booked */
1609 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1610 }
1611 }
1612 else
1613 {
1614 /*
1615 * Specified resource is not owned by this instance
1616 * of the Resource Manager
1617 */
1618 result = EDMA3_RM_E_RES_NOT_OWNED;
1619 }
1620 }
1621 else
1622 {
1623 result = EDMA3_RM_E_INVALID_PARAM;
1624 }
1625 }
1626 }
1627 break;
1629 default:
1630 result = EDMA3_RM_E_INVALID_PARAM;
1631 break;
1632 }
1634 /* Return the semaphore back */
1635 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
1636 }
1637 }
1638 }
1639 }
1641 /**
1642 * Check the Resource Allocation Result 'result' first. If Resource
1643 * Allocation has resulted in an error, return it (having more priority than
1644 * semResult.
1645 * Else, return semResult.
1646 */
1647 if (EDMA3_RM_SOK == result)
1648 {
1649 /**
1650 * Resource Allocation successful, return semResult for returning
1651 * semaphore.
1652 */
1653 result = semResult;
1654 if ((rmInstance->configScrMapXbarToEvt != NULL) &&
1655 (mapXbarEvtToChanFlag == TRUE))
1656 {
1657 rmInstance->configScrMapXbarToEvt(xBarEvtBeforeMap, resObj->resId);
1658 }
1659 }
1661 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1662 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1663 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1664 EDMA3_DVT_dCOUNTER,
1665 EDMA3_DVT_dNONE,
1666 EDMA3_DVT_dNONE));
1667 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1669 return result;
1670 }
1672 EDMA3_RM_Result EDMA3_RM_freeResource(EDMA3_RM_Handle hEdmaResMgr,
1673 const EDMA3_RM_ResDesc *resObj)
1674 {
1675 EDMA3_RM_Instance *rmInstance = NULL;
1676 EDMA3_RM_Obj *rmObj = NULL;
1677 EDMA3_RM_Result result = EDMA3_RM_SOK;
1678 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
1679 uint32_t resId;
1680 uint32_t resIdSet = 0x0;
1681 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1682 uint32_t edma3Id;
1684 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1685 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1686 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1687 EDMA3_DVT_dCOUNTER,
1688 EDMA3_DVT_dNONE,
1689 EDMA3_DVT_dNONE));
1690 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1692 /* If parameter checking is enabled... */
1693 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1694 if ((hEdmaResMgr == NULL) || (resObj == NULL))
1695 {
1696 result = EDMA3_RM_E_INVALID_PARAM;
1697 }
1698 #endif
1700 /* Check if the parameters are OK. */
1701 if (EDMA3_RM_SOK == result)
1702 {
1703 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1704 rmObj = rmInstance->pResMgrObjHandle;
1706 if ((rmObj == NULL) ||
1707 (rmObj->gblCfgParams.globalRegs == NULL))
1708 {
1709 result = EDMA3_RM_E_INVALID_PARAM;
1710 }
1711 else
1712 {
1713 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1714 edma3Id = rmObj->phyCtrllerInstId;
1715 resId = resObj->resId;
1717 resIdSet = 1U << (resId%32U);
1719 /**
1720 * Take the instance specific semaphore, to prevent simultaneous
1721 * access to the shared resources.
1722 */
1723 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
1724 EDMA3_OSSEM_NO_TIMEOUT);
1726 if (EDMA3_RM_SOK == semResult)
1727 {
1728 switch (resObj->type)
1729 {
1730 case EDMA3_RM_RES_DMA_CHANNEL :
1731 {
1732 if (resId < rmObj->gblCfgParams.numDmaChannels)
1733 {
1734 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels [resId/32U]) & (resIdSet))!=FALSE)
1735 {
1736 if (((~(rmInstance->avlblDmaChannels[resId/32U]))&(resIdSet))!=FALSE)
1737 {
1738 /*
1739 * Mark the specified channel as "Available"
1740 * for future requests
1741 */
1742 rmInstance->avlblDmaChannels[resId/32U] |= resIdSet;
1744 /**
1745 * Check if the register modification flag is
1746 * set or not.
1747 */
1748 if (TRUE == rmInstance->regModificationRequired)
1749 {
1750 /**
1751 * DMA Channel is freed.
1752 * Reset the bit specific to the DMA channel
1753 * in the DRAE/DRAEH register also.
1754 */
1755 if (resId < 32U)
1756 {
1757 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1758 &= (~((uint32_t)0x1U << resId));
1759 }
1760 else
1761 {
1762 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1763 &= (~((uint32_t)0x1U << (resId-32U)));
1764 }
1765 }
1767 result = EDMA3_RM_SOK;
1768 }
1769 else
1770 {
1771 result = EDMA3_RM_E_RES_ALREADY_FREE;
1772 }
1773 }
1774 else
1775 {
1776 /*
1777 * Specified resource is not owned by this instance
1778 * of the Resource Manager
1779 */
1780 result = EDMA3_RM_E_RES_NOT_OWNED;
1781 }
1782 }
1783 else
1784 {
1785 result = EDMA3_RM_E_INVALID_PARAM;
1786 }
1787 }
1788 break;
1790 case EDMA3_RM_RES_QDMA_CHANNEL :
1791 {
1792 if (resId < rmObj->gblCfgParams.numQdmaChannels)
1793 {
1794 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32U]) & (resIdSet))!=FALSE)
1795 {
1796 if (((~(rmInstance->avlblQdmaChannels [resId/32U])) & (resIdSet))!=FALSE)
1797 {
1798 rmInstance->avlblQdmaChannels [resId/32U] |= resIdSet;
1800 /**
1801 * Check if the register modification flag is
1802 * set or not.
1803 */
1804 if (TRUE == rmInstance->regModificationRequired)
1805 {
1806 /**
1807 * QDMA Channel is freed.
1808 * Reset the bit specific to the QDMA channel
1809 * in the QRAE register also.
1810 */
1811 gblRegs->QRAE[rmInstance->initParam.regionId]
1812 &= (~((uint32_t)0x1U << resId));
1813 }
1815 result = EDMA3_RM_SOK;
1816 }
1817 else
1818 {
1819 result = EDMA3_RM_E_RES_ALREADY_FREE;
1820 }
1821 }
1822 else
1823 {
1824 /*
1825 * Specified resource is not owned by this instance
1826 * of the Resource Manager
1827 */
1828 result = EDMA3_RM_E_RES_NOT_OWNED;
1829 }
1830 }
1831 else
1832 {
1833 result = EDMA3_RM_E_INVALID_PARAM;
1834 }
1835 }
1836 break;
1838 case EDMA3_RM_RES_TCC :
1839 {
1840 if (resId < rmObj->gblCfgParams.numTccs)
1841 {
1842 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32U]) & (resIdSet))!=FALSE)
1843 {
1844 if (((~(rmInstance->avlblTccs [resId/32U])) & (resIdSet))!=FALSE)
1845 {
1846 rmInstance->avlblTccs [resId/32U] |= resIdSet;
1848 /**
1849 * Check if the register modification flag is
1850 * set or not.
1851 */
1852 if (TRUE == rmInstance->regModificationRequired)
1853 {
1854 /**
1855 * Interrupt Channel is freed.
1856 * Reset the bit specific to the Interrupt
1857 * channel in the DRAE/DRAEH register also.
1858 * Also, if we have earlier saved this
1859 * TCC in allocatedTCCs[] array,
1860 * remove it from there too.
1861 */
1862 if (resId < 32U)
1863 {
1864 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1865 &= (~((uint32_t)0x1U << resId));
1867 if (edma3RegionId == rmInstance->initParam.regionId)
1868 {
1869 allocatedTCCs[edma3Id][0U] &= (~((uint32_t)0x1U << resId));
1870 }
1871 }
1872 else
1873 {
1874 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1875 &= (~((uint32_t)0x1U << (resId-32U)));
1877 if (edma3RegionId == rmInstance->initParam.regionId)
1878 {
1879 allocatedTCCs[edma3Id][1U] &= (~((uint32_t)0x1U << (resId -32U)));
1880 }
1881 }
1882 }
1884 result = EDMA3_RM_SOK;
1885 }
1886 else
1887 {
1888 result = EDMA3_RM_E_RES_ALREADY_FREE;
1889 }
1890 }
1891 else
1892 {
1893 /*
1894 * Specified resource is not owned by this instance
1895 * of the Resource Manager
1896 */
1897 result = EDMA3_RM_E_RES_NOT_OWNED;
1898 }
1899 }
1900 else
1901 {
1902 result = EDMA3_RM_E_INVALID_PARAM;
1903 }
1904 }
1905 break;
1907 case EDMA3_RM_RES_PARAM_SET :
1908 {
1909 if (resId < rmObj->gblCfgParams.numPaRAMSets)
1910 {
1911 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32U])&(resIdSet))!=FALSE)
1912 {
1913 if (((~(rmInstance->avlblPaRAMSets [resId/32U]))&(resIdSet))!=FALSE)
1914 {
1915 rmInstance->avlblPaRAMSets [resId/32U] |= resIdSet;
1917 result = EDMA3_RM_SOK;
1918 }
1919 else
1920 {
1921 result = EDMA3_RM_E_RES_ALREADY_FREE;
1922 }
1923 }
1924 else
1925 {
1926 /*
1927 * Specified resource is not owned by this instance
1928 * of the Resource Manager
1929 */
1930 result = EDMA3_RM_E_RES_NOT_OWNED;
1931 }
1932 }
1933 else
1934 {
1935 result = EDMA3_RM_E_INVALID_PARAM;
1936 }
1937 }
1938 break;
1940 default:
1941 result = EDMA3_RM_E_INVALID_PARAM;
1942 break;
1943 }
1944 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
1945 }
1946 }
1947 }
1949 /**
1950 * Check the Free Resource Result 'result' first. If Free Resource
1951 * has resulted in an error, return it (having more priority than
1952 * semResult.
1953 * Else, return semResult.
1954 */
1955 if (EDMA3_RM_SOK == result)
1956 {
1957 /**
1958 * Free Resource successful, return semResult for returning
1959 * semaphore.
1960 */
1961 result = semResult;
1962 }
1964 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1965 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1966 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1967 EDMA3_DVT_dCOUNTER,
1968 EDMA3_DVT_dNONE,
1969 EDMA3_DVT_dNONE));
1970 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1972 return result;
1973 }
1975 EDMA3_RM_Result EDMA3_RM_allocLogicalChannel(EDMA3_RM_Handle hEdmaResMgr,
1976 EDMA3_RM_ResDesc *lChObj,
1977 uint32_t *pParam,
1978 uint32_t *pTcc)
1979 {
1980 EDMA3_RM_ResDesc *chObj;
1981 EDMA3_RM_ResDesc resObj;
1982 EDMA3_RM_Result result = EDMA3_RM_SOK;
1983 EDMA3_RM_Instance *rmInstance = NULL;
1984 EDMA3_RM_Obj *rmObj = NULL;
1985 uint32_t mappedPaRAMId=0U;
1986 uint32_t mappedTcc = EDMA3_RM_CH_NO_TCC_MAP;
1987 int32_t paRAMId = (int32_t)EDMA3_RM_RES_ANY;
1988 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1989 uint32_t qdmaChId = EDMA3_MAX_PARAM_SETS;
1990 uint32_t edma3Id;
1992 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1993 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1994 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1995 EDMA3_DVT_dCOUNTER,
1996 EDMA3_DVT_dNONE,
1997 EDMA3_DVT_dNONE));
1998 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2000 /* If parameter checking is enabled... */
2001 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2002 if ((lChObj == NULL) || (hEdmaResMgr == NULL))
2003 {
2004 result = EDMA3_RM_E_INVALID_PARAM;
2005 }
2006 #endif
2008 /* Check if the parameters are OK. */
2009 if (EDMA3_RM_SOK == result)
2010 {
2011 chObj = lChObj;
2013 if ((chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
2014 || (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL))
2015 {
2016 /**
2017 * If the request is for a DMA or QDMA channel, check the
2018 * pParam and pTcc objects also.
2019 * For the Link channel request, they could be NULL.
2020 */
2021 /* If parameter checking is enabled... */
2022 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2023 if ((pParam == NULL) || (pTcc == NULL))
2024 {
2025 result = EDMA3_RM_E_INVALID_PARAM;
2026 }
2027 #endif
2028 }
2029 }
2031 if (result == EDMA3_RM_SOK)
2032 {
2033 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2035 if (rmInstance == NULL)
2036 {
2037 result = EDMA3_RM_E_INVALID_PARAM;
2038 }
2039 }
2041 if (result == EDMA3_RM_SOK)
2042 {
2043 rmObj = rmInstance->pResMgrObjHandle;
2045 if (rmObj == NULL)
2046 {
2047 result = EDMA3_RM_E_INVALID_PARAM;
2048 }
2049 else
2050 {
2051 if (rmObj->gblCfgParams.globalRegs == NULL)
2052 {
2053 result = EDMA3_RM_E_INVALID_PARAM;
2054 }
2055 }
2056 }
2058 if (result == EDMA3_RM_SOK)
2059 {
2060 edma3Id = rmObj->phyCtrllerInstId;
2061 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2063 switch (chObj->type)
2064 {
2065 case EDMA3_RM_RES_DMA_CHANNEL:
2066 {
2067 if ((chObj->resId == EDMA3_RM_DMA_CHANNEL_ANY)
2068 || (chObj->resId == EDMA3_RM_RES_ANY))
2069 {
2070 /* Request for ANY DMA channel. */
2071 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2072 resObj.resId = EDMA3_RM_RES_ANY;
2073 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2075 if (result == EDMA3_RM_SOK)
2076 {
2077 /* DMA channel allocated successfully. */
2078 chObj->resId = resObj.resId;
2080 /**
2081 * Check the PaRAM Set user has specified for this DMA channel.
2082 * Two cases exist:
2083 * a) DCHMAP exists: Any PaRAM Set can be used
2084 * b) DCHMAP does not exist: Should not be possible
2085 * only if the channel allocated (ANY) and PaRAM requested
2086 * are same.
2087 */
2088 if ((*pParam) == EDMA3_RM_PARAM_ANY)
2089 {
2090 /* User specified ANY PaRAM Set; Check the mapping. */
2091 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2092 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2093 {
2094 /** If some PaRAM set is statically mapped to the returned
2095 * channel number, use that.
2096 */
2097 paRAMId = (int32_t)mappedPaRAMId;
2098 }
2099 }
2100 else
2101 {
2102 /* User specified some PaRAM Set; check that can be used or not. */
2103 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2104 {
2105 paRAMId = (int32_t)(*pParam);
2106 }
2107 else
2108 {
2109 /**
2110 * Channel mapping does not exist. If the PaRAM Set requested
2111 * is the same as dma channel allocated (coincidentally), it is fine.
2112 * Else return error.
2113 */
2114 if ((*pParam) != (resObj.resId))
2115 {
2116 result = EDMA3_RM_E_INVALID_PARAM;
2118 /**
2119 * Free the previously allocated DMA channel also.
2120 */
2121 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2122 }
2123 else
2124 {
2125 paRAMId = (int32_t)(*pParam);
2126 }
2127 }
2128 }
2130 mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[resObj.resId];
2131 }
2132 }
2133 else
2134 {
2135 if (chObj->resId <= edma3_dma_ch_max_val[edma3Id])
2136 {
2137 /* Request for a specific DMA channel */
2138 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2139 resObj.resId = chObj->resId;
2140 result = EDMA3_RM_allocResource(hEdmaResMgr,
2141 (EDMA3_RM_ResDesc *)&resObj);
2143 if (result == EDMA3_RM_SOK)
2144 {
2145 /**
2146 * Check the PaRAM Set user has specified for this DMA channel.
2147 * Two cases exist:
2148 * a) DCHMAP exists: Any PaRAM Set can be used
2149 * b) DCHMAP does not exist: Should not be possible
2150 * only if the channel allocated (ANY) and PaRAM requested
2151 * are same.
2152 */
2153 if ((*pParam) == EDMA3_RM_PARAM_ANY)
2154 {
2155 /* User specified ANY PaRAM Set; Check the mapping. */
2156 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2157 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2158 {
2159 /** If some PaRAM set is statically mapped to the returned
2160 * channel number, use that.
2161 */
2162 paRAMId = (int32_t)mappedPaRAMId;
2163 }
2164 }
2165 else
2166 {
2167 /* User specified some PaRAM Set; check that can be used or not. */
2168 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2169 {
2170 paRAMId = (int32_t)(*pParam);
2171 }
2172 else
2173 {
2174 /**
2175 * Channel mapping does not exist. If the PaRAM Set requested
2176 * is the same as dma channel allocated (coincidentally), it is fine.
2177 * Else return error.
2178 */
2179 if ((*pParam) != (resObj.resId))
2180 {
2181 result = EDMA3_RM_E_INVALID_PARAM;
2183 /**
2184 * Free the previously allocated DMA channel also.
2185 */
2186 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2187 }
2188 else
2189 {
2190 paRAMId = (int32_t)(*pParam);
2191 }
2192 }
2193 }
2195 mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[chObj->resId];
2196 }
2197 }
2198 else
2199 {
2200 result = EDMA3_RM_E_INVALID_PARAM;
2201 }
2202 }
2203 }
2204 break;
2207 case EDMA3_RM_RES_QDMA_CHANNEL:
2208 {
2209 if ((chObj->resId == EDMA3_RM_QDMA_CHANNEL_ANY)
2210 || (chObj->resId == EDMA3_RM_RES_ANY))
2211 {
2212 /* First request for any available QDMA channel */
2213 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2214 resObj.resId = EDMA3_RM_RES_ANY;
2215 result = EDMA3_RM_allocResource(hEdmaResMgr,
2216 (EDMA3_RM_ResDesc *)&resObj);
2218 if (result == EDMA3_RM_SOK)
2219 {
2220 /* Return the actual QDMA channel id. */
2221 chObj->resId = resObj.resId;
2223 /* Save the Logical-QDMA channel id for future use. */
2224 qdmaChId = resObj.resId + edma3_qdma_ch_min_val[edma3Id];
2226 /**
2227 * Check the PaRAM Set user has specified for this QDMA channel.
2228 * If he has specified any particular PaRAM Set, use that.
2229 */
2230 if ((*pParam) != EDMA3_RM_PARAM_ANY)
2231 {
2232 /* User specified ANY PaRAM Set; Check the mapping. */
2233 paRAMId = (int32_t)(*pParam);
2234 }
2235 }
2236 }
2237 else
2238 {
2239 if (chObj->resId < rmObj->gblCfgParams.numQdmaChannels)
2240 {
2241 /* Request for a specific QDMA channel */
2242 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2243 resObj.resId = chObj->resId;
2244 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2246 if (result == EDMA3_RM_SOK)
2247 {
2248 /* Save the Logical-QDMA channel id for future use. */
2249 qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
2251 /**
2252 * Check the PaRAM Set user has specified for this QDMA channel.
2253 * If he has specified any particular PaRAM Set, use that.
2254 */
2255 if ((*pParam) != EDMA3_RM_PARAM_ANY)
2256 {
2257 /* User specified ANY PaRAM Set; Check the mapping. */
2258 paRAMId = (int32_t)(*pParam);
2259 }
2260 }
2261 }
2262 else
2263 {
2264 result = EDMA3_RM_E_INVALID_PARAM;
2265 }
2266 }
2267 }
2268 break;
2270 case EDMA3_RM_RES_PARAM_SET:
2271 {
2272 /* Request for a LINK channel. */
2273 if ((chObj->resId == EDMA3_RM_PARAM_ANY)
2274 || (chObj->resId == EDMA3_RM_RES_ANY))
2275 {
2276 /* Request for ANY LINK channel. */
2277 paRAMId = (int32_t)EDMA3_RM_RES_ANY;
2278 }
2279 else
2280 {
2281 if (chObj->resId < edma3NumPaRAMSets)
2282 {
2283 /* Request for a Specific LINK channel. */
2284 paRAMId = (int32_t)(chObj->resId);
2285 }
2286 else
2287 {
2288 result = EDMA3_RM_E_INVALID_PARAM;
2289 }
2290 }
2292 if (result == EDMA3_RM_SOK)
2293 {
2294 /* Try to allocate the link channel */
2295 resObj.type = EDMA3_RM_RES_PARAM_SET;
2296 resObj.resId = (uint32_t)paRAMId;
2297 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2299 if (result == EDMA3_RM_SOK)
2300 {
2301 uint32_t linkCh = edma3_link_ch_min_val[edma3Id];
2303 /* Return the actual PaRAM Id. */
2304 chObj->resId = resObj.resId;
2306 /*
2307 * Search for the next Link channel place-holder available,
2308 * starting from EDMA3_RM_LINK_CH_MIN_VAL.
2309 * It will be used for future operations on the Link channel.
2310 */
2311 while ((edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId != -1)
2312 && (linkCh <= edma3_link_ch_max_val[edma3Id]))
2313 {
2314 /* Move to the next place-holder. */
2315 linkCh++;
2316 }
2318 /* Verify the returned handle, it should lie in the correct range */
2319 if (linkCh > edma3_link_ch_max_val[edma3Id])
2320 {
2321 result = EDMA3_RM_E_INVALID_PARAM;
2323 /* Free the PaRAM Set now. */
2324 resObj.type = EDMA3_RM_RES_PARAM_SET;
2325 resObj.resId = chObj->resId;
2326 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2327 }
2328 else
2329 {
2330 /* Save the PaRAM Id for the Link Channel. */
2331 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = (int32_t)(chObj->resId);
2333 /**
2334 * Remove any linking. Before doing that, check
2335 * whether it is permitted or not.
2336 */
2337 if (TRUE == rmInstance->regModificationRequired)
2338 {
2339 *((&gblRegs->PARAMENTRY[chObj->resId].OPT)
2340 + (uint32_t)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFU;
2341 }
2342 }
2343 }
2344 }
2345 }
2346 break;
2348 default:
2349 {
2350 result = EDMA3_RM_E_INVALID_PARAM;
2351 break;
2352 }
2353 }
2354 }
2357 if (result == EDMA3_RM_SOK)
2358 {
2359 /**
2360 * For DMA/QDMA channels, we still have to allocate more resources like
2361 * TCC, PaRAM Set etc.
2362 * For Link channel, only the PaRAMSet is required and that has been
2363 * allocated so no further operations required.
2364 */
2366 /* Further resources' allocation for DMA channel. */
2367 if (chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
2368 {
2369 /* First allocate a PaRAM Set */
2370 resObj.type = EDMA3_RM_RES_PARAM_SET;
2371 /* Use the saved param id now. */
2372 resObj.resId = (uint32_t)paRAMId;
2373 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2374 if (result == EDMA3_RM_SOK)
2375 {
2376 /**
2377 * PaRAM Set allocation succeeded.
2378 * Save the PaRAM Set first.
2379 */
2380 *pParam = resObj.resId;
2381 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = (int32_t)(resObj.resId);
2383 /* Allocate the TCC now. */
2384 resObj.type = EDMA3_RM_RES_TCC;
2385 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2386 {
2387 if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2388 {
2389 resObj.resId = EDMA3_RM_RES_ANY;
2390 }
2391 else
2392 {
2393 resObj.resId = mappedTcc;
2394 }
2395 }
2396 else
2397 {
2398 resObj.resId = *pTcc;
2399 }
2401 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2402 if (result == EDMA3_RM_SOK)
2403 {
2404 /* TCC allocation succeeded. Save it first. */
2405 *pTcc = resObj.resId;
2406 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].tcc = resObj.resId;
2408 /**
2409 * Check first whether the global registers and the allocated
2410 * PaRAM Set can be modified or not. If yes, do the needful.
2411 * Else leave this for the user.
2412 */
2413 if (TRUE == rmInstance->regModificationRequired)
2414 {
2415 /* Set TCC of the allocated Param Set. */
2416 gblRegs->PARAMENTRY[*pParam].OPT &= EDMA3_RM_OPT_TCC_CLR_MASK;
2417 gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2419 /**
2420 * Do the mapping between DMA channel and PaRAM Set.
2421 * Do this for the EDMA3 Controllers which have a register for mapping
2422 * DMA Channel to a particular PaRAM Set.
2423 */
2424 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2425 {
2426 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2428 /* Map Parameter RAM Set Number for specified channelId */
2429 gblRegs->DCHMAP[chObj->resId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
2430 gblRegs->DCHMAP[chObj->resId] |= EDMA3_RM_DCH_PARAM_SET_MASK(*pParam);
2431 }
2433 /* Remove any linking */
2434 *((&gblRegs->PARAMENTRY[*pParam].OPT)
2435 + (uint32_t)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFU;
2436 }
2437 }
2438 else
2439 {
2440 /**
2441 * TCC allocation failed, free the previously allocated
2442 * PaRAM Set and DMA channel.
2443 */
2444 resObj.type = EDMA3_RM_RES_PARAM_SET;
2445 resObj.resId = *pParam;
2446 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2448 /* Reset the book-keeping data structure also. */
2449 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = -1;
2451 resObj.type = chObj->type;
2452 resObj.resId = chObj->resId;
2453 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2454 }
2455 }
2456 else
2457 {
2458 /**
2459 * PaRAM Set allocation failed, free the previously allocated
2460 * DMA channel also.
2461 */
2462 resObj.type = chObj->type;
2463 resObj.resId = chObj->resId;
2464 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2465 }
2466 }
2469 /* Further resources' allocation for QDMA channel. */
2470 if (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
2471 {
2472 /* First allocate a PaRAM Set */
2473 resObj.type = EDMA3_RM_RES_PARAM_SET;
2474 /* Use the saved param id now. */
2475 resObj.resId = (uint32_t)paRAMId;
2476 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2477 if (result == EDMA3_RM_SOK)
2478 {
2479 /**
2480 * PaRAM Set allocation succeeded.
2481 * Save the PaRAM Set first.
2482 */
2483 *pParam = resObj.resId;
2484 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = (int32_t)(resObj.resId);
2486 /* Allocate the TCC now. */
2487 resObj.type = EDMA3_RM_RES_TCC;
2488 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2489 {
2490 if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2491 {
2492 resObj.resId = EDMA3_RM_RES_ANY;
2493 }
2494 else
2495 {
2496 resObj.resId = mappedTcc;
2497 }
2498 }
2499 else
2500 {
2501 resObj.resId = *pTcc;
2502 }
2504 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2505 if (result == EDMA3_RM_SOK)
2506 {
2507 /* TCC allocation succeeded. Save it first. */
2508 *pTcc = resObj.resId;
2509 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = resObj.resId;
2511 /**
2512 * Check first whether the global registers and the allocated
2513 * PaRAM Set can be modified or not. If yes, do the needful.
2514 * Else leave this for the user.
2515 */
2516 if (TRUE == rmInstance->regModificationRequired)
2517 {
2518 /* Set TCC of the allocated Param Set. */
2519 gblRegs->PARAMENTRY[*pParam].OPT &= EDMA3_RM_OPT_TCC_CLR_MASK;
2520 gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2522 /* Do the mapping between QDMA channel and PaRAM Set. */
2523 /* Map Parameter RAM Set Number for specified channelId */
2524 gblRegs->QCHMAP[chObj->resId]
2525 &= EDMA3_RM_QCH_PARAM_CLR_MASK;
2526 gblRegs->QCHMAP[chObj->resId]
2527 |= EDMA3_RM_QCH_PARAM_SET_MASK(*pParam);
2529 /* Set the Trigger Word */
2530 gblRegs->QCHMAP[chObj->resId]
2531 &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
2532 gblRegs->QCHMAP[chObj->resId]
2533 |= EDMA3_RM_QCH_TRWORD_SET_MASK(EDMA3_RM_QDMA_TRIG_DEFAULT);
2535 /* Remove any linking */
2536 *((&gblRegs->PARAMENTRY[*pParam].OPT)
2537 + (uint32_t)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFU;
2539 /* Enable the transfer also. */
2540 rmInstance->shadowRegs->QEESR = (1U << chObj->resId);
2541 }
2542 }
2543 else
2544 {
2545 /**
2546 * TCC allocation failed, free the previously allocated
2547 * PaRAM Set and QDMA channel.
2548 */
2549 resObj.type = EDMA3_RM_RES_PARAM_SET;
2550 resObj.resId = *pParam;
2551 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2553 /* Reset the book-keeping data structure also. */
2554 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
2556 resObj.type = chObj->type;
2557 resObj.resId = chObj->resId;
2558 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2559 }
2560 }
2561 else
2562 {
2563 /**
2564 * PaRAM Set allocation failed, free the previously allocated
2565 * QDMA channel also.
2566 */
2567 resObj.type = chObj->type;
2568 resObj.resId = chObj->resId;
2569 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2570 }
2571 }
2572 }
2575 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2576 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2577 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2578 EDMA3_DVT_dCOUNTER,
2579 EDMA3_DVT_dNONE,
2580 EDMA3_DVT_dNONE));
2581 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2584 return result;
2585 }
2587 EDMA3_RM_Result EDMA3_RM_freeLogicalChannel (EDMA3_RM_Handle hEdmaResMgr,
2588 EDMA3_RM_ResDesc *lChObj)
2589 {
2590 EDMA3_RM_ResDesc *chObj;
2591 EDMA3_RM_ResDesc resObj;
2592 EDMA3_RM_Result result = EDMA3_RM_SOK;
2593 EDMA3_RM_Instance *rmInstance = NULL;
2594 EDMA3_RM_Obj *rmObj = NULL;
2595 int32_t paRAMId;
2596 uint32_t tcc;
2597 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
2598 uint32_t qdmaChId;
2599 uint32_t dmaChId;
2600 EDMA3_RM_InstanceInitConfig *rmConfig = NULL;
2601 uint32_t edma3Id;
2603 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2604 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2605 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2606 EDMA3_DVT_dCOUNTER,
2607 EDMA3_DVT_dNONE,
2608 EDMA3_DVT_dNONE));
2609 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2612 /* If parameter checking is enabled... */
2613 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2614 if ((lChObj == NULL) || (hEdmaResMgr == NULL))
2615 {
2616 result = (EDMA3_RM_E_INVALID_PARAM);
2617 }
2618 #endif
2620 /* Check if the parameters are OK. */
2621 if (result == EDMA3_RM_SOK)
2622 {
2623 chObj = lChObj;
2625 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2627 if (rmInstance == NULL)
2628 {
2629 result = EDMA3_RM_E_INVALID_PARAM;
2630 }
2631 }
2633 if (result == EDMA3_RM_SOK)
2634 {
2635 rmConfig = rmInstance->initParam.rmInstInitConfig;
2636 rmObj = rmInstance->pResMgrObjHandle;
2638 if (rmObj == NULL)
2639 {
2640 result = EDMA3_RM_E_INVALID_PARAM;
2641 }
2642 else
2643 {
2644 if (rmObj->gblCfgParams.globalRegs == NULL)
2645 {
2646 result = EDMA3_RM_E_INVALID_PARAM;
2647 }
2648 else
2649 {
2650 edma3Id = rmObj->phyCtrllerInstId;
2651 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2652 }
2653 }
2654 }
2657 if (result == EDMA3_RM_SOK)
2658 {
2659 switch (chObj->type)
2660 {
2661 case EDMA3_RM_RES_DMA_CHANNEL:
2662 {
2663 /* Save the DMA channel first. */
2664 dmaChId = chObj->resId;
2666 /**
2667 * Validate DMA channel id first.
2668 * It should be a valid channel id.
2669 */
2670 if (dmaChId >= EDMA3_MAX_DMA_CH)
2671 {
2672 result = EDMA3_RM_E_INVALID_PARAM;
2673 }
2675 /* It should be owned and allocated by this RM only. */
2676 if (result == EDMA3_RM_SOK)
2677 {
2678 if (((rmConfig->ownDmaChannels[dmaChId/32U])
2679 &
2680 (~(rmInstance->avlblDmaChannels[dmaChId/32U]))
2681 &
2682 ((uint32_t)1U << (dmaChId%32U))) != FALSE)
2683 {
2684 /** Perfectly valid channel id.
2685 * Clear some channel specific registers, if it is permitted.
2686 */
2687 if (TRUE == rmInstance->regModificationRequired)
2688 {
2689 if (dmaChId < 32U)
2690 {
2691 if((rmInstance->shadowRegs->SER & ((uint32_t)1U<<dmaChId))!=FALSE)
2692 {
2693 rmInstance->shadowRegs->SECR = (1U<<dmaChId);
2694 }
2695 if((globalRegs->EMR & ((uint32_t)1U<<dmaChId))!=FALSE)
2696 {
2697 globalRegs->EMCR = (1U<<dmaChId);
2698 }
2699 }
2700 else
2701 {
2702 if((rmInstance->shadowRegs->SERH & ((uint32_t)1U<<(dmaChId-32U)))!=FALSE)
2703 {
2704 rmInstance->shadowRegs->SECRH = (1U<<(dmaChId-32U));
2705 }
2706 if((globalRegs->EMRH & ((uint32_t)1U<<(dmaChId-32U)))!=FALSE)
2707 {
2708 globalRegs->EMCRH = (1U<<(dmaChId-32U));
2709 }
2710 }
2712 /* Clear DCHMAP register also. */
2713 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2714 {
2715 globalRegs->DCHMAP[dmaChId] &=
2716 EDMA3_RM_DCH_PARAM_CLR_MASK;
2717 }
2718 }
2720 /* Free the PaRAM Set Now. */
2721 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].paRAMId;
2722 resObj.type = EDMA3_RM_RES_PARAM_SET;
2723 resObj.resId = (uint32_t)paRAMId;
2724 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2725 }
2726 else
2727 {
2728 /* Channel id has some problem. */
2729 result = EDMA3_RM_E_INVALID_PARAM;
2730 }
2731 }
2734 if (result == EDMA3_RM_SOK)
2735 {
2736 /* PaRAM Set Freed */
2737 edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].paRAMId = -1;
2739 /* Free the TCC */
2740 tcc = edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].tcc;
2741 resObj.type = EDMA3_RM_RES_TCC;
2742 resObj.resId = tcc;
2743 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2744 }
2746 if (result == EDMA3_RM_SOK)
2747 {
2748 /* TCC Freed */
2749 edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].tcc = EDMA3_MAX_TCC;
2751 /**
2752 * Try to free the DMA Channel now. DMA Channel should
2753 * be freed only in the end because while freeing, DRAE
2754 * registers will be RESET.
2755 * After that, no shadow region specific DMA channel
2756 * register can be modified. So reset that DRAE register
2757 * ONLY in the end.
2758 */
2759 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2760 resObj.resId = dmaChId;
2761 result = EDMA3_RM_freeResource(hEdmaResMgr,
2762 (EDMA3_RM_ResDesc *)&resObj);
2763 }
2764 }
2765 break;
2768 case EDMA3_RM_RES_QDMA_CHANNEL:
2769 {
2770 /**
2771 * Calculate QDMA Logical Channel Id first.
2772 * User has given the actual QDMA channel id.
2773 * So we have to convert it to make the logical
2774 * QDMA channel id first.
2775 */
2776 qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
2778 /**
2779 * Validate QDMA channel id first.
2780 * It should be a valid channel id.
2781 */
2782 if (chObj->resId >= EDMA3_MAX_QDMA_CH)
2783 {
2784 result = EDMA3_RM_E_INVALID_PARAM;
2785 }
2787 /* It should be owned and allocated by this RM only. */
2788 if (result == EDMA3_RM_SOK)
2789 {
2790 if (((rmConfig->ownQdmaChannels[0U])
2791 &
2792 (~(rmInstance->avlblQdmaChannels[0U]))
2793 &
2794 ((uint32_t)1U << chObj->resId)) != FALSE)
2795 {
2796 /** Perfectly valid channel id.
2797 * Clear some channel specific registers, if
2798 * it is permitted.
2799 */
2800 if (TRUE == rmInstance->regModificationRequired)
2801 {
2802 rmInstance->shadowRegs->QEECR = (1U<<chObj->resId);
2804 if((globalRegs->QEMR & ((uint32_t)1U<<chObj->resId))!=FALSE)
2805 {
2806 globalRegs->QEMCR = (1U<<chObj->resId);
2807 }
2809 /* Unmap PARAM Set Number for specified channelId */
2810 globalRegs->QCHMAP[chObj->resId] &=
2811 EDMA3_RM_QCH_PARAM_CLR_MASK;
2813 /* Reset the Trigger Word */
2814 globalRegs->QCHMAP[chObj->resId] &=
2815 EDMA3_RM_QCH_TRWORD_CLR_MASK;
2816 }
2818 /* Free the PaRAM Set now */
2819 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId;
2820 resObj.type = EDMA3_RM_RES_PARAM_SET;
2821 resObj.resId = (int32_t)paRAMId;
2822 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2823 }
2824 else
2825 {
2826 /* Channel id has some problem. */
2827 result = EDMA3_RM_E_INVALID_PARAM;
2828 }
2829 }
2832 if (result == EDMA3_RM_SOK)
2833 {
2834 /* PaRAM Set Freed */
2835 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
2837 /* Free the TCC */
2838 tcc = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc;
2839 resObj.type = EDMA3_RM_RES_TCC;
2840 resObj.resId = tcc;
2841 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2842 }
2844 if (result == EDMA3_RM_SOK)
2845 {
2846 /* TCC Freed */
2847 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = EDMA3_MAX_TCC;
2849 /**
2850 * Try to free the QDMA Channel now. QDMA Channel should
2851 * be freed only in the end because while freeing, QRAE
2852 * registers will be RESET.
2853 * After that, no shadow region specific QDMA channel
2854 * register can be modified. So reset that QDRAE register
2855 * ONLY in the end.
2856 */
2857 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2858 resObj.resId = chObj->resId;
2859 result = EDMA3_RM_freeResource(hEdmaResMgr,
2860 (EDMA3_RM_ResDesc *)&resObj);
2861 }
2862 }
2863 break;
2866 case EDMA3_RM_RES_PARAM_SET:
2867 {
2868 /* Link Channel */
2869 if (chObj->resId < edma3NumPaRAMSets)
2870 {
2871 resObj.type = EDMA3_RM_RES_PARAM_SET;
2872 resObj.resId = chObj->resId;
2874 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2875 if (result == EDMA3_RM_SOK)
2876 {
2877 /* PaRAM Set freed successfully. */
2878 uint32_t linkCh = edma3_link_ch_min_val[edma3Id];
2880 /* Reset the Logical-Link channel */
2881 /* Search for the Logical-Link channel first */
2882 for (linkCh = edma3_link_ch_min_val[edma3Id];
2883 linkCh < edma3_link_ch_max_val[edma3Id];
2884 linkCh++)
2885 {
2886 if (edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId == chObj->resId)
2887 {
2888 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = -1;
2889 break;
2890 }
2891 }
2892 }
2893 }
2894 else
2895 {
2896 result = EDMA3_RM_E_INVALID_PARAM;
2897 }
2898 }
2899 break;
2901 default:
2902 {
2903 result = EDMA3_RM_E_INVALID_PARAM;
2904 break;
2905 }
2906 }
2907 }
2910 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2911 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2912 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2913 EDMA3_DVT_dCOUNTER,
2914 EDMA3_DVT_dNONE,
2915 EDMA3_DVT_dNONE));
2916 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2918 return result;
2919 }
2921 EDMA3_RM_Result EDMA3_RM_mapEdmaChannel (EDMA3_RM_Handle hEdmaResMgr,
2922 uint32_t channelId,
2923 uint32_t paRAMId)
2924 {
2925 EDMA3_RM_Instance *rmInstance = NULL;
2926 EDMA3_RM_Obj *rmObj = NULL;
2927 EDMA3_RM_Result result = EDMA3_RM_SOK;
2928 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
2930 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2931 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2932 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2933 EDMA3_DVT_dCOUNTER,
2934 EDMA3_DVT_dNONE,
2935 EDMA3_DVT_dNONE));
2936 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2938 /* If parameter checking is enabled... */
2939 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2940 if (hEdmaResMgr == NULL)
2941 {
2942 result = EDMA3_RM_E_INVALID_PARAM;
2943 }
2944 #endif
2946 if (result == EDMA3_RM_SOK)
2947 {
2948 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2950 if (rmInstance == NULL)
2951 {
2952 result = EDMA3_RM_E_INVALID_PARAM;
2953 }
2954 }
2956 if (result == EDMA3_RM_SOK)
2957 {
2958 rmObj = rmInstance->pResMgrObjHandle;
2960 if (rmObj == NULL)
2961 {
2962 result = EDMA3_RM_E_INVALID_PARAM;
2963 }
2964 else
2965 {
2966 if (rmObj->gblCfgParams.globalRegs == NULL)
2967 {
2968 result = EDMA3_RM_E_INVALID_PARAM;
2969 }
2970 }
2971 }
2973 if (result == EDMA3_RM_SOK)
2974 {
2975 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2977 /* If parameter checking is enabled... */
2978 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2979 if ((paRAMId >= rmObj->gblCfgParams.numPaRAMSets)
2980 || (channelId >= rmObj->gblCfgParams.numDmaChannels))
2981 {
2982 result = EDMA3_RM_E_INVALID_PARAM;
2983 }
2984 #endif
2985 }
2987 /* DMA channel and PaRAM Set should be previously allocated. */
2988 if (result == EDMA3_RM_SOK)
2989 {
2990 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[channelId/32U])
2991 &
2992 (~(rmInstance->avlblDmaChannels[channelId/32U]))
2993 &
2994 ((uint32_t)1U << (channelId%32U))) != FALSE)
2995 {
2996 /* DMA channel allocated, check for the PaRAM Set */
2997 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[paRAMId/32U])
2998 &
2999 (~(rmInstance->avlblPaRAMSets[paRAMId/32U]))
3000 &
3001 ((uint32_t)1U << (paRAMId%32U))) == FALSE)
3002 {
3003 /* PaRAM Set NOT allocated, return error */
3004 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3005 }
3006 }
3007 else
3008 {
3009 /* DMA channel NOT allocated, return error */
3010 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3011 }
3012 }
3015 if (result == EDMA3_RM_SOK)
3016 {
3017 /* Map the Dma Channel to the PaRAM Set corresponding to paramId */
3018 /**
3019 * Do this for the EDMA3 Controllers which have a register for mapping
3020 * DMA Channel to a particular PaRAM Set. So check
3021 * dmaChPaRAMMapExists first.
3022 */
3023 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
3024 {
3025 /* Map Parameter RAM Set Number for specified channelId */
3026 gblRegs->DCHMAP[channelId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
3027 gblRegs->DCHMAP[channelId] |= EDMA3_RM_DCH_PARAM_SET_MASK(paRAMId);
3028 }
3029 else
3030 {
3031 /* Feature NOT supported on the current platform, return error. */
3032 result = EDMA3_RM_E_FEATURE_UNSUPPORTED;
3033 }
3034 }
3036 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3037 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3038 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3039 EDMA3_DVT_dCOUNTER,
3040 EDMA3_DVT_dNONE,
3041 EDMA3_DVT_dNONE));
3042 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3044 return result;
3045 }
3047 EDMA3_RM_Result EDMA3_RM_mapQdmaChannel (EDMA3_RM_Handle hEdmaResMgr,
3048 uint32_t channelId,
3049 uint32_t paRAMId,
3050 EDMA3_RM_QdmaTrigWord trigWord)
3051 {
3052 EDMA3_RM_Instance *rmInstance = NULL;
3053 EDMA3_RM_Obj *rmObj = NULL;
3054 EDMA3_RM_Result result = EDMA3_RM_SOK;
3055 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3057 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3058 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3059 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3060 EDMA3_DVT_dCOUNTER,
3061 EDMA3_DVT_dNONE,
3062 EDMA3_DVT_dNONE));
3063 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3065 /* If parameter checking is enabled... */
3066 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3067 if ((hEdmaResMgr == NULL)
3068 || (((int32_t)trigWord < (int32_t)EDMA3_RM_QDMA_TRIG_OPT)
3069 || (trigWord > EDMA3_RM_QDMA_TRIG_CCNT)))
3070 {
3071 result = EDMA3_RM_E_INVALID_PARAM;
3072 }
3073 #endif
3075 if (result == EDMA3_RM_SOK)
3076 {
3077 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3079 if (rmInstance == NULL)
3080 {
3081 result = EDMA3_RM_E_INVALID_PARAM;
3082 }
3083 }
3085 if (result == EDMA3_RM_SOK)
3086 {
3087 rmObj = rmInstance->pResMgrObjHandle;
3089 if (rmObj == NULL)
3090 {
3091 result = EDMA3_RM_E_INVALID_PARAM;
3092 }
3093 else
3094 {
3095 if (rmObj->gblCfgParams.globalRegs == NULL)
3096 {
3097 result = EDMA3_RM_E_INVALID_PARAM;
3098 }
3099 }
3100 }
3102 if (result == EDMA3_RM_SOK)
3103 {
3104 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3106 /* If parameter checking is enabled... */
3107 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3108 if ((paRAMId >= rmObj->gblCfgParams.numPaRAMSets)
3109 || (channelId >= rmObj->gblCfgParams.numQdmaChannels))
3110 {
3111 result = EDMA3_RM_E_INVALID_PARAM;
3112 }
3113 #endif
3114 }
3116 /* QDMA channel and PaRAM Set should be previously allocated. */
3117 if (result == EDMA3_RM_SOK)
3118 {
3119 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[channelId/32U])
3120 &
3121 (~(rmInstance->avlblQdmaChannels[channelId/32U]))
3122 &
3123 ((uint32_t)1U << (channelId%32U))) != FALSE)
3124 {
3125 /* QDMA channel allocated, check for the PaRAM Set */
3126 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[paRAMId/32U])
3127 &
3128 (~(rmInstance->avlblPaRAMSets[paRAMId/32U]))
3129 &
3130 ((uint32_t)1U << (paRAMId%32U))) == FALSE)
3131 {
3132 /* PaRAM Set NOT allocated, return error */
3133 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3134 }
3135 }
3136 else
3137 {
3138 /* QDMA channel NOT allocated, return error */
3139 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3140 }
3141 }
3143 if (result == EDMA3_RM_SOK)
3144 {
3145 /* Map Parameter RAM Set Number for specified channelId */
3146 gblRegs->QCHMAP[channelId] &= EDMA3_RM_QCH_PARAM_CLR_MASK;
3147 gblRegs->QCHMAP[channelId] |= EDMA3_RM_QCH_PARAM_SET_MASK(paRAMId);
3149 /* Set the Trigger Word */
3150 gblRegs->QCHMAP[channelId] &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
3151 gblRegs->QCHMAP[channelId] |= EDMA3_RM_QCH_TRWORD_SET_MASK(trigWord);
3152 }
3155 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3156 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3157 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3158 EDMA3_DVT_dCOUNTER,
3159 EDMA3_DVT_dNONE,
3160 EDMA3_DVT_dNONE));
3161 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3163 return result;
3164 }
3166 EDMA3_RM_Result EDMA3_RM_registerTccCb(EDMA3_RM_Handle hEdmaResMgr,
3167 const EDMA3_RM_ResDesc *channelObj,
3168 uint32_t tcc,
3169 EDMA3_RM_TccCallback tccCb,
3170 void *cbData)
3171 {
3172 EDMA3_RM_Instance *rmInstance = NULL;
3173 EDMA3_RM_Obj *rmObj = NULL;
3174 EDMA3_RM_Result result = EDMA3_RM_SOK;
3175 uint32_t edma3Id;
3176 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3178 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3179 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3180 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3181 EDMA3_DVT_dCOUNTER,
3182 EDMA3_DVT_dNONE,
3183 EDMA3_DVT_dNONE));
3184 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3186 /* If parameter checking is enabled... */
3187 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3188 if ((NULL == hEdmaResMgr) || (NULL == channelObj))
3189 {
3190 result = EDMA3_RM_E_INVALID_PARAM;
3191 }
3193 /* Callback function should NOT be NULL */
3194 if (NULL == tccCb)
3195 {
3196 result = EDMA3_RM_E_INVALID_PARAM;
3197 }
3198 #endif
3200 if (result == EDMA3_RM_SOK)
3201 {
3202 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3203 rmObj = rmInstance->pResMgrObjHandle;
3205 if (rmObj == NULL)
3206 {
3207 result = EDMA3_RM_E_INVALID_PARAM;
3208 }
3209 else
3210 {
3211 edma3Id = rmObj->phyCtrllerInstId;
3212 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3213 }
3214 }
3216 if (result == EDMA3_RM_SOK)
3217 {
3218 if ((gblRegs == NULL) || (tcc >= rmObj->gblCfgParams.numTccs))
3219 {
3220 result = EDMA3_RM_E_INVALID_PARAM;
3221 }
3222 }
3224 /* Check if the parameters are OK. */
3225 if (EDMA3_RM_SOK == result)
3226 {
3227 /* Check whether the callback has already registered. */
3228 if (NULL != edma3IntrParams[edma3Id][tcc].tccCb)
3229 {
3230 result = EDMA3_RM_E_CALLBACK_ALREADY_REGISTERED;
3231 }
3232 else
3233 {
3234 /* Store the mapping b/w DMA/QDMA channel and TCC first. */
3235 if (channelObj->type == EDMA3_RM_RES_DMA_CHANNEL)
3236 {
3237 /* DMA channel */
3238 if (channelObj->resId < rmObj->gblCfgParams.numDmaChannels)
3239 {
3240 /* Save the TCC */
3241 edma3DmaChTccMapping[edma3Id][channelObj->resId] = tcc;
3242 }
3243 else
3244 {
3245 /* Error!!! */
3246 result = EDMA3_RM_E_INVALID_PARAM;
3247 }
3248 }
3249 else
3250 {
3251 if (channelObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
3252 {
3253 /* QDMA channel */
3254 if (channelObj->resId < rmObj->gblCfgParams.numQdmaChannels)
3255 {
3256 /* Save the TCC */
3257 edma3QdmaChTccMapping[edma3Id][channelObj->resId] = tcc;
3258 }
3259 else
3260 {
3261 /* Error!!! */
3262 result = EDMA3_RM_E_INVALID_PARAM;
3263 }
3264 }
3265 else
3266 {
3267 /* Error!!! */
3268 result = EDMA3_RM_E_INVALID_PARAM;
3269 }
3270 }
3271 }
3272 }
3274 if (EDMA3_RM_SOK == result)
3275 {
3277 /* Enable the interrupts in IESR/IESRH */
3278 if (tcc < 32U)
3279 {
3280 rmInstance->shadowRegs->IESR = (1UL << tcc);
3281 }
3282 else
3283 {
3284 rmInstance->shadowRegs->IESRH = (1UL << (tcc-32U));
3285 }
3287 /* Save the callback functions also */
3288 edma3IntrParams[edma3Id][tcc].cbData = cbData;
3289 edma3IntrParams[edma3Id][tcc].tccCb = tccCb;
3290 }
3292 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3293 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3294 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3295 EDMA3_DVT_dCOUNTER,
3296 EDMA3_DVT_dNONE,
3297 EDMA3_DVT_dNONE));
3298 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3300 return result;
3301 }
3303 EDMA3_RM_Result EDMA3_RM_unregisterTccCb(EDMA3_RM_Handle hEdmaResMgr,
3304 const EDMA3_RM_ResDesc *channelObj)
3305 {
3306 EDMA3_RM_Instance *rmInstance = NULL;
3307 EDMA3_RM_Obj *rmObj = NULL;
3308 EDMA3_RM_Result result = EDMA3_RM_SOK;
3309 uint32_t mappedTcc = EDMA3_MAX_TCC;
3310 uint32_t edma3Id;
3311 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3313 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3314 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3315 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3316 EDMA3_DVT_dCOUNTER,
3317 EDMA3_DVT_dNONE,
3318 EDMA3_DVT_dNONE));
3319 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3321 /* If parameter checking is enabled... */
3322 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3323 if ((NULL == hEdmaResMgr) || (NULL == channelObj))
3324 {
3325 result = EDMA3_RM_E_INVALID_PARAM;
3326 }
3327 #endif
3329 /* Check if the parameters are OK. */
3330 if (EDMA3_RM_SOK == result)
3331 {
3332 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3333 rmObj = rmInstance->pResMgrObjHandle;
3335 if (rmObj == NULL)
3336 {
3337 result = EDMA3_RM_E_INVALID_PARAM;
3338 }
3339 else
3340 {
3341 edma3Id = rmObj->phyCtrllerInstId;
3342 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3343 }
3344 }
3346 if (result == EDMA3_RM_SOK)
3347 {
3348 if (gblRegs == NULL)
3349 {
3350 result = EDMA3_RM_E_INVALID_PARAM;
3351 }
3352 else
3353 {
3354 if (channelObj->type == EDMA3_RM_RES_DMA_CHANNEL)
3355 {
3356 /* DMA channel */
3357 if (channelObj->resId < rmObj->gblCfgParams.numDmaChannels)
3358 {
3359 /* Save the mapped TCC */
3360 mappedTcc = edma3DmaChTccMapping[edma3Id][channelObj->resId];
3362 /* Remove the mapping now. */
3363 edma3DmaChTccMapping[edma3Id][channelObj->resId] = EDMA3_MAX_TCC;
3364 }
3365 else
3366 {
3367 /* Error!!! */
3368 result = EDMA3_RM_E_INVALID_PARAM;
3369 }
3370 }
3371 else
3372 {
3373 if (channelObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
3374 {
3375 /* QDMA channel */
3376 if (channelObj->resId < rmObj->gblCfgParams.numQdmaChannels)
3377 {
3378 /* Save the mapped TCC */
3379 mappedTcc = edma3QdmaChTccMapping[edma3Id][channelObj->resId];
3381 /* Remove the mapping now. */
3382 edma3QdmaChTccMapping[edma3Id][channelObj->resId] = EDMA3_MAX_TCC;
3383 }
3384 else
3385 {
3386 /* Error!!! */
3387 result = EDMA3_RM_E_INVALID_PARAM;
3388 }
3389 }
3390 else
3391 {
3392 /* Error!!! */
3393 result = EDMA3_RM_E_INVALID_PARAM;
3394 }
3395 }
3396 }
3397 }
3399 if (EDMA3_RM_SOK == result)
3400 {
3402 /* Remove the callback function too */
3403 if (mappedTcc < 32U)
3404 {
3405 rmInstance->shadowRegs->IECR = (1UL << mappedTcc);
3406 }
3407 else if(mappedTcc < 64U)
3408 {
3409 rmInstance->shadowRegs->IECRH = (1UL << (mappedTcc-32U));
3410 }
3411 else
3412 {
3413 /* To Comply MISRA C warning */
3414 result = EDMA3_RM_SOK;
3415 }
3417 if(mappedTcc < EDMA3_MAX_TCC)
3418 {
3419 edma3IntrParams[edma3Id][mappedTcc].cbData = NULL;
3420 edma3IntrParams[edma3Id][mappedTcc].tccCb = NULL;
3421 }
3422 }
3424 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3425 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3426 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3427 EDMA3_DVT_dCOUNTER,
3428 EDMA3_DVT_dNONE,
3429 EDMA3_DVT_dNONE));
3430 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3432 return result;
3433 }
3435 EDMA3_RM_Result EDMA3_RM_allocContiguousResource(EDMA3_RM_Handle hEdmaResMgr,
3436 EDMA3_RM_ResDesc *firstResIdObj,
3437 uint32_t numResources)
3438 {
3439 EDMA3_RM_Instance *rmInstance = NULL;
3440 EDMA3_RM_Obj *rmObj = NULL;
3441 EDMA3_RM_Result result = EDMA3_RM_SOK;
3442 EDMA3_RM_ResDesc *resObj = NULL;
3443 uint32_t resAllocIdx = 0U;
3444 uint32_t firstResId;
3445 uint32_t lastResId = 0U;
3446 uint32_t maxNumResources = 0U;
3447 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
3448 uint32_t resIdClr = 0x0;
3449 uint32_t resIdSet = 0x0;
3450 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3451 uint32_t i = 0U;
3452 uint32_t position = 0U;
3453 uint32_t edma3Id;
3454 uint32_t errFlag=0U;
3456 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3457 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3458 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3459 EDMA3_DVT_dCOUNTER,
3460 EDMA3_DVT_dNONE,
3461 EDMA3_DVT_dNONE));
3462 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3465 /* If parameter checking is enabled... */
3466 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3467 if ((hEdmaResMgr == NULL) || (firstResIdObj == NULL))
3468 {
3469 result = EDMA3_RM_E_INVALID_PARAM;
3470 }
3471 #endif
3473 if (EDMA3_RM_SOK == result)
3474 {
3475 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3476 if (rmInstance == NULL)
3477 {
3478 result = EDMA3_RM_E_INVALID_PARAM;
3479 }
3480 }
3482 if (EDMA3_RM_SOK == result)
3483 {
3484 rmObj = rmInstance->pResMgrObjHandle;
3486 if (rmObj == NULL)
3487 {
3488 result = EDMA3_RM_E_INVALID_PARAM;
3489 }
3490 }
3492 if (EDMA3_RM_SOK == result)
3493 {
3494 edma3Id = rmObj->phyCtrllerInstId;
3495 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3497 if (rmInstance->initParam.rmSemHandle == NULL)
3498 {
3499 result = EDMA3_RM_E_INVALID_PARAM;
3500 }
3501 }
3503 if (EDMA3_RM_SOK == result)
3504 {
3505 resObj = firstResIdObj;
3506 if (resObj != NULL)
3507 {
3508 firstResId = resObj->resId;
3509 }
3511 switch (resObj->type)
3512 {
3513 case EDMA3_RM_RES_DMA_CHANNEL :
3514 maxNumResources = rmObj->gblCfgParams.numDmaChannels;
3515 break;
3516 case EDMA3_RM_RES_QDMA_CHANNEL :
3517 maxNumResources = rmObj->gblCfgParams.numQdmaChannels;
3518 break;
3519 case EDMA3_RM_RES_TCC :
3520 maxNumResources = rmObj->gblCfgParams.numTccs;
3521 break;
3522 case EDMA3_RM_RES_PARAM_SET :
3523 maxNumResources = rmObj->gblCfgParams.numPaRAMSets;
3524 break;
3525 default:
3526 result = EDMA3_RM_E_INVALID_PARAM;
3527 break;
3528 }
3529 }
3532 if (EDMA3_RM_SOK == result)
3533 {
3534 /* First resource id (firstResId) can be a valid Resource ID as well as
3535 * 'EDMA3_RM_RES_ANY', in case user does not want to
3536 * start from a specific resource. For eg, user allocating link channels.
3537 */
3538 if (firstResId != EDMA3_RM_RES_ANY)
3539 {
3540 /* User want specific resources. */
3541 lastResId = firstResId + numResources;
3543 if (((firstResId >= maxNumResources) || (firstResId > lastResId))
3544 || (lastResId > maxNumResources))
3545 {
3546 result = EDMA3_RM_E_INVALID_PARAM;
3547 }
3548 }
3549 else
3550 {
3551 /* (firstResId == EDMA3_RM_RES_ANY)
3552 * So just check whether the number of resources
3553 * requested does not cross the limit.
3554 */
3555 if (numResources > maxNumResources)
3556 {
3557 result = EDMA3_RM_E_INVALID_PARAM;
3558 }
3559 }
3560 }
3563 if (result == EDMA3_RM_SOK)
3564 {
3565 /* Now try to allocate resources for the first case */
3566 if (firstResId != EDMA3_RM_RES_ANY)
3567 {
3568 /* Request for specific resources */
3570 /**
3571 * Take the instance specific semaphore, to prevent simultaneous
3572 * access to the shared resources.
3573 */
3574 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
3575 EDMA3_OSSEM_NO_TIMEOUT);
3577 if (EDMA3_RM_SOK == semResult)
3578 {
3579 switch (resObj->type)
3580 {
3581 case EDMA3_RM_RES_DMA_CHANNEL :
3582 {
3583 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3584 {
3585 resIdClr = (uint32_t)(~((uint32_t)1U << (resAllocIdx%32U)));
3586 resIdSet = (1U << (resAllocIdx%32U));
3588 /* Check whether it is owned or not */
3589 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resAllocIdx/32U])&(resIdSet)) != FALSE)
3590 {
3591 /* Now check if specified resource is available presently*/
3592 if (((rmInstance->avlblDmaChannels[resAllocIdx/32U])&(resIdSet)) != FALSE)
3593 {
3594 /*
3595 * Mark the specified resource as "Not Available"
3596 * for future requests
3597 */
3598 rmInstance->avlblDmaChannels[resAllocIdx/32U] &= resIdClr;
3600 if (resAllocIdx < 32U)
3601 {
3602 rmInstance->shadowRegs->EECR = (1UL << resAllocIdx);
3604 /**
3605 * Enable the DMA channel in the
3606 * DRAE registers also.
3607 */
3608 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
3609 |= ((uint32_t)0x1U << resAllocIdx);
3610 }
3611 else
3612 {
3613 rmInstance->shadowRegs->EECRH = (1UL << (resAllocIdx - 32U));
3615 /**
3616 * Enable the DMA channel in the
3617 * DRAEH registers also.
3618 */
3619 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
3620 |= ((uint32_t)0x1U << (resAllocIdx - 32U));
3621 }
3623 result = EDMA3_RM_SOK;
3624 }
3625 else
3626 {
3627 /* Specified resource is owned but is already booked */
3628 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3629 errFlag = 1U;
3630 }
3631 }
3632 else
3633 {
3634 /*
3635 * Specified resource is not owned by this instance
3636 * of the Resource Manager
3637 */
3638 result = EDMA3_RM_E_RES_NOT_OWNED;
3639 errFlag = 1U;
3640 }
3641 if(errFlag == 1U)
3642 {
3643 break;
3644 }
3645 }
3647 break;
3648 }
3650 case EDMA3_RM_RES_QDMA_CHANNEL:
3651 {
3652 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3653 {
3654 resIdClr = (uint32_t)(~((uint32_t)1U << resAllocIdx));
3655 resIdSet = (1U << resAllocIdx);
3657 /* Check whether it is owned or not */
3658 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0U])&(resIdSet))!=FALSE)
3659 {
3660 /* Now check if specified resource is available presently*/
3661 if (((rmInstance->avlblQdmaChannels[0U])&(resIdSet))!=FALSE)
3662 {
3663 /*
3664 * Mark the specified resource as "Not Available"
3665 * for future requests
3666 */
3667 rmInstance->avlblQdmaChannels[0U] &= resIdClr;
3669 /**
3670 * Enable the QDMA channel in the
3671 * QRAE register also.
3672 */
3673 gblRegs->QRAE[rmInstance->initParam.regionId]
3674 |= ((uint32_t)0x1U << resAllocIdx);
3676 result = EDMA3_RM_SOK;
3677 }
3678 else
3679 {
3680 /* Specified resource is owned but is already booked */
3681 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3682 errFlag = 1U;
3683 }
3684 }
3685 else
3686 {
3687 /*
3688 * Specified resource is not owned by this instance
3689 * of the Resource Manager
3690 */
3691 result = EDMA3_RM_E_RES_NOT_OWNED;
3692 errFlag = 1U;
3693 }
3694 if(errFlag == 1U)
3695 {
3696 break;
3697 }
3698 }
3700 break;
3701 }
3703 case EDMA3_RM_RES_TCC:
3704 {
3705 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3706 {
3707 resIdClr = (uint32_t)(~((uint32_t)1U << (resAllocIdx%32U)));
3708 resIdSet = (1U << (resAllocIdx%32U));
3710 /* Check whether it is owned or not */
3711 if (((rmInstance->initParam.rmInstInitConfig->ownTccs[resAllocIdx/32U])&(resIdSet))!=FALSE)
3712 {
3713 /* Now check if specified resource is available presently*/
3714 if (((rmInstance->avlblTccs[resAllocIdx/32U])&(resIdSet))!=FALSE)
3715 {
3716 /*
3717 * Mark the specified resource as "Not Available"
3718 * for future requests
3719 */
3720 rmInstance->avlblTccs[resAllocIdx/32U] &= resIdClr;
3722 /**
3723 * If the region id coming from this
3724 * RM instance is same as the Master RM
3725 * Instance's region id, only then we will be
3726 * getting the interrupts on the same side.
3727 * So save the TCC in the allocatedTCCs[] array.
3728 */
3729 if (edma3RegionId == rmInstance->initParam.regionId)
3730 {
3731 if (resAllocIdx < 32U)
3732 {
3733 allocatedTCCs[edma3Id][0U] |= ((uint32_t)0x1U << resAllocIdx);
3734 }
3735 else
3736 {
3737 allocatedTCCs[edma3Id][1U] |= ((uint32_t)0x1U << (resAllocIdx - 32U));
3738 }
3739 }
3740 result = EDMA3_RM_SOK;
3741 }
3742 else
3743 {
3744 /* Specified resource is owned but is already booked */
3745 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3746 errFlag = 1U;
3747 }
3748 }
3749 else
3750 {
3751 /*
3752 * Specified resource is not owned by this instance
3753 * of the Resource Manager
3754 */
3755 result = EDMA3_RM_E_RES_NOT_OWNED;
3756 errFlag = 1U;
3757 }
3758 if(errFlag == 1U)
3759 {
3760 break;
3761 }
3762 }
3764 break;
3765 }
3767 case EDMA3_RM_RES_PARAM_SET:
3768 {
3769 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3770 {
3771 resIdClr = (uint32_t)(~((uint32_t)1U << (resAllocIdx%32U)));
3772 resIdSet = (1U << (resAllocIdx%32U));
3774 /* Check whether it is owned or not */
3775 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[resAllocIdx/32U])&(resIdSet))!=FALSE)
3776 {
3777 /* Now check if specified resource is available presently*/
3778 if (((rmInstance->avlblPaRAMSets[resAllocIdx/32U])&(resIdSet))!=FALSE)
3779 {
3780 /*
3781 * Mark the specified resource as "Not Available"
3782 * for future requests
3783 */
3784 rmInstance->avlblPaRAMSets[resAllocIdx/32U] &= resIdClr;
3786 /**
3787 * Also, make the actual PARAM Set NULL, checking the flag
3788 * whether it is required or not.
3789 */
3790 if (TRUE == rmInstance->paramInitRequired)
3791 {
3792 edma3MemZero((void *)(&gblRegs->PARAMENTRY[resAllocIdx]),
3793 sizeof(gblRegs->PARAMENTRY[resAllocIdx]));
3794 }
3796 result = EDMA3_RM_SOK;
3797 }
3798 else
3799 {
3800 /* Specified resource is owned but is already booked */
3801 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3802 errFlag = 1U;
3803 }
3804 }
3805 else
3806 {
3807 /*
3808 * Specified resource is not owned by this instance
3809 * of the Resource Manager
3810 */
3811 result = EDMA3_RM_E_RES_NOT_OWNED;
3812 errFlag = 1U;
3813 }
3814 if(errFlag == 1U)
3815 {
3816 break;
3817 }
3818 }
3820 break;
3821 }
3823 default:
3824 {
3825 result = EDMA3_RM_E_INVALID_PARAM;
3826 break;
3827 }
3828 }
3830 /* resource allocation completed, release the semaphore first */
3831 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
3832 }
3834 }
3835 else
3836 {
3837 /* (firstResId == EDMA3_RM_RES_ANY) */
3838 /**
3839 * Take the instance specific semaphore, to prevent simultaneous
3840 * access to the shared resources.
3841 */
3842 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
3843 EDMA3_OSSEM_NO_TIMEOUT);
3845 if (EDMA3_RM_SOK == semResult)
3846 {
3847 /**
3848 * We have to search three different arrays, namely ownedResoures,
3849 * avlblResources and resvdResources, to find the 'common' contiguous
3850 * resources. For this, take an 'AND' of all three arrays in one single
3851 * array and use your algorithm on that array.
3852 */
3853 switch (resObj->type)
3854 {
3855 case EDMA3_RM_RES_DMA_CHANNEL:
3856 {
3857 /* AND all the arrays to look into */
3858 contiguousDmaRes[0U] = ((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[0U]
3859 & rmInstance->avlblDmaChannels[0U])
3860 & (~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[0U]))
3861 );
3862 contiguousDmaRes[1U] = ((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[1U]
3863 & rmInstance->avlblDmaChannels[1U])
3864 & (~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[1U]))
3865 );
3866 }
3867 break;
3869 case EDMA3_RM_RES_QDMA_CHANNEL:
3870 {
3871 /* AND all the arrays to look into */
3872 contiguousQdmaRes[0U] = ((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0U]
3873 & rmInstance->avlblQdmaChannels[0U])
3874 & (~(rmInstance->initParam.rmInstInitConfig->resvdQdmaChannels[0U]))
3875 );
3876 }
3877 break;
3879 case EDMA3_RM_RES_TCC:
3880 {
3881 /* AND all the arrays to look into */
3882 contiguousTccRes[0U] = ((rmInstance->initParam.rmInstInitConfig->ownTccs[0U]
3883 & rmInstance->avlblTccs[0U])
3884 & (~(rmInstance->initParam.rmInstInitConfig->resvdTccs[0U]))
3885 );
3886 contiguousTccRes[1U] = ((rmInstance->initParam.rmInstInitConfig->ownTccs[1U]
3887 & rmInstance->avlblTccs[1U])
3888 & (~(rmInstance->initParam.rmInstInitConfig->resvdTccs[1U]))
3889 );
3890 }
3891 break;
3893 case EDMA3_RM_RES_PARAM_SET:
3894 {
3895 /* AND all the arrays to look into */
3896 for (i = 0U; i < (maxNumResources/32U); ++i)
3897 {
3898 contiguousParamRes[i] = ((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[i]
3899 & rmInstance->avlblPaRAMSets[i])
3900 & (~(rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[i]))
3901 );
3902 }
3903 }
3904 break;
3906 default:
3907 {
3908 result = EDMA3_RM_E_INVALID_PARAM;
3909 }
3910 break;
3911 }
3913 if (EDMA3_RM_SOK == result)
3914 {
3915 /**
3916 * Try to allocate 'numResources' contiguous resources
3917 * of type RES_ANY.
3918 */
3919 result = allocAnyContigRes (resObj->type, numResources, &position);
3921 /**
3922 * If result != EDMA3_RM_SOK, resource allocation failed.
3923 * Else resources successfully allocated.
3924 */
3925 if (result == EDMA3_RM_SOK)
3926 {
3927 /* Update the first resource id with the position returned. */
3928 resObj->resId = position;
3930 /*
3931 * Do some further changes in the book-keeping
3932 * data structures and global registers accordingly.
3933 */
3934 result = gblChngAllocContigRes(rmInstance, resObj, numResources);
3935 }
3936 }
3938 /* resource allocation completed, release the semaphore first */
3939 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
3940 }
3941 }
3942 }
3945 /**
3946 * Check the Resource Allocation Result 'result' first. If Resource
3947 * Allocation has resulted in an error, return it (having more priority than
3948 * semResult. Else, return semResult.
3949 */
3950 if (EDMA3_RM_SOK == result)
3951 {
3952 /**
3953 * Resource Allocation successful, return semResult for returning
3954 * semaphore.
3955 */
3956 result = semResult;
3957 }
3960 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3961 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3962 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3963 EDMA3_DVT_dCOUNTER,
3964 EDMA3_DVT_dNONE,
3965 EDMA3_DVT_dNONE));
3966 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3968 return result;
3969 }
3971 EDMA3_RM_Result EDMA3_RM_freeContiguousResource(EDMA3_RM_Handle hEdmaResMgr,
3972 EDMA3_RM_ResDesc *firstResIdObj,
3973 uint32_t numResources)
3974 {
3975 EDMA3_RM_Instance *rmInstance = NULL;
3976 EDMA3_RM_Obj *rmObj = NULL;
3977 EDMA3_RM_Result result = EDMA3_RM_SOK;
3978 EDMA3_RM_ResDesc *resObj;
3979 uint32_t resFreeIdx = 0U;
3980 uint32_t firstResId;
3981 uint32_t lastResId;
3982 uint32_t maxNumResources = 0U;
3984 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3985 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3986 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3987 EDMA3_DVT_dCOUNTER,
3988 EDMA3_DVT_dNONE,
3989 EDMA3_DVT_dNONE));
3990 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3992 /* If parameter checking is enabled... */
3993 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3994 if ((hEdmaResMgr == NULL) || (firstResIdObj == NULL))
3995 {
3996 result = EDMA3_RM_E_INVALID_PARAM;
3997 }
3998 #endif
4000 /* Check if the parameters are OK. */
4001 if (EDMA3_RM_SOK == result)
4002 {
4003 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4004 rmObj = rmInstance->pResMgrObjHandle;
4006 if (rmObj == NULL)
4007 {
4008 result = EDMA3_RM_E_INVALID_PARAM;
4009 }
4010 else
4011 {
4012 resObj = firstResIdObj;
4013 if (resObj != NULL)
4014 {
4015 firstResId = resObj->resId;
4016 lastResId = firstResId + (numResources - 1U);
4017 }
4019 switch (resObj->type)
4020 {
4021 case EDMA3_RM_RES_DMA_CHANNEL :
4022 maxNumResources = rmObj->gblCfgParams.numDmaChannels;
4023 break;
4024 case EDMA3_RM_RES_QDMA_CHANNEL :
4025 maxNumResources = rmObj->gblCfgParams.numQdmaChannels;
4026 break;
4027 case EDMA3_RM_RES_TCC :
4028 maxNumResources = rmObj->gblCfgParams.numTccs;
4029 break;
4030 case EDMA3_RM_RES_PARAM_SET :
4031 maxNumResources = rmObj->gblCfgParams.numPaRAMSets;
4032 break;
4033 default:
4034 result = EDMA3_RM_E_INVALID_PARAM;
4035 break;
4036 }
4038 if (result == EDMA3_RM_SOK)
4039 {
4040 if ((firstResId > lastResId) || (lastResId >= maxNumResources))
4041 {
4042 result = EDMA3_RM_E_INVALID_PARAM;
4043 }
4044 else
4045 {
4046 for (resFreeIdx = firstResId; resFreeIdx <= lastResId; ++resFreeIdx)
4047 {
4048 resObj->resId = resFreeIdx;
4049 result = EDMA3_RM_freeResource(rmInstance, resObj);
4051 if (result != EDMA3_RM_SOK)
4052 {
4053 break;
4054 }
4055 }
4056 }
4057 }
4058 }
4059 }
4061 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4062 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4063 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4064 EDMA3_DVT_dCOUNTER,
4065 EDMA3_DVT_dNONE,
4066 EDMA3_DVT_dNONE));
4067 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4069 return result;
4070 }
4072 EDMA3_RM_Result EDMA3_RM_setCCRegister (EDMA3_RM_Handle hEdmaResMgr,
4073 uint32_t regOffset,
4074 uint32_t newRegValue)
4075 {
4076 uint32_t intState;
4077 EDMA3_RM_Result result = EDMA3_RM_SOK;
4078 EDMA3_RM_Instance *rmInstance = NULL;
4079 EDMA3_RM_Obj *rmObj = NULL;
4080 volatile uint32_t regPhyAddr = 0x0U;
4083 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4084 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4085 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4086 EDMA3_DVT_dCOUNTER,
4087 EDMA3_DVT_dNONE,
4088 EDMA3_DVT_dNONE));
4089 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4092 /* If parameter checking is enabled... */
4093 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4094 if ((hEdmaResMgr == NULL) || ((regOffset % 4U) != 0))
4095 {
4096 result = (EDMA3_RM_E_INVALID_PARAM);
4097 }
4098 #endif
4100 /* Check if the parameters are OK. */
4101 if (EDMA3_RM_SOK == result)
4102 {
4103 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4104 rmObj = rmInstance->pResMgrObjHandle;
4106 if (rmObj == NULL)
4107 {
4108 result = (EDMA3_RM_E_INVALID_PARAM);
4109 }
4110 else
4111 {
4112 if (rmObj->gblCfgParams.globalRegs != NULL)
4113 {
4114 /**
4115 * Take the instance specific semaphore, to prevent simultaneous
4116 * access to the shared resources.
4117 */
4118 result = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
4119 EDMA3_OSSEM_NO_TIMEOUT);
4121 if (EDMA3_RM_SOK == result)
4122 {
4123 /* Semaphore taken successfully, modify the registers. */
4124 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
4125 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
4126 &intState);
4127 /* Global interrupts disabled, modify the registers. */
4128 regPhyAddr = (uint32_t)(rmObj->gblCfgParams.globalRegs) + regOffset;
4130 *(uint32_t *)regPhyAddr = newRegValue;
4131 edma3OsProtectExit (rmObj->phyCtrllerInstId,
4132 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
4133 intState);
4135 /* Return the semaphore back */
4136 result = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
4137 }
4138 }
4139 }
4140 }
4143 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4144 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4145 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4146 EDMA3_DVT_dCOUNTER,
4147 EDMA3_DVT_dNONE,
4148 EDMA3_DVT_dNONE));
4149 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4152 return result;
4153 }
4155 EDMA3_RM_Result EDMA3_RM_getCCRegister (EDMA3_RM_Handle hEdmaResMgr,
4156 uint32_t regOffset,
4157 uint32_t *regValue)
4158 {
4159 EDMA3_RM_Result result = EDMA3_RM_SOK;
4160 EDMA3_RM_Instance *rmInstance = NULL;
4161 EDMA3_RM_Obj *rmObj = NULL;
4162 volatile uint32_t regPhyAddr = 0x0U;
4165 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4166 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4167 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4168 EDMA3_DVT_dCOUNTER,
4169 EDMA3_DVT_dNONE,
4170 EDMA3_DVT_dNONE));
4171 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4174 /* If parameter checking is enabled... */
4175 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4176 if (((hEdmaResMgr == NULL) || (regValue == NULL))
4177 || ((regOffset % 4U) != 0))
4178 {
4179 result = (EDMA3_RM_E_INVALID_PARAM);
4180 }
4181 #endif
4183 /* Check if the parameters are OK. */
4184 if (EDMA3_RM_SOK == result)
4185 {
4186 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4187 rmObj = rmInstance->pResMgrObjHandle;
4189 if (rmObj == NULL)
4190 {
4191 result = (EDMA3_RM_E_INVALID_PARAM);
4192 }
4193 else
4194 {
4195 if (rmObj->gblCfgParams.globalRegs != NULL)
4196 {
4197 regPhyAddr = (uint32_t)(rmObj->gblCfgParams.globalRegs) + regOffset;
4199 *regValue = *(uint32_t *)regPhyAddr;
4200 }
4201 }
4202 }
4205 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4206 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4207 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4208 EDMA3_DVT_dCOUNTER,
4209 EDMA3_DVT_dNONE,
4210 EDMA3_DVT_dNONE));
4211 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4214 return result;
4215 }
4217 EDMA3_RM_Result EDMA3_RM_waitAndClearTcc (EDMA3_RM_Handle hEdmaResMgr,
4218 uint32_t tccNo)
4219 {
4220 EDMA3_RM_Result result = EDMA3_RM_SOK;
4221 EDMA3_RM_Instance *rmInstance = NULL;
4222 EDMA3_RM_Obj *rmObj = NULL;
4223 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4224 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
4225 uint32_t tccBitMask = 0x0U;
4228 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4229 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4230 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4231 EDMA3_DVT_dCOUNTER,
4232 EDMA3_DVT_dNONE,
4233 EDMA3_DVT_dNONE));
4234 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4237 /* If parameter checking is enabled... */
4238 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4239 if (hEdmaResMgr == NULL)
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 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4249 rmObj = rmInstance->pResMgrObjHandle;
4251 if ((rmObj == NULL) || (rmObj->gblCfgParams.globalRegs == NULL))
4252 {
4253 result = (EDMA3_RM_E_INVALID_PARAM);
4254 }
4255 else
4256 {
4257 /* If parameter checking is enabled... */
4258 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4259 if (tccNo >= rmObj->gblCfgParams.numTccs)
4260 {
4261 result = (EDMA3_RM_E_INVALID_PARAM);
4262 }
4263 #endif
4265 /* Check if the parameters are OK. */
4266 if (EDMA3_RM_SOK == result)
4267 {
4268 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4269 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
4270 (&globalRegs->SHADOW[rmInstance->initParam.regionId]);
4273 if (shadowRegs != NULL)
4274 {
4275 if(tccNo < 32U)
4276 {
4277 tccBitMask = (1U << tccNo);
4279 /* Check the status of the IPR[tccNo] bit. */
4280 while ((uint32_t)FALSE == (shadowRegs->IPR & tccBitMask))
4281 {
4282 /* Transfer not yet completed, bit not SET */
4283 }
4285 /**
4286 * Bit found SET, transfer is completed,
4287 * clear the pending interrupt and return.
4288 */
4289 shadowRegs->ICR = tccBitMask;
4290 }
4291 else
4292 {
4293 tccBitMask = (1U << (tccNo - 32U));
4295 /* Check the status of the IPRH[tccNo-32] bit. */
4296 while ((uint32_t)FALSE == (shadowRegs->IPRH & tccBitMask))
4297 {
4298 /* Transfer not yet completed, bit not SET */
4299 }
4301 /**
4302 * Bit found SET, transfer is completed,
4303 * clear the pending interrupt and return.
4304 */
4305 shadowRegs->ICRH = tccBitMask;
4306 }
4307 }
4308 }
4309 }
4310 }
4313 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4314 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4315 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4316 EDMA3_DVT_dCOUNTER,
4317 EDMA3_DVT_dNONE,
4318 EDMA3_DVT_dNONE));
4319 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4322 return result;
4323 }
4325 EDMA3_RM_Result EDMA3_RM_checkAndClearTcc (EDMA3_RM_Handle hEdmaResMgr,
4326 uint32_t tccNo,
4327 uint16_t *tccStatus)
4328 {
4329 EDMA3_RM_Result result = EDMA3_RM_SOK;
4330 EDMA3_RM_Instance *rmInstance = NULL;
4331 EDMA3_RM_Obj *rmObj = NULL;
4332 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4333 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
4334 uint32_t tccBitMask = 0x0U;
4337 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4338 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4339 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4340 EDMA3_DVT_dCOUNTER,
4341 EDMA3_DVT_dNONE,
4342 EDMA3_DVT_dNONE));
4343 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4346 /* If parameter checking is enabled... */
4347 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4348 if ((hEdmaResMgr == NULL) || (tccStatus == NULL))
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 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4358 rmObj = rmInstance->pResMgrObjHandle;
4360 if ((rmObj == NULL) || (rmObj->gblCfgParams.globalRegs == NULL))
4361 {
4362 result = (EDMA3_RM_E_INVALID_PARAM);
4363 }
4364 else
4365 {
4366 /* If parameter checking is enabled... */
4367 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4368 if (tccNo >= rmObj->gblCfgParams.numTccs)
4369 {
4370 result = (EDMA3_RM_E_INVALID_PARAM);
4371 }
4372 #endif
4374 /* Check if the parameters are OK. */
4375 if (EDMA3_RM_SOK == result)
4376 {
4377 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4378 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
4379 (&globalRegs->SHADOW[rmInstance->initParam.regionId]);
4381 /* Reset the tccStatus */
4382 *tccStatus = FALSE;
4384 if (shadowRegs != NULL)
4385 {
4386 if(tccNo < 32U)
4387 {
4388 tccBitMask = (1U << tccNo);
4390 /* Check the status of the IPR[tccNo] bit. */
4391 if ((shadowRegs->IPR & tccBitMask) != FALSE)
4392 {
4393 /* Transfer completed, bit found SET */
4394 *tccStatus = TRUE;
4396 /* Clear the pending interrupt also. */
4397 shadowRegs->ICR = tccBitMask;
4398 }
4399 }
4400 else
4401 {
4402 tccBitMask = (1U << (tccNo - 32U));
4404 /* Check the status of the IPRH[tccNo-32] bit. */
4405 if ((shadowRegs->IPRH & tccBitMask) != FALSE)
4406 {
4407 /* Transfer completed, bit found SET */
4408 *tccStatus = TRUE;
4410 /* Clear the pending interrupt also. */
4411 shadowRegs->ICRH = tccBitMask;
4412 }
4413 }
4414 }
4415 }
4416 }
4417 }
4420 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4421 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4422 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4423 EDMA3_DVT_dCOUNTER,
4424 EDMA3_DVT_dNONE,
4425 EDMA3_DVT_dNONE));
4426 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4429 return result;
4430 }
4432 EDMA3_RM_Result EDMA3_RM_setPaRAM (EDMA3_RM_Handle hEdmaResMgr,
4433 const EDMA3_RM_ResDesc *lChObj,
4434 const EDMA3_RM_PaRAMRegs *newPaRAM)
4435 {
4436 EDMA3_RM_Result result = EDMA3_RM_SOK;
4437 EDMA3_RM_Instance *rmInstance = NULL;
4438 EDMA3_RM_Obj *rmObj = NULL;
4439 int32_t paRAMId = 0;
4440 uint32_t qdmaChId = 0U;
4441 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4442 uint32_t edma3Id;
4444 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4445 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4446 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4447 EDMA3_DVT_dCOUNTER,
4448 EDMA3_DVT_dNONE,
4449 EDMA3_DVT_dNONE));
4450 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4452 /* If parameter checking is enabled... */
4453 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4454 if (hEdmaResMgr == NULL)
4455 {
4456 result = EDMA3_RM_E_INVALID_PARAM;
4457 }
4459 if ((lChObj == NULL) || (newPaRAM == NULL))
4460 {
4461 result = EDMA3_RM_E_INVALID_PARAM;
4462 }
4463 #endif
4465 /* Check if the parameters are OK. */
4466 if (result == EDMA3_RM_SOK)
4467 {
4468 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4470 if (rmInstance == NULL)
4471 {
4472 result = EDMA3_RM_E_INVALID_PARAM;
4473 }
4474 }
4476 if (result == EDMA3_RM_SOK)
4477 {
4478 rmObj = rmInstance->pResMgrObjHandle;
4480 if (rmObj == NULL)
4481 {
4482 result = EDMA3_RM_E_INVALID_PARAM;
4483 }
4484 else
4485 {
4486 if (rmObj->gblCfgParams.globalRegs == NULL)
4487 {
4488 result = EDMA3_RM_E_INVALID_PARAM;
4489 }
4490 }
4491 }
4493 if (result == EDMA3_RM_SOK)
4494 {
4495 edma3Id = rmObj->phyCtrllerInstId;
4496 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4498 switch (lChObj->type)
4499 {
4500 case EDMA3_RM_RES_DMA_CHANNEL:
4501 {
4502 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4503 {
4504 paRAMId = edma3RmChBoundRes[edma3Id][lChObj->resId].paRAMId;
4505 }
4506 else
4507 {
4508 result = EDMA3_RM_E_INVALID_PARAM;
4509 }
4510 }
4511 break;
4513 case EDMA3_RM_RES_QDMA_CHANNEL:
4514 {
4515 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4516 {
4517 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4518 paRAMId = edma3RmChBoundRes[edma3Id][qdmaChId].paRAMId;
4519 }
4520 else
4521 {
4522 result = EDMA3_RM_E_INVALID_PARAM;
4523 }
4524 }
4525 break;
4527 case EDMA3_RM_RES_PARAM_SET:
4528 {
4529 if (lChObj->resId < edma3NumPaRAMSets)
4530 {
4531 /**
4532 * User has passed the actual param set value here.
4533 * Use this value only
4534 */
4535 paRAMId = (int32_t)(lChObj->resId);
4536 }
4537 else
4538 {
4539 result = EDMA3_RM_E_INVALID_PARAM;
4540 }
4541 }
4542 break;
4544 default:
4545 {
4546 result = EDMA3_RM_E_INVALID_PARAM;
4547 break;
4548 }
4549 }
4550 }
4553 if (result == EDMA3_RM_SOK)
4554 {
4555 /* Check the param id first. */
4556 if ((paRAMId != -1) && ((uint32_t)paRAMId < edma3NumPaRAMSets))
4557 {
4558 /* Set the PaRAM Set now. */
4559 edma3ParamCpy ((volatile void *)(&(globalRegs->PARAMENTRY[paRAMId].OPT)),
4560 (const void *)newPaRAM);
4561 }
4562 else
4563 {
4564 result = EDMA3_RM_E_INVALID_PARAM;
4565 }
4566 }
4569 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4570 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4571 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4572 EDMA3_DVT_dCOUNTER,
4573 EDMA3_DVT_dNONE,
4574 EDMA3_DVT_dNONE));
4575 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4577 return result;
4578 }
4580 EDMA3_RM_Result EDMA3_RM_getPaRAM (EDMA3_RM_Handle hEdmaResMgr,
4581 const EDMA3_RM_ResDesc *lChObj,
4582 EDMA3_RM_PaRAMRegs *currPaRAM)
4583 {
4584 EDMA3_RM_Result result = EDMA3_RM_SOK;
4585 EDMA3_RM_Instance *rmInstance = NULL;
4586 EDMA3_RM_Obj *rmObj = NULL;
4587 int32_t paRAMId = 0;
4588 uint32_t qdmaChId = 0U;
4589 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4590 uint32_t edma3Id;
4592 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4593 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4594 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4595 EDMA3_DVT_dCOUNTER,
4596 EDMA3_DVT_dNONE,
4597 EDMA3_DVT_dNONE));
4598 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4600 /* If parameter checking is enabled... */
4601 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4602 if (hEdmaResMgr == NULL)
4603 {
4604 result = EDMA3_RM_E_INVALID_PARAM;
4605 }
4607 if ((lChObj == NULL) || (currPaRAM == NULL))
4608 {
4609 result = EDMA3_RM_E_INVALID_PARAM;
4610 }
4611 #endif
4613 /* Check if the parameters are OK. */
4614 if (result == EDMA3_RM_SOK)
4615 {
4616 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4618 if (rmInstance == NULL)
4619 {
4620 result = EDMA3_RM_E_INVALID_PARAM;
4621 }
4622 }
4624 if (result == EDMA3_RM_SOK)
4625 {
4626 rmObj = rmInstance->pResMgrObjHandle;
4628 if (rmObj == NULL)
4629 {
4630 result = EDMA3_RM_E_INVALID_PARAM;
4631 }
4632 else
4633 {
4634 if (rmObj->gblCfgParams.globalRegs == NULL)
4635 {
4636 result = EDMA3_RM_E_INVALID_PARAM;
4637 }
4638 }
4639 }
4641 if (result == EDMA3_RM_SOK)
4642 {
4643 edma3Id = rmObj->phyCtrllerInstId;
4644 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4646 switch (lChObj->type)
4647 {
4648 case EDMA3_RM_RES_DMA_CHANNEL:
4649 {
4650 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4651 {
4652 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][lChObj->resId].paRAMId;
4653 }
4654 else
4655 {
4656 result = EDMA3_RM_E_INVALID_PARAM;
4657 }
4658 }
4659 break;
4661 case EDMA3_RM_RES_QDMA_CHANNEL:
4662 {
4663 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4664 {
4665 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4666 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId;
4667 }
4668 else
4669 {
4670 result = EDMA3_RM_E_INVALID_PARAM;
4671 }
4672 }
4673 break;
4675 case EDMA3_RM_RES_PARAM_SET:
4676 {
4677 if (lChObj->resId < edma3NumPaRAMSets)
4678 {
4679 /**
4680 * User has passed the actual param set value here.
4681 * Use this value only
4682 */
4683 paRAMId = (int32_t)(lChObj->resId);
4684 }
4685 else
4686 {
4687 result = EDMA3_RM_E_INVALID_PARAM;
4688 }
4689 }
4690 break;
4692 default:
4693 {
4694 result = EDMA3_RM_E_INVALID_PARAM;
4695 break;
4696 }
4697 }
4698 }
4701 if (result == EDMA3_RM_SOK)
4702 {
4703 /* Check the param id first. */
4704 if ((paRAMId != -1) && ((uint32_t)paRAMId < edma3NumPaRAMSets))
4705 {
4706 /* Get the PaRAM Set now. */
4707 edma3ParamCpy ((void *)currPaRAM ,
4708 (const volatile void *)(&(globalRegs->PARAMENTRY [paRAMId].OPT)));
4709 }
4710 else
4711 {
4712 result = EDMA3_RM_E_INVALID_PARAM;
4713 }
4714 }
4717 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4718 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4719 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4720 EDMA3_DVT_dCOUNTER,
4721 EDMA3_DVT_dNONE,
4722 EDMA3_DVT_dNONE));
4723 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4726 return result;
4727 }
4729 EDMA3_RM_Result EDMA3_RM_getPaRAMPhyAddr(EDMA3_RM_Handle hEdmaResMgr,
4730 const EDMA3_RM_ResDesc *lChObj,
4731 uint32_t *paramPhyAddr)
4732 {
4733 EDMA3_RM_Result result = EDMA3_RM_SOK;
4734 EDMA3_RM_Instance *rmInstance = NULL;
4735 EDMA3_RM_Obj *rmObj = NULL;
4736 int32_t paRAMId = 0;
4737 uint32_t qdmaChId = 0U;
4738 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4739 uint32_t edma3Id;
4741 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4742 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4743 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4744 EDMA3_DVT_dCOUNTER,
4745 EDMA3_DVT_dNONE,
4746 EDMA3_DVT_dNONE));
4747 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4750 /* If parameter checking is enabled... */
4751 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4752 if (hEdmaResMgr == NULL)
4753 {
4754 result = EDMA3_RM_E_INVALID_PARAM;
4755 }
4757 if ((lChObj == NULL) || (paramPhyAddr == NULL))
4758 {
4759 result = EDMA3_RM_E_INVALID_PARAM;
4760 }
4761 #endif
4763 if (result == EDMA3_RM_SOK)
4764 {
4765 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4767 if (rmInstance == NULL)
4768 {
4769 result = EDMA3_RM_E_INVALID_PARAM;
4770 }
4771 }
4773 if (result == EDMA3_RM_SOK)
4774 {
4775 rmObj = rmInstance->pResMgrObjHandle;
4777 if (rmObj == NULL)
4778 {
4779 result = EDMA3_RM_E_INVALID_PARAM;
4780 }
4781 else
4782 {
4783 if (rmObj->gblCfgParams.globalRegs == NULL)
4784 {
4785 result = EDMA3_RM_E_INVALID_PARAM;
4786 }
4787 }
4788 }
4790 if (result == EDMA3_RM_SOK)
4791 {
4792 edma3Id = rmObj->phyCtrllerInstId;
4793 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4795 switch (lChObj->type)
4796 {
4797 case EDMA3_RM_RES_DMA_CHANNEL:
4798 {
4799 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4800 {
4801 paRAMId = edma3RmChBoundRes[edma3Id][lChObj->resId].paRAMId;
4802 }
4803 else
4804 {
4805 result = EDMA3_RM_E_INVALID_PARAM;
4806 }
4807 }
4808 break;
4810 case EDMA3_RM_RES_QDMA_CHANNEL:
4811 {
4812 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4813 {
4814 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4815 paRAMId = edma3RmChBoundRes[edma3Id][qdmaChId].paRAMId;
4816 }
4817 else
4818 {
4819 result = EDMA3_RM_E_INVALID_PARAM;
4820 }
4821 }
4822 break;
4824 case EDMA3_RM_RES_PARAM_SET:
4825 {
4826 if (lChObj->resId < edma3NumPaRAMSets)
4827 {
4828 /**
4829 * User has passed the actual param set value here.
4830 * Use this value only
4831 */
4832 paRAMId = (int32_t)(lChObj->resId);
4833 }
4834 else
4835 {
4836 result = EDMA3_RM_E_INVALID_PARAM;
4837 }
4838 }
4839 break;
4841 default:
4842 {
4843 result = EDMA3_RM_E_INVALID_PARAM;
4844 break;
4845 }
4846 }
4847 }
4849 if (result == EDMA3_RM_SOK)
4850 {
4851 /* Check the param id first. */
4852 if ((paRAMId != -1) && (paRAMId < (int32_t)edma3NumPaRAMSets))
4853 {
4854 /* Get the PaRAM Set Address now. */
4855 *paramPhyAddr = (uint32_t)(&(globalRegs->PARAMENTRY [paRAMId].OPT));
4856 }
4857 else
4858 {
4859 result = EDMA3_RM_E_INVALID_PARAM;
4860 }
4861 }
4863 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4864 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4865 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4866 EDMA3_DVT_dCOUNTER,
4867 EDMA3_DVT_dNONE,
4868 EDMA3_DVT_dNONE));
4869 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4871 return result;
4872 }
4874 EDMA3_RM_Result EDMA3_RM_getBaseAddress (EDMA3_RM_Handle hEdmaResMgr,
4875 EDMA3_RM_Cntrlr_PhyAddr controllerId,
4876 uint32_t *phyAddress)
4877 {
4878 EDMA3_RM_Result result = EDMA3_RM_SOK;
4879 EDMA3_RM_Instance *rmInstance = NULL;
4880 EDMA3_RM_Obj *rmObj = NULL;
4882 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4883 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4884 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4885 EDMA3_DVT_dCOUNTER,
4886 EDMA3_DVT_dNONE,
4887 EDMA3_DVT_dNONE));
4888 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4891 /* If parameter checking is enabled... */
4892 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4893 if ((hEdmaResMgr == NULL) || (phyAddress == NULL))
4894 {
4895 result = EDMA3_RM_E_INVALID_PARAM;
4896 }
4897 #endif
4899 if (result == EDMA3_RM_SOK)
4900 {
4901 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4903 if (rmInstance == NULL)
4904 {
4905 result = EDMA3_RM_E_INVALID_PARAM;
4906 }
4907 }
4909 if (result == EDMA3_RM_SOK)
4910 {
4911 rmObj = rmInstance->pResMgrObjHandle;
4913 if (rmObj == NULL)
4914 {
4915 result = EDMA3_RM_E_INVALID_PARAM;
4916 }
4917 }
4919 if (result == EDMA3_RM_SOK)
4920 {
4921 /* If parameter checking is enabled... */
4922 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4923 /* Verify the 'controllerId' */
4924 if (((int32_t)controllerId < (int32_t)((EDMA3_RM_Cntrlr_PhyAddr)(EDMA3_RM_CC_PHY_ADDR)))
4925 || (controllerId > (EDMA3_RM_Cntrlr_PhyAddr)(rmObj->gblCfgParams.numTcs)))
4926 {
4927 /* Invalid controllerId */
4928 result = EDMA3_RM_E_INVALID_PARAM;
4929 }
4930 #endif
4932 /* Check if the parameters are OK. */
4933 if (EDMA3_RM_SOK == result)
4934 {
4935 if (controllerId == EDMA3_RM_CC_PHY_ADDR)
4936 {
4937 /* EDMA3 Channel Controller Address */
4938 *phyAddress = (uint32_t)(rmObj->gblCfgParams.globalRegs);
4939 }
4940 else
4941 {
4942 /**
4943 * Since the TCs enum start from 1, and TCs start from 0,
4944 * subtract 1 from the enum to get the actual address.
4945 */
4946 *phyAddress = (uint32_t)(rmObj->gblCfgParams.tcRegs[controllerId-1U]);
4947 }
4948 }
4949 }
4951 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4952 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4953 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4954 EDMA3_DVT_dCOUNTER,
4955 EDMA3_DVT_dNONE,
4956 EDMA3_DVT_dNONE));
4957 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4959 return result;
4960 }
4962 EDMA3_RM_Result EDMA3_RM_getGblConfigParams (
4963 uint32_t phyCtrllerInstId,
4964 EDMA3_RM_GblConfigParams *gblCfgParams)
4965 {
4966 EDMA3_RM_Result result = EDMA3_RM_SOK;
4968 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4969 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4970 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4971 EDMA3_DVT_dCOUNTER,
4972 EDMA3_DVT_dNONE,
4973 EDMA3_DVT_dNONE));
4974 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4976 /* If parameter checking is enabled... */
4977 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4978 if ((phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
4979 || (NULL == gblCfgParams))
4980 {
4981 result = EDMA3_RM_E_INVALID_PARAM;
4982 }
4983 #endif
4985 if (EDMA3_RM_SOK == result)
4986 {
4987 /* Return the previously saved global config information for the EDMA3 HW */
4988 edma3MemCpy((void *)(gblCfgParams),
4989 (const void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
4990 sizeof (EDMA3_RM_GblConfigParams));
4991 }
4993 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4994 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4995 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4996 EDMA3_DVT_dCOUNTER,
4997 EDMA3_DVT_dNONE,
4998 EDMA3_DVT_dNONE));
4999 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5001 return result;
5002 }
5004 EDMA3_RM_Result EDMA3_RM_getInstanceInitCfg (
5005 EDMA3_RM_Handle hEdmaResMgr,
5006 EDMA3_RM_InstanceInitConfig *instanceInitConfig)
5007 {
5008 EDMA3_RM_Result result = EDMA3_RM_SOK;
5009 EDMA3_RM_Instance *rmInstance = NULL;
5010 EDMA3_RM_Obj *rmObj = NULL;
5011 uint32_t resMgrIdx = 0U;
5012 uint32_t hwId;
5014 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5015 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5016 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
5017 EDMA3_DVT_dCOUNTER,
5018 EDMA3_DVT_dNONE,
5019 EDMA3_DVT_dNONE));
5020 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5022 /* If parameter checking is enabled... */
5023 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5024 if ((hEdmaResMgr == NULL) || (instanceInitConfig == NULL))
5025 {
5026 result = EDMA3_RM_E_INVALID_PARAM;
5027 }
5028 #endif
5030 if (result == EDMA3_RM_SOK)
5031 {
5032 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
5034 if (rmInstance == NULL)
5035 {
5036 result = EDMA3_RM_E_INVALID_PARAM;
5037 }
5038 }
5040 if (result == EDMA3_RM_SOK)
5041 {
5042 rmObj = rmInstance->pResMgrObjHandle;
5044 if (rmObj == NULL)
5045 {
5046 result = EDMA3_RM_E_INVALID_PARAM;
5047 }
5048 }
5050 if (result == EDMA3_RM_SOK)
5051 {
5052 hwId = rmObj->phyCtrllerInstId;
5054 for (resMgrIdx = 0U; resMgrIdx < EDMA3_MAX_RM_INSTANCES; resMgrIdx++)
5055 {
5056 if (rmInstance == ((EDMA3_RM_Instance *)(ptrRMIArray) +
5057 (hwId*EDMA3_MAX_RM_INSTANCES) +
5058 resMgrIdx))
5059 {
5060 /* RM Id found. Return the specific config info to the user. */
5061 edma3MemCpy((void *)(instanceInitConfig),
5062 (const void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) +
5063 (hwId*EDMA3_MAX_RM_INSTANCES) +
5064 resMgrIdx),
5065 sizeof (EDMA3_RM_InstanceInitConfig));
5066 break;
5067 }
5068 }
5070 if (EDMA3_MAX_RM_INSTANCES == resMgrIdx)
5071 {
5072 /* RM Id not found, report error... */
5073 result = EDMA3_RM_E_INVALID_PARAM;
5074 }
5075 }
5077 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5078 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5079 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5080 EDMA3_DVT_dCOUNTER,
5081 EDMA3_DVT_dNONE,
5082 EDMA3_DVT_dNONE));
5083 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5085 return result;
5086 }
5088 EDMA3_RM_Result EDMA3_RM_Ioctl(
5089 EDMA3_RM_Handle hEdmaResMgr,
5090 EDMA3_RM_IoctlCmd cmd,
5091 void *cmdArg,
5092 void *param
5093 )
5094 {
5095 EDMA3_RM_Result result = EDMA3_RM_SOK;
5096 EDMA3_RM_Instance *rmInstance = NULL;
5097 uint32_t paramInitRequired = 0xFFU;
5098 uint32_t regModificationRequired = 0xFFU;
5099 uint32_t *ret_val = NULL;
5101 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5102 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5103 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
5104 EDMA3_DVT_dCOUNTER,
5105 EDMA3_DVT_dNONE,
5106 EDMA3_DVT_dNONE));
5107 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5109 /* If parameter checking is enabled... */
5110 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5111 if (hEdmaResMgr == NULL)
5112 {
5113 result = EDMA3_RM_E_INVALID_PARAM;
5114 }
5116 if ((cmd <= EDMA3_RM_IOCTL_MIN_IOCTL)
5117 || (cmd >= EDMA3_RM_IOCTL_MAX_IOCTL))
5118 {
5119 result = EDMA3_RM_E_INVALID_PARAM;
5120 }
5121 #endif
5123 if (result == EDMA3_RM_SOK)
5124 {
5125 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
5127 if (rmInstance == NULL)
5128 {
5129 result = EDMA3_RM_E_INVALID_PARAM;
5130 }
5131 }
5133 if (result == EDMA3_RM_SOK)
5134 {
5135 switch (cmd)
5136 {
5137 case EDMA3_RM_IOCTL_SET_PARAM_CLEAR_OPTION:
5138 {
5139 paramInitRequired = (uint32_t)cmdArg;
5141 /* If parameter checking is enabled... */
5142 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5143 if ((paramInitRequired != 0U)
5144 && (paramInitRequired != 1U))
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 /* Set/Reset the flag which is being used to do the PaRAM clearing. */
5154 rmInstance->paramInitRequired = paramInitRequired;
5155 }
5157 break;
5158 }
5160 case EDMA3_RM_IOCTL_GET_PARAM_CLEAR_OPTION:
5161 {
5162 /* If parameter checking is enabled... */
5163 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5164 if (NULL == cmdArg)
5165 {
5166 result = EDMA3_RM_E_INVALID_PARAM;
5167 }
5168 #endif
5170 /* Check if the parameters are OK. */
5171 if (EDMA3_RM_SOK == result)
5172 {
5173 ret_val = (uint32_t *)cmdArg;
5175 /* Get the flag which is being used to do the PaRAM clearing. */
5176 *ret_val = rmInstance->paramInitRequired;
5177 }
5179 break;
5180 }
5182 case EDMA3_RM_IOCTL_SET_GBL_REG_MODIFY_OPTION:
5183 {
5184 regModificationRequired = (uint32_t)cmdArg;
5186 /* If parameter checking is enabled... */
5187 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5188 if ((regModificationRequired != 0U)
5189 && (regModificationRequired != 1U))
5190 {
5191 /* All other values are invalid. */
5192 result = EDMA3_RM_E_INVALID_PARAM;
5193 }
5194 #endif
5196 /* Check if the parameters are OK. */
5197 if (EDMA3_RM_SOK == result)
5198 {
5199 /**
5200 * Set/Reset the flag which is being used to do the global
5201 * registers and PaRAM modification.
5202 */
5203 rmInstance->regModificationRequired = regModificationRequired;
5204 }
5206 break;
5207 }
5209 case EDMA3_RM_IOCTL_GET_GBL_REG_MODIFY_OPTION:
5210 {
5211 /* If parameter checking is enabled... */
5212 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5213 if (NULL == cmdArg)
5214 {
5215 result = EDMA3_RM_E_INVALID_PARAM;
5216 }
5217 #endif
5219 /* Check if the parameters are OK. */
5220 if (EDMA3_RM_SOK == result)
5221 {
5222 ret_val = (uint32_t *)cmdArg;
5224 /**
5225 * Get the flag which is being used to do the global
5226 * registers and PaRAM modification.
5227 */
5228 *ret_val = rmInstance->regModificationRequired;
5229 }
5231 break;
5232 }
5234 default:
5235 {
5236 /* Hey dude! you passed invalid IOCTL cmd */
5237 result = EDMA3_RM_E_INVALID_PARAM;
5238 break;
5239 }
5241 }
5242 }
5245 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5246 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5247 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5248 EDMA3_DVT_dCOUNTER,
5249 EDMA3_DVT_dNONE,
5250 EDMA3_DVT_dNONE));
5251 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5253 return result;
5255 }
5257 /**
5258 * edma3ComplHandler
5259 * \brief Interrupt handler for successful transfer completion.
5260 *
5261 * \note This function first disables its own interrupt to make it non-
5262 * entrant. Later, after calling all the callback functions, it
5263 * re-enables its own interrupt.
5264 *
5265 * \return None.
5266 */
5267 static void edma3ComplHandler (const EDMA3_RM_Obj *rmObj)
5268 {
5269 uint32_t Cnt;
5270 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
5271 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
5272 volatile uint32_t pendingIrqs;
5273 volatile uint32_t isIPR = 0;
5275 uint32_t indexl;
5276 uint32_t indexh;
5277 uint32_t edma3Id;
5278 uint32_t numTCCs;
5280 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5281 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5282 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5283 EDMA3_DVT_dNONE,
5284 EDMA3_DVT_dNONE,
5285 EDMA3_DVT_dNONE));
5286 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5288 assert (NULL != rmObj);
5290 edma3Id = rmObj->phyCtrllerInstId;
5291 numTCCs = rmObj->gblCfgParams.numTccs;
5292 ptrEdmaccRegs =
5293 (volatile EDMA3_CCRL_Regs *)rmObj->gblCfgParams.globalRegs;
5294 if (ptrEdmaccRegs != NULL)
5295 {
5296 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
5297 (&ptrEdmaccRegs->SHADOW[edma3RegionId]);
5298 }
5300 Cnt = 0U;
5301 pendingIrqs = 0U;
5302 indexl = 1U;
5303 indexh = 1U;
5305 if(shadowRegs != NULL)
5306 {
5307 if (numTCCs > 32U)
5308 {
5309 isIPR = shadowRegs->IPR | shadowRegs->IPRH;
5310 }
5311 else
5312 {
5313 isIPR = shadowRegs->IPR;
5314 }
5316 if(isIPR)
5317 {
5318 /**
5319 * Since an interrupt has found, we have to make sure that this
5320 * interrupt (TCC) belongs to the TCCs allocated by us only.
5321 * It might happen that someone else, who is using EDMA3 also,
5322 * is the owner of this interrupt channel i.e. the TCC.
5323 * For this, use the allocatedTCCs[], to check which all interrupt
5324 * channels are owned by the EDMA3 RM Instances.
5325 */
5327 edma3OsProtectEntry (edma3Id,
5328 (int32_t)EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,
5329 NULL);
5331 /* Loop for EDMA3_RM_COMPL_HANDLER_RETRY_COUNT number of time,
5332 breaks when no pending interrupt is found */
5333 while ((Cnt < EDMA3_RM_COMPL_HANDLER_RETRY_COUNT)
5334 && ((indexl != 0U) || (indexh != 0U)))
5335 {
5336 indexl = 0U;
5337 pendingIrqs = shadowRegs->IPR;
5339 /**
5340 * Choose interrupts coming from our allocated TCCs
5341 * and MASK remaining ones.
5342 */
5343 pendingIrqs = (pendingIrqs & allocatedTCCs[edma3Id][0U]);
5345 while (pendingIrqs)
5346 {
5347 /*Process all the pending interrupts*/
5348 if((pendingIrqs & 1U) == TRUE)
5349 {
5350 /**
5351 * If the user has not given any callback function
5352 * while requesting the TCC, its TCC specific bit
5353 * in the IPR register will NOT be cleared.
5354 */
5355 if(edma3IntrParams[edma3Id][indexl].tccCb != NULL)
5356 {
5357 /* here write to ICR to clear the corresponding IPR bits*/
5358 shadowRegs->ICR = (1U << indexl);
5360 edma3IntrParams[edma3Id][indexl].tccCb (indexl,
5361 EDMA3_RM_XFER_COMPLETE,
5362 edma3IntrParams[edma3Id][indexl].cbData);
5363 }
5364 }
5365 ++indexl;
5366 pendingIrqs >>= 1U;
5367 }
5369 if(numTCCs > 32U)
5370 {
5371 indexh = 0U;
5372 pendingIrqs = shadowRegs->IPRH;
5374 /**
5375 * Choose interrupts coming from our allocated TCCs
5376 * and MASK remaining ones.
5377 */
5378 pendingIrqs = (pendingIrqs & allocatedTCCs[edma3Id][1U]);
5380 while (pendingIrqs)
5381 {
5382 /*Process all the pending interrupts*/
5383 if((pendingIrqs & 1U)==TRUE)
5384 {
5385 /**
5386 * If the user has not given any callback function
5387 * while requesting the TCC, its TCC specific bit
5388 * in the IPRH register will NOT be cleared.
5389 */
5390 if(edma3IntrParams[edma3Id][32U+indexh].tccCb!=NULL)
5391 {
5392 /* here write to ICR to clear the corresponding IPR bits*/
5393 shadowRegs->ICRH = (1U << indexh);
5395 edma3IntrParams[edma3Id][32U+indexh].tccCb(32U+indexh,
5396 EDMA3_RM_XFER_COMPLETE,
5397 edma3IntrParams[edma3Id][32U+indexh].cbData);
5398 }
5399 }
5400 ++indexh;
5401 pendingIrqs >>= 1U;
5402 }
5403 }
5405 Cnt++;
5406 }
5408 indexl = (shadowRegs->IPR & allocatedTCCs[edma3Id][0U]);
5409 if (numTCCs > 32U)
5410 {
5411 indexh = (shadowRegs->IPRH & allocatedTCCs[edma3Id][1U]);
5412 }
5414 if((indexl !=0 ) || (indexh !=0 ))
5415 {
5416 shadowRegs->IEVAL=0x1U;
5417 }
5419 edma3OsProtectExit (rmObj->phyCtrllerInstId,
5420 (int32_t)EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,
5421 0);
5422 }
5423 }
5425 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5426 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5427 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5428 EDMA3_DVT_dNONE,
5429 EDMA3_DVT_dNONE,
5430 EDMA3_DVT_dNONE));
5431 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5432 }
5435 void lisrEdma3ComplHandler0(uint32_t edma3InstanceId)
5436 {
5437 /* Invoke Completion Handler ISR */
5438 edma3ComplHandler(&resMgrObj[edma3InstanceId]);
5439 }
5442 /**
5443 * \brief Interrupt handler for Channel Controller Error.
5444 *
5445 * \note This function first disables its own interrupt to make it non-
5446 * entrant. Later, after calling all the callback functions, it
5447 * re-enables its own interrupt.
5448 *
5449 * \return None.
5450 */
5451 static void edma3CCErrHandler(const EDMA3_RM_Obj *rmObj)
5452 {
5453 uint32_t Cnt = 0U;
5454 uint32_t resMgrInstIdx = 0U;
5455 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
5456 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
5457 volatile uint32_t pendingIrqs = 0;
5458 uint32_t index;
5459 uint32_t evtqueNum;
5460 EDMA3_RM_Instance *rm_instance = NULL;
5461 uint32_t edma3Id;
5462 uint32_t num_rm_instances_opened;
5463 EDMA3_RM_Instance *rmInstance = NULL;
5464 uint32_t ownedDmaError = 0;
5465 uint32_t ownedDmaHError = 0;
5466 uint32_t ownedQdmaError = 0;
5467 uint32_t numTCCs;
5469 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5470 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_CCERR",
5471 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5472 EDMA3_DVT_dNONE,
5473 EDMA3_DVT_dNONE,
5474 EDMA3_DVT_dNONE));
5475 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5477 assert (rmObj != NULL);
5479 edma3Id = rmObj->phyCtrllerInstId;
5480 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)rmObj->gblCfgParams.globalRegs;
5481 numTCCs = rmObj->gblCfgParams.numTccs;
5482 if (ptrEdmaccRegs != NULL)
5483 {
5484 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)&ptrEdmaccRegs->SHADOW[edma3RegionId];
5485 rmInstance = ((EDMA3_RM_Instance *)(ptrRMIArray)
5486 + (edma3Id*EDMA3_MAX_RM_INSTANCES)
5487 + edma3RegionId);
5489 if((ptrEdmaccRegs->EMR != 0 )
5490 || (ptrEdmaccRegs->QEMR != 0)
5491 || (ptrEdmaccRegs->CCERR != 0))
5492 {
5493 pendingIrqs = 1U;
5494 }
5495 if (numTCCs > 32U)
5496 {
5497 if((pendingIrqs != 0) || (ptrEdmaccRegs->EMRH != 0))
5498 {
5499 pendingIrqs = 1U;
5500 }
5501 }
5502 index = 1U;
5504 if(pendingIrqs)
5505 {
5506 edma3OsProtectEntry (edma3Id,
5507 (int32_t)EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR,
5508 NULL);
5510 /* Loop for EDMA3_RM_CCERR_HANDLER_RETRY_COUNT number of time,
5511 breaks when no pending interrupt is found */
5512 while ((Cnt < EDMA3_RM_CCERR_HANDLER_RETRY_COUNT)
5513 && (index != 0U))
5514 {
5515 index = 0U;
5516 pendingIrqs = ptrEdmaccRegs->EMR;
5518 while (pendingIrqs)
5519 {
5520 /*Process all the pending interrupts*/
5521 if((pendingIrqs & 1U)==TRUE)
5522 {
5523 uint32_t mappedTcc = 0U;
5525 /**
5526 * Using the 'index' value (basically the DMA
5527 * channel), fetch the corresponding TCC
5528 * value, mapped to this DMA channel.
5529 */
5530 mappedTcc = edma3DmaChTccMapping[edma3Id][index];
5532 /**
5533 * Ensure that the mapped tcc is valid and the call
5534 * back is not NULL
5535 */
5536 if (mappedTcc < EDMA3_MAX_TCC)
5537 {
5538 /**
5539 * TCC owned and allocated by RM.
5540 * Write to EMCR to clear the corresponding EMR bits.
5541 */
5542 ptrEdmaccRegs->EMCR = (1U<<index);
5543 /*Clear any SER*/
5544 shadowRegs->SECR = (1U<<index);
5546 /* Call the callback function if registered earlier. */
5547 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5548 {
5549 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5550 mappedTcc,
5551 EDMA3_RM_E_CC_DMA_EVT_MISS,
5552 edma3IntrParams[edma3Id][mappedTcc].cbData
5553 );
5554 }
5555 }
5556 else
5557 {
5558 /**
5559 * DMA channel not owned by the RM instance.
5560 * Check the global error interrupt clearing option.
5561 * If it is TRUE, clear the error interupt else leave
5562 * it like that.
5563 */
5564 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5565 /* here write to EMCR to clear the corresponding EMR bits. */
5566 ptrEdmaccRegs->EMCR = (1U<<index);
5567 /*Clear any SER*/
5568 ptrEdmaccRegs->SECR = (1U<<index);
5569 #endif
5570 }
5571 }
5572 ++index;
5573 pendingIrqs >>= 1U;
5574 }
5576 if(numTCCs > 32U)
5577 {
5578 index = 0U;
5579 pendingIrqs = ptrEdmaccRegs->EMRH;
5580 while (pendingIrqs)
5581 {
5582 /*Process all the pending interrupts*/
5583 if((pendingIrqs & 1U)==TRUE)
5584 {
5585 uint32_t mappedTcc = 0U;
5587 /**
5588 * Using the 'index' value (basically the DMA
5589 * channel), fetch the corresponding TCC
5590 * value, mapped to this DMA channel.
5591 */
5592 mappedTcc = edma3DmaChTccMapping[edma3Id][32U+index];
5594 /**
5595 * Ensure that the mapped tcc is valid and the call
5596 * back is not NULL
5597 */
5598 if (mappedTcc < EDMA3_MAX_TCC)
5599 {
5600 /**
5601 * TCC owned and allocated by RM.
5602 * Write to EMCR to clear the corresponding EMR bits.
5603 */
5604 ptrEdmaccRegs->EMCRH = (1U<<index);
5605 /*Clear any SERH*/
5606 shadowRegs->SECRH = (1U<<index);
5608 /* Call the callback function if registered earlier. */
5609 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5610 {
5611 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5612 mappedTcc,
5613 EDMA3_RM_E_CC_DMA_EVT_MISS,
5614 edma3IntrParams[edma3Id][mappedTcc].cbData
5615 );
5616 }
5617 }
5618 else
5619 {
5620 /**
5621 * DMA channel not owned by the RM instance.
5622 * Check the global error interrupt clearing option.
5623 * If it is TRUE, clear the error interupt else leave
5624 * it like that.
5625 */
5626 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5627 /**
5628 * TCC NOT owned by RM.
5629 * Write to EMCRH to clear the corresponding EMRH bits.
5630 */
5631 ptrEdmaccRegs->EMCRH = (1U<<index);
5632 /*Clear any SERH*/
5633 shadowRegs->SECRH = (1U<<index);
5634 #endif
5635 }
5636 }
5637 ++index;
5638 pendingIrqs >>= 1U;
5639 }
5640 }
5642 index = 0U;
5643 pendingIrqs = ptrEdmaccRegs->QEMR;
5644 while (pendingIrqs)
5645 {
5646 /*Process all the pending interrupts*/
5647 if((pendingIrqs & 1U)==TRUE)
5648 {
5649 uint32_t mappedTcc = 0U;
5651 /**
5652 * Using the 'index' value (basically the QDMA
5653 * channel), fetch the corresponding TCC
5654 * value, mapped to this QDMA channel.
5655 */
5656 mappedTcc = edma3QdmaChTccMapping[edma3Id][index];
5658 if (mappedTcc < EDMA3_MAX_TCC)
5659 {
5660 /* here write to QEMCR to clear the corresponding QEMR bits*/
5661 ptrEdmaccRegs->QEMCR = (1U<<index);
5662 /*Clear any QSER*/
5663 shadowRegs->QSECR = (1U<<index);
5665 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5666 {
5667 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5668 mappedTcc,
5669 EDMA3_RM_E_CC_QDMA_EVT_MISS,
5670 edma3IntrParams[edma3Id][mappedTcc].cbData
5671 );
5672 }
5673 }
5674 else
5675 {
5676 /**
5677 * QDMA channel not owned by the RM instance.
5678 * Check the global error interrupt clearing option.
5679 * If it is TRUE, clear the error interupt else leave
5680 * the ISR.
5681 */
5682 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5683 /* here write to QEMCR to clear the corresponding QEMR bits*/
5684 ptrEdmaccRegs->QEMCR = (1U<<index);
5686 /*Clear any QSER*/
5687 ptrEdmaccRegs->QSECR = (1U<<index);
5688 #endif
5689 }
5690 }
5691 ++index;
5692 pendingIrqs >>= 1U;
5693 }
5695 index = 0U;
5696 pendingIrqs = ptrEdmaccRegs->CCERR;
5697 if (pendingIrqs!=0)
5698 {
5699 /* Process all the pending CC error interrupts. */
5701 /* Queue threshold error for different event queues.*/
5702 for (evtqueNum = 0U; evtqueNum < rmObj->gblCfgParams.numEvtQueue; evtqueNum++)
5703 {
5704 if((pendingIrqs & ((uint32_t)1U << evtqueNum)) != 0)
5705 {
5706 /**
5707 * Queue threshold error for queue 'evtqueNum' raised.
5708 * Inform all the RM instances working on this region
5709 * about the error by calling their global callback functions.
5710 */
5711 resMgrInstIdx = 0U;
5712 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5713 {
5714 /* Check whether the RM instance opened working on this region */
5715 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5716 if (NULL != rm_instance)
5717 {
5718 if (rm_instance->initParam.regionId == edma3RegionId)
5719 {
5720 /* Region id matches, call the callback function */
5721 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5722 {
5723 rm_instance->initParam.gblerrCbParams.gblerrCb(
5724 EDMA3_RM_E_CC_QUE_THRES_EXCEED,
5725 evtqueNum,
5726 rm_instance->initParam.gblerrCbParams.gblerrData);
5727 }
5728 }
5729 }
5731 ++resMgrInstIdx;
5732 /* Check next opened instance */
5733 }
5735 /* Clear the error interrupt. */
5736 ptrEdmaccRegs->CCERRCLR = (1U << evtqueNum);
5737 }
5738 }
5741 /* Transfer completion code error. */
5742 if ((pendingIrqs & ((uint32_t)1 << EDMA3_CCRL_CCERR_TCCERR_SHIFT))!=0)
5743 {
5744 /**
5745 * Transfer completion code error raised.
5746 * Inform all the RM instances working on this region
5747 * about the error by calling their global callback functions.
5748 */
5750 resMgrInstIdx = 0U;
5751 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5752 {
5753 /* Check whether the RM instance opened working on this region */
5754 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5755 if (NULL != rm_instance)
5756 {
5757 if (rm_instance->initParam.regionId == edma3RegionId)
5758 {
5759 /* Region id matches, call the callback function */
5760 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5761 {
5762 rm_instance->initParam.gblerrCbParams.gblerrCb(
5763 EDMA3_RM_E_CC_TCC,
5764 0,
5765 rm_instance->initParam.gblerrCbParams.gblerrData);
5766 }
5767 }
5768 }
5770 ++resMgrInstIdx;
5771 /* Check next opened instance */
5772 }
5774 ptrEdmaccRegs->CCERRCLR = ((uint32_t)1<<EDMA3_CCRL_CCERR_TCCERR_SHIFT);
5775 }
5777 ++index;
5778 }
5780 Cnt++;
5781 }
5784 /**
5785 * Read the error registers again. If any interrupt is pending,
5786 * write the EEVAL register.
5787 * Moreover, according to the global error interrupt clearing
5788 * option, check either error bits associated with all the
5789 * DMA/QDMA channels (option is SET) OR check error bits
5790 * associated with owned DMA/QDMA channels.
5791 */
5792 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5793 /* To remove warning. */
5794 rmInstance = rmInstance;
5796 /* Check all the error bits. */
5797 ownedDmaError = ptrEdmaccRegs->EMR;
5798 if (numTCCs > 32U)
5799 {
5800 ownedDmaHError = ptrEdmaccRegs->EMRH;
5801 }
5802 ownedQdmaError = ptrEdmaccRegs->QEMR;
5803 #else
5804 /* Check ONLY owned error bits. */
5805 ownedDmaError = (ptrEdmaccRegs->EMR & rmInstance->initParam.rmInstInitConfig->ownDmaChannels[0U]);
5806 if (numTCCs > 32)
5807 ownedDmaHError = (ptrEdmaccRegs->EMRH & rmInstance->initParam.rmInstInitConfig->ownDmaChannels[1U]);
5808 ownedQdmaError = (ptrEdmaccRegs->QEMR & rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0U]);
5809 #endif
5811 if (((ownedDmaError != 0 ) || (ownedDmaHError != 0 ))
5812 || ((ownedQdmaError != 0) || (ptrEdmaccRegs->CCERR != 0)))
5813 {
5814 ptrEdmaccRegs->EEVAL=0x1U;
5815 }
5817 edma3OsProtectExit (rmObj->phyCtrllerInstId,
5818 (int32_t)EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR,
5819 0);
5820 }
5821 }
5823 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5824 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_CCERR",
5825 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5826 EDMA3_DVT_dNONE,
5827 EDMA3_DVT_dNONE,
5828 EDMA3_DVT_dNONE));
5829 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5830 }
5832 void lisrEdma3CCErrHandler0(uint32_t edma3InstanceId)
5833 {
5834 /* Invoke CC Error Handler ISR */
5835 edma3CCErrHandler(&resMgrObj[edma3InstanceId]);
5836 }
5840 /**
5841 * \brief Interrupt handler for Transfer Controller Error.
5842 *
5843 * \note This function first disables its own interrupt to make it non-
5844 * entrant. Later, after calling all the callback functions, it
5845 * re-enables its own interrupt.
5846 *
5847 * \return None.
5848 */
5849 static void edma3TCErrHandler (const EDMA3_RM_Obj *rmObj, uint32_t tcNum)
5850 {
5851 volatile EDMA3_TCRL_Regs *tcRegs = NULL;
5852 uint32_t tcMemErrRdWr = 0U;
5853 uint32_t resMgrInstIdx = 0U;
5854 EDMA3_RM_Instance *rm_instance = NULL;
5855 uint32_t edma3Id;
5856 uint32_t num_rm_instances_opened;
5858 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5859 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_TCERR",
5860 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5861 EDMA3_DVT_dNONE,
5862 EDMA3_DVT_dNONE,
5863 EDMA3_DVT_dNONE));
5864 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5866 assert (rmObj != NULL);
5868 assert (tcNum < rmObj->gblCfgParams.numTcs);
5870 if (rmObj->gblCfgParams.tcRegs[tcNum] != NULL)
5871 {
5872 tcRegs = (volatile EDMA3_TCRL_Regs *)(rmObj->gblCfgParams.tcRegs[tcNum]);
5873 edma3Id = rmObj->phyCtrllerInstId;
5874 }
5876 if (tcRegs != NULL)
5877 {
5878 if(tcRegs->ERRSTAT != 0)
5879 {
5880 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
5881 (int32_t)EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR,
5882 &tcNum);
5884 if((tcRegs->ERRSTAT & ((uint32_t)1 << EDMA3_TCRL_ERRSTAT_BUSERR_SHIFT))!= 0)
5885 {
5886 /* Bus error event. */
5887 /**
5888 * EDMA3TC has detected an error at source or destination
5889 * address. Error information can be read from the error
5890 * details register (ERRDET).
5891 */
5892 tcMemErrRdWr = tcRegs->ERRDET & ((uint32_t)EDMA3_TCRL_ERRDET_STAT_MASK);
5893 if ((tcMemErrRdWr > 0U) && (tcMemErrRdWr < 8U))
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_READ_ERROR,
5913 tcNum,
5914 rm_instance->initParam.gblerrCbParams.gblerrData);
5915 }
5916 }
5917 }
5919 ++resMgrInstIdx;
5920 /* Check next opened instance */
5921 }
5922 }
5923 else
5924 {
5925 if ((tcMemErrRdWr >= 8U) && (tcMemErrRdWr <= 0xFU))
5926 {
5927 /**
5928 * Inform all the RM instances working on this region
5929 * about the error by calling their global callback functions.
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_MEM_LOCATION_WRITE_ERROR,
5945 tcNum,
5946 rm_instance->initParam.gblerrCbParams.gblerrData);
5947 }
5948 }
5949 }
5951 ++resMgrInstIdx;
5952 /* Check next opened instance */
5953 }
5954 }
5955 }
5956 tcRegs->ERRCLR = ((uint32_t)1<<EDMA3_TCRL_ERRSTAT_BUSERR_SHIFT);
5957 }
5958 else
5959 {
5960 /* Transfer request (TR) error event. */
5961 if((tcRegs->ERRSTAT & ((uint32_t)1 << EDMA3_TCRL_ERRSTAT_TRERR_SHIFT))!= 0)
5962 {
5963 resMgrInstIdx = 0U;
5964 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5965 {
5966 /* Check whether the RM instance opened working on this region */
5967 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5968 if (NULL != rm_instance)
5969 {
5970 if (rm_instance->initParam.regionId == edma3RegionId)
5971 {
5972 /* Region id matches, call the callback function */
5973 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5974 {
5975 rm_instance->initParam.gblerrCbParams.gblerrCb(
5976 EDMA3_RM_E_TC_TR_ERROR,
5977 tcNum,
5978 rm_instance->initParam.gblerrCbParams.gblerrData);
5979 }
5980 }
5981 }
5983 ++resMgrInstIdx;
5984 /* Check next opened instance */
5985 }
5987 tcRegs->ERRCLR = ((uint32_t)1<<EDMA3_TCRL_ERRSTAT_TRERR_SHIFT);
5988 }
5989 else
5990 {
5991 if((tcRegs->ERRSTAT & ((uint32_t)1 << EDMA3_TCRL_ERRSTAT_MMRAERR_SHIFT))!= 0)
5992 {
5993 resMgrInstIdx = 0U;
5994 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5995 {
5996 /* Check whether the RM instance opened working on this region */
5997 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5998 if (NULL != rm_instance)
5999 {
6000 if (rm_instance->initParam.regionId == edma3RegionId)
6001 {
6002 /* Region id matches, call the callback function */
6003 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
6004 {
6005 rm_instance->initParam.gblerrCbParams.gblerrCb(
6006 EDMA3_RM_E_TC_INVALID_ADDR,
6007 tcNum,
6008 rm_instance->initParam.gblerrCbParams.gblerrData);
6009 }
6010 }
6011 }
6013 ++resMgrInstIdx;
6014 /* Check next opened instance */
6015 }
6017 tcRegs->ERRCLR = ((uint32_t)1<<EDMA3_TCRL_ERRSTAT_MMRAERR_SHIFT);
6018 }
6019 }
6020 }
6022 edma3OsProtectExit (rmObj->phyCtrllerInstId,
6023 (int32_t)EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR,
6024 tcNum);
6025 }
6026 }
6028 #ifdef EDMA3_INSTRUMENTATION_ENABLED
6029 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_TCERR",
6030 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
6031 EDMA3_DVT_dNONE,
6032 EDMA3_DVT_dNONE,
6033 EDMA3_DVT_dNONE));
6034 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
6035 }
6039 /*
6040 * ======== lisrEdma3TC0ErrHandler0 ========
6041 * EDMA3 instance 0 TC0 Error Interrupt Service Routine
6042 */
6043 void lisrEdma3TC0ErrHandler0(uint32_t edma3InstanceId)
6044 {
6045 /* Invoke Error Handler ISR for TC0*/
6046 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)0U);
6047 }
6050 /*
6051 * ======== lisrEdma3TC1ErrHandler0 ========
6052 * EDMA3 instance 0 TC1 Error Interrupt Service Routine
6053 */
6054 void lisrEdma3TC1ErrHandler0(uint32_t edma3InstanceId)
6055 {
6056 /* Invoke Error Handler ISR for TC1*/
6057 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)1U);
6058 }
6060 /*
6061 * ======== lisrEdma3TC2ErrHandler0 ========
6062 * EDMA3 instance 0 TC2 Error Interrupt Service Routine
6063 */
6064 void lisrEdma3TC2ErrHandler0(uint32_t edma3InstanceId)
6065 {
6066 /* Invoke Error Handler ISR for TC2*/
6067 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)2U);
6068 }
6070 /*
6071 * ======== lisrEdma3TC3ErrHandler0 ========
6072 * EDMA3 instance 0 TC3 Error Interrupt Service Routine
6073 */
6074 void lisrEdma3TC3ErrHandler0(uint32_t edma3InstanceId)
6075 {
6076 /* Invoke Error Handler ISR for TC3*/
6077 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)3U);
6078 }
6080 /*
6081 * ======== lisrEdma3TC4ErrHandler0 ========
6082 * EDMA3 instance 0 TC4 Error Interrupt Service Routine
6083 */
6084 void lisrEdma3TC4ErrHandler0(uint32_t edma3InstanceId)
6085 {
6086 /* Invoke Error Handler ISR for TC4*/
6087 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)4U);
6088 }
6091 /*
6092 * ======== lisrEdma3TC5ErrHandler0 ========
6093 * EDMA3 instance 0 TC5 Error Interrupt Service Routine
6094 */
6095 void lisrEdma3TC5ErrHandler0(uint32_t edma3InstanceId)
6096 {
6097 /* Invoke Error Handler ISR for TC5*/
6098 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)5U);
6099 }
6101 /*
6102 * ======== lisrEdma3TC6ErrHandler0 ========
6103 * EDMA3 instance 0 TC6 Error Interrupt Service Routine
6104 */
6105 /* ARGSUSED */
6106 void lisrEdma3TC6ErrHandler0(uint32_t edma3InstanceId)
6107 {
6108 /* Invoke Error Handler ISR for TC6*/
6109 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)6U);
6110 }
6112 /*
6113 * ======== lisrEdma3TC7ErrHandler0 ========
6114 * EDMA3 instance 0 TC7 Error Interrupt Service Routine
6115 */
6116 void lisrEdma3TC7ErrHandler0(uint32_t edma3InstanceId)
6117 {
6118 /* Invoke Error Handler ISR for TC7*/
6119 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)7U);
6120 }
6124 /* Resource Manager Internal functions - Start */
6126 /** Initialization of the Global region registers of the EDMA3 Controller */
6127 static void edma3GlobalRegionInit (uint32_t phyCtrllerInstId, uint32_t numDmaChannels)
6128 {
6129 uint32_t evtQNum = 0U;
6130 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
6132 assert (phyCtrllerInstId < EDMA3_MAX_EDMA3_INSTANCES);
6134 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)
6135 (resMgrObj[phyCtrllerInstId].gblCfgParams.globalRegs);
6137 if (ptrEdmaccRegs != NULL)
6138 {
6139 ptrEdmaccRegs->EMCR = EDMA3_RM_SET_ALL_BITS;
6140 if ( numDmaChannels > 32U)
6141 {
6142 /* Clear the EMCRH only if available channels are more than 32 */
6143 ptrEdmaccRegs->EMCRH = EDMA3_RM_SET_ALL_BITS;
6144 }
6145 ptrEdmaccRegs->QEMCR = EDMA3_RM_SET_ALL_BITS;
6147 /*
6148 * Set all Instance-wide EDMA3 parameters (not channel-specific)
6149 */
6151 /**
6152 * Set TC Priority among system-wide bus-masters and Queue
6153 * Watermark Level
6154 */
6155 while (evtQNum <
6156 resMgrObj[phyCtrllerInstId].gblCfgParams.numEvtQueue)
6157 {
6158 ptrEdmaccRegs->QUEPRI &= EDMA3_RM_QUEPRI_CLR_MASK(evtQNum);
6159 ptrEdmaccRegs->QUEPRI |= EDMA3_RM_QUEPRI_SET_MASK(evtQNum,
6160 resMgrObj[phyCtrllerInstId].gblCfgParams.evtQPri[evtQNum]);
6162 ptrEdmaccRegs->QWMTHRA |= EDMA3_RM_QUEWMTHR_SET_MASK(evtQNum,
6163 resMgrObj[phyCtrllerInstId].gblCfgParams.evtQueueWaterMarkLvl[evtQNum]);
6165 evtQNum++;
6166 }
6168 /* Clear CCERR register */
6169 ptrEdmaccRegs ->CCERRCLR = 0xFFFFU;
6170 }
6172 return;
6173 }
6178 /** Initialization of the Shadow region registers of the EDMA3 Controller */
6179 static void edma3ShadowRegionInit (const EDMA3_RM_Instance *pRMInstance)
6180 {
6181 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
6182 volatile EDMA3_CCRL_ShadowRegs *ptrEdmaShadowRegs = NULL;
6183 uint32_t phyCtrllerInstId;
6184 uint32_t regionId;
6185 const EDMA3_RM_InstanceInitConfig *rmInstInitConfig = NULL;
6187 assert (pRMInstance != NULL);
6189 rmInstInitConfig = pRMInstance->initParam.rmInstInitConfig;
6191 if (rmInstInitConfig != NULL)
6192 {
6193 phyCtrllerInstId = pRMInstance->pResMgrObjHandle->phyCtrllerInstId;
6194 regionId = pRMInstance->initParam.regionId;
6196 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)
6197 (resMgrObj[phyCtrllerInstId].gblCfgParams.globalRegs);
6199 if (ptrEdmaccRegs != NULL)
6200 {
6201 ptrEdmaShadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
6202 (&ptrEdmaccRegs->SHADOW[regionId]);
6204 ptrEdmaShadowRegs->ECR = (rmInstInitConfig->ownDmaChannels[0U]
6205 | rmInstInitConfig->ownTccs[0U]);
6206 ptrEdmaShadowRegs->ECRH = (rmInstInitConfig->ownDmaChannels[1U]
6207 | rmInstInitConfig->ownTccs[1U]);
6208 ptrEdmaShadowRegs->EECR = (rmInstInitConfig->ownDmaChannels[0U]
6209 | rmInstInitConfig->ownTccs[0U]);
6210 ptrEdmaShadowRegs->SECR = (rmInstInitConfig->ownDmaChannels[0U]
6211 | rmInstInitConfig->ownTccs[0U]);
6212 ptrEdmaShadowRegs->SECRH = (rmInstInitConfig->ownDmaChannels[1U]
6213 | rmInstInitConfig->ownTccs[1U]);
6214 ptrEdmaShadowRegs->EECR = (rmInstInitConfig->ownDmaChannels[0U]
6215 | rmInstInitConfig->ownTccs[0U]);
6216 ptrEdmaShadowRegs->EECRH = (rmInstInitConfig->ownDmaChannels[1U]
6217 | rmInstInitConfig->ownTccs[1U]);
6219 ptrEdmaShadowRegs->QEECR = rmInstInitConfig->ownQdmaChannels[0U];
6221 ptrEdmaShadowRegs->IECR = (rmInstInitConfig->ownDmaChannels[0U]
6222 | rmInstInitConfig->ownTccs[0U]);
6223 ptrEdmaShadowRegs->IECRH = (rmInstInitConfig->ownDmaChannels[1U]
6224 | rmInstInitConfig->ownTccs[1U]);
6225 ptrEdmaShadowRegs->ICR = (rmInstInitConfig->ownDmaChannels[0U]
6226 | rmInstInitConfig->ownTccs[0U]);
6227 ptrEdmaShadowRegs->ICRH = (rmInstInitConfig->ownDmaChannels[1U]
6228 | rmInstInitConfig->ownTccs[1U]);
6230 ptrEdmaShadowRegs->QSECR = rmInstInitConfig->ownQdmaChannels[0U];
6232 /*
6233 * Set all EDMA3 Resource<->Region mapping parameters
6234 */
6236 /* 1. Dma Channel (and TCC) <-> Region */
6237 ptrEdmaccRegs->DRA[regionId].DRAE = 0U;
6238 ptrEdmaccRegs->DRA[regionId].DRAEH = 0U;
6240 /* 2. Qdma Channel <-> Region */
6241 ptrEdmaccRegs->QRAE[regionId] = 0U;
6242 }
6243 }
6245 return;
6246 }
6250 /** Local MemZero function */
6251 void edma3MemZero(void *dst, uint32_t len)
6252 {
6253 uint32_t i = 0U;
6254 uint32_t *ds = NULL;
6256 assert (dst != NULL);
6258 ds = (uint32_t *)dst;
6260 for (i = 0U ; i < (len/4U) ; i++)
6261 {
6262 *ds = 0x0;
6263 ds++;
6264 }
6266 return;
6267 }
6270 /* Local MemCopy function */
6271 void edma3MemCpy(void *dst, const void *src, uint32_t len)
6272 {
6273 uint32_t i=0U;
6274 const uint32_t *sr;
6275 uint32_t *ds;
6277 assert (src != NULL);
6278 assert (dst != NULL);
6279 assert ((len%4) == 0);
6281 sr = (const uint32_t *)src;
6282 ds = (uint32_t *)dst;
6284 for (i = 0U ; i < (len/4U) ; i++)
6285 {
6286 *ds = *sr;
6287 ds++;
6288 sr++;
6289 }
6291 return;
6292 }
6295 /* Local MemCopy function to copy Param Set ONLY */
6296 void edma3ParamCpy(volatile void *dst, const volatile void *src)
6297 {
6298 uint32_t i = 0U;
6299 const volatile uint32_t *sr;
6300 volatile uint32_t *ds;
6302 assert (src != NULL);
6303 assert (dst != NULL);
6305 sr = (const volatile uint32_t *)src;
6306 ds = (volatile uint32_t *)dst;
6308 for (i = 0U; i < 8U; i++)
6309 {
6310 *ds = *sr;
6311 ds++;
6312 sr++;
6313 }
6315 return;
6316 }
6319 /**
6320 * Finds a particular bit ('0' or '1') in the particular word from 'start'.
6321 * If found, returns the position, else return -1.
6322 */
6323 static int32_t findBitInWord (int32_t source, uint32_t start, uint16_t bit)
6324 {
6325 uint32_t position = start;
6326 uint16_t found = 0;
6327 uint32_t iterations_left = 0;
6328 uint32_t sourceTmp=0;
6330 switch (bit)
6331 {
6332 case 1U:
6333 {
6334 sourceTmp = (uint32_t)source >> (start%32U);
6335 source = (int32_t)sourceTmp;
6337 while ((found==0U) && (source!=0))
6338 {
6339 if (((uint32_t)source & 0x1U) == 0x1U)
6340 {
6341 /* 1 */
6342 found++;
6343 }
6344 else
6345 {
6346 /* 0 */
6347 sourceTmp = (uint32_t)source >> 1;
6348 source = (int32_t)sourceTmp;
6349 position++;
6350 }
6351 }
6353 }
6354 break;
6356 case 0:
6357 {
6358 sourceTmp = (uint32_t)source >> (start%32U);
6359 source = (int32_t)sourceTmp;
6360 iterations_left = (uint32_t)32U - (start%32U);
6362 while ((found==0U) && (iterations_left>0U))
6363 {
6364 if (((uint32_t)source & 0x1U) == 0x1U)
6365 {
6366 /* 1 */
6367 sourceTmp = (uint32_t)source >> 1;
6368 source = (int32_t)sourceTmp;
6369 position++;
6370 iterations_left--;
6371 }
6372 else
6373 {
6374 /* 0 */
6375 found++;
6376 }
6377 }
6378 }
6379 break;
6381 default:
6382 break;
6383 }
6385 return (found ? (int32_t)position : -1);
6386 }
6389 /**
6390 * Finds a particular bit ('0' or '1') in the specified resources' array
6391 * from 'start' to 'end'. If found, returns the position, else return -1.
6392 */
6393 static int32_t findBit (EDMA3_RM_ResType resType,
6394 uint32_t start,
6395 uint32_t end,
6396 uint16_t bit)
6397 {
6398 int32_t position = -1;
6399 uint32_t start_index = start / 32U;
6400 uint32_t end_index = end / 32U;
6401 int32_t i;
6402 uint32_t *resPtr = 0x0;
6403 int32_t ret = -1;
6404 EDMA3_RM_Result result = EDMA3_RM_SOK;
6406 assert (start <= end);
6408 /**
6409 * job is to find 'bit' in an array[start_index:end_index]
6410 * algo used:
6411 * first search in array[start_index]
6412 * then search in array[start_index + 1 : end_index - 1]
6413 * then search in array[end_index]
6414 */
6415 switch (resType)
6416 {
6417 case EDMA3_RM_RES_DMA_CHANNEL:
6418 resPtr = &contiguousDmaRes[0];
6419 break;
6421 case EDMA3_RM_RES_QDMA_CHANNEL:
6422 resPtr = &contiguousQdmaRes[0];
6423 break;
6425 case EDMA3_RM_RES_TCC:
6426 resPtr = &contiguousTccRes[0];
6427 break;
6429 case EDMA3_RM_RES_PARAM_SET:
6430 resPtr = &contiguousParamRes[0];
6431 break;
6433 default:
6434 result = EDMA3_RM_E_INVALID_PARAM;
6435 break;
6436 }
6438 if (EDMA3_RM_SOK == result)
6439 {
6440 switch (bit)
6441 {
6442 case 1U:
6443 {
6444 /* Find '1' in first word. */
6445 position = findBitInWord (resPtr[start_index], start, (uint16_t)1U);
6447 if (position != -1)
6448 {
6449 ret = position;
6450 }
6451 else
6452 {
6453 /* '1' NOT found, look into other words. */
6454 for (i = ((int32_t)start_index + (int32_t)1U); i <= ((int32_t)end_index - (int32_t)1U); i++)
6455 {
6456 position = findBitInWord (resPtr[i], (uint32_t)0U, (uint16_t)1U);
6457 if (position != -1)
6458 {
6459 /* '1' Found... */
6460 ret = (position + (i*32));
6461 break;
6462 }
6463 }
6465 /* First check whether we have found '1' or not. */
6466 if (ret == -1)
6467 {
6468 /* Still not found, look in the last word. */
6469 position = findBitInWord(resPtr[end_index], (uint32_t)0U, (uint16_t)1U);
6470 if (position != -1)
6471 {
6472 /* Finally got it. */
6473 ret = (position + ((int32_t)end_index*(int32_t)32U));
6474 }
6475 else
6476 {
6477 /* Sorry, could not find it, return -1. */
6478 ret = -1;
6479 }
6480 }
6481 }
6482 }
6483 break;
6485 case 0U:
6486 {
6487 /* Find '0' in first word. */
6488 position = findBitInWord(resPtr[start_index], start, (uint16_t)0U);
6489 if (position != -1)
6490 {
6491 ret = position;
6492 }
6493 else
6494 {
6495 /* '0' NOT found, look into other words. */
6496 for (i = ((int32_t)start_index + (int32_t)1U); i <= ((int32_t)end_index - (int32_t)1U); i++)
6497 {
6498 position = findBitInWord(resPtr[i], (uint32_t)0U, (uint16_t)0U);
6499 if (position != -1)
6500 {
6501 /* '0' found... */
6502 ret = (position + (i*32));
6503 break;
6504 }
6505 }
6507 /* First check whether we have found '0' or not. */
6508 if (ret == -1)
6509 {
6510 position = findBitInWord(resPtr[end_index], (uint32_t)0U, (uint16_t)0U);
6511 if (position != -1)
6512 {
6513 /* Finally got it. */
6514 ret = (position + ((int32_t)end_index*(int32_t)32U));
6515 }
6516 else
6517 {
6518 /* Sorry, could not find it, return -1. */
6519 ret = -1;
6520 }
6521 }
6522 }
6523 }
6524 break;
6526 default:
6527 break;
6528 }
6529 }
6533 return ((ret >= (int32_t)start) ? ret : -1);
6534 }
6538 /**
6539 * If successful, this function returns EDMA3_RM_SOK and the position
6540 * of first available resource in 'positionRes'. Else returns error.
6541 */
6542 static EDMA3_RM_Result allocAnyContigRes(EDMA3_RM_ResType resType,
6543 uint32_t numResources,
6544 uint32_t *positionRes)
6545 {
6546 uint16_t found = 0U;
6547 int32_t first_one, next_zero;
6548 uint32_t num_available;
6549 int32_t ret = -1;
6550 uint32_t start = 0;
6551 uint32_t end;
6552 EDMA3_RM_Result result = EDMA3_RM_SOK;
6554 assert (positionRes != NULL);
6556 switch (resType)
6557 {
6558 case EDMA3_RM_RES_DMA_CHANNEL:
6559 end = EDMA3_MAX_DMA_CH - 1U;
6560 break;
6562 case EDMA3_RM_RES_QDMA_CHANNEL:
6563 end = EDMA3_MAX_QDMA_CH - 1U;
6564 break;
6566 case EDMA3_RM_RES_TCC:
6567 end = EDMA3_MAX_TCC - 1U;
6568 break;
6570 case EDMA3_RM_RES_PARAM_SET:
6571 end = edma3NumPaRAMSets - 1U;
6572 break;
6574 default:
6575 result = EDMA3_RM_E_INVALID_PARAM;
6576 break;
6577 }
6579 if (result == EDMA3_RM_SOK)
6580 {
6581 /**
6582 * Algorithm used for finding N contiguous resources.
6583 * In the resources' array, '1' means available and '0' means
6584 * not-available.
6585 * Step a) Find first '1' starting from 'start'. If successful,
6586 * store it in first_one, else return error.
6587 * Step b) Find first '0' starting from (first_one+1) to 'end'.
6588 * If successful, store returned value in next_zero. If '0' could
6589 * not be located, it means all the resources are available.
6590 * Store 'end' (i.e. the last resource id) in next_zero.
6591 * Step c) Count the number of contiguous resources available
6592 * by subtracting first_one from next_zero.
6593 * Step d) If result < N, do the whole process again untill you
6594 * reach end. Else you have found enough resources, return success.
6595 */
6596 while((found == 0) && (start<=end) && (((end-start)+1U) >= numResources))
6597 {
6598 /* Find first '1' starting from 'start' till 'end'. */
6599 first_one = findBit (resType, start, end, (uint16_t)1U);
6600 if (first_one != -1)
6601 {
6602 /* Got first 1, search for first '0' now. */
6603 next_zero = findBit (resType, (uint32_t)first_one+(uint32_t)1, end, (uint16_t)0U);
6604 if (next_zero == -1)
6605 {
6606 /* Unable to find next zero, all 1' are there */
6607 next_zero = (int32_t)end + (int32_t)1U;
6608 }
6610 /* check no of resources available */
6611 num_available = (uint32_t)next_zero - (uint32_t)first_one;
6612 if (num_available >= numResources)
6613 {
6614 /* hurrah..., we have found enough resources. */
6615 found = 1U;
6616 ret = first_one;
6617 }
6618 else
6619 {
6620 /* Not enough resources, try again */
6621 start = (uint32_t)next_zero + (uint32_t)1;
6622 }
6623 }
6624 else
6625 {
6626 /* do nothing, first 1 is not there, return. */
6627 break;
6628 }
6629 }
6630 }
6633 if (result == EDMA3_RM_SOK)
6634 {
6635 if (found == 1U)
6636 {
6637 /* required resources found, retrun the first available res id. */
6638 *positionRes = (uint32_t)ret;
6639 }
6640 else
6641 {
6642 /* No resources allocated */
6643 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
6644 }
6645 }
6647 return result;
6648 }
6652 /**
6653 * Starting from 'firstResIdObj', this function makes the next 'numResources'
6654 * Resources non-available for future. Also, it does some global resisters'
6655 * setting also.
6656 */
6657 static EDMA3_RM_Result gblChngAllocContigRes(EDMA3_RM_Instance *rmInstance,
6658 const EDMA3_RM_ResDesc *firstResIdObj,
6659 uint32_t numResources)
6660 {
6661 EDMA3_RM_Result result = EDMA3_RM_SOK;
6662 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
6663 EDMA3_RM_Obj *rmObj = NULL;
6664 uint32_t avlblIdx = 0U;
6665 uint32_t firstResId=0U;
6666 uint32_t lastResId=0U;
6667 uint32_t edma3Id;
6669 assert (rmInstance != NULL);
6670 assert (firstResIdObj != NULL);
6672 rmObj = rmInstance->pResMgrObjHandle;
6674 if (rmObj == NULL)
6675 {
6676 result = EDMA3_RM_E_INVALID_PARAM;
6677 }
6679 if (EDMA3_RM_SOK == result)
6680 {
6681 edma3Id = rmObj->phyCtrllerInstId;
6682 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
6684 if (gblRegs == NULL)
6685 {
6686 result = EDMA3_RM_E_INVALID_PARAM;
6687 }
6688 }
6690 if (result == EDMA3_RM_SOK)
6691 {
6692 switch (firstResIdObj->type)
6693 {
6694 case EDMA3_RM_RES_DMA_CHANNEL:
6695 {
6696 firstResId = firstResIdObj->resId;
6697 lastResId = firstResId + (numResources - 1U);
6699 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6700 {
6701 rmInstance->avlblDmaChannels[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
6703 /**
6704 * Enable the DMA channel in the DRAE/DRAEH registers also.
6705 */
6706 if (avlblIdx < 32U)
6707 {
6708 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
6709 |= ((uint32_t)0x1U << avlblIdx);
6710 }
6711 else
6712 {
6713 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
6714 |= ((uint32_t)0x1U << (avlblIdx - 32U));
6715 }
6716 }
6717 }
6718 break;
6720 case EDMA3_RM_RES_QDMA_CHANNEL:
6721 {
6722 firstResId = firstResIdObj->resId;
6723 lastResId = firstResId + (numResources - 1U);
6725 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6726 {
6727 rmInstance->avlblQdmaChannels[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
6729 /**
6730 * Enable the QDMA channel in the QRAE register also.
6731 */
6732 gblRegs->QRAE[rmInstance->initParam.regionId]
6733 |= ((uint32_t)0x1U << avlblIdx);
6734 }
6735 }
6736 break;
6738 case EDMA3_RM_RES_TCC:
6739 {
6740 firstResId = firstResIdObj->resId;
6741 lastResId = firstResId + (numResources - 1U);
6743 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6744 {
6745 rmInstance->avlblTccs[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
6747 /**
6748 * If the region id coming from this
6749 * RM instance is same as the Master RM
6750 * Instance's region id, only then we will be
6751 * getting the interrupts on the same side.
6752 * So save the TCC in the allocatedTCCs[] array.
6753 */
6754 if (edma3RegionId == rmInstance->initParam.regionId)
6755 {
6756 if (avlblIdx < 32U)
6757 {
6758 allocatedTCCs[edma3Id][0U] |= ((uint32_t)0x1U << avlblIdx);
6759 }
6760 else
6761 {
6762 allocatedTCCs[edma3Id][1U] |= ((uint32_t)0x1U << (avlblIdx - 32U));
6763 }
6764 }
6765 }
6766 }
6767 break;
6769 case EDMA3_RM_RES_PARAM_SET:
6770 {
6771 firstResId = firstResIdObj->resId;
6772 lastResId = firstResId + (numResources - 1U);
6774 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6775 {
6776 rmInstance->avlblPaRAMSets [avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
6778 /**
6779 * Also, make the actual PARAM Set NULL, checking the flag
6780 * whether it is required or not.
6781 */
6782 if (TRUE == rmInstance->paramInitRequired)
6783 {
6784 edma3MemZero((void *)(&gblRegs->PARAMENTRY[avlblIdx]),
6785 sizeof(gblRegs->PARAMENTRY[avlblIdx]));
6786 }
6787 }
6788 }
6789 break;
6791 default:
6792 result = EDMA3_RM_E_INVALID_PARAM;
6793 break;
6794 }
6795 }
6798 return result;
6799 }
6802 EDMA3_RM_Result EDMA3_RM_initXbarEventMap (EDMA3_RM_Handle hEdma,
6803 const EDMA3_RM_GblXbarToChanConfigParams * edmaGblXbarConfig,
6804 EDMA3_RM_mapXbarEvtToChan mapXbarEvtFunc,
6805 EDMA3_RM_xbarConfigScr configXbarScr)
6806 {
6807 EDMA3_RM_Result result = EDMA3_DRV_SOK;
6808 EDMA3_RM_Instance *rmInstance = NULL;
6810 /* If parameter checking is enabled... */
6811 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
6812 if (hEdma == NULL)
6813 {
6814 result = EDMA3_RM_E_INVALID_PARAM;
6815 }
6816 #endif
6818 /* Check if the parameters are OK. */
6819 if (EDMA3_DRV_SOK == result)
6820 {
6821 rmInstance = (EDMA3_RM_Instance *)hEdma;
6823 if (mapXbarEvtFunc != NULL)
6824 {
6825 rmInstance->mapXbarToChan = mapXbarEvtFunc;
6826 }
6827 if (configXbarScr != NULL)
6828 {
6829 rmInstance->configScrMapXbarToEvt = configXbarScr;
6830 }
6831 if (edmaGblXbarConfig != NULL)
6832 {
6833 edma3MemCpy((void *)(&rmInstance->rmXbarToEvtMapConfig),
6834 (const void *)(edmaGblXbarConfig),
6835 sizeof (EDMA3_RM_GblXbarToChanConfigParams));
6836 }
6837 }
6839 return (result);
6840 }
6842 /* Resource Manager Internal functions - End */
6844 /* End of File */