blob: dc0b7550e10ed4fc8e9d6b5fe68fae6825f63416 [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 Dharmapurikar3ff7cba2012-10-10 17:48:29 -070031#include <mach/msm_iomap.h>
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070032
33#include "spm.h"
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -080034#include "pm.h"
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070035
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070036/*
37 * supply
38 * from
39 * pmic
40 * gang
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -080041 * |
42 * |________________________________
43 * | | |
44 * ___|___ | |
45 * | | | |
46 * | | / /
47 * | LDO | / /LDO BYP [6]
48 * | | / BHS[6] /(bypass is a weak BHS
49 * |_______| | | needs to be on when in
50 * | | | BHS mode)
51 * |________________|_______________|
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070052 * |
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
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -080073#define MDD_SETTLING_DELAY_US 5
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070074
75#define _KRAIT_MASK(BITS, POS) (((u32)(1 << (BITS)) - 1) << POS)
76#define KRAIT_MASK(LEFT_BIT_POS, RIGHT_BIT_POS) \
77 _KRAIT_MASK(LEFT_BIT_POS - RIGHT_BIT_POS + 1, RIGHT_BIT_POS)
78
79#define APC_SECURE 0x00000000
80#define CPU_PWR_CTL 0x00000004
81#define APC_PWR_STATUS 0x00000008
82#define APC_TEST_BUS_SEL 0x0000000C
83#define CPU_TRGTD_DBG_RST 0x00000010
84#define APC_PWR_GATE_CTL 0x00000014
85#define APC_LDO_VREF_SET 0x00000018
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -070086#define APC_PWR_GATE_MODE 0x0000001C
87#define APC_PWR_GATE_DLY 0x00000020
88
89#define PWR_GATE_CONFIG 0x00000044
90#define VERSION 0x00000FD0
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070091
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -080092/* MDD register group */
93#define MDD_CONFIG_CTL 0x00000000
94#define MDD_MODE 0x00000010
95
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070096/* bit definitions for APC_PWR_GATE_CTL */
97#define BHS_CNT_BIT_POS 24
98#define BHS_CNT_MASK KRAIT_MASK(31, 24)
99#define BHS_CNT_DEFAULT 64
100
101#define CLK_SRC_SEL_BIT_POS 15
102#define CLK_SRC_SEL_MASK KRAIT_MASK(15, 15)
103#define CLK_SRC_DEFAULT 0
104
105#define LDO_PWR_DWN_BIT_POS 16
106#define LDO_PWR_DWN_MASK KRAIT_MASK(21, 16)
107
108#define LDO_BYP_BIT_POS 8
109#define LDO_BYP_MASK KRAIT_MASK(13, 8)
110
111#define BHS_SEG_EN_BIT_POS 1
112#define BHS_SEG_EN_MASK KRAIT_MASK(6, 1)
113#define BHS_SEG_EN_DEFAULT 0x3F
114
115#define BHS_EN_BIT_POS 0
116#define BHS_EN_MASK KRAIT_MASK(0, 0)
117
118/* bit definitions for APC_LDO_VREF_SET register */
119#define VREF_RET_POS 8
120#define VREF_RET_MASK KRAIT_MASK(14, 8)
121
122#define VREF_LDO_BIT_POS 0
123#define VREF_LDO_MASK KRAIT_MASK(6, 0)
124
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800125#define LDO_HDROOM_MIN 50000
126#define LDO_HDROOM_MAX 250000
127
128#define LDO_UV_MIN 465000
129#define LDO_UV_MAX 750000
130
131#define LDO_TH_MIN 600000
132#define LDO_TH_MAX 900000
133
134#define LDO_DELTA_MIN 10000
135#define LDO_DELTA_MAX 100000
136
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700137/**
138 * struct pmic_gang_vreg -
139 * @name: the string used to represent the gang
140 * @pmic_vmax_uV: the current pmic gang voltage
141 * @pmic_phase_count: the number of phases turned on in the gang
142 * @krait_power_vregs: a list of krait consumers this gang supplies to
143 * @krait_power_vregs_lock: lock to prevent simultaneous access to the list
144 * and its nodes. This needs to be taken by each
145 * regulator's callback functions to prevent
146 * simultaneous updates to the pmic's phase
147 * voltage.
148 */
149struct pmic_gang_vreg {
150 const char *name;
151 int pmic_vmax_uV;
152 int pmic_phase_count;
153 struct list_head krait_power_vregs;
154 struct mutex krait_power_vregs_lock;
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700155 bool pfm_mode;
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -0800156 int pmic_min_uV_for_retention;
157 bool retention_enabled;
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800158 bool use_phase_switching;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700159};
160
161static struct pmic_gang_vreg *the_gang;
162
163enum krait_supply_mode {
164 HS_MODE = REGULATOR_MODE_NORMAL,
165 LDO_MODE = REGULATOR_MODE_IDLE,
166};
167
168struct krait_power_vreg {
169 struct list_head link;
170 struct regulator_desc desc;
171 struct regulator_dev *rdev;
172 const char *name;
173 struct pmic_gang_vreg *pvreg;
174 int uV;
175 int load_uA;
176 enum krait_supply_mode mode;
177 void __iomem *reg_base;
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800178 void __iomem *mdd_base;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700179 int ldo_default_uV;
180 int retention_uV;
181 int headroom_uV;
182 int ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800183 int ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800184 int cpu_num;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800185 bool online;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700186};
187
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800188DEFINE_PER_CPU(struct krait_power_vreg *, krait_vregs);
189
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700190static u32 version;
191
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800192static int is_between(int left, int right, int value)
193{
194 if (left >= right && left >= value && value >= right)
195 return 1;
196 if (left <= right && left <= value && value <= right)
197 return 1;
198 return 0;
199}
200
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700201static void krait_masked_write(struct krait_power_vreg *kvreg,
202 int reg, uint32_t mask, uint32_t val)
203{
204 uint32_t reg_val;
205
206 reg_val = readl_relaxed(kvreg->reg_base + reg);
207 reg_val &= ~mask;
208 reg_val |= (val & mask);
209 writel_relaxed(reg_val, kvreg->reg_base + reg);
210
211 /*
212 * Barrier to ensure that the reads and writes from
213 * other regulator regions (they are 1k apart) execute in
214 * order to the above write.
215 */
216 mb();
217}
218
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800219static int get_krait_retention_ldo_uv(struct krait_power_vreg *kvreg)
220{
221 uint32_t reg_val;
222 int uV;
223
224 reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
225 reg_val &= VREF_RET_MASK;
226 reg_val >>= VREF_RET_POS;
227
228 if (reg_val == 0)
229 uV = 0;
230 else
231 uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
232
233 return uV;
234}
235
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700236static int get_krait_ldo_uv(struct krait_power_vreg *kvreg)
237{
238 uint32_t reg_val;
239 int uV;
240
241 reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
242 reg_val &= VREF_LDO_MASK;
243 reg_val >>= VREF_LDO_BIT_POS;
244
245 if (reg_val == 0)
246 uV = 0;
247 else
248 uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
249
250 return uV;
251}
252
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700253static int set_krait_retention_uv(struct krait_power_vreg *kvreg, int uV)
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700254{
255 uint32_t reg_val;
256
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700257 reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
258 krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_RET_MASK,
259 reg_val << VREF_RET_POS);
260
261 return 0;
262}
263
264static int set_krait_ldo_uv(struct krait_power_vreg *kvreg, int uV)
265{
266 uint32_t reg_val;
267
268 reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700269 krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_LDO_MASK,
270 reg_val << VREF_LDO_BIT_POS);
271
272 return 0;
273}
274
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800275static int __krait_power_mdd_enable(struct krait_power_vreg *kvreg, bool on)
276{
277 if (on) {
278 writel_relaxed(0x00000002, kvreg->mdd_base + MDD_MODE);
279 /* complete the above write before the delay */
280 mb();
281 udelay(MDD_SETTLING_DELAY_US);
282 } else {
283 writel_relaxed(0x00000000, kvreg->mdd_base + MDD_MODE);
284 /*
285 * complete the above write before other accesses
286 * to krait regulator
287 */
288 mb();
289 }
290 return 0;
291}
292
293int krait_power_mdd_enable(int cpu_num, bool on)
294{
Abhijeet Dharmapurikarc962e092013-02-20 00:57:21 -0800295 /*
296 * Expected to be called when the cpu goes to retention mode as a part
297 * of idle power collapse. IT is guaranteed that cpu won't be put in
298 * retention while being hotplugged out
299 */
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800300 struct krait_power_vreg *kvreg = per_cpu(krait_vregs, cpu_num);
301
302 if (!on && kvreg->mode == LDO_MODE) {
303 pr_debug("%s using LDO - cannot turn off MDD\n", kvreg->name);
304 return -EINVAL;
305 }
306
Abhijeet Dharmapurikarc962e092013-02-20 00:57:21 -0800307 if (on && kvreg->mode == LDO_MODE)
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800308 return 0;
309
310 __krait_power_mdd_enable(kvreg, on);
311 return 0;
312}
313
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700314static int switch_to_using_hs(struct krait_power_vreg *kvreg)
315{
316 if (kvreg->mode == HS_MODE)
317 return 0;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700318 /* enable bhs */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800319 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
320 BHS_SEG_EN_MASK | BHS_EN_MASK,
321 BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS | BHS_EN_MASK);
322
323 /* complete the above write before the delay */
324 mb();
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700325
326 /*
327 * wait for the bhs to settle - note that
328 * after the voltage has settled both BHS and LDO are supplying power
329 * to the krait. This avoids glitches during switching
330 */
331 udelay(BHS_SETTLING_DELAY_US);
332
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800333 /*
334 * enable ldo bypass - the krait is powered still by LDO since
335 * LDO is enabled
336 */
337 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_BYP_MASK, LDO_BYP_MASK);
338
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700339 /* disable ldo - only the BHS provides voltage to the cpu after this */
340 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
341 LDO_PWR_DWN_MASK, LDO_PWR_DWN_MASK);
342
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800343 /* turn off MDD since LDO is not used */
344 __krait_power_mdd_enable(kvreg, false);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700345 kvreg->mode = HS_MODE;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800346 pr_debug("%s using BHS\n", kvreg->name);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700347 return 0;
348}
349
350static int switch_to_using_ldo(struct krait_power_vreg *kvreg)
351{
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800352 if (kvreg->mode == LDO_MODE
353 && get_krait_ldo_uv(kvreg) == kvreg->uV - kvreg->ldo_delta_uV)
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700354 return 0;
355
356 /*
357 * if the krait is in ldo mode and a voltage change is requested on the
358 * ldo switch to using hs before changing ldo voltage
359 */
360 if (kvreg->mode == LDO_MODE)
361 switch_to_using_hs(kvreg);
362
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800363 /* turn on MDD since LDO is being turned on */
364 __krait_power_mdd_enable(kvreg, true);
365
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800366 set_krait_ldo_uv(kvreg, kvreg->uV - kvreg->ldo_delta_uV);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700367
368 /*
369 * enable ldo - note that both LDO and BHS are are supplying voltage to
370 * the cpu after this. This avoids glitches during switching from BHS
371 * to LDO.
372 */
373 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_PWR_DWN_MASK, 0);
374
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800375 /* complete the writes before the delay */
376 mb();
377
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700378 /* wait for the ldo to settle */
379 udelay(LDO_SETTLING_DELAY_US);
380
381 /*
382 * disable BHS and disable LDO bypass seperate from enabling
383 * the LDO above.
384 */
385 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
386 BHS_EN_MASK | LDO_BYP_MASK, 0);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800387 krait_masked_write(kvreg, APC_PWR_GATE_CTL, BHS_SEG_EN_MASK, 0);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700388
389 kvreg->mode = LDO_MODE;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800390 pr_debug("%s using LDO\n", kvreg->name);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700391 return 0;
392}
393
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800394static int set_pmic_gang_phases(struct pmic_gang_vreg *pvreg, int phase_count)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700395{
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800396 pr_debug("programming phase_count = %d\n", phase_count);
397 if (pvreg->use_phase_switching)
398 /*
399 * note the PMIC sets the phase count to one more than
400 * the value in the register - hence subtract 1 from it
401 */
402 return msm_spm_apcs_set_phase(phase_count - 1);
403 else
404 return 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700405}
406
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800407static int set_pmic_gang_voltage(struct pmic_gang_vreg *pvreg, int uV)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700408{
409 int setpoint;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800410 int rc;
411
412 if (pvreg->pmic_vmax_uV == uV)
413 return 0;
414
415 pr_debug("%d\n", uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700416
417 if (uV < PMIC_VOLTAGE_MIN) {
418 pr_err("requested %d < %d, restricting it to %d\n",
419 uV, PMIC_VOLTAGE_MIN, PMIC_VOLTAGE_MIN);
420 uV = PMIC_VOLTAGE_MIN;
421 }
422 if (uV > PMIC_VOLTAGE_MAX) {
423 pr_err("requested %d > %d, restricting it to %d\n",
424 uV, PMIC_VOLTAGE_MAX, PMIC_VOLTAGE_MAX);
425 uV = PMIC_VOLTAGE_MAX;
426 }
427
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -0800428 if (uV < pvreg->pmic_min_uV_for_retention) {
429 if (pvreg->retention_enabled) {
430 pr_debug("Disabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
431 uV, pvreg->pmic_min_uV_for_retention);
432 msm_pm_enable_retention(false);
433 pvreg->retention_enabled = false;
434 }
435 } else {
436 if (!pvreg->retention_enabled) {
437 pr_debug("Enabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
438 uV, pvreg->pmic_min_uV_for_retention);
439 msm_pm_enable_retention(true);
440 pvreg->retention_enabled = true;
441 }
442 }
443
Abhijeet Dharmapurikard4f38da2012-08-08 21:42:06 -0700444 setpoint = DIV_ROUND_UP(uV, LV_RANGE_STEP);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800445
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800446 rc = msm_spm_apcs_set_vdd(setpoint);
447 if (rc < 0)
448 pr_err("could not set %duV setpt = 0x%x rc = %d\n",
449 uV, setpoint, rc);
450 else
451 pvreg->pmic_vmax_uV = uV;
452
453 return rc;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700454}
455
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800456static int configure_ldo_or_hs_all(struct krait_power_vreg *from, int vmax)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700457{
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700458 struct pmic_gang_vreg *pvreg = from->pvreg;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700459 struct krait_power_vreg *kvreg;
460 int rc = 0;
461
462 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800463 if (!kvreg->online)
464 continue;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800465 if (kvreg->uV <= kvreg->ldo_threshold_uV
466 && kvreg->uV - kvreg->ldo_delta_uV + kvreg->headroom_uV
467 <= vmax) {
468 rc = switch_to_using_ldo(kvreg);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700469 if (rc < 0) {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800470 pr_err("could not switch %s to ldo rc = %d\n",
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700471 kvreg->name, rc);
472 return rc;
473 }
474 } else {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800475 rc = switch_to_using_hs(kvreg);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700476 if (rc < 0) {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800477 pr_err("could not switch %s to hs rc = %d\n",
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700478 kvreg->name, rc);
479 return rc;
480 }
481 }
482 }
483
484 return rc;
485}
486
487#define SLEW_RATE 2994
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800488static int krait_voltage_increase(struct krait_power_vreg *from,
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700489 int vmax)
490{
491 struct pmic_gang_vreg *pvreg = from->pvreg;
492 int rc = 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700493 int settling_us;
494
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700495 /*
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800496 * since krait voltage is increasing set the gang voltage
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700497 * prior to changing ldo/hs states of the requesting krait
498 */
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800499 rc = set_pmic_gang_voltage(pvreg, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700500 if (rc < 0) {
501 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
502 pvreg->name, vmax, rc);
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800503 return rc;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700504 }
505
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800506
507 /* complete the above writes before the delay */
508 mb();
509
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700510 /* delay until the voltage is settled when it is raised */
511 settling_us = DIV_ROUND_UP(vmax - pvreg->pmic_vmax_uV, SLEW_RATE);
512 udelay(settling_us);
513
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800514 rc = configure_ldo_or_hs_all(from, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700515 if (rc < 0) {
516 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
517 pvreg->name, vmax, rc);
518 }
519
520 return rc;
521}
522
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800523static int krait_voltage_decrease(struct krait_power_vreg *from,
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700524 int vmax)
525{
526 struct pmic_gang_vreg *pvreg = from->pvreg;
527 int rc = 0;
528
529 /*
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800530 * since krait voltage is decreasing ldos might get out of their
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700531 * operating range. Hence configure such kraits to be in hs mode prior
532 * to setting the pmic gang voltage
533 */
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800534 rc = configure_ldo_or_hs_all(from, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700535 if (rc < 0) {
536 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
537 pvreg->name, vmax, rc);
538 return rc;
539 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700540
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800541 rc = set_pmic_gang_voltage(pvreg, vmax);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700542 if (rc < 0) {
543 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
544 pvreg->name, vmax, rc);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700545 }
546
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700547 return rc;
548}
549
550#define PHASE_SETTLING_TIME_US 10
551static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
552 int load_uA)
553{
554 struct pmic_gang_vreg *pvreg = from->pvreg;
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800555 int phase_count = DIV_ROUND_UP(load_uA, LOAD_PER_PHASE);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700556 int rc = 0;
557
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800558 if (phase_count <= 0)
559 phase_count = 1;
560
561 /* Increase phases if it is less than the number of cpus online */
562 if (phase_count < num_online_cpus()) {
563 phase_count = num_online_cpus();
564 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700565
566 if (phase_count != pvreg->pmic_phase_count) {
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800567 rc = set_pmic_gang_phases(pvreg, phase_count);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700568 if (rc < 0) {
569 dev_err(&from->rdev->dev,
570 "%s failed set phase %d rc = %d\n",
571 pvreg->name, phase_count, rc);
572 return rc;
573 }
574
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800575 /* complete the writes before the delay */
576 mb();
577
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700578 /*
579 * delay until the phases are settled when
580 * the count is raised
581 */
582 if (phase_count > pvreg->pmic_phase_count)
583 udelay(PHASE_SETTLING_TIME_US);
584
585 pvreg->pmic_phase_count = phase_count;
586 }
587 return rc;
588}
589
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700590static int krait_power_get_voltage(struct regulator_dev *rdev)
591{
592 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
593
594 return kvreg->uV;
595}
596
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800597static int get_vmax(struct pmic_gang_vreg *pvreg)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700598{
599 int vmax = 0;
600 int v;
601 struct krait_power_vreg *kvreg;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700602
603 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800604 if (!kvreg->online)
605 continue;
606
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700607 v = kvreg->uV;
608
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700609 if (vmax < v)
610 vmax = v;
611 }
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800612
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700613 return vmax;
614}
615
616static int get_total_load(struct krait_power_vreg *from)
617{
618 int load_total = 0;
619 struct krait_power_vreg *kvreg;
620 struct pmic_gang_vreg *pvreg = from->pvreg;
621
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800622 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
623 if (!kvreg->online)
624 continue;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700625 load_total += kvreg->load_uA;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800626 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700627
628 return load_total;
629}
630
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700631#define ROUND_UP_VOLTAGE(v, res) (DIV_ROUND_UP(v, res) * res)
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800632static int _set_voltage(struct regulator_dev *rdev,
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800633 int orig_krait_uV, int requested_uV)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700634{
635 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
636 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
637 int rc;
638 int vmax;
639
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800640 pr_debug("%s: %d to %d\n", kvreg->name, orig_krait_uV, requested_uV);
641 /*
642 * Assign the voltage before updating the gang voltage as we iterate
643 * over all the core voltages and choose HS or LDO for each of them
644 */
645 kvreg->uV = requested_uV;
646
647 vmax = get_vmax(pvreg);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800648
649 /* round up the pmic voltage as per its resolution */
650 vmax = ROUND_UP_VOLTAGE(vmax, LV_RANGE_STEP);
651
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800652 if (requested_uV > orig_krait_uV)
653 rc = krait_voltage_increase(kvreg, vmax);
654 else
655 rc = krait_voltage_decrease(kvreg, vmax);
656
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800657 if (rc < 0) {
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800658 dev_err(&rdev->dev, "%s failed to set %duV from %duV rc = %d\n",
659 kvreg->name, requested_uV, orig_krait_uV, rc);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800660 }
661
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800662 return rc;
663}
664
665static int krait_power_set_voltage(struct regulator_dev *rdev,
666 int min_uV, int max_uV, unsigned *selector)
667{
668 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
669 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
670 int rc;
671
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700672 /*
673 * if the voltage requested is below LDO_THRESHOLD this cpu could
674 * switch to LDO mode. Hence round the voltage as per the LDO
675 * resolution
676 */
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700677 if (min_uV < kvreg->ldo_threshold_uV) {
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700678 if (min_uV < KRAIT_LDO_VOLTAGE_MIN)
679 min_uV = KRAIT_LDO_VOLTAGE_MIN;
680 min_uV = ROUND_UP_VOLTAGE(min_uV, KRAIT_LDO_STEP);
681 }
682
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700683 mutex_lock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800684 if (!kvreg->online) {
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800685 kvreg->uV = min_uV;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800686 mutex_unlock(&pvreg->krait_power_vregs_lock);
687 return 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700688 }
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700689
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800690 rc = _set_voltage(rdev, kvreg->uV, min_uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700691 mutex_unlock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800692
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700693 return rc;
694}
695
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700696#define PMIC_FTS_MODE_PFM 0x00
697#define PMIC_FTS_MODE_PWM 0x80
698#define PFM_LOAD_UA 500000
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800699static unsigned int _get_optimum_mode(struct regulator_dev *rdev,
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700700 int input_uV, int output_uV, int load_uA)
701{
702 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
703 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
704 int rc;
705 int load_total_uA;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700706
707 load_total_uA = get_total_load(kvreg);
708
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700709 if (load_total_uA < PFM_LOAD_UA) {
710 if (!pvreg->pfm_mode) {
711 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PFM);
712 if (rc) {
713 dev_err(&rdev->dev,
714 "%s enter PFM failed load %d rc = %d\n",
715 kvreg->name, load_total_uA, rc);
716 goto out;
717 } else {
718 pvreg->pfm_mode = true;
719 }
720 }
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800721 return kvreg->mode;
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700722 }
723
724 if (pvreg->pfm_mode) {
725 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PWM);
726 if (rc) {
727 dev_err(&rdev->dev,
728 "%s exit PFM failed load %d rc = %d\n",
729 kvreg->name, load_total_uA, rc);
730 goto out;
731 } else {
732 pvreg->pfm_mode = false;
733 }
734 }
735
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700736 rc = pmic_gang_set_phases(kvreg, load_total_uA);
737 if (rc < 0) {
738 dev_err(&rdev->dev, "%s failed set mode %d rc = %d\n",
739 kvreg->name, load_total_uA, rc);
740 goto out;
741 }
742
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700743out:
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800744 return kvreg->mode;
745}
746
747static unsigned int krait_power_get_optimum_mode(struct regulator_dev *rdev,
748 int input_uV, int output_uV, int load_uA)
749{
750 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
751 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
752 int rc;
753
754 mutex_lock(&pvreg->krait_power_vregs_lock);
755 kvreg->load_uA = load_uA;
756 if (!kvreg->online) {
757 mutex_unlock(&pvreg->krait_power_vregs_lock);
758 return kvreg->mode;
759 }
760
761 rc = _get_optimum_mode(rdev, input_uV, output_uV, load_uA);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700762 mutex_unlock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800763
764 return rc;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700765}
766
767static int krait_power_set_mode(struct regulator_dev *rdev, unsigned int mode)
768{
769 return 0;
770}
771
772static unsigned int krait_power_get_mode(struct regulator_dev *rdev)
773{
774 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
775
776 return kvreg->mode;
777}
778
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800779static int krait_power_is_enabled(struct regulator_dev *rdev)
780{
781 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
782
783 return kvreg->online;
784}
785
786static int krait_power_enable(struct regulator_dev *rdev)
787{
788 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
789 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
790 int rc;
791
792 mutex_lock(&pvreg->krait_power_vregs_lock);
Abhijeet Dharmapurikarc962e092013-02-20 00:57:21 -0800793 if (kvreg->mode == LDO_MODE)
794 __krait_power_mdd_enable(kvreg, true);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800795 kvreg->online = true;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800796 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV, kvreg->load_uA);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800797 if (rc < 0)
798 goto en_err;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800799 /*
800 * since the core is being enabled, behave as if it is increasing
801 * the core voltage
802 */
803 rc = _set_voltage(rdev, 0, kvreg->uV);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800804en_err:
805 mutex_unlock(&pvreg->krait_power_vregs_lock);
806 return rc;
807}
808
809static int krait_power_disable(struct regulator_dev *rdev)
810{
811 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
812 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
813 int rc;
814
815 mutex_lock(&pvreg->krait_power_vregs_lock);
816 kvreg->online = false;
817
818 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV,
819 kvreg->load_uA);
820 if (rc < 0)
821 goto dis_err;
822
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800823 rc = _set_voltage(rdev, kvreg->uV, kvreg->uV);
Abhijeet Dharmapurikarc962e092013-02-20 00:57:21 -0800824 if (kvreg->mode == LDO_MODE)
825 __krait_power_mdd_enable(kvreg, false);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800826dis_err:
827 mutex_unlock(&pvreg->krait_power_vregs_lock);
828 return rc;
829}
830
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700831static struct regulator_ops krait_power_ops = {
832 .get_voltage = krait_power_get_voltage,
833 .set_voltage = krait_power_set_voltage,
834 .get_optimum_mode = krait_power_get_optimum_mode,
835 .set_mode = krait_power_set_mode,
836 .get_mode = krait_power_get_mode,
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800837 .enable = krait_power_enable,
838 .disable = krait_power_disable,
839 .is_enabled = krait_power_is_enabled,
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700840};
841
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800842static struct dentry *dent;
843static int get_retention_dbg_uV(void *data, u64 *val)
844{
845 struct pmic_gang_vreg *pvreg = data;
846 struct krait_power_vreg *kvreg;
847
848 mutex_lock(&pvreg->krait_power_vregs_lock);
849 if (!list_empty(&pvreg->krait_power_vregs)) {
850 /* return the retention voltage on just the first cpu */
851 kvreg = list_entry((&pvreg->krait_power_vregs)->next,
852 typeof(*kvreg), link);
853 *val = get_krait_retention_ldo_uv(kvreg);
854 }
855 mutex_unlock(&pvreg->krait_power_vregs_lock);
856 return 0;
857}
858
859static int set_retention_dbg_uV(void *data, u64 val)
860{
861 struct pmic_gang_vreg *pvreg = data;
862 struct krait_power_vreg *kvreg;
863 int retention_uV = val;
864
865 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV))
866 return -EINVAL;
867
868 mutex_lock(&pvreg->krait_power_vregs_lock);
869 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
870 kvreg->retention_uV = retention_uV;
871 set_krait_retention_uv(kvreg, retention_uV);
872 }
873 mutex_unlock(&pvreg->krait_power_vregs_lock);
874 return 0;
875}
876DEFINE_SIMPLE_ATTRIBUTE(retention_fops,
877 get_retention_dbg_uV, set_retention_dbg_uV, "%llu\n");
878
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700879static void kvreg_hw_init(struct krait_power_vreg *kvreg)
880{
881 /*
882 * bhs_cnt value sets the ramp-up time from power collapse,
883 * initialize the ramp up time
884 */
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700885 set_krait_retention_uv(kvreg, kvreg->retention_uV);
886 set_krait_ldo_uv(kvreg, kvreg->ldo_default_uV);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800887
888 /* setup the bandgap that configures the reference to the LDO */
889 writel_relaxed(0x00000190, kvreg->mdd_base + MDD_CONFIG_CTL);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800890 mb();
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700891}
892
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700893static void glb_init(struct platform_device *pdev)
894{
895 /* configure bi-modal switch */
896 writel_relaxed(0x0008736E, MSM_APCS_GCC_BASE + PWR_GATE_CONFIG);
897 /* read kpss version */
898 version = readl_relaxed(MSM_APCS_GCC_BASE + VERSION);
899 pr_debug("version= 0x%x\n", version);
900}
901
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700902static int __devinit krait_power_probe(struct platform_device *pdev)
903{
904 struct krait_power_vreg *kvreg;
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800905 struct resource *res, *res_mdd;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700906 struct regulator_init_data *init_data = pdev->dev.platform_data;
907 int rc = 0;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700908 int headroom_uV, retention_uV, ldo_default_uV, ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800909 int ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800910 int cpu_num;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700911
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700912 if (pdev->dev.of_node) {
913 /* Get init_data from device tree. */
914 init_data = of_get_regulator_init_data(&pdev->dev,
915 pdev->dev.of_node);
916 init_data->constraints.valid_ops_mask
917 |= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_DRMS
918 | REGULATOR_CHANGE_MODE;
919 init_data->constraints.valid_modes_mask
920 |= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE
921 | REGULATOR_MODE_FAST;
922 init_data->constraints.input_uV = init_data->constraints.max_uV;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700923 rc = of_property_read_u32(pdev->dev.of_node,
924 "qcom,headroom-voltage",
925 &headroom_uV);
926 if (rc < 0) {
927 pr_err("headroom-voltage missing rc=%d\n", rc);
928 return rc;
929 }
930 if (!is_between(LDO_HDROOM_MIN, LDO_HDROOM_MAX, headroom_uV)) {
931 pr_err("bad headroom-voltage = %d specified\n",
932 headroom_uV);
933 return -EINVAL;
934 }
935
936 rc = of_property_read_u32(pdev->dev.of_node,
937 "qcom,retention-voltage",
938 &retention_uV);
939 if (rc < 0) {
940 pr_err("retention-voltage missing rc=%d\n", rc);
941 return rc;
942 }
943 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV)) {
944 pr_err("bad retention-voltage = %d specified\n",
945 retention_uV);
946 return -EINVAL;
947 }
948
949 rc = of_property_read_u32(pdev->dev.of_node,
950 "qcom,ldo-default-voltage",
951 &ldo_default_uV);
952 if (rc < 0) {
953 pr_err("ldo-default-voltage missing rc=%d\n", rc);
954 return rc;
955 }
956 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, ldo_default_uV)) {
957 pr_err("bad ldo-default-voltage = %d specified\n",
958 ldo_default_uV);
959 return -EINVAL;
960 }
961
962 rc = of_property_read_u32(pdev->dev.of_node,
963 "qcom,ldo-threshold-voltage",
964 &ldo_threshold_uV);
965 if (rc < 0) {
966 pr_err("ldo-threshold-voltage missing rc=%d\n", rc);
967 return rc;
968 }
969 if (!is_between(LDO_TH_MIN, LDO_TH_MAX, ldo_threshold_uV)) {
970 pr_err("bad ldo-threshold-voltage = %d specified\n",
971 ldo_threshold_uV);
972 return -EINVAL;
973 }
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800974
975 rc = of_property_read_u32(pdev->dev.of_node,
976 "qcom,ldo-delta-voltage",
977 &ldo_delta_uV);
978 if (rc < 0) {
979 pr_err("ldo-delta-voltage missing rc=%d\n", rc);
980 return rc;
981 }
982 if (!is_between(LDO_DELTA_MIN, LDO_DELTA_MAX, ldo_delta_uV)) {
983 pr_err("bad ldo-delta-voltage = %d specified\n",
984 ldo_delta_uV);
985 return -EINVAL;
986 }
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800987 rc = of_property_read_u32(pdev->dev.of_node,
988 "qcom,cpu-num",
989 &cpu_num);
990 if (cpu_num > num_possible_cpus()) {
991 pr_err("bad cpu-num= %d specified\n", cpu_num);
992 return -EINVAL;
993 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700994 }
995
996 if (!init_data) {
997 dev_err(&pdev->dev, "init data required.\n");
998 return -EINVAL;
999 }
1000
1001 if (!init_data->constraints.name) {
1002 dev_err(&pdev->dev,
1003 "regulator name must be specified in constraints.\n");
1004 return -EINVAL;
1005 }
1006
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001007 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acs");
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001008 if (!res) {
1009 dev_err(&pdev->dev, "missing physical register addresses\n");
1010 return -EINVAL;
1011 }
1012
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001013 res_mdd = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mdd");
1014 if (!res_mdd) {
1015 dev_err(&pdev->dev, "missing mdd register addresses\n");
1016 return -EINVAL;
1017 }
1018
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001019 kvreg = devm_kzalloc(&pdev->dev,
1020 sizeof(struct krait_power_vreg), GFP_KERNEL);
1021 if (!kvreg) {
1022 dev_err(&pdev->dev, "kzalloc failed.\n");
1023 return -ENOMEM;
1024 }
1025
1026 kvreg->reg_base = devm_ioremap(&pdev->dev,
1027 res->start, resource_size(res));
1028
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001029 kvreg->mdd_base = devm_ioremap(&pdev->dev,
1030 res_mdd->start, resource_size(res));
1031
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -07001032 kvreg->pvreg = the_gang;
1033 kvreg->name = init_data->constraints.name;
1034 kvreg->desc.name = kvreg->name;
1035 kvreg->desc.ops = &krait_power_ops;
1036 kvreg->desc.type = REGULATOR_VOLTAGE;
1037 kvreg->desc.owner = THIS_MODULE;
1038 kvreg->uV = CORE_VOLTAGE_MIN;
1039 kvreg->mode = HS_MODE;
1040 kvreg->desc.ops = &krait_power_ops;
1041 kvreg->headroom_uV = headroom_uV;
1042 kvreg->retention_uV = retention_uV;
1043 kvreg->ldo_default_uV = ldo_default_uV;
1044 kvreg->ldo_threshold_uV = ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -08001045 kvreg->ldo_delta_uV = ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001046 kvreg->cpu_num = cpu_num;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001047
1048 platform_set_drvdata(pdev, kvreg);
1049
1050 mutex_lock(&the_gang->krait_power_vregs_lock);
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -08001051 the_gang->pmic_min_uV_for_retention
1052 = min(the_gang->pmic_min_uV_for_retention,
1053 kvreg->retention_uV + kvreg->headroom_uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001054 list_add_tail(&kvreg->link, &the_gang->krait_power_vregs);
1055 mutex_unlock(&the_gang->krait_power_vregs_lock);
1056
1057 kvreg->rdev = regulator_register(&kvreg->desc, &pdev->dev, init_data,
1058 kvreg, pdev->dev.of_node);
1059 if (IS_ERR(kvreg->rdev)) {
1060 rc = PTR_ERR(kvreg->rdev);
1061 pr_err("regulator_register failed, rc=%d.\n", rc);
1062 goto out;
1063 }
1064
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -07001065 kvreg_hw_init(kvreg);
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001066 per_cpu(krait_vregs, cpu_num) = kvreg;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001067 dev_dbg(&pdev->dev, "id=%d, name=%s\n", pdev->id, kvreg->name);
1068
1069 return 0;
1070out:
1071 mutex_lock(&the_gang->krait_power_vregs_lock);
1072 list_del(&kvreg->link);
1073 mutex_unlock(&the_gang->krait_power_vregs_lock);
1074
1075 platform_set_drvdata(pdev, NULL);
1076 return rc;
1077}
1078
1079static int __devexit krait_power_remove(struct platform_device *pdev)
1080{
1081 struct krait_power_vreg *kvreg = platform_get_drvdata(pdev);
1082 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
1083
1084 mutex_lock(&pvreg->krait_power_vregs_lock);
1085 list_del(&kvreg->link);
1086 mutex_unlock(&pvreg->krait_power_vregs_lock);
1087
1088 regulator_unregister(kvreg->rdev);
1089 platform_set_drvdata(pdev, NULL);
1090 return 0;
1091}
1092
1093static struct of_device_id krait_power_match_table[] = {
1094 { .compatible = "qcom,krait-regulator", },
1095 {}
1096};
1097
1098static struct platform_driver krait_power_driver = {
1099 .probe = krait_power_probe,
1100 .remove = __devexit_p(krait_power_remove),
1101 .driver = {
1102 .name = KRAIT_REGULATOR_DRIVER_NAME,
1103 .of_match_table = krait_power_match_table,
1104 .owner = THIS_MODULE,
1105 },
1106};
1107
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001108static struct of_device_id krait_pdn_match_table[] = {
1109 { .compatible = "qcom,krait-pdn", },
1110 {}
1111};
1112
1113static int __devinit krait_pdn_probe(struct platform_device *pdev)
1114{
1115 int rc;
1116 bool use_phase_switching = false;
1117 struct device *dev = &pdev->dev;
1118 struct device_node *node = dev->of_node;
1119 struct pmic_gang_vreg *pvreg;
1120
1121 if (!dev->of_node) {
1122 dev_err(dev, "device tree information missing\n");
1123 return -ENODEV;
1124 }
1125
1126 use_phase_switching = of_property_read_bool(node,
1127 "qcom,use-phase-switching");
1128 pvreg = devm_kzalloc(&pdev->dev,
1129 sizeof(struct pmic_gang_vreg), GFP_KERNEL);
1130 if (!pvreg) {
1131 pr_err("kzalloc failed.\n");
1132 return 0;
1133 }
1134
1135 pvreg->name = "pmic_gang";
1136 pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
1137 pvreg->pmic_phase_count = -EINVAL;
1138 pvreg->retention_enabled = true;
1139 pvreg->pmic_min_uV_for_retention = INT_MAX;
1140 pvreg->use_phase_switching = use_phase_switching;
1141
1142 mutex_init(&pvreg->krait_power_vregs_lock);
1143 INIT_LIST_HEAD(&pvreg->krait_power_vregs);
1144 the_gang = pvreg;
1145
1146 pr_debug("name=%s inited\n", pvreg->name);
1147
1148 /* global initializtion */
1149 glb_init(pdev);
1150
1151 rc = of_platform_populate(node, NULL, NULL, dev);
1152 if (rc) {
1153 dev_err(dev, "failed to add child nodes, rc=%d\n", rc);
1154 return rc;
1155 }
1156
1157 dent = debugfs_create_dir(KRAIT_REGULATOR_DRIVER_NAME, NULL);
1158 debugfs_create_file("retention_uV",
1159 0644, dent, the_gang, &retention_fops);
1160 return 0;
1161}
1162
1163static int __devexit krait_pdn_remove(struct platform_device *pdev)
1164{
1165 the_gang = NULL;
1166 debugfs_remove_recursive(dent);
1167 return 0;
1168}
1169
1170static struct platform_driver krait_pdn_driver = {
1171 .probe = krait_pdn_probe,
1172 .remove = __devexit_p(krait_pdn_remove),
1173 .driver = {
1174 .name = KRAIT_PDN_DRIVER_NAME,
1175 .of_match_table = krait_pdn_match_table,
1176 .owner = THIS_MODULE,
1177 },
1178};
1179
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001180int __init krait_power_init(void)
1181{
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001182 int rc = platform_driver_register(&krait_power_driver);
1183 if (rc) {
1184 pr_err("failed to add %s driver rc = %d\n",
1185 KRAIT_REGULATOR_DRIVER_NAME, rc);
1186 return rc;
1187 }
1188 return platform_driver_register(&krait_pdn_driver);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001189}
1190
1191static void __exit krait_power_exit(void)
1192{
1193 platform_driver_unregister(&krait_power_driver);
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001194 platform_driver_unregister(&krait_pdn_driver);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001195}
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001196module_exit(krait_power_exit);
1197
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001198void secondary_cpu_hs_init(void *base_ptr)
1199{
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001200 /* Turn on the BHS, turn off LDO Bypass and power down LDO */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001201 writel_relaxed(
1202 BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
1203 | LDO_PWR_DWN_MASK
1204 | CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
1205 | BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
1206 | BHS_EN_MASK,
1207 base_ptr + APC_PWR_GATE_CTL);
1208
1209 /* complete the above write before the delay */
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001210 mb();
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001211
1212 /*
1213 * wait for the bhs to settle
1214 */
1215 udelay(BHS_SETTLING_DELAY_US);
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001216
1217 /* Finally turn on the bypass so that BHS supplies power */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001218 writel_relaxed(
1219 BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
1220 | LDO_PWR_DWN_MASK
1221 | CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
1222 | LDO_BYP_MASK
1223 | BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
1224 | BHS_EN_MASK,
1225 base_ptr + APC_PWR_GATE_CTL);
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001226}
1227
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001228MODULE_LICENSE("GPL v2");
1229MODULE_DESCRIPTION("KRAIT POWER regulator driver");
1230MODULE_VERSION("1.0");
1231MODULE_ALIAS("platform:"KRAIT_REGULATOR_DRIVER_NAME);