]> git.karo-electronics.de Git - mv-sheeva.git/blob - arch/arm/mach-omap2/powerdomain44xx.c
2903c7cb2d5e183d51fb95f4882699f200b9b925
[mv-sheeva.git] / arch / arm / mach-omap2 / powerdomain44xx.c
1 /*
2  * OMAP4 powerdomain control
3  *
4  * Copyright (C) 2009-2010 Texas Instruments, Inc.
5  * Copyright (C) 2007-2009 Nokia Corporation
6  *
7  * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
8  * Rajendra Nayak <rnayak@ti.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  */
14
15 #include <linux/io.h>
16 #include <linux/errno.h>
17 #include <linux/delay.h>
18 #include <plat/powerdomain.h>
19 #include <plat/prcm.h>
20 #include "prm.h"
21 #include "prm-regbits-44xx.h"
22 #include "powerdomains.h"
23
24 static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
25 {
26         prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
27                                 (pwrst << OMAP_POWERSTATE_SHIFT),
28                                 pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
29         return 0;
30 }
31
32 static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
33 {
34         return prm_read_mod_bits_shift(pwrdm->prcm_offs,
35                                 OMAP4_PM_PWSTCTRL, OMAP_POWERSTATE_MASK);
36 }
37
38 static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm)
39 {
40         return prm_read_mod_bits_shift(pwrdm->prcm_offs,
41                                 OMAP4_PM_PWSTST, OMAP_POWERSTATEST_MASK);
42 }
43
44 static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
45 {
46         return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTST,
47                                 OMAP4430_LASTPOWERSTATEENTERED_MASK);
48 }
49
50 static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
51 {
52         prm_rmw_mod_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
53                                 (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
54                                 pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
55         return 0;
56 }
57
58 static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
59 {
60         prm_rmw_mod_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK,
61                                 OMAP4430_LASTPOWERSTATEENTERED_MASK,
62                                 pwrdm->prcm_offs, OMAP4_PM_PWSTST);
63         return 0;
64 }
65
66 static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
67 {
68         u32 v;
69
70         v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK);
71         prm_rmw_mod_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v,
72                                 pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
73
74         return 0;
75 }
76
77 static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
78                                                                 u8 pwrst)
79 {
80         u32 m;
81
82         m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
83
84         prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
85                                 OMAP4_PM_PWSTCTRL);
86
87         return 0;
88 }
89
90 static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
91                                                                 u8 pwrst)
92 {
93         u32 m;
94
95         m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
96
97         prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
98                                 OMAP4_PM_PWSTCTRL);
99
100         return 0;
101 }
102
103 static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
104 {
105         return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTST,
106                                 OMAP4430_LOGICSTATEST_MASK);
107 }
108
109 static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
110 {
111         return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL,
112                                 OMAP4430_LOGICRETSTATE_MASK);
113 }
114
115 static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
116 {
117         u32 m;
118
119         m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
120
121         return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTST, m);
122 }
123
124 static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
125 {
126         u32 m;
127
128         m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
129
130         return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL, m);
131 }
132
133 static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
134 {
135         u32 c = 0;
136
137         /*
138          * REVISIT: pwrdm_wait_transition() may be better implemented
139          * via a callback and a periodic timer check -- how long do we expect
140          * powerdomain transitions to take?
141          */
142
143         /* XXX Is this udelay() value meaningful? */
144         while ((prm_read_mod_reg(pwrdm->prcm_offs, OMAP4_PM_PWSTST) &
145                 OMAP_INTRANSITION_MASK) &&
146                 (c++ < PWRDM_TRANSITION_BAILOUT))
147                         udelay(1);
148
149         if (c > PWRDM_TRANSITION_BAILOUT) {
150                 printk(KERN_ERR "powerdomain: waited too long for "
151                         "powerdomain %s to complete transition\n", pwrdm->name);
152                 return -EAGAIN;
153         }
154
155         pr_debug("powerdomain: completed transition in %d loops\n", c);
156
157         return 0;
158 }
159
160 struct pwrdm_ops omap4_pwrdm_operations = {
161         .pwrdm_set_next_pwrst   = omap4_pwrdm_set_next_pwrst,
162         .pwrdm_read_next_pwrst  = omap4_pwrdm_read_next_pwrst,
163         .pwrdm_read_pwrst       = omap4_pwrdm_read_pwrst,
164         .pwrdm_read_prev_pwrst  = omap4_pwrdm_read_prev_pwrst,
165         .pwrdm_set_lowpwrstchange       = omap4_pwrdm_set_lowpwrstchange,
166         .pwrdm_clear_all_prev_pwrst     = omap4_pwrdm_clear_all_prev_pwrst,
167         .pwrdm_set_logic_retst  = omap4_pwrdm_set_logic_retst,
168         .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst,
169         .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst,
170         .pwrdm_read_mem_pwrst   = omap4_pwrdm_read_mem_pwrst,
171         .pwrdm_read_mem_retst   = omap4_pwrdm_read_mem_retst,
172         .pwrdm_set_mem_onst     = omap4_pwrdm_set_mem_onst,
173         .pwrdm_set_mem_retst    = omap4_pwrdm_set_mem_retst,
174         .pwrdm_wait_transition  = omap4_pwrdm_wait_transition,
175 };