OMAP3+: voltage: convert to PRM register access functions
[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                 (vdd->pmic_info->vp_erroroffset <<
88                  vdd->vp_data->vp_common->vpconfig_erroroffset_shift);
89
90         timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
91         vdd->vp_rt_data.vlimitto_timeout = timeout_val;
92         vdd->vp_rt_data.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
93         vdd->vp_rt_data.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
94
95         waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->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 = vdd->pmic_info->vp_vstepmin;
100         vdd->vp_rt_data.vstepmax_stepmax = vdd->pmic_info->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         struct omap_vdd_info *vdd = voltdm->vdd;
153         int ret = -EINVAL;
154
155         if (!vdd->pmic_info) {
156                 pr_err("%s: PMIC info requried to configure vdd_%s not"
157                         "populated.Hence cannot initialize vdd_%s\n",
158                         __func__, voltdm->name, voltdm->name);
159                 goto ovdc_out;
160         }
161
162         if (IS_ERR_VALUE(_config_common_vdd_data(voltdm)))
163                 goto ovdc_out;
164
165         ret = 0;
166
167 ovdc_out:
168         return ret;
169 }
170
171 /* Public functions */
172 /**
173  * omap_voltage_get_nom_volt() - Gets the current non-auto-compensated voltage
174  * @voltdm:     pointer to the VDD for which current voltage info is needed
175  *
176  * API to get the current non-auto-compensated voltage for a VDD.
177  * Returns 0 in case of error else returns the current voltage for the VDD.
178  */
179 unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm)
180 {
181         struct omap_vdd_info *vdd;
182
183         if (!voltdm || IS_ERR(voltdm)) {
184                 pr_warning("%s: VDD specified does not exist!\n", __func__);
185                 return 0;
186         }
187
188         vdd = voltdm->vdd;
189
190         return vdd->curr_volt;
191 }
192
193 /**
194  * omap_voltage_scale_vdd() - API to scale voltage of a particular
195  *                              voltage domain.
196  * @voltdm:     pointer to the VDD which is to be scaled.
197  * @target_volt:        The target voltage of the voltage domain
198  *
199  * This API should be called by the kernel to do the voltage scaling
200  * for a particular voltage domain during dvfs or any other situation.
201  */
202 int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
203                 unsigned long target_volt)
204 {
205         struct omap_vdd_info *vdd;
206
207         if (!voltdm || IS_ERR(voltdm)) {
208                 pr_warning("%s: VDD specified does not exist!\n", __func__);
209                 return -EINVAL;
210         }
211
212         vdd = voltdm->vdd;
213
214         if (!vdd->volt_scale) {
215                 pr_err("%s: No voltage scale API registered for vdd_%s\n",
216                         __func__, voltdm->name);
217                 return -ENODATA;
218         }
219
220         return vdd->volt_scale(voltdm, target_volt);
221 }
222
223 /**
224  * omap_voltage_reset() - Resets the voltage of a particular voltage domain
225  *                      to that of the current OPP.
226  * @voltdm:     pointer to the VDD whose voltage is to be reset.
227  *
228  * This API finds out the correct voltage the voltage domain is supposed
229  * to be at and resets the voltage to that level. Should be used especially
230  * while disabling any voltage compensation modules.
231  */
232 void omap_voltage_reset(struct voltagedomain *voltdm)
233 {
234         unsigned long target_uvdc;
235
236         if (!voltdm || IS_ERR(voltdm)) {
237                 pr_warning("%s: VDD specified does not exist!\n", __func__);
238                 return;
239         }
240
241         target_uvdc = omap_voltage_get_nom_volt(voltdm);
242         if (!target_uvdc) {
243                 pr_err("%s: unable to find current voltage for vdd_%s\n",
244                         __func__, voltdm->name);
245                 return;
246         }
247
248         omap_voltage_scale_vdd(voltdm, target_uvdc);
249 }
250
251 /**
252  * omap_voltage_get_volttable() - API to get the voltage table associated with a
253  *                              particular voltage domain.
254  * @voltdm:     pointer to the VDD for which the voltage table is required
255  * @volt_data:  the voltage table for the particular vdd which is to be
256  *              populated by this API
257  *
258  * This API populates the voltage table associated with a VDD into the
259  * passed parameter pointer. Returns the count of distinct voltages
260  * supported by this vdd.
261  *
262  */
263 void omap_voltage_get_volttable(struct voltagedomain *voltdm,
264                 struct omap_volt_data **volt_data)
265 {
266         struct omap_vdd_info *vdd;
267
268         if (!voltdm || IS_ERR(voltdm)) {
269                 pr_warning("%s: VDD specified does not exist!\n", __func__);
270                 return;
271         }
272
273         vdd = voltdm->vdd;
274
275         *volt_data = vdd->volt_data;
276 }
277
278 /**
279  * omap_voltage_get_voltdata() - API to get the voltage table entry for a
280  *                              particular voltage
281  * @voltdm:     pointer to the VDD whose voltage table has to be searched
282  * @volt:       the voltage to be searched in the voltage table
283  *
284  * This API searches through the voltage table for the required voltage
285  * domain and tries to find a matching entry for the passed voltage volt.
286  * If a matching entry is found volt_data is populated with that entry.
287  * This API searches only through the non-compensated voltages int the
288  * voltage table.
289  * Returns pointer to the voltage table entry corresponding to volt on
290  * success. Returns -ENODATA if no voltage table exisits for the passed voltage
291  * domain or if there is no matching entry.
292  */
293 struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
294                 unsigned long volt)
295 {
296         struct omap_vdd_info *vdd;
297         int i;
298
299         if (!voltdm || IS_ERR(voltdm)) {
300                 pr_warning("%s: VDD specified does not exist!\n", __func__);
301                 return ERR_PTR(-EINVAL);
302         }
303
304         vdd = voltdm->vdd;
305
306         if (!vdd->volt_data) {
307                 pr_warning("%s: voltage table does not exist for vdd_%s\n",
308                         __func__, voltdm->name);
309                 return ERR_PTR(-ENODATA);
310         }
311
312         for (i = 0; vdd->volt_data[i].volt_nominal != 0; i++) {
313                 if (vdd->volt_data[i].volt_nominal == volt)
314                         return &vdd->volt_data[i];
315         }
316
317         pr_notice("%s: Unable to match the current voltage with the voltage"
318                 "table for vdd_%s\n", __func__, voltdm->name);
319
320         return ERR_PTR(-ENODATA);
321 }
322
323 /**
324  * omap_voltage_register_pmic() - API to register PMIC specific data
325  * @voltdm:     pointer to the VDD for which the PMIC specific data is
326  *              to be registered
327  * @pmic_info:  the structure containing pmic info
328  *
329  * This API is to be called by the SOC/PMIC file to specify the
330  * pmic specific info as present in omap_volt_pmic_info structure.
331  */
332 int omap_voltage_register_pmic(struct voltagedomain *voltdm,
333                 struct omap_volt_pmic_info *pmic_info)
334 {
335         struct omap_vdd_info *vdd;
336
337         if (!voltdm || IS_ERR(voltdm)) {
338                 pr_warning("%s: VDD specified does not exist!\n", __func__);
339                 return -EINVAL;
340         }
341
342         vdd = voltdm->vdd;
343
344         vdd->pmic_info = pmic_info;
345
346         return 0;
347 }
348
349 /**
350  * omap_voltage_get_dbgdir() - API to get pointer to the debugfs directory
351  *                              corresponding to a voltage domain.
352  *
353  * @voltdm:     pointer to the VDD whose debug directory is required.
354  *
355  * This API returns pointer to the debugfs directory corresponding
356  * to the voltage domain. Should be used by drivers requiring to
357  * add any debug entry for a particular voltage domain. Returns NULL
358  * in case of error.
359  */
360 struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm)
361 {
362         struct omap_vdd_info *vdd;
363
364         if (!voltdm || IS_ERR(voltdm)) {
365                 pr_warning("%s: VDD specified does not exist!\n", __func__);
366                 return NULL;
367         }
368
369         vdd = voltdm->vdd;
370
371         return vdd->debug_dir;
372 }
373
374 /**
375  * omap_change_voltscale_method() - API to change the voltage scaling method.
376  * @voltdm:     pointer to the VDD whose voltage scaling method
377  *              has to be changed.
378  * @voltscale_method:   the method to be used for voltage scaling.
379  *
380  * This API can be used by the board files to change the method of voltage
381  * scaling between vpforceupdate and vcbypass. The parameter values are
382  * defined in voltage.h
383  */
384 void omap_change_voltscale_method(struct voltagedomain *voltdm,
385                 int voltscale_method)
386 {
387         struct omap_vdd_info *vdd;
388
389         if (!voltdm || IS_ERR(voltdm)) {
390                 pr_warning("%s: VDD specified does not exist!\n", __func__);
391                 return;
392         }
393
394         vdd = voltdm->vdd;
395
396         switch (voltscale_method) {
397         case VOLTSCALE_VPFORCEUPDATE:
398                 vdd->volt_scale = omap_vp_forceupdate_scale;
399                 return;
400         case VOLTSCALE_VCBYPASS:
401                 vdd->volt_scale = omap_vc_bypass_scale;
402                 return;
403         default:
404                 pr_warning("%s: Trying to change the method of voltage scaling"
405                         "to an unsupported one!\n", __func__);
406         }
407 }
408
409 /**
410  * omap_voltage_late_init() - Init the various voltage parameters
411  *
412  * This API is to be called in the later stages of the
413  * system boot to init the voltage controller and
414  * voltage processors.
415  */
416 int __init omap_voltage_late_init(void)
417 {
418         struct voltagedomain *voltdm;
419
420         if (list_empty(&voltdm_list)) {
421                 pr_err("%s: Voltage driver support not added\n",
422                         __func__);
423                 return -EINVAL;
424         }
425
426         voltage_dir = debugfs_create_dir("voltage", NULL);
427         if (IS_ERR(voltage_dir))
428                 pr_err("%s: Unable to create voltage debugfs main dir\n",
429                         __func__);
430         list_for_each_entry(voltdm, &voltdm_list, node) {
431                 if (!voltdm->scalable)
432                         continue;
433
434                 if (voltdm->vc) {
435                         voltdm->vdd->volt_scale = omap_vc_bypass_scale;
436                         omap_vc_init_channel(voltdm);
437                 }
438
439                 if (voltdm->vdd) {
440                         if (omap_vdd_data_configure(voltdm))
441                                 continue;
442                         vdd_debugfs_init(voltdm);
443                         omap_vp_init(voltdm);
444                 }
445         }
446
447         return 0;
448 }
449
450 static struct voltagedomain *_voltdm_lookup(const char *name)
451 {
452         struct voltagedomain *voltdm, *temp_voltdm;
453
454         voltdm = NULL;
455
456         list_for_each_entry(temp_voltdm, &voltdm_list, node) {
457                 if (!strcmp(name, temp_voltdm->name)) {
458                         voltdm = temp_voltdm;
459                         break;
460                 }
461         }
462
463         return voltdm;
464 }
465
466 /**
467  * voltdm_add_pwrdm - add a powerdomain to a voltagedomain
468  * @voltdm: struct voltagedomain * to add the powerdomain to
469  * @pwrdm: struct powerdomain * to associate with a voltagedomain
470  *
471  * Associate the powerdomain @pwrdm with a voltagedomain @voltdm.  This
472  * enables the use of voltdm_for_each_pwrdm().  Returns -EINVAL if
473  * presented with invalid pointers; -ENOMEM if memory could not be allocated;
474  * or 0 upon success.
475  */
476 int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm)
477 {
478         if (!voltdm || !pwrdm)
479                 return -EINVAL;
480
481         pr_debug("voltagedomain: associating powerdomain %s with voltagedomain "
482                  "%s\n", pwrdm->name, voltdm->name);
483
484         list_add(&pwrdm->voltdm_node, &voltdm->pwrdm_list);
485
486         return 0;
487 }
488
489 /**
490  * voltdm_for_each_pwrdm - call function for each pwrdm in a voltdm
491  * @voltdm: struct voltagedomain * to iterate over
492  * @fn: callback function *
493  *
494  * Call the supplied function @fn for each powerdomain in the
495  * voltagedomain @voltdm.  Returns -EINVAL if presented with invalid
496  * pointers; or passes along the last return value of the callback
497  * function, which should be 0 for success or anything else to
498  * indicate failure.
499  */
500 int voltdm_for_each_pwrdm(struct voltagedomain *voltdm,
501                           int (*fn)(struct voltagedomain *voltdm,
502                                     struct powerdomain *pwrdm))
503 {
504         struct powerdomain *pwrdm;
505         int ret = 0;
506
507         if (!fn)
508                 return -EINVAL;
509
510         list_for_each_entry(pwrdm, &voltdm->pwrdm_list, voltdm_node)
511                 ret = (*fn)(voltdm, pwrdm);
512
513         return ret;
514 }
515
516 /**
517  * voltdm_for_each - call function on each registered voltagedomain
518  * @fn: callback function *
519  *
520  * Call the supplied function @fn for each registered voltagedomain.
521  * The callback function @fn can return anything but 0 to bail out
522  * early from the iterator.  Returns the last return value of the
523  * callback function, which should be 0 for success or anything else
524  * to indicate failure; or -EINVAL if the function pointer is null.
525  */
526 int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user),
527                     void *user)
528 {
529         struct voltagedomain *temp_voltdm;
530         int ret = 0;
531
532         if (!fn)
533                 return -EINVAL;
534
535         list_for_each_entry(temp_voltdm, &voltdm_list, node) {
536                 ret = (*fn)(temp_voltdm, user);
537                 if (ret)
538                         break;
539         }
540
541         return ret;
542 }
543
544 static int _voltdm_register(struct voltagedomain *voltdm)
545 {
546         if (!voltdm || !voltdm->name)
547                 return -EINVAL;
548
549         INIT_LIST_HEAD(&voltdm->pwrdm_list);
550         list_add(&voltdm->node, &voltdm_list);
551
552         pr_debug("voltagedomain: registered %s\n", voltdm->name);
553
554         return 0;
555 }
556
557 /**
558  * voltdm_lookup - look up a voltagedomain by name, return a pointer
559  * @name: name of voltagedomain
560  *
561  * Find a registered voltagedomain by its name @name.  Returns a pointer
562  * to the struct voltagedomain if found, or NULL otherwise.
563  */
564 struct voltagedomain *voltdm_lookup(const char *name)
565 {
566         struct voltagedomain *voltdm ;
567
568         if (!name)
569                 return NULL;
570
571         voltdm = _voltdm_lookup(name);
572
573         return voltdm;
574 }
575
576 /**
577  * voltdm_init - set up the voltagedomain layer
578  * @voltdm_list: array of struct voltagedomain pointers to register
579  *
580  * Loop through the array of voltagedomains @voltdm_list, registering all
581  * that are available on the current CPU. If voltdm_list is supplied
582  * and not null, all of the referenced voltagedomains will be
583  * registered.  No return value.
584  */
585 void voltdm_init(struct voltagedomain **voltdms)
586 {
587         struct voltagedomain **v;
588
589         if (voltdms) {
590                 for (v = voltdms; *v; v++)
591                         _voltdm_register(*v);
592         }
593 }