bugfix: 待机休眠arm电压保持在1.2v(希望降到1v)

platform: rk3026 MID

pmu: axp192

system: android4.2


日前碰到机器休眠arm电压偏高的问题。自己找问题,找啊找,就是找不到,一直改那个arm电压表,没用,因为那个表是机器运行时的arm动态电压调整。

当机器休眠时的arm电压是另外设置的,不在这个表格内。

baord-rk3026-86v.c文件中的arm电压表如下:

/***********************************************************
*	clock
************************************************************/
static struct cpufreq_frequency_table dvfs_arm_table[] = {
	{.frequency = 312 * 1000,       .index = 950 * 1000},
	{.frequency = 504 * 1000,       .index = 1200 * 1000},
	{.frequency = 816 * 1000,       .index = 1275 * 1000},
	{.frequency = 912 * 1000,       .index = 1350 * 1000},
	{.frequency = 1008 * 1000,      .index = 1400 * 1000},

	{.frequency = CPUFREQ_TABLE_END},
};
用工具测量arm电压,确实会随着cpu的频率而动态变化。但是机器休眠的时候cpu是不工作的,频率大概是24M,所以arm电压设置就不在这个表格内了。(这个表格在哪里被调用以后在更新to be continued).

arm电压是由axp192的dcdc2来输出实现动态调压。原理图如下:

bugfix: 待机休眠arm电压保持在1.2v(希望降到1v)_第1张图片


根据这个思路,arm休眠电压必须去pmu的代码里面设置。机器休眠的时候,pmu也是跟着休眠,所以最后设置arm电压的任务就落在了suspend函数。 

上面完全错了,设置arm休眠电压不是在axp的suspend函数里面,而是在i2c的suspend函数里面。不过这个i2c和一般的i2c又有区别,等有时间仔细研究(to be continued).

在kernel/arm/arch/mach-rk2928/i2c_sram.c文件中,suspend函数首先将arm电压保存在arm_voltage中了,然后将arm电压设置为1v。在resume函数中,将arm电压设置为休眠前的arm_voltage电压:

void __sramfunc rk30_suspend_voltage_set(unsigned int vol)
{
    uint8 slaveaddr;
    uint8 slavereg;
    uint8 data,ret = 0;
	uint8 rtc_status_reg = 0x11;
	sram_i2c_init();  //init i2c device
    	#if defined(CONFIG_MFD_TPS65910)	
	if(pmic_is_tps65910())
	{
		slaveaddr = 0x2d;            //slave device addr
		slavereg = 0x22;            // reg addr
		data = 0x1C;       //set arm 1.0v

		ret = sram_i2c_read(slaveaddr, rtc_status_reg);
		sram_i2c_write(slaveaddr, rtc_status_reg, ret);
		arm_voltage = sram_i2c_read(slaveaddr, slavereg);
#if defined ( CONFIG_ARCH_RK3026)
		logic_voltage = sram_i2c_read(slaveaddr, 0x25);
		sram_i2c_write(slaveaddr, 0x25, data);//
#endif
		//sram_printhex(ret);
		sram_i2c_write(slaveaddr, slavereg, data);//	
	}
	#endif
	
	#if defined(CONFIG_REGULATOR_ACT8931)	
	if(pmic_is_act8931())
	{
		slaveaddr = 0x5b;            //slave device addr
		slavereg = 0x40;            // reg addr
		data = 0x10;       //set arm 1.0v

		arm_voltage = sram_i2c_read(slaveaddr, slavereg);
		
		//sram_printhex(ret);
		sram_i2c_write(slaveaddr, slavereg, data);//	
		sram_i2c_write(slaveaddr,( slavereg+0x1), data);//	
	}
	#endif
	
    #if defined(CONFIG_KP_AXP19)      
               slaveaddr = 0x34;            //slave device addr
               slavereg = 0x23;            // reg addr
              data = 0x0a;       //set arm 1.0v // 0.7v + data*0.025v

            //  ret = sram_i2c_read(slaveaddr, rtc_status_reg);
            //   sram_i2c_write(slaveaddr, rtc_status_reg, ret);
               arm_voltage = sram_i2c_read(slaveaddr, slavereg);//保存休眠前arm电压值
               //sram_printhex(ret);
              sram_i2c_write(slaveaddr, slavereg, data);//   
       #endif

	  sram_i2c_deinit();  //deinit i2c device

}

void __sramfunc rk30_suspend_voltage_resume(unsigned int vol)
{
	uint8 slaveaddr;
	uint8 slavereg;
	uint8 data,ret = 0;
#if defined ( CONFIG_ARCH_RK3026)
	uint8 data2;
	data2 = logic_voltage;
#endif

	data = arm_voltage;
	sram_i2c_init();  //init i2c device
	#if defined(CONFIG_MFD_TPS65910)	
	if(pmic_is_tps65910())
	{
		slaveaddr = 0x2d;            //slave device addr
		slavereg = 0x22;            // reg add
		sram_i2c_write(slaveaddr, slavereg, data);
		sram_udelay(20000);
#if defined ( CONFIG_ARCH_RK3026)
		sram_i2c_write(slaveaddr, 0x25, data2);
		sram_udelay(20000);
#endif
	}
	#endif
	#if defined(CONFIG_REGULATOR_ACT8931)	
	if(pmic_is_act8931())
	{
		slaveaddr = 0x5b;            //slave device addr
		slavereg = 0x40;            // reg addr
		sram_i2c_write(slaveaddr, slavereg, data);
		sram_i2c_write(slaveaddr, (slavereg+0x1), data);
		sram_udelay(20000);
	}
	#endif
#if defined(CONFIG_KP_AXP19)   
               slaveaddr = 0x34;            //slave device addr
               slavereg = 0x23;            // reg add
               sram_i2c_write(slaveaddr, slavereg, data);//写入休眠前arm电压值
               sram_udelay(20000);
       #endif

    sram_i2c_deinit();  //deinit i2c device
}



你可能感兴趣的:(BUGLIST,RK)