Hi all,
I am working on MX53 power consumption based on android bsp 10.3. I would like to use DVFS to minimize the power consumption in idle state.
I am not sure how the GPC works with DVFS. Please correct me if I am wrong.
From my understanding, GPC takes the lead of the flow. Once an GPC interrupt is triggered (I don't know who trigger the interrupt and how.), dvfs_irq(...) is called and then it schedules a delayed routine call dvs_core_work_handler(...). The delayed routine would tune up/down the core frequency based on the setpoint provided.
However, following the code, I have enabled GPC interrupt and DVFS. But no GPC interrupt is triggered after the kernel start.
Here is the result of "sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state"
cat time_in_state
400000 0
800000 0
1000000 95956
The system kept running at 1GHz.
What should I do if I want the cpu runs at 400MHz in idle mode?
Regards,
CPKwok
Can anyone help?
Hello,Left,
Let me assume your project's name is mx53_pad. then please refer to the following code or advice.
(1) in bsp file , the following steps should be done.
.....
#define TZIC_WAKEUP0_OFFSET (0x0E00)
#define TZIC_WAKEUP1_OFFSET (0x0E04)
#define TZIC_WAKEUP2_OFFSET (0x0E08)
#define TZIC_WAKEUP3_OFFSET (0x0E0C)
#define GPIO1_8_18_IRQ_BIT (0x1<<18)
//Setting wakeup resource
static void pad_tzic_irq_wakeup(void)
{
void __iomem *tzic_base;
tzic_base = ioremap(MX53_TZIC_BASE_ADDR, SZ_4K);
if (NULL == tzic_base) {
pr_err("fail to map MX53_TZIC_BASE_ADDR\n");
return;
}
__raw_writel(0, tzic_base + TZIC_WAKEUP0_OFFSET);
__raw_writel(0, tzic_base + TZIC_WAKEUP2_OFFSET);
__raw_writel(0, tzic_base + TZIC_WAKEUP3_OFFSET);
__raw_writel(GPIO1_8_18_IRQ_BIT, tzic_base + TZIC_WAKEUP1_OFFSET);
iounmap(tzic_base);
pr_info("TZIC irq is wakeup-enabled\n");
}
static void pad_suspend_enter(void)
{
pad_tzic_irq_wakeup();
}
static void pad_suspend_exit(void)
{
printk(KERN_INFO "GPIO1_8 irq is to wakeup system\n");
}
static struct mxc_pm_platform_data pad_pm_data = {
.suspend_enter = pad_suspend_enter,
.suspend_exit = pad_suspend_exit,
};
//if you are using mc34708,dvfs setting is :
static struct mxc_dvfs_platform_data dvfs_core_data = {
.reg_id = "SW1A",
.clk1_id = "cpu_clk",
.clk2_id = "gpc_dvfs_clk",
.gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
.gpc_vcr_offset = MXC_GPC_VCR_OFFSET,
.ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
.ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
.ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
.prediv_mask = 0x1F800,
.prediv_offset = 11,
.prediv_val = 3,
.div3ck_mask = 0xE0000000,
.div3ck_offset = 29,
.div3ck_val = 2,
.emac_val = 0x08,
.upthr_val = 25,
.dnthr_val = 9,
.pncthr_val = 33,
.upcnt_val = 10,
.dncnt_val = 10,
.delay_time = 30,
};
static struct mxc_bus_freq_platform_data bus_freq_data = {
.gp_reg_id = "SW1A",
.lp_reg_id = "SW2",
};
//in board_init founction , Registering pm device / initializing PMIC(mc34708)
mxc_register_device(&pm_device, &pad_pm_data);
.....
//don't forget initialize i.mx53 base address of i2c connected to PMIC
pm_i2c_init(I2C1_BASE_ADDR - MX53_OFFSET);
(2)pm device driver.
See linux/arch/arm/mach-mx5/pm.c
(3)dvfs device driver
See linux/arch/arm/plat-mxc/dvfs_core.c
Regards,
Weidong
Thanks Sun,
We are using PMIC DA9053, and are still working on the idle state current consumption on Android system.
I believe our platform is DVFSC functioning, we measured the change current change of VDDGP. At Idle state, VDDGP is only 2mA. At operating state, VDDGP can be over 400mA. However there is a few question about reducing the power consumption.
1. the current of VCC_1V3 is 116mA at idle state and 200mA at operating state. Can the current of VCC_1V3 be reduced?
2. In the file MX53_wp.c, I believe the following structure are related to DVFSC
static struct dvfs_wp dvfs_core_setpoint_ces[] = {
{33, 25, 33, 10, 10, 0x08}, /*1GHz*/
{30, 18, 33, 20, 10, 0x08}, /* 800MHz */
{25, 8, 33, 20, 10, 0x08}, /* 400MHz */
{28, 8, 33, 20, 30, 0x08}, /* 400MHz, 133MHz */
{29, 0, 33, 20, 10, 0x08},}; /* 400MHz, 50MHz. */
and
static struct cpu_wp cpu_wp_ces[] = {
{
.pll_rate = 1000000000,
.cpu_rate = 1000000000,
.pdf = 0,
.mfi = 10,
.mfd = 11,
.mfn = 5,
.cpu_podf = 0,
.cpu_voltage = 1250000,},
{
.pll_rate = 800000000,
.cpu_rate = 800000000,
.pdf = 0,
.mfi = 8,
.mfd = 2,
.mfn = 1,
.cpu_podf = 0,
.cpu_voltage = 1100000,},
{
.pll_rate = 800000000,
.cpu_rate = 400000000,
.pdf = 0,
.mfi = 8,
.mfd = 2,
.mfn = 1,
.cpu_podf = 1,
.cpu_voltage = 950000,},
};
I am not sure what is the usage of this two structures.
cpu_wp_ces changes the PLL setting, when and how the setting be used?
dvfs_core_setpoint_ces changes the DVFSC threshold setting, how does the setting be used?
Hello,Left
mx53_loco.c has been initilized DVFS and GPC, you can check pm device driver and dvfs driver , duiring linux booting, they should be loaded successfuly.
Regards,
Weidong
Thanks Weidong,
Yes, "mxc_dvfs_core" and "mx5_pm" are working on our platform. And we can observe the difference of power consumption between operating and idle state. But the power consumption in idle state is still too high(it is overall 180mA now) to our requirement. We need to further reduce the power consumption in idle state. As we notice that the VCC_1V3 still takes a large current(116mA) at idle state, we are suspecting if there is any method to minimize the consumption....
Hello,Left,
You can try to modify above code(add a new work point for CPU in mx53_wp.c) to make CPU work at lower frequency when system enters suspend. such as 160MHz or 200MHz.
My customer has ever set i.mx538 work at 160MHz , and system can normally work. I didn't validate it by myself, Since standby current is a little big, I suggest you should try this methord.
Regards,
Weidong
Thanks Weidong,
Yes, I have modified the working point as follow, from 400 MHz to 200 MHz at idle state.
static struct cpu_wp cpu_wp_ces[] = {
{
.pll_rate = 1000000000,
.cpu_rate = 1000000000,
.pdf = 0,
.mfi = 10,
.mfd = 11,
.mfn = 5,
.cpu_podf = 0,
.cpu_voltage = 1250000,},
{
.pll_rate = 400000000,
.cpu_rate = 200000000,
.pdf = 0,
.mfi = 4,
.mfd = 5,
.mfn = 1,
.cpu_podf = 1,
.cpu_voltage = 1000000,},
{
.pll_rate = 400000000,
.cpu_rate = 200000000,
.pdf = 0,
.mfi = 4,
.mfd = 5,
.mfn = 1,
.cpu_podf = 1,
.cpu_voltage = 1000000,},
};
But the current consumption doesn't change so much. Do you know how to modified to setpoint dvfs_core_setpoint_ces if I want to change it to 200MHz? I don't know how do these DVFSC threshold value work.
static struct dvfs_wp dvfs_core_setpoint_ces[] = {
{33, 25, 33, 10, 10, 0x08}, /*1GHz*/
{30, 18, 33, 20, 10, 0x08}, /* 800MHz */
{25, 8, 33, 20, 10, 0x08}, /* 400MHz */
{28, 8, 33, 20, 30, 0x08}, /* 400MHz, 133MHz */
{29, 0, 33, 20, 10, 0x08},}; /* 400MHz, 50MHz. */
Weidong, can you answer Left's latest question - Do you know how to modified to setpoint dvfs_core_setpoint_ces if I want to change it to 200MHz?
Thanks
Hello,Left,
I tested original BSP source code on android platform yesterday night, Only when system enters into SLEEP mode, CPU frequency is changed to 400MHz. If I waked up the board, CPU frequency will restore 1GHz(I used max frequency 1 GHz ).
Did you do this step on your board ?
weidong
Left, have you tried this?
Thanks Weidong and Grant,
We have done this already. But your latest reply has confused me. Weidong said "Only when system enters into SLEEP mode, CPU frequency is changed to 400MHz." Does this mean that the system is still running in 1GHz when it is in idle state. (Not sleep)
Hello,Left,
Accroding to GPC/DVFS function, CPU should also work at 400MHz when it is in idle state. But I tested it switch between normal work and sleep.
I have added some messages in code, so I observed CPU's working state.
Weidong
Hi Weidong,
So, do u mean that you traced that the system still running 1GHZ in Idle state?
I can see the current consumption difference in idle state and running state.
Hello, Left,
Did you resolve your problem ?
Regards,
Weidong