Power Management Debug and Profiling

From OMAPpedia

(Difference between revisions)
Jump to: navigation, search
Line 31: Line 31:
The filesystem has been build using Arago's arago-console-image task:
The filesystem has been build using Arago's arago-console-image task:
<pre>
<pre>
-
MACHINE=omap3evm bitbake arago-console-image''
+
MACHINE=omap3evm bitbake arago-console-image
</pre>
</pre>
A few extra packages have been added by adding the following to ''arago/conf/local.conf''
A few extra packages have been added by adding the following to ''arago/conf/local.conf''
<pre>
<pre>
-
IMAGE_INSTALL += " bash sshd linux-perf cpufrequtils"
+
IMAGE_INSTALL += " bash sshd linux-perf cpufrequtils"
</pre>
</pre>

Revision as of 15:07, 20 August 2010

Contents

PM debug and profiling

Tracing of clock and power domains events

The perf and ftrace frameworks are used to generate the following events:

The new events definitions have been added to the existing 'power' events in include/trace/events/power.h. The new events tracepoints have been added to the ARM/OMAP specific code. A patch with the new _generic_ events has been submitted to the LKML, cf. http://marc.info/?l=linux-kernel&m=128195697205096&w=4. Cf. the patch/RFC below for code details (code is in WIP status).

Compilation and usage

Starting from the pm branch of Tony's tree (at http://git.kernel.org/?p=linux/kernel/git/tmlind/linux-omap-2.6.git), the patch below needs to be applied in order to get support for the new events and the OMAP specific trace points.

The config in use is omap3_pm_defconfig, with the following extra options to be enabled:

Userspace filesystem

File:Arago-console-image-omap3evm.tar.gz contains the necessary power management related utilities (cpufreq, perf) as well as a few useful utilities (bash, sshd). The filesystem has been build using Arago's arago-console-image task:

MACHINE=omap3evm bitbake arago-console-image

A few extra packages have been added by adding the following to arago/conf/local.conf

IMAGE_INSTALL += " bash sshd linux-perf cpufrequtils"

More info at [[Arago wiki page][1]].

Note about the kernel: Arago builds the TI PSP kernel for OMAP. The kernel used for PM Debug and Profiling comes from the pm branch of Tony's git tree.

Tracing instructions

Mounting debugfs

# mount -t debugfs nodev /sys/kernel/debug/

Enabling power events

# echo 1 > /sys/kernel/debug/tracing/events/power/enable
# echo 1 > /sys/kernel/debug/tracing/events/power/power_end/enable
# echo 0 > /sys/kernel/debug/tracing/events/power/power_end/enable

Dump trace

# cat /sys/kernel/debug/tracing/trace_pipe
# cat /sys/kernel/debug/tracing/trace

PM specific commands reference

cpuidle

# echo 5 > /sys/devices/platform/serial8250.0/sleep_timeout 
# echo 5 > /sys/devices/platform/serial8250.1/sleep_timeout 
# echo 5 > /sys/devices/platform/serial8250.2/sleep_timeout 
# echo 1 > /sys/kernel/debug/pm_debug/sleep_while_idle
# echo 1 > /sys/kernel/debug/pm_debug/enable_off_mode

# cat /sys/kernel/debug/pm_debug/count
usbhost_pwrdm (OFF),OFF:1,RET:1,INA:0,ON:1,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0
sgx_pwrdm (OFF),OFF:1,RET:0,INA:0,ON:1,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0
per_pwrdm (ON),OFF:3833,RET:1603,INA:0,ON:5437,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0
dss_pwrdm (OFF),OFF:1,RET:1,INA:0,ON:1,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0
cam_pwrdm (OFF),OFF:1,RET:1,INA:0,ON:1,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0
core_pwrdm (ON),OFF:2160,RET:1673,INA:0,ON:3834,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0,RET-MEMBANK2-OFF:0
neon_pwrdm (ON),OFF:4088,RET:1244,INA:253,ON:5586,RET-LOGIC-OFF:0
mpu_pwrdm (ON),OFF:4088,RET:1244,INA:253,ON:5586,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0
iva2_pwrdm (OFF),OFF:1,RET:1,INA:0,ON:1,RET-LOGIC-OFF:0,RET-MEMBANK1-OFF:0,RET-MEMBANK2-OFF:0,RET-MEMBANK3-OFF:0,RET-MEMBANK4-OFF:0
per_clkdm->per_pwrdm (11)
usbhost_clkdm->usbhost_pwrdm (0)
cam_clkdm->cam_pwrdm (0)
dss_clkdm->dss_pwrdm (0)
core_l4_clkdm->core_pwrdm (8)
core_l3_clkdm->core_pwrdm (4)
d2d_clkdm->core_pwrdm (0)
sgx_clkdm->sgx_pwrdm (0)
iva2_clkdm->iva2_pwrdm (0)
neon_clkdm->neon_pwrdm (0)
mpu_clkdm->mpu_pwrdm (2)
prm_clkdm->wkup_pwrdm (0)
cm_clkdm->core_pwrdm (0)

