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