Files
banban/ql-bootloader/common/src/FreqChange.c
T

977 lines
28 KiB
C

/******************************************************************************
** (C) Copyright 2007 Marvell International Ltd. ?
** All Rights Reserved
******************************************************************************/
#include "FreqChange.h"
#include "bsp.h"
//#include "acipc.h"
//#include "diag_API.h"
//#include <bsp.h>
//#include "utilities.h"
#include "pmic.h"
extern UINT64 T32kHzBase;
extern UINT32 T32kCountLast;
extern int T32kCountInitialized;
extern UINT64 timerCountReadU64(void);
//extern rti_rt_t rti_rt;
#define FREQ_MODE "[SYS ]"
#define RTI_CURRENT_TICK timerCountReadU64()
//#define CHIP_IS_CRANE_Z1 (getLongChipId()==0XF06731)
/*
__inline void Delay_32k(UINT32 delay){
UINT32 countBefore, countAfter, i;
if(delay == 0)
return;
countBefore = timerCountRead(TS_TIMER_ID);
while(1){
countAfter = timerCountRead(TS_TIMER_ID);
if(countAfter>countBefore){
if(countAfter - countBefore >= delay)
break;
}else{
countAfter += 0xFFFFFFFF;
if(countAfter - countBefore >= delay)
break;
}
}
}
__inline UINT32 Delta_32k_Tick(UINT32 initTick){
UINT32 deltaTick = 0, currentTick = 0;
currentTick = timerCountRead(TS_TIMER_ID);
if(currentTick >= initTick){
deltaTick = currentTick - initTick;
}else{
currentTick += 0xFFFFFFFF;
deltaTick = currentTick - initTick;
}
return deltaTick;
}
*/
//#include "timer.h"
//#include "timer_config.h"
//#include "timer_hw.h"
//#include "osa.h"
//#include "global_types.h"
//#include "diag_API.h"
//#include "log.h"
#define CALC_DURATION 1
#define RUNNING_MODE_L 0
#define RUNNING_MODE_H 1
#define DDR_HIGH_TO_LOW_THRESHOLD (5)
#define RTI_ENABLE_THRESHOLD (10)
#define PS_DL_H (3276800) //25mbps*1024*1024/8
#define PS_DL_L (1310720) //10mbps
#define PS_UL_H (655360) //5mbps
#define PS_UL_L (262144) //2mbps
extern UINT32 PsUploadDataSize;
extern UINT32 PsDownloadDataSize;
extern void GetRTISetting(int *enable, int *ht, int *lt);
extern void GetModeSetting(int *enable, int *ht, int *lt);
extern int CPUUsageInfo(UINT64 duration);
extern void DDRFrequencyChangeRequestForPlatform(DDR_FREQUENCY frequency);
extern void rti_set_enable(UINT32 enable);
UINT8 current_PP = 0x02; //boot_PP
UINT32 RunningMode = RUNNING_MODE_L;
extern UINT32 DDRFreq_Id_Plat;
extern void tft_hash_table_clean(void);
extern UINT32 commpmdebuglog[36];
void FreqChangeUpdate(void)
{
#ifdef NEZHA3_1826
UINT64 tick;
UINT32 dummytick;//we need read 32K ts timer to update timer.last32kvalue when pmu is disable, wdt kick API need this value to be updated
UINT32 usage;
static UINT64 last_tick = 0;
static UINT32 DDRHighToLowTriggerCount=0;
static UINT32 RtiEnableTriggerCount=0;
int rtiChange, rtiHT, rtiLT;
int modeChange, modeHT, modeLT;
GetRTISetting(&rtiChange, &rtiHT, &rtiLT);
GetModeSetting(&modeChange, &modeHT, &modeLT);
dummytick = timerCountRead(TS_TIMER_ID);
tick = RTI_CURRENT_TICK;
if (last_tick == 0)
{
last_tick = tick;
return;
}
if (tick - last_tick > 13000000 * CALC_DURATION)
{
#ifndef LWIP_IPNETBUF_SUPPORT
tft_hash_table_clean();
#endif
usage = CPUUsageInfo(tick - last_tick);
last_tick = tick;
/* change running mode */
if (modeChange)
{
if ((usage == 0)||(usage > 100)) return; //neglect the case that TS read overflow.
if ((RunningMode == RUNNING_MODE_L) && (usage <= modeHT))
{
/* switch to high speed */
RunningMode = RUNNING_MODE_H;
//log_printf(LOG_INFO FREQ_MODE "switch to high freq by CPU loading\n");
DDRHighToLowTriggerCount=0;
commpmdebuglog[32] = 12;
CpCoreFreqChangeTo624();
commpmdebuglog[32] = 13;
}
if (RunningMode == RUNNING_MODE_H)
{
if(usage >= modeLT)
{
DDRHighToLowTriggerCount++;
if(DDRHighToLowTriggerCount>=DDR_HIGH_TO_LOW_THRESHOLD)
{
/* switch to low speed */
RunningMode = RUNNING_MODE_L;
DDRHighToLowTriggerCount=0;
//log_printf(LOG_INFO FREQ_MODE "switch to low freq by CPU loading\n");
commpmdebuglog[32] = 14;
CpCoreFreqChangeTo416();
commpmdebuglog[32] = 15;
}
}
else
{
DDRHighToLowTriggerCount=0;
}
}
}
/* change RTI */
if (rtiChange)
{
if (RunningMode == RUNNING_MODE_H || !modeChange)
{
if (usage <= rtiHT)
{
RtiEnableTriggerCount=0;
rti_set_enable(0);
}
}
if (usage >= rtiLT)
{
RtiEnableTriggerCount++;
if(RtiEnableTriggerCount>=RTI_ENABLE_THRESHOLD)
{
rti_set_enable(1);
RtiEnableTriggerCount=0;
}
}else{
RtiEnableTriggerCount=0;
}
}
}
#endif
}
/************************** Added frequency change module code for Crane below. *********************************/
typedef struct
{
volatile unsigned int CC_CP; //0x0
volatile unsigned int CC_AP; //0x4
volatile unsigned int DM_CC_CP; //0x8
volatile unsigned int DM_CC_AP; //0xC
volatile unsigned int FC_TIMER; //0x10
volatile unsigned int CP_IDLE_CFG; //0x14
volatile unsigned int AP_IDLE_CFG; //0x18
volatile unsigned int SQU_CLK_GATE_CTRL; //0x1C
volatile unsigned int IRE_CLK_GATE_CTRL; //0x20
volatile unsigned int RESERVED0; //0x24
volatile unsigned int CCIC_CLK_GATE_CTRL; //0x28
volatile unsigned int FBRC0_CLK_GATE_CTRL; //0x2C
volatile unsigned int FBRC1_CLK_GATE_CTRL; //0x30
volatile unsigned int USB_CLK_GATE_CTRL; //0x34
volatile unsigned int RESERVED1[2]; //0x38-0x3C
volatile unsigned int PMU_CLK_GATE_CTRL; //0x40
volatile unsigned int LTE_DMA_AXI2MC0_CLK_RES_CTRL; //0x44
volatile unsigned int AXI_CLK_RES_CTRL; //0x48
volatile unsigned int HSI_CLK_RES_CTRL; //0x4C
volatile unsigned int CCIC_CLK_RES_CTRL; //0x50
volatile unsigned int SDH0_CLK_RES_CTRL; //0x54
volatile unsigned int SDH1_CLK_RES_CTRL; //0x58
volatile unsigned int USB_CLK_RES_CTRL; //0x5C
volatile unsigned int QSPI_CLK_RES_CTRL; //0x60
volatile unsigned int DMA_CLK_RES_CTRL; //0x64
volatile unsigned int AES_CLK_RES_CTRL; //0x68
volatile unsigned int MCB_CLK_RES_CTRL; //0X6C
volatile unsigned int CP_IMR; //0x70
volatile unsigned int CP_IRWC; //0x74
volatile unsigned int CP_ISR; //0x78
volatile unsigned int SD_ROT_WAKE_CLR; //0X7C
volatile unsigned int PMU_FBRC_CLK; //0x80
volatile unsigned int PWR_STBL_TIMER; //0X84
volatile unsigned int DEBUG_REG; //0x88
volatile unsigned int SRAM_PWR_DWN; //0x8C
volatile unsigned int CORE_STATUS; //0x90
volatile unsigned int RES_FRM_SLP_CLR; //0x94
volatile unsigned int AP_IMR; //0x98
volatile unsigned int AP_IRWC; //0x9C
volatile unsigned int AP_ISR; //0xA0
volatile unsigned int DX8_CLK_RES_CTRL; //0XA4
volatile unsigned int PMU_VPRO_PWRDWN; //0xA8
volatile unsigned int DTC_CLK_RES_CTRL; //0xAC
volatile unsigned int MC_HW_SLP_TYPE; //0XB0
volatile unsigned int MC_SLP_REQ_AP; //0XB4
volatile unsigned int MC_SLP_REQ_CP; //0xb8
volatile unsigned int MC_SLP_REQ_MSA; //0xbc
volatile unsigned int MC_MC_SLP_TYPE; //0XC0
volatile unsigned int PLL_SEL_STATUS; //0xc4
volatile unsigned int SYNC_MODE_BYPASS; //0xC8
volatile unsigned int GC_CLK_RES_CTRL; //0xCC
volatile unsigned int GC_PWRDWN; //0xd0 GPU_3D_PWRDWN
volatile unsigned int SMC_CLK_RES_CTRL; //0xD4
volatile unsigned int PWR_CTRL_REG; //0xD8
volatile unsigned int PWR_BLK_TMR_REG; //0xDC
volatile unsigned int SDH2_CLK_RES_CTRL; //0xE0
volatile unsigned int SDH_NOM_DENOM_CTRL; //0xE4
volatile unsigned int RESERVED2[2]; //0xE8-0XEC
volatile unsigned int PWR_STATUS_REG; //0xF0
volatile unsigned int MCK4_CTRL; //0xF4
volatile unsigned int RESERVED3[(0x100-0xF4)/4-1];
volatile unsigned int CC2_AP; //0x100
volatile unsigned int CC2_CP; //0x104
volatile unsigned int TRACE_CONFIG; //0x108
volatile unsigned int CP_CLK_CTRL; //0x10C
volatile unsigned int AP_CLK_CTRL; //0x110
volatile unsigned int RESERVED4[(0x120-0x110)/4-1];
volatile unsigned int CA7MP_IDLE_CFG0; //0x120
volatile unsigned int CA7_CORE0_IDLE_CFG; //0x124
volatile unsigned int RESERVED5[(0x140-0x124)/4-1];
volatile unsigned int DVC_DEBUG; //0x140
volatile unsigned int ACLK_CTL; //0x144
volatile unsigned int DDR_CKPHY_PLL1_CTRL1; //0x148
volatile unsigned int DDR_CKPHY_PLL1_CTRL2; //0x14c
volatile unsigned int RESERVED6[(0x15c-0x14c)/4-1];
volatile unsigned int CKPHY_FC_CTRL; //0x15c
} PMUA_TypeDef;
#define PMUA_BASE 0xD4282800
#define PMUA (( PMUA_TypeDef *) PMUA_BASE )
typedef struct
{
volatile unsigned int APB_SPARE0;
volatile unsigned int RESERVED0[2];
volatile unsigned int SENSOR_V18;
volatile unsigned int RECERVED1[(0x100-0x0C)/4-1];
volatile unsigned int PLL1_SW_CTRL;//0X100
volatile unsigned int PLL1_SW_CTRL2;
volatile unsigned int PLL2_SW_CTRL2;
volatile unsigned int APB_spare4_reg;
volatile unsigned int ANA_GRP_SW;
volatile unsigned int APB_spare6_reg; //0x114
volatile unsigned int APB_spare7_reg; //0x118
}APBSPARE_TypeDef;
#define APBSPARE_BASE 0xD4090000
#define APBSPARE (( APBSPARE_TypeDef *) APBSPARE_BASE )
unsigned int exp_cpcore_pclk_freq=0;
unsigned int exp_cpcore_bus_freq=0;
unsigned int exp_cpcore_mc_freq=0;
unsigned int exp_axi_clk_freq=0;
unsigned int fc_config_fix = 0;
unsigned int fc_config_fix_wifi = 0;
/* PP Semaphore*/
OSSemaRef PPSysRef = NULL;
void PP_Mutex_Lock(void)
{
//OSA_STATUS status;
if (PPSysRef != NULL) {
//status = OSASemaphoreAcquire(PPSysRef, OS_SUSPEND);
//ASSERT(status == OS_SUCCESS);
}
}
void PP_Mutex_Unlock(void)
{
//OSA_STATUS status;
if (PPSysRef != NULL) {
//status = OSASemaphoreRelease(PPSysRef);
//ASSERT(status == OS_SUCCESS);
}
}
void PP_init(void)
{
//OSA_STATUS status;
//status = OSASemaphoreCreate (&PPSysRef, 1, OSA_FIFO);
//ASSERT(status == OS_SUCCESS);
}
void CommPMSwitch(unsigned char ProductPoint)
{
// if (ProductPoint < 5)
cpcore_fc_config(ProductPoint);
}
void vccmain_switch(unsigned int idx)
{
switch (idx)
{
case 2:
PlatformVcoreConfigLow();
//set_cpu_dvc(CP_DVC_LV0);//416
return;
case 3:
PlatformVcoreConfigLow();
//set_cpu_dvc(CP_DVC_LV1);//499
return;
case 4:
PlatformVcoreConfigHigh();
//set_cpu_dvc(CP_DVC_LV2);//624
return;
case 5:
PlatformVcoreConfigTop();
//set_cpu_dvc(CP_DVC_LV3);//832
return;
default:
PlatformVcoreConfigLow();
//set_cpu_dvc(CP_DVC_LV0);
return;
}
}
void cpcore_fc_fix_bywifi(UINT8 OnOff)
{
fc_config_fix_wifi = (OnOff)?1:0;
}
void cpcore_fc_config(unsigned int idx)
{
UINT32 ts_now;
if( (idx> 6) || fc_config_fix || (current_PP == idx) || fc_config_fix_wifi)
{
// fatal_printf("=== Abort cpcore_fc_config: idx=%d, current_PP=%d, fc_config_fix=%d", idx, current_PP, fc_config_fix);
//DIAG_FILTER(PM, FreqChange, cpcore_fc_config1, DIAG_INFORMATION)
uart_printf ("=== Abort cpcore_fc_config: idx=%d, current_PP=%d, fc_config_fix=%d, fc_config_fix_wifi=%d.\n\r", idx, current_PP, fc_config_fix, fc_config_fix_wifi);
return;
}
PP_Mutex_Lock();
//apb_spare2[5:0]=0x3F: enable PLL1 307M & 350M & 409M & 491M & 614M & 819M
APBSPARE->PLL1_SW_CTRL2 |= 0x3F;
if (idx > current_PP){
vccmain_switch(idx);
//uart_printf("cpcore_fc_config before\r\n");
}
switch(idx)
{
case 0:
// fatal_printf("cpcore clock change to PLL1_208\n\r");
PMUA->CP_CLK_CTRL = (0x1<<9) | (0x1<<6) | (0x1<<3) | (0x0<<0); //bus_clk_div=0x1, mem_clk_div=0x1, pclk_div=0x1
exp_cpcore_pclk_freq = 208;
exp_cpcore_mc_freq = 104;
exp_cpcore_bus_freq = 104;
RunningMode = RUNNING_MODE_L;
break;
case 1:
// fatal_printf("cpcore clock change to PLL1_312\n\r");
PMUA->CP_CLK_CTRL = (0x1<<9) | (0x1<<6) | (0x0<<3) | (0x1<<0); //bus_clk_div=0x1, mem_clk_div=0x1, pclk_div=0x0
exp_cpcore_pclk_freq = 312;
exp_cpcore_mc_freq = 156;
exp_cpcore_bus_freq = 156;
RunningMode = RUNNING_MODE_L;
break;
case 2:
// fatal_printf("cpcore clock change to PLL1_416\n\r");
PMUA->CP_CLK_CTRL = (0x1<<9) | (0x1<<6) | (0x0<<3) | (0x0<<0); //bus_clk_div=0x1, mem_clk_div=0x1, pclk_div=0x0
exp_cpcore_pclk_freq = 416;
exp_cpcore_mc_freq = 208;
exp_cpcore_bus_freq = 208;
RunningMode = RUNNING_MODE_L;
break;
case 3:
// fatal_printf("cpcore clock change to PLL1_499\n\r");
PMUA->CP_CLK_CTRL = (0x1<<9) | (0x1<<6) | (0x0<<3) | (0x2<<0); //bus_clk_div=0x1, mem_clk_div=0x1, pclk_div=0x0
exp_cpcore_pclk_freq = 499;
exp_cpcore_mc_freq = 249;
exp_cpcore_bus_freq = 249;
RunningMode = RUNNING_MODE_H;
break;
case 4:
// fatal_printf("cpcore clock change to PLL1_624\n\r");
PMUA->CP_CLK_CTRL = (0x1<<9) | (0x1<<6) | (0x0<<3) | (0x3<<0); //bus_clk_div=0x1, mem_clk_div=0x1, pclk_div=0x0
exp_cpcore_pclk_freq = 624;
exp_cpcore_mc_freq = 312;
exp_cpcore_bus_freq = 312;
RunningMode = RUNNING_MODE_H;
break;
case 5:
// fatal_printf("cpcore clock change to PLL1_832\n\r");
PMUA->CP_CLK_CTRL = (0x1<<9) | (0x1<<6) | (0x0<<3) | (0x4<<0); //bus_clk_div=0x1, mem_clk_div=0x1, pclk_div=0x0
exp_cpcore_pclk_freq = 832;
exp_cpcore_mc_freq = 416;
exp_cpcore_bus_freq = 416;
RunningMode = RUNNING_MODE_H;
break;
case 6:
// fatal_printf("cpcore clock change to PLL1_104\n\r");
PMUA->CP_CLK_CTRL = (0x0<<9) | (0x0<<6) | (0x3<<3) | (0x0<<0); //bus_clk_div=0x1, mem_clk_div=0x1, pclk_div=0x3
exp_cpcore_pclk_freq = 104;
exp_cpcore_mc_freq = 104;
exp_cpcore_bus_freq = 104;
RunningMode = RUNNING_MODE_L;
break;
}
PMUA->CP_CLK_CTRL |= (1 << 12);
while((PMUA->CP_CLK_CTRL & 0x1000) != 0x0);
if (idx < current_PP){
vccmain_switch(idx);
//uart_printf("cpcore_fc_config after\r\n");
}
#if 0
/*update 13HMZ counter with 32K timer, begin, gsfan*/
if(T32kCountInitialized == 1)
{
ts_now = timerCountRead(TS_TIMER_ID);
enable_performance_count();/// clear the performance_count
if(ts_now > T32kCountLast)
{
T32kHzBase = ((T32kHzBase>>32)<<32) + ts_now;
}
else
{
T32kHzBase = (((T32kHzBase + 0xffffffff)>>32)<<32) + ts_now;
}
T32kCountLast = ts_now;
}
/*update 13HMZ counter with 32K timer, end, gsfan*/
#endif
current_PP = idx;
PP_Mutex_Unlock();
//DIAG_FILTER(PM, FreqChange, cpcore_fc_config, DIAG_INFORMATION)
CP_LOGD("CpCoreFreqChangeTo %d, CP_CLK_CTRL: 0x%x\n\r", exp_cpcore_pclk_freq, PMUA->CP_CLK_CTRL);
}
UINT32 get_cr5_cpu_freq(void)
{
int currentCPFreq, clk_sel, divider;
if (0 == exp_cpcore_pclk_freq)
{
divider = (PMUA->CP_CLK_CTRL >> 3) & 0x7;
clk_sel = PMUA->CP_CLK_CTRL & 0x7;
switch (clk_sel)
{
case 0:
exp_cpcore_pclk_freq = 416 / (divider+1);
break;
case 1:
exp_cpcore_pclk_freq = 312 / (divider+1);
break;
case 2:
exp_cpcore_pclk_freq = 499 / (divider+1);
break;
case 3:
exp_cpcore_pclk_freq = 624 / (divider+1);
break;
case 4:
exp_cpcore_pclk_freq = 832;
break;
default:
exp_cpcore_pclk_freq = 1; //not existing
break;
}
}
switch (exp_cpcore_pclk_freq)
{ //The actual signoff freq values are different.
case 208:
currentCPFreq=204;
break;
case 312 :
currentCPFreq=307;
break;
case 416 :
currentCPFreq=409;
break;
case 499:
currentCPFreq=491;
break;
case 624 :
currentCPFreq=614;
break;
case 832 :
currentCPFreq=818;
break;
default:
currentCPFreq=1; //not existing
break;
}
return currentCPFreq;
}
UINT32 get_cpu_freq(void)
{
return exp_cpcore_pclk_freq;
}
struct PsramPP_t
{
const char *label;
int pp; //clock
int pll; //clock selection
int fcp; //FC point
int dvc; //dvc level
};
static struct PsramPP_t pphy_pp[] = {
/*label pp, pll, fcp, dvc*/
{"OP0", 156, 0x5, 0, 0},
{"OP1", 208, 0x4, 0, 0},
{"OP2", 312, 0x0, 1, 0},
{"OP3", 350, 0x1, 1, 0},
{"OP4", 416, 0x2, 1, 0},
{"OP5", 26, 0x3, 1, 0},
};
#pragma arm section code="PSRAM_FC"
void psram_phy_fc_config(int phy_idx)
{
unsigned int rd_data;
unsigned int fc_trigger_bit = 24; // Note: from CraneZ2, PHYCLK Frequency Change Request is bit24.
if(phy_idx>4)
{
uart_printf("=== Error: psram_phy_fc_config, idx=%d", phy_idx);
return;
}
//apb_spare2[2:0]=0x7: enable PLL1 832M & 624M & 499M
//APBSPARE->PLL1_SW_CTRL2 |= 0x3F;
rd_data = PMUA->MC_HW_SLP_TYPE;
#if 1
rd_data &= ~((0x7 << 26) | (0x7 << 18) | (0x3 << 16) | (1 << 8) | (0xf << 3));
rd_data |= (0x1 << 26) /*fix PSRAM ctrl @350M*/ | (pphy_pp[phy_idx].pll << 18) | (0x1 << 16) | (pphy_pp[phy_idx].fcp << 4);
#else
rd_data &= ~(0x7 << 26);
rd_data |= (0x1 << 26); //fix PSRAM ctrl @350M
rd_data &= ~(0x7 << 18);
rd_data |= (pphy_pp[phy_idx].pll << 18);
rd_data &= ~(0x7 << 4);
rd_data |= (pphy_pp[phy_idx].fcp << 4);
#endif
//if (CHIP_IS_CRANEG_AX)
// rd_data |= ((1 << 8)|(1 << 6)); //fc for controller and phy, clk mode 2x
//else
rd_data |= (1 << 5); //fc for controller and phy, phy clk mode 1x for CraneLR/LS-A0 (with bit 8) and 2x for others
PMUA->MC_HW_SLP_TYPE = rd_data;
PMUA->MC_HW_SLP_TYPE |= 0x1<<fc_trigger_bit ; //phy_clk fc request
while(PMUA->MC_HW_SLP_TYPE & (0x1<<fc_trigger_bit));
__asm {NOP};
__asm {ISB};
__asm {DSB};
__asm {NOP};
}
#pragma arm section code
void axi_clk_fc_config(unsigned int idx)
{
//apb_spare2[5:0]=0x3F: enable PLL1 307M & 350M & 409M & 491M & 614M & 819M
APBSPARE->PLL1_SW_CTRL2 |= 0x3F;
switch(idx)
{
case 0: //156M
uart_printf("aclk clock change to 156\n\r");
PMUA->ACLK_CTL = 0x0<<0;
exp_axi_clk_freq = 156;
break;
case 1: //208M
uart_printf("aclk clock change to 208\n\r");
PMUA->ACLK_CTL = 0x1<<0;
exp_axi_clk_freq = 208;
break;
default:
return;
}
PMUA->ACLK_CTL |= (1 << 4);
while((PMUA->ACLK_CTL & 0x10) != 0x0);
}
static CP_DVC_LEVEL CPDVCValue = CP_DVC_NO_SET;
unsigned char CRN_SVC_FP[];
void cpu_dvc_init(void)
{
/* NOTE: the following three stable time registers should be updated
according to real core voltage once chip SVC data is ready for use. */
BU_REG_WRITE(PMU_DVC_STBL_0_1, (CRN_SVC_FP[1]-CRN_SVC_FP[0])*26); //stable time 0_1
BU_REG_WRITE(PMU_DVC_STBL_1_2, (CRN_SVC_FP[2]-CRN_SVC_FP[1])*26); //stable time 1_2
BU_REG_WRITE(PMU_DVC_STBL_2_3, (CRN_SVC_FP[3]-CRN_SVC_FP[2])*26); //stable time 2_3
BU_REG_WRITE(PMU_DVC_EX_STR, 0x1A0); //extra stable time
BU_REG_WRITE(PMU_DVC_IMR, 0x7); //enable DVC int
BU_REG_WRITE(PMU_DVC_CTRL, 0x3); //enable DVC
}
void set_cpu_dvc(CP_DVC_LEVEL cp_dvc_val)
{
volatile UINT32 tmp;
if(cp_dvc_val == CPDVCValue)
return;
CPDVCValue = cp_dvc_val;
// uart_printf("set_cpu_dvc %d.\r\n", cp_dvc_val);
tmp = BU_REG_READ(PMU_DVC_CP);
tmp &= (~(0xf<<4));
switch (cp_dvc_val)
{
case CP_DVC_LV0:
break;
case CP_DVC_LV1 :
tmp |= (0x1<<4);
break;
case CP_DVC_LV2:
tmp |= (0x2<<4);
break;
case CP_DVC_LV3 :
tmp |= (0x3<<4);
break;
default:
return;
}
BU_REG_WRITE(PMU_DVC_CP, (tmp |(0x1<<7)));
while (!(BU_REG_READ(PMU_DVC_ISR) & (0x1<<1))) ;// wait until DVC change is done
BU_REG_WRITE(PMU_DVC_ISR, 0x5); //only clear bit1 of CP DVC done
}
//ICAT EXPORTED FUNCTION - PM, FreqChange, CpCoreGetFreq
void CpCoreGetFreq(void)
{
CP_LOGD("CpCoreFreq = %d.\r\n", exp_cpcore_pclk_freq);
//DIAG_FILTER(PM, FreqChange, CpCoreGetFreq, DIAG_INFORMATION)
CP_LOGD ("CpCoreFreq = %d.\n\r", exp_cpcore_pclk_freq);
}
//ICAT EXPORTED FUNCTION - PM, FreqChange, CpCoreFreqChangeTo312
void CpCoreFreqChangeTo104(void)
{
cpcore_fc_config(6);
//DIAG_FILTER(PM, FreqChange, CpCoreFreqChangeTo312, DIAG_INFORMATION)
CP_LOGD("CpCoreFreqChangeTo104.\r\n");
}
//ICAT EXPORTED FUNCTION - PM, FreqChange, CpCoreFreqChangeTo312
void CpCoreFreqChangeTo312(void)
{
cpcore_fc_config(1);
//DIAG_FILTER(PM, FreqChange, CpCoreFreqChangeTo312, DIAG_INFORMATION)
CP_LOGD("CpCoreFreqChangeTo312.\r\n");
}
//ICAT EXPORTED FUNCTION - PM, FreqChange, CpCoreFreqChangeTo416
void CpCoreFreqChangeTo416(void)
{
cpcore_fc_config(2);
//DIAG_FILTER(PM, FreqChange, CpCoreFreqChangeTo416, DIAG_INFORMATION)
CP_LOGD("CpCoreFreqChangeTo416.\r\n");
}
//ICAT EXPORTED FUNCTION - PM, FreqChange, CpCoreFreqChangeTo624
void CpCoreFreqChangeTo624(void)
{
cpcore_fc_config(4);
//DIAG_FILTER(PM, FreqChange, CpCoreFreqChangeTo624, DIAG_INFORMATION)
CP_LOGD ("CpCoreFreqChangeTo624.\n\r");
}
//ICAT EXPORTED FUNCTION - PM, FreqChange, CpCoreFreqChangeTo832
void CpCoreFreqChangeTo832(void)
{
cpcore_fc_config(5);
//DIAG_FILTER(PM, FreqChange, CpCoreFreqChangeTo832, DIAG_INFORMATION)
CP_LOGD ("CpCoreFreqChangeTo832.\n\r");
}
//ICAT EXPORTED FUNCTION - PM, FreqChange, PsramPhyFreqChangeTo156
void PsramPhyFreqChangeTo156(void)
{
psram_phy_fc_config(0);
//DIAG_FILTER(PM, FreqChange, PsramPhyFreqChangeTo156, DIAG_INFORMATION)
CP_LOGD ("PsramPhyFreqChangeTo156.\n\r");
}
//ICAT EXPORTED FUNCTION - PM, FreqChange, PsramPhyFreqChangeTo208
void PsramPhyFreqChangeTo208(void)
{
psram_phy_fc_config(1);
//DIAG_FILTER(PM, FreqChange, PsramPhyFreqChangeTo208, DIAG_INFORMATION)
CP_LOGD ("PsramPhyFreqChangeTo208.\n\r");
}
//ICAT EXPORTED FUNCTION - PM, FreqChange, PsramPhyFreqChangeTo312
void PsramPhyFreqChangeTo312(void)
{
psram_phy_fc_config(2);
//DIAG_FILTER(PM, FreqChange, PsramPhyFreqChangeTo312, DIAG_INFORMATION)
CP_LOGD ("PsramPhyFreqChangeTo312.\n\r");
}
//ICAT EXPORTED FUNCTION - PM, FreqChange, PsramPhyFreqChangeTo350
void PsramPhyFreqChangeTo350(void)
{
psram_phy_fc_config(3);
//DIAG_FILTER(PM, FreqChange, PsramPhyFreqChangeTo350, DIAG_INFORMATION)
CP_LOGD ("PsramPhyFreqChangeTo350.\n\r");
}
//ICAT EXPORTED FUNCTION - PM, FreqChange, PsramPhyFreqChangeTo416
void PsramPhyFreqChangeTo416(void)
{
psram_phy_fc_config(4);
//DIAG_FILTER(PM, FreqChange, PsramPhyFreqChangeTo416, DIAG_INFORMATION)
CP_LOGD ("PsramPhyFreqChangeTo416.\n\r");
}
//ICAT EXPORTED FUNCTION - PM, FreqChange, AxiFreqChangeTo208
void AxiFreqChangeTo208(void)
{
axi_clk_fc_config(1);
//DIAG_FILTER(PM, FreqChange, AxiFreqChangeTo208, DIAG_INFORMATION)
CP_LOGD ("AxiFreqChangeTo208.\n\r");
}
static void se_clock_on(void)
{
unsigned long reg;
reg = BU_REG_READ(REG_MAIN_CCGR);
reg |= 0x1000;
BU_REG_WRITE(REG_MAIN_CCGR, reg);
reg = BU_REG_READ(SE_CLOCK_REG);
reg |= 0x09; // 0x08; TODO check reset
BU_REG_WRITE(SE_CLOCK_REG, reg);
}
static void se_clock_off(void)
{
BU_REG_WRITE(SE_CLOCK_REG, 0x0);
}
unsigned int efuse_dro( void)
{
unsigned long buffer;
static unsigned long dro_val = 0;//svt_val
se_clock_on();
buffer = BU_REG_READ(REG_GEU_GEU_FUSE_BANK3_255_224);
dro_val = (buffer >> 19) & 0x000000ff;
se_clock_off();
return dro_val;
}
void PlatformVcoreConfigForDro(void)
{
switch(PMIC_ID_GET())
{
case PMIC_812:
break;
case PMIC_813:
break;
}
return;
}
unsigned int read_dro(void)
{
unsigned int val;
unsigned int lvt_cyc,svt_cyc;
unsigned int svt_dro = 0;
unsigned int dro_efuse;
//read efuse dro
dro_efuse = efuse_dro();
//if efuse dro exists, only use efuse
if(dro_efuse != 0)
{
svt_dro = dro_efuse;
uart_printf("dro_efuse = %d\r\n", dro_efuse);
return svt_dro;
}
//Set core voltage
PlatformVcoreConfigForDro(); //get DRO under 1.05
//trace("set vcc_main as [%6.2f]mV!!!\n", (double)start_vol/1000);
//float lvt,hvt,svt;
//Enable DRO clock
*((volatile unsigned int *)REG_APBC_APBC_DRO_CLK_RST)=0x5;
*((volatile unsigned int *)REG_APBC_APBC_DRO_CLK_RST)=0x1;
//Enable DRO
*((volatile unsigned int *)REG_DRO_CONTROLIS_DRO_CNT_TIME) = 0x1FFF;
*((volatile unsigned int *)REG_DRO_CONTROLIS_DRO_CTRL) = 0x3;
//Wait for dro timer done
do{
val=*((volatile unsigned int *)REG_DRO_CONTROLIS_DRO_CNT_TIME);
}while((val&1<<31)!=(1<<31));
*((volatile unsigned int *)REG_DRO_CONTROLIS_DRO_CTRL) = 0x2;
//Get svt cycle number
svt_cyc = *((volatile unsigned int *)REG_DRO_CONTROLIS_DRO_SVT);
uart_printf("DRO_SVT_REG=0x%x\n",svt_cyc);
svt_cyc = (((svt_cyc>>16)&0xffff) + (svt_cyc&0xffff))/2;
//Calculate dro instric freq
svt_dro = (int)(svt_cyc/315);
uart_printf("SVT %d vs TYP 149\n",svt_dro);
return svt_dro;
}
const unsigned char SVC_LVL_TBL_CRN[NUM_PROFILES_CRN][NUM_SVC_LVL_CRN] =
{
//Profile SVT_DRO 416MHz 499MHz 624MHz 832MHz
/*0 156-163*/ { VOLTAGE_0_9375, VOLTAGE_0_9375, VOLTAGE_0_9875, VOLTAGE_1_025 },
/*1 148-155*/ { VOLTAGE_0_9375, VOLTAGE_0_95, VOLTAGE_1_0125, VOLTAGE_1_0375 },
/*2 140-147*/ { VOLTAGE_0_95, VOLTAGE_0_9625, VOLTAGE_1_025, VOLTAGE_1_0625 },
/*3 132-139*/ { VOLTAGE_0_975, VOLTAGE_0_975, VOLTAGE_1_05, VOLTAGE_1_0875 },
/*4 124-131*/ { VOLTAGE_0_9875, VOLTAGE_1_00, VOLTAGE_1_0625, VOLTAGE_1_10 },
/*5 116-123*/ { VOLTAGE_1_00, VOLTAGE_1_0125, VOLTAGE_1_0875, VOLTAGE_1_125 },
/*6 108-115*/ { VOLTAGE_1_025, VOLTAGE_1_0375, VOLTAGE_1_10, VOLTAGE_1_15 },
/*7 100-107*/ { VOLTAGE_1_0375, VOLTAGE_1_05, VOLTAGE_1_1125, VOLTAGE_1_1625 },
};
unsigned char CRN_SVC_FP[NUM_SVC_LVL_CRN] = {0};
int get_prf_num_by_dro_crn(unsigned int dro)
{
int prf_num = -1;
if ((dro < 100)||(dro > 163))
{
uart_printf("ERROR: Invalid dro=%d vs exp[100~163]\r\n", dro);
return -1;
}
/* profile num 0~14, vs DRO 100~163, 8 as stepping */
prf_num = 7 - (dro - 100)/8;
uart_printf("profile num = %d\r\n", prf_num);
return prf_num;
}
void Crane_Get_Svc_Level_Values(void)
{
int profile = NUM_PROFILES_CRN; //out of range
unsigned int i = 0, dro = read_dro();
profile = get_prf_num_by_dro_crn(dro);
if ((profile >= NUM_PROFILES_CRN)||(profile < 0))
{
ASSERT(0);
}
for (i = 0; i < NUM_SVC_LVL_CRN; i++)
{
CRN_SVC_FP[i] = SVC_LVL_TBL_CRN[profile][i];
uart_printf("CRN_SVC_FP[%d] = 0x%x\r\n", i, CRN_SVC_FP[i]);
}
}