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