]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/blob - arch/arm/mach-omap2/omap-pm-noop.c
Merge remote-tracking branch 'origin/omaplfb' into p-ti-android-3.8.y-video
[android-sdk/kernel-video.git] / arch / arm / mach-omap2 / omap-pm-noop.c
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  */
18 #undef DEBUG
20 #include <linux/init.h>
21 #include <linux/cpufreq.h>
22 #include <linux/device.h>
23 #include <linux/platform_device.h>
24 #include <linux/export.h>
26 #include "omap_device.h"
27 #include "omap-pm.h"
29 static bool off_mode_enabled;
30 static int dummy_context_loss_counter;
32 /*
33  * Device-driver-originated constraints (via board-*.c files)
34  */
36 int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
37 {
38         if (!dev || t < -1) {
39                 WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
40                 return -EINVAL;
41         }
43         if (t == -1)
44                 pr_debug("OMAP PM: remove max MPU wakeup latency constraint: dev %s\n",
45                          dev_name(dev));
46         else
47                 pr_debug("OMAP PM: add max MPU wakeup latency constraint: dev %s, t = %ld usec\n",
48                          dev_name(dev), t);
50         /*
51          * For current Linux, this needs to map the MPU to a
52          * powerdomain, then go through the list of current max lat
53          * constraints on the MPU and find the smallest.  If
54          * the latency constraint has changed, the code should
55          * recompute the state to enter for the next powerdomain
56          * state.
57          *
58          * TI CDP code can call constraint_set here.
59          */
61         return 0;
62 }
64 int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
65 {
66         if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
67             agent_id != OCP_TARGET_AGENT)) {
68                 WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
69                 return -EINVAL;
70         }
72         if (r == 0)
73                 pr_debug("OMAP PM: remove min bus tput constraint: dev %s for agent_id %d\n",
74                          dev_name(dev), agent_id);
75         else
76                 pr_debug("OMAP PM: add min bus tput constraint: dev %s for agent_id %d: rate %ld KiB\n",
77                          dev_name(dev), agent_id, r);
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          */
87         return 0;
88 }
90 int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
91                                    long t)
92 {
93         if (!req_dev || !dev || t < -1) {
94                 WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
95                 return -EINVAL;
96         }
98         if (t == -1)
99                 pr_debug("OMAP PM: remove max device latency constraint: dev %s\n",
100                          dev_name(dev));
101         else
102                 pr_debug("OMAP PM: add max device latency constraint: dev %s, t = %ld usec\n",
103                          dev_name(dev), t);
105         /*
106          * For current Linux, this needs to map the device to a
107          * powerdomain, then go through the list of current max lat
108          * constraints on that powerdomain and find the smallest.  If
109          * the latency constraint has changed, the code should
110          * recompute the state to enter for the next powerdomain
111          * state.  Conceivably, this code should also determine
112          * whether to actually disable the device clocks or not,
113          * depending on how long it takes to re-enable the clocks.
114          *
115          * TI CDP code can call constraint_set here.
116          */
118         return 0;
121 int omap_pm_set_max_sdma_lat(struct device *dev, long t)
123         if (!dev || t < -1) {
124                 WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
125                 return -EINVAL;
126         }
128         if (t == -1)
129                 pr_debug("OMAP PM: remove max DMA latency constraint: dev %s\n",
130                          dev_name(dev));
131         else
132                 pr_debug("OMAP PM: add max DMA latency constraint: dev %s, t = %ld usec\n",
133                          dev_name(dev), t);
135         /*
136          * For current Linux PM QOS params, this code should scan the
137          * list of maximum CPU and DMA latencies and select the
138          * smallest, then set cpu_dma_latency pm_qos_param
139          * accordingly.
140          *
141          * For future Linux PM QOS params, with separate CPU and DMA
142          * latency params, this code should just set the dma_latency param.
143          *
144          * TI CDP code can call constraint_set here.
145          */
147         return 0;
150 int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
152         if (!dev || !c || r < 0) {
153                 WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
154                 return -EINVAL;
155         }
157         if (r == 0)
158                 pr_debug("OMAP PM: remove min clk rate constraint: dev %s\n",
159                          dev_name(dev));
160         else
161                 pr_debug("OMAP PM: add min clk rate constraint: dev %s, rate = %ld Hz\n",
162                          dev_name(dev), r);
164         /*
165          * Code in a real implementation should keep track of these
166          * constraints on the clock, and determine the highest minimum
167          * clock rate.  It should iterate over each OPP and determine
168          * whether the OPP will result in a clock rate that would
169          * satisfy this constraint (and any other PM constraint in effect
170          * at that time).  Once it finds the lowest-voltage OPP that
171          * meets those conditions, it should switch to it, or return
172          * an error if the code is not capable of doing so.
173          */
175         return 0;
178 /*
179  * DSP Bridge-specific constraints
180  */
182 const struct omap_opp *omap_pm_dsp_get_opp_table(void)
184         pr_debug("OMAP PM: DSP request for OPP table\n");
186         /*
187          * Return DSP frequency table here:  The final item in the
188          * array should have .rate = .opp_id = 0.
189          */
191         return NULL;
194 void omap_pm_dsp_set_min_opp(u8 opp_id)
196         if (opp_id == 0) {
197                 WARN_ON(1);
198                 return;
199         }
201         pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id);
203         /*
204          *
205          * For l-o dev tree, our VDD1 clk is keyed on OPP ID, so we
206          * can just test to see which is higher, the CPU's desired OPP
207          * ID or the DSP's desired OPP ID, and use whichever is
208          * highest.
209          *
210          * In CDP12.14+, the VDD1 OPP custom clock that controls the DSP
211          * rate is keyed on MPU speed, not the OPP ID.  So we need to
212          * map the OPP ID to the MPU speed for use with clk_set_rate()
213          * if it is higher than the current OPP clock rate.
214          *
215          */
219 u8 omap_pm_dsp_get_opp(void)
221         pr_debug("OMAP PM: DSP requests current DSP OPP ID\n");
223         /*
224          * For l-o dev tree, call clk_get_rate() on VDD1 OPP clock
225          *
226          * CDP12.14+:
227          * Call clk_get_rate() on the OPP custom clock, map that to an
228          * OPP ID using the tables defined in board-*.c/chip-*.c files.
229          */
231         return 0;
234 /*
235  * CPUFreq-originated constraint
236  *
237  * In the future, this should be handled by custom OPP clocktype
238  * functions.
239  */
241 struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void)
243         pr_debug("OMAP PM: CPUFreq request for frequency table\n");
245         /*
246          * Return CPUFreq frequency table here: loop over
247          * all VDD1 clkrates, pull out the mpu_ck frequencies, build
248          * table
249          */
251         return NULL;
254 void omap_pm_cpu_set_freq(unsigned long f)
256         if (f == 0) {
257                 WARN_ON(1);
258                 return;
259         }
261         pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n",
262                  f);
264         /*
265          * For l-o dev tree, determine whether MPU freq or DSP OPP id
266          * freq is higher.  Find the OPP ID corresponding to the
267          * higher frequency.  Call clk_round_rate() and clk_set_rate()
268          * on the OPP custom clock.
269          *
270          * CDP should just be able to set the VDD1 OPP clock rate here.
271          */
274 unsigned long omap_pm_cpu_get_freq(void)
276         pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n");
278         /*
279          * Call clk_get_rate() on the mpu_ck.
280          */
282         return 0;
285 /**
286  * omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled
287  *
288  * Intended for use only by OMAP PM core code to notify this layer
289  * that off mode has been enabled.
290  */
291 void omap_pm_enable_off_mode(void)
293         off_mode_enabled = true;
296 /**
297  * omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled
298  *
299  * Intended for use only by OMAP PM core code to notify this layer
300  * that off mode has been disabled.
301  */
302 void omap_pm_disable_off_mode(void)
304         off_mode_enabled = false;
307 /*
308  * Device context loss tracking
309  */
311 #ifdef CONFIG_ARCH_OMAP2PLUS
313 int omap_pm_get_dev_context_loss_count(struct device *dev)
315         struct platform_device *pdev = to_platform_device(dev);
316         int count;
318         if (WARN_ON(!dev))
319                 return -ENODEV;
321         if (dev->pm_domain == &omap_device_pm_domain) {
322                 count = omap_device_get_context_loss_count(pdev);
323         } else {
324                 WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device",
325                           dev_name(dev));
327                 count = dummy_context_loss_counter;
329                 if (off_mode_enabled) {
330                         count++;
331                         /*
332                          * Context loss count has to be a non-negative value.
333                          * Clear the sign bit to get a value range from 0 to
334                          * INT_MAX.
335                          */
336                         count &= INT_MAX;
337                         dummy_context_loss_counter = count;
338                 }
339         }
341         pr_debug("OMAP PM: context loss count for dev %s = %d\n",
342                  dev_name(dev), count);
344         return count;
347 #else
349 int omap_pm_get_dev_context_loss_count(struct device *dev)
351         return dummy_context_loss_counter;
354 #endif
355 EXPORT_SYMBOL(omap_pm_get_dev_context_loss_count);
357 /* Should be called before clk framework init */
358 int __init omap_pm_if_early_init(void)
360         return 0;
363 /* Must be called after clock framework is initialized */
364 int __init omap_pm_if_init(void)
366         return 0;
369 void omap_pm_if_exit(void)
371         /* Deallocate CPUFreq frequency table here */