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