📄 dvfc.c
字号:
DVFC_UNLOCK();
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: BSPDvfcIntrServ
//
// This function is invoked from the DVFC interrupt service thread to
// perform the frequency/voltage switch.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
void BSPDvfcIntrServ(void)
{
UINT32 pmcr;
PDVFC_SETPOINT pSP = &g_SetPoint[g_CurSpeed];
BOOL bVoltUpdate = FALSE;
DVFC_LOCK();
pmcr = INREG32(&g_pSYSCTRL->PMCR);
// Handle adjustment cases and give priority to
// rising voltagerequests
// DPTC voltage increase request. Make sure DPTC is
// enabled for this speed and we are not already at the
// highest voltage.
if (((CSP_BITFEXT(pmcr, SYSCTRL_PMCR_LO) == 1) || \
(CSP_BITFEXT(pmcr, SYSCTRL_PMCR_EM) == 1)) \
&& (pSP->dpten) && (pSP->voltIndex != 0))
{
--pSP->voltIndex;
bVoltUpdate = TRUE;
RETAILMSG(1, (_T("WPL = %d\r\n"),pSP->voltIndex));
}
// DPTC voltage decrease request. Make sure DPTC is
// enabled for this speed and we are not already at the
// lowest voltage.
else if ((CSP_BITFEXT(pmcr, SYSCTRL_PMCR_UP) == 1) && \
(pSP->dpten) && (pSP->voltIndex < (DVFC_VOLT_LEVELS-1)))
{
++pSP->voltIndex;
bVoltUpdate = TRUE;
RETAILMSG(1, (_T("WPU = %d\r\n"),pSP->voltIndex));
}
else
{
goto cleanUp;
}
// Update the power management control register
OUTREG32(&g_pSYSCTRL->PMCR, pmcr);
// 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]);
}
// Update the DPTC threshold registers
OUTREG32(&g_pSYSCTRL->DCVR[0], g_DptcDcvrTable[pSP->freqIndex][pSP->voltIndex][0]);
OUTREG32(&g_pSYSCTRL->DCVR[1], g_DptcDcvrTable[pSP->freqIndex][pSP->voltIndex][1]);
OUTREG32(&g_pSYSCTRL->DCVR[2], g_DptcDcvrTable[pSP->freqIndex][pSP->voltIndex][2]);
OUTREG32(&g_pSYSCTRL->DCVR[3], g_DptcDcvrTable[pSP->freqIndex][pSP->voltIndex][3]);
// Enable the DPTC hardware
INSREG32BF(&g_pSYSCTRL->PMCR, SYSCTRL_PMCR_DPTEN, SYSCTRL_PMCR_DPTEN_DPTC_ENABLE);
INSREG32BF(&g_pSYSCTRL->PMCR, SYSCTRL_PMCR_DIE, SYSCTRL_PMCR_DIE_DPTC_ENABLE);
INSREG32BF(&g_pSYSCTRL->PMCR, SYSCTRL_PMCR_DIM, SYSCTRL_PMCR_DIM_DPTC_ALL);
}
cleanUp:
DVFC_UNLOCK();
}
//-----------------------------------------------------------------------------
//
// Function: BSPDvfcInit
//
// This function provides platform-specific initialization for supporting
// DPTC.
// Separate API needs to be provided for DVFS (Software Support only)
// Parameters:
// None.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL BSPDvfcInit(void)
{
BOOL rc = FALSE;
UINT32 freq = 0;
PHYSICAL_ADDRESS phyAddr;
if (g_pSYSCTRL == NULL)
{
phyAddr.QuadPart = CSP_BASE_REG_PA_SYSCTRL;
// Map peripheral physical address to virtual address
g_pSYSCTRL = (PCSP_SYSCTRL_REGS) MmMapIoSpace(phyAddr, sizeof(CSP_SYSCTRL_REGS),
FALSE);
// Check if virtual mapping failed
if (g_pSYSCTRL == NULL)
{
ERRORMSG(TRUE, (_T("MmMapIoSpace failed!\r\n")));
goto cleanUp;
}
}
// 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_MPLL_CLK_FREQ:
#ifdef MX27TO2
// for TO2 MPLL can run at higher freq than processor
case (BSP_MPLL_CLK_FREQ*2/3):
#endif
// Start in high speed
g_CurSpeed = DVFC_SPEED_HIGH;
break;
default:
ERRORMSG(TRUE, (_T("Unsupported MCUPLL frequency.\r\n")));
goto cleanUp;
}
// Configure the default high-speed voltage
// Configure the default high-speed DPTC thresholds
OUTREG32(&g_pSYSCTRL->DCVR[0], g_DptcDcvrTable[g_SetPoint[DVFC_SPEED_HIGH].freqIndex][g_SetPoint[DVFC_SPEED_HIGH].voltIndex][0]);
OUTREG32(&g_pSYSCTRL->DCVR[1], g_DptcDcvrTable[g_SetPoint[DVFC_SPEED_HIGH].freqIndex][g_SetPoint[DVFC_SPEED_HIGH].voltIndex][1]);
OUTREG32(&g_pSYSCTRL->DCVR[2], g_DptcDcvrTable[g_SetPoint[DVFC_SPEED_HIGH].freqIndex][g_SetPoint[DVFC_SPEED_HIGH].voltIndex][2]);
OUTREG32(&g_pSYSCTRL->DCVR[3], g_DptcDcvrTable[g_SetPoint[DVFC_SPEED_HIGH].freqIndex][g_SetPoint[DVFC_SPEED_HIGH].voltIndex][3]);
if (PmicSwitchModeRegulatorSetVoltageLevel(SW1A,SW_VOLTAGE_NORMAL,0x1C)
!= PMIC_SUCCESS)
{
ERRORMSG(TRUE, (_T("PmicSwitchModeRegulatorSetVoltageLevel failed!\r\n")));
goto cleanUp;
}
// Configure counting range for 256 system clocks
INSREG32BF(&g_pSYSCTRL->PMCR, SYSCTRL_PMCR_DCR, SYSCTRL_PMCR_DCR_128_CLOCKS);
// Enable DPTC reference circuits
SETREG32(&g_pSYSCTRL->PMCR, DPTC_REF_CIRCUIT_MASK);
if (g_SetPoint[g_CurSpeed].dpten)
{
// Enable the DPTC hardware
INSREG32BF(&g_pSYSCTRL->PMCR, SYSCTRL_PMCR_DPTEN, SYSCTRL_PMCR_DPTEN_DPTC_ENABLE);
// INSREG32BF(&g_pSYSCTRL->PMCR, SYSCTRL_PMCR_DIE, SYSCTRL_PMCR_DIE_DPTC_ENABLE);
INSREG32BF(&g_pSYSCTRL->PMCR, SYSCTRL_PMCR_DIM, SYSCTRL_PMCR_DIM_DPTC_ALL);
RETAILMSG(DVFC_VERBOSE, (_T("DPTC enabled\r\n")));
}
else
{
// Disable the DPTC hardware
INSREG32BF(&g_pSYSCTRL->PMCR, SYSCTRL_PMCR_DPTEN, SYSCTRL_PMCR_DPTEN_DPTC_DISABLE);
INSREG32BF(&g_pSYSCTRL->PMCR, SYSCTRL_PMCR_DIE, SYSCTRL_PMCR_DIE_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
//
//-----------------------------------------------------------------------------
BOOL BSPDvfcDeinit(void)
{
// Disable DPTC reference circuits
CLRREG32(&g_pSYSCTRL->PMCR, DPTC_REF_CIRCUIT_MASK);
// Unmap PBC registers
if (g_pPBC)
{
MmUnmapIoSpace(g_pPBC, sizeof(CSP_PBC_REGS));
g_pPBC = NULL;
}
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: BSPSetVoltage
//
// This function sets a desired volatge via PMIC
//
// Parameters:
// Volt[in] - deisred Volatge
//
// Returns:
// None
//
//-----------------------------------------------------------------------------
void BSPSetVoltage(UINT8 Volt)
{
unsigned int i = 0;
PmicSwitchModeRegulatorSetVoltageLevel(SW1A,SW_VOLTAGE_NORMAL, Volt);
for (i=0;i<0xFFF;i++);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -