misc: tegra-baseband: support bypass/boost DC/DC
[linux-3.10.git] / drivers / misc / tegra_ppm.c
1 /*
2  * Copyright (c) 2011-2014, NVIDIA CORPORATION. All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/seq_file.h>
20 #include <linux/slab.h>
21 #include <linux/module.h>
22 #include <linux/uaccess.h>
23 #include <linux/clk.h>
24 #include <linux/hashtable.h>
25 #include <linux/fs.h>
26 #include <linux/debugfs.h>
27 #include <linux/of.h>
28 #include <linux/tegra_ppm.h>
29
30 #define for_each_fv_entry(fv, fve) \
31         for (fve = fv->table + fv->size - 1; fve >= fv->table; fve--)
32
33 struct fv_relation {
34         struct mutex lock;
35         struct clk *c;
36         int (*lookup_voltage)(struct clk*, long unsigned int);
37
38         ssize_t max_size;
39         int freq_step;
40
41         ssize_t size;
42         struct fv_entry {
43                 unsigned int freq;
44                 int voltage_mv;
45         } *table;
46 };
47
48 struct maxf_cache_entry {
49         u32 budget;
50         s16 temp_c;
51         u8 cores;
52         u8 units;
53         unsigned maxf;
54         struct hlist_node nib; /* next in bucket*/
55 };
56
57 struct tegra_ppm {
58         const char *name;
59
60         struct fv_relation *fv;
61         struct tegra_ppm_params *params;
62         int iddq_ma;
63
64         DECLARE_HASHTABLE(maxf_cache, 7);
65
66         struct mutex lock;
67
68         struct dentry *debugfs_dir;
69
70         struct {
71                 s32 temp_c;
72                 u32 volt_mv;
73                 u32 freq_hz;
74                 u32 cores;
75                 u32 iddq_ma;
76         } model_query;
77
78         struct {
79                 s32 temp_c;
80                 u32 cores;
81                 u32 iddq_ma;
82                 u32 budget;
83         } cap_query;
84 };
85
86 static int fv_relation_update(struct fv_relation *fv)
87 {
88         int ret = 0;
89         unsigned long f, maxf;
90         struct fv_entry *fve;
91
92         mutex_lock(&fv->lock);
93
94         maxf = clk_round_rate(fv->c, ULONG_MAX);
95         if (IS_ERR_VALUE(maxf))
96                 return -ENODATA;
97
98         fv->size = maxf / fv->freq_step + 1;
99
100         if (fv->size > fv->max_size) {
101                 pr_warn("%s: fv->table ought to be bigger (%zu > %zu)\n",
102                         __func__, fv->size, fv->max_size);
103                 fv->size = fv->max_size;
104         }
105
106         f = maxf;
107         for_each_fv_entry(fv, fve) {
108                 fve->freq = f;
109                 fve->voltage_mv = fv->lookup_voltage(fv->c, fve->freq);
110
111                 if (fve->voltage_mv < 0) {
112                         int mv = (f == maxf ? INT_MAX : fve[1].voltage_mv);
113                         pr_warn("%s: failure %d. guessing %dmV for %uHz\n",
114                                 __func__, fve->voltage_mv, mv, fve->freq);
115                         fve->voltage_mv = mv;
116                         ret = -ENODATA;
117                 }
118                 f -= fv->freq_step;
119         }
120
121         mutex_unlock(&fv->lock);
122
123         return ret;
124 }
125
126 /**
127  * fv_relation_create() - build a voltage/frequency table for a clock
128  * @c : the subject clock domain
129  * @freq_step : step size between frequency points in Hz
130  * @max_size : max number of frequency/voltage entries
131  * @lookup_voltage : callback to get the minimium voltage for a frequency
132  *
133  * fv_relation_create constructs a voltage/frequency table for a given
134  * clock. The table has evenly spaced frequencies from 0Hz to the maximum
135  * rate of the clock.
136  *
137  * Return: pointer to the the newly created &struct fv_relation on
138  *  success. -%ENOMEM or -%EINVAL for the usual reasons. -%ENODATA if
139  *  a call to @lookup_voltage or clk_round_rate fails
140  */
141 struct fv_relation *fv_relation_create(struct clk *c, int freq_step,
142                                        ssize_t max_size, int (*lookup_voltage)(
143                                                struct clk *, long unsigned int))
144 {
145         int ret = 0;
146         struct fv_relation *result;
147         struct fv_entry *table;
148
149         if (WARN_ON(!c || !lookup_voltage || freq_step <= 0))
150                 return ERR_PTR(-EINVAL);
151
152         result = kzalloc(sizeof(struct fv_relation), GFP_KERNEL);
153         table = kzalloc(sizeof(struct fv_entry[max_size]), GFP_KERNEL);
154
155         if (!result || !table) {
156                 kfree(result);
157                 kfree(table);
158                 return ERR_PTR(-ENOMEM);
159         }
160
161         mutex_init(&result->lock);
162         result->c = c;
163         result->lookup_voltage = lookup_voltage;
164         result->freq_step = freq_step;
165         result->max_size = max_size;
166         result->table = table;
167
168         ret = fv_relation_update(result);
169         if (ret) {
170                 kfree(result->table);
171                 kfree(result);
172                 result = ERR_PTR(ret);
173         }
174         return result;
175 }
176 EXPORT_SYMBOL_GPL(fv_relation_create);
177
178 /**
179  * fv_relation_destroy() - inverse of fv_relation_create
180  * @fv : pointer to the &struct fv_relation to be destroyed
181  *
182  * Free the resources created by a previous call to fv_relation_create
183  */
184 void fv_relation_destroy(struct fv_relation *fv)
185 {
186         if (fv)
187                 kfree(fv->table);
188         kfree(fv);
189 }
190 EXPORT_SYMBOL_GPL(fv_relation_destroy);
191
192 static inline s64 _pow(s64 val, int pwr)
193 {
194         s64 retval = val ? 1 : 0;
195
196         while (val && pwr) {
197                 if (pwr & 1)
198                         retval *= val;
199                 pwr >>= 1;
200                 if (pwr)
201                         val *= val;
202         }
203
204         return retval;
205 }
206
207 static s64 calc_leakage_calc_step(struct tegra_ppm_params *common,
208                                   int iddq_ma, int temp_c, unsigned voltage_mv,
209                                   int i, int j, int k)
210 {
211         s64 leakage_calc_step;
212
213         leakage_calc_step = common->leakage_consts_ijk[i][j][k];
214
215         /* iddq raised to i */
216         for (; i; i--) {
217                 leakage_calc_step *= iddq_ma;
218
219                 /* Convert (mA) to (A) */
220                 leakage_calc_step = div64_s64(leakage_calc_step, 1000);
221         }
222
223         leakage_calc_step = div64_s64(leakage_calc_step, _pow(1000, i));
224
225         /* voltage raised to j */
226         leakage_calc_step *= _pow(voltage_mv, j);
227
228         /* Convert (mV)^j to (V)^j */
229         leakage_calc_step = div64_s64(leakage_calc_step, _pow(1000, j));
230
231         /* temp raised to k */
232         leakage_calc_step *= _pow(temp_c, k);
233
234         /* Convert (C)^k to (dC)^k */
235         leakage_calc_step = div64_s64(leakage_calc_step,
236                                         _pow(10, k));
237
238         return leakage_calc_step;
239 }
240
241 static s64 calc_leakage_ma(struct tegra_ppm_params *common,
242                            int iddq_ma, int temp_c,
243                            unsigned int voltage_mv, int cores)
244 {
245         int i, j, k;
246         s64 leakage_ma = 0;
247
248         for (i = 0; i <= 3; i++)
249                 for (j = 0; j <= 3; j++)
250                         for (k = 0; k <= 3; k++)
251                                 leakage_ma +=
252                                         calc_leakage_calc_step(
253                                                 common, iddq_ma,
254                                                 temp_c, voltage_mv, i, j, k);
255
256         /* leakage model coefficients were pre-scaled */
257         leakage_ma = div64_s64(leakage_ma, common->ijk_scaled);
258
259         /* scale leakage based on number of cores */
260         leakage_ma *= common->leakage_consts_n[cores - 1];
261         leakage_ma = div64_s64(leakage_ma, 1000);
262
263         /* set floor for leakage current */
264         if (leakage_ma <= common->leakage_min)
265                 leakage_ma = common->leakage_min;
266
267         return leakage_ma;
268 }
269
270 static s64 calc_dynamic_ma(struct tegra_ppm_params *common,
271                            unsigned int voltage_mv, int cores,
272                            unsigned int freq_khz)
273 {
274         s64 dyn_ma;
275
276         /* Convert freq to MHz */
277         dyn_ma = voltage_mv * freq_khz / 1000;
278
279         /* Convert mV to V */
280         dyn_ma = div64_s64(dyn_ma, 1000);
281         dyn_ma *= common->dyn_consts_n[cores - 1];
282
283         /* dyn_const_n was in fF, convert it to nF */
284         dyn_ma = div64_s64(dyn_ma, 1000000);
285
286         return dyn_ma;
287 }
288
289 static s64 calc_total_ma(struct tegra_ppm_params *params,
290                         int iddq_ma, int temp_c,
291                         unsigned int voltage_mv, int cores,
292                         unsigned int freq_khz)
293 {
294         s64 leak = calc_leakage_ma(params, iddq_ma,
295                                    temp_c, voltage_mv, cores);
296         s64 dyn = calc_dynamic_ma(params, voltage_mv,
297                                   cores, freq_khz);
298         return leak + dyn;
299 }
300
301 static s64 calc_total_mw(struct tegra_ppm_params *params,
302                         int iddq_ma, int temp_c,
303                         unsigned int voltage_mv, int cores,
304                         unsigned int freq_khz)
305 {
306         s64 cur_ma = calc_total_ma(params, iddq_ma, temp_c,
307                                    voltage_mv, cores, freq_khz);
308         return div64_s64(cur_ma * voltage_mv, 1000);
309 }
310
311 static unsigned int calculate_maxf(
312         struct tegra_ppm_params *params,
313         struct fv_relation *fv, int cores,
314         unsigned int budget, int units, int temp_c, int iddq_ma)
315 {
316         unsigned int voltage_mv, freq_khz = 0;
317         struct fv_entry *fve;
318         s64 val = 0;
319
320         mutex_lock(&fv->lock);
321         for_each_fv_entry(fv, fve) {
322                 freq_khz = fve->freq / 1000;
323                 voltage_mv = fve->voltage_mv;
324
325                 if (units == TEGRA_PPM_UNITS_MILLIWATTS)
326                         val = calc_total_mw(params, iddq_ma, temp_c,
327                                             voltage_mv, cores, freq_khz);
328                 else if (units == TEGRA_PPM_UNITS_MILLIAMPS)
329                         val = calc_total_ma(params, iddq_ma, temp_c,
330                                             voltage_mv, cores, freq_khz);
331
332                 if (val <= budget)
333                         goto end;
334
335                 freq_khz = 0;
336         }
337  end:
338         mutex_unlock(&fv->lock);
339         return freq_khz;
340 }
341
342 #define make_key(budget, units, temp_c, ncores) \
343         ((ncores<<24) ^ (units<<23) ^ (budget << 8) ^ temp_c)
344
345 static unsigned get_maxf_locked(struct tegra_ppm *ctx, unsigned limit,
346                                 int units, int temp_c, int cores)
347 {
348         unsigned maxf;
349         struct maxf_cache_entry *me;
350         u32 key = make_key(limit, units, temp_c, cores);
351
352         if ((WARN(cores < 0 || cores > ctx->params->n_cores,
353                   "power model can't handle %d cores", cores))
354             || (WARN(units != TEGRA_PPM_UNITS_MILLIAMPS &&
355                      units != TEGRA_PPM_UNITS_MILLIWATTS,
356                      "illegal value for units (%d)", units)))
357                 return 0;
358
359         /* check cache */
360         hash_for_each_possible(ctx->maxf_cache, me, nib, key)
361                 if (me->budget == limit && me->temp_c == temp_c &&
362                     me->cores == cores && me->units == units) {
363                         maxf = me->maxf;
364                         return maxf;
365                 }
366
367         /* service a miss */
368         maxf = calculate_maxf(ctx->params,
369                               ctx->fv,
370                               cores,
371                               limit,
372                               units,
373                               temp_c,
374                               ctx->iddq_ma);
375
376         /* best effort to cache the result */
377         me = kzalloc(sizeof(*me), GFP_KERNEL);
378         if (!IS_ERR_OR_NULL(me)) {
379                 me->budget = limit;
380                 me->units = units;
381                 me->temp_c = temp_c;
382                 me->maxf = maxf;
383                 me->cores = cores;
384                 hash_add(ctx->maxf_cache, &me->nib, key);
385         }
386         return maxf;
387 }
388
389 /**
390  * tegra_ppm_get_maxf() - query maximum allowable frequency given a budget
391  * @ctx : the power model to query
392  * @units: %TEGRA_PPM_MILLIWATTS or %TEGRA_PPM_MILLIAMPS
393  * @limit : the budget
394  * @temp_c : the temperature in degrees C
395  * @cores : the number of "cores" consuming power
396  *
397  * If the result has not been previously memoized, compute and memoize
398  * the maximum allowable frequency give a power model (@ctx), a budget
399  * (@limit, in mA or mW as specified by @units), a temperature
400  * (temp_c, in degrees Celcius), and the number of active cores
401  * (@cores).
402  *
403  * Return: If the value of cores is outside the model's expected range, 0.
404  *    Otherwise, the (previously) computed frequency in Hz.
405  */
406 unsigned tegra_ppm_get_maxf(struct tegra_ppm *ctx, unsigned int limit,
407                             int units, int temp_c, int cores)
408 {
409         unsigned ret;
410         mutex_lock(&ctx->lock);
411
412         ret = get_maxf_locked(ctx, limit, units, temp_c, cores);
413
414         mutex_unlock(&ctx->lock);
415         return ret;
416 }
417
418 /**
419  * tegra_ppm_drop_cache() - eliminate memoized data for a struct tegra_ppm
420  * @ctx
421  *
422  * Discards previously memoized results from tegra_ppm_get_maxf. Also,
423  * recomputes the v/f curve for the &struct fv_relation used during the creation
424  * of @ctx. Typically called when by the holder of a &struct tegra_ppm pointer
425  * when the underlying v/f operating curve has changed.
426  *
427  */
428 void tegra_ppm_drop_cache(struct tegra_ppm *ctx)
429 {
430         int bucket;
431         struct hlist_node *tmp;
432         struct maxf_cache_entry *me;
433
434         mutex_lock(&ctx->lock);
435         hash_for_each_safe(ctx->maxf_cache, bucket, tmp, me, nib) {
436                 hash_del(&me->nib);
437                 kfree(me);
438         }
439
440         WARN_ON(fv_relation_update(ctx->fv));
441         mutex_unlock(&ctx->lock);
442 }
443 EXPORT_SYMBOL_GPL(tegra_ppm_drop_cache);
444
445 #ifdef CONFIG_DEBUG_FS
446
447 static int total_ma_show(void *data, u64 *val)
448 {
449         struct tegra_ppm *ctx = data;
450         int cores = ctx->model_query.cores;
451
452         if (cores <= 0 || cores > ctx->params->n_cores)
453                 return -EINVAL;
454
455         mutex_lock(&ctx->lock);
456         *val = calc_total_ma(ctx->params, ctx->model_query.iddq_ma,
457                              ctx->model_query.temp_c, ctx->model_query.volt_mv,
458                              ctx->model_query.cores,
459                              ctx->model_query.freq_hz / 1000);
460         mutex_unlock(&ctx->lock);
461
462         return 0;
463 }
464 DEFINE_SIMPLE_ATTRIBUTE(total_ma_fops, total_ma_show, NULL, "%llu\n");
465
466 static int total_mw_show(void *data, u64 *val)
467 {
468         struct tegra_ppm *ctx = data;
469         int cores = ctx->model_query.cores;
470
471         if (cores <= 0 || cores > ctx->params->n_cores)
472                 return -EINVAL;
473
474         mutex_lock(&ctx->lock);
475         *val = calc_total_mw(ctx->params, ctx->model_query.iddq_ma,
476                              ctx->model_query.temp_c, ctx->model_query.volt_mv,
477                              ctx->model_query.cores,
478                              ctx->model_query.freq_hz / 1000);
479         mutex_unlock(&ctx->lock);
480
481         return 0;
482 }
483 DEFINE_SIMPLE_ATTRIBUTE(total_mw_fops, total_mw_show, NULL, "%llu\n");
484
485 static int show_ma_limited_hz(void *data, u64 *val)
486 {
487         struct tegra_ppm *ctx = data;
488         int cores = ctx->cap_query.cores;
489
490         if (cores <= 0 || cores > ctx->params->n_cores)
491                 return -EINVAL;
492
493         *val = tegra_ppm_get_maxf(ctx, ctx->cap_query.budget,
494                                   TEGRA_PPM_UNITS_MILLIAMPS,
495                                   ctx->cap_query.temp_c,
496                                   ctx->cap_query.cores);
497         return 0;
498 }
499 DEFINE_SIMPLE_ATTRIBUTE(ma_limited_hz_fops, show_ma_limited_hz, NULL, "%llu\n");
500
501 static int show_mw_limited_hz(void *data, u64 *val)
502 {
503         struct tegra_ppm *ctx = data;
504         int cores = ctx->cap_query.cores;
505
506         if (cores <= 0 || cores > ctx->params->n_cores)
507                 return -EINVAL;
508
509         *val = tegra_ppm_get_maxf(ctx, ctx->cap_query.budget,
510                                   TEGRA_PPM_UNITS_MILLIWATTS,
511                                   ctx->cap_query.temp_c,
512                                   ctx->cap_query.cores);
513         return 0;
514 }
515 DEFINE_SIMPLE_ATTRIBUTE(mw_limited_hz_fops, show_mw_limited_hz, NULL, "%llu\n");
516
517 static int ppm_cache_show(struct seq_file *s, void *data)
518 {
519         int bucket;
520         struct maxf_cache_entry *me;
521         struct tegra_ppm *ctx = s->private;
522
523         seq_printf(s, "%10s %5s %10s %10s %10s\n",
524                    "budget", "units", "temp['C]", "cores[#]", "fmax [Hz]");
525
526         hash_for_each(ctx->maxf_cache, bucket, me, nib)
527                 seq_printf(s, "%10d %5s %10d %10d %10d\n",
528                            me->budget,
529                            me->units == TEGRA_PPM_UNITS_MILLIAMPS ? "mA" : "mW",
530                            me->temp_c, me->cores, me->maxf);
531
532         return 0;
533 }
534
535 static ssize_t ppm_cache_poison(struct file *f, const char __user *buf,
536                             size_t sz, loff_t *off)
537 {
538         struct tegra_ppm *ctx = f->f_inode->i_private;
539         tegra_ppm_drop_cache(ctx);
540
541         return sz;
542 }
543
544 static int ppm_cache_open(struct inode *inode, struct file *file)
545 {
546         return single_open(file, ppm_cache_show, inode->i_private);
547 }
548
549 static const struct file_operations ppm_cache_fops = {
550         .open = ppm_cache_open,
551         .read = seq_read,
552         .write = ppm_cache_poison,
553         .release = single_release,
554 };
555
556 static struct dentry *ppm_debugfs_dir(void)
557 {
558         static struct mutex lock = __MUTEX_INITIALIZER(lock);
559         static struct dentry *base_dir;
560
561         mutex_lock(&lock);
562         if (IS_ERR_OR_NULL(base_dir))
563                 base_dir = debugfs_create_dir("tegra_ppm", NULL);
564         mutex_unlock(&lock);
565
566         return base_dir;
567 }
568
569 static int model_debugfs_init(struct tegra_ppm *ctx, struct dentry *parent)
570 {
571         parent = debugfs_create_dir("query_model", parent);
572         if (IS_ERR_OR_NULL(parent))
573                 return PTR_ERR(parent);
574
575         debugfs_create_u32("temp_c", S_IRUSR | S_IWUSR, parent,
576                            &ctx->model_query.temp_c);
577         debugfs_create_u32("volt_mv", S_IRUSR | S_IWUSR, parent,
578                            &ctx->model_query.volt_mv);
579         debugfs_create_u32("freq_hz", S_IRUSR | S_IWUSR, parent,
580                            &ctx->model_query.freq_hz);
581         debugfs_create_u32("cores", S_IRUSR | S_IWUSR, parent,
582                            &ctx->model_query.cores);
583         debugfs_create_u32("iddq_ma", S_IRUSR | S_IWUSR, parent,
584                            &ctx->model_query.iddq_ma);
585         debugfs_create_file("total_ma", S_IRUSR, parent, ctx,
586                             &total_ma_fops);
587         debugfs_create_file("total_mw", S_IRUSR, parent, ctx,
588                             &total_mw_fops);
589
590         return 0;
591 }
592
593 static int cap_debugfs_init(struct tegra_ppm *ctx, struct dentry *parent)
594 {
595         parent = debugfs_create_dir("query_cap", parent);
596         if (IS_ERR_OR_NULL(parent))
597                 return PTR_ERR(parent);
598
599         debugfs_create_u32("temp_c", S_IRUSR | S_IWUSR, parent,
600                            &ctx->cap_query.temp_c);
601         debugfs_create_u32("cores", S_IRUSR | S_IWUSR, parent,
602                            &ctx->cap_query.cores);
603         debugfs_create_u32("iddq_ma", S_IRUSR | S_IWUSR, parent,
604                            &ctx->cap_query.iddq_ma);
605         debugfs_create_u32("budget", S_IRUSR | S_IWUSR, parent,
606                            &ctx->cap_query.budget);
607         debugfs_create_file("ma_limited_hz", S_IRUSR, parent, ctx,
608                             &ma_limited_hz_fops);
609         debugfs_create_file("mw_limited_hz", S_IRUSR, parent, ctx,
610                             &mw_limited_hz_fops);
611
612         return 0;
613 }
614
615 static int ppm_debugfs_init(struct tegra_ppm *ctx,
616                             struct dentry *parent)
617 {
618         if (!parent) {
619                 parent = ppm_debugfs_dir();
620                 if (IS_ERR_OR_NULL(parent))
621                         return PTR_ERR(parent);
622                 parent = debugfs_create_dir(ctx->name, parent);
623         } else {
624                 char buf[32];
625                 snprintf(buf, sizeof(buf), "ppm.%s", ctx->name);
626                 parent = debugfs_create_dir(buf, parent);
627         }
628
629         if (IS_ERR_OR_NULL(parent))
630                 return PTR_ERR(parent);
631
632         ctx->debugfs_dir = parent;
633
634         debugfs_create_file("ppm_cache", S_IRUSR | S_IWUSR, parent,
635                             ctx, &ppm_cache_fops);
636         debugfs_create_u32_array("vf_lut", S_IRUSR, parent,
637                                  (u32 *)ctx->fv->table, 2*ctx->fv->size);
638         debugfs_create_u32("iddq_ma", S_IRUSR, parent,
639                            &ctx->iddq_ma);
640
641         model_debugfs_init(ctx, parent);
642         cap_debugfs_init(ctx, parent);
643
644         return 0;
645 }
646
647 #else
648 static int ppm_debugfs_init(struct tegra_ppm *ctx
649                             struct dentry *parent)
650 { return 0; }
651 #endif /* CONFIG_DEBUG_FS */
652
653 /**
654  * of_read_tegra_ppm_params() - read PPM parameters from device tree
655  * @np : the device tree node containing the PPM information
656  *
657  * Allocate a &struct tegra_ppm_params. Populate it according to the
658  * device tree properties in *@np.
659  *
660  * If this function succeeds, the caller is responsible for
661  * (eventually) calling kfree on the returned result.
662  *
663  * Return: on success, a pointer to thew new &struct
664  * tegra_ppm_params. -%EINVAL or -%EDOM for device tree content
665  * errors. %NULL or other errors for a kzalloc failure.
666  */
667 struct tegra_ppm_params *of_read_tegra_ppm_params(struct device_node *np)
668 {
669         int ret;
670         int n_dyn, n_leak, n_coeff;
671         struct tegra_ppm_params *params;
672
673         if (!np)
674                 return ERR_PTR(-EINVAL);
675
676         n_dyn = of_property_count_u32(np, "nvidia,tegra-ppm-cdyn");
677         if (n_dyn <= 0) {
678                 pr_warn("%s: missing required property nvidia,tegra-ppm-cdyn\n",
679                         __func__);
680                 return ERR_PTR(-EINVAL);
681         } else if (n_dyn > TEGRA_PPM_MAX_CORES) {
682                 pr_warn("%s: can't handle nvidia,tegra-ppm-cdyn of length %d\n",
683                         __func__, n_dyn);
684                 return ERR_PTR(-EDOM);
685         }
686
687         n_coeff = of_property_count_u32(np, "nvidia,tegra-ppm-leakage_coeffs");
688         if (n_coeff <= 0) {
689                 pr_warn("%s: missing required property %s\n",
690                         __func__, "nvidia,tegra-ppm-leakage_coeffs");
691                 return ERR_PTR(-EINVAL);
692         } else if (n_coeff != 64) {
693                 pr_warn("%s: expected nvidia,tegra-ppm-cdyn length 64, not %d\n",
694                         __func__, n_coeff);
695                 return ERR_PTR(-EDOM);
696         }
697
698         n_leak = of_property_count_u32(np, "nvidia,tegra-ppm-leakage_weights");
699         if ((n_dyn == 1) ? (n_leak > 1) : (n_leak != n_dyn)) {
700                 pr_warn("__func__: nvidia,tegra-ppm-leakage_weights required but invalid\n");
701                 return ERR_PTR(-EINVAL);
702         }
703
704         params = kzalloc(sizeof(struct tegra_ppm_params), GFP_KERNEL);
705         if (IS_ERR_OR_NULL(params))
706                 return params;
707         params->n_cores = n_dyn;
708
709         ret = (of_property_read_u32_array(
710                        np, "nvidia,tegra-ppm-cdyn",
711                        (u32 *)&params->dyn_consts_n, params->n_cores)
712                || of_property_read_u32_array(
713                        np, "nvidia,tegra-ppm-leakage_coeffs",
714                        (u32 *)&params->leakage_consts_ijk, 4 * 4 * 4));
715         WARN_ON(ret); /* this shouldn't happen */
716         if (ret)
717                 goto err;
718
719         if (n_leak < 0)
720                 params->leakage_consts_n[0] = 1000;
721         else
722                 ret = of_property_read_u32_array(
723                         np, "nvidia,tegra-ppm-leakage_weights",
724                         (u32 *)&params->leakage_consts_n, params->n_cores);
725         WARN_ON(ret); /* this shouldn't happen */
726         if (ret)
727                 goto err;
728
729         if (of_property_read_u32(np, "nvidia,tegra-ppm-min_leakage",
730                                  &params->leakage_min))
731                 params->leakage_min = 0;
732
733         if (of_property_read_u32(np, "nvidia,tegra-ppm-coeff_scale",
734                                  &params->ijk_scaled))
735                 params->ijk_scaled = 100000;
736
737         return params;
738 err:
739         kfree(params);
740         return ERR_PTR(ret);
741 }
742 EXPORT_SYMBOL_GPL(of_read_tegra_ppm_params);
743
744
745 /**
746  * tegra_ppm_create() - build a processor power model
747  * @name : a name for this model to use in debugfs
748  * @fv : relation between frequency and minimum allowable voltage
749  * @params : parameters for the active and leakage power calculations
750  * @iddq_ma : the quiescent current of the voltage domain
751  * @debugfs_dir : optional location for debugfs nodes
752  *
753  * Construct a processor power model which supports querying the maximum
754  * allowable frequency (for a given temperature) within a current (mA)
755  * budget.
756  *
757  * Return: pointer to the the newly created &struct tegra_ppm on
758  * success. -%EINVAL if name, fv, or params doesn't point to anything.
759  * -%ENOMEM on memory allocation failure.
760  */
761 struct tegra_ppm *tegra_ppm_create(const char *name,
762                                    struct fv_relation *fv,
763                                    struct tegra_ppm_params *params,
764                                    int iddq_ma,
765                                    struct dentry *debugfs_dir)
766 {
767         struct tegra_ppm *result;
768
769         if (IS_ERR_OR_NULL(name) || IS_ERR_OR_NULL(fv) ||
770             IS_ERR_OR_NULL(params))
771                 return ERR_PTR(-EINVAL);
772
773         result = kzalloc(sizeof(struct tegra_ppm), GFP_KERNEL);
774         if (!result)
775                 return ERR_PTR(-ENOMEM);
776
777         mutex_init(&result->lock);
778
779         result->name = name;
780         result->fv = fv;
781         result->params = params;
782         result->iddq_ma = iddq_ma;
783
784         ppm_debugfs_init(result, debugfs_dir);
785
786         return result;
787 }
788 EXPORT_SYMBOL_GPL(tegra_ppm_create);
789
790 /**
791  * tegra_ppm_destroy() - inverse of tegra_ppm_create
792  * @doomed : pointer to struct to destroy
793  * @pfv : receptable for @doomed's fv_relation pointer
794  * @pparams : receptable for @doomed's tegra_ppm_params pointer
795  *
796  * Reverse the operations done by tegra_ppm create resulting in the
797  * deallocation of struct *@doomed. If @doomed is NULL, nothing is
798  * deallocated.
799  *
800  * If @pfv is non-NULL *@pfv is set to value passed to
801  * tegra_ppm_create as fv. Callers may use that value to destroy an
802  * fv_relation. Similarly for @pparams and the value passed to
803  * tegra_ppm_create as params.
804  *
805  * if @doomed is %NULL, *@pfv and *@pparams will still be set to %NULL
806  *
807  */
808 void tegra_ppm_destroy(struct tegra_ppm *doomed,
809                        struct fv_relation **pfv,
810                        struct tegra_ppm_params **pparams)
811 {
812         if (pfv)
813                 *pfv = doomed ? doomed->fv : NULL;
814         if (pparams)
815                 *pparams = doomed ? doomed->params : NULL;
816
817         if (!doomed)
818                 return;
819
820         debugfs_remove_recursive(doomed->debugfs_dir);
821         kfree(doomed);
822 }
823 EXPORT_SYMBOL_GPL(tegra_ppm_destroy);