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