by Yuan Zhao
This document is intended to introduce debug tips about i.MX power management based on i.MX Android software. The following topics are involved in this document:
- How to debug suspend/resume issues
- How to do power optimization
How to debug suspend/resume issues
- General method: Capture more PM debug message
- Enable PM debug system to get more info about PM in kernel and debug interface
Power management options --->
[*] Power Management Debug Support
[*] Extra PM attributes in sysfs for low-level debugging/testing
- Enable wakelock debug_mask to capture more message about wakelock
root@android:/ # echo 15 > /sys/module/wakelock/parameters/debug_mask
root@android:/ # echo 15 > /sys/module/userwakelock/parameters/debug_mask
- Enable earlysuspend debug_mask to capture more message about early suspend and late resume.
root@sabresd_6dq:/ # echo 15 > /sys/module/earlysuspend/parameters/debug_mask
- Add no_console_suspend=1 to the boot option for kernel
This makes the system print more useful info before entry in suspend
-BOARD_KERNEL_CMDLINE := console=ttymxc0,115200 init=/init video=mxcfb0:dev=ldb,bpp=32 video=mxcfb1:off video=mxcfb2:off fbmem=10M fb0base=0x27b00000 vmalloc=400M androidboot.console=ttymxc0 androidboot.hardware=freescale
+BOARD_KERNEL_CMDLINE := console=ttymxc0,115200 init=/init video=mxcfb0:dev=ldb,bpp=32 video=mxcfb1:off video=mxcfb2:off fbmem=10M fb0base=0x27b00000 vmalloc=400M androidboot.console=ttymxc0 androidboot.hardware=freescale no_console_suspend=1
- System cannot enter suspend mode
- Check below setting items have been disabled:
§ Whether the usb cable has been removed(usb gadget will hold a wake lock)
§ Setting->Display->Sleep, check whether the inactivity timeout period setting is longer than your expected time.
§ Setting->System->Developer options->stay awake(stay awake not be set), check whether the option is disabled
- Check if all wake locks have been released(You can see which wake lock is held, and then debug into the specific module):
root@sabresd_6dq:/ # cat /sys/power/wake_lock
- System could not resume from suspend/System crash when resume or suspend
- Check the PMIC_STBY_REQ signal.
System use PMIC_STBY_REQ signal to notify power management IC to change voltage from standby voltage to functional voltage and vice versa. In general, pmic_stby_req pin is connected to pmic standby pin. So measure the pin to check whether the de-assert signal is triggered.
If the signal is not triggered, we may consider whether wake-up sources are correctly setup. If the signal is triggered, we may double-check whether the pmic supply power normally.
And not limited to the two points, we should also double-check everything we doubt according to the system log and hardware measured waves.
- Using Trace32 or ICE to locate the problem.
Please view trace32 website to get more details.
- Track from mx6_suspend_enter in arch/arm/mach-mx6 .
Track "state" value and try to map to different the low power mode via function mxc_cpu_lp_set.
Check "mx6_suspend.S" which conduct the detailed operations in suspend:
- "MEM" is mapped to "dormant" mode. So goto "dormant" symbol and try to dump different operations to narrow down suspend/resume failure
- If this failure maybe related to DDR operation, try to dummy DDR IO relative low power operation.
- Using ram console to dump kernel log after reboot.
Ram console will keep one kernel log copy into one certain memory space. You can use the following command to check last time kernel log, if memory power was not cut off during the reboot process.
Eg(if it is the first time boot, you cannot find the /proc/last_kmsg file):
root@sabresd_6dq:/ # cat /proc/last_kmsg
- Kernel resume back from suspend but android not
- This is usually introduced by the wrong key layout file
Use getevent/sendevent tool to get power key scan code
Correct the Keylayout file
Correct the scandcode with your power key report value to Match the POWE key
- Suspend/Resume consume too much time:
We can print the specific module name and time consume details, if the module's suspend/resume time consume more than the threshold parameter by read/write /sys/power/device_suspend_time_threshold file. By default, the parameter is setup to 0, via disabled the function. We can enable it by the following command:
root@android:/ # echo 10 > /sys/power/device_suspend_time_threshold
This command means that if the module's suspend/resume time consume more than 10 us, the system will print the module's detail out. If you want to know the more details how to implement it on kernel, please check kernel/power/main.c
Can use the shell command to enter different system level low power modes for debug (For more details: you can check Linux_6DQ_RM.pdf):
#echo mem > /sys/power/state
#echo standby > /sys/power/state
How to do power optimization
- Runtime Mode
- Check whether CPUFreq and Bus_freq scale are enabled
root@android:/ # cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
root@android:/ # cat /sys/devices/platform/imx_busfreq.0/enable
More details about this, please refer to "Documentation/cpu-freq/ governors.txt” .
- Check whether the system bus is working on your expected frequency.
root@android:/ # cat /sys/kernel/debug/clock/osc_clk/pll2_528_bus_main_clk/periph_clk/mmdc_ch0_axi_clk/rate
- Check CPU Loading and Interrupt(cat /proc/interrupts)
root@android:/ # cat /proc/interrupts
Through this command you can check whether some module will trigger interrupt frequently. And consider that whether we have some chances to reduce the interrupt count.
- Check clock tree carefully to see which clocks are not gated off but no any modules need them.
root@android:/ # powerdebug -d -c
- Reduce GPU frequency.GPU also offered interface to modify the frequency. According to your own product, you can reduce the gpu frequency.
Default gpu3DMaxClock is set to 64 in init.rc file, we can tuning a suitable value by ourselves.
diff --git a/imx6/etc/init.rc b/imx6/etc/init.rc
index 8c420b5..eb11ffe 100755
@@ -397,6 +397,9 @@ on boot
# Set GPU 3D minimum clock to 3/64
write /sys/module/galcore/parameters/gpu3DMinClock 3
+# Set GPU 3D maximum clock to 64/64
+ write /sys/module/galcore/parameters/gpu3DMaxClock 64
- Suspend Mode
- Check whether all devices enter suspend mode or low power mode:
- Add debug message into devices drivers to check whether all devices driver suspend interface are called
- Use oscilloscope to measure the related signal (depend on specific device datasheet and custom hw design) to check whether every device enter low power mode
- Remove devices from the board(or rmmod the device driver) , and do hardware rework to exclude some hardware module if needed. Then we can figure out which module introduced the high consumption, and debug into the specific module.
- Check whether all devices enter suspend mode or low power mode:
Add debug message in device drivers which may lead high power consumption, catch the waveform from these modules which may impact the high power consumption
- Check whether DDR enter in self-refresh mode(Please check the DDR datasheet to figure out which pin indicate self-refresh state, and check it with oscilloscope)
- Config GPIO PADs as output zero or input mode (depending to HW design)
- Cut off LDOs/DCDCs which no modules need (depending to HW design)
- Check all PLLs will cut off, just 32KHZ sleep clock living