dd9f40eba4772349dcaa3ea02564afc3786d76e4
[pandora-kernel.git] / arch / arm / mach-omap2 / powerdomain.c
1 /*
2  * OMAP powerdomain control
3  *
4  * Copyright (C) 2007-2008 Texas Instruments, Inc.
5  * Copyright (C) 2007-2008 Nokia Corporation
6  *
7  * Written by Paul Walmsley
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13 #ifdef CONFIG_OMAP_DEBUG_POWERDOMAIN
14 # define DEBUG
15 #endif
16
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/types.h>
20 #include <linux/delay.h>
21 #include <linux/mutex.h>
22 #include <linux/list.h>
23 #include <linux/errno.h>
24 #include <linux/err.h>
25
26 #include <asm/atomic.h>
27
28 #include "cm.h"
29 #include "cm-regbits-34xx.h"
30 #include "prm.h"
31 #include "prm-regbits-34xx.h"
32
33 #include <asm/arch/cpu.h>
34 #include <asm/arch/powerdomain.h>
35 #include <asm/arch/clockdomain.h>
36
37 /* pwrdm_list contains all registered struct powerdomains */
38 static LIST_HEAD(pwrdm_list);
39
40 /* pwrdm_mutex protects pwrdm_list add and del ops */
41 static DEFINE_MUTEX(pwrdm_mutex);
42
43 /* Private functions */
44
45 static u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
46 {
47         u32 v;
48
49         v = prm_read_mod_reg(domain, idx);
50         v &= mask;
51         v >>= __ffs(mask);
52
53         return v;
54 }
55
56 static struct powerdomain *_pwrdm_lookup(const char *name)
57 {
58         struct powerdomain *pwrdm, *temp_pwrdm;
59
60         pwrdm = NULL;
61
62         list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
63                 if (!strcmp(name, temp_pwrdm->name)) {
64                         pwrdm = temp_pwrdm;
65                         break;
66                 }
67         }
68
69         return pwrdm;
70 }
71
72 /* _pwrdm_deps_lookup - look up the specified powerdomain in a pwrdm list */
73 static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
74                                               struct pwrdm_dep *deps)
75 {
76         struct pwrdm_dep *pd;
77
78         if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip))
79                 return ERR_PTR(-EINVAL);
80
81         for (pd = deps; pd; pd++) {
82
83                 if (!omap_chip_is(pd->omap_chip))
84                         continue;
85
86                 if (!pd->pwrdm && pd->pwrdm_name)
87                         pd->pwrdm = pwrdm_lookup(pd->pwrdm_name);
88
89                 if (pd->pwrdm == pwrdm)
90                         break;
91
92         }
93
94         if (!pd)
95                 return ERR_PTR(-ENOENT);
96
97         return pd->pwrdm;
98 }
99
100
101 /* Public functions */
102
103 /**
104  * pwrdm_init - set up the powerdomain layer
105  *
106  * Loop through the list of powerdomains, registering all that are
107  * available on the current CPU. If pwrdm_list is supplied and not
108  * null, all of the referenced powerdomains will be registered.  No
109  * return value.
110  */
111 void pwrdm_init(struct powerdomain **pwrdm_list)
112 {
113         struct powerdomain **p = NULL;
114
115         if (pwrdm_list)
116                 for (p = pwrdm_list; *p; p++)
117                         pwrdm_register(*p);
118 }
119
120 /**
121  * pwrdm_register - register a powerdomain
122  * @pwrdm: struct powerdomain * to register
123  *
124  * Adds a powerdomain to the internal powerdomain list.  Returns
125  * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
126  * already registered by the provided name, or 0 upon success.
127  */
128 int pwrdm_register(struct powerdomain *pwrdm)
129 {
130         int ret = -EINVAL;
131
132         if (!pwrdm)
133                 return -EINVAL;
134
135         if (!omap_chip_is(pwrdm->omap_chip))
136                 return -EINVAL;
137
138         mutex_lock(&pwrdm_mutex);
139         if (_pwrdm_lookup(pwrdm->name)) {
140                 ret = -EEXIST;
141                 goto pr_unlock;
142         }
143
144         list_add(&pwrdm->node, &pwrdm_list);
145
146         pr_debug("powerdomain: registered %s\n", pwrdm->name);
147         ret = 0;
148
149 pr_unlock:
150         mutex_unlock(&pwrdm_mutex);
151
152         return ret;
153 }
154
155 /**
156  * pwrdm_unregister - unregister a powerdomain
157  * @pwrdm: struct powerdomain * to unregister
158  *
159  * Removes a powerdomain from the internal powerdomain list.  Returns
160  * -EINVAL if pwrdm argument is NULL.
161  */
162 int pwrdm_unregister(struct powerdomain *pwrdm)
163 {
164         if (!pwrdm)
165                 return -EINVAL;
166
167         mutex_lock(&pwrdm_mutex);
168         list_del(&pwrdm->node);
169         mutex_unlock(&pwrdm_mutex);
170
171         pr_debug("powerdomain: unregistered %s\n", pwrdm->name);
172
173         return 0;
174 }
175
176 /**
177  * pwrdm_lookup - look up a powerdomain by name, return a pointer
178  * @name: name of powerdomain
179  *
180  * Find a registered powerdomain by its name.  Returns a pointer to the
181  * struct powerdomain if found, or NULL otherwise.
182  */
183 struct powerdomain *pwrdm_lookup(const char *name)
184 {
185         struct powerdomain *pwrdm;
186
187         if (!name)
188                 return NULL;
189
190         mutex_lock(&pwrdm_mutex);
191         pwrdm = _pwrdm_lookup(name);
192         mutex_unlock(&pwrdm_mutex);
193
194         return pwrdm;
195 }
196
197 /**
198  * pwrdm_for_each - call function on each registered clockdomain
199  * @fn: callback function *
200  *
201  * Call the supplied function for each registered powerdomain.
202  * The callback function can return anything but 0 to bail
203  * out early from the iterator.  The callback function is called with
204  * the pwrdm_mutex held, so no powerdomain structure manipulation
205  * functions should be called from the callback, although hardware
206  * powerdomain control functions are fine.  Returns the last return
207  * value of the callback function, which should be 0 for success or
208  * anything else to indicate failure; or -EINVAL if the function pointer
209  * is null.
210  */
211 int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm))
212 {
213         struct powerdomain *temp_pwrdm;
214         int ret = 0;
215
216         if (!fn)
217                 return -EINVAL;
218
219         mutex_lock(&pwrdm_mutex);
220         list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
221                 ret = (*fn)(temp_pwrdm);
222                 if (ret)
223                         break;
224         }
225         mutex_unlock(&pwrdm_mutex);
226
227         return ret;
228 }
229
230 /**
231  * pwrdm_add_clkdm - add a clockdomain to a powerdomain
232  * @pwrdm: struct powerdomain * to add the clockdomain to
233  * @clkdm: struct clockdomain * to associate with a powerdomain
234  *
235  * Associate the clockdomain 'clkdm' with a powerdomain 'pwrdm'.  This
236  * enables the use of pwrdm_for_each_clkdm().  Returns -EINVAL if
237  * presented with invalid pointers; -ENOMEM if memory could not be allocated;
238  * or 0 upon success.
239  */
240 int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
241 {
242         int i;
243         int ret = -EINVAL;
244
245         if (!pwrdm || !clkdm)
246                 return -EINVAL;
247
248         pr_debug("powerdomain: associating clockdomain %s with powerdomain "
249                  "%s\n", clkdm->name, pwrdm->name);
250         mutex_lock(&pwrdm_mutex);
251
252         for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
253                 if (!pwrdm->pwrdm_clkdms[i])
254                         break;
255 #ifdef DEBUG
256                 if (pwrdm->pwrdm_clkdms[i] == clkdm) {
257                         ret = -EINVAL;
258                         goto pac_exit;
259                 }
260 #endif
261         }
262
263         if (i == PWRDM_MAX_CLKDMS) {
264                 pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for "
265                          "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name);
266                 WARN_ON(1);
267                 ret = -ENOMEM;
268                 goto pac_exit;
269         }
270
271         pwrdm->pwrdm_clkdms[i] = clkdm;
272
273         ret = 0;
274
275 pac_exit:
276         mutex_unlock(&pwrdm_mutex);
277
278         return ret;
279 }
280
281 /**
282  * pwrdm_del_clkdm - remove a clockdomain to a powerdomain
283  * @pwrdm: struct powerdomain * to add the clockdomain to
284  * @clkdm: struct clockdomain * to associate with a powerdomain
285  *
286  * Dissociate the clockdomain 'clkdm' from the powerdomain
287  * 'pwrdm'. Returns -EINVAL if presented with invalid pointers;
288  * -ENOENT if the clkdm was not associated with the powerdomain, or 0
289  * upon success.
290  */
291 int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
292 {
293         int ret = -EINVAL;
294         int i;
295
296         if (!pwrdm || !clkdm)
297                 return -EINVAL;
298
299         pr_debug("powerdomain: dissociating clockdomain %s from powerdomain "
300                  "%s\n", clkdm->name, pwrdm->name);
301
302         mutex_lock(&pwrdm_mutex);
303
304         for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
305                 if (pwrdm->pwrdm_clkdms[i] == clkdm)
306                         break;
307
308         if (i == PWRDM_MAX_CLKDMS) {
309                 pr_debug("powerdomain: clkdm %s not associated with pwrdm "
310                          "%s ?!\n", clkdm->name, pwrdm->name);
311                 ret = -ENOENT;
312                 goto pdc_exit;
313         }
314
315         pwrdm->pwrdm_clkdms[i] = NULL;
316
317         ret = 0;
318
319 pdc_exit:
320         mutex_unlock(&pwrdm_mutex);
321
322         return ret;
323 }
324
325 /**
326  * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
327  * @pwrdm: struct powerdomain * to iterate over
328  * @fn: callback function *
329  *
330  * Call the supplied function for each clockdomain in the powerdomain
331  * 'pwrdm'.  The callback function can return anything but 0 to bail
332  * out early from the iterator.  The callback function is called with
333  * the pwrdm_mutex held, so no powerdomain structure manipulation
334  * functions should be called from the callback, although hardware
335  * powerdomain control functions are fine.  Returns -EINVAL if
336  * presented with invalid pointers; or passes along the last return
337  * value of the callback function, which should be 0 for success or
338  * anything else to indicate failure.
339  */
340 int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
341                          int (*fn)(struct powerdomain *pwrdm,
342                                    struct clockdomain *clkdm))
343 {
344         int ret = 0;
345         int i;
346
347         if (!fn)
348                 return -EINVAL;
349
350         mutex_lock(&pwrdm_mutex);
351
352         for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
353                 ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
354
355         mutex_unlock(&pwrdm_mutex);
356
357         return ret;
358 }
359
360
361 /**
362  * pwrdm_add_wkdep - add a wakeup dependency from pwrdm2 to pwrdm1
363  * @pwrdm1: wake this struct powerdomain * up (dependent)
364  * @pwrdm2: when this struct powerdomain * wakes up (source)
365  *
366  * When the powerdomain represented by pwrdm2 wakes up (due to an
367  * interrupt), wake up pwrdm1.  Implemented in hardware on the OMAP,
368  * this feature is designed to reduce wakeup latency of the dependent
369  * powerdomain.  Returns -EINVAL if presented with invalid powerdomain
370  * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
371  * 0 upon success.
372  */
373 int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
374 {
375         struct powerdomain *p;
376
377         if (!pwrdm1)
378                 return -EINVAL;
379
380         p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
381         if (IS_ERR(p)) {
382                 pr_debug("powerdomain: hardware cannot set/clear wake up of "
383                          "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
384                 return IS_ERR(p);
385         }
386
387         pr_debug("powerdomain: hardware will wake up %s when %s wakes up\n",
388                  pwrdm1->name, pwrdm2->name);
389
390         prm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
391                              pwrdm1->prcm_offs, PM_WKDEP);
392
393         return 0;
394 }
395
396 /**
397  * pwrdm_del_wkdep - remove a wakeup dependency from pwrdm2 to pwrdm1
398  * @pwrdm1: wake this struct powerdomain * up (dependent)
399  * @pwrdm2: when this struct powerdomain * wakes up (source)
400  *
401  * Remove a wakeup dependency that causes pwrdm1 to wake up when pwrdm2
402  * wakes up.  Returns -EINVAL if presented with invalid powerdomain
403  * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
404  * 0 upon success.
405  */
406 int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
407 {
408         struct powerdomain *p;
409
410         if (!pwrdm1)
411                 return -EINVAL;
412
413         p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
414         if (IS_ERR(p)) {
415                 pr_debug("powerdomain: hardware cannot set/clear wake up of "
416                          "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
417                 return IS_ERR(p);
418         }
419
420         pr_debug("powerdomain: hardware will no longer wake up %s after %s "
421                  "wakes up\n", pwrdm1->name, pwrdm2->name);
422
423         prm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
424                                pwrdm1->prcm_offs, PM_WKDEP);
425
426         return 0;
427 }
428
429 /**
430  * pwrdm_read_wkdep - read wakeup dependency state from pwrdm2 to pwrdm1
431  * @pwrdm1: wake this struct powerdomain * up (dependent)
432  * @pwrdm2: when this struct powerdomain * wakes up (source)
433  *
434  * Return 1 if a hardware wakeup dependency exists wherein pwrdm1 will be
435  * awoken when pwrdm2 wakes up; 0 if dependency is not set; -EINVAL
436  * if either powerdomain pointer is invalid; or -ENOENT if the hardware
437  * is incapable.
438  *
439  * REVISIT: Currently this function only represents software-controllable
440  * wakeup dependencies.  Wakeup dependencies fixed in hardware are not
441  * yet handled here.
442  */
443 int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
444 {
445         struct powerdomain *p;
446
447         if (!pwrdm1)
448                 return -EINVAL;
449
450         p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
451         if (IS_ERR(p)) {
452                 pr_debug("powerdomain: hardware cannot set/clear wake up of "
453                          "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
454                 return IS_ERR(p);
455         }
456
457         return prm_read_mod_bits_shift(pwrdm1->prcm_offs, PM_WKDEP,
458                                         (1 << pwrdm2->dep_bit));
459 }
460
461 /**
462  * pwrdm_add_sleepdep - add a sleep dependency from pwrdm2 to pwrdm1
463  * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
464  * @pwrdm2: when this struct powerdomain * is active (source)
465  *
466  * Prevent pwrdm1 from automatically going inactive (and then to
467  * retention or off) if pwrdm2 is still active.  Returns -EINVAL if
468  * presented with invalid powerdomain pointers or called on a machine
469  * that does not support software-configurable hardware sleep dependencies,
470  * -ENOENT if the specified dependency cannot be set in hardware, or
471  * 0 upon success.
472  */
473 int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
474 {
475         struct powerdomain *p;
476
477         if (!pwrdm1)
478                 return -EINVAL;
479
480         if (!cpu_is_omap34xx())
481                 return -EINVAL;
482
483         p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
484         if (IS_ERR(p)) {
485                 pr_debug("powerdomain: hardware cannot set/clear sleep "
486                          "dependency affecting %s from %s\n", pwrdm1->name,
487                          pwrdm2->name);
488                 return IS_ERR(p);
489         }
490
491         pr_debug("powerdomain: will prevent %s from sleeping if %s is active\n",
492                  pwrdm1->name, pwrdm2->name);
493
494         cm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
495                             pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
496
497         return 0;
498 }
499
500 /**
501  * pwrdm_del_sleepdep - remove a sleep dependency from pwrdm2 to pwrdm1
502  * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
503  * @pwrdm2: when this struct powerdomain * is active (source)
504  *
505  * Allow pwrdm1 to automatically go inactive (and then to retention or
506  * off), independent of the activity state of pwrdm2.  Returns -EINVAL
507  * if presented with invalid powerdomain pointers or called on a machine
508  * that does not support software-configurable hardware sleep dependencies,
509  * -ENOENT if the specified dependency cannot be cleared in hardware, or
510  * 0 upon success.
511  */
512 int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
513 {
514         struct powerdomain *p;
515
516         if (!pwrdm1)
517                 return -EINVAL;
518
519         if (!cpu_is_omap34xx())
520                 return -EINVAL;
521
522         p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
523         if (IS_ERR(p)) {
524                 pr_debug("powerdomain: hardware cannot set/clear sleep "
525                          "dependency affecting %s from %s\n", pwrdm1->name,
526                          pwrdm2->name);
527                 return IS_ERR(p);
528         }
529
530         pr_debug("powerdomain: will no longer prevent %s from sleeping if "
531                  "%s is active\n", pwrdm1->name, pwrdm2->name);
532
533         cm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
534                               pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
535
536         return 0;
537 }
538
539 /**
540  * pwrdm_read_sleepdep - read sleep dependency state from pwrdm2 to pwrdm1
541  * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
542  * @pwrdm2: when this struct powerdomain * is active (source)
543  *
544  * Return 1 if a hardware sleep dependency exists wherein pwrdm1 will
545  * not be allowed to automatically go inactive if pwrdm2 is active;
546  * 0 if pwrdm1's automatic power state inactivity transition is independent
547  * of pwrdm2's; -EINVAL if either powerdomain pointer is invalid or called
548  * on a machine that does not support software-configurable hardware sleep
549  * dependencies; or -ENOENT if the hardware is incapable.
550  *
551  * REVISIT: Currently this function only represents software-controllable
552  * sleep dependencies.  Sleep dependencies fixed in hardware are not
553  * yet handled here.
554  */
555 int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
556 {
557         struct powerdomain *p;
558
559         if (!pwrdm1)
560                 return -EINVAL;
561
562         if (!cpu_is_omap34xx())
563                 return -EINVAL;
564
565         p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
566         if (IS_ERR(p)) {
567                 pr_debug("powerdomain: hardware cannot set/clear sleep "
568                          "dependency affecting %s from %s\n", pwrdm1->name,
569                          pwrdm2->name);
570                 return IS_ERR(p);
571         }
572
573         return prm_read_mod_bits_shift(pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP,
574                                         (1 << pwrdm2->dep_bit));
575 }
576
577
578 /**
579  * pwrdm_set_next_pwrst - set next powerdomain power state
580  * @pwrdm: struct powerdomain * to set
581  * @pwrst: one of the PWRDM_POWER_* macros
582  *
583  * Set the powerdomain pwrdm's next power state to pwrst.  The powerdomain
584  * may not enter this state immediately if the preconditions for this state
585  * have not been satisfied.  Returns -EINVAL if the powerdomain pointer is
586  * null or if the power state is invalid for the powerdomin, or returns 0
587  * upon success.
588  */
589 int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
590 {
591         if (!pwrdm)
592                 return -EINVAL;
593
594         if (!(pwrdm->pwrsts & (1 << pwrst)))
595                 return -EINVAL;
596
597         pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
598                  pwrdm->name, pwrst);
599
600         prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
601                              (pwrst << OMAP_POWERSTATE_SHIFT),
602                              pwrdm->prcm_offs, PM_PWSTCTRL);
603
604         return 0;
605 }
606
607 /**
608  * pwrdm_read_next_pwrst - get next powerdomain power state
609  * @pwrdm: struct powerdomain * to get power state
610  *
611  * Return the powerdomain pwrdm's next power state.  Returns -EINVAL
612  * if the powerdomain pointer is null or returns the next power state
613  * upon success.
614  */
615 int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
616 {
617         if (!pwrdm)
618                 return -EINVAL;
619
620         return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL,
621                                         OMAP_POWERSTATE_MASK);
622 }
623
624 /**
625  * pwrdm_read_pwrst - get current powerdomain power state
626  * @pwrdm: struct powerdomain * to get power state
627  *
628  * Return the powerdomain pwrdm's current power state.  Returns -EINVAL
629  * if the powerdomain pointer is null or returns the current power state
630  * upon success.
631  */
632 int pwrdm_read_pwrst(struct powerdomain *pwrdm)
633 {
634         if (!pwrdm)
635                 return -EINVAL;
636
637         return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
638                                         OMAP_POWERSTATEST_MASK);
639 }
640
641 /**
642  * pwrdm_read_prev_pwrst - get previous powerdomain power state
643  * @pwrdm: struct powerdomain * to get previous power state
644  *
645  * Return the powerdomain pwrdm's previous power state.  Returns -EINVAL
646  * if the powerdomain pointer is null or returns the previous power state
647  * upon success.
648  */
649 int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
650 {
651         if (!pwrdm)
652                 return -EINVAL;
653
654         return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
655                                         OMAP3430_LASTPOWERSTATEENTERED_MASK);
656 }
657
658 /**
659  * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
660  * @pwrdm: struct powerdomain * to set
661  * @pwrst: one of the PWRDM_POWER_* macros
662  *
663  * Set the next power state that the logic portion of the powerdomain
664  * pwrdm will enter when the powerdomain enters retention.  This will
665  * be either RETENTION or OFF, if supported.  Returns -EINVAL if the
666  * powerdomain pointer is null or the target power state is not not
667  * supported, or returns 0 upon success.
668  */
669 int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
670 {
671         if (!pwrdm)
672                 return -EINVAL;
673
674         if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
675                 return -EINVAL;
676
677         pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n",
678                  pwrdm->name, pwrst);
679
680         /*
681          * The register bit names below may not correspond to the
682          * actual names of the bits in each powerdomain's register,
683          * but the type of value returned is the same for each
684          * powerdomain.
685          */
686         prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE,
687                              (pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE)),
688                              pwrdm->prcm_offs, PM_PWSTCTRL);
689
690         return 0;
691 }
692
693 /**
694  * pwrdm_set_mem_onst - set memory power state while powerdomain ON
695  * @pwrdm: struct powerdomain * to set
696  * @bank: memory bank number to set (0-3)
697  * @pwrst: one of the PWRDM_POWER_* macros
698  *
699  * Set the next power state that memory bank x of the powerdomain
700  * pwrdm will enter when the powerdomain enters the ON state.  Bank
701  * will be a number from 0 to 3, and represents different types of
702  * memory, depending on the powerdomain.  Returns -EINVAL if the
703  * powerdomain pointer is null or the target power state is not not
704  * supported for this memory bank, -EEXIST if the target memory bank
705  * does not exist or is not controllable, or returns 0 upon success.
706  */
707 int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
708 {
709         u32 m;
710
711         if (!pwrdm)
712                 return -EINVAL;
713
714         if (pwrdm->banks < (bank + 1))
715                 return -EEXIST;
716
717         if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
718                 return -EINVAL;
719
720         pr_debug("powerdomain: setting next memory powerstate for domain %s "
721                  "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst);
722
723         /*
724          * The register bit names below may not correspond to the
725          * actual names of the bits in each powerdomain's register,
726          * but the type of value returned is the same for each
727          * powerdomain.
728          */
729         switch (bank) {
730         case 0:
731                 m = OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK;
732                 break;
733         case 1:
734                 m = OMAP3430_L1FLATMEMONSTATE_MASK;
735                 break;
736         case 2:
737                 m = OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK;
738                 break;
739         case 3:
740                 m = OMAP3430_L2FLATMEMONSTATE_MASK;
741                 break;
742         default:
743                 WARN_ON(1); /* should never happen */
744                 return -EEXIST;
745         }
746
747         prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)),
748                              pwrdm->prcm_offs, PM_PWSTCTRL);
749
750         return 0;
751 }
752
753 /**
754  * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
755  * @pwrdm: struct powerdomain * to set
756  * @bank: memory bank number to set (0-3)
757  * @pwrst: one of the PWRDM_POWER_* macros
758  *
759  * Set the next power state that memory bank x of the powerdomain
760  * pwrdm will enter when the powerdomain enters the RETENTION state.
761  * Bank will be a number from 0 to 3, and represents different types
762  * of memory, depending on the powerdomain.  pwrst will be either
763  * RETENTION or OFF, if supported. Returns -EINVAL if the powerdomain
764  * pointer is null or the target power state is not not supported for
765  * this memory bank, -EEXIST if the target memory bank does not exist
766  * or is not controllable, or returns 0 upon success.
767  */
768 int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
769 {
770         u32 m;
771
772         if (!pwrdm)
773                 return -EINVAL;
774
775         if (pwrdm->banks < (bank + 1))
776                 return -EEXIST;
777
778         if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
779                 return -EINVAL;
780
781         pr_debug("powerdomain: setting next memory powerstate for domain %s "
782                  "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst);
783
784         /*
785          * The register bit names below may not correspond to the
786          * actual names of the bits in each powerdomain's register,
787          * but the type of value returned is the same for each
788          * powerdomain.
789          */
790         switch (bank) {
791         case 0:
792                 m = OMAP3430_SHAREDL1CACHEFLATRETSTATE;
793                 break;
794         case 1:
795                 m = OMAP3430_L1FLATMEMRETSTATE;
796                 break;
797         case 2:
798                 m = OMAP3430_SHAREDL2CACHEFLATRETSTATE;
799                 break;
800         case 3:
801                 m = OMAP3430_L2FLATMEMRETSTATE;
802                 break;
803         default:
804                 WARN_ON(1); /* should never happen */
805                 return -EEXIST;
806         }
807
808         prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
809                              PM_PWSTCTRL);
810
811         return 0;
812 }
813
814 /**
815  * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
816  * @pwrdm: struct powerdomain * to get current logic retention power state
817  *
818  * Return the current power state that the logic portion of
819  * powerdomain pwrdm will enter
820  * Returns -EINVAL if the powerdomain pointer is null or returns the
821  * current logic retention power state upon success.
822  */
823 int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
824 {
825         if (!pwrdm)
826                 return -EINVAL;
827
828         return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
829                                         OMAP3430_LOGICSTATEST);
830 }
831
832 /**
833  * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
834  * @pwrdm: struct powerdomain * to get previous logic power state
835  *
836  * Return the powerdomain pwrdm's logic power state.  Returns -EINVAL
837  * if the powerdomain pointer is null or returns the previous logic
838  * power state upon success.
839  */
840 int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
841 {
842         if (!pwrdm)
843                 return -EINVAL;
844
845         /*
846          * The register bit names below may not correspond to the
847          * actual names of the bits in each powerdomain's register,
848          * but the type of value returned is the same for each
849          * powerdomain.
850          */
851         return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
852                                         OMAP3430_LASTLOGICSTATEENTERED);
853 }
854
855 /**
856  * pwrdm_read_mem_pwrst - get current memory bank power state
857  * @pwrdm: struct powerdomain * to get current memory bank power state
858  * @bank: memory bank number (0-3)
859  *
860  * Return the powerdomain pwrdm's current memory power state for bank
861  * x.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
862  * the target memory bank does not exist or is not controllable, or
863  * returns the current memory power state upon success.
864  */
865 int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
866 {
867         u32 m;
868
869         if (!pwrdm)
870                 return -EINVAL;
871
872         if (pwrdm->banks < (bank + 1))
873                 return -EEXIST;
874
875         /*
876          * The register bit names below may not correspond to the
877          * actual names of the bits in each powerdomain's register,
878          * but the type of value returned is the same for each
879          * powerdomain.
880          */
881         switch (bank) {
882         case 0:
883                 m = OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK;
884                 break;
885         case 1:
886                 m = OMAP3430_L1FLATMEMSTATEST_MASK;
887                 break;
888         case 2:
889                 m = OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK;
890                 break;
891         case 3:
892                 m = OMAP3430_L2FLATMEMSTATEST_MASK;
893                 break;
894         default:
895                 WARN_ON(1); /* should never happen */
896                 return -EEXIST;
897         }
898
899         return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, m);
900 }
901
902 /**
903  * pwrdm_read_prev_mem_pwrst - get previous memory bank power state
904  * @pwrdm: struct powerdomain * to get previous memory bank power state
905  * @bank: memory bank number (0-3)
906  *
907  * Return the powerdomain pwrdm's previous memory power state for bank
908  * x.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
909  * the target memory bank does not exist or is not controllable, or
910  * returns the previous memory power state upon success.
911  */
912 int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
913 {
914         u32 m;
915
916         if (!pwrdm)
917                 return -EINVAL;
918
919         if (pwrdm->banks < (bank + 1))
920                 return -EEXIST;
921
922         /*
923          * The register bit names below may not correspond to the
924          * actual names of the bits in each powerdomain's register,
925          * but the type of value returned is the same for each
926          * powerdomain.
927          */
928         switch (bank) {
929         case 0:
930                 m = OMAP3430_LASTMEM1STATEENTERED_MASK;
931                 break;
932         case 1:
933                 m = OMAP3430_LASTMEM2STATEENTERED_MASK;
934                 break;
935         case 2:
936                 m = OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
937                 break;
938         case 3:
939                 m = OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
940                 break;
941         default:
942                 WARN_ON(1); /* should never happen */
943                 return -EEXIST;
944         }
945
946         return prm_read_mod_bits_shift(pwrdm->prcm_offs,
947                                         OMAP3430_PM_PREPWSTST, m);
948 }
949
950 /**
951  * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
952  * @pwrdm: struct powerdomain * to clear
953  *
954  * Clear the powerdomain's previous power state register.  Clears the
955  * entire register, including logic and memory bank previous power states.
956  * Returns -EINVAL if the powerdomain pointer is null, or returns 0 upon
957  * success.
958  */
959 int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
960 {
961         if (!pwrdm)
962                 return -EINVAL;
963
964         /*
965          * XXX should get the powerdomain's current state here;
966          * warn & fail if it is not ON.
967          */
968
969         pr_debug("powerdomain: clearing previous power state reg for %s\n",
970                  pwrdm->name);
971
972         prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
973
974         return 0;
975 }
976
977 /**
978  * pwrdm_wait_transition - wait for powerdomain power transition to finish
979  * @pwrdm: struct powerdomain * to wait for
980  *
981  * If the powerdomain pwrdm is in the process of a state transition,
982  * spin until it completes the power transition, or until an iteration
983  * bailout value is reached. Returns -EINVAL if the powerdomain
984  * pointer is null, -EAGAIN if the bailout value was reached, or
985  * returns 0 upon success.
986  */
987 int pwrdm_wait_transition(struct powerdomain *pwrdm)
988 {
989         u32 c = 0;
990
991         if (!pwrdm)
992                 return -EINVAL;
993
994         /*
995          * REVISIT: pwrdm_wait_transition() may be better implemented
996          * via a callback and a periodic timer check -- how long do we expect
997          * powerdomain transitions to take?
998          */
999
1000         /* XXX Is this udelay() value meaningful? */
1001         while ((prm_read_mod_reg(pwrdm->prcm_offs, PM_PWSTST) &
1002                 OMAP_INTRANSITION) &&
1003                (c++ < PWRDM_TRANSITION_BAILOUT))
1004                 udelay(1);
1005
1006         if (c >= PWRDM_TRANSITION_BAILOUT) {
1007                 printk(KERN_ERR "powerdomain: waited too long for "
1008                        "powerdomain %s to complete transition\n", pwrdm->name);
1009                 return -EAGAIN;
1010         }
1011
1012         pr_debug("powerdomain: completed transition in %d loops\n", c);
1013
1014         return 0;
1015 }
1016
1017