blob: 3035155e3f627767386bd367862432b19a9dfe7d [file] [log] [blame]
David Collins7370f1a2017-01-18 16:21:53 -08001/*
2 * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14/*
15 * This file contains utility functions to be used by platform specific CPR3
16 * regulator drivers.
17 */
18
19#define pr_fmt(fmt) "%s: " fmt, __func__
20
21#include <linux/cpumask.h>
22#include <linux/device.h>
23#include <linux/io.h>
24#include <linux/kernel.h>
25#include <linux/of.h>
26#include <linux/platform_device.h>
27#include <linux/slab.h>
28#include <linux/types.h>
29
30#include "cpr3-regulator.h"
31
32#define BYTES_PER_FUSE_ROW 8
33#define MAX_FUSE_ROW_BIT 63
34
35#define CPR3_CONSECUTIVE_UP_DOWN_MIN 0
36#define CPR3_CONSECUTIVE_UP_DOWN_MAX 15
37#define CPR3_UP_DOWN_THRESHOLD_MIN 0
38#define CPR3_UP_DOWN_THRESHOLD_MAX 31
39#define CPR3_STEP_QUOT_MIN 0
40#define CPR3_STEP_QUOT_MAX 63
41#define CPR3_IDLE_CLOCKS_MIN 0
42#define CPR3_IDLE_CLOCKS_MAX 31
43
44/* This constant has units of uV/mV so 1000 corresponds to 100%. */
45#define CPR3_AGING_DERATE_UNITY 1000
46
47/**
48 * cpr3_allocate_regulators() - allocate and initialize CPR3 regulators for a
49 * given thread based upon device tree data
50 * @thread: Pointer to the CPR3 thread
51 *
52 * This function allocates the thread->vreg array based upon the number of
53 * device tree regulator subnodes. It also initializes generic elements of each
54 * regulator struct such as name, of_node, and thread.
55 *
56 * Return: 0 on success, errno on failure
57 */
58static int cpr3_allocate_regulators(struct cpr3_thread *thread)
59{
60 struct device_node *node;
61 int i, rc;
62
63 thread->vreg_count = 0;
64
65 for_each_available_child_of_node(thread->of_node, node) {
66 thread->vreg_count++;
67 }
68
69 thread->vreg = devm_kcalloc(thread->ctrl->dev, thread->vreg_count,
70 sizeof(*thread->vreg), GFP_KERNEL);
71 if (!thread->vreg)
72 return -ENOMEM;
73
74 i = 0;
75 for_each_available_child_of_node(thread->of_node, node) {
76 thread->vreg[i].of_node = node;
77 thread->vreg[i].thread = thread;
78
79 rc = of_property_read_string(node, "regulator-name",
80 &thread->vreg[i].name);
81 if (rc) {
82 dev_err(thread->ctrl->dev, "could not find regulator name, rc=%d\n",
83 rc);
84 return rc;
85 }
86
87 i++;
88 }
89
90 return 0;
91}
92
93/**
94 * cpr3_allocate_threads() - allocate and initialize CPR3 threads for a given
95 * controller based upon device tree data
96 * @ctrl: Pointer to the CPR3 controller
97 * @min_thread_id: Minimum allowed hardware thread ID for this controller
98 * @max_thread_id: Maximum allowed hardware thread ID for this controller
99 *
100 * This function allocates the ctrl->thread array based upon the number of
101 * device tree thread subnodes. It also initializes generic elements of each
102 * thread struct such as thread_id, of_node, ctrl, and vreg array.
103 *
104 * Return: 0 on success, errno on failure
105 */
106int cpr3_allocate_threads(struct cpr3_controller *ctrl, u32 min_thread_id,
107 u32 max_thread_id)
108{
109 struct device *dev = ctrl->dev;
110 struct device_node *thread_node;
111 int i, j, rc;
112
113 ctrl->thread_count = 0;
114
115 for_each_available_child_of_node(dev->of_node, thread_node) {
116 ctrl->thread_count++;
117 }
118
119 ctrl->thread = devm_kcalloc(dev, ctrl->thread_count,
120 sizeof(*ctrl->thread), GFP_KERNEL);
121 if (!ctrl->thread)
122 return -ENOMEM;
123
124 i = 0;
125 for_each_available_child_of_node(dev->of_node, thread_node) {
126 ctrl->thread[i].of_node = thread_node;
127 ctrl->thread[i].ctrl = ctrl;
128
129 rc = of_property_read_u32(thread_node, "qcom,cpr-thread-id",
130 &ctrl->thread[i].thread_id);
131 if (rc) {
132 dev_err(dev, "could not read DT property qcom,cpr-thread-id, rc=%d\n",
133 rc);
134 return rc;
135 }
136
137 if (ctrl->thread[i].thread_id < min_thread_id ||
138 ctrl->thread[i].thread_id > max_thread_id) {
139 dev_err(dev, "invalid thread id = %u; not within [%u, %u]\n",
140 ctrl->thread[i].thread_id, min_thread_id,
141 max_thread_id);
142 return -EINVAL;
143 }
144
145 /* Verify that the thread ID is unique for all child nodes. */
146 for (j = 0; j < i; j++) {
147 if (ctrl->thread[j].thread_id
148 == ctrl->thread[i].thread_id) {
149 dev_err(dev, "duplicate thread id = %u found\n",
150 ctrl->thread[i].thread_id);
151 return -EINVAL;
152 }
153 }
154
155 rc = cpr3_allocate_regulators(&ctrl->thread[i]);
156 if (rc)
157 return rc;
158
159 i++;
160 }
161
162 return 0;
163}
164
165/**
166 * cpr3_map_fuse_base() - ioremap the base address of the fuse region
167 * @ctrl: Pointer to the CPR3 controller
168 * @pdev: Platform device pointer for the CPR3 controller
169 *
170 * Return: 0 on success, errno on failure
171 */
172int cpr3_map_fuse_base(struct cpr3_controller *ctrl,
173 struct platform_device *pdev)
174{
175 struct resource *res;
176
177 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fuse_base");
178 if (!res || !res->start) {
179 dev_err(&pdev->dev, "fuse base address is missing\n");
180 return -ENXIO;
181 }
182
183 ctrl->fuse_base = devm_ioremap(&pdev->dev, res->start,
184 resource_size(res));
185
186 return 0;
187}
188
189/**
190 * cpr3_read_fuse_param() - reads a CPR3 fuse parameter out of eFuses
191 * @fuse_base_addr: Virtual memory address of the eFuse base address
192 * @param: Null terminated array of fuse param segments to read
193 * from
194 * @param_value: Output with value read from the eFuses
195 *
196 * This function reads from each of the parameter segments listed in the param
197 * array and concatenates their values together. Reading stops when an element
198 * is reached which has all 0 struct values. The total number of bits specified
199 * for the fuse parameter across all segments must be less than or equal to 64.
200 *
201 * Return: 0 on success, errno on failure
202 */
203int cpr3_read_fuse_param(void __iomem *fuse_base_addr,
204 const struct cpr3_fuse_param *param, u64 *param_value)
205{
206 u64 fuse_val, val;
207 int bits;
208 int bits_total = 0;
209
210 *param_value = 0;
211
212 while (param->row || param->bit_start || param->bit_end) {
213 if (param->bit_start > param->bit_end
214 || param->bit_end > MAX_FUSE_ROW_BIT) {
215 pr_err("Invalid fuse parameter segment: row=%u, start=%u, end=%u\n",
216 param->row, param->bit_start, param->bit_end);
217 return -EINVAL;
218 }
219
220 bits = param->bit_end - param->bit_start + 1;
221 if (bits_total + bits > 64) {
222 pr_err("Invalid fuse parameter segments; total bits = %d\n",
223 bits_total + bits);
224 return -EINVAL;
225 }
226
227 fuse_val = readq_relaxed(fuse_base_addr
228 + param->row * BYTES_PER_FUSE_ROW);
229 val = (fuse_val >> param->bit_start) & ((1ULL << bits) - 1);
230 *param_value |= val << bits_total;
231 bits_total += bits;
232
233 param++;
234 }
235
236 return 0;
237}
238
239/**
240 * cpr3_convert_open_loop_voltage_fuse() - converts an open loop voltage fuse
241 * value into an absolute voltage with units of microvolts
242 * @ref_volt: Reference voltage in microvolts
243 * @step_volt: The step size in microvolts of the fuse LSB
244 * @fuse: Open loop voltage fuse value
245 * @fuse_len: The bit length of the fuse value
246 *
247 * The MSB of the fuse parameter corresponds to a sign bit. If it is set, then
248 * the lower bits correspond to the number of steps to go down from the
249 * reference voltage. If it is not set, then the lower bits correspond to the
250 * number of steps to go up from the reference voltage.
251 */
252int cpr3_convert_open_loop_voltage_fuse(int ref_volt, int step_volt, u32 fuse,
253 int fuse_len)
254{
255 int sign, steps;
256
257 sign = (fuse & (1 << (fuse_len - 1))) ? -1 : 1;
258 steps = fuse & ((1 << (fuse_len - 1)) - 1);
259
260 return ref_volt + sign * steps * step_volt;
261}
262
263/**
264 * cpr3_interpolate() - performs linear interpolation
265 * @x1 Lower known x value
266 * @y1 Lower known y value
267 * @x2 Upper known x value
268 * @y2 Upper known y value
269 * @x Intermediate x value
270 *
271 * Returns y where (x, y) falls on the line between (x1, y1) and (x2, y2).
272 * It is required that x1 < x2, y1 <= y2, and x1 <= x <= x2. If these
273 * conditions are not met, then y2 will be returned.
274 */
275u64 cpr3_interpolate(u64 x1, u64 y1, u64 x2, u64 y2, u64 x)
276{
277 u64 temp;
278
279 if (x1 >= x2 || y1 > y2 || x1 > x || x > x2)
280 return y2;
281
282 temp = (x2 - x) * (y2 - y1);
283 do_div(temp, (u32)(x2 - x1));
284
285 return y2 - temp;
286}
287
288/**
289 * cpr3_parse_array_property() - fill an array from a portion of the values
290 * specified for a device tree property
291 * @vreg: Pointer to the CPR3 regulator
292 * @prop_name: The name of the device tree property to read from
293 * @tuple_size: The number of elements in each tuple
294 * @out: Output data array which must be of size tuple_size
295 *
296 * cpr3_parse_common_corner_data() must be called for vreg before this function
297 * is called so that fuse combo and speed bin size elements are initialized.
298 *
299 * Three formats are supported for the device tree property:
300 * 1. Length == tuple_size
301 * (reading begins at index 0)
302 * 2. Length == tuple_size * vreg->fuse_combos_supported
303 * (reading begins at index tuple_size * vreg->fuse_combo)
304 * 3. Length == tuple_size * vreg->speed_bins_supported
305 * (reading begins at index tuple_size * vreg->speed_bin_fuse)
306 *
307 * All other property lengths are treated as errors.
308 *
309 * Return: 0 on success, errno on failure
310 */
311int cpr3_parse_array_property(struct cpr3_regulator *vreg,
312 const char *prop_name, int tuple_size, u32 *out)
313{
314 struct device_node *node = vreg->of_node;
315 int len = 0;
316 int i, offset, rc;
317
318 if (!of_find_property(node, prop_name, &len)) {
319 cpr3_err(vreg, "property %s is missing\n", prop_name);
320 return -EINVAL;
321 }
322
323 if (len == tuple_size * sizeof(u32)) {
324 offset = 0;
325 } else if (len == tuple_size * vreg->fuse_combos_supported
326 * sizeof(u32)) {
327 offset = tuple_size * vreg->fuse_combo;
328 } else if (vreg->speed_bins_supported > 0 &&
329 len == tuple_size * vreg->speed_bins_supported * sizeof(u32)) {
330 offset = tuple_size * vreg->speed_bin_fuse;
331 } else {
332 if (vreg->speed_bins_supported > 0)
333 cpr3_err(vreg, "property %s has invalid length=%d, should be %zu, %zu, or %zu\n",
334 prop_name, len,
335 tuple_size * sizeof(u32),
336 tuple_size * vreg->speed_bins_supported
337 * sizeof(u32),
338 tuple_size * vreg->fuse_combos_supported
339 * sizeof(u32));
340 else
341 cpr3_err(vreg, "property %s has invalid length=%d, should be %zu or %zu\n",
342 prop_name, len,
343 tuple_size * sizeof(u32),
344 tuple_size * vreg->fuse_combos_supported
345 * sizeof(u32));
346 return -EINVAL;
347 }
348
349 for (i = 0; i < tuple_size; i++) {
350 rc = of_property_read_u32_index(node, prop_name, offset + i,
351 &out[i]);
352 if (rc) {
353 cpr3_err(vreg, "error reading property %s, rc=%d\n",
354 prop_name, rc);
355 return rc;
356 }
357 }
358
359 return 0;
360}
361
362/**
363 * cpr3_parse_corner_array_property() - fill a per-corner array from a portion
364 * of the values specified for a device tree property
365 * @vreg: Pointer to the CPR3 regulator
366 * @prop_name: The name of the device tree property to read from
367 * @tuple_size: The number of elements in each per-corner tuple
368 * @out: Output data array which must be of size:
369 * tuple_size * vreg->corner_count
370 *
371 * cpr3_parse_common_corner_data() must be called for vreg before this function
372 * is called so that fuse combo and speed bin size elements are initialized.
373 *
374 * Three formats are supported for the device tree property:
375 * 1. Length == tuple_size * vreg->corner_count
376 * (reading begins at index 0)
377 * 2. Length == tuple_size * vreg->fuse_combo_corner_sum
378 * (reading begins at index tuple_size * vreg->fuse_combo_offset)
379 * 3. Length == tuple_size * vreg->speed_bin_corner_sum
380 * (reading begins at index tuple_size * vreg->speed_bin_offset)
381 *
382 * All other property lengths are treated as errors.
383 *
384 * Return: 0 on success, errno on failure
385 */
386int cpr3_parse_corner_array_property(struct cpr3_regulator *vreg,
387 const char *prop_name, int tuple_size, u32 *out)
388{
389 struct device_node *node = vreg->of_node;
390 int len = 0;
391 int i, offset, rc;
392
393 if (!of_find_property(node, prop_name, &len)) {
394 cpr3_err(vreg, "property %s is missing\n", prop_name);
395 return -EINVAL;
396 }
397
398 if (len == tuple_size * vreg->corner_count * sizeof(u32)) {
399 offset = 0;
400 } else if (len == tuple_size * vreg->fuse_combo_corner_sum
401 * sizeof(u32)) {
402 offset = tuple_size * vreg->fuse_combo_offset;
403 } else if (vreg->speed_bin_corner_sum > 0 &&
404 len == tuple_size * vreg->speed_bin_corner_sum * sizeof(u32)) {
405 offset = tuple_size * vreg->speed_bin_offset;
406 } else {
407 if (vreg->speed_bin_corner_sum > 0)
408 cpr3_err(vreg, "property %s has invalid length=%d, should be %zu, %zu, or %zu\n",
409 prop_name, len,
410 tuple_size * vreg->corner_count * sizeof(u32),
411 tuple_size * vreg->speed_bin_corner_sum
412 * sizeof(u32),
413 tuple_size * vreg->fuse_combo_corner_sum
414 * sizeof(u32));
415 else
416 cpr3_err(vreg, "property %s has invalid length=%d, should be %zu or %zu\n",
417 prop_name, len,
418 tuple_size * vreg->corner_count * sizeof(u32),
419 tuple_size * vreg->fuse_combo_corner_sum
420 * sizeof(u32));
421 return -EINVAL;
422 }
423
424 for (i = 0; i < tuple_size * vreg->corner_count; i++) {
425 rc = of_property_read_u32_index(node, prop_name, offset + i,
426 &out[i]);
427 if (rc) {
428 cpr3_err(vreg, "error reading property %s, rc=%d\n",
429 prop_name, rc);
430 return rc;
431 }
432 }
433
434 return 0;
435}
436
437/**
438 * cpr3_parse_corner_band_array_property() - fill a per-corner band array
439 * from a portion of the values specified for a device tree
440 * property
441 * @vreg: Pointer to the CPR3 regulator
442 * @prop_name: The name of the device tree property to read from
443 * @tuple_size: The number of elements in each per-corner band tuple
444 * @out: Output data array which must be of size:
445 * tuple_size * vreg->corner_band_count
446 *
447 * cpr3_parse_common_corner_data() must be called for vreg before this function
448 * is called so that fuse combo and speed bin size elements are initialized.
449 * In addition, corner band fuse combo and speed bin sum and offset elements
450 * must be initialized prior to executing this function.
451 *
452 * Three formats are supported for the device tree property:
453 * 1. Length == tuple_size * vreg->corner_band_count
454 * (reading begins at index 0)
455 * 2. Length == tuple_size * vreg->fuse_combo_corner_band_sum
456 * (reading begins at index tuple_size *
457 * vreg->fuse_combo_corner_band_offset)
458 * 3. Length == tuple_size * vreg->speed_bin_corner_band_sum
459 * (reading begins at index tuple_size *
460 * vreg->speed_bin_corner_band_offset)
461 *
462 * All other property lengths are treated as errors.
463 *
464 * Return: 0 on success, errno on failure
465 */
466int cpr3_parse_corner_band_array_property(struct cpr3_regulator *vreg,
467 const char *prop_name, int tuple_size, u32 *out)
468{
469 struct device_node *node = vreg->of_node;
470 int len = 0;
471 int i, offset, rc;
472
473 if (!of_find_property(node, prop_name, &len)) {
474 cpr3_err(vreg, "property %s is missing\n", prop_name);
475 return -EINVAL;
476 }
477
478 if (len == tuple_size * vreg->corner_band_count * sizeof(u32)) {
479 offset = 0;
480 } else if (len == tuple_size * vreg->fuse_combo_corner_band_sum
481 * sizeof(u32)) {
482 offset = tuple_size * vreg->fuse_combo_corner_band_offset;
483 } else if (vreg->speed_bin_corner_band_sum > 0 &&
484 len == tuple_size * vreg->speed_bin_corner_band_sum *
485 sizeof(u32)) {
486 offset = tuple_size * vreg->speed_bin_corner_band_offset;
487 } else {
488 if (vreg->speed_bin_corner_band_sum > 0)
489 cpr3_err(vreg, "property %s has invalid length=%d, should be %zu, %zu, or %zu\n",
490 prop_name, len,
491 tuple_size * vreg->corner_band_count *
492 sizeof(u32),
493 tuple_size * vreg->speed_bin_corner_band_sum
494 * sizeof(u32),
495 tuple_size * vreg->fuse_combo_corner_band_sum
496 * sizeof(u32));
497 else
498 cpr3_err(vreg, "property %s has invalid length=%d, should be %zu or %zu\n",
499 prop_name, len,
500 tuple_size * vreg->corner_band_count *
501 sizeof(u32),
502 tuple_size * vreg->fuse_combo_corner_band_sum
503 * sizeof(u32));
504 return -EINVAL;
505 }
506
507 for (i = 0; i < tuple_size * vreg->corner_band_count; i++) {
508 rc = of_property_read_u32_index(node, prop_name, offset + i,
509 &out[i]);
510 if (rc) {
511 cpr3_err(vreg, "error reading property %s, rc=%d\n",
512 prop_name, rc);
513 return rc;
514 }
515 }
516
517 return 0;
518}
519
520/**
521 * cpr3_parse_common_corner_data() - parse common CPR3 properties relating to
522 * the corners supported by a CPR3 regulator from device tree
523 * @vreg: Pointer to the CPR3 regulator
524 *
525 * This function reads, validates, and utilizes the following device tree
526 * properties: qcom,cpr-fuse-corners, qcom,cpr-fuse-combos, qcom,cpr-speed-bins,
527 * qcom,cpr-speed-bin-corners, qcom,cpr-corners, qcom,cpr-voltage-ceiling,
528 * qcom,cpr-voltage-floor, qcom,corner-frequencies,
529 * and qcom,cpr-corner-fmax-map.
530 *
531 * It initializes these CPR3 regulator elements: corner, corner_count,
532 * fuse_combos_supported, fuse_corner_map, and speed_bins_supported. It
533 * initializes these elements for each corner: ceiling_volt, floor_volt,
534 * proc_freq, and cpr_fuse_corner.
535 *
536 * It requires that the following CPR3 regulator elements be initialized before
537 * being called: fuse_corner_count, fuse_combo, and speed_bin_fuse.
538 *
539 * Return: 0 on success, errno on failure
540 */
541int cpr3_parse_common_corner_data(struct cpr3_regulator *vreg)
542{
543 struct device_node *node = vreg->of_node;
544 struct cpr3_controller *ctrl = vreg->thread->ctrl;
545 u32 max_fuse_combos, fuse_corners, aging_allowed = 0;
546 u32 max_speed_bins = 0;
547 u32 *combo_corners;
548 u32 *speed_bin_corners;
549 u32 *temp;
550 int i, j, rc;
551
552 rc = of_property_read_u32(node, "qcom,cpr-fuse-corners", &fuse_corners);
553 if (rc) {
554 cpr3_err(vreg, "error reading property qcom,cpr-fuse-corners, rc=%d\n",
555 rc);
556 return rc;
557 }
558
559 if (vreg->fuse_corner_count != fuse_corners) {
560 cpr3_err(vreg, "device tree config supports %d fuse corners but the hardware has %d fuse corners\n",
561 fuse_corners, vreg->fuse_corner_count);
562 return -EINVAL;
563 }
564
565 rc = of_property_read_u32(node, "qcom,cpr-fuse-combos",
566 &max_fuse_combos);
567 if (rc) {
568 cpr3_err(vreg, "error reading property qcom,cpr-fuse-combos, rc=%d\n",
569 rc);
570 return rc;
571 }
572
573 /*
574 * Sanity check against arbitrarily large value to avoid excessive
575 * memory allocation.
576 */
577 if (max_fuse_combos > 100 || max_fuse_combos == 0) {
578 cpr3_err(vreg, "qcom,cpr-fuse-combos is invalid: %u\n",
579 max_fuse_combos);
580 return -EINVAL;
581 }
582
583 if (vreg->fuse_combo >= max_fuse_combos) {
584 cpr3_err(vreg, "device tree config supports fuse combos 0-%u but the hardware has combo %d\n",
585 max_fuse_combos - 1, vreg->fuse_combo);
586 BUG_ON(1);
587 return -EINVAL;
588 }
589
590 vreg->fuse_combos_supported = max_fuse_combos;
591
592 of_property_read_u32(node, "qcom,cpr-speed-bins", &max_speed_bins);
593
594 /*
595 * Sanity check against arbitrarily large value to avoid excessive
596 * memory allocation.
597 */
598 if (max_speed_bins > 100) {
599 cpr3_err(vreg, "qcom,cpr-speed-bins is invalid: %u\n",
600 max_speed_bins);
601 return -EINVAL;
602 }
603
604 if (max_speed_bins && vreg->speed_bin_fuse >= max_speed_bins) {
605 cpr3_err(vreg, "device tree config supports speed bins 0-%u but the hardware has speed bin %d\n",
606 max_speed_bins - 1, vreg->speed_bin_fuse);
607 BUG();
608 return -EINVAL;
609 }
610
611 vreg->speed_bins_supported = max_speed_bins;
612
613 combo_corners = kcalloc(vreg->fuse_combos_supported,
614 sizeof(*combo_corners), GFP_KERNEL);
615 if (!combo_corners)
616 return -ENOMEM;
617
618 rc = of_property_read_u32_array(node, "qcom,cpr-corners", combo_corners,
619 vreg->fuse_combos_supported);
620 if (rc == -EOVERFLOW) {
621 /* Single value case */
622 rc = of_property_read_u32(node, "qcom,cpr-corners",
623 combo_corners);
624 for (i = 1; i < vreg->fuse_combos_supported; i++)
625 combo_corners[i] = combo_corners[0];
626 }
627 if (rc) {
628 cpr3_err(vreg, "error reading property qcom,cpr-corners, rc=%d\n",
629 rc);
630 kfree(combo_corners);
631 return rc;
632 }
633
634 vreg->fuse_combo_offset = 0;
635 vreg->fuse_combo_corner_sum = 0;
636 for (i = 0; i < vreg->fuse_combos_supported; i++) {
637 vreg->fuse_combo_corner_sum += combo_corners[i];
638 if (i < vreg->fuse_combo)
639 vreg->fuse_combo_offset += combo_corners[i];
640 }
641
642 vreg->corner_count = combo_corners[vreg->fuse_combo];
643
644 kfree(combo_corners);
645
646 vreg->speed_bin_offset = 0;
647 vreg->speed_bin_corner_sum = 0;
648 if (vreg->speed_bins_supported > 0) {
649 speed_bin_corners = kcalloc(vreg->speed_bins_supported,
650 sizeof(*speed_bin_corners), GFP_KERNEL);
651 if (!speed_bin_corners)
652 return -ENOMEM;
653
654 rc = of_property_read_u32_array(node,
655 "qcom,cpr-speed-bin-corners", speed_bin_corners,
656 vreg->speed_bins_supported);
657 if (rc) {
658 cpr3_err(vreg, "error reading property qcom,cpr-speed-bin-corners, rc=%d\n",
659 rc);
660 kfree(speed_bin_corners);
661 return rc;
662 }
663
664 for (i = 0; i < vreg->speed_bins_supported; i++) {
665 vreg->speed_bin_corner_sum += speed_bin_corners[i];
666 if (i < vreg->speed_bin_fuse)
667 vreg->speed_bin_offset += speed_bin_corners[i];
668 }
669
670 if (speed_bin_corners[vreg->speed_bin_fuse]
671 != vreg->corner_count) {
672 cpr3_err(vreg, "qcom,cpr-corners and qcom,cpr-speed-bin-corners conflict on number of corners: %d vs %u\n",
673 vreg->corner_count,
674 speed_bin_corners[vreg->speed_bin_fuse]);
675 kfree(speed_bin_corners);
676 return -EINVAL;
677 }
678
679 kfree(speed_bin_corners);
680 }
681
682 /*
683 * For CPRh compliant controllers two additional corners are
684 * allocated to correspond to the APM crossover voltage and the MEM ACC
685 * crossover voltage.
686 */
687 vreg->corner = devm_kcalloc(ctrl->dev, ctrl->ctrl_type ==
688 CPR_CTRL_TYPE_CPRH ?
689 vreg->corner_count + 2 :
690 vreg->corner_count,
691 sizeof(*vreg->corner), GFP_KERNEL);
692 temp = kcalloc(vreg->corner_count, sizeof(*temp), GFP_KERNEL);
693 if (!vreg->corner || !temp)
694 return -ENOMEM;
695
696 rc = cpr3_parse_corner_array_property(vreg, "qcom,cpr-voltage-ceiling",
697 1, temp);
698 if (rc)
699 goto free_temp;
700 for (i = 0; i < vreg->corner_count; i++) {
701 vreg->corner[i].ceiling_volt
702 = CPR3_ROUND(temp[i], ctrl->step_volt);
703 vreg->corner[i].abs_ceiling_volt = vreg->corner[i].ceiling_volt;
704 }
705
706 rc = cpr3_parse_corner_array_property(vreg, "qcom,cpr-voltage-floor",
707 1, temp);
708 if (rc)
709 goto free_temp;
710 for (i = 0; i < vreg->corner_count; i++)
711 vreg->corner[i].floor_volt
712 = CPR3_ROUND(temp[i], ctrl->step_volt);
713
714 /* Validate ceiling and floor values */
715 for (i = 0; i < vreg->corner_count; i++) {
716 if (vreg->corner[i].floor_volt
717 > vreg->corner[i].ceiling_volt) {
718 cpr3_err(vreg, "CPR floor[%d]=%d > ceiling[%d]=%d uV\n",
719 i, vreg->corner[i].floor_volt,
720 i, vreg->corner[i].ceiling_volt);
721 rc = -EINVAL;
722 goto free_temp;
723 }
724 }
725
726 /* Load optional system-supply voltages */
727 if (of_find_property(vreg->of_node, "qcom,system-voltage", NULL)) {
728 rc = cpr3_parse_corner_array_property(vreg,
729 "qcom,system-voltage", 1, temp);
730 if (rc)
731 goto free_temp;
732 for (i = 0; i < vreg->corner_count; i++)
733 vreg->corner[i].system_volt = temp[i];
734 }
735
736 rc = cpr3_parse_corner_array_property(vreg, "qcom,corner-frequencies",
737 1, temp);
738 if (rc)
739 goto free_temp;
740 for (i = 0; i < vreg->corner_count; i++)
741 vreg->corner[i].proc_freq = temp[i];
742
743 /* Validate frequencies */
744 for (i = 1; i < vreg->corner_count; i++) {
745 if (vreg->corner[i].proc_freq
746 < vreg->corner[i - 1].proc_freq) {
747 cpr3_err(vreg, "invalid frequency: freq[%d]=%u < freq[%d]=%u\n",
748 i, vreg->corner[i].proc_freq, i - 1,
749 vreg->corner[i - 1].proc_freq);
750 rc = -EINVAL;
751 goto free_temp;
752 }
753 }
754
755 vreg->fuse_corner_map = devm_kcalloc(ctrl->dev, vreg->fuse_corner_count,
756 sizeof(*vreg->fuse_corner_map), GFP_KERNEL);
757 if (!vreg->fuse_corner_map) {
758 rc = -ENOMEM;
759 goto free_temp;
760 }
761
762 rc = cpr3_parse_array_property(vreg, "qcom,cpr-corner-fmax-map",
763 vreg->fuse_corner_count, temp);
764 if (rc)
765 goto free_temp;
766 for (i = 0; i < vreg->fuse_corner_count; i++) {
767 vreg->fuse_corner_map[i] = temp[i] - CPR3_CORNER_OFFSET;
768 if (temp[i] < CPR3_CORNER_OFFSET
769 || temp[i] > vreg->corner_count + CPR3_CORNER_OFFSET) {
770 cpr3_err(vreg, "invalid corner value specified in qcom,cpr-corner-fmax-map: %u\n",
771 temp[i]);
772 rc = -EINVAL;
773 goto free_temp;
774 } else if (i > 0 && temp[i - 1] >= temp[i]) {
775 cpr3_err(vreg, "invalid corner %u less than or equal to previous corner %u\n",
776 temp[i], temp[i - 1]);
777 rc = -EINVAL;
778 goto free_temp;
779 }
780 }
781 if (temp[vreg->fuse_corner_count - 1] != vreg->corner_count)
782 cpr3_debug(vreg, "Note: highest Fmax corner %u in qcom,cpr-corner-fmax-map does not match highest supported corner %d\n",
783 temp[vreg->fuse_corner_count - 1],
784 vreg->corner_count);
785
786 for (i = 0; i < vreg->corner_count; i++) {
787 for (j = 0; j < vreg->fuse_corner_count; j++) {
788 if (i + CPR3_CORNER_OFFSET <= temp[j]) {
789 vreg->corner[i].cpr_fuse_corner = j;
790 break;
791 }
792 }
793 if (j == vreg->fuse_corner_count) {
794 /*
795 * Handle the case where the highest fuse corner maps
796 * to a corner below the highest corner.
797 */
798 vreg->corner[i].cpr_fuse_corner
799 = vreg->fuse_corner_count - 1;
800 }
801 }
802
803 if (of_find_property(vreg->of_node,
804 "qcom,allow-aging-voltage-adjustment", NULL)) {
805 rc = cpr3_parse_array_property(vreg,
806 "qcom,allow-aging-voltage-adjustment",
807 1, &aging_allowed);
808 if (rc)
809 goto free_temp;
810
811 vreg->aging_allowed = aging_allowed;
812 }
813
814 if (of_find_property(vreg->of_node,
815 "qcom,allow-aging-open-loop-voltage-adjustment", NULL)) {
816 rc = cpr3_parse_array_property(vreg,
817 "qcom,allow-aging-open-loop-voltage-adjustment",
818 1, &aging_allowed);
819 if (rc)
820 goto free_temp;
821
822 vreg->aging_allow_open_loop_adj = aging_allowed;
823 }
824
825 if (vreg->aging_allowed) {
826 if (ctrl->aging_ref_volt <= 0) {
827 cpr3_err(ctrl, "qcom,cpr-aging-ref-voltage must be specified\n");
828 rc = -EINVAL;
829 goto free_temp;
830 }
831
832 rc = cpr3_parse_array_property(vreg,
833 "qcom,cpr-aging-max-voltage-adjustment",
834 1, &vreg->aging_max_adjust_volt);
835 if (rc)
836 goto free_temp;
837
838 rc = cpr3_parse_array_property(vreg,
839 "qcom,cpr-aging-ref-corner", 1, &vreg->aging_corner);
840 if (rc) {
841 goto free_temp;
842 } else if (vreg->aging_corner < CPR3_CORNER_OFFSET
843 || vreg->aging_corner > vreg->corner_count - 1
844 + CPR3_CORNER_OFFSET) {
845 cpr3_err(vreg, "aging reference corner=%d not in range [%d, %d]\n",
846 vreg->aging_corner, CPR3_CORNER_OFFSET,
847 vreg->corner_count - 1 + CPR3_CORNER_OFFSET);
848 rc = -EINVAL;
849 goto free_temp;
850 }
851 vreg->aging_corner -= CPR3_CORNER_OFFSET;
852
853 if (of_find_property(vreg->of_node, "qcom,cpr-aging-derate",
854 NULL)) {
855 rc = cpr3_parse_corner_array_property(vreg,
856 "qcom,cpr-aging-derate", 1, temp);
857 if (rc)
858 goto free_temp;
859
860 for (i = 0; i < vreg->corner_count; i++)
861 vreg->corner[i].aging_derate = temp[i];
862 } else {
863 for (i = 0; i < vreg->corner_count; i++)
864 vreg->corner[i].aging_derate
865 = CPR3_AGING_DERATE_UNITY;
866 }
867 }
868
869free_temp:
870 kfree(temp);
871 return rc;
872}
873
874/**
875 * cpr3_parse_thread_u32() - parse the specified property from the CPR3 thread's
876 * device tree node and verify that it is within the allowed limits
877 * @thread: Pointer to the CPR3 thread
878 * @propname: The name of the device tree property to read
879 * @out_value: The output pointer to fill with the value read
880 * @value_min: The minimum allowed property value
881 * @value_max: The maximum allowed property value
882 *
883 * This function prints a verbose error message if the property is missing or
884 * has a value which is not within the specified range.
885 *
886 * Return: 0 on success, errno on failure
887 */
888int cpr3_parse_thread_u32(struct cpr3_thread *thread, const char *propname,
889 u32 *out_value, u32 value_min, u32 value_max)
890{
891 int rc;
892
893 rc = of_property_read_u32(thread->of_node, propname, out_value);
894 if (rc) {
895 cpr3_err(thread->ctrl, "thread %u error reading property %s, rc=%d\n",
896 thread->thread_id, propname, rc);
897 return rc;
898 }
899
900 if (*out_value < value_min || *out_value > value_max) {
901 cpr3_err(thread->ctrl, "thread %u %s=%u is invalid; allowed range: [%u, %u]\n",
902 thread->thread_id, propname, *out_value, value_min,
903 value_max);
904 return -EINVAL;
905 }
906
907 return 0;
908}
909
910/**
911 * cpr3_parse_ctrl_u32() - parse the specified property from the CPR3
912 * controller's device tree node and verify that it is within the
913 * allowed limits
914 * @ctrl: Pointer to the CPR3 controller
915 * @propname: The name of the device tree property to read
916 * @out_value: The output pointer to fill with the value read
917 * @value_min: The minimum allowed property value
918 * @value_max: The maximum allowed property value
919 *
920 * This function prints a verbose error message if the property is missing or
921 * has a value which is not within the specified range.
922 *
923 * Return: 0 on success, errno on failure
924 */
925int cpr3_parse_ctrl_u32(struct cpr3_controller *ctrl, const char *propname,
926 u32 *out_value, u32 value_min, u32 value_max)
927{
928 int rc;
929
930 rc = of_property_read_u32(ctrl->dev->of_node, propname, out_value);
931 if (rc) {
932 cpr3_err(ctrl, "error reading property %s, rc=%d\n",
933 propname, rc);
934 return rc;
935 }
936
937 if (*out_value < value_min || *out_value > value_max) {
938 cpr3_err(ctrl, "%s=%u is invalid; allowed range: [%u, %u]\n",
939 propname, *out_value, value_min, value_max);
940 return -EINVAL;
941 }
942
943 return 0;
944}
945
946/**
947 * cpr3_parse_common_thread_data() - parse common CPR3 thread properties from
948 * device tree
949 * @thread: Pointer to the CPR3 thread
950 *
951 * Return: 0 on success, errno on failure
952 */
953int cpr3_parse_common_thread_data(struct cpr3_thread *thread)
954{
955 int rc;
956
957 rc = cpr3_parse_thread_u32(thread, "qcom,cpr-consecutive-up",
958 &thread->consecutive_up, CPR3_CONSECUTIVE_UP_DOWN_MIN,
959 CPR3_CONSECUTIVE_UP_DOWN_MAX);
960 if (rc)
961 return rc;
962
963 rc = cpr3_parse_thread_u32(thread, "qcom,cpr-consecutive-down",
964 &thread->consecutive_down, CPR3_CONSECUTIVE_UP_DOWN_MIN,
965 CPR3_CONSECUTIVE_UP_DOWN_MAX);
966 if (rc)
967 return rc;
968
969 rc = cpr3_parse_thread_u32(thread, "qcom,cpr-up-threshold",
970 &thread->up_threshold, CPR3_UP_DOWN_THRESHOLD_MIN,
971 CPR3_UP_DOWN_THRESHOLD_MAX);
972 if (rc)
973 return rc;
974
975 rc = cpr3_parse_thread_u32(thread, "qcom,cpr-down-threshold",
976 &thread->down_threshold, CPR3_UP_DOWN_THRESHOLD_MIN,
977 CPR3_UP_DOWN_THRESHOLD_MAX);
978 if (rc)
979 return rc;
980
981 return rc;
982}
983
984/**
985 * cpr3_parse_irq_affinity() - parse CPR IRQ affinity information
986 * @ctrl: Pointer to the CPR3 controller
987 *
988 * Return: 0 on success, errno on failure
989 */
990static int cpr3_parse_irq_affinity(struct cpr3_controller *ctrl)
991{
992 struct device_node *cpu_node;
993 int i, cpu;
994 int len = 0;
995
996 if (!of_find_property(ctrl->dev->of_node, "qcom,cpr-interrupt-affinity",
997 &len)) {
998 /* No IRQ affinity required */
999 return 0;
1000 }
1001
1002 len /= sizeof(u32);
1003
1004 for (i = 0; i < len; i++) {
1005 cpu_node = of_parse_phandle(ctrl->dev->of_node,
1006 "qcom,cpr-interrupt-affinity", i);
1007 if (!cpu_node) {
1008 cpr3_err(ctrl, "could not find CPU node %d\n", i);
1009 return -EINVAL;
1010 }
1011
1012 for_each_possible_cpu(cpu) {
1013 if (of_get_cpu_node(cpu, NULL) == cpu_node) {
1014 cpumask_set_cpu(cpu, &ctrl->irq_affinity_mask);
1015 break;
1016 }
1017 }
1018 of_node_put(cpu_node);
1019 }
1020
1021 return 0;
1022}
1023
1024static int cpr3_panic_notifier_init(struct cpr3_controller *ctrl)
1025{
1026 struct device_node *node = ctrl->dev->of_node;
1027 struct cpr3_panic_regs_info *panic_regs_info;
1028 struct cpr3_reg_info *regs;
1029 int i, reg_count, len, rc = 0;
1030
1031 if (!of_find_property(node, "qcom,cpr-panic-reg-addr-list", &len)) {
1032 /* panic register address list not specified */
1033 return rc;
1034 }
1035
1036 reg_count = len / sizeof(u32);
1037 if (!reg_count) {
1038 cpr3_err(ctrl, "qcom,cpr-panic-reg-addr-list has invalid len = %d\n",
1039 len);
1040 return -EINVAL;
1041 }
1042
1043 if (!of_find_property(node, "qcom,cpr-panic-reg-name-list", NULL)) {
1044 cpr3_err(ctrl, "property qcom,cpr-panic-reg-name-list not specified\n");
1045 return -EINVAL;
1046 }
1047
1048 len = of_property_count_strings(node, "qcom,cpr-panic-reg-name-list");
1049 if (reg_count != len) {
1050 cpr3_err(ctrl, "qcom,cpr-panic-reg-name-list should have %d strings\n",
1051 reg_count);
1052 return -EINVAL;
1053 }
1054
1055 panic_regs_info = devm_kzalloc(ctrl->dev, sizeof(*panic_regs_info),
1056 GFP_KERNEL);
1057 if (!panic_regs_info)
1058 return -ENOMEM;
1059
1060 regs = devm_kcalloc(ctrl->dev, reg_count, sizeof(*regs), GFP_KERNEL);
1061 if (!regs)
1062 return -ENOMEM;
1063
1064 for (i = 0; i < reg_count; i++) {
1065 rc = of_property_read_string_index(node,
1066 "qcom,cpr-panic-reg-name-list", i,
1067 &(regs[i].name));
1068 if (rc) {
1069 cpr3_err(ctrl, "error reading property qcom,cpr-panic-reg-name-list, rc=%d\n",
1070 rc);
1071 return rc;
1072 }
1073
1074 rc = of_property_read_u32_index(node,
1075 "qcom,cpr-panic-reg-addr-list", i,
1076 &(regs[i].addr));
1077 if (rc) {
1078 cpr3_err(ctrl, "error reading property qcom,cpr-panic-reg-addr-list, rc=%d\n",
1079 rc);
1080 return rc;
1081 }
1082 regs[i].virt_addr = devm_ioremap(ctrl->dev, regs[i].addr, 0x4);
1083 if (!regs[i].virt_addr) {
1084 pr_err("Unable to map panic register addr 0x%08x\n",
1085 regs[i].addr);
1086 return -EINVAL;
1087 }
1088 regs[i].value = 0xFFFFFFFF;
1089 }
1090
1091 panic_regs_info->reg_count = reg_count;
1092 panic_regs_info->regs = regs;
1093 ctrl->panic_regs_info = panic_regs_info;
1094
1095 return rc;
1096}
1097
1098/**
1099 * cpr3_parse_common_ctrl_data() - parse common CPR3 controller properties from
1100 * device tree
1101 * @ctrl: Pointer to the CPR3 controller
1102 *
1103 * Return: 0 on success, errno on failure
1104 */
1105int cpr3_parse_common_ctrl_data(struct cpr3_controller *ctrl)
1106{
1107 int rc;
1108
1109 rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-sensor-time",
1110 &ctrl->sensor_time, 0, UINT_MAX);
1111 if (rc)
1112 return rc;
1113
1114 rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-loop-time",
1115 &ctrl->loop_time, 0, UINT_MAX);
1116 if (rc)
1117 return rc;
1118
1119 rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-idle-cycles",
1120 &ctrl->idle_clocks, CPR3_IDLE_CLOCKS_MIN,
1121 CPR3_IDLE_CLOCKS_MAX);
1122 if (rc)
1123 return rc;
1124
1125 rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-step-quot-init-min",
1126 &ctrl->step_quot_init_min, CPR3_STEP_QUOT_MIN,
1127 CPR3_STEP_QUOT_MAX);
1128 if (rc)
1129 return rc;
1130
1131 rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-step-quot-init-max",
1132 &ctrl->step_quot_init_max, CPR3_STEP_QUOT_MIN,
1133 CPR3_STEP_QUOT_MAX);
1134 if (rc)
1135 return rc;
1136
1137 rc = of_property_read_u32(ctrl->dev->of_node, "qcom,voltage-step",
1138 &ctrl->step_volt);
1139 if (rc) {
1140 cpr3_err(ctrl, "error reading property qcom,voltage-step, rc=%d\n",
1141 rc);
1142 return rc;
1143 }
1144 if (ctrl->step_volt <= 0) {
1145 cpr3_err(ctrl, "qcom,voltage-step=%d is invalid\n",
1146 ctrl->step_volt);
1147 return -EINVAL;
1148 }
1149
1150 rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-count-mode",
1151 &ctrl->count_mode, CPR3_COUNT_MODE_ALL_AT_ONCE_MIN,
1152 CPR3_COUNT_MODE_STAGGERED);
1153 if (rc)
1154 return rc;
1155
1156 /* Count repeat is optional */
1157 ctrl->count_repeat = 0;
1158 of_property_read_u32(ctrl->dev->of_node, "qcom,cpr-count-repeat",
1159 &ctrl->count_repeat);
1160
1161 ctrl->cpr_allowed_sw = of_property_read_bool(ctrl->dev->of_node,
1162 "qcom,cpr-enable");
1163
1164 rc = cpr3_parse_irq_affinity(ctrl);
1165 if (rc)
1166 return rc;
1167
David Collins044e9e72017-03-06 16:47:09 -08001168 ctrl->ignore_invalid_fuses = of_property_read_bool(ctrl->dev->of_node,
1169 "qcom,cpr-ignore-invalid-fuses");
1170
David Collins7370f1a2017-01-18 16:21:53 -08001171 /* Aging reference voltage is optional */
1172 ctrl->aging_ref_volt = 0;
1173 of_property_read_u32(ctrl->dev->of_node, "qcom,cpr-aging-ref-voltage",
1174 &ctrl->aging_ref_volt);
1175
1176 /* Aging possible bitmask is optional */
1177 ctrl->aging_possible_mask = 0;
1178 of_property_read_u32(ctrl->dev->of_node,
1179 "qcom,cpr-aging-allowed-reg-mask",
1180 &ctrl->aging_possible_mask);
1181
1182 if (ctrl->aging_possible_mask) {
1183 /*
1184 * Aging possible register value required if bitmask is
1185 * specified
1186 */
1187 rc = cpr3_parse_ctrl_u32(ctrl,
1188 "qcom,cpr-aging-allowed-reg-value",
1189 &ctrl->aging_possible_val, 0, UINT_MAX);
1190 if (rc)
1191 return rc;
1192 }
1193
1194 if (of_find_property(ctrl->dev->of_node, "clock-names", NULL)) {
1195 ctrl->core_clk = devm_clk_get(ctrl->dev, "core_clk");
1196 if (IS_ERR(ctrl->core_clk)) {
1197 rc = PTR_ERR(ctrl->core_clk);
1198 if (rc != -EPROBE_DEFER)
1199 cpr3_err(ctrl, "unable request core clock, rc=%d\n",
1200 rc);
1201 return rc;
1202 }
1203 }
1204
1205 rc = cpr3_panic_notifier_init(ctrl);
1206 if (rc)
1207 return rc;
1208
1209 if (of_find_property(ctrl->dev->of_node, "vdd-supply", NULL)) {
1210 ctrl->vdd_regulator = devm_regulator_get(ctrl->dev, "vdd");
1211 if (IS_ERR(ctrl->vdd_regulator)) {
1212 rc = PTR_ERR(ctrl->vdd_regulator);
1213 if (rc != -EPROBE_DEFER)
1214 cpr3_err(ctrl, "unable to request vdd regulator, rc=%d\n",
1215 rc);
1216 return rc;
1217 }
1218 } else if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPRH) {
1219 /* vdd-supply is optional for CPRh controllers. */
1220 ctrl->vdd_regulator = NULL;
1221 } else {
1222 cpr3_err(ctrl, "vdd supply is not defined\n");
1223 return -ENODEV;
1224 }
1225
1226 /*
Tirupathi Reddy718bc802017-02-09 16:29:24 +05301227 * Reset step_quot to default on each loop_en = 0 transition is
1228 * optional.
1229 */
1230 ctrl->reset_step_quot_loop_en
1231 = of_property_read_bool(ctrl->dev->of_node,
1232 "qcom,cpr-reset-step-quot-loop-en");
1233
1234 /*
David Collins7370f1a2017-01-18 16:21:53 -08001235 * Regulator device handles are not necessary for CPRh controllers
1236 * since communication with the regulators is completely managed
1237 * in hardware.
1238 */
1239 if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPRH)
1240 return rc;
1241
1242 ctrl->system_regulator = devm_regulator_get_optional(ctrl->dev,
1243 "system");
1244 if (IS_ERR(ctrl->system_regulator)) {
1245 rc = PTR_ERR(ctrl->system_regulator);
1246 if (rc != -EPROBE_DEFER) {
1247 rc = 0;
1248 ctrl->system_regulator = NULL;
1249 } else {
1250 return rc;
1251 }
1252 }
1253
1254 ctrl->mem_acc_regulator = devm_regulator_get_optional(ctrl->dev,
1255 "mem-acc");
1256 if (IS_ERR(ctrl->mem_acc_regulator)) {
1257 rc = PTR_ERR(ctrl->mem_acc_regulator);
1258 if (rc != -EPROBE_DEFER) {
1259 rc = 0;
1260 ctrl->mem_acc_regulator = NULL;
1261 } else {
1262 return rc;
1263 }
1264 }
1265
1266 return rc;
1267}
1268
1269/**
1270 * cpr3_limit_open_loop_voltages() - modify the open-loop voltage of each corner
1271 * so that it fits within the floor to ceiling
1272 * voltage range of the corner
1273 * @vreg: Pointer to the CPR3 regulator
1274 *
1275 * This function clips the open-loop voltage for each corner so that it is
1276 * limited to the floor to ceiling range. It also rounds each open-loop voltage
1277 * so that it corresponds to a set point available to the underlying regulator.
1278 *
1279 * Return: 0 on success, errno on failure
1280 */
1281int cpr3_limit_open_loop_voltages(struct cpr3_regulator *vreg)
1282{
1283 int i, volt;
1284
1285 cpr3_debug(vreg, "open-loop voltages after trimming and rounding:\n");
1286 for (i = 0; i < vreg->corner_count; i++) {
1287 volt = CPR3_ROUND(vreg->corner[i].open_loop_volt,
1288 vreg->thread->ctrl->step_volt);
1289 if (volt < vreg->corner[i].floor_volt)
1290 volt = vreg->corner[i].floor_volt;
1291 else if (volt > vreg->corner[i].ceiling_volt)
1292 volt = vreg->corner[i].ceiling_volt;
1293 vreg->corner[i].open_loop_volt = volt;
1294 cpr3_debug(vreg, "corner[%2d]: open-loop=%d uV\n", i, volt);
1295 }
1296
1297 return 0;
1298}
1299
1300/**
1301 * cpr3_open_loop_voltage_as_ceiling() - configures the ceiling voltage for each
1302 * corner to equal the open-loop voltage if the relevant device
1303 * tree property is found for the CPR3 regulator
1304 * @vreg: Pointer to the CPR3 regulator
1305 *
1306 * This function assumes that the the open-loop voltage for each corner has
1307 * already been rounded to the nearest allowed set point and that it falls
1308 * within the floor to ceiling range.
1309 *
1310 * Return: none
1311 */
1312void cpr3_open_loop_voltage_as_ceiling(struct cpr3_regulator *vreg)
1313{
1314 int i;
1315
1316 if (!of_property_read_bool(vreg->of_node,
1317 "qcom,cpr-scaled-open-loop-voltage-as-ceiling"))
1318 return;
1319
1320 for (i = 0; i < vreg->corner_count; i++)
1321 vreg->corner[i].ceiling_volt
1322 = vreg->corner[i].open_loop_volt;
1323}
1324
1325/**
1326 * cpr3_limit_floor_voltages() - raise the floor voltage of each corner so that
1327 * the optional maximum floor to ceiling voltage range specified in
1328 * device tree is satisfied
1329 * @vreg: Pointer to the CPR3 regulator
1330 *
1331 * This function also ensures that the open-loop voltage for each corner falls
1332 * within the final floor to ceiling voltage range and that floor voltages
1333 * increase monotonically.
1334 *
1335 * Return: 0 on success, errno on failure
1336 */
1337int cpr3_limit_floor_voltages(struct cpr3_regulator *vreg)
1338{
1339 char *prop = "qcom,cpr-floor-to-ceiling-max-range";
1340 int i, floor_new;
1341 u32 *floor_range;
1342 int rc = 0;
1343
1344 if (!of_find_property(vreg->of_node, prop, NULL))
1345 goto enforce_monotonicity;
1346
1347 floor_range = kcalloc(vreg->corner_count, sizeof(*floor_range),
1348 GFP_KERNEL);
1349 if (!floor_range)
1350 return -ENOMEM;
1351
1352 rc = cpr3_parse_corner_array_property(vreg, prop, 1, floor_range);
1353 if (rc)
1354 goto free_floor_adjust;
1355
1356 for (i = 0; i < vreg->corner_count; i++) {
1357 if ((s32)floor_range[i] >= 0) {
1358 floor_new = CPR3_ROUND(vreg->corner[i].ceiling_volt
1359 - floor_range[i],
1360 vreg->thread->ctrl->step_volt);
1361
1362 vreg->corner[i].floor_volt = max(floor_new,
1363 vreg->corner[i].floor_volt);
1364 if (vreg->corner[i].open_loop_volt
1365 < vreg->corner[i].floor_volt)
1366 vreg->corner[i].open_loop_volt
1367 = vreg->corner[i].floor_volt;
1368 }
1369 }
1370
1371free_floor_adjust:
1372 kfree(floor_range);
1373
1374enforce_monotonicity:
1375 /* Ensure that floor voltages increase monotonically. */
1376 for (i = 1; i < vreg->corner_count; i++) {
1377 if (vreg->corner[i].floor_volt
1378 < vreg->corner[i - 1].floor_volt) {
1379 cpr3_debug(vreg, "corner %d floor voltage=%d uV < corner %d voltage=%d uV; overriding: corner %d voltage=%d\n",
1380 i, vreg->corner[i].floor_volt,
1381 i - 1, vreg->corner[i - 1].floor_volt,
1382 i, vreg->corner[i - 1].floor_volt);
1383 vreg->corner[i].floor_volt
1384 = vreg->corner[i - 1].floor_volt;
1385
1386 if (vreg->corner[i].open_loop_volt
1387 < vreg->corner[i].floor_volt)
1388 vreg->corner[i].open_loop_volt
1389 = vreg->corner[i].floor_volt;
1390 if (vreg->corner[i].ceiling_volt
1391 < vreg->corner[i].floor_volt)
1392 vreg->corner[i].ceiling_volt
1393 = vreg->corner[i].floor_volt;
1394 }
1395 }
1396
1397 return rc;
1398}
1399
1400/**
1401 * cpr3_print_quots() - print CPR target quotients into the kernel log for
1402 * debugging purposes
1403 * @vreg: Pointer to the CPR3 regulator
1404 *
1405 * Return: none
1406 */
1407void cpr3_print_quots(struct cpr3_regulator *vreg)
1408{
1409 int i, j, pos;
1410 size_t buflen;
1411 char *buf;
1412
1413 buflen = sizeof(*buf) * CPR3_RO_COUNT * (MAX_CHARS_PER_INT + 2);
1414 buf = kzalloc(buflen, GFP_KERNEL);
1415 if (!buf)
1416 return;
1417
1418 for (i = 0; i < vreg->corner_count; i++) {
1419 for (j = 0, pos = 0; j < CPR3_RO_COUNT; j++)
1420 pos += scnprintf(buf + pos, buflen - pos, " %u",
1421 vreg->corner[i].target_quot[j]);
1422 cpr3_debug(vreg, "target quots[%2d]:%s\n", i, buf);
1423 }
1424
1425 kfree(buf);
1426}
1427
1428/**
1429 * cpr3_adjust_fused_open_loop_voltages() - adjust the fused open-loop voltages
1430 * for each fuse corner according to device tree values
1431 * @vreg: Pointer to the CPR3 regulator
1432 * @fuse_volt: Pointer to an array of the fused open-loop voltage
1433 * values
1434 *
1435 * Voltage values in fuse_volt are modified in place.
1436 *
1437 * Return: 0 on success, errno on failure
1438 */
1439int cpr3_adjust_fused_open_loop_voltages(struct cpr3_regulator *vreg,
1440 int *fuse_volt)
1441{
1442 int i, rc, prev_volt;
1443 int *volt_adjust;
1444
1445 if (!of_find_property(vreg->of_node,
1446 "qcom,cpr-open-loop-voltage-fuse-adjustment", NULL)) {
1447 /* No adjustment required. */
1448 return 0;
1449 }
1450
1451 volt_adjust = kcalloc(vreg->fuse_corner_count, sizeof(*volt_adjust),
1452 GFP_KERNEL);
1453 if (!volt_adjust)
1454 return -ENOMEM;
1455
1456 rc = cpr3_parse_array_property(vreg,
1457 "qcom,cpr-open-loop-voltage-fuse-adjustment",
1458 vreg->fuse_corner_count, volt_adjust);
1459 if (rc) {
1460 cpr3_err(vreg, "could not load open-loop fused voltage adjustments, rc=%d\n",
1461 rc);
1462 goto done;
1463 }
1464
1465 for (i = 0; i < vreg->fuse_corner_count; i++) {
1466 if (volt_adjust[i]) {
1467 prev_volt = fuse_volt[i];
1468 fuse_volt[i] += volt_adjust[i];
1469 cpr3_debug(vreg, "adjusted fuse corner %d open-loop voltage: %d --> %d uV\n",
1470 i, prev_volt, fuse_volt[i]);
1471 }
1472 }
1473
1474done:
1475 kfree(volt_adjust);
1476 return rc;
1477}
1478
1479/**
1480 * cpr3_adjust_open_loop_voltages() - adjust the open-loop voltages for each
1481 * corner according to device tree values
1482 * @vreg: Pointer to the CPR3 regulator
1483 *
1484 * Return: 0 on success, errno on failure
1485 */
1486int cpr3_adjust_open_loop_voltages(struct cpr3_regulator *vreg)
1487{
1488 int i, rc, prev_volt, min_volt;
1489 int *volt_adjust, *volt_diff;
1490
1491 if (!of_find_property(vreg->of_node,
1492 "qcom,cpr-open-loop-voltage-adjustment", NULL)) {
1493 /* No adjustment required. */
1494 return 0;
1495 }
1496
1497 volt_adjust = kcalloc(vreg->corner_count, sizeof(*volt_adjust),
1498 GFP_KERNEL);
1499 volt_diff = kcalloc(vreg->corner_count, sizeof(*volt_diff), GFP_KERNEL);
1500 if (!volt_adjust || !volt_diff) {
1501 rc = -ENOMEM;
1502 goto done;
1503 }
1504
1505 rc = cpr3_parse_corner_array_property(vreg,
1506 "qcom,cpr-open-loop-voltage-adjustment", 1, volt_adjust);
1507 if (rc) {
1508 cpr3_err(vreg, "could not load open-loop voltage adjustments, rc=%d\n",
1509 rc);
1510 goto done;
1511 }
1512
1513 for (i = 0; i < vreg->corner_count; i++) {
1514 if (volt_adjust[i]) {
1515 prev_volt = vreg->corner[i].open_loop_volt;
1516 vreg->corner[i].open_loop_volt += volt_adjust[i];
1517 cpr3_debug(vreg, "adjusted corner %d open-loop voltage: %d --> %d uV\n",
1518 i, prev_volt, vreg->corner[i].open_loop_volt);
1519 }
1520 }
1521
1522 if (of_find_property(vreg->of_node,
1523 "qcom,cpr-open-loop-voltage-min-diff", NULL)) {
1524 rc = cpr3_parse_corner_array_property(vreg,
1525 "qcom,cpr-open-loop-voltage-min-diff", 1, volt_diff);
1526 if (rc) {
1527 cpr3_err(vreg, "could not load minimum open-loop voltage differences, rc=%d\n",
1528 rc);
1529 goto done;
1530 }
1531 }
1532
1533 /*
1534 * Ensure that open-loop voltages increase monotonically with respect
1535 * to configurable minimum allowed differences.
1536 */
1537 for (i = 1; i < vreg->corner_count; i++) {
1538 min_volt = vreg->corner[i - 1].open_loop_volt + volt_diff[i];
1539 if (vreg->corner[i].open_loop_volt < min_volt) {
1540 cpr3_debug(vreg, "adjusted corner %d open-loop voltage=%d uV < corner %d voltage=%d uV + min diff=%d uV; overriding: corner %d voltage=%d\n",
1541 i, vreg->corner[i].open_loop_volt,
1542 i - 1, vreg->corner[i - 1].open_loop_volt,
1543 volt_diff[i], i, min_volt);
1544 vreg->corner[i].open_loop_volt = min_volt;
1545 }
1546 }
1547
1548done:
1549 kfree(volt_diff);
1550 kfree(volt_adjust);
1551 return rc;
1552}
1553
1554/**
1555 * cpr3_quot_adjustment() - returns the quotient adjustment value resulting from
1556 * the specified voltage adjustment and RO scaling factor
1557 * @ro_scale: The CPR ring oscillator (RO) scaling factor with units
1558 * of QUOT/V
1559 * @volt_adjust: The amount to adjust the voltage by in units of
1560 * microvolts. This value may be positive or negative.
1561 */
1562int cpr3_quot_adjustment(int ro_scale, int volt_adjust)
1563{
1564 unsigned long long temp;
1565 int quot_adjust;
1566 int sign = 1;
1567
1568 if (ro_scale < 0) {
1569 sign = -sign;
1570 ro_scale = -ro_scale;
1571 }
1572
1573 if (volt_adjust < 0) {
1574 sign = -sign;
1575 volt_adjust = -volt_adjust;
1576 }
1577
1578 temp = (unsigned long long)ro_scale * (unsigned long long)volt_adjust;
1579 do_div(temp, 1000000);
1580
1581 quot_adjust = temp;
1582 quot_adjust *= sign;
1583
1584 return quot_adjust;
1585}
1586
1587/**
1588 * cpr3_voltage_adjustment() - returns the voltage adjustment value resulting
1589 * from the specified quotient adjustment and RO scaling factor
1590 * @ro_scale: The CPR ring oscillator (RO) scaling factor with units
1591 * of QUOT/V
1592 * @quot_adjust: The amount to adjust the quotient by in units of
1593 * QUOT. This value may be positive or negative.
1594 */
1595int cpr3_voltage_adjustment(int ro_scale, int quot_adjust)
1596{
1597 unsigned long long temp;
1598 int volt_adjust;
1599 int sign = 1;
1600
1601 if (ro_scale < 0) {
1602 sign = -sign;
1603 ro_scale = -ro_scale;
1604 }
1605
1606 if (quot_adjust < 0) {
1607 sign = -sign;
1608 quot_adjust = -quot_adjust;
1609 }
1610
1611 if (ro_scale == 0)
1612 return 0;
1613
1614 temp = (unsigned long long)quot_adjust * 1000000;
1615 do_div(temp, ro_scale);
1616
1617 volt_adjust = temp;
1618 volt_adjust *= sign;
1619
1620 return volt_adjust;
1621}
1622
1623/**
1624 * cpr3_parse_closed_loop_voltage_adjustments() - load per-fuse-corner and
1625 * per-corner closed-loop adjustment values from device tree
1626 * @vreg: Pointer to the CPR3 regulator
1627 * @ro_sel: Array of ring oscillator values selected for each
1628 * fuse corner
1629 * @volt_adjust: Pointer to array which will be filled with the
1630 * per-corner closed-loop adjustment voltages
1631 * @volt_adjust_fuse: Pointer to array which will be filled with the
1632 * per-fuse-corner closed-loop adjustment voltages
1633 * @ro_scale: Pointer to array which will be filled with the
1634 * per-fuse-corner RO scaling factor values with units of
1635 * QUOT/V
1636 *
1637 * Return: 0 on success, errno on failure
1638 */
1639int cpr3_parse_closed_loop_voltage_adjustments(
1640 struct cpr3_regulator *vreg, u64 *ro_sel,
1641 int *volt_adjust, int *volt_adjust_fuse, int *ro_scale)
1642{
1643 int i, rc;
1644 u32 *ro_all_scale;
1645
1646 if (!of_find_property(vreg->of_node,
1647 "qcom,cpr-closed-loop-voltage-adjustment", NULL)
1648 && !of_find_property(vreg->of_node,
1649 "qcom,cpr-closed-loop-voltage-fuse-adjustment", NULL)
1650 && !vreg->aging_allowed) {
1651 /* No adjustment required. */
1652 return 0;
1653 } else if (!of_find_property(vreg->of_node,
1654 "qcom,cpr-ro-scaling-factor", NULL)) {
1655 cpr3_err(vreg, "qcom,cpr-ro-scaling-factor is required for closed-loop voltage adjustment, but is missing\n");
1656 return -EINVAL;
1657 }
1658
1659 ro_all_scale = kcalloc(vreg->fuse_corner_count * CPR3_RO_COUNT,
1660 sizeof(*ro_all_scale), GFP_KERNEL);
1661 if (!ro_all_scale)
1662 return -ENOMEM;
1663
1664 rc = cpr3_parse_array_property(vreg, "qcom,cpr-ro-scaling-factor",
1665 vreg->fuse_corner_count * CPR3_RO_COUNT, ro_all_scale);
1666 if (rc) {
1667 cpr3_err(vreg, "could not load RO scaling factors, rc=%d\n",
1668 rc);
1669 goto done;
1670 }
1671
1672 for (i = 0; i < vreg->fuse_corner_count; i++)
1673 ro_scale[i] = ro_all_scale[i * CPR3_RO_COUNT + ro_sel[i]];
1674
1675 for (i = 0; i < vreg->corner_count; i++)
1676 memcpy(vreg->corner[i].ro_scale,
1677 &ro_all_scale[vreg->corner[i].cpr_fuse_corner * CPR3_RO_COUNT],
1678 sizeof(*ro_all_scale) * CPR3_RO_COUNT);
1679
1680 if (of_find_property(vreg->of_node,
1681 "qcom,cpr-closed-loop-voltage-fuse-adjustment", NULL)) {
1682 rc = cpr3_parse_array_property(vreg,
1683 "qcom,cpr-closed-loop-voltage-fuse-adjustment",
1684 vreg->fuse_corner_count, volt_adjust_fuse);
1685 if (rc) {
1686 cpr3_err(vreg, "could not load closed-loop fused voltage adjustments, rc=%d\n",
1687 rc);
1688 goto done;
1689 }
1690 }
1691
1692 if (of_find_property(vreg->of_node,
1693 "qcom,cpr-closed-loop-voltage-adjustment", NULL)) {
1694 rc = cpr3_parse_corner_array_property(vreg,
1695 "qcom,cpr-closed-loop-voltage-adjustment",
1696 1, volt_adjust);
1697 if (rc) {
1698 cpr3_err(vreg, "could not load closed-loop voltage adjustments, rc=%d\n",
1699 rc);
1700 goto done;
1701 }
1702 }
1703
1704done:
1705 kfree(ro_all_scale);
1706 return rc;
1707}
1708
1709/**
1710 * cpr3_apm_init() - initialize APM data for a CPR3 controller
1711 * @ctrl: Pointer to the CPR3 controller
1712 *
1713 * This function loads memory array power mux (APM) data from device tree
1714 * if it is present and requests a handle to the appropriate APM controller
1715 * device.
1716 *
1717 * Return: 0 on success, errno on failure
1718 */
1719int cpr3_apm_init(struct cpr3_controller *ctrl)
1720{
1721 struct device_node *node = ctrl->dev->of_node;
1722 int rc;
1723
1724 if (!of_find_property(node, "qcom,apm-ctrl", NULL)) {
1725 /* No APM used */
1726 return 0;
1727 }
1728
1729 ctrl->apm = msm_apm_ctrl_dev_get(ctrl->dev);
1730 if (IS_ERR(ctrl->apm)) {
1731 rc = PTR_ERR(ctrl->apm);
1732 if (rc != -EPROBE_DEFER)
1733 cpr3_err(ctrl, "APM get failed, rc=%d\n", rc);
1734 return rc;
1735 }
1736
1737 rc = of_property_read_u32(node, "qcom,apm-threshold-voltage",
1738 &ctrl->apm_threshold_volt);
1739 if (rc) {
1740 cpr3_err(ctrl, "error reading qcom,apm-threshold-voltage, rc=%d\n",
1741 rc);
1742 return rc;
1743 }
1744 ctrl->apm_threshold_volt
1745 = CPR3_ROUND(ctrl->apm_threshold_volt, ctrl->step_volt);
1746
1747 /* No error check since this is an optional property. */
1748 of_property_read_u32(node, "qcom,apm-hysteresis-voltage",
1749 &ctrl->apm_adj_volt);
1750 ctrl->apm_adj_volt = CPR3_ROUND(ctrl->apm_adj_volt, ctrl->step_volt);
1751
1752 ctrl->apm_high_supply = MSM_APM_SUPPLY_APCC;
1753 ctrl->apm_low_supply = MSM_APM_SUPPLY_MX;
1754
1755 return 0;
1756}
1757
1758/**
1759 * cpr3_mem_acc_init() - initialize mem-acc regulator data for
1760 * a CPR3 regulator
1761 * @ctrl: Pointer to the CPR3 controller
1762 *
1763 * Return: 0 on success, errno on failure
1764 */
1765int cpr3_mem_acc_init(struct cpr3_regulator *vreg)
1766{
1767 struct cpr3_controller *ctrl = vreg->thread->ctrl;
1768 u32 *temp;
1769 int i, rc;
1770
1771 if (!ctrl->mem_acc_regulator) {
1772 cpr3_info(ctrl, "not using memory accelerator regulator\n");
1773 return 0;
1774 }
1775
1776 temp = kcalloc(vreg->corner_count, sizeof(*temp), GFP_KERNEL);
1777 if (!temp)
1778 return -ENOMEM;
1779
1780 rc = cpr3_parse_corner_array_property(vreg, "qcom,mem-acc-voltage",
1781 1, temp);
1782 if (rc) {
1783 cpr3_err(ctrl, "could not load mem-acc corners, rc=%d\n", rc);
1784 } else {
1785 for (i = 0; i < vreg->corner_count; i++)
1786 vreg->corner[i].mem_acc_volt = temp[i];
1787 }
1788
1789 kfree(temp);
1790 return rc;
1791}
1792
1793/**
1794 * cpr4_load_core_and_temp_adj() - parse amount of voltage adjustment for
1795 * per-online-core and per-temperature voltage adjustment for a
1796 * given corner or corner band from device tree.
1797 * @vreg: Pointer to the CPR3 regulator
1798 * @num: Corner number or corner band number
1799 * @use_corner_band: Boolean indicating if the CPR3 regulator supports
1800 * adjustments per corner band
1801 *
1802 * Return: 0 on success, errno on failure
1803 */
1804static int cpr4_load_core_and_temp_adj(struct cpr3_regulator *vreg,
1805 int num, bool use_corner_band)
1806{
1807 struct cpr3_controller *ctrl = vreg->thread->ctrl;
1808 struct cpr4_sdelta *sdelta;
1809 int sdelta_size, i, j, pos, rc = 0;
1810 char str[75];
1811 size_t buflen;
1812 char *buf;
1813
1814 sdelta = use_corner_band ? vreg->corner_band[num].sdelta :
1815 vreg->corner[num].sdelta;
1816
1817 if (!sdelta->allow_core_count_adj && !sdelta->allow_temp_adj) {
1818 /* corner doesn't need sdelta table */
1819 sdelta->max_core_count = 0;
1820 sdelta->temp_band_count = 0;
1821 return rc;
1822 }
1823
1824 sdelta_size = sdelta->max_core_count * sdelta->temp_band_count;
1825 snprintf(str, sizeof(str), use_corner_band ?
1826 "corner_band=%d core_config_count=%d temp_band_count=%d sdelta_size=%d\n"
1827 : "corner=%d core_config_count=%d temp_band_count=%d sdelta_size=%d\n",
1828 num, sdelta->max_core_count,
1829 sdelta->temp_band_count, sdelta_size);
1830
1831 cpr3_debug(vreg, "%s", str);
1832
1833 sdelta->table = devm_kcalloc(ctrl->dev, sdelta_size,
1834 sizeof(*sdelta->table), GFP_KERNEL);
1835 if (!sdelta->table)
1836 return -ENOMEM;
1837
1838 snprintf(str, sizeof(str), use_corner_band ?
1839 "qcom,cpr-corner-band%d-temp-core-voltage-adjustment" :
1840 "qcom,cpr-corner%d-temp-core-voltage-adjustment",
1841 num + CPR3_CORNER_OFFSET);
1842
1843 rc = cpr3_parse_array_property(vreg, str, sdelta_size,
1844 sdelta->table);
1845 if (rc) {
1846 cpr3_err(vreg, "could not load %s, rc=%d\n", str, rc);
1847 return rc;
1848 }
1849
1850 /*
1851 * Convert sdelta margins from uV to PMIC steps and apply negation to
1852 * follow the SDELTA register semantics.
1853 */
1854 for (i = 0; i < sdelta_size; i++)
1855 sdelta->table[i] = -(sdelta->table[i] / ctrl->step_volt);
1856
1857 buflen = sizeof(*buf) * sdelta_size * (MAX_CHARS_PER_INT + 2);
1858 buf = kzalloc(buflen, GFP_KERNEL);
1859 if (!buf)
1860 return rc;
1861
1862 for (i = 0; i < sdelta->max_core_count; i++) {
1863 for (j = 0, pos = 0; j < sdelta->temp_band_count; j++)
1864 pos += scnprintf(buf + pos, buflen - pos, " %u",
1865 sdelta->table[i * sdelta->temp_band_count + j]);
1866 cpr3_debug(vreg, "sdelta[%d]:%s\n", i, buf);
1867 }
1868
1869 kfree(buf);
1870 return rc;
1871}
1872
1873/**
1874 * cpr4_parse_core_count_temp_voltage_adj() - parse configuration data for
1875 * per-online-core and per-temperature voltage adjustment for
1876 * a CPR3 regulator from device tree.
1877 * @vreg: Pointer to the CPR3 regulator
1878 * @use_corner_band: Boolean indicating if the CPR3 regulator supports
1879 * adjustments per corner band
1880 *
1881 * This function supports parsing of per-online-core and per-temperature
1882 * adjustments per corner or per corner band. CPR controllers which support
1883 * corner bands apply the same adjustments to all corners within a corner band.
1884 *
1885 * Return: 0 on success, errno on failure
1886 */
1887int cpr4_parse_core_count_temp_voltage_adj(
1888 struct cpr3_regulator *vreg, bool use_corner_band)
1889{
1890 struct cpr3_controller *ctrl = vreg->thread->ctrl;
1891 struct device_node *node = vreg->of_node;
1892 struct cpr3_corner *corner;
1893 struct cpr4_sdelta *sdelta;
1894 int i, sdelta_table_count, rc = 0;
1895 int *allow_core_count_adj = NULL, *allow_temp_adj = NULL;
1896 char prop_str[75];
1897
1898 if (of_find_property(node, use_corner_band ?
1899 "qcom,corner-band-allow-temp-adjustment"
1900 : "qcom,corner-allow-temp-adjustment", NULL)) {
1901 if (!ctrl->allow_temp_adj) {
1902 cpr3_err(ctrl, "Temperature adjustment configurations missing\n");
1903 return -EINVAL;
1904 }
1905
1906 vreg->allow_temp_adj = true;
1907 }
1908
1909 if (of_find_property(node, use_corner_band ?
1910 "qcom,corner-band-allow-core-count-adjustment"
1911 : "qcom,corner-allow-core-count-adjustment",
1912 NULL)) {
1913 rc = of_property_read_u32(node, "qcom,max-core-count",
1914 &vreg->max_core_count);
1915 if (rc) {
1916 cpr3_err(vreg, "error reading qcom,max-core-count, rc=%d\n",
1917 rc);
1918 return -EINVAL;
1919 }
1920
1921 vreg->allow_core_count_adj = true;
1922 ctrl->allow_core_count_adj = true;
1923 }
1924
1925 if (!vreg->allow_temp_adj && !vreg->allow_core_count_adj) {
1926 /*
1927 * Both per-online-core and temperature based adjustments are
1928 * disabled for this regulator.
1929 */
1930 return 0;
1931 } else if (!vreg->allow_core_count_adj) {
1932 /*
1933 * Only per-temperature voltage adjusments are allowed.
1934 * Keep max core count value as 1 to allocate SDELTA.
1935 */
1936 vreg->max_core_count = 1;
1937 }
1938
1939 if (vreg->allow_core_count_adj) {
1940 allow_core_count_adj = kcalloc(vreg->corner_count,
1941 sizeof(*allow_core_count_adj),
1942 GFP_KERNEL);
1943 if (!allow_core_count_adj)
1944 return -ENOMEM;
1945
1946 snprintf(prop_str, sizeof(prop_str), use_corner_band ?
1947 "qcom,corner-band-allow-core-count-adjustment" :
1948 "qcom,corner-allow-core-count-adjustment");
1949
1950 rc = use_corner_band ?
1951 cpr3_parse_corner_band_array_property(vreg, prop_str,
1952 1, allow_core_count_adj) :
1953 cpr3_parse_corner_array_property(vreg, prop_str,
1954 1, allow_core_count_adj);
1955 if (rc) {
1956 cpr3_err(vreg, "error reading %s, rc=%d\n", prop_str,
1957 rc);
1958 goto done;
1959 }
1960 }
1961
1962 if (vreg->allow_temp_adj) {
1963 allow_temp_adj = kcalloc(vreg->corner_count,
1964 sizeof(*allow_temp_adj), GFP_KERNEL);
1965 if (!allow_temp_adj) {
1966 rc = -ENOMEM;
1967 goto done;
1968 }
1969
1970 snprintf(prop_str, sizeof(prop_str), use_corner_band ?
1971 "qcom,corner-band-allow-temp-adjustment" :
1972 "qcom,corner-allow-temp-adjustment");
1973
1974 rc = use_corner_band ?
1975 cpr3_parse_corner_band_array_property(vreg, prop_str,
1976 1, allow_temp_adj) :
1977 cpr3_parse_corner_array_property(vreg, prop_str,
1978 1, allow_temp_adj);
1979 if (rc) {
1980 cpr3_err(vreg, "error reading %s, rc=%d\n", prop_str,
1981 rc);
1982 goto done;
1983 }
1984 }
1985
1986 sdelta_table_count = use_corner_band ? vreg->corner_band_count :
1987 vreg->corner_count;
1988
1989 for (i = 0; i < sdelta_table_count; i++) {
1990 sdelta = devm_kzalloc(ctrl->dev, sizeof(*corner->sdelta),
1991 GFP_KERNEL);
1992 if (!sdelta) {
1993 rc = -ENOMEM;
1994 goto done;
1995 }
1996
1997 if (allow_core_count_adj)
1998 sdelta->allow_core_count_adj = allow_core_count_adj[i];
1999 if (allow_temp_adj)
2000 sdelta->allow_temp_adj = allow_temp_adj[i];
2001 sdelta->max_core_count = vreg->max_core_count;
2002 sdelta->temp_band_count = ctrl->temp_band_count;
2003
2004 if (use_corner_band)
2005 vreg->corner_band[i].sdelta = sdelta;
2006 else
2007 vreg->corner[i].sdelta = sdelta;
2008
2009 rc = cpr4_load_core_and_temp_adj(vreg, i, use_corner_band);
2010 if (rc) {
2011 cpr3_err(vreg, "corner/band %d core and temp adjustment loading failed, rc=%d\n",
2012 i, rc);
2013 goto done;
2014 }
2015 }
2016
2017done:
2018 kfree(allow_core_count_adj);
2019 kfree(allow_temp_adj);
2020
2021 return rc;
2022}
2023
2024/**
2025 * cprh_adjust_voltages_for_apm() - adjust per-corner floor and ceiling voltages
2026 * so that they do not overlap the APM threshold voltage.
2027 * @vreg: Pointer to the CPR3 regulator
2028 *
2029 * The memory array power mux (APM) must be configured for a specific supply
2030 * based upon where the VDD voltage lies with respect to the APM threshold
2031 * voltage. When using CPR hardware closed-loop, the voltage may vary anywhere
2032 * between the floor and ceiling voltage without software notification.
2033 * Therefore, it is required that the floor to ceiling range for every corner
2034 * not intersect the APM threshold voltage. This function adjusts the floor to
2035 * ceiling range for each corner which violates this requirement.
2036 *
2037 * The following algorithm is applied:
2038 * if floor < threshold <= ceiling:
2039 * if open_loop >= threshold, then floor = threshold - adj
2040 * else ceiling = threshold - step
2041 * where:
2042 * adj = APM hysteresis voltage established to minimize the number of
2043 * corners with artificially increased floor voltages
2044 * step = voltage in microvolts of a single step of the VDD supply
2045 *
2046 * The open-loop voltage is also bounded by the new floor or ceiling value as
2047 * needed.
2048 *
2049 * Return: none
2050 */
2051void cprh_adjust_voltages_for_apm(struct cpr3_regulator *vreg)
2052{
2053 struct cpr3_controller *ctrl = vreg->thread->ctrl;
2054 struct cpr3_corner *corner;
2055 int i, adj, threshold, prev_ceiling, prev_floor, prev_open_loop;
2056
2057 if (!ctrl->apm_threshold_volt) {
2058 /* APM not being used. */
2059 return;
2060 }
2061
2062 ctrl->apm_threshold_volt = CPR3_ROUND(ctrl->apm_threshold_volt,
2063 ctrl->step_volt);
2064 ctrl->apm_adj_volt = CPR3_ROUND(ctrl->apm_adj_volt, ctrl->step_volt);
2065
2066 threshold = ctrl->apm_threshold_volt;
2067 adj = ctrl->apm_adj_volt;
2068
2069 for (i = 0; i < vreg->corner_count; i++) {
2070 corner = &vreg->corner[i];
2071
2072 if (threshold <= corner->floor_volt
2073 || threshold > corner->ceiling_volt)
2074 continue;
2075
2076 prev_floor = corner->floor_volt;
2077 prev_ceiling = corner->ceiling_volt;
2078 prev_open_loop = corner->open_loop_volt;
2079
2080 if (corner->open_loop_volt >= threshold) {
2081 corner->floor_volt = max(corner->floor_volt,
2082 threshold - adj);
2083 if (corner->open_loop_volt < corner->floor_volt)
2084 corner->open_loop_volt = corner->floor_volt;
2085 } else {
2086 corner->ceiling_volt = threshold - ctrl->step_volt;
2087 }
2088
2089 if (corner->floor_volt != prev_floor
2090 || corner->ceiling_volt != prev_ceiling
2091 || corner->open_loop_volt != prev_open_loop)
2092 cpr3_debug(vreg, "APM threshold=%d, APM adj=%d changed corner %d voltages; prev: floor=%d, ceiling=%d, open-loop=%d; new: floor=%d, ceiling=%d, open-loop=%d\n",
2093 threshold, adj, i, prev_floor, prev_ceiling,
2094 prev_open_loop, corner->floor_volt,
2095 corner->ceiling_volt, corner->open_loop_volt);
2096 }
2097}
2098
2099/**
2100 * cprh_adjust_voltages_for_mem_acc() - adjust per-corner floor and ceiling
2101 * voltages so that they do not intersect the MEM ACC threshold
2102 * voltage
2103 * @vreg: Pointer to the CPR3 regulator
2104 *
2105 * The following algorithm is applied:
2106 * if floor < threshold <= ceiling:
2107 * if open_loop >= threshold, then floor = threshold
2108 * else ceiling = threshold - step
2109 * where:
2110 * step = voltage in microvolts of a single step of the VDD supply
2111 *
2112 * The open-loop voltage is also bounded by the new floor or ceiling value as
2113 * needed.
2114 *
2115 * Return: none
2116 */
2117void cprh_adjust_voltages_for_mem_acc(struct cpr3_regulator *vreg)
2118{
2119 struct cpr3_controller *ctrl = vreg->thread->ctrl;
2120 struct cpr3_corner *corner;
2121 int i, threshold, prev_ceiling, prev_floor, prev_open_loop;
2122
2123 if (!ctrl->mem_acc_threshold_volt) {
2124 /* MEM ACC not being used. */
2125 return;
2126 }
2127
2128 ctrl->mem_acc_threshold_volt = CPR3_ROUND(ctrl->mem_acc_threshold_volt,
2129 ctrl->step_volt);
2130
2131 threshold = ctrl->mem_acc_threshold_volt;
2132
2133 for (i = 0; i < vreg->corner_count; i++) {
2134 corner = &vreg->corner[i];
2135
2136 if (threshold <= corner->floor_volt
2137 || threshold > corner->ceiling_volt)
2138 continue;
2139
2140 prev_floor = corner->floor_volt;
2141 prev_ceiling = corner->ceiling_volt;
2142 prev_open_loop = corner->open_loop_volt;
2143
2144 if (corner->open_loop_volt >= threshold) {
2145 corner->floor_volt = max(corner->floor_volt, threshold);
2146 if (corner->open_loop_volt < corner->floor_volt)
2147 corner->open_loop_volt = corner->floor_volt;
2148 } else {
2149 corner->ceiling_volt = threshold - ctrl->step_volt;
2150 }
2151
2152 if (corner->floor_volt != prev_floor
2153 || corner->ceiling_volt != prev_ceiling
2154 || corner->open_loop_volt != prev_open_loop)
2155 cpr3_debug(vreg, "MEM ACC threshold=%d changed corner %d voltages; prev: floor=%d, ceiling=%d, open-loop=%d; new: floor=%d, ceiling=%d, open-loop=%d\n",
2156 threshold, i, prev_floor, prev_ceiling,
2157 prev_open_loop, corner->floor_volt,
2158 corner->ceiling_volt, corner->open_loop_volt);
2159 }
2160}
2161
2162/**
2163 * cpr3_apply_closed_loop_offset_voltages() - modify the closed-loop voltage
2164 * adjustments by the amounts that are needed for this
2165 * fuse combo
2166 * @vreg: Pointer to the CPR3 regulator
2167 * @volt_adjust: Array of closed-loop voltage adjustment values of length
2168 * vreg->corner_count which is further adjusted based upon
2169 * offset voltage fuse values.
2170 * @fuse_volt_adjust: Fused closed-loop voltage adjustment values of length
2171 * vreg->fuse_corner_count.
2172 *
2173 * Return: 0 on success, errno on failure
2174 */
2175static int cpr3_apply_closed_loop_offset_voltages(struct cpr3_regulator *vreg,
2176 int *volt_adjust, int *fuse_volt_adjust)
2177{
2178 u32 *corner_map;
2179 int rc = 0, i;
2180
2181 if (!of_find_property(vreg->of_node,
2182 "qcom,cpr-fused-closed-loop-voltage-adjustment-map", NULL)) {
2183 /* No closed-loop offset required. */
2184 return 0;
2185 }
2186
2187 corner_map = kcalloc(vreg->corner_count, sizeof(*corner_map),
2188 GFP_KERNEL);
2189 if (!corner_map)
2190 return -ENOMEM;
2191
2192 rc = cpr3_parse_corner_array_property(vreg,
2193 "qcom,cpr-fused-closed-loop-voltage-adjustment-map",
2194 1, corner_map);
2195 if (rc)
2196 goto done;
2197
2198 for (i = 0; i < vreg->corner_count; i++) {
2199 if (corner_map[i] == 0) {
2200 continue;
2201 } else if (corner_map[i] > vreg->fuse_corner_count) {
2202 cpr3_err(vreg, "corner %d mapped to invalid fuse corner: %u\n",
2203 i, corner_map[i]);
2204 rc = -EINVAL;
2205 goto done;
2206 }
2207
2208 volt_adjust[i] += fuse_volt_adjust[corner_map[i] - 1];
2209 }
2210
2211done:
2212 kfree(corner_map);
2213 return rc;
2214}
2215
2216/**
2217 * cpr3_enforce_inc_quotient_monotonicity() - Ensure that target quotients
2218 * increase monotonically from lower to higher corners
2219 * @vreg: Pointer to the CPR3 regulator
2220 *
2221 * Return: 0 on success, errno on failure
2222 */
2223static void cpr3_enforce_inc_quotient_monotonicity(struct cpr3_regulator *vreg)
2224{
2225 int i, j;
2226
2227 for (i = 1; i < vreg->corner_count; i++) {
2228 for (j = 0; j < CPR3_RO_COUNT; j++) {
2229 if (vreg->corner[i].target_quot[j]
2230 && vreg->corner[i].target_quot[j]
2231 < vreg->corner[i - 1].target_quot[j]) {
2232 cpr3_debug(vreg, "corner %d RO%u target quot=%u < corner %d RO%u target quot=%u; overriding: corner %d RO%u target quot=%u\n",
2233 i, j,
2234 vreg->corner[i].target_quot[j],
2235 i - 1, j,
2236 vreg->corner[i - 1].target_quot[j],
2237 i, j,
2238 vreg->corner[i - 1].target_quot[j]);
2239 vreg->corner[i].target_quot[j]
2240 = vreg->corner[i - 1].target_quot[j];
2241 }
2242 }
2243 }
2244}
2245
2246/**
2247 * cpr3_enforce_dec_quotient_monotonicity() - Ensure that target quotients
2248 * decrease monotonically from higher to lower corners
2249 * @vreg: Pointer to the CPR3 regulator
2250 *
2251 * Return: 0 on success, errno on failure
2252 */
2253static void cpr3_enforce_dec_quotient_monotonicity(struct cpr3_regulator *vreg)
2254{
2255 int i, j;
2256
2257 for (i = vreg->corner_count - 2; i >= 0; i--) {
2258 for (j = 0; j < CPR3_RO_COUNT; j++) {
2259 if (vreg->corner[i + 1].target_quot[j]
2260 && vreg->corner[i].target_quot[j]
2261 > vreg->corner[i + 1].target_quot[j]) {
2262 cpr3_debug(vreg, "corner %d RO%u target quot=%u > corner %d RO%u target quot=%u; overriding: corner %d RO%u target quot=%u\n",
2263 i, j,
2264 vreg->corner[i].target_quot[j],
2265 i + 1, j,
2266 vreg->corner[i + 1].target_quot[j],
2267 i, j,
2268 vreg->corner[i + 1].target_quot[j]);
2269 vreg->corner[i].target_quot[j]
2270 = vreg->corner[i + 1].target_quot[j];
2271 }
2272 }
2273 }
2274}
2275
2276/**
2277 * _cpr3_adjust_target_quotients() - adjust the target quotients for each
2278 * corner of the regulator according to input adjustment and
2279 * scaling arrays
2280 * @vreg: Pointer to the CPR3 regulator
2281 * @volt_adjust: Pointer to an array of closed-loop voltage adjustments
2282 * with units of microvolts. The array must have
2283 * vreg->corner_count number of elements.
2284 * @ro_scale: Pointer to a flattened 2D array of RO scaling factors.
2285 * The array must have an inner dimension of CPR3_RO_COUNT
2286 * and an outer dimension of vreg->corner_count
2287 * @label: Null terminated string providing a label for the type
2288 * of adjustment.
2289 *
2290 * Return: true if any corners received a positive voltage adjustment (> 0),
2291 * else false
2292 */
2293static bool _cpr3_adjust_target_quotients(struct cpr3_regulator *vreg,
2294 const int *volt_adjust, const int *ro_scale, const char *label)
2295{
2296 int i, j, quot_adjust;
2297 bool is_increasing = false;
2298 u32 prev_quot;
2299
2300 for (i = 0; i < vreg->corner_count; i++) {
2301 for (j = 0; j < CPR3_RO_COUNT; j++) {
2302 if (vreg->corner[i].target_quot[j]) {
2303 quot_adjust = cpr3_quot_adjustment(
2304 ro_scale[i * CPR3_RO_COUNT + j],
2305 volt_adjust[i]);
2306 if (quot_adjust) {
2307 prev_quot = vreg->corner[i].
2308 target_quot[j];
2309 vreg->corner[i].target_quot[j]
2310 += quot_adjust;
2311 cpr3_debug(vreg, "adjusted corner %d RO%d target quot %s: %u --> %u (%d uV)\n",
2312 i, j, label, prev_quot,
2313 vreg->corner[i].target_quot[j],
2314 volt_adjust[i]);
2315 }
2316 }
2317 }
2318 if (volt_adjust[i] > 0)
2319 is_increasing = true;
2320 }
2321
2322 return is_increasing;
2323}
2324
2325/**
2326 * cpr3_adjust_target_quotients() - adjust the target quotients for each
2327 * corner according to device tree values and fuse values
2328 * @vreg: Pointer to the CPR3 regulator
2329 * @fuse_volt_adjust: Fused closed-loop voltage adjustment values of length
2330 * vreg->fuse_corner_count. This parameter could be null
2331 * pointer when no fused adjustments are needed.
2332 *
2333 * Return: 0 on success, errno on failure
2334 */
2335int cpr3_adjust_target_quotients(struct cpr3_regulator *vreg,
2336 int *fuse_volt_adjust)
2337{
2338 int i, rc;
2339 int *volt_adjust, *ro_scale;
2340 bool explicit_adjustment, fused_adjustment, is_increasing;
2341
2342 explicit_adjustment = of_find_property(vreg->of_node,
2343 "qcom,cpr-closed-loop-voltage-adjustment", NULL);
2344 fused_adjustment = of_find_property(vreg->of_node,
2345 "qcom,cpr-fused-closed-loop-voltage-adjustment-map", NULL);
2346
2347 if (!explicit_adjustment && !fused_adjustment && !vreg->aging_allowed) {
2348 /* No adjustment required. */
2349 return 0;
2350 } else if (!of_find_property(vreg->of_node,
2351 "qcom,cpr-ro-scaling-factor", NULL)) {
2352 cpr3_err(vreg, "qcom,cpr-ro-scaling-factor is required for closed-loop voltage adjustment, but is missing\n");
2353 return -EINVAL;
2354 }
2355
2356 volt_adjust = kcalloc(vreg->corner_count, sizeof(*volt_adjust),
2357 GFP_KERNEL);
2358 ro_scale = kcalloc(vreg->corner_count * CPR3_RO_COUNT,
2359 sizeof(*ro_scale), GFP_KERNEL);
2360 if (!volt_adjust || !ro_scale) {
2361 rc = -ENOMEM;
2362 goto done;
2363 }
2364
2365 rc = cpr3_parse_corner_array_property(vreg,
2366 "qcom,cpr-ro-scaling-factor", CPR3_RO_COUNT, ro_scale);
2367 if (rc) {
2368 cpr3_err(vreg, "could not load RO scaling factors, rc=%d\n",
2369 rc);
2370 goto done;
2371 }
2372
2373 for (i = 0; i < vreg->corner_count; i++)
2374 memcpy(vreg->corner[i].ro_scale, &ro_scale[i * CPR3_RO_COUNT],
2375 sizeof(*ro_scale) * CPR3_RO_COUNT);
2376
2377 if (explicit_adjustment) {
2378 rc = cpr3_parse_corner_array_property(vreg,
2379 "qcom,cpr-closed-loop-voltage-adjustment",
2380 1, volt_adjust);
2381 if (rc) {
2382 cpr3_err(vreg, "could not load closed-loop voltage adjustments, rc=%d\n",
2383 rc);
2384 goto done;
2385 }
2386
2387 _cpr3_adjust_target_quotients(vreg, volt_adjust, ro_scale,
2388 "from DT");
2389 cpr3_enforce_inc_quotient_monotonicity(vreg);
2390 }
2391
2392 if (fused_adjustment && fuse_volt_adjust) {
2393 memset(volt_adjust, 0,
2394 sizeof(*volt_adjust) * vreg->corner_count);
2395
2396 rc = cpr3_apply_closed_loop_offset_voltages(vreg, volt_adjust,
2397 fuse_volt_adjust);
2398 if (rc) {
2399 cpr3_err(vreg, "could not apply fused closed-loop voltage reductions, rc=%d\n",
2400 rc);
2401 goto done;
2402 }
2403
2404 is_increasing = _cpr3_adjust_target_quotients(vreg, volt_adjust,
2405 ro_scale, "from fuse");
2406 if (is_increasing)
2407 cpr3_enforce_inc_quotient_monotonicity(vreg);
2408 else
2409 cpr3_enforce_dec_quotient_monotonicity(vreg);
2410 }
2411
2412done:
2413 kfree(volt_adjust);
2414 kfree(ro_scale);
2415 return rc;
2416}