blob: 0c1e279b4d15ed41822f89a6f59db0ccb14b6b2a [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 Dharmapurikar00269e52012-05-14 17:59:10 -0700158};
159
160static struct pmic_gang_vreg *the_gang;
161
162enum krait_supply_mode {
163 HS_MODE = REGULATOR_MODE_NORMAL,
164 LDO_MODE = REGULATOR_MODE_IDLE,
165};
166
167struct krait_power_vreg {
168 struct list_head link;
169 struct regulator_desc desc;
170 struct regulator_dev *rdev;
171 const char *name;
172 struct pmic_gang_vreg *pvreg;
173 int uV;
174 int load_uA;
175 enum krait_supply_mode mode;
176 void __iomem *reg_base;
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800177 void __iomem *mdd_base;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700178 int ldo_default_uV;
179 int retention_uV;
180 int headroom_uV;
181 int ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800182 int ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800183 int cpu_num;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800184 bool online;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700185};
186
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800187DEFINE_PER_CPU(struct krait_power_vreg *, krait_vregs);
188
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700189static u32 version;
190
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800191static int is_between(int left, int right, int value)
192{
193 if (left >= right && left >= value && value >= right)
194 return 1;
195 if (left <= right && left <= value && value <= right)
196 return 1;
197 return 0;
198}
199
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700200static void krait_masked_write(struct krait_power_vreg *kvreg,
201 int reg, uint32_t mask, uint32_t val)
202{
203 uint32_t reg_val;
204
205 reg_val = readl_relaxed(kvreg->reg_base + reg);
206 reg_val &= ~mask;
207 reg_val |= (val & mask);
208 writel_relaxed(reg_val, kvreg->reg_base + reg);
209
210 /*
211 * Barrier to ensure that the reads and writes from
212 * other regulator regions (they are 1k apart) execute in
213 * order to the above write.
214 */
215 mb();
216}
217
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800218static int get_krait_retention_ldo_uv(struct krait_power_vreg *kvreg)
219{
220 uint32_t reg_val;
221 int uV;
222
223 reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
224 reg_val &= VREF_RET_MASK;
225 reg_val >>= VREF_RET_POS;
226
227 if (reg_val == 0)
228 uV = 0;
229 else
230 uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
231
232 return uV;
233}
234
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700235static int get_krait_ldo_uv(struct krait_power_vreg *kvreg)
236{
237 uint32_t reg_val;
238 int uV;
239
240 reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
241 reg_val &= VREF_LDO_MASK;
242 reg_val >>= VREF_LDO_BIT_POS;
243
244 if (reg_val == 0)
245 uV = 0;
246 else
247 uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
248
249 return uV;
250}
251
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700252static int set_krait_retention_uv(struct krait_power_vreg *kvreg, int uV)
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700253{
254 uint32_t reg_val;
255
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700256 reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
257 krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_RET_MASK,
258 reg_val << VREF_RET_POS);
259
260 return 0;
261}
262
263static int set_krait_ldo_uv(struct krait_power_vreg *kvreg, int uV)
264{
265 uint32_t reg_val;
266
267 reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700268 krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_LDO_MASK,
269 reg_val << VREF_LDO_BIT_POS);
270
271 return 0;
272}
273
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800274static int __krait_power_mdd_enable(struct krait_power_vreg *kvreg, bool on)
275{
276 if (on) {
277 writel_relaxed(0x00000002, kvreg->mdd_base + MDD_MODE);
278 /* complete the above write before the delay */
279 mb();
280 udelay(MDD_SETTLING_DELAY_US);
281 } else {
282 writel_relaxed(0x00000000, kvreg->mdd_base + MDD_MODE);
283 /*
284 * complete the above write before other accesses
285 * to krait regulator
286 */
287 mb();
288 }
289 return 0;
290}
291
292int krait_power_mdd_enable(int cpu_num, bool on)
293{
Abhijeet Dharmapurikarc962e092013-02-20 00:57:21 -0800294 /*
295 * Expected to be called when the cpu goes to retention mode as a part
296 * of idle power collapse. IT is guaranteed that cpu won't be put in
297 * retention while being hotplugged out
298 */
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800299 struct krait_power_vreg *kvreg = per_cpu(krait_vregs, cpu_num);
300
301 if (!on && kvreg->mode == LDO_MODE) {
302 pr_debug("%s using LDO - cannot turn off MDD\n", kvreg->name);
303 return -EINVAL;
304 }
305
Abhijeet Dharmapurikarc962e092013-02-20 00:57:21 -0800306 if (on && kvreg->mode == LDO_MODE)
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800307 return 0;
308
309 __krait_power_mdd_enable(kvreg, on);
310 return 0;
311}
312
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700313static int switch_to_using_hs(struct krait_power_vreg *kvreg)
314{
315 if (kvreg->mode == HS_MODE)
316 return 0;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700317 /* enable bhs */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800318 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
319 BHS_SEG_EN_MASK | BHS_EN_MASK,
320 BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS | BHS_EN_MASK);
321
322 /* complete the above write before the delay */
323 mb();
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700324
325 /*
326 * wait for the bhs to settle - note that
327 * after the voltage has settled both BHS and LDO are supplying power
328 * to the krait. This avoids glitches during switching
329 */
330 udelay(BHS_SETTLING_DELAY_US);
331
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800332 /*
333 * enable ldo bypass - the krait is powered still by LDO since
334 * LDO is enabled
335 */
336 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_BYP_MASK, LDO_BYP_MASK);
337
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700338 /* disable ldo - only the BHS provides voltage to the cpu after this */
339 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
340 LDO_PWR_DWN_MASK, LDO_PWR_DWN_MASK);
341
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800342 /* turn off MDD since LDO is not used */
343 __krait_power_mdd_enable(kvreg, false);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700344 kvreg->mode = HS_MODE;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800345 pr_debug("%s using BHS\n", kvreg->name);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700346 return 0;
347}
348
349static int switch_to_using_ldo(struct krait_power_vreg *kvreg)
350{
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800351 if (kvreg->mode == LDO_MODE
352 && get_krait_ldo_uv(kvreg) == kvreg->uV - kvreg->ldo_delta_uV)
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700353 return 0;
354
355 /*
356 * if the krait is in ldo mode and a voltage change is requested on the
357 * ldo switch to using hs before changing ldo voltage
358 */
359 if (kvreg->mode == LDO_MODE)
360 switch_to_using_hs(kvreg);
361
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800362 /* turn on MDD since LDO is being turned on */
363 __krait_power_mdd_enable(kvreg, true);
364
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800365 set_krait_ldo_uv(kvreg, kvreg->uV - kvreg->ldo_delta_uV);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700366
367 /*
368 * enable ldo - note that both LDO and BHS are are supplying voltage to
369 * the cpu after this. This avoids glitches during switching from BHS
370 * to LDO.
371 */
372 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_PWR_DWN_MASK, 0);
373
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800374 /* complete the writes before the delay */
375 mb();
376
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700377 /* wait for the ldo to settle */
378 udelay(LDO_SETTLING_DELAY_US);
379
380 /*
381 * disable BHS and disable LDO bypass seperate from enabling
382 * the LDO above.
383 */
384 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
385 BHS_EN_MASK | LDO_BYP_MASK, 0);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800386 krait_masked_write(kvreg, APC_PWR_GATE_CTL, BHS_SEG_EN_MASK, 0);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700387
388 kvreg->mode = LDO_MODE;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800389 pr_debug("%s using LDO\n", kvreg->name);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700390 return 0;
391}
392
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700393static int set_pmic_gang_phases(int phase_count)
394{
Abhijeet Dharmapurikare4b89ee2012-08-07 18:53:53 -0700395 /*
396 * TODO : spm writes for phase control,
397 * pmic phase control is not working yet
398 */
399 return 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700400}
401
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800402static int set_pmic_gang_voltage(struct pmic_gang_vreg *pvreg, int uV)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700403{
404 int setpoint;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800405 int rc;
406
407 if (pvreg->pmic_vmax_uV == uV)
408 return 0;
409
410 pr_debug("%d\n", uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700411
412 if (uV < PMIC_VOLTAGE_MIN) {
413 pr_err("requested %d < %d, restricting it to %d\n",
414 uV, PMIC_VOLTAGE_MIN, PMIC_VOLTAGE_MIN);
415 uV = PMIC_VOLTAGE_MIN;
416 }
417 if (uV > PMIC_VOLTAGE_MAX) {
418 pr_err("requested %d > %d, restricting it to %d\n",
419 uV, PMIC_VOLTAGE_MAX, PMIC_VOLTAGE_MAX);
420 uV = PMIC_VOLTAGE_MAX;
421 }
422
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -0800423 if (uV < pvreg->pmic_min_uV_for_retention) {
424 if (pvreg->retention_enabled) {
425 pr_debug("Disabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
426 uV, pvreg->pmic_min_uV_for_retention);
427 msm_pm_enable_retention(false);
428 pvreg->retention_enabled = false;
429 }
430 } else {
431 if (!pvreg->retention_enabled) {
432 pr_debug("Enabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
433 uV, pvreg->pmic_min_uV_for_retention);
434 msm_pm_enable_retention(true);
435 pvreg->retention_enabled = true;
436 }
437 }
438
Abhijeet Dharmapurikard4f38da2012-08-08 21:42:06 -0700439 setpoint = DIV_ROUND_UP(uV, LV_RANGE_STEP);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800440
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800441 rc = msm_spm_apcs_set_vdd(setpoint);
442 if (rc < 0)
443 pr_err("could not set %duV setpt = 0x%x rc = %d\n",
444 uV, setpoint, rc);
445 else
446 pvreg->pmic_vmax_uV = uV;
447
448 return rc;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700449}
450
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800451static int configure_ldo_or_hs_all(struct krait_power_vreg *from, int vmax)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700452{
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700453 struct pmic_gang_vreg *pvreg = from->pvreg;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700454 struct krait_power_vreg *kvreg;
455 int rc = 0;
456
457 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800458 if (!kvreg->online)
459 continue;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800460 if (kvreg->uV <= kvreg->ldo_threshold_uV
461 && kvreg->uV - kvreg->ldo_delta_uV + kvreg->headroom_uV
462 <= vmax) {
463 rc = switch_to_using_ldo(kvreg);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700464 if (rc < 0) {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800465 pr_err("could not switch %s to ldo rc = %d\n",
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700466 kvreg->name, rc);
467 return rc;
468 }
469 } else {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800470 rc = switch_to_using_hs(kvreg);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700471 if (rc < 0) {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800472 pr_err("could not switch %s to hs rc = %d\n",
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700473 kvreg->name, rc);
474 return rc;
475 }
476 }
477 }
478
479 return rc;
480}
481
482#define SLEW_RATE 2994
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800483static int krait_voltage_increase(struct krait_power_vreg *from,
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700484 int vmax)
485{
486 struct pmic_gang_vreg *pvreg = from->pvreg;
487 int rc = 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700488 int settling_us;
489
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700490 /*
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800491 * since krait voltage is increasing set the gang voltage
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700492 * prior to changing ldo/hs states of the requesting krait
493 */
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800494 rc = set_pmic_gang_voltage(pvreg, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700495 if (rc < 0) {
496 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
497 pvreg->name, vmax, rc);
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800498 return rc;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700499 }
500
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800501
502 /* complete the above writes before the delay */
503 mb();
504
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700505 /* delay until the voltage is settled when it is raised */
506 settling_us = DIV_ROUND_UP(vmax - pvreg->pmic_vmax_uV, SLEW_RATE);
507 udelay(settling_us);
508
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800509 rc = configure_ldo_or_hs_all(from, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700510 if (rc < 0) {
511 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
512 pvreg->name, vmax, rc);
513 }
514
515 return rc;
516}
517
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800518static int krait_voltage_decrease(struct krait_power_vreg *from,
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700519 int vmax)
520{
521 struct pmic_gang_vreg *pvreg = from->pvreg;
522 int rc = 0;
523
524 /*
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800525 * since krait voltage is decreasing ldos might get out of their
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700526 * operating range. Hence configure such kraits to be in hs mode prior
527 * to setting the pmic gang voltage
528 */
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800529 rc = configure_ldo_or_hs_all(from, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700530 if (rc < 0) {
531 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
532 pvreg->name, vmax, rc);
533 return rc;
534 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700535
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800536 rc = set_pmic_gang_voltage(pvreg, vmax);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700537 if (rc < 0) {
538 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
539 pvreg->name, vmax, rc);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700540 }
541
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700542 return rc;
543}
544
545#define PHASE_SETTLING_TIME_US 10
546static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
547 int load_uA)
548{
549 struct pmic_gang_vreg *pvreg = from->pvreg;
550 int phase_count = DIV_ROUND_UP(load_uA, LOAD_PER_PHASE) - 1;
551 int rc = 0;
552
553 if (phase_count < 0)
554 phase_count = 0;
555
556 if (phase_count != pvreg->pmic_phase_count) {
557 rc = set_pmic_gang_phases(phase_count);
558 if (rc < 0) {
559 dev_err(&from->rdev->dev,
560 "%s failed set phase %d rc = %d\n",
561 pvreg->name, phase_count, rc);
562 return rc;
563 }
564
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800565 /* complete the writes before the delay */
566 mb();
567
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700568 /*
569 * delay until the phases are settled when
570 * the count is raised
571 */
572 if (phase_count > pvreg->pmic_phase_count)
573 udelay(PHASE_SETTLING_TIME_US);
574
575 pvreg->pmic_phase_count = phase_count;
576 }
577 return rc;
578}
579
Matt Wagantall98bfbe92012-11-12 18:39:47 -0800580static int __devinit pvreg_init(struct platform_device *pdev)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700581{
582 struct pmic_gang_vreg *pvreg;
583
584 pvreg = devm_kzalloc(&pdev->dev,
585 sizeof(struct pmic_gang_vreg), GFP_KERNEL);
586 if (!pvreg) {
587 pr_err("kzalloc failed.\n");
588 return -ENOMEM;
589 }
590
591 pvreg->name = "pmic_gang";
592 pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
593 pvreg->pmic_phase_count = 1;
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -0800594 pvreg->retention_enabled = true;
595 pvreg->pmic_min_uV_for_retention = INT_MAX;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700596
597 mutex_init(&pvreg->krait_power_vregs_lock);
598 INIT_LIST_HEAD(&pvreg->krait_power_vregs);
599 the_gang = pvreg;
600
601 pr_debug("name=%s inited\n", pvreg->name);
602
603 return 0;
604}
605
606static int krait_power_get_voltage(struct regulator_dev *rdev)
607{
608 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
609
610 return kvreg->uV;
611}
612
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800613static int get_vmax(struct pmic_gang_vreg *pvreg)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700614{
615 int vmax = 0;
616 int v;
617 struct krait_power_vreg *kvreg;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700618
619 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800620 if (!kvreg->online)
621 continue;
622
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700623 v = kvreg->uV;
624
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700625 if (vmax < v)
626 vmax = v;
627 }
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800628
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700629 return vmax;
630}
631
632static int get_total_load(struct krait_power_vreg *from)
633{
634 int load_total = 0;
635 struct krait_power_vreg *kvreg;
636 struct pmic_gang_vreg *pvreg = from->pvreg;
637
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800638 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
639 if (!kvreg->online)
640 continue;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700641 load_total += kvreg->load_uA;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800642 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700643
644 return load_total;
645}
646
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700647#define ROUND_UP_VOLTAGE(v, res) (DIV_ROUND_UP(v, res) * res)
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800648static int _set_voltage(struct regulator_dev *rdev,
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800649 int orig_krait_uV, int requested_uV)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700650{
651 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
652 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
653 int rc;
654 int vmax;
655
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800656 pr_debug("%s: %d to %d\n", kvreg->name, orig_krait_uV, requested_uV);
657 /*
658 * Assign the voltage before updating the gang voltage as we iterate
659 * over all the core voltages and choose HS or LDO for each of them
660 */
661 kvreg->uV = requested_uV;
662
663 vmax = get_vmax(pvreg);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800664
665 /* round up the pmic voltage as per its resolution */
666 vmax = ROUND_UP_VOLTAGE(vmax, LV_RANGE_STEP);
667
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800668 if (requested_uV > orig_krait_uV)
669 rc = krait_voltage_increase(kvreg, vmax);
670 else
671 rc = krait_voltage_decrease(kvreg, vmax);
672
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800673 if (rc < 0) {
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800674 dev_err(&rdev->dev, "%s failed to set %duV from %duV rc = %d\n",
675 kvreg->name, requested_uV, orig_krait_uV, rc);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800676 }
677
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800678 return rc;
679}
680
681static int krait_power_set_voltage(struct regulator_dev *rdev,
682 int min_uV, int max_uV, unsigned *selector)
683{
684 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
685 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
686 int rc;
687
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700688 /*
689 * if the voltage requested is below LDO_THRESHOLD this cpu could
690 * switch to LDO mode. Hence round the voltage as per the LDO
691 * resolution
692 */
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700693 if (min_uV < kvreg->ldo_threshold_uV) {
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700694 if (min_uV < KRAIT_LDO_VOLTAGE_MIN)
695 min_uV = KRAIT_LDO_VOLTAGE_MIN;
696 min_uV = ROUND_UP_VOLTAGE(min_uV, KRAIT_LDO_STEP);
697 }
698
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700699 mutex_lock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800700 if (!kvreg->online) {
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800701 kvreg->uV = min_uV;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800702 mutex_unlock(&pvreg->krait_power_vregs_lock);
703 return 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700704 }
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700705
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800706 rc = _set_voltage(rdev, kvreg->uV, min_uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700707 mutex_unlock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800708
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700709 return rc;
710}
711
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700712#define PMIC_FTS_MODE_PFM 0x00
713#define PMIC_FTS_MODE_PWM 0x80
714#define PFM_LOAD_UA 500000
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800715static unsigned int _get_optimum_mode(struct regulator_dev *rdev,
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700716 int input_uV, int output_uV, int load_uA)
717{
718 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
719 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
720 int rc;
721 int load_total_uA;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700722
723 load_total_uA = get_total_load(kvreg);
724
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700725 if (load_total_uA < PFM_LOAD_UA) {
726 if (!pvreg->pfm_mode) {
727 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PFM);
728 if (rc) {
729 dev_err(&rdev->dev,
730 "%s enter PFM failed load %d rc = %d\n",
731 kvreg->name, load_total_uA, rc);
732 goto out;
733 } else {
734 pvreg->pfm_mode = true;
735 }
736 }
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800737 return kvreg->mode;
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700738 }
739
740 if (pvreg->pfm_mode) {
741 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PWM);
742 if (rc) {
743 dev_err(&rdev->dev,
744 "%s exit PFM failed load %d rc = %d\n",
745 kvreg->name, load_total_uA, rc);
746 goto out;
747 } else {
748 pvreg->pfm_mode = false;
749 }
750 }
751
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700752 rc = pmic_gang_set_phases(kvreg, load_total_uA);
753 if (rc < 0) {
754 dev_err(&rdev->dev, "%s failed set mode %d rc = %d\n",
755 kvreg->name, load_total_uA, rc);
756 goto out;
757 }
758
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700759out:
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800760 return kvreg->mode;
761}
762
763static unsigned int krait_power_get_optimum_mode(struct regulator_dev *rdev,
764 int input_uV, int output_uV, int load_uA)
765{
766 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
767 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
768 int rc;
769
770 mutex_lock(&pvreg->krait_power_vregs_lock);
771 kvreg->load_uA = load_uA;
772 if (!kvreg->online) {
773 mutex_unlock(&pvreg->krait_power_vregs_lock);
774 return kvreg->mode;
775 }
776
777 rc = _get_optimum_mode(rdev, input_uV, output_uV, load_uA);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700778 mutex_unlock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800779
780 return rc;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700781}
782
783static int krait_power_set_mode(struct regulator_dev *rdev, unsigned int mode)
784{
785 return 0;
786}
787
788static unsigned int krait_power_get_mode(struct regulator_dev *rdev)
789{
790 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
791
792 return kvreg->mode;
793}
794
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800795static int krait_power_is_enabled(struct regulator_dev *rdev)
796{
797 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
798
799 return kvreg->online;
800}
801
802static int krait_power_enable(struct regulator_dev *rdev)
803{
804 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
805 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
806 int rc;
807
808 mutex_lock(&pvreg->krait_power_vregs_lock);
Abhijeet Dharmapurikarc962e092013-02-20 00:57:21 -0800809 if (kvreg->mode == LDO_MODE)
810 __krait_power_mdd_enable(kvreg, true);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800811 kvreg->online = true;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800812 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV, kvreg->load_uA);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800813 if (rc < 0)
814 goto en_err;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800815 /*
816 * since the core is being enabled, behave as if it is increasing
817 * the core voltage
818 */
819 rc = _set_voltage(rdev, 0, kvreg->uV);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800820en_err:
821 mutex_unlock(&pvreg->krait_power_vregs_lock);
822 return rc;
823}
824
825static int krait_power_disable(struct regulator_dev *rdev)
826{
827 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
828 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
829 int rc;
830
831 mutex_lock(&pvreg->krait_power_vregs_lock);
832 kvreg->online = false;
833
834 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV,
835 kvreg->load_uA);
836 if (rc < 0)
837 goto dis_err;
838
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800839 rc = _set_voltage(rdev, kvreg->uV, kvreg->uV);
Abhijeet Dharmapurikarc962e092013-02-20 00:57:21 -0800840 if (kvreg->mode == LDO_MODE)
841 __krait_power_mdd_enable(kvreg, false);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800842dis_err:
843 mutex_unlock(&pvreg->krait_power_vregs_lock);
844 return rc;
845}
846
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700847static struct regulator_ops krait_power_ops = {
848 .get_voltage = krait_power_get_voltage,
849 .set_voltage = krait_power_set_voltage,
850 .get_optimum_mode = krait_power_get_optimum_mode,
851 .set_mode = krait_power_set_mode,
852 .get_mode = krait_power_get_mode,
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800853 .enable = krait_power_enable,
854 .disable = krait_power_disable,
855 .is_enabled = krait_power_is_enabled,
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700856};
857
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800858static struct dentry *dent;
859static int get_retention_dbg_uV(void *data, u64 *val)
860{
861 struct pmic_gang_vreg *pvreg = data;
862 struct krait_power_vreg *kvreg;
863
864 mutex_lock(&pvreg->krait_power_vregs_lock);
865 if (!list_empty(&pvreg->krait_power_vregs)) {
866 /* return the retention voltage on just the first cpu */
867 kvreg = list_entry((&pvreg->krait_power_vregs)->next,
868 typeof(*kvreg), link);
869 *val = get_krait_retention_ldo_uv(kvreg);
870 }
871 mutex_unlock(&pvreg->krait_power_vregs_lock);
872 return 0;
873}
874
875static int set_retention_dbg_uV(void *data, u64 val)
876{
877 struct pmic_gang_vreg *pvreg = data;
878 struct krait_power_vreg *kvreg;
879 int retention_uV = val;
880
881 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV))
882 return -EINVAL;
883
884 mutex_lock(&pvreg->krait_power_vregs_lock);
885 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
886 kvreg->retention_uV = retention_uV;
887 set_krait_retention_uv(kvreg, retention_uV);
888 }
889 mutex_unlock(&pvreg->krait_power_vregs_lock);
890 return 0;
891}
892DEFINE_SIMPLE_ATTRIBUTE(retention_fops,
893 get_retention_dbg_uV, set_retention_dbg_uV, "%llu\n");
894
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700895static void kvreg_hw_init(struct krait_power_vreg *kvreg)
896{
897 /*
898 * bhs_cnt value sets the ramp-up time from power collapse,
899 * initialize the ramp up time
900 */
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700901 set_krait_retention_uv(kvreg, kvreg->retention_uV);
902 set_krait_ldo_uv(kvreg, kvreg->ldo_default_uV);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800903
904 /* setup the bandgap that configures the reference to the LDO */
905 writel_relaxed(0x00000190, kvreg->mdd_base + MDD_CONFIG_CTL);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800906 mb();
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700907}
908
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700909static void glb_init(struct platform_device *pdev)
910{
911 /* configure bi-modal switch */
912 writel_relaxed(0x0008736E, MSM_APCS_GCC_BASE + PWR_GATE_CONFIG);
913 /* read kpss version */
914 version = readl_relaxed(MSM_APCS_GCC_BASE + VERSION);
915 pr_debug("version= 0x%x\n", version);
916}
917
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700918static int __devinit krait_power_probe(struct platform_device *pdev)
919{
920 struct krait_power_vreg *kvreg;
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800921 struct resource *res, *res_mdd;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700922 struct regulator_init_data *init_data = pdev->dev.platform_data;
923 int rc = 0;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700924 int headroom_uV, retention_uV, ldo_default_uV, ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800925 int ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800926 int cpu_num;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700927
928 /* Initialize the pmic gang if it hasn't been initialized already */
929 if (the_gang == NULL) {
930 rc = pvreg_init(pdev);
931 if (rc < 0) {
932 dev_err(&pdev->dev,
933 "failed to init pmic gang rc = %d\n", rc);
934 return rc;
935 }
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700936 /* global initializtion */
937 glb_init(pdev);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700938 }
939
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800940 if (dent == NULL) {
941 dent = debugfs_create_dir(KRAIT_REGULATOR_DRIVER_NAME, NULL);
942 debugfs_create_file("retention_uV",
943 0644, dent, the_gang, &retention_fops);
944 }
945
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700946 if (pdev->dev.of_node) {
947 /* Get init_data from device tree. */
948 init_data = of_get_regulator_init_data(&pdev->dev,
949 pdev->dev.of_node);
950 init_data->constraints.valid_ops_mask
951 |= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_DRMS
952 | REGULATOR_CHANGE_MODE;
953 init_data->constraints.valid_modes_mask
954 |= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE
955 | REGULATOR_MODE_FAST;
956 init_data->constraints.input_uV = init_data->constraints.max_uV;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700957 rc = of_property_read_u32(pdev->dev.of_node,
958 "qcom,headroom-voltage",
959 &headroom_uV);
960 if (rc < 0) {
961 pr_err("headroom-voltage missing rc=%d\n", rc);
962 return rc;
963 }
964 if (!is_between(LDO_HDROOM_MIN, LDO_HDROOM_MAX, headroom_uV)) {
965 pr_err("bad headroom-voltage = %d specified\n",
966 headroom_uV);
967 return -EINVAL;
968 }
969
970 rc = of_property_read_u32(pdev->dev.of_node,
971 "qcom,retention-voltage",
972 &retention_uV);
973 if (rc < 0) {
974 pr_err("retention-voltage missing rc=%d\n", rc);
975 return rc;
976 }
977 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV)) {
978 pr_err("bad retention-voltage = %d specified\n",
979 retention_uV);
980 return -EINVAL;
981 }
982
983 rc = of_property_read_u32(pdev->dev.of_node,
984 "qcom,ldo-default-voltage",
985 &ldo_default_uV);
986 if (rc < 0) {
987 pr_err("ldo-default-voltage missing rc=%d\n", rc);
988 return rc;
989 }
990 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, ldo_default_uV)) {
991 pr_err("bad ldo-default-voltage = %d specified\n",
992 ldo_default_uV);
993 return -EINVAL;
994 }
995
996 rc = of_property_read_u32(pdev->dev.of_node,
997 "qcom,ldo-threshold-voltage",
998 &ldo_threshold_uV);
999 if (rc < 0) {
1000 pr_err("ldo-threshold-voltage missing rc=%d\n", rc);
1001 return rc;
1002 }
1003 if (!is_between(LDO_TH_MIN, LDO_TH_MAX, ldo_threshold_uV)) {
1004 pr_err("bad ldo-threshold-voltage = %d specified\n",
1005 ldo_threshold_uV);
1006 return -EINVAL;
1007 }
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -08001008
1009 rc = of_property_read_u32(pdev->dev.of_node,
1010 "qcom,ldo-delta-voltage",
1011 &ldo_delta_uV);
1012 if (rc < 0) {
1013 pr_err("ldo-delta-voltage missing rc=%d\n", rc);
1014 return rc;
1015 }
1016 if (!is_between(LDO_DELTA_MIN, LDO_DELTA_MAX, ldo_delta_uV)) {
1017 pr_err("bad ldo-delta-voltage = %d specified\n",
1018 ldo_delta_uV);
1019 return -EINVAL;
1020 }
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001021 rc = of_property_read_u32(pdev->dev.of_node,
1022 "qcom,cpu-num",
1023 &cpu_num);
1024 if (cpu_num > num_possible_cpus()) {
1025 pr_err("bad cpu-num= %d specified\n", cpu_num);
1026 return -EINVAL;
1027 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001028 }
1029
1030 if (!init_data) {
1031 dev_err(&pdev->dev, "init data required.\n");
1032 return -EINVAL;
1033 }
1034
1035 if (!init_data->constraints.name) {
1036 dev_err(&pdev->dev,
1037 "regulator name must be specified in constraints.\n");
1038 return -EINVAL;
1039 }
1040
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001041 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acs");
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001042 if (!res) {
1043 dev_err(&pdev->dev, "missing physical register addresses\n");
1044 return -EINVAL;
1045 }
1046
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001047 res_mdd = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mdd");
1048 if (!res_mdd) {
1049 dev_err(&pdev->dev, "missing mdd register addresses\n");
1050 return -EINVAL;
1051 }
1052
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001053 kvreg = devm_kzalloc(&pdev->dev,
1054 sizeof(struct krait_power_vreg), GFP_KERNEL);
1055 if (!kvreg) {
1056 dev_err(&pdev->dev, "kzalloc failed.\n");
1057 return -ENOMEM;
1058 }
1059
1060 kvreg->reg_base = devm_ioremap(&pdev->dev,
1061 res->start, resource_size(res));
1062
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001063 kvreg->mdd_base = devm_ioremap(&pdev->dev,
1064 res_mdd->start, resource_size(res));
1065
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -07001066 kvreg->pvreg = the_gang;
1067 kvreg->name = init_data->constraints.name;
1068 kvreg->desc.name = kvreg->name;
1069 kvreg->desc.ops = &krait_power_ops;
1070 kvreg->desc.type = REGULATOR_VOLTAGE;
1071 kvreg->desc.owner = THIS_MODULE;
1072 kvreg->uV = CORE_VOLTAGE_MIN;
1073 kvreg->mode = HS_MODE;
1074 kvreg->desc.ops = &krait_power_ops;
1075 kvreg->headroom_uV = headroom_uV;
1076 kvreg->retention_uV = retention_uV;
1077 kvreg->ldo_default_uV = ldo_default_uV;
1078 kvreg->ldo_threshold_uV = ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -08001079 kvreg->ldo_delta_uV = ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001080 kvreg->cpu_num = cpu_num;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001081
1082 platform_set_drvdata(pdev, kvreg);
1083
1084 mutex_lock(&the_gang->krait_power_vregs_lock);
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -08001085 the_gang->pmic_min_uV_for_retention
1086 = min(the_gang->pmic_min_uV_for_retention,
1087 kvreg->retention_uV + kvreg->headroom_uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001088 list_add_tail(&kvreg->link, &the_gang->krait_power_vregs);
1089 mutex_unlock(&the_gang->krait_power_vregs_lock);
1090
1091 kvreg->rdev = regulator_register(&kvreg->desc, &pdev->dev, init_data,
1092 kvreg, pdev->dev.of_node);
1093 if (IS_ERR(kvreg->rdev)) {
1094 rc = PTR_ERR(kvreg->rdev);
1095 pr_err("regulator_register failed, rc=%d.\n", rc);
1096 goto out;
1097 }
1098
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -07001099 kvreg_hw_init(kvreg);
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001100 per_cpu(krait_vregs, cpu_num) = kvreg;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001101 dev_dbg(&pdev->dev, "id=%d, name=%s\n", pdev->id, kvreg->name);
1102
1103 return 0;
1104out:
1105 mutex_lock(&the_gang->krait_power_vregs_lock);
1106 list_del(&kvreg->link);
1107 mutex_unlock(&the_gang->krait_power_vregs_lock);
1108
1109 platform_set_drvdata(pdev, NULL);
1110 return rc;
1111}
1112
1113static int __devexit krait_power_remove(struct platform_device *pdev)
1114{
1115 struct krait_power_vreg *kvreg = platform_get_drvdata(pdev);
1116 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
1117
1118 mutex_lock(&pvreg->krait_power_vregs_lock);
1119 list_del(&kvreg->link);
1120 mutex_unlock(&pvreg->krait_power_vregs_lock);
1121
1122 regulator_unregister(kvreg->rdev);
1123 platform_set_drvdata(pdev, NULL);
1124 return 0;
1125}
1126
1127static struct of_device_id krait_power_match_table[] = {
1128 { .compatible = "qcom,krait-regulator", },
1129 {}
1130};
1131
1132static struct platform_driver krait_power_driver = {
1133 .probe = krait_power_probe,
1134 .remove = __devexit_p(krait_power_remove),
1135 .driver = {
1136 .name = KRAIT_REGULATOR_DRIVER_NAME,
1137 .of_match_table = krait_power_match_table,
1138 .owner = THIS_MODULE,
1139 },
1140};
1141
1142int __init krait_power_init(void)
1143{
1144 return platform_driver_register(&krait_power_driver);
1145}
1146
1147static void __exit krait_power_exit(void)
1148{
1149 platform_driver_unregister(&krait_power_driver);
1150}
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001151module_exit(krait_power_exit);
1152
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001153void secondary_cpu_hs_init(void *base_ptr)
1154{
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001155 /* Turn on the BHS, turn off LDO Bypass and power down LDO */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001156 writel_relaxed(
1157 BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
1158 | LDO_PWR_DWN_MASK
1159 | CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
1160 | BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
1161 | BHS_EN_MASK,
1162 base_ptr + APC_PWR_GATE_CTL);
1163
1164 /* complete the above write before the delay */
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001165 mb();
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001166
1167 /*
1168 * wait for the bhs to settle
1169 */
1170 udelay(BHS_SETTLING_DELAY_US);
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001171
1172 /* Finally turn on the bypass so that BHS supplies power */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001173 writel_relaxed(
1174 BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
1175 | LDO_PWR_DWN_MASK
1176 | CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
1177 | LDO_BYP_MASK
1178 | BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
1179 | BHS_EN_MASK,
1180 base_ptr + APC_PWR_GATE_CTL);
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001181}
1182
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001183MODULE_LICENSE("GPL v2");
1184MODULE_DESCRIPTION("KRAIT POWER regulator driver");
1185MODULE_VERSION("1.0");
1186MODULE_ALIAS("platform:"KRAIT_REGULATOR_DRIVER_NAME);