cpufreq/DVFS

# echo 550000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
# echo 500000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
# echo 250000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
# echo ondemand > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

Trace logs

# cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
#           TASK-PID    CPU#    TIMESTAMP  FUNCTION
#              | |       |          |         |
          <idle>-0     [000]  1606.593781: power_start: type=1 state=1                       <= Here starts the idle loop           
          <idle>-0     [000]  1606.593781: power_domain_transition: mpu_pwrdm state=0         |  Power domain transition, MPU domain to target state OFF
          <idle>-0     [000]  1606.593781: power_domain_transition: core_pwrdm state=1        |  Power domain transition, CORE domain to target state RET
          <idle>-0     [000]  1606.593842: power_domain_transition: neon_pwrdm state=0        |  Power domain transition, NEON domain to target state OFF
          <idle>-0     [000]  1606.593872: clock_disable: gpio6_dbck state=0                  |  Clock gpio6_dbck disable
          <idle>-0     [000]  1606.593903: clock_disable: uart3_ick state=0                   |  ...
          <idle>-0     [000]  1606.593903: clock_disable: uart3_fck state=0                   |  All UARTs clocks disable
          <idle>-0     [000]  1606.593903: clock_disable: uart1_ick state=0                   |  ...
          <idle>-0     [000]  1606.593903: clock_disable: uart1_fck state=0                   |
          <idle>-0     [000]  1606.593933: clock_disable: uart2_ick state=0                   |
          <idle>-0     [000]  1606.593933: clock_disable: uart2_fck state=0                   |
          <idle>-0     [000]  1606.640106: clock_enable: uart1_ick state=1                    |  All UARTs clocks enable
          <idle>-0     [000]  1606.640137: clock_enable: uart1_fck state=1                    |  ...
          <idle>-0     [000]  1606.640228: clock_enable: uart2_ick state=1                    |
          <idle>-0     [000]  1606.640228: clock_enable: uart2_fck state=1                    |
          <idle>-0     [000]  1606.640259: clock_enable: gpio6_dbck state=1                   |
          <idle>-0     [000]  1606.640259: clock_enable: uart3_ick state=1                    |
          <idle>-0     [000]  1606.640259: clock_enable: uart3_fck state=1                    |
          <idle>-0     [000]  1606.640564: power_end: dummy=65535                            <= Here ends the idle loop
     kondemand/0-404   [000]  1606.640717: power_frequency: type=2 state=125000000           <= DVFS event triggered by the on-demand governor, MPU freq=125MHz
     kondemand/0-404   [000]  1606.640778: clock_set_rate: dpll3_m2_ck state=166000000        |  Clock tree updates: dpll3_m2 to 166MHz
     kondemand/0-404   [000]  1606.641144: clock_set_rate: dpll1_ck state=125000000           |                      dpll1 to 125MHz
     kondemand/0-404   [000]  1606.641357: clock_set_rate: dpll2_ck state=90000000            |                      dpll2 to 90MHz
          <idle>-0     [000]  1606.642914: power_start: type=1 state=1                       <= End of DVFS, idle loop entry 
          <idle>-0     [000]  1606.642914: power_domain_transition: mpu_pwrdm state=0
          <idle>-0     [000]  1606.642944: power_domain_transition: core_pwrdm state=3
          <idle>-0     [000]  1606.643127: power_domain_transition: neon_pwrdm state=0
          <idle>-0     [000]  1606.643158: clock_disable: gpio6_dbck state=0
          <idle>-0     [000]  1606.643188: power_domain_transition: per_pwrdm state=1
          <idle>-0     [000]  1606.643219: clock_disable: uart3_ick state=0
          <idle>-0     [000]  1606.643250: clock_disable: uart3_fck state=0
          <idle>-0     [000]  1606.654236: clock_enable: gpio6_dbck state=1
          <idle>-0     [000]  1606.654266: clock_enable: uart3_ick state=1
          <idle>-0     [000]  1606.654266: clock_enable: uart3_fck state=1
          <idle>-0     [000]  1606.654297: power_domain_transition: per_pwrdm state=0
          <idle>-0     [000]  1606.654846: power_end: dummy=65535
          <idle>-0     [000]  1606.677887: power_start: type=1 state=1
          <idle>-0     [000]  1606.677948: power_domain_transition: mpu_pwrdm state=3
          <idle>-0     [000]  1606.677948: power_domain_transition: core_pwrdm state=3
          <idle>-0     [000]  1606.678131: power_domain_transition: neon_pwrdm state=3
          <idle>-0     [000]  1606.678192: clock_disable: gpio6_dbck state=0
          <idle>-0     [000]  1606.678223: power_domain_transition: per_pwrdm state=1
          <idle>-0     [000]  1606.678253: clock_disable: uart3_ick state=0
          <idle>-0     [000]  1606.678253: clock_disable: uart3_fck state=0
          <idle>-0     [000]  1606.678314: clock_enable: gpio6_dbck state=1
          <idle>-0     [000]  1606.678345: clock_enable: uart3_ick state=1
          <idle>-0     [000]  1606.678375: clock_enable: uart3_fck state=1
          <idle>-0     [000]  1606.678406: power_domain_transition: per_pwrdm state=0
          <idle>-0     [000]  1606.678925: power_end: dummy=65535
          <idle>-0     [000]  1606.682739: power_start: type=1 state=1
          <idle>-0     [000]  1606.682770: power_domain_transition: mpu_pwrdm state=0
          <idle>-0     [000]  1606.682800: power_domain_transition: core_pwrdm state=1
          <idle>-0     [000]  1606.682953: power_domain_transition: neon_pwrdm state=0
          <idle>-0     [000]  1606.683014: clock_disable: gpio6_dbck state=0
          <idle>-0     [000]  1606.683105: clock_disable: uart3_ick state=0
          <idle>-0     [000]  1606.683105: clock_disable: uart3_fck state=0
          <idle>-0     [000]  1606.683136: clock_disable: uart1_ick state=0
          <idle>-0     [000]  1606.683167: clock_disable: uart1_fck state=0
          <idle>-0     [000]  1606.683197: clock_disable: uart2_ick state=0
          <idle>-0     [000]  1606.683197: clock_disable: uart2_fck state=0
          <idle>-0     [000]  1606.767761: clock_enable: uart1_ick state=1
          <idle>-0     [000]  1606.767822: clock_enable: uart1_fck state=1
          <idle>-0     [000]  1606.767975: clock_enable: uart2_ick state=1
          <idle>-0     [000]  1606.768005: clock_enable: uart2_fck state=1
          <idle>-0     [000]  1606.768066: clock_enable: gpio6_dbck state=1
          <idle>-0     [000]  1606.768097: clock_enable: uart3_ick state=1
          <idle>-0     [000]  1606.768097: clock_enable: uart3_fck state=1
          <idle>-0     [000]  1606.768921: power_end: dummy=65535
