diff options
author | Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com> | 2008-10-15 10:48:43 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2009-09-02 18:08:23 -0400 |
commit | ba20bb126940ce4847e146a0d00b7f7b0868d773 (patch) | |
tree | d9a8f3c316aa66261ba026e9bd2507fa4ec9a931 | |
parent | 36d568ec055cb3ac4507d38ebabba955cdbb443e (diff) |
OMAP: PM counter infrastructure.
This patch provides the infrastructure to count how many times a
powerdomain entered a given power state (on, inactive, retention,
off). A number of functions are provided which will be called by the
chip specific powerdomain and clockdomain code whenever a transition
might have happened.
Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
-rw-r--r-- | arch/arm/mach-omap2/clockdomain.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/powerdomain.c | 101 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/mach/powerdomain.h | 7 |
3 files changed, 108 insertions, 2 deletions
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 0e7d501865b6..26912a95dc18 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c | |||
@@ -484,6 +484,8 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm) | |||
484 | v << __ffs(clkdm->clktrctrl_mask), | 484 | v << __ffs(clkdm->clktrctrl_mask), |
485 | clkdm->pwrdm.ptr->prcm_offs, | 485 | clkdm->pwrdm.ptr->prcm_offs, |
486 | CM_CLKSTCTRL); | 486 | CM_CLKSTCTRL); |
487 | |||
488 | pwrdm_clkdm_state_switch(clkdm); | ||
487 | } | 489 | } |
488 | 490 | ||
489 | /** | 491 | /** |
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 983f1cb676be..a2d98718c6d7 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c | |||
@@ -35,6 +35,11 @@ | |||
35 | #include <mach/powerdomain.h> | 35 | #include <mach/powerdomain.h> |
36 | #include <mach/clockdomain.h> | 36 | #include <mach/clockdomain.h> |
37 | 37 | ||
38 | enum { | ||
39 | PWRDM_STATE_NOW = 0, | ||
40 | PWRDM_STATE_PREV, | ||
41 | }; | ||
42 | |||
38 | /* pwrdm_list contains all registered struct powerdomains */ | 43 | /* pwrdm_list contains all registered struct powerdomains */ |
39 | static LIST_HEAD(pwrdm_list); | 44 | static LIST_HEAD(pwrdm_list); |
40 | 45 | ||
@@ -102,6 +107,63 @@ static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm, | |||
102 | return pd->pwrdm; | 107 | return pd->pwrdm; |
103 | } | 108 | } |
104 | 109 | ||
110 | static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) | ||
111 | { | ||
112 | |||
113 | int prev; | ||
114 | int state; | ||
115 | |||
116 | if (pwrdm == NULL) | ||
117 | return -EINVAL; | ||
118 | |||
119 | state = pwrdm_read_pwrst(pwrdm); | ||
120 | |||
121 | switch (flag) { | ||
122 | case PWRDM_STATE_NOW: | ||
123 | prev = pwrdm->state; | ||
124 | break; | ||
125 | case PWRDM_STATE_PREV: | ||
126 | prev = pwrdm_read_prev_pwrst(pwrdm); | ||
127 | if (pwrdm->state != prev) | ||
128 | pwrdm->state_counter[prev]++; | ||
129 | break; | ||
130 | default: | ||
131 | return -EINVAL; | ||
132 | } | ||
133 | |||
134 | if (state != prev) | ||
135 | pwrdm->state_counter[state]++; | ||
136 | |||
137 | pwrdm->state = state; | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm) | ||
143 | { | ||
144 | pwrdm_clear_all_prev_pwrst(pwrdm); | ||
145 | _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm) | ||
150 | { | ||
151 | _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV); | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static __init void _pwrdm_setup(struct powerdomain *pwrdm) | ||
156 | { | ||
157 | int i; | ||
158 | |||
159 | for (i = 0; i < 4; i++) | ||
160 | pwrdm->state_counter[i] = 0; | ||
161 | |||
162 | pwrdm_wait_transition(pwrdm); | ||
163 | pwrdm->state = pwrdm_read_pwrst(pwrdm); | ||
164 | pwrdm->state_counter[pwrdm->state] = 1; | ||
165 | |||
166 | } | ||
105 | 167 | ||
106 | /* Public functions */ | 168 | /* Public functions */ |
107 | 169 | ||
@@ -117,9 +179,12 @@ void pwrdm_init(struct powerdomain **pwrdm_list) | |||
117 | { | 179 | { |
118 | struct powerdomain **p = NULL; | 180 | struct powerdomain **p = NULL; |
119 | 181 | ||
120 | if (pwrdm_list) | 182 | if (pwrdm_list) { |
121 | for (p = pwrdm_list; *p; p++) | 183 | for (p = pwrdm_list; *p; p++) { |
122 | pwrdm_register(*p); | 184 | pwrdm_register(*p); |
185 | _pwrdm_setup(*p); | ||
186 | } | ||
187 | } | ||
123 | } | 188 | } |
124 | 189 | ||
125 | /** | 190 | /** |
@@ -1110,4 +1175,36 @@ int pwrdm_wait_transition(struct powerdomain *pwrdm) | |||
1110 | return 0; | 1175 | return 0; |
1111 | } | 1176 | } |
1112 | 1177 | ||
1178 | int pwrdm_state_switch(struct powerdomain *pwrdm) | ||
1179 | { | ||
1180 | return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); | ||
1181 | } | ||
1182 | |||
1183 | int pwrdm_clkdm_state_switch(struct clockdomain *clkdm) | ||
1184 | { | ||
1185 | if (clkdm != NULL && clkdm->pwrdm.ptr != NULL) { | ||
1186 | pwrdm_wait_transition(clkdm->pwrdm.ptr); | ||
1187 | return pwrdm_state_switch(clkdm->pwrdm.ptr); | ||
1188 | } | ||
1189 | |||
1190 | return -EINVAL; | ||
1191 | } | ||
1192 | int pwrdm_clk_state_switch(struct clk *clk) | ||
1193 | { | ||
1194 | if (clk != NULL && clk->clkdm != NULL) | ||
1195 | return pwrdm_clkdm_state_switch(clk->clkdm); | ||
1196 | return -EINVAL; | ||
1197 | } | ||
1198 | |||
1199 | int pwrdm_pre_transition(void) | ||
1200 | { | ||
1201 | pwrdm_for_each(_pwrdm_pre_transition_cb); | ||
1202 | return 0; | ||
1203 | } | ||
1204 | |||
1205 | int pwrdm_post_transition(void) | ||
1206 | { | ||
1207 | pwrdm_for_each(_pwrdm_post_transition_cb); | ||
1208 | return 0; | ||
1209 | } | ||
1113 | 1210 | ||
diff --git a/arch/arm/plat-omap/include/mach/powerdomain.h b/arch/arm/plat-omap/include/mach/powerdomain.h index 69c9e675d8ee..52663fc549d2 100644 --- a/arch/arm/plat-omap/include/mach/powerdomain.h +++ b/arch/arm/plat-omap/include/mach/powerdomain.h | |||
@@ -117,6 +117,8 @@ struct powerdomain { | |||
117 | 117 | ||
118 | struct list_head node; | 118 | struct list_head node; |
119 | 119 | ||
120 | int state; | ||
121 | unsigned state_counter[4]; | ||
120 | }; | 122 | }; |
121 | 123 | ||
122 | 124 | ||
@@ -164,4 +166,9 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm); | |||
164 | 166 | ||
165 | int pwrdm_wait_transition(struct powerdomain *pwrdm); | 167 | int pwrdm_wait_transition(struct powerdomain *pwrdm); |
166 | 168 | ||
169 | int pwrdm_state_switch(struct powerdomain *pwrdm); | ||
170 | int pwrdm_clkdm_state_switch(struct clockdomain *clkdm); | ||
171 | int pwrdm_pre_transition(void); | ||
172 | int pwrdm_post_transition(void); | ||
173 | |||
167 | #endif | 174 | #endif |