Difference between revisions of "OMAP Power Management"

From eLinux.org
Jump to: navigation, search
(Known Problems)
m (Known Problems)
Line 47: Line 47:
 
** Background: GPIO wakeups can happen either via the GPIO module itself (module-level wakeups) or via IO pad wakeups if the CORE powerdomain is inactive, in retention or off.
 
** Background: GPIO wakeups can happen either via the GPIO module itself (module-level wakeups) or via IO pad wakeups if the CORE powerdomain is inactive, in retention or off.
 
** If the IO pad wakeups are not enabled (either because CORE remains on, or because IO pad is not armed) GPIO wakeups may not happen unless the GPIO module-level wakeups are programmed correctly.
 
** If the IO pad wakeups are not enabled (either because CORE remains on, or because IO pad is not armed) GPIO wakeups may not happen unless the GPIO module-level wakeups are programmed correctly.
** To ensure GPIO module wakeups
+
** To ensure GPIO module wakeups are programmed correctly:
 
*** Enable GPIO IRQ for wakeup GPIO, including ISR.  Use <tt>request_irq()</tt>
 
*** Enable GPIO IRQ for wakeup GPIO, including ISR.  Use <tt>request_irq()</tt>
 
*** Ensure GPIO is edge-triggered.  Only edge triggered GPIOs are wakeup capable (c.f. omap34xx TRM Sec. 25.5.3.1)
 
*** Ensure GPIO is edge-triggered.  Only edge triggered GPIOs are wakeup capable (c.f. omap34xx TRM Sec. 25.5.3.1)

Revision as of 08:00, 10 September 2009

PM branch

The PM branch is a developement branch of the linux-omap kernel for the purposes of developing and stabilizing the PM infrastructure for OMAP and submitting it upstream.

The maintainer of the PM branch is Kevin Hilman.

Features

  • full-chip retention in idle and suspend
  • full-chip OFF in idle and suspend
  • CPUidle
  • DVFS using CPUfreq
  • support for multiple OMAP3 boards

The latest, tested PM branch is available as a branch named 'pm' from the linux-omap-pm repository. This branch is also sync'd daily as the 'pm' branch of the main linux-omap repository.

Current version (25 aug 2009)

Significant changes since previous version

  • rebased to omap/master (currently v2.6.31-rc7)
  • Using new omap_hwmod and omap_device infrastructure from Paul Walmsley
  • more reorg into groups of commits for easier submission upstream