...
     kondemand/0-404   [000]  2043.842743: power_frequency: type=2 state=600000000
     kondemand/0-404   [000]  2043.843628: clock_set_rate: dpll1_ck state=600000000
     kondemand/0-404   [000]  2043.843903: clock_set_rate: dpll2_ck state=430000000
     kondemand/0-404   [000]  2043.844299: clock_set_rate: dpll3_m2_ck state=332000000
# echo mem > /sys/power/state
PM: Syncing filesystems ... done.
Freezing user space processes ... (elapsed 0.01 seconds) done.
Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
Suspending console(s) (use no_console_suspend to debug)
PM: suspend of devices complete after 8.514 msecs
PM: late suspend of devices complete after 3.112 msecs
Successfully put all powerdomains to target state
PM: early resume of devices complete after 0.457 msecs
PM: resume of devices complete after 9.918 msecs
Restarting tasks ... done.

# cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
#           TASK-PID    CPU#    TIMESTAMP  FUNCTION
#              | |       |          |         |
          <idle>-0     [000]  2153.873413: power_start: type=1 state=1                       <= Here starts the idle loop
          <idle>-0     [000]  2153.873444: power_domain_transition: mpu_pwrdm state=3         |  Power domain transition, MPU domain to target state ON
          <idle>-0     [000]  2153.873474: power_domain_transition: core_pwrdm state=3        |  Power domain transition, CORE domain to target state ON
          <idle>-0     [000]  2153.873688: power_domain_transition: neon_pwrdm state=3        |  Power domain transition, NEON domain to target state ON
          <idle>-0     [000]  2153.873749: clock_disable: gpio6_dbck state=0                  |  Clock gpio6_dbck disable
          <idle>-0     [000]  2153.873749: power_domain_transition: per_pwrdm state=1         |  ...
          <idle>-0     [000]  2153.873779: clock_disable: uart3_ick state=0                   |
          <idle>-0     [000]  2153.873810: clock_disable: uart3_fck state=0                   |
          <idle>-0     [000]  2153.889099: clock_enable: gpio6_dbck state=1                   |
          <idle>-0     [000]  2153.889130: clock_enable: uart3_ick state=1                    |  Clock uart3_ick enable
          <idle>-0     [000]  2153.889130: clock_enable: uart3_fck state=1                    |
          <idle>-0     [000]  2153.889160: power_domain_transition: per_pwrdm state=0         |
          <idle>-0     [000]  2153.889740: power_end: dummy=65535                            <= Here ends the idle loop
              sh-1148  [000]  2153.915649: power_domain_transition: mpu_pwrdm state=0        <= Suspend entry: all power domains to OFF
              sh-1148  [000]  2153.915710: power_domain_transition: neon_pwrdm state=0        |
              sh-1148  [000]  2153.915741: power_domain_transition: core_pwrdm state=0        |
              sh-1148  [000]  2153.915771: power_start: type=1 state=0                        |  state=0: suspend entry
              sh-1148  [000]  2153.915985: power_domain_transition: neon_pwrdm state=0        |  ...
              sh-1148  [000]  2153.916016: clock_disable: gpio6_dbck state=0                  |  Clocks disable
              sh-1148  [000]  2153.916138: clock_disable: uart3_ick state=0                   |  ...
              sh-1148  [000]  2153.916138: clock_disable: uart3_fck state=0                   |
              sh-1148  [000]  2153.916199: clock_disable: uart1_ick state=0                   |
              sh-1148  [000]  2153.916199: clock_disable: uart1_fck state=0                   |
              sh-1148  [000]  2153.916229: clock_disable: uart2_ick state=0                   |
              sh-1148  [000]  2153.916260: clock_disable: uart2_fck state=0                   | Board frozen for ~10s ...
              sh-1148  [000]  2164.128876: clock_enable: hsotgusb_ick state=1                 | Resuming from deep sleep, enabling clocks
              sh-1148  [000]  2164.128967: clock_disable: hsotgusb_ick state=0                | ...
              sh-1148  [000]  2164.128998: clock_enable: uart1_ick state=1                    |
              sh-1148  [000]  2164.129028: clock_enable: uart1_fck state=1                    |
              sh-1148  [000]  2164.129150: clock_enable: uart2_ick state=1                    |
              sh-1148  [000]  2164.129181: clock_enable: uart2_fck state=1                    |
              sh-1148  [000]  2164.129272: clock_enable: gpio6_dbck state=1                   |
              sh-1148  [000]  2164.129303: clock_enable: uart3_ick state=1                    |
              sh-1148  [000]  2164.129333: clock_enable: uart3_fck state=1                    |
              sh-1148  [000]  2164.129608: power_domain_transition: mpu_pwrdm state=3         |  Power domain transition, MPU domain to target state ON
              sh-1148  [000]  2164.129639: power_domain_transition: neon_pwrdm state=3        |  Power domain transition, NEON domain to target state ON
              sh-1148  [000]  2164.129669: power_domain_transition: core_pwrdm state=3        |  Power domain transition, CORE domain to target state ON.
          <idle>-0     [000]  2164.270233: power_start: type=1 state=1                       <= System fully awake, idle loop entry
          <idle>-0     [000]  2164.270294: power_domain_transition: mpu_pwrdm state=3         |  ...
          <idle>-0     [000]  2164.270325: power_domain_transition: core_pwrdm state=3
          <idle>-0     [000]  2164.270538: power_domain_transition: neon_pwrdm state=3
          <idle>-0     [000]  2164.270569: clock_disable: gpio6_dbck state=0
          <idle>-0     [000]  2164.270599: power_domain_transition: per_pwrdm state=1
          <idle>-0     [000]  2164.270660: clock_disable: uart3_ick state=0
          <idle>-0     [000]  2164.270660: clock_disable: uart3_fck state=0
          <idle>-0     [000]  2164.275848: clock_enable: gpio6_dbck state=1
          <idle>-0     [000]  2164.275879: clock_enable: uart3_ick state=1
          <idle>-0     [000]  2164.275909: clock_enable: uart3_fck state=1
          <idle>-0     [000]  2164.275940: power_domain_transition: per_pwrdm state=0         | ...
          <idle>-0     [000]  2164.276642: power_end: dummy=65535                            <= Idle loop ends
