OMAP3+: voltage domain: move PMIC struct from vdd_info into struct voltagedomain
[pandora-kernel.git] / arch / arm / mach-omap2 / voltage.c
1 /*
2  * OMAP3/OMAP4 Voltage Management Routines
3  *
4  * Author: Thara Gopinath       <thara@ti.com>
5  *
6  * Copyright (C) 2007 Texas Instruments, Inc.
7  * Rajendra Nayak <rnayak@ti.com>
8  * Lesly A M <x0080970@ti.com>
9  *
10  * Copyright (C) 2008, 2011 Nokia Corporation
11  * Kalle Jokiniemi
12  * Paul Walmsley
13  *
14  * Copyright (C) 2010 Texas Instruments, Inc.
15  * Thara Gopinath <thara@ti.com>
16  *
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
19  * published by the Free Software Foundation.
20  */
21
22 #include <linux/delay.h>
23 #include <linux/io.h>
24 #include <linux/clk.h>
25 #include <linux/err.h>
26 #include <linux/debugfs.h>
27 #include <linux/slab.h>
28
29 #include <plat/common.h>
30
31 #include "prm-regbits-34xx.h"
32 #include "prm-regbits-44xx.h"
33 #include "prm44xx.h"
34 #include "prcm44xx.h"
35 #include "prminst44xx.h"
36 #include "control.h"
37
38 #include "voltage.h"
39 #include "powerdomain.h"
40
41 #include "vc.h"
42 #include "vp.h"
43
44 static LIST_HEAD(voltdm_list);
45
46 #define VOLTAGE_DIR_SIZE        16
47 static struct dentry *voltage_dir;
48
49 static int __init _config_common_vdd_data(struct voltagedomain *voltdm)
50 {
51         char *sys_ck_name;
52         struct clk *sys_ck;
53         u32 sys_clk_speed, timeout_val, waittime;
54         struct omap_vdd_info *vdd = voltdm->vdd;
55
56         /*
57          * XXX Clockfw should handle this, or this should be in a
58          * struct record
59          */
60         if (cpu_is_omap24xx() || cpu_is_omap34xx())
61                 sys_ck_name = "sys_ck";
62         else if (cpu_is_omap44xx())
63                 sys_ck_name = "sys_clkin_ck";
64         else
65                 return -EINVAL;
66
67         /*
68          * Sys clk rate is require to calculate vp timeout value and
69          * smpswaittimemin and smpswaittimemax.
70          */
71         sys_ck = clk_get(NULL, sys_ck_name);
72         if (IS_ERR(sys_ck)) {
73                 pr_warning("%s: Could not get the sys clk to calculate"
74                         "various vdd_%s params\n", __func__, voltdm->name);
75                 return -EINVAL;
76         }
77         sys_clk_speed = clk_get_rate(sys_ck);
78         clk_put(sys_ck);
79         /* Divide to avoid overflow */
80         sys_clk_speed /= 1000;
81
82         /* Generic voltage parameters */
83         vdd->volt_scale = omap_vp_forceupdate_scale;
84         vdd->vp_enabled = false;
85
86         vdd->vp_rt_data.vpconfig_erroroffset =
87                 (voltdm->pmic->vp_erroroffset <<
88                  vdd->vp_data->vp_common->vpconfig_erroroffset_shift);
89
90         timeout_val = (sys_clk_speed * voltdm->pmic->vp_timeout_us) / 1000;
91         vdd->vp_rt_data.vlimitto_timeout = timeout_val;
92         vdd->vp_rt_data.vlimitto_vddmin = voltdm->pmic->vp_vddmin;
93         vdd->vp_rt_data.vlimitto_vddmax = voltdm->pmic->vp_vddmax;
94
95         waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
96                                 sys_clk_speed) / 1000;
97         vdd->vp_rt_data.vstepmin_smpswaittimemin = waittime;
98         vdd->vp_rt_data.vstepmax_smpswaittimemax = waittime;
99         vdd->vp_rt_data.vstepmin_stepmin = voltdm->pmic->vp_vstepmin;
100         vdd->vp_rt_data.vstepmax_stepmax = voltdm->pmic->vp_vstepmax;
101
102         return 0;
103 }
104
105 static int nom_volt_debug_get(void *data, u64 *val)
106 {
107         struct voltagedomain *voltdm = (struct voltagedomain *)data;
108
109         if (!voltdm) {
110                 pr_warning("Wrong paramater passed\n");
111                 return -EINVAL;
112         }
113
114         *val = omap_voltage_get_nom_volt(voltdm);
115
116         return 0;
117 }
118
119 DEFINE_SIMPLE_ATTRIBUTE(nom_volt_debug_fops, nom_volt_debug_get, NULL,
120                                                                 "%llu\n");
121 static void __init vdd_debugfs_init(struct voltagedomain *voltdm)
122 {
123         char *name;
124         struct omap_vdd_info *vdd = voltdm->vdd;
125
126         name = kzalloc(VOLTAGE_DIR_SIZE, GFP_KERNEL);
127         if (!name) {
128                 pr_warning("%s: Unable to allocate memory for debugfs"
129                         " directory name for vdd_%s",
130                         __func__, voltdm->name);
131                 return;
132         }
133         strcpy(name, "vdd_");
134         strcat(name, voltdm->name);
135
136         vdd->debug_dir = debugfs_create_dir(name, voltage_dir);
137         kfree(name);
138         if (IS_ERR(vdd->debug_dir)) {
139                 pr_warning("%s: Unable to create debugfs directory for"
140                         " vdd_%s\n", __func__, voltdm->name);
141                 vdd->debug_dir = NULL;
142                 return;
143         }
144
145         (void) debugfs_create_file("curr_nominal_volt", S_IRUGO,
146                                 vdd->debug_dir, (void *) voltdm,
147                                 &nom_volt_debug_fops);
148 }
149
150 static int __init omap_vdd_data_configure(struct voltagedomain *voltdm)
151 {
152         int ret = -EINVAL;
153
154         if (!voltdm->pmic) {
155                 pr_err("%s: PMIC info requried to configure vdd_%s not"
156                         "populated.Hence cannot initialize vdd_%s\n",
157                         __func__, voltdm->name, voltdm->name);
158                 goto ovdc_out;
159         }
160
161         if (IS_ERR_VALUE(_config_common_vdd_data(voltdm)))
162                 goto ovdc_out;
163
164         ret = 0;
165
166 ovdc_out:
167         return ret;
168 }
169
170 /* Public functions */
171 /**
172  * omap_voltage_get_nom_volt() - Gets the current non-auto-compensated voltage
173  * @voltdm:     pointer to the VDD for which current voltage info is needed
174  *
175  * API to get the current non-auto-compensated voltage for a VDD.
176  * Returns 0 in case of error else returns the current voltage for the VDD.
177  */
178 unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm)
179 {
180         struct omap_vdd_info *vdd;
181
182         if (!voltdm || IS_ERR(voltdm)) {
183                 pr_warning("%s: VDD specified does not exist!\n", __func__);
184                 return 0;
185         }
186
187         vdd = voltdm->vdd;
188
189         return vdd->curr_volt;
190 }
191
192 /**
193  * omap_voltage_scale_vdd() - API to scale voltage of a particular
194  *                              voltage domain.
195  * @voltdm:     pointer to the VDD which is to be scaled.
196  * @target_volt:        The target voltage of the voltage domain
197  *
198  * This API should be called by the kernel to do the voltage scaling
199  * for a particular voltage domain during dvfs or any other situation.
200  */
201 int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
202                 unsigned long target_volt)
203 {
204         struct omap_vdd_info *vdd;
205
206         if (!voltdm || IS_ERR(voltdm)) {
207                 pr_warning("%s: VDD specified does not exist!\n", __func__);
208                 return -EINVAL;
209         }
210
211         vdd = voltdm->vdd;
212
213         if (!vdd->volt_scale) {
214                 pr_err("%s: No voltage scale API registered for vdd_%s\n",
215                         __func__, voltdm->name);
216                 return -ENODATA;
217         }
218
219         return vdd->volt_scale(voltdm, target_volt);
220 }
221
222 /**
223  * omap_voltage_reset() - Resets the voltage of a particular voltage domain
224  *                      to that of the current OPP.
225  * @voltdm:     pointer to the VDD whose voltage is to be reset.
226  *
227  * This API finds out the correct voltage the voltage domain is supposed
228  * to be at and resets the voltage to that level. Should be used especially
229  * while disabling any voltage compensation modules.
230  */
231 void omap_voltage_reset(struct voltagedomain *voltdm)
232 {
233         unsigned long target_uvdc;
234
235         if (!voltdm || IS_ERR(voltdm)) {
236                 pr_warning("%s: VDD specified does not exist!\n", __func__);
237                 return;
238         }
239
240         target_uvdc = omap_voltage_get_nom_volt(voltdm);
241         if (!target_uvdc) {
242                 pr_err("%s: unable to find current voltage for vdd_%s\n",
243                         __func__, voltdm->name);
244                 return;
245         }
246
247         omap_voltage_scale_vdd(voltdm, target_uvdc);
248 }
249
250 /**
251  * omap_voltage_get_volttable() - API to get the voltage table associated with a
252  *                              particular voltage domain.
253  * @voltdm:     pointer to the VDD for which the voltage table is required
254  * @volt_data:  the voltage table for the particular vdd which is to be
255  *              populated by this API
256  *
257  * This API populates the voltage table associated with a VDD into the
258  * passed parameter pointer. Returns the count of distinct voltages
259  * supported by this vdd.
260  *
261  */
262 void omap_voltage_get_volttable(struct voltagedomain *voltdm,
263                 struct omap_volt_data **volt_data)
264 {
265         struct omap_vdd_info *vdd;
266
267         if (!voltdm || IS_ERR(voltdm)) {
268                 pr_warning("%s: VDD specified does not exist!\n", __func__);
269                 return;
270         }
271
272         vdd = voltdm->vdd;
273
274         *volt_data = vdd->volt_data;
275 }
276
277 /**
278  * omap_voltage_get_voltdata() - API to get the voltage table entry for a
279  *                              particular voltage
280  * @voltdm:     pointer to the VDD whose voltage table has to be searched
281  * @volt:       the voltage to be searched in the voltage table
282  *
283  * This API searches through the voltage table for the required voltage
284  * domain and tries to find a matching entry for the passed voltage volt.
285  * If a matching entry is found volt_data is populated with that entry.
286  * This API searches only through the non-compensated voltages int the
287  * voltage table.
288  * Returns pointer to the voltage table entry corresponding to volt on
289  * success. Returns -ENODATA if no voltage table exisits for the passed voltage
290  * domain or if there is no matching entry.
291  */
292 struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
293                 unsigned long volt)
294 {
295         struct omap_vdd_info *vdd;
296         int i;
297
298         if (!voltdm || IS_ERR(voltdm)) {
299                 pr_warning("%s: VDD specified does not exist!\n", __func__);
300                 return ERR_PTR(-EINVAL);
301         }
302
303         vdd = voltdm->vdd;
304
305         if (!vdd->volt_data) {
306                 pr_warning("%s: voltage table does not exist for vdd_%s\n",
307                         __func__, voltdm->name);
308                 return ERR_PTR(-ENODATA);
309         }
310
311         for (i = 0; vdd->volt_data[i].volt_nominal != 0; i++) {
312                 if (vdd->volt_data[i].volt_nominal == volt)
313                         return &vdd->volt_data[i];
314         }
315
316         pr_notice("%s: Unable to match the current voltage with the voltage"
317                 "table for vdd_%s\n", __func__, voltdm->name);
318
319         return ERR_PTR(-ENODATA);
320 }
321
322 /**
323  * omap_voltage_register_pmic() - API to register PMIC specific data
324  * @voltdm:     pointer to the VDD for which the PMIC specific data is
325  *              to be registered
326  * @pmic:       the structure containing pmic info
327  *
328  * This API is to be called by the SOC/PMIC file to specify the
329  * pmic specific info as present in omap_voltdm_pmic structure.
330  */
331 int omap_voltage_register_pmic(struct voltagedomain *voltdm,
332                                struct omap_voltdm_pmic *pmic)
333 {
334         if (!voltdm || IS_ERR(voltdm)) {
335                 pr_warning("%s: VDD specified does not exist!\n", __func__);
336                 return -EINVAL;
337         }
338
339         voltdm->pmic = pmic;
340
341         return 0;
342 }
343
344 /**
345  * omap_voltage_get_dbgdir() - API to get pointer to the debugfs directory
346  *                              corresponding to a voltage domain.
347  *
348  * @voltdm:     pointer to the VDD whose debug directory is required.
349  *
350  * This API returns pointer to the debugfs directory corresponding
351  * to the voltage domain. Should be used by drivers requiring to
352  * add any debug entry for a particular voltage domain. Returns NULL
353  * in case of error.
354  */
355 struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm)
356 {
357         struct omap_vdd_info *vdd;
358
359         if (!voltdm || IS_ERR(voltdm)) {
360                 pr_warning("%s: VDD specified does not exist!\n", __func__);
361                 return NULL;
362         }
363
364         vdd = voltdm->vdd;
365
366         return vdd->debug_dir;
367 }
368
369 /**
370  * omap_change_voltscale_method() - API to change the voltage scaling method.
371  * @voltdm:     pointer to the VDD whose voltage scaling method
372  *              has to be changed.
373  * @voltscale_method:   the method to be used for voltage scaling.
374  *
375  * This API can be used by the board files to change the method of voltage
376  * scaling between vpforceupdate and vcbypass. The parameter values are
377  * defined in voltage.h
378  */
379 void omap_change_voltscale_method(struct voltagedomain *voltdm,
380                 int voltscale_method)
381 {
382         struct omap_vdd_info *vdd;
383
384         if (!voltdm || IS_ERR(voltdm)) {
385                 pr_warning("%s: VDD specified does not exist!\n", __func__);
386                 return;
387         }
388
389         vdd = voltdm->vdd;
390
391         switch (voltscale_method) {
392         case VOLTSCALE_VPFORCEUPDATE:
393                 vdd->volt_scale = omap_vp_forceupdate_scale;
394                 return;
395         case VOLTSCALE_VCBYPASS:
396                 vdd->volt_scale = omap_vc_bypass_scale;
397                 return;
398         default:
399                 pr_warning("%s: Trying to change the method of voltage scaling"
400                         "to an unsupported one!\n", __func__);
401         }
402 }
403
404 /**
405  * omap_voltage_late_init() - Init the various voltage parameters
406  *
407  * This API is to be called in the later stages of the
408  * system boot to init the voltage controller and
409  * voltage processors.
410  */
411 int __init omap_voltage_late_init(void)
412 {
413         struct voltagedomain *voltdm;
414
415         if (list_empty(&voltdm_list)) {
416                 pr_err("%s: Voltage driver support not added\n",
417                         __func__);
418                 return -EINVAL;
419         }
420
421         voltage_dir = debugfs_create_dir("voltage", NULL);
422         if (IS_ERR(voltage_dir))
423                 pr_err("%s: Unable to create voltage debugfs main dir\n",
424                         __func__);
425         list_for_each_entry(voltdm, &voltdm_list, node) {
426                 if (!voltdm->scalable)
427                         continue;
428
429                 if (voltdm->vc) {
430                         voltdm->vdd->volt_scale = omap_vc_bypass_scale;
431                         omap_vc_init_channel(voltdm);
432                 }
433
434                 if (voltdm->vdd) {
435                         if (omap_vdd_data_configure(voltdm))
436                                 continue;
437                         vdd_debugfs_init(voltdm);
438                         omap_vp_init(voltdm);
439                 }
440         }
441
442         return 0;
443 }
444
445 static struct voltagedomain *_voltdm_lookup(const char *name)
446 {
447         struct voltagedomain *voltdm, *temp_voltdm;
448
449         voltdm = NULL;
450
451         list_for_each_entry(temp_voltdm, &voltdm_list, node) {
452                 if (!strcmp(name, temp_voltdm->name)) {
453                         voltdm = temp_voltdm;
454                         break;
455                 }
456         }
457
458         return voltdm;
459 }
460
461 /**
462  * voltdm_add_pwrdm - add a powerdomain to a voltagedomain
463  * @voltdm: struct voltagedomain * to add the powerdomain to
464  * @pwrdm: struct powerdomain * to associate with a voltagedomain
465  *
466  * Associate the powerdomain @pwrdm with a voltagedomain @voltdm.  This
467  * enables the use of voltdm_for_each_pwrdm().  Returns -EINVAL if
468  * presented with invalid pointers; -ENOMEM if memory could not be allocated;
469  * or 0 upon success.
470  */
471 int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm)
472 {
473         if (!voltdm || !pwrdm)
474                 return -EINVAL;
475
476         pr_debug("voltagedomain: associating powerdomain %s with voltagedomain "
477                  "%s\n", pwrdm->name, voltdm->name);
478
479         list_add(&pwrdm->voltdm_node, &voltdm->pwrdm_list);
480
481         return 0;
482 }
483
484 /**
485  * voltdm_for_each_pwrdm - call function for each pwrdm in a voltdm
486  * @voltdm: struct voltagedomain * to iterate over
487  * @fn: callback function *
488  *
489  * Call the supplied function @fn for each powerdomain in the
490  * voltagedomain @voltdm.  Returns -EINVAL if presented with invalid
491  * pointers; or passes along the last return value of the callback
492  * function, which should be 0 for success or anything else to
493  * indicate failure.
494  */
495 int voltdm_for_each_pwrdm(struct voltagedomain *voltdm,
496                           int (*fn)(struct voltagedomain *voltdm,
497                                     struct powerdomain *pwrdm))
498 {
499         struct powerdomain *pwrdm;
500         int ret = 0;
501
502         if (!fn)
503                 return -EINVAL;
504
505         list_for_each_entry(pwrdm, &voltdm->pwrdm_list, voltdm_node)
506                 ret = (*fn)(voltdm, pwrdm);
507
508         return ret;
509 }
510
511 /**
512  * voltdm_for_each - call function on each registered voltagedomain
513  * @fn: callback function *
514  *
515  * Call the supplied function @fn for each registered voltagedomain.
516  * The callback function @fn can return anything but 0 to bail out
517  * early from the iterator.  Returns the last return value of the
518  * callback function, which should be 0 for success or anything else
519  * to indicate failure; or -EINVAL if the function pointer is null.
520  */
521 int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user),
522                     void *user)
523 {
524         struct voltagedomain *temp_voltdm;
525         int ret = 0;
526
527         if (!fn)
528                 return -EINVAL;
529
530         list_for_each_entry(temp_voltdm, &voltdm_list, node) {
531                 ret = (*fn)(temp_voltdm, user);
532                 if (ret)
533                         break;
534         }
535
536         return ret;
537 }
538
539 static int _voltdm_register(struct voltagedomain *voltdm)
540 {
541         if (!voltdm || !voltdm->name)
542                 return -EINVAL;
543
544         INIT_LIST_HEAD(&voltdm->pwrdm_list);
545         list_add(&voltdm->node, &voltdm_list);
546
547         pr_debug("voltagedomain: registered %s\n", voltdm->name);
548
549         return 0;
550 }
551
552 /**
553  * voltdm_lookup - look up a voltagedomain by name, return a pointer
554  * @name: name of voltagedomain
555  *
556  * Find a registered voltagedomain by its name @name.  Returns a pointer
557  * to the struct voltagedomain if found, or NULL otherwise.
558  */
559 struct voltagedomain *voltdm_lookup(const char *name)
560 {
561         struct voltagedomain *voltdm ;
562
563         if (!name)
564                 return NULL;
565
566         voltdm = _voltdm_lookup(name);
567
568         return voltdm;
569 }
570
571 /**
572  * voltdm_init - set up the voltagedomain layer
573  * @voltdm_list: array of struct voltagedomain pointers to register
574  *
575  * Loop through the array of voltagedomains @voltdm_list, registering all
576  * that are available on the current CPU. If voltdm_list is supplied
577  * and not null, all of the referenced voltagedomains will be
578  * registered.  No return value.
579  */
580 void voltdm_init(struct voltagedomain **voltdms)
581 {
582         struct voltagedomain **v;
583
584         if (voltdms) {
585                 for (v = voltdms; *v; v++)
586                         _voltdm_register(*v);
587         }
588 }