Example #1
0
static int mt_fh_hal_dfs_mpll(unsigned int target_dds)
{
	unsigned long 	flags = 0;
	const unsigned int  pll_id  = FH_M_PLLID;
	const unsigned int  reg_cfg = g_reg_cfg[pll_id];

	FH_MSG("%s, current dds(MPLL_CON1): 0x%x, target dds %d",
	    __func__,(fh_read32(g_reg_pll_con1[pll_id])&MASK21b),
	    target_dds);

	spin_lock_irqsave(&g_fh_lock, flags);

	if(g_fh_pll[pll_id].fh_status == FH_FH_ENABLE_SSC){
        unsigned int	pll_dds = 0;
        unsigned int	fh_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);
	}

	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_mpll_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 mpll 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;
}
Example #2
0
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();
	}
}
Example #3
0
//armpll dfs mdoe
static int mt_fh_hal_dfs_armpll(unsigned int pll, unsigned int dds)
{
	unsigned long 	flags = 0;
	unsigned int    reg_cfg = 0;

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

	switch(pll){
	case FH_ARMCA7_PLLID:
    case FH_ARMCA15_PLLID:
        reg_cfg = g_reg_cfg[pll];
        FH_MSG("(PLL_CON1): 0x%x",(fh_read32(g_reg_pll_con1[pll])&MASK21b));
        break;
    default:
        BUG_ON(1);
        return 1;
    };

	//TODO: provelock issue spin_lock(&g_fh_lock);
	spin_lock_irqsave(&g_fh_lock, flags);

	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

	mt_fh_hal_dvfs(pll, dds);

	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

	spin_unlock_irqrestore(&g_fh_lock, flags);

	return 0;
}
Example #4
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;
}
Example #5
0
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));
	}
}
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 {
Example #7
0
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;
}
Example #8
0
static int mt_fh_hal_dfs_mmpll(unsigned int target_freq)  //mmpll dfs mode
{
	unsigned long 	flags = 0;
	unsigned int	target_dds = 0;
	const unsigned int  pll_id  = FH_MM_PLLID;
	const unsigned int  reg_cfg = g_reg_cfg[pll_id];

	FH_MSG("%s, current dds(MMPLL_CON1): 0x%x, target freq %d",
	    __func__,(fh_read32(g_reg_pll_con1[pll_id])&MASK21b),
	    target_freq);

	spin_lock_irqsave(&g_fh_lock, flags);

	if(g_fh_pll[pll_id].fh_status == FH_FH_ENABLE_SSC){
        unsigned int	pll_dds = 0;
        unsigned int	fh_dds  = 0;

        //only when SSC is enable, turn off MEMPLL 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(">p:f< %x:%x",pll_dds,fh_dds);

        wait_dds_stable(pll_dds, g_reg_mon[pll_id], 100);
	}

    #if 1
    //target_dds = (target_freq/26000) * pow(2, 14);
    //target_dds = (unsigned int)(((double)(target_freq)/26000.0) * 16384.0);
    //target_dds = target_freq * 16384 / 26000;
    //target_dds = (target_freq / 1000) * 16384 / 26;
    target_dds = (target_freq / 1000) * 8192 / 13;
    #else
	switch(target_freq){
	    case MMPLL_TARGET1_VCO:
		    target_dds = MMPLL_TARGET1_DDS;
		    break;
	    case MMPLL_TARGET2_VCO:
		    target_dds = MMPLL_TARGET2_DDS;
		    break;
        case MMPLL_TARGET3_VCO:
		    target_dds = MMPLL_TARGET3_DDS;
		    break;
	    case MMPLL_TARGET4_VCO:
		    target_dds = MMPLL_TARGET4_DDS;
		    break;
	    case MMPLL_TARGET5_VCO:
		    target_dds = MMPLL_TARGET5_DDS;
		    break;
	    case MMPLL_TARGET6_VCO:
		    target_dds = MMPLL_TARGET6_DDS;
		    break;
    	default:
    		FH_BUG_ON("incorrect target_freq");
    		break;
	};
	#endif
	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_mmpll_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 mmpll 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;
}
Example #9
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;
}
Example #10
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;
}