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

📄 stclkrv.c

📁 st40 clock driver source code. 用于st40 linux
💻 C
📖 第 1 页 / 共 5 页
字号:
Parameters   : STCLKRV_Handle_t Handle

Return Value : ST_ErrorCode_t specified as
               ST_NO_ERROR                     No errors determined
               ST_ERROR_INVALID_HANDLE         Invalid Handle

See Also     : STCLKRV_Disable()
 ****************************************************************************/
#ifndef STCLKRV_NO_PTI
ST_ErrorCode_t STCLKRV_Enable( STCLKRV_Handle_t Handle )
{
    /* Temp ptr into instance list */
    STCLKRV_ControlBlock_t *TmpCB_p = NULL;

    /* Check handle is valid */
    TmpCB_p = FindInstanceByHandle(Handle);

    if (TmpCB_p  == NULL)
    {
        return (ST_ERROR_INVALID_HANDLE);
    }
    if (TmpCB_p->InitPars.DeviceType==STCLKRV_DEVICE_TYPE_BASELINE_ONLY)
    {
        return (ST_ERROR_FEATURE_NOT_SUPPORTED);
    }
    /* Protect data and write to PCR control switch */
    EnterCriticalSection();
    TmpCB_p->ActvRefPcr.PCRHandlingActive = TRUE;
    LeaveCriticalSection();

    return (ST_NO_ERROR);

}

/****************************************************************************
Name         : STCLKRV_SetSTCSource

Description  : Sets thes STC source control switch of the clock recovery
               instance given to the given value.
               Allows selection of either user STC baseline or PCR derived
               STC reference value.

Parameters   : STCLKRV_Handle_t Handle
               STCLKRV_STCSource_t STCSource

Return Value : ST_ErrorCode_t specified as
               ST_NO_ERROR                     No errors determined
               ST_ERROR_INVALID_HANDLE         Invalid Handle

 ****************************************************************************/
ST_ErrorCode_t STCLKRV_SetSTCSource( STCLKRV_Handle_t Handle,
                                     STCLKRV_STCSource_t STCSource)
{
    /* Temp ptr into instance list */
    STCLKRV_ControlBlock_t *TmpCB_p = NULL;

    /* Check handle is valid */

    TmpCB_p = FindInstanceByHandle(Handle);

    if (TmpCB_p  == NULL)
    {
        return (ST_ERROR_INVALID_HANDLE);
    }
    if (TmpCB_p->InitPars.DeviceType==STCLKRV_DEVICE_TYPE_BASELINE_ONLY)
    {
        if ((STCSource != STCLKRV_STC_SOURCE_BASELINE))
        {
            return (ST_ERROR_BAD_PARAMETER);
        }
    }
    /* Check valid source supplied */
    if ((STCSource != STCLKRV_STC_SOURCE_PCR) &&
        (STCSource != STCLKRV_STC_SOURCE_BASELINE))
    {
        return (ST_ERROR_BAD_PARAMETER);
    }
    /* Protect and update instance data */
    EnterCriticalSection();

    TmpCB_p->STCBaseline.STCReferenceControl = STCSource;
    if (STCSource !=  STCLKRV_STC_SOURCE_BASELINE)
    {
        TmpCB_p->FreerunSTC.Active = FALSE;
    }

    LeaveCriticalSection();

    return (ST_NO_ERROR);
}

/****************************************************************************
Name         : STCLKRV_SetPCRSource

Description  : Sets source for the PCR collection required for clock recovery
               and invalidate the decode clock

Parameters   : STCLKRV_Handle_t ClkHandle :- Handle identifying instance to set
               STCLKRV_SourceParams_t :- PCRSource data regarding PCR
               collection


Return Value :  ST_NO_ERROR
                ST_ERROR_INVALID_HANDLE
                ST_ERROR_BAD_PARAMETER
 ****************************************************************************/
ST_ErrorCode_t STCLKRV_SetPCRSource( STCLKRV_Handle_t Handle,
                                     STCLKRV_SourceParams_t *PCRSource_p)
{
    STCLKRV_ControlBlock_t *TmpCB_p;

#ifdef ST_5188
    if ( PCRSource_p->Source_u.STPTI_s.Slot == (STDEMUX_Slot_t )NULL)
#else
    if ( PCRSource_p->Source_u.STPTI_s.Slot == (STPTI_Slot_t )NULL)
#endif
    {
        return(ST_ERROR_BAD_PARAMETER);
    }

    TmpCB_p = FindInstanceByHandle(Handle);

    if (TmpCB_p == NULL)
    {
        return (ST_ERROR_INVALID_HANDLE);
    }
    if (TmpCB_p->InitPars.DeviceType==STCLKRV_DEVICE_TYPE_BASELINE_ONLY)
    {
        return (ST_ERROR_FEATURE_NOT_SUPPORTED);
    }
    EnterCriticalSection();

    TmpCB_p->Slot = PCRSource_p->Source_u.STPTI_s.Slot;
    TmpCB_p->SlotEnabled = TRUE;

    /* flag reset reference PCR */
    TmpCB_p->ActvRefPcr.Valid = FALSE;
    TmpCB_p->ActvRefPcr.AwaitingPCR = TRUE;

    LeaveCriticalSection();

    /* Update state machine and generate STCLKRV_PCR_DISCONTINUOUS_EVT */
    UpdateStateMachine(TmpCB_p, TRUE ); /* GNBvd06145 */

    return ST_NO_ERROR;

}

