blob: e22a2595ef97aad60c8dc5655007edadc4ecb899 [file] [log] [blame]
David Collins7370f1a2017-01-18 16:21:53 -08001/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#define pr_fmt(fmt) "ACC: %s: " fmt, __func__
13
14#include <linux/module.h>
15#include <linux/mutex.h>
16#include <linux/types.h>
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <linux/err.h>
20#include <linux/of.h>
21#include <linux/of_device.h>
22#include <linux/io.h>
23#include <linux/platform_device.h>
24#include <linux/regulator/driver.h>
25#include <linux/regulator/machine.h>
26#include <linux/regulator/of_regulator.h>
27#include <linux/string.h>
28#include <soc/qcom/scm.h>
29
30#define MEM_ACC_DEFAULT_SEL_SIZE 2
31
32#define BYTES_PER_FUSE_ROW 8
33
34/* mem-acc config flags */
35
36enum {
37 MEM_ACC_USE_CORNER_ACC_MAP = BIT(0),
38 MEM_ACC_USE_ADDR_VAL_MAP = BIT(1),
39};
40
41#define FUSE_MAP_NO_MATCH (-1)
42#define FUSE_PARAM_MATCH_ANY (-1)
43#define PARAM_MATCH_ANY (-1)
44
45enum {
46 MEMORY_L1,
47 MEMORY_L2,
48 MEMORY_MAX,
49};
50
51#define MEM_ACC_TYPE_MAX 6
52
53/**
54 * struct acc_reg_value - Acc register configuration structure
55 * @addr_index: An index in to phys_reg_addr_list and remap_reg_addr_list
56 * to get the ACC register physical address and remapped address.
57 * @reg_val: Value to program in to the register mapped by addr_index.
58 */
59struct acc_reg_value {
60 u32 addr_index;
61 u32 reg_val;
62};
63
64struct corner_acc_reg_config {
65 struct acc_reg_value *reg_config_list;
66 int max_reg_config_len;
67};
68
69struct mem_acc_regulator {
70 struct device *dev;
71 struct regulator_desc rdesc;
72 struct regulator_dev *rdev;
73
74 int corner;
75 bool mem_acc_supported[MEMORY_MAX];
76 bool mem_acc_custom_supported[MEMORY_MAX];
77
78 u32 *acc_sel_mask[MEMORY_MAX];
79 u32 *acc_sel_bit_pos[MEMORY_MAX];
80 u32 acc_sel_bit_size[MEMORY_MAX];
81 u32 num_acc_sel[MEMORY_MAX];
82 u32 *acc_en_bit_pos;
83 u32 num_acc_en;
84 u32 *corner_acc_map;
85 u32 num_corners;
86 u32 override_fuse_value;
87 int override_map_match;
88 int override_map_count;
89
90
91 void __iomem *acc_sel_base[MEMORY_MAX];
92 void __iomem *acc_en_base;
93 phys_addr_t acc_sel_addr[MEMORY_MAX];
94 phys_addr_t acc_en_addr;
95 u32 flags;
96
97 void __iomem *acc_custom_addr[MEMORY_MAX];
98 u32 *acc_custom_data[MEMORY_MAX];
99
100 phys_addr_t mem_acc_type_addr[MEM_ACC_TYPE_MAX];
101 u32 *mem_acc_type_data;
102
103 /* eFuse parameters */
104 phys_addr_t efuse_addr;
105 void __iomem *efuse_base;
106
107 u32 num_acc_reg;
108 u32 *phys_reg_addr_list;
109 void __iomem **remap_reg_addr_list;
110 struct corner_acc_reg_config *corner_acc_reg_config;
Tirupathi Reddya1cacb42016-10-25 12:35:22 +0530111 u32 *override_acc_range_fuse_list;
112 int override_acc_range_fuse_num;
David Collins7370f1a2017-01-18 16:21:53 -0800113};
114
115static DEFINE_MUTEX(mem_acc_memory_mutex);
116
117static u64 mem_acc_read_efuse_row(struct mem_acc_regulator *mem_acc_vreg,
118 u32 row_num, bool use_tz_api)
119{
120 int rc;
121 u64 efuse_bits;
122 struct scm_desc desc = {0};
123 struct mem_acc_read_req {
124 u32 row_address;
125 int addr_type;
126 } req;
127
128 struct mem_acc_read_rsp {
129 u32 row_data[2];
130 u32 status;
131 } rsp;
132
133 if (!use_tz_api) {
134 efuse_bits = readq_relaxed(mem_acc_vreg->efuse_base
135 + row_num * BYTES_PER_FUSE_ROW);
136 return efuse_bits;
137 }
138
139 desc.args[0] = req.row_address = mem_acc_vreg->efuse_addr +
140 row_num * BYTES_PER_FUSE_ROW;
141 desc.args[1] = req.addr_type = 0;
142 desc.arginfo = SCM_ARGS(2);
143 efuse_bits = 0;
144
145 if (!is_scm_armv8()) {
146 rc = scm_call(SCM_SVC_FUSE, SCM_FUSE_READ,
147 &req, sizeof(req), &rsp, sizeof(rsp));
148 } else {
149 rc = scm_call2(SCM_SIP_FNID(SCM_SVC_FUSE, SCM_FUSE_READ),
150 &desc);
151 rsp.row_data[0] = desc.ret[0];
152 rsp.row_data[1] = desc.ret[1];
153 rsp.status = desc.ret[2];
154 }
155
156 if (rc) {
157 pr_err("read row %d failed, err code = %d", row_num, rc);
158 } else {
159 efuse_bits = ((u64)(rsp.row_data[1]) << 32) +
160 (u64)rsp.row_data[0];
161 }
162
163 return efuse_bits;
164}
165
166static inline u32 apc_to_acc_corner(struct mem_acc_regulator *mem_acc_vreg,
167 int corner)
168{
169 /*
170 * corner_acc_map maps the corner from index 0 and APC corner value
171 * starts from the value 1
172 */
173 return mem_acc_vreg->corner_acc_map[corner - 1];
174}
175
176static void __update_acc_sel(struct mem_acc_regulator *mem_acc_vreg,
177 int corner, int mem_type)
178{
179 u32 acc_data, acc_data_old, i, bit, acc_corner;
180
181 acc_data = readl_relaxed(mem_acc_vreg->acc_sel_base[mem_type]);
182 acc_data_old = acc_data;
183 for (i = 0; i < mem_acc_vreg->num_acc_sel[mem_type]; i++) {
184 bit = mem_acc_vreg->acc_sel_bit_pos[mem_type][i];
185 acc_data &= ~mem_acc_vreg->acc_sel_mask[mem_type][i];
186 acc_corner = apc_to_acc_corner(mem_acc_vreg, corner);
187 acc_data |= (acc_corner << bit) &
188 mem_acc_vreg->acc_sel_mask[mem_type][i];
189 }
190 pr_debug("corner=%d old_acc_sel=0x%02x new_acc_sel=0x%02x mem_type=%d\n",
191 corner, acc_data_old, acc_data, mem_type);
192 writel_relaxed(acc_data, mem_acc_vreg->acc_sel_base[mem_type]);
193}
194
195static void __update_acc_type(struct mem_acc_regulator *mem_acc_vreg,
196 int corner)
197{
198 int i, rc;
199
200 for (i = 0; i < MEM_ACC_TYPE_MAX; i++) {
201 if (mem_acc_vreg->mem_acc_type_addr[i]) {
202 rc = scm_io_write(mem_acc_vreg->mem_acc_type_addr[i],
203 mem_acc_vreg->mem_acc_type_data[corner - 1 + i *
204 mem_acc_vreg->num_corners]);
205 if (rc)
206 pr_err("scm_io_write: %pa failure rc:%d\n",
207 &(mem_acc_vreg->mem_acc_type_addr[i]),
208 rc);
209 }
210 }
211}
212
213static void __update_acc_custom(struct mem_acc_regulator *mem_acc_vreg,
214 int corner, int mem_type)
215{
216 writel_relaxed(
217 mem_acc_vreg->acc_custom_data[mem_type][corner-1],
218 mem_acc_vreg->acc_custom_addr[mem_type]);
219 pr_debug("corner=%d mem_type=%d custom_data=0x%2x\n", corner,
220 mem_type, mem_acc_vreg->acc_custom_data[mem_type][corner-1]);
221}
222
223static void update_acc_sel(struct mem_acc_regulator *mem_acc_vreg, int corner)
224{
225 int i;
226
227 for (i = 0; i < MEMORY_MAX; i++) {
228 if (mem_acc_vreg->mem_acc_supported[i])
229 __update_acc_sel(mem_acc_vreg, corner, i);
230 if (mem_acc_vreg->mem_acc_custom_supported[i])
231 __update_acc_custom(mem_acc_vreg, corner, i);
232 }
233
234 if (mem_acc_vreg->mem_acc_type_data)
235 __update_acc_type(mem_acc_vreg, corner);
236}
237
238static void update_acc_reg(struct mem_acc_regulator *mem_acc_vreg, int corner)
239{
240 struct corner_acc_reg_config *corner_acc_reg_config;
241 struct acc_reg_value *reg_config_list;
242 int i, index;
243 u32 addr_index, reg_val;
244
245 corner_acc_reg_config =
246 &mem_acc_vreg->corner_acc_reg_config[mem_acc_vreg->corner];
247 reg_config_list = corner_acc_reg_config->reg_config_list;
248 for (i = 0; i < corner_acc_reg_config->max_reg_config_len; i++) {
249 /*
250 * Use (corner - 1) in the below equation as
251 * the reg_config_list[] stores the values starting from
252 * index '0' where as the minimum corner value allowed
253 * in regulator framework is '1'.
254 */
255 index = (corner - 1) * corner_acc_reg_config->max_reg_config_len
256 + i;
257 addr_index = reg_config_list[index].addr_index;
258 reg_val = reg_config_list[index].reg_val;
259
260 if (addr_index == PARAM_MATCH_ANY)
261 break;
262
263 writel_relaxed(reg_val,
264 mem_acc_vreg->remap_reg_addr_list[addr_index]);
265 /* make sure write complete */
266 mb();
267
268 pr_debug("corner=%d register:0x%x value:0x%x\n", corner,
269 mem_acc_vreg->phys_reg_addr_list[addr_index], reg_val);
270 }
271}
272
273static int mem_acc_regulator_set_voltage(struct regulator_dev *rdev,
274 int corner, int corner_max, unsigned int *selector)
275{
276 struct mem_acc_regulator *mem_acc_vreg = rdev_get_drvdata(rdev);
277 int i;
278
279 if (corner > mem_acc_vreg->num_corners) {
280 pr_err("Invalid corner=%d requested\n", corner);
281 return -EINVAL;
282 }
283
284 pr_debug("old corner=%d, new corner=%d\n",
285 mem_acc_vreg->corner, corner);
286
287 if (corner == mem_acc_vreg->corner)
288 return 0;
289
290 /* go up or down one level at a time */
291 mutex_lock(&mem_acc_memory_mutex);
292
293 if (mem_acc_vreg->flags & MEM_ACC_USE_ADDR_VAL_MAP) {
294 update_acc_reg(mem_acc_vreg, corner);
295 } else if (mem_acc_vreg->flags & MEM_ACC_USE_CORNER_ACC_MAP) {
296 if (corner > mem_acc_vreg->corner) {
297 for (i = mem_acc_vreg->corner + 1; i <= corner; i++) {
298 pr_debug("UP: to corner %d\n", i);
299 update_acc_sel(mem_acc_vreg, i);
300 }
301 } else {
302 for (i = mem_acc_vreg->corner - 1; i >= corner; i--) {
303 pr_debug("DOWN: to corner %d\n", i);
304 update_acc_sel(mem_acc_vreg, i);
305 }
306 }
307 }
308
309 mutex_unlock(&mem_acc_memory_mutex);
310
311 pr_debug("new voltage corner set %d\n", corner);
312
313 mem_acc_vreg->corner = corner;
314
315 return 0;
316}
317
318static int mem_acc_regulator_get_voltage(struct regulator_dev *rdev)
319{
320 struct mem_acc_regulator *mem_acc_vreg = rdev_get_drvdata(rdev);
321
322 return mem_acc_vreg->corner;
323}
324
325static struct regulator_ops mem_acc_corner_ops = {
326 .set_voltage = mem_acc_regulator_set_voltage,
327 .get_voltage = mem_acc_regulator_get_voltage,
328};
329
330static int __mem_acc_sel_init(struct mem_acc_regulator *mem_acc_vreg,
331 int mem_type)
332{
333 int i;
334 u32 bit, mask;
335
336 mem_acc_vreg->acc_sel_mask[mem_type] = devm_kzalloc(mem_acc_vreg->dev,
337 mem_acc_vreg->num_acc_sel[mem_type] * sizeof(u32), GFP_KERNEL);
338 if (!mem_acc_vreg->acc_sel_mask[mem_type])
339 return -ENOMEM;
340
341 for (i = 0; i < mem_acc_vreg->num_acc_sel[mem_type]; i++) {
342 bit = mem_acc_vreg->acc_sel_bit_pos[mem_type][i];
343 mask = BIT(mem_acc_vreg->acc_sel_bit_size[mem_type]) - 1;
344 mem_acc_vreg->acc_sel_mask[mem_type][i] = mask << bit;
345 }
346
347 return 0;
348}
349
350static int mem_acc_sel_init(struct mem_acc_regulator *mem_acc_vreg)
351{
352 int i, rc;
353
354 for (i = 0; i < MEMORY_MAX; i++) {
355 if (mem_acc_vreg->mem_acc_supported[i]) {
356 rc = __mem_acc_sel_init(mem_acc_vreg, i);
357 if (rc) {
358 pr_err("Unable to initialize mem_type=%d rc=%d\n",
359 i, rc);
360 return rc;
361 }
362 }
363 }
364
365 return 0;
366}
367
368static void mem_acc_en_init(struct mem_acc_regulator *mem_acc_vreg)
369{
370 int i, bit;
371 u32 acc_data;
372
373 acc_data = readl_relaxed(mem_acc_vreg->acc_en_base);
374 pr_debug("init: acc_en_register=%x\n", acc_data);
375 for (i = 0; i < mem_acc_vreg->num_acc_en; i++) {
376 bit = mem_acc_vreg->acc_en_bit_pos[i];
377 acc_data |= BIT(bit);
378 }
379 pr_debug("final: acc_en_register=%x\n", acc_data);
380 writel_relaxed(acc_data, mem_acc_vreg->acc_en_base);
381}
382
383static int populate_acc_data(struct mem_acc_regulator *mem_acc_vreg,
384 const char *prop_name, u32 **value, u32 *len)
385{
386 int rc;
387
388 if (!of_get_property(mem_acc_vreg->dev->of_node, prop_name, len)) {
389 pr_err("Unable to find %s property\n", prop_name);
390 return -EINVAL;
391 }
392 *len /= sizeof(u32);
393 if (!(*len)) {
394 pr_err("Incorrect entries in %s\n", prop_name);
395 return -EINVAL;
396 }
397
398 *value = devm_kzalloc(mem_acc_vreg->dev, (*len) * sizeof(u32),
399 GFP_KERNEL);
400 if (!(*value)) {
401 pr_err("Unable to allocate memory for %s\n", prop_name);
402 return -ENOMEM;
403 }
404
405 pr_debug("Found %s, data-length = %d\n", prop_name, *len);
406
407 rc = of_property_read_u32_array(mem_acc_vreg->dev->of_node,
408 prop_name, *value, *len);
409 if (rc) {
410 pr_err("Unable to populate %s rc=%d\n", prop_name, rc);
411 return rc;
412 }
413
414 return 0;
415}
416
417static int mem_acc_sel_setup(struct mem_acc_regulator *mem_acc_vreg,
418 struct resource *res, int mem_type)
419{
420 int len, rc;
421 char *mem_select_str;
422 char *mem_select_size_str;
423
424 mem_acc_vreg->acc_sel_addr[mem_type] = res->start;
425 len = res->end - res->start + 1;
426 pr_debug("'acc_sel_addr' = %pa mem_type=%d (len=%d)\n",
427 &res->start, mem_type, len);
428
429 mem_acc_vreg->acc_sel_base[mem_type] = devm_ioremap(mem_acc_vreg->dev,
430 mem_acc_vreg->acc_sel_addr[mem_type], len);
431 if (!mem_acc_vreg->acc_sel_base[mem_type]) {
432 pr_err("Unable to map 'acc_sel_addr' %pa for mem_type=%d\n",
433 &mem_acc_vreg->acc_sel_addr[mem_type], mem_type);
434 return -EINVAL;
435 }
436
437 switch (mem_type) {
438 case MEMORY_L1:
439 mem_select_str = "qcom,acc-sel-l1-bit-pos";
440 mem_select_size_str = "qcom,acc-sel-l1-bit-size";
441 break;
442 case MEMORY_L2:
443 mem_select_str = "qcom,acc-sel-l2-bit-pos";
444 mem_select_size_str = "qcom,acc-sel-l2-bit-size";
445 break;
446 default:
447 pr_err("Invalid memory type: %d\n", mem_type);
448 return -EINVAL;
449 }
450
451 mem_acc_vreg->acc_sel_bit_size[mem_type] = MEM_ACC_DEFAULT_SEL_SIZE;
452 of_property_read_u32(mem_acc_vreg->dev->of_node, mem_select_size_str,
453 &mem_acc_vreg->acc_sel_bit_size[mem_type]);
454
455 rc = populate_acc_data(mem_acc_vreg, mem_select_str,
456 &mem_acc_vreg->acc_sel_bit_pos[mem_type],
457 &mem_acc_vreg->num_acc_sel[mem_type]);
458 if (rc)
459 pr_err("Unable to populate '%s' rc=%d\n", mem_select_str, rc);
460
461 return rc;
462}
463
464static int mem_acc_efuse_init(struct platform_device *pdev,
465 struct mem_acc_regulator *mem_acc_vreg)
466{
467 struct resource *res;
468 int len;
469
470 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "efuse_addr");
471 if (!res || !res->start) {
472 mem_acc_vreg->efuse_base = NULL;
473 pr_debug("'efuse_addr' resource missing or not used.\n");
474 return 0;
475 }
476
477 mem_acc_vreg->efuse_addr = res->start;
478 len = res->end - res->start + 1;
479
480 pr_info("efuse_addr = %pa (len=0x%x)\n", &res->start, len);
481
482 mem_acc_vreg->efuse_base = devm_ioremap(&pdev->dev,
483 mem_acc_vreg->efuse_addr, len);
484 if (!mem_acc_vreg->efuse_base) {
485 pr_err("Unable to map efuse_addr %pa\n",
486 &mem_acc_vreg->efuse_addr);
487 return -EINVAL;
488 }
489
490 return 0;
491}
492
493static int mem_acc_custom_data_init(struct platform_device *pdev,
494 struct mem_acc_regulator *mem_acc_vreg,
495 int mem_type)
496{
497 struct resource *res;
498 char *custom_apc_addr_str, *custom_apc_data_str;
499 int len, rc = 0;
500
501 switch (mem_type) {
502 case MEMORY_L1:
503 custom_apc_addr_str = "acc-l1-custom";
504 custom_apc_data_str = "qcom,l1-acc-custom-data";
505 break;
506 case MEMORY_L2:
507 custom_apc_addr_str = "acc-l2-custom";
508 custom_apc_data_str = "qcom,l2-acc-custom-data";
509 break;
510 default:
511 pr_err("Invalid memory type: %d\n", mem_type);
512 return -EINVAL;
513 }
514
515 if (!of_find_property(mem_acc_vreg->dev->of_node,
516 custom_apc_data_str, NULL)) {
517 pr_debug("%s custom_data not specified\n", custom_apc_data_str);
518 return 0;
519 }
520
521 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
522 custom_apc_addr_str);
523 if (!res || !res->start) {
524 pr_debug("%s resource missing\n", custom_apc_addr_str);
525 return -EINVAL;
526 }
527
528 len = res->end - res->start + 1;
529 mem_acc_vreg->acc_custom_addr[mem_type] =
530 devm_ioremap(mem_acc_vreg->dev, res->start, len);
531 if (!mem_acc_vreg->acc_custom_addr[mem_type]) {
532 pr_err("Unable to map %s %pa\n",
533 custom_apc_addr_str, &res->start);
534 return -EINVAL;
535 }
536
537 rc = populate_acc_data(mem_acc_vreg, custom_apc_data_str,
538 &mem_acc_vreg->acc_custom_data[mem_type], &len);
539 if (rc) {
540 pr_err("Unable to find %s rc=%d\n", custom_apc_data_str, rc);
541 return rc;
542 }
543
544 if (mem_acc_vreg->num_corners != len) {
545 pr_err("Custom data is not present for all the corners\n");
546 return -EINVAL;
547 }
548
549 mem_acc_vreg->mem_acc_custom_supported[mem_type] = true;
550
551 return 0;
552}
553
Tirupathi Reddya1cacb42016-10-25 12:35:22 +0530554static int override_mem_acc_custom_data(struct mem_acc_regulator *mem_acc_vreg,
555 int mem_type)
David Collins7370f1a2017-01-18 16:21:53 -0800556{
557 char *custom_apc_data_str;
558 int len, rc = 0, i;
559 int tuple_count, tuple_match;
560 u32 index = 0, value = 0;
561
562 switch (mem_type) {
563 case MEMORY_L1:
564 custom_apc_data_str = "qcom,override-l1-acc-custom-data";
565 break;
566 case MEMORY_L2:
567 custom_apc_data_str = "qcom,override-l2-acc-custom-data";
568 break;
569 default:
570 pr_err("Invalid memory type: %d\n", mem_type);
571 return -EINVAL;
572 }
573
574 if (!of_find_property(mem_acc_vreg->dev->of_node,
575 custom_apc_data_str, &len)) {
576 pr_debug("%s not specified\n", custom_apc_data_str);
577 return 0;
578 }
579
580 if (mem_acc_vreg->override_map_count) {
581 if (mem_acc_vreg->override_map_match == FUSE_MAP_NO_MATCH)
582 return 0;
583 tuple_count = mem_acc_vreg->override_map_count;
584 tuple_match = mem_acc_vreg->override_map_match;
585 } else {
586 tuple_count = 1;
587 tuple_match = 0;
588 }
589
590 if (len != mem_acc_vreg->num_corners * tuple_count * sizeof(u32)) {
591 pr_err("%s length=%d is invalid\n", custom_apc_data_str, len);
592 return -EINVAL;
593 }
594
595 for (i = 0; i < mem_acc_vreg->num_corners; i++) {
596 index = (tuple_match * mem_acc_vreg->num_corners) + i;
597 rc = of_property_read_u32_index(mem_acc_vreg->dev->of_node,
598 custom_apc_data_str, index, &value);
599 if (rc) {
600 pr_err("Unable read %s index %u, rc=%d\n",
601 custom_apc_data_str, index, rc);
602 return rc;
603 }
604 mem_acc_vreg->acc_custom_data[mem_type][i] = value;
605 }
606
607 return 0;
608}
609
610static int mem_acc_override_corner_map(struct mem_acc_regulator *mem_acc_vreg)
611{
612 int len = 0, i, rc;
613 int tuple_count, tuple_match;
614 u32 index = 0, value = 0;
615 char *prop_str = "qcom,override-corner-acc-map";
616
617 if (!of_find_property(mem_acc_vreg->dev->of_node, prop_str, &len))
618 return 0;
619
620 if (mem_acc_vreg->override_map_count) {
621 if (mem_acc_vreg->override_map_match == FUSE_MAP_NO_MATCH)
622 return 0;
623 tuple_count = mem_acc_vreg->override_map_count;
624 tuple_match = mem_acc_vreg->override_map_match;
625 } else {
626 tuple_count = 1;
627 tuple_match = 0;
628 }
629
630 if (len != mem_acc_vreg->num_corners * tuple_count * sizeof(u32)) {
631 pr_err("%s length=%d is invalid\n", prop_str, len);
632 return -EINVAL;
633 }
634
635 for (i = 0; i < mem_acc_vreg->num_corners; i++) {
636 index = (tuple_match * mem_acc_vreg->num_corners) + i;
637 rc = of_property_read_u32_index(mem_acc_vreg->dev->of_node,
638 prop_str, index, &value);
639 if (rc) {
640 pr_err("Unable read %s index %u, rc=%d\n",
641 prop_str, index, rc);
642 return rc;
643 }
644 mem_acc_vreg->corner_acc_map[i] = value;
645 }
646
647 return 0;
648
649}
650
Tirupathi Reddya1cacb42016-10-25 12:35:22 +0530651static void mem_acc_read_efuse_param(struct mem_acc_regulator *mem_acc_vreg,
652 u32 *fuse_sel, int *val)
David Collins7370f1a2017-01-18 16:21:53 -0800653{
Tirupathi Reddya1cacb42016-10-25 12:35:22 +0530654 u64 fuse_bits;
655
656 fuse_bits = mem_acc_read_efuse_row(mem_acc_vreg, fuse_sel[0],
657 fuse_sel[3]);
658 /*
659 * fuse_sel[1] = LSB position in row (shift)
660 * fuse_sel[2] = num of bits (mask)
661 */
662 *val = (fuse_bits >> fuse_sel[1]) & ((1 << fuse_sel[2]) - 1);
663}
664
665#define FUSE_TUPLE_SIZE 4
666static int mem_acc_parse_override_fuse_version_map(
667 struct mem_acc_regulator *mem_acc_vreg)
668{
669 struct device_node *of_node = mem_acc_vreg->dev->of_node;
David Collins7370f1a2017-01-18 16:21:53 -0800670 int i, rc, tuple_size;
671 int len = 0;
672 u32 *tmp;
Tirupathi Reddya1cacb42016-10-25 12:35:22 +0530673 u32 fuse_sel[4];
674 char *prop_str;
David Collins7370f1a2017-01-18 16:21:53 -0800675
Tirupathi Reddya1cacb42016-10-25 12:35:22 +0530676 prop_str = "qcom,override-acc-fuse-sel";
677 rc = of_property_read_u32_array(of_node, prop_str, fuse_sel,
678 FUSE_TUPLE_SIZE);
679 if (rc < 0) {
680 pr_err("Read failed - %s rc=%d\n", prop_str, rc);
681 return rc;
David Collins7370f1a2017-01-18 16:21:53 -0800682 }
683
Tirupathi Reddya1cacb42016-10-25 12:35:22 +0530684 mem_acc_read_efuse_param(mem_acc_vreg, fuse_sel,
685 &mem_acc_vreg->override_fuse_value);
686
687 prop_str = "qcom,override-fuse-version-map";
688 if (!of_find_property(of_node, prop_str, &len))
689 return -EINVAL;
690
David Collins7370f1a2017-01-18 16:21:53 -0800691 tuple_size = 1;
692 mem_acc_vreg->override_map_count = len / (sizeof(u32) * tuple_size);
David Collins7370f1a2017-01-18 16:21:53 -0800693 if (len == 0 || len % (sizeof(u32) * tuple_size)) {
694 pr_err("%s length=%d is invalid\n", prop_str, len);
695 return -EINVAL;
696 }
697
698 tmp = kzalloc(len, GFP_KERNEL);
699 if (!tmp)
700 return -ENOMEM;
701
702 rc = of_property_read_u32_array(of_node, prop_str, tmp,
703 mem_acc_vreg->override_map_count * tuple_size);
704 if (rc) {
705 pr_err("could not read %s rc=%d\n", prop_str, rc);
706 goto done;
707 }
708
709 for (i = 0; i < mem_acc_vreg->override_map_count; i++) {
710 if (tmp[i * tuple_size] != mem_acc_vreg->override_fuse_value
711 && tmp[i * tuple_size] != FUSE_PARAM_MATCH_ANY) {
712 continue;
713 } else {
714 mem_acc_vreg->override_map_match = i;
715 break;
716 }
717 }
718
719 if (mem_acc_vreg->override_map_match != FUSE_MAP_NO_MATCH)
Tirupathi Reddya1cacb42016-10-25 12:35:22 +0530720 pr_info("override_fuse_val=%d, %s tuple match found: %d\n",
721 mem_acc_vreg->override_fuse_value, prop_str,
722 mem_acc_vreg->override_map_match);
David Collins7370f1a2017-01-18 16:21:53 -0800723 else
724 pr_err("%s tuple match not found\n", prop_str);
725
726done:
727 kfree(tmp);
728 return rc;
729}
730
Tirupathi Reddya1cacb42016-10-25 12:35:22 +0530731static int mem_acc_parse_override_fuse_version_range(
732 struct mem_acc_regulator *mem_acc_vreg)
733{
734 struct device_node *of_node = mem_acc_vreg->dev->of_node;
735 int i, j, rc, size, row_size;
736 int num_fuse_sel, len = 0;
737 u32 *tmp = NULL;
738 char *prop_str;
739 u32 *fuse_val, *fuse_sel;
740 char *buf = NULL;
741 int pos = 0, buflen;
742
743 prop_str = "qcom,override-acc-range-fuse-list";
744 if (!of_find_property(of_node, prop_str, &len)) {
745 pr_err("%s property is missing\n", prop_str);
746 return -EINVAL;
747 }
748
749 size = len / sizeof(u32);
750 if (len == 0 || (size % FUSE_TUPLE_SIZE)) {
751 pr_err("%s property length (%d) is invalid\n", prop_str, len);
752 return -EINVAL;
753 }
754
755 num_fuse_sel = size / FUSE_TUPLE_SIZE;
756 fuse_val = devm_kcalloc(mem_acc_vreg->dev, num_fuse_sel,
757 sizeof(*fuse_val), GFP_KERNEL);
758 if (!fuse_val)
759 return -ENOMEM;
760 mem_acc_vreg->override_acc_range_fuse_list = fuse_val;
761 mem_acc_vreg->override_acc_range_fuse_num = num_fuse_sel;
762
763 fuse_sel = kzalloc(len, GFP_KERNEL);
764 if (!fuse_sel) {
765 rc = -ENOMEM;
766 goto done;
767 }
768
769 rc = of_property_read_u32_array(of_node, prop_str, fuse_sel,
770 size);
771 if (rc) {
772 pr_err("%s read failed, rc=%d\n", prop_str, rc);
773 goto done;
774 }
775
776 for (i = 0; i < num_fuse_sel; i++) {
777 mem_acc_read_efuse_param(mem_acc_vreg, &fuse_sel[i * 4],
778 &fuse_val[i]);
779 }
780
781 prop_str = "qcom,override-fuse-range-map";
782 if (!of_find_property(of_node, prop_str, &len))
783 goto done;
784
785 row_size = num_fuse_sel * 2;
786 mem_acc_vreg->override_map_count = len / (sizeof(u32) * row_size);
787
788 if (len == 0 || len % (sizeof(u32) * row_size)) {
789 pr_err("%s length=%d is invalid\n", prop_str, len);
790 rc = -EINVAL;
791 goto done;
792 }
793
794 tmp = kzalloc(len, GFP_KERNEL);
795 if (!tmp) {
796 rc = -ENOMEM;
797 goto done;
798 }
799
800 rc = of_property_read_u32_array(of_node, prop_str, tmp,
801 mem_acc_vreg->override_map_count * row_size);
802 if (rc) {
803 pr_err("could not read %s rc=%d\n", prop_str, rc);
804 goto done;
805 }
806
807 for (i = 0; i < mem_acc_vreg->override_map_count; i++) {
808 for (j = 0; j < num_fuse_sel; j++) {
809 if (tmp[i * row_size + j * 2] > fuse_val[j]
810 || tmp[i * row_size + j * 2 + 1] < fuse_val[j])
811 break;
812 }
813
814 if (j == num_fuse_sel) {
815 mem_acc_vreg->override_map_match = i;
816 break;
817 }
818 }
819
820 /*
821 * Log register and value mapping since they are useful for
822 * baseline MEM ACC logging.
823 */
824 buflen = num_fuse_sel * sizeof("fuse_selxxxx = XXXX ");
825 buf = kzalloc(buflen, GFP_KERNEL);
826 if (!buf)
827 goto done;
828
829 for (j = 0; j < num_fuse_sel; j++)
830 pos += scnprintf(buf + pos, buflen - pos, "fuse_sel%d = %d ",
831 j, fuse_val[j]);
832 buf[pos] = '\0';
833 if (mem_acc_vreg->override_map_match != FUSE_MAP_NO_MATCH)
834 pr_info("%s %s tuple match found: %d\n", buf, prop_str,
835 mem_acc_vreg->override_map_match);
836 else
837 pr_err("%s %s tuple match not found\n", buf, prop_str);
838
839done:
840 kfree(fuse_sel);
841 kfree(tmp);
842 kfree(buf);
843 return rc;
844}
845
David Collins7370f1a2017-01-18 16:21:53 -0800846#define MAX_CHARS_PER_INT 20
847
848static int mem_acc_reg_addr_val_dump(struct mem_acc_regulator *mem_acc_vreg,
849 struct corner_acc_reg_config *corner_acc_reg_config,
850 u32 corner)
851{
852 int i, k, index, pos = 0;
853 u32 addr_index;
854 size_t buflen;
855 char *buf;
856 struct acc_reg_value *reg_config_list =
857 corner_acc_reg_config->reg_config_list;
858 int max_reg_config_len = corner_acc_reg_config->max_reg_config_len;
859 int num_corners = mem_acc_vreg->num_corners;
860
861 /*
862 * Log register and value mapping since they are useful for
863 * baseline MEM ACC logging.
864 */
865 buflen = max_reg_config_len * (MAX_CHARS_PER_INT + 6) * sizeof(*buf);
866 buf = kzalloc(buflen, GFP_KERNEL);
867 if (buf == NULL) {
868 pr_err("Could not allocate memory for acc register and value logging\n");
869 return -ENOMEM;
870 }
871
872 for (i = 0; i < num_corners; i++) {
873 if (corner == i + 1)
874 continue;
875
876 pr_debug("Corner: %d --> %d:\n", corner, i + 1);
877 pos = 0;
878 for (k = 0; k < max_reg_config_len; k++) {
879 index = i * max_reg_config_len + k;
880 addr_index = reg_config_list[index].addr_index;
881 if (addr_index == PARAM_MATCH_ANY)
882 break;
883
884 pos += scnprintf(buf + pos, buflen - pos,
885 "<0x%x 0x%x> ",
886 mem_acc_vreg->phys_reg_addr_list[addr_index],
887 reg_config_list[index].reg_val);
888 }
889 buf[pos] = '\0';
890 pr_debug("%s\n", buf);
891 }
892
893 kfree(buf);
894 return 0;
895}
896
897static int mem_acc_get_reg_addr_val(struct device_node *of_node,
898 const char *prop_str, struct acc_reg_value *reg_config_list,
899 int list_offset, int list_size, u32 max_reg_index)
900{
901
902 int i, index, rc = 0;
903
904 for (i = 0; i < list_size / 2; i++) {
905 index = (list_offset * list_size) + i * 2;
906 rc = of_property_read_u32_index(of_node, prop_str, index,
907 &reg_config_list[i].addr_index);
908 rc |= of_property_read_u32_index(of_node, prop_str, index + 1,
909 &reg_config_list[i].reg_val);
910 if (rc) {
911 pr_err("could not read %s at tuple %u: rc=%d\n",
912 prop_str, index, rc);
913 return rc;
914 }
915
916 if (reg_config_list[i].addr_index == PARAM_MATCH_ANY)
917 continue;
918
919 if ((!reg_config_list[i].addr_index) ||
920 reg_config_list[i].addr_index > max_reg_index) {
921 pr_err("Invalid register index %u in %s at tuple %u\n",
922 reg_config_list[i].addr_index, prop_str, index);
923 return -EINVAL;
924 }
925 }
926
927 return rc;
928}
929
Tirupathi Reddya1cacb42016-10-25 12:35:22 +0530930static int mem_acc_override_reg_addr_val_init(
931 struct mem_acc_regulator *mem_acc_vreg)
932{
933 struct device_node *of_node = mem_acc_vreg->dev->of_node;
934 struct corner_acc_reg_config *corner_acc_reg_config;
935 struct acc_reg_value *override_reg_config_list;
936 int i, tuple_count, tuple_match, len = 0, rc = 0;
937 u32 list_size, override_max_reg_config_len;
938 char prop_str[40];
939 struct property *prop;
940 int num_corners = mem_acc_vreg->num_corners;
941
942 if (!mem_acc_vreg->corner_acc_reg_config)
943 return 0;
944
945 if (mem_acc_vreg->override_map_count) {
946 if (mem_acc_vreg->override_map_match == FUSE_MAP_NO_MATCH)
947 return 0;
948 tuple_count = mem_acc_vreg->override_map_count;
949 tuple_match = mem_acc_vreg->override_map_match;
950 } else {
951 tuple_count = 1;
952 tuple_match = 0;
953 }
954
955 corner_acc_reg_config = mem_acc_vreg->corner_acc_reg_config;
956 for (i = 1; i <= num_corners; i++) {
957 snprintf(prop_str, sizeof(prop_str),
958 "qcom,override-corner%d-addr-val-map", i);
959 prop = of_find_property(of_node, prop_str, &len);
960 list_size = len / (tuple_count * sizeof(u32));
961 if (!prop) {
962 pr_debug("%s property not specified\n", prop_str);
963 continue;
964 }
965
966 if ((!list_size) || list_size < (num_corners * 2)) {
967 pr_err("qcom,override-corner%d-addr-val-map property is missed or invalid length: len=%d\n",
968 i, len);
969 return -EINVAL;
970 }
971
972 override_max_reg_config_len = list_size / (num_corners * 2);
973 override_reg_config_list =
974 corner_acc_reg_config[i].reg_config_list;
975
976 if (corner_acc_reg_config[i].max_reg_config_len
977 != override_max_reg_config_len) {
978 /* Free already allocate memory */
979 devm_kfree(mem_acc_vreg->dev, override_reg_config_list);
980
981 /* Allocated memory for new requirement */
982 override_reg_config_list =
983 devm_kcalloc(mem_acc_vreg->dev,
984 override_max_reg_config_len * num_corners,
985 sizeof(*override_reg_config_list), GFP_KERNEL);
986 if (!override_reg_config_list)
987 return -ENOMEM;
988
989 corner_acc_reg_config[i].max_reg_config_len =
990 override_max_reg_config_len;
991 corner_acc_reg_config[i].reg_config_list =
992 override_reg_config_list;
993 }
994
995 rc = mem_acc_get_reg_addr_val(of_node, prop_str,
996 override_reg_config_list, tuple_match,
997 list_size, mem_acc_vreg->num_acc_reg);
998 if (rc) {
999 pr_err("Failed to read %s property: rc=%d\n",
1000 prop_str, rc);
1001 return rc;
1002 }
1003
1004 rc = mem_acc_reg_addr_val_dump(mem_acc_vreg,
1005 &corner_acc_reg_config[i], i);
1006 if (rc) {
1007 pr_err("could not dump acc address-value dump for corner=%d: rc=%d\n",
1008 i, rc);
1009 return rc;
1010 }
1011 }
1012
1013 return rc;
1014}
1015
1016static int mem_acc_parse_override_config(struct mem_acc_regulator *mem_acc_vreg)
1017{
1018 struct device_node *of_node = mem_acc_vreg->dev->of_node;
1019 int i, rc = 0;
1020
1021 /* Specify default no match case. */
1022 mem_acc_vreg->override_map_match = FUSE_MAP_NO_MATCH;
1023 mem_acc_vreg->override_map_count = 0;
1024
1025 if (of_find_property(of_node, "qcom,override-fuse-range-map",
1026 NULL)) {
1027 rc = mem_acc_parse_override_fuse_version_range(mem_acc_vreg);
1028 if (rc) {
1029 pr_err("parsing qcom,override-fuse-range-map property failed, rc=%d\n",
1030 rc);
1031 return rc;
1032 }
1033 } else if (of_find_property(of_node, "qcom,override-fuse-version-map",
1034 NULL)) {
1035 rc = mem_acc_parse_override_fuse_version_map(mem_acc_vreg);
1036 if (rc) {
1037 pr_err("parsing qcom,override-fuse-version-map property failed, rc=%d\n",
1038 rc);
1039 return rc;
1040 }
1041 } else {
1042 /* No override fuse configuration defined in device node */
1043 return 0;
1044 }
1045
1046 if (mem_acc_vreg->override_map_match == FUSE_MAP_NO_MATCH)
1047 return 0;
1048
1049 rc = mem_acc_override_corner_map(mem_acc_vreg);
1050 if (rc) {
1051 pr_err("Unable to override corner map rc=%d\n", rc);
1052 return rc;
1053 }
1054
1055 rc = mem_acc_override_reg_addr_val_init(mem_acc_vreg);
1056 if (rc) {
1057 pr_err("Unable to override reg_config_list init rc=%d\n",
1058 rc);
1059 return rc;
1060 }
1061
1062 for (i = 0; i < MEMORY_MAX; i++) {
1063 rc = override_mem_acc_custom_data(mem_acc_vreg, i);
1064 if (rc) {
1065 pr_err("Unable to override custom data for mem_type=%d rc=%d\n",
1066 i, rc);
1067 return rc;
1068 }
1069 }
1070
1071 return rc;
1072}
1073
David Collins7370f1a2017-01-18 16:21:53 -08001074static int mem_acc_init_reg_config(struct mem_acc_regulator *mem_acc_vreg)
1075{
1076 struct device_node *of_node = mem_acc_vreg->dev->of_node;
1077 int i, size, len = 0, rc = 0;
1078 u32 addr_index, reg_val, index;
1079 char *prop_str = "qcom,acc-init-reg-config";
1080
1081 if (!of_find_property(of_node, prop_str, &len)) {
1082 /* Initial acc register configuration not specified */
1083 return rc;
1084 }
1085
1086 size = len / sizeof(u32);
1087 if ((!size) || (size % 2)) {
1088 pr_err("%s specified with invalid length: %d\n",
1089 prop_str, size);
1090 return -EINVAL;
1091 }
1092
1093 for (i = 0; i < size / 2; i++) {
1094 index = i * 2;
1095 rc = of_property_read_u32_index(of_node, prop_str, index,
1096 &addr_index);
1097 rc |= of_property_read_u32_index(of_node, prop_str, index + 1,
1098 &reg_val);
1099 if (rc) {
1100 pr_err("could not read %s at tuple %u: rc=%d\n",
1101 prop_str, index, rc);
1102 return rc;
1103 }
1104
1105 if ((!addr_index) || addr_index > mem_acc_vreg->num_acc_reg) {
1106 pr_err("Invalid register index %u in %s at tuple %u\n",
1107 addr_index, prop_str, index);
1108 return -EINVAL;
1109 }
1110
1111 writel_relaxed(reg_val,
1112 mem_acc_vreg->remap_reg_addr_list[addr_index]);
1113 /* make sure write complete */
1114 mb();
1115
1116 pr_debug("acc initial config: register:0x%x value:0x%x\n",
1117 mem_acc_vreg->phys_reg_addr_list[addr_index], reg_val);
1118 }
1119
1120 return rc;
1121}
1122
1123static int mem_acc_get_reg_addr(struct mem_acc_regulator *mem_acc_vreg)
1124{
1125 struct device_node *of_node = mem_acc_vreg->dev->of_node;
1126 void __iomem **remap_reg_addr_list;
1127 u32 *phys_reg_addr_list;
1128 int i, num_acc_reg, len = 0, rc = 0;
1129
1130 if (!of_find_property(of_node, "qcom,acc-reg-addr-list", &len)) {
1131 /* acc register address list not specified */
1132 return rc;
1133 }
1134
1135 num_acc_reg = len / sizeof(u32);
1136 if (!num_acc_reg) {
1137 pr_err("qcom,acc-reg-addr-list has invalid len = %d\n", len);
1138 return -EINVAL;
1139 }
1140
1141 phys_reg_addr_list = devm_kcalloc(mem_acc_vreg->dev, num_acc_reg + 1,
1142 sizeof(*phys_reg_addr_list), GFP_KERNEL);
1143 if (!phys_reg_addr_list)
1144 return -ENOMEM;
1145
1146 remap_reg_addr_list = devm_kcalloc(mem_acc_vreg->dev, num_acc_reg + 1,
1147 sizeof(*remap_reg_addr_list), GFP_KERNEL);
1148 if (!remap_reg_addr_list)
1149 return -ENOMEM;
1150
1151 rc = of_property_read_u32_array(of_node, "qcom,acc-reg-addr-list",
1152 &phys_reg_addr_list[1], num_acc_reg);
1153 if (rc) {
1154 pr_err("Read- qcom,acc-reg-addr-list failed: rc=%d\n", rc);
1155 return rc;
1156 }
1157
1158 for (i = 1; i <= num_acc_reg; i++) {
1159 remap_reg_addr_list[i] = devm_ioremap(mem_acc_vreg->dev,
1160 phys_reg_addr_list[i], 0x4);
1161 if (!remap_reg_addr_list[i]) {
1162 pr_err("Unable to map register address 0x%x\n",
1163 phys_reg_addr_list[i]);
1164 return -EINVAL;
1165 }
1166 }
1167
1168 mem_acc_vreg->num_acc_reg = num_acc_reg;
1169 mem_acc_vreg->phys_reg_addr_list = phys_reg_addr_list;
1170 mem_acc_vreg->remap_reg_addr_list = remap_reg_addr_list;
1171
1172 return rc;
1173}
1174
1175static int mem_acc_reg_config_init(struct mem_acc_regulator *mem_acc_vreg)
1176{
1177 struct device_node *of_node = mem_acc_vreg->dev->of_node;
1178 struct acc_reg_value *reg_config_list;
1179 int len, size, rc, i, num_corners;
1180 struct property *prop;
1181 char prop_str[30];
1182 struct corner_acc_reg_config *corner_acc_reg_config;
1183
1184 rc = of_property_read_u32(of_node, "qcom,num-acc-corners",
1185 &num_corners);
1186 if (rc) {
1187 pr_err("could not read qcom,num-acc-corners: rc=%d\n", rc);
1188 return rc;
1189 }
1190
1191 mem_acc_vreg->num_corners = num_corners;
1192
1193 rc = of_property_read_u32(of_node, "qcom,boot-acc-corner",
1194 &mem_acc_vreg->corner);
1195 if (rc) {
1196 pr_err("could not read qcom,boot-acc-corner: rc=%d\n", rc);
1197 return rc;
1198 }
1199 pr_debug("boot acc corner = %d\n", mem_acc_vreg->corner);
1200
1201 corner_acc_reg_config = devm_kcalloc(mem_acc_vreg->dev, num_corners + 1,
1202 sizeof(*corner_acc_reg_config),
1203 GFP_KERNEL);
1204 if (!corner_acc_reg_config)
1205 return -ENOMEM;
1206
1207 for (i = 1; i <= num_corners; i++) {
1208 snprintf(prop_str, sizeof(prop_str),
1209 "qcom,corner%d-reg-config", i);
1210 prop = of_find_property(of_node, prop_str, &len);
1211 size = len / sizeof(u32);
1212 if ((!prop) || (!size) || size < (num_corners * 2)) {
1213 pr_err("%s property is missed or invalid length: len=%d\n",
1214 prop_str, len);
1215 return -EINVAL;
1216 }
1217
1218 reg_config_list = devm_kcalloc(mem_acc_vreg->dev, size / 2,
1219 sizeof(*reg_config_list), GFP_KERNEL);
1220 if (!reg_config_list)
1221 return -ENOMEM;
1222
1223 rc = mem_acc_get_reg_addr_val(of_node, prop_str,
1224 reg_config_list, 0, size,
1225 mem_acc_vreg->num_acc_reg);
1226 if (rc) {
1227 pr_err("Failed to read %s property: rc=%d\n",
1228 prop_str, rc);
1229 return rc;
1230 }
1231
1232 corner_acc_reg_config[i].max_reg_config_len =
1233 size / (num_corners * 2);
1234 corner_acc_reg_config[i].reg_config_list = reg_config_list;
1235
1236 rc = mem_acc_reg_addr_val_dump(mem_acc_vreg,
1237 &corner_acc_reg_config[i], i);
1238 if (rc) {
1239 pr_err("could not dump acc address-value dump for corner=%d: rc=%d\n",
1240 i, rc);
1241 return rc;
1242 }
1243 }
1244
1245 mem_acc_vreg->corner_acc_reg_config = corner_acc_reg_config;
1246 mem_acc_vreg->flags |= MEM_ACC_USE_ADDR_VAL_MAP;
1247 return rc;
1248}
1249
David Collins7370f1a2017-01-18 16:21:53 -08001250#define MEM_TYPE_STRING_LEN 20
1251static int mem_acc_init(struct platform_device *pdev,
1252 struct mem_acc_regulator *mem_acc_vreg)
1253{
1254 struct device_node *of_node = pdev->dev.of_node;
1255 struct resource *res;
1256 int len, rc, i, j;
David Collins7370f1a2017-01-18 16:21:53 -08001257 bool acc_type_present = false;
1258 char tmps[MEM_TYPE_STRING_LEN];
1259
1260 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acc-en");
1261 if (!res || !res->start) {
1262 pr_debug("'acc-en' resource missing or not used.\n");
1263 } else {
1264 mem_acc_vreg->acc_en_addr = res->start;
1265 len = res->end - res->start + 1;
1266 pr_debug("'acc_en_addr' = %pa (len=0x%x)\n", &res->start, len);
1267
1268 mem_acc_vreg->acc_en_base = devm_ioremap(mem_acc_vreg->dev,
1269 mem_acc_vreg->acc_en_addr, len);
1270 if (!mem_acc_vreg->acc_en_base) {
1271 pr_err("Unable to map 'acc_en_addr' %pa\n",
1272 &mem_acc_vreg->acc_en_addr);
1273 return -EINVAL;
1274 }
1275
1276 rc = populate_acc_data(mem_acc_vreg, "qcom,acc-en-bit-pos",
1277 &mem_acc_vreg->acc_en_bit_pos,
1278 &mem_acc_vreg->num_acc_en);
1279 if (rc) {
1280 pr_err("Unable to populate 'qcom,acc-en-bit-pos' rc=%d\n",
1281 rc);
1282 return rc;
1283 }
1284 }
1285
1286 rc = mem_acc_efuse_init(pdev, mem_acc_vreg);
1287 if (rc) {
1288 pr_err("Wrong eFuse address specified: rc=%d\n", rc);
1289 return rc;
1290 }
1291
1292 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acc-sel-l1");
1293 if (!res || !res->start) {
1294 pr_debug("'acc-sel-l1' resource missing or not used.\n");
1295 } else {
1296 rc = mem_acc_sel_setup(mem_acc_vreg, res, MEMORY_L1);
1297 if (rc) {
1298 pr_err("Unable to setup mem-acc for mem_type=%d rc=%d\n",
1299 MEMORY_L1, rc);
1300 return rc;
1301 }
1302 mem_acc_vreg->mem_acc_supported[MEMORY_L1] = true;
1303 }
1304
1305 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acc-sel-l2");
1306 if (!res || !res->start) {
1307 pr_debug("'acc-sel-l2' resource missing or not used.\n");
1308 } else {
1309 rc = mem_acc_sel_setup(mem_acc_vreg, res, MEMORY_L2);
1310 if (rc) {
1311 pr_err("Unable to setup mem-acc for mem_type=%d rc=%d\n",
1312 MEMORY_L2, rc);
1313 return rc;
1314 }
1315 mem_acc_vreg->mem_acc_supported[MEMORY_L2] = true;
1316 }
1317
1318 for (i = 0; i < MEM_ACC_TYPE_MAX; i++) {
1319 snprintf(tmps, MEM_TYPE_STRING_LEN, "mem-acc-type%d", i + 1);
1320 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, tmps);
1321
1322 if (!res || !res->start) {
1323 pr_debug("'%s' resource missing or not used.\n", tmps);
1324 } else {
1325 mem_acc_vreg->mem_acc_type_addr[i] = res->start;
1326 acc_type_present = true;
1327 }
1328 }
1329
1330 rc = mem_acc_get_reg_addr(mem_acc_vreg);
1331 if (rc) {
1332 pr_err("Unable to get acc register addresses: rc=%d\n", rc);
1333 return rc;
1334 }
1335
1336 if (mem_acc_vreg->phys_reg_addr_list) {
1337 rc = mem_acc_reg_config_init(mem_acc_vreg);
1338 if (rc) {
1339 pr_err("acc register address-value map failed: rc=%d\n",
1340 rc);
1341 return rc;
1342 }
1343 }
1344
1345 if (of_find_property(of_node, "qcom,corner-acc-map", NULL)) {
1346 rc = populate_acc_data(mem_acc_vreg, "qcom,corner-acc-map",
1347 &mem_acc_vreg->corner_acc_map,
1348 &mem_acc_vreg->num_corners);
1349
1350 /* Check if at least one valid mem-acc config. is specified */
1351 for (i = 0; i < MEMORY_MAX; i++) {
1352 if (mem_acc_vreg->mem_acc_supported[i])
1353 break;
1354 }
1355 if (i == MEMORY_MAX && !acc_type_present) {
1356 pr_err("No mem-acc configuration specified\n");
1357 return -EINVAL;
1358 }
1359
1360 mem_acc_vreg->flags |= MEM_ACC_USE_CORNER_ACC_MAP;
1361 }
1362
1363 if ((mem_acc_vreg->flags & MEM_ACC_USE_CORNER_ACC_MAP) &&
1364 (mem_acc_vreg->flags & MEM_ACC_USE_ADDR_VAL_MAP)) {
1365 pr_err("Invalid configuration, both qcom,corner-acc-map and qcom,cornerX-addr-val-map specified\n");
1366 return -EINVAL;
1367 }
1368
1369 pr_debug("num_corners = %d\n", mem_acc_vreg->num_corners);
1370
1371 if (mem_acc_vreg->num_acc_en)
1372 mem_acc_en_init(mem_acc_vreg);
1373
1374 if (mem_acc_vreg->phys_reg_addr_list) {
1375 rc = mem_acc_init_reg_config(mem_acc_vreg);
1376 if (rc) {
1377 pr_err("acc initial register configuration failed: rc=%d\n",
1378 rc);
1379 return rc;
1380 }
1381 }
1382
1383 rc = mem_acc_sel_init(mem_acc_vreg);
1384 if (rc) {
1385 pr_err("Unable to initialize mem_acc_sel reg rc=%d\n", rc);
1386 return rc;
1387 }
1388
1389 for (i = 0; i < MEMORY_MAX; i++) {
1390 rc = mem_acc_custom_data_init(pdev, mem_acc_vreg, i);
1391 if (rc) {
1392 pr_err("Unable to initialize custom data for mem_type=%d rc=%d\n",
1393 i, rc);
1394 return rc;
1395 }
1396 }
1397
Tirupathi Reddya1cacb42016-10-25 12:35:22 +05301398 rc = mem_acc_parse_override_config(mem_acc_vreg);
1399 if (rc) {
1400 pr_err("Unable to parse mem acc override configuration, rc=%d\n",
1401 rc);
1402 return rc;
David Collins7370f1a2017-01-18 16:21:53 -08001403 }
David Collins7370f1a2017-01-18 16:21:53 -08001404 if (acc_type_present) {
1405 mem_acc_vreg->mem_acc_type_data = devm_kzalloc(
1406 mem_acc_vreg->dev, mem_acc_vreg->num_corners *
1407 MEM_ACC_TYPE_MAX * sizeof(u32), GFP_KERNEL);
1408
1409 if (!mem_acc_vreg->mem_acc_type_data) {
1410 pr_err("Unable to allocate memory for mem_acc_type\n");
1411 return -ENOMEM;
1412 }
1413
1414 for (i = 0; i < MEM_ACC_TYPE_MAX; i++) {
1415 if (mem_acc_vreg->mem_acc_type_addr[i]) {
1416 snprintf(tmps, MEM_TYPE_STRING_LEN,
1417 "qcom,mem-acc-type%d", i + 1);
1418
1419 j = i * mem_acc_vreg->num_corners;
1420 rc = of_property_read_u32_array(
1421 mem_acc_vreg->dev->of_node,
1422 tmps,
1423 &mem_acc_vreg->mem_acc_type_data[j],
1424 mem_acc_vreg->num_corners);
1425 if (rc) {
1426 pr_err("Unable to get property %s rc=%d\n",
1427 tmps, rc);
1428 return rc;
1429 }
1430 }
1431 }
1432 }
1433
1434 return 0;
1435}
1436
1437static int mem_acc_regulator_probe(struct platform_device *pdev)
1438{
1439 struct regulator_config reg_config = {};
1440 struct mem_acc_regulator *mem_acc_vreg;
1441 struct regulator_desc *rdesc;
1442 struct regulator_init_data *init_data;
1443 int rc;
1444
1445 if (!pdev->dev.of_node) {
1446 pr_err("Device tree node is missing\n");
1447 return -EINVAL;
1448 }
1449
1450 init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
1451 NULL);
1452 if (!init_data) {
1453 pr_err("regulator init data is missing\n");
1454 return -EINVAL;
1455 }
1456
1457 init_data->constraints.input_uV = init_data->constraints.max_uV;
1458 init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE;
1459
1460 mem_acc_vreg = devm_kzalloc(&pdev->dev, sizeof(*mem_acc_vreg),
1461 GFP_KERNEL);
1462 if (!mem_acc_vreg)
1463 return -ENOMEM;
1464
1465 mem_acc_vreg->dev = &pdev->dev;
1466
1467 rc = mem_acc_init(pdev, mem_acc_vreg);
1468 if (rc) {
1469 pr_err("Unable to initialize mem_acc configuration rc=%d\n",
1470 rc);
1471 return rc;
1472 }
1473
1474 rdesc = &mem_acc_vreg->rdesc;
1475 rdesc->owner = THIS_MODULE;
1476 rdesc->type = REGULATOR_VOLTAGE;
1477 rdesc->ops = &mem_acc_corner_ops;
1478 rdesc->name = init_data->constraints.name;
1479
1480 reg_config.dev = &pdev->dev;
1481 reg_config.init_data = init_data;
1482 reg_config.driver_data = mem_acc_vreg;
1483 reg_config.of_node = pdev->dev.of_node;
1484 mem_acc_vreg->rdev = regulator_register(rdesc, &reg_config);
1485 if (IS_ERR(mem_acc_vreg->rdev)) {
1486 rc = PTR_ERR(mem_acc_vreg->rdev);
1487 if (rc != -EPROBE_DEFER)
1488 pr_err("regulator_register failed: rc=%d\n", rc);
1489 return rc;
1490 }
1491
1492 platform_set_drvdata(pdev, mem_acc_vreg);
1493
1494 return 0;
1495}
1496
1497static int mem_acc_regulator_remove(struct platform_device *pdev)
1498{
1499 struct mem_acc_regulator *mem_acc_vreg = platform_get_drvdata(pdev);
1500
1501 regulator_unregister(mem_acc_vreg->rdev);
1502
1503 return 0;
1504}
1505
1506static const struct of_device_id mem_acc_regulator_match_table[] = {
1507 { .compatible = "qcom,mem-acc-regulator", },
1508 {}
1509};
1510
1511static struct platform_driver mem_acc_regulator_driver = {
1512 .probe = mem_acc_regulator_probe,
1513 .remove = mem_acc_regulator_remove,
1514 .driver = {
1515 .name = "qcom,mem-acc-regulator",
1516 .of_match_table = mem_acc_regulator_match_table,
1517 .owner = THIS_MODULE,
1518 },
1519};
1520
1521int __init mem_acc_regulator_init(void)
1522{
1523 return platform_driver_register(&mem_acc_regulator_driver);
1524}
1525postcore_initcall(mem_acc_regulator_init);
1526
1527static void __exit mem_acc_regulator_exit(void)
1528{
1529 platform_driver_unregister(&mem_acc_regulator_driver);
1530}
1531module_exit(mem_acc_regulator_exit);
1532
1533MODULE_DESCRIPTION("MEM-ACC-SEL regulator driver");
1534MODULE_LICENSE("GPL v2");