⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 edma3resmgr.c

📁 vicp做为dm6446上的硬件加速器
💻 C
📖 第 1 页 / 共 5 页
字号:
                        }

                    rmInstance->avlblQdmaChannels[0u]
                        = rmInstance->initParam.rmInstInitConfig->ownQdmaChannels[0u];

                    for (resMgrIdx = 0u; resMgrIdx < paramSetDwrds; ++resMgrIdx)
                        {
                        rmInstance->avlblPaRAMSets[resMgrIdx]
                            = rmInstance->initParam.rmInstInitConfig->ownPaRAMSets[resMgrIdx];
                        }

                    for (resMgrIdx = 0u; resMgrIdx < tccDwrds; ++resMgrIdx)
                        {
                        rmInstance->avlblTccs [resMgrIdx]
                            = rmInstance->initParam.rmInstInitConfig->ownTccs[resMgrIdx];
                        }

                    /*
                    * If mapping exists b/w DMA channel and PaRAM set (i.e. programmable),
                    * then mark those PaRAM sets which are mapped to some specific
                    * DMA channels as RESERVED. If NO mapping (ie ch 0 is tied to PaRAM 0,
                    * ch 1 is tied to PaRAM 1), mark all as RESERVED.
                    */
                    if (rmObj->gblCfgParams.dmaChPaRAMMapExists == TRUE)
                        {
                        /* Mapping Exists */
                        for (resMgrIdx = 0u; resMgrIdx < rmObj->gblCfgParams.numDmaChannels; ++resMgrIdx)
                            {
                            mappedPaRAMId = rmObj->gblCfgParams.dmaChannelPaRAMMap[resMgrIdx];
                            if (mappedPaRAMId != EDMA3_RM_CH_NO_PARAM_MAP)
                                {
                                /* Channel is mapped to a particular PaRAM Set, mark it as Reserved. */
                                rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[mappedPaRAMId/32u] |= (1u<<(mappedPaRAMId%32u));
                                }
                            }
                        }
                    else
                        {
                        /* Mapping Doesnot Exist, PaRAM Sets are 1-to-1 mapped, mark all as Reserved */
                        for (resMgrIdx = 0u; resMgrIdx < dmaChDwrds; ++resMgrIdx)
                            {
                            rmInstance->initParam.rmInstInitConfig->resvdPaRAMSets[resMgrIdx] = 0xFFFFFFFFu;
                            }
                        }

                    /*
                    * If the EDMA RM instance is MASTER (ie. initParam->isMaster
                    * is TRUE), save the region ID.
                    * Only this shadow region will receive the
                    * EDMA3 interrupts, if enabled.
                    */
                    if (TRUE == initParam->isMaster)
                        {
                        /* Store the region id to use it in the ISRs */
                        edma3RegionId = rmInstance->initParam.regionId;
                        masterExists = TRUE;
                        }

                    if (TRUE == initParam->regionInitEnable)
                        {
                        edma3ShadowRegionInit (rmInstance);
                        }

                    /**
                     * By default, PaRAM Sets allocated using this RM Instance
                     * will get cleared during their allocation.
                     * User can stop their clearing by calling specific IOCTL
                     * command.
                     */
                    rmInstance->paramInitRequired = TRUE;


                    /**
                     * By default, during the EDMA3_RM_allocLogicalChannel (),
                     * global EDMA3 registers (DCHMAP/QCHMAP) and the allocated
                     * PaRAM Set will be programmed accordingly, for users using this
                     * RM Instance.
                     * User can stop their pre-programming by calling
                     * EDMA3_RM_IOCTL_SET_GBL_REG_MODIFY_OPTION
                     * IOCTL command.
                     */
                    rmInstance->regModificationRequired = TRUE;


                    if (EDMA3_RM_SOK == result)
                        {
                        rmObj->state = EDMA3_RM_OPENED;
                        /* Increase the Instance count */
                        resMgrObj[phyCtrllerInstId].numOpens++;
                        retVal = rmInstance;
                        }
                    }
                else
                    {
                    result = EDMA3_RM_E_INVALID_PARAM;
                    }

                edma3OsProtectExit (EDMA3_OS_PROTECT_INTERRUPT, intState);
                }
            }
        }

    *errorCode = result;
    return (EDMA3_RM_Handle)retVal;
    }


/**\fn      EDMA3_RM_Result EDMA3_RM_close (EDMA3_RM_Handle hEdmaResMgr,
 *                                const void *param)
 * \brief  Close EDMA3 Resource Manager Instance
 *
 * This API is used to close a previously opened EDMA3 RM Instance.
 *
 * \param  hEdmaResMgr         [IN]    Handle to the previously opened Resource
 *                                     Manager Instance.
 * \param  param               [IN]    For possible future use.
 *
 * \return EDMA3_RM_SOK or EDMA3_RM Error Code
 *
 * \note    This function disables the global interrupts (by calling API
 *          edma3OsProtectEntry with protection level
 *          EDMA3_OS_PROTECT_INTERRUPT) while modifying the global RM data
 *          structures, to make it re-entrant.
 */