#endif /* STCLKRV_NO_PTI */

#if defined (ST_7710) || defined (ST_7100) || defined (ST_7109)
/****************************************************************************
Name         : STCLKRV_SetApplicationMode()

Description  : Sets the application mode available.

Parameters   : STCLKRV_Handle_t      Handle
               STCLKRV_ApplicationMode_t AppMode

Return Value : ST_ErrorCode_t specified as
               ST_NO_ERROR                     No errors determined
               ST_ERROR_INVALID_HANDLE         Invalid Handle

See Also     : STCLKRV_Enable()
****************************************************************************/

ST_ErrorCode_t STCLKRV_SetApplicationMode( STCLKRV_Handle_t    Handle,
                                           STCLKRV_ApplicationMode_t AppMode)
{

    STSYS_DU32 *BaseAddress = NULL;
    STCLKRV_ControlBlock_t *CB_p = NULL;
    U32 RegValue;

    /* Check handle is valid */
    CB_p = FindInstanceByHandle(Handle);

    if (CB_p == NULL)
    {
        return (ST_ERROR_INVALID_HANDLE);
    }
    if (CB_p->InitPars.DeviceType==STCLKRV_DEVICE_TYPE_BASELINE_ONLY)
    {
        return (ST_ERROR_FEATURE_NOT_SUPPORTED);
    }
    if ( ( AppMode < STCLKRV_APPLICATION_MODE_NORMAL) ||
          (AppMode > STCLKRV_APPLICATION_MODE_SD_ONLY) )
    {
        return( ST_ERROR_BAD_PARAMETER );
    }

    if (CB_p->HWContext.ApplicationMode == AppMode)
        return (ST_NO_ERROR);

    BaseAddress = CB_p->InitPars.FSBaseAddress_p;

    if (AppMode == STCLKRV_APPLICATION_MODE_SD_ONLY )
    {
#ifdef ST_7710
        RegValue = 0;
        /* Set the EN_PRG bit to Zero */
        clkrv_readReg(BaseAddress, FS_CLOCKGEN_CFG_2, &RegValue);
        RegValue |= 0x20;
        RegValue = (RegValue & 0x0000FFFF) | UNLOCK_KEY;   /* key for registers access */
        clkrv_writeReg(BaseAddress, FS_CLOCKGEN_CFG_2, RegValue);
#elif defined(ST_7100) || defined (ST_7109)
        RegValue = 0;
        clkrv_readReg(BaseAddress, CKGB_CLK_SRC, &RegValue);
        RegValue &= 0xFFFFFFFD;
        clkrv_writeReg(BaseAddress, CKGB_CLK_SRC, RegValue);
        /* clk_pix_sd =clk_hd/4 */
        clkrv_readReg(BaseAddress, CKGB_DISP_CFG, &RegValue);
        RegValue &= 0xFFFFF7FF;
        RegValue |= 0x400;
        clkrv_writeReg(BaseAddress, CKGB_DISP_CFG, RegValue);
#endif
        CB_p->HWContext.ApplicationMode = AppMode;

    }
    else if (AppMode == STCLKRV_APPLICATION_MODE_NORMAL )
    {
#ifdef ST_7710
        RegValue = 0;
        /* Set the EN_PRG bit to Zero */
        clkrv_readReg(BaseAddress, FS_CLOCKGEN_CFG_2, &RegValue);
        RegValue &= 0xFFFFFFDF;
        RegValue = (RegValue & 0x0000FFFF) | UNLOCK_KEY;   /* key for registers access */
        clkrv_writeReg(BaseAddress, FS_CLOCKGEN_CFG_2, RegValue);
#elif defined(ST_7100) || defined (ST_7109)
        RegValue = 0;
        clkrv_readReg(BaseAddress, CKGB_CLK_SRC, &RegValue);
        RegValue |= 0x02;
        clkrv_writeReg(BaseAddress, CKGB_CLK_SRC, RegValue);
#endif
        CB_p->HWContext.ApplicationMode = AppMode;
    }
    return (ST_NO_ERROR);
}
#endif

