From b38dd76a4f14dbe4ec37ac92ab8267805e365b08 Mon Sep 17 00:00:00 2001 From: Gokul S Date: Thu, 30 Apr 2026 13:27:16 +0530 Subject: [PATCH] virtual context implementation for csitx Signed-off-by: Gokul S --- source/drivers/csitx/v0/csitx.h | 14 + .../drivers/csitx/v0/include/csitx_drvPriv.h | 51 +- .../drivers/csitx/v0/include/csitx_drvUdma.h | 5 +- source/drivers/csitx/v0/soc/V0/csitx_soc.h | 3 + source/drivers/csitx/v0/src/csitx_drv.c | 647 +++++++++++------- source/drivers/csitx/v0/src/csitx_drvInit.c | 42 +- source/drivers/csitx/v0/src/csitx_drvUdma.c | 180 +++-- 7 files changed, 600 insertions(+), 342 deletions(-) diff --git a/source/drivers/csitx/v0/csitx.h b/source/drivers/csitx/v0/csitx.h index 6d7313a..5f33a0a 100755 --- a/source/drivers/csitx/v0/csitx.h +++ b/source/drivers/csitx/v0/csitx.h @@ -144,6 +144,20 @@ extern "C" { * */ #define IOCTL_CSITX_PRINT_DEBUG_LOGS (FVID2_CSITX_DRV_IOCTL_BASE + 0x0100U) + +/** + * \brief Get the context id + * + * This IOCTL can be used to get the context id for an instance + * Note: + * + * \param cmdArgs [OUT] NULL + * \param cmdArgsStatus [OUT] NULL + * + * \return FVID2_SOK on success, else failure + * + */ +#define IOCTL_CSITX_GET_INST_CONTEXT_ID (FVID2_CSITX_DRV_IOCTL_BASE + 0x0200U) /* @} */ /** diff --git a/source/drivers/csitx/v0/include/csitx_drvPriv.h b/source/drivers/csitx/v0/include/csitx_drvPriv.h index 863c434..c9a1393 100755 --- a/source/drivers/csitx/v0/include/csitx_drvPriv.h +++ b/source/drivers/csitx/v0/include/csitx_drvPriv.h @@ -205,6 +205,8 @@ extern "C" { /* ========================================================================== */ typedef struct CsitxDrv_ChObj CsitxDrv_ChObj; typedef struct CsitxDrv_InstObj CsitxDrv_InstObj; +typedef struct CsitxDrv_VirtContext_t CsitxDrv_VirtContext; +typedef struct CsitxDrv_CommonObj_t CsitxDrv_CommonObj; /** * \brief This structure contains information about data type and bpp. @@ -344,6 +346,32 @@ typedef struct Fvid2UtilsLinkListObj doneLlObj; /**< Linked List object for doneQ for all channels of each stream. */ } CsitxDrv_InstBufManObj; +/* + * struct CsitxDrv_VirtContext_t + * \brief CSITX driver global/common driver object. + */ +struct CsitxDrv_VirtContext_t +{ + uint32_t contextId; + /**< Context ID */ + uint32_t state; + /**< Instance state. + * See \ref CSITX_DrvState for details */ + CsitxDrv_InstObj *instObj; + /**< Reference to instance object. */ + uint32_t inUse; + /**< Current is being used or not. + * See \ref CSITX_DrvUsageStatus for details */ + uint32_t chId[CSITX_NUM_CH]; + /**< Array containing channel for this context */ + uint32_t numCh; + /**< Number of channels registered on this context */ + Csitx_CreateParams createParams; + /**< CSI Rx module create configurations. + * See \ref Csitx_CreateParams for details */ + Fvid2_DrvCbParams fdmCbParams; + /**< FVID2 driver manager callback function parameters. */ +}; /** * \brief CSITX Driver Channel Object. @@ -354,6 +382,11 @@ struct CsitxDrv_ChObj /**< CSI Tx Channel configuration passed down by application. */ CsitxDrv_InstObj *instObj; /**< Reference to instance object. */ + CsitxDrv_VirtContext *virtContext; + uint32_t chId; + /**< Channel ID */ + uint32_t numCh; + /**< Number of channels registered on this context */ uint32_t status; /**< Channel status * See \ref CSITXDRV_ChState for details */ @@ -420,9 +453,7 @@ struct CsitxDrv_InstObj uint32_t inUse; /**< Current is being used or not. * See \ref CSITX_DrvUsageStatus for details */ - uint32_t state; - /**< Instance state. - * See \ref CSITX_DrvState for details */ + CsitxDrv_CommonObj *commonObjRef; Csitx_CreateParams createParams; /**< CSI Tx module create configurations. * See \ref Csitx_CreateParams for details */ @@ -460,13 +491,19 @@ struct CsitxDrv_InstObj /**< CSITX D-PHY configurations. */ CsitxDrv_EventObj eventObj[CSITX_EVENT_GROUP_MAX]; /**< Event object for event management. */ + uint32_t dpyCfgDone; + /**< DPHY configuration done. 0: Not done 1: Done */ + Csitx_EventPrms eventParams; + /**< CSITX Event configurations. */ + uint32_t eventRegDone; + /**< Error Event configuration done. 0: Not done 1: Done */ }; /* * struct CsitxDrv_CommonObj * \brief Transmit driver global/common driver object. */ -typedef struct +struct CsitxDrv_CommonObj_t { Fvid2_DrvOps fvidDrvOps; /**< FVID2 driver ops. */ @@ -474,6 +511,10 @@ typedef struct /**< FVID2 registration complete flag. */ uint32_t numInst; /**< Number of valid instance. */ + uint32_t numVirtContUsed[CSITX_INSTANCE_ID_MAX]; + /**< Number of virtual context used */ + CsitxDrv_VirtContext virtContext[CSITX_INSTANCE_ID_MAX][CSITX_NUM_VIRTUAL_CONTEXT]; + /**< Virtual context objects. */ CsitxDrv_InstObj instObj[CSITX_INSTANCE_ID_MAX]; /**< Transmit instance objects pointer. */ Csitx_PlatformData platData; @@ -504,7 +545,7 @@ typedef struct /**< Get timestamp function. */ Udma_EventObject masterEvent; /**< UDMA Master event handle. */ -} CsitxDrv_CommonObj; +}; /* ========================================================================== */ /* Global Variables */ /* ========================================================================== */ diff --git a/source/drivers/csitx/v0/include/csitx_drvUdma.h b/source/drivers/csitx/v0/include/csitx_drvUdma.h index 49756ae..1653f62 100755 --- a/source/drivers/csitx/v0/include/csitx_drvUdma.h +++ b/source/drivers/csitx/v0/include/csitx_drvUdma.h @@ -85,10 +85,9 @@ extern "C" { /* ========================================================================== */ int32_t CsitxDrv_setDMACfgParams(CsitxDrv_ChObj *chObj); -int32_t CsitxDrv_setUdmaParams(CsitxDrv_CommonObj *txObj, - CsitxDrv_InstObj *instObj); +int32_t CsitxDrv_setChUdmaParams(CsitxDrv_ChObj *chObj); -int32_t CsitxDrv_clearUdmaParams(CsitxDrv_InstObj *instObj); +int32_t CsitxDrv_clearUdmaParams(CsitxDrv_ChObj *chObj); int32_t CsitxDrv_udmaTxTrpdInit(Udma_ChHandle txChHandle, uint8_t *pTrpdMem, diff --git a/source/drivers/csitx/v0/soc/V0/csitx_soc.h b/source/drivers/csitx/v0/soc/V0/csitx_soc.h index ef1d961..b2e1ba4 100755 --- a/source/drivers/csitx/v0/soc/V0/csitx_soc.h +++ b/source/drivers/csitx/v0/soc/V0/csitx_soc.h @@ -229,6 +229,9 @@ extern "C" { /** \brief CSITX DRV Numbers: Number of stream per CSI TX module */ #define CSITX_NUM_STREAM (1U) +/** \brief CSITX DRV Virtual Context: Number of virtual contexts per CSI TX port */ +#define CSITX_NUM_VIRTUAL_CONTEXT (8U) + /** * \anchor CSITX_CoreIntrNum * \name CSITX Module Core Interrupts Numbers diff --git a/source/drivers/csitx/v0/src/csitx_drv.c b/source/drivers/csitx/v0/src/csitx_drv.c index 792bcfb..b66a551 100755 --- a/source/drivers/csitx/v0/src/csitx_drv.c +++ b/source/drivers/csitx/v0/src/csitx_drv.c @@ -126,7 +126,9 @@ uint32_t gTxTrOutCnt = 0U; static int32_t CsitxDrv_setInstCfgParams(CsitxDrv_InstObj *instObj, Csitx_CreateParams *createParams); -static int32_t CsitxDrv_createChQueues(CsitxDrv_InstObj *instObj); +static int32_t CsitxDrv_createChQueues(CsitxDrv_ChObj *chObj); + +static int32_t CsitxDrv_setChCfgParams(CsitxDrv_ChObj *chObj, Csitx_ChCfg *chCfg); static int32_t CsitxDrv_setCslCfgParams(CsitxDrv_CommonObj *txObj, CsitxDrv_InstObj *instObj, @@ -135,19 +137,24 @@ static int32_t CsitxDrv_setCslCfgParams(CsitxDrv_CommonObj *txObj, static int32_t CsitxDrv_configShim(CsitxDrv_CommonObj *txObj, CsitxDrv_InstObj *instObj); -int32_t Csitx_setDphyCfg(Csitx_DPhyCfg *dphyCfg); +static int32_t CsitxDrv_chConfigShim(CsitxDrv_ChObj *chObj); + +static int32_t CsitxDrv_getFreeChNumIoctl(CsitxDrv_InstObj *instObj, + uint32_t *chNum); -static void CsitxDrv_deleteChObj(CsitxDrv_InstObj *instObj); +int32_t Csitx_setDphyCfg(CsitxDrv_VirtContext *virtContext, Csitx_DPhyCfg *dphyCfg); + +static void CsitxDrv_deleteChObj(CsitxDrv_ChObj *chObj); static void CsitxDrv_deleteChQueues(CsitxDrv_ChObj *chObj); -static int32_t CsitxDrv_startIoctl(CsitxDrv_InstObj *instObj); +static int32_t CsitxDrv_startIoctl(CsitxDrv_VirtContext *virtContext); -static int32_t CsitxDrv_stopIoctl(CsitxDrv_InstObj *instObj); +static int32_t CsitxDrv_stopIoctl(CsitxDrv_VirtContext *virtContext); void Csitx_printLogs(void); -static int32_t CsitxDrv_getStatusIoctl(CsitxDrv_InstObj *instObj, +static int32_t CsitxDrv_getStatusIoctl(const CsitxDrv_VirtContext *virtContext, Csitx_InstStatus *txStat); /* This function returns the size aligned to wordSize boundary @@ -169,7 +176,8 @@ Fdrv_Handle CsitxDrv_create(uint32_t drvId, CsitxDrv_InstObj *instObj = NULL; Csitx_CreateParams *createParams; Csitx_CreateStatus *status; - uint32_t eventIdx; + uint32_t eventIdx, virtContextId, chId, chIdx; + CsitxDrv_VirtContext *virtContext; /* Check for NULL pointers and invalid arguments */ if ((createArgs == NULL) || @@ -185,24 +193,39 @@ Fdrv_Handle CsitxDrv_create(uint32_t drvId, txObj = &gCsitxCommonObj; status = (Csitx_CreateStatus *)createStatusArgs; createParams = (Csitx_CreateParams *)createArgs; - /* check if provided instance is free */ - if (txObj->instObj[instId].inUse != - (uint32_t)CSITX_DRV_USAGE_STATUS_NOT_USED) + + /* Get free virtual context */ + for (virtContextId = 0U ; + virtContextId < CSITX_NUM_VIRTUAL_CONTEXT ; + virtContextId++) + { + if (CSITX_DRV_USAGE_STATUS_NOT_USED == + txObj->virtContext[instId][virtContextId].inUse) + { + virtContext = &txObj->virtContext[instId][virtContextId]; + /* Get the instance object for this instance */ + instObj = virtContext->instObj; + /* Copy createParams to instance object */ + Fvid2Utils_memcpy(&virtContext->createParams, + createParams, + sizeof (virtContext->createParams)); + Fvid2Utils_memcpy(&virtContext->fdmCbParams, + fdmCbParams, + sizeof (virtContext->fdmCbParams)); + break; + } + } + + if (CSITX_NUM_VIRTUAL_CONTEXT <= virtContextId) { GT_0trace(CsitxTrace, GT_ERR, "Provided instance is already in use\r\n"); - retVal = FVID2_EINVALID_PARAMS; - } - else - { - /* Get the instance object for this instance */ - instObj = &txObj->instObj[instId]; - GT_assert(CsitxTrace, (instObj != NULL)); + retVal = FVID2_EDEVICE_INUSE; } } /* If the selected instance is IDLE or not */ - if ((retVal == FVID2_SOK) && (instObj->state != CSITX_DRV_STATE_IDLE)) + if ((retVal == FVID2_SOK) && (virtContext->state != CSITX_DRV_STATE_IDLE)) { retVal = FVID2_EFAIL; GT_0trace(CsitxTrace, @@ -210,17 +233,22 @@ Fdrv_Handle CsitxDrv_create(uint32_t drvId, "Selected instance is not in IDLE state\r\n"); } - if (instObj != NULL) + if (NULL != instObj) { /* Pend on the instance semaphore */ (void)SemaphoreP_pend(&instObj->lockSem, SystemP_WAIT_FOREVER); - /* Assert reset to pixel interface */ - CSL_csitxAssertPixelIfReset((CSL_csi_tx_ifRegs *)instObj->shimBaseAddr, - TRUE); + } + else + { + retVal = FVID2_EFAIL; } - if (retVal == FVID2_SOK) + if ((retVal == FVID2_SOK) && + (CSITX_DRV_USAGE_STATUS_NOT_USED == instObj->inUse)) { + /* De-assert reset to pixel interface in case of failure. */ + CSL_csitxAssertPixelIfReset((CSL_csi_tx_ifRegs *)instObj->shimBaseAddr, + TRUE); /* Copy createParams to instance object */ Fvid2Utils_memcpy(&instObj->createParams, createParams, @@ -228,9 +256,14 @@ Fdrv_Handle CsitxDrv_create(uint32_t drvId, /* Initialize instance configuration parameters */ instObj->drvInstId = instId; instObj->inUse = (uint32_t)CSITX_DRV_USAGE_STATUS_IN_USE; - Fvid2Utils_memcpy(&instObj->fdmCbParams, - fdmCbParams, - sizeof (instObj->fdmCbParams)); + /* Set CSITX Module configuration parameters */ + retVal = CsitxDrv_setCslCfgParams(txObj, + instObj, + &instObj->createParams); + /* Assert reset to pixel interface */ + CSL_csitxAssertPixelIfReset((CSL_csi_tx_ifRegs *)instObj->shimBaseAddr, + UFALSE); + /* Create done Queue */ retVal = Fvid2Utils_constructQ(&instObj->bufManObj.doneLlObj); GT_assert(CsitxTrace, (retVal == FVID2_SOK)); @@ -244,51 +277,63 @@ Fdrv_Handle CsitxDrv_create(uint32_t drvId, instObj->bufManObj.waitQ = &instObj->bufManObj.waitLlObj; } } - /* Call this API before configuration of SHIM/UDMA as some of variables are - set in this function which will be used in 'CsitxDrv_setUdmaParams()' */ - if (retVal == FVID2_SOK) - { - /* Set CSITX Module configuration parameters */ - retVal = CsitxDrv_setCslCfgParams(txObj, - instObj, - &instObj->createParams); - } - if (retVal == FVID2_SOK) - { - /* Set SHIL/PSIL, UDMA configuration parameters */ - retVal = CsitxDrv_setInstCfgParams(instObj, &instObj->createParams); - } - if (retVal == FVID2_SOK) - { - /* Configure UDMA */ - retVal = CsitxDrv_setUdmaParams(txObj, instObj); - } - if (retVal == FVID2_SOK) + + /* Do channels configurations here, these has to be done per context */ + if ((FVID2_SOK == retVal) && + (CSITX_DRV_USAGE_STATUS_IN_USE == instObj->inUse)) { - /* Set CSITX Module configuration parameters */ - retVal = CsitxDrv_createChQueues(instObj); + for (chIdx = 0U ; chIdx < createParams->numCh ; chIdx++) + { + if (FVID2_SOK == CsitxDrv_getFreeChNumIoctl(instObj, &chId)) + { + retVal = CsitxDrv_setChCfgParams(&instObj->chObj[chId], + &createParams->chCfg[chIdx]); + if (FVID2_SOK == retVal) + { + /* Configure UDMA */ + retVal = CsitxDrv_setChUdmaParams( + &instObj->chObj[chId]); + } + if (FVID2_SOK == retVal) + { + /* Set CSITX Module configuration parameters */ + retVal = CsitxDrv_createChQueues( + &instObj->chObj[chId]); + } + if (FVID2_SOK == retVal) + { + /* Set SHIM- CSITX Module configuration parameters */ + retVal = CsitxDrv_chConfigShim(&instObj->chObj[chId]); + } + if (FVID2_SOK != retVal) + { + break; + } + else + { + instObj->chObj[chId].virtContext = virtContext; + virtContext->chId[virtContext->numCh] = chId; + virtContext->numCh++; + } + } + } } - if (retVal == FVID2_SOK) + + if (FVID2_SOK == retVal) { /* Copy Csitx_DPhyCfg to instance object */ Fvid2Utils_memcpy(&instObj->dphyCfg, &createParams->instCfg.dphyCfg, sizeof (instObj->dphyCfg)); /* Configure DPHY */ - retVal = Csitx_setDphyCfg(&instObj->dphyCfg); - } - if (retVal == FVID2_SOK) - { - /* Set SHIM- CSITX Module configuration parameters */ - retVal = CsitxDrv_configShim(txObj, instObj); + retVal = Csitx_setDphyCfg(virtContext, &instObj->dphyCfg); } - if (retVal == FVID2_SOK) + if (FVID2_SOK == retVal) { for (eventIdx = 0U ; eventIdx < CSITX_EVENT_GROUP_MAX; eventIdx++) - { /* Initialize event configuration parameters */ retVal = CsitxDrv_eventGroupRegister(instObj, @@ -296,25 +341,22 @@ Fdrv_Handle CsitxDrv_create(uint32_t drvId, } } - if (retVal != FVID2_SOK) + if (FVID2_SOK != retVal) { - if (instObj != NULL) + if (NULL != instObj) { - /* De-assert reset to pixel interface in case of failure. - In normal scenario, this will de-asserted in Fvid_start() call */ - CSL_csitxAssertPixelIfReset((CSL_csi_tx_ifRegs *)instObj->shimBaseAddr, - FALSE); GT_0trace(CsitxTrace, GT_ERR, "Instance create failed!!!\r\n"); } } - if (retVal == FVID2_SOK) + if (FVID2_SOK == retVal) { - instObj->state = CSITX_DRV_STATE_CREATED; - drvHandle = instObj; - status->retVal = retVal; + drvHandle = virtContext; + virtContext->state = CSITX_DRV_STATE_CREATED; + virtContext->inUse = CSITX_DRV_USAGE_STATUS_IN_USE; + txObj->numVirtContUsed[instId]++; } else { @@ -323,16 +365,22 @@ Fdrv_Handle CsitxDrv_create(uint32_t drvId, status = (Csitx_CreateStatus *)createStatusArgs; status->retVal = retVal; } - if (instObj != NULL) + if (NULL != instObj) { /* Deallocate if error occurs */ - CsitxDrv_deleteChObj(instObj); + for (chIdx = 0U ; chIdx < createParams->numCh ; chIdx++) + { + chId = virtContext->chId[chIdx]; + /* Deallocate if error occurs */ + CsitxDrv_deleteChObj(&instObj->chObj[chId]); + } } + GT_0trace(CsitxTrace, GT_ERR, "Create failed for given configuration\r\n"); } - if (instObj != NULL) + if (NULL != instObj) { /* Post the instance semaphore */ SemaphoreP_post(&instObj->lockSem); @@ -367,7 +415,7 @@ int32_t CsitxDrv_control(Fdrv_Handle handle, void *cmdStatusArgs) { int32_t retVal = FVID2_SOK; - CsitxDrv_InstObj *instObj; + CsitxDrv_VirtContext *virtContext; Fvid2_TimeStampParams *tsParams; /* Check for NULL pointers */ @@ -378,18 +426,18 @@ int32_t CsitxDrv_control(Fdrv_Handle handle, } else { - instObj = (CsitxDrv_InstObj *) handle; + virtContext = (CsitxDrv_VirtContext *) handle; switch (cmd) { case FVID2_START: - retVal = CsitxDrv_startIoctl(instObj); + retVal = CsitxDrv_startIoctl(virtContext); break; case FVID2_STOP: - retVal = CsitxDrv_stopIoctl(instObj); + retVal = CsitxDrv_stopIoctl(virtContext); break; case IOCTL_CSITX_GET_INST_STATUS: retVal = CsitxDrv_getStatusIoctl( - instObj, + virtContext, (Csitx_InstStatus *)cmdArgs); break; case IOCTL_CSITX_PRINT_DEBUG_LOGS: @@ -400,6 +448,9 @@ int32_t CsitxDrv_control(Fdrv_Handle handle, tsParams = (Fvid2_TimeStampParams *)cmdArgs; gCsitxCommonObj.getTimeStamp = tsParams->timeStampFxn; break; + case IOCTL_CSITX_GET_INST_CONTEXT_ID: + (*(uint32_t *)cmdArgs) = (uint32_t)virtContext->contextId; + break; default: { GT_0trace(CsitxTrace, GT_ERR, @@ -416,7 +467,9 @@ int32_t CsitxDrv_delete(Fdrv_Handle handle, void *reserved) { int32_t retVal = FVID2_SOK; CsitxDrv_InstObj *instObj = NULL; - uint32_t eventIdx; + CsitxDrv_VirtContext *virtContext = NULL; + CsitxDrv_CommonObj *txObj = &gCsitxCommonObj; + uint32_t eventIdx, chIdx; /* Check for NULL pointers and invalid arguments */ if (handle == NULL) @@ -426,59 +479,77 @@ int32_t CsitxDrv_delete(Fdrv_Handle handle, void *reserved) } else { - instObj = (CsitxDrv_InstObj *) handle; + virtContext = (CsitxDrv_VirtContext *) handle; + instObj = virtContext->instObj; } - if (instObj != NULL) + if (NULL != instObj) { /* Pend on the instance semaphore */ (void)SemaphoreP_pend(&instObj->lockSem, SystemP_WAIT_FOREVER); /* Check if the instance is already opened and in a stopped state */ - if ((instObj->state == CSITX_DRV_STATE_STOPPED) || - (instObj->state == CSITX_DRV_STATE_CREATED)) + if ((virtContext->state == CSITX_DRV_STATE_STOPPED) || + (virtContext->state == CSITX_DRV_STATE_CREATED)) { - /* Un-register events if any */ - if (retVal == FVID2_SOK) - { - for (eventIdx = 0U ; - eventIdx < CSITX_EVENT_GROUP_MAX; - eventIdx++) + /* Un-register events if any */ + if (retVal == FVID2_SOK) { - /* Initialize event configuration parameters */ - retVal = CsitxDrv_eventGroupUnRegister(instObj, - instObj->createParams.instCfg.eventParams[eventIdx].eventGroup); + for (eventIdx = 0U ; + eventIdx < CSITX_EVENT_GROUP_MAX; + eventIdx++) + { + /* Initialize event configuration parameters */ + retVal = CsitxDrv_eventGroupUnRegister(instObj, + instObj->createParams.instCfg.eventParams[eventIdx].eventGroup); + } } - } - CsitxDrv_deleteChObj(instObj); - if (instObj->bufManObj.doneQ != NULL) + /* Clean up virtual context */ + for (chIdx = 0U ; chIdx < virtContext->numCh ; chIdx++) { - /* Delete the done Q */ - Fvid2Utils_destructQ(instObj->bufManObj.doneQ); - instObj->bufManObj.doneQ = NULL; - } - if (gCsitxCommonObj.platData.serialMultiChanEnable == - CSITX_ENABLE_SERIAL_TRANS_ENABLE) - { - if (instObj->bufManObj.waitQ != NULL) + if (CSITX_DRV_CH_STATE_STOPPED == + instObj->chObj[virtContext->chId[chIdx]].status) { - /* Delete the free Q */ - Fvid2Utils_destructQ(instObj->bufManObj.waitQ); - instObj->bufManObj.waitQ = NULL; + CsitxDrv_deleteChObj(&instObj->chObj[virtContext->chId[chIdx]]); + instObj->chObj[virtContext->chId[chIdx]].status = + CSITX_DRV_CH_STATE_IDLE; } } - /* Mark state as idle */ - instObj->state = CSITX_DRV_STATE_IDLE; - - /* Mark as not in use */ - instObj->inUse = (uint32_t)CSITX_DRV_USAGE_STATUS_NOT_USED; + /* Set configuration parameter to '0' */ + Fvid2Utils_memset(&virtContext->createParams, + 0U, + sizeof (Csitx_CreateParams)); + Fvid2Utils_memset(&virtContext->fdmCbParams, + 0U, + sizeof (Fvid2_DrvCbParams)); + virtContext->state = CSITX_DRV_STATE_IDLE; + virtContext->numCh = 0U; + + virtContext->inUse = (uint32_t)CSITX_DRV_USAGE_STATUS_NOT_USED; + if(1U == txObj->numVirtContUsed[instObj->drvInstId]) + { + instObj->inUse = (uint32_t)CSITX_DRV_USAGE_STATUS_NOT_USED; - /* Reset all channel numbers */ - instObj->numTxCh = 0U; - instObj->numColorbarCh = 0U; - instObj->numLpbkCh = 0U; + if (NULL != instObj->bufManObj.doneQ) + { + /* Delete the done Q */ + Fvid2Utils_destructQ(instObj->bufManObj.doneQ); + instObj->bufManObj.doneQ = NULL; + } + if (CSITX_ENABLE_SERIAL_TRANS_ENABLE == + gCsitxCommonObj.platData.serialMultiChanEnable) + { + if (NULL != instObj->bufManObj.waitQ) + { + /* Delete the free Q */ + Fvid2Utils_destructQ(instObj->bufManObj.waitQ); + instObj->bufManObj.waitQ = NULL; + } + } + } + txObj->numVirtContUsed[instObj->drvInstId]--; } else { @@ -505,6 +576,7 @@ int32_t CsitxDrv_queue(Fdrv_Handle handle, Fvid2_Frame *frm; CSL_UdmapTR1 *pTr; CsitxDrv_QueObj *qObj; + CsitxDrv_VirtContext *virtContext; /* Check for NULL pointers */ if((NULL == handle) || (NULL == frmList)) { @@ -513,13 +585,14 @@ int32_t CsitxDrv_queue(Fdrv_Handle handle, } if(retVal == FVID2_SOK) { - instObj = (CsitxDrv_InstObj *)handle; + virtContext = (CsitxDrv_VirtContext *)handle; + instObj = virtContext->instObj; retVal = Fvid2_checkFrameList(frmList, (uint32_t) FVID2_MAX_FRAME_PTR); if (retVal != FVID2_SOK) { GT_0trace(CsitxTrace, GT_ERR, "Check frame list error\n"); } - if (instObj->state == CSITX_DRV_STATE_IDLE) + if (virtContext->state == CSITX_DRV_STATE_IDLE) { /* If driver handle is not open then skip this frame queue */ GT_0trace( @@ -538,8 +611,8 @@ int32_t CsitxDrv_queue(Fdrv_Handle handle, /* Get FVID2 frame pointer - NULL check is already done in * check frame list function */ frm = frmList->frames[frmCnt]; - chIdx = frm->chNum; - if (chIdx >= instObj->createParams.numCh) + chIdx = virtContext->chId[frm->chNum]; + if (frm->chNum >= virtContext->numCh) { /* invalid stream ID skip this frame queue */ GT_0trace(CsitxTrace, GT_ERR, "Invalid Channel ID\r\n"); @@ -715,6 +788,7 @@ int32_t CsitxDrv_dequeue(Fdrv_Handle handle, volatile uint32_t loopBreakFlag = 1U; CsitxDrv_QueObj *qObj; uint64_t pDesc; + CsitxDrv_VirtContext *virtContext; /* Check for NULL pointers */ if((handle == NULL) || @@ -725,8 +799,9 @@ int32_t CsitxDrv_dequeue(Fdrv_Handle handle, } if(retVal == FVID2_SOK) { - instObj = (CsitxDrv_InstObj *) handle; - if (instObj->state == CSITX_DRV_STATE_IDLE) + virtContext = (CsitxDrv_VirtContext *) handle; + instObj = virtContext->instObj; + if (virtContext->state == CSITX_DRV_STATE_IDLE) { GT_0trace( CsitxTrace, GT_ERR, @@ -755,7 +830,7 @@ int32_t CsitxDrv_dequeue(Fdrv_Handle handle, GT_assert(CsitxTrace, (qObj->frm != NULL)); frmList->frames[frmList->numFrames] = qObj->frm; frmList->numFrames++; - instObj->status.dequeueCount[chObj->chCfg->chId]++; + instObj->status.dequeueCount[chObj->chId]++; /* Give back the queue object back to the free pool */ qObj->frm = NULL; @@ -778,11 +853,11 @@ int32_t CsitxDrv_dequeue(Fdrv_Handle handle, /* When an instance is stopped, return all the request in * channel's current queue as well. */ GT_assert(CsitxTrace, (instObj != NULL)); - if (instObj->state == CSITX_DRV_STATE_STOPPED) + if (virtContext->state == CSITX_DRV_STATE_STOPPED) { - for (chIdx = 0U ; chIdx < instObj->createParams.numCh ; chIdx++) + for (chIdx = 0U ; chIdx < virtContext->numCh ; chIdx++) { - chObj = &instObj->chObj[chIdx]; + chObj = &instObj->chObj[(virtContext->chId[chIdx])]; if (chObj->chCfg->chType == CSITX_CH_TYPE_TX) { /* Extract frames from queue till the queue @@ -805,7 +880,7 @@ int32_t CsitxDrv_dequeue(Fdrv_Handle handle, Fvid2Utils_dequeue(chObj->bufManObj.curQ); GT_assert(CsitxTrace, (qObj != NULL)); GT_assert(CsitxTrace, - (chObj->chCfg->chId == qObj->chObj->chCfg->chId)); + (chObj->chId == qObj->chObj->chId)); /* Check returned descriptor pointer */ GT_assert(CsitxTrace, (pDesc == ((uint64_t) qObj->trpd))); @@ -814,7 +889,7 @@ int32_t CsitxDrv_dequeue(Fdrv_Handle handle, qObj->frm->status = FVID2_FRAME_STATUS_ABORTED; frmList->frames[frmList->numFrames] = qObj->frm; frmList->numFrames++; - instObj->status.dequeueCount[chObj->chCfg->chId]++; + instObj->status.dequeueCount[chObj->chId]++; /* Give back the queue object back to the free pool */ qObj->frm = NULL; GT_assert(CsitxTrace, (chObj == qObj->chObj)); @@ -854,7 +929,7 @@ int32_t CsitxDrv_dequeue(Fdrv_Handle handle, GT_assert(CsitxTrace, (qObj->frm != NULL)); frmList->frames[frmList->numFrames] = qObj->frm; frmList->numFrames++; - instObj->status.dequeueCount[chObj->chCfg->chId]++; + instObj->status.dequeueCount[chObj->chId]++; qObj->frm = NULL; @@ -882,8 +957,8 @@ int32_t CsitxDrv_dequeue(Fdrv_Handle handle, /* If no frame is dequeued, then return appropriate error */ if (frmList->numFrames == 0U) { - if ((instObj->state == CSITX_DRV_STATE_CREATED) || - (instObj->state == CSITX_DRV_STATE_STOPPED)) + if ((virtContext->state == CSITX_DRV_STATE_CREATED) || + (virtContext->state == CSITX_DRV_STATE_STOPPED)) { GT_0trace( CsitxTrace, GT_DEBUG, @@ -993,82 +1068,143 @@ static int32_t CsitxDrv_setInstCfgParams(CsitxDrv_InstObj *instObj, return retVal; } -static int32_t CsitxDrv_createChQueues(CsitxDrv_InstObj *instObj) +static int32_t CsitxDrv_setChCfgParams(CsitxDrv_ChObj *chObj, Csitx_ChCfg *chCfg) +{ + int32_t retVal = FVID2_SOK; + CsitxDrv_InstObj *instObj; + + instObj = chObj->instObj; + chObj->chCfg = chCfg; + + if (CSITX_CH_TYPE_TX == chCfg->chType) + { + if (instObj->numTxCh < CSITX_NUM_CH_TX) + { + instObj->numTxCh++; + retVal = CsitxDrv_setDMACfgParams(chObj); + } + else + { + GT_0trace( + CsitxTrace, + GT_ERR, + "More Capture channels are provided than HW " + "can process\r\n"); + retVal = FVID2_EINVALID_PARAMS; + } + } + if (CSITX_CH_TYPE_COLORBAR == chCfg->chType) + { + if (instObj->numColorbarCh < CSITX_NUM_CH_COLORBAR_MAX) + { + instObj->colorbarChId[instObj->numColorbarCh] = chObj->chId; + instObj->numColorbarCh++; + /* Only capture channel will have 'psilThreadId' other than + 'CSITX_DRV_DEF_PSIL_THREAD_ID' */ + chObj->psilThreadId = CSITX_DRV_DEF_PSIL_THREAD_ID; + } + else + { + GT_0trace( + CsitxTrace, + GT_ERR, + "More OTF channels are provided than HW can " + "process\r\n"); + retVal = FVID2_EINVALID_PARAMS; + } + } + if (CSITX_CH_TYPE_LPBK == chCfg->chType) + { + if (instObj->numLpbkCh < CSITX_NUM_CH_LPBK_MAX) + { + instObj->lpbkChId[instObj->numLpbkCh] = chObj->chId; + instObj->numLpbkCh++; + /* Only capture channel will have 'psilThreadId' other than + 'CSITX_DRV_DEF_PSIL_THREAD_ID' */ + chObj->psilThreadId = CSITX_DRV_DEF_PSIL_THREAD_ID; + CSL_csitxRetransCfg((CSL_csi_tx_ifRegs *)instObj->shimBaseAddr, + &instObj->createParams.instCfg.retransCfg); + retVal = CsirtxDrv_lpbkSel(instObj->drvInstId, instObj->createParams.instCfg.lpbkCsiRxInst); + } + else + { + GT_0trace( + CsitxTrace, + GT_ERR, + "More Loop-back channels are provided than " + "HW can process\r\n"); + retVal = FVID2_EINVALID_PARAMS; + } + } + + return retVal; +} + +static int32_t CsitxDrv_createChQueues(CsitxDrv_ChObj *chObj) { int32_t retVal = FVID2_SOK, tempRetVal; uint32_t chIdx = 0U; uint32_t qCnt = 0U; CsitxDrv_QueObj *qObj; - CsitxDrv_ChObj *chObj; CsitxDrv_ChBufManObj *bmObj; CsitxDrv_InstBufManObj *instBmObj; + CsitxDrv_InstObj *instObj; - /* NULL pointer check */ - GT_assert(CsitxTrace, (NULL != instObj)); - for (chIdx = 0U ; chIdx < instObj->createParams.numCh ; chIdx++) + instObj = chObj->instObj; + chIdx = chObj->chId; + /* Do configuration for CSITX_CH_TYPE_TX type of channel */ + if (CSITX_CH_TYPE_TX == chObj->chCfg->chType) { - chObj = &instObj->chObj[chIdx]; - /* Do configuration for CSITX_CH_TYPE_TX type of channel */ - if (chObj->chCfg->chType == CSITX_CH_TYPE_TX) + bmObj = &chObj->bufManObj; + + bmObj->freeQ = NULL; + /* Create Queues */ + retVal = Fvid2Utils_constructQ(&bmObj->freeLlObj); + GT_assert(CsitxTrace, (FVID2_SOK == retVal)); + bmObj->freeQ = &bmObj->freeLlObj; + + bmObj->curQ = NULL; + retVal = Fvid2Utils_constructQ(&bmObj->curLlObj); + GT_assert(CsitxTrace, (FVID2_SOK == retVal)); + bmObj->curQ = &bmObj->curLlObj; + instBmObj = &instObj->bufManObj; + /* Initialize and queue the allocate queue object to free Q */ + for (qCnt = 0U; qCnt < CSITX_TX_QUEUE_DEPTH_PER_CH ; qCnt++) { - bmObj = &chObj->bufManObj; - - bmObj->freeQ = NULL; - /* Create Queues */ - retVal = Fvid2Utils_constructQ(&bmObj->freeLlObj); - GT_assert(CsitxTrace, (retVal == FVID2_SOK)); - bmObj->freeQ = &bmObj->freeLlObj; - - bmObj->curQ = NULL; - retVal = Fvid2Utils_constructQ(&bmObj->curLlObj); - GT_assert(CsitxTrace, (retVal == FVID2_SOK)); - bmObj->curQ = &bmObj->curLlObj; - instBmObj = &instObj->bufManObj; - /* Initialize and queue the allocate queue object to free Q */ - for (qCnt = 0U; qCnt < CSITX_TX_QUEUE_DEPTH_PER_CH ; qCnt++) + if (CSITX_ENABLE_SERIAL_TRANS_DISABLE == + gCsitxCommonObj.platData.serialMultiChanEnable) { - if (gCsitxCommonObj.platData.serialMultiChanEnable == - CSITX_ENABLE_SERIAL_TRANS_DISABLE) - { - qObj = &bmObj->txQObj[qCnt]; - } - else - { - qObj = &instBmObj->txQObj[((chIdx * CSITX_TX_QUEUE_DEPTH_PER_CH) + qCnt)]; - } - qObj->inUse = CSITX_DRV_USAGE_STATUS_NOT_USED; - qObj->chObj = &instObj->chObj[chIdx]; - qObj->frm = NULL; - qObj->trpd = - (CSL_UdmapCppi5TRPD *)CsitxDrv_getTrpdMemAddr(chIdx, - qCnt); - tempRetVal = CsitxDrv_udmaTxTrpdInit( - &instObj->chObj[chIdx].txChObj, - (uint8_t *)qObj->trpd, - NULL, - instObj->chObj[chIdx].chCfg, - chIdx); - if (tempRetVal != FVID2_SOK) - { - retVal = FVID2_EINVALID_PARAMS; - break; - } - Fvid2Utils_queue(bmObj->freeQ, &qObj->qElem, qObj); + qObj = &bmObj->txQObj[qCnt]; } - if (retVal != FVID2_SOK) + else { + qObj = &instBmObj->txQObj[((chIdx * CSITX_TX_QUEUE_DEPTH_PER_CH) + qCnt)]; + } + qObj->inUse = CSITX_DRV_USAGE_STATUS_NOT_USED; + qObj->chObj = chObj; + qObj->frm = NULL; + qObj->trpd = + (CSL_UdmapCppi5TRPD *)CsitxDrv_getTrpdMemAddr(chIdx, + qCnt); + tempRetVal = CsitxDrv_udmaTxTrpdInit( + &chObj->txChObj, + (uint8_t *)qObj->trpd, + NULL, + chObj->chCfg, + chObj->chId); + if (FVID2_SOK != tempRetVal) + { + retVal = FVID2_EINVALID_PARAMS; break; } + Fvid2Utils_queue(bmObj->freeQ, &qObj->qElem, qObj); } } /* Deallocate if error occurs */ - if (retVal != FVID2_SOK) + if (FVID2_SOK != retVal) { - for (chIdx = 0U ; chIdx < CSITX_NUM_CH; chIdx++) - { - CsitxDrv_deleteChQueues(&instObj->chObj[chIdx]); - } + CsitxDrv_deleteChQueues(chObj); } return retVal; @@ -1308,27 +1444,49 @@ static int32_t CsitxDrv_configShim(CsitxDrv_CommonObj *txObj, return retVal; } -int32_t Csitx_setDphyCfg(Csitx_DPhyCfg *dphyCfg) +static int32_t CsitxDrv_chConfigShim(CsitxDrv_ChObj *chObj) +{ + int32_t retVal = FVID2_SOK, status = CSL_PASS; + + if (chObj->psilThreadId != CSITX_DRV_DEF_PSIL_THREAD_ID) + { + /* Do following for Capture channels only */ + status+= CSL_csitxConfigDMA( + (CSL_csi_tx_ifRegs *)chObj->instObj->shimBaseAddr, + &chObj->dmaCfgParams); + if (CSL_PASS != status) + { + GT_0trace(CsitxTrace, + GT_ERR, + "Invalid SHIM Capture config arguments\r\n"); + retVal = FVID2_EBADARGS; + } + } + + return retVal; +} + +int32_t Csitx_setDphyCfg(CsitxDrv_VirtContext *virtContext, Csitx_DPhyCfg *dphyCfg) { int32_t retVal = FVID2_SOK; CsitxDrv_InstObj *instObj; - if (dphyCfg == NULL) + if (NULL == dphyCfg) { retVal = FVID2_EBADARGS; } - if (retVal == FVID2_SOK) + if (FVID2_SOK == retVal) { instObj = &gCsitxCommonObj.instObj[dphyCfg->inst]; retVal = Csitx_dphyConfig(instObj); } /* put lanes into LP state if clock mode is non continuous */ - if ((retVal == FVID2_SOK) && - (dphyCfg->clkMode == CSITX_CLK_MODE_NON_CONTINUOUS)) + if ((FVID2_SOK == retVal) && + (CSITX_CLK_MODE_NON_CONTINUOUS == dphyCfg->clkMode)) { retVal = CsitxDrv_dphytxSetLaneState(instObj, CSITX_DPHY_MODE_LOW_POWER); } - if (retVal != FVID2_SOK) + if (FVID2_SOK != retVal) { GT_0trace(CsitxTrace, GT_ERR, @@ -1338,30 +1496,20 @@ int32_t Csitx_setDphyCfg(Csitx_DPhyCfg *dphyCfg) return retVal; } -static void CsitxDrv_deleteChObj(CsitxDrv_InstObj *instObj) +static void CsitxDrv_deleteChObj(CsitxDrv_ChObj *chObj) { int32_t retVal = FVID2_SOK; - uint32_t chIdx; - CsitxDrv_ChObj *chObj; - GT_assert(CsitxTrace, (instObj != NULL)); - GT_assert(CsitxTrace, - (instObj->createParams.numCh <= CSITX_NUM_CH)); /* Close sequence for UDMA DRV */ - retVal = CsitxDrv_clearUdmaParams(instObj); - if (retVal != UDMA_SOK) + retVal = CsitxDrv_clearUdmaParams(chObj); + if (UDMA_SOK != retVal) { GT_0trace(CsitxTrace, GT_ERR, "[ERROR]UDMA channel close FAILED!!!\r\n"); } - for (chIdx = 0U; chIdx < instObj->createParams.numCh; chIdx++) - { - /* Get channel object */ - chObj = &instObj->chObj[chIdx]; - /* Delete channel queues */ - CsitxDrv_deleteChQueues(chObj); - } + /* Delete channel queues */ + CsitxDrv_deleteChQueues(chObj); } static void CsitxDrv_deleteChQueues(CsitxDrv_ChObj *chObj) @@ -1399,35 +1547,37 @@ static void CsitxDrv_deleteChQueues(CsitxDrv_ChObj *chObj) } } -static int32_t CsitxDrv_startIoctl(CsitxDrv_InstObj *instObj) +static int32_t CsitxDrv_startIoctl(CsitxDrv_VirtContext *virtContext) { int32_t retVal = FVID2_SOK, tempRetVal = UDMA_SOK; uint32_t chIdx = 0U; CsitxDrv_ChObj *chObj; + CsitxDrv_InstObj *instObj; /* Check for NULL pointers */ - GT_assert(CsitxTrace, (instObj != NULL)); + GT_assert(CsitxTrace, (NULL != virtContext)); GT_assert(CsitxTrace, - (instObj->createParams.numCh <= CSITX_NUM_CH)); + (CSITX_NUM_CH >= virtContext->numCh)); + instObj = virtContext->instObj; /* Pend the instance semaphore */ (void)SemaphoreP_pend(&instObj->lockSem, SystemP_WAIT_FOREVER); - for (chIdx = 0U ; chIdx < instObj->createParams.numCh ; chIdx++) + for (chIdx = 0U ; chIdx < virtContext->numCh ; chIdx++) { /* Get channel object */ - chObj = &instObj->chObj[chIdx]; + chObj = &instObj->chObj[(virtContext->chId[chIdx])]; /* Enable channel only if it is created */ if (chObj->status == CSITX_DRV_CH_STATE_CREATED) { /* Enable DMA context for PSIL threads and UDMA channels only for capture channels */ - if (chObj->chCfg->chType == CSITX_CH_TYPE_TX) + if (CSITX_CH_TYPE_TX == chObj->chCfg->chType) { - if (retVal == FVID2_SOK) + if (FVID2_SOK == retVal) { /* Enable UDMA channel */ tempRetVal = Udma_chEnable(&chObj->txChObj); - if(tempRetVal != UDMA_SOK) + if (UDMA_SOK != tempRetVal) { retVal = FVID2_EFAIL; GT_0trace( @@ -1437,7 +1587,7 @@ static int32_t CsitxDrv_startIoctl(CsitxDrv_InstObj *instObj) } } } - if (retVal == FVID2_SOK) + if (FVID2_SOK == retVal) { /* set channel state to running */ chObj->status = CSITX_DRV_CH_STATE_RUNNING; @@ -1447,7 +1597,7 @@ static int32_t CsitxDrv_startIoctl(CsitxDrv_InstObj *instObj) if (retVal == FVID2_SOK) { /* change driver instance to started/running state */ - instObj->state = CSITX_DRV_STATE_RUNNING; + virtContext->state = CSITX_DRV_STATE_RUNNING; /* release pixel reset */ CSL_csitxAssertPixelIfReset((CSL_csi_tx_ifRegs *)instObj->shimBaseAddr, FALSE); @@ -1458,38 +1608,38 @@ static int32_t CsitxDrv_startIoctl(CsitxDrv_InstObj *instObj) return retVal; } -static int32_t CsitxDrv_stopIoctl(CsitxDrv_InstObj *instObj) +static int32_t CsitxDrv_stopIoctl(CsitxDrv_VirtContext *virtContext) { int32_t retVal = FVID2_SOK, tempRetVal = UDMA_SOK; uint32_t chIdx = 0U, cookie; CsitxDrv_ChObj *chObj; + CsitxDrv_InstObj *instObj; /* Check for NULL pointers */ - GT_assert(CsitxTrace, (instObj != NULL)); + GT_assert(CsitxTrace, (NULL != virtContext)); GT_assert(CsitxTrace, - (instObj->createParams.numCh <= CSITX_NUM_CH)); + (CSITX_NUM_CH >= virtContext->numCh)); + instObj = virtContext->instObj; /* Pend the instance semaphore */ (void)SemaphoreP_pend(&instObj->lockSem, SystemP_WAIT_FOREVER); /* Disable HW interrupts here */ cookie = HwiP_disable(); - for (chIdx = 0U ; chIdx < instObj->createParams.numCh ; chIdx++) + for (chIdx = 0U ; chIdx < virtContext->numCh ; chIdx++) { - /* Get channel object */ - chObj = &instObj->chObj[chIdx]; + /* Get channel object */ + chObj = &instObj->chObj[(virtContext->chId[chIdx])]; /* set channel state to stopping */ chObj->status = CSITX_DRV_CH_STATE_STOPPING; - /* Get channel object */ - chObj = &instObj->chObj[chIdx]; /* Disable DMA context for PSIL threads and UDMA channels only for capture channels */ - if (chObj->chCfg->chType == CSITX_CH_TYPE_TX) + if (CSITX_CH_TYPE_TX == chObj->chCfg->chType) { - if (retVal == FVID2_SOK) + if (FVID2_SOK == retVal) { /* Disable UDMA channel */ tempRetVal = Udma_chDisable(&chObj->txChObj, UDMA_DEFAULT_CH_DISABLE_TIMEOUT); - if(tempRetVal != UDMA_SOK) + if(UDMA_SOK != tempRetVal) { retVal = FVID2_EFAIL; GT_0trace( @@ -1499,7 +1649,7 @@ static int32_t CsitxDrv_stopIoctl(CsitxDrv_InstObj *instObj) } } } - if (retVal == FVID2_SOK) + if (FVID2_SOK == retVal) { /* set channel state to stopped */ chObj->status = CSITX_DRV_CH_STATE_STOPPED; @@ -1511,7 +1661,7 @@ static int32_t CsitxDrv_stopIoctl(CsitxDrv_InstObj *instObj) if (retVal == FVID2_SOK) { /* change driver isntance to stopped state */ - instObj->state = CSITX_DRV_STATE_STOPPED; + virtContext->state = CSITX_DRV_STATE_STOPPED; } /* Post the instance semaphore */ @@ -1520,17 +1670,24 @@ static int32_t CsitxDrv_stopIoctl(CsitxDrv_InstObj *instObj) return retVal; } -static int32_t CsitxDrv_getStatusIoctl(CsitxDrv_InstObj *instObj, +static int32_t CsitxDrv_getStatusIoctl(const CsitxDrv_VirtContext *virtContext, Csitx_InstStatus *txStat) { int32_t retVal = FVID2_SOK; + uint32_t chIdx; + CsitxDrv_InstObj *instObj; + instObj = virtContext->instObj; /* Pend on the instance semaphore */ (void)SemaphoreP_pend(&instObj->lockSem, SystemP_WAIT_FOREVER); /* Copy capture status from DRV object to application provided parameter */ - Fvid2Utils_memcpy(txStat, - &instObj->status, - sizeof (instObj->status)); + for (chIdx = 0U ; chIdx < virtContext->numCh ; chIdx++) + { + txStat->queueCount[chIdx] = + instObj->status.queueCount[virtContext->chId[chIdx]]; + txStat->dequeueCount[chIdx] = + instObj->status.dequeueCount[virtContext->chId[chIdx]]; + } /* Post the instance semaphore */ SemaphoreP_post(&instObj->lockSem); @@ -1694,3 +1851,31 @@ int32_t CsitxDrv_dphytxSetLaneState(CsitxDrv_InstObj *instObj, return retVal; } + +static int32_t CsitxDrv_getFreeChNumIoctl(CsitxDrv_InstObj *instObj, + uint32_t *chNum) +{ + int32_t retVal = FVID2_SOK; + uint32_t chIdx; + + GT_assert(CsitxTrace, (instObj != NULL)); + + for (chIdx = 0U ; chIdx < CSITX_NUM_CH ; chIdx++) + { + if (CSITX_DRV_CH_STATE_IDLE == instObj->chObj[chIdx].status) + { + break; + } + } + + if (chIdx < CSITX_NUM_CH) + { + *chNum = chIdx; + } + else + { + retVal = FVID2_EAGAIN; + } + + return retVal; +} diff --git a/source/drivers/csitx/v0/src/csitx_drvInit.c b/source/drivers/csitx/v0/src/csitx_drvInit.c index 2cb3ca2..78a34a9 100755 --- a/source/drivers/csitx/v0/src/csitx_drvInit.c +++ b/source/drivers/csitx/v0/src/csitx_drvInit.c @@ -86,7 +86,7 @@ int32_t CsitxDrv_init(CsitxDrv_CommonObj *txObj); int32_t Csitx_init(const Csitx_InitParams *initParams) { int32_t retVal = FVID2_SOK; - uint32_t instCnt, CsitxInstCnt = 0, loopCnt; + uint32_t instCnt, CsitxInstCnt = 0, loopCnt, contextId; CsitxDrv_CommonObj *txObj; CsitxDrv_InstObj *instObj; int32_t status = SystemP_SUCCESS; @@ -112,12 +112,33 @@ int32_t Csitx_init(const Csitx_InitParams *initParams) gCsitxCommonObj.getTimeStamp = NULL; for (instCnt = 0U; instCnt < CSITX_INSTANCE_ID_MAX; instCnt++) { + for (contextId = 0U ; + contextId < CSITX_NUM_VIRTUAL_CONTEXT ; + contextId++) + { + txObj->virtContext[instCnt][contextId].contextId = contextId; + txObj->virtContext[instCnt][contextId].numCh = 0U; + txObj->virtContext[instCnt][contextId].state = + CSITX_DRV_STATE_IDLE; + Fvid2Utils_memset( + &txObj->virtContext[instCnt][contextId].chId[0U], + 0U, + sizeof (txObj->virtContext[instCnt][contextId].chId)); + txObj->virtContext[instCnt][contextId].instObj = + &instObj[instCnt]; + txObj->virtContext[instCnt][contextId].inUse = + CSITX_DRV_USAGE_STATUS_NOT_USED; + txObj->numVirtContUsed[instCnt] = 0U; + } + + instObj[instCnt].dpyCfgDone = 0U; + instObj[instCnt].eventRegDone = 0U; /* Initialize D-PHY configuration parameters */ instObj[instCnt].dphyCfg.inst = instCnt; instObj[instCnt].drvInstId = instCnt; + instObj[instCnt].commonObjRef = txObj; instObj[instCnt].inUse = CSITX_DRV_USAGE_STATUS_NOT_USED; - instObj[instCnt].state = CSITX_DRV_STATE_IDLE; instObj[instCnt].numTxCh = 0U; instObj[instCnt].numColorbarCh = 0U; instObj[instCnt].numLpbkCh = 0U; @@ -131,6 +152,8 @@ int32_t Csitx_init(const Csitx_InitParams *initParams) Csitx_instStatusInit(&instObj[instCnt].status); for (loopCnt = 0U ; loopCnt < CSITX_NUM_CH; loopCnt++) { + instObj[instCnt].chObj[loopCnt].chId = loopCnt; + instObj[instCnt].chObj[loopCnt].virtContext = NULL; instObj[instCnt].chObj[loopCnt].psilThreadstatus = (uint32_t)FALSE; } @@ -174,7 +197,7 @@ int32_t Csitx_deInit(void) int32_t retVal = FVID2_SOK; CsitxDrv_CommonObj *txObj; CsitxDrv_InstObj *instObj; - uint32_t instIdx; + uint32_t instIdx, contextId; txObj = &gCsitxCommonObj; /* un-initialize instance object variables */ @@ -185,7 +208,16 @@ int32_t Csitx_deInit(void) instObj->inUse = CSITX_DRV_USAGE_STATUS_NOT_USED; /* putting to init state, this will prevent condition where user calls create() before calling init() after doing unint()*/ - instObj->state = CSITX_DRV_STATE_UNINIT; + for (contextId = 0U ; + contextId < CSITX_NUM_VIRTUAL_CONTEXT ; + contextId++) + { + txObj->virtContext[instIdx][contextId].state = + CSITX_DRV_STATE_UNINIT; + txObj->virtContext[instIdx][contextId].numCh = 0U; + txObj->virtContext[instIdx][contextId].inUse = + CSITX_DRV_USAGE_STATUS_NOT_USED; + } /* Delete semaphore */ SemaphoreP_destruct(&instObj->lockSem); } @@ -317,7 +349,7 @@ static int32_t CsitxDrv_chInit(CsitxDrv_InstObj *instObj) /* Only capture channel will have 'psilThreadId' other than 'CSITX_DRV_DEF_PSIL_THREAD_ID' */ instObj[instCnt].chObj[chNum].psilThreadId = - CSITX_DRV_DEF_PSIL_THREAD_ID; + chNum; } } diff --git a/source/drivers/csitx/v0/src/csitx_drvUdma.c b/source/drivers/csitx/v0/src/csitx_drvUdma.c index 5b0d275..4143324 100755 --- a/source/drivers/csitx/v0/src/csitx_drvUdma.c +++ b/source/drivers/csitx/v0/src/csitx_drvUdma.c @@ -200,125 +200,110 @@ int32_t CsitxDrv_setDMACfgParams(CsitxDrv_ChObj *chObj) return retVal; } -int32_t CsitxDrv_setUdmaParams(CsitxDrv_CommonObj *txObj, - CsitxDrv_InstObj *instObj) +int32_t CsitxDrv_setChUdmaParams(CsitxDrv_ChObj *chObj) { int32_t retVal = FVID2_SOK, tempRetVal = UDMA_SOK; - uint32_t chIdx, chType; - CsitxDrv_ChObj *chObj; + uint32_t chType; Udma_EventHandle eventHandle; Udma_EventPrms eventParams; + CsitxDrv_CommonObj *txObj; - - if(retVal ==FVID2_SOK) + txObj = chObj->instObj->commonObjRef; + if (chObj->chCfg->chType == CSITX_CH_TYPE_TX) { - for (chIdx = 0U ; chIdx < instObj->createParams.numCh ; chIdx++) + if (txObj->initParams.drvHandle == NULL) + { + retVal = FVID2_EBADARGS; + GT_0trace(CsitxTrace, + GT_ERR, + "Invalid UDMA DRV Handle!!\r\n"); + } + if (gCsitxUdmaMasterEvntInitDone != INITIALIZED) { - chObj =&instObj->chObj[chIdx]; - if (chObj->chCfg->chType == CSITX_CH_TYPE_TX) - { - if (txObj->initParams.drvHandle == NULL) - { - retVal = FVID2_EBADARGS; - GT_0trace(CsitxTrace, - GT_ERR, - "Invalid UDMA DRV Handle!!\r\n"); - break; - } - if (gCsitxUdmaMasterEvntInitDone != INITIALIZED) - { - - /* Register the UDMA Master event handle */ - UdmaEventPrms_init(&eventParams); - eventParams.eventType = UDMA_EVENT_TYPE_MASTER; - eventParams.appData = txObj; - tempRetVal = Udma_eventRegister(txObj->initParams.drvHandle, - &txObj->masterEvent, - &eventParams); - gCsitxUdmaMasterEvntInitDone = INITIALIZED; - } - /* Program UDMA channels only for Tx channels */ - chType = UDMA_CH_TYPE_TX_TR; - /* Open UDMA channel */ - tempRetVal = Udma_chOpen(txObj->initParams.drvHandle, - &chObj->txChObj, - chType, - &chObj->chParams); - - if(tempRetVal != UDMA_SOK) - { - retVal = FVID2_EFAIL; - GT_0trace(CsitxTrace, - GT_ERR, - "[ERROR]UDMA channel open FAILED!!!\r\n"); - } - - if (retVal == FVID2_SOK) - { - /* Configure UDMA Tx Channel */ - tempRetVal = Udma_chConfigTx(&chObj->txChObj, - chObj->txChParams); - - if(tempRetVal != UDMA_SOK) - { - retVal = FVID2_EFAIL; - GT_0trace(CsitxTrace, - GT_ERR, - "[ERROR]UDMA TX channel config FAILED!!!\r\n"); - } - } + /* Register the UDMA Master event handle */ + UdmaEventPrms_init(&eventParams); + eventParams.eventType = UDMA_EVENT_TYPE_MASTER; + eventParams.appData = txObj; + tempRetVal = Udma_eventRegister(txObj->initParams.drvHandle, + &txObj->masterEvent, + &eventParams); + gCsitxUdmaMasterEvntInitDone = INITIALIZED; + } + /* Program UDMA channels only for Tx channels */ + chType = UDMA_CH_TYPE_TX_TR; + /* Open UDMA channel */ + tempRetVal = Udma_chOpen(txObj->initParams.drvHandle, + &chObj->txChObj, + chType, + &chObj->chParams); + + if(tempRetVal != UDMA_SOK) + { + retVal = FVID2_EFAIL; + GT_0trace(CsitxTrace, + GT_ERR, + "[ERROR]UDMA channel open FAILED!!!\r\n"); + } - if (retVal == FVID2_SOK) - { - /* Register callbacks here */ - /* Register ring completion callback */ - eventHandle = &chObj->cqEventObj; - UdmaEventPrms_init(&eventParams); - eventParams.eventType = UDMA_EVENT_TYPE_DMA_COMPLETION; - eventParams.eventMode = UDMA_EVENT_MODE_SHARED; - eventParams.chHandle = &chObj->txChObj; - eventParams.masterEventHandle = &txObj->masterEvent; - eventParams.eventCb = &CsitxDrv_udmaCQEventCb; - eventParams.appData = chObj; - tempRetVal = Udma_eventRegister(txObj->initParams.drvHandle, - eventHandle, - &eventParams); - - if(tempRetVal != UDMA_SOK) - { - retVal = FVID2_EFAIL; - GT_0trace(CsitxTrace, - GT_ERR, - "[ERROR]UDMA CQ event register FAILED!!!\r\n"); - } + if (retVal == FVID2_SOK) + { + /* Configure UDMA Tx Channel */ + tempRetVal = Udma_chConfigTx(&chObj->txChObj, + chObj->txChParams); - } + if(tempRetVal != UDMA_SOK) + { + retVal = FVID2_EFAIL; + GT_0trace(CsitxTrace, + GT_ERR, + "[ERROR]UDMA TX channel config FAILED!!!\r\n"); } - if (retVal == FVID2_SOK) + } + + if (retVal == FVID2_SOK) + { + /* Register callbacks here */ + /* Register ring completion callback */ + eventHandle = &chObj->cqEventObj; + UdmaEventPrms_init(&eventParams); + eventParams.eventType = UDMA_EVENT_TYPE_DMA_COMPLETION; + eventParams.eventMode = UDMA_EVENT_MODE_SHARED; + eventParams.chHandle = &chObj->txChObj; + eventParams.masterEventHandle = &txObj->masterEvent; + eventParams.eventCb = &CsitxDrv_udmaCQEventCb; + eventParams.appData = chObj; + tempRetVal = Udma_eventRegister(txObj->initParams.drvHandle, + eventHandle, + &eventParams); + + if(tempRetVal != UDMA_SOK) { - /* Set channel status to created */ - chObj->status = CSITX_DRV_CH_STATE_CREATED; + retVal = FVID2_EFAIL; + GT_0trace(CsitxTrace, + GT_ERR, + "[ERROR]UDMA CQ event register FAILED!!!\r\n"); } } } + if (retVal == FVID2_SOK) + { + /* Set channel status to created */ + chObj->status = CSITX_DRV_CH_STATE_CREATED; + } + return retVal; } -int32_t CsitxDrv_clearUdmaParams(CsitxDrv_InstObj *instObj) +int32_t CsitxDrv_clearUdmaParams(CsitxDrv_ChObj *chObj) { int32_t retVal = FVID2_SOK, tempRetVal = UDMA_SOK; - uint32_t chIdx; - CsitxDrv_ChObj *chObj; Udma_EventHandle eventHandle; - for (chIdx = 0U ; chIdx < instObj->createParams.numCh ; chIdx++) - { - chObj =&instObj->chObj[chIdx]; - if (chObj->chCfg->chType == CSITX_CH_TYPE_TX) + if (CSITX_CH_TYPE_TX == chObj->chCfg->chType) { /* Unregister ring completion callback */ eventHandle = &chObj->cqEventObj; @@ -327,9 +312,8 @@ int32_t CsitxDrv_clearUdmaParams(CsitxDrv_InstObj *instObj) /* Close UDMA channel */ tempRetVal += Udma_chClose(&chObj->txChObj); } - } - if (tempRetVal != UDMA_SOK) + if (UDMA_SOK != tempRetVal) { retVal = FVID2_EFAIL; } @@ -669,9 +653,9 @@ void CsitxDrv_udmaCQEventCb(Udma_EventHandle eventHandle, /* Application call back */ if (appCb == 1U) { - if(instObj->fdmCbParams.fdmCbFxn != NULL) + if(NULL != chObj->virtContext->fdmCbParams.fdmCbFxn) { - instObj->fdmCbParams.fdmCbFxn(instObj->fdmCbParams.fdmData); + chObj->virtContext->fdmCbParams.fdmCbFxn(chObj->virtContext->fdmCbParams.fdmData); } } } -- 2.34.1