1 /*
2 * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6 //#define DEBUG
7 #include <linux/clk.h>
8 #include <linux/cpufreq.h>
9 #include <linux/devfreq.h>
10 #include <linux/mfd/syscon.h>
11 #include <linux/module.h>
12 #include <linux/nvmem-consumer.h>
13 #include <linux/regmap.h>
14 #include <linux/regulator/consumer.h>
15 #include <linux/slab.h>
16 #include <linux/soc/rockchip/pvtm.h>
17 #include <linux/thermal.h>
18 #include <linux/pm_opp.h>
19 #include <linux/version.h>
20 #include <soc/rockchip/rockchip_opp_select.h>
21
22 #include "../../clk/rockchip/clk.h"
23 #include "../../opp/opp.h"
24 #include "../../devfreq/governor.h"
25
26 #define MAX_PROP_NAME_LEN 6
27 #define SEL_TABLE_END ~1
28 #define AVS_DELETE_OPP 0
29 #define AVS_SCALING_RATE 1
30
31 #define LEAKAGE_V1 1
32 #define LEAKAGE_V2 2
33 #define LEAKAGE_V3 3
34
35 #define to_thermal_opp_info(nb) container_of(nb, struct thermal_opp_info, \
36 thermal_nb)
37
38 struct sel_table {
39 int min;
40 int max;
41 int sel;
42 };
43
44 struct bin_sel_table {
45 int bin;
46 int sel;
47 };
48
49 struct pvtm_config {
50 unsigned int freq;
51 unsigned int volt;
52 unsigned int ch[2];
53 unsigned int sample_time;
54 unsigned int num;
55 unsigned int err;
56 unsigned int ref_temp;
57 unsigned int offset;
58 int temp_prop[2];
59 const char *tz_name;
60 struct thermal_zone_device *tz;
61 struct regmap *grf;
62 };
63
64 struct lkg_conversion_table {
65 int temp;
66 int conv;
67 };
68
69 struct otp_opp_info {
70 u16 min_freq;
71 u16 max_freq;
72 u8 volt;
73 u8 length;
74 } __packed;
75
76 #define PVTM_CH_MAX 8
77 #define PVTM_SUB_CH_MAX 8
78
79 #define FRAC_BITS 10
80 #define int_to_frac(x) ((x) << FRAC_BITS)
81 #define frac_to_int(x) ((x) >> FRAC_BITS)
82
83 static int pvtm_value[PVTM_CH_MAX][PVTM_SUB_CH_MAX];
84 static int lkg_version;
85
86 /*
87 * temp = temp * 10
88 * conv = exp(-ln(1.2) / 5 * (temp - 23)) * 100
89 */
90 static const struct lkg_conversion_table conv_table[] = {
91 { 200, 111 },
92 { 205, 109 },
93 { 210, 107 },
94 { 215, 105 },
95 { 220, 103 },
96 { 225, 101 },
97 { 230, 100 },
98 { 235, 98 },
99 { 240, 96 },
100 { 245, 94 },
101 { 250, 92 },
102 { 255, 91 },
103 { 260, 89 },
104 { 265, 88 },
105 { 270, 86 },
106 { 275, 84 },
107 { 280, 83 },
108 { 285, 81 },
109 { 290, 80 },
110 { 295, 78 },
111 { 300, 77 },
112 { 305, 76 },
113 { 310, 74 },
114 { 315, 73 },
115 { 320, 72 },
116 { 325, 70 },
117 { 330, 69 },
118 { 335, 68 },
119 { 340, 66 },
120 { 345, 65 },
121 { 350, 64 },
122 { 355, 63 },
123 { 360, 62 },
124 { 365, 61 },
125 { 370, 60 },
126 { 375, 58 },
127 { 380, 57 },
128 { 385, 56 },
129 { 390, 55 },
130 { 395, 54 },
131 { 400, 53 },
132 };
133
rockchip_nvmem_cell_read_common(struct device_node * np,const char * cell_id,void * val,size_t count)134 static int rockchip_nvmem_cell_read_common(struct device_node *np,
135 const char *cell_id,
136 void *val, size_t count)
137 {
138 struct nvmem_cell *cell;
139 void *buf;
140 size_t len;
141
142 cell = of_nvmem_cell_get(np, cell_id);
143 if (IS_ERR(cell))
144 return PTR_ERR(cell);
145
146 buf = nvmem_cell_read(cell, &len);
147 if (IS_ERR(buf)) {
148 nvmem_cell_put(cell);
149 return PTR_ERR(buf);
150 }
151 if (len != count) {
152 kfree(buf);
153 nvmem_cell_put(cell);
154 return -EINVAL;
155 }
156 memcpy(val, buf, count);
157 kfree(buf);
158 nvmem_cell_put(cell);
159
160 return 0;
161 }
162
rockchip_nvmem_cell_read_u8(struct device_node * np,const char * cell_id,u8 * val)163 int rockchip_nvmem_cell_read_u8(struct device_node *np, const char *cell_id,
164 u8 *val)
165 {
166 return rockchip_nvmem_cell_read_common(np, cell_id, val, sizeof(*val));
167 }
168 EXPORT_SYMBOL(rockchip_nvmem_cell_read_u8);
169
rockchip_nvmem_cell_read_u16(struct device_node * np,const char * cell_id,u16 * val)170 int rockchip_nvmem_cell_read_u16(struct device_node *np, const char *cell_id,
171 u16 *val)
172 {
173 return rockchip_nvmem_cell_read_common(np, cell_id, val, sizeof(*val));
174 }
175 EXPORT_SYMBOL(rockchip_nvmem_cell_read_u16);
176
rockchip_get_sel_table(struct device_node * np,char * porp_name,struct sel_table ** table)177 static int rockchip_get_sel_table(struct device_node *np, char *porp_name,
178 struct sel_table **table)
179 {
180 struct sel_table *sel_table;
181 const struct property *prop;
182 int count, i;
183
184 prop = of_find_property(np, porp_name, NULL);
185 if (!prop)
186 return -EINVAL;
187
188 if (!prop->value)
189 return -ENODATA;
190
191 count = of_property_count_u32_elems(np, porp_name);
192 if (count < 0)
193 return -EINVAL;
194
195 if (count % 3)
196 return -EINVAL;
197
198 sel_table = kzalloc(sizeof(*sel_table) * (count / 3 + 1), GFP_KERNEL);
199 if (!sel_table)
200 return -ENOMEM;
201
202 for (i = 0; i < count / 3; i++) {
203 of_property_read_u32_index(np, porp_name, 3 * i,
204 &sel_table[i].min);
205 of_property_read_u32_index(np, porp_name, 3 * i + 1,
206 &sel_table[i].max);
207 of_property_read_u32_index(np, porp_name, 3 * i + 2,
208 &sel_table[i].sel);
209 }
210 sel_table[i].min = 0;
211 sel_table[i].max = 0;
212 sel_table[i].sel = SEL_TABLE_END;
213
214 *table = sel_table;
215
216 return 0;
217 }
218
rockchip_get_bin_sel_table(struct device_node * np,char * porp_name,struct bin_sel_table ** table)219 static int rockchip_get_bin_sel_table(struct device_node *np, char *porp_name,
220 struct bin_sel_table **table)
221 {
222 struct bin_sel_table *sel_table;
223 const struct property *prop;
224 int count, i;
225
226 prop = of_find_property(np, porp_name, NULL);
227 if (!prop)
228 return -EINVAL;
229
230 if (!prop->value)
231 return -ENODATA;
232
233 count = of_property_count_u32_elems(np, porp_name);
234 if (count < 0)
235 return -EINVAL;
236
237 if (count % 2)
238 return -EINVAL;
239
240 sel_table = kzalloc(sizeof(*sel_table) * (count / 2 + 1), GFP_KERNEL);
241 if (!sel_table)
242 return -ENOMEM;
243
244 for (i = 0; i < count / 2; i++) {
245 of_property_read_u32_index(np, porp_name, 2 * i,
246 &sel_table[i].bin);
247 of_property_read_u32_index(np, porp_name, 2 * i + 1,
248 &sel_table[i].sel);
249 }
250
251 sel_table[i].bin = 0;
252 sel_table[i].sel = SEL_TABLE_END;
253
254 *table = sel_table;
255
256 return 0;
257 }
258
rockchip_get_sel(struct device_node * np,char * name,int value,int * sel)259 static int rockchip_get_sel(struct device_node *np, char *name,
260 int value, int *sel)
261 {
262 struct sel_table *table = NULL;
263 int i, ret = -EINVAL;
264
265 if (!sel)
266 return -EINVAL;
267
268 if (rockchip_get_sel_table(np, name, &table))
269 return -EINVAL;
270
271 for (i = 0; table[i].sel != SEL_TABLE_END; i++) {
272 if (value >= table[i].min) {
273 *sel = table[i].sel;
274 ret = 0;
275 }
276 }
277 kfree(table);
278
279 return ret;
280 }
281
rockchip_get_bin_sel(struct device_node * np,char * name,int value,int * sel)282 static int rockchip_get_bin_sel(struct device_node *np, char *name,
283 int value, int *sel)
284 {
285 struct bin_sel_table *table = NULL;
286 int i, ret = -EINVAL;
287
288 if (!sel)
289 return -EINVAL;
290
291 if (rockchip_get_bin_sel_table(np, name, &table))
292 return -EINVAL;
293
294 for (i = 0; table[i].sel != SEL_TABLE_END; i++) {
295 if (value == table[i].bin) {
296 *sel = table[i].sel;
297 ret = 0;
298 break;
299 }
300 }
301 kfree(table);
302
303 return ret;
304 }
305
rockchip_parse_pvtm_config(struct device_node * np,struct pvtm_config * pvtm)306 static int rockchip_parse_pvtm_config(struct device_node *np,
307 struct pvtm_config *pvtm)
308 {
309 if (of_property_read_u32(np, "rockchip,pvtm-freq", &pvtm->freq))
310 return -EINVAL;
311 if (of_property_read_u32(np, "rockchip,pvtm-volt", &pvtm->volt))
312 return -EINVAL;
313 if (of_property_read_u32(np, "rockchip,pvtm-sample-time",
314 &pvtm->sample_time))
315 return -EINVAL;
316 if (of_property_read_u32(np, "rockchip,pvtm-ref-temp", &pvtm->ref_temp))
317 return -EINVAL;
318 if (of_property_read_u32_array(np, "rockchip,pvtm-temp-prop",
319 pvtm->temp_prop, 2))
320 return -EINVAL;
321 if (of_property_read_string(np, "rockchip,pvtm-thermal-zone",
322 &pvtm->tz_name)) {
323 if (of_property_read_string(np, "rockchip,thermal-zone",
324 &pvtm->tz_name))
325 return -EINVAL;
326 }
327 pvtm->tz = thermal_zone_get_zone_by_name(pvtm->tz_name);
328 if (IS_ERR(pvtm->tz))
329 return -EINVAL;
330 if (!pvtm->tz->ops->get_temp)
331 return -EINVAL;
332 if (of_property_read_bool(np, "rockchip,pvtm-pvtpll")) {
333 if (of_property_read_u32(np, "rockchip,pvtm-offset",
334 &pvtm->offset))
335 return -EINVAL;
336 pvtm->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
337 if (IS_ERR(pvtm->grf))
338 return -EINVAL;
339 return 0;
340 }
341 if (of_property_read_u32_array(np, "rockchip,pvtm-ch", pvtm->ch, 2))
342 return -EINVAL;
343 if (pvtm->ch[0] >= PVTM_CH_MAX || pvtm->ch[1] >= PVTM_SUB_CH_MAX)
344 return -EINVAL;
345 if (of_property_read_u32(np, "rockchip,pvtm-number", &pvtm->num))
346 return -EINVAL;
347 if (of_property_read_u32(np, "rockchip,pvtm-error", &pvtm->err))
348 return -EINVAL;
349
350 return 0;
351 }
352
rockchip_get_pvtm_specific_value(struct device * dev,struct device_node * np,struct clk * clk,struct regulator * reg,int * target_value)353 static int rockchip_get_pvtm_specific_value(struct device *dev,
354 struct device_node *np,
355 struct clk *clk,
356 struct regulator *reg,
357 int *target_value)
358 {
359 struct pvtm_config *pvtm;
360 unsigned long old_freq;
361 unsigned int old_volt;
362 int cur_temp, diff_temp;
363 int cur_value, total_value, avg_value, diff_value;
364 int min_value, max_value;
365 int ret = 0, i = 0, retry = 2;
366
367 pvtm = kzalloc(sizeof(*pvtm), GFP_KERNEL);
368 if (!pvtm)
369 return -ENOMEM;
370
371 ret = rockchip_parse_pvtm_config(np, pvtm);
372 if (ret)
373 goto pvtm_value_out;
374
375 old_freq = clk_get_rate(clk);
376 old_volt = regulator_get_voltage(reg);
377
378 /*
379 * Set pvtm_freq to the lowest frequency in dts,
380 * so change frequency first.
381 */
382 ret = clk_set_rate(clk, pvtm->freq * 1000);
383 if (ret) {
384 dev_err(dev, "Failed to set pvtm freq\n");
385 goto pvtm_value_out;
386 }
387
388 ret = regulator_set_voltage(reg, pvtm->volt, pvtm->volt);
389 if (ret) {
390 dev_err(dev, "Failed to set pvtm_volt\n");
391 goto restore_clk;
392 }
393
394 /* The first few values may be fluctuant, if error is too big, retry*/
395 while (retry--) {
396 total_value = 0;
397 min_value = INT_MAX;
398 max_value = 0;
399
400 for (i = 0; i < pvtm->num; i++) {
401 cur_value = rockchip_get_pvtm_value(pvtm->ch[0],
402 pvtm->ch[1],
403 pvtm->sample_time);
404 if (cur_value <= 0) {
405 ret = -EINVAL;
406 goto resetore_volt;
407 }
408 if (cur_value < min_value)
409 min_value = cur_value;
410 if (cur_value > max_value)
411 max_value = cur_value;
412 total_value += cur_value;
413 }
414 if (max_value - min_value < pvtm->err)
415 break;
416 }
417 if (!total_value || !pvtm->num) {
418 ret = -EINVAL;
419 goto resetore_volt;
420 }
421 avg_value = total_value / pvtm->num;
422
423 /*
424 * As pvtm is influenced by temperature, compute difference between
425 * current temperature and reference temperature
426 */
427 pvtm->tz->ops->get_temp(pvtm->tz, &cur_temp);
428 diff_temp = (cur_temp / 1000 - pvtm->ref_temp);
429 diff_value = diff_temp *
430 (diff_temp < 0 ? pvtm->temp_prop[0] : pvtm->temp_prop[1]);
431 *target_value = avg_value + diff_value;
432
433 pvtm_value[pvtm->ch[0]][pvtm->ch[1]] = *target_value;
434
435 dev_info(dev, "temp=%d, pvtm=%d (%d + %d)\n",
436 cur_temp, *target_value, avg_value, diff_value);
437
438 resetore_volt:
439 regulator_set_voltage(reg, old_volt, INT_MAX);
440 restore_clk:
441 clk_set_rate(clk, old_freq);
442 pvtm_value_out:
443 kfree(pvtm);
444
445 return ret;
446 }
447
448 /**
449 * mul_frac() - multiply two fixed-point numbers
450 * @x: first multiplicand
451 * @y: second multiplicand
452 *
453 * Return: the result of multiplying two fixed-point numbers. The
454 * result is also a fixed-point number.
455 */
mul_frac(s64 x,s64 y)456 static inline s64 mul_frac(s64 x, s64 y)
457 {
458 return (x * y) >> FRAC_BITS;
459 }
460
temp_to_conversion_rate(int temp)461 static int temp_to_conversion_rate(int temp)
462 {
463 int high, low, mid;
464
465 low = 0;
466 high = ARRAY_SIZE(conv_table) - 1;
467 mid = (high + low) / 2;
468
469 /* No temp available, return max conversion_rate */
470 if (temp <= conv_table[low].temp)
471 return conv_table[low].conv;
472 if (temp >= conv_table[high].temp)
473 return conv_table[high].conv;
474
475 while (low <= high) {
476 if (temp <= conv_table[mid].temp && temp >
477 conv_table[mid - 1].temp) {
478 return conv_table[mid - 1].conv +
479 (conv_table[mid].conv - conv_table[mid - 1].conv) *
480 (temp - conv_table[mid - 1].temp) /
481 (conv_table[mid].temp - conv_table[mid - 1].temp);
482 } else if (temp > conv_table[mid].temp) {
483 low = mid + 1;
484 } else {
485 high = mid - 1;
486 }
487 mid = (low + high) / 2;
488 }
489
490 return 100;
491 }
492
rockchip_adjust_leakage(struct device * dev,struct device_node * np,int * leakage)493 static int rockchip_adjust_leakage(struct device *dev, struct device_node *np,
494 int *leakage)
495 {
496 struct nvmem_cell *cell;
497 u8 value = 0;
498 u32 temp;
499 int conversion;
500 int ret;
501
502 cell = of_nvmem_cell_get(np, "leakage_temp");
503 if (IS_ERR(cell))
504 goto next;
505 nvmem_cell_put(cell);
506 ret = rockchip_nvmem_cell_read_u8(np, "leakage_temp", &value);
507 if (ret) {
508 dev_err(dev, "Failed to get leakage temp\n");
509 return -EINVAL;
510 }
511 /*
512 * The ambient temperature range: 20C to 40C
513 * In order to improve the precision, we do a conversion.
514 * The temp in efuse : temp_efuse = (temp - 20) / (40 - 20) * 63
515 * The ambient temp : temp = (temp_efuse / 63) * (40 - 20) + 20
516 * Reserves a decimal point : temp = temp * 10
517 */
518 temp = value;
519 temp = mul_frac((int_to_frac(temp) / 63 * 20 + int_to_frac(20)),
520 int_to_frac(10));
521 conversion = temp_to_conversion_rate(frac_to_int(temp));
522 *leakage = *leakage * conversion / 100;
523
524 next:
525 cell = of_nvmem_cell_get(np, "leakage_volt");
526 if (IS_ERR(cell))
527 return 0;
528 nvmem_cell_put(cell);
529 ret = rockchip_nvmem_cell_read_u8(np, "leakage_volt", &value);
530 if (ret) {
531 dev_err(dev, "Failed to get leakage volt\n");
532 return -EINVAL;
533 }
534 /*
535 * if ft write leakage use 1.35v, need convert to 1v.
536 * leakage(1v) = leakage(1.35v) / 4
537 */
538 if (value)
539 *leakage = *leakage / 4;
540
541 return 0;
542 }
543
rockchip_get_leakage_version(int * version)544 static int rockchip_get_leakage_version(int *version)
545 {
546 if (*version)
547 return 0;
548
549 if (of_machine_is_compatible("rockchip,rk3368"))
550 *version = LEAKAGE_V2;
551 else if (of_machine_is_compatible("rockchip,rv1126") ||
552 of_machine_is_compatible("rockchip,rv1109"))
553 *version = LEAKAGE_V3;
554 else
555 *version = LEAKAGE_V1;
556
557 return 0;
558 }
559
rockchip_get_leakage_v1(struct device * dev,struct device_node * np,char * lkg_name,int * leakage)560 static int rockchip_get_leakage_v1(struct device *dev, struct device_node *np,
561 char *lkg_name, int *leakage)
562 {
563 struct nvmem_cell *cell;
564 int ret = 0;
565 u8 value = 0;
566
567 cell = of_nvmem_cell_get(np, "leakage");
568 if (IS_ERR(cell)) {
569 ret = rockchip_nvmem_cell_read_u8(np, lkg_name, &value);
570 } else {
571 nvmem_cell_put(cell);
572 ret = rockchip_nvmem_cell_read_u8(np, "leakage", &value);
573 }
574 if (ret)
575 dev_err(dev, "Failed to get %s\n", lkg_name);
576 else
577 *leakage = value;
578
579 return ret;
580 }
581
rockchip_get_leakage_v2(struct device * dev,struct device_node * np,char * lkg_name,int * leakage)582 static int rockchip_get_leakage_v2(struct device *dev, struct device_node *np,
583 char *lkg_name, int *leakage)
584 {
585 int lkg = 0, ret = 0;
586
587 if (rockchip_get_leakage_v1(dev, np, lkg_name, &lkg))
588 return -EINVAL;
589
590 ret = rockchip_adjust_leakage(dev, np, &lkg);
591 if (ret)
592 dev_err(dev, "Failed to adjust leakage, value=%d\n", lkg);
593 else
594 *leakage = lkg;
595
596 return ret;
597 }
598
rockchip_get_leakage_v3(struct device * dev,struct device_node * np,char * lkg_name,int * leakage)599 static int rockchip_get_leakage_v3(struct device *dev, struct device_node *np,
600 char *lkg_name, int *leakage)
601 {
602 int lkg = 0;
603
604 if (rockchip_get_leakage_v1(dev, np, lkg_name, &lkg))
605 return -EINVAL;
606
607 *leakage = (((lkg & 0xf8) >> 3) * 1000) + ((lkg & 0x7) * 125);
608
609 return 0;
610 }
611
rockchip_of_get_leakage(struct device * dev,char * lkg_name,int * leakage)612 int rockchip_of_get_leakage(struct device *dev, char *lkg_name, int *leakage)
613 {
614 struct device_node *np;
615 int ret = -EINVAL;
616
617 np = of_parse_phandle(dev->of_node, "operating-points-v2", 0);
618 if (!np) {
619 dev_warn(dev, "OPP-v2 not supported\n");
620 return -ENOENT;
621 }
622
623 rockchip_get_leakage_version(&lkg_version);
624
625 switch (lkg_version) {
626 case LEAKAGE_V1:
627 ret = rockchip_get_leakage_v1(dev, np, lkg_name, leakage);
628 break;
629 case LEAKAGE_V2:
630 ret = rockchip_get_leakage_v2(dev, np, lkg_name, leakage);
631 break;
632 case LEAKAGE_V3:
633 ret = rockchip_get_leakage_v3(dev, np, lkg_name, leakage);
634 if (!ret) {
635 /*
636 * round up to the nearest whole number for calculating
637 * static power, it does not need to be precise.
638 */
639 if (*leakage % 1000 > 500)
640 *leakage = *leakage / 1000 + 1;
641 else
642 *leakage = *leakage / 1000;
643 }
644 break;
645 default:
646 break;
647 }
648
649 of_node_put(np);
650
651 return ret;
652 }
653 EXPORT_SYMBOL(rockchip_of_get_leakage);
654
rockchip_of_get_lkg_sel(struct device * dev,struct device_node * np,char * lkg_name,int process,int * volt_sel,int * scale_sel)655 void rockchip_of_get_lkg_sel(struct device *dev, struct device_node *np,
656 char *lkg_name, int process,
657 int *volt_sel, int *scale_sel)
658 {
659 struct property *prop = NULL;
660 int leakage = -EINVAL, ret = 0;
661 char name[NAME_MAX];
662
663 rockchip_get_leakage_version(&lkg_version);
664
665 switch (lkg_version) {
666 case LEAKAGE_V1:
667 ret = rockchip_get_leakage_v1(dev, np, lkg_name, &leakage);
668 if (ret)
669 return;
670 dev_info(dev, "leakage=%d\n", leakage);
671 break;
672 case LEAKAGE_V2:
673 ret = rockchip_get_leakage_v2(dev, np, lkg_name, &leakage);
674 if (ret)
675 return;
676 dev_info(dev, "leakage=%d\n", leakage);
677 break;
678 case LEAKAGE_V3:
679 ret = rockchip_get_leakage_v3(dev, np, lkg_name, &leakage);
680 if (ret)
681 return;
682 dev_info(dev, "leakage=%d.%d\n", leakage / 1000,
683 leakage % 1000);
684 break;
685 default:
686 return;
687 }
688
689 if (!volt_sel)
690 goto next;
691 if (process >= 0) {
692 snprintf(name, sizeof(name),
693 "rockchip,p%d-leakage-voltage-sel", process);
694 prop = of_find_property(np, name, NULL);
695 }
696 if (!prop)
697 sprintf(name, "rockchip,leakage-voltage-sel");
698 ret = rockchip_get_sel(np, name, leakage, volt_sel);
699 if (!ret)
700 dev_info(dev, "leakage-volt-sel=%d\n", *volt_sel);
701
702 next:
703 if (!scale_sel)
704 return;
705 if (process >= 0) {
706 snprintf(name, sizeof(name),
707 "rockchip,p%d-leakage-scaling-sel", process);
708 prop = of_find_property(np, name, NULL);
709 }
710 if (!prop)
711 sprintf(name, "rockchip,leakage-scaling-sel");
712 ret = rockchip_get_sel(np, name, leakage, scale_sel);
713 if (!ret)
714 dev_info(dev, "leakage-scale=%d\n", *scale_sel);
715 }
716 EXPORT_SYMBOL(rockchip_of_get_lkg_sel);
717
rockchip_pvtpll_get_rate(struct rockchip_opp_info * info)718 static unsigned long rockchip_pvtpll_get_rate(struct rockchip_opp_info *info)
719 {
720 unsigned int rate0, rate1, delta;
721 int i;
722
723 #define MIN_STABLE_DELTA 3
724 regmap_read(info->grf, info->pvtpll_avg_offset, &rate0);
725 /* max delay 2ms */
726 for (i = 0; i < 20; i++) {
727 udelay(100);
728 regmap_read(info->grf, info->pvtpll_avg_offset, &rate1);
729 delta = abs(rate1 - rate0);
730 rate0 = rate1;
731 if (delta <= MIN_STABLE_DELTA)
732 break;
733 }
734
735 if (delta > MIN_STABLE_DELTA) {
736 dev_err(info->dev, "%s: bad delta: %u\n", __func__, delta);
737 return 0;
738 }
739
740 return rate0 * 1000000;
741 }
742
rockchip_pvtpll_parse_dt(struct rockchip_opp_info * info)743 static int rockchip_pvtpll_parse_dt(struct rockchip_opp_info *info)
744 {
745 struct device_node *np;
746 int ret;
747
748 np = of_parse_phandle(info->dev->of_node, "operating-points-v2", 0);
749 if (!np) {
750 dev_warn(info->dev, "OPP-v2 not supported\n");
751 return -ENOENT;
752 }
753
754 ret = of_property_read_u32(np, "rockchip,pvtpll-avg-offset", &info->pvtpll_avg_offset);
755 if (ret)
756 goto out;
757
758 ret = of_property_read_u32(np, "rockchip,pvtpll-min-rate", &info->pvtpll_min_rate);
759 if (ret)
760 goto out;
761
762 ret = of_property_read_u32(np, "rockchip,pvtpll-volt-step", &info->pvtpll_volt_step);
763 out:
764 of_node_put(np);
765
766 return ret;
767 }
768
rockchip_init_pvtpll_info(struct rockchip_opp_info * info)769 static int rockchip_init_pvtpll_info(struct rockchip_opp_info *info)
770 {
771 struct opp_table *opp_table;
772 struct dev_pm_opp *opp;
773 int i = 0, max_count, ret;
774
775 ret = rockchip_pvtpll_parse_dt(info);
776 if (ret)
777 return ret;
778
779 max_count = dev_pm_opp_get_opp_count(info->dev);
780 if (max_count <= 0)
781 return max_count ? max_count : -ENODATA;
782
783 info->opp_table = kcalloc(max_count, sizeof(*info->opp_table), GFP_KERNEL);
784 if (!info->opp_table)
785 return -ENOMEM;
786
787 opp_table = dev_pm_opp_get_opp_table(info->dev);
788 if (!opp_table) {
789 kfree(info->opp_table);
790 info->opp_table = NULL;
791 return -ENOMEM;
792 }
793
794 mutex_lock(&opp_table->lock);
795 list_for_each_entry(opp, &opp_table->opp_list, node) {
796 if (!opp->available)
797 continue;
798
799 info->opp_table[i].u_volt = opp->supplies[0].u_volt;
800 info->opp_table[i].u_volt_min = opp->supplies[0].u_volt_min;
801 info->opp_table[i].u_volt_max = opp->supplies[0].u_volt_max;
802 if (opp_table->regulator_count > 1) {
803 info->opp_table[i].u_volt_mem = opp->supplies[1].u_volt;
804 info->opp_table[i].u_volt_mem_min = opp->supplies[1].u_volt_min;
805 info->opp_table[i].u_volt_mem_max = opp->supplies[1].u_volt_max;
806 }
807 info->opp_table[i++].rate = opp->rate;
808 }
809 mutex_unlock(&opp_table->lock);
810
811 dev_pm_opp_put_opp_table(opp_table);
812
813 return 0;
814 }
815
rockchip_pvtpll_set_volt(struct device * dev,struct regulator * reg,int target_uV,int max_uV,char * reg_name)816 static int rockchip_pvtpll_set_volt(struct device *dev, struct regulator *reg,
817 int target_uV, int max_uV, char *reg_name)
818 {
819 int ret = 0;
820
821 ret = regulator_set_voltage(reg, target_uV, max_uV);
822 if (ret)
823 dev_err(dev, "%s: failed to set %s voltage (%d %d uV): %d\n",
824 __func__, reg_name, target_uV, max_uV, ret);
825
826 return ret;
827 }
828
rockchip_pvtpll_set_clk(struct device * dev,struct clk * clk,unsigned long rate)829 static int rockchip_pvtpll_set_clk(struct device *dev, struct clk *clk,
830 unsigned long rate)
831 {
832 int ret = 0;
833
834 ret = clk_set_rate(clk, rate);
835 if (ret)
836 dev_err(dev, "%s: failed to set rate %lu Hz, ret:%d\n",
837 __func__, rate, ret);
838
839 return ret;
840 }
841
rockchip_pvtpll_calibrate_opp(struct rockchip_opp_info * info)842 void rockchip_pvtpll_calibrate_opp(struct rockchip_opp_info *info)
843 {
844 struct opp_table *opp_table;
845 struct dev_pm_opp *opp;
846 struct regulator *reg = NULL, *reg_mem = NULL;
847 unsigned long old_volt = 0, old_volt_mem = 0;
848 unsigned long volt = 0, volt_mem = 0;
849 unsigned long volt_min, volt_max, volt_mem_min, volt_mem_max;
850 unsigned long rate, pvtpll_rate, old_rate, cur_rate, delta0, delta1;
851 int i = 0, max_count, step, cur_step, ret;
852
853 if (!info || !info->grf)
854 return;
855
856 dev_dbg(info->dev, "calibrating opp ...\n");
857 ret = rockchip_init_pvtpll_info(info);
858 if (ret)
859 return;
860
861 max_count = dev_pm_opp_get_opp_count(info->dev);
862 if (max_count <= 0)
863 return;
864
865 opp_table = dev_pm_opp_get_opp_table(info->dev);
866 if (!opp_table)
867 return;
868
869 if ((!opp_table->regulators) || IS_ERR(opp_table->clk))
870 goto out_put;
871
872 reg = opp_table->regulators[0];
873 old_volt = regulator_get_voltage(reg);
874 if (opp_table->regulator_count > 1) {
875 reg_mem = opp_table->regulators[1];
876 old_volt_mem = regulator_get_voltage(reg_mem);
877 if (IS_ERR_VALUE(old_volt_mem))
878 goto out_put;
879 }
880 old_rate = clk_get_rate(opp_table->clk);
881 if (IS_ERR_VALUE(old_volt) || IS_ERR_VALUE(old_rate))
882 goto out_put;
883 cur_rate = old_rate;
884
885 step = regulator_get_linear_step(reg);
886 if (!step || info->pvtpll_volt_step > step)
887 step = info->pvtpll_volt_step;
888
889 if (old_rate > info->pvtpll_min_rate * 1000) {
890 if (rockchip_pvtpll_set_clk(info->dev, opp_table->clk,
891 info->pvtpll_min_rate * 1000))
892 goto out_put;
893 }
894
895 for (i = 0; i < max_count; i++) {
896 rate = info->opp_table[i].rate;
897 if (rate < 1000 * info->pvtpll_min_rate)
898 continue;
899
900 volt = max(volt, info->opp_table[i].u_volt);
901 volt_min = info->opp_table[i].u_volt_min;
902 volt_max = info->opp_table[i].u_volt_max;
903
904 if (opp_table->regulator_count > 1) {
905 volt_mem = max(volt_mem, info->opp_table[i].u_volt_mem);
906 volt_mem_min = info->opp_table[i].u_volt_mem_min;
907 volt_mem_max = info->opp_table[i].u_volt_mem_max;
908 if (rockchip_pvtpll_set_volt(info->dev, reg_mem,
909 volt_mem, volt_mem_max, "mem"))
910 goto out;
911 }
912 if (rockchip_pvtpll_set_volt(info->dev, reg, volt, volt_max, "vdd"))
913 goto out;
914
915 if (rockchip_pvtpll_set_clk(info->dev, opp_table->clk, rate))
916 goto out;
917 cur_rate = rate;
918 pvtpll_rate = rockchip_pvtpll_get_rate(info);
919 if (!pvtpll_rate)
920 goto out;
921 cur_step = (pvtpll_rate < rate) ? step : -step;
922 delta1 = abs(pvtpll_rate - rate);
923 do {
924 delta0 = delta1;
925 volt += cur_step;
926 if ((volt < volt_min) || (volt > volt_max))
927 break;
928 if (opp_table->regulator_count > 1) {
929 if (volt > volt_mem_max)
930 break;
931 else if (volt < volt_mem_min)
932 volt_mem = volt_mem_min;
933 else
934 volt_mem = volt;
935 if (rockchip_pvtpll_set_volt(info->dev, reg_mem,
936 volt_mem, volt_mem_max,
937 "mem"))
938 break;
939 }
940 if (rockchip_pvtpll_set_volt(info->dev, reg, volt,
941 volt_max, "vdd"))
942 break;
943 pvtpll_rate = rockchip_pvtpll_get_rate(info);
944 if (!pvtpll_rate)
945 goto out;
946 delta1 = abs(pvtpll_rate - rate);
947 } while (delta1 < delta0);
948
949 volt -= cur_step;
950 info->opp_table[i].u_volt = volt;
951 if (opp_table->regulator_count > 1) {
952 if (volt < volt_mem_min)
953 volt_mem = volt_mem_min;
954 else
955 volt_mem = volt;
956 info->opp_table[i].u_volt_mem = volt_mem;
957 }
958 }
959
960 i = 0;
961 mutex_lock(&opp_table->lock);
962 list_for_each_entry(opp, &opp_table->opp_list, node) {
963 if (!opp->available)
964 continue;
965
966 opp->supplies[0].u_volt = info->opp_table[i].u_volt;
967 if (opp_table->regulator_count > 1)
968 opp->supplies[1].u_volt = info->opp_table[i].u_volt_mem;
969 i++;
970 }
971 mutex_unlock(&opp_table->lock);
972 dev_info(info->dev, "opp calibration done\n");
973 out:
974 if (cur_rate > old_rate)
975 rockchip_pvtpll_set_clk(info->dev, opp_table->clk, old_rate);
976 if (opp_table->regulator_count > 1)
977 rockchip_pvtpll_set_volt(info->dev, reg_mem, old_volt_mem,
978 INT_MAX, "mem");
979 rockchip_pvtpll_set_volt(info->dev, reg, old_volt, INT_MAX, "vdd");
980 if (cur_rate < old_rate)
981 rockchip_pvtpll_set_clk(info->dev, opp_table->clk, old_rate);
982 out_put:
983 dev_pm_opp_put_opp_table(opp_table);
984 }
985 EXPORT_SYMBOL(rockchip_pvtpll_calibrate_opp);
986
rockchip_pvtpll_add_length(struct rockchip_opp_info * info)987 void rockchip_pvtpll_add_length(struct rockchip_opp_info *info)
988 {
989 struct device_node *np;
990 struct opp_table *opp_table;
991 struct dev_pm_opp *opp;
992 unsigned long old_rate;
993 unsigned int min_rate = 0, max_rate = 0, margin = 0;
994 u32 opp_flag = 0;
995 int ret;
996
997 if (!info)
998 return;
999
1000 np = of_parse_phandle(info->dev->of_node, "operating-points-v2", 0);
1001 if (!np) {
1002 dev_warn(info->dev, "OPP-v2 not supported\n");
1003 return;
1004 }
1005
1006 if (of_property_read_u32(np, "rockchip,pvtpll-len-min-rate", &min_rate))
1007 return;
1008 if (of_property_read_u32(np, "rockchip,pvtpll-len-max-rate", &max_rate))
1009 return;
1010 if (of_property_read_u32(np, "rockchip,pvtpll-len-margin", &margin))
1011 return;
1012
1013 opp_table = dev_pm_opp_get_opp_table(info->dev);
1014 if (!opp_table)
1015 return;
1016 old_rate = clk_get_rate(opp_table->clk);
1017 opp_flag = OPP_ADD_LENGTH | ((margin & OPP_LENGTH_MASK) << OPP_LENGTH_SHIFT);
1018
1019 mutex_lock(&opp_table->lock);
1020 list_for_each_entry(opp, &opp_table->opp_list, node) {
1021 if (opp->rate < min_rate * 1000 || opp->rate > max_rate * 1000)
1022 continue;
1023 ret = clk_set_rate(opp_table->clk, opp->rate | opp_flag);
1024 if (ret) {
1025 dev_err(info->dev,
1026 "failed to change %lu len margin %d\n",
1027 opp->rate, margin);
1028 break;
1029 }
1030 }
1031 mutex_unlock(&opp_table->lock);
1032
1033 clk_set_rate(opp_table->clk, old_rate);
1034
1035 dev_pm_opp_put_opp_table(opp_table);
1036 }
1037 EXPORT_SYMBOL(rockchip_pvtpll_add_length);
1038
rockchip_get_pvtm_pvtpll(struct device * dev,struct device_node * np,char * reg_name)1039 static int rockchip_get_pvtm_pvtpll(struct device *dev, struct device_node *np,
1040 char *reg_name)
1041 {
1042 struct regulator *reg;
1043 struct clk *clk;
1044 struct pvtm_config *pvtm;
1045 unsigned long old_freq;
1046 unsigned int old_volt;
1047 int cur_temp, diff_temp, prop_temp, diff_value;
1048 int pvtm_value = 0;
1049 int ret = 0;
1050
1051 if (!rockchip_nvmem_cell_read_u16(np, "pvtm", (u16 *)&pvtm_value) && pvtm_value) {
1052 dev_info(dev, "pvtm = %d, get from otp\n", pvtm_value);
1053 return pvtm_value;
1054 }
1055
1056 pvtm = kzalloc(sizeof(*pvtm), GFP_KERNEL);
1057 if (!pvtm)
1058 return -ENOMEM;
1059
1060 ret = rockchip_parse_pvtm_config(np, pvtm);
1061 if (ret)
1062 goto out;
1063
1064 clk = clk_get(dev, NULL);
1065 if (IS_ERR_OR_NULL(clk)) {
1066 dev_warn(dev, "Failed to get clk\n");
1067 goto out;
1068 }
1069
1070 reg = regulator_get_optional(dev, reg_name);
1071 if (IS_ERR_OR_NULL(reg)) {
1072 dev_warn(dev, "Failed to get reg\n");
1073 clk_put(clk);
1074 goto out;
1075 }
1076 old_freq = clk_get_rate(clk);
1077 old_volt = regulator_get_voltage(reg);
1078
1079 ret = clk_set_rate(clk, pvtm->freq * 1000);
1080 if (ret) {
1081 dev_err(dev, "Failed to set pvtm freq\n");
1082 goto put_reg;
1083 }
1084 ret = regulator_set_voltage(reg, pvtm->volt, INT_MAX);
1085 if (ret) {
1086 dev_err(dev, "Failed to set pvtm_volt\n");
1087 goto restore_clk;
1088 }
1089 usleep_range(pvtm->sample_time, pvtm->sample_time + 100);
1090
1091 ret = regmap_read(pvtm->grf, pvtm->offset, &pvtm_value);
1092 if (ret < 0) {
1093 dev_err(dev, "failed to get pvtm from 0x%x\n", pvtm->offset);
1094 goto resetore_volt;
1095 }
1096 pvtm->tz->ops->get_temp(pvtm->tz, &cur_temp);
1097 diff_temp = (cur_temp / 1000 - pvtm->ref_temp);
1098 if (diff_temp < 0)
1099 prop_temp = pvtm->temp_prop[0];
1100 else
1101 prop_temp = pvtm->temp_prop[1];
1102 diff_value = diff_temp * prop_temp / 1000;
1103 pvtm_value += diff_value;
1104
1105 dev_info(dev, "pvtm=%d\n", pvtm_value);
1106
1107 resetore_volt:
1108 regulator_set_voltage(reg, old_volt, INT_MAX);
1109 restore_clk:
1110 clk_set_rate(clk, old_freq);
1111 put_reg:
1112 regulator_put(reg);
1113 clk_put(clk);
1114 out:
1115 kfree(pvtm);
1116
1117 return pvtm_value;
1118 }
1119
rockchip_get_pvtm(struct device * dev,struct device_node * np,char * reg_name)1120 static int rockchip_get_pvtm(struct device *dev, struct device_node *np,
1121 char *reg_name)
1122 {
1123 struct regulator *reg;
1124 struct clk *clk;
1125 unsigned int ch[2];
1126 int pvtm = 0;
1127 u16 tmp = 0;
1128
1129 if (!rockchip_nvmem_cell_read_u16(np, "pvtm", &tmp) && tmp) {
1130 pvtm = 10 * tmp;
1131 dev_info(dev, "pvtm = %d, from nvmem\n", pvtm);
1132 return pvtm;
1133 }
1134
1135 if (of_property_read_u32_array(np, "rockchip,pvtm-ch", ch, 2))
1136 return -EINVAL;
1137
1138 if (ch[0] >= PVTM_CH_MAX || ch[1] >= PVTM_SUB_CH_MAX)
1139 return -EINVAL;
1140
1141 if (pvtm_value[ch[0]][ch[1]]) {
1142 dev_info(dev, "pvtm = %d, form pvtm_value\n", pvtm_value[ch[0]][ch[1]]);
1143 return pvtm_value[ch[0]][ch[1]];
1144 }
1145
1146 clk = clk_get(dev, NULL);
1147 if (IS_ERR_OR_NULL(clk)) {
1148 dev_warn(dev, "Failed to get clk\n");
1149 return PTR_ERR_OR_ZERO(clk);
1150 }
1151
1152 reg = regulator_get_optional(dev, reg_name);
1153 if (IS_ERR_OR_NULL(reg)) {
1154 dev_warn(dev, "Failed to get reg\n");
1155 clk_put(clk);
1156 return PTR_ERR_OR_ZERO(reg);
1157 }
1158
1159 rockchip_get_pvtm_specific_value(dev, np, clk, reg, &pvtm);
1160
1161 regulator_put(reg);
1162 clk_put(clk);
1163
1164 return pvtm;
1165 }
1166
rockchip_of_get_pvtm_sel(struct device * dev,struct device_node * np,char * reg_name,int bin,int process,int * volt_sel,int * scale_sel)1167 void rockchip_of_get_pvtm_sel(struct device *dev, struct device_node *np,
1168 char *reg_name, int bin, int process,
1169 int *volt_sel, int *scale_sel)
1170 {
1171 struct property *prop = NULL;
1172 char name[NAME_MAX];
1173 int pvtm, ret;
1174 u32 hw = 0;
1175
1176 if (of_property_read_bool(np, "rockchip,pvtm-pvtpll"))
1177 pvtm = rockchip_get_pvtm_pvtpll(dev, np, reg_name);
1178 else
1179 pvtm = rockchip_get_pvtm(dev, np, reg_name);
1180 if (pvtm <= 0)
1181 return;
1182
1183 if (!volt_sel)
1184 goto next;
1185 if (process >= 0) {
1186 snprintf(name, sizeof(name),
1187 "rockchip,p%d-pvtm-voltage-sel", process);
1188 prop = of_find_property(np, name, NULL);
1189 } else if (bin >= 0) {
1190 of_property_read_u32(np, "rockchip,pvtm-hw", &hw);
1191 if (hw && (hw & BIT(bin))) {
1192 sprintf(name, "rockchip,pvtm-voltage-sel-hw");
1193 prop = of_find_property(np, name, NULL);
1194 }
1195 }
1196 if (!prop)
1197 sprintf(name, "rockchip,pvtm-voltage-sel");
1198 ret = rockchip_get_sel(np, name, pvtm, volt_sel);
1199 if (!ret && volt_sel)
1200 dev_info(dev, "pvtm-volt-sel=%d\n", *volt_sel);
1201
1202 next:
1203 if (!scale_sel)
1204 return;
1205 prop = NULL;
1206 if (process >= 0) {
1207 snprintf(name, sizeof(name),
1208 "rockchip,p%d-pvtm-scaling-sel", process);
1209 prop = of_find_property(np, name, NULL);
1210 }
1211 if (!prop)
1212 sprintf(name, "rockchip,pvtm-scaling-sel");
1213 ret = rockchip_get_sel(np, name, pvtm, scale_sel);
1214 if (!ret)
1215 dev_info(dev, "pvtm-scale=%d\n", *scale_sel);
1216 }
1217 EXPORT_SYMBOL(rockchip_of_get_pvtm_sel);
1218
rockchip_of_get_bin_sel(struct device * dev,struct device_node * np,int bin,int * scale_sel)1219 void rockchip_of_get_bin_sel(struct device *dev, struct device_node *np,
1220 int bin, int *scale_sel)
1221 {
1222 int ret = 0;
1223
1224 if (!scale_sel || bin < 0)
1225 return;
1226
1227 ret = rockchip_get_bin_sel(np, "rockchip,bin-scaling-sel",
1228 bin, scale_sel);
1229 if (!ret)
1230 dev_info(dev, "bin-scale=%d\n", *scale_sel);
1231 }
1232 EXPORT_SYMBOL(rockchip_of_get_bin_sel);
1233
rockchip_of_get_bin_volt_sel(struct device * dev,struct device_node * np,int bin,int * bin_volt_sel)1234 void rockchip_of_get_bin_volt_sel(struct device *dev, struct device_node *np,
1235 int bin, int *bin_volt_sel)
1236 {
1237 int ret = 0;
1238
1239 if (!bin_volt_sel || bin < 0)
1240 return;
1241
1242 ret = rockchip_get_bin_sel(np, "rockchip,bin-voltage-sel",
1243 bin, bin_volt_sel);
1244 if (!ret)
1245 dev_info(dev, "bin-volt-sel=%d\n", *bin_volt_sel);
1246 }
1247 EXPORT_SYMBOL(rockchip_of_get_bin_volt_sel);
1248
rockchip_get_opp_data(const struct of_device_id * matches,struct rockchip_opp_info * info)1249 void rockchip_get_opp_data(const struct of_device_id *matches,
1250 struct rockchip_opp_info *info)
1251 {
1252 const struct of_device_id *match;
1253 struct device_node *node;
1254
1255 node = of_find_node_by_path("/");
1256 match = of_match_node(matches, node);
1257 if (match && match->data)
1258 info->data = match->data;
1259 of_node_put(node);
1260 }
1261 EXPORT_SYMBOL(rockchip_get_opp_data);
1262
rockchip_get_volt_rm_table(struct device * dev,struct device_node * np,char * porp_name,struct volt_rm_table ** table)1263 int rockchip_get_volt_rm_table(struct device *dev, struct device_node *np,
1264 char *porp_name, struct volt_rm_table **table)
1265 {
1266 struct volt_rm_table *rm_table;
1267 const struct property *prop;
1268 int count, i;
1269
1270 prop = of_find_property(np, porp_name, NULL);
1271 if (!prop)
1272 return -EINVAL;
1273
1274 if (!prop->value)
1275 return -ENODATA;
1276
1277 count = of_property_count_u32_elems(np, porp_name);
1278 if (count < 0)
1279 return -EINVAL;
1280
1281 if (count % 2)
1282 return -EINVAL;
1283
1284 rm_table = devm_kzalloc(dev, sizeof(*rm_table) * (count / 2 + 1),
1285 GFP_KERNEL);
1286 if (!rm_table)
1287 return -ENOMEM;
1288
1289 for (i = 0; i < count / 2; i++) {
1290 of_property_read_u32_index(np, porp_name, 2 * i,
1291 &rm_table[i].volt);
1292 of_property_read_u32_index(np, porp_name, 2 * i + 1,
1293 &rm_table[i].rm);
1294 }
1295
1296 rm_table[i].volt = 0;
1297 rm_table[i].rm = VOLT_RM_TABLE_END;
1298
1299 *table = rm_table;
1300
1301 return 0;
1302 }
1303 EXPORT_SYMBOL(rockchip_get_volt_rm_table);
1304
rockchip_get_soc_info(struct device * dev,struct device_node * np,int * bin,int * process)1305 int rockchip_get_soc_info(struct device *dev, struct device_node *np, int *bin,
1306 int *process)
1307 {
1308 u8 value = 0;
1309 int ret = 0;
1310
1311 if (*bin >= 0 || *process >= 0)
1312 return 0;
1313
1314 if (of_property_match_string(np, "nvmem-cell-names",
1315 "specification_serial_number") >= 0) {
1316 ret = rockchip_nvmem_cell_read_u8(np,
1317 "specification_serial_number",
1318 &value);
1319 if (ret) {
1320 dev_err(dev,
1321 "Failed to get specification_serial_number\n");
1322 return ret;
1323 }
1324 /* M */
1325 if (value == 0xd)
1326 *bin = 1;
1327 /* J */
1328 else if (value == 0xa)
1329 *bin = 2;
1330 }
1331
1332 if (*bin < 0)
1333 *bin = 0;
1334 dev_info(dev, "bin=%d\n", *bin);
1335
1336 return 0;
1337 }
1338 EXPORT_SYMBOL(rockchip_get_soc_info);
1339
rockchip_get_scale_volt_sel(struct device * dev,char * lkg_name,char * reg_name,int bin,int process,int * scale,int * volt_sel)1340 void rockchip_get_scale_volt_sel(struct device *dev, char *lkg_name,
1341 char *reg_name, int bin, int process,
1342 int *scale, int *volt_sel)
1343 {
1344 struct device_node *np;
1345 int lkg_scale = 0, pvtm_scale = 0, bin_scale = 0;
1346 int lkg_volt_sel = -EINVAL, pvtm_volt_sel = -EINVAL;
1347 int bin_volt_sel = -EINVAL;
1348
1349 np = of_parse_phandle(dev->of_node, "operating-points-v2", 0);
1350 if (!np) {
1351 dev_warn(dev, "OPP-v2 not supported\n");
1352 return;
1353 }
1354
1355 rockchip_of_get_lkg_sel(dev, np, lkg_name, process,
1356 &lkg_volt_sel, &lkg_scale);
1357 rockchip_of_get_pvtm_sel(dev, np, reg_name, bin, process,
1358 &pvtm_volt_sel, &pvtm_scale);
1359 rockchip_of_get_bin_sel(dev, np, bin, &bin_scale);
1360 rockchip_of_get_bin_volt_sel(dev, np, bin, &bin_volt_sel);
1361 if (scale)
1362 *scale = max3(lkg_scale, pvtm_scale, bin_scale);
1363 if (volt_sel) {
1364 if (bin_volt_sel >= 0)
1365 *volt_sel = bin_volt_sel;
1366 else
1367 *volt_sel = max(lkg_volt_sel, pvtm_volt_sel);
1368 }
1369
1370 of_node_put(np);
1371 }
1372 EXPORT_SYMBOL(rockchip_get_scale_volt_sel);
1373
rockchip_set_opp_prop_name(struct device * dev,int process,int volt_sel)1374 struct opp_table *rockchip_set_opp_prop_name(struct device *dev, int process,
1375 int volt_sel)
1376 {
1377 char name[MAX_PROP_NAME_LEN];
1378
1379 if (process >= 0) {
1380 if (volt_sel >= 0)
1381 snprintf(name, MAX_PROP_NAME_LEN, "P%d-L%d",
1382 process, volt_sel);
1383 else
1384 snprintf(name, MAX_PROP_NAME_LEN, "P%d", process);
1385 } else if (volt_sel >= 0) {
1386 snprintf(name, MAX_PROP_NAME_LEN, "L%d", volt_sel);
1387 } else {
1388 return NULL;
1389 }
1390
1391 return dev_pm_opp_set_prop_name(dev, name);
1392 }
1393 EXPORT_SYMBOL(rockchip_set_opp_prop_name);
1394
rockchip_set_opp_supported_hw(struct device * dev,struct device_node * np,int bin,int volt_sel)1395 struct opp_table *rockchip_set_opp_supported_hw(struct device *dev,
1396 struct device_node *np,
1397 int bin, int volt_sel)
1398 {
1399 struct opp_table *opp_table;
1400 u32 supported_hw[2];
1401 u32 version = 0, speed = 0;
1402
1403 if (!of_property_read_bool(np, "rockchip,supported-hw"))
1404 return NULL;
1405
1406 opp_table = dev_pm_opp_get_opp_table(dev);
1407 if (!opp_table)
1408 return NULL;
1409 if (opp_table->supported_hw) {
1410 dev_pm_opp_put_opp_table(opp_table);
1411 return NULL;
1412 }
1413 dev_pm_opp_put_opp_table(opp_table);
1414
1415 if (bin >= 0)
1416 version = bin;
1417 if (volt_sel >= 0)
1418 speed = volt_sel;
1419
1420 /* SoC Version */
1421 supported_hw[0] = BIT(version);
1422 /* Speed Grade */
1423 supported_hw[1] = BIT(speed);
1424
1425 dev_info(dev, "soc version=%d, speed=%d\n", version, speed);
1426
1427 return dev_pm_opp_set_supported_hw(dev, supported_hw, 2);
1428 }
1429 EXPORT_SYMBOL(rockchip_set_opp_supported_hw);
1430
rockchip_adjust_opp_by_irdrop(struct device * dev,struct device_node * np,unsigned long * safe_rate,unsigned long * max_rate)1431 static int rockchip_adjust_opp_by_irdrop(struct device *dev,
1432 struct device_node *np,
1433 unsigned long *safe_rate,
1434 unsigned long *max_rate)
1435 {
1436 struct sel_table *irdrop_table = NULL;
1437 struct opp_table *opp_table;
1438 struct dev_pm_opp *opp;
1439 unsigned long tmp_safe_rate = 0;
1440 int evb_irdrop = 0, board_irdrop, delta_irdrop;
1441 int opp_rate, i, ret = 0;
1442 u32 max_volt = UINT_MAX;
1443 bool reach_max_volt = false;
1444
1445 of_property_read_u32_index(np, "rockchip,max-volt", 0, &max_volt);
1446 of_property_read_u32_index(np, "rockchip,evb-irdrop", 0, &evb_irdrop);
1447 rockchip_get_sel_table(np, "rockchip,board-irdrop", &irdrop_table);
1448
1449 opp_table = dev_pm_opp_get_opp_table(dev);
1450 if (!opp_table) {
1451 ret = -ENOMEM;
1452 goto out;
1453 }
1454
1455 mutex_lock(&opp_table->lock);
1456 list_for_each_entry(opp, &opp_table->opp_list, node) {
1457 if (!opp->available)
1458 continue;
1459 if (!irdrop_table) {
1460 delta_irdrop = 0;
1461 } else {
1462 opp_rate = opp->rate / 1000000;
1463 board_irdrop = -EINVAL;
1464 for (i = 0; irdrop_table[i].sel != SEL_TABLE_END; i++) {
1465 if (opp_rate >= irdrop_table[i].min)
1466 board_irdrop = irdrop_table[i].sel;
1467 }
1468 if (board_irdrop == -EINVAL)
1469 delta_irdrop = 0;
1470 else
1471 delta_irdrop = board_irdrop - evb_irdrop;
1472 }
1473 if ((opp->supplies[0].u_volt + delta_irdrop) <= max_volt) {
1474 opp->supplies[0].u_volt += delta_irdrop;
1475 opp->supplies[0].u_volt_min += delta_irdrop;
1476 if (opp->supplies[0].u_volt_max + delta_irdrop <=
1477 max_volt)
1478 opp->supplies[0].u_volt_max += delta_irdrop;
1479 else
1480 opp->supplies[0].u_volt_max = max_volt;
1481 if (!reach_max_volt)
1482 tmp_safe_rate = opp->rate;
1483 if (opp->supplies[0].u_volt == max_volt)
1484 reach_max_volt = true;
1485 } else {
1486 opp->supplies[0].u_volt = max_volt;
1487 opp->supplies[0].u_volt_min = max_volt;
1488 opp->supplies[0].u_volt_max = max_volt;
1489 }
1490 if (max_rate)
1491 *max_rate = opp->rate;
1492 if (safe_rate && tmp_safe_rate != opp->rate)
1493 *safe_rate = tmp_safe_rate;
1494 }
1495 mutex_unlock(&opp_table->lock);
1496
1497 dev_pm_opp_put_opp_table(opp_table);
1498 out:
1499 kfree(irdrop_table);
1500
1501 return ret;
1502 }
1503
rockchip_adjust_opp_by_mbist_vmin(struct device * dev,struct device_node * np)1504 static void rockchip_adjust_opp_by_mbist_vmin(struct device *dev,
1505 struct device_node *np)
1506 {
1507 struct opp_table *opp_table;
1508 struct dev_pm_opp *opp;
1509 u32 vmin = 0;
1510 u8 index = 0;
1511
1512 if (rockchip_nvmem_cell_read_u8(np, "mbist-vmin", &index))
1513 return;
1514
1515 if (!index)
1516 return;
1517
1518 if (of_property_read_u32_index(np, "mbist-vmin", index-1, &vmin))
1519 return;
1520
1521 opp_table = dev_pm_opp_get_opp_table(dev);
1522 if (!opp_table)
1523 return;
1524
1525 mutex_lock(&opp_table->lock);
1526 list_for_each_entry(opp, &opp_table->opp_list, node) {
1527 if (!opp->available)
1528 continue;
1529 if (opp->supplies->u_volt < vmin) {
1530 opp->supplies->u_volt = vmin;
1531 opp->supplies->u_volt_min = vmin;
1532 }
1533 }
1534 mutex_unlock(&opp_table->lock);
1535 }
1536
rockchip_adjust_opp_by_otp(struct device * dev,struct device_node * np)1537 static void rockchip_adjust_opp_by_otp(struct device *dev,
1538 struct device_node *np)
1539 {
1540 struct dev_pm_opp *opp;
1541 struct opp_table *opp_table;
1542 struct otp_opp_info opp_info = {};
1543 int ret;
1544
1545 ret = rockchip_nvmem_cell_read_common(np, "opp-info", &opp_info,
1546 sizeof(opp_info));
1547 if (ret || !opp_info.volt)
1548 return;
1549
1550 dev_info(dev, "adjust opp-table by otp: min=%uM, max=%uM, volt=%umV\n",
1551 opp_info.min_freq, opp_info.max_freq, opp_info.volt);
1552
1553 opp_table = dev_pm_opp_get_opp_table(dev);
1554 if (!opp_table)
1555 return;
1556
1557 mutex_lock(&opp_table->lock);
1558 list_for_each_entry(opp, &opp_table->opp_list, node) {
1559 if (!opp->available)
1560 continue;
1561 if (opp->rate < opp_info.min_freq * 1000000)
1562 continue;
1563 if (opp->rate > opp_info.max_freq * 1000000)
1564 continue;
1565
1566 opp->supplies[0].u_volt += opp_info.volt * 1000;
1567 if (opp->supplies[0].u_volt > opp->supplies[0].u_volt_max)
1568 opp->supplies[0].u_volt = opp->supplies[0].u_volt_max;
1569 if (opp_table->regulator_count > 1) {
1570 opp->supplies[1].u_volt += opp_info.volt * 1000;
1571 if (opp->supplies[1].u_volt > opp->supplies[1].u_volt_max)
1572 opp->supplies[1].u_volt = opp->supplies[1].u_volt_max;
1573 }
1574 }
1575 mutex_unlock(&opp_table->lock);
1576
1577 dev_pm_opp_put_opp_table(opp_table);
1578 }
1579
rockchip_adjust_opp_table(struct device * dev,unsigned long scale_rate)1580 static int rockchip_adjust_opp_table(struct device *dev,
1581 unsigned long scale_rate)
1582 {
1583 struct dev_pm_opp *opp;
1584 unsigned long rate;
1585 int i, count, ret = 0;
1586
1587 count = dev_pm_opp_get_opp_count(dev);
1588 if (count <= 0) {
1589 ret = count ? count : -ENODATA;
1590 goto out;
1591 }
1592
1593 for (i = 0, rate = 0; i < count; i++, rate++) {
1594 /* find next rate */
1595 opp = dev_pm_opp_find_freq_ceil(dev, &rate);
1596 if (IS_ERR(opp)) {
1597 ret = PTR_ERR(opp);
1598 goto out;
1599 }
1600 if (opp->rate > scale_rate)
1601 dev_pm_opp_disable(dev, opp->rate);
1602 dev_pm_opp_put(opp);
1603 }
1604 out:
1605 return ret;
1606 }
1607
rockchip_adjust_power_scale(struct device * dev,int scale)1608 int rockchip_adjust_power_scale(struct device *dev, int scale)
1609 {
1610 struct device_node *np;
1611 struct clk *clk;
1612 unsigned long safe_rate = 0, max_rate = 0;
1613 int irdrop_scale = 0, opp_scale = 0;
1614 u32 target_scale, avs = 0, avs_scale = 0;
1615 long scale_rate = 0;
1616 int ret = 0;
1617
1618 np = of_parse_phandle(dev->of_node, "operating-points-v2", 0);
1619 if (!np) {
1620 dev_warn(dev, "OPP-v2 not supported\n");
1621 return -ENOENT;
1622 }
1623 of_property_read_u32(np, "rockchip,avs-enable", &avs);
1624 of_property_read_u32(np, "rockchip,avs", &avs);
1625 of_property_read_u32(np, "rockchip,avs-scale", &avs_scale);
1626 rockchip_adjust_opp_by_otp(dev, np);
1627 rockchip_adjust_opp_by_mbist_vmin(dev, np);
1628 rockchip_adjust_opp_by_irdrop(dev, np, &safe_rate, &max_rate);
1629
1630 dev_info(dev, "avs=%d\n", avs);
1631 clk = of_clk_get_by_name(np, NULL);
1632 if (IS_ERR(clk)) {
1633 if (!safe_rate)
1634 goto out_np;
1635 dev_dbg(dev, "Failed to get clk, safe_rate=%lu\n", safe_rate);
1636 ret = rockchip_adjust_opp_table(dev, safe_rate);
1637 if (ret)
1638 dev_err(dev, "Failed to adjust opp table\n");
1639 goto out_np;
1640 }
1641
1642 if (safe_rate)
1643 irdrop_scale = rockchip_pll_clk_rate_to_scale(clk, safe_rate);
1644 if (max_rate)
1645 opp_scale = rockchip_pll_clk_rate_to_scale(clk, max_rate);
1646 target_scale = max(irdrop_scale, scale);
1647 if (target_scale <= 0)
1648 goto out_clk;
1649 dev_dbg(dev, "target_scale=%d, irdrop_scale=%d, scale=%d\n",
1650 target_scale, irdrop_scale, scale);
1651
1652 if (avs == AVS_SCALING_RATE) {
1653 ret = rockchip_pll_clk_adaptive_scaling(clk, target_scale);
1654 if (ret)
1655 dev_err(dev, "Failed to adaptive scaling\n");
1656 if (opp_scale >= avs_scale)
1657 goto out_clk;
1658 dev_info(dev, "avs-scale=%d, opp-scale=%d\n", avs_scale,
1659 opp_scale);
1660 scale_rate = rockchip_pll_clk_scale_to_rate(clk, avs_scale);
1661 if (scale_rate <= 0) {
1662 dev_err(dev, "Failed to get avs scale rate, %d\n",
1663 avs_scale);
1664 goto out_clk;
1665 }
1666 dev_dbg(dev, "scale_rate=%lu\n", scale_rate);
1667 ret = rockchip_adjust_opp_table(dev, scale_rate);
1668 if (ret)
1669 dev_err(dev, "Failed to adjust opp table\n");
1670 } else if (avs == AVS_DELETE_OPP) {
1671 if (opp_scale >= target_scale)
1672 goto out_clk;
1673 dev_info(dev, "target_scale=%d, opp-scale=%d\n", target_scale,
1674 opp_scale);
1675 scale_rate = rockchip_pll_clk_scale_to_rate(clk, target_scale);
1676 if (scale_rate <= 0) {
1677 dev_err(dev, "Failed to get scale rate, %d\n",
1678 target_scale);
1679 goto out_clk;
1680 }
1681 dev_dbg(dev, "scale_rate=%lu\n", scale_rate);
1682 ret = rockchip_adjust_opp_table(dev, scale_rate);
1683 if (ret)
1684 dev_err(dev, "Failed to adjust opp table\n");
1685 }
1686
1687 out_clk:
1688 clk_put(clk);
1689 out_np:
1690 of_node_put(np);
1691
1692 return ret;
1693 }
1694 EXPORT_SYMBOL(rockchip_adjust_power_scale);
1695
rockchip_get_read_margin(struct device * dev,struct rockchip_opp_info * opp_info,unsigned long volt,u32 * target_rm)1696 int rockchip_get_read_margin(struct device *dev,
1697 struct rockchip_opp_info *opp_info,
1698 unsigned long volt, u32 *target_rm)
1699 {
1700 int i;
1701
1702 if (!opp_info || !opp_info->volt_rm_tbl)
1703 return 0;
1704
1705 for (i = 0; opp_info->volt_rm_tbl[i].rm != VOLT_RM_TABLE_END; i++) {
1706 if (volt >= opp_info->volt_rm_tbl[i].volt) {
1707 opp_info->target_rm = opp_info->volt_rm_tbl[i].rm;
1708 break;
1709 }
1710 }
1711 *target_rm = opp_info->target_rm;
1712
1713 return 0;
1714 }
1715 EXPORT_SYMBOL(rockchip_get_read_margin);
1716
rockchip_set_read_margin(struct device * dev,struct rockchip_opp_info * opp_info,u32 rm,bool is_set_rm)1717 int rockchip_set_read_margin(struct device *dev,
1718 struct rockchip_opp_info *opp_info, u32 rm,
1719 bool is_set_rm)
1720 {
1721 if (!is_set_rm || !opp_info)
1722 return 0;
1723 if (!opp_info || !opp_info->volt_rm_tbl)
1724 return 0;
1725 if (!opp_info->data || !opp_info->data->set_read_margin)
1726 return 0;
1727 if (rm == opp_info->current_rm)
1728 return 0;
1729
1730 return opp_info->data->set_read_margin(dev, opp_info, rm);
1731 }
1732 EXPORT_SYMBOL(rockchip_set_read_margin);
1733
rockchip_init_read_margin(struct device * dev,struct rockchip_opp_info * opp_info,char * reg_name)1734 int rockchip_init_read_margin(struct device *dev,
1735 struct rockchip_opp_info *opp_info,
1736 char *reg_name)
1737 {
1738 struct clk *clk;
1739 struct regulator *reg;
1740 unsigned long cur_rate;
1741 int cur_volt, ret = 0;
1742 u32 target_rm = UINT_MAX;
1743
1744 reg = regulator_get_optional(dev, reg_name);
1745 if (IS_ERR(reg)) {
1746 ret = PTR_ERR(reg);
1747 if (ret != -EPROBE_DEFER)
1748 dev_err(dev, "%s: no regulator (%s) found: %d\n",
1749 __func__, reg_name, ret);
1750 return ret;
1751 }
1752 cur_volt = regulator_get_voltage(reg);
1753 if (cur_volt < 0) {
1754 ret = cur_volt;
1755 if (ret != -EPROBE_DEFER)
1756 dev_err(dev, "%s: failed to get (%s) volt: %d\n",
1757 __func__, reg_name, ret);
1758 goto out;
1759 }
1760
1761 clk = clk_get(dev, NULL);
1762 if (IS_ERR(clk)) {
1763 ret = PTR_ERR(clk);
1764 dev_err(dev, "%s: failed to get clk: %d\n", __func__, ret);
1765 goto out;
1766 }
1767 cur_rate = clk_get_rate(clk);
1768
1769 rockchip_get_read_margin(dev, opp_info, cur_volt, &target_rm);
1770 dev_dbg(dev, "cur_rate=%lu, threshold=%lu, cur_volt=%d, target_rm=%d\n",
1771 cur_rate, opp_info->intermediate_threshold_freq,
1772 cur_volt, target_rm);
1773 if (opp_info->intermediate_threshold_freq &&
1774 cur_rate > opp_info->intermediate_threshold_freq) {
1775 clk_set_rate(clk, opp_info->intermediate_threshold_freq);
1776 rockchip_set_read_margin(dev, opp_info, target_rm, true);
1777 clk_set_rate(clk, cur_rate);
1778 } else {
1779 rockchip_set_read_margin(dev, opp_info, target_rm, true);
1780 }
1781
1782 clk_put(clk);
1783 out:
1784 regulator_put(reg);
1785
1786 return ret;
1787 }
1788 EXPORT_SYMBOL(rockchip_init_read_margin);
1789
rockchip_set_intermediate_rate(struct device * dev,struct rockchip_opp_info * opp_info,struct clk * clk,unsigned long old_freq,unsigned long new_freq,bool is_scaling_up,bool is_set_clk)1790 int rockchip_set_intermediate_rate(struct device *dev,
1791 struct rockchip_opp_info *opp_info,
1792 struct clk *clk, unsigned long old_freq,
1793 unsigned long new_freq, bool is_scaling_up,
1794 bool is_set_clk)
1795 {
1796 if (!is_set_clk)
1797 return 0;
1798 if (!opp_info || !opp_info->volt_rm_tbl)
1799 return 0;
1800 if (!opp_info->data || !opp_info->data->set_read_margin)
1801 return 0;
1802 if (opp_info->target_rm == opp_info->current_rm)
1803 return 0;
1804 /*
1805 * There is no need to set intermediate rate if the new voltage
1806 * and the current voltage are high voltage.
1807 */
1808 if ((opp_info->target_rm < opp_info->low_rm) &&
1809 (opp_info->current_rm < opp_info->low_rm))
1810 return 0;
1811
1812 if (is_scaling_up) {
1813 /*
1814 * If scaling up and the current frequency is less than
1815 * or equal to intermediate threshold frequency, there is
1816 * no need to set intermediate rate.
1817 */
1818 if (opp_info->intermediate_threshold_freq &&
1819 old_freq <= opp_info->intermediate_threshold_freq)
1820 return 0;
1821 return clk_set_rate(clk, new_freq | OPP_SCALING_UP_INTER);
1822 }
1823 /*
1824 * If scaling down and the new frequency is less than or equal to
1825 * intermediate threshold frequency , there is no need to set
1826 * intermediate rate and set the new frequency directly.
1827 */
1828 if (opp_info->intermediate_threshold_freq &&
1829 new_freq <= opp_info->intermediate_threshold_freq)
1830 return clk_set_rate(clk, new_freq);
1831
1832 return clk_set_rate(clk, new_freq | OPP_SCALING_DOWN_INTER);
1833 }
1834 EXPORT_SYMBOL(rockchip_set_intermediate_rate);
1835
rockchip_init_opp_table(struct device * dev,struct rockchip_opp_info * info,char * lkg_name,char * reg_name)1836 int rockchip_init_opp_table(struct device *dev, struct rockchip_opp_info *info,
1837 char *lkg_name, char *reg_name)
1838 {
1839 struct device_node *np;
1840 int bin = -EINVAL, process = -EINVAL;
1841 int scale = 0, volt_sel = -EINVAL;
1842 int ret = 0, num_clks = 0, i;
1843 u32 freq;
1844
1845 /* Get OPP descriptor node */
1846 np = of_parse_phandle(dev->of_node, "operating-points-v2", 0);
1847 if (!np) {
1848 dev_dbg(dev, "Failed to find operating-points-v2\n");
1849 return -ENOENT;
1850 }
1851 if (!info)
1852 goto next;
1853 info->dev = dev;
1854
1855 num_clks = of_clk_get_parent_count(np);
1856 if (num_clks > 0) {
1857 info->clks = devm_kcalloc(dev, num_clks, sizeof(*info->clks),
1858 GFP_KERNEL);
1859 if (!info->clks) {
1860 ret = -ENOMEM;
1861 goto out;
1862 }
1863 for (i = 0; i < num_clks; i++) {
1864 info->clks[i].clk = of_clk_get(np, i);
1865 if (IS_ERR(info->clks[i].clk)) {
1866 ret = PTR_ERR(info->clks[i].clk);
1867 dev_err(dev, "%s: failed to get clk %d\n",
1868 np->name, i);
1869 goto out;
1870 }
1871 }
1872 info->num_clks = num_clks;
1873 ret = clk_bulk_prepare_enable(info->num_clks, info->clks);
1874 if (ret) {
1875 dev_err(dev, "failed to enable opp clks\n");
1876 goto out;
1877 }
1878 }
1879 if (info->data && info->data->set_read_margin) {
1880 info->current_rm = UINT_MAX;
1881 info->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
1882 if (IS_ERR(info->grf))
1883 info->grf = NULL;
1884 rockchip_get_volt_rm_table(dev, np, "volt-mem-read-margin",
1885 &info->volt_rm_tbl);
1886 of_property_read_u32(np, "low-volt-mem-read-margin",
1887 &info->low_rm);
1888 if (!of_property_read_u32(np, "intermediate-threshold-freq",
1889 &freq))
1890 info->intermediate_threshold_freq = freq * 1000;
1891 rockchip_init_read_margin(dev, info, reg_name);
1892 }
1893 if (info->data && info->data->get_soc_info)
1894 info->data->get_soc_info(dev, np, &bin, &process);
1895
1896 next:
1897 rockchip_get_soc_info(dev, np, &bin, &process);
1898 rockchip_get_scale_volt_sel(dev, lkg_name, reg_name, bin, process,
1899 &scale, &volt_sel);
1900 if (info && info->data && info->data->set_soc_info)
1901 info->data->set_soc_info(dev, np, bin, process, volt_sel);
1902 rockchip_set_opp_prop_name(dev, process, volt_sel);
1903 rockchip_set_opp_supported_hw(dev, np, bin, volt_sel);
1904 ret = dev_pm_opp_of_add_table(dev);
1905 if (ret) {
1906 dev_err(dev, "Invalid operating-points in device tree.\n");
1907 goto dis_opp_clk;
1908 }
1909 rockchip_adjust_power_scale(dev, scale);
1910 rockchip_pvtpll_calibrate_opp(info);
1911 rockchip_pvtpll_add_length(info);
1912
1913 dis_opp_clk:
1914 if (info && info->clks)
1915 clk_bulk_disable_unprepare(info->num_clks, info->clks);
1916 out:
1917 of_node_put(np);
1918
1919 return ret;
1920 }
1921 EXPORT_SYMBOL(rockchip_init_opp_table);
1922
1923 MODULE_DESCRIPTION("ROCKCHIP OPP Select");
1924 MODULE_AUTHOR("Finley Xiao <finley.xiao@rock-chips.com>, Liang Chen <cl@rock-chips.com>");
1925 MODULE_LICENSE("GPL");
1926