blob: c4aef84e26eb1c2c23fbd60facdf963087ffaabe [file] [log] [blame]
David Collins7370f1a2017-01-18 16:21:53 -08001/*
2 * Copyright (c) 2016-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#define pr_fmt(fmt) "%s: " fmt, __func__
15
16#include <linux/bitops.h>
17#include <linux/debugfs.h>
18#include <linux/err.h>
19#include <linux/init.h>
20#include <linux/interrupt.h>
21#include <linux/io.h>
22#include <linux/kernel.h>
23#include <linux/list.h>
24#include <linux/module.h>
25#include <linux/of.h>
26#include <linux/of_device.h>
27#include <linux/platform_device.h>
28#include <linux/pm_opp.h>
29#include <linux/slab.h>
30#include <linux/string.h>
31#include <linux/uaccess.h>
32#include <linux/regulator/driver.h>
33#include <linux/regulator/machine.h>
34#include <linux/regulator/of_regulator.h>
35#include <linux/regulator/msm-ldo-regulator.h>
36
37#include "cpr3-regulator.h"
38
39#define SDM660_MMSS_FUSE_CORNERS 6
40
41/**
42 * struct cpr4_sdm660_mmss_fuses - MMSS specific fuse data for SDM660
43 * @init_voltage: Initial (i.e. open-loop) voltage fuse parameter value
44 * for each fuse corner (raw, not converted to a voltage)
45 * @offset_voltage: The closed-loop voltage margin adjustment fuse parameter
46 * value for each fuse corner (raw, not converted to a
47 * voltage)
48 * @cpr_fusing_rev: CPR fusing revision fuse parameter value
49 * @ldo_enable: The ldo enable fuse parameter for each fuse corner
50 * indicates that VDD_GFX can be configured to LDO mode in
51 * the corresponding fuse corner.
52 * @ldo_cpr_cl_enable: A fuse parameter indicates that GFX CPR can be
53 * configured to operate in closed-loop mode when VDD_GFX
54 * is configured for LDO sub-regulated mode.
55 *
56 * This struct holds the values for all of the fuses read from memory.
57 */
58struct cpr4_sdm660_mmss_fuses {
59 u64 init_voltage[SDM660_MMSS_FUSE_CORNERS];
60 u64 offset_voltage[SDM660_MMSS_FUSE_CORNERS];
61 u64 cpr_fusing_rev;
62 u64 ldo_enable[SDM660_MMSS_FUSE_CORNERS];
63 u64 ldo_cpr_cl_enable;
64};
65
66/* Fuse combos 0 - 7 map to CPR fusing revision 0 - 7 */
67#define CPR4_SDM660_MMSS_FUSE_COMBO_COUNT 8
68
69/*
70 * SDM660 MMSS fuse parameter locations:
71 *
72 * Structs are organized with the following dimensions:
73 * Outer: 0 to 3 for fuse corners from lowest to highest corner
74 * Inner: large enough to hold the longest set of parameter segments which
75 * fully defines a fuse parameter, +1 (for NULL termination).
76 * Each segment corresponds to a contiguous group of bits from a
77 * single fuse row. These segments are concatentated together in
78 * order to form the full fuse parameter value. The segments for
79 * a given parameter may correspond to different fuse rows.
80 */
81static const struct cpr3_fuse_param
82sdm660_mmss_init_voltage_param[SDM660_MMSS_FUSE_CORNERS][2] = {
83 {{65, 39, 43}, {} },
84 {{65, 39, 43}, {} },
85 {{65, 34, 38}, {} },
86 {{65, 34, 38}, {} },
87 {{65, 29, 33}, {} },
88 {{65, 24, 28}, {} },
89};
90
91static const struct cpr3_fuse_param sdm660_cpr_fusing_rev_param[] = {
92 {71, 34, 36},
93 {},
94};
95
96static const struct cpr3_fuse_param
97sdm660_mmss_offset_voltage_param[SDM660_MMSS_FUSE_CORNERS][2] = {
98 {{} },
99 {{} },
100 {{} },
101 {{65, 52, 55}, {} },
102 {{65, 48, 51}, {} },
103 {{65, 44, 47}, {} },
104};
105
106static const struct cpr3_fuse_param
107sdm660_mmss_ldo_enable_param[SDM660_MMSS_FUSE_CORNERS][2] = {
108 {{73, 62, 62}, {} },
109 {{73, 61, 61}, {} },
110 {{73, 60, 60}, {} },
111 {{73, 59, 59}, {} },
112 {{73, 58, 58}, {} },
113 {{73, 57, 57}, {} },
114};
115
116static const struct cpr3_fuse_param sdm660_ldo_cpr_cl_enable_param[] = {
117 {71, 38, 38},
118 {},
119};
120
121/* Additional SDM660 specific data: */
122
123/* Open loop voltage fuse reference voltages in microvolts */
124static const int sdm660_mmss_fuse_ref_volt[SDM660_MMSS_FUSE_CORNERS] = {
125 585000,
126 645000,
127 725000,
128 790000,
129 870000,
130 925000,
131};
132
133#define SDM660_MMSS_FUSE_STEP_VOLT 10000
134#define SDM660_MMSS_OFFSET_FUSE_STEP_VOLT 10000
135#define SDM660_MMSS_VOLTAGE_FUSE_SIZE 5
136
137#define SDM660_MMSS_CPR_SENSOR_COUNT 11
138
139#define SDM660_MMSS_CPR_CLOCK_RATE 19200000
140
141/**
142 * cpr4_sdm660_mmss_read_fuse_data() - load MMSS specific fuse parameter
143 * values
144 * @vreg: Pointer to the CPR3 regulator
145 *
146 * This function allocates a cpr4_sdm660_mmss_fuses struct, fills it with
147 * values read out of hardware fuses, and finally copies common fuse values
148 * into the regulator struct.
149 *
150 * Return: 0 on success, errno on failure
151 */
152static int cpr4_sdm660_mmss_read_fuse_data(struct cpr3_regulator *vreg)
153{
154 void __iomem *base = vreg->thread->ctrl->fuse_base;
155 struct cpr4_sdm660_mmss_fuses *fuse;
156 int i, rc;
157
158 fuse = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*fuse), GFP_KERNEL);
159 if (!fuse)
160 return -ENOMEM;
161
162 rc = cpr3_read_fuse_param(base, sdm660_cpr_fusing_rev_param,
163 &fuse->cpr_fusing_rev);
164 if (rc) {
165 cpr3_err(vreg, "Unable to read CPR fusing revision fuse, rc=%d\n",
166 rc);
167 return rc;
168 }
169 cpr3_info(vreg, "CPR fusing revision = %llu\n", fuse->cpr_fusing_rev);
170
171 rc = cpr3_read_fuse_param(base, sdm660_ldo_cpr_cl_enable_param,
172 &fuse->ldo_cpr_cl_enable);
173 if (rc) {
174 cpr3_err(vreg, "Unable to read ldo cpr closed-loop enable fuse, rc=%d\n",
175 rc);
176 return rc;
177 }
178
179 for (i = 0; i < SDM660_MMSS_FUSE_CORNERS; i++) {
180 rc = cpr3_read_fuse_param(base,
181 sdm660_mmss_init_voltage_param[i],
182 &fuse->init_voltage[i]);
183 if (rc) {
184 cpr3_err(vreg, "Unable to read fuse-corner %d initial voltage fuse, rc=%d\n",
185 i, rc);
186 return rc;
187 }
188
189 rc = cpr3_read_fuse_param(base,
190 sdm660_mmss_offset_voltage_param[i],
191 &fuse->offset_voltage[i]);
192 if (rc) {
193 cpr3_err(vreg, "Unable to read fuse-corner %d offset voltage fuse, rc=%d\n",
194 i, rc);
195 return rc;
196 }
197
198 rc = cpr3_read_fuse_param(base,
199 sdm660_mmss_ldo_enable_param[i],
200 &fuse->ldo_enable[i]);
201 if (rc) {
202 cpr3_err(vreg, "Unable to read fuse-corner %d ldo enable fuse, rc=%d\n",
203 i, rc);
204 return rc;
205 }
206 }
207
208 vreg->fuse_combo = fuse->cpr_fusing_rev;
209 if (vreg->fuse_combo >= CPR4_SDM660_MMSS_FUSE_COMBO_COUNT) {
210 cpr3_err(vreg, "invalid CPR fuse combo = %d found, not in range 0 - %d\n",
211 vreg->fuse_combo,
212 CPR4_SDM660_MMSS_FUSE_COMBO_COUNT - 1);
213 return -EINVAL;
214 }
215
216 vreg->cpr_rev_fuse = fuse->cpr_fusing_rev;
217 vreg->fuse_corner_count = SDM660_MMSS_FUSE_CORNERS;
218 vreg->platform_fuses = fuse;
219
220 return 0;
221}
222
223/**
224 * cpr3_sdm660_mmss_calculate_open_loop_voltages() - calculate the open-loop
225 * voltage for each corner of a CPR3 regulator
226 * @vreg: Pointer to the CPR3 regulator
227 *
228 * Return: 0 on success, errno on failure
229 */
230static int cpr4_sdm660_mmss_calculate_open_loop_voltages(
231 struct cpr3_regulator *vreg)
232{
233 struct cpr4_sdm660_mmss_fuses *fuse = vreg->platform_fuses;
234 int i, rc = 0;
235 const int *ref_volt;
236 int *fuse_volt;
237
238 fuse_volt = kcalloc(vreg->fuse_corner_count, sizeof(*fuse_volt),
239 GFP_KERNEL);
240 if (!fuse_volt)
241 return -ENOMEM;
242
243 ref_volt = sdm660_mmss_fuse_ref_volt;
244 for (i = 0; i < vreg->fuse_corner_count; i++) {
245 fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse(ref_volt[i],
246 SDM660_MMSS_FUSE_STEP_VOLT, fuse->init_voltage[i],
247 SDM660_MMSS_VOLTAGE_FUSE_SIZE);
248 cpr3_info(vreg, "fuse_corner[%d] open-loop=%7d uV\n",
249 i, fuse_volt[i]);
250 }
251
252 rc = cpr3_adjust_fused_open_loop_voltages(vreg, fuse_volt);
253 if (rc) {
254 cpr3_err(vreg, "fused open-loop voltage adjustment failed, rc=%d\n",
255 rc);
256 goto done;
257 }
258
259 for (i = 1; i < vreg->fuse_corner_count; i++) {
260 if (fuse_volt[i] < fuse_volt[i - 1]) {
261 cpr3_debug(vreg, "fuse corner %d voltage=%d uV < fuse corner %d voltage=%d uV; overriding: fuse corner %d voltage=%d\n",
262 i, fuse_volt[i], i - 1, fuse_volt[i - 1],
263 i, fuse_volt[i - 1]);
264 fuse_volt[i] = fuse_volt[i - 1];
265 }
266 }
267
268 for (i = 0; i < vreg->corner_count; i++)
269 vreg->corner[i].open_loop_volt
270 = fuse_volt[vreg->corner[i].cpr_fuse_corner];
271
272 cpr3_debug(vreg, "unadjusted per-corner open-loop voltages:\n");
273 for (i = 0; i < vreg->corner_count; i++)
274 cpr3_debug(vreg, "open-loop[%2d] = %d uV\n", i,
275 vreg->corner[i].open_loop_volt);
276
277 rc = cpr3_adjust_open_loop_voltages(vreg);
278 if (rc)
279 cpr3_err(vreg, "open-loop voltage adjustment failed, rc=%d\n",
280 rc);
281
282done:
283 kfree(fuse_volt);
284 return rc;
285}
286
287/**
288 * cpr4_mmss_parse_ldo_mode_data() - Parse the LDO mode enable state for each
289 * corner of a CPR3 regulator
290 * @vreg: Pointer to the CPR3 regulator
291 *
292 * This function considers 2 sets of data: one set from device node and other
293 * set from fuses and applies set intersection to decide the final LDO mode
294 * enable state of each corner. If the device node configuration is not
295 * specified, then the function applies LDO mode disable for all corners.
296 *
297 * Return: 0 on success, errno on failure
298 */
299static int cpr4_mmss_parse_ldo_mode_data(struct cpr3_regulator *vreg)
300{
301 struct cpr4_sdm660_mmss_fuses *fuse = vreg->platform_fuses;
302 int i, rc = 0;
303 u32 *ldo_allowed;
304 char *prop_str = "qcom,cpr-corner-allow-ldo-mode";
305
306 if (!of_find_property(vreg->of_node, prop_str, NULL)) {
307 cpr3_debug(vreg, "%s property is missing. LDO mode is disabled for all corners\n",
308 prop_str);
309 return 0;
310 }
311
312 ldo_allowed = kcalloc(vreg->corner_count, sizeof(*ldo_allowed),
313 GFP_KERNEL);
314 if (!ldo_allowed)
315 return -ENOMEM;
316
317 rc = cpr3_parse_corner_array_property(vreg, prop_str, 1, ldo_allowed);
318 if (rc) {
319 cpr3_err(vreg, "%s read failed, rc=%d\n", prop_str, rc);
320 goto done;
321 }
322
323 for (i = 0; i < vreg->corner_count; i++)
324 vreg->corner[i].ldo_mode_allowed
325 = (ldo_allowed[i] && fuse->ldo_enable[i]);
326
327done:
328 kfree(ldo_allowed);
329 return rc;
330}
331
332/**
333 * cpr4_mmss_parse_corner_operating_mode() - Parse the CPR closed-loop operation
334 * enable state for each corner of a CPR3 regulator
335 * @vreg: Pointer to the CPR3 regulator
336 *
337 * This function ensures that closed-loop operation is enabled only for LDO
338 * mode allowed corners.
339 *
340 * Return: 0 on success, errno on failure
341 */
342static int cpr4_mmss_parse_corner_operating_mode(struct cpr3_regulator *vreg)
343{
344 struct cpr4_sdm660_mmss_fuses *fuse = vreg->platform_fuses;
345 int i, rc = 0;
346 u32 *use_closed_loop;
347 char *prop_str = "qcom,cpr-corner-allow-closed-loop";
348
349 if (!of_find_property(vreg->of_node, prop_str, NULL)) {
350 cpr3_debug(vreg, "%s property is missing. Use open-loop for all corners\n",
351 prop_str);
352 for (i = 0; i < vreg->corner_count; i++)
353 vreg->corner[i].use_open_loop = true;
354
355 return 0;
356 }
357
358 use_closed_loop = kcalloc(vreg->corner_count, sizeof(*use_closed_loop),
359 GFP_KERNEL);
360 if (!use_closed_loop)
361 return -ENOMEM;
362
363 rc = cpr3_parse_corner_array_property(vreg, prop_str, 1,
364 use_closed_loop);
365 if (rc) {
366 cpr3_err(vreg, "%s read failed, rc=%d\n", prop_str, rc);
367 goto done;
368 }
369
370 for (i = 0; i < vreg->corner_count; i++)
371 vreg->corner[i].use_open_loop
372 = !(fuse->ldo_cpr_cl_enable && use_closed_loop[i]
373 && vreg->corner[i].ldo_mode_allowed);
374
375done:
376 kfree(use_closed_loop);
377 return rc;
378}
379
380/**
381 * cpr4_mmss_parse_corner_data() - parse MMSS corner data from device tree
382 * properties of the regulator's device node
383 * @vreg: Pointer to the CPR3 regulator
384 *
385 * Return: 0 on success, errno on failure
386 */
387static int cpr4_mmss_parse_corner_data(struct cpr3_regulator *vreg)
388{
389 int i, rc;
390 u32 *temp;
391
392 rc = cpr3_parse_common_corner_data(vreg);
393 if (rc) {
394 cpr3_err(vreg, "error reading corner data, rc=%d\n", rc);
395 return rc;
396 }
397
398 temp = kcalloc(vreg->corner_count * CPR3_RO_COUNT, sizeof(*temp),
399 GFP_KERNEL);
400 if (!temp)
401 return -ENOMEM;
402
403 rc = cpr3_parse_corner_array_property(vreg, "qcom,cpr-target-quotients",
404 CPR3_RO_COUNT, temp);
405 if (rc) {
406 cpr3_err(vreg, "could not load target quotients, rc=%d\n", rc);
407 goto done;
408 }
409
410 for (i = 0; i < vreg->corner_count; i++)
411 memcpy(vreg->corner[i].target_quot, &temp[i * CPR3_RO_COUNT],
412 sizeof(*temp) * CPR3_RO_COUNT);
413
414done:
415 kfree(temp);
416 return rc;
417}
418
419/**
420 * cpr4_sdm660_mmss_adjust_target_quotients() - adjust the target quotients for
421 * each corner according to device tree values and fuse values
422 * @vreg: Pointer to the CPR3 regulator
423 *
424 * Return: 0 on success, errno on failure
425 */
426static int cpr4_sdm660_mmss_adjust_target_quotients(struct cpr3_regulator *vreg)
427{
428 struct cpr4_sdm660_mmss_fuses *fuse = vreg->platform_fuses;
429 const struct cpr3_fuse_param (*offset_param)[2];
430 int *volt_offset;
431 int i, fuse_len, rc = 0;
432
433 volt_offset = kcalloc(vreg->fuse_corner_count, sizeof(*volt_offset),
434 GFP_KERNEL);
435 if (!volt_offset)
436 return -ENOMEM;
437
438 offset_param = sdm660_mmss_offset_voltage_param;
439 for (i = 0; i < vreg->fuse_corner_count; i++) {
440 fuse_len = offset_param[i][0].bit_end + 1
441 - offset_param[i][0].bit_start;
442 volt_offset[i] = cpr3_convert_open_loop_voltage_fuse(
443 0, SDM660_MMSS_OFFSET_FUSE_STEP_VOLT,
444 fuse->offset_voltage[i], fuse_len);
445 if (volt_offset[i])
446 cpr3_info(vreg, "fuse_corner[%d] offset=%7d uV\n",
447 i, volt_offset[i]);
448 }
449
450 rc = cpr3_adjust_target_quotients(vreg, volt_offset);
451 if (rc)
452 cpr3_err(vreg, "adjust target quotients failed, rc=%d\n", rc);
453
454 kfree(volt_offset);
455 return rc;
456}
457
458/**
459 * cpr4_mmss_print_settings() - print out MMSS CPR configuration settings into
460 * the kernel log for debugging purposes
461 * @vreg: Pointer to the CPR3 regulator
462 */
463static void cpr4_mmss_print_settings(struct cpr3_regulator *vreg)
464{
465 struct cpr3_corner *corner;
466 int i;
467
468 cpr3_debug(vreg, "Corner: Frequency (Hz), Fuse Corner, Floor (uV), Open-Loop (uV), Ceiling (uV)\n");
469 for (i = 0; i < vreg->corner_count; i++) {
470 corner = &vreg->corner[i];
471 cpr3_debug(vreg, "%3d: %10u, %2d, %7d, %7d, %7d\n",
472 i, corner->proc_freq, corner->cpr_fuse_corner,
473 corner->floor_volt, corner->open_loop_volt,
474 corner->ceiling_volt);
475 }
476}
477
478/**
479 * cpr4_mmss_init_thread() - perform all steps necessary to initialize the
480 * configuration data for a CPR3 thread
481 * @thread: Pointer to the CPR3 thread
482 *
483 * Return: 0 on success, errno on failure
484 */
485static int cpr4_mmss_init_thread(struct cpr3_thread *thread)
486{
487 struct cpr3_controller *ctrl = thread->ctrl;
488 struct cpr3_regulator *vreg = &thread->vreg[0];
489 int rc;
490
491 rc = cpr3_parse_common_thread_data(thread);
492 if (rc) {
493 cpr3_err(vreg, "unable to read CPR thread data from device tree, rc=%d\n",
494 rc);
495 return rc;
496 }
497
498 if (!of_find_property(ctrl->dev->of_node, "vdd-thread0-ldo-supply",
499 NULL)) {
500 cpr3_err(vreg, "ldo supply regulator is not specified\n");
501 return -EINVAL;
502 }
503
504 vreg->ldo_regulator = devm_regulator_get(ctrl->dev, "vdd-thread0-ldo");
505 if (IS_ERR(vreg->ldo_regulator)) {
506 rc = PTR_ERR(vreg->ldo_regulator);
507 if (rc != -EPROBE_DEFER)
508 cpr3_err(vreg, "unable to request vdd-thread0-ldo regulator, rc=%d\n",
509 rc);
510 return rc;
511 }
512
513 vreg->ldo_mode_allowed = !of_property_read_bool(vreg->of_node,
514 "qcom,ldo-disable");
515 vreg->ldo_regulator_bypass = BHS_MODE;
516 vreg->ldo_type = CPR3_LDO300;
517
518 rc = cpr4_sdm660_mmss_read_fuse_data(vreg);
519 if (rc) {
520 cpr3_err(vreg, "unable to read CPR fuse data, rc=%d\n", rc);
521 return rc;
522 }
523
524 rc = cpr4_mmss_parse_corner_data(vreg);
525 if (rc) {
526 cpr3_err(vreg, "unable to read CPR corner data from device tree, rc=%d\n",
527 rc);
528 return rc;
529 }
530
531 rc = cpr4_sdm660_mmss_adjust_target_quotients(vreg);
532 if (rc) {
533 cpr3_err(vreg, "unable to adjust target quotients, rc=%d\n",
534 rc);
535 return rc;
536 }
537
538 rc = cpr4_sdm660_mmss_calculate_open_loop_voltages(vreg);
539 if (rc) {
540 cpr3_err(vreg, "unable to calculate open-loop voltages, rc=%d\n",
541 rc);
542 return rc;
543 }
544
545 rc = cpr3_limit_open_loop_voltages(vreg);
546 if (rc) {
547 cpr3_err(vreg, "unable to limit open-loop voltages, rc=%d\n",
548 rc);
549 return rc;
550 }
551
552 cpr3_open_loop_voltage_as_ceiling(vreg);
553
554 rc = cpr3_limit_floor_voltages(vreg);
555 if (rc) {
556 cpr3_err(vreg, "unable to limit floor voltages, rc=%d\n", rc);
557 return rc;
558 }
559
560 rc = cpr4_mmss_parse_ldo_mode_data(vreg);
561 if (rc) {
562 cpr3_err(vreg, "unable to parse ldo mode data, rc=%d\n", rc);
563 return rc;
564 }
565
566 rc = cpr4_mmss_parse_corner_operating_mode(vreg);
567 if (rc) {
568 cpr3_err(vreg, "unable to parse closed-loop operating mode data, rc=%d\n",
569 rc);
570 return rc;
571 }
572
573 cpr4_mmss_print_settings(vreg);
574
575 return 0;
576}
577
578/**
579 * cpr4_mmss_init_controller() - perform MMSS CPR4 controller specific
580 * initializations
581 * @ctrl: Pointer to the CPR3 controller
582 *
583 * Return: 0 on success, errno on failure
584 */
585static int cpr4_mmss_init_controller(struct cpr3_controller *ctrl)
586{
587 int rc;
588
589 rc = cpr3_parse_common_ctrl_data(ctrl);
590 if (rc) {
591 if (rc != -EPROBE_DEFER)
592 cpr3_err(ctrl, "unable to parse common controller data, rc=%d\n",
593 rc);
594 return rc;
595 }
596
597 ctrl->sensor_count = SDM660_MMSS_CPR_SENSOR_COUNT;
598
599 /*
600 * MMSS only has one thread (0) so the zeroed array does not need
601 * further modification.
602 */
603 ctrl->sensor_owner = devm_kcalloc(ctrl->dev, ctrl->sensor_count,
604 sizeof(*ctrl->sensor_owner), GFP_KERNEL);
605 if (!ctrl->sensor_owner)
606 return -ENOMEM;
607
608 ctrl->cpr_clock_rate = SDM660_MMSS_CPR_CLOCK_RATE;
609 ctrl->ctrl_type = CPR_CTRL_TYPE_CPR4;
610 ctrl->support_ldo300_vreg = true;
611
612 /*
613 * Use fixed step quotient if specified otherwise use dynamic
614 * calculated per RO step quotient
615 */
616 of_property_read_u32(ctrl->dev->of_node,
617 "qcom,cpr-step-quot-fixed",
618 &ctrl->step_quot_fixed);
619 ctrl->use_dynamic_step_quot = !ctrl->step_quot_fixed;
620
621 /* iface_clk is optional for sdm660 */
622 ctrl->iface_clk = NULL;
623 ctrl->bus_clk = devm_clk_get(ctrl->dev, "bus_clk");
624 if (IS_ERR(ctrl->bus_clk)) {
625 rc = PTR_ERR(ctrl->bus_clk);
626 if (rc != -EPROBE_DEFER)
627 cpr3_err(ctrl, "unable request bus clock, rc=%d\n",
628 rc);
629 return rc;
630 }
631
632 return 0;
633}
634
635static int cpr4_mmss_regulator_probe(struct platform_device *pdev)
636{
637 struct device *dev = &pdev->dev;
638 struct cpr3_controller *ctrl;
639 int rc;
640
641 if (!dev->of_node) {
642 dev_err(dev, "Device tree node is missing\n");
643 return -EINVAL;
644 }
645
646 ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
647 if (!ctrl)
648 return -ENOMEM;
649
650 ctrl->dev = dev;
651 /* Set to false later if anything precludes CPR operation. */
652 ctrl->cpr_allowed_hw = true;
653
654 rc = of_property_read_string(dev->of_node, "qcom,cpr-ctrl-name",
655 &ctrl->name);
656 if (rc) {
657 cpr3_err(ctrl, "unable to read qcom,cpr-ctrl-name, rc=%d\n",
658 rc);
659 return rc;
660 }
661
662 rc = cpr3_map_fuse_base(ctrl, pdev);
663 if (rc) {
664 cpr3_err(ctrl, "could not map fuse base address\n");
665 return rc;
666 }
667
668 rc = cpr3_allocate_threads(ctrl, 0, 0);
669 if (rc) {
670 cpr3_err(ctrl, "failed to allocate CPR thread array, rc=%d\n",
671 rc);
672 return rc;
673 }
674
675 if (ctrl->thread_count != 1) {
676 cpr3_err(ctrl, "expected 1 thread but found %d\n",
677 ctrl->thread_count);
678 return -EINVAL;
679 } else if (ctrl->thread[0].vreg_count != 1) {
680 cpr3_err(ctrl, "expected 1 regulator but found %d\n",
681 ctrl->thread[0].vreg_count);
682 return -EINVAL;
683 }
684
685 rc = cpr4_mmss_init_controller(ctrl);
686 if (rc) {
687 if (rc != -EPROBE_DEFER)
688 cpr3_err(ctrl, "failed to initialize CPR controller parameters, rc=%d\n",
689 rc);
690 return rc;
691 }
692
693 rc = cpr4_mmss_init_thread(&ctrl->thread[0]);
694 if (rc) {
695 cpr3_err(&ctrl->thread[0].vreg[0], "thread initialization failed, rc=%d\n",
696 rc);
697 return rc;
698 }
699
700 rc = cpr3_mem_acc_init(&ctrl->thread[0].vreg[0]);
701 if (rc) {
702 cpr3_err(ctrl, "failed to initialize mem-acc configuration, rc=%d\n",
703 rc);
704 return rc;
705 }
706
707 platform_set_drvdata(pdev, ctrl);
708
709 return cpr3_regulator_register(pdev, ctrl);
710}
711
712static int cpr4_mmss_regulator_remove(struct platform_device *pdev)
713{
714 struct cpr3_controller *ctrl = platform_get_drvdata(pdev);
715
716 return cpr3_regulator_unregister(ctrl);
717}
718
719static int cpr4_mmss_regulator_suspend(struct platform_device *pdev,
720 pm_message_t state)
721{
722 struct cpr3_controller *ctrl = platform_get_drvdata(pdev);
723
724 return cpr3_regulator_suspend(ctrl);
725}
726
727static int cpr4_mmss_regulator_resume(struct platform_device *pdev)
728{
729 struct cpr3_controller *ctrl = platform_get_drvdata(pdev);
730
731 return cpr3_regulator_resume(ctrl);
732}
733
734/* Data corresponds to the SoC revision */
735static const struct of_device_id cpr4_mmss_regulator_match_table[] = {
736 {
737 .compatible = "qcom,cpr4-sdm660-mmss-ldo-regulator",
738 .data = (void *)NULL,
739 },
740 { },
741};
742
743static struct platform_driver cpr4_mmss_regulator_driver = {
744 .driver = {
745 .name = "qcom,cpr4-mmss-ldo-regulator",
746 .of_match_table = cpr4_mmss_regulator_match_table,
747 .owner = THIS_MODULE,
748 },
749 .probe = cpr4_mmss_regulator_probe,
750 .remove = cpr4_mmss_regulator_remove,
751 .suspend = cpr4_mmss_regulator_suspend,
752 .resume = cpr4_mmss_regulator_resume,
753};
754
755static int cpr_regulator_init(void)
756{
757 return platform_driver_register(&cpr4_mmss_regulator_driver);
758}
759
760static void cpr_regulator_exit(void)
761{
762 platform_driver_unregister(&cpr4_mmss_regulator_driver);
763}
764
765MODULE_DESCRIPTION("CPR4 MMSS LDO regulator driver");
766MODULE_LICENSE("GPL v2");
767
768arch_initcall(cpr_regulator_init);
769module_exit(cpr_regulator_exit);