//TODO: __init void mt_freqhopping_init(void) static void mt_fh_hal_init(void) { int i = 0; unsigned long flags = 0; FH_MSG_DEBUG("EN: %s",__func__); if(g_initialize == 1){ return; } for(i = 0;i < FH_PLL_NUM;++i) { unsigned int mask = 1<<i; spin_lock_irqsave(&g_fh_lock, flags); //TODO: clock should be turned on only when FH is needed //Turn on all clock fh_set_field(REG_FHCTL_CLK_CON, mask, 1); //Release software-reset to reset fh_set_field(REG_FHCTL_RST_CON, mask, 0); fh_set_field(REG_FHCTL_RST_CON, mask, 1); g_fh_pll[i].setting_id = 0; fh_write32(g_reg_cfg[i], 0x00000000); //No SSC and FH enabled fh_write32(g_reg_updnlmt[i], 0x00000000); //clear all the settings fh_write32(g_reg_dds[i], 0x00000000); //clear all the settings spin_unlock_irqrestore(&g_fh_lock, flags); } g_initialize = 1; }
static void mt_fh_hal_popod_save(void) { const unsigned int pll_id = FH_MAIN_PLLID; FH_MSG_DEBUG("EN: %s",__func__); //disable maipll SSC mode if(g_fh_pll[pll_id].fh_status == FH_FH_ENABLE_SSC){ unsigned int fh_dds = 0; unsigned int pll_dds = 0; const unsigned int reg_cfg = g_reg_cfg[pll_id]; //only when SSC is enable, turn off MAINPLL hopping fh_set_field(reg_cfg, FH_FRDDSX_EN, 0); //disable SSC mode fh_set_field(reg_cfg, FH_SFSTRX_EN, 0); //disable dvfs mode fh_set_field(reg_cfg, FH_FHCTLX_EN, 0); //disable hopping control pll_dds = (DRV_Reg32(g_reg_dds[pll_id])) & MASK21b; fh_dds = (DRV_Reg32(g_reg_mon[pll_id])) & MASK21b; FH_MSG("Org pll_dds:%x fh_dds:%x",pll_dds,fh_dds); wait_dds_stable(pll_dds, g_reg_mon[pll_id], 100); //write back to ncpo fh_write32(g_reg_pll_con1[pll_id], (fh_read32(g_reg_dds[pll_id])&MASK21b)|(fh_read32(MAINPLL_CON1)&0xFFE00000)|(BIT32)); FH_MSG("MAINPLL_CON1: 0x%08x",(fh_read32(g_reg_pll_con1[pll_id])&MASK21b)); // switch to register control fh_switch2fhctl(pll_id,0); mb(); } }
/* caller: clk mgr */ static void mt_fh_hal_default_conf(void) { FH_MSG_DEBUG("%s", __func__); freqhopping_config(FH_ARM_PLLID, g_default_freq[FH_ARM_PLLID], true); freqhopping_config(FH_MAIN_PLLID, g_default_freq[FH_MAIN_PLLID], true); freqhopping_config(FH_MEM_PLLID, g_default_freq[FH_MEM_PLLID], true); /* freqhopping_config(FH_MM_PLLID, g_default_freq[FH_MM_PLLID], true); */ freqhopping_config(FH_VENC_PLLID, g_default_freq[FH_VENC_PLLID], true); freqhopping_config(FH_MSDC_PLLID, g_default_freq[FH_MSDC_PLLID], true); /* freqhopping_config(FH_TVD_PLLID, g_default_freq[FH_TVD_PLLID], true); */ }
//caller: clk mgr static void mt_fh_hal_default_conf(void) { FH_MSG_DEBUG("%s",__func__); #if 1 //freqhopping_config(FH_ARMCA7_PLLID, g_default_freq[FH_ARMCA7_PLLID], false); //freqhopping_config(FH_ARMCA15_PLLID, g_default_freq[FH_ARMCA15_PLLID], false); freqhopping_config(FH_MAIN_PLLID, g_default_freq[FH_MAIN_PLLID], true); freqhopping_config(FH_M_PLLID, g_default_freq[FH_M_PLLID], true); freqhopping_config(FH_MSDC_PLLID, g_default_freq[FH_MSDC_PLLID], true); //Turn off MMPLL SSC after CHIP_SW_VER_01 if (CHIP_SW_VER_01 <= mt_get_chip_sw_ver()) freqhopping_config(FH_MM_PLLID, g_default_freq[FH_MM_PLLID], true); //freqhopping_config(FH_VENC_PLLID, g_default_freq[FH_VENC_PLLID], true); //freqhopping_config(FH_TVD_PLLID, g_default_freq[FH_TVD_PLLID], true); //freqhopping_config(FH_VCODEC_PLLID, g_default_freq[FH_VCODEC_PLLID], true); #endif }
static void __disable_ssc(unsigned int pll_id,const struct freqhopping_ssc* ssc_setting) { unsigned long flags = 0; unsigned int reg_cfg = g_reg_cfg[pll_id]; FH_MSG_DEBUG("Calling %s", __func__); local_irq_save(flags); //Set the relative registers fh_set_field(reg_cfg,FH_FRDDSX_EN,0); fh_set_field(reg_cfg,FH_FHCTLX_EN,0); mb(); fh_switch2fhctl(pll_id, 0); g_fh_pll[pll_id].fh_status = FH_FH_DISABLE; local_irq_restore(flags); mb() ; return; }
static void __enable_ssc(unsigned int pll_id,const struct freqhopping_ssc* setting) { unsigned long flags = 0; const unsigned int reg_cfg = g_reg_cfg[pll_id]; const unsigned int reg_updnlmt = g_reg_updnlmt[pll_id]; const unsigned int reg_dds = g_reg_dds[pll_id]; FH_MSG_DEBUG("%s: %x~%x df:%d dt:%d dds:%x", __func__ , setting->lowbnd, setting->upbnd ,setting->df ,setting->dt ,setting->dds); mb(); g_fh_pll[pll_id].fh_status = FH_FH_ENABLE_SSC; local_irq_save(flags); //Set the relative parameter registers (dt/df/upbnd/downbnd) fh_set_field(reg_cfg, MASK_FRDDSX_DYS, setting->df); fh_set_field(reg_cfg, MASK_FRDDSX_DTS, setting->dt); fh_sync_ncpo_to_fhctl_dds(pll_id); //TODO: Not setting upper due to they are all 0? fh_write32(reg_updnlmt, (PERCENT_TO_DDSLMT((fh_read32(reg_dds)&MASK21b), setting->lowbnd) << 16)); //Switch to FHCTL fh_switch2fhctl(pll_id, 1); mb(); //Enable SSC fh_set_field(reg_cfg, FH_FRDDSX_EN, 1); //Enable Hopping control fh_set_field(reg_cfg, FH_FHCTLX_EN, 1); local_irq_restore(flags); return; }
static void mt_fh_hal_popod_restore(void) { const unsigned int pll_id = FH_MAIN_PLLID; FH_MSG_DEBUG("EN: %s",__func__); //enable maipll SSC mode if(g_fh_pll[pll_id].fh_status == FH_FH_ENABLE_SSC){ const struct freqhopping_ssc* p_setting = &ssc_mainpll_setting[2]; const unsigned int reg_cfg = g_reg_cfg[pll_id]; fh_set_field(reg_cfg, FH_FRDDSX_EN, 0); //disable SSC mode fh_set_field(reg_cfg, FH_SFSTRX_EN, 0); //disable dvfs mode fh_set_field(reg_cfg, FH_FHCTLX_EN, 0); //disable hopping control fh_sync_ncpo_to_fhctl_dds(pll_id); FH_MSG("Enable mainpll SSC mode"); FH_MSG("sync ncpo to DDS of FHCTL"); FH_MSG("FHCTL1_DDS: 0x%08x", (fh_read32(g_reg_dds[pll_id])&MASK21b)); fh_set_field(reg_cfg, MASK_FRDDSX_DYS, p_setting->df); fh_set_field(reg_cfg, MASK_FRDDSX_DTS, p_setting->dt); fh_write32(g_reg_updnlmt[pll_id], (PERCENT_TO_DDSLMT((fh_read32(g_reg_dds[pll_id])&MASK21b), p_setting->lowbnd) << 16)); FH_MSG("REG_FHCTL2_UPDNLMT: 0x%08x", fh_read32(g_reg_updnlmt[pll_id])); fh_switch2fhctl(pll_id,1); fh_set_field(reg_cfg, FH_FRDDSX_EN, 1); //enable SSC mode fh_set_field(reg_cfg, FH_FHCTLX_EN, 1); //enable hopping control FH_MSG("REG_FHCTL2_CFG: 0x%08x", fh_read32(reg_cfg)); } }
int mt_fh_hal_dfs_vcodecpll(unsigned int target_dds) { unsigned long flags = 0; //unsigned int target_dds = 0; const unsigned int pll_id = FH_VCODEC_PLLID; const unsigned int reg_cfg = g_reg_cfg[pll_id]; FH_MSG_DEBUG("%s current dds(VCODECPLL_CON1): 0x%x",__func__, (fh_read32(g_reg_pll_con1[pll_id])&MASK21b)); //TODO: provelock issue spin_lock(&g_fh_lock); spin_lock_irqsave(&g_fh_lock, flags); if (g_fh_pll[pll_id].fh_status == FH_FH_ENABLE_SSC){ unsigned int fh_dds = 0; unsigned int pll_dds = 0; fh_set_field(reg_cfg, FH_FRDDSX_EN, 0); //disable SSC mode fh_set_field(reg_cfg, FH_SFSTRX_EN, 0); //disable dvfs mode fh_set_field(reg_cfg, FH_FHCTLX_EN, 0); //disable hopping control pll_dds = (DRV_Reg32(g_reg_dds[pll_id])) & MASK21b; fh_dds = (DRV_Reg32(g_reg_mon[pll_id])) & MASK21b; FH_MSG(">p:f< %x:%x",pll_dds,fh_dds); wait_dds_stable(pll_dds, g_reg_mon[pll_id], 100); } FH_MSG("target dds: 0x%x",target_dds); mt_fh_hal_dvfs(pll_id, target_dds); if(g_fh_pll[pll_id].fh_status == FH_FH_ENABLE_SSC){ const struct freqhopping_ssc* p_setting = &ssc_vencpll_setting[2]; fh_set_field(reg_cfg, FH_FRDDSX_EN, 0); //disable SSC mode fh_set_field(reg_cfg, FH_SFSTRX_EN, 0); //disable dvfs mode fh_set_field(reg_cfg, FH_FHCTLX_EN, 0); //disable hopping control fh_sync_ncpo_to_fhctl_dds(pll_id); FH_MSG("Enable vcodecpll SSC mode"); FH_MSG("DDS: 0x%08x", (fh_read32(g_reg_dds[pll_id])&MASK21b)); fh_set_field(reg_cfg, MASK_FRDDSX_DYS, p_setting->df); fh_set_field(reg_cfg, MASK_FRDDSX_DTS, p_setting->dt); fh_write32(g_reg_updnlmt[pll_id], (PERCENT_TO_DDSLMT((fh_read32(g_reg_dds[pll_id])&MASK21b), p_setting->lowbnd)<< 16)); FH_MSG("UPDNLMT: 0x%08x", fh_read32(g_reg_updnlmt[pll_id])); fh_switch2fhctl(pll_id, 1); fh_set_field(reg_cfg, FH_FRDDSX_EN, 1); //enable SSC mode fh_set_field(reg_cfg, FH_FHCTLX_EN, 1); //enable hopping control FH_MSG("CFG: 0x%08x", fh_read32(reg_cfg)); } spin_unlock_irqrestore(&g_fh_lock, flags); return 0; }