blob: e0dd3dc69f878e9b9660bd130111e2395dcbbc5e [file] [log] [blame]
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -08001/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07002 *
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
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -080013#define pr_fmt(fmt) "PDN %s: " fmt, __func__
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070014
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 Dharmapurikar37c47a82013-01-08 18:44:21 -080030#include <linux/debugfs.h>
Abhijeet Dharmapurikarc8605a62013-03-11 21:24:25 -070031#include <linux/syscore_ops.h>
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -070032#include <mach/msm_iomap.h>
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070033
34#include "spm.h"
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -080035#include "pm.h"
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070036
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070037/*
38 * supply
39 * from
40 * pmic
41 * gang
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -080042 * |
43 * |________________________________
44 * | | |
45 * ___|___ | |
46 * | | | |
47 * | | / /
48 * | LDO | / /LDO BYP [6]
49 * | | / BHS[6] /(bypass is a weak BHS
50 * |_______| | | needs to be on when in
51 * | | | BHS mode)
52 * |________________|_______________|
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070053 * |
54 * ________|________
55 * | |
56 * | KRAIT |
57 * |_________________|
58 */
59
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070060#define PMIC_VOLTAGE_MIN 350000
61#define PMIC_VOLTAGE_MAX 1355000
62#define LV_RANGE_STEP 5000
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070063
Patrick Cain92f4fa12013-04-22 16:23:19 -070064#define CORE_VOLTAGE_BOOTUP 900000
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070065
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070066#define KRAIT_LDO_VOLTAGE_MIN 465000
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -070067#define KRAIT_LDO_VOLTAGE_OFFSET 465000
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070068#define KRAIT_LDO_STEP 5000
69
70#define BHS_SETTLING_DELAY_US 1
71#define LDO_SETTLING_DELAY_US 1
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -080072#define MDD_SETTLING_DELAY_US 5
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070073
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
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -080091/* MDD register group */
92#define MDD_CONFIG_CTL 0x00000000
93#define MDD_MODE 0x00000010
94
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070095/* bit definitions for APC_PWR_GATE_CTL */
96#define BHS_CNT_BIT_POS 24
97#define BHS_CNT_MASK KRAIT_MASK(31, 24)
98#define BHS_CNT_DEFAULT 64
99
100#define CLK_SRC_SEL_BIT_POS 15
101#define CLK_SRC_SEL_MASK KRAIT_MASK(15, 15)
102#define CLK_SRC_DEFAULT 0
103
104#define LDO_PWR_DWN_BIT_POS 16
105#define LDO_PWR_DWN_MASK KRAIT_MASK(21, 16)
106
107#define LDO_BYP_BIT_POS 8
108#define LDO_BYP_MASK KRAIT_MASK(13, 8)
109
110#define BHS_SEG_EN_BIT_POS 1
111#define BHS_SEG_EN_MASK KRAIT_MASK(6, 1)
112#define BHS_SEG_EN_DEFAULT 0x3F
113
114#define BHS_EN_BIT_POS 0
115#define BHS_EN_MASK KRAIT_MASK(0, 0)
116
117/* bit definitions for APC_LDO_VREF_SET register */
118#define VREF_RET_POS 8
119#define VREF_RET_MASK KRAIT_MASK(14, 8)
120
121#define VREF_LDO_BIT_POS 0
122#define VREF_LDO_MASK KRAIT_MASK(6, 0)
123
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800124#define LDO_HDROOM_MIN 50000
125#define LDO_HDROOM_MAX 250000
126
127#define LDO_UV_MIN 465000
128#define LDO_UV_MAX 750000
129
130#define LDO_TH_MIN 600000
131#define LDO_TH_MAX 900000
132
133#define LDO_DELTA_MIN 10000
134#define LDO_DELTA_MAX 100000
135
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700136/**
137 * struct pmic_gang_vreg -
138 * @name: the string used to represent the gang
139 * @pmic_vmax_uV: the current pmic gang voltage
140 * @pmic_phase_count: the number of phases turned on in the gang
141 * @krait_power_vregs: a list of krait consumers this gang supplies to
142 * @krait_power_vregs_lock: lock to prevent simultaneous access to the list
143 * and its nodes. This needs to be taken by each
144 * regulator's callback functions to prevent
145 * simultaneous updates to the pmic's phase
146 * voltage.
Patrick Cain92f4fa12013-04-22 16:23:19 -0700147 * @apcs_gcc_base: virtual address of the APCS GCC registers
148 * @manage_phases: begin phase control
149 * @pfm_threshold: the sum of coefficients below which PFM can be
150 * enabled
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700151 */
152struct pmic_gang_vreg {
153 const char *name;
154 int pmic_vmax_uV;
155 int pmic_phase_count;
156 struct list_head krait_power_vregs;
157 struct mutex krait_power_vregs_lock;
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700158 bool pfm_mode;
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -0800159 int pmic_min_uV_for_retention;
160 bool retention_enabled;
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800161 bool use_phase_switching;
Stepan Moskovchenko7663b782013-03-08 20:13:06 -0800162 void __iomem *apcs_gcc_base;
Patrick Cain92f4fa12013-04-22 16:23:19 -0700163 bool manage_phases;
164 int pfm_threshold;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700165};
166
167static struct pmic_gang_vreg *the_gang;
168
169enum krait_supply_mode {
170 HS_MODE = REGULATOR_MODE_NORMAL,
171 LDO_MODE = REGULATOR_MODE_IDLE,
172};
173
174struct krait_power_vreg {
175 struct list_head link;
176 struct regulator_desc desc;
177 struct regulator_dev *rdev;
178 const char *name;
179 struct pmic_gang_vreg *pvreg;
180 int uV;
Patrick Cain92f4fa12013-04-22 16:23:19 -0700181 int load;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700182 enum krait_supply_mode mode;
183 void __iomem *reg_base;
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800184 void __iomem *mdd_base;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700185 int ldo_default_uV;
186 int retention_uV;
187 int headroom_uV;
188 int ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800189 int ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800190 int cpu_num;
Patrick Cain92f4fa12013-04-22 16:23:19 -0700191 int coeff1;
192 int coeff2;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800193 bool online;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700194};
195
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800196DEFINE_PER_CPU(struct krait_power_vreg *, krait_vregs);
197
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700198static u32 version;
199
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800200static int is_between(int left, int right, int value)
201{
202 if (left >= right && left >= value && value >= right)
203 return 1;
204 if (left <= right && left <= value && value <= right)
205 return 1;
206 return 0;
207}
208
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700209static void krait_masked_write(struct krait_power_vreg *kvreg,
210 int reg, uint32_t mask, uint32_t val)
211{
212 uint32_t reg_val;
213
214 reg_val = readl_relaxed(kvreg->reg_base + reg);
215 reg_val &= ~mask;
216 reg_val |= (val & mask);
217 writel_relaxed(reg_val, kvreg->reg_base + reg);
218
219 /*
220 * Barrier to ensure that the reads and writes from
221 * other regulator regions (they are 1k apart) execute in
222 * order to the above write.
223 */
224 mb();
225}
226
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800227static int get_krait_retention_ldo_uv(struct krait_power_vreg *kvreg)
228{
229 uint32_t reg_val;
230 int uV;
231
232 reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
233 reg_val &= VREF_RET_MASK;
234 reg_val >>= VREF_RET_POS;
235
236 if (reg_val == 0)
237 uV = 0;
238 else
239 uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
240
241 return uV;
242}
243
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700244static int get_krait_ldo_uv(struct krait_power_vreg *kvreg)
245{
246 uint32_t reg_val;
247 int uV;
248
249 reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
250 reg_val &= VREF_LDO_MASK;
251 reg_val >>= VREF_LDO_BIT_POS;
252
253 if (reg_val == 0)
254 uV = 0;
255 else
256 uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
257
258 return uV;
259}
260
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700261static int set_krait_retention_uv(struct krait_power_vreg *kvreg, int uV)
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700262{
263 uint32_t reg_val;
264
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700265 reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
266 krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_RET_MASK,
267 reg_val << VREF_RET_POS);
268
269 return 0;
270}
271
272static int set_krait_ldo_uv(struct krait_power_vreg *kvreg, int uV)
273{
274 uint32_t reg_val;
275
276 reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700277 krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_LDO_MASK,
278 reg_val << VREF_LDO_BIT_POS);
279
280 return 0;
281}
282
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800283static int __krait_power_mdd_enable(struct krait_power_vreg *kvreg, bool on)
284{
285 if (on) {
286 writel_relaxed(0x00000002, kvreg->mdd_base + MDD_MODE);
287 /* complete the above write before the delay */
288 mb();
289 udelay(MDD_SETTLING_DELAY_US);
290 } else {
291 writel_relaxed(0x00000000, kvreg->mdd_base + MDD_MODE);
292 /*
293 * complete the above write before other accesses
294 * to krait regulator
295 */
296 mb();
297 }
298 return 0;
299}
300
Patrick Cain92f4fa12013-04-22 16:23:19 -0700301#define COEFF2_UV_THRESHOLD 850000
302static int get_coeff2(int krait_uV)
303{
304 int coeff2 = 0;
305 int krait_mV = krait_uV / 1000;
306
307 if (krait_uV <= COEFF2_UV_THRESHOLD)
308 coeff2 = (612229 * krait_mV) / 1000 - 211258;
309 else
310 coeff2 = (892564 * krait_mV) / 1000 - 449543;
311
312 return coeff2;
313}
314
315static int get_coeff1(int actual_uV, int requested_uV, int load)
316{
317 int ratio = actual_uV * 1000 / requested_uV;
318 int coeff1 = 330 * load + (load * 673 * ratio / 1000);
319
320 return coeff1;
321}
322
323static int get_coeff_total(struct krait_power_vreg *from)
324{
325 int coeff_total = 0;
326 struct krait_power_vreg *kvreg;
327 struct pmic_gang_vreg *pvreg = from->pvreg;
328
329 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
330 if (!kvreg->online)
331 continue;
332
333 if (kvreg->mode == LDO_MODE) {
334 kvreg->coeff1 =
335 get_coeff1(kvreg->uV - kvreg->ldo_delta_uV,
336 kvreg->uV, kvreg->load);
337 kvreg->coeff2 =
338 get_coeff2(kvreg->uV - kvreg->ldo_delta_uV);
339 } else {
340 kvreg->coeff1 =
341 get_coeff1(pvreg->pmic_vmax_uV,
342 kvreg->uV, kvreg->load);
343 kvreg->coeff2 = get_coeff2(pvreg->pmic_vmax_uV);
344 }
345 coeff_total += kvreg->coeff1 + kvreg->coeff2;
346 }
347
348 return coeff_total;
349}
350
351static int set_pmic_gang_phases(struct pmic_gang_vreg *pvreg, int phase_count)
352{
353 pr_debug("programming phase_count = %d\n", phase_count);
354 if (pvreg->use_phase_switching)
355 /*
356 * note the PMIC sets the phase count to one more than
357 * the value in the register - hence subtract 1 from it
358 */
359 return msm_spm_apcs_set_phase(phase_count - 1);
360 else
361 return 0;
362}
363
364static int num_online(struct pmic_gang_vreg *pvreg)
365{
366 int online_total = 0;
367 struct krait_power_vreg *kvreg;
368
369 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
370 if (kvreg->online)
371 online_total++;
372 }
373 return online_total;
374}
375
376static int get_total_load(struct krait_power_vreg *from)
377{
378 int load_total = 0;
379 struct krait_power_vreg *kvreg;
380 struct pmic_gang_vreg *pvreg = from->pvreg;
381
382 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
383 if (!kvreg->online)
384 continue;
385 load_total += kvreg->load;
386 }
387
388 return load_total;
389}
390
391#define PMIC_FTS_MODE_PFM 0x00
392#define PMIC_FTS_MODE_PWM 0x80
393#define ONE_PHASE_COEFF 1000000
394#define TWO_PHASE_COEFF 2000000
395
396#define PHASE_SETTLING_TIME_US 10
397static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
398 int coeff_total)
399{
400 struct pmic_gang_vreg *pvreg = from->pvreg;
401 int phase_count;
402 int rc = 0;
403 int n_online = num_online(pvreg);
404 int load_total;
405
406 load_total = get_total_load(from);
407
408 if (pvreg->manage_phases == false)
409 return 0;
410
411 /* First check if the coeff is low for PFM mode */
412 if (load_total <= pvreg->pfm_threshold && n_online == 1) {
413 if (!pvreg->pfm_mode) {
414 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PFM);
415 if (rc) {
416 pr_err("%s PFM en failed load_t %d rc = %d\n",
417 from->name, load_total, rc);
418 return rc;
419 } else {
420 pvreg->pfm_mode = true;
421 }
422 }
423 return rc;
424 }
425
426 /* coeff is high switch to PWM mode before changing phases */
427 if (pvreg->pfm_mode) {
428 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PWM);
429 if (rc) {
430 pr_err("%s PFM exit failed load %d rc = %d\n",
431 from->name, coeff_total, rc);
432 return rc;
433 } else {
434 pvreg->pfm_mode = false;
435 }
436 }
437
438 /* calculate phases */
439 if (coeff_total < ONE_PHASE_COEFF)
440 phase_count = 1;
441 else if (coeff_total < TWO_PHASE_COEFF)
442 phase_count = 2;
443 else
444 phase_count = 4;
445
446 /* don't increase the phase count higher than number of online cpus */
447 if (phase_count > n_online)
448 phase_count = n_online;
449
450 if (phase_count != pvreg->pmic_phase_count) {
451 rc = set_pmic_gang_phases(pvreg, phase_count);
452 if (rc < 0) {
453 pr_err("%s failed set phase %d rc = %d\n",
454 from->name, phase_count, rc);
455 return rc;
456 }
457
458 /* complete the writes before the delay */
459 mb();
460
461 /*
462 * delay until the phases are settled when
463 * the count is raised
464 */
465 if (phase_count > pvreg->pmic_phase_count)
466 udelay(PHASE_SETTLING_TIME_US);
467
468 pvreg->pmic_phase_count = phase_count;
469 }
470
471 return rc;
472}
473
474static unsigned int _get_optimum_mode(struct regulator_dev *rdev,
475 int input_uV, int output_uV, int load)
476{
477 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
478 int coeff_total;
479 int rc;
480
481 coeff_total = get_coeff_total(kvreg);
482
483 rc = pmic_gang_set_phases(kvreg, coeff_total);
484 if (rc < 0) {
485 dev_err(&rdev->dev, "%s failed set mode %d rc = %d\n",
486 kvreg->name, coeff_total, rc);
487 }
488
489 return kvreg->mode;
490}
491
492static unsigned int krait_power_get_optimum_mode(struct regulator_dev *rdev,
493 int input_uV, int output_uV, int load_uA)
494{
495 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
496 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
497 int rc;
498
499 mutex_lock(&pvreg->krait_power_vregs_lock);
500 kvreg->load = load_uA;
501 if (!kvreg->online) {
502 mutex_unlock(&pvreg->krait_power_vregs_lock);
503 return kvreg->mode;
504 }
505
506 rc = _get_optimum_mode(rdev, input_uV, output_uV, load_uA);
507 mutex_unlock(&pvreg->krait_power_vregs_lock);
508
509 return rc;
510}
511
512static int krait_power_set_mode(struct regulator_dev *rdev, unsigned int mode)
513{
514 return 0;
515}
516
517static unsigned int krait_power_get_mode(struct regulator_dev *rdev)
518{
519 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
520
521 return kvreg->mode;
522}
523
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700524static int switch_to_using_hs(struct krait_power_vreg *kvreg)
525{
526 if (kvreg->mode == HS_MODE)
527 return 0;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700528 /* enable bhs */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800529 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
530 BHS_SEG_EN_MASK | BHS_EN_MASK,
531 BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS | BHS_EN_MASK);
532
533 /* complete the above write before the delay */
534 mb();
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700535
536 /*
537 * wait for the bhs to settle - note that
538 * after the voltage has settled both BHS and LDO are supplying power
539 * to the krait. This avoids glitches during switching
540 */
541 udelay(BHS_SETTLING_DELAY_US);
542
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800543 /*
544 * enable ldo bypass - the krait is powered still by LDO since
545 * LDO is enabled
546 */
547 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_BYP_MASK, LDO_BYP_MASK);
548
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700549 /* disable ldo - only the BHS provides voltage to the cpu after this */
550 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
551 LDO_PWR_DWN_MASK, LDO_PWR_DWN_MASK);
552
553 kvreg->mode = HS_MODE;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800554 pr_debug("%s using BHS\n", kvreg->name);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700555 return 0;
556}
557
558static int switch_to_using_ldo(struct krait_power_vreg *kvreg)
559{
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800560 if (kvreg->mode == LDO_MODE
561 && get_krait_ldo_uv(kvreg) == kvreg->uV - kvreg->ldo_delta_uV)
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700562 return 0;
563
564 /*
565 * if the krait is in ldo mode and a voltage change is requested on the
566 * ldo switch to using hs before changing ldo voltage
567 */
568 if (kvreg->mode == LDO_MODE)
569 switch_to_using_hs(kvreg);
570
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800571 set_krait_ldo_uv(kvreg, kvreg->uV - kvreg->ldo_delta_uV);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700572
573 /*
574 * enable ldo - note that both LDO and BHS are are supplying voltage to
575 * the cpu after this. This avoids glitches during switching from BHS
576 * to LDO.
577 */
578 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_PWR_DWN_MASK, 0);
579
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800580 /* complete the writes before the delay */
581 mb();
582
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700583 /* wait for the ldo to settle */
584 udelay(LDO_SETTLING_DELAY_US);
585
586 /*
587 * disable BHS and disable LDO bypass seperate from enabling
588 * the LDO above.
589 */
590 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
591 BHS_EN_MASK | LDO_BYP_MASK, 0);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800592 krait_masked_write(kvreg, APC_PWR_GATE_CTL, BHS_SEG_EN_MASK, 0);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700593
594 kvreg->mode = LDO_MODE;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800595 pr_debug("%s using LDO\n", kvreg->name);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700596 return 0;
597}
598
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800599static int set_pmic_gang_voltage(struct pmic_gang_vreg *pvreg, int uV)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700600{
601 int setpoint;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800602 int rc;
603
604 if (pvreg->pmic_vmax_uV == uV)
605 return 0;
606
607 pr_debug("%d\n", uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700608
609 if (uV < PMIC_VOLTAGE_MIN) {
610 pr_err("requested %d < %d, restricting it to %d\n",
611 uV, PMIC_VOLTAGE_MIN, PMIC_VOLTAGE_MIN);
612 uV = PMIC_VOLTAGE_MIN;
613 }
614 if (uV > PMIC_VOLTAGE_MAX) {
615 pr_err("requested %d > %d, restricting it to %d\n",
616 uV, PMIC_VOLTAGE_MAX, PMIC_VOLTAGE_MAX);
617 uV = PMIC_VOLTAGE_MAX;
618 }
619
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -0800620 if (uV < pvreg->pmic_min_uV_for_retention) {
621 if (pvreg->retention_enabled) {
622 pr_debug("Disabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
623 uV, pvreg->pmic_min_uV_for_retention);
624 msm_pm_enable_retention(false);
625 pvreg->retention_enabled = false;
626 }
627 } else {
628 if (!pvreg->retention_enabled) {
629 pr_debug("Enabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
630 uV, pvreg->pmic_min_uV_for_retention);
631 msm_pm_enable_retention(true);
632 pvreg->retention_enabled = true;
633 }
634 }
635
Abhijeet Dharmapurikard4f38da2012-08-08 21:42:06 -0700636 setpoint = DIV_ROUND_UP(uV, LV_RANGE_STEP);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800637
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800638 rc = msm_spm_apcs_set_vdd(setpoint);
639 if (rc < 0)
640 pr_err("could not set %duV setpt = 0x%x rc = %d\n",
641 uV, setpoint, rc);
642 else
643 pvreg->pmic_vmax_uV = uV;
644
645 return rc;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700646}
647
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800648static int configure_ldo_or_hs_all(struct krait_power_vreg *from, int vmax)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700649{
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700650 struct pmic_gang_vreg *pvreg = from->pvreg;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700651 struct krait_power_vreg *kvreg;
652 int rc = 0;
653
654 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800655 if (!kvreg->online)
656 continue;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800657 if (kvreg->uV <= kvreg->ldo_threshold_uV
658 && kvreg->uV - kvreg->ldo_delta_uV + kvreg->headroom_uV
659 <= vmax) {
660 rc = switch_to_using_ldo(kvreg);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700661 if (rc < 0) {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800662 pr_err("could not switch %s to ldo rc = %d\n",
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700663 kvreg->name, rc);
664 return rc;
665 }
666 } else {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800667 rc = switch_to_using_hs(kvreg);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700668 if (rc < 0) {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800669 pr_err("could not switch %s to hs rc = %d\n",
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700670 kvreg->name, rc);
671 return rc;
672 }
673 }
674 }
675
676 return rc;
677}
678
679#define SLEW_RATE 2994
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800680static int krait_voltage_increase(struct krait_power_vreg *from,
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700681 int vmax)
682{
683 struct pmic_gang_vreg *pvreg = from->pvreg;
684 int rc = 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700685 int settling_us;
686
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700687 /*
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800688 * since krait voltage is increasing set the gang voltage
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700689 * prior to changing ldo/hs states of the requesting krait
690 */
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800691 rc = set_pmic_gang_voltage(pvreg, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700692 if (rc < 0) {
693 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
694 pvreg->name, vmax, rc);
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800695 return rc;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700696 }
697
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800698
699 /* complete the above writes before the delay */
700 mb();
701
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700702 /* delay until the voltage is settled when it is raised */
703 settling_us = DIV_ROUND_UP(vmax - pvreg->pmic_vmax_uV, SLEW_RATE);
704 udelay(settling_us);
705
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800706 rc = configure_ldo_or_hs_all(from, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700707 if (rc < 0) {
708 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
709 pvreg->name, vmax, rc);
710 }
711
712 return rc;
713}
714
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800715static int krait_voltage_decrease(struct krait_power_vreg *from,
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700716 int vmax)
717{
718 struct pmic_gang_vreg *pvreg = from->pvreg;
719 int rc = 0;
720
721 /*
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800722 * since krait voltage is decreasing ldos might get out of their
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700723 * operating range. Hence configure such kraits to be in hs mode prior
724 * to setting the pmic gang voltage
725 */
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800726 rc = configure_ldo_or_hs_all(from, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700727 if (rc < 0) {
728 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
729 pvreg->name, vmax, rc);
730 return rc;
731 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700732
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800733 rc = set_pmic_gang_voltage(pvreg, vmax);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700734 if (rc < 0) {
735 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
736 pvreg->name, vmax, rc);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700737 }
738
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700739 return rc;
740}
741
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700742static int krait_power_get_voltage(struct regulator_dev *rdev)
743{
744 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
745
746 return kvreg->uV;
747}
748
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800749static int get_vmax(struct pmic_gang_vreg *pvreg)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700750{
751 int vmax = 0;
752 int v;
753 struct krait_power_vreg *kvreg;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700754
755 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800756 if (!kvreg->online)
757 continue;
758
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700759 v = kvreg->uV;
760
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700761 if (vmax < v)
762 vmax = v;
763 }
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800764
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700765 return vmax;
766}
767
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700768#define ROUND_UP_VOLTAGE(v, res) (DIV_ROUND_UP(v, res) * res)
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800769static int _set_voltage(struct regulator_dev *rdev,
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800770 int orig_krait_uV, int requested_uV)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700771{
772 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
773 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
774 int rc;
775 int vmax;
Patrick Cain92f4fa12013-04-22 16:23:19 -0700776 int coeff_total;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700777
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800778 pr_debug("%s: %d to %d\n", kvreg->name, orig_krait_uV, requested_uV);
779 /*
780 * Assign the voltage before updating the gang voltage as we iterate
781 * over all the core voltages and choose HS or LDO for each of them
782 */
783 kvreg->uV = requested_uV;
784
785 vmax = get_vmax(pvreg);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800786
787 /* round up the pmic voltage as per its resolution */
788 vmax = ROUND_UP_VOLTAGE(vmax, LV_RANGE_STEP);
789
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800790 if (requested_uV > orig_krait_uV)
791 rc = krait_voltage_increase(kvreg, vmax);
792 else
793 rc = krait_voltage_decrease(kvreg, vmax);
794
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800795 if (rc < 0) {
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800796 dev_err(&rdev->dev, "%s failed to set %duV from %duV rc = %d\n",
797 kvreg->name, requested_uV, orig_krait_uV, rc);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800798 }
799
Patrick Cain92f4fa12013-04-22 16:23:19 -0700800 coeff_total = get_coeff_total(kvreg);
801 /* adjust the phases since coeff2 would have changed */
802 rc = pmic_gang_set_phases(kvreg, coeff_total);
803
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800804 return rc;
805}
806
807static int krait_power_set_voltage(struct regulator_dev *rdev,
808 int min_uV, int max_uV, unsigned *selector)
809{
810 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
811 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
812 int rc;
813
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700814 /*
815 * if the voltage requested is below LDO_THRESHOLD this cpu could
816 * switch to LDO mode. Hence round the voltage as per the LDO
817 * resolution
818 */
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700819 if (min_uV < kvreg->ldo_threshold_uV) {
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700820 if (min_uV < KRAIT_LDO_VOLTAGE_MIN)
821 min_uV = KRAIT_LDO_VOLTAGE_MIN;
822 min_uV = ROUND_UP_VOLTAGE(min_uV, KRAIT_LDO_STEP);
823 }
824
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700825 mutex_lock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800826 if (!kvreg->online) {
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800827 kvreg->uV = min_uV;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800828 mutex_unlock(&pvreg->krait_power_vregs_lock);
829 return 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700830 }
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700831
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800832 rc = _set_voltage(rdev, kvreg->uV, min_uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700833 mutex_unlock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800834
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700835 return rc;
836}
837
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800838static int krait_power_is_enabled(struct regulator_dev *rdev)
839{
840 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
841
842 return kvreg->online;
843}
844
845static int krait_power_enable(struct regulator_dev *rdev)
846{
847 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
848 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
849 int rc;
850
851 mutex_lock(&pvreg->krait_power_vregs_lock);
Abhijeet Dharmapurikarc8605a62013-03-11 21:24:25 -0700852 __krait_power_mdd_enable(kvreg, true);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800853 kvreg->online = true;
Patrick Cain92f4fa12013-04-22 16:23:19 -0700854 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV, kvreg->load);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800855 if (rc < 0)
856 goto en_err;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800857 /*
858 * since the core is being enabled, behave as if it is increasing
859 * the core voltage
860 */
861 rc = _set_voltage(rdev, 0, kvreg->uV);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800862en_err:
863 mutex_unlock(&pvreg->krait_power_vregs_lock);
864 return rc;
865}
866
867static int krait_power_disable(struct regulator_dev *rdev)
868{
869 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
870 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
871 int rc;
872
873 mutex_lock(&pvreg->krait_power_vregs_lock);
874 kvreg->online = false;
875
Patrick Cain92f4fa12013-04-22 16:23:19 -0700876 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV, kvreg->load);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800877 if (rc < 0)
878 goto dis_err;
879
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800880 rc = _set_voltage(rdev, kvreg->uV, kvreg->uV);
Abhijeet Dharmapurikarc8605a62013-03-11 21:24:25 -0700881 __krait_power_mdd_enable(kvreg, false);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800882dis_err:
883 mutex_unlock(&pvreg->krait_power_vregs_lock);
884 return rc;
885}
886
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700887static struct regulator_ops krait_power_ops = {
888 .get_voltage = krait_power_get_voltage,
889 .set_voltage = krait_power_set_voltage,
890 .get_optimum_mode = krait_power_get_optimum_mode,
891 .set_mode = krait_power_set_mode,
892 .get_mode = krait_power_get_mode,
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800893 .enable = krait_power_enable,
894 .disable = krait_power_disable,
895 .is_enabled = krait_power_is_enabled,
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700896};
897
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800898static struct dentry *dent;
899static int get_retention_dbg_uV(void *data, u64 *val)
900{
901 struct pmic_gang_vreg *pvreg = data;
902 struct krait_power_vreg *kvreg;
903
904 mutex_lock(&pvreg->krait_power_vregs_lock);
905 if (!list_empty(&pvreg->krait_power_vregs)) {
906 /* return the retention voltage on just the first cpu */
907 kvreg = list_entry((&pvreg->krait_power_vregs)->next,
908 typeof(*kvreg), link);
909 *val = get_krait_retention_ldo_uv(kvreg);
910 }
911 mutex_unlock(&pvreg->krait_power_vregs_lock);
912 return 0;
913}
914
915static int set_retention_dbg_uV(void *data, u64 val)
916{
917 struct pmic_gang_vreg *pvreg = data;
918 struct krait_power_vreg *kvreg;
919 int retention_uV = val;
920
921 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV))
922 return -EINVAL;
923
924 mutex_lock(&pvreg->krait_power_vregs_lock);
925 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
926 kvreg->retention_uV = retention_uV;
927 set_krait_retention_uv(kvreg, retention_uV);
928 }
929 mutex_unlock(&pvreg->krait_power_vregs_lock);
930 return 0;
931}
932DEFINE_SIMPLE_ATTRIBUTE(retention_fops,
933 get_retention_dbg_uV, set_retention_dbg_uV, "%llu\n");
934
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700935static void kvreg_hw_init(struct krait_power_vreg *kvreg)
936{
937 /*
938 * bhs_cnt value sets the ramp-up time from power collapse,
939 * initialize the ramp up time
940 */
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700941 set_krait_retention_uv(kvreg, kvreg->retention_uV);
942 set_krait_ldo_uv(kvreg, kvreg->ldo_default_uV);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800943
944 /* setup the bandgap that configures the reference to the LDO */
945 writel_relaxed(0x00000190, kvreg->mdd_base + MDD_CONFIG_CTL);
Abhijeet Dharmapurikarc8605a62013-03-11 21:24:25 -0700946 /* Enable MDD */
947 writel_relaxed(0x00000002, kvreg->mdd_base + MDD_MODE);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800948 mb();
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700949}
950
Stepan Moskovchenko7663b782013-03-08 20:13:06 -0800951static void glb_init(void __iomem *apcs_gcc_base)
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700952{
953 /* configure bi-modal switch */
Stepan Moskovchenko7663b782013-03-08 20:13:06 -0800954 writel_relaxed(0x0008736E, apcs_gcc_base + PWR_GATE_CONFIG);
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700955 /* read kpss version */
Stepan Moskovchenko7663b782013-03-08 20:13:06 -0800956 version = readl_relaxed(apcs_gcc_base + VERSION);
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700957 pr_debug("version= 0x%x\n", version);
958}
959
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700960static int __devinit krait_power_probe(struct platform_device *pdev)
961{
962 struct krait_power_vreg *kvreg;
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800963 struct resource *res, *res_mdd;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700964 struct regulator_init_data *init_data = pdev->dev.platform_data;
965 int rc = 0;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700966 int headroom_uV, retention_uV, ldo_default_uV, ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800967 int ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800968 int cpu_num;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700969
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700970 if (pdev->dev.of_node) {
971 /* Get init_data from device tree. */
972 init_data = of_get_regulator_init_data(&pdev->dev,
973 pdev->dev.of_node);
974 init_data->constraints.valid_ops_mask
975 |= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_DRMS
976 | REGULATOR_CHANGE_MODE;
977 init_data->constraints.valid_modes_mask
978 |= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE
979 | REGULATOR_MODE_FAST;
980 init_data->constraints.input_uV = init_data->constraints.max_uV;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700981 rc = of_property_read_u32(pdev->dev.of_node,
982 "qcom,headroom-voltage",
983 &headroom_uV);
984 if (rc < 0) {
985 pr_err("headroom-voltage missing rc=%d\n", rc);
986 return rc;
987 }
988 if (!is_between(LDO_HDROOM_MIN, LDO_HDROOM_MAX, headroom_uV)) {
989 pr_err("bad headroom-voltage = %d specified\n",
990 headroom_uV);
991 return -EINVAL;
992 }
993
994 rc = of_property_read_u32(pdev->dev.of_node,
995 "qcom,retention-voltage",
996 &retention_uV);
997 if (rc < 0) {
998 pr_err("retention-voltage missing rc=%d\n", rc);
999 return rc;
1000 }
1001 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV)) {
1002 pr_err("bad retention-voltage = %d specified\n",
1003 retention_uV);
1004 return -EINVAL;
1005 }
1006
1007 rc = of_property_read_u32(pdev->dev.of_node,
1008 "qcom,ldo-default-voltage",
1009 &ldo_default_uV);
1010 if (rc < 0) {
1011 pr_err("ldo-default-voltage missing rc=%d\n", rc);
1012 return rc;
1013 }
1014 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, ldo_default_uV)) {
1015 pr_err("bad ldo-default-voltage = %d specified\n",
1016 ldo_default_uV);
1017 return -EINVAL;
1018 }
1019
1020 rc = of_property_read_u32(pdev->dev.of_node,
1021 "qcom,ldo-threshold-voltage",
1022 &ldo_threshold_uV);
1023 if (rc < 0) {
1024 pr_err("ldo-threshold-voltage missing rc=%d\n", rc);
1025 return rc;
1026 }
1027 if (!is_between(LDO_TH_MIN, LDO_TH_MAX, ldo_threshold_uV)) {
1028 pr_err("bad ldo-threshold-voltage = %d specified\n",
1029 ldo_threshold_uV);
1030 return -EINVAL;
1031 }
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -08001032
1033 rc = of_property_read_u32(pdev->dev.of_node,
1034 "qcom,ldo-delta-voltage",
1035 &ldo_delta_uV);
1036 if (rc < 0) {
1037 pr_err("ldo-delta-voltage missing rc=%d\n", rc);
1038 return rc;
1039 }
1040 if (!is_between(LDO_DELTA_MIN, LDO_DELTA_MAX, ldo_delta_uV)) {
1041 pr_err("bad ldo-delta-voltage = %d specified\n",
1042 ldo_delta_uV);
1043 return -EINVAL;
1044 }
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001045 rc = of_property_read_u32(pdev->dev.of_node,
1046 "qcom,cpu-num",
1047 &cpu_num);
1048 if (cpu_num > num_possible_cpus()) {
1049 pr_err("bad cpu-num= %d specified\n", cpu_num);
1050 return -EINVAL;
1051 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001052 }
1053
1054 if (!init_data) {
1055 dev_err(&pdev->dev, "init data required.\n");
1056 return -EINVAL;
1057 }
1058
1059 if (!init_data->constraints.name) {
1060 dev_err(&pdev->dev,
1061 "regulator name must be specified in constraints.\n");
1062 return -EINVAL;
1063 }
1064
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001065 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acs");
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001066 if (!res) {
1067 dev_err(&pdev->dev, "missing physical register addresses\n");
1068 return -EINVAL;
1069 }
1070
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001071 res_mdd = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mdd");
1072 if (!res_mdd) {
1073 dev_err(&pdev->dev, "missing mdd register addresses\n");
1074 return -EINVAL;
1075 }
1076
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001077 kvreg = devm_kzalloc(&pdev->dev,
1078 sizeof(struct krait_power_vreg), GFP_KERNEL);
1079 if (!kvreg) {
1080 dev_err(&pdev->dev, "kzalloc failed.\n");
1081 return -ENOMEM;
1082 }
1083
1084 kvreg->reg_base = devm_ioremap(&pdev->dev,
1085 res->start, resource_size(res));
1086
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001087 kvreg->mdd_base = devm_ioremap(&pdev->dev,
1088 res_mdd->start, resource_size(res));
1089
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -07001090 kvreg->pvreg = the_gang;
1091 kvreg->name = init_data->constraints.name;
1092 kvreg->desc.name = kvreg->name;
1093 kvreg->desc.ops = &krait_power_ops;
1094 kvreg->desc.type = REGULATOR_VOLTAGE;
1095 kvreg->desc.owner = THIS_MODULE;
Patrick Cain92f4fa12013-04-22 16:23:19 -07001096 kvreg->uV = CORE_VOLTAGE_BOOTUP;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -07001097 kvreg->mode = HS_MODE;
1098 kvreg->desc.ops = &krait_power_ops;
1099 kvreg->headroom_uV = headroom_uV;
1100 kvreg->retention_uV = retention_uV;
1101 kvreg->ldo_default_uV = ldo_default_uV;
1102 kvreg->ldo_threshold_uV = ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -08001103 kvreg->ldo_delta_uV = ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001104 kvreg->cpu_num = cpu_num;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001105
1106 platform_set_drvdata(pdev, kvreg);
1107
1108 mutex_lock(&the_gang->krait_power_vregs_lock);
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -08001109 the_gang->pmic_min_uV_for_retention
1110 = min(the_gang->pmic_min_uV_for_retention,
1111 kvreg->retention_uV + kvreg->headroom_uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001112 list_add_tail(&kvreg->link, &the_gang->krait_power_vregs);
1113 mutex_unlock(&the_gang->krait_power_vregs_lock);
1114
1115 kvreg->rdev = regulator_register(&kvreg->desc, &pdev->dev, init_data,
1116 kvreg, pdev->dev.of_node);
1117 if (IS_ERR(kvreg->rdev)) {
1118 rc = PTR_ERR(kvreg->rdev);
1119 pr_err("regulator_register failed, rc=%d.\n", rc);
1120 goto out;
1121 }
1122
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -07001123 kvreg_hw_init(kvreg);
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001124 per_cpu(krait_vregs, cpu_num) = kvreg;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001125 dev_dbg(&pdev->dev, "id=%d, name=%s\n", pdev->id, kvreg->name);
1126
1127 return 0;
1128out:
1129 mutex_lock(&the_gang->krait_power_vregs_lock);
1130 list_del(&kvreg->link);
1131 mutex_unlock(&the_gang->krait_power_vregs_lock);
1132
1133 platform_set_drvdata(pdev, NULL);
1134 return rc;
1135}
1136
1137static int __devexit krait_power_remove(struct platform_device *pdev)
1138{
1139 struct krait_power_vreg *kvreg = platform_get_drvdata(pdev);
1140 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
1141
1142 mutex_lock(&pvreg->krait_power_vregs_lock);
1143 list_del(&kvreg->link);
1144 mutex_unlock(&pvreg->krait_power_vregs_lock);
1145
1146 regulator_unregister(kvreg->rdev);
1147 platform_set_drvdata(pdev, NULL);
1148 return 0;
1149}
1150
1151static struct of_device_id krait_power_match_table[] = {
1152 { .compatible = "qcom,krait-regulator", },
1153 {}
1154};
1155
1156static struct platform_driver krait_power_driver = {
1157 .probe = krait_power_probe,
1158 .remove = __devexit_p(krait_power_remove),
1159 .driver = {
1160 .name = KRAIT_REGULATOR_DRIVER_NAME,
1161 .of_match_table = krait_power_match_table,
1162 .owner = THIS_MODULE,
1163 },
1164};
1165
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001166static struct of_device_id krait_pdn_match_table[] = {
1167 { .compatible = "qcom,krait-pdn", },
1168 {}
1169};
1170
Abhijeet Dharmapurikarc8605a62013-03-11 21:24:25 -07001171static int boot_cpu_mdd_off(void)
1172{
1173 struct krait_power_vreg *kvreg = per_cpu(krait_vregs, 0);
1174
1175 __krait_power_mdd_enable(kvreg, false);
1176 return 0;
1177}
1178
1179static void boot_cpu_mdd_on(void)
1180{
1181 struct krait_power_vreg *kvreg = per_cpu(krait_vregs, 0);
1182
1183 __krait_power_mdd_enable(kvreg, true);
1184}
1185
1186static struct syscore_ops boot_cpu_mdd_ops = {
1187 .suspend = boot_cpu_mdd_off,
1188 .resume = boot_cpu_mdd_on,
1189};
1190
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001191static int __devinit krait_pdn_probe(struct platform_device *pdev)
1192{
1193 int rc;
1194 bool use_phase_switching = false;
Patrick Cain92f4fa12013-04-22 16:23:19 -07001195 int pfm_threshold;
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001196 struct device *dev = &pdev->dev;
1197 struct device_node *node = dev->of_node;
1198 struct pmic_gang_vreg *pvreg;
Stepan Moskovchenko7663b782013-03-08 20:13:06 -08001199 struct resource *res;
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001200
1201 if (!dev->of_node) {
1202 dev_err(dev, "device tree information missing\n");
1203 return -ENODEV;
1204 }
1205
1206 use_phase_switching = of_property_read_bool(node,
1207 "qcom,use-phase-switching");
Patrick Cain92f4fa12013-04-22 16:23:19 -07001208
1209 rc = of_property_read_u32(node, "qcom,pfm-threshold", &pfm_threshold);
1210 if (rc < 0) {
1211 dev_err(dev, "pfm-threshold missing rc=%d, pfm disabled\n", rc);
1212 return -EINVAL;
1213 }
1214
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001215 pvreg = devm_kzalloc(&pdev->dev,
1216 sizeof(struct pmic_gang_vreg), GFP_KERNEL);
1217 if (!pvreg) {
1218 pr_err("kzalloc failed.\n");
1219 return 0;
1220 }
1221
Stepan Moskovchenko7663b782013-03-08 20:13:06 -08001222 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apcs_gcc");
1223 if (!res) {
1224 dev_err(&pdev->dev, "missing apcs gcc base addresses\n");
1225 return -EINVAL;
1226 }
1227
1228 pvreg->apcs_gcc_base = devm_ioremap(&pdev->dev, res->start,
1229 resource_size(res));
1230
1231 if (pvreg->apcs_gcc_base == NULL)
1232 return -ENOMEM;
1233
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001234 pvreg->name = "pmic_gang";
1235 pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
1236 pvreg->pmic_phase_count = -EINVAL;
1237 pvreg->retention_enabled = true;
1238 pvreg->pmic_min_uV_for_retention = INT_MAX;
1239 pvreg->use_phase_switching = use_phase_switching;
Patrick Cain92f4fa12013-04-22 16:23:19 -07001240 pvreg->pfm_threshold = pfm_threshold;
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001241
1242 mutex_init(&pvreg->krait_power_vregs_lock);
1243 INIT_LIST_HEAD(&pvreg->krait_power_vregs);
1244 the_gang = pvreg;
1245
1246 pr_debug("name=%s inited\n", pvreg->name);
1247
1248 /* global initializtion */
Stepan Moskovchenko7663b782013-03-08 20:13:06 -08001249 glb_init(pvreg->apcs_gcc_base);
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001250
1251 rc = of_platform_populate(node, NULL, NULL, dev);
1252 if (rc) {
1253 dev_err(dev, "failed to add child nodes, rc=%d\n", rc);
1254 return rc;
1255 }
1256
1257 dent = debugfs_create_dir(KRAIT_REGULATOR_DRIVER_NAME, NULL);
1258 debugfs_create_file("retention_uV",
1259 0644, dent, the_gang, &retention_fops);
Abhijeet Dharmapurikarc8605a62013-03-11 21:24:25 -07001260 register_syscore_ops(&boot_cpu_mdd_ops);
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001261 return 0;
1262}
1263
1264static int __devexit krait_pdn_remove(struct platform_device *pdev)
1265{
1266 the_gang = NULL;
1267 debugfs_remove_recursive(dent);
1268 return 0;
1269}
1270
1271static struct platform_driver krait_pdn_driver = {
1272 .probe = krait_pdn_probe,
1273 .remove = __devexit_p(krait_pdn_remove),
1274 .driver = {
1275 .name = KRAIT_PDN_DRIVER_NAME,
1276 .of_match_table = krait_pdn_match_table,
1277 .owner = THIS_MODULE,
1278 },
1279};
1280
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001281int __init krait_power_init(void)
1282{
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001283 int rc = platform_driver_register(&krait_power_driver);
1284 if (rc) {
1285 pr_err("failed to add %s driver rc = %d\n",
1286 KRAIT_REGULATOR_DRIVER_NAME, rc);
1287 return rc;
1288 }
1289 return platform_driver_register(&krait_pdn_driver);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001290}
1291
1292static void __exit krait_power_exit(void)
1293{
1294 platform_driver_unregister(&krait_power_driver);
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001295 platform_driver_unregister(&krait_pdn_driver);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001296}
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001297module_exit(krait_power_exit);
1298
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001299void secondary_cpu_hs_init(void *base_ptr)
1300{
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001301 /* Turn on the BHS, turn off LDO Bypass and power down LDO */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001302 writel_relaxed(
1303 BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
1304 | LDO_PWR_DWN_MASK
1305 | CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
1306 | BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
1307 | BHS_EN_MASK,
1308 base_ptr + APC_PWR_GATE_CTL);
1309
1310 /* complete the above write before the delay */
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001311 mb();
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001312
1313 /*
1314 * wait for the bhs to settle
1315 */
1316 udelay(BHS_SETTLING_DELAY_US);
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001317
1318 /* Finally turn on the bypass so that BHS supplies power */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001319 writel_relaxed(
1320 BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
1321 | LDO_PWR_DWN_MASK
1322 | CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
1323 | LDO_BYP_MASK
1324 | BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
1325 | BHS_EN_MASK,
1326 base_ptr + APC_PWR_GATE_CTL);
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001327}
1328
Patrick Cain92f4fa12013-04-22 16:23:19 -07001329static int __devinit begin_pmic_phase_management(void)
1330{
1331 if (the_gang != NULL)
1332 the_gang->manage_phases = true;
1333 return 0;
1334}
1335late_initcall(begin_pmic_phase_management);
1336
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001337MODULE_LICENSE("GPL v2");
1338MODULE_DESCRIPTION("KRAIT POWER regulator driver");
1339MODULE_VERSION("1.0");
1340MODULE_ALIAS("platform:"KRAIT_REGULATOR_DRIVER_NAME);