...
          <idle>-0     [000]  2167.608856: power_start: type=1 state=1
          <idle>-0     [000]  2167.608887: power_domain_transition: mpu_pwrdm state=3
          <idle>-0     [000]  2167.608887: power_domain_transition: core_pwrdm state=3
          <idle>-0     [000]  2167.609131: power_domain_transition: neon_pwrdm state=3
          <idle>-0     [000]  2167.609161: clock_disable: gpio6_dbck state=0
          <idle>-0     [000]  2167.609192: power_domain_transition: per_pwrdm state=1
          <idle>-0     [000]  2167.609222: clock_disable: uart3_ick state=0
          <idle>-0     [000]  2167.609253: clock_disable: uart3_fck state=0
          <idle>-0     [000]  2167.689941: clock_enable: gpio6_dbck state=1
          <idle>-0     [000]  2167.689972: clock_enable: uart3_ick state=1
          <idle>-0     [000]  2167.690002: clock_enable: uart3_fck state=1
          <idle>-0     [000]  2167.690033: power_domain_transition: per_pwrdm state=0
          <idle>-0     [000]  2167.690613: power_end: dummy=65535
...
                                                                                             !! Need to wait ~6s for idle to change states from ON to RET/OFF ??
...
          <idle>-0     [000]  2170.605103: power_start: type=1 state=1
          <idle>-0     [000]  2170.605133: power_domain_transition: mpu_pwrdm state=0
          <idle>-0     [000]  2170.605133: power_domain_transition: core_pwrdm state=0
          <idle>-0     [000]  2170.605316: power_domain_transition: neon_pwrdm state=0
          <idle>-0     [000]  2170.605347: clock_disable: gpio6_dbck state=0
          <idle>-0     [000]  2170.605438: clock_disable: uart3_ick state=0
          <idle>-0     [000]  2170.605469: clock_disable: uart3_fck state=0
          <idle>-0     [000]  2170.605499: clock_disable: uart1_ick state=0
          <idle>-0     [000]  2170.605499: clock_disable: uart1_fck state=0
          <idle>-0     [000]  2170.605530: clock_disable: uart2_ick state=0
          <idle>-0     [000]  2170.605560: clock_disable: uart2_fck state=0
          <idle>-0     [000]  2171.031067: clock_enable: hsotgusb_ick state=1
          <idle>-0     [000]  2171.031158: clock_disable: hsotgusb_ick state=0
          <idle>-0     [000]  2171.031189: clock_enable: uart1_ick state=1
          <idle>-0     [000]  2171.031189: clock_enable: uart1_fck state=1
          <idle>-0     [000]  2171.031311: clock_enable: uart2_ick state=1
          <idle>-0     [000]  2171.031311: clock_enable: uart2_fck state=1
          <idle>-0     [000]  2171.031403: clock_enable: gpio6_dbck state=1
          <idle>-0     [000]  2171.031433: clock_enable: uart3_ick state=1
          <idle>-0     [000]  2171.031433: clock_enable: uart3_fck state=1
          <idle>-0     [000]  2171.032379: power_end: dummy=65535
          <idle>-0     [000]  2171.033203: power_start: type=1 state=1
          <idle>-0     [000]  2171.033234: power_domain_transition: mpu_pwrdm state=0
          <idle>-0     [000]  2171.033264: power_domain_transition: core_pwrdm state=3
          <idle>-0     [000]  2171.033447: power_domain_transition: neon_pwrdm state=0
          <idle>-0     [000]  2171.033478: clock_disable: gpio6_dbck state=0
          <idle>-0     [000]  2171.033508: power_domain_transition: per_pwrdm state=1
          <idle>-0     [000]  2171.033539: clock_disable: uart3_ick state=0
          <idle>-0     [000]  2171.033569: clock_disable: uart3_fck state=0
          <idle>-0     [000]  2171.138824: clock_enable: gpio6_dbck state=1
          <idle>-0     [000]  2171.138916: clock_enable: uart3_ick state=1
          <idle>-0     [000]  2171.138916: clock_enable: uart3_fck state=1
          <idle>-0     [000]  2171.138977: power_domain_transition: per_pwrdm state=0
          <idle>-0     [000]  2171.139832: power_end: dummy=65535