EDMA3_RM_Result EDMA3_RM_close (EDMA3_RM_Handle hEdmaResMgr,
                                    const void *param)
    {
    EDMA3_RM_Result result = EDMA3_RM_SOK;
    unsigned int intState = 0u;
    unsigned int resMgrIdx = 0u;
    EDMA3_RM_Obj *rmObj             = NULL;
    EDMA3_RM_Instance *rmInstance   = NULL;
    unsigned int dmaChDwrds;
    unsigned int paramSetDwrds;
    unsigned int tccDwrds;

    /*to remove CCS remark: parameter "param" was never referenced */
    (void)param;

    if (hEdmaResMgr == NULL)
        {
        result = EDMA3_RM_E_INVALID_PARAM;
        }
    else
        {
        rmInstance = (EDMA3_RM_Instance *)hEdmaResMgr;
        rmObj = rmInstance->pResMgrObjHandle;

        if (rmObj == NULL)
            {
            result = (EDMA3_RM_E_INVALID_PARAM);
            }
        else
            {
            /* Check state of driver, state should be opened */
            if (rmObj->state != EDMA3_RM_OPENED)
                {
                result = (EDMA3_RM_E_OBJ_NOT_OPENED);
                }
            else
                {
                dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / 32u;
                paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / 32u;
                tccDwrds = rmObj->gblCfgParams.numTccs / 32u;

                /* Set the instance config as NULL*/
                for (resMgrIdx = 0u; resMgrIdx < dmaChDwrds; ++resMgrIdx)
                    {
                    rmInstance->avlblDmaChannels[resMgrIdx] = 0x0u;
                    }
                for (resMgrIdx = 0u; resMgrIdx < paramSetDwrds; ++resMgrIdx)
                    {
                    rmInstance->avlblPaRAMSets[resMgrIdx] = 0x0u;
                    }
                rmInstance->avlblQdmaChannels[0u] = 0x0u;
                for (resMgrIdx = 0u; resMgrIdx < tccDwrds; ++resMgrIdx)
                    {
                    rmInstance->avlblTccs[resMgrIdx] = 0x0u;
                    }

                /**
                 * If this is the Master Instance, reset the static variable
                 * 'masterExists'.
                 */
                if (TRUE == rmInstance->initParam.isMaster)
                    {
                    masterExists = FALSE;
                    edma3RegionId = EDMA3_MAX_REGIONS;
                    }

                /* Reset the Initparam for this RM Instance */
                edma3MemSet((void *)&(rmInstance->initParam) , 0x00u,
                                            sizeof(EDMA3_RM_Param));

                /* Critical section starts */
                edma3OsProtectEntry (EDMA3_OS_PROTECT_INTERRUPT, &intState);

                /* Decrease the Number of Opens */
                --rmObj->numOpens;
                if (NULL == rmObj->numOpens)
                    {
                    edma3MemSet((void *)&(edma3RmChBoundRes[rmObj->phyCtrllerInstId]), 0x00u,
                                            sizeof(edma3RmChBoundRes));

                    rmObj->state = EDMA3_RM_CLOSED;
                    }

                /* Critical section ends */
                edma3OsProtectExit (EDMA3_OS_PROTECT_INTERRUPT, intState);

                rmInstance->pResMgrObjHandle = NULL;
                rmInstance->shadowRegs = NULL;
                rmInstance = NULL;
                }
            }
        }

    return result;
    }


/**\fn      EDMA3_RM_Result EDMA3_RM_allocResource (EDMA3_RM_Handle hEdmaResMgr,
 *                                        EDMA3_RM_ResDesc *resObj)
 * \brief   This API is used to allocate specified EDMA3 Resources like
 * DMA/QDMA channel, PaRAM Set or TCC.
 *
 * Note: To free the resources allocated by this API, user should call
 * EDMA3_RM_freeResource () ONLY to de-allocate all the allocated resources.
 *
 * User can either request a specific resource by passing the resource id
 * in 'resObj->resId' OR request ANY available resource of the type
 * 'resObj->type'.
 *
 * ANY types of resources are those resources when user doesn't care about the
 * actual resource allocated; user just wants a resource of the type specified.
 * One use-case is to perform memory-to-memory data transfer operation. This
 * operation can be performed using any available DMA or QDMA channel.
 * User doesn't need any specific channel for the same.
 *
 * To allocate a specific resource, first this API checks whether that resource
 * is OWNED by the Resource Manager instance. Then it checks the current
 * availability of that resource.
 *
 * To allocate ANY available resource, this API tries to allocate a resource
 * from the pool of (owned && non_reserved && available_right_now) resources.
 *
 * After allocating a DMA/QDMA channel or TCC, the same resource is enabled in
 * the shadow region specific register (DRAE/DRAEH/QRAE).
 *
 * Allocated PaRAM Set is initialized to NULL before this API returns if user
 * has requested for one.
 *
 * \param  hEdmaResMgr      [IN]        Handle to the previously opened Resource
 *                                      Manager Instance.
 * \param   resObj          [IN/OUT]    Handle to the resource descriptor
 *                                      object, which needs to be allocated.
 *                                      In case user passes a specific resource
 *                                      Id, resObj value is left unchanged.
 *                                      In case user requests ANY available
 *                                      resource, the allocated resource id is
 *                                      returned in resObj.
 *
 * \return  EDMA3_RM_SOK or EDMA3_RM Error Code
 *
 * \note    This function acquires a RM Instance specific semaphore
 *          to prevent simultaneous access to the global pool of resources.
 *          It is re-entrant, but should not be called from the user callback
 *          function (ISR context).
 */
EDMA3_RM_Result EDMA3_RM_allocResource(EDMA3_RM_Handle hEdmaResMgr,
                                        EDMA3_RM_ResDesc *resObj)
    {
    EDMA3_RM_Instance *rmInstance = NULL;
    EDMA3_RM_Obj *rmObj = NULL;
    EDMA3_RM_Result result = EDMA3_RM_SOK;
    EDMA3_RM_Result semResult = EDMA3_RM_SOK;
    unsigned int avlblIdx = 0u;
    unsigned int resIdClr = 0x0;
    unsigned int resIdSet = 0x0;
    unsigned int resId;
    volatile EDMA3_CCRL_Regs *gblRegs = NULL;

#ifdef EDMA3_INSTRUMENTATION_ENABLED
    EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -