Commit 35e75d51d235b5bcfb78c8401c906708f7064cb6

Authored by Vaibhav Bedia
Committed by Afzal Mohammed
1 parent afa54fe7c2
Exists in master

OMAP: voltage: add a hook for normal regulator calls

TI processors in TI81x and AM33x family work with PMICs like
TPS65910/1 which are not part of the TWL series. These processors
also do not have a voltage controller/processor module.

In order to invoke the normal regulator calls from the voltage
layer the following changes are done to struct voltagedomain
	- Add a flag use_regulator for the SoC voltagedomain
	  code to indicate its intention of using a PMIC which
	  is not controlled by VC/VP
	- Add a regulator_init callback which the platform code
	  can utilise for any custom init sequence before making
	  use of the regulator. Platform code is also expected
	  to set the voltdm->scale function in the init callback

Signed-off-by: Ravikumar Kattekola <rk@ti.com>
Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>

Showing 2 changed files with 9 additions and 0 deletions Inline Diff

arch/arm/mach-omap2/voltage.c
1 /* 1 /*
2 * OMAP3/OMAP4 Voltage Management Routines 2 * OMAP3/OMAP4 Voltage Management Routines
3 * 3 *
4 * Author: Thara Gopinath <thara@ti.com> 4 * Author: Thara Gopinath <thara@ti.com>
5 * 5 *
6 * Copyright (C) 2007 Texas Instruments, Inc. 6 * Copyright (C) 2007 Texas Instruments, Inc.
7 * Rajendra Nayak <rnayak@ti.com> 7 * Rajendra Nayak <rnayak@ti.com>
8 * Lesly A M <x0080970@ti.com> 8 * Lesly A M <x0080970@ti.com>
9 * 9 *
10 * Copyright (C) 2008, 2011 Nokia Corporation 10 * Copyright (C) 2008, 2011 Nokia Corporation
11 * Kalle Jokiniemi 11 * Kalle Jokiniemi
12 * Paul Walmsley 12 * Paul Walmsley
13 * 13 *
14 * Copyright (C) 2010 Texas Instruments, Inc. 14 * Copyright (C) 2010 Texas Instruments, Inc.
15 * Thara Gopinath <thara@ti.com> 15 * Thara Gopinath <thara@ti.com>
16 * 16 *
17 * This program is free software; you can redistribute it and/or modify 17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as 18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation. 19 * published by the Free Software Foundation.
20 */ 20 */
21 21
22 #include <linux/delay.h> 22 #include <linux/delay.h>
23 #include <linux/io.h> 23 #include <linux/io.h>
24 #include <linux/err.h> 24 #include <linux/err.h>
25 #include <linux/debugfs.h> 25 #include <linux/debugfs.h>
26 #include <linux/slab.h> 26 #include <linux/slab.h>
27 #include <linux/clk.h> 27 #include <linux/clk.h>
28 28
29 #include <plat/common.h> 29 #include <plat/common.h>
30 #include <plat/voltage.h> 30 #include <plat/voltage.h>
31 #include <plat/vc.h> 31 #include <plat/vc.h>
32 #include <plat/vp.h> 32 #include <plat/vp.h>
33 33
34 #include "prm-regbits-34xx.h" 34 #include "prm-regbits-34xx.h"
35 #include "prm-regbits-44xx.h" 35 #include "prm-regbits-44xx.h"
36 #include "prm44xx.h" 36 #include "prm44xx.h"
37 #include "prcm44xx.h" 37 #include "prcm44xx.h"
38 #include "prminst44xx.h" 38 #include "prminst44xx.h"
39 #include "control.h" 39 #include "control.h"
40 40
41 #include "powerdomain.h" 41 #include "powerdomain.h"
42 42
43 static LIST_HEAD(voltdm_list); 43 static LIST_HEAD(voltdm_list);
44 44
45 /* Public functions */ 45 /* Public functions */
46 /** 46 /**
47 * voltdm_get_voltage() - Gets the current non-auto-compensated voltage 47 * voltdm_get_voltage() - Gets the current non-auto-compensated voltage
48 * @voltdm: pointer to the voltdm for which current voltage info is needed 48 * @voltdm: pointer to the voltdm for which current voltage info is needed
49 * 49 *
50 * API to get the current non-auto-compensated voltage for a voltage domain. 50 * API to get the current non-auto-compensated voltage for a voltage domain.
51 * Returns 0 in case of error else returns the current voltage. 51 * Returns 0 in case of error else returns the current voltage.
52 */ 52 */
53 unsigned long voltdm_get_voltage(struct voltagedomain *voltdm) 53 unsigned long voltdm_get_voltage(struct voltagedomain *voltdm)
54 { 54 {
55 if (!voltdm || IS_ERR(voltdm)) { 55 if (!voltdm || IS_ERR(voltdm)) {
56 pr_warning("%s: VDD specified does not exist!\n", __func__); 56 pr_warning("%s: VDD specified does not exist!\n", __func__);
57 return 0; 57 return 0;
58 } 58 }
59 59
60 return voltdm->nominal_volt; 60 return voltdm->nominal_volt;
61 } 61 }
62 62
63 /** 63 /**
64 * voltdm_scale() - API to scale voltage of a particular voltage domain. 64 * voltdm_scale() - API to scale voltage of a particular voltage domain.
65 * @voltdm: pointer to the voltage domain which is to be scaled. 65 * @voltdm: pointer to the voltage domain which is to be scaled.
66 * @target_volt: The target voltage of the voltage domain 66 * @target_volt: The target voltage of the voltage domain
67 * 67 *
68 * This API should be called by the kernel to do the voltage scaling 68 * This API should be called by the kernel to do the voltage scaling
69 * for a particular voltage domain during DVFS. 69 * for a particular voltage domain during DVFS.
70 */ 70 */
71 int voltdm_scale(struct voltagedomain *voltdm, 71 int voltdm_scale(struct voltagedomain *voltdm,
72 unsigned long target_volt) 72 unsigned long target_volt)
73 { 73 {
74 int ret; 74 int ret;
75 75
76 if (!voltdm || IS_ERR(voltdm)) { 76 if (!voltdm || IS_ERR(voltdm)) {
77 pr_warning("%s: VDD specified does not exist!\n", __func__); 77 pr_warning("%s: VDD specified does not exist!\n", __func__);
78 return -EINVAL; 78 return -EINVAL;
79 } 79 }
80 80
81 if (!voltdm->scale) { 81 if (!voltdm->scale) {
82 pr_err("%s: No voltage scale API registered for vdd_%s\n", 82 pr_err("%s: No voltage scale API registered for vdd_%s\n",
83 __func__, voltdm->name); 83 __func__, voltdm->name);
84 return -ENODATA; 84 return -ENODATA;
85 } 85 }
86 86
87 ret = voltdm->scale(voltdm, target_volt); 87 ret = voltdm->scale(voltdm, target_volt);
88 if (!ret) 88 if (!ret)
89 voltdm->nominal_volt = target_volt; 89 voltdm->nominal_volt = target_volt;
90 90
91 return ret; 91 return ret;
92 } 92 }
93 93
94 /** 94 /**
95 * voltdm_reset() - Resets the voltage of a particular voltage domain 95 * voltdm_reset() - Resets the voltage of a particular voltage domain
96 * to that of the current OPP. 96 * to that of the current OPP.
97 * @voltdm: pointer to the voltage domain whose voltage is to be reset. 97 * @voltdm: pointer to the voltage domain whose voltage is to be reset.
98 * 98 *
99 * This API finds out the correct voltage the voltage domain is supposed 99 * This API finds out the correct voltage the voltage domain is supposed
100 * to be at and resets the voltage to that level. Should be used especially 100 * to be at and resets the voltage to that level. Should be used especially
101 * while disabling any voltage compensation modules. 101 * while disabling any voltage compensation modules.
102 */ 102 */
103 void voltdm_reset(struct voltagedomain *voltdm) 103 void voltdm_reset(struct voltagedomain *voltdm)
104 { 104 {
105 unsigned long target_volt; 105 unsigned long target_volt;
106 106
107 if (!voltdm || IS_ERR(voltdm)) { 107 if (!voltdm || IS_ERR(voltdm)) {
108 pr_warning("%s: VDD specified does not exist!\n", __func__); 108 pr_warning("%s: VDD specified does not exist!\n", __func__);
109 return; 109 return;
110 } 110 }
111 111
112 target_volt = voltdm_get_voltage(voltdm); 112 target_volt = voltdm_get_voltage(voltdm);
113 if (!target_volt) { 113 if (!target_volt) {
114 pr_err("%s: unable to find current voltage for vdd_%s\n", 114 pr_err("%s: unable to find current voltage for vdd_%s\n",
115 __func__, voltdm->name); 115 __func__, voltdm->name);
116 return; 116 return;
117 } 117 }
118 118
119 voltdm_scale(voltdm, target_volt); 119 voltdm_scale(voltdm, target_volt);
120 } 120 }
121 121
122 /** 122 /**
123 * omap_voltage_get_volttable() - API to get the voltage table associated with a 123 * omap_voltage_get_volttable() - API to get the voltage table associated with a
124 * particular voltage domain. 124 * particular voltage domain.
125 * @voltdm: pointer to the VDD for which the voltage table is required 125 * @voltdm: pointer to the VDD for which the voltage table is required
126 * @volt_data: the voltage table for the particular vdd which is to be 126 * @volt_data: the voltage table for the particular vdd which is to be
127 * populated by this API 127 * populated by this API
128 * 128 *
129 * This API populates the voltage table associated with a VDD into the 129 * This API populates the voltage table associated with a VDD into the
130 * passed parameter pointer. Returns the count of distinct voltages 130 * passed parameter pointer. Returns the count of distinct voltages
131 * supported by this vdd. 131 * supported by this vdd.
132 * 132 *
133 */ 133 */
134 void omap_voltage_get_volttable(struct voltagedomain *voltdm, 134 void omap_voltage_get_volttable(struct voltagedomain *voltdm,
135 struct omap_volt_data **volt_data) 135 struct omap_volt_data **volt_data)
136 { 136 {
137 if (!voltdm || IS_ERR(voltdm)) { 137 if (!voltdm || IS_ERR(voltdm)) {
138 pr_warning("%s: VDD specified does not exist!\n", __func__); 138 pr_warning("%s: VDD specified does not exist!\n", __func__);
139 return; 139 return;
140 } 140 }
141 141
142 *volt_data = voltdm->volt_data; 142 *volt_data = voltdm->volt_data;
143 } 143 }
144 144
145 /** 145 /**
146 * omap_voltage_get_voltdata() - API to get the voltage table entry for a 146 * omap_voltage_get_voltdata() - API to get the voltage table entry for a
147 * particular voltage 147 * particular voltage
148 * @voltdm: pointer to the VDD whose voltage table has to be searched 148 * @voltdm: pointer to the VDD whose voltage table has to be searched
149 * @volt: the voltage to be searched in the voltage table 149 * @volt: the voltage to be searched in the voltage table
150 * 150 *
151 * This API searches through the voltage table for the required voltage 151 * This API searches through the voltage table for the required voltage
152 * domain and tries to find a matching entry for the passed voltage volt. 152 * domain and tries to find a matching entry for the passed voltage volt.
153 * If a matching entry is found volt_data is populated with that entry. 153 * If a matching entry is found volt_data is populated with that entry.
154 * This API searches only through the non-compensated voltages int the 154 * This API searches only through the non-compensated voltages int the
155 * voltage table. 155 * voltage table.
156 * Returns pointer to the voltage table entry corresponding to volt on 156 * Returns pointer to the voltage table entry corresponding to volt on
157 * success. Returns -ENODATA if no voltage table exisits for the passed voltage 157 * success. Returns -ENODATA if no voltage table exisits for the passed voltage
158 * domain or if there is no matching entry. 158 * domain or if there is no matching entry.
159 */ 159 */
160 struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm, 160 struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
161 unsigned long volt) 161 unsigned long volt)
162 { 162 {
163 int i; 163 int i;
164 164
165 if (!voltdm || IS_ERR(voltdm)) { 165 if (!voltdm || IS_ERR(voltdm)) {
166 pr_warning("%s: VDD specified does not exist!\n", __func__); 166 pr_warning("%s: VDD specified does not exist!\n", __func__);
167 return ERR_PTR(-EINVAL); 167 return ERR_PTR(-EINVAL);
168 } 168 }
169 169
170 if (!voltdm->volt_data) { 170 if (!voltdm->volt_data) {
171 pr_warning("%s: voltage table does not exist for vdd_%s\n", 171 pr_warning("%s: voltage table does not exist for vdd_%s\n",
172 __func__, voltdm->name); 172 __func__, voltdm->name);
173 return ERR_PTR(-ENODATA); 173 return ERR_PTR(-ENODATA);
174 } 174 }
175 175
176 for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) { 176 for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) {
177 if (voltdm->volt_data[i].volt_nominal == volt) 177 if (voltdm->volt_data[i].volt_nominal == volt)
178 return &voltdm->volt_data[i]; 178 return &voltdm->volt_data[i];
179 } 179 }
180 180
181 pr_notice("%s: Unable to match the current voltage with the voltage" 181 pr_notice("%s: Unable to match the current voltage with the voltage"
182 "table for vdd_%s\n", __func__, voltdm->name); 182 "table for vdd_%s\n", __func__, voltdm->name);
183 183
184 return ERR_PTR(-ENODATA); 184 return ERR_PTR(-ENODATA);
185 } 185 }
186 186
187 /** 187 /**
188 * omap_voltage_register_pmic() - API to register PMIC specific data 188 * omap_voltage_register_pmic() - API to register PMIC specific data
189 * @voltdm: pointer to the VDD for which the PMIC specific data is 189 * @voltdm: pointer to the VDD for which the PMIC specific data is
190 * to be registered 190 * to be registered
191 * @pmic: the structure containing pmic info 191 * @pmic: the structure containing pmic info
192 * 192 *
193 * This API is to be called by the SOC/PMIC file to specify the 193 * This API is to be called by the SOC/PMIC file to specify the
194 * pmic specific info as present in omap_voltdm_pmic structure. 194 * pmic specific info as present in omap_voltdm_pmic structure.
195 */ 195 */
196 int omap_voltage_register_pmic(struct voltagedomain *voltdm, 196 int omap_voltage_register_pmic(struct voltagedomain *voltdm,
197 struct omap_voltdm_pmic *pmic) 197 struct omap_voltdm_pmic *pmic)
198 { 198 {
199 if (!voltdm || IS_ERR(voltdm)) { 199 if (!voltdm || IS_ERR(voltdm)) {
200 pr_warning("%s: VDD specified does not exist!\n", __func__); 200 pr_warning("%s: VDD specified does not exist!\n", __func__);
201 return -EINVAL; 201 return -EINVAL;
202 } 202 }
203 203
204 voltdm->pmic = pmic; 204 voltdm->pmic = pmic;
205 205
206 return 0; 206 return 0;
207 } 207 }
208 208
209 /** 209 /**
210 * omap_change_voltscale_method() - API to change the voltage scaling method. 210 * omap_change_voltscale_method() - API to change the voltage scaling method.
211 * @voltdm: pointer to the VDD whose voltage scaling method 211 * @voltdm: pointer to the VDD whose voltage scaling method
212 * has to be changed. 212 * has to be changed.
213 * @voltscale_method: the method to be used for voltage scaling. 213 * @voltscale_method: the method to be used for voltage scaling.
214 * 214 *
215 * This API can be used by the board files to change the method of voltage 215 * This API can be used by the board files to change the method of voltage
216 * scaling between vpforceupdate and vcbypass. The parameter values are 216 * scaling between vpforceupdate and vcbypass. The parameter values are
217 * defined in voltage.h 217 * defined in voltage.h
218 */ 218 */
219 void omap_change_voltscale_method(struct voltagedomain *voltdm, 219 void omap_change_voltscale_method(struct voltagedomain *voltdm,
220 int voltscale_method) 220 int voltscale_method)
221 { 221 {
222 if (!voltdm || IS_ERR(voltdm)) { 222 if (!voltdm || IS_ERR(voltdm)) {
223 pr_warning("%s: VDD specified does not exist!\n", __func__); 223 pr_warning("%s: VDD specified does not exist!\n", __func__);
224 return; 224 return;
225 } 225 }
226 226
227 switch (voltscale_method) { 227 switch (voltscale_method) {
228 case VOLTSCALE_VPFORCEUPDATE: 228 case VOLTSCALE_VPFORCEUPDATE:
229 voltdm->scale = omap_vp_forceupdate_scale; 229 voltdm->scale = omap_vp_forceupdate_scale;
230 return; 230 return;
231 case VOLTSCALE_VCBYPASS: 231 case VOLTSCALE_VCBYPASS:
232 voltdm->scale = omap_vc_bypass_scale; 232 voltdm->scale = omap_vc_bypass_scale;
233 return; 233 return;
234 default: 234 default:
235 pr_warning("%s: Trying to change the method of voltage scaling" 235 pr_warning("%s: Trying to change the method of voltage scaling"
236 "to an unsupported one!\n", __func__); 236 "to an unsupported one!\n", __func__);
237 } 237 }
238 } 238 }
239 239
240 /** 240 /**
241 * omap_voltage_late_init() - Init the various voltage parameters 241 * omap_voltage_late_init() - Init the various voltage parameters
242 * 242 *
243 * This API is to be called in the later stages of the 243 * This API is to be called in the later stages of the
244 * system boot to init the voltage controller and 244 * system boot to init the voltage controller and
245 * voltage processors. 245 * voltage processors.
246 */ 246 */
247 int __init omap_voltage_late_init(void) 247 int __init omap_voltage_late_init(void)
248 { 248 {
249 struct voltagedomain *voltdm; 249 struct voltagedomain *voltdm;
250 250
251 if (list_empty(&voltdm_list)) { 251 if (list_empty(&voltdm_list)) {
252 pr_err("%s: Voltage driver support not added\n", 252 pr_err("%s: Voltage driver support not added\n",
253 __func__); 253 __func__);
254 return -EINVAL; 254 return -EINVAL;
255 } 255 }
256 256
257 list_for_each_entry(voltdm, &voltdm_list, node) { 257 list_for_each_entry(voltdm, &voltdm_list, node) {
258 struct clk *sys_ck; 258 struct clk *sys_ck;
259 259
260 if (!voltdm->scalable) 260 if (!voltdm->scalable)
261 continue; 261 continue;
262 262
263 sys_ck = clk_get(NULL, voltdm->sys_clk.name); 263 sys_ck = clk_get(NULL, voltdm->sys_clk.name);
264 if (IS_ERR(sys_ck)) { 264 if (IS_ERR(sys_ck)) {
265 pr_warning("%s: Could not get sys clk.\n", __func__); 265 pr_warning("%s: Could not get sys clk.\n", __func__);
266 return -EINVAL; 266 return -EINVAL;
267 } 267 }
268 voltdm->sys_clk.rate = clk_get_rate(sys_ck); 268 voltdm->sys_clk.rate = clk_get_rate(sys_ck);
269 WARN_ON(!voltdm->sys_clk.rate); 269 WARN_ON(!voltdm->sys_clk.rate);
270 clk_put(sys_ck); 270 clk_put(sys_ck);
271 271
272 if (voltdm->vc) { 272 if (voltdm->vc) {
273 voltdm->scale = omap_vc_bypass_scale; 273 voltdm->scale = omap_vc_bypass_scale;
274 omap_vc_init_channel(voltdm); 274 omap_vc_init_channel(voltdm);
275 } 275 }
276 276
277 if (voltdm->vp) { 277 if (voltdm->vp) {
278 voltdm->scale = omap_vp_forceupdate_scale; 278 voltdm->scale = omap_vp_forceupdate_scale;
279 omap_vp_init(voltdm); 279 omap_vp_init(voltdm);
280 } 280 }
281
282 if (voltdm->use_regulator) {
283 if(voltdm->regulator_init)
284 voltdm->regulator_init(voltdm);
285 }
281 } 286 }
282 287
283 return 0; 288 return 0;
284 } 289 }
285 290
286 static struct voltagedomain *_voltdm_lookup(const char *name) 291 static struct voltagedomain *_voltdm_lookup(const char *name)
287 { 292 {
288 struct voltagedomain *voltdm, *temp_voltdm; 293 struct voltagedomain *voltdm, *temp_voltdm;
289 294
290 voltdm = NULL; 295 voltdm = NULL;
291 296
292 list_for_each_entry(temp_voltdm, &voltdm_list, node) { 297 list_for_each_entry(temp_voltdm, &voltdm_list, node) {
293 if (!strcmp(name, temp_voltdm->name)) { 298 if (!strcmp(name, temp_voltdm->name)) {
294 voltdm = temp_voltdm; 299 voltdm = temp_voltdm;
295 break; 300 break;
296 } 301 }
297 } 302 }
298 303
299 return voltdm; 304 return voltdm;
300 } 305 }
301 306
302 /** 307 /**
303 * voltdm_add_pwrdm - add a powerdomain to a voltagedomain 308 * voltdm_add_pwrdm - add a powerdomain to a voltagedomain
304 * @voltdm: struct voltagedomain * to add the powerdomain to 309 * @voltdm: struct voltagedomain * to add the powerdomain to
305 * @pwrdm: struct powerdomain * to associate with a voltagedomain 310 * @pwrdm: struct powerdomain * to associate with a voltagedomain
306 * 311 *
307 * Associate the powerdomain @pwrdm with a voltagedomain @voltdm. This 312 * Associate the powerdomain @pwrdm with a voltagedomain @voltdm. This
308 * enables the use of voltdm_for_each_pwrdm(). Returns -EINVAL if 313 * enables the use of voltdm_for_each_pwrdm(). Returns -EINVAL if
309 * presented with invalid pointers; -ENOMEM if memory could not be allocated; 314 * presented with invalid pointers; -ENOMEM if memory could not be allocated;
310 * or 0 upon success. 315 * or 0 upon success.
311 */ 316 */
312 int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm) 317 int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm)
313 { 318 {
314 if (!voltdm || !pwrdm) 319 if (!voltdm || !pwrdm)
315 return -EINVAL; 320 return -EINVAL;
316 321
317 pr_debug("voltagedomain: associating powerdomain %s with voltagedomain " 322 pr_debug("voltagedomain: associating powerdomain %s with voltagedomain "
318 "%s\n", pwrdm->name, voltdm->name); 323 "%s\n", pwrdm->name, voltdm->name);
319 324
320 list_add(&pwrdm->voltdm_node, &voltdm->pwrdm_list); 325 list_add(&pwrdm->voltdm_node, &voltdm->pwrdm_list);
321 326
322 return 0; 327 return 0;
323 } 328 }
324 329
325 /** 330 /**
326 * voltdm_for_each_pwrdm - call function for each pwrdm in a voltdm 331 * voltdm_for_each_pwrdm - call function for each pwrdm in a voltdm
327 * @voltdm: struct voltagedomain * to iterate over 332 * @voltdm: struct voltagedomain * to iterate over
328 * @fn: callback function * 333 * @fn: callback function *
329 * 334 *
330 * Call the supplied function @fn for each powerdomain in the 335 * Call the supplied function @fn for each powerdomain in the
331 * voltagedomain @voltdm. Returns -EINVAL if presented with invalid 336 * voltagedomain @voltdm. Returns -EINVAL if presented with invalid
332 * pointers; or passes along the last return value of the callback 337 * pointers; or passes along the last return value of the callback
333 * function, which should be 0 for success or anything else to 338 * function, which should be 0 for success or anything else to
334 * indicate failure. 339 * indicate failure.
335 */ 340 */
336 int voltdm_for_each_pwrdm(struct voltagedomain *voltdm, 341 int voltdm_for_each_pwrdm(struct voltagedomain *voltdm,
337 int (*fn)(struct voltagedomain *voltdm, 342 int (*fn)(struct voltagedomain *voltdm,
338 struct powerdomain *pwrdm)) 343 struct powerdomain *pwrdm))
339 { 344 {
340 struct powerdomain *pwrdm; 345 struct powerdomain *pwrdm;
341 int ret = 0; 346 int ret = 0;
342 347
343 if (!fn) 348 if (!fn)
344 return -EINVAL; 349 return -EINVAL;
345 350
346 list_for_each_entry(pwrdm, &voltdm->pwrdm_list, voltdm_node) 351 list_for_each_entry(pwrdm, &voltdm->pwrdm_list, voltdm_node)
347 ret = (*fn)(voltdm, pwrdm); 352 ret = (*fn)(voltdm, pwrdm);
348 353
349 return ret; 354 return ret;
350 } 355 }
351 356
352 /** 357 /**
353 * voltdm_for_each - call function on each registered voltagedomain 358 * voltdm_for_each - call function on each registered voltagedomain
354 * @fn: callback function * 359 * @fn: callback function *
355 * 360 *
356 * Call the supplied function @fn for each registered voltagedomain. 361 * Call the supplied function @fn for each registered voltagedomain.
357 * The callback function @fn can return anything but 0 to bail out 362 * The callback function @fn can return anything but 0 to bail out
358 * early from the iterator. Returns the last return value of the 363 * early from the iterator. Returns the last return value of the
359 * callback function, which should be 0 for success or anything else 364 * callback function, which should be 0 for success or anything else
360 * to indicate failure; or -EINVAL if the function pointer is null. 365 * to indicate failure; or -EINVAL if the function pointer is null.
361 */ 366 */
362 int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user), 367 int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user),
363 void *user) 368 void *user)
364 { 369 {
365 struct voltagedomain *temp_voltdm; 370 struct voltagedomain *temp_voltdm;
366 int ret = 0; 371 int ret = 0;
367 372
368 if (!fn) 373 if (!fn)
369 return -EINVAL; 374 return -EINVAL;
370 375
371 list_for_each_entry(temp_voltdm, &voltdm_list, node) { 376 list_for_each_entry(temp_voltdm, &voltdm_list, node) {
372 ret = (*fn)(temp_voltdm, user); 377 ret = (*fn)(temp_voltdm, user);
373 if (ret) 378 if (ret)
374 break; 379 break;
375 } 380 }
376 381
377 return ret; 382 return ret;
378 } 383 }
379 384
380 static int _voltdm_register(struct voltagedomain *voltdm) 385 static int _voltdm_register(struct voltagedomain *voltdm)
381 { 386 {
382 if (!voltdm || !voltdm->name) 387 if (!voltdm || !voltdm->name)
383 return -EINVAL; 388 return -EINVAL;
384 389
385 INIT_LIST_HEAD(&voltdm->pwrdm_list); 390 INIT_LIST_HEAD(&voltdm->pwrdm_list);
386 list_add(&voltdm->node, &voltdm_list); 391 list_add(&voltdm->node, &voltdm_list);
387 392
388 pr_debug("voltagedomain: registered %s\n", voltdm->name); 393 pr_debug("voltagedomain: registered %s\n", voltdm->name);
389 394
390 return 0; 395 return 0;
391 } 396 }
392 397
393 /** 398 /**
394 * voltdm_lookup - look up a voltagedomain by name, return a pointer 399 * voltdm_lookup - look up a voltagedomain by name, return a pointer
395 * @name: name of voltagedomain 400 * @name: name of voltagedomain
396 * 401 *
397 * Find a registered voltagedomain by its name @name. Returns a pointer 402 * Find a registered voltagedomain by its name @name. Returns a pointer
398 * to the struct voltagedomain if found, or NULL otherwise. 403 * to the struct voltagedomain if found, or NULL otherwise.
399 */ 404 */
400 struct voltagedomain *voltdm_lookup(const char *name) 405 struct voltagedomain *voltdm_lookup(const char *name)
401 { 406 {
402 struct voltagedomain *voltdm ; 407 struct voltagedomain *voltdm ;
403 408
404 if (!name) 409 if (!name)
405 return NULL; 410 return NULL;
406 411
407 voltdm = _voltdm_lookup(name); 412 voltdm = _voltdm_lookup(name);
408 413
409 return voltdm; 414 return voltdm;
410 } 415 }
411 416
412 /** 417 /**
413 * voltdm_init - set up the voltagedomain layer 418 * voltdm_init - set up the voltagedomain layer
414 * @voltdm_list: array of struct voltagedomain pointers to register 419 * @voltdm_list: array of struct voltagedomain pointers to register
415 * 420 *
416 * Loop through the array of voltagedomains @voltdm_list, registering all 421 * Loop through the array of voltagedomains @voltdm_list, registering all
417 * that are available on the current CPU. If voltdm_list is supplied 422 * that are available on the current CPU. If voltdm_list is supplied
418 * and not null, all of the referenced voltagedomains will be 423 * and not null, all of the referenced voltagedomains will be
419 * registered. No return value. 424 * registered. No return value.
420 */ 425 */
421 void voltdm_init(struct voltagedomain **voltdms) 426 void voltdm_init(struct voltagedomain **voltdms)
422 { 427 {
423 struct voltagedomain **v; 428 struct voltagedomain **v;
424 429
425 if (voltdms) { 430 if (voltdms) {
426 for (v = voltdms; *v; v++) 431 for (v = voltdms; *v; v++)
427 _voltdm_register(*v); 432 _voltdm_register(*v);
428 } 433 }
429 } 434 }
430 435
arch/arm/plat-omap/include/plat/voltage.h
1 /* 1 /*
2 * OMAP Voltage Management Routines 2 * OMAP Voltage Management Routines
3 * 3 *
4 * Author: Thara Gopinath <thara@ti.com> 4 * Author: Thara Gopinath <thara@ti.com>
5 * 5 *
6 * Copyright (C) 2009 Texas Instruments, Inc. 6 * Copyright (C) 2009 Texas Instruments, Inc.
7 * Thara Gopinath <thara@ti.com> 7 * Thara Gopinath <thara@ti.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14 #ifndef __ARCH_ARM_OMAP_VOLTAGE_H 14 #ifndef __ARCH_ARM_OMAP_VOLTAGE_H
15 #define __ARCH_ARM_OMAP_VOLTAGE_H 15 #define __ARCH_ARM_OMAP_VOLTAGE_H
16 16
17 #include <linux/err.h> 17 #include <linux/err.h>
18 18
19 #include <plat/vc.h> 19 #include <plat/vc.h>
20 #include <plat/vp.h> 20 #include <plat/vp.h>
21 21
22 struct powerdomain; 22 struct powerdomain;
23 23
24 /* XXX document */ 24 /* XXX document */
25 #define VOLTSCALE_VPFORCEUPDATE 1 25 #define VOLTSCALE_VPFORCEUPDATE 1
26 #define VOLTSCALE_VCBYPASS 2 26 #define VOLTSCALE_VCBYPASS 2
27 27
28 /* 28 /*
29 * OMAP3 GENERIC setup times. Revisit to see if these needs to be 29 * OMAP3 GENERIC setup times. Revisit to see if these needs to be
30 * passed from board or PMIC file 30 * passed from board or PMIC file
31 */ 31 */
32 #define OMAP3_CLKSETUP 0xff 32 #define OMAP3_CLKSETUP 0xff
33 #define OMAP3_VOLTOFFSET 0xff 33 #define OMAP3_VOLTOFFSET 0xff
34 #define OMAP3_VOLTSETUP2 0xff 34 #define OMAP3_VOLTSETUP2 0xff
35 35
36 struct omap_vdd_info; 36 struct omap_vdd_info;
37 37
38 /** 38 /**
39 * struct omap_vfsm_instance - per-voltage manager FSM register/bitfield 39 * struct omap_vfsm_instance - per-voltage manager FSM register/bitfield
40 * data 40 * data
41 * @voltsetup_mask: SETUP_TIME* bitmask in the PRM_VOLTSETUP* register 41 * @voltsetup_mask: SETUP_TIME* bitmask in the PRM_VOLTSETUP* register
42 * @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base 42 * @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base
43 * 43 *
44 * XXX What about VOLTOFFSET/VOLTCTRL? 44 * XXX What about VOLTOFFSET/VOLTCTRL?
45 */ 45 */
46 struct omap_vfsm_instance { 46 struct omap_vfsm_instance {
47 u32 voltsetup_mask; 47 u32 voltsetup_mask;
48 u8 voltsetup_reg; 48 u8 voltsetup_reg;
49 }; 49 };
50 50
51 /** 51 /**
52 * struct voltagedomain - omap voltage domain global structure. 52 * struct voltagedomain - omap voltage domain global structure.
53 * @name: Name of the voltage domain which can be used as a unique identifier. 53 * @name: Name of the voltage domain which can be used as a unique identifier.
54 * @scalable: Whether or not this voltage domain is scalable 54 * @scalable: Whether or not this voltage domain is scalable
55 * @node: list_head linking all voltage domains 55 * @node: list_head linking all voltage domains
56 * @pwrdm_list: list_head linking all powerdomains in this voltagedomain 56 * @pwrdm_list: list_head linking all powerdomains in this voltagedomain
57 * @vc: pointer to VC channel associated with this voltagedomain 57 * @vc: pointer to VC channel associated with this voltagedomain
58 * @vp: pointer to VP associated with this voltagedomain 58 * @vp: pointer to VP associated with this voltagedomain
59 * @read: read a VC/VP register 59 * @read: read a VC/VP register
60 * @write: write a VC/VP register 60 * @write: write a VC/VP register
61 * @read: read-modify-write a VC/VP register 61 * @read: read-modify-write a VC/VP register
62 * @sys_clk: system clock name/frequency, used for various timing calculations 62 * @sys_clk: system clock name/frequency, used for various timing calculations
63 * @scale: function used to scale the voltage of the voltagedomain 63 * @scale: function used to scale the voltage of the voltagedomain
64 * @nominal_volt: current nominal voltage for this voltage domain 64 * @nominal_volt: current nominal voltage for this voltage domain
65 * @volt_data: voltage table having the distinct voltages supported 65 * @volt_data: voltage table having the distinct voltages supported
66 * by the domain and other associated per voltage data. 66 * by the domain and other associated per voltage data.
67 */ 67 */
68 struct voltagedomain { 68 struct voltagedomain {
69 char *name; 69 char *name;
70 bool scalable; 70 bool scalable;
71 struct list_head node; 71 struct list_head node;
72 struct list_head pwrdm_list; 72 struct list_head pwrdm_list;
73 struct omap_vc_channel *vc; 73 struct omap_vc_channel *vc;
74 const struct omap_vfsm_instance *vfsm; 74 const struct omap_vfsm_instance *vfsm;
75 struct omap_vp_instance *vp; 75 struct omap_vp_instance *vp;
76 struct omap_voltdm_pmic *pmic; 76 struct omap_voltdm_pmic *pmic;
77 77
78 /* VC/VP register access functions: SoC specific */ 78 /* VC/VP register access functions: SoC specific */
79 u32 (*read) (u8 offset); 79 u32 (*read) (u8 offset);
80 void (*write) (u32 val, u8 offset); 80 void (*write) (u32 val, u8 offset);
81 u32 (*rmw)(u32 mask, u32 bits, u8 offset); 81 u32 (*rmw)(u32 mask, u32 bits, u8 offset);
82 82
83 union { 83 union {
84 const char *name; 84 const char *name;
85 u32 rate; 85 u32 rate;
86 } sys_clk; 86 } sys_clk;
87 87
88 int (*scale) (struct voltagedomain *voltdm, 88 int (*scale) (struct voltagedomain *voltdm,
89 unsigned long target_volt); 89 unsigned long target_volt);
90 90
91 u32 nominal_volt; 91 u32 nominal_volt;
92 struct omap_volt_data *volt_data; 92 struct omap_volt_data *volt_data;
93 struct omap_vdd_info *vdd; 93 struct omap_vdd_info *vdd;
94 struct dentry *debug_dir; 94 struct dentry *debug_dir;
95
96 bool use_regulator;
97 struct regulator *regulator;
98 int (*regulator_init) (struct voltagedomain *voltdm);
95 }; 99 };
96 100
97 /** 101 /**
98 * struct omap_volt_data - Omap voltage specific data. 102 * struct omap_volt_data - Omap voltage specific data.
99 * @voltage_nominal: The possible voltage value in uV 103 * @voltage_nominal: The possible voltage value in uV
100 * @sr_efuse_offs: The offset of the efuse register(from system 104 * @sr_efuse_offs: The offset of the efuse register(from system
101 * control module base address) from where to read 105 * control module base address) from where to read
102 * the n-target value for the smartreflex module. 106 * the n-target value for the smartreflex module.
103 * @sr_errminlimit: Error min limit value for smartreflex. This value 107 * @sr_errminlimit: Error min limit value for smartreflex. This value
104 * differs at differnet opp and thus is linked 108 * differs at differnet opp and thus is linked
105 * with voltage. 109 * with voltage.
106 * @vp_errorgain: Error gain value for the voltage processor. This 110 * @vp_errorgain: Error gain value for the voltage processor. This
107 * field also differs according to the voltage/opp. 111 * field also differs according to the voltage/opp.
108 */ 112 */
109 struct omap_volt_data { 113 struct omap_volt_data {
110 u32 volt_nominal; 114 u32 volt_nominal;
111 u32 sr_efuse_offs; 115 u32 sr_efuse_offs;
112 u8 sr_errminlimit; 116 u8 sr_errminlimit;
113 u8 vp_errgain; 117 u8 vp_errgain;
114 }; 118 };
115 119
116 /** 120 /**
117 * struct omap_voltdm_pmic - PMIC specific data required by voltage driver. 121 * struct omap_voltdm_pmic - PMIC specific data required by voltage driver.
118 * @slew_rate: PMIC slew rate (in uv/us) 122 * @slew_rate: PMIC slew rate (in uv/us)
119 * @step_size: PMIC voltage step size (in uv) 123 * @step_size: PMIC voltage step size (in uv)
120 * @i2c_slave_addr: I2C slave address of PMIC 124 * @i2c_slave_addr: I2C slave address of PMIC
121 * @volt_reg_addr: voltage configuration register address 125 * @volt_reg_addr: voltage configuration register address
122 * @cmd_reg_addr: command (on, on-LP, ret, off) configuration register address 126 * @cmd_reg_addr: command (on, on-LP, ret, off) configuration register address
123 * @i2c_high_speed: whether VC uses I2C high-speed mode to PMIC 127 * @i2c_high_speed: whether VC uses I2C high-speed mode to PMIC
124 * @i2c_mcode: master code value for I2C high-speed preamble transmission 128 * @i2c_mcode: master code value for I2C high-speed preamble transmission
125 * @vsel_to_uv: PMIC API to convert vsel value to actual voltage in uV. 129 * @vsel_to_uv: PMIC API to convert vsel value to actual voltage in uV.
126 * @uv_to_vsel: PMIC API to convert voltage in uV to vsel value. 130 * @uv_to_vsel: PMIC API to convert voltage in uV to vsel value.
127 */ 131 */
128 struct omap_voltdm_pmic { 132 struct omap_voltdm_pmic {
129 int slew_rate; 133 int slew_rate;
130 int step_size; 134 int step_size;
131 u32 on_volt; 135 u32 on_volt;
132 u32 onlp_volt; 136 u32 onlp_volt;
133 u32 ret_volt; 137 u32 ret_volt;
134 u32 off_volt; 138 u32 off_volt;
135 u16 volt_setup_time; 139 u16 volt_setup_time;
136 u16 i2c_slave_addr; 140 u16 i2c_slave_addr;
137 u16 volt_reg_addr; 141 u16 volt_reg_addr;
138 u16 cmd_reg_addr; 142 u16 cmd_reg_addr;
139 u8 vp_erroroffset; 143 u8 vp_erroroffset;
140 u8 vp_vstepmin; 144 u8 vp_vstepmin;
141 u8 vp_vstepmax; 145 u8 vp_vstepmax;
142 u8 vp_vddmin; 146 u8 vp_vddmin;
143 u8 vp_vddmax; 147 u8 vp_vddmax;
144 u8 vp_timeout_us; 148 u8 vp_timeout_us;
145 bool i2c_high_speed; 149 bool i2c_high_speed;
146 u8 i2c_mcode; 150 u8 i2c_mcode;
147 unsigned long (*vsel_to_uv) (const u8 vsel); 151 unsigned long (*vsel_to_uv) (const u8 vsel);
148 u8 (*uv_to_vsel) (unsigned long uV); 152 u8 (*uv_to_vsel) (unsigned long uV);
149 }; 153 };
150 154
151 /** 155 /**
152 * struct omap_vdd_dep_volt - Map table for voltage dependencies 156 * struct omap_vdd_dep_volt - Map table for voltage dependencies
153 * @main_vdd_volt : The main vdd voltage 157 * @main_vdd_volt : The main vdd voltage
154 * @dep_vdd_volt : The voltage at which the dependent vdd should be 158 * @dep_vdd_volt : The voltage at which the dependent vdd should be
155 * when the main vdd is at <main_vdd_volt> voltage 159 * when the main vdd is at <main_vdd_volt> voltage
156 * 160 *
157 * Table containing the parent vdd voltage and the dependent vdd voltage 161 * Table containing the parent vdd voltage and the dependent vdd voltage
158 * corresponding to it. 162 * corresponding to it.
159 */ 163 */
160 struct omap_vdd_dep_volt { 164 struct omap_vdd_dep_volt {
161 u32 main_vdd_volt; 165 u32 main_vdd_volt;
162 u32 dep_vdd_volt; 166 u32 dep_vdd_volt;
163 }; 167 };
164 168
165 /** 169 /**
166 * struct omap_vdd_dep_info - Dependent vdd info 170 * struct omap_vdd_dep_info - Dependent vdd info
167 * @name : Dependent vdd name 171 * @name : Dependent vdd name
168 * @_dep_voltdm : internal structure meant to prevent multiple lookups 172 * @_dep_voltdm : internal structure meant to prevent multiple lookups
169 * @dep_table : Table containing the dependent vdd voltage 173 * @dep_table : Table containing the dependent vdd voltage
170 * corresponding to every main vdd voltage. 174 * corresponding to every main vdd voltage.
171 * @nr_dep_entries : number of dependency voltage entries 175 * @nr_dep_entries : number of dependency voltage entries
172 */ 176 */
173 struct omap_vdd_dep_info { 177 struct omap_vdd_dep_info {
174 char *name; 178 char *name;
175 struct voltagedomain *_dep_voltdm; 179 struct voltagedomain *_dep_voltdm;
176 struct omap_vdd_dep_volt *dep_table; 180 struct omap_vdd_dep_volt *dep_table;
177 int nr_dep_entries; 181 int nr_dep_entries;
178 }; 182 };
179 183
180 /** 184 /**
181 * omap_vdd_info - Per Voltage Domain info 185 * omap_vdd_info - Per Voltage Domain info
182 * 186 *
183 * @volt_data : voltage table having the distinct voltages supported 187 * @volt_data : voltage table having the distinct voltages supported
184 * by the domain and other associated per voltage data. 188 * by the domain and other associated per voltage data.
185 * @dep_vdd_info : Array ending with a 0 terminator for dependency 189 * @dep_vdd_info : Array ending with a 0 terminator for dependency
186 * voltage information. 190 * voltage information.
187 */ 191 */
188 struct omap_vdd_info { 192 struct omap_vdd_info {
189 struct omap_volt_data *volt_data; 193 struct omap_volt_data *volt_data;
190 struct omap_vdd_dep_info *dep_vdd_info; 194 struct omap_vdd_dep_info *dep_vdd_info;
191 }; 195 };
192 196
193 void omap_voltage_get_volttable(struct voltagedomain *voltdm, 197 void omap_voltage_get_volttable(struct voltagedomain *voltdm,
194 struct omap_volt_data **volt_data); 198 struct omap_volt_data **volt_data);
195 struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm, 199 struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
196 unsigned long volt); 200 unsigned long volt);
197 int omap_voltage_register_pmic(struct voltagedomain *voltdm, 201 int omap_voltage_register_pmic(struct voltagedomain *voltdm,
198 struct omap_voltdm_pmic *pmic); 202 struct omap_voltdm_pmic *pmic);
199 void omap_change_voltscale_method(struct voltagedomain *voltdm, 203 void omap_change_voltscale_method(struct voltagedomain *voltdm,
200 int voltscale_method); 204 int voltscale_method);
201 int omap_voltage_late_init(void); 205 int omap_voltage_late_init(void);
202 206
203 extern void omap2xxx_voltagedomains_init(void); 207 extern void omap2xxx_voltagedomains_init(void);
204 extern void omap3xxx_voltagedomains_init(void); 208 extern void omap3xxx_voltagedomains_init(void);
205 extern void am33xx_voltagedomains_init(void); 209 extern void am33xx_voltagedomains_init(void);
206 extern void omap44xx_voltagedomains_init(void); 210 extern void omap44xx_voltagedomains_init(void);
207 211
208 struct voltagedomain *voltdm_lookup(const char *name); 212 struct voltagedomain *voltdm_lookup(const char *name);
209 void voltdm_init(struct voltagedomain **voltdm_list); 213 void voltdm_init(struct voltagedomain **voltdm_list);
210 int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm); 214 int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm);
211 int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user), 215 int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user),
212 void *user); 216 void *user);
213 int voltdm_for_each_pwrdm(struct voltagedomain *voltdm, 217 int voltdm_for_each_pwrdm(struct voltagedomain *voltdm,
214 int (*fn)(struct voltagedomain *voltdm, 218 int (*fn)(struct voltagedomain *voltdm,
215 struct powerdomain *pwrdm)); 219 struct powerdomain *pwrdm));
216 int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt); 220 int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt);
217 void voltdm_reset(struct voltagedomain *voltdm); 221 void voltdm_reset(struct voltagedomain *voltdm);
218 unsigned long voltdm_get_voltage(struct voltagedomain *voltdm); 222 unsigned long voltdm_get_voltage(struct voltagedomain *voltdm);
219 #endif 223 #endif
220 224