示例#1
0
static void fh_switch2fhctl(enum FH_PLL_ID pll_id, int i_control)
{
    unsigned int mask = 0;

    VALIDATE_PLLID(pll_id);

    mask = 0x1U<<pll_id;

    //FIXME: clock should be turned on/off at entry functions
    // Turn on clock
    //if (i_control == 1)
        //fh_set_field(REG_FHCTL_CLK_CON, mask, i_control);

    // Release software reset
    //fh_set_field(REG_FHCTL_RST_CON, mask, 0);

    // Switch to FHCTL_CORE controller
    fh_set_field(REG_FHCTL_HP_EN, mask, i_control);

    //Turn off clock
    //if (i_control == 0)
        //fh_set_field(REG_FHCTL_CLK_CON, mask, i_control);

    return;
}
示例#2
0
static void fh_sync_ncpo_to_fhctl_dds(enum FH_PLL_ID pll_id)
{
    unsigned int reg_src = 0;
    unsigned int reg_dst = 0;

    VALIDATE_PLLID(pll_id);

    reg_src = g_reg_pll_con1[pll_id];
    reg_dst = g_reg_dds[pll_id];
    fh_write32(reg_dst, (fh_read32(reg_src)&MASK21b)|BIT32);

    return;
}
static void fh_sync_ncpo_to_fhctl_dds(enum FH_PLL_ID pll_id)
{
	unsigned long reg_src = 0;
	unsigned long reg_dst = 0;

	VALIDATE_PLLID(pll_id);

	reg_src = g_reg_pll_con1[pll_id];
	reg_dst = g_reg_dds[pll_id];

	if (pll_id == FH_MEM_PLLID) {
		/* MEMPLL_CON1 field mapping. Integer: [31:25] =>
		   FHCTL_DDS[20:14] ; Fraction: [24:1] => FHCTL_DDS[13:0] */
		fh_write32(reg_dst, (((fh_read32(reg_src) & 0xFFFFFFFE) >> 11) & MASK21b) | BIT32);
	} else {
示例#4
0
static int mt_fh_hal_dvfs(enum FH_PLL_ID pll_id, unsigned int dds_value)
{
	unsigned long 	flags = 0;

	FH_MSG("%s for pll %d:",__func__, pll_id);

	VALIDATE_PLLID(pll_id);

	local_irq_save(flags);

	//1. sync ncpo to DDS of FHCTL
	fh_sync_ncpo_to_fhctl_dds(pll_id);

	//FH_MSG("1. sync ncpo to DDS of FHCTL");
	FH_MSG("FHCTL%d_DDS: 0x%08x", pll_id,
	    (fh_read32(g_reg_dds[pll_id])&MASK21b));

	//2. enable DVFS and Hopping control
	{
	    unsigned int reg_cfg = g_reg_cfg[pll_id];

    	fh_set_field(reg_cfg, FH_SFSTRX_EN, 1);  //enable dvfs mode
        fh_set_field(reg_cfg, FH_FHCTLX_EN, 1);  //enable hopping control
    }

    //for slope setting.
    //TODO: Does this need to be changed?
    fh_write32(REG_FHCTL_SLOPE0, 0x6003c97);

    //FH_MSG("2. enable DVFS and Hopping control");

	//3. switch to hopping control
	fh_switch2fhctl(pll_id, 1);
	mb();

	//FH_MSG("3. switch to hopping control");

	//4. set DFS DDS
	{
	    unsigned int dvfs_req = g_reg_dvfs[pll_id];
	    fh_write32(dvfs_req, (dds_value)|(BIT32));  //set dds

		//FH_MSG("4. set DFS DDS");
		FH_MSG("FHCTL%d_DDS: 0x%08x", pll_id, (fh_read32(dvfs_req)&MASK21b));
		FH_MSG("FHCTL%d_DVFS: 0x%08x", pll_id, (fh_read32(dvfs_req)&MASK21b));
	}

	//4.1 ensure jump to target DDS
	wait_dds_stable(dds_value, g_reg_mon[pll_id], 100);
	//FH_MSG("4.1 ensure jump to target DDS");

	//5. write back to ncpo
	//FH_MSG("5. write back to ncpo");
    {
        unsigned int reg_dvfs = 0;
        unsigned int reg_pll_con1 = 0;

        reg_pll_con1 = g_reg_pll_con1[pll_id];
        reg_dvfs = g_reg_dvfs[pll_id];
        FH_MSG("PLL_CON1: 0x%08x",(fh_read32(reg_pll_con1)&MASK21b));

    	fh_write32(reg_pll_con1,
    	    (fh_read32(g_reg_mon[pll_id])&MASK21b)
    	    |(fh_read32(reg_pll_con1)&0xFFE00000)|(BIT32));
		FH_MSG("PLL_CON1: 0x%08x",(fh_read32(reg_pll_con1)&MASK21b));
	}

	//6. switch to register control
	fh_switch2fhctl(pll_id, 0);
	mb();

	//FH_MSG("6. switch to register control");

	local_irq_restore(flags);
	return 0;
}
示例#5
0
static int __freqhopping_ctrl(struct freqhopping_ioctl* fh_ctl,bool enable)
{
	const struct freqhopping_ssc* pSSC_setting = NULL;
	unsigned int    ssc_setting_id = 0;
	int retVal = 1;
	fh_pll_t* pfh_pll = NULL;

	FH_MSG("%s for pll %d", __func__, fh_ctl->pll_id);

	//Check the out of range of frequency hopping PLL ID
	VALIDATE_PLLID(fh_ctl->pll_id);

	pfh_pll = &g_fh_pll[fh_ctl->pll_id];

    pfh_pll->curr_freq = g_default_freq[fh_ctl->pll_id];

	if((enable == true) && (pfh_pll->fh_status == FH_FH_ENABLE_SSC)){
		__disable_ssc(fh_ctl->pll_id,pSSC_setting);
	}
	else if((enable == false) && (pfh_pll->fh_status == FH_FH_DISABLE)){
		retVal = 0;
		goto Exit;
	}

    //enable freq. hopping @ fh_ctl->pll_id
	if( enable == true) {
		if(pfh_pll->pll_status == FH_PLL_DISABLE) {
			pfh_pll->fh_status = FH_FH_ENABLE_SSC;
			retVal = 0;
			goto Exit;
		}
		else {
			if(pfh_pll->user_defined == true){
				FH_MSG("Apply user defined setting");

				pSSC_setting = &mt_ssc_fhpll_userdefined[fh_ctl->pll_id];
				pfh_pll->setting_id = USER_DEFINE_SETTING_ID;
			}
			else {
				if( pfh_pll->curr_freq != 0 ){
					ssc_setting_id = pfh_pll->setting_id =
					    __freq_to_index(fh_ctl->pll_id, pfh_pll->curr_freq);
				}
				else{
					ssc_setting_id = 0;
				}

				if(ssc_setting_id == 0){
					FH_MSG("!!! No corresponding setting found !!!");

					//just disable FH & exit
					__disable_ssc(fh_ctl->pll_id,pSSC_setting);
					goto Exit;
				}

                pSSC_setting = &g_ssc_setting[fh_ctl->pll_id][ssc_setting_id];
			}//user defined

			if(pSSC_setting == NULL){
				FH_MSG("SSC_setting is NULL!");

				//disable FH & exit
				__disable_ssc(fh_ctl->pll_id, pSSC_setting);
				goto Exit;
			}

			__enable_ssc(fh_ctl->pll_id, pSSC_setting);
			retVal = 0;
		}
	}
	else{ //disable req. hopping @ fh_ctl->pll_id
		__disable_ssc(fh_ctl->pll_id, pSSC_setting);
		retVal = 0;
	}

Exit:
	return retVal;
}
示例#6
0
static int fh_dvfs_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
{
    unsigned int	p1,p2,p3,p4,p5;

    p1 = p2 = p3 = p4 = p5 = 0;

    FH_MSG("EN: %s",__func__);

    if (count == 0)
        return -1;

    FH_MSG("EN: p1=%d p2=%d p3=%d", p1, p2, p3);

    switch(p1){
    case FH_ARMCA7_PLLID:
        mt_fh_hal_dfs_armpll(p2, p3);
        FH_MSG("ARMCA7PLL DVFS completed\n");
        break;
    case FH_ARMCA15_PLLID:
        mt_fh_hal_dfs_armpll(p2, p3);
        FH_MSG("ARMCA15PLL DVFS completed\n");
        break;
    case FH_MM_PLLID:
        mt_fh_hal_dfs_mmpll(p3);
        FH_MSG("MMPLL DVFS completed\n");
        break;
    case FH_VENC_PLLID:
        mt_fh_hal_dfs_vencpll(p3);
        FH_MSG("VENCPLL DVFS completed\n");
        break;
    case 4370:
        {
            unsigned int reg_cfg = 0;

            VALIDATE_PLLID(p2);

            reg_cfg = g_reg_cfg[p2];

             //TODO: Find out who use this case
            FH_MSG("pllid=%d dt=%d df=%d lowbnd=%d", p2, p3, p4, p5);
            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(p2);

            FH_MSG("Enable FHCTL%d SSC mode", p2);
            FH_MSG("DDS: 0x%08x", (fh_read32(reg_cfg)&MASK21b));

            fh_set_field(reg_cfg, MASK_FRDDSX_DYS, p4);
            fh_set_field(reg_cfg, MASK_FRDDSX_DTS, p3);

            fh_write32(g_reg_updnlmt[p2], (PERCENT_TO_DDSLMT((fh_read32(reg_cfg)&MASK21b),p5) << 16));
            FH_MSG("UPDNLMT: 0x%08x", fh_read32(g_reg_updnlmt[p2]));

            fh_switch2fhctl(p2, 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));
        }
        break;
    case 2222:
    //TODO: and what this case for?
    if (p2==0) //disable
        mt_fh_hal_popod_save();
    else if (p2==1) //enable
        mt_fh_hal_popod_restore();
        break;
    default:
        mt_fh_hal_dvfs(p1, p2);
        break;
    };

    return count;
}