Tested on the following platforms using omap3_pm_defconfig with busybox-based initramfs, and tested full-chip RET and OFF in idle and suspend:

  • 3430SDP
  • OMAP3EVM
  • Beagle
  • Overo (Water + Tobi)
  • RX51
  • Zoom2 (use 'pm-staging/zoom2' branch as well, which is the 'zoom2' branch of Vikram's omap3 repo rebased on top of PM branch with DEBUG_LL support and misc. fixes)


Known Problems

  • Zoom2: serial console wakeups not working
    • Problem: on suspend, by default the serial driver will disable serial interrupts, thus disabling the GPIO IRQ needed for wakeup.
    • Fix: enable the wakeup feature for the tty used as console:
 # echo enabled > /sys/devices/platform/serial8250.3/tty/ttyS3/power/wakeup 
  • 3430SDP ES3.0
    • UART1 doesn't come back from off-while-idle (ok on es3.1 SDP)
  • GPIO module-level wakeups not always working
    • Background: GPIO wakeups can happen either via the GPIO module itself (module-level wakeups) or via IO pad wakeups if the CORE powerdomain is inactive, in retention or off.
    • If the IO pad wakeups are not enabled (either because CORE remains on, or because IO pad is not armed) GPIO wakeups may not happen unless the GPIO module-level wakeups are programmed correctly.
    • To ensure GPIO module wakeups are programmed correctly:
      • Enable GPIO IRQ for wakeup GPIO, including ISR. Use request_irq()
      • Ensure GPIO is edge-triggered. Only edge triggered GPIOs are wakeup capable (c.f. omap34xx TRM Sec. 25.5.3.1)
        • the flags argument of request_irq() should have either IRQF_TRIGGER_FALLING, IRQF_TRIGGER_RISING or both.
      • Enable GPIO IRQ as wakeup source using enable_irq_wake(gpio_to_irq(<gpio>))
    • NOTE: It is very important that an interrupt handler be configured for the GPIO IRQ, even if it does nothing but return IRQ_HANDLED. This is because without an interrupt handler, the GPIO IRQ event will never be properly cleared and this can prevent the GPIO module from hitting retention or off on the next idle request.

Using the PM branch

Features

By default, the OMAP is configured to hit full-chip retention in suspend.

Suspend/Resume
# echo mem > /sys/power/state

Serial console activity or other configured wakeup sources (keypad, touchscreen) will trigger resume.

Optionally you can use a wake-up timer:

# echo '15' > /sys/power/wakeup_timer_seconds

Upon resume, you can use the powerdomain state statistics to check whether all states hit the desired state, cf. 'Debug info'

# cat /debug/pm_debug/count

In addition, if any powerdomains did not hit the desired state, you will see a message on the console.

Enabling system for hitting retention during idle

By default, the kernel will not try to hit retention or off while idle. To enable idle path to attempt deeper sleep states:

# echo 1 > /sys/power/sleep_while_idle

Then, wait for any inactivity timers to expire (such as the 5 second UART timer) and check the powerdomain transition statistics to see that transitions are happening

 # cat /debug/pm_debug/count
Enabling system for hitting OFF

By default, only retention is the deepest sleep state attempted. To enable powerdomain transitions to off mode

# echo 1 > /sys/power/enable_off_mode

In addition, to enable VDD1 and VDD2 to hit 0V

# echo 1 > /sys/power/voltage_off_while_idle

Once again, after a suspend or after some idle time, use the powerdomain transition stats to check that transitions to off-mode are happening

 # cat /debug/pm_debug/count

DVFS: Dynamic Voltage and Frequency Scaling

By default, no DVFS transitions will occur because the CPUfreq 'userspace' governor is the default governor. This means that any DVFS transitions must be manually triggered by a userspace application, or by using the CPUfreq sysfs interface( cf. 'CPUfreq kernel interface'). The OnDemand governor enables DVFS transitions based on CPU load.

Usage of the CPUfreq utils:

# cpufreq-info

Shows the current CPUfreq info: current governor, possible OPPs, current OPP ...

To change the current governor to e.g. 'userspace' or 'ondemand':

# cpufreq-set -g userspace
# cpufreq-set -g ondemand

Note: the corresponding governor support must be compiled in the kernel or as a module.

To change the frequency (with 'userspace' as the current governor):

# cpufreq-set -f 550000

The frequency is in KHz, as shown by cpufreq-info


Advanced features for PM developers and power users

Debug info

First, mount the debug filesystem (debugfs)

# mount -t debugfs debugfs /debug

Show powerdomain state statistics and clockdomain active clocks

# cat /debug/pm_debug/count

Dump current PRCM registers

# cat /debug/pm_debug/registers/current

Dump PRCM registers at last suspend

# cat /debug/pm_debug/registers/1

Misc. options

OPPs control

Request an OPP (where <opp> = [1|2|3|4|5])

# echo <opp> > /sys/power/vdd1_opp
# echo <opp> > /sys/power/vdd2_opp

Show the current OPPs

# cat /sys/power/vdd1_opp
# cat /sys/power/vdd2_opp

Lock at given OPP

# echo <opp> > /sys/power/vdd1_lock
# echo <opp> > /sys/power/vdd2_lock
SmartReflex control

Enables SmartReflex autocompensation on VDD1 (Note: This feature can only be tested on a ES3.1 silicon)

# echo 1 > /sys/power/sr_vdd1_autocomp

Disables SmartReflex? autocompensation on VDD1

# echo 0 > /sys/power/sr_vdd1_autocomp

Enables SmartReflex autocompensation on VDD2 (Note: This feature can only be tested on a ES3.1 silicon)

# echo 1 > /sys/power/sr_vdd2_autocomp

Disables SmartReflex? autocompensation on VDD2

# echo 0 > /sys/power/sr_vdd2_autocomp
CPUfreq kernel interface

Although the cpufreq utils are the preferred way to use the DVFS feature, the cpufreq kernel interface has some more information available. The main entry point is in /sys/devices/system/cpu/cpu0/cpufreq.

To list the available governors:

# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors

To list the available frequencies:

# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies

To show the current frequency:

# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq

To change the default governor:

# echo ondemand > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

The 'stats' directory has info about the cpufreq transitions and the time spent in the various OPPs:

# cat /sys/devices/system/cpu/cpu0/cpufreq/stats/total_trans
# cat /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state

TODO

omap_hwmod

  • Need omap3 modules coded for hwmod

mainline plans

Here's a very crude outline of my plans for getting PM branch code to mainline. Unless otherwise stated, this has only been tested on OMAP3, although some care has been taken to not break OMAP2 in the process.

Currently in mainline (2.6.31)

  • clock framework and infrastructure
  • clockdomain and powerdomain core
  • full-chip retention in suspend
  • full-chip retention in idle

submitted for next merge window (2.6.32)

  • misc. PM driver updates
    • I2C, SPI
  • PM debug infrastructure
  • OMAP PM layer ? (Paul)
  • omap_hwmod/omap_device  ? (Paul)

next, next merge window

  • off-mode support
    • context save/restore support
    • CPUidle w/off-mode C-states
  • SmartReflex driver core (deps: OMAP PM layer)
  • anything else is getting difficult to predict...

future directions

Run-time PM

Run-time PM is a recent development in the upstream kernel community. It provides an architecture independent framework for doing runtime power management of IO devices. It also extends the platform_bus/platform_device infrastructure to allow arch-specific extentions of the platform_device.

  • Key features
    • architecture independent
    • only a framework, does nothing without platform specific hooks
  • Plans for use in linux-omap
    • OMAP-specific extention of platform_device: contains an omap_device
    • implement platform specific runtime PM hooks for OMAP
    • runtime PM API used by all OMAP drivers
    • Explore platform_bus notifiers for automatic init/idle/suspend of devices
  • TODO
    • (add overview of API from driver perspective)