1*e790a4ceSJonathan Corbet=====================
2*e790a4ceSJonathan CorbetThe OMAP PM interface
3*e790a4ceSJonathan Corbet=====================
4*e790a4ceSJonathan Corbet
5*e790a4ceSJonathan CorbetThis document describes the temporary OMAP PM interface.  Driver
6*e790a4ceSJonathan Corbetauthors use these functions to communicate minimum latency or
7*e790a4ceSJonathan Corbetthroughput constraints to the kernel power management code.
8*e790a4ceSJonathan CorbetOver time, the intention is to merge features from the OMAP PM
9*e790a4ceSJonathan Corbetinterface into the Linux PM QoS code.
10*e790a4ceSJonathan Corbet
11*e790a4ceSJonathan CorbetDrivers need to express PM parameters which:
12*e790a4ceSJonathan Corbet
13*e790a4ceSJonathan Corbet- support the range of power management parameters present in the TI SRF;
14*e790a4ceSJonathan Corbet
15*e790a4ceSJonathan Corbet- separate the drivers from the underlying PM parameter
16*e790a4ceSJonathan Corbet  implementation, whether it is the TI SRF or Linux PM QoS or Linux
17*e790a4ceSJonathan Corbet  latency framework or something else;
18*e790a4ceSJonathan Corbet
19*e790a4ceSJonathan Corbet- specify PM parameters in terms of fundamental units, such as
20*e790a4ceSJonathan Corbet  latency and throughput, rather than units which are specific to OMAP
21*e790a4ceSJonathan Corbet  or to particular OMAP variants;
22*e790a4ceSJonathan Corbet
23*e790a4ceSJonathan Corbet- allow drivers which are shared with other architectures (e.g.,
24*e790a4ceSJonathan Corbet  DaVinci) to add these constraints in a way which won't affect non-OMAP
25*e790a4ceSJonathan Corbet  systems,
26*e790a4ceSJonathan Corbet
27*e790a4ceSJonathan Corbet- can be implemented immediately with minimal disruption of other
28*e790a4ceSJonathan Corbet  architectures.
29*e790a4ceSJonathan Corbet
30*e790a4ceSJonathan Corbet
31*e790a4ceSJonathan CorbetThis document proposes the OMAP PM interface, including the following
32*e790a4ceSJonathan Corbetfive power management functions for driver code:
33*e790a4ceSJonathan Corbet
34*e790a4ceSJonathan Corbet1. Set the maximum MPU wakeup latency::
35*e790a4ceSJonathan Corbet
36*e790a4ceSJonathan Corbet   (*pdata->set_max_mpu_wakeup_lat)(struct device *dev, unsigned long t)
37*e790a4ceSJonathan Corbet
38*e790a4ceSJonathan Corbet2. Set the maximum device wakeup latency::
39*e790a4ceSJonathan Corbet
40*e790a4ceSJonathan Corbet   (*pdata->set_max_dev_wakeup_lat)(struct device *dev, unsigned long t)
41*e790a4ceSJonathan Corbet
42*e790a4ceSJonathan Corbet3. Set the maximum system DMA transfer start latency (CORE pwrdm)::
43*e790a4ceSJonathan Corbet
44*e790a4ceSJonathan Corbet   (*pdata->set_max_sdma_lat)(struct device *dev, long t)
45*e790a4ceSJonathan Corbet
46*e790a4ceSJonathan Corbet4. Set the minimum bus throughput needed by a device::
47*e790a4ceSJonathan Corbet
48*e790a4ceSJonathan Corbet   (*pdata->set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r)
49*e790a4ceSJonathan Corbet
50*e790a4ceSJonathan Corbet5. Return the number of times the device has lost context::
51*e790a4ceSJonathan Corbet
52*e790a4ceSJonathan Corbet   (*pdata->get_dev_context_loss_count)(struct device *dev)
53*e790a4ceSJonathan Corbet
54*e790a4ceSJonathan Corbet
55*e790a4ceSJonathan CorbetFurther documentation for all OMAP PM interface functions can be
56*e790a4ceSJonathan Corbetfound in arch/arm/plat-omap/include/mach/omap-pm.h.
57*e790a4ceSJonathan Corbet
58*e790a4ceSJonathan Corbet
59*e790a4ceSJonathan CorbetThe OMAP PM layer is intended to be temporary
60*e790a4ceSJonathan Corbet---------------------------------------------
61*e790a4ceSJonathan Corbet
62*e790a4ceSJonathan CorbetThe intention is that eventually the Linux PM QoS layer should support
63*e790a4ceSJonathan Corbetthe range of power management features present in OMAP3.  As this
64*e790a4ceSJonathan Corbethappens, existing drivers using the OMAP PM interface can be modified
65*e790a4ceSJonathan Corbetto use the Linux PM QoS code; and the OMAP PM interface can disappear.
66*e790a4ceSJonathan Corbet
67*e790a4ceSJonathan Corbet
68*e790a4ceSJonathan CorbetDriver usage of the OMAP PM functions
69*e790a4ceSJonathan Corbet-------------------------------------
70*e790a4ceSJonathan Corbet
71*e790a4ceSJonathan CorbetAs the 'pdata' in the above examples indicates, these functions are
72*e790a4ceSJonathan Corbetexposed to drivers through function pointers in driver .platform_data
73*e790a4ceSJonathan Corbetstructures.  The function pointers are initialized by the `board-*.c`
74*e790a4ceSJonathan Corbetfiles to point to the corresponding OMAP PM functions:
75*e790a4ceSJonathan Corbet
76*e790a4ceSJonathan Corbet- set_max_dev_wakeup_lat will point to
77*e790a4ceSJonathan Corbet  omap_pm_set_max_dev_wakeup_lat(), etc.  Other architectures which do
78*e790a4ceSJonathan Corbet  not support these functions should leave these function pointers set
79*e790a4ceSJonathan Corbet  to NULL.  Drivers should use the following idiom::
80*e790a4ceSJonathan Corbet
81*e790a4ceSJonathan Corbet        if (pdata->set_max_dev_wakeup_lat)
82*e790a4ceSJonathan Corbet            (*pdata->set_max_dev_wakeup_lat)(dev, t);
83*e790a4ceSJonathan Corbet
84*e790a4ceSJonathan CorbetThe most common usage of these functions will probably be to specify
85*e790a4ceSJonathan Corbetthe maximum time from when an interrupt occurs, to when the device
86*e790a4ceSJonathan Corbetbecomes accessible.  To accomplish this, driver writers should use the
87*e790a4ceSJonathan Corbetset_max_mpu_wakeup_lat() function to constrain the MPU wakeup
88*e790a4ceSJonathan Corbetlatency, and the set_max_dev_wakeup_lat() function to constrain the
89*e790a4ceSJonathan Corbetdevice wakeup latency (from clk_enable() to accessibility).  For
90*e790a4ceSJonathan Corbetexample::
91*e790a4ceSJonathan Corbet
92*e790a4ceSJonathan Corbet        /* Limit MPU wakeup latency */
93*e790a4ceSJonathan Corbet        if (pdata->set_max_mpu_wakeup_lat)
94*e790a4ceSJonathan Corbet            (*pdata->set_max_mpu_wakeup_lat)(dev, tc);
95*e790a4ceSJonathan Corbet
96*e790a4ceSJonathan Corbet        /* Limit device powerdomain wakeup latency */
97*e790a4ceSJonathan Corbet        if (pdata->set_max_dev_wakeup_lat)
98*e790a4ceSJonathan Corbet            (*pdata->set_max_dev_wakeup_lat)(dev, td);
99*e790a4ceSJonathan Corbet
100*e790a4ceSJonathan Corbet        /* total wakeup latency in this example: (tc + td) */
101*e790a4ceSJonathan Corbet
102*e790a4ceSJonathan CorbetThe PM parameters can be overwritten by calling the function again
103*e790a4ceSJonathan Corbetwith the new value.  The settings can be removed by calling the
104*e790a4ceSJonathan Corbetfunction with a t argument of -1 (except in the case of
105*e790a4ceSJonathan Corbetset_max_bus_tput(), which should be called with an r argument of 0).
106*e790a4ceSJonathan Corbet
107*e790a4ceSJonathan CorbetThe fifth function above, omap_pm_get_dev_context_loss_count(),
108*e790a4ceSJonathan Corbetis intended as an optimization to allow drivers to determine whether the
109*e790a4ceSJonathan Corbetdevice has lost its internal context.  If context has been lost, the
110*e790a4ceSJonathan Corbetdriver must restore its internal context before proceeding.
111*e790a4ceSJonathan Corbet
112*e790a4ceSJonathan Corbet
113*e790a4ceSJonathan CorbetOther specialized interface functions
114*e790a4ceSJonathan Corbet-------------------------------------
115*e790a4ceSJonathan Corbet
116*e790a4ceSJonathan CorbetThe five functions listed above are intended to be usable by any
117*e790a4ceSJonathan Corbetdevice driver.  DSPBridge and CPUFreq have a few special requirements.
118*e790a4ceSJonathan CorbetDSPBridge expresses target DSP performance levels in terms of OPP IDs.
119*e790a4ceSJonathan CorbetCPUFreq expresses target MPU performance levels in terms of MPU
120*e790a4ceSJonathan Corbetfrequency.  The OMAP PM interface contains functions for these
121*e790a4ceSJonathan Corbetspecialized cases to convert that input information (OPPs/MPU
122*e790a4ceSJonathan Corbetfrequency) into the form that the underlying power management
123*e790a4ceSJonathan Corbetimplementation needs:
124*e790a4ceSJonathan Corbet
125*e790a4ceSJonathan Corbet6. `(*pdata->dsp_get_opp_table)(void)`
126*e790a4ceSJonathan Corbet
127*e790a4ceSJonathan Corbet7. `(*pdata->dsp_set_min_opp)(u8 opp_id)`
128*e790a4ceSJonathan Corbet
129*e790a4ceSJonathan Corbet8. `(*pdata->dsp_get_opp)(void)`
130*e790a4ceSJonathan Corbet
131*e790a4ceSJonathan Corbet9. `(*pdata->cpu_get_freq_table)(void)`
132*e790a4ceSJonathan Corbet
133*e790a4ceSJonathan Corbet10. `(*pdata->cpu_set_freq)(unsigned long f)`
134*e790a4ceSJonathan Corbet
135*e790a4ceSJonathan Corbet11. `(*pdata->cpu_get_freq)(void)`
136*e790a4ceSJonathan Corbet
137*e790a4ceSJonathan CorbetCustomizing OPP for platform
138*e790a4ceSJonathan Corbet============================
139*e790a4ceSJonathan CorbetDefining CONFIG_PM should enable OPP layer for the silicon
140*e790a4ceSJonathan Corbetand the registration of OPP table should take place automatically.
141*e790a4ceSJonathan CorbetHowever, in special cases, the default OPP table may need to be
142*e790a4ceSJonathan Corbettweaked, for e.g.:
143*e790a4ceSJonathan Corbet
144*e790a4ceSJonathan Corbet * enable default OPPs which are disabled by default, but which
145*e790a4ceSJonathan Corbet   could be enabled on a platform
146*e790a4ceSJonathan Corbet * Disable an unsupported OPP on the platform
147*e790a4ceSJonathan Corbet * Define and add a custom opp table entry
148*e790a4ceSJonathan Corbet   in these cases, the board file needs to do additional steps as follows:
149*e790a4ceSJonathan Corbet
150*e790a4ceSJonathan Corbetarch/arm/mach-omapx/board-xyz.c::
151*e790a4ceSJonathan Corbet
152*e790a4ceSJonathan Corbet	#include "pm.h"
153*e790a4ceSJonathan Corbet	....
154*e790a4ceSJonathan Corbet	static void __init omap_xyz_init_irq(void)
155*e790a4ceSJonathan Corbet	{
156*e790a4ceSJonathan Corbet		....
157*e790a4ceSJonathan Corbet		/* Initialize the default table */
158*e790a4ceSJonathan Corbet		omapx_opp_init();
159*e790a4ceSJonathan Corbet		/* Do customization to the defaults */
160*e790a4ceSJonathan Corbet		....
161*e790a4ceSJonathan Corbet	}
162*e790a4ceSJonathan Corbet
163*e790a4ceSJonathan CorbetNOTE:
164*e790a4ceSJonathan Corbet  omapx_opp_init will be omap3_opp_init or as required
165*e790a4ceSJonathan Corbet  based on the omap family.
166