diff options
Diffstat (limited to 'arch/arm/plat-omap/omap-pm-noop.c')
-rw-r--r-- | arch/arm/plat-omap/omap-pm-noop.c | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c new file mode 100644 index 000000000000..e98f0a2a6c26 --- /dev/null +++ b/arch/arm/plat-omap/omap-pm-noop.c | |||
@@ -0,0 +1,296 @@ | |||
1 | /* | ||
2 | * omap-pm-noop.c - OMAP power management interface - dummy version | ||
3 | * | ||
4 | * This code implements the OMAP power management interface to | ||
5 | * drivers, CPUIdle, CPUFreq, and DSP Bridge. It is strictly for | ||
6 | * debug/demonstration use, as it does nothing but printk() whenever a | ||
7 | * function is called (when DEBUG is defined, below) | ||
8 | * | ||
9 | * Copyright (C) 2008-2009 Texas Instruments, Inc. | ||
10 | * Copyright (C) 2008-2009 Nokia Corporation | ||
11 | * Paul Walmsley | ||
12 | * | ||
13 | * Interface developed by (in alphabetical order): | ||
14 | * Karthik Dasu, Tony Lindgren, Rajendra Nayak, Sakari Poussa, Veeramanikandan | ||
15 | * Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, Richard Woodruff | ||
16 | */ | ||
17 | |||
18 | #undef DEBUG | ||
19 | |||
20 | #include <linux/init.h> | ||
21 | #include <linux/cpufreq.h> | ||
22 | #include <linux/device.h> | ||
23 | |||
24 | /* Interface documentation is in mach/omap-pm.h */ | ||
25 | #include <mach/omap-pm.h> | ||
26 | |||
27 | #include <mach/powerdomain.h> | ||
28 | |||
29 | struct omap_opp *dsp_opps; | ||
30 | struct omap_opp *mpu_opps; | ||
31 | struct omap_opp *l3_opps; | ||
32 | |||
33 | /* | ||
34 | * Device-driver-originated constraints (via board-*.c files) | ||
35 | */ | ||
36 | |||
37 | void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t) | ||
38 | { | ||
39 | if (!dev || t < -1) { | ||
40 | WARN_ON(1); | ||
41 | return; | ||
42 | }; | ||
43 | |||
44 | if (t == -1) | ||
45 | pr_debug("OMAP PM: remove max MPU wakeup latency constraint: " | ||
46 | "dev %s\n", dev_name(dev)); | ||
47 | else | ||
48 | pr_debug("OMAP PM: add max MPU wakeup latency constraint: " | ||
49 | "dev %s, t = %ld usec\n", dev_name(dev), t); | ||
50 | |||
51 | /* | ||
52 | * For current Linux, this needs to map the MPU to a | ||
53 | * powerdomain, then go through the list of current max lat | ||
54 | * constraints on the MPU and find the smallest. If | ||
55 | * the latency constraint has changed, the code should | ||
56 | * recompute the state to enter for the next powerdomain | ||
57 | * state. | ||
58 | * | ||
59 | * TI CDP code can call constraint_set here. | ||
60 | */ | ||
61 | } | ||
62 | |||
63 | void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r) | ||
64 | { | ||
65 | if (!dev || (agent_id != OCP_INITIATOR_AGENT && | ||
66 | agent_id != OCP_TARGET_AGENT)) { | ||
67 | WARN_ON(1); | ||
68 | return; | ||
69 | }; | ||
70 | |||
71 | if (r == 0) | ||
72 | pr_debug("OMAP PM: remove min bus tput constraint: " | ||
73 | "dev %s for agent_id %d\n", dev_name(dev), agent_id); | ||
74 | else | ||
75 | pr_debug("OMAP PM: add min bus tput constraint: " | ||
76 | "dev %s for agent_id %d: rate %ld KiB\n", | ||
77 | dev_name(dev), agent_id, r); | ||
78 | |||
79 | /* | ||
80 | * This code should model the interconnect and compute the | ||
81 | * required clock frequency, convert that to a VDD2 OPP ID, then | ||
82 | * set the VDD2 OPP appropriately. | ||
83 | * | ||
84 | * TI CDP code can call constraint_set here on the VDD2 OPP. | ||
85 | */ | ||
86 | } | ||
87 | |||
88 | void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t) | ||
89 | { | ||
90 | if (!dev || t < -1) { | ||
91 | WARN_ON(1); | ||
92 | return; | ||
93 | }; | ||
94 | |||
95 | if (t == -1) | ||
96 | pr_debug("OMAP PM: remove max device latency constraint: " | ||
97 | "dev %s\n", dev_name(dev)); | ||
98 | else | ||
99 | pr_debug("OMAP PM: add max device latency constraint: " | ||
100 | "dev %s, t = %ld usec\n", dev_name(dev), t); | ||
101 | |||
102 | /* | ||
103 | * For current Linux, this needs to map the device to a | ||
104 | * powerdomain, then go through the list of current max lat | ||
105 | * constraints on that powerdomain and find the smallest. If | ||
106 | * the latency constraint has changed, the code should | ||
107 | * recompute the state to enter for the next powerdomain | ||
108 | * state. Conceivably, this code should also determine | ||
109 | * whether to actually disable the device clocks or not, | ||
110 | * depending on how long it takes to re-enable the clocks. | ||
111 | * | ||
112 | * TI CDP code can call constraint_set here. | ||
113 | */ | ||
114 | } | ||
115 | |||
116 | void omap_pm_set_max_sdma_lat(struct device *dev, long t) | ||
117 | { | ||
118 | if (!dev || t < -1) { | ||
119 | WARN_ON(1); | ||
120 | return; | ||
121 | }; | ||
122 | |||
123 | if (t == -1) | ||
124 | pr_debug("OMAP PM: remove max DMA latency constraint: " | ||
125 | "dev %s\n", dev_name(dev)); | ||
126 | else | ||
127 | pr_debug("OMAP PM: add max DMA latency constraint: " | ||
128 | "dev %s, t = %ld usec\n", dev_name(dev), t); | ||
129 | |||
130 | /* | ||
131 | * For current Linux PM QOS params, this code should scan the | ||
132 | * list of maximum CPU and DMA latencies and select the | ||
133 | * smallest, then set cpu_dma_latency pm_qos_param | ||
134 | * accordingly. | ||
135 | * | ||
136 | * For future Linux PM QOS params, with separate CPU and DMA | ||
137 | * latency params, this code should just set the dma_latency param. | ||
138 | * | ||
139 | * TI CDP code can call constraint_set here. | ||
140 | */ | ||
141 | |||
142 | } | ||
143 | |||
144 | |||
145 | /* | ||
146 | * DSP Bridge-specific constraints | ||
147 | */ | ||
148 | |||
149 | const struct omap_opp *omap_pm_dsp_get_opp_table(void) | ||
150 | { | ||
151 | pr_debug("OMAP PM: DSP request for OPP table\n"); | ||
152 | |||
153 | /* | ||
154 | * Return DSP frequency table here: The final item in the | ||
155 | * array should have .rate = .opp_id = 0. | ||
156 | */ | ||
157 | |||
158 | return NULL; | ||
159 | } | ||
160 | |||
161 | void omap_pm_dsp_set_min_opp(u8 opp_id) | ||
162 | { | ||
163 | if (opp_id == 0) { | ||
164 | WARN_ON(1); | ||
165 | return; | ||
166 | } | ||
167 | |||
168 | pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id); | ||
169 | |||
170 | /* | ||
171 | * | ||
172 | * For l-o dev tree, our VDD1 clk is keyed on OPP ID, so we | ||
173 | * can just test to see which is higher, the CPU's desired OPP | ||
174 | * ID or the DSP's desired OPP ID, and use whichever is | ||
175 | * highest. | ||
176 | * | ||
177 | * In CDP12.14+, the VDD1 OPP custom clock that controls the DSP | ||
178 | * rate is keyed on MPU speed, not the OPP ID. So we need to | ||
179 | * map the OPP ID to the MPU speed for use with clk_set_rate() | ||
180 | * if it is higher than the current OPP clock rate. | ||
181 | * | ||
182 | */ | ||
183 | } | ||
184 | |||
185 | |||
186 | u8 omap_pm_dsp_get_opp(void) | ||
187 | { | ||
188 | pr_debug("OMAP PM: DSP requests current DSP OPP ID\n"); | ||
189 | |||
190 | /* | ||
191 | * For l-o dev tree, call clk_get_rate() on VDD1 OPP clock | ||
192 | * | ||
193 | * CDP12.14+: | ||
194 | * Call clk_get_rate() on the OPP custom clock, map that to an | ||
195 | * OPP ID using the tables defined in board-*.c/chip-*.c files. | ||
196 | */ | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * CPUFreq-originated constraint | ||
203 | * | ||
204 | * In the future, this should be handled by custom OPP clocktype | ||
205 | * functions. | ||
206 | */ | ||
207 | |||
208 | struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void) | ||
209 | { | ||
210 | pr_debug("OMAP PM: CPUFreq request for frequency table\n"); | ||
211 | |||
212 | /* | ||
213 | * Return CPUFreq frequency table here: loop over | ||
214 | * all VDD1 clkrates, pull out the mpu_ck frequencies, build | ||
215 | * table | ||
216 | */ | ||
217 | |||
218 | return NULL; | ||
219 | } | ||
220 | |||
221 | void omap_pm_cpu_set_freq(unsigned long f) | ||
222 | { | ||
223 | if (f == 0) { | ||
224 | WARN_ON(1); | ||
225 | return; | ||
226 | } | ||
227 | |||
228 | pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n", | ||
229 | f); | ||
230 | |||
231 | /* | ||
232 | * For l-o dev tree, determine whether MPU freq or DSP OPP id | ||
233 | * freq is higher. Find the OPP ID corresponding to the | ||
234 | * higher frequency. Call clk_round_rate() and clk_set_rate() | ||
235 | * on the OPP custom clock. | ||
236 | * | ||
237 | * CDP should just be able to set the VDD1 OPP clock rate here. | ||
238 | */ | ||
239 | } | ||
240 | |||
241 | unsigned long omap_pm_cpu_get_freq(void) | ||
242 | { | ||
243 | pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n"); | ||
244 | |||
245 | /* | ||
246 | * Call clk_get_rate() on the mpu_ck. | ||
247 | */ | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * Device context loss tracking | ||
254 | */ | ||
255 | |||
256 | int omap_pm_get_dev_context_loss_count(struct device *dev) | ||
257 | { | ||
258 | if (!dev) { | ||
259 | WARN_ON(1); | ||
260 | return -EINVAL; | ||
261 | }; | ||
262 | |||
263 | pr_debug("OMAP PM: returning context loss count for dev %s\n", | ||
264 | dev_name(dev)); | ||
265 | |||
266 | /* | ||
267 | * Map the device to the powerdomain. Return the powerdomain | ||
268 | * off counter. | ||
269 | */ | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | |||
275 | /* Should be called before clk framework init */ | ||
276 | int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table, | ||
277 | struct omap_opp *dsp_opp_table, | ||
278 | struct omap_opp *l3_opp_table) | ||
279 | { | ||
280 | mpu_opps = mpu_opp_table; | ||
281 | dsp_opps = dsp_opp_table; | ||
282 | l3_opps = l3_opp_table; | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | /* Must be called after clock framework is initialized */ | ||
287 | int __init omap_pm_if_init(void) | ||
288 | { | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | void omap_pm_if_exit(void) | ||
293 | { | ||
294 | /* Deallocate CPUFreq frequency table here */ | ||
295 | } | ||
296 | |||