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

📄 dvfc.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 3 页
字号:
        // Release bus scaling lock
        DVFC_ACRUNLOCK();

        // If we are scaling bus down, use software scaling
        // to drop the voltage for the slower bus
        if (acr == SDMA_CONFIG_ACR_AHB1X)
        {
            DvfcScaleVoltage(g_SetPoint[DVFC_SPEED_LOW].sw,
                g_SetPoint[DVFC_SPEED_LOW].swVolt,
                BSP_PMIC_LOWSPEED_VOLT,
                BSP_PMIC_LOWBUS_VOLT);
        }

        // Else bus was scaled up.  If we switched to high speed,
        // we need to reconfigure the low-speed voltage since we
        // used software voltage scaling on this voltage setting.
        else if (pSP->dvs == 0x0)
        {
            // Configure DVS voltage
            PmicSwitchModeRegulatorSetVoltageLevel(
                g_SetPoint[DVFC_SPEED_LOW].sw, 
                g_SetPoint[DVFC_SPEED_LOW].swVolt, 
                BSP_PMIC_LOWSPEED_VOLT);
    
        }
        
        RETAILMSG(DVFC_VERBOSE, (_T("ACR = %d\r\n"), acr));

    }

    // If DPTC is enabled for the current setpoint
    if (pSP->dpten)
    {

        // If DPTC wants us to update the voltage
        if (bVoltUpdate)
        {
            // Request for transition to new voltage
            PmicSwitchModeRegulatorSetVoltageLevel(pSP->sw, pSP->swVolt, 
                g_MC13783SwitcherVoltTable[pSP->voltIndex]);

            RETAILMSG(DVFC_VERBOSE, (_T("DPTC volt update (swVolt = 0x%x)\r\n"), 
                g_MC13783SwitcherVoltTable[pSP->voltIndex]));
        }
        
        // Update the DPTC threshold registers
        OUTREG32(&g_pCCM->DCVR[0], g_DptcDcvrTable[pSP->freqIndex][pSP->voltIndex][0]);
        OUTREG32(&g_pCCM->DCVR[1], g_DptcDcvrTable[pSP->freqIndex][pSP->voltIndex][1]);
        OUTREG32(&g_pCCM->DCVR[2], g_DptcDcvrTable[pSP->freqIndex][pSP->voltIndex][2]);
        OUTREG32(&g_pCCM->DCVR[3], g_DptcDcvrTable[pSP->freqIndex][pSP->voltIndex][3]);

        // Enable the DPTC hardware
        CSP_BITFINS(pmcr0, CCM_PMCR0_DPVCR, CCM_PMCR0_DPVCR_CHANGE_REQ);
        OUTREG32(&g_pCCM->PMCR0, pmcr0);

        // Avoid immediately overriding DPVV (voltage valid) when DVFS is
        // transitioning to a higher voltage.  The MC13783 PWRREADY signal
        // can be used to set the DPVV after the new voltage setpoint 
        // has been reached, or we can just insert a fixed delay.
        if (bFreqUpdate && 
            (CSP_BITFEXT(pmcr0, CCM_PMCR0_UDSC) == CCM_PMCR0_UDSC_FREQ_UP))
        {
            Sleep(1);
        }
        
        CSP_BITFINS(pmcr0, CCM_PMCR0_DPVV, CCM_PMCR0_DPVV_VOLT_VALID);
        OUTREG32(&g_pCCM->PMCR0, pmcr0);
    }

cleanUp:

    DVFC_UNLOCK();
}


