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