blob: b66285a2ed8cb7c99dd4048604be02495f08863c [file] [log] [blame]
Anirudh Ghayal6ece10a2014-01-10 16:44:46 +05301/* Copyright (c) 2014, 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/types.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/err.h>
19#include <linux/of.h>
20#include <linux/of_device.h>
21#include <linux/io.h>
22#include <linux/platform_device.h>
23#include <linux/regulator/driver.h>
24#include <linux/regulator/machine.h>
25#include <linux/regulator/of_regulator.h>
26
27#define MEM_ACC_SEL_MASK 0x3
28
29enum {
30 MEMORY_L1,
31 MEMORY_L2,
32 MEMORY_MAX,
33};
34
35struct mem_acc_regulator {
36 struct device *dev;
37 struct regulator_desc rdesc;
38 struct regulator_dev *rdev;
39
40 int corner;
41 bool mem_acc_supported[MEMORY_MAX];
42
43 u32 acc_sel_reg[MEMORY_MAX];
44 u32 *acc_sel_mask[MEMORY_MAX];
45 u32 *acc_sel_bit_pos[MEMORY_MAX];
46 u32 num_acc_sel[MEMORY_MAX];
47 u32 *acc_en_bit_pos;
48 u32 num_acc_en;
49 u32 *corner_acc_map;
50 u32 num_corners;
51
52 void __iomem *acc_sel_base[MEMORY_MAX];
53 void __iomem *acc_en_base;
54 phys_addr_t acc_sel_addr[MEMORY_MAX];
55 phys_addr_t acc_en_addr;
56};
57
58static inline u32 apc_to_acc_corner(struct mem_acc_regulator *mem_acc_vreg,
59 int corner)
60{
61 /*
62 * corner_acc_map maps the corner from index 0 and APC corner value
63 * starts from the value 1
64 */
65 return mem_acc_vreg->corner_acc_map[corner - 1];
66}
67
68static void __update_acc_sel(struct mem_acc_regulator *mem_acc_vreg,
69 int corner, int mem_type)
70{
71 u32 acc_data, i, bit, acc_corner;
72
73 acc_data = mem_acc_vreg->acc_sel_reg[mem_type];
74 for (i = 0; i < mem_acc_vreg->num_acc_sel[mem_type]; i++) {
75 bit = mem_acc_vreg->acc_sel_bit_pos[mem_type][i];
76 acc_data &= ~mem_acc_vreg->acc_sel_mask[mem_type][i];
77 acc_corner = apc_to_acc_corner(mem_acc_vreg, corner);
78 acc_data |= (acc_corner << bit) &
79 mem_acc_vreg->acc_sel_mask[mem_type][i];
80 }
81 pr_debug("corner=%d old_acc_sel=0x%02x new_acc_sel=0x%02x mem_type=%d\n",
82 corner, mem_acc_vreg->acc_sel_reg[mem_type],
83 acc_data, mem_type);
84 writel_relaxed(acc_data, mem_acc_vreg->acc_sel_base[mem_type]);
85 mem_acc_vreg->acc_sel_reg[mem_type] = acc_data;
86}
87
88static void update_acc_sel(struct mem_acc_regulator *mem_acc_vreg, int corner)
89{
90 int i;
91
92 for (i = 0; i < MEMORY_MAX; i++) {
93 if (mem_acc_vreg->mem_acc_supported[i])
94 __update_acc_sel(mem_acc_vreg, corner, i);
95 }
96}
97
98static int mem_acc_regulator_set_voltage(struct regulator_dev *rdev,
99 int corner, int corner_max, unsigned *selector)
100{
101 struct mem_acc_regulator *mem_acc_vreg = rdev_get_drvdata(rdev);
102 int i;
103
104 if (corner > mem_acc_vreg->num_corners) {
105 pr_err("Invalid corner=%d requested\n", corner);
106 return -EINVAL;
107 }
108
109 pr_debug("old corner=%d, new corner=%d\n",
110 mem_acc_vreg->corner, corner);
111
112 if (corner == mem_acc_vreg->corner)
113 return 0;
114
115 /* go up or down one level at a time */
116 if (corner > mem_acc_vreg->corner) {
117 for (i = mem_acc_vreg->corner + 1; i <= corner; i++) {
118 pr_debug("UP: to corner %d\n", i);
119 update_acc_sel(mem_acc_vreg, i);
120 }
121 } else {
122 for (i = mem_acc_vreg->corner - 1; i >= corner; i--) {
123 pr_debug("DOWN: to corner %d\n", i);
124 update_acc_sel(mem_acc_vreg, i);
125 }
126 }
127
128 pr_debug("new voltage corner set %d\n", corner);
129
130 mem_acc_vreg->corner = corner;
131
132 return 0;
133}
134
135static int mem_acc_regulator_get_voltage(struct regulator_dev *rdev)
136{
137 struct mem_acc_regulator *mem_acc_vreg = rdev_get_drvdata(rdev);
138
139 return mem_acc_vreg->corner;
140}
141
142static struct regulator_ops mem_acc_corner_ops = {
143 .set_voltage = mem_acc_regulator_set_voltage,
144 .get_voltage = mem_acc_regulator_get_voltage,
145};
146
147static int __mem_acc_sel_init(struct mem_acc_regulator *mem_acc_vreg,
148 int mem_type)
149{
150 int i;
151 u32 bit;
152
153 mem_acc_vreg->acc_sel_mask[mem_type] = devm_kzalloc(mem_acc_vreg->dev,
154 mem_acc_vreg->num_acc_sel[mem_type] * sizeof(u32), GFP_KERNEL);
155 if (!mem_acc_vreg->acc_sel_mask[mem_type]) {
156 pr_err("Unable to allocate memory for mem_type=%d\n", mem_type);
157 return -ENOMEM;
158 }
159
160 for (i = 0; i < mem_acc_vreg->num_acc_sel[mem_type]; i++) {
161 bit = mem_acc_vreg->acc_sel_bit_pos[mem_type][i];
162 mem_acc_vreg->acc_sel_mask[mem_type][i] =
163 MEM_ACC_SEL_MASK << bit;
164 }
165
166 mem_acc_vreg->acc_sel_reg[mem_type] =
167 readl_relaxed(mem_acc_vreg->acc_sel_base[mem_type]);
168
169 return 0;
170}
171
172static int mem_acc_sel_init(struct mem_acc_regulator *mem_acc_vreg)
173{
174 int i, rc;
175
176 for (i = 0; i < MEMORY_MAX; i++) {
177 if (mem_acc_vreg->mem_acc_supported[i]) {
178 rc = __mem_acc_sel_init(mem_acc_vreg, i);
179 if (rc) {
180 pr_err("Unable to intialize mem_type=%d rc=%d\n",
181 i, rc);
182 return rc;
183 }
184 }
185 }
186
187 return 0;
188}
189
190static void mem_acc_en_init(struct mem_acc_regulator *mem_acc_vreg)
191{
192 int i, bit;
193 u32 acc_data;
194
195 acc_data = readl_relaxed(mem_acc_vreg->acc_en_base);
196 pr_debug("init: acc_en_register=%x\n", acc_data);
197 for (i = 0; i < mem_acc_vreg->num_acc_en; i++) {
198 bit = mem_acc_vreg->acc_en_bit_pos[i];
199 acc_data |= BIT(bit);
200 }
201 pr_debug("final: acc_en_register=%x\n", acc_data);
202 writel_relaxed(acc_data, mem_acc_vreg->acc_en_base);
203}
204
205static int populate_acc_data(struct mem_acc_regulator *mem_acc_vreg,
206 const char *prop_name, u32 **value, u32 *len)
207{
208 int rc;
209
210 if (!of_get_property(mem_acc_vreg->dev->of_node, prop_name, len)) {
211 pr_err("Unable to find %s property\n", prop_name);
212 return -EINVAL;
213 }
214 *len /= sizeof(u32);
215 if (!(*len)) {
216 pr_err("Incorrect entries in %s\n", prop_name);
217 return -EINVAL;
218 }
219
220 *value = devm_kzalloc(mem_acc_vreg->dev, (*len) * sizeof(u32),
221 GFP_KERNEL);
222 if (!(*value)) {
223 pr_err("Unable to allocate memory for %s\n", prop_name);
224 return -ENOMEM;
225 }
226
227 pr_debug("Found %s, data-length = %d\n", prop_name, *len);
228
229 rc = of_property_read_u32_array(mem_acc_vreg->dev->of_node,
230 prop_name, *value, *len);
231 if (rc) {
232 pr_err("Unable to populate %s rc=%d\n", prop_name, rc);
233 return rc;
234 }
235
236 return 0;
237}
238
239static int mem_acc_sel_setup(struct mem_acc_regulator *mem_acc_vreg,
240 struct resource *res, int mem_type)
241{
242 int len, rc;
243 char *mem_select_str;
244
245 mem_acc_vreg->acc_sel_addr[mem_type] = res->start;
246 len = res->end - res->start + 1;
247 pr_debug("'acc_sel_addr' = %pa mem_type=%d (len=%d)\n",
248 &res->start, mem_type, len);
249
250 mem_acc_vreg->acc_sel_base[mem_type] = devm_ioremap(mem_acc_vreg->dev,
251 mem_acc_vreg->acc_sel_addr[mem_type], len);
252 if (!mem_acc_vreg->acc_sel_base[mem_type]) {
253 pr_err("Unable to map 'acc_sel_addr' %pa for mem_type=%d\n",
254 &mem_acc_vreg->acc_sel_addr[mem_type], mem_type);
255 return -EINVAL;
256 }
257
258 switch (mem_type) {
259 case MEMORY_L1:
260 mem_select_str = "qcom,acc-sel-l1-bit-pos";
261 break;
262 case MEMORY_L2:
263 mem_select_str = "qcom,acc-sel-l2-bit-pos";
264 break;
265 }
266
267 rc = populate_acc_data(mem_acc_vreg, mem_select_str,
268 &mem_acc_vreg->acc_sel_bit_pos[mem_type],
269 &mem_acc_vreg->num_acc_sel[mem_type]);
270 if (rc)
271 pr_err("Unable to populate '%s' rc=%d\n", mem_select_str, rc);
272
273 return rc;
274}
275
276static int mem_acc_init(struct platform_device *pdev,
277 struct mem_acc_regulator *mem_acc_vreg)
278{
279 struct resource *res;
280 int len, rc, i;
281
282 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acc-en");
283 if (!res || !res->start) {
284 pr_debug("'acc-en' resource missing or not used.\n");
285 } else {
286 mem_acc_vreg->acc_en_addr = res->start;
287 len = res->end - res->start + 1;
288 pr_debug("'acc_en_addr' = %pa (len=0x%x)\n", &res->start, len);
289
290 mem_acc_vreg->acc_en_base = devm_ioremap(mem_acc_vreg->dev,
291 mem_acc_vreg->acc_en_addr, len);
292 if (!mem_acc_vreg->acc_en_base) {
293 pr_err("Unable to map 'acc_en_addr' %pa\n",
294 &mem_acc_vreg->acc_en_addr);
295 return -EINVAL;
296 }
297
298 rc = populate_acc_data(mem_acc_vreg, "qcom,acc-en-bit-pos",
299 &mem_acc_vreg->acc_en_bit_pos,
300 &mem_acc_vreg->num_acc_en);
301 if (rc) {
302 pr_err("Unable to populate 'qcom,acc-en-bit-pos' rc=%d\n",
303 rc);
304 return rc;
305 }
306 }
307
308 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acc-sel-l1");
309 if (!res || !res->start) {
310 pr_debug("'acc-sel-l1' resource missing or not used.\n");
311 } else {
312 rc = mem_acc_sel_setup(mem_acc_vreg, res, MEMORY_L1);
313 if (rc) {
314 pr_err("Unable to setup mem-acc for mem_type=%d rc=%d\n",
315 MEMORY_L1, rc);
316 return rc;
317 }
318 mem_acc_vreg->mem_acc_supported[MEMORY_L1] = true;
319 }
320
321 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acc-sel-l2");
322 if (!res || !res->start) {
323 pr_debug("'acc-sel-l2' resource missing or not used.\n");
324 } else {
325 rc = mem_acc_sel_setup(mem_acc_vreg, res, MEMORY_L2);
326 if (rc) {
327 pr_err("Unable to setup mem-acc for mem_type=%d rc=%d\n",
328 MEMORY_L2, rc);
329 return rc;
330 }
331 mem_acc_vreg->mem_acc_supported[MEMORY_L2] = true;
332 }
333
334 rc = populate_acc_data(mem_acc_vreg, "qcom,corner-acc-map",
335 &mem_acc_vreg->corner_acc_map,
336 &mem_acc_vreg->num_corners);
337 if (rc) {
338 pr_err("Unable to find 'qcom,corner-acc-map' rc=%d\n", rc);
339 return rc;
340 }
341
342 pr_debug("num_corners = %d\n", mem_acc_vreg->num_corners);
343
344 /* Check if at least one valid mem-acc config. is specified */
345 for (i = 0; i < MEMORY_MAX; i++) {
346 if (mem_acc_vreg->mem_acc_supported[i])
347 break;
348 }
349 if (i == MEMORY_MAX) {
350 pr_err("No mem-acc configuration specified\n");
351 return -EINVAL;
352 }
353
354 if (mem_acc_vreg->num_acc_en)
355 mem_acc_en_init(mem_acc_vreg);
356
357 rc = mem_acc_sel_init(mem_acc_vreg);
358 if (rc) {
359 pr_err("Unable to intialize mem_acc_sel reg rc=%d\n", rc);
360 return rc;
361 }
362
363 return 0;
364}
365
366static int mem_acc_regulator_probe(struct platform_device *pdev)
367{
368 struct mem_acc_regulator *mem_acc_vreg;
369 struct regulator_desc *rdesc;
370 struct regulator_init_data *init_data;
371 int rc;
372
373 if (!pdev->dev.of_node) {
374 pr_err("Device tree node is missing\n");
375 return -EINVAL;
376 }
377
378 init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
379 if (!init_data) {
380 pr_err("regulator init data is missing\n");
381 return -EINVAL;
382 } else {
383 init_data->constraints.input_uV
384 = init_data->constraints.max_uV;
385 init_data->constraints.valid_ops_mask
386 |= REGULATOR_CHANGE_VOLTAGE;
387 }
388
389 mem_acc_vreg = devm_kzalloc(&pdev->dev, sizeof(*mem_acc_vreg),
390 GFP_KERNEL);
391 if (!mem_acc_vreg) {
392 pr_err("Can't allocate mem_acc_vreg memory\n");
393 return -ENOMEM;
394 }
395 mem_acc_vreg->dev = &pdev->dev;
396
397 rc = mem_acc_init(pdev, mem_acc_vreg);
398 if (rc) {
399 pr_err("Unable to initialize mem_acc configuration rc=%d\n",
400 rc);
401 return rc;
402 }
403
404 rdesc = &mem_acc_vreg->rdesc;
405 rdesc->owner = THIS_MODULE;
406 rdesc->type = REGULATOR_VOLTAGE;
407 rdesc->ops = &mem_acc_corner_ops;
408 rdesc->name = init_data->constraints.name;
409
410 mem_acc_vreg->rdev = regulator_register(rdesc, &pdev->dev,
411 init_data, mem_acc_vreg, pdev->dev.of_node);
412 if (IS_ERR(mem_acc_vreg->rdev)) {
413 rc = PTR_ERR(mem_acc_vreg->rdev);
414 if (rc != -EPROBE_DEFER)
415 pr_err("regulator_register failed: rc=%d\n", rc);
416 return rc;
417 }
418
419 platform_set_drvdata(pdev, mem_acc_vreg);
420
421 return 0;
422}
423
424static int mem_acc_regulator_remove(struct platform_device *pdev)
425{
426 struct mem_acc_regulator *mem_acc_vreg = platform_get_drvdata(pdev);
427
428 regulator_unregister(mem_acc_vreg->rdev);
429
430 return 0;
431}
432
433static struct of_device_id mem_acc_regulator_match_table[] = {
434 { .compatible = "qcom,mem-acc-regulator", },
435 {}
436};
437
438static struct platform_driver mem_acc_regulator_driver = {
439 .probe = mem_acc_regulator_probe,
440 .remove = mem_acc_regulator_remove,
441 .driver = {
442 .name = "qcom,mem-acc-regulator",
443 .of_match_table = mem_acc_regulator_match_table,
444 .owner = THIS_MODULE,
445 },
446};
447
448int __init mem_acc_regulator_init(void)
449{
450 return platform_driver_register(&mem_acc_regulator_driver);
451}
452postcore_initcall(mem_acc_regulator_init);
453
454static void __exit mem_acc_regulator_exit(void)
455{
456 platform_driver_unregister(&mem_acc_regulator_driver);
457}
458module_exit(mem_acc_regulator_exit);
459
460MODULE_DESCRIPTION("MEM-ACC-SEL regulator driver");
461MODULE_LICENSE("GPL v2");