/****************************************************************************
Name         : STCLKRV_SetNominalFreq()

Description  : Programs the FS registers to the Nominal Frequency
               It will take around 100-150 WC time to take effect
               for the new frequency.

Parameters   : STCLKRV_Handle_t      Handle
               STCLKRV_ClockSource_t ClockSource
               U32                   Frequency

Return Value : ST_ErrorCode_t specified as
               ST_NO_ERROR                     No errors determined
               ST_ERROR_INVALID_HANDLE         Invalid Handle
               STCLKRV_INVALID_FREQUENCY       Invalid Frequency
               STCLKRV_INVALID_SLAVE           Invalid Slave

See Also     : STCLKRV_Enable()
****************************************************************************/

ST_ErrorCode_t STCLKRV_SetNominalFreq( STCLKRV_Handle_t      Handle,
                                       STCLKRV_ClockSource_t ClockSource,
                                       U32                   Frequency )
{
    U32 i = 0;
    U32 SlaveClock;
    U16 CorrectedIPE = 0;
    S32 FreqOffsetInSTC = 0;
    S32 InitialOffsetInPE = 0;
    S8  ChangeInMD=0,CorrectedMD=0;
    U32 CorrectedFrequency = 0;
    STSYS_DU32 *BaseAddress = NULL;
    STCLKRV_ControlBlock_t *CB_p = NULL;
    U32 Index = 0;

    /* Check handle is valid */
    if (NULL == (CB_p = FindInstanceByHandle(Handle)))
        return (ST_ERROR_INVALID_HANDLE);

    /* No clock programming in base line mode */
    if (CB_p->InitPars.DeviceType == STCLKRV_DEVICE_TYPE_BASELINE_ONLY)
        return (ST_ERROR_FEATURE_NOT_SUPPORTED);

    /* Check if clock is valid on this chip */
    if( ! IsClockValid(CB_p, ClockSource) )
        return (STCLKRV_ERROR_INVALID_SLAVE);

    /* Check if clock is valid on this chip */

    /* Search Frequency in Freq. Table */
    for(i=0;((i<MAX_NO_IN_FREQ_TABLE)&&(Frequency!= NominalFreqTable[i].Frequency));i++);

    if(i == MAX_NO_IN_FREQ_TABLE)
    {
        /* Could not find the given frequency in the table */
        return STCLKRV_ERROR_INVALID_FREQUENCY;
    }

    /* Valid clock & freq. */
    BaseAddress = CB_p->InitPars.FSBaseAddress_p;

    EnterCriticalSection();

    /* Reset DCO_CMD  to 0x01 so that no interrupt occurs */
    clkrv_writeReg(BaseAddress, CLKRV_REC_CMD(GetRegIndex(CB_p)), 0x01);

    LeaveCriticalSection();

    /* Mutually exclusive with FILTER task */

    STOS_SemaphoreWait(CB_p->InstanceSemaphore_p);

    Index = FindClockIndex(CB_p, ClockSource);


    /* Zero Offset in table for STC/SD clock*/
    FreqOffsetInSTC = (S32)(CB_p->HWContext.Clocks[0].Frequency
                                - NominalFreqTable[0].Frequency);

    /* Ratio is multiple of 1000 and Step is of 100 so there we placed 10 */
    InitialOffsetInPE = (S32)((FreqOffsetInSTC * (S32)NominalFreqTable[0].Ratio)
                                         / (S32)(NominalFreqTable[0].Step * 10));

    /* Calculate change in MD, IPE */
    CorrectedIPE = (U16)((S32)NominalFreqTable[i].IPE + (S32)InitialOffsetInPE);
    /* if roll over, md needs to be changed */
    if(CorrectedIPE&0x8000)
    {
        /* calculate change in md, +ve or -ve change */
        ChangeInMD = (InitialOffsetInPE >= 0 ? 1 : -1);
        /* MD change, +1, -1 or 0*/
        CorrectedMD = NominalFreqTable[i].MD - ChangeInMD;
    }
    else
    {
        CorrectedMD = NominalFreqTable[i].MD;
    }
    /* Corrected IPE value */
    CorrectedIPE = CorrectedIPE & 0x7fff;

    /* Reset the clocks in software, HW should take care of itself */
    /* Doing this will discard any previous drift of other slave
       It is like resetting Drfit correction process */
    /* Everything else for other slave must be untouched */

    /* Clock[0] - Always Pixel clock */
    for ( SlaveClock = 1; SlaveClock < Index; SlaveClock++)
    {
        CB_p->HWContext.Clocks[SlaveClock].PrevCounter = 0;
        CB_p->HWContext.Clocks[SlaveClock].DriftError  = 0;
    }

    /* update Slave clock */
    CorrectedFrequency = (S32)NominalFreqTable[i].Frequency +
                                (S32)((InitialOffsetInPE * (S32)NominalFreqTable[i].Step)/100);

    CB_p->HWContext.Clocks[Index].PrevCounter = 0;
    CB_p->HWContext.Clocks[Index].DriftError  = 0;
    CB_p->HWContext.Clocks[Index].MD    = CorrectedMD;

⌨️ 快捷键说明

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