//-----------------------------------------------------------------------------
//
//  Function: BSPDvfcInit
//
//  This function provides platform-specific initialization for supporting 
//  DVFS/DPTC.
//
//  Parameters:
//      None.
//
//  Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL BSPDvfcInit(void)
{
    BOOL rc = FALSE;
    PHYSICAL_ADDRESS phyAddr;
    UINT32 freq = 0;

    // DDKClockSetCKO(TRUE, DDK_CLOCK_CKO_SRC_AHB, DDK_CLOCK_CKO_DIV_4);

    // Map SDMA registers for access to ACR bit
    if (g_pSDMA == NULL)
    {
        phyAddr.QuadPart = CSP_BASE_REG_PA_SDMA;

        // Map peripheral physical address to virtual address
        g_pSDMA = (PCSP_SDMA_REGS) MmMapIoSpace(phyAddr, sizeof(CSP_SDMA_REGS),
            FALSE);

        // Check if virtual mapping failed
        if (g_pSDMA == NULL)
        {
            ERRORMSG(TRUE, (_T("MmMapIoSpace failed!\r\n")));
            goto cleanUp;
        }

    }

    // Map PBC registers for access to power ready signal from MC13783
    if (g_pPBC == NULL)
    {
        phyAddr.QuadPart = BSP_BASE_REG_PA_PBC_BASE;

        // Map peripheral physical address to virtual address
        g_pPBC = (PCSP_PBC_REGS) MmMapIoSpace(phyAddr, sizeof(CSP_PBC_REGS),
            FALSE);

        // Check if virtual mapping failed
        if (g_pPBC == NULL)
        {
            ERRORMSG(TRUE, (_T("MmMapIoSpace failed!\r\n")));
            goto cleanUp;
        }

    }

    g_PBC_DSW = EXTREG16BF(&g_pPBC->BSTAT2, PBC_BSTAT2_DSW);

    // Mask DVFC interrupts 
    INSREG32BF(&g_pCCM->PMCR0, CCM_PMCR0_FSVAIM, CCM_PMCR0_FSVAIM_MASK);
    INSREG32BF(&g_pCCM->PMCR0, CCM_PMCR0_PTVAIM, CCM_PMCR0_PTVAIM_MASK);

    // Claim the DVS pins
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_DVFS0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_NONE);    
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_DVFS1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_NONE);    
    
    // Determine current working point frequency
    if (!DDKClockGetFreq(DDK_CLOCK_SIGNAL_ARM, &freq))
    {
        ERRORMSG(TRUE, (_T("DDKClockGetFreq failed for DDK_CLOCK_SIGNAL_ARM.\r\n")));
        goto cleanUp;
    }

    // Configure DVFC setpoint parameters tied to CPU frequency
    switch (freq)
    {
    case BSP_CLK_MCUPLL_FREQ:
    case BSP_CLK_MCUPLL_FREQ_ALT:
        // Start in high speed
        g_CurSpeed = DVFC_SPEED_HIGH;        
        break;
        
    default:
        ERRORMSG(TRUE, (_T("Unsupported MCUPLL frequency.\r\n")));
        goto cleanUp;
        
    }

    // Save off default bus configuration to restore from bus scaling
    g_AhbPodf = EXTREG32BF(&g_pCCM->PDR0, CCM_PDR0_MAX_PODF);
    g_IpgPodf = EXTREG32BF(&g_pCCM->PDR0, CCM_PDR0_IPG_PODF);
    g_SdmaAcr = EXTREG32BF(&g_pSDMA->CONFIG, SDMA_CONFIG_ACR);

    // Initialize the forced mode globals
    g_DvfcForcedMode = DDK_CLOCK_DVFC_MODE_NORMAL;

#if 0
    // Configure MC13783 for dual-DVS mode
    if (PmicRegisterWrite(MC13783_ARB_SW_ADDR, CSP_BITFVAL(MC13783_ARB_SW_SW1ABDVS, 1), 
        CSP_BITFMASK(MC13783_ARB_SW_SW1ABDVS)) != PMIC_SUCCESS)
    {
        ERRORMSG(TRUE, (_T("PmicRegisterWrite failed\r\n")));
        goto cleanUp;
    }