Trace parsing and GUIs

pytimechart UI

Intro

PyTimechart is a tool that parses ftrace text traces, and display them with the help of a dynamic plot framework, Chaco (http://code.enthought.com/chaco/ ) The GUI makes the best it can to ease the browsing of huge traces.

Download and installation

Cf. http://gitorious.com/pytimechart/ for download of the latest code.

pytimechart depends on python-chaco. It can be installed on recent distributions (tested on Debian 6 and Ubuntu 10.04).

Usage

Cf. http://gitorious.com/pytimechart/pages/Home for usage instructions.

Screenshot

A good screenshot says it all!

Pytimechart screenshot2 rs.jpg
Pytimechart screenshot5 rs.jpg

ToDo

pytimechart needs some changes to display the new PM events correctly, with the correct parameters (i.e. clock names for the clock_enable and clock_disable events...).

A patch to the current pytimechart must be submitted and included in the putimechart git tree.

l-o kernel patch/RFC

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 3d3d035..d5aa967 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -24,6 +24,7 @@
 
 #include <linux/sched.h>
 #include <linux/cpuidle.h>
+#include <trace/events/power.h>
 
 #include <plat/prcm.h>
 #include <plat/irqs.h>
@@ -130,6 +131,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
 	local_irq_disable();
 	local_fiq_disable();
 
+	trace_power_start(POWER_CSTATE, cx->type);
 	pwrdm_set_next_pwrst(mpu_pd, mpu_state);
 	pwrdm_set_next_pwrst(core_pd, core_state);
 
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 207905d..d399e34 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -28,6 +28,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <trace/events/power.h>
 
 #include <plat/sram.h>
 #include <plat/clockdomain.h>
@@ -592,6 +593,7 @@ static void omap3_pm_idle(void)
 	if (omap_irq_pending() || need_resched())
 		goto out;
 
+	trace_power_start(POWER_CSTATE, -1);
 	omap_sram_idle();
 
 out:
@@ -632,6 +634,8 @@ static int omap3_pm_suspend(void)
 		omap2_pm_wakeup_on_timer(wakeup_timer_seconds,
 					 wakeup_timer_milliseconds);
 
+	trace_power_start(POWER_CSTATE, -2);
+
 	/* Read current next_pwrsts */
 	list_for_each_entry(pwrst, &pwrst_list, node)
 		pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index a2904aa..67e5560 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -23,6 +23,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <trace/events/power.h>
 
 #include <asm/atomic.h>
 
@@ -440,6 +441,7 @@ int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
 	pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
 		 pwrdm->name, pwrst);
 
+	trace_power_domain_transition(pwrdm->name, pwrst);
 	prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
 			     (pwrst << OMAP_POWERSTATE_SHIFT),
 			     pwrdm->prcm_offs, pwrstctrl_reg_offs);
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 7190cbd..affaf78 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -21,6 +21,7 @@
 #include <linux/cpufreq.h>
 #include <linux/debugfs.h>
 #include <linux/io.h>
+#include <trace/events/power.h>
 
 #include <plat/clock.h>
 
@@ -43,8 +44,10 @@ int clk_enable(struct clk *clk)
 		return -EINVAL;
 
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_enable)
+	if (arch_clock->clk_enable) {
+		trace_clock_enable(clk->name, 1);
 		ret = arch_clock->clk_enable(clk);
+	}
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 
 	return ret;
@@ -66,8 +69,10 @@ void clk_disable(struct clk *clk)
 		goto out;
 	}
 
-	if (arch_clock->clk_disable)
+	if (arch_clock->clk_disable) {
+		trace_clock_disable(clk->name, 0);
 		arch_clock->clk_disable(clk);
+	}
 
 out:
 	spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -120,8 +125,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 		return ret;
 
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_set_rate)
+	if (arch_clock->clk_set_rate) {
+		trace_clock_set_rate(clk->name, rate);
 		ret = arch_clock->clk_set_rate(clk, rate);
+	}
 	if (ret == 0) {
 		if (clk->recalc)
 			clk->rate = clk->recalc(clk);
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index 9467827..6a0a07d 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -25,6 +25,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <trace/events/power.h>
 
 #include <mach/hardware.h>
 #include <plat/clock.h>
@@ -116,8 +117,10 @@ static int omap_target(struct cpufreq_policy *policy,
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 #elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
 	freq = target_freq * 1000;
-	if (opp_find_freq_ceil(mpu_dev, &freq))
+	if (opp_find_freq_ceil(mpu_dev, &freq)) {
+		trace_power_frequency(POWER_PSTATE, freq);
 		omap_pm_cpu_set_freq(freq);
+	}
 #endif
 	return ret;
 }
diff --git a/include/trace/events/power.h b/include/trace/events/power.h
index c4efe9b..67887aa 100644
--- a/include/trace/events/power.h
+++ b/include/trace/events/power.h
@@ -16,6 +16,10 @@ enum {
 };
 #endif
 
+/* 
+ * The power events are used for cpuidle (power_start, power_end) and for
+ *  cpufreq (power_frequency)
+ */
 DECLARE_EVENT_CLASS(power,
 
 	TP_PROTO(unsigned int type, unsigned int state),
@@ -67,6 +71,81 @@ TRACE_EVENT(power_end,
 
 );
 
+/*
+ * The clock events are used for clock enable/disable and for
+ *  clock rate change
+ */
+DECLARE_EVENT_CLASS(clock,
+
+	TP_PROTO(const char *name, unsigned int state),
+
+	TP_ARGS(name, state),
+
+	TP_STRUCT__entry(
+		__string(	name,		name		)
+		__field(	u64,		state		)
+	),
+
+	TP_fast_assign(
+		__assign_str(name, name);
+		__entry->state = state;
+	),
+
+	TP_printk("%s state=%lu", __get_str(name), (unsigned long)__entry->state)
+);
+
+
+DEFINE_EVENT(clock, clock_enable,
+
+	TP_PROTO(const char *name, unsigned int state),
+
+	TP_ARGS(name, state)
+);
+
+DEFINE_EVENT(clock, clock_disable,
+
+	TP_PROTO(const char *name, unsigned int state),
+
+	TP_ARGS(name, state)
+);
+
+DEFINE_EVENT(clock, clock_set_rate,
+
+	TP_PROTO(const char *name, unsigned int state),
+
+	TP_ARGS(name, state)
+);
+
+/*
+ * The power domain events are used for power domains transitions
+ */
+DECLARE_EVENT_CLASS(power_domain,
+
+	TP_PROTO(const char *name, unsigned int state),
+
+	TP_ARGS(name, state),
+
+	TP_STRUCT__entry(
+		__string(	name,		name		)
+		__field(	u64,		state		)
+	),
+
+	TP_fast_assign(
+		__assign_str(name, name);
+		__entry->state = state;
+	),
+
+	TP_printk("%s state=%lu", __get_str(name), (unsigned long)__entry->state)
+);
+
+
+DEFINE_EVENT(power_domain, power_domain_transition,
+
+	TP_PROTO(const char *name, unsigned int state),
+
+	TP_ARGS(name, state)
+);
+
 #endif /* _TRACE_POWER_H */
 
 /* This part must be outside protection */
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox