OMAP: powerdomain: Arch specific funcs for logic 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         int ret = -EINVAL;
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         if (arch_pwrdm && arch_pwrdm->pwrdm_set_logic_retst)
547                 ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, pwrst);
548
549         return ret;
550 }
551
552 /**
553  * pwrdm_set_mem_onst - set memory power state while powerdomain ON
554  * @pwrdm: struct powerdomain * to set
555  * @bank: memory bank number to set (0-3)
556  * @pwrst: one of the PWRDM_POWER_* macros
557  *
558  * Set the next power state @pwrst that memory bank @bank of the
559  * powerdomain @pwrdm will enter when the powerdomain enters the ON
560  * state.  @bank will be a number from 0 to 3, and represents different
561  * types of memory, depending on the powerdomain.  Returns -EINVAL if
562  * the powerdomain pointer is null or the target power state is not
563  * not supported for this memory bank, -EEXIST if the target memory
564  * bank does not exist or is not controllable, or returns 0 upon
565  * success.
566  */
567 int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
568 {
569         u32 m;
570
571         if (!pwrdm)
572                 return -EINVAL;
573
574         if (pwrdm->banks < (bank + 1))
575                 return -EEXIST;
576
577         if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
578                 return -EINVAL;
579
580         pr_debug("powerdomain: setting next memory powerstate for domain %s "
581                  "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst);
582
583         /*
584          * The register bit names below may not correspond to the
585          * actual names of the bits in each powerdomain's register,
586          * but the type of value returned is the same for each
587          * powerdomain.
588          */
589         switch (bank) {
590         case 0:
591                 m = OMAP_MEM0_ONSTATE_MASK;
592                 break;
593         case 1:
594                 m = OMAP_MEM1_ONSTATE_MASK;
595                 break;
596         case 2:
597                 m = OMAP_MEM2_ONSTATE_MASK;
598                 break;
599         case 3:
600                 m = OMAP_MEM3_ONSTATE_MASK;
601                 break;
602         case 4:
603                 m = OMAP_MEM4_ONSTATE_MASK;
604                 break;
605         default:
606                 WARN_ON(1); /* should never happen */
607                 return -EEXIST;
608         }
609
610         prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)),
611                              pwrdm->prcm_offs, pwrstctrl_reg_offs);
612
613         return 0;
614 }
615
616 /**
617  * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
618  * @pwrdm: struct powerdomain * to set
619  * @bank: memory bank number to set (0-3)
620  * @pwrst: one of the PWRDM_POWER_* macros
621  *
622  * Set the next power state @pwrst that memory bank @bank of the
623  * powerdomain @pwrdm will enter when the powerdomain enters the
624  * RETENTION state.  Bank will be a number from 0 to 3, and represents
625  * different types of memory, depending on the powerdomain.  @pwrst
626  * will be either RETENTION or OFF, if supported.  Returns -EINVAL if
627  * the powerdomain pointer is null or the target power state is not
628  * not supported for this memory bank, -EEXIST if the target memory
629  * bank does not exist or is not controllable, or returns 0 upon
630  * success.
631  */
632 int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
633 {
634         u32 m;
635
636         if (!pwrdm)
637                 return -EINVAL;
638
639         if (pwrdm->banks < (bank + 1))
640                 return -EEXIST;
641
642         if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
643                 return -EINVAL;
644
645         pr_debug("powerdomain: setting next memory powerstate for domain %s "
646                  "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst);
647
648         /*
649          * The register bit names below may not correspond to the
650          * actual names of the bits in each powerdomain's register,
651          * but the type of value returned is the same for each
652          * powerdomain.
653          */
654         switch (bank) {
655         case 0:
656                 m = OMAP_MEM0_RETSTATE_MASK;
657                 break;
658         case 1:
659                 m = OMAP_MEM1_RETSTATE_MASK;
660                 break;
661         case 2:
662                 m = OMAP_MEM2_RETSTATE_MASK;
663                 break;
664         case 3:
665                 m = OMAP_MEM3_RETSTATE_MASK;
666                 break;
667         case 4:
668                 m = OMAP_MEM4_RETSTATE_MASK;
669                 break;
670         default:
671                 WARN_ON(1); /* should never happen */
672                 return -EEXIST;
673         }
674
675         prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
676                              pwrstctrl_reg_offs);
677
678         return 0;
679 }
680
681 /**
682  * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
683  * @pwrdm: struct powerdomain * to get current logic retention power state
684  *
685  * Return the power state that the logic portion of powerdomain @pwrdm
686  * will enter when the powerdomain enters retention.  Returns -EINVAL
687  * if the powerdomain pointer is null or returns the logic retention
688  * power state upon success.
689  */
690 int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
691 {
692         int ret = -EINVAL;
693
694         if (!pwrdm)
695                 return -EINVAL;
696
697         if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_pwrst)
698                 ret = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm);
699
700         return ret;
701 }
702
703 /**
704  * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
705  * @pwrdm: struct powerdomain * to get previous logic power state
706  *
707  * Return the powerdomain @pwrdm's previous logic power state.  Returns
708  * -EINVAL if the powerdomain pointer is null or returns the previous
709  * logic power state upon success.
710  */
711 int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
712 {
713         int ret = -EINVAL;
714
715         if (!pwrdm)
716                 return -EINVAL;
717
718         if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_logic_pwrst)
719                 ret = arch_pwrdm->pwrdm_read_prev_logic_pwrst(pwrdm);
720
721         return ret;
722 }
723
724 /**
725  * pwrdm_read_logic_retst - get next powerdomain logic power state
726  * @pwrdm: struct powerdomain * to get next logic power state
727  *
728  * Return the powerdomain pwrdm's logic power state.  Returns -EINVAL
729  * if the powerdomain pointer is null or returns the next logic
730  * power state upon success.
731  */
732 int pwrdm_read_logic_retst(struct powerdomain *pwrdm)
733 {
734         int ret = -EINVAL;
735
736         if (!pwrdm)
737                 return -EINVAL;
738
739         if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_retst)
740                 ret = arch_pwrdm->pwrdm_read_logic_retst(pwrdm);
741
742         return ret;
743 }
744
745 /**
746  * pwrdm_read_mem_pwrst - get current memory bank power state
747  * @pwrdm: struct powerdomain * to get current memory bank power state
748  * @bank: memory bank number (0-3)
749  *
750  * Return the powerdomain @pwrdm's current memory power state for bank
751  * @bank.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
752  * the target memory bank does not exist or is not controllable, or
753  * returns the current memory power state upon success.
754  */
755 int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
756 {
757         u32 m;
758
759         if (!pwrdm)
760                 return -EINVAL;
761
762         if (pwrdm->banks < (bank + 1))
763                 return -EEXIST;
764
765         if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
766                 bank = 1;
767
768         /*
769          * The register bit names below may not correspond to the
770          * actual names of the bits in each powerdomain's register,
771          * but the type of value returned is the same for each
772          * powerdomain.
773          */
774         switch (bank) {
775         case 0:
776                 m = OMAP_MEM0_STATEST_MASK;
777                 break;
778         case 1:
779                 m = OMAP_MEM1_STATEST_MASK;
780                 break;
781         case 2:
782                 m = OMAP_MEM2_STATEST_MASK;
783                 break;
784         case 3:
785                 m = OMAP_MEM3_STATEST_MASK;
786                 break;
787         case 4:
788                 m = OMAP_MEM4_STATEST_MASK;
789                 break;
790         default:
791                 WARN_ON(1); /* should never happen */
792                 return -EEXIST;
793         }
794
795         return prm_read_mod_bits_shift(pwrdm->prcm_offs,
796                                          pwrstst_reg_offs, m);
797 }
798
799 /**
800  * pwrdm_read_prev_mem_pwrst - get previous memory bank power state
801  * @pwrdm: struct powerdomain * to get previous memory bank power state
802  * @bank: memory bank number (0-3)
803  *
804  * Return the powerdomain @pwrdm's previous memory power state for
805  * bank @bank.  Returns -EINVAL if the powerdomain pointer is null,
806  * -EEXIST if the target memory bank does not exist or is not
807  * controllable, or returns the previous memory power state upon
808  * success.
809  */
810 int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
811 {
812         u32 m;
813
814         if (!pwrdm)
815                 return -EINVAL;
816
817         if (pwrdm->banks < (bank + 1))
818                 return -EEXIST;
819
820         if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
821                 bank = 1;
822
823         /*
824          * The register bit names below may not correspond to the
825          * actual names of the bits in each powerdomain's register,
826          * but the type of value returned is the same for each
827          * powerdomain.
828          */
829         switch (bank) {
830         case 0:
831                 m = OMAP3430_LASTMEM1STATEENTERED_MASK;
832                 break;
833         case 1:
834                 m = OMAP3430_LASTMEM2STATEENTERED_MASK;
835                 break;
836         case 2:
837                 m = OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
838                 break;
839         case 3:
840                 m = OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
841                 break;
842         default:
843                 WARN_ON(1); /* should never happen */
844                 return -EEXIST;
845         }
846
847         return prm_read_mod_bits_shift(pwrdm->prcm_offs,
848                                         OMAP3430_PM_PREPWSTST, m);
849 }
850
851 /**
852  * pwrdm_read_mem_retst - get next memory bank power state
853  * @pwrdm: struct powerdomain * to get mext memory bank power state
854  * @bank: memory bank number (0-3)
855  *
856  * Return the powerdomain pwrdm's next memory power state for bank
857  * x.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
858  * the target memory bank does not exist or is not controllable, or
859  * returns the next memory power state upon success.
860  */
861 int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
862 {
863         u32 m;
864
865         if (!pwrdm)
866                 return -EINVAL;
867
868         if (pwrdm->banks < (bank + 1))
869                 return -EEXIST;
870
871         /*
872          * The register bit names below may not correspond to the
873          * actual names of the bits in each powerdomain's register,
874          * but the type of value returned is the same for each
875          * powerdomain.
876          */
877         switch (bank) {
878         case 0:
879                 m = OMAP_MEM0_RETSTATE_MASK;
880                 break;
881         case 1:
882                 m = OMAP_MEM1_RETSTATE_MASK;
883                 break;
884         case 2:
885                 m = OMAP_MEM2_RETSTATE_MASK;
886                 break;
887         case 3:
888                 m = OMAP_MEM3_RETSTATE_MASK;
889                 break;
890         case 4:
891                 m = OMAP_MEM4_RETSTATE_MASK;
892                 break;
893         default:
894                 WARN_ON(1); /* should never happen */
895                 return -EEXIST;
896         }
897
898         return prm_read_mod_bits_shift(pwrdm->prcm_offs,
899                                         pwrstctrl_reg_offs, m);
900 }
901
902 /**
903  * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
904  * @pwrdm: struct powerdomain * to clear
905  *
906  * Clear the powerdomain's previous power state register @pwrdm.
907  * Clears the entire register, including logic and memory bank
908  * previous power states.  Returns -EINVAL if the powerdomain pointer
909  * is null, or returns 0 upon success.
910  */
911 int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
912 {
913         if (!pwrdm)
914                 return -EINVAL;
915
916         /*
917          * XXX should get the powerdomain's current state here;
918          * warn & fail if it is not ON.
919          */
920
921         pr_debug("powerdomain: clearing previous power state reg for %s\n",
922                  pwrdm->name);
923
924         prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
925
926         return 0;
927 }
928
929 /**
930  * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm
931  * @pwrdm: struct powerdomain *
932  *
933  * Enable automatic context save-and-restore upon power state change
934  * for some devices in the powerdomain @pwrdm.  Warning: this only
935  * affects a subset of devices in a powerdomain; check the TRM
936  * closely.  Returns -EINVAL if the powerdomain pointer is null or if
937  * the powerdomain does not support automatic save-and-restore, or
938  * returns 0 upon success.
939  */
940 int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
941 {
942         if (!pwrdm)
943                 return -EINVAL;
944
945         if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
946                 return -EINVAL;
947
948         pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n",
949                  pwrdm->name);
950
951         prm_rmw_mod_reg_bits(0, 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
952                              pwrdm->prcm_offs, pwrstctrl_reg_offs);
953
954         return 0;
955 }
956
957 /**
958  * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm
959  * @pwrdm: struct powerdomain *
960  *
961  * Disable automatic context save-and-restore upon power state change
962  * for some devices in the powerdomain @pwrdm.  Warning: this only
963  * affects a subset of devices in a powerdomain; check the TRM
964  * closely.  Returns -EINVAL if the powerdomain pointer is null or if
965  * the powerdomain does not support automatic save-and-restore, or
966  * returns 0 upon success.
967  */
968 int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
969 {
970         if (!pwrdm)
971                 return -EINVAL;
972
973         if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
974                 return -EINVAL;
975
976         pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n",
977                  pwrdm->name);
978
979         prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 0,
980                              pwrdm->prcm_offs, pwrstctrl_reg_offs);
981
982         return 0;
983 }
984
985 /**
986  * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
987  * @pwrdm: struct powerdomain *
988  *
989  * Returns 1 if powerdomain @pwrdm supports hardware save-and-restore
990  * for some devices, or 0 if it does not.
991  */
992 bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
993 {
994         return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
995 }
996
997 /**
998  * pwrdm_set_lowpwrstchange - Request a low power state change
999  * @pwrdm: struct powerdomain *
1000  *
1001  * Allows a powerdomain to transtion to a lower power sleep state
1002  * from an existing sleep state without waking up the powerdomain.
1003  * Returns -EINVAL if the powerdomain pointer is null or if the
1004  * powerdomain does not support LOWPOWERSTATECHANGE, or returns 0
1005  * upon success.
1006  */
1007 int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
1008 {
1009         if (!pwrdm)
1010                 return -EINVAL;
1011
1012         if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE))
1013                 return -EINVAL;
1014
1015         pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n",
1016                  pwrdm->name);
1017
1018         prm_rmw_mod_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
1019                              (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
1020                              pwrdm->prcm_offs, pwrstctrl_reg_offs);
1021
1022         return 0;
1023 }
1024
1025 /**
1026  * pwrdm_wait_transition - wait for powerdomain power transition to finish
1027  * @pwrdm: struct powerdomain * to wait for
1028  *
1029  * If the powerdomain @pwrdm is in the process of a state transition,
1030  * spin until it completes the power transition, or until an iteration
1031  * bailout value is reached. Returns -EINVAL if the powerdomain
1032  * pointer is null, -EAGAIN if the bailout value was reached, or
1033  * returns 0 upon success.
1034  */
1035 int pwrdm_wait_transition(struct powerdomain *pwrdm)
1036 {
1037         u32 c = 0;
1038
1039         if (!pwrdm)
1040                 return -EINVAL;
1041
1042         /*
1043          * REVISIT: pwrdm_wait_transition() may be better implemented
1044          * via a callback and a periodic timer check -- how long do we expect
1045          * powerdomain transitions to take?
1046          */
1047
1048         /* XXX Is this udelay() value meaningful? */
1049         while ((prm_read_mod_reg(pwrdm->prcm_offs, pwrstst_reg_offs) &
1050                 OMAP_INTRANSITION_MASK) &&
1051                (c++ < PWRDM_TRANSITION_BAILOUT))
1052                         udelay(1);
1053
1054         if (c > PWRDM_TRANSITION_BAILOUT) {
1055                 printk(KERN_ERR "powerdomain: waited too long for "
1056                        "powerdomain %s to complete transition\n", pwrdm->name);
1057                 return -EAGAIN;
1058         }
1059
1060         pr_debug("powerdomain: completed transition in %d loops\n", c);
1061
1062         return 0;
1063 }
1064
1065 int pwrdm_state_switch(struct powerdomain *pwrdm)
1066 {
1067         return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
1068 }
1069
1070 int pwrdm_clkdm_state_switch(struct clockdomain *clkdm)
1071 {
1072         if (clkdm != NULL && clkdm->pwrdm.ptr != NULL) {
1073                 pwrdm_wait_transition(clkdm->pwrdm.ptr);
1074                 return pwrdm_state_switch(clkdm->pwrdm.ptr);
1075         }
1076
1077         return -EINVAL;
1078 }
1079
1080 int pwrdm_pre_transition(void)
1081 {
1082         pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
1083         return 0;
1084 }
1085
1086 int pwrdm_post_transition(void)
1087 {
1088         pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
1089         return 0;
1090 }