#endif

    // Configure the default high-speed voltage
    if (PmicSwitchModeRegulatorSetVoltageLevel(g_SetPoint[DVFC_SPEED_HIGH].sw, 
        g_SetPoint[DVFC_SPEED_HIGH].swVolt, 
        g_MC13783SwitcherVoltTable[g_SetPoint[DVFC_SPEED_HIGH].voltIndex]) 
        != PMIC_SUCCESS)
    {
        ERRORMSG(TRUE, (_T("PmicSwitchModeRegulatorSetVoltageLevel failed!\r\n")));
        goto cleanUp;
    }

    // Configure the default high-speed DPTC thresholds
    OUTREG32(&g_pCCM->DCVR[0], g_DptcDcvrTable[g_SetPoint[DVFC_SPEED_HIGH].freqIndex][g_SetPoint[DVFC_SPEED_HIGH].voltIndex][0]);
    OUTREG32(&g_pCCM->DCVR[1], g_DptcDcvrTable[g_SetPoint[DVFC_SPEED_HIGH].freqIndex][g_SetPoint[DVFC_SPEED_HIGH].voltIndex][1]);
    OUTREG32(&g_pCCM->DCVR[2], g_DptcDcvrTable[g_SetPoint[DVFC_SPEED_HIGH].freqIndex][g_SetPoint[DVFC_SPEED_HIGH].voltIndex][2]);
    OUTREG32(&g_pCCM->DCVR[3], g_DptcDcvrTable[g_SetPoint[DVFC_SPEED_HIGH].freqIndex][g_SetPoint[DVFC_SPEED_HIGH].voltIndex][3]);
        
    // Configure the default low-speed voltage
    if (PmicSwitchModeRegulatorSetVoltageLevel(g_SetPoint[DVFC_SPEED_LOW].sw, 
        g_SetPoint[DVFC_SPEED_LOW].swVolt, BSP_PMIC_LOWSPEED_VOLT) 
        != PMIC_SUCCESS)
    {
        ERRORMSG(TRUE, (_T("PmicSwitchModeRegulatorSetVoltageLevel failed!\r\n")));
        goto cleanUp;
    }

    // Configure the DVS transition speed
    if (PmicSwitchModeRegulatorSetDVSSpeed(g_SetPoint[DVFC_SPEED_HIGH].sw, 
        DVFC_DVSSPEED) != PMIC_SUCCESS)
    {
        ERRORMSG(TRUE, (_T("PmicSwitchModeRegulatorSetDVSSpeed failed!\r\n")));
        goto cleanUp;
    }

    // Configure counting range for 256 system clocks
    INSREG32BF(&g_pCCM->PMCR0, CCM_PMCR0_DCR, CCM_PMCR0_DCR_256_CLOCKS);
    
    // Configure DVFS logic for integer frequency scaling of MCUPLL
    // using MCU post-divider
    INSREG32BF(&g_pCCM->PMCR0, CCM_PMCR0_DFSUP1, 
        CCM_PMCR0_DFSUP1_MCUPLL_UPDATE);
    INSREG32BF(&g_pCCM->PMCR0, CCM_PMCR0_DFSUP0, 
        CCM_PMCR0_DFSUP0_POSTDIV_UPDATE);

    // Configure WFI sampling granularity
    INSREG32BF(&g_pCCM->LTR0, CCM_LTR0_DIV3CK, DVFC_DIV3CK);

    // Configure frequency transition thresholds compared against EMA
    // for WFI signal
    INSREG32BF(&g_pCCM->LTR0, CCM_LTR0_DNTHR, DVFC_DNTHR);
    INSREG32BF(&g_pCCM->LTR0, CCM_LTR0_UPTHR, DVFC_UPTHR);
    INSREG32BF(&g_pCCM->LTR1, CCM_LTR1_PNCTHR, DVFC_PNCTHR);

    // Configure number of consecutive times a threshold is exceeded 
    // before a frequency transition is requested
    INSREG32BF(&g_pCCM->LTR1, CCM_LTR1_DNCNT, DVFC_DNCNT);
    INSREG32BF(&g_pCCM->LTR1, CCM_LTR1_UPCNT, DVFC_UPCNT);
    INSREG32BF(&g_pCCM->LTR1, CCM_LTR1_LTBRSR, 1);

    // Disable weighted load tracking signals
    OUTREG32(&g_pCCM->LTR2, 0);
    OUTREG32(&g_pCCM->LTR3, 0);

    // Configure EMA calculation
    INSREG32BF(&g_pCCM->LTR2, CCM_LTR2_EMAC, DVFC_EMAC);

    // Unmask selected DVFC interrupts
    INSREG32(&g_pCCM->PMCR0, DVFC_INTR_MASK, DVFC_INTR_VAL);

    // Initialize mutex for safe access to CCM registers
    // used by the DVFC driver
    g_hDvfcMutex = CreateMutex(NULL, FALSE, L"MUTEX_DVFC");

    if (g_hDvfcMutex == NULL)
    {
        ERRORMSG(1, (_T("CreateMutex failed!\r\n")));
        goto cleanUp;
    }

    // Initialize mutex for protecting bus scaling
    g_hAcrMutex = CreateMutex(NULL, FALSE, L"MUTEX_ACR");

    if (g_hAcrMutex == NULL)
    {
        ERRORMSG(1, (_T("CreateMutex failed!\r\n")));
        goto cleanUp;
    }

    // Enable/disable DVFS features
    if (g_PBC_DSW & BSP_PBC_DSW_DVFS)
    {
        INSREG32BF(&g_pCCM->PMCR0, CCM_PMCR0_DVFEN, CCM_PMCR0_DVFEN_DVFS_DISABLE);
        RETAILMSG(DVFC_VERBOSE, (_T("DVFS disabled\r\n")));
    }
    else
    {
        INSREG32BF(&g_pCCM->PMCR0, CCM_PMCR0_DVFEN, CCM_PMCR0_DVFEN_DVFS_ENABLE);
        RETAILMSG(DVFC_VERBOSE, (_T("DVFS enabled (DVSSPEED = %d, VSCNT = %d)\r\n"), 
            DVFC_DVSSPEED, DVFC_VSCNT));
    }

    if (g_SetPoint[g_CurSpeed].dpten)
    {
        if (g_PBC_DSW & BSP_PBC_DSW_DPTC)
        {
            g_SetPoint[g_CurSpeed].dpten = FALSE;
            // Disable the DPTC hardware
            INSREG32BF(&g_pCCM->PMCR0, CCM_PMCR0_DPTEN, CCM_PMCR0_DPTEN_DPTC_DISABLE);
            RETAILMSG(DVFC_VERBOSE, (_T("DPTC disabled\r\n")));
        }
        else
        {       
            // Enable the DPTC hardware
            INSREG32BF(&g_pCCM->PMCR0, CCM_PMCR0_DPTEN, CCM_PMCR0_DPTEN_DPTC_ENABLE);

            // Enable DPTC reference circuits
            SETREG32(&g_pCCM->PMCR0, DPTC_REF_CIRCUIT_MASK);

            RETAILMSG(DVFC_VERBOSE, (_T("DPTC enabled\r\n")));
        }
    }
    else
    {
        // Disable the DPTC hardware
        INSREG32BF(&g_pCCM->PMCR0, CCM_PMCR0_DPTEN, CCM_PMCR0_DPTEN_DPTC_DISABLE);
        RETAILMSG(DVFC_VERBOSE, (_T("DPTC disabled")));
    }

    rc = TRUE;

cleanUp:

    return rc;
}


//-----------------------------------------------------------------------------
//
//  Function:  BSPDvfcDeinit
//
//  This function deinitializes the platform-specific DVFS/DPTC support 
//  established by BSPDvfcInit.
//
//  Parameters:
//      None.
//
//  Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL BSPDvfcDeinit(void)
{
    // Disable DPTC & DVFS
    CLRREG32(&g_pCCM->PMCR0, DPTC_REF_CIRCUIT_MASK);
    INSREG32BF(&g_pCCM->PMCR0, CCM_PMCR0_DPTEN, CCM_PMCR0_DPTEN_DPTC_DISABLE);
    INSREG32BF(&g_pCCM->PMCR0, CCM_PMCR0_DVFEN, CCM_PMCR0_DVFEN_DVFS_DISABLE);

    // Unmap SDMA registers
    if (g_pSDMA)
    {
        MmUnmapIoSpace(g_pSDMA, sizeof(CSP_SDMA_REGS));
        g_pSDMA = NULL;
    }
    
    // Unmap PBC registers
    if (g_pPBC)
    {
        MmUnmapIoSpace(g_pPBC, sizeof(CSP_PBC_REGS));
        g_pPBC = NULL;
    }

    return TRUE;
    
}


⌨️ 快捷键说明

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