📄 dvm_dfm_api.c
字号:
// just read it for some let the cpu wati a little time
freq_status = XLLPGetCurrentFreqSetting(v_pClkReg);
// NKDbgPrintfW(TEXT("!!frequency %d\r\n"),freq_status.frequency);
//XllpXSC1ReadCLKCFG();
memc_reg->MDREFR = mdrefr;
}
memc_reg->MSC0 = (memc_reg->MSC0 & (~0x7FF07FF0)) | MSC0;
tmp = memc_reg->MSC0;
memc_reg->MDCNFG = (memc_reg->MDCNFG & (~MDCNFG_DTCx)) | DTC;
}
// calcualte KxDBx configuration according to A, B, L
UINT32 calc_KxDBx(int A, int B, int L)
{
if (A)
{
if (B)
{
// A = 1, B = 1
if (L >= 5 && L <= 8)
return MDREFR_K0DB2;
else if (L > 8)
return MDREFR_K0DB4 | MDREFR_K1DB2;
} else
{
// A = 1, B = 0
if (L >= 9 && L <=16)
return MDREFR_K0DB2;
else if (L >= 17 && L <= 31)
return MDREFR_K0DB4 | MDREFR_K1DB2;
}
} else
{
if (B)
{
// A = 0, B = 1
if (L >= 5 && L <= 8 || L >= 11 && L <= 16)
return MDREFR_K0DB2;
else if (L == 9 || L == 10)
return MDREFR_K0DB4 | MDREFR_K1DB2;
} else
{
// A = 0, B = 0
if (L >= 5 && L <= 8 || L >= 11 && L <= 16
|| L >= 21 && L <= 31)
return MDREFR_K0DB2;
else if (L == 9 || L == 10 || L >= 17 && L <= 20)
return MDREFR_K0DB4 | MDREFR_K1DB2;
}
}
return 0;
}
void IPMSetCLKCFG(int cccr, unsigned long newCLKCFGValue)
{
// please open here to catch the LCD_OU interrupt when frequen change
// set clkcfg and configure the memory configuration register
clock_set(cccr, newCLKCFGValue);
}
// todo: add 520 workaround
// todo: add constraints for 13m+ (see Jeff's email)
//
BOOL ComboChange(COMBO_PARAM cp)
{
unsigned long StartTime;
FREQ_VOLT_STATUS CurrentFrequencyStatus;
int newCLKCFGValue = 0;
BOOL DoCoupledVCS = FALSE;
BOOL DoManualVCS = FALSE;
BOOL DoNoVCS = FALSE;
BOOL RetVal = TRUE;
BOOL SPLIT_TRANSACTION = FALSE;
BOOL EXITING_DEEP_IDLE = FALSE;
DWORD CCCR_Bits=0;
static int bEnter = 1;
// add this to avoid ComboChange re-enter
while(bEnter ==0);
bEnter = 0;
//NKDbgPrintfW(TEXT("...................1: Enter combochange ............\r\n"));
CurrentFrequencyStatus = GetCurrentFrequencyStatus();
// Format parameters for safe shifting
//
fixupParams(&cp, &CurrentFrequencyStatus);
//
// Look for error condition
//
if (!ValidParameters(&cp, &CurrentFrequencyStatus))
{
RetVal=FALSE;
NKDbgPrintfW(TEXT("invalid parameter\r\n"));
goto EXIT;
}
//
// Build CLKCFG. Not preserving current state. Assumes that if you want something set, you pass it.
//
if ((CurrentFrequencyStatus.LMulti != cp.LMulti) || (CurrentFrequencyStatus.NMulti != cp.NMulti) ||
(CurrentFrequencyStatus.CPDIS != cp.CPDIS) || (CurrentFrequencyStatus.A_Bit != cp.A_Bit) || (CurrentFrequencyStatus.LCD_26 != cp.LCD_26))
{
newCLKCFGValue = 2; // new 'L', 'N', 'A', CPDIS, LCD_26 value; set FCS bit.
}
newCLKCFGValue |= ((cp.fastbus_mode << 3) | (cp.half_turbo_mode << 2) | cp.turbo_mode);
if(cp.half_turbo_mode && (newCLKCFGValue & 2))
{
// Must split into 2 transactions only if also doing an FCS, which is not guaranteed
//
// Mask out the HT bit in this case, and do the first FCS. Then, we will set the HT bit.
//
newCLKCFGValue &= 0xB;
SPLIT_TRANSACTION=TRUE;
//EdbgOutputDebugString ("ComboChange: Detected an attempt to FCS and HT. newCLKCFGValue = 0x%x\r\n", newCLKCFGValue); // for eboot
}
START:
//
// Check to see if we need to do a full FCS. If so, we will do a coupled VCS.
//
#ifdef PMIC_SUPPORTS_COUPLED_VCS
// bman debug: alter the above logic for 13M (any 13M for now): do a manual VCS to avoid DMAC blackout that is assumed to cause FIFO underruns and audiable artifacts
// May want to make for all FCSes!
//
DoCoupledVCS = (
(CurrentFrequencyStatus.Volts != cp.Volts) && // only change voltage if using a new voltaqe
(
(CurrentFrequencyStatus.LMulti != cp.LMulti) || // L changing
(CurrentFrequencyStatus.NMulti != cp.NMulti && cp.turbo_mode) // 2N changing, plus entering/staying in turbo.
)
)
? TRUE : FALSE;
DoManualVCS = (
((FALSE==DoCoupledVCS) && (CurrentFrequencyStatus.Volts != cp.Volts)) && // only change voltage if using a new voltaqe
(
(CurrentFrequencyStatus.turbo_mode != cp.turbo_mode) || // entering/exiting turbo mode
(CurrentFrequencyStatus.fastbus_mode != cp.fastbus_mode)|| // entering/exiting fast bus mode
(CurrentFrequencyStatus.CPDIS != cp.CPDIS) || // entering/exiting 13M
(FALSE==SPLIT_TRANSACTION && (CurrentFrequencyStatus.half_turbo_mode != cp.half_turbo_mode))
)
) // entering/exiting half turbo mode
? TRUE : FALSE;
#else
//
// PMIC/system design does not support coupled voltage/frequency changes. Must do all cases manually.
// *Currently lumping a new 'B' bit into this case.
// *TODO* Add HT condition
//
DoManualVCS = (
(CurrentFrequencyStatus.Volts != cp.Volts) && // only change voltage if using a new voltaqe
(
(CurrentFrequencyStatus.LMulti != cp.LMulti) || // L changing
((CurrentFrequencyStatus.NMulti != cp.NMulti) && (cp.turbo_mode)) || // 2N changing, plus entering turbo. Only care when entering turbo too.
(CurrentFrequencyStatus.CPDIS != cp.CPDIS) || // entering/exiting 13M
(CurrentFrequencyStatus.turbo_mode != cp.turbo_mode) || // entering/exiting turbo mode
(CurrentFrequencyStatus.fastbus_mode != cp.fastbus_mode) || // entering/exiting fast bus mode
(FALSE==SPLIT_TRANSACTION && (CurrentFrequencyStatus.half_turbo_mode != cp.half_turbo_mode)) // entering/exiting half turbo mode
)
)
? TRUE : FALSE;
#endif
//
// It is not always necessary to change the voltage
//
DoNoVCS = (
(CurrentFrequencyStatus.Volts == cp.Volts) || // Not changing voltage request.
(
(FALSE==DoCoupledVCS && FALSE==DoManualVCS) &&
(
((CurrentFrequencyStatus.NMulti != cp.NMulti) && (!cp.turbo_mode)) || // if altering N, but not entering/staying in turbo mode.
(CurrentFrequencyStatus.A_Bit != cp.A_Bit) || // simply altering A-bit
(CurrentFrequencyStatus.LCD_26 != cp.LCD_26) || // simply altering LCD input clock.
(cp.PLL_EARLY) // setting PLL_EARLY while in 13M (clearing is disallowed)
)
)
)
? TRUE : FALSE;
/* Now, set up CCCR. If CPDIS=1, can either have PPDIS also set, or Clear. Can never clear CPDIS while setting PPDIS. */
// Will allow the user to set cp/ppdis at the same time as setting new L and N (may be useful for getting a step ahead)
//
//
// Build the CCCR value
//
//CCCR_Bits = ((cp.CPDIS << 31) | (cp.PPDIS << 30) | (cp.LCD_26 << 27) | (cp.PLL_EARLY << 26) | (cp.A_Bit << 25) | (cp.NMulti<<7) | cp.LMulti);
CCCR_Bits = ((cp.CPDIS << 31) | (cp.PPDIS << 30) | (cp.LCD_26 << 27) | (cp.A_Bit << 25) | (cp.NMulti<<7) | cp.LMulti); // no pll_early support
//
// Look for special case- 13M+ exit sequence
//
if((CurrentFrequencyStatus.CPDIS==1 && CurrentFrequencyStatus.PPDIS==0) && cp.CPDIS==0)
{
//
// We are currently operating in deep idle (P-PLL on, C-PLL off), and are exiting.
//
// NKDbgPrintfW(TEXT("currently operating in deep idle\r\n"));
EXITING_DEEP_IDLE = TRUE;
// Set PLL_EARLY regardless as it is a requirement when exiting deep idle
//
CCCR_Bits |= (1 << 26);
}
//
// Program the CCCR accordingly
//
v_pClkReg->cccr = CCCR_Bits; // just blast them for now.
while ((v_pClkReg->cccr & 0xCE00079F) != CCCR_Bits);
if(EXITING_DEEP_IDLE)
{
//
// spin for ~150us (120us minimal is required; testing using a bit longer interval).
// 120us = 3900 tix. 150us = 4875 tix. 500us = 16,250.
//
StartTime = v_pOSTReg->oscr0;
while((StartTime + 4875) >= v_pOSTReg->oscr0);
//
// Wait until both PLLs have spun. Another way to handle this would be to arm a timer interrupt of 120us, then return to this snippet.
//
while((v_pClkReg->ccsr & 0x30000000) != 0x30000000);
}
//
// Ensure PI2C clock is not gated. Will leave this clock on to ensure other SW is not affected.
//
v_pClkReg->cken = ((v_pClkReg->cken & ~CKEN_RSVD) | (1 << 15));
//
// If doing a coupled VCS on the next FCS/FastBusMode Change, stage it
//
if (DoCoupledVCS)
{
//NKDbgPrintfW(TEXT("DoCoupledVCS\r\n"));
gLastVoltage = cp.Volts; // create a shadow copy to be used in GetCurrentFrequencyStatus()
//
// Convert Volts to DAC Value and stage VCS for the next FCS
//
VM_SetVoltage(Volts2Dac(cp.Volts));
//
// Adjust LCD Controller's PCD
//
//ShiftLCD_PCD(cp.LMulti); // this needs to: wait till eof, alter pcd, do the fcs. *No need for 13M if we use the new hidden mode (only 13m)
//
// Perform the coupled frequency/voltage change
//
IPMSetCLKCFG(CCCR_Bits, newCLKCFGValue); // FCS; coupled VCS will occur during this FCS/FBM.
v_pPwrReg->PCFR = (v_pPwrReg->PCFR & ~(PCFR_RSVD | PCFR_FVC)); // Disable coupled VCS
}
else if (DoManualVCS)
{
//
// If doing a manual VCS (turbo switch, fast bus switch). Fast bus switching not supported currently.
//
//NKDbgPrintfW(TEXT("DoManualVCS\r\n"));
gLastVoltage = cp.Volts; // create a shadow copy to be used in GetCurrentFrequencyStatus()
if ((CurrentFrequencyStatus.turbo_mode==0 && cp.turbo_mode==1) || (CurrentFrequencyStatus.CPDIS==1 && cp.CPDIS==0))
{
//
// going from run->turbo, or 13M->Run. Must alter voltage before FCS.
//
// convert Volts to DAC Value
// and set the voltage manually
//
//NKDbgPrintfW(TEXT("run->turbo, or 13M->Run\r\n"));
SetCoreVoltage(Volts2Dac(cp.Volts));
// perform only the frequency change
//
IPMSetCLKCFG(CCCR_Bits, newCLKCFGValue);
}
else if ((CurrentFrequencyStatus.turbo_mode==1 && cp.turbo_mode==0) || (CurrentFrequencyStatus.CPDIS==0 && cp.CPDIS==1))
{
//
// going from turbo->run, or Run->13M. Must alter voltage after FCS.
//
// perform only the frequency change
//
// NKDbgPrintfW(TEXT("turbo->run, or Run->13M\r\n"));
IPMSetCLKCFG(CCCR_Bits, newCLKCFGValue);
// convert Volts to DAC Value
// and set the voltage manually
//
SetCoreVoltage(Volts2Dac(cp.Volts));
}
}
else if (DoNoVCS)
{
//WRITE_HEX_LEDS(0x00000009);
// No Voltage change is required. Just do a FCS.
//
//NKDbgPrintfW(TEXT("DoNoVCS\r\n"));
IPMSetCLKCFG(CCCR_Bits, newCLKCFGValue);
//WRITE_HEX_LEDS(0x0000000A);
}
else
{
// nothing to do
// NKDbgPrintfW(TEXT("Doing nothing\r\n"));
}
if(SPLIT_TRANSACTION)
{
//
// We just did the FCS; now we need to enter HT
//
SPLIT_TRANSACTION=FALSE;
newCLKCFGValue = ((newCLKCFGValue & 0xD) | 0x4); // clear F, and set HT
goto START;
}
EXIT:
// WRITE_HEX_LEDS(0x666);
bEnter = 1;
//NKDbgPrintfW(TEXT(".................2: Leave combochange ..............\r\n"));
return (RetVal);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -