blob: f7b2b1e80d6503fffc0b6c5d573c29324583d2bd [file] [log] [blame]
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001/* Copyright (c) 2012, Code Aurora Forum. 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
13#define pr_fmt(fmt) "%s: " fmt, __func__
14
15#include <linux/err.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/slab.h>
21#include <linux/string.h>
22#include <linux/io.h>
23#include <linux/of.h>
24#include <linux/of_device.h>
25#include <linux/platform_device.h>
26#include <linux/regulator/driver.h>
27#include <linux/regulator/machine.h>
28#include <linux/regulator/of_regulator.h>
29#include <linux/regulator/krait-regulator.h>
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -070030#include <mach/msm_iomap.h>
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070031
32#include "spm.h"
33
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070034/*
35 * supply
36 * from
37 * pmic
38 * gang
39 * | LDO BYP [6]
40 * | /
41 * | /
42 * |_______/ _____
43 * | |
44 * ___|___ |
45 * | | |
46 * | | /
47 * | LDO | /
48 * | | / BHS[6]
49 * |_______| |
50 * | |
51 * |________________|
52 * |
53 * ________|________
54 * | |
55 * | KRAIT |
56 * |_________________|
57 */
58
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070059#define PMIC_VOLTAGE_MIN 350000
60#define PMIC_VOLTAGE_MAX 1355000
61#define LV_RANGE_STEP 5000
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070062
63#define LOAD_PER_PHASE 3200000
64
Michael Bohan5daee152012-08-14 16:39:35 -070065#define CORE_VOLTAGE_MIN 900000
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070066
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070067#define KRAIT_LDO_VOLTAGE_MIN 465000
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -070068#define KRAIT_LDO_VOLTAGE_OFFSET 465000
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070069#define KRAIT_LDO_STEP 5000
70
71#define BHS_SETTLING_DELAY_US 1
72#define LDO_SETTLING_DELAY_US 1
73
74#define _KRAIT_MASK(BITS, POS) (((u32)(1 << (BITS)) - 1) << POS)
75#define KRAIT_MASK(LEFT_BIT_POS, RIGHT_BIT_POS) \
76 _KRAIT_MASK(LEFT_BIT_POS - RIGHT_BIT_POS + 1, RIGHT_BIT_POS)
77
78#define APC_SECURE 0x00000000
79#define CPU_PWR_CTL 0x00000004
80#define APC_PWR_STATUS 0x00000008
81#define APC_TEST_BUS_SEL 0x0000000C
82#define CPU_TRGTD_DBG_RST 0x00000010
83#define APC_PWR_GATE_CTL 0x00000014
84#define APC_LDO_VREF_SET 0x00000018
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -070085#define APC_PWR_GATE_MODE 0x0000001C
86#define APC_PWR_GATE_DLY 0x00000020
87
88#define PWR_GATE_CONFIG 0x00000044
89#define VERSION 0x00000FD0
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070090
91/* bit definitions for APC_PWR_GATE_CTL */
92#define BHS_CNT_BIT_POS 24
93#define BHS_CNT_MASK KRAIT_MASK(31, 24)
94#define BHS_CNT_DEFAULT 64
95
96#define CLK_SRC_SEL_BIT_POS 15
97#define CLK_SRC_SEL_MASK KRAIT_MASK(15, 15)
98#define CLK_SRC_DEFAULT 0
99
100#define LDO_PWR_DWN_BIT_POS 16
101#define LDO_PWR_DWN_MASK KRAIT_MASK(21, 16)
102
103#define LDO_BYP_BIT_POS 8
104#define LDO_BYP_MASK KRAIT_MASK(13, 8)
105
106#define BHS_SEG_EN_BIT_POS 1
107#define BHS_SEG_EN_MASK KRAIT_MASK(6, 1)
108#define BHS_SEG_EN_DEFAULT 0x3F
109
110#define BHS_EN_BIT_POS 0
111#define BHS_EN_MASK KRAIT_MASK(0, 0)
112
113/* bit definitions for APC_LDO_VREF_SET register */
114#define VREF_RET_POS 8
115#define VREF_RET_MASK KRAIT_MASK(14, 8)
116
117#define VREF_LDO_BIT_POS 0
118#define VREF_LDO_MASK KRAIT_MASK(6, 0)
119
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700120/**
121 * struct pmic_gang_vreg -
122 * @name: the string used to represent the gang
123 * @pmic_vmax_uV: the current pmic gang voltage
124 * @pmic_phase_count: the number of phases turned on in the gang
125 * @krait_power_vregs: a list of krait consumers this gang supplies to
126 * @krait_power_vregs_lock: lock to prevent simultaneous access to the list
127 * and its nodes. This needs to be taken by each
128 * regulator's callback functions to prevent
129 * simultaneous updates to the pmic's phase
130 * voltage.
131 */
132struct pmic_gang_vreg {
133 const char *name;
134 int pmic_vmax_uV;
135 int pmic_phase_count;
136 struct list_head krait_power_vregs;
137 struct mutex krait_power_vregs_lock;
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700138 bool pfm_mode;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700139};
140
141static struct pmic_gang_vreg *the_gang;
142
143enum krait_supply_mode {
144 HS_MODE = REGULATOR_MODE_NORMAL,
145 LDO_MODE = REGULATOR_MODE_IDLE,
146};
147
148struct krait_power_vreg {
149 struct list_head link;
150 struct regulator_desc desc;
151 struct regulator_dev *rdev;
152 const char *name;
153 struct pmic_gang_vreg *pvreg;
154 int uV;
155 int load_uA;
156 enum krait_supply_mode mode;
157 void __iomem *reg_base;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700158 int ldo_default_uV;
159 int retention_uV;
160 int headroom_uV;
161 int ldo_threshold_uV;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800162 bool online;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700163};
164
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700165static u32 version;
166
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700167static void krait_masked_write(struct krait_power_vreg *kvreg,
168 int reg, uint32_t mask, uint32_t val)
169{
170 uint32_t reg_val;
171
172 reg_val = readl_relaxed(kvreg->reg_base + reg);
173 reg_val &= ~mask;
174 reg_val |= (val & mask);
175 writel_relaxed(reg_val, kvreg->reg_base + reg);
176
177 /*
178 * Barrier to ensure that the reads and writes from
179 * other regulator regions (they are 1k apart) execute in
180 * order to the above write.
181 */
182 mb();
183}
184
185static int get_krait_ldo_uv(struct krait_power_vreg *kvreg)
186{
187 uint32_t reg_val;
188 int uV;
189
190 reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
191 reg_val &= VREF_LDO_MASK;
192 reg_val >>= VREF_LDO_BIT_POS;
193
194 if (reg_val == 0)
195 uV = 0;
196 else
197 uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
198
199 return uV;
200}
201
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700202static int set_krait_retention_uv(struct krait_power_vreg *kvreg, int uV)
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700203{
204 uint32_t reg_val;
205
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700206 reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
207 krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_RET_MASK,
208 reg_val << VREF_RET_POS);
209
210 return 0;
211}
212
213static int set_krait_ldo_uv(struct krait_power_vreg *kvreg, int uV)
214{
215 uint32_t reg_val;
216
217 reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700218 krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_LDO_MASK,
219 reg_val << VREF_LDO_BIT_POS);
220
221 return 0;
222}
223
224static int switch_to_using_hs(struct krait_power_vreg *kvreg)
225{
226 if (kvreg->mode == HS_MODE)
227 return 0;
228
229 /*
230 * enable ldo bypass - the krait is powered still by LDO since
231 * LDO is enabled and BHS is disabled
232 */
233 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_BYP_MASK, LDO_BYP_MASK);
234
235 /* enable bhs */
236 krait_masked_write(kvreg, APC_PWR_GATE_CTL, BHS_EN_MASK, BHS_EN_MASK);
237
238 /*
239 * wait for the bhs to settle - note that
240 * after the voltage has settled both BHS and LDO are supplying power
241 * to the krait. This avoids glitches during switching
242 */
243 udelay(BHS_SETTLING_DELAY_US);
244
245 /* disable ldo - only the BHS provides voltage to the cpu after this */
246 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
247 LDO_PWR_DWN_MASK, LDO_PWR_DWN_MASK);
248
249 kvreg->mode = HS_MODE;
250 return 0;
251}
252
253static int switch_to_using_ldo(struct krait_power_vreg *kvreg)
254{
255 if (kvreg->mode == LDO_MODE && get_krait_ldo_uv(kvreg) == kvreg->uV)
256 return 0;
257
258 /*
259 * if the krait is in ldo mode and a voltage change is requested on the
260 * ldo switch to using hs before changing ldo voltage
261 */
262 if (kvreg->mode == LDO_MODE)
263 switch_to_using_hs(kvreg);
264
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700265 set_krait_ldo_uv(kvreg, kvreg->uV);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700266
267 /*
268 * enable ldo - note that both LDO and BHS are are supplying voltage to
269 * the cpu after this. This avoids glitches during switching from BHS
270 * to LDO.
271 */
272 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_PWR_DWN_MASK, 0);
273
274 /* wait for the ldo to settle */
275 udelay(LDO_SETTLING_DELAY_US);
276
277 /*
278 * disable BHS and disable LDO bypass seperate from enabling
279 * the LDO above.
280 */
281 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
282 BHS_EN_MASK | LDO_BYP_MASK, 0);
283
284 kvreg->mode = LDO_MODE;
285 return 0;
286}
287
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700288static int set_pmic_gang_phases(int phase_count)
289{
Abhijeet Dharmapurikare4b89ee2012-08-07 18:53:53 -0700290 /*
291 * TODO : spm writes for phase control,
292 * pmic phase control is not working yet
293 */
294 return 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700295}
296
297static int set_pmic_gang_voltage(int uV)
298{
299 int setpoint;
300
301 if (uV < PMIC_VOLTAGE_MIN) {
302 pr_err("requested %d < %d, restricting it to %d\n",
303 uV, PMIC_VOLTAGE_MIN, PMIC_VOLTAGE_MIN);
304 uV = PMIC_VOLTAGE_MIN;
305 }
306 if (uV > PMIC_VOLTAGE_MAX) {
307 pr_err("requested %d > %d, restricting it to %d\n",
308 uV, PMIC_VOLTAGE_MAX, PMIC_VOLTAGE_MAX);
309 uV = PMIC_VOLTAGE_MAX;
310 }
311
Abhijeet Dharmapurikard4f38da2012-08-08 21:42:06 -0700312 setpoint = DIV_ROUND_UP(uV, LV_RANGE_STEP);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800313
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700314 return msm_spm_apcs_set_vdd(setpoint);
315}
316
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700317static int configure_ldo_or_hs(struct krait_power_vreg *from, int vmax)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700318{
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700319 struct pmic_gang_vreg *pvreg = from->pvreg;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700320 struct krait_power_vreg *kvreg;
321 int rc = 0;
322
323 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800324 if (!kvreg->online)
325 continue;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700326 if (kvreg->uV > kvreg->ldo_threshold_uV
327 || kvreg->uV > vmax - kvreg->headroom_uV) {
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700328 rc = switch_to_using_hs(kvreg);
329 if (rc < 0) {
330 pr_err("could not switch %s to hs rc = %d\n",
331 kvreg->name, rc);
332 return rc;
333 }
334 } else {
335 rc = switch_to_using_ldo(kvreg);
336 if (rc < 0) {
337 pr_err("could not switch %s to ldo rc = %d\n",
338 kvreg->name, rc);
339 return rc;
340 }
341 }
342 }
343
344 return rc;
345}
346
347#define SLEW_RATE 2994
348static int pmic_gang_set_voltage_increase(struct krait_power_vreg *from,
349 int vmax)
350{
351 struct pmic_gang_vreg *pvreg = from->pvreg;
352 int rc = 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700353 int settling_us;
354
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700355 /*
356 * since pmic gang voltage is increasing set the gang voltage
357 * prior to changing ldo/hs states of the requesting krait
358 */
359 rc = set_pmic_gang_voltage(vmax);
360 if (rc < 0) {
361 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
362 pvreg->name, vmax, rc);
363 }
364
365 /* delay until the voltage is settled when it is raised */
366 settling_us = DIV_ROUND_UP(vmax - pvreg->pmic_vmax_uV, SLEW_RATE);
367 udelay(settling_us);
368
369 rc = configure_ldo_or_hs(from, vmax);
370 if (rc < 0) {
371 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
372 pvreg->name, vmax, rc);
373 }
374
375 return rc;
376}
377
378static int pmic_gang_set_voltage_decrease(struct krait_power_vreg *from,
379 int vmax)
380{
381 struct pmic_gang_vreg *pvreg = from->pvreg;
382 int rc = 0;
383
384 /*
385 * since pmic gang voltage is decreasing ldos might get out of their
386 * operating range. Hence configure such kraits to be in hs mode prior
387 * to setting the pmic gang voltage
388 */
389 rc = configure_ldo_or_hs(from, vmax);
390 if (rc < 0) {
391 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
392 pvreg->name, vmax, rc);
393 return rc;
394 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700395
396 rc = set_pmic_gang_voltage(vmax);
397 if (rc < 0) {
398 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
399 pvreg->name, vmax, rc);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700400 }
401
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700402 return rc;
403}
404
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700405static int pmic_gang_set_voltage(struct krait_power_vreg *from,
406 int vmax)
407{
408 struct pmic_gang_vreg *pvreg = from->pvreg;
409
410 if (pvreg->pmic_vmax_uV == vmax)
411 return 0;
412 else if (vmax < pvreg->pmic_vmax_uV)
413 return pmic_gang_set_voltage_decrease(from, vmax);
414
415 return pmic_gang_set_voltage_increase(from, vmax);
416}
417
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700418#define PHASE_SETTLING_TIME_US 10
419static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
420 int load_uA)
421{
422 struct pmic_gang_vreg *pvreg = from->pvreg;
423 int phase_count = DIV_ROUND_UP(load_uA, LOAD_PER_PHASE) - 1;
424 int rc = 0;
425
426 if (phase_count < 0)
427 phase_count = 0;
428
429 if (phase_count != pvreg->pmic_phase_count) {
430 rc = set_pmic_gang_phases(phase_count);
431 if (rc < 0) {
432 dev_err(&from->rdev->dev,
433 "%s failed set phase %d rc = %d\n",
434 pvreg->name, phase_count, rc);
435 return rc;
436 }
437
438 /*
439 * delay until the phases are settled when
440 * the count is raised
441 */
442 if (phase_count > pvreg->pmic_phase_count)
443 udelay(PHASE_SETTLING_TIME_US);
444
445 pvreg->pmic_phase_count = phase_count;
446 }
447 return rc;
448}
449
Matt Wagantall98bfbe92012-11-12 18:39:47 -0800450static int __devinit pvreg_init(struct platform_device *pdev)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700451{
452 struct pmic_gang_vreg *pvreg;
453
454 pvreg = devm_kzalloc(&pdev->dev,
455 sizeof(struct pmic_gang_vreg), GFP_KERNEL);
456 if (!pvreg) {
457 pr_err("kzalloc failed.\n");
458 return -ENOMEM;
459 }
460
461 pvreg->name = "pmic_gang";
462 pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
463 pvreg->pmic_phase_count = 1;
464
465 mutex_init(&pvreg->krait_power_vregs_lock);
466 INIT_LIST_HEAD(&pvreg->krait_power_vregs);
467 the_gang = pvreg;
468
469 pr_debug("name=%s inited\n", pvreg->name);
470
471 return 0;
472}
473
474static int krait_power_get_voltage(struct regulator_dev *rdev)
475{
476 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
477
478 return kvreg->uV;
479}
480
481static int get_vmax(struct krait_power_vreg *from, int min_uV)
482{
483 int vmax = 0;
484 int v;
485 struct krait_power_vreg *kvreg;
486 struct pmic_gang_vreg *pvreg = from->pvreg;
487
488 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800489 if (!kvreg->online)
490 continue;
491
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700492 v = kvreg->uV;
493
494 if (kvreg == from)
495 v = min_uV;
496
497 if (vmax < v)
498 vmax = v;
499 }
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800500
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700501 return vmax;
502}
503
504static int get_total_load(struct krait_power_vreg *from)
505{
506 int load_total = 0;
507 struct krait_power_vreg *kvreg;
508 struct pmic_gang_vreg *pvreg = from->pvreg;
509
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800510 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
511 if (!kvreg->online)
512 continue;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700513 load_total += kvreg->load_uA;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800514 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700515
516 return load_total;
517}
518
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700519#define ROUND_UP_VOLTAGE(v, res) (DIV_ROUND_UP(v, res) * res)
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800520static int _set_voltage(struct regulator_dev *rdev,
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700521 int min_uV, int max_uV, unsigned *selector)
522{
523 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
524 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
525 int rc;
526 int vmax;
527
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800528 vmax = get_vmax(kvreg, min_uV);
529
530 /* round up the pmic voltage as per its resolution */
531 vmax = ROUND_UP_VOLTAGE(vmax, LV_RANGE_STEP);
532
533 rc = pmic_gang_set_voltage(kvreg, vmax);
534 if (rc < 0) {
535 dev_err(&rdev->dev, "%s failed set voltage (%d, %d) rc = %d\n",
536 kvreg->name, min_uV, max_uV, rc);
537 goto out;
538 }
539
540 pvreg->pmic_vmax_uV = vmax;
541
542out:
543 return rc;
544}
545
546static int krait_power_set_voltage(struct regulator_dev *rdev,
547 int min_uV, int max_uV, unsigned *selector)
548{
549 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
550 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
551 int rc;
552
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700553 /*
554 * if the voltage requested is below LDO_THRESHOLD this cpu could
555 * switch to LDO mode. Hence round the voltage as per the LDO
556 * resolution
557 */
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700558 if (min_uV < kvreg->ldo_threshold_uV) {
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700559 if (min_uV < KRAIT_LDO_VOLTAGE_MIN)
560 min_uV = KRAIT_LDO_VOLTAGE_MIN;
561 min_uV = ROUND_UP_VOLTAGE(min_uV, KRAIT_LDO_STEP);
562 }
563
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700564 mutex_lock(&pvreg->krait_power_vregs_lock);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700565 kvreg->uV = min_uV;
566
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800567 if (!kvreg->online) {
568 mutex_unlock(&pvreg->krait_power_vregs_lock);
569 return 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700570 }
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700571
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800572 rc = _set_voltage(rdev, min_uV, max_uV, selector);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700573 mutex_unlock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800574
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700575 return rc;
576}
577
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700578#define PMIC_FTS_MODE_PFM 0x00
579#define PMIC_FTS_MODE_PWM 0x80
580#define PFM_LOAD_UA 500000
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800581static unsigned int _get_optimum_mode(struct regulator_dev *rdev,
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700582 int input_uV, int output_uV, int load_uA)
583{
584 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
585 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
586 int rc;
587 int load_total_uA;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700588
589 load_total_uA = get_total_load(kvreg);
590
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700591 if (load_total_uA < PFM_LOAD_UA) {
592 if (!pvreg->pfm_mode) {
593 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PFM);
594 if (rc) {
595 dev_err(&rdev->dev,
596 "%s enter PFM failed load %d rc = %d\n",
597 kvreg->name, load_total_uA, rc);
598 goto out;
599 } else {
600 pvreg->pfm_mode = true;
601 }
602 }
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800603 return kvreg->mode;
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700604 }
605
606 if (pvreg->pfm_mode) {
607 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PWM);
608 if (rc) {
609 dev_err(&rdev->dev,
610 "%s exit PFM failed load %d rc = %d\n",
611 kvreg->name, load_total_uA, rc);
612 goto out;
613 } else {
614 pvreg->pfm_mode = false;
615 }
616 }
617
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700618 rc = pmic_gang_set_phases(kvreg, load_total_uA);
619 if (rc < 0) {
620 dev_err(&rdev->dev, "%s failed set mode %d rc = %d\n",
621 kvreg->name, load_total_uA, rc);
622 goto out;
623 }
624
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700625out:
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800626 return kvreg->mode;
627}
628
629static unsigned int krait_power_get_optimum_mode(struct regulator_dev *rdev,
630 int input_uV, int output_uV, int load_uA)
631{
632 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
633 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
634 int rc;
635
636 mutex_lock(&pvreg->krait_power_vregs_lock);
637 kvreg->load_uA = load_uA;
638 if (!kvreg->online) {
639 mutex_unlock(&pvreg->krait_power_vregs_lock);
640 return kvreg->mode;
641 }
642
643 rc = _get_optimum_mode(rdev, input_uV, output_uV, load_uA);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700644 mutex_unlock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800645
646 return rc;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700647}
648
649static int krait_power_set_mode(struct regulator_dev *rdev, unsigned int mode)
650{
651 return 0;
652}
653
654static unsigned int krait_power_get_mode(struct regulator_dev *rdev)
655{
656 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
657
658 return kvreg->mode;
659}
660
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800661static int krait_power_is_enabled(struct regulator_dev *rdev)
662{
663 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
664
665 return kvreg->online;
666}
667
668static int krait_power_enable(struct regulator_dev *rdev)
669{
670 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
671 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
672 int rc;
673
674 mutex_lock(&pvreg->krait_power_vregs_lock);
675 kvreg->online = true;
676 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV,
677 kvreg->load_uA);
678 if (rc < 0)
679 goto en_err;
680 rc = _set_voltage(rdev, kvreg->uV,
681 rdev->constraints->max_uV, NULL);
682en_err:
683 mutex_unlock(&pvreg->krait_power_vregs_lock);
684 return rc;
685}
686
687static int krait_power_disable(struct regulator_dev *rdev)
688{
689 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
690 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
691 int rc;
692
693 mutex_lock(&pvreg->krait_power_vregs_lock);
694 kvreg->online = false;
695
696 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV,
697 kvreg->load_uA);
698 if (rc < 0)
699 goto dis_err;
700
701 rc = _set_voltage(rdev, kvreg->uV,
702 rdev->constraints->max_uV, NULL);
703dis_err:
704 mutex_unlock(&pvreg->krait_power_vregs_lock);
705 return rc;
706}
707
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700708static struct regulator_ops krait_power_ops = {
709 .get_voltage = krait_power_get_voltage,
710 .set_voltage = krait_power_set_voltage,
711 .get_optimum_mode = krait_power_get_optimum_mode,
712 .set_mode = krait_power_set_mode,
713 .get_mode = krait_power_get_mode,
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800714 .enable = krait_power_enable,
715 .disable = krait_power_disable,
716 .is_enabled = krait_power_is_enabled,
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700717};
718
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700719static void kvreg_hw_init(struct krait_power_vreg *kvreg)
720{
721 /*
722 * bhs_cnt value sets the ramp-up time from power collapse,
723 * initialize the ramp up time
724 */
725 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
726 BHS_CNT_MASK, BHS_CNT_DEFAULT << BHS_CNT_BIT_POS);
727
728 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
729 CLK_SRC_SEL_MASK, CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS);
730
731 /* BHS has six different segments, turn them all on */
732 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
733 BHS_SEG_EN_MASK, BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS);
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700734
735 set_krait_retention_uv(kvreg, kvreg->retention_uV);
736 set_krait_ldo_uv(kvreg, kvreg->ldo_default_uV);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700737}
738
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700739static void glb_init(struct platform_device *pdev)
740{
741 /* configure bi-modal switch */
742 writel_relaxed(0x0008736E, MSM_APCS_GCC_BASE + PWR_GATE_CONFIG);
743 /* read kpss version */
744 version = readl_relaxed(MSM_APCS_GCC_BASE + VERSION);
745 pr_debug("version= 0x%x\n", version);
746}
747
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700748static int is_between(int left, int right, int value)
749{
750 if (left >= right && left >= value && value >= right)
751 return 1;
752 if (left <= right && left <= value && value <= right)
753 return 1;
754 return 0;
755}
756
757#define LDO_HDROOM_MIN 50000
758#define LDO_HDROOM_MAX 250000
759
760#define LDO_UV_MIN 465000
761#define LDO_UV_MAX 750000
762
763#define LDO_TH_MIN 600000
764#define LDO_TH_MAX 800000
765
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700766static int __devinit krait_power_probe(struct platform_device *pdev)
767{
768 struct krait_power_vreg *kvreg;
769 struct resource *res;
770 struct regulator_init_data *init_data = pdev->dev.platform_data;
771 int rc = 0;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700772 int headroom_uV, retention_uV, ldo_default_uV, ldo_threshold_uV;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700773
774 /* Initialize the pmic gang if it hasn't been initialized already */
775 if (the_gang == NULL) {
776 rc = pvreg_init(pdev);
777 if (rc < 0) {
778 dev_err(&pdev->dev,
779 "failed to init pmic gang rc = %d\n", rc);
780 return rc;
781 }
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700782 /* global initializtion */
783 glb_init(pdev);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700784 }
785
786 if (pdev->dev.of_node) {
787 /* Get init_data from device tree. */
788 init_data = of_get_regulator_init_data(&pdev->dev,
789 pdev->dev.of_node);
790 init_data->constraints.valid_ops_mask
791 |= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_DRMS
792 | REGULATOR_CHANGE_MODE;
793 init_data->constraints.valid_modes_mask
794 |= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE
795 | REGULATOR_MODE_FAST;
796 init_data->constraints.input_uV = init_data->constraints.max_uV;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700797 rc = of_property_read_u32(pdev->dev.of_node,
798 "qcom,headroom-voltage",
799 &headroom_uV);
800 if (rc < 0) {
801 pr_err("headroom-voltage missing rc=%d\n", rc);
802 return rc;
803 }
804 if (!is_between(LDO_HDROOM_MIN, LDO_HDROOM_MAX, headroom_uV)) {
805 pr_err("bad headroom-voltage = %d specified\n",
806 headroom_uV);
807 return -EINVAL;
808 }
809
810 rc = of_property_read_u32(pdev->dev.of_node,
811 "qcom,retention-voltage",
812 &retention_uV);
813 if (rc < 0) {
814 pr_err("retention-voltage missing rc=%d\n", rc);
815 return rc;
816 }
817 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV)) {
818 pr_err("bad retention-voltage = %d specified\n",
819 retention_uV);
820 return -EINVAL;
821 }
822
823 rc = of_property_read_u32(pdev->dev.of_node,
824 "qcom,ldo-default-voltage",
825 &ldo_default_uV);
826 if (rc < 0) {
827 pr_err("ldo-default-voltage missing rc=%d\n", rc);
828 return rc;
829 }
830 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, ldo_default_uV)) {
831 pr_err("bad ldo-default-voltage = %d specified\n",
832 ldo_default_uV);
833 return -EINVAL;
834 }
835
836 rc = of_property_read_u32(pdev->dev.of_node,
837 "qcom,ldo-threshold-voltage",
838 &ldo_threshold_uV);
839 if (rc < 0) {
840 pr_err("ldo-threshold-voltage missing rc=%d\n", rc);
841 return rc;
842 }
843 if (!is_between(LDO_TH_MIN, LDO_TH_MAX, ldo_threshold_uV)) {
844 pr_err("bad ldo-threshold-voltage = %d specified\n",
845 ldo_threshold_uV);
846 return -EINVAL;
847 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700848 }
849
850 if (!init_data) {
851 dev_err(&pdev->dev, "init data required.\n");
852 return -EINVAL;
853 }
854
855 if (!init_data->constraints.name) {
856 dev_err(&pdev->dev,
857 "regulator name must be specified in constraints.\n");
858 return -EINVAL;
859 }
860
861 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
862 if (!res) {
863 dev_err(&pdev->dev, "missing physical register addresses\n");
864 return -EINVAL;
865 }
866
867 kvreg = devm_kzalloc(&pdev->dev,
868 sizeof(struct krait_power_vreg), GFP_KERNEL);
869 if (!kvreg) {
870 dev_err(&pdev->dev, "kzalloc failed.\n");
871 return -ENOMEM;
872 }
873
874 kvreg->reg_base = devm_ioremap(&pdev->dev,
875 res->start, resource_size(res));
876
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700877 kvreg->pvreg = the_gang;
878 kvreg->name = init_data->constraints.name;
879 kvreg->desc.name = kvreg->name;
880 kvreg->desc.ops = &krait_power_ops;
881 kvreg->desc.type = REGULATOR_VOLTAGE;
882 kvreg->desc.owner = THIS_MODULE;
883 kvreg->uV = CORE_VOLTAGE_MIN;
884 kvreg->mode = HS_MODE;
885 kvreg->desc.ops = &krait_power_ops;
886 kvreg->headroom_uV = headroom_uV;
887 kvreg->retention_uV = retention_uV;
888 kvreg->ldo_default_uV = ldo_default_uV;
889 kvreg->ldo_threshold_uV = ldo_threshold_uV;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700890
891 platform_set_drvdata(pdev, kvreg);
892
893 mutex_lock(&the_gang->krait_power_vregs_lock);
894 list_add_tail(&kvreg->link, &the_gang->krait_power_vregs);
895 mutex_unlock(&the_gang->krait_power_vregs_lock);
896
897 kvreg->rdev = regulator_register(&kvreg->desc, &pdev->dev, init_data,
898 kvreg, pdev->dev.of_node);
899 if (IS_ERR(kvreg->rdev)) {
900 rc = PTR_ERR(kvreg->rdev);
901 pr_err("regulator_register failed, rc=%d.\n", rc);
902 goto out;
903 }
904
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700905 kvreg_hw_init(kvreg);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700906 dev_dbg(&pdev->dev, "id=%d, name=%s\n", pdev->id, kvreg->name);
907
908 return 0;
909out:
910 mutex_lock(&the_gang->krait_power_vregs_lock);
911 list_del(&kvreg->link);
912 mutex_unlock(&the_gang->krait_power_vregs_lock);
913
914 platform_set_drvdata(pdev, NULL);
915 return rc;
916}
917
918static int __devexit krait_power_remove(struct platform_device *pdev)
919{
920 struct krait_power_vreg *kvreg = platform_get_drvdata(pdev);
921 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
922
923 mutex_lock(&pvreg->krait_power_vregs_lock);
924 list_del(&kvreg->link);
925 mutex_unlock(&pvreg->krait_power_vregs_lock);
926
927 regulator_unregister(kvreg->rdev);
928 platform_set_drvdata(pdev, NULL);
929 return 0;
930}
931
932static struct of_device_id krait_power_match_table[] = {
933 { .compatible = "qcom,krait-regulator", },
934 {}
935};
936
937static struct platform_driver krait_power_driver = {
938 .probe = krait_power_probe,
939 .remove = __devexit_p(krait_power_remove),
940 .driver = {
941 .name = KRAIT_REGULATOR_DRIVER_NAME,
942 .of_match_table = krait_power_match_table,
943 .owner = THIS_MODULE,
944 },
945};
946
947int __init krait_power_init(void)
948{
949 return platform_driver_register(&krait_power_driver);
950}
951
952static void __exit krait_power_exit(void)
953{
954 platform_driver_unregister(&krait_power_driver);
955}
956
957module_exit(krait_power_exit);
958
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -0700959void secondary_cpu_hs_init(void *base_ptr)
960{
961 /* 605mV retention and 705mV operational voltage */
962 writel_relaxed(0x1C30, base_ptr + APC_LDO_VREF_SET);
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700963 /* HS_EN_DLY=3; LDO_BYP_DLY=1; */
964 writel_relaxed(0x430000, base_ptr + APC_PWR_GATE_DLY);
965 /* MODE = BHS; EN=1; */
966 writel_relaxed(0x21, base_ptr + APC_PWR_GATE_MODE);
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -0700967
968 /* Turn on the BHS, turn off LDO Bypass and power down LDO */
969 writel_relaxed(0x403F007F, base_ptr + APC_PWR_GATE_CTL);
970 mb();
971 udelay(1);
972
973 /* Finally turn on the bypass so that BHS supplies power */
974 writel_relaxed(0x403F3F7F, base_ptr + APC_PWR_GATE_CTL);
975}
976
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700977MODULE_LICENSE("GPL v2");
978MODULE_DESCRIPTION("KRAIT POWER regulator driver");
979MODULE_VERSION("1.0");
980MODULE_ALIAS("platform:"KRAIT_REGULATOR_DRIVER_NAME);