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