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[0U]),
450 sizeof(resMgrObj));
451 edma3MemZero((void *)(&(edma3IntrParams[0U][0U])),
452 sizeof(edma3IntrParams));
453 rmInitDone = TRUE;
454 }
456 /* Initialization has been done */
457 if (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_DELETED)
458 {
459 result = EDMA3_RM_E_OBJ_NOT_DELETED;
460 }
461 else
462 {
463 /**
464 * Check whether user has passed the Global Config Info.
465 * If yes, copy it to the driver data structures. Else, use the
466 * info from the config file edma3Cfg.c
467 */
468 #ifndef GENERIC
469 if (NULL == gblCfgParams)
470 {
471 /* Take info from the specific config file */
472 edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
473 (const void *)(&edma3GblCfgParams[phyCtrllerInstId]),
474 sizeof (EDMA3_RM_GblConfigParams));
475 }
476 else
477 {
478 #endif
479 /* User passed the info, save it in the RM object first */
480 edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
481 (const void *)(gblCfgParams),
482 sizeof (EDMA3_RM_GblConfigParams));
483 #ifndef GENERIC
484 }
485 #endif
488 /**
489 * Check whether DMA channel to PaRAM Set mapping exists or not.
490 * If it does not exist, set the mapping array as 1-to-1 mapped.
491 */
492 if (FALSE == resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChPaRAMMapExists)
493 {
494 for (count = 0U; count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels; count++)
495 {
496 resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChannelPaRAMMap[count] = count;
497 }
498 }
501 /**
502 * Update the actual number of PaRAM sets and
503 * Initialize Boundary Values for Logical Channel Ranges.
504 */
505 edma3NumPaRAMSets = resMgrObj[phyCtrllerInstId].gblCfgParams.numPaRAMSets;
506 edma3_dma_ch_max_val[phyCtrllerInstId] = resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels - 1U;
507 edma3_link_ch_min_val[phyCtrllerInstId] = edma3_dma_ch_max_val[phyCtrllerInstId] + 1U;
508 edma3_link_ch_max_val[phyCtrllerInstId] = edma3_link_ch_min_val[phyCtrllerInstId] + (resMgrObj[phyCtrllerInstId].gblCfgParams.numPaRAMSets - 1U);
509 edma3_qdma_ch_min_val[phyCtrllerInstId] = edma3_link_ch_max_val[phyCtrllerInstId] + 1U;
510 edma3_qdma_ch_max_val[phyCtrllerInstId] = edma3_qdma_ch_min_val[phyCtrllerInstId] + (resMgrObj[phyCtrllerInstId].gblCfgParams.numQdmaChannels - 1U);
511 edma3_log_ch_max_val[phyCtrllerInstId] = edma3_qdma_ch_max_val[phyCtrllerInstId];
513 resMgrObj[phyCtrllerInstId].phyCtrllerInstId = phyCtrllerInstId;
514 resMgrObj[phyCtrllerInstId].state = EDMA3_RM_CREATED;
515 resMgrObj[phyCtrllerInstId].numOpens = 0U;
517 /* Make all the RM instances for this EDMA3 HW NULL */
518 for (count = 0U; count < EDMA3_MAX_RM_INSTANCES; count++)
519 {
520 edma3MemZero((void *)((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
521 sizeof(EDMA3_RM_Instance));
523 /* Also make this data structure NULL */
524 edma3MemZero((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
525 sizeof(EDMA3_RM_InstanceInitConfig));
526 }
528 /* Initialize the global edma3DmaChTccMapping array with EDMA3_MAX_TCC */
529 for ( count = 0U;
530 count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels;
531 count++
532 )
533 {
534 edma3DmaChTccMapping[phyCtrllerInstId][count] = EDMA3_MAX_TCC;
535 }
537 /* Initialize the global edma3QdmaChTccMapping array with EDMA3_MAX_TCC */
538 for ( count = 0U;
539 count < resMgrObj[phyCtrllerInstId].gblCfgParams.numQdmaChannels;
540 count++
541 )
542 {
543 edma3QdmaChTccMapping[phyCtrllerInstId][count] = EDMA3_MAX_TCC;
544 }
546 /* Reset edma3RmChBoundRes Array*/
547 for (count = 0U; count < EDMA3_MAX_LOGICAL_CH; count++)
548 {
549 edma3RmChBoundRes[phyCtrllerInstId][count].paRAMId = -1;
550 edma3RmChBoundRes[phyCtrllerInstId][count].tcc = EDMA3_MAX_TCC;
551 }
553 /* Make the contiguousParamRes array NULL */
554 edma3MemZero((void *)(&(contiguousParamRes[0U])),
555 sizeof(contiguousParamRes));
558 /**
559 * Check the misc configuration options structure.
560 * Check whether the global registers' initialization
561 * is required or not.
562 * It is required ONLY if RM is running on the Master Processor.
563 */
564 if (NULL != miscOpt)
565 {
566 if (miscOpt->isSlave == FALSE)
567 {
568 /* It is a master. */
569 edma3GlobalRegionInit(phyCtrllerInstId, (resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels));
570 }
571 }
572 else
573 {
574 /* By default, global registers will be initialized. */
575 edma3GlobalRegionInit(phyCtrllerInstId, (resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels));
576 }
577 }
578 }
580 return result;
581 }
583 EDMA3_RM_Result EDMA3_RM_delete (uint32_t phyCtrllerInstId,
584 const void *param)
585 {
586 EDMA3_RM_Result result = EDMA3_RM_SOK;
588 /* If parameter checking is enabled... */
589 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
590 if (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
591 {
592 result = EDMA3_RM_E_INVALID_PARAM;
593 }
594 #endif
596 /* Check if the parameters are OK. */
597 if (EDMA3_RM_SOK == result)
598 {
599 /**
600 * If number of RM Instances is 0, then state should be
601 * EDMA3_RM_CLOSED OR EDMA3_RM_CREATED.
602 */
603 if ((0 == resMgrObj[phyCtrllerInstId].numOpens)
604 && ((resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CLOSED)
605 && (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CREATED)))
606 {
607 result = EDMA3_RM_E_OBJ_NOT_CLOSED;
608 }
609 else
610 {
611 /**
612 * If number of RM Instances is NOT 0, then this function
613 * SHOULD NOT be called by anybody.
614 */
615 if (0 != resMgrObj[phyCtrllerInstId].numOpens)
616 {
617 result = EDMA3_RM_E_INVALID_STATE;
618 }
619 else
620 {
621 /** Change state to EDMA3_RM_DELETED */
622 resMgrObj[phyCtrllerInstId].state = EDMA3_RM_DELETED;
624 /* Reset the Allocated TCCs Array also. */
625 allocatedTCCs[phyCtrllerInstId][0U] = 0x0U;
626 allocatedTCCs[phyCtrllerInstId][1U] = 0x0U;
628 /* Also, reset the RM Object Global Config Info */
629 edma3MemZero((void *)&(resMgrObj[phyCtrllerInstId].gblCfgParams),
630 sizeof(EDMA3_RM_GblConfigParams));
631 }
632 }
633 }
635 return result;
636 }
638 EDMA3_RM_Handle EDMA3_RM_open (uint32_t phyCtrllerInstId,
639 const EDMA3_RM_Param *initParam,
640 EDMA3_RM_Result *errorCode)
641 {
642 uint32_t intState = 0U;
643 uint32_t resMgrIdx = 0U;
644 EDMA3_RM_Result result = EDMA3_RM_SOK;
645 EDMA3_RM_Obj *rmObj = NULL;
646 EDMA3_RM_Instance *rmInstance = NULL;
647 EDMA3_RM_Instance *temp_ptr_rm_inst = NULL;
648 EDMA3_RM_Handle retVal = NULL;
649 uint32_t dmaChDwrds = 0U;
650 uint32_t paramSetDwrds = 0U;
651 uint32_t tccDwrds = 0U;
652 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
654 #ifdef GENERIC
655 /* GENERIC libraries don't come with a default confifguration, always
656 needs to be supplied with a parameter */
657 if ((initParam == NULL) || (initParam->rmInstInitConfig == NULL))
658 {
659 result = EDMA3_RM_E_INVALID_PARAM;
660 }
661 #endif
664 /* If parameter checking is enabled... */
665 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
666 if (((initParam == NULL)
667 || (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES))
668 || (errorCode == NULL))
669 {
670 result = EDMA3_RM_E_INVALID_PARAM;
671 }
672 #endif
674 /* Check if the parameters are OK. */
675 if (EDMA3_RM_SOK == result)
676 {
677 /* Check whether the semaphore handle is null or not */
678 if (NULL == initParam->rmSemHandle)
679 {
680 result = EDMA3_RM_E_INVALID_PARAM;
681 }
682 else
683 {
684 rmObj = &resMgrObj[phyCtrllerInstId];
685 if (
686 (NULL == rmObj)
687 || (initParam->regionId >=
688 resMgrObj[phyCtrllerInstId].gblCfgParams.numRegions)
689 )
690 {
691 result = EDMA3_RM_E_INVALID_PARAM;
692 }
693 else
694 {
695 edma3OsProtectEntry (phyCtrllerInstId,
696 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
697 &intState);
699 /** Check state of RM Object.
700 * If no RM instance is opened and this is the first one,
701 * then state should be created/closed.
702 */
703 if ((rmObj->numOpens == 0) &&
704 ((rmObj->state != EDMA3_RM_CREATED) &&
705 (rmObj->state != EDMA3_RM_CLOSED)))
706 {
707 result = EDMA3_RM_E_INVALID_STATE;
708 edma3OsProtectExit (phyCtrllerInstId,
709 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
710 intState);
711 }
712 else
713 {
714 /**
715 * If num of instances opened is more than 0 and less than
716 * max allowed, then state should be opened.
717 */
718 if (((rmObj->numOpens > 0) &&
719 (rmObj->numOpens < EDMA3_MAX_RM_INSTANCES))
720 && (rmObj->state != EDMA3_RM_OPENED))
721 {
722 result = EDMA3_RM_E_INVALID_STATE;
723 edma3OsProtectExit (phyCtrllerInstId,
724 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
725 intState);
726 }
727 else
728 {
729 /* Check if max opens have passed */
730 if (rmObj->numOpens >= EDMA3_MAX_RM_INSTANCES)
731 {
732 result = EDMA3_RM_E_MAX_RM_INST_OPENED;
733 edma3OsProtectExit (phyCtrllerInstId,
734 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
735 intState);
736 }
737 }
738 }
739 }
740 }
741 }
743 if (EDMA3_RM_SOK == result)
744 {
745 /*
746 * Check whether the RM instance is Master or not.
747 * If it is master, check whether a master already exists
748 * or not. There should NOT be more than 1 master.
749 * Return error code if master already exists
750 */
751 if ((TRUE == masterExists[phyCtrllerInstId]) && (TRUE == initParam->isMaster))
752 {
753 /* No two masters should exist, return error */
754 result = EDMA3_RM_E_RM_MASTER_ALREADY_EXISTS;
755 edma3OsProtectExit (phyCtrllerInstId,
756 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
757 intState);
758 }
759 else
760 {
761 /* Create Res Mgr Instance */
762 for (resMgrIdx = 0U; resMgrIdx < EDMA3_MAX_RM_INSTANCES; resMgrIdx++)
763 {
764 temp_ptr_rm_inst = ((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
766 if (NULL != temp_ptr_rm_inst)
767 {
768 if (NULL == temp_ptr_rm_inst->pResMgrObjHandle)
769 {
770 /* Handle to the EDMA3 HW Object */
771 temp_ptr_rm_inst->pResMgrObjHandle = rmObj;
772 /* Handle of the Res Mgr Instance */
773 rmInstance = temp_ptr_rm_inst;
775 /* Also make this data structure NULL, just for safety. */
776 edma3MemZero((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
777 sizeof(EDMA3_RM_InstanceInitConfig));
779 break;
780 }
781 }
782 }
784 /* Check whether a RM instance has been created or not */
785 if (NULL == rmInstance)
786 {
787 result = EDMA3_RM_E_MAX_RM_INST_OPENED;
788 edma3OsProtectExit (phyCtrllerInstId,
789 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
790 intState);
791 }
792 else
793 {
794 /* Copy the InitPaRAM first */
795 edma3MemCpy((void *)(&rmInstance->initParam),
796 (const void *)(initParam),
797 sizeof (EDMA3_RM_Param));
799 if (rmObj->gblCfgParams.globalRegs != NULL)
800 {
801 globalRegs = (volatile EDMA3_CCRL_Regs *)
802 (rmObj->gblCfgParams.globalRegs);
803 rmInstance->shadowRegs = (EDMA3_CCRL_ShadowRegs *)
804 &(globalRegs->SHADOW[rmInstance->initParam.regionId]);
806 /* copy the instance specific semaphore handle */
807 rmInstance->initParam.rmSemHandle = initParam->rmSemHandle;
809 /**
810 * Check whether user has passed information about resources
811 * owned and reserved by this instance. This is region specific
812 * information. If he has not passed, dafault static config info will be taken
813 * from the config file edma3Cfg.c, according to the regionId specified.
814 *
815 * resMgrIdx specifies the RM instance number created just now.
816 * Use it to populate the userInitConfig [].
817 */
818 #ifndef GENERIC
819 if (NULL == initParam->rmInstInitConfig)
820 {
821 /* Take the info from the specific config file */
822 edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
823 (const void *)(&defInstInitConfig[phyCtrllerInstId][initParam->regionId]),
824 sizeof (EDMA3_RM_InstanceInitConfig));
825 }
826 else
827 {
828 #endif
829 /* User has passed the region specific info. */
830 edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
831 (const void *)(initParam->rmInstInitConfig),
832 sizeof (EDMA3_RM_InstanceInitConfig));
833 #ifndef GENERIC
834 }
835 #endif
837 rmInstance->initParam.rmInstInitConfig =
838 ((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
840 dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / (uint32_t)32U;
841 if (dmaChDwrds == 0)
842 {
843 /* In case DMA channels are < 32 */
844 dmaChDwrds = 1U;
845 }
847 paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / (uint32_t)32U;
848 if (paramSetDwrds == 0)
849 {
850 /* In case PaRAM Sets are < 32 */
851 paramSetDwrds = 1U;
852 }
854 tccDwrds = rmObj->gblCfgParams.numTccs / (uint32_t)32U;
855 if (tccDwrds == 0)
856 {
857 /* In case TCCs are < 32 */
858 tccDwrds = 1U;
859 }
861 for (resMgrIdx = 0U; resMgrIdx < dmaChDwrds; ++resMgrIdx)
862 {
863 rmInstance->avlblDmaChannels[resMgrIdx]
864 = rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resMgrIdx];
865 }
867 rmInstance->avlblQdmaChannels[0U]
868 = rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0U];
870 for (resMgrIdx = 0U; resMgrIdx < paramSetDwrds; ++resMgrIdx)
871 {
872 rmInstance->avlblPaRAMSets[resMgrIdx]
873 = rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[resMgrIdx];
874 }
876 for (resMgrIdx = 0U; resMgrIdx < tccDwrds; ++resMgrIdx)
877 {
878 rmInstance->avlblTccs [resMgrIdx]
879 = rmInstance->initParam.rmInstInitConfig->ownTccs[resMgrIdx];
880 }
882 /*
883 * If the EDMA RM instance is MASTER (ie. initParam->isMaster
884 * is TRUE), save the region ID.
885 * Only this shadow region will receive the
886 * EDMA3 interrupts, if enabled.
887 */
888 if (TRUE == initParam->isMaster)
889 {
890 /* Store the region id to use it in the ISRs */
891 edma3RegionId = rmInstance->initParam.regionId;
892 masterExists[phyCtrllerInstId] = TRUE;
893 }
895 if (TRUE == initParam->regionInitEnable)
896 {
897 edma3ShadowRegionInit (rmInstance);
898 }
900 /**
901 * By default, PaRAM Sets allocated using this RM Instance
902 * will get cleared during their allocation.
903 * User can stop their clearing by calling specific IOCTL
904 * command.
905 */
906 rmInstance->paramInitRequired = TRUE;
909 /**
910 * By default, during the EDMA3_RM_allocLogicalChannel (),
911 * global EDMA3 registers (DCHMAP/QCHMAP) and the allocated
912 * PaRAM Set will be programmed accordingly, for users using this
913 * RM Instance.
914 * User can stop their pre-programming by calling
915 * EDMA3_RM_IOCTL_SET_GBL_REG_MODIFY_OPTION
916 * IOCTL command.
917 */
918 rmInstance->regModificationRequired = TRUE;
921 if (EDMA3_RM_SOK == result)
922 {
923 rmObj->state = EDMA3_RM_OPENED;
924 /* Increase the Instance count */
925 resMgrObj[phyCtrllerInstId].numOpens++;
926 retVal = rmInstance;
927 }
928 }
929 else
930 {
931 result = EDMA3_RM_E_INVALID_PARAM;
932 }
934 edma3OsProtectExit (phyCtrllerInstId,
935 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
936 intState);
937 }
938 }
939 }
941 if(errorCode != NULL)
942 {
943 *errorCode = result;
944 }
945 return (EDMA3_RM_Handle)retVal;
946 }
948 EDMA3_RM_Result EDMA3_RM_close (EDMA3_RM_Handle hEdmaResMgr,
949 const void *param)
950 {
951 EDMA3_RM_Result result = EDMA3_RM_SOK;
952 uint32_t intState = 0U;
953 uint32_t resMgrIdx = 0U;
954 EDMA3_RM_Obj *rmObj = NULL;
955 EDMA3_RM_Instance *rmInstance = NULL;
956 uint32_t dmaChDwrds;
957 uint32_t paramSetDwrds;
958 uint32_t tccDwrds;
960 /* If parameter checking is enabled... */
961 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
962 if (NULL == hEdmaResMgr)
963 {
964 result = EDMA3_RM_E_INVALID_PARAM;
965 }
966 #endif
968 /* Check if the parameters are OK. */
969 if (EDMA3_RM_SOK == result)
970 {
971 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
972 rmObj = rmInstance->pResMgrObjHandle;
974 if (rmObj == NULL)
975 {
976 result = (EDMA3_RM_E_INVALID_PARAM);
977 }
978 else
979 {
980 /* Check state of driver, state should be opened */
981 if (rmObj->state != EDMA3_RM_OPENED)
982 {
983 result = (EDMA3_RM_E_OBJ_NOT_OPENED);
984 }
985 else
986 {
987 dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / (uint32_t)32U;
988 paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / (uint32_t)32U;
989 tccDwrds = rmObj->gblCfgParams.numTccs / (uint32_t)32U;
991 /* Set the instance config as NULL*/
992 for (resMgrIdx = 0U; resMgrIdx < dmaChDwrds; ++resMgrIdx)
993 {
994 rmInstance->avlblDmaChannels[resMgrIdx] = 0x0U;
995 }
996 for (resMgrIdx = 0U; resMgrIdx < paramSetDwrds; ++resMgrIdx)
997 {
998 rmInstance->avlblPaRAMSets[resMgrIdx] = 0x0U;
999 }
1000 rmInstance->avlblQdmaChannels[0U] = 0x0U;
1001 for (resMgrIdx = 0U; resMgrIdx < tccDwrds; ++resMgrIdx)
1002 {
1003 rmInstance->avlblTccs[resMgrIdx] = 0x0U;
1004 }
1006 /**
1007 * If this is the Master Instance, reset the static variable
1008 * 'masterExists[]'.
1009 */
1010 if (TRUE == rmInstance->initParam.isMaster)
1011 {
1012 masterExists[rmObj->phyCtrllerInstId] = FALSE;
1013 edma3RegionId = EDMA3_MAX_REGIONS;
1014 }
1016 /* Reset the Initparam for this RM Instance */
1017 edma3MemZero((void *)&(rmInstance->initParam),
1018 sizeof(EDMA3_RM_Param));
1020 /* Critical section starts */
1021 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
1022 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
1023 &intState);
1025 /* Decrease the Number of Opens */
1026 --rmObj->numOpens;
1027 if (0 == rmObj->numOpens)
1028 {
1029 edma3MemZero((void *)&(edma3RmChBoundRes[rmObj->phyCtrllerInstId][0]),
1030 sizeof(edma3RmChBoundRes[rmObj->phyCtrllerInstId]));
1032 rmObj->state = EDMA3_RM_CLOSED;
1033 }
1035 /* Critical section ends */
1036 edma3OsProtectExit (rmObj->phyCtrllerInstId,
1037 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
1038 intState);
1040 rmInstance->pResMgrObjHandle = NULL;
1041 rmInstance->shadowRegs = NULL;
1042 rmInstance = NULL;
1043 }
1044 }
1045 }
1047 return result;
1048 }
1050 EDMA3_RM_Result EDMA3_RM_allocResource(EDMA3_RM_Handle hEdmaResMgr,
1051 EDMA3_RM_ResDesc *resObj)
1052 {
1053 EDMA3_RM_Instance *rmInstance = NULL;
1054 EDMA3_RM_Obj *rmObj = NULL;
1055 EDMA3_RM_Result result = EDMA3_RM_SOK;
1056 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
1057 uint32_t avlblIdx = 0U;
1058 uint32_t resIdClr = 0x0;
1059 uint32_t resIdSet = 0x0;
1060 uint32_t resId;
1061 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1062 uint32_t mapXbarEvtToChanFlag = FALSE;
1063 uint32_t xBarEvtBeforeMap = 0;
1064 uint32_t edma3Id;
1066 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1067 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1068 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1069 EDMA3_DVT_dCOUNTER,
1070 EDMA3_DVT_dNONE,
1071 EDMA3_DVT_dNONE));
1072 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1074 /* If parameter checking is enabled... */
1075 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1076 if ((hEdmaResMgr == NULL) || (resObj == NULL))
1077 {
1078 result = (EDMA3_RM_E_INVALID_PARAM);
1079 }
1080 #endif
1082 /* Check if the parameters are OK. */
1083 if (EDMA3_RM_SOK == result)
1084 {
1085 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1086 rmObj = rmInstance->pResMgrObjHandle;
1088 if ((rmObj == NULL) ||
1089 (rmObj->gblCfgParams.globalRegs == NULL))
1090 {
1091 result = (EDMA3_RM_E_INVALID_PARAM);
1092 }
1093 else
1094 {
1095 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1096 edma3Id = rmObj->phyCtrllerInstId;
1097 resId = resObj->resId;
1099 resIdClr = (uint32_t)(~((uint32_t)1U << (resId%32U)));
1100 resIdSet = (1U << (resId%32U));
1102 if ( rmInstance->mapXbarToChan != NULL)
1103 {
1104 xBarEvtBeforeMap = resId;
1105 if ((resId > rmObj->gblCfgParams.numDmaChannels) &&
1106 (resId != EDMA3_RM_RES_ANY) &&
1107 (resObj->type == EDMA3_RM_RES_DMA_CHANNEL))
1108 {
1109 result = rmInstance->mapXbarToChan(xBarEvtBeforeMap,
1110 &resObj->resId,
1111 &rmInstance->rmXbarToEvtMapConfig);
1112 if (EDMA3_RM_SOK == result)
1113 {
1114 resId = resObj->resId;
1115 mapXbarEvtToChanFlag = TRUE;
1116 }
1117 }
1118 }
1120 if (result == EDMA3_RM_SOK)
1121 {
1122 /**
1123 * Take the instance specific semaphore, to prevent simultaneous
1124 * access to the shared resources.
1125 */
1126 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
1127 EDMA3_OSSEM_NO_TIMEOUT);
1128 if (EDMA3_RM_SOK == semResult)
1129 {
1130 switch (resObj->type)
1131 {
1132 case EDMA3_RM_RES_DMA_CHANNEL :
1133 {
1134 if (resId == EDMA3_RM_RES_ANY)
1135 {
1136 for (avlblIdx=0U;
1137 avlblIdx <
1138 rmObj->gblCfgParams.numDmaChannels;
1139 ++avlblIdx)
1140 {
1141 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[avlblIdx/32U])
1142 &
1143 (rmInstance->avlblDmaChannels[avlblIdx/32U])
1144 &
1145 ~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[avlblIdx/32U])
1146 &
1147 ((uint32_t)1U << (avlblIdx%32U))) != FALSE)
1148 {
1149 /*
1150 * Match found.
1151 * A resource which is owned by this instance of the
1152 * Resource Manager and which is presently available
1153 * and which has not been reserved - is found.
1154 */
1155 resObj->resId = avlblIdx;
1156 /*
1157 * Mark the 'match found' resource as "Not Available"
1158 * for future requests
1159 */
1160 rmInstance->avlblDmaChannels[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
1162 /**
1163 * Check if the register modification flag is
1164 * set or not.
1165 */
1166 if (TRUE == rmInstance->regModificationRequired)
1167 {
1168 /**
1169 * Enable the DMA channel in the
1170 * DRAE/DRAEH registers also.
1171 */
1172 if (avlblIdx < 32U)
1173 {
1174 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1175 |= ((uint32_t)0x1U << avlblIdx);
1176 }
1177 else
1178 {
1179 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1180 |= ((uint32_t)0x1U << (avlblIdx - 32U));
1181 }
1182 }
1184 result = EDMA3_RM_SOK;
1185 break;
1186 }
1187 }
1188 /*
1189 * If none of the owned resources of this type is available
1190 * then report "All Resources of this type not available" error
1191 */
1192 if (avlblIdx == rmObj->gblCfgParams.numDmaChannels)
1193 {
1194 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1195 }
1196 }
1197 else
1198 {
1199 if (resId < rmObj->gblCfgParams.numDmaChannels)
1200 {
1201 /*
1202 * Check if specified resource is owned
1203 * by this instance of the resource manager
1204 */
1205 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resId/32U])&(resIdSet))!=FALSE)
1206 {
1207 /* Now check if specified resource is available presently*/
1208 if (((rmInstance->avlblDmaChannels[resId/32U])&(resIdSet))!=FALSE)
1209 {
1210 /*
1211 * Mark the specified channel as "Not Available"
1212 * for future requests
1213 */
1214 rmInstance->avlblDmaChannels[resId/32U] &= resIdClr;
1216 /**
1217 * Check if the register modification flag is
1218 * set or not.
1219 */
1220 if (TRUE == rmInstance->regModificationRequired)
1221 {
1222 if (resId < 32U)
1223 {
1224 rmInstance->shadowRegs->EECR = (1UL << resId);
1226 /**
1227 * Enable the DMA channel in the
1228 * DRAE registers also.
1229 */
1230 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1231 |= ((uint32_t)0x1U << resId);
1232 }
1233 else
1234 {
1235 rmInstance->shadowRegs->EECRH = (1UL << resId);
1237 /**
1238 * Enable the DMA channel in the
1239 * DRAEH registers also.
1240 */
1241 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1242 |= ((uint32_t)0x1U << (resId - 32U));
1243 }
1244 }
1246 result = EDMA3_RM_SOK;
1247 }
1248 else
1249 {
1250 /* Specified resource is owned but is already booked */
1251 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1252 }
1253 }
1254 else
1255 {
1256 /*
1257 * Specified resource is not owned by this instance
1258 * of the Resource Manager
1259 */
1260 result = EDMA3_RM_E_RES_NOT_OWNED;
1261 }
1262 }
1263 else
1264 {
1265 result = EDMA3_RM_E_INVALID_PARAM;
1266 }
1267 }
1268 }
1269 break;
1271 case EDMA3_RM_RES_QDMA_CHANNEL :
1272 {
1273 if (resId == EDMA3_RM_RES_ANY)
1274 {
1275 for (avlblIdx=0U; avlblIdx<rmObj->gblCfgParams.numQdmaChannels; ++avlblIdx)
1276 {
1277 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[avlblIdx/32U])
1278 &
1279 (rmInstance->avlblQdmaChannels[avlblIdx/32U])
1280 &
1281 ~(rmInstance->initParam.rmInstInitConfig->resvdQdmaChannels[avlblIdx/32U])
1282 &
1283 ((uint32_t)1U << (avlblIdx%32U))) != FALSE)
1284 {
1285 resObj->resId = avlblIdx;
1286 rmInstance->avlblQdmaChannels[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
1288 /**
1289 * Check if the register modification flag is
1290 * set or not.
1291 */
1292 if (TRUE == rmInstance->regModificationRequired)
1293 {
1294 /**
1295 * Enable the QDMA channel in the
1296 * QRAE register also.
1297 */
1298 gblRegs->QRAE[rmInstance->initParam.regionId]
1299 |= ((uint32_t)0x1U << avlblIdx);
1300 }
1302 result = EDMA3_RM_SOK;
1303 break;
1304 }
1305 }
1306 /*
1307 * If none of the owned resources of this type is available
1308 * then report "All Resources of this type not available" error
1309 */
1310 if (avlblIdx == rmObj->gblCfgParams.numQdmaChannels)
1311 {
1312 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1313 }
1314 }
1315 else
1316 {
1317 if (resId < rmObj->gblCfgParams.numQdmaChannels)
1318 {
1319 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32U])&(resIdSet))!=FALSE)
1320 {
1321 if (((rmInstance->avlblQdmaChannels [resId/32U])&(resIdSet))!=FALSE)
1322 {
1323 rmInstance->avlblQdmaChannels [resId/32U] &= resIdClr;
1325 /**
1326 * Check if the register modification flag is
1327 * set or not.
1328 */
1329 if (TRUE == rmInstance->regModificationRequired)
1330 {
1331 /**
1332 * Enable the QDMA channel in the
1333 * QRAE register also.
1334 */
1335 gblRegs->QRAE[rmInstance->initParam.regionId]
1336 |= ((uint32_t)0x1U << resId);
1337 }
1339 result = EDMA3_RM_SOK;
1340 }
1341 else
1342 {
1343 /* Specified resource is owned but is already booked */
1344 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1345 }
1346 }
1347 else
1348 {
1349 /*
1350 * Specified resource is not owned by this instance
1351 * of the Resource Manager
1352 */
1353 result = EDMA3_RM_E_RES_NOT_OWNED;
1354 }
1355 }
1356 else
1357 {
1358 result = EDMA3_RM_E_INVALID_PARAM;
1359 }
1360 }
1361 }
1362 break;
1364 case EDMA3_RM_RES_TCC :
1365 {
1366 if (resId == EDMA3_RM_RES_ANY)
1367 {
1368 for (avlblIdx=0U; avlblIdx<rmObj->gblCfgParams.numTccs; ++avlblIdx)
1369 {
1370 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [avlblIdx/32U])
1371 & (rmInstance->avlblTccs [avlblIdx/32U])
1372 & ~(rmInstance->initParam.rmInstInitConfig->resvdTccs [avlblIdx/32U])
1373 & ((uint32_t)1U << (avlblIdx%32U)))!=FALSE)
1374 {
1375 resObj->resId = avlblIdx;
1376 rmInstance->avlblTccs [avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
1378 /**
1379 * Check if the register modification flag is
1380 * set or not.
1381 */
1382 if (TRUE == rmInstance->regModificationRequired)
1383 {
1384 /**
1385 * Enable the Interrupt channel in the
1386 * DRAE/DRAEH registers also.
1387 * Also, If the region id coming from this
1388 * RM instance is same as the Master RM
1389 * Instance's region id, only then we will be
1390 * getting the interrupts on the same side.
1391 * So save the TCC in the allocatedTCCs[] array.
1392 */
1393 if (avlblIdx < 32U)
1394 {
1395 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1396 |= ((uint32_t)0x1U << avlblIdx);
1398 /**
1399 * Do not modify this global array if the register
1400 * modificatio flag is not set.
1401 * Reason being is based on this flag, the IPR/ICR
1402 * or error bit is cleared in the completion or
1403 * error handler ISR.
1404 */
1405 if (edma3RegionId == rmInstance->initParam.regionId)
1406 {
1407 allocatedTCCs[edma3Id][0U] |= ((uint32_t)0x1U << avlblIdx);
1408 }
1409 }
1410 else
1411 {
1412 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1413 |= ((uint32_t)0x1U << (avlblIdx - 32U));
1415 /**
1416 * Do not modify this global array if the register
1417 * modificatio flag is not set.
1418 * Reason being is based on this flag, the IPR/ICR
1419 * or error bit is cleared in the completion or
1420 * error handler ISR.
1421 */
1422 if (edma3RegionId == rmInstance->initParam.regionId)
1423 {
1424 allocatedTCCs[edma3Id][1U] |= ((uint32_t)0x1U << (avlblIdx - 32U));
1425 }
1426 }
1427 }
1430 result = EDMA3_RM_SOK;
1431 break;
1432 }
1433 }
1434 /*
1435 * If none of the owned resources of this type is available
1436 * then report "All Resources of this type not available" error
1437 */
1438 if ( avlblIdx == rmObj->gblCfgParams.numTccs)
1439 {
1440 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1441 }
1442 }
1443 else
1444 {
1445 if (resId < rmObj->gblCfgParams.numTccs)
1446 {
1447 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32U])&(resIdSet))!=FALSE)
1448 {
1449 if (((rmInstance->avlblTccs [resId/32U])&(resIdSet))!=FALSE)
1450 {
1451 rmInstance->avlblTccs [resId/32U] &= resIdClr;
1453 /**
1454 * Check if the register modification flag is
1455 * set or not.
1456 */
1457 if (TRUE == rmInstance->regModificationRequired)
1458 {
1459 /**
1460 * Enable the Interrupt channel in the
1461 * DRAE/DRAEH registers also.
1462 * Also, If the region id coming from this
1463 * RM instance is same as the Master RM
1464 * Instance's region id, only then we will be
1465 * getting the interrupts on the same side.
1466 * So save the TCC in the allocatedTCCs[] array.
1467 */
1468 if (resId < 32U)
1469 {
1470 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1471 |= ((uint32_t)0x1U << resId);
1473 /**
1474 * Do not modify this global array if the register
1475 * modificatio flag is not set.
1476 * Reason being is based on this flag, the IPR/ICR
1477 * or error bit is cleared in the completion or
1478 * error handler ISR.
1479 */
1480 if (edma3RegionId == rmInstance->initParam.regionId)
1481 {
1482 allocatedTCCs[edma3Id][0U] |= ((uint32_t)0x1U << resId);
1483 }
1484 }
1485 else
1486 {
1487 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1488 |= ((uint32_t)0x1U << (resId - 32U));
1490 /**
1491 * Do not modify this global array if the register
1492 * modificatio flag is not set.
1493 * Reason being is based on this flag, the IPR/ICR
1494 * or error bit is cleared in the completion or
1495 * error handler ISR.
1496 */
1497 if (edma3RegionId == rmInstance->initParam.regionId)
1498 {
1499 allocatedTCCs[edma3Id][1U] |= ((uint32_t)0x1U << (resId - 32U));
1500 }
1501 }
1502 }
1504 result = EDMA3_RM_SOK;
1505 }
1506 else
1507 {
1508 /* Specified resource is owned but is already booked */
1509 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1510 }
1511 }
1512 else
1513 {
1514 /*
1515 * Specified resource is not owned by this instance
1516 * of the Resource Manager
1517 */
1518 result = EDMA3_RM_E_RES_NOT_OWNED;
1519 }
1520 }
1521 else
1522 {
1523 result = EDMA3_RM_E_INVALID_PARAM;
1524 }
1525 }
1526 }
1527 break;
1529 case EDMA3_RM_RES_PARAM_SET :
1530 {
1531 if (resId == EDMA3_RM_RES_ANY)
1532 {
1533 for (avlblIdx=0U; avlblIdx<rmObj->gblCfgParams.numPaRAMSets; ++avlblIdx)
1534 {
1535 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [avlblIdx/32U])
1536 &
1537 (rmInstance->avlblPaRAMSets [avlblIdx/32U])
1538 &
1539 ~(rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets [avlblIdx/32U])
1540 &
1541 ((uint32_t)1U << (avlblIdx%32U)))!=FALSE)
1542 {
1543 resObj->resId = avlblIdx;
1544 rmInstance->avlblPaRAMSets [avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
1546 /**
1547 * Also, make the actual PARAM Set NULL, checking the flag
1548 * whether it is required or not.
1549 */
1550 if ((TRUE == rmInstance->regModificationRequired)
1551 && (TRUE == rmInstance->paramInitRequired))
1552 {
1553 edma3MemZero((void *)(&gblRegs->PARAMENTRY[avlblIdx]),
1554 sizeof(gblRegs->PARAMENTRY[avlblIdx]));
1555 }
1557 result = EDMA3_RM_SOK;
1558 break;
1559 }
1560 }
1561 /*
1562 * If none of the owned resources of this type is available
1563 * then report "All Resources of this type not available" error
1564 */
1565 if ( avlblIdx == rmObj->gblCfgParams.numPaRAMSets)
1566 {
1567 result = EDMA3_RM_E_ALL_RES_NOT_AVAILABLE;
1568 }
1569 }
1570 else
1571 {
1572 if (resId < rmObj->gblCfgParams.numPaRAMSets)
1573 {
1574 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32U])&(resIdSet))!=FALSE)
1575 {
1576 if (((rmInstance->avlblPaRAMSets [resId/32U])&(resIdSet)) !=FALSE)
1577 {
1578 rmInstance->avlblPaRAMSets [resId/32U] &= resIdClr;
1580 /**
1581 * Also, make the actual PARAM Set NULL, checking the flag
1582 * whether it is required or not.
1583 */
1584 if ((TRUE == rmInstance->regModificationRequired)
1585 && (TRUE == rmInstance->paramInitRequired))
1586 {
1587 edma3MemZero((void *)(&gblRegs->PARAMENTRY[resId]),
1588 sizeof(gblRegs->PARAMENTRY[resId]));
1589 }
1591 result = EDMA3_RM_SOK;
1592 }
1593 else
1594 {
1595 /* Specified resource is owned but is already booked */
1596 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
1597 }
1598 }
1599 else
1600 {
1601 /*
1602 * Specified resource is not owned by this instance
1603 * of the Resource Manager
1604 */
1605 result = EDMA3_RM_E_RES_NOT_OWNED;
1606 }
1607 }
1608 else
1609 {
1610 result = EDMA3_RM_E_INVALID_PARAM;
1611 }
1612 }
1613 }
1614 break;
1616 default:
1617 result = EDMA3_RM_E_INVALID_PARAM;
1618 break;
1619 }
1621 /* Return the semaphore back */
1622 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
1623 }
1624 }
1625 }
1626 }
1628 /**
1629 * Check the Resource Allocation Result 'result' first. If Resource
1630 * Allocation has resulted in an error, return it (having more priority than
1631 * semResult.
1632 * Else, return semResult.
1633 */
1634 if (EDMA3_RM_SOK == result)
1635 {
1636 /**
1637 * Resource Allocation successful, return semResult for returning
1638 * semaphore.
1639 */
1640 result = semResult;
1641 if ((rmInstance->configScrMapXbarToEvt != NULL) &&
1642 (mapXbarEvtToChanFlag == TRUE))
1643 {
1644 rmInstance->configScrMapXbarToEvt(xBarEvtBeforeMap, resObj->resId);
1645 }
1646 }
1648 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1649 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1650 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1651 EDMA3_DVT_dCOUNTER,
1652 EDMA3_DVT_dNONE,
1653 EDMA3_DVT_dNONE));
1654 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1656 return result;
1657 }
1659 EDMA3_RM_Result EDMA3_RM_freeResource(EDMA3_RM_Handle hEdmaResMgr,
1660 const EDMA3_RM_ResDesc *resObj)
1661 {
1662 EDMA3_RM_Instance *rmInstance = NULL;
1663 EDMA3_RM_Obj *rmObj = NULL;
1664 EDMA3_RM_Result result = EDMA3_RM_SOK;
1665 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
1666 uint32_t resId;
1667 uint32_t resIdSet = 0x0;
1668 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1669 uint32_t edma3Id;
1671 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1672 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1673 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1674 EDMA3_DVT_dCOUNTER,
1675 EDMA3_DVT_dNONE,
1676 EDMA3_DVT_dNONE));
1677 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1679 /* If parameter checking is enabled... */
1680 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1681 if ((hEdmaResMgr == NULL) || (resObj == NULL))
1682 {
1683 result = EDMA3_RM_E_INVALID_PARAM;
1684 }
1685 #endif
1687 /* Check if the parameters are OK. */
1688 if (EDMA3_RM_SOK == result)
1689 {
1690 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
1691 rmObj = rmInstance->pResMgrObjHandle;
1693 if ((rmObj == NULL) ||
1694 (rmObj->gblCfgParams.globalRegs == NULL))
1695 {
1696 result = EDMA3_RM_E_INVALID_PARAM;
1697 }
1698 else
1699 {
1700 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
1701 edma3Id = rmObj->phyCtrllerInstId;
1702 resId = resObj->resId;
1704 resIdSet = 1U << (resId%32U);
1706 /**
1707 * Take the instance specific semaphore, to prevent simultaneous
1708 * access to the shared resources.
1709 */
1710 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
1711 EDMA3_OSSEM_NO_TIMEOUT);
1713 if (EDMA3_RM_SOK == semResult)
1714 {
1715 switch (resObj->type)
1716 {
1717 case EDMA3_RM_RES_DMA_CHANNEL :
1718 {
1719 if ((resId < rmObj->gblCfgParams.numDmaChannels) && ((resId/32U) < 2))
1720 {
1721 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels [resId/32U]) & (resIdSet))!=FALSE)
1722 {
1723 if (((~(rmInstance->avlblDmaChannels[resId/32U]))&(resIdSet))!=FALSE)
1724 {
1725 /*
1726 * Mark the specified channel as "Available"
1727 * for future requests
1728 */
1729 rmInstance->avlblDmaChannels[resId/32U] |= resIdSet;
1731 /**
1732 * Check if the register modification flag is
1733 * set or not.
1734 */
1735 if (TRUE == rmInstance->regModificationRequired)
1736 {
1737 /**
1738 * DMA Channel is freed.
1739 * Reset the bit specific to the DMA channel
1740 * in the DRAE/DRAEH register also.
1741 */
1742 if (resId < 32U)
1743 {
1744 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1745 &= (~((uint32_t)0x1U << resId));
1746 }
1747 else
1748 {
1749 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1750 &= (~((uint32_t)0x1U << (resId-32U)));
1751 }
1752 }
1754 result = EDMA3_RM_SOK;
1755 }
1756 else
1757 {
1758 result = EDMA3_RM_E_RES_ALREADY_FREE;
1759 }
1760 }
1761 else
1762 {
1763 /*
1764 * Specified resource is not owned by this instance
1765 * of the Resource Manager
1766 */
1767 result = EDMA3_RM_E_RES_NOT_OWNED;
1768 }
1769 }
1770 else
1771 {
1772 result = EDMA3_RM_E_INVALID_PARAM;
1773 }
1774 }
1775 break;
1777 case EDMA3_RM_RES_QDMA_CHANNEL :
1778 {
1779 if (resId < rmObj->gblCfgParams.numQdmaChannels)
1780 {
1781 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels [resId/32U]) & (resIdSet))!=FALSE)
1782 {
1783 if (((~(rmInstance->avlblQdmaChannels [resId/32U])) & (resIdSet))!=FALSE)
1784 {
1785 rmInstance->avlblQdmaChannels [resId/32U] |= resIdSet;
1787 /**
1788 * Check if the register modification flag is
1789 * set or not.
1790 */
1791 if (TRUE == rmInstance->regModificationRequired)
1792 {
1793 /**
1794 * QDMA Channel is freed.
1795 * Reset the bit specific to the QDMA channel
1796 * in the QRAE register also.
1797 */
1798 gblRegs->QRAE[rmInstance->initParam.regionId]
1799 &= (~((uint32_t)0x1U << resId));
1800 }
1802 result = EDMA3_RM_SOK;
1803 }
1804 else
1805 {
1806 result = EDMA3_RM_E_RES_ALREADY_FREE;
1807 }
1808 }
1809 else
1810 {
1811 /*
1812 * Specified resource is not owned by this instance
1813 * of the Resource Manager
1814 */
1815 result = EDMA3_RM_E_RES_NOT_OWNED;
1816 }
1817 }
1818 else
1819 {
1820 result = EDMA3_RM_E_INVALID_PARAM;
1821 }
1822 }
1823 break;
1825 case EDMA3_RM_RES_TCC :
1826 {
1827 if (resId < rmObj->gblCfgParams.numTccs)
1828 {
1829 if (((rmInstance->initParam.rmInstInitConfig->ownTccs [resId/32U]) & (resIdSet))!=FALSE)
1830 {
1831 if (((~(rmInstance->avlblTccs [resId/32U])) & (resIdSet))!=FALSE)
1832 {
1833 rmInstance->avlblTccs [resId/32U] |= resIdSet;
1835 /**
1836 * Check if the register modification flag is
1837 * set or not.
1838 */
1839 if (TRUE == rmInstance->regModificationRequired)
1840 {
1841 /**
1842 * Interrupt Channel is freed.
1843 * Reset the bit specific to the Interrupt
1844 * channel in the DRAE/DRAEH register also.
1845 * Also, if we have earlier saved this
1846 * TCC in allocatedTCCs[] array,
1847 * remove it from there too.
1848 */
1849 if (resId < 32U)
1850 {
1851 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
1852 &= (~((uint32_t)0x1U << resId));
1854 if (edma3RegionId == rmInstance->initParam.regionId)
1855 {
1856 allocatedTCCs[edma3Id][0U] &= (~((uint32_t)0x1U << resId));
1857 }
1858 }
1859 else
1860 {
1861 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
1862 &= (~((uint32_t)0x1U << (resId-32U)));
1864 if (edma3RegionId == rmInstance->initParam.regionId)
1865 {
1866 allocatedTCCs[edma3Id][1U] &= (~((uint32_t)0x1U << (resId -32U)));
1867 }
1868 }
1869 }
1871 result = EDMA3_RM_SOK;
1872 }
1873 else
1874 {
1875 result = EDMA3_RM_E_RES_ALREADY_FREE;
1876 }
1877 }
1878 else
1879 {
1880 /*
1881 * Specified resource is not owned by this instance
1882 * of the Resource Manager
1883 */
1884 result = EDMA3_RM_E_RES_NOT_OWNED;
1885 }
1886 }
1887 else
1888 {
1889 result = EDMA3_RM_E_INVALID_PARAM;
1890 }
1891 }
1892 break;
1894 case EDMA3_RM_RES_PARAM_SET :
1895 {
1896 if (resId < rmObj->gblCfgParams.numPaRAMSets)
1897 {
1898 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets [resId/32U])&(resIdSet))!=FALSE)
1899 {
1900 if (((~(rmInstance->avlblPaRAMSets [resId/32U]))&(resIdSet))!=FALSE)
1901 {
1902 rmInstance->avlblPaRAMSets [resId/32U] |= resIdSet;
1904 result = EDMA3_RM_SOK;
1905 }
1906 else
1907 {
1908 result = EDMA3_RM_E_RES_ALREADY_FREE;
1909 }
1910 }
1911 else
1912 {
1913 /*
1914 * Specified resource is not owned by this instance
1915 * of the Resource Manager
1916 */
1917 result = EDMA3_RM_E_RES_NOT_OWNED;
1918 }
1919 }
1920 else
1921 {
1922 result = EDMA3_RM_E_INVALID_PARAM;
1923 }
1924 }
1925 break;
1927 default:
1928 result = EDMA3_RM_E_INVALID_PARAM;
1929 break;
1930 }
1931 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
1932 }
1933 }
1934 }
1936 /**
1937 * Check the Free Resource Result 'result' first. If Free Resource
1938 * has resulted in an error, return it (having more priority than
1939 * semResult.
1940 * Else, return semResult.
1941 */
1942 if (EDMA3_RM_SOK == result)
1943 {
1944 /**
1945 * Free Resource successful, return semResult for returning
1946 * semaphore.
1947 */
1948 result = semResult;
1949 }
1951 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1952 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1953 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
1954 EDMA3_DVT_dCOUNTER,
1955 EDMA3_DVT_dNONE,
1956 EDMA3_DVT_dNONE));
1957 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1959 return result;
1960 }
1962 EDMA3_RM_Result EDMA3_RM_allocLogicalChannel(EDMA3_RM_Handle hEdmaResMgr,
1963 EDMA3_RM_ResDesc *lChObj,
1964 uint32_t *pParam,
1965 uint32_t *pTcc)
1966 {
1967 EDMA3_RM_ResDesc *chObj;
1968 EDMA3_RM_ResDesc resObj;
1969 EDMA3_RM_Result result = EDMA3_RM_SOK;
1970 EDMA3_RM_Instance *rmInstance = NULL;
1971 EDMA3_RM_Obj *rmObj = NULL;
1972 uint32_t mappedPaRAMId=0U;
1973 uint32_t mappedTcc = EDMA3_RM_CH_NO_TCC_MAP;
1974 int32_t paRAMId = (int32_t)EDMA3_RM_RES_ANY;
1975 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
1976 uint32_t qdmaChId = EDMA3_MAX_PARAM_SETS;
1977 uint32_t edma3Id;
1979 #ifdef EDMA3_INSTRUMENTATION_ENABLED
1980 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
1981 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
1982 EDMA3_DVT_dCOUNTER,
1983 EDMA3_DVT_dNONE,
1984 EDMA3_DVT_dNONE));
1985 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
1987 /* If parameter checking is enabled... */
1988 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
1989 if ((lChObj == NULL) || (hEdmaResMgr == NULL))
1990 {
1991 result = EDMA3_RM_E_INVALID_PARAM;
1992 }
1993 #endif
1995 /* Check if the parameters are OK. */
1996 if (EDMA3_RM_SOK == result)
1997 {
1998 chObj = lChObj;
2000 if ((chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
2001 || (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL))
2002 {
2003 /**
2004 * If the request is for a DMA or QDMA channel, check the
2005 * pParam and pTcc objects also.
2006 * For the Link channel request, they could be NULL.
2007 */
2008 /* If parameter checking is enabled... */
2009 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2010 if ((pParam == NULL) || (pTcc == NULL))
2011 {
2012 result = EDMA3_RM_E_INVALID_PARAM;
2013 }
2014 #endif
2015 }
2016 }
2018 if (result == EDMA3_RM_SOK)
2019 {
2020 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2022 if (rmInstance == NULL)
2023 {
2024 result = EDMA3_RM_E_INVALID_PARAM;
2025 }
2026 }
2028 if (result == EDMA3_RM_SOK)
2029 {
2030 rmObj = rmInstance->pResMgrObjHandle;
2032 if (rmObj == NULL)
2033 {
2034 result = EDMA3_RM_E_INVALID_PARAM;
2035 }
2036 else
2037 {
2038 if (rmObj->gblCfgParams.globalRegs == NULL)
2039 {
2040 result = EDMA3_RM_E_INVALID_PARAM;
2041 }
2042 }
2043 }
2045 if (result == EDMA3_RM_SOK)
2046 {
2047 edma3Id = rmObj->phyCtrllerInstId;
2048 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2050 switch (chObj->type)
2051 {
2052 case EDMA3_RM_RES_DMA_CHANNEL:
2053 {
2054 if ((chObj->resId == EDMA3_RM_DMA_CHANNEL_ANY)
2055 || (chObj->resId == EDMA3_RM_RES_ANY))
2056 {
2057 /* Request for ANY DMA channel. */
2058 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2059 resObj.resId = EDMA3_RM_RES_ANY;
2060 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2062 if (result == EDMA3_RM_SOK)
2063 {
2064 /* DMA channel allocated successfully. */
2065 chObj->resId = resObj.resId;
2067 /**
2068 * Check the PaRAM Set user has specified for this DMA channel.
2069 * Two cases exist:
2070 * a) DCHMAP exists: Any PaRAM Set can be used
2071 * b) DCHMAP does not exist: Should not be possible
2072 * only if the channel allocated (ANY) and PaRAM requested
2073 * are same.
2074 */
2075 if ((*pParam) == EDMA3_RM_PARAM_ANY)
2076 {
2077 /* User specified ANY PaRAM Set; Check the mapping. */
2078 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2079 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2080 {
2081 /** If some PaRAM set is statically mapped to the returned
2082 * channel number, use that.
2083 */
2084 paRAMId = (int32_t)mappedPaRAMId;
2085 }
2086 }
2087 else
2088 {
2089 /* User specified some PaRAM Set; check that can be used or not. */
2090 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2091 {
2092 paRAMId = (int32_t)(*pParam);
2093 }
2094 else
2095 {
2096 /**
2097 * Channel mapping does not exist. If the PaRAM Set requested
2098 * is the same as dma channel allocated (coincidentally), it is fine.
2099 * Else return error.
2100 */
2101 if ((*pParam) != (resObj.resId))
2102 {
2103 result = EDMA3_RM_E_INVALID_PARAM;
2105 /**
2106 * Free the previously allocated DMA channel also.
2107 */
2108 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2109 }
2110 else
2111 {
2112 paRAMId = (int32_t)(*pParam);
2113 }
2114 }
2115 }
2117 mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[resObj.resId];
2118 }
2119 }
2120 else
2121 {
2122 if (chObj->resId <= edma3_dma_ch_max_val[edma3Id])
2123 {
2124 /* Request for a specific DMA channel */
2125 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2126 resObj.resId = chObj->resId;
2127 result = EDMA3_RM_allocResource(hEdmaResMgr,
2128 (EDMA3_RM_ResDesc *)&resObj);
2130 if (result == EDMA3_RM_SOK)
2131 {
2132 /**
2133 * Check the PaRAM Set user has specified for this DMA channel.
2134 * Two cases exist:
2135 * a) DCHMAP exists: Any PaRAM Set can be used
2136 * b) DCHMAP does not exist: Should not be possible
2137 * only if the channel allocated (ANY) and PaRAM requested
2138 * are same.
2139 */
2140 if ((*pParam) == EDMA3_RM_PARAM_ANY)
2141 {
2142 /* User specified ANY PaRAM Set; Check the mapping. */
2143 mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resObj.resId];
2144 if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
2145 {
2146 /** If some PaRAM set is statically mapped to the returned
2147 * channel number, use that.
2148 */
2149 paRAMId = (int32_t)mappedPaRAMId;
2150 }
2151 }
2152 else
2153 {
2154 /* User specified some PaRAM Set; check that can be used or not. */
2155 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2156 {
2157 paRAMId = (int32_t)(*pParam);
2158 }
2159 else
2160 {
2161 /**
2162 * Channel mapping does not exist. If the PaRAM Set requested
2163 * is the same as dma channel allocated (coincidentally), it is fine.
2164 * Else return error.
2165 */
2166 if ((*pParam) != (resObj.resId))
2167 {
2168 result = EDMA3_RM_E_INVALID_PARAM;
2170 /**
2171 * Free the previously allocated DMA channel also.
2172 */
2173 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2174 }
2175 else
2176 {
2177 paRAMId = (int32_t)(*pParam);
2178 }
2179 }
2180 }
2182 mappedTcc = rmObj->gblCfgParams.dmaChannelTccMap[chObj->resId];
2183 }
2184 }
2185 else
2186 {
2187 result = EDMA3_RM_E_INVALID_PARAM;
2188 }
2189 }
2190 }
2191 break;
2194 case EDMA3_RM_RES_QDMA_CHANNEL:
2195 {
2196 if ((chObj->resId == EDMA3_RM_QDMA_CHANNEL_ANY)
2197 || (chObj->resId == EDMA3_RM_RES_ANY))
2198 {
2199 /* First request for any available QDMA channel */
2200 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2201 resObj.resId = EDMA3_RM_RES_ANY;
2202 result = EDMA3_RM_allocResource(hEdmaResMgr,
2203 (EDMA3_RM_ResDesc *)&resObj);
2205 if (result == EDMA3_RM_SOK)
2206 {
2207 /* Return the actual QDMA channel id. */
2208 chObj->resId = resObj.resId;
2210 /* Save the Logical-QDMA channel id for future use. */
2211 qdmaChId = resObj.resId + edma3_qdma_ch_min_val[edma3Id];
2213 /**
2214 * Check the PaRAM Set user has specified for this QDMA channel.
2215 * If he has specified any particular PaRAM Set, use that.
2216 */
2217 if ((*pParam) != EDMA3_RM_PARAM_ANY)
2218 {
2219 /* User specified ANY PaRAM Set; Check the mapping. */
2220 paRAMId = (int32_t)(*pParam);
2221 }
2222 }
2223 }
2224 else
2225 {
2226 if (chObj->resId < rmObj->gblCfgParams.numQdmaChannels)
2227 {
2228 /* Request for a specific QDMA channel */
2229 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2230 resObj.resId = chObj->resId;
2231 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2233 if (result == EDMA3_RM_SOK)
2234 {
2235 /* Save the Logical-QDMA channel id for future use. */
2236 qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
2238 /**
2239 * Check the PaRAM Set user has specified for this QDMA channel.
2240 * If he has specified any particular PaRAM Set, use that.
2241 */
2242 if ((*pParam) != EDMA3_RM_PARAM_ANY)
2243 {
2244 /* User specified ANY PaRAM Set; Check the mapping. */
2245 paRAMId = (int32_t)(*pParam);
2246 }
2247 }
2248 }
2249 else
2250 {
2251 result = EDMA3_RM_E_INVALID_PARAM;
2252 }
2253 }
2254 }
2255 break;
2257 case EDMA3_RM_RES_PARAM_SET:
2258 {
2259 /* Request for a LINK channel. */
2260 if ((chObj->resId == EDMA3_RM_PARAM_ANY)
2261 || (chObj->resId == EDMA3_RM_RES_ANY))
2262 {
2263 /* Request for ANY LINK channel. */
2264 paRAMId = (int32_t)EDMA3_RM_RES_ANY;
2265 }
2266 else
2267 {
2268 if (chObj->resId < edma3NumPaRAMSets)
2269 {
2270 /* Request for a Specific LINK channel. */
2271 paRAMId = (int32_t)(chObj->resId);
2272 }
2273 else
2274 {
2275 result = EDMA3_RM_E_INVALID_PARAM;
2276 }
2277 }
2279 if (result == EDMA3_RM_SOK)
2280 {
2281 /* Try to allocate the link channel */
2282 resObj.type = EDMA3_RM_RES_PARAM_SET;
2283 resObj.resId = (uint32_t)paRAMId;
2284 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2286 if (result == EDMA3_RM_SOK)
2287 {
2288 uint32_t linkCh = edma3_link_ch_min_val[edma3Id];
2290 /* Return the actual PaRAM Id. */
2291 chObj->resId = resObj.resId;
2293 /*
2294 * Search for the next Link channel place-holder available,
2295 * starting from EDMA3_RM_LINK_CH_MIN_VAL.
2296 * It will be used for future operations on the Link channel.
2297 */
2298 while ((edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId != -1)
2299 && (linkCh <= edma3_link_ch_max_val[edma3Id]))
2300 {
2301 /* Move to the next place-holder. */
2302 linkCh++;
2303 }
2305 /* Verify the returned handle, it should lie in the correct range */
2306 if (linkCh > edma3_link_ch_max_val[edma3Id])
2307 {
2308 result = EDMA3_RM_E_INVALID_PARAM;
2310 /* Free the PaRAM Set now. */
2311 resObj.type = EDMA3_RM_RES_PARAM_SET;
2312 resObj.resId = chObj->resId;
2313 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2314 }
2315 else
2316 {
2317 /* Save the PaRAM Id for the Link Channel. */
2318 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = (int32_t)(chObj->resId);
2320 /**
2321 * Remove any linking. Before doing that, check
2322 * whether it is permitted or not.
2323 */
2324 if (TRUE == rmInstance->regModificationRequired)
2325 {
2326 *((&gblRegs->PARAMENTRY[chObj->resId].OPT)
2327 + (uint32_t)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFU;
2328 }
2329 }
2330 }
2331 }
2332 }
2333 break;
2335 default:
2336 {
2337 result = EDMA3_RM_E_INVALID_PARAM;
2338 break;
2339 }
2340 }
2341 }
2344 if (result == EDMA3_RM_SOK)
2345 {
2346 /**
2347 * For DMA/QDMA channels, we still have to allocate more resources like
2348 * TCC, PaRAM Set etc.
2349 * For Link channel, only the PaRAMSet is required and that has been
2350 * allocated so no further operations required.
2351 */
2353 /* Further resources' allocation for DMA channel. */
2354 if (chObj->type == EDMA3_RM_RES_DMA_CHANNEL)
2355 {
2356 /* First allocate a PaRAM Set */
2357 resObj.type = EDMA3_RM_RES_PARAM_SET;
2358 /* Use the saved param id now. */
2359 resObj.resId = (uint32_t)paRAMId;
2360 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2361 if (result == EDMA3_RM_SOK)
2362 {
2363 /**
2364 * PaRAM Set allocation succeeded.
2365 * Save the PaRAM Set first.
2366 */
2367 *pParam = resObj.resId;
2368 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = (int32_t)(resObj.resId);
2370 /* Allocate the TCC now. */
2371 resObj.type = EDMA3_RM_RES_TCC;
2372 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2373 {
2374 if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2375 {
2376 resObj.resId = EDMA3_RM_RES_ANY;
2377 }
2378 else
2379 {
2380 resObj.resId = mappedTcc;
2381 }
2382 }
2383 else
2384 {
2385 resObj.resId = *pTcc;
2386 }
2388 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2389 if (result == EDMA3_RM_SOK)
2390 {
2391 /* TCC allocation succeeded. Save it first. */
2392 *pTcc = resObj.resId;
2393 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].tcc = resObj.resId;
2395 /**
2396 * Check first whether the global registers and the allocated
2397 * PaRAM Set can be modified or not. If yes, do the needful.
2398 * Else leave this for the user.
2399 */
2400 if (TRUE == rmInstance->regModificationRequired)
2401 {
2402 /* Set TCC of the allocated Param Set. */
2403 gblRegs->PARAMENTRY[*pParam].OPT &= EDMA3_RM_OPT_TCC_CLR_MASK;
2404 gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2406 /**
2407 * Do the mapping between DMA channel and PaRAM Set.
2408 * Do this for the EDMA3 Controllers which have a register for mapping
2409 * DMA Channel to a particular PaRAM Set.
2410 */
2411 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2412 {
2413 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2415 /* Map Parameter RAM Set Number for specified channelId */
2416 gblRegs->DCHMAP[chObj->resId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
2417 gblRegs->DCHMAP[chObj->resId] |= EDMA3_RM_DCH_PARAM_SET_MASK(*pParam);
2418 }
2420 /* Remove any linking */
2421 *((&gblRegs->PARAMENTRY[*pParam].OPT)
2422 + (uint32_t)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFU;
2423 }
2424 }
2425 else
2426 {
2427 /**
2428 * TCC allocation failed, free the previously allocated
2429 * PaRAM Set and DMA channel.
2430 */
2431 resObj.type = EDMA3_RM_RES_PARAM_SET;
2432 resObj.resId = *pParam;
2433 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2435 /* Reset the book-keeping data structure also. */
2436 edma3RmChBoundRes[rmObj->phyCtrllerInstId][chObj->resId].paRAMId = -1;
2438 resObj.type = chObj->type;
2439 resObj.resId = chObj->resId;
2440 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2441 }
2442 }
2443 else
2444 {
2445 /**
2446 * PaRAM Set allocation failed, free the previously allocated
2447 * DMA channel also.
2448 */
2449 resObj.type = chObj->type;
2450 resObj.resId = chObj->resId;
2451 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2452 }
2453 }
2456 /* Further resources' allocation for QDMA channel. */
2457 if (chObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
2458 {
2459 /* First allocate a PaRAM Set */
2460 resObj.type = EDMA3_RM_RES_PARAM_SET;
2461 /* Use the saved param id now. */
2462 resObj.resId = (uint32_t)paRAMId;
2463 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2464 if (result == EDMA3_RM_SOK)
2465 {
2466 /**
2467 * PaRAM Set allocation succeeded.
2468 * Save the PaRAM Set first.
2469 */
2470 *pParam = resObj.resId;
2471 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = (int32_t)(resObj.resId);
2473 /* Allocate the TCC now. */
2474 resObj.type = EDMA3_RM_RES_TCC;
2475 if ((*pTcc) == EDMA3_RM_TCC_ANY)
2476 {
2477 if (mappedTcc == EDMA3_RM_CH_NO_TCC_MAP)
2478 {
2479 resObj.resId = EDMA3_RM_RES_ANY;
2480 }
2481 else
2482 {
2483 resObj.resId = mappedTcc;
2484 }
2485 }
2486 else
2487 {
2488 resObj.resId = *pTcc;
2489 }
2491 result = EDMA3_RM_allocResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2492 if (result == EDMA3_RM_SOK)
2493 {
2494 /* TCC allocation succeeded. Save it first. */
2495 *pTcc = resObj.resId;
2496 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = resObj.resId;
2498 /**
2499 * Check first whether the global registers and the allocated
2500 * PaRAM Set can be modified or not. If yes, do the needful.
2501 * Else leave this for the user.
2502 */
2503 if (TRUE == rmInstance->regModificationRequired)
2504 {
2505 /* Set TCC of the allocated Param Set. */
2506 gblRegs->PARAMENTRY[*pParam].OPT &= EDMA3_RM_OPT_TCC_CLR_MASK;
2507 gblRegs->PARAMENTRY[*pParam].OPT |= EDMA3_RM_OPT_TCC_SET_MASK(*pTcc);
2509 /* Do the mapping between QDMA channel and PaRAM Set. */
2510 /* Map Parameter RAM Set Number for specified channelId */
2511 gblRegs->QCHMAP[chObj->resId]
2512 &= EDMA3_RM_QCH_PARAM_CLR_MASK;
2513 gblRegs->QCHMAP[chObj->resId]
2514 |= EDMA3_RM_QCH_PARAM_SET_MASK(*pParam);
2516 /* Set the Trigger Word */
2517 gblRegs->QCHMAP[chObj->resId]
2518 &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
2519 gblRegs->QCHMAP[chObj->resId]
2520 |= EDMA3_RM_QCH_TRWORD_SET_MASK(EDMA3_RM_QDMA_TRIG_DEFAULT);
2522 /* Remove any linking */
2523 *((&gblRegs->PARAMENTRY[*pParam].OPT)
2524 + (uint32_t)EDMA3_RM_PARAM_ENTRY_LINK_BCNTRLD) = 0xFFFFU;
2526 /* Enable the transfer also. */
2527 rmInstance->shadowRegs->QEESR = (1U << chObj->resId);
2528 }
2529 }
2530 else
2531 {
2532 /**
2533 * TCC allocation failed, free the previously allocated
2534 * PaRAM Set and QDMA channel.
2535 */
2536 resObj.type = EDMA3_RM_RES_PARAM_SET;
2537 resObj.resId = *pParam;
2538 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2540 /* Reset the book-keeping data structure also. */
2541 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
2543 resObj.type = chObj->type;
2544 resObj.resId = chObj->resId;
2545 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2546 }
2547 }
2548 else
2549 {
2550 /**
2551 * PaRAM Set allocation failed, free the previously allocated
2552 * QDMA channel also.
2553 */
2554 resObj.type = chObj->type;
2555 resObj.resId = chObj->resId;
2556 EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2557 }
2558 }
2559 }
2562 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2563 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2564 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2565 EDMA3_DVT_dCOUNTER,
2566 EDMA3_DVT_dNONE,
2567 EDMA3_DVT_dNONE));
2568 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2571 return result;
2572 }
2574 EDMA3_RM_Result EDMA3_RM_freeLogicalChannel (EDMA3_RM_Handle hEdmaResMgr,
2575 EDMA3_RM_ResDesc *lChObj)
2576 {
2577 EDMA3_RM_ResDesc *chObj;
2578 EDMA3_RM_ResDesc resObj;
2579 EDMA3_RM_Result result = EDMA3_RM_SOK;
2580 EDMA3_RM_Instance *rmInstance = NULL;
2581 EDMA3_RM_Obj *rmObj = NULL;
2582 int32_t paRAMId;
2583 uint32_t tcc;
2584 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
2585 uint32_t qdmaChId;
2586 uint32_t dmaChId;
2587 EDMA3_RM_InstanceInitConfig *rmConfig = NULL;
2588 uint32_t edma3Id;
2590 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2591 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2592 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2593 EDMA3_DVT_dCOUNTER,
2594 EDMA3_DVT_dNONE,
2595 EDMA3_DVT_dNONE));
2596 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2599 /* If parameter checking is enabled... */
2600 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2601 if ((lChObj == NULL) || (hEdmaResMgr == NULL))
2602 {
2603 result = (EDMA3_RM_E_INVALID_PARAM);
2604 }
2605 #endif
2607 /* Check if the parameters are OK. */
2608 if (result == EDMA3_RM_SOK)
2609 {
2610 chObj = lChObj;
2612 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2614 if (rmInstance == NULL)
2615 {
2616 result = EDMA3_RM_E_INVALID_PARAM;
2617 }
2618 }
2620 if (result == EDMA3_RM_SOK)
2621 {
2622 rmConfig = rmInstance->initParam.rmInstInitConfig;
2623 rmObj = rmInstance->pResMgrObjHandle;
2625 if (rmObj == NULL)
2626 {
2627 result = EDMA3_RM_E_INVALID_PARAM;
2628 }
2629 else
2630 {
2631 if (rmObj->gblCfgParams.globalRegs == NULL)
2632 {
2633 result = EDMA3_RM_E_INVALID_PARAM;
2634 }
2635 else
2636 {
2637 edma3Id = rmObj->phyCtrllerInstId;
2638 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2639 }
2640 }
2641 }
2644 if (result == EDMA3_RM_SOK)
2645 {
2646 switch (chObj->type)
2647 {
2648 case EDMA3_RM_RES_DMA_CHANNEL:
2649 {
2650 /* Save the DMA channel first. */
2651 dmaChId = chObj->resId;
2653 /**
2654 * Validate DMA channel id first.
2655 * It should be a valid channel id.
2656 */
2657 if (dmaChId >= EDMA3_MAX_DMA_CH)
2658 {
2659 result = EDMA3_RM_E_INVALID_PARAM;
2660 }
2662 /* It should be owned and allocated by this RM only. */
2663 if (result == EDMA3_RM_SOK)
2664 {
2665 if (((rmConfig->ownDmaChannels[dmaChId/32U])
2666 &
2667 (~(rmInstance->avlblDmaChannels[dmaChId/32U]))
2668 &
2669 ((uint32_t)1U << (dmaChId%32U))) != FALSE)
2670 {
2671 /** Perfectly valid channel id.
2672 * Clear some channel specific registers, if it is permitted.
2673 */
2674 if (TRUE == rmInstance->regModificationRequired)
2675 {
2676 if (dmaChId < 32U)
2677 {
2678 if((rmInstance->shadowRegs->SER & ((uint32_t)1U<<dmaChId))!=FALSE)
2679 {
2680 rmInstance->shadowRegs->SECR = (1U<<dmaChId);
2681 }
2682 if((globalRegs->EMR & ((uint32_t)1U<<dmaChId))!=FALSE)
2683 {
2684 globalRegs->EMCR = (1U<<dmaChId);
2685 }
2686 }
2687 else
2688 {
2689 if((rmInstance->shadowRegs->SERH & ((uint32_t)1U<<(dmaChId-32U)))!=FALSE)
2690 {
2691 rmInstance->shadowRegs->SECRH = (1U<<(dmaChId-32U));
2692 }
2693 if((globalRegs->EMRH & ((uint32_t)1U<<(dmaChId-32U)))!=FALSE)
2694 {
2695 globalRegs->EMCRH = (1U<<(dmaChId-32U));
2696 }
2697 }
2699 /* Clear DCHMAP register also. */
2700 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
2701 {
2702 globalRegs->DCHMAP[dmaChId] &=
2703 EDMA3_RM_DCH_PARAM_CLR_MASK;
2704 }
2705 }
2707 /* Free the PaRAM Set Now. */
2708 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].paRAMId;
2709 resObj.type = EDMA3_RM_RES_PARAM_SET;
2710 resObj.resId = (uint32_t)paRAMId;
2711 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2712 }
2713 else
2714 {
2715 /* Channel id has some problem. */
2716 result = EDMA3_RM_E_INVALID_PARAM;
2717 }
2718 }
2721 if (result == EDMA3_RM_SOK)
2722 {
2723 /* PaRAM Set Freed */
2724 edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].paRAMId = -1;
2726 /* Free the TCC */
2727 tcc = edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].tcc;
2728 resObj.type = EDMA3_RM_RES_TCC;
2729 resObj.resId = tcc;
2730 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2731 }
2733 if (result == EDMA3_RM_SOK)
2734 {
2735 /* TCC Freed */
2736 edma3RmChBoundRes[rmObj->phyCtrllerInstId][dmaChId].tcc = EDMA3_MAX_TCC;
2738 /**
2739 * Try to free the DMA Channel now. DMA Channel should
2740 * be freed only in the end because while freeing, DRAE
2741 * registers will be RESET.
2742 * After that, no shadow region specific DMA channel
2743 * register can be modified. So reset that DRAE register
2744 * ONLY in the end.
2745 */
2746 resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
2747 resObj.resId = dmaChId;
2748 result = EDMA3_RM_freeResource(hEdmaResMgr,
2749 (EDMA3_RM_ResDesc *)&resObj);
2750 }
2751 }
2752 break;
2755 case EDMA3_RM_RES_QDMA_CHANNEL:
2756 {
2757 /**
2758 * Calculate QDMA Logical Channel Id first.
2759 * User has given the actual QDMA channel id.
2760 * So we have to convert it to make the logical
2761 * QDMA channel id first.
2762 */
2763 qdmaChId = chObj->resId + edma3_qdma_ch_min_val[edma3Id];
2765 /**
2766 * Validate QDMA channel id first.
2767 * It should be a valid channel id.
2768 */
2769 if (chObj->resId >= EDMA3_MAX_QDMA_CH)
2770 {
2771 result = EDMA3_RM_E_INVALID_PARAM;
2772 }
2774 /* It should be owned and allocated by this RM only. */
2775 if (result == EDMA3_RM_SOK)
2776 {
2777 if (((rmConfig->ownQdmaChannels[0U])
2778 &
2779 (~(rmInstance->avlblQdmaChannels[0U]))
2780 &
2781 ((uint32_t)1U << chObj->resId)) != FALSE)
2782 {
2783 /** Perfectly valid channel id.
2784 * Clear some channel specific registers, if
2785 * it is permitted.
2786 */
2787 if (TRUE == rmInstance->regModificationRequired)
2788 {
2789 rmInstance->shadowRegs->QEECR = (1U<<chObj->resId);
2791 if((globalRegs->QEMR & ((uint32_t)1U<<chObj->resId))!=FALSE)
2792 {
2793 globalRegs->QEMCR = (1U<<chObj->resId);
2794 }
2796 /* Unmap PARAM Set Number for specified channelId */
2797 globalRegs->QCHMAP[chObj->resId] &=
2798 EDMA3_RM_QCH_PARAM_CLR_MASK;
2800 /* Reset the Trigger Word */
2801 globalRegs->QCHMAP[chObj->resId] &=
2802 EDMA3_RM_QCH_TRWORD_CLR_MASK;
2803 }
2805 /* Free the PaRAM Set now */
2806 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId;
2807 resObj.type = EDMA3_RM_RES_PARAM_SET;
2808 resObj.resId = (int32_t)paRAMId;
2809 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2810 }
2811 else
2812 {
2813 /* Channel id has some problem. */
2814 result = EDMA3_RM_E_INVALID_PARAM;
2815 }
2816 }
2819 if (result == EDMA3_RM_SOK)
2820 {
2821 /* PaRAM Set Freed */
2822 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId = -1;
2824 /* Free the TCC */
2825 tcc = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc;
2826 resObj.type = EDMA3_RM_RES_TCC;
2827 resObj.resId = tcc;
2828 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2829 }
2831 if (result == EDMA3_RM_SOK)
2832 {
2833 /* TCC Freed */
2834 edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].tcc = EDMA3_MAX_TCC;
2836 /**
2837 * Try to free the QDMA Channel now. QDMA Channel should
2838 * be freed only in the end because while freeing, QRAE
2839 * registers will be RESET.
2840 * After that, no shadow region specific QDMA channel
2841 * register can be modified. So reset that QDRAE register
2842 * ONLY in the end.
2843 */
2844 resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
2845 resObj.resId = chObj->resId;
2846 result = EDMA3_RM_freeResource(hEdmaResMgr,
2847 (EDMA3_RM_ResDesc *)&resObj);
2848 }
2849 }
2850 break;
2853 case EDMA3_RM_RES_PARAM_SET:
2854 {
2855 /* Link Channel */
2856 if (chObj->resId < edma3NumPaRAMSets)
2857 {
2858 resObj.type = EDMA3_RM_RES_PARAM_SET;
2859 resObj.resId = chObj->resId;
2861 result = EDMA3_RM_freeResource(hEdmaResMgr, (EDMA3_RM_ResDesc *)&resObj);
2862 if (result == EDMA3_RM_SOK)
2863 {
2864 /* PaRAM Set freed successfully. */
2865 uint32_t linkCh = edma3_link_ch_min_val[edma3Id];
2867 /* Reset the Logical-Link channel */
2868 /* Search for the Logical-Link channel first */
2869 for (linkCh = edma3_link_ch_min_val[edma3Id];
2870 linkCh < edma3_link_ch_max_val[edma3Id];
2871 linkCh++)
2872 {
2873 if (edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId == chObj->resId)
2874 {
2875 edma3RmChBoundRes[rmObj->phyCtrllerInstId][linkCh].paRAMId = -1;
2876 break;
2877 }
2878 }
2879 }
2880 }
2881 else
2882 {
2883 result = EDMA3_RM_E_INVALID_PARAM;
2884 }
2885 }
2886 break;
2888 default:
2889 {
2890 result = EDMA3_RM_E_INVALID_PARAM;
2891 break;
2892 }
2893 }
2894 }
2897 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2898 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2899 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
2900 EDMA3_DVT_dCOUNTER,
2901 EDMA3_DVT_dNONE,
2902 EDMA3_DVT_dNONE));
2903 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2905 return result;
2906 }
2908 EDMA3_RM_Result EDMA3_RM_mapEdmaChannel (EDMA3_RM_Handle hEdmaResMgr,
2909 uint32_t channelId,
2910 uint32_t paRAMId)
2911 {
2912 EDMA3_RM_Instance *rmInstance = NULL;
2913 EDMA3_RM_Obj *rmObj = NULL;
2914 EDMA3_RM_Result result = EDMA3_RM_SOK;
2915 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
2917 #ifdef EDMA3_INSTRUMENTATION_ENABLED
2918 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
2919 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
2920 EDMA3_DVT_dCOUNTER,
2921 EDMA3_DVT_dNONE,
2922 EDMA3_DVT_dNONE));
2923 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
2925 /* If parameter checking is enabled... */
2926 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2927 if (hEdmaResMgr == NULL)
2928 {
2929 result = EDMA3_RM_E_INVALID_PARAM;
2930 }
2931 #endif
2933 if (result == EDMA3_RM_SOK)
2934 {
2935 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
2937 if (rmInstance == NULL)
2938 {
2939 result = EDMA3_RM_E_INVALID_PARAM;
2940 }
2941 }
2943 if (result == EDMA3_RM_SOK)
2944 {
2945 rmObj = rmInstance->pResMgrObjHandle;
2947 if (rmObj == NULL)
2948 {
2949 result = EDMA3_RM_E_INVALID_PARAM;
2950 }
2951 else
2952 {
2953 if (rmObj->gblCfgParams.globalRegs == NULL)
2954 {
2955 result = EDMA3_RM_E_INVALID_PARAM;
2956 }
2957 }
2958 }
2960 if (result == EDMA3_RM_SOK)
2961 {
2962 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
2964 /* If parameter checking is enabled... */
2965 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
2966 if ((paRAMId >= rmObj->gblCfgParams.numPaRAMSets)
2967 || (channelId >= rmObj->gblCfgParams.numDmaChannels))
2968 {
2969 result = EDMA3_RM_E_INVALID_PARAM;
2970 }
2971 #endif
2972 }
2974 /* DMA channel and PaRAM Set should be previously allocated. */
2975 if (result == EDMA3_RM_SOK)
2976 {
2977 if(((channelId/32U) < 2) && ((paRAMId/32U) < 16))
2978 {
2979 if (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[channelId/32U])
2980 &
2981 (~(rmInstance->avlblDmaChannels[channelId/32U]))
2982 &
2983 ((uint32_t)1U << (channelId%32U))) != FALSE)
2984 {
2985 /* DMA channel allocated, check for the PaRAM Set */
2986 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[paRAMId/32U])
2987 &
2988 (~(rmInstance->avlblPaRAMSets[paRAMId/32U]))
2989 &
2990 ((uint32_t)1U << (paRAMId%32U))) == FALSE)
2991 {
2992 /* PaRAM Set NOT allocated, return error */
2993 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
2994 }
2995 }
2996 else
2997 {
2998 /* DMA channel NOT allocated, return error */
2999 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3000 }
3001 }
3002 }
3005 if (result == EDMA3_RM_SOK)
3006 {
3007 /* Map the Dma Channel to the PaRAM Set corresponding to paramId */
3008 /**
3009 * Do this for the EDMA3 Controllers which have a register for mapping
3010 * DMA Channel to a particular PaRAM Set. So check
3011 * dmaChPaRAMMapExists first.
3012 */
3013 if (TRUE == rmObj->gblCfgParams.dmaChPaRAMMapExists)
3014 {
3015 /* Map Parameter RAM Set Number for specified channelId */
3016 gblRegs->DCHMAP[channelId] &= EDMA3_RM_DCH_PARAM_CLR_MASK;
3017 gblRegs->DCHMAP[channelId] |= EDMA3_RM_DCH_PARAM_SET_MASK(paRAMId);
3018 }
3019 else
3020 {
3021 /* Feature NOT supported on the current platform, return error. */
3022 result = EDMA3_RM_E_FEATURE_UNSUPPORTED;
3023 }
3024 }
3026 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3027 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3028 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3029 EDMA3_DVT_dCOUNTER,
3030 EDMA3_DVT_dNONE,
3031 EDMA3_DVT_dNONE));
3032 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3034 return result;
3035 }
3037 EDMA3_RM_Result EDMA3_RM_mapQdmaChannel (EDMA3_RM_Handle hEdmaResMgr,
3038 uint32_t channelId,
3039 uint32_t paRAMId,
3040 EDMA3_RM_QdmaTrigWord trigWord)
3041 {
3042 EDMA3_RM_Instance *rmInstance = NULL;
3043 EDMA3_RM_Obj *rmObj = NULL;
3044 EDMA3_RM_Result result = EDMA3_RM_SOK;
3045 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3047 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3048 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3049 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3050 EDMA3_DVT_dCOUNTER,
3051 EDMA3_DVT_dNONE,
3052 EDMA3_DVT_dNONE));
3053 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3055 /* If parameter checking is enabled... */
3056 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3057 if ((hEdmaResMgr == NULL)
3058 || (((int32_t)trigWord < (int32_t)EDMA3_RM_QDMA_TRIG_OPT)
3059 || (trigWord > EDMA3_RM_QDMA_TRIG_CCNT)))
3060 {
3061 result = EDMA3_RM_E_INVALID_PARAM;
3062 }
3063 #endif
3065 if (result == EDMA3_RM_SOK)
3066 {
3067 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3069 if (rmInstance == NULL)
3070 {
3071 result = EDMA3_RM_E_INVALID_PARAM;
3072 }
3073 }
3075 if (result == EDMA3_RM_SOK)
3076 {
3077 rmObj = rmInstance->pResMgrObjHandle;
3079 if (rmObj == NULL)
3080 {
3081 result = EDMA3_RM_E_INVALID_PARAM;
3082 }
3083 else
3084 {
3085 if (rmObj->gblCfgParams.globalRegs == NULL)
3086 {
3087 result = EDMA3_RM_E_INVALID_PARAM;
3088 }
3089 }
3090 }
3092 if (result == EDMA3_RM_SOK)
3093 {
3094 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3096 /* If parameter checking is enabled... */
3097 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3098 if ((paRAMId >= rmObj->gblCfgParams.numPaRAMSets)
3099 || (channelId >= rmObj->gblCfgParams.numQdmaChannels))
3100 {
3101 result = EDMA3_RM_E_INVALID_PARAM;
3102 }
3103 #endif
3104 }
3106 /* QDMA channel and PaRAM Set should be previously allocated. */
3107 if (result == EDMA3_RM_SOK)
3108 {
3109 if(((channelId/32U) < 1) && ((paRAMId/32U) < 16))
3110 {
3111 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[channelId/32U])
3112 &
3113 (~(rmInstance->avlblQdmaChannels[channelId/32U]))
3114 &
3115 ((uint32_t)1U << (channelId%32U))) != FALSE)
3116 {
3117 /* QDMA channel allocated, check for the PaRAM Set */
3118 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[paRAMId/32U])
3119 &
3120 (~(rmInstance->avlblPaRAMSets[paRAMId/32U]))
3121 &
3122 ((uint32_t)1U << (paRAMId%32U))) == FALSE)
3123 {
3124 /* PaRAM Set NOT allocated, return error */
3125 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3126 }
3127 }
3128 else
3129 {
3130 /* QDMA channel NOT allocated, return error */
3131 result = EDMA3_RM_E_RES_NOT_ALLOCATED;
3132 }
3133 }
3134 }
3136 if (result == EDMA3_RM_SOK)
3137 {
3138 /* Map Parameter RAM Set Number for specified channelId */
3139 gblRegs->QCHMAP[channelId] &= EDMA3_RM_QCH_PARAM_CLR_MASK;
3140 gblRegs->QCHMAP[channelId] |= EDMA3_RM_QCH_PARAM_SET_MASK(paRAMId);
3142 /* Set the Trigger Word */
3143 gblRegs->QCHMAP[channelId] &= EDMA3_RM_QCH_TRWORD_CLR_MASK;
3144 gblRegs->QCHMAP[channelId] |= EDMA3_RM_QCH_TRWORD_SET_MASK(trigWord);
3145 }
3148 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3149 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3150 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3151 EDMA3_DVT_dCOUNTER,
3152 EDMA3_DVT_dNONE,
3153 EDMA3_DVT_dNONE));
3154 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3156 return result;
3157 }
3159 EDMA3_RM_Result EDMA3_RM_registerTccCb(EDMA3_RM_Handle hEdmaResMgr,
3160 const EDMA3_RM_ResDesc *channelObj,
3161 uint32_t tcc,
3162 EDMA3_RM_TccCallback tccCb,
3163 void *cbData)
3164 {
3165 EDMA3_RM_Instance *rmInstance = NULL;
3166 EDMA3_RM_Obj *rmObj = NULL;
3167 EDMA3_RM_Result result = EDMA3_RM_SOK;
3168 uint32_t edma3Id;
3169 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3171 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3172 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3173 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3174 EDMA3_DVT_dCOUNTER,
3175 EDMA3_DVT_dNONE,
3176 EDMA3_DVT_dNONE));
3177 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3179 /* If parameter checking is enabled... */
3180 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3181 if ((NULL == hEdmaResMgr) || (NULL == channelObj))
3182 {
3183 result = EDMA3_RM_E_INVALID_PARAM;
3184 }
3186 /* Callback function should NOT be NULL */
3187 if (NULL == tccCb)
3188 {
3189 result = EDMA3_RM_E_INVALID_PARAM;
3190 }
3191 #endif
3193 if (result == EDMA3_RM_SOK)
3194 {
3195 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3196 rmObj = rmInstance->pResMgrObjHandle;
3198 if (rmObj == NULL)
3199 {
3200 result = EDMA3_RM_E_INVALID_PARAM;
3201 }
3202 else
3203 {
3204 edma3Id = rmObj->phyCtrllerInstId;
3205 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3206 }
3207 }
3209 if (result == EDMA3_RM_SOK)
3210 {
3211 if ((gblRegs == NULL) || (tcc >= rmObj->gblCfgParams.numTccs))
3212 {
3213 result = EDMA3_RM_E_INVALID_PARAM;
3214 }
3215 }
3217 /* Check if the parameters are OK. */
3218 if (EDMA3_RM_SOK == result)
3219 {
3220 /* Check whether the callback has already registered. */
3221 if (NULL != edma3IntrParams[edma3Id][tcc].tccCb)
3222 {
3223 result = EDMA3_RM_E_CALLBACK_ALREADY_REGISTERED;
3224 }
3225 else
3226 {
3227 /* Store the mapping b/w DMA/QDMA channel and TCC first. */
3228 if (channelObj->type == EDMA3_RM_RES_DMA_CHANNEL)
3229 {
3230 /* DMA channel */
3231 if (channelObj->resId < rmObj->gblCfgParams.numDmaChannels)
3232 {
3233 /* Save the TCC */
3234 edma3DmaChTccMapping[edma3Id][channelObj->resId] = tcc;
3235 }
3236 else
3237 {
3238 /* Error!!! */
3239 result = EDMA3_RM_E_INVALID_PARAM;
3240 }
3241 }
3242 else
3243 {
3244 if (channelObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
3245 {
3246 /* QDMA channel */
3247 if (channelObj->resId < rmObj->gblCfgParams.numQdmaChannels)
3248 {
3249 /* Save the TCC */
3250 edma3QdmaChTccMapping[edma3Id][channelObj->resId] = tcc;
3251 }
3252 else
3253 {
3254 /* Error!!! */
3255 result = EDMA3_RM_E_INVALID_PARAM;
3256 }
3257 }
3258 else
3259 {
3260 /* Error!!! */
3261 result = EDMA3_RM_E_INVALID_PARAM;
3262 }
3263 }
3264 }
3265 }
3267 if (EDMA3_RM_SOK == result)
3268 {
3270 /* Enable the interrupts in IESR/IESRH */
3271 if (tcc < 32U)
3272 {
3273 rmInstance->shadowRegs->IESR = (1UL << tcc);
3274 }
3275 else
3276 {
3277 rmInstance->shadowRegs->IESRH = (1UL << (tcc-32U));
3278 }
3280 /* Save the callback functions also */
3281 edma3IntrParams[edma3Id][tcc].cbData = cbData;
3282 edma3IntrParams[edma3Id][tcc].tccCb = tccCb;
3283 }
3285 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3286 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3287 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3288 EDMA3_DVT_dCOUNTER,
3289 EDMA3_DVT_dNONE,
3290 EDMA3_DVT_dNONE));
3291 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3293 return result;
3294 }
3296 EDMA3_RM_Result EDMA3_RM_unregisterTccCb(EDMA3_RM_Handle hEdmaResMgr,
3297 const EDMA3_RM_ResDesc *channelObj)
3298 {
3299 EDMA3_RM_Instance *rmInstance = NULL;
3300 EDMA3_RM_Obj *rmObj = NULL;
3301 EDMA3_RM_Result result = EDMA3_RM_SOK;
3302 uint32_t mappedTcc = EDMA3_MAX_TCC;
3303 uint32_t edma3Id;
3304 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3306 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3307 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3308 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3309 EDMA3_DVT_dCOUNTER,
3310 EDMA3_DVT_dNONE,
3311 EDMA3_DVT_dNONE));
3312 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3314 /* If parameter checking is enabled... */
3315 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3316 if ((NULL == hEdmaResMgr) || (NULL == channelObj))
3317 {
3318 result = EDMA3_RM_E_INVALID_PARAM;
3319 }
3320 #endif
3322 /* Check if the parameters are OK. */
3323 if (EDMA3_RM_SOK == result)
3324 {
3325 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3326 rmObj = rmInstance->pResMgrObjHandle;
3328 if (rmObj == NULL)
3329 {
3330 result = EDMA3_RM_E_INVALID_PARAM;
3331 }
3332 else
3333 {
3334 edma3Id = rmObj->phyCtrllerInstId;
3335 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3336 }
3337 }
3339 if (result == EDMA3_RM_SOK)
3340 {
3341 if (gblRegs == NULL)
3342 {
3343 result = EDMA3_RM_E_INVALID_PARAM;
3344 }
3345 else
3346 {
3347 if (channelObj->type == EDMA3_RM_RES_DMA_CHANNEL)
3348 {
3349 /* DMA channel */
3350 if (channelObj->resId < rmObj->gblCfgParams.numDmaChannels)
3351 {
3352 /* Save the mapped TCC */
3353 mappedTcc = edma3DmaChTccMapping[edma3Id][channelObj->resId];
3355 /* Remove the mapping now. */
3356 edma3DmaChTccMapping[edma3Id][channelObj->resId] = EDMA3_MAX_TCC;
3357 }
3358 else
3359 {
3360 /* Error!!! */
3361 result = EDMA3_RM_E_INVALID_PARAM;
3362 }
3363 }
3364 else
3365 {
3366 if (channelObj->type == EDMA3_RM_RES_QDMA_CHANNEL)
3367 {
3368 /* QDMA channel */
3369 if (channelObj->resId < rmObj->gblCfgParams.numQdmaChannels)
3370 {
3371 /* Save the mapped TCC */
3372 mappedTcc = edma3QdmaChTccMapping[edma3Id][channelObj->resId];
3374 /* Remove the mapping now. */
3375 edma3QdmaChTccMapping[edma3Id][channelObj->resId] = EDMA3_MAX_TCC;
3376 }
3377 else
3378 {
3379 /* Error!!! */
3380 result = EDMA3_RM_E_INVALID_PARAM;
3381 }
3382 }
3383 else
3384 {
3385 /* Error!!! */
3386 result = EDMA3_RM_E_INVALID_PARAM;
3387 }
3388 }
3389 }
3390 }
3392 if (EDMA3_RM_SOK == result)
3393 {
3395 /* Remove the callback function too */
3396 if (mappedTcc < 32U)
3397 {
3398 rmInstance->shadowRegs->IECR = (1UL << mappedTcc);
3399 }
3400 else if(mappedTcc < 64U)
3401 {
3402 rmInstance->shadowRegs->IECRH = (1UL << (mappedTcc-32U));
3403 }
3404 else
3405 {
3406 /* To Comply MISRA C warning */
3407 result = EDMA3_RM_SOK;
3408 }
3410 if(mappedTcc < EDMA3_MAX_TCC)
3411 {
3412 edma3IntrParams[edma3Id][mappedTcc].cbData = NULL;
3413 edma3IntrParams[edma3Id][mappedTcc].tccCb = NULL;
3414 }
3415 }
3417 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3418 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3419 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3420 EDMA3_DVT_dCOUNTER,
3421 EDMA3_DVT_dNONE,
3422 EDMA3_DVT_dNONE));
3423 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3425 return result;
3426 }
3428 EDMA3_RM_Result EDMA3_RM_allocContiguousResource(EDMA3_RM_Handle hEdmaResMgr,
3429 EDMA3_RM_ResDesc *firstResIdObj,
3430 uint32_t numResources)
3431 {
3432 EDMA3_RM_Instance *rmInstance = NULL;
3433 EDMA3_RM_Obj *rmObj = NULL;
3434 EDMA3_RM_Result result = EDMA3_RM_SOK;
3435 EDMA3_RM_ResDesc *resObj = NULL;
3436 uint32_t resAllocIdx = 0U;
3437 uint32_t firstResId;
3438 uint32_t lastResId = 0U;
3439 uint32_t maxNumResources = 0U;
3440 EDMA3_RM_Result semResult = EDMA3_RM_SOK;
3441 uint32_t resIdClr = 0x0;
3442 uint32_t resIdSet = 0x0;
3443 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
3444 uint32_t i = 0U;
3445 uint32_t position = 0U;
3446 uint32_t edma3Id;
3447 uint32_t errFlag=0U;
3449 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3450 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3451 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3452 EDMA3_DVT_dCOUNTER,
3453 EDMA3_DVT_dNONE,
3454 EDMA3_DVT_dNONE));
3455 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3458 /* If parameter checking is enabled... */
3459 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3460 if ((hEdmaResMgr == NULL) || (firstResIdObj == NULL))
3461 {
3462 result = EDMA3_RM_E_INVALID_PARAM;
3463 }
3464 #endif
3466 if (EDMA3_RM_SOK == result)
3467 {
3468 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3469 if (rmInstance == NULL)
3470 {
3471 result = EDMA3_RM_E_INVALID_PARAM;
3472 }
3473 }
3475 if (EDMA3_RM_SOK == result)
3476 {
3477 rmObj = rmInstance->pResMgrObjHandle;
3479 if (rmObj == NULL)
3480 {
3481 result = EDMA3_RM_E_INVALID_PARAM;
3482 }
3483 }
3485 if (EDMA3_RM_SOK == result)
3486 {
3487 edma3Id = rmObj->phyCtrllerInstId;
3488 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
3490 if (rmInstance->initParam.rmSemHandle == NULL)
3491 {
3492 result = EDMA3_RM_E_INVALID_PARAM;
3493 }
3494 }
3496 if (EDMA3_RM_SOK == result)
3497 {
3498 resObj = firstResIdObj;
3499 if (resObj != NULL)
3500 {
3501 firstResId = resObj->resId;
3502 }
3504 switch (resObj->type)
3505 {
3506 case EDMA3_RM_RES_DMA_CHANNEL :
3507 maxNumResources = rmObj->gblCfgParams.numDmaChannels;
3508 break;
3509 case EDMA3_RM_RES_QDMA_CHANNEL :
3510 maxNumResources = rmObj->gblCfgParams.numQdmaChannels;
3511 break;
3512 case EDMA3_RM_RES_TCC :
3513 maxNumResources = rmObj->gblCfgParams.numTccs;
3514 break;
3515 case EDMA3_RM_RES_PARAM_SET :
3516 maxNumResources = rmObj->gblCfgParams.numPaRAMSets;
3517 break;
3518 default:
3519 result = EDMA3_RM_E_INVALID_PARAM;
3520 break;
3521 }
3522 }
3525 if (EDMA3_RM_SOK == result)
3526 {
3527 /* First resource id (firstResId) can be a valid Resource ID as well as
3528 * 'EDMA3_RM_RES_ANY', in case user does not want to
3529 * start from a specific resource. For eg, user allocating link channels.
3530 */
3531 if (firstResId != EDMA3_RM_RES_ANY)
3532 {
3533 /* User want specific resources. */
3534 lastResId = firstResId + numResources;
3536 if (((firstResId >= maxNumResources) || (firstResId > lastResId))
3537 || (lastResId > maxNumResources))
3538 {
3539 result = EDMA3_RM_E_INVALID_PARAM;
3540 }
3541 }
3542 else
3543 {
3544 /* (firstResId == EDMA3_RM_RES_ANY)
3545 * So just check whether the number of resources
3546 * requested does not cross the limit.
3547 */
3548 if (numResources > maxNumResources)
3549 {
3550 result = EDMA3_RM_E_INVALID_PARAM;
3551 }
3552 }
3553 }
3556 if (result == EDMA3_RM_SOK)
3557 {
3558 /* Now try to allocate resources for the first case */
3559 if (firstResId != EDMA3_RM_RES_ANY)
3560 {
3561 /* Request for specific resources */
3563 /**
3564 * Take the instance specific semaphore, to prevent simultaneous
3565 * access to the shared resources.
3566 */
3567 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
3568 EDMA3_OSSEM_NO_TIMEOUT);
3570 if (EDMA3_RM_SOK == semResult)
3571 {
3572 switch (resObj->type)
3573 {
3574 case EDMA3_RM_RES_DMA_CHANNEL :
3575 {
3576 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3577 {
3578 resIdClr = (uint32_t)(~((uint32_t)1U << (resAllocIdx%32U)));
3579 resIdSet = (1U << (resAllocIdx%32U));
3581 /* Check whether it is owned or not */
3582 if (((resAllocIdx/32U) < 2) && (((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resAllocIdx/32U])&(resIdSet)) != FALSE))
3583 {
3584 /* Now check if specified resource is available presently*/
3585 if (((rmInstance->avlblDmaChannels[resAllocIdx/32U])&(resIdSet)) != FALSE)
3586 {
3587 /*
3588 * Mark the specified resource as "Not Available"
3589 * for future requests
3590 */
3591 rmInstance->avlblDmaChannels[resAllocIdx/32U] &= resIdClr;
3593 if (resAllocIdx < 32U)
3594 {
3595 rmInstance->shadowRegs->EECR = (1UL << resAllocIdx);
3597 /**
3598 * Enable the DMA channel in the
3599 * DRAE registers also.
3600 */
3601 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
3602 |= ((uint32_t)0x1U << resAllocIdx);
3603 }
3604 else
3605 {
3606 rmInstance->shadowRegs->EECRH = (1UL << (resAllocIdx - 32U));
3608 /**
3609 * Enable the DMA channel in the
3610 * DRAEH registers also.
3611 */
3612 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
3613 |= ((uint32_t)0x1U << (resAllocIdx - 32U));
3614 }
3616 result = EDMA3_RM_SOK;
3617 }
3618 else
3619 {
3620 /* Specified resource is owned but is already booked */
3621 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3622 errFlag = 1U;
3623 }
3624 }
3625 else
3626 {
3627 /*
3628 * Specified resource is not owned by this instance
3629 * of the Resource Manager
3630 */
3631 result = EDMA3_RM_E_RES_NOT_OWNED;
3632 errFlag = 1U;
3633 }
3634 if(errFlag == 1U)
3635 {
3636 break;
3637 }
3638 }
3640 break;
3641 }
3643 case EDMA3_RM_RES_QDMA_CHANNEL:
3644 {
3645 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3646 {
3647 resIdClr = (uint32_t)(~((uint32_t)1U << resAllocIdx));
3648 resIdSet = (1U << resAllocIdx);
3650 /* Check whether it is owned or not */
3651 if (((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0U])&(resIdSet))!=FALSE)
3652 {
3653 /* Now check if specified resource is available presently*/
3654 if (((rmInstance->avlblQdmaChannels[0U])&(resIdSet))!=FALSE)
3655 {
3656 /*
3657 * Mark the specified resource as "Not Available"
3658 * for future requests
3659 */
3660 rmInstance->avlblQdmaChannels[0U] &= resIdClr;
3662 /**
3663 * Enable the QDMA channel in the
3664 * QRAE register also.
3665 */
3666 gblRegs->QRAE[rmInstance->initParam.regionId]
3667 |= ((uint32_t)0x1U << resAllocIdx);
3669 result = EDMA3_RM_SOK;
3670 }
3671 else
3672 {
3673 /* Specified resource is owned but is already booked */
3674 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3675 errFlag = 1U;
3676 }
3677 }
3678 else
3679 {
3680 /*
3681 * Specified resource is not owned by this instance
3682 * of the Resource Manager
3683 */
3684 result = EDMA3_RM_E_RES_NOT_OWNED;
3685 errFlag = 1U;
3686 }
3687 if(errFlag == 1U)
3688 {
3689 break;
3690 }
3691 }
3693 break;
3694 }
3696 case EDMA3_RM_RES_TCC:
3697 {
3698 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3699 {
3700 resIdClr = (uint32_t)(~((uint32_t)1U << (resAllocIdx%32U)));
3701 resIdSet = (1U << (resAllocIdx%32U));
3703 /* Check whether it is owned or not */
3704 if (((resAllocIdx/32U) < 2) && (((rmInstance->initParam.rmInstInitConfig->ownTccs[resAllocIdx/32U])&(resIdSet))!=FALSE))
3705 {
3706 /* Now check if specified resource is available presently*/
3707 if (((rmInstance->avlblTccs[resAllocIdx/32U])&(resIdSet))!=FALSE)
3708 {
3709 /*
3710 * Mark the specified resource as "Not Available"
3711 * for future requests
3712 */
3713 rmInstance->avlblTccs[resAllocIdx/32U] &= resIdClr;
3715 /**
3716 * If the region id coming from this
3717 * RM instance is same as the Master RM
3718 * Instance's region id, only then we will be
3719 * getting the interrupts on the same side.
3720 * So save the TCC in the allocatedTCCs[] array.
3721 */
3722 if (edma3RegionId == rmInstance->initParam.regionId)
3723 {
3724 if (resAllocIdx < 32U)
3725 {
3726 allocatedTCCs[edma3Id][0U] |= ((uint32_t)0x1U << resAllocIdx);
3727 }
3728 else
3729 {
3730 allocatedTCCs[edma3Id][1U] |= ((uint32_t)0x1U << (resAllocIdx - 32U));
3731 }
3732 }
3733 result = EDMA3_RM_SOK;
3734 }
3735 else
3736 {
3737 /* Specified resource is owned but is already booked */
3738 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3739 errFlag = 1U;
3740 }
3741 }
3742 else
3743 {
3744 /*
3745 * Specified resource is not owned by this instance
3746 * of the Resource Manager
3747 */
3748 result = EDMA3_RM_E_RES_NOT_OWNED;
3749 errFlag = 1U;
3750 }
3751 if(errFlag == 1U)
3752 {
3753 break;
3754 }
3755 }
3757 break;
3758 }
3760 case EDMA3_RM_RES_PARAM_SET:
3761 {
3762 for (resAllocIdx = firstResId; resAllocIdx < lastResId; ++resAllocIdx)
3763 {
3764 resIdClr = (uint32_t)(~((uint32_t)1U << (resAllocIdx%32U)));
3765 resIdSet = (1U << (resAllocIdx%32U));
3767 /* Check whether it is owned or not */
3768 if (((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[resAllocIdx/32U])&(resIdSet))!=FALSE)
3769 {
3770 /* Now check if specified resource is available presently*/
3771 if (((resAllocIdx/32U) < 16) && (((rmInstance->avlblPaRAMSets[resAllocIdx/32U])&(resIdSet))!=FALSE))
3772 {
3773 /*
3774 * Mark the specified resource as "Not Available"
3775 * for future requests
3776 */
3777 rmInstance->avlblPaRAMSets[resAllocIdx/32U] &= resIdClr;
3779 /**
3780 * Also, make the actual PARAM Set NULL, checking the flag
3781 * whether it is required or not.
3782 */
3783 if (TRUE == rmInstance->paramInitRequired)
3784 {
3785 edma3MemZero((void *)(&gblRegs->PARAMENTRY[resAllocIdx]),
3786 sizeof(gblRegs->PARAMENTRY[resAllocIdx]));
3787 }
3789 result = EDMA3_RM_SOK;
3790 }
3791 else
3792 {
3793 /* Specified resource is owned but is already booked */
3794 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
3795 errFlag = 1U;
3796 }
3797 }
3798 else
3799 {
3800 /*
3801 * Specified resource is not owned by this instance
3802 * of the Resource Manager
3803 */
3804 result = EDMA3_RM_E_RES_NOT_OWNED;
3805 errFlag = 1U;
3806 }
3807 if(errFlag == 1U)
3808 {
3809 break;
3810 }
3811 }
3813 break;
3814 }
3816 default:
3817 {
3818 result = EDMA3_RM_E_INVALID_PARAM;
3819 break;
3820 }
3821 }
3823 /* resource allocation completed, release the semaphore first */
3824 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
3825 }
3827 }
3828 else
3829 {
3830 /* (firstResId == EDMA3_RM_RES_ANY) */
3831 /**
3832 * Take the instance specific semaphore, to prevent simultaneous
3833 * access to the shared resources.
3834 */
3835 semResult = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
3836 EDMA3_OSSEM_NO_TIMEOUT);
3838 if (EDMA3_RM_SOK == semResult)
3839 {
3840 /**
3841 * We have to search three different arrays, namely ownedResoures,
3842 * avlblResources and resvdResources, to find the 'common' contiguous
3843 * resources. For this, take an 'AND' of all three arrays in one single
3844 * array and use your algorithm on that array.
3845 */
3846 switch (resObj->type)
3847 {
3848 case EDMA3_RM_RES_DMA_CHANNEL:
3849 {
3850 /* AND all the arrays to look into */
3851 contiguousDmaRes[0U] = ((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[0U]
3852 & rmInstance->avlblDmaChannels[0U])
3853 & (~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[0U]))
3854 );
3855 contiguousDmaRes[1U] = ((rmInstance->initParam.rmInstInitConfig->ownDmaChannels[1U]
3856 & rmInstance->avlblDmaChannels[1U])
3857 & (~(rmInstance->initParam.rmInstInitConfig->resvdDmaChannels[1U]))
3858 );
3859 }
3860 break;
3862 case EDMA3_RM_RES_QDMA_CHANNEL:
3863 {
3864 /* AND all the arrays to look into */
3865 contiguousQdmaRes[0U] = ((rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0U]
3866 & rmInstance->avlblQdmaChannels[0U])
3867 & (~(rmInstance->initParam.rmInstInitConfig->resvdQdmaChannels[0U]))
3868 );
3869 }
3870 break;
3872 case EDMA3_RM_RES_TCC:
3873 {
3874 /* AND all the arrays to look into */
3875 contiguousTccRes[0U] = ((rmInstance->initParam.rmInstInitConfig->ownTccs[0U]
3876 & rmInstance->avlblTccs[0U])
3877 & (~(rmInstance->initParam.rmInstInitConfig->resvdTccs[0U]))
3878 );
3879 contiguousTccRes[1U] = ((rmInstance->initParam.rmInstInitConfig->ownTccs[1U]
3880 & rmInstance->avlblTccs[1U])
3881 & (~(rmInstance->initParam.rmInstInitConfig->resvdTccs[1U]))
3882 );
3883 }
3884 break;
3886 case EDMA3_RM_RES_PARAM_SET:
3887 {
3888 /* AND all the arrays to look into */
3889 for (i = 0U; i < (maxNumResources/32U); ++i)
3890 {
3891 contiguousParamRes[i] = ((rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[i]
3892 & rmInstance->avlblPaRAMSets[i])
3893 & (~(rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[i]))
3894 );
3895 }
3896 }
3897 break;
3899 default:
3900 {
3901 result = EDMA3_RM_E_INVALID_PARAM;
3902 }
3903 break;
3904 }
3906 if (EDMA3_RM_SOK == result)
3907 {
3908 /**
3909 * Try to allocate 'numResources' contiguous resources
3910 * of type RES_ANY.
3911 */
3912 result = allocAnyContigRes (resObj->type, numResources, &position);
3914 /**
3915 * If result != EDMA3_RM_SOK, resource allocation failed.
3916 * Else resources successfully allocated.
3917 */
3918 if (result == EDMA3_RM_SOK)
3919 {
3920 /* Update the first resource id with the position returned. */
3921 resObj->resId = position;
3923 /*
3924 * Do some further changes in the book-keeping
3925 * data structures and global registers accordingly.
3926 */
3927 result = gblChngAllocContigRes(rmInstance, resObj, numResources);
3928 }
3929 }
3931 /* resource allocation completed, release the semaphore first */
3932 semResult = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
3933 }
3934 }
3935 }
3938 /**
3939 * Check the Resource Allocation Result 'result' first. If Resource
3940 * Allocation has resulted in an error, return it (having more priority than
3941 * semResult. Else, return semResult.
3942 */
3943 if (EDMA3_RM_SOK == result)
3944 {
3945 /**
3946 * Resource Allocation successful, return semResult for returning
3947 * semaphore.
3948 */
3949 result = semResult;
3950 }
3953 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3954 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3955 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
3956 EDMA3_DVT_dCOUNTER,
3957 EDMA3_DVT_dNONE,
3958 EDMA3_DVT_dNONE));
3959 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3961 return result;
3962 }
3964 EDMA3_RM_Result EDMA3_RM_freeContiguousResource(EDMA3_RM_Handle hEdmaResMgr,
3965 EDMA3_RM_ResDesc *firstResIdObj,
3966 uint32_t numResources)
3967 {
3968 EDMA3_RM_Instance *rmInstance = NULL;
3969 EDMA3_RM_Obj *rmObj = NULL;
3970 EDMA3_RM_Result result = EDMA3_RM_SOK;
3971 EDMA3_RM_ResDesc *resObj;
3972 uint32_t resFreeIdx = 0U;
3973 uint32_t firstResId;
3974 uint32_t lastResId;
3975 uint32_t maxNumResources = 0U;
3977 #ifdef EDMA3_INSTRUMENTATION_ENABLED
3978 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
3979 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
3980 EDMA3_DVT_dCOUNTER,
3981 EDMA3_DVT_dNONE,
3982 EDMA3_DVT_dNONE));
3983 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
3985 /* If parameter checking is enabled... */
3986 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
3987 if ((hEdmaResMgr == NULL) || (firstResIdObj == NULL))
3988 {
3989 result = EDMA3_RM_E_INVALID_PARAM;
3990 }
3991 #endif
3993 /* Check if the parameters are OK. */
3994 if (EDMA3_RM_SOK == result)
3995 {
3996 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
3997 rmObj = rmInstance->pResMgrObjHandle;
3999 if (rmObj == NULL)
4000 {
4001 result = EDMA3_RM_E_INVALID_PARAM;
4002 }
4003 else
4004 {
4005 resObj = firstResIdObj;
4006 if (resObj != NULL)
4007 {
4008 firstResId = resObj->resId;
4009 lastResId = firstResId + (numResources - 1U);
4010 }
4012 switch (resObj->type)
4013 {
4014 case EDMA3_RM_RES_DMA_CHANNEL :
4015 maxNumResources = rmObj->gblCfgParams.numDmaChannels;
4016 break;
4017 case EDMA3_RM_RES_QDMA_CHANNEL :
4018 maxNumResources = rmObj->gblCfgParams.numQdmaChannels;
4019 break;
4020 case EDMA3_RM_RES_TCC :
4021 maxNumResources = rmObj->gblCfgParams.numTccs;
4022 break;
4023 case EDMA3_RM_RES_PARAM_SET :
4024 maxNumResources = rmObj->gblCfgParams.numPaRAMSets;
4025 break;
4026 default:
4027 result = EDMA3_RM_E_INVALID_PARAM;
4028 break;
4029 }
4031 if (result == EDMA3_RM_SOK)
4032 {
4033 if ((firstResId > lastResId) || (lastResId >= maxNumResources))
4034 {
4035 result = EDMA3_RM_E_INVALID_PARAM;
4036 }
4037 else
4038 {
4039 for (resFreeIdx = firstResId; resFreeIdx <= lastResId; ++resFreeIdx)
4040 {
4041 resObj->resId = resFreeIdx;
4042 result = EDMA3_RM_freeResource(rmInstance, resObj);
4044 if (result != EDMA3_RM_SOK)
4045 {
4046 break;
4047 }
4048 }
4049 }
4050 }
4051 }
4052 }
4054 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4055 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4056 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4057 EDMA3_DVT_dCOUNTER,
4058 EDMA3_DVT_dNONE,
4059 EDMA3_DVT_dNONE));
4060 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4062 return result;
4063 }
4065 EDMA3_RM_Result EDMA3_RM_setCCRegister (EDMA3_RM_Handle hEdmaResMgr,
4066 uint32_t regOffset,
4067 uint32_t newRegValue)
4068 {
4069 uint32_t intState;
4070 EDMA3_RM_Result result = EDMA3_RM_SOK;
4071 EDMA3_RM_Instance *rmInstance = NULL;
4072 EDMA3_RM_Obj *rmObj = NULL;
4073 volatile uint32_t regPhyAddr = 0x0U;
4076 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4077 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4078 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4079 EDMA3_DVT_dCOUNTER,
4080 EDMA3_DVT_dNONE,
4081 EDMA3_DVT_dNONE));
4082 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4085 /* If parameter checking is enabled... */
4086 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4087 if ((hEdmaResMgr == NULL) || ((regOffset % 4U) != 0))
4088 {
4089 result = (EDMA3_RM_E_INVALID_PARAM);
4090 }
4091 #endif
4093 /* Check if the parameters are OK. */
4094 if (EDMA3_RM_SOK == result)
4095 {
4096 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4097 rmObj = rmInstance->pResMgrObjHandle;
4099 if (rmObj == NULL)
4100 {
4101 result = (EDMA3_RM_E_INVALID_PARAM);
4102 }
4103 else
4104 {
4105 if (rmObj->gblCfgParams.globalRegs != NULL)
4106 {
4107 /**
4108 * Take the instance specific semaphore, to prevent simultaneous
4109 * access to the shared resources.
4110 */
4111 result = edma3OsSemTake(rmInstance->initParam.rmSemHandle,
4112 EDMA3_OSSEM_NO_TIMEOUT);
4114 if (EDMA3_RM_SOK == result)
4115 {
4116 /* Semaphore taken successfully, modify the registers. */
4117 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
4118 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
4119 &intState);
4120 /* Global interrupts disabled, modify the registers. */
4121 regPhyAddr = (uint32_t)(rmObj->gblCfgParams.globalRegs) + regOffset;
4123 *(uint32_t *)regPhyAddr = newRegValue;
4124 edma3OsProtectExit (rmObj->phyCtrllerInstId,
4125 (int32_t)EDMA3_OS_PROTECT_INTERRUPT,
4126 intState);
4128 /* Return the semaphore back */
4129 result = edma3OsSemGive(rmInstance->initParam.rmSemHandle);
4130 }
4131 }
4132 }
4133 }
4136 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4137 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4138 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4139 EDMA3_DVT_dCOUNTER,
4140 EDMA3_DVT_dNONE,
4141 EDMA3_DVT_dNONE));
4142 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4145 return result;
4146 }
4148 EDMA3_RM_Result EDMA3_RM_getCCRegister (EDMA3_RM_Handle hEdmaResMgr,
4149 uint32_t regOffset,
4150 uint32_t *regValue)
4151 {
4152 EDMA3_RM_Result result = EDMA3_RM_SOK;
4153 EDMA3_RM_Instance *rmInstance = NULL;
4154 EDMA3_RM_Obj *rmObj = NULL;
4155 volatile uint32_t regPhyAddr = 0x0U;
4158 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4159 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4160 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4161 EDMA3_DVT_dCOUNTER,
4162 EDMA3_DVT_dNONE,
4163 EDMA3_DVT_dNONE));
4164 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4167 /* If parameter checking is enabled... */
4168 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4169 if (((hEdmaResMgr == NULL) || (regValue == NULL))
4170 || ((regOffset % 4U) != 0))
4171 {
4172 result = (EDMA3_RM_E_INVALID_PARAM);
4173 }
4174 #endif
4176 /* Check if the parameters are OK. */
4177 if (EDMA3_RM_SOK == result)
4178 {
4179 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4180 rmObj = rmInstance->pResMgrObjHandle;
4182 if (rmObj == NULL)
4183 {
4184 result = (EDMA3_RM_E_INVALID_PARAM);
4185 }
4186 else
4187 {
4188 if (rmObj->gblCfgParams.globalRegs != NULL)
4189 {
4190 regPhyAddr = (uint32_t)(rmObj->gblCfgParams.globalRegs) + regOffset;
4192 *regValue = *(uint32_t *)regPhyAddr;
4193 }
4194 }
4195 }
4198 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4199 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4200 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4201 EDMA3_DVT_dCOUNTER,
4202 EDMA3_DVT_dNONE,
4203 EDMA3_DVT_dNONE));
4204 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4207 return result;
4208 }
4210 EDMA3_RM_Result EDMA3_RM_waitAndClearTcc (EDMA3_RM_Handle hEdmaResMgr,
4211 uint32_t tccNo)
4212 {
4213 EDMA3_RM_Result result = EDMA3_RM_SOK;
4214 EDMA3_RM_Instance *rmInstance = NULL;
4215 EDMA3_RM_Obj *rmObj = NULL;
4216 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4217 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
4218 uint32_t tccBitMask = 0x0U;
4221 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4222 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4223 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4224 EDMA3_DVT_dCOUNTER,
4225 EDMA3_DVT_dNONE,
4226 EDMA3_DVT_dNONE));
4227 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4230 /* If parameter checking is enabled... */
4231 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4232 if (hEdmaResMgr == NULL)
4233 {
4234 result = (EDMA3_RM_E_INVALID_PARAM);
4235 }
4236 #endif
4238 /* Check if the parameters are OK. */
4239 if (EDMA3_RM_SOK == result)
4240 {
4241 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4242 rmObj = rmInstance->pResMgrObjHandle;
4244 if ((rmObj == NULL) || (rmObj->gblCfgParams.globalRegs == NULL))
4245 {
4246 result = (EDMA3_RM_E_INVALID_PARAM);
4247 }
4248 else
4249 {
4250 /* If parameter checking is enabled... */
4251 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4252 if (tccNo >= rmObj->gblCfgParams.numTccs)
4253 {
4254 result = (EDMA3_RM_E_INVALID_PARAM);
4255 }
4256 #endif
4258 /* Check if the parameters are OK. */
4259 if (EDMA3_RM_SOK == result)
4260 {
4261 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4262 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
4263 (&globalRegs->SHADOW[rmInstance->initParam.regionId]);
4266 if (shadowRegs != NULL)
4267 {
4268 if(tccNo < 32U)
4269 {
4270 tccBitMask = (1U << tccNo);
4272 /* Check the status of the IPR[tccNo] bit. */
4273 while ((uint32_t)FALSE == (shadowRegs->IPR & tccBitMask))
4274 {
4275 /* Transfer not yet completed, bit not SET */
4276 }
4278 /**
4279 * Bit found SET, transfer is completed,
4280 * clear the pending interrupt and return.
4281 */
4282 shadowRegs->ICR = tccBitMask;
4283 }
4284 else
4285 {
4286 tccBitMask = (1U << (tccNo - 32U));
4288 /* Check the status of the IPRH[tccNo-32] bit. */
4289 while ((uint32_t)FALSE == (shadowRegs->IPRH & tccBitMask))
4290 {
4291 /* Transfer not yet completed, bit not SET */
4292 }
4294 /**
4295 * Bit found SET, transfer is completed,
4296 * clear the pending interrupt and return.
4297 */
4298 shadowRegs->ICRH = tccBitMask;
4299 }
4300 }
4301 }
4302 }
4303 }
4306 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4307 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4308 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4309 EDMA3_DVT_dCOUNTER,
4310 EDMA3_DVT_dNONE,
4311 EDMA3_DVT_dNONE));
4312 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4315 return result;
4316 }
4318 EDMA3_RM_Result EDMA3_RM_checkAndClearTcc (EDMA3_RM_Handle hEdmaResMgr,
4319 uint32_t tccNo,
4320 uint16_t *tccStatus)
4321 {
4322 EDMA3_RM_Result result = EDMA3_RM_SOK;
4323 EDMA3_RM_Instance *rmInstance = NULL;
4324 EDMA3_RM_Obj *rmObj = NULL;
4325 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4326 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
4327 uint32_t tccBitMask = 0x0U;
4330 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4331 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4332 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4333 EDMA3_DVT_dCOUNTER,
4334 EDMA3_DVT_dNONE,
4335 EDMA3_DVT_dNONE));
4336 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4339 /* If parameter checking is enabled... */
4340 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4341 if ((hEdmaResMgr == NULL) || (tccStatus == NULL))
4342 {
4343 result = (EDMA3_RM_E_INVALID_PARAM);
4344 }
4345 #endif
4347 /* Check if the parameters are OK. */
4348 if (EDMA3_RM_SOK == result)
4349 {
4350 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4351 rmObj = rmInstance->pResMgrObjHandle;
4353 if ((rmObj == NULL) || (rmObj->gblCfgParams.globalRegs == NULL))
4354 {
4355 result = (EDMA3_RM_E_INVALID_PARAM);
4356 }
4357 else
4358 {
4359 /* If parameter checking is enabled... */
4360 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4361 if (tccNo >= rmObj->gblCfgParams.numTccs)
4362 {
4363 result = (EDMA3_RM_E_INVALID_PARAM);
4364 }
4365 #endif
4367 /* Check if the parameters are OK. */
4368 if (EDMA3_RM_SOK == result)
4369 {
4370 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4371 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
4372 (&globalRegs->SHADOW[rmInstance->initParam.regionId]);
4374 /* Reset the tccStatus */
4375 *tccStatus = FALSE;
4377 if (shadowRegs != NULL)
4378 {
4379 if(tccNo < 32U)
4380 {
4381 tccBitMask = (1U << tccNo);
4383 /* Check the status of the IPR[tccNo] bit. */
4384 if ((shadowRegs->IPR & tccBitMask) != FALSE)
4385 {
4386 /* Transfer completed, bit found SET */
4387 *tccStatus = TRUE;
4389 /* Clear the pending interrupt also. */
4390 shadowRegs->ICR = tccBitMask;
4391 }
4392 }
4393 else
4394 {
4395 tccBitMask = (1U << (tccNo - 32U));
4397 /* Check the status of the IPRH[tccNo-32] bit. */
4398 if ((shadowRegs->IPRH & tccBitMask) != FALSE)
4399 {
4400 /* Transfer completed, bit found SET */
4401 *tccStatus = TRUE;
4403 /* Clear the pending interrupt also. */
4404 shadowRegs->ICRH = tccBitMask;
4405 }
4406 }
4407 }
4408 }
4409 }
4410 }
4413 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4414 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4415 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4416 EDMA3_DVT_dCOUNTER,
4417 EDMA3_DVT_dNONE,
4418 EDMA3_DVT_dNONE));
4419 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4422 return result;
4423 }
4425 EDMA3_RM_Result EDMA3_RM_setPaRAM (EDMA3_RM_Handle hEdmaResMgr,
4426 const EDMA3_RM_ResDesc *lChObj,
4427 const EDMA3_RM_PaRAMRegs *newPaRAM)
4428 {
4429 EDMA3_RM_Result result = EDMA3_RM_SOK;
4430 EDMA3_RM_Instance *rmInstance = NULL;
4431 EDMA3_RM_Obj *rmObj = NULL;
4432 int32_t paRAMId = 0;
4433 uint32_t qdmaChId = 0U;
4434 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4435 uint32_t edma3Id;
4437 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4438 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4439 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4440 EDMA3_DVT_dCOUNTER,
4441 EDMA3_DVT_dNONE,
4442 EDMA3_DVT_dNONE));
4443 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4445 /* If parameter checking is enabled... */
4446 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4447 if (hEdmaResMgr == NULL)
4448 {
4449 result = EDMA3_RM_E_INVALID_PARAM;
4450 }
4452 if ((lChObj == NULL) || (newPaRAM == NULL))
4453 {
4454 result = EDMA3_RM_E_INVALID_PARAM;
4455 }
4456 #endif
4458 /* Check if the parameters are OK. */
4459 if (result == EDMA3_RM_SOK)
4460 {
4461 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4463 if (rmInstance == NULL)
4464 {
4465 result = EDMA3_RM_E_INVALID_PARAM;
4466 }
4467 }
4469 if (result == EDMA3_RM_SOK)
4470 {
4471 rmObj = rmInstance->pResMgrObjHandle;
4473 if (rmObj == NULL)
4474 {
4475 result = EDMA3_RM_E_INVALID_PARAM;
4476 }
4477 else
4478 {
4479 if (rmObj->gblCfgParams.globalRegs == NULL)
4480 {
4481 result = EDMA3_RM_E_INVALID_PARAM;
4482 }
4483 }
4484 }
4486 if (result == EDMA3_RM_SOK)
4487 {
4488 edma3Id = rmObj->phyCtrllerInstId;
4489 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4491 switch (lChObj->type)
4492 {
4493 case EDMA3_RM_RES_DMA_CHANNEL:
4494 {
4495 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4496 {
4497 paRAMId = edma3RmChBoundRes[edma3Id][lChObj->resId].paRAMId;
4498 }
4499 else
4500 {
4501 result = EDMA3_RM_E_INVALID_PARAM;
4502 }
4503 }
4504 break;
4506 case EDMA3_RM_RES_QDMA_CHANNEL:
4507 {
4508 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4509 {
4510 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4511 paRAMId = edma3RmChBoundRes[edma3Id][qdmaChId].paRAMId;
4512 }
4513 else
4514 {
4515 result = EDMA3_RM_E_INVALID_PARAM;
4516 }
4517 }
4518 break;
4520 case EDMA3_RM_RES_PARAM_SET:
4521 {
4522 if (lChObj->resId < edma3NumPaRAMSets)
4523 {
4524 /**
4525 * User has passed the actual param set value here.
4526 * Use this value only
4527 */
4528 paRAMId = (int32_t)(lChObj->resId);
4529 }
4530 else
4531 {
4532 result = EDMA3_RM_E_INVALID_PARAM;
4533 }
4534 }
4535 break;
4537 default:
4538 {
4539 result = EDMA3_RM_E_INVALID_PARAM;
4540 break;
4541 }
4542 }
4543 }
4546 if (result == EDMA3_RM_SOK)
4547 {
4548 /* Check the param id first. */
4549 if ((paRAMId != -1) && ((uint32_t)paRAMId < edma3NumPaRAMSets))
4550 {
4551 /* Set the PaRAM Set now. */
4552 edma3ParamCpy ((volatile void *)(&(globalRegs->PARAMENTRY[paRAMId].OPT)),
4553 (const void *)newPaRAM);
4554 }
4555 else
4556 {
4557 result = EDMA3_RM_E_INVALID_PARAM;
4558 }
4559 }
4562 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4563 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4564 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4565 EDMA3_DVT_dCOUNTER,
4566 EDMA3_DVT_dNONE,
4567 EDMA3_DVT_dNONE));
4568 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4570 return result;
4571 }
4573 EDMA3_RM_Result EDMA3_RM_getPaRAM (EDMA3_RM_Handle hEdmaResMgr,
4574 const EDMA3_RM_ResDesc *lChObj,
4575 EDMA3_RM_PaRAMRegs *currPaRAM)
4576 {
4577 EDMA3_RM_Result result = EDMA3_RM_SOK;
4578 EDMA3_RM_Instance *rmInstance = NULL;
4579 EDMA3_RM_Obj *rmObj = NULL;
4580 int32_t paRAMId = 0;
4581 uint32_t qdmaChId = 0U;
4582 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4583 uint32_t edma3Id;
4585 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4586 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4587 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4588 EDMA3_DVT_dCOUNTER,
4589 EDMA3_DVT_dNONE,
4590 EDMA3_DVT_dNONE));
4591 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4593 /* If parameter checking is enabled... */
4594 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4595 if (hEdmaResMgr == NULL)
4596 {
4597 result = EDMA3_RM_E_INVALID_PARAM;
4598 }
4600 if ((lChObj == NULL) || (currPaRAM == NULL))
4601 {
4602 result = EDMA3_RM_E_INVALID_PARAM;
4603 }
4604 #endif
4606 /* Check if the parameters are OK. */
4607 if (result == EDMA3_RM_SOK)
4608 {
4609 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4611 if (rmInstance == NULL)
4612 {
4613 result = EDMA3_RM_E_INVALID_PARAM;
4614 }
4615 }
4617 if (result == EDMA3_RM_SOK)
4618 {
4619 rmObj = rmInstance->pResMgrObjHandle;
4621 if (rmObj == NULL)
4622 {
4623 result = EDMA3_RM_E_INVALID_PARAM;
4624 }
4625 else
4626 {
4627 if (rmObj->gblCfgParams.globalRegs == NULL)
4628 {
4629 result = EDMA3_RM_E_INVALID_PARAM;
4630 }
4631 }
4632 }
4634 if (result == EDMA3_RM_SOK)
4635 {
4636 edma3Id = rmObj->phyCtrllerInstId;
4637 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4639 switch (lChObj->type)
4640 {
4641 case EDMA3_RM_RES_DMA_CHANNEL:
4642 {
4643 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4644 {
4645 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][lChObj->resId].paRAMId;
4646 }
4647 else
4648 {
4649 result = EDMA3_RM_E_INVALID_PARAM;
4650 }
4651 }
4652 break;
4654 case EDMA3_RM_RES_QDMA_CHANNEL:
4655 {
4656 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4657 {
4658 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4659 paRAMId = edma3RmChBoundRes[rmObj->phyCtrllerInstId][qdmaChId].paRAMId;
4660 }
4661 else
4662 {
4663 result = EDMA3_RM_E_INVALID_PARAM;
4664 }
4665 }
4666 break;
4668 case EDMA3_RM_RES_PARAM_SET:
4669 {
4670 if (lChObj->resId < edma3NumPaRAMSets)
4671 {
4672 /**
4673 * User has passed the actual param set value here.
4674 * Use this value only
4675 */
4676 paRAMId = (int32_t)(lChObj->resId);
4677 }
4678 else
4679 {
4680 result = EDMA3_RM_E_INVALID_PARAM;
4681 }
4682 }
4683 break;
4685 default:
4686 {
4687 result = EDMA3_RM_E_INVALID_PARAM;
4688 break;
4689 }
4690 }
4691 }
4694 if (result == EDMA3_RM_SOK)
4695 {
4696 /* Check the param id first. */
4697 if ((paRAMId != -1) && ((uint32_t)paRAMId < edma3NumPaRAMSets))
4698 {
4699 /* Get the PaRAM Set now. */
4700 edma3ParamCpy ((void *)currPaRAM ,
4701 (const volatile void *)(&(globalRegs->PARAMENTRY [paRAMId].OPT)));
4702 }
4703 else
4704 {
4705 result = EDMA3_RM_E_INVALID_PARAM;
4706 }
4707 }
4710 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4711 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4712 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4713 EDMA3_DVT_dCOUNTER,
4714 EDMA3_DVT_dNONE,
4715 EDMA3_DVT_dNONE));
4716 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4719 return result;
4720 }
4722 EDMA3_RM_Result EDMA3_RM_getPaRAMPhyAddr(EDMA3_RM_Handle hEdmaResMgr,
4723 const EDMA3_RM_ResDesc *lChObj,
4724 uint32_t *paramPhyAddr)
4725 {
4726 EDMA3_RM_Result result = EDMA3_RM_SOK;
4727 EDMA3_RM_Instance *rmInstance = NULL;
4728 EDMA3_RM_Obj *rmObj = NULL;
4729 int32_t paRAMId = 0;
4730 uint32_t qdmaChId = 0U;
4731 volatile EDMA3_CCRL_Regs *globalRegs = NULL;
4732 uint32_t edma3Id;
4734 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4735 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4736 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4737 EDMA3_DVT_dCOUNTER,
4738 EDMA3_DVT_dNONE,
4739 EDMA3_DVT_dNONE));
4740 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4743 /* If parameter checking is enabled... */
4744 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4745 if (hEdmaResMgr == NULL)
4746 {
4747 result = EDMA3_RM_E_INVALID_PARAM;
4748 }
4750 if ((lChObj == NULL) || (paramPhyAddr == NULL))
4751 {
4752 result = EDMA3_RM_E_INVALID_PARAM;
4753 }
4754 #endif
4756 if (result == EDMA3_RM_SOK)
4757 {
4758 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4760 if (rmInstance == NULL)
4761 {
4762 result = EDMA3_RM_E_INVALID_PARAM;
4763 }
4764 }
4766 if (result == EDMA3_RM_SOK)
4767 {
4768 rmObj = rmInstance->pResMgrObjHandle;
4770 if (rmObj == NULL)
4771 {
4772 result = EDMA3_RM_E_INVALID_PARAM;
4773 }
4774 else
4775 {
4776 if (rmObj->gblCfgParams.globalRegs == NULL)
4777 {
4778 result = EDMA3_RM_E_INVALID_PARAM;
4779 }
4780 }
4781 }
4783 if (result == EDMA3_RM_SOK)
4784 {
4785 edma3Id = rmObj->phyCtrllerInstId;
4786 globalRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
4788 switch (lChObj->type)
4789 {
4790 case EDMA3_RM_RES_DMA_CHANNEL:
4791 {
4792 if (lChObj->resId <= edma3_dma_ch_max_val[edma3Id])
4793 {
4794 paRAMId = edma3RmChBoundRes[edma3Id][lChObj->resId].paRAMId;
4795 }
4796 else
4797 {
4798 result = EDMA3_RM_E_INVALID_PARAM;
4799 }
4800 }
4801 break;
4803 case EDMA3_RM_RES_QDMA_CHANNEL:
4804 {
4805 if (lChObj->resId < EDMA3_MAX_QDMA_CH)
4806 {
4807 qdmaChId = lChObj->resId + edma3_qdma_ch_min_val[edma3Id];
4808 paRAMId = edma3RmChBoundRes[edma3Id][qdmaChId].paRAMId;
4809 }
4810 else
4811 {
4812 result = EDMA3_RM_E_INVALID_PARAM;
4813 }
4814 }
4815 break;
4817 case EDMA3_RM_RES_PARAM_SET:
4818 {
4819 if (lChObj->resId < edma3NumPaRAMSets)
4820 {
4821 /**
4822 * User has passed the actual param set value here.
4823 * Use this value only
4824 */
4825 paRAMId = (int32_t)(lChObj->resId);
4826 }
4827 else
4828 {
4829 result = EDMA3_RM_E_INVALID_PARAM;
4830 }
4831 }
4832 break;
4834 default:
4835 {
4836 result = EDMA3_RM_E_INVALID_PARAM;
4837 break;
4838 }
4839 }
4840 }
4842 if (result == EDMA3_RM_SOK)
4843 {
4844 /* Check the param id first. */
4845 if ((paRAMId != -1) && (paRAMId < (int32_t)edma3NumPaRAMSets))
4846 {
4847 /* Get the PaRAM Set Address now. */
4848 *paramPhyAddr = (uint32_t)(&(globalRegs->PARAMENTRY [paRAMId].OPT));
4849 }
4850 else
4851 {
4852 result = EDMA3_RM_E_INVALID_PARAM;
4853 }
4854 }
4856 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4857 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4858 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4859 EDMA3_DVT_dCOUNTER,
4860 EDMA3_DVT_dNONE,
4861 EDMA3_DVT_dNONE));
4862 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4864 return result;
4865 }
4867 EDMA3_RM_Result EDMA3_RM_getBaseAddress (EDMA3_RM_Handle hEdmaResMgr,
4868 EDMA3_RM_Cntrlr_PhyAddr controllerId,
4869 uint32_t *phyAddress)
4870 {
4871 EDMA3_RM_Result result = EDMA3_RM_SOK;
4872 EDMA3_RM_Instance *rmInstance = NULL;
4873 EDMA3_RM_Obj *rmObj = NULL;
4875 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4876 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4877 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4878 EDMA3_DVT_dCOUNTER,
4879 EDMA3_DVT_dNONE,
4880 EDMA3_DVT_dNONE));
4881 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4884 /* If parameter checking is enabled... */
4885 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4886 if ((hEdmaResMgr == NULL) || (phyAddress == NULL))
4887 {
4888 result = EDMA3_RM_E_INVALID_PARAM;
4889 }
4890 #endif
4892 if (result == EDMA3_RM_SOK)
4893 {
4894 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
4896 if (rmInstance == NULL)
4897 {
4898 result = EDMA3_RM_E_INVALID_PARAM;
4899 }
4900 }
4902 if (result == EDMA3_RM_SOK)
4903 {
4904 rmObj = rmInstance->pResMgrObjHandle;
4906 if (rmObj == NULL)
4907 {
4908 result = EDMA3_RM_E_INVALID_PARAM;
4909 }
4910 }
4912 if (result == EDMA3_RM_SOK)
4913 {
4914 /* If parameter checking is enabled... */
4915 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4916 /* Verify the 'controllerId' */
4917 if (((int32_t)controllerId < (int32_t)((EDMA3_RM_Cntrlr_PhyAddr)(EDMA3_RM_CC_PHY_ADDR)))
4918 || (controllerId > (EDMA3_RM_Cntrlr_PhyAddr)(rmObj->gblCfgParams.numTcs)))
4919 {
4920 /* Invalid controllerId */
4921 result = EDMA3_RM_E_INVALID_PARAM;
4922 }
4923 #endif
4925 /* Check if the parameters are OK. */
4926 if (EDMA3_RM_SOK == result)
4927 {
4928 if (controllerId == EDMA3_RM_CC_PHY_ADDR)
4929 {
4930 /* EDMA3 Channel Controller Address */
4931 *phyAddress = (uint32_t)(rmObj->gblCfgParams.globalRegs);
4932 }
4933 else
4934 {
4935 /**
4936 * Since the TCs enum start from 1, and TCs start from 0,
4937 * subtract 1 from the enum to get the actual address.
4938 */
4939 *phyAddress = (uint32_t)(rmObj->gblCfgParams.tcRegs[controllerId-1U]);
4940 }
4941 }
4942 }
4944 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4945 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4946 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4947 EDMA3_DVT_dCOUNTER,
4948 EDMA3_DVT_dNONE,
4949 EDMA3_DVT_dNONE));
4950 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4952 return result;
4953 }
4955 EDMA3_RM_Result EDMA3_RM_getGblConfigParams (
4956 uint32_t phyCtrllerInstId,
4957 EDMA3_RM_GblConfigParams *gblCfgParams)
4958 {
4959 EDMA3_RM_Result result = EDMA3_RM_SOK;
4961 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4962 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4963 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
4964 EDMA3_DVT_dCOUNTER,
4965 EDMA3_DVT_dNONE,
4966 EDMA3_DVT_dNONE));
4967 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4969 /* If parameter checking is enabled... */
4970 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
4971 if ((phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
4972 || (NULL == gblCfgParams))
4973 {
4974 result = EDMA3_RM_E_INVALID_PARAM;
4975 }
4976 #endif
4978 if (EDMA3_RM_SOK == result)
4979 {
4980 /* Return the previously saved global config information for the EDMA3 HW */
4981 edma3MemCpy((void *)(gblCfgParams),
4982 (const void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
4983 sizeof (EDMA3_RM_GblConfigParams));
4984 }
4986 #ifdef EDMA3_INSTRUMENTATION_ENABLED
4987 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
4988 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
4989 EDMA3_DVT_dCOUNTER,
4990 EDMA3_DVT_dNONE,
4991 EDMA3_DVT_dNONE));
4992 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
4994 return result;
4995 }
4997 EDMA3_RM_Result EDMA3_RM_getInstanceInitCfg (
4998 EDMA3_RM_Handle hEdmaResMgr,
4999 EDMA3_RM_InstanceInitConfig *instanceInitConfig)
5000 {
5001 EDMA3_RM_Result result = EDMA3_RM_SOK;
5002 EDMA3_RM_Instance *rmInstance = NULL;
5003 EDMA3_RM_Obj *rmObj = NULL;
5004 uint32_t resMgrIdx = 0U;
5005 uint32_t hwId;
5007 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5008 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5009 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
5010 EDMA3_DVT_dCOUNTER,
5011 EDMA3_DVT_dNONE,
5012 EDMA3_DVT_dNONE));
5013 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5015 /* If parameter checking is enabled... */
5016 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5017 if ((hEdmaResMgr == NULL) || (instanceInitConfig == NULL))
5018 {
5019 result = EDMA3_RM_E_INVALID_PARAM;
5020 }
5021 #endif
5023 if (result == EDMA3_RM_SOK)
5024 {
5025 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
5027 if (rmInstance == NULL)
5028 {
5029 result = EDMA3_RM_E_INVALID_PARAM;
5030 }
5031 }
5033 if (result == EDMA3_RM_SOK)
5034 {
5035 rmObj = rmInstance->pResMgrObjHandle;
5037 if (rmObj == NULL)
5038 {
5039 result = EDMA3_RM_E_INVALID_PARAM;
5040 }
5041 }
5043 if (result == EDMA3_RM_SOK)
5044 {
5045 hwId = rmObj->phyCtrllerInstId;
5047 for (resMgrIdx = 0U; resMgrIdx < EDMA3_MAX_RM_INSTANCES; resMgrIdx++)
5048 {
5049 if (rmInstance == ((EDMA3_RM_Instance *)(ptrRMIArray) +
5050 (hwId*EDMA3_MAX_RM_INSTANCES) +
5051 resMgrIdx))
5052 {
5053 /* RM Id found. Return the specific config info to the user. */
5054 edma3MemCpy((void *)(instanceInitConfig),
5055 (const void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) +
5056 (hwId*EDMA3_MAX_RM_INSTANCES) +
5057 resMgrIdx),
5058 sizeof (EDMA3_RM_InstanceInitConfig));
5059 break;
5060 }
5061 }
5063 if (EDMA3_MAX_RM_INSTANCES == resMgrIdx)
5064 {
5065 /* RM Id not found, report error... */
5066 result = EDMA3_RM_E_INVALID_PARAM;
5067 }
5068 }
5070 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5071 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5072 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5073 EDMA3_DVT_dCOUNTER,
5074 EDMA3_DVT_dNONE,
5075 EDMA3_DVT_dNONE));
5076 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5078 return result;
5079 }
5081 EDMA3_RM_Result EDMA3_RM_Ioctl(
5082 EDMA3_RM_Handle hEdmaResMgr,
5083 EDMA3_RM_IoctlCmd cmd,
5084 void *cmdArg,
5085 void *param
5086 )
5087 {
5088 EDMA3_RM_Result result = EDMA3_RM_SOK;
5089 EDMA3_RM_Instance *rmInstance = NULL;
5090 uint32_t paramInitRequired = 0xFFU;
5091 uint32_t regModificationRequired = 0xFFU;
5092 uint32_t *ret_val = NULL;
5094 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5095 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5096 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
5097 EDMA3_DVT_dCOUNTER,
5098 EDMA3_DVT_dNONE,
5099 EDMA3_DVT_dNONE));
5100 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5102 /* If parameter checking is enabled... */
5103 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5104 if (hEdmaResMgr == NULL)
5105 {
5106 result = EDMA3_RM_E_INVALID_PARAM;
5107 }
5109 if ((cmd <= EDMA3_RM_IOCTL_MIN_IOCTL)
5110 || (cmd >= EDMA3_RM_IOCTL_MAX_IOCTL))
5111 {
5112 result = EDMA3_RM_E_INVALID_PARAM;
5113 }
5114 #endif
5116 if (result == EDMA3_RM_SOK)
5117 {
5118 rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
5120 if (rmInstance == NULL)
5121 {
5122 result = EDMA3_RM_E_INVALID_PARAM;
5123 }
5124 }
5126 if (result == EDMA3_RM_SOK)
5127 {
5128 switch (cmd)
5129 {
5130 case EDMA3_RM_IOCTL_SET_PARAM_CLEAR_OPTION:
5131 {
5132 paramInitRequired = (uint32_t)cmdArg;
5134 /* If parameter checking is enabled... */
5135 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5136 if ((paramInitRequired != 0U)
5137 && (paramInitRequired != 1U))
5138 {
5139 result = EDMA3_RM_E_INVALID_PARAM;
5140 }
5141 #endif
5143 /* Check if the parameters are OK. */
5144 if (EDMA3_RM_SOK == result)
5145 {
5146 /* Set/Reset the flag which is being used to do the PaRAM clearing. */
5147 rmInstance->paramInitRequired = paramInitRequired;
5148 }
5150 break;
5151 }
5153 case EDMA3_RM_IOCTL_GET_PARAM_CLEAR_OPTION:
5154 {
5155 /* If parameter checking is enabled... */
5156 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5157 if (NULL == cmdArg)
5158 {
5159 result = EDMA3_RM_E_INVALID_PARAM;
5160 }
5161 #endif
5163 /* Check if the parameters are OK. */
5164 if (EDMA3_RM_SOK == result)
5165 {
5166 ret_val = (uint32_t *)cmdArg;
5168 /* Get the flag which is being used to do the PaRAM clearing. */
5169 *ret_val = rmInstance->paramInitRequired;
5170 }
5172 break;
5173 }
5175 case EDMA3_RM_IOCTL_SET_GBL_REG_MODIFY_OPTION:
5176 {
5177 regModificationRequired = (uint32_t)cmdArg;
5179 /* If parameter checking is enabled... */
5180 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5181 if ((regModificationRequired != 0U)
5182 && (regModificationRequired != 1U))
5183 {
5184 /* All other values are invalid. */
5185 result = EDMA3_RM_E_INVALID_PARAM;
5186 }
5187 #endif
5189 /* Check if the parameters are OK. */
5190 if (EDMA3_RM_SOK == result)
5191 {
5192 /**
5193 * Set/Reset the flag which is being used to do the global
5194 * registers and PaRAM modification.
5195 */
5196 rmInstance->regModificationRequired = regModificationRequired;
5197 }
5199 break;
5200 }
5202 case EDMA3_RM_IOCTL_GET_GBL_REG_MODIFY_OPTION:
5203 {
5204 /* If parameter checking is enabled... */
5205 #ifndef EDMA3_RM_PARAM_CHECK_DISABLE
5206 if (NULL == cmdArg)
5207 {
5208 result = EDMA3_RM_E_INVALID_PARAM;
5209 }
5210 #endif
5212 /* Check if the parameters are OK. */
5213 if (EDMA3_RM_SOK == result)
5214 {
5215 ret_val = (uint32_t *)cmdArg;
5217 /**
5218 * Get the flag which is being used to do the global
5219 * registers and PaRAM modification.
5220 */
5221 *ret_val = rmInstance->regModificationRequired;
5222 }
5224 break;
5225 }
5227 default:
5228 {
5229 /* Hey dude! you passed invalid IOCTL cmd */
5230 result = EDMA3_RM_E_INVALID_PARAM;
5231 break;
5232 }
5234 }
5235 }
5238 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5239 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5240 EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
5241 EDMA3_DVT_dCOUNTER,
5242 EDMA3_DVT_dNONE,
5243 EDMA3_DVT_dNONE));
5244 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5246 return result;
5248 }
5250 /**
5251 * edma3ComplHandler
5252 * \brief Interrupt handler for successful transfer completion.
5253 *
5254 * \note This function first disables its own interrupt to make it non-
5255 * entrant. Later, after calling all the callback functions, it
5256 * re-enables its own interrupt.
5257 *
5258 * \return None.
5259 */
5260 static void edma3ComplHandler (const EDMA3_RM_Obj *rmObj)
5261 {
5262 uint32_t Cnt;
5263 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
5264 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
5265 volatile uint32_t pendingIrqs;
5266 volatile uint32_t isIPR = 0;
5268 uint32_t indexl;
5269 uint32_t indexh;
5270 uint32_t edma3Id;
5271 uint32_t numTCCs;
5273 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5274 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5275 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5276 EDMA3_DVT_dNONE,
5277 EDMA3_DVT_dNONE,
5278 EDMA3_DVT_dNONE));
5279 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5281 assert (NULL != rmObj);
5283 edma3Id = rmObj->phyCtrllerInstId;
5284 numTCCs = rmObj->gblCfgParams.numTccs;
5285 ptrEdmaccRegs =
5286 (volatile EDMA3_CCRL_Regs *)rmObj->gblCfgParams.globalRegs;
5287 if (ptrEdmaccRegs != NULL)
5288 {
5289 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
5290 (&ptrEdmaccRegs->SHADOW[edma3RegionId]);
5291 }
5293 Cnt = 0U;
5294 pendingIrqs = 0U;
5295 indexl = 1U;
5296 indexh = 1U;
5298 if(shadowRegs != NULL)
5299 {
5300 if (numTCCs > 32U)
5301 {
5302 isIPR = shadowRegs->IPR | shadowRegs->IPRH;
5303 }
5304 else
5305 {
5306 isIPR = shadowRegs->IPR;
5307 }
5309 if(isIPR)
5310 {
5311 /**
5312 * Since an interrupt has found, we have to make sure that this
5313 * interrupt (TCC) belongs to the TCCs allocated by us only.
5314 * It might happen that someone else, who is using EDMA3 also,
5315 * is the owner of this interrupt channel i.e. the TCC.
5316 * For this, use the allocatedTCCs[], to check which all interrupt
5317 * channels are owned by the EDMA3 RM Instances.
5318 */
5320 edma3OsProtectEntry (edma3Id,
5321 (int32_t)EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,
5322 NULL);
5324 /* Loop for EDMA3_RM_COMPL_HANDLER_RETRY_COUNT number of time,
5325 breaks when no pending interrupt is found */
5326 while ((Cnt < EDMA3_RM_COMPL_HANDLER_RETRY_COUNT)
5327 && ((indexl != 0U) || (indexh != 0U)))
5328 {
5329 indexl = 0U;
5330 pendingIrqs = shadowRegs->IPR;
5332 /**
5333 * Choose interrupts coming from our allocated TCCs
5334 * and MASK remaining ones.
5335 */
5336 pendingIrqs = (pendingIrqs & allocatedTCCs[edma3Id][0U]);
5338 while (pendingIrqs)
5339 {
5340 /*Process all the pending interrupts*/
5341 if((pendingIrqs & 1U) == TRUE)
5342 {
5343 /**
5344 * If the user has not given any callback function
5345 * while requesting the TCC, its TCC specific bit
5346 * in the IPR register will NOT be cleared.
5347 */
5348 if(edma3IntrParams[edma3Id][indexl].tccCb != NULL)
5349 {
5350 /* here write to ICR to clear the corresponding IPR bits*/
5351 shadowRegs->ICR = (1U << indexl);
5353 edma3IntrParams[edma3Id][indexl].tccCb (indexl,
5354 EDMA3_RM_XFER_COMPLETE,
5355 edma3IntrParams[edma3Id][indexl].cbData);
5356 }
5357 }
5358 ++indexl;
5359 pendingIrqs >>= 1U;
5360 }
5362 if(numTCCs > 32U)
5363 {
5364 indexh = 0U;
5365 pendingIrqs = shadowRegs->IPRH;
5367 /**
5368 * Choose interrupts coming from our allocated TCCs
5369 * and MASK remaining ones.
5370 */
5371 pendingIrqs = (pendingIrqs & allocatedTCCs[edma3Id][1U]);
5373 while (pendingIrqs)
5374 {
5375 /*Process all the pending interrupts*/
5376 if((pendingIrqs & 1U)==TRUE)
5377 {
5378 /**
5379 * If the user has not given any callback function
5380 * while requesting the TCC, its TCC specific bit
5381 * in the IPRH register will NOT be cleared.
5382 */
5383 if(edma3IntrParams[edma3Id][32U+indexh].tccCb!=NULL)
5384 {
5385 /* here write to ICR to clear the corresponding IPR bits*/
5386 shadowRegs->ICRH = (1U << indexh);
5388 edma3IntrParams[edma3Id][32U+indexh].tccCb(32U+indexh,
5389 EDMA3_RM_XFER_COMPLETE,
5390 edma3IntrParams[edma3Id][32U+indexh].cbData);
5391 }
5392 }
5393 ++indexh;
5394 pendingIrqs >>= 1U;
5395 }
5396 }
5398 Cnt++;
5399 }
5401 indexl = (shadowRegs->IPR & allocatedTCCs[edma3Id][0U]);
5402 if (numTCCs > 32U)
5403 {
5404 indexh = (shadowRegs->IPRH & allocatedTCCs[edma3Id][1U]);
5405 }
5407 if((indexl !=0 ) || (indexh !=0 ))
5408 {
5409 shadowRegs->IEVAL=0x1U;
5410 }
5412 edma3OsProtectExit (rmObj->phyCtrllerInstId,
5413 (int32_t)EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,
5414 0);
5415 }
5416 }
5418 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5419 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
5420 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5421 EDMA3_DVT_dNONE,
5422 EDMA3_DVT_dNONE,
5423 EDMA3_DVT_dNONE));
5424 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5425 }
5428 void lisrEdma3ComplHandler0(uint32_t edma3InstanceId)
5429 {
5430 /* Invoke Completion Handler ISR */
5431 edma3ComplHandler(&resMgrObj[edma3InstanceId]);
5432 }
5435 /**
5436 * \brief Interrupt handler for Channel Controller Error.
5437 *
5438 * \note This function first disables its own interrupt to make it non-
5439 * entrant. Later, after calling all the callback functions, it
5440 * re-enables its own interrupt.
5441 *
5442 * \return None.
5443 */
5444 static void edma3CCErrHandler(const EDMA3_RM_Obj *rmObj)
5445 {
5446 uint32_t Cnt = 0U;
5447 uint32_t resMgrInstIdx = 0U;
5448 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
5449 volatile EDMA3_CCRL_ShadowRegs *shadowRegs = NULL;
5450 volatile uint32_t pendingIrqs = 0;
5451 uint32_t index;
5452 uint32_t evtqueNum;
5453 EDMA3_RM_Instance *rm_instance = NULL;
5454 uint32_t edma3Id;
5455 uint32_t num_rm_instances_opened;
5456 EDMA3_RM_Instance *rmInstance = NULL;
5457 uint32_t ownedDmaError = 0;
5458 uint32_t ownedDmaHError = 0;
5459 uint32_t ownedQdmaError = 0;
5460 uint32_t numTCCs;
5462 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5463 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_CCERR",
5464 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5465 EDMA3_DVT_dNONE,
5466 EDMA3_DVT_dNONE,
5467 EDMA3_DVT_dNONE));
5468 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5470 assert (rmObj != NULL);
5472 edma3Id = rmObj->phyCtrllerInstId;
5473 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)rmObj->gblCfgParams.globalRegs;
5474 numTCCs = rmObj->gblCfgParams.numTccs;
5475 if (ptrEdmaccRegs != NULL)
5476 {
5477 shadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)&ptrEdmaccRegs->SHADOW[edma3RegionId];
5478 rmInstance = ((EDMA3_RM_Instance *)(ptrRMIArray)
5479 + (edma3Id*EDMA3_MAX_RM_INSTANCES)
5480 + edma3RegionId);
5482 if((ptrEdmaccRegs->EMR != 0 )
5483 || (ptrEdmaccRegs->QEMR != 0)
5484 || (ptrEdmaccRegs->CCERR != 0))
5485 {
5486 pendingIrqs = 1U;
5487 }
5488 if (numTCCs > 32U)
5489 {
5490 if(ptrEdmaccRegs->EMRH != 0)
5491 {
5492 pendingIrqs = 1U;
5493 }
5494 }
5495 index = 1U;
5497 if(pendingIrqs)
5498 {
5499 edma3OsProtectEntry (edma3Id,
5500 (int32_t)EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR,
5501 NULL);
5503 /* Loop for EDMA3_RM_CCERR_HANDLER_RETRY_COUNT number of time,
5504 breaks when no pending interrupt is found */
5505 while ((Cnt < EDMA3_RM_CCERR_HANDLER_RETRY_COUNT)
5506 && (index != 0U))
5507 {
5508 index = 0U;
5509 pendingIrqs = ptrEdmaccRegs->EMR;
5511 while (pendingIrqs)
5512 {
5513 /*Process all the pending interrupts*/
5514 if((pendingIrqs & 1U)==TRUE)
5515 {
5516 uint32_t mappedTcc = 0U;
5518 /**
5519 * Using the 'index' value (basically the DMA
5520 * channel), fetch the corresponding TCC
5521 * value, mapped to this DMA channel.
5522 */
5523 mappedTcc = edma3DmaChTccMapping[edma3Id][index];
5525 /**
5526 * Ensure that the mapped tcc is valid and the call
5527 * back is not NULL
5528 */
5529 if (mappedTcc < EDMA3_MAX_TCC)
5530 {
5531 /**
5532 * TCC owned and allocated by RM.
5533 * Write to EMCR to clear the corresponding EMR bits.
5534 */
5535 ptrEdmaccRegs->EMCR = (1U<<index);
5536 /*Clear any SER*/
5537 shadowRegs->SECR = (1U<<index);
5539 /* Call the callback function if registered earlier. */
5540 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5541 {
5542 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5543 mappedTcc,
5544 EDMA3_RM_E_CC_DMA_EVT_MISS,
5545 edma3IntrParams[edma3Id][mappedTcc].cbData
5546 );
5547 }
5548 }
5549 else
5550 {
5551 /**
5552 * DMA channel not owned by the RM instance.
5553 * Check the global error interrupt clearing option.
5554 * If it is TRUE, clear the error interupt else leave
5555 * it like that.
5556 */
5557 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5558 /* here write to EMCR to clear the corresponding EMR bits. */
5559 ptrEdmaccRegs->EMCR = (1U<<index);
5560 /*Clear any SER*/
5561 ptrEdmaccRegs->SECR = (1U<<index);
5562 #endif
5563 }
5564 }
5565 ++index;
5566 pendingIrqs >>= 1U;
5567 }
5569 if(numTCCs > 32U)
5570 {
5571 index = 0U;
5572 pendingIrqs = ptrEdmaccRegs->EMRH;
5573 while (pendingIrqs)
5574 {
5575 /*Process all the pending interrupts*/
5576 if((pendingIrqs & 1U)==TRUE)
5577 {
5578 uint32_t mappedTcc = 0U;
5580 /**
5581 * Using the 'index' value (basically the DMA
5582 * channel), fetch the corresponding TCC
5583 * value, mapped to this DMA channel.
5584 */
5585 mappedTcc = edma3DmaChTccMapping[edma3Id][32U+index];
5587 /**
5588 * Ensure that the mapped tcc is valid and the call
5589 * back is not NULL
5590 */
5591 if (mappedTcc < EDMA3_MAX_TCC)
5592 {
5593 /**
5594 * TCC owned and allocated by RM.
5595 * Write to EMCR to clear the corresponding EMR bits.
5596 */
5597 ptrEdmaccRegs->EMCRH = (1U<<index);
5598 /*Clear any SERH*/
5599 shadowRegs->SECRH = (1U<<index);
5601 /* Call the callback function if registered earlier. */
5602 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5603 {
5604 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5605 mappedTcc,
5606 EDMA3_RM_E_CC_DMA_EVT_MISS,
5607 edma3IntrParams[edma3Id][mappedTcc].cbData
5608 );
5609 }
5610 }
5611 else
5612 {
5613 /**
5614 * DMA channel not owned by the RM instance.
5615 * Check the global error interrupt clearing option.
5616 * If it is TRUE, clear the error interupt else leave
5617 * it like that.
5618 */
5619 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5620 /**
5621 * TCC NOT owned by RM.
5622 * Write to EMCRH to clear the corresponding EMRH bits.
5623 */
5624 ptrEdmaccRegs->EMCRH = (1U<<index);
5625 /*Clear any SERH*/
5626 shadowRegs->SECRH = (1U<<index);
5627 #endif
5628 }
5629 }
5630 ++index;
5631 pendingIrqs >>= 1U;
5632 }
5633 }
5635 index = 0U;
5636 pendingIrqs = ptrEdmaccRegs->QEMR;
5637 while (pendingIrqs)
5638 {
5639 /*Process all the pending interrupts*/
5640 if((pendingIrqs & 1U)==TRUE)
5641 {
5642 uint32_t mappedTcc = 0U;
5644 /**
5645 * Using the 'index' value (basically the QDMA
5646 * channel), fetch the corresponding TCC
5647 * value, mapped to this QDMA channel.
5648 */
5649 mappedTcc = edma3QdmaChTccMapping[edma3Id][index];
5651 if (mappedTcc < EDMA3_MAX_TCC)
5652 {
5653 /* here write to QEMCR to clear the corresponding QEMR bits*/
5654 ptrEdmaccRegs->QEMCR = (1U<<index);
5655 /*Clear any QSER*/
5656 shadowRegs->QSECR = (1U<<index);
5658 if((edma3IntrParams[edma3Id][mappedTcc].tccCb) != NULL)
5659 {
5660 edma3IntrParams[edma3Id][mappedTcc].tccCb (
5661 mappedTcc,
5662 EDMA3_RM_E_CC_QDMA_EVT_MISS,
5663 edma3IntrParams[edma3Id][mappedTcc].cbData
5664 );
5665 }
5666 }
5667 else
5668 {
5669 /**
5670 * QDMA channel not owned by the RM instance.
5671 * Check the global error interrupt clearing option.
5672 * If it is TRUE, clear the error interupt else leave
5673 * the ISR.
5674 */
5675 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5676 /* here write to QEMCR to clear the corresponding QEMR bits*/
5677 ptrEdmaccRegs->QEMCR = (1U<<index);
5679 /*Clear any QSER*/
5680 ptrEdmaccRegs->QSECR = (1U<<index);
5681 #endif
5682 }
5683 }
5684 ++index;
5685 pendingIrqs >>= 1U;
5686 }
5688 index = 0U;
5689 pendingIrqs = ptrEdmaccRegs->CCERR;
5690 if (pendingIrqs!=0)
5691 {
5692 /* Process all the pending CC error interrupts. */
5694 /* Queue threshold error for different event queues.*/
5695 for (evtqueNum = 0U; evtqueNum < rmObj->gblCfgParams.numEvtQueue; evtqueNum++)
5696 {
5697 if((pendingIrqs & ((uint32_t)1U << evtqueNum)) != 0)
5698 {
5699 /**
5700 * Queue threshold error for queue 'evtqueNum' raised.
5701 * Inform all the RM instances working on this region
5702 * about the error by calling their global callback functions.
5703 */
5704 resMgrInstIdx = 0U;
5705 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5706 {
5707 /* Check whether the RM instance opened working on this region */
5708 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5709 if (NULL != rm_instance)
5710 {
5711 if (rm_instance->initParam.regionId == edma3RegionId)
5712 {
5713 /* Region id matches, call the callback function */
5714 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5715 {
5716 rm_instance->initParam.gblerrCbParams.gblerrCb(
5717 EDMA3_RM_E_CC_QUE_THRES_EXCEED,
5718 evtqueNum,
5719 rm_instance->initParam.gblerrCbParams.gblerrData);
5720 }
5721 }
5722 }
5724 ++resMgrInstIdx;
5725 /* Check next opened instance */
5726 }
5728 /* Clear the error interrupt. */
5729 ptrEdmaccRegs->CCERRCLR = (1U << evtqueNum);
5730 }
5731 }
5734 /* Transfer completion code error. */
5735 if ((pendingIrqs & ((uint32_t)1 << EDMA3_CCRL_CCERR_TCCERR_SHIFT))!=0)
5736 {
5737 /**
5738 * Transfer completion code error raised.
5739 * Inform all the RM instances working on this region
5740 * about the error by calling their global callback functions.
5741 */
5743 resMgrInstIdx = 0U;
5744 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5745 {
5746 /* Check whether the RM instance opened working on this region */
5747 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5748 if (NULL != rm_instance)
5749 {
5750 if (rm_instance->initParam.regionId == edma3RegionId)
5751 {
5752 /* Region id matches, call the callback function */
5753 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5754 {
5755 rm_instance->initParam.gblerrCbParams.gblerrCb(
5756 EDMA3_RM_E_CC_TCC,
5757 0,
5758 rm_instance->initParam.gblerrCbParams.gblerrData);
5759 }
5760 }
5761 }
5763 ++resMgrInstIdx;
5764 /* Check next opened instance */
5765 }
5767 ptrEdmaccRegs->CCERRCLR = ((uint32_t)1<<EDMA3_CCRL_CCERR_TCCERR_SHIFT);
5768 }
5770 ++index;
5771 }
5773 Cnt++;
5774 }
5777 /**
5778 * Read the error registers again. If any interrupt is pending,
5779 * write the EEVAL register.
5780 * Moreover, according to the global error interrupt clearing
5781 * option, check either error bits associated with all the
5782 * DMA/QDMA channels (option is SET) OR check error bits
5783 * associated with owned DMA/QDMA channels.
5784 */
5785 #if (EDMA3_RM_RES_CLEAR_ERROR_STATUS_FOR_ALL_CHANNELS == TRUE)
5786 /* To remove warning. */
5787 rmInstance = rmInstance;
5789 /* Check all the error bits. */
5790 ownedDmaError = ptrEdmaccRegs->EMR;
5791 if (numTCCs > 32U)
5792 {
5793 ownedDmaHError = ptrEdmaccRegs->EMRH;
5794 }
5795 ownedQdmaError = ptrEdmaccRegs->QEMR;
5796 #else
5797 /* Check ONLY owned error bits. */
5798 ownedDmaError = (ptrEdmaccRegs->EMR & rmInstance->initParam.rmInstInitConfig->ownDmaChannels[0U]);
5799 if (numTCCs > 32)
5800 ownedDmaHError = (ptrEdmaccRegs->EMRH & rmInstance->initParam.rmInstInitConfig->ownDmaChannels[1U]);
5801 ownedQdmaError = (ptrEdmaccRegs->QEMR & rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0U]);
5802 #endif
5804 if (((ownedDmaError != 0 ) || (ownedDmaHError != 0 ))
5805 || ((ownedQdmaError != 0) || (ptrEdmaccRegs->CCERR != 0)))
5806 {
5807 ptrEdmaccRegs->EEVAL=0x1U;
5808 }
5810 edma3OsProtectExit (rmObj->phyCtrllerInstId,
5811 (int32_t)EDMA3_OS_PROTECT_INTERRUPT_CC_ERROR,
5812 0);
5813 }
5814 /* Write to EEVAL is required to re-evaluate the Error interrupt */
5815 /* Without this error interrupt will not be deassarted */
5816 ptrEdmaccRegs->EEVAL=0x1U;
5817 }
5819 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5820 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_CCERR",
5821 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
5822 EDMA3_DVT_dNONE,
5823 EDMA3_DVT_dNONE,
5824 EDMA3_DVT_dNONE));
5825 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5826 }
5828 void lisrEdma3CCErrHandler0(uint32_t edma3InstanceId)
5829 {
5830 /* Invoke CC Error Handler ISR */
5831 edma3CCErrHandler(&resMgrObj[edma3InstanceId]);
5832 }
5836 /**
5837 * \brief Interrupt handler for Transfer Controller Error.
5838 *
5839 * \note This function first disables its own interrupt to make it non-
5840 * entrant. Later, after calling all the callback functions, it
5841 * re-enables its own interrupt.
5842 *
5843 * \return None.
5844 */
5845 static void edma3TCErrHandler (const EDMA3_RM_Obj *rmObj, uint32_t tcNum)
5846 {
5847 volatile EDMA3_TCRL_Regs *tcRegs = NULL;
5848 uint32_t tcMemErrRdWr = 0U;
5849 uint32_t resMgrInstIdx = 0U;
5850 EDMA3_RM_Instance *rm_instance = NULL;
5851 uint32_t edma3Id;
5852 uint32_t num_rm_instances_opened;
5854 #ifdef EDMA3_INSTRUMENTATION_ENABLED
5855 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_TCERR",
5856 EDMA3_DVT_DESC(EDMA3_DVT_eINT_START,
5857 EDMA3_DVT_dNONE,
5858 EDMA3_DVT_dNONE,
5859 EDMA3_DVT_dNONE));
5860 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
5862 assert (rmObj != NULL);
5864 assert (tcNum < rmObj->gblCfgParams.numTcs);
5866 if (rmObj->gblCfgParams.tcRegs[tcNum] != NULL)
5867 {
5868 tcRegs = (volatile EDMA3_TCRL_Regs *)(rmObj->gblCfgParams.tcRegs[tcNum]);
5869 edma3Id = rmObj->phyCtrllerInstId;
5870 }
5872 if (tcRegs != NULL)
5873 {
5874 if(tcRegs->ERRSTAT != 0)
5875 {
5876 edma3OsProtectEntry (rmObj->phyCtrllerInstId,
5877 (int32_t)EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR,
5878 &tcNum);
5880 if((tcRegs->ERRSTAT & ((uint32_t)1 << EDMA3_TCRL_ERRSTAT_BUSERR_SHIFT))!= 0)
5881 {
5882 /* Bus error event. */
5883 /**
5884 * EDMA3TC has detected an error at source or destination
5885 * address. Error information can be read from the error
5886 * details register (ERRDET).
5887 */
5888 tcMemErrRdWr = tcRegs->ERRDET & ((uint32_t)EDMA3_TCRL_ERRDET_STAT_MASK);
5889 if ((tcMemErrRdWr > 0U) && (tcMemErrRdWr < 8U))
5890 {
5891 /**
5892 * Inform all the RM instances working on this region
5893 * about the error by calling their global callback functions.
5894 */
5895 resMgrInstIdx = 0U;
5896 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5897 {
5898 /* Check whether the RM instance opened working on this region */
5899 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5900 if (NULL != rm_instance)
5901 {
5902 if (rm_instance->initParam.regionId == edma3RegionId)
5903 {
5904 /* Region id matches, call the callback function */
5905 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5906 {
5907 rm_instance->initParam.gblerrCbParams.gblerrCb(
5908 EDMA3_RM_E_TC_MEM_LOCATION_READ_ERROR,
5909 tcNum,
5910 rm_instance->initParam.gblerrCbParams.gblerrData);
5911 }
5912 }
5913 }
5915 ++resMgrInstIdx;
5916 /* Check next opened instance */
5917 }
5918 }
5919 else
5920 {
5921 if ((tcMemErrRdWr >= 8U) && (tcMemErrRdWr <= 0xFU))
5922 {
5923 /**
5924 * Inform all the RM instances working on this region
5925 * about the error by calling their global callback functions.
5926 */
5927 resMgrInstIdx = 0U;
5928 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5929 {
5930 /* Check whether the RM instance opened working on this region */
5931 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5932 if (NULL != rm_instance)
5933 {
5934 if (rm_instance->initParam.regionId == edma3RegionId)
5935 {
5936 /* Region id matches, call the callback function */
5937 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5938 {
5939 rm_instance->initParam.gblerrCbParams.gblerrCb(
5940 EDMA3_RM_E_TC_MEM_LOCATION_WRITE_ERROR,
5941 tcNum,
5942 rm_instance->initParam.gblerrCbParams.gblerrData);
5943 }
5944 }
5945 }
5947 ++resMgrInstIdx;
5948 /* Check next opened instance */
5949 }
5950 }
5951 }
5952 tcRegs->ERRCLR = ((uint32_t)1<<EDMA3_TCRL_ERRSTAT_BUSERR_SHIFT);
5953 }
5954 else
5955 {
5956 /* Transfer request (TR) error event. */
5957 if((tcRegs->ERRSTAT & ((uint32_t)1 << EDMA3_TCRL_ERRSTAT_TRERR_SHIFT))!= 0)
5958 {
5959 resMgrInstIdx = 0U;
5960 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5961 {
5962 /* Check whether the RM instance opened working on this region */
5963 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5964 if (NULL != rm_instance)
5965 {
5966 if (rm_instance->initParam.regionId == edma3RegionId)
5967 {
5968 /* Region id matches, call the callback function */
5969 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
5970 {
5971 rm_instance->initParam.gblerrCbParams.gblerrCb(
5972 EDMA3_RM_E_TC_TR_ERROR,
5973 tcNum,
5974 rm_instance->initParam.gblerrCbParams.gblerrData);
5975 }
5976 }
5977 }
5979 ++resMgrInstIdx;
5980 /* Check next opened instance */
5981 }
5983 tcRegs->ERRCLR = ((uint32_t)1<<EDMA3_TCRL_ERRSTAT_TRERR_SHIFT);
5984 }
5985 else
5986 {
5987 if((tcRegs->ERRSTAT & ((uint32_t)1 << EDMA3_TCRL_ERRSTAT_MMRAERR_SHIFT))!= 0)
5988 {
5989 resMgrInstIdx = 0U;
5990 for (num_rm_instances_opened = resMgrObj[edma3Id].numOpens; num_rm_instances_opened != 0; num_rm_instances_opened--)
5991 {
5992 /* Check whether the RM instance opened working on this region */
5993 rm_instance = ((EDMA3_RM_Instance *)(ptrRMIArray) + (edma3Id*EDMA3_MAX_RM_INSTANCES) + resMgrInstIdx);
5994 if (NULL != rm_instance)
5995 {
5996 if (rm_instance->initParam.regionId == edma3RegionId)
5997 {
5998 /* Region id matches, call the callback function */
5999 if (rm_instance->initParam.gblerrCbParams.gblerrCb != NULL)
6000 {
6001 rm_instance->initParam.gblerrCbParams.gblerrCb(
6002 EDMA3_RM_E_TC_INVALID_ADDR,
6003 tcNum,
6004 rm_instance->initParam.gblerrCbParams.gblerrData);
6005 }
6006 }
6007 }
6009 ++resMgrInstIdx;
6010 /* Check next opened instance */
6011 }
6013 tcRegs->ERRCLR = ((uint32_t)1<<EDMA3_TCRL_ERRSTAT_MMRAERR_SHIFT);
6014 }
6015 }
6016 }
6018 edma3OsProtectExit (rmObj->phyCtrllerInstId,
6019 (int32_t)EDMA3_OS_PROTECT_INTERRUPT_TC_ERROR,
6020 tcNum);
6021 }
6022 }
6024 #ifdef EDMA3_INSTRUMENTATION_ENABLED
6025 EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3_TCERR",
6026 EDMA3_DVT_DESC(EDMA3_DVT_eINT_END,
6027 EDMA3_DVT_dNONE,
6028 EDMA3_DVT_dNONE,
6029 EDMA3_DVT_dNONE));
6030 #endif /* EDMA3_INSTRUMENTATION_ENABLED */
6031 }
6035 /*
6036 * ======== lisrEdma3TC0ErrHandler0 ========
6037 * EDMA3 instance 0 TC0 Error Interrupt Service Routine
6038 */
6039 void lisrEdma3TC0ErrHandler0(uint32_t edma3InstanceId)
6040 {
6041 /* Invoke Error Handler ISR for TC0*/
6042 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)0U);
6043 }
6046 /*
6047 * ======== lisrEdma3TC1ErrHandler0 ========
6048 * EDMA3 instance 0 TC1 Error Interrupt Service Routine
6049 */
6050 void lisrEdma3TC1ErrHandler0(uint32_t edma3InstanceId)
6051 {
6052 /* Invoke Error Handler ISR for TC1*/
6053 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)1U);
6054 }
6056 /*
6057 * ======== lisrEdma3TC2ErrHandler0 ========
6058 * EDMA3 instance 0 TC2 Error Interrupt Service Routine
6059 */
6060 void lisrEdma3TC2ErrHandler0(uint32_t edma3InstanceId)
6061 {
6062 /* Invoke Error Handler ISR for TC2*/
6063 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)2U);
6064 }
6066 /*
6067 * ======== lisrEdma3TC3ErrHandler0 ========
6068 * EDMA3 instance 0 TC3 Error Interrupt Service Routine
6069 */
6070 void lisrEdma3TC3ErrHandler0(uint32_t edma3InstanceId)
6071 {
6072 /* Invoke Error Handler ISR for TC3*/
6073 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)3U);
6074 }
6076 /*
6077 * ======== lisrEdma3TC4ErrHandler0 ========
6078 * EDMA3 instance 0 TC4 Error Interrupt Service Routine
6079 */
6080 void lisrEdma3TC4ErrHandler0(uint32_t edma3InstanceId)
6081 {
6082 /* Invoke Error Handler ISR for TC4*/
6083 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)4U);
6084 }
6087 /*
6088 * ======== lisrEdma3TC5ErrHandler0 ========
6089 * EDMA3 instance 0 TC5 Error Interrupt Service Routine
6090 */
6091 void lisrEdma3TC5ErrHandler0(uint32_t edma3InstanceId)
6092 {
6093 /* Invoke Error Handler ISR for TC5*/
6094 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)5U);
6095 }
6097 /*
6098 * ======== lisrEdma3TC6ErrHandler0 ========
6099 * EDMA3 instance 0 TC6 Error Interrupt Service Routine
6100 */
6101 /* ARGSUSED */
6102 void lisrEdma3TC6ErrHandler0(uint32_t edma3InstanceId)
6103 {
6104 /* Invoke Error Handler ISR for TC6*/
6105 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)6U);
6106 }
6108 /*
6109 * ======== lisrEdma3TC7ErrHandler0 ========
6110 * EDMA3 instance 0 TC7 Error Interrupt Service Routine
6111 */
6112 void lisrEdma3TC7ErrHandler0(uint32_t edma3InstanceId)
6113 {
6114 /* Invoke Error Handler ISR for TC7*/
6115 edma3TCErrHandler(&resMgrObj[edma3InstanceId], (uint32_t)7U);
6116 }
6120 /* Resource Manager Internal functions - Start */
6122 /** Initialization of the Global region registers of the EDMA3 Controller */
6123 static void edma3GlobalRegionInit (uint32_t phyCtrllerInstId, uint32_t numDmaChannels)
6124 {
6125 uint32_t evtQNum = 0U;
6126 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
6128 assert (phyCtrllerInstId < EDMA3_MAX_EDMA3_INSTANCES);
6130 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)
6131 (resMgrObj[phyCtrllerInstId].gblCfgParams.globalRegs);
6133 if (ptrEdmaccRegs != NULL)
6134 {
6135 ptrEdmaccRegs->EMCR = EDMA3_RM_SET_ALL_BITS;
6136 if ( numDmaChannels > 32U)
6137 {
6138 /* Clear the EMCRH only if available channels are more than 32 */
6139 ptrEdmaccRegs->EMCRH = EDMA3_RM_SET_ALL_BITS;
6140 }
6141 ptrEdmaccRegs->QEMCR = EDMA3_RM_SET_ALL_BITS;
6143 /*
6144 * Set all Instance-wide EDMA3 parameters (not channel-specific)
6145 */
6147 /**
6148 * Set TC Priority among system-wide bus-masters and Queue
6149 * Watermark Level
6150 */
6151 while (evtQNum <
6152 resMgrObj[phyCtrllerInstId].gblCfgParams.numEvtQueue)
6153 {
6154 ptrEdmaccRegs->QUEPRI &= EDMA3_RM_QUEPRI_CLR_MASK(evtQNum);
6155 ptrEdmaccRegs->QUEPRI |= EDMA3_RM_QUEPRI_SET_MASK(evtQNum,
6156 resMgrObj[phyCtrllerInstId].gblCfgParams.evtQPri[evtQNum]);
6158 ptrEdmaccRegs->QWMTHRA |= EDMA3_RM_QUEWMTHR_SET_MASK(evtQNum,
6159 resMgrObj[phyCtrllerInstId].gblCfgParams.evtQueueWaterMarkLvl[evtQNum]);
6161 evtQNum++;
6162 }
6164 /* Clear CCERR register */
6165 ptrEdmaccRegs ->CCERRCLR = 0xFFFFU;
6166 }
6168 return;
6169 }
6174 /** Initialization of the Shadow region registers of the EDMA3 Controller */
6175 static void edma3ShadowRegionInit (const EDMA3_RM_Instance *pRMInstance)
6176 {
6177 volatile EDMA3_CCRL_Regs *ptrEdmaccRegs = NULL;
6178 volatile EDMA3_CCRL_ShadowRegs *ptrEdmaShadowRegs = NULL;
6179 uint32_t phyCtrllerInstId;
6180 uint32_t regionId;
6181 const EDMA3_RM_InstanceInitConfig *rmInstInitConfig = NULL;
6183 assert (pRMInstance != NULL);
6185 rmInstInitConfig = pRMInstance->initParam.rmInstInitConfig;
6187 if (rmInstInitConfig != NULL)
6188 {
6189 phyCtrllerInstId = pRMInstance->pResMgrObjHandle->phyCtrllerInstId;
6190 regionId = pRMInstance->initParam.regionId;
6192 ptrEdmaccRegs = (volatile EDMA3_CCRL_Regs *)
6193 (resMgrObj[phyCtrllerInstId].gblCfgParams.globalRegs);
6195 if (ptrEdmaccRegs != NULL)
6196 {
6197 ptrEdmaShadowRegs = (volatile EDMA3_CCRL_ShadowRegs *)
6198 (&ptrEdmaccRegs->SHADOW[regionId]);
6200 ptrEdmaShadowRegs->ECR = (rmInstInitConfig->ownDmaChannels[0U]
6201 | rmInstInitConfig->ownTccs[0U]);
6202 ptrEdmaShadowRegs->ECRH = (rmInstInitConfig->ownDmaChannels[1U]
6203 | rmInstInitConfig->ownTccs[1U]);
6204 ptrEdmaShadowRegs->EECR = (rmInstInitConfig->ownDmaChannels[0U]
6205 | rmInstInitConfig->ownTccs[0U]);
6206 ptrEdmaShadowRegs->SECR = (rmInstInitConfig->ownDmaChannels[0U]
6207 | rmInstInitConfig->ownTccs[0U]);
6208 ptrEdmaShadowRegs->SECRH = (rmInstInitConfig->ownDmaChannels[1U]
6209 | rmInstInitConfig->ownTccs[1U]);
6210 ptrEdmaShadowRegs->EECR = (rmInstInitConfig->ownDmaChannels[0U]
6211 | rmInstInitConfig->ownTccs[0U]);
6212 ptrEdmaShadowRegs->EECRH = (rmInstInitConfig->ownDmaChannels[1U]
6213 | rmInstInitConfig->ownTccs[1U]);
6215 ptrEdmaShadowRegs->QEECR = rmInstInitConfig->ownQdmaChannels[0U];
6217 ptrEdmaShadowRegs->IECR = (rmInstInitConfig->ownDmaChannels[0U]
6218 | rmInstInitConfig->ownTccs[0U]);
6219 ptrEdmaShadowRegs->IECRH = (rmInstInitConfig->ownDmaChannels[1U]
6220 | rmInstInitConfig->ownTccs[1U]);
6221 ptrEdmaShadowRegs->ICR = (rmInstInitConfig->ownDmaChannels[0U]
6222 | rmInstInitConfig->ownTccs[0U]);
6223 ptrEdmaShadowRegs->ICRH = (rmInstInitConfig->ownDmaChannels[1U]
6224 | rmInstInitConfig->ownTccs[1U]);
6226 ptrEdmaShadowRegs->QSECR = rmInstInitConfig->ownQdmaChannels[0U];
6228 /*
6229 * Set all EDMA3 Resource<->Region mapping parameters
6230 */
6232 /* 1. Dma Channel (and TCC) <-> Region */
6233 ptrEdmaccRegs->DRA[regionId].DRAE = 0U;
6234 ptrEdmaccRegs->DRA[regionId].DRAEH = 0U;
6236 /* 2. Qdma Channel <-> Region */
6237 ptrEdmaccRegs->QRAE[regionId] = 0U;
6238 }
6239 }
6241 return;
6242 }
6246 /** Local MemZero function */
6247 void edma3MemZero(void *dst, uint32_t len)
6248 {
6249 uint32_t i = 0U;
6250 uint32_t *ds = NULL;
6252 assert (dst != NULL);
6254 ds = (uint32_t *)dst;
6256 for (i = 0U ; i < (len/4U) ; i++)
6257 {
6258 *ds = 0x0;
6259 ds++;
6260 }
6262 return;
6263 }
6266 /* Local MemCopy function */
6267 void edma3MemCpy(void *dst, const void *src, uint32_t len)
6268 {
6269 uint32_t i=0U;
6270 const uint32_t *sr;
6271 uint32_t *ds;
6273 assert (src != NULL);
6274 assert (dst != NULL);
6275 assert ((len%4U) == 0);
6277 sr = (const uint32_t *)src;
6278 ds = (uint32_t *)dst;
6280 for (i = 0U ; i < (len/4U) ; i++)
6281 {
6282 *ds = *sr;
6283 ds++;
6284 sr++;
6285 }
6287 return;
6288 }
6291 /* Local MemCopy function to copy Param Set ONLY */
6292 void edma3ParamCpy(volatile void *dst, const volatile void *src)
6293 {
6294 uint32_t i = 0U;
6295 const volatile uint32_t *sr;
6296 volatile uint32_t *ds;
6298 assert (src != NULL);
6299 assert (dst != NULL);
6301 sr = (const volatile uint32_t *)src;
6302 ds = (volatile uint32_t *)dst;
6304 for (i = 0U; i < 8U; i++)
6305 {
6306 *ds = *sr;
6307 ds++;
6308 sr++;
6309 }
6311 return;
6312 }
6315 /**
6316 * Finds a particular bit ('0' or '1') in the particular word from 'start'.
6317 * If found, returns the position, else return -1.
6318 */
6319 static int32_t findBitInWord (int32_t source, uint32_t start, uint16_t bit)
6320 {
6321 uint32_t position = start;
6322 uint16_t found = 0;
6323 uint32_t iterations_left = 0;
6324 uint32_t sourceTmp=0;
6326 switch (bit)
6327 {
6328 case 1U:
6329 {
6330 sourceTmp = (uint32_t)source >> (start%32U);
6331 source = (int32_t)sourceTmp;
6333 while ((found==0U) && (source!=0))
6334 {
6335 if (((uint32_t)source & 0x1U) == 0x1U)
6336 {
6337 /* 1 */
6338 found++;
6339 }
6340 else
6341 {
6342 /* 0 */
6343 sourceTmp = (uint32_t)source >> 1;
6344 source = (int32_t)sourceTmp;
6345 position++;
6346 }
6347 }
6349 }
6350 break;
6352 case 0:
6353 {
6354 sourceTmp = (uint32_t)source >> (start%32U);
6355 source = (int32_t)sourceTmp;
6356 iterations_left = (uint32_t)32U - (start%32U);
6358 while ((found==0U) && (iterations_left>0U))
6359 {
6360 if (((uint32_t)source & 0x1U) == 0x1U)
6361 {
6362 /* 1 */
6363 sourceTmp = (uint32_t)source >> 1;
6364 source = (int32_t)sourceTmp;
6365 position++;
6366 iterations_left--;
6367 }
6368 else
6369 {
6370 /* 0 */
6371 found++;
6372 }
6373 }
6374 }
6375 break;
6377 default:
6378 break;
6379 }
6381 return (found ? (int32_t)position : -1);
6382 }
6385 /**
6386 * Finds a particular bit ('0' or '1') in the specified resources' array
6387 * from 'start' to 'end'. If found, returns the position, else return -1.
6388 */
6389 static int32_t findBit (EDMA3_RM_ResType resType,
6390 uint32_t start,
6391 uint32_t end,
6392 uint16_t bit)
6393 {
6394 int32_t position = -1;
6395 uint32_t start_index = start / 32U;
6396 uint32_t end_index = end / 32U;
6397 int32_t i;
6398 uint32_t *resPtr = 0x0;
6399 int32_t ret = -1;
6400 EDMA3_RM_Result result = EDMA3_RM_SOK;
6402 assert (start <= end);
6404 /**
6405 * job is to find 'bit' in an array[start_index:end_index]
6406 * algo used:
6407 * first search in array[start_index]
6408 * then search in array[start_index + 1 : end_index - 1]
6409 * then search in array[end_index]
6410 */
6411 switch (resType)
6412 {
6413 case EDMA3_RM_RES_DMA_CHANNEL:
6414 resPtr = &contiguousDmaRes[0];
6415 break;
6417 case EDMA3_RM_RES_QDMA_CHANNEL:
6418 resPtr = &contiguousQdmaRes[0];
6419 break;
6421 case EDMA3_RM_RES_TCC:
6422 resPtr = &contiguousTccRes[0];
6423 break;
6425 case EDMA3_RM_RES_PARAM_SET:
6426 resPtr = &contiguousParamRes[0];
6427 break;
6429 default:
6430 result = EDMA3_RM_E_INVALID_PARAM;
6431 break;
6432 }
6434 if (EDMA3_RM_SOK == result)
6435 {
6436 switch (bit)
6437 {
6438 case 1U:
6439 {
6440 /* Find '1' in first word. */
6441 position = findBitInWord (resPtr[start_index], start, (uint16_t)1U);
6443 if (position != -1)
6444 {
6445 ret = position;
6446 }
6447 else
6448 {
6449 /* '1' NOT found, look into other words. */
6450 for (i = ((int32_t)start_index + (int32_t)1U); i <= ((int32_t)end_index - (int32_t)1U); i++)
6451 {
6452 position = findBitInWord (resPtr[i], (uint32_t)0U, (uint16_t)1U);
6453 if (position != -1)
6454 {
6455 /* '1' Found... */
6456 ret = (position + (i*32));
6457 break;
6458 }
6459 }
6461 /* First check whether we have found '1' or not. */
6462 if (ret == -1)
6463 {
6464 /* Still not found, look in the last word. */
6465 position = findBitInWord(resPtr[end_index], (uint32_t)0U, (uint16_t)1U);
6466 if (position != -1)
6467 {
6468 /* Finally got it. */
6469 ret = (position + ((int32_t)end_index*(int32_t)32U));
6470 }
6471 else
6472 {
6473 /* Sorry, could not find it, return -1. */
6474 ret = -1;
6475 }
6476 }
6477 }
6478 }
6479 break;
6481 case 0U:
6482 {
6483 /* Find '0' in first word. */
6484 position = findBitInWord(resPtr[start_index], start, (uint16_t)0U);
6485 if (position != -1)
6486 {
6487 ret = position;
6488 }
6489 else
6490 {
6491 /* '0' NOT found, look into other words. */
6492 for (i = ((int32_t)start_index + (int32_t)1U); i <= ((int32_t)end_index - (int32_t)1U); i++)
6493 {
6494 position = findBitInWord(resPtr[i], (uint32_t)0U, (uint16_t)0U);
6495 if (position != -1)
6496 {
6497 /* '0' found... */
6498 ret = (position + (i*32));
6499 break;
6500 }
6501 }
6503 /* First check whether we have found '0' or not. */
6504 if (ret == -1)
6505 {
6506 position = findBitInWord(resPtr[end_index], (uint32_t)0U, (uint16_t)0U);
6507 if (position != -1)
6508 {
6509 /* Finally got it. */
6510 ret = (position + ((int32_t)end_index*(int32_t)32U));
6511 }
6512 else
6513 {
6514 /* Sorry, could not find it, return -1. */
6515 ret = -1;
6516 }
6517 }
6518 }
6519 }
6520 break;
6522 default:
6523 break;
6524 }
6525 }
6529 return ((ret >= (int32_t)start) ? ret : -1);
6530 }
6534 /**
6535 * If successful, this function returns EDMA3_RM_SOK and the position
6536 * of first available resource in 'positionRes'. Else returns error.
6537 */
6538 static EDMA3_RM_Result allocAnyContigRes(EDMA3_RM_ResType resType,
6539 uint32_t numResources,
6540 uint32_t *positionRes)
6541 {
6542 uint16_t found = 0U;
6543 int32_t first_one, next_zero;
6544 uint32_t num_available;
6545 int32_t ret = -1;
6546 uint32_t start = 0;
6547 uint32_t end;
6548 EDMA3_RM_Result result = EDMA3_RM_SOK;
6550 assert (positionRes != NULL);
6552 switch (resType)
6553 {
6554 case EDMA3_RM_RES_DMA_CHANNEL:
6555 end = EDMA3_MAX_DMA_CH - 1U;
6556 break;
6558 case EDMA3_RM_RES_QDMA_CHANNEL:
6559 end = EDMA3_MAX_QDMA_CH - 1U;
6560 break;
6562 case EDMA3_RM_RES_TCC:
6563 end = EDMA3_MAX_TCC - 1U;
6564 break;
6566 case EDMA3_RM_RES_PARAM_SET:
6567 end = edma3NumPaRAMSets - 1U;
6568 break;
6570 default:
6571 result = EDMA3_RM_E_INVALID_PARAM;
6572 break;
6573 }
6575 if (result == EDMA3_RM_SOK)
6576 {
6577 /**
6578 * Algorithm used for finding N contiguous resources.
6579 * In the resources' array, '1' means available and '0' means
6580 * not-available.
6581 * Step a) Find first '1' starting from 'start'. If successful,
6582 * store it in first_one, else return error.
6583 * Step b) Find first '0' starting from (first_one+1) to 'end'.
6584 * If successful, store returned value in next_zero. If '0' could
6585 * not be located, it means all the resources are available.
6586 * Store 'end' (i.e. the last resource id) in next_zero.
6587 * Step c) Count the number of contiguous resources available
6588 * by subtracting first_one from next_zero.
6589 * Step d) If result < N, do the whole process again untill you
6590 * reach end. Else you have found enough resources, return success.
6591 */
6592 while((found == 0) && (start<=end) && (((end-start)+1U) >= numResources))
6593 {
6594 /* Find first '1' starting from 'start' till 'end'. */
6595 first_one = findBit (resType, start, end, (uint16_t)1U);
6596 if (first_one != -1)
6597 {
6598 /* Got first 1, search for first '0' now. */
6599 next_zero = findBit (resType, (uint32_t)first_one+(uint32_t)1, end, (uint16_t)0U);
6600 if (next_zero == -1)
6601 {
6602 /* Unable to find next zero, all 1' are there */
6603 next_zero = (int32_t)end + (int32_t)1U;
6604 }
6606 /* check no of resources available */
6607 num_available = (uint32_t)next_zero - (uint32_t)first_one;
6608 if (num_available >= numResources)
6609 {
6610 /* hurrah..., we have found enough resources. */
6611 found = 1U;
6612 ret = first_one;
6613 }
6614 else
6615 {
6616 /* Not enough resources, try again */
6617 start = (uint32_t)next_zero + (uint32_t)1;
6618 }
6619 }
6620 else
6621 {
6622 /* do nothing, first 1 is not there, return. */
6623 break;
6624 }
6625 }
6626 }
6629 if (result == EDMA3_RM_SOK)
6630 {
6631 if (found == 1U)
6632 {
6633 /* required resources found, retrun the first available res id. */
6634 *positionRes = (uint32_t)ret;
6635 }
6636 else
6637 {
6638 /* No resources allocated */
6639 result = EDMA3_RM_E_SPECIFIED_RES_NOT_AVAILABLE;
6640 }
6641 }
6643 return result;
6644 }
6648 /**
6649 * Starting from 'firstResIdObj', this function makes the next 'numResources'
6650 * Resources non-available for future. Also, it does some global resisters'
6651 * setting also.
6652 */
6653 static EDMA3_RM_Result gblChngAllocContigRes(EDMA3_RM_Instance *rmInstance,
6654 const EDMA3_RM_ResDesc *firstResIdObj,
6655 uint32_t numResources)
6656 {
6657 EDMA3_RM_Result result = EDMA3_RM_SOK;
6658 volatile EDMA3_CCRL_Regs *gblRegs = NULL;
6659 EDMA3_RM_Obj *rmObj = NULL;
6660 uint32_t avlblIdx = 0U;
6661 uint32_t firstResId=0U;
6662 uint32_t lastResId=0U;
6663 uint32_t edma3Id;
6665 assert (rmInstance != NULL);
6666 assert (firstResIdObj != NULL);
6668 rmObj = rmInstance->pResMgrObjHandle;
6670 if (rmObj == NULL)
6671 {
6672 result = EDMA3_RM_E_INVALID_PARAM;
6673 }
6675 if (EDMA3_RM_SOK == result)
6676 {
6677 edma3Id = rmObj->phyCtrllerInstId;
6678 gblRegs = (volatile EDMA3_CCRL_Regs *)(rmObj->gblCfgParams.globalRegs);
6680 if (gblRegs == NULL)
6681 {
6682 result = EDMA3_RM_E_INVALID_PARAM;
6683 }
6684 }
6686 if (result == EDMA3_RM_SOK)
6687 {
6688 switch (firstResIdObj->type)
6689 {
6690 case EDMA3_RM_RES_DMA_CHANNEL:
6691 {
6692 firstResId = firstResIdObj->resId;
6693 lastResId = firstResId + (numResources - 1U);
6695 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6696 {
6697 rmInstance->avlblDmaChannels[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
6699 /**
6700 * Enable the DMA channel in the DRAE/DRAEH registers also.
6701 */
6702 if (avlblIdx < 32U)
6703 {
6704 gblRegs->DRA[rmInstance->initParam.regionId].DRAE
6705 |= ((uint32_t)0x1U << avlblIdx);
6706 }
6707 else
6708 {
6709 gblRegs->DRA[rmInstance->initParam.regionId].DRAEH
6710 |= ((uint32_t)0x1U << (avlblIdx - 32U));
6711 }
6712 }
6713 }
6714 break;
6716 case EDMA3_RM_RES_QDMA_CHANNEL:
6717 {
6718 firstResId = firstResIdObj->resId;
6719 lastResId = firstResId + (numResources - 1U);
6721 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6722 {
6723 rmInstance->avlblQdmaChannels[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
6725 /**
6726 * Enable the QDMA channel in the QRAE register also.
6727 */
6728 gblRegs->QRAE[rmInstance->initParam.regionId]
6729 |= ((uint32_t)0x1U << avlblIdx);
6730 }
6731 }
6732 break;
6734 case EDMA3_RM_RES_TCC:
6735 {
6736 firstResId = firstResIdObj->resId;
6737 lastResId = firstResId + (numResources - 1U);
6739 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6740 {
6741 rmInstance->avlblTccs[avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
6743 /**
6744 * If the region id coming from this
6745 * RM instance is same as the Master RM
6746 * Instance's region id, only then we will be
6747 * getting the interrupts on the same side.
6748 * So save the TCC in the allocatedTCCs[] array.
6749 */
6750 if (edma3RegionId == rmInstance->initParam.regionId)
6751 {
6752 if (avlblIdx < 32U)
6753 {
6754 allocatedTCCs[edma3Id][0U] |= ((uint32_t)0x1U << avlblIdx);
6755 }
6756 else
6757 {
6758 allocatedTCCs[edma3Id][1U] |= ((uint32_t)0x1U << (avlblIdx - 32U));
6759 }
6760 }
6761 }
6762 }
6763 break;
6765 case EDMA3_RM_RES_PARAM_SET:
6766 {
6767 firstResId = firstResIdObj->resId;
6768 lastResId = firstResId + (numResources - 1U);
6770 for (avlblIdx=firstResId; avlblIdx <= lastResId; ++avlblIdx)
6771 {
6772 rmInstance->avlblPaRAMSets [avlblIdx/32U] &= (uint32_t)(~((uint32_t)1U << (avlblIdx%32U)));
6774 /**
6775 * Also, make the actual PARAM Set NULL, checking the flag
6776 * whether it is required or not.
6777 */
6778 if (TRUE == rmInstance->paramInitRequired)
6779 {
6780 edma3MemZero((void *)(&gblRegs->PARAMENTRY[avlblIdx]),
6781 sizeof(gblRegs->PARAMENTRY[avlblIdx]));
6782 }
6783 }
6784 }
6785 break;
6787 default:
6788 result = EDMA3_RM_E_INVALID_PARAM;
6789 break;
6790 }
6791 }
6794 return result;
6795 }
6798 EDMA3_RM_Result EDMA3_RM_initXbarEventMap (EDMA3_RM_Handle hEdma,
6799 const EDMA3_RM_GblXbarToChanConfigParams * edmaGblXbarConfig,
6800 EDMA3_RM_mapXbarEvtToChan mapXbarEvtFunc,
6801 EDMA3_RM_xbarConfigScr configXbarScr)
6802 {
6803 EDMA3_RM_Result result = EDMA3_DRV_SOK;
6804 EDMA3_RM_Instance *rmInstance = NULL;
6806 /* If parameter checking is enabled... */
6807 #ifndef EDMA3_DRV_PARAM_CHECK_DISABLE
6808 if (hEdma == NULL)
6809 {
6810 result = EDMA3_RM_E_INVALID_PARAM;
6811 }
6812 #endif
6814 /* Check if the parameters are OK. */
6815 if (EDMA3_DRV_SOK == result)
6816 {
6817 rmInstance = (EDMA3_RM_Instance *)hEdma;
6819 if (mapXbarEvtFunc != NULL)
6820 {
6821 rmInstance->mapXbarToChan = mapXbarEvtFunc;
6822 }
6823 if (configXbarScr != NULL)
6824 {
6825 rmInstance->configScrMapXbarToEvt = configXbarScr;
6826 }
6827 if (edmaGblXbarConfig != NULL)
6828 {
6829 edma3MemCpy((void *)(&rmInstance->rmXbarToEvtMapConfig),
6830 (const void *)(edmaGblXbarConfig),
6831 sizeof (EDMA3_RM_GblXbarToChanConfigParams));
6832 }
6833 }
6835 return (result);
6836 }
6838 /* Resource Manager Internal functions - End */
6840 /* End of File */