blob: 01be64137db0ce46f7a2943c12148dd267517387 [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{
294 struct krait_power_vreg *kvreg = per_cpu(krait_vregs, cpu_num);
295
296 if (!on && kvreg->mode == LDO_MODE) {
297 pr_debug("%s using LDO - cannot turn off MDD\n", kvreg->name);
298 return -EINVAL;
299 }
300
301 if ((on && kvreg->mode == LDO_MODE) || (!on && kvreg->mode == HS_MODE))
302 return 0;
303
304 __krait_power_mdd_enable(kvreg, on);
305 return 0;
306}
307
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700308static int switch_to_using_hs(struct krait_power_vreg *kvreg)
309{
310 if (kvreg->mode == HS_MODE)
311 return 0;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700312 /* enable bhs */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800313 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
314 BHS_SEG_EN_MASK | BHS_EN_MASK,
315 BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS | BHS_EN_MASK);
316
317 /* complete the above write before the delay */
318 mb();
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700319
320 /*
321 * wait for the bhs to settle - note that
322 * after the voltage has settled both BHS and LDO are supplying power
323 * to the krait. This avoids glitches during switching
324 */
325 udelay(BHS_SETTLING_DELAY_US);
326
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800327 /*
328 * enable ldo bypass - the krait is powered still by LDO since
329 * LDO is enabled
330 */
331 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_BYP_MASK, LDO_BYP_MASK);
332
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700333 /* disable ldo - only the BHS provides voltage to the cpu after this */
334 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
335 LDO_PWR_DWN_MASK, LDO_PWR_DWN_MASK);
336
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800337 /* turn off MDD since LDO is not used */
338 __krait_power_mdd_enable(kvreg, false);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700339 kvreg->mode = HS_MODE;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800340 pr_debug("%s using BHS\n", kvreg->name);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700341 return 0;
342}
343
344static int switch_to_using_ldo(struct krait_power_vreg *kvreg)
345{
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800346 if (kvreg->mode == LDO_MODE
347 && get_krait_ldo_uv(kvreg) == kvreg->uV - kvreg->ldo_delta_uV)
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700348 return 0;
349
350 /*
351 * if the krait is in ldo mode and a voltage change is requested on the
352 * ldo switch to using hs before changing ldo voltage
353 */
354 if (kvreg->mode == LDO_MODE)
355 switch_to_using_hs(kvreg);
356
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800357 /* turn on MDD since LDO is being turned on */
358 __krait_power_mdd_enable(kvreg, true);
359
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800360 set_krait_ldo_uv(kvreg, kvreg->uV - kvreg->ldo_delta_uV);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700361
362 /*
363 * enable ldo - note that both LDO and BHS are are supplying voltage to
364 * the cpu after this. This avoids glitches during switching from BHS
365 * to LDO.
366 */
367 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_PWR_DWN_MASK, 0);
368
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800369 /* complete the writes before the delay */
370 mb();
371
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700372 /* wait for the ldo to settle */
373 udelay(LDO_SETTLING_DELAY_US);
374
375 /*
376 * disable BHS and disable LDO bypass seperate from enabling
377 * the LDO above.
378 */
379 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
380 BHS_EN_MASK | LDO_BYP_MASK, 0);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800381 krait_masked_write(kvreg, APC_PWR_GATE_CTL, BHS_SEG_EN_MASK, 0);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700382
383 kvreg->mode = LDO_MODE;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800384 pr_debug("%s using LDO\n", kvreg->name);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700385 return 0;
386}
387
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700388static int set_pmic_gang_phases(int phase_count)
389{
Abhijeet Dharmapurikare4b89ee2012-08-07 18:53:53 -0700390 /*
391 * TODO : spm writes for phase control,
392 * pmic phase control is not working yet
393 */
394 return 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700395}
396
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800397static int set_pmic_gang_voltage(struct pmic_gang_vreg *pvreg, int uV)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700398{
399 int setpoint;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800400 int rc;
401
402 if (pvreg->pmic_vmax_uV == uV)
403 return 0;
404
405 pr_debug("%d\n", uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700406
407 if (uV < PMIC_VOLTAGE_MIN) {
408 pr_err("requested %d < %d, restricting it to %d\n",
409 uV, PMIC_VOLTAGE_MIN, PMIC_VOLTAGE_MIN);
410 uV = PMIC_VOLTAGE_MIN;
411 }
412 if (uV > PMIC_VOLTAGE_MAX) {
413 pr_err("requested %d > %d, restricting it to %d\n",
414 uV, PMIC_VOLTAGE_MAX, PMIC_VOLTAGE_MAX);
415 uV = PMIC_VOLTAGE_MAX;
416 }
417
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -0800418 if (uV < pvreg->pmic_min_uV_for_retention) {
419 if (pvreg->retention_enabled) {
420 pr_debug("Disabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
421 uV, pvreg->pmic_min_uV_for_retention);
422 msm_pm_enable_retention(false);
423 pvreg->retention_enabled = false;
424 }
425 } else {
426 if (!pvreg->retention_enabled) {
427 pr_debug("Enabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
428 uV, pvreg->pmic_min_uV_for_retention);
429 msm_pm_enable_retention(true);
430 pvreg->retention_enabled = true;
431 }
432 }
433
Abhijeet Dharmapurikard4f38da2012-08-08 21:42:06 -0700434 setpoint = DIV_ROUND_UP(uV, LV_RANGE_STEP);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800435
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800436 rc = msm_spm_apcs_set_vdd(setpoint);
437 if (rc < 0)
438 pr_err("could not set %duV setpt = 0x%x rc = %d\n",
439 uV, setpoint, rc);
440 else
441 pvreg->pmic_vmax_uV = uV;
442
443 return rc;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700444}
445
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800446static int configure_ldo_or_hs_all(struct krait_power_vreg *from, int vmax)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700447{
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700448 struct pmic_gang_vreg *pvreg = from->pvreg;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700449 struct krait_power_vreg *kvreg;
450 int rc = 0;
451
452 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800453 if (!kvreg->online)
454 continue;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800455 if (kvreg->uV <= kvreg->ldo_threshold_uV
456 && kvreg->uV - kvreg->ldo_delta_uV + kvreg->headroom_uV
457 <= vmax) {
458 rc = switch_to_using_ldo(kvreg);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700459 if (rc < 0) {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800460 pr_err("could not switch %s to ldo rc = %d\n",
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700461 kvreg->name, rc);
462 return rc;
463 }
464 } else {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800465 rc = switch_to_using_hs(kvreg);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700466 if (rc < 0) {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800467 pr_err("could not switch %s to hs rc = %d\n",
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700468 kvreg->name, rc);
469 return rc;
470 }
471 }
472 }
473
474 return rc;
475}
476
477#define SLEW_RATE 2994
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800478static int krait_voltage_increase(struct krait_power_vreg *from,
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700479 int vmax)
480{
481 struct pmic_gang_vreg *pvreg = from->pvreg;
482 int rc = 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700483 int settling_us;
484
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700485 /*
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800486 * since krait voltage is increasing set the gang voltage
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700487 * prior to changing ldo/hs states of the requesting krait
488 */
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800489 rc = set_pmic_gang_voltage(pvreg, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700490 if (rc < 0) {
491 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
492 pvreg->name, vmax, rc);
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800493 return rc;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700494 }
495
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800496
497 /* complete the above writes before the delay */
498 mb();
499
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700500 /* delay until the voltage is settled when it is raised */
501 settling_us = DIV_ROUND_UP(vmax - pvreg->pmic_vmax_uV, SLEW_RATE);
502 udelay(settling_us);
503
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800504 rc = configure_ldo_or_hs_all(from, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700505 if (rc < 0) {
506 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
507 pvreg->name, vmax, rc);
508 }
509
510 return rc;
511}
512
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800513static int krait_voltage_decrease(struct krait_power_vreg *from,
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700514 int vmax)
515{
516 struct pmic_gang_vreg *pvreg = from->pvreg;
517 int rc = 0;
518
519 /*
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800520 * since krait voltage is decreasing ldos might get out of their
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700521 * operating range. Hence configure such kraits to be in hs mode prior
522 * to setting the pmic gang voltage
523 */
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800524 rc = configure_ldo_or_hs_all(from, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700525 if (rc < 0) {
526 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
527 pvreg->name, vmax, rc);
528 return rc;
529 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700530
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800531 rc = set_pmic_gang_voltage(pvreg, vmax);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700532 if (rc < 0) {
533 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
534 pvreg->name, vmax, rc);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700535 }
536
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700537 return rc;
538}
539
540#define PHASE_SETTLING_TIME_US 10
541static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
542 int load_uA)
543{
544 struct pmic_gang_vreg *pvreg = from->pvreg;
545 int phase_count = DIV_ROUND_UP(load_uA, LOAD_PER_PHASE) - 1;
546 int rc = 0;
547
548 if (phase_count < 0)
549 phase_count = 0;
550
551 if (phase_count != pvreg->pmic_phase_count) {
552 rc = set_pmic_gang_phases(phase_count);
553 if (rc < 0) {
554 dev_err(&from->rdev->dev,
555 "%s failed set phase %d rc = %d\n",
556 pvreg->name, phase_count, rc);
557 return rc;
558 }
559
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800560 /* complete the writes before the delay */
561 mb();
562
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700563 /*
564 * delay until the phases are settled when
565 * the count is raised
566 */
567 if (phase_count > pvreg->pmic_phase_count)
568 udelay(PHASE_SETTLING_TIME_US);
569
570 pvreg->pmic_phase_count = phase_count;
571 }
572 return rc;
573}
574
Matt Wagantall98bfbe92012-11-12 18:39:47 -0800575static int __devinit pvreg_init(struct platform_device *pdev)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700576{
577 struct pmic_gang_vreg *pvreg;
578
579 pvreg = devm_kzalloc(&pdev->dev,
580 sizeof(struct pmic_gang_vreg), GFP_KERNEL);
581 if (!pvreg) {
582 pr_err("kzalloc failed.\n");
583 return -ENOMEM;
584 }
585
586 pvreg->name = "pmic_gang";
587 pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
588 pvreg->pmic_phase_count = 1;
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -0800589 pvreg->retention_enabled = true;
590 pvreg->pmic_min_uV_for_retention = INT_MAX;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700591
592 mutex_init(&pvreg->krait_power_vregs_lock);
593 INIT_LIST_HEAD(&pvreg->krait_power_vregs);
594 the_gang = pvreg;
595
596 pr_debug("name=%s inited\n", pvreg->name);
597
598 return 0;
599}
600
601static int krait_power_get_voltage(struct regulator_dev *rdev)
602{
603 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
604
605 return kvreg->uV;
606}
607
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800608static int get_vmax(struct pmic_gang_vreg *pvreg)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700609{
610 int vmax = 0;
611 int v;
612 struct krait_power_vreg *kvreg;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700613
614 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800615 if (!kvreg->online)
616 continue;
617
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700618 v = kvreg->uV;
619
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700620 if (vmax < v)
621 vmax = v;
622 }
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800623
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700624 return vmax;
625}
626
627static int get_total_load(struct krait_power_vreg *from)
628{
629 int load_total = 0;
630 struct krait_power_vreg *kvreg;
631 struct pmic_gang_vreg *pvreg = from->pvreg;
632
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800633 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
634 if (!kvreg->online)
635 continue;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700636 load_total += kvreg->load_uA;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800637 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700638
639 return load_total;
640}
641
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700642#define ROUND_UP_VOLTAGE(v, res) (DIV_ROUND_UP(v, res) * res)
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800643static int _set_voltage(struct regulator_dev *rdev,
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800644 int orig_krait_uV, int requested_uV)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700645{
646 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
647 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
648 int rc;
649 int vmax;
650
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800651 pr_debug("%s: %d to %d\n", kvreg->name, orig_krait_uV, requested_uV);
652 /*
653 * Assign the voltage before updating the gang voltage as we iterate
654 * over all the core voltages and choose HS or LDO for each of them
655 */
656 kvreg->uV = requested_uV;
657
658 vmax = get_vmax(pvreg);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800659
660 /* round up the pmic voltage as per its resolution */
661 vmax = ROUND_UP_VOLTAGE(vmax, LV_RANGE_STEP);
662
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800663 if (requested_uV > orig_krait_uV)
664 rc = krait_voltage_increase(kvreg, vmax);
665 else
666 rc = krait_voltage_decrease(kvreg, vmax);
667
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800668 if (rc < 0) {
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800669 dev_err(&rdev->dev, "%s failed to set %duV from %duV rc = %d\n",
670 kvreg->name, requested_uV, orig_krait_uV, rc);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800671 }
672
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800673 return rc;
674}
675
676static int krait_power_set_voltage(struct regulator_dev *rdev,
677 int min_uV, int max_uV, unsigned *selector)
678{
679 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
680 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
681 int rc;
682
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700683 /*
684 * if the voltage requested is below LDO_THRESHOLD this cpu could
685 * switch to LDO mode. Hence round the voltage as per the LDO
686 * resolution
687 */
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700688 if (min_uV < kvreg->ldo_threshold_uV) {
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700689 if (min_uV < KRAIT_LDO_VOLTAGE_MIN)
690 min_uV = KRAIT_LDO_VOLTAGE_MIN;
691 min_uV = ROUND_UP_VOLTAGE(min_uV, KRAIT_LDO_STEP);
692 }
693
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700694 mutex_lock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800695 if (!kvreg->online) {
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800696 kvreg->uV = min_uV;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800697 mutex_unlock(&pvreg->krait_power_vregs_lock);
698 return 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700699 }
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700700
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800701 rc = _set_voltage(rdev, kvreg->uV, min_uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700702 mutex_unlock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800703
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700704 return rc;
705}
706
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700707#define PMIC_FTS_MODE_PFM 0x00
708#define PMIC_FTS_MODE_PWM 0x80
709#define PFM_LOAD_UA 500000
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800710static unsigned int _get_optimum_mode(struct regulator_dev *rdev,
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700711 int input_uV, int output_uV, int load_uA)
712{
713 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
714 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
715 int rc;
716 int load_total_uA;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700717
718 load_total_uA = get_total_load(kvreg);
719
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700720 if (load_total_uA < PFM_LOAD_UA) {
721 if (!pvreg->pfm_mode) {
722 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PFM);
723 if (rc) {
724 dev_err(&rdev->dev,
725 "%s enter PFM failed load %d rc = %d\n",
726 kvreg->name, load_total_uA, rc);
727 goto out;
728 } else {
729 pvreg->pfm_mode = true;
730 }
731 }
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800732 return kvreg->mode;
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700733 }
734
735 if (pvreg->pfm_mode) {
736 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PWM);
737 if (rc) {
738 dev_err(&rdev->dev,
739 "%s exit PFM failed load %d rc = %d\n",
740 kvreg->name, load_total_uA, rc);
741 goto out;
742 } else {
743 pvreg->pfm_mode = false;
744 }
745 }
746
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700747 rc = pmic_gang_set_phases(kvreg, load_total_uA);
748 if (rc < 0) {
749 dev_err(&rdev->dev, "%s failed set mode %d rc = %d\n",
750 kvreg->name, load_total_uA, rc);
751 goto out;
752 }
753
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700754out:
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800755 return kvreg->mode;
756}
757
758static unsigned int krait_power_get_optimum_mode(struct regulator_dev *rdev,
759 int input_uV, int output_uV, int load_uA)
760{
761 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
762 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
763 int rc;
764
765 mutex_lock(&pvreg->krait_power_vregs_lock);
766 kvreg->load_uA = load_uA;
767 if (!kvreg->online) {
768 mutex_unlock(&pvreg->krait_power_vregs_lock);
769 return kvreg->mode;
770 }
771
772 rc = _get_optimum_mode(rdev, input_uV, output_uV, load_uA);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700773 mutex_unlock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800774
775 return rc;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700776}
777
778static int krait_power_set_mode(struct regulator_dev *rdev, unsigned int mode)
779{
780 return 0;
781}
782
783static unsigned int krait_power_get_mode(struct regulator_dev *rdev)
784{
785 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
786
787 return kvreg->mode;
788}
789
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800790static int krait_power_is_enabled(struct regulator_dev *rdev)
791{
792 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
793
794 return kvreg->online;
795}
796
797static int krait_power_enable(struct regulator_dev *rdev)
798{
799 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
800 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
801 int rc;
802
803 mutex_lock(&pvreg->krait_power_vregs_lock);
804 kvreg->online = true;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800805 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV, kvreg->load_uA);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800806 if (rc < 0)
807 goto en_err;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800808 /*
809 * since the core is being enabled, behave as if it is increasing
810 * the core voltage
811 */
812 rc = _set_voltage(rdev, 0, kvreg->uV);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800813en_err:
814 mutex_unlock(&pvreg->krait_power_vregs_lock);
815 return rc;
816}
817
818static int krait_power_disable(struct regulator_dev *rdev)
819{
820 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
821 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
822 int rc;
823
824 mutex_lock(&pvreg->krait_power_vregs_lock);
825 kvreg->online = false;
826
827 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV,
828 kvreg->load_uA);
829 if (rc < 0)
830 goto dis_err;
831
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800832 rc = _set_voltage(rdev, kvreg->uV, kvreg->uV);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800833dis_err:
834 mutex_unlock(&pvreg->krait_power_vregs_lock);
835 return rc;
836}
837
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700838static struct regulator_ops krait_power_ops = {
839 .get_voltage = krait_power_get_voltage,
840 .set_voltage = krait_power_set_voltage,
841 .get_optimum_mode = krait_power_get_optimum_mode,
842 .set_mode = krait_power_set_mode,
843 .get_mode = krait_power_get_mode,
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800844 .enable = krait_power_enable,
845 .disable = krait_power_disable,
846 .is_enabled = krait_power_is_enabled,
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700847};
848
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800849static struct dentry *dent;
850static int get_retention_dbg_uV(void *data, u64 *val)
851{
852 struct pmic_gang_vreg *pvreg = data;
853 struct krait_power_vreg *kvreg;
854
855 mutex_lock(&pvreg->krait_power_vregs_lock);
856 if (!list_empty(&pvreg->krait_power_vregs)) {
857 /* return the retention voltage on just the first cpu */
858 kvreg = list_entry((&pvreg->krait_power_vregs)->next,
859 typeof(*kvreg), link);
860 *val = get_krait_retention_ldo_uv(kvreg);
861 }
862 mutex_unlock(&pvreg->krait_power_vregs_lock);
863 return 0;
864}
865
866static int set_retention_dbg_uV(void *data, u64 val)
867{
868 struct pmic_gang_vreg *pvreg = data;
869 struct krait_power_vreg *kvreg;
870 int retention_uV = val;
871
872 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV))
873 return -EINVAL;
874
875 mutex_lock(&pvreg->krait_power_vregs_lock);
876 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
877 kvreg->retention_uV = retention_uV;
878 set_krait_retention_uv(kvreg, retention_uV);
879 }
880 mutex_unlock(&pvreg->krait_power_vregs_lock);
881 return 0;
882}
883DEFINE_SIMPLE_ATTRIBUTE(retention_fops,
884 get_retention_dbg_uV, set_retention_dbg_uV, "%llu\n");
885
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700886static void kvreg_hw_init(struct krait_power_vreg *kvreg)
887{
888 /*
889 * bhs_cnt value sets the ramp-up time from power collapse,
890 * initialize the ramp up time
891 */
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700892 set_krait_retention_uv(kvreg, kvreg->retention_uV);
893 set_krait_ldo_uv(kvreg, kvreg->ldo_default_uV);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800894
895 /* setup the bandgap that configures the reference to the LDO */
896 writel_relaxed(0x00000190, kvreg->mdd_base + MDD_CONFIG_CTL);
897 /* Enable MDD */
898 writel_relaxed(0x00000002, kvreg->mdd_base + MDD_MODE);
899 mb();
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700900}
901
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700902static void glb_init(struct platform_device *pdev)
903{
904 /* configure bi-modal switch */
905 writel_relaxed(0x0008736E, MSM_APCS_GCC_BASE + PWR_GATE_CONFIG);
906 /* read kpss version */
907 version = readl_relaxed(MSM_APCS_GCC_BASE + VERSION);
908 pr_debug("version= 0x%x\n", version);
909}
910
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700911static int __devinit krait_power_probe(struct platform_device *pdev)
912{
913 struct krait_power_vreg *kvreg;
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800914 struct resource *res, *res_mdd;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700915 struct regulator_init_data *init_data = pdev->dev.platform_data;
916 int rc = 0;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700917 int headroom_uV, retention_uV, ldo_default_uV, ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800918 int ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800919 int cpu_num;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700920
921 /* Initialize the pmic gang if it hasn't been initialized already */
922 if (the_gang == NULL) {
923 rc = pvreg_init(pdev);
924 if (rc < 0) {
925 dev_err(&pdev->dev,
926 "failed to init pmic gang rc = %d\n", rc);
927 return rc;
928 }
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700929 /* global initializtion */
930 glb_init(pdev);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700931 }
932
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800933 if (dent == NULL) {
934 dent = debugfs_create_dir(KRAIT_REGULATOR_DRIVER_NAME, NULL);
935 debugfs_create_file("retention_uV",
936 0644, dent, the_gang, &retention_fops);
937 }
938
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700939 if (pdev->dev.of_node) {
940 /* Get init_data from device tree. */
941 init_data = of_get_regulator_init_data(&pdev->dev,
942 pdev->dev.of_node);
943 init_data->constraints.valid_ops_mask
944 |= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_DRMS
945 | REGULATOR_CHANGE_MODE;
946 init_data->constraints.valid_modes_mask
947 |= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE
948 | REGULATOR_MODE_FAST;
949 init_data->constraints.input_uV = init_data->constraints.max_uV;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700950 rc = of_property_read_u32(pdev->dev.of_node,
951 "qcom,headroom-voltage",
952 &headroom_uV);
953 if (rc < 0) {
954 pr_err("headroom-voltage missing rc=%d\n", rc);
955 return rc;
956 }
957 if (!is_between(LDO_HDROOM_MIN, LDO_HDROOM_MAX, headroom_uV)) {
958 pr_err("bad headroom-voltage = %d specified\n",
959 headroom_uV);
960 return -EINVAL;
961 }
962
963 rc = of_property_read_u32(pdev->dev.of_node,
964 "qcom,retention-voltage",
965 &retention_uV);
966 if (rc < 0) {
967 pr_err("retention-voltage missing rc=%d\n", rc);
968 return rc;
969 }
970 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV)) {
971 pr_err("bad retention-voltage = %d specified\n",
972 retention_uV);
973 return -EINVAL;
974 }
975
976 rc = of_property_read_u32(pdev->dev.of_node,
977 "qcom,ldo-default-voltage",
978 &ldo_default_uV);
979 if (rc < 0) {
980 pr_err("ldo-default-voltage missing rc=%d\n", rc);
981 return rc;
982 }
983 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, ldo_default_uV)) {
984 pr_err("bad ldo-default-voltage = %d specified\n",
985 ldo_default_uV);
986 return -EINVAL;
987 }
988
989 rc = of_property_read_u32(pdev->dev.of_node,
990 "qcom,ldo-threshold-voltage",
991 &ldo_threshold_uV);
992 if (rc < 0) {
993 pr_err("ldo-threshold-voltage missing rc=%d\n", rc);
994 return rc;
995 }
996 if (!is_between(LDO_TH_MIN, LDO_TH_MAX, ldo_threshold_uV)) {
997 pr_err("bad ldo-threshold-voltage = %d specified\n",
998 ldo_threshold_uV);
999 return -EINVAL;
1000 }
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -08001001
1002 rc = of_property_read_u32(pdev->dev.of_node,
1003 "qcom,ldo-delta-voltage",
1004 &ldo_delta_uV);
1005 if (rc < 0) {
1006 pr_err("ldo-delta-voltage missing rc=%d\n", rc);
1007 return rc;
1008 }
1009 if (!is_between(LDO_DELTA_MIN, LDO_DELTA_MAX, ldo_delta_uV)) {
1010 pr_err("bad ldo-delta-voltage = %d specified\n",
1011 ldo_delta_uV);
1012 return -EINVAL;
1013 }
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001014 rc = of_property_read_u32(pdev->dev.of_node,
1015 "qcom,cpu-num",
1016 &cpu_num);
1017 if (cpu_num > num_possible_cpus()) {
1018 pr_err("bad cpu-num= %d specified\n", cpu_num);
1019 return -EINVAL;
1020 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001021 }
1022
1023 if (!init_data) {
1024 dev_err(&pdev->dev, "init data required.\n");
1025 return -EINVAL;
1026 }
1027
1028 if (!init_data->constraints.name) {
1029 dev_err(&pdev->dev,
1030 "regulator name must be specified in constraints.\n");
1031 return -EINVAL;
1032 }
1033
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001034 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acs");
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001035 if (!res) {
1036 dev_err(&pdev->dev, "missing physical register addresses\n");
1037 return -EINVAL;
1038 }
1039
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001040 res_mdd = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mdd");
1041 if (!res_mdd) {
1042 dev_err(&pdev->dev, "missing mdd register addresses\n");
1043 return -EINVAL;
1044 }
1045
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001046 kvreg = devm_kzalloc(&pdev->dev,
1047 sizeof(struct krait_power_vreg), GFP_KERNEL);
1048 if (!kvreg) {
1049 dev_err(&pdev->dev, "kzalloc failed.\n");
1050 return -ENOMEM;
1051 }
1052
1053 kvreg->reg_base = devm_ioremap(&pdev->dev,
1054 res->start, resource_size(res));
1055
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001056 kvreg->mdd_base = devm_ioremap(&pdev->dev,
1057 res_mdd->start, resource_size(res));
1058
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -07001059 kvreg->pvreg = the_gang;
1060 kvreg->name = init_data->constraints.name;
1061 kvreg->desc.name = kvreg->name;
1062 kvreg->desc.ops = &krait_power_ops;
1063 kvreg->desc.type = REGULATOR_VOLTAGE;
1064 kvreg->desc.owner = THIS_MODULE;
1065 kvreg->uV = CORE_VOLTAGE_MIN;
1066 kvreg->mode = HS_MODE;
1067 kvreg->desc.ops = &krait_power_ops;
1068 kvreg->headroom_uV = headroom_uV;
1069 kvreg->retention_uV = retention_uV;
1070 kvreg->ldo_default_uV = ldo_default_uV;
1071 kvreg->ldo_threshold_uV = ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -08001072 kvreg->ldo_delta_uV = ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001073 kvreg->cpu_num = cpu_num;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001074
1075 platform_set_drvdata(pdev, kvreg);
1076
1077 mutex_lock(&the_gang->krait_power_vregs_lock);
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -08001078 the_gang->pmic_min_uV_for_retention
1079 = min(the_gang->pmic_min_uV_for_retention,
1080 kvreg->retention_uV + kvreg->headroom_uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001081 list_add_tail(&kvreg->link, &the_gang->krait_power_vregs);
1082 mutex_unlock(&the_gang->krait_power_vregs_lock);
1083
1084 kvreg->rdev = regulator_register(&kvreg->desc, &pdev->dev, init_data,
1085 kvreg, pdev->dev.of_node);
1086 if (IS_ERR(kvreg->rdev)) {
1087 rc = PTR_ERR(kvreg->rdev);
1088 pr_err("regulator_register failed, rc=%d.\n", rc);
1089 goto out;
1090 }
1091
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -07001092 kvreg_hw_init(kvreg);
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001093 per_cpu(krait_vregs, cpu_num) = kvreg;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001094 dev_dbg(&pdev->dev, "id=%d, name=%s\n", pdev->id, kvreg->name);
1095
1096 return 0;
1097out:
1098 mutex_lock(&the_gang->krait_power_vregs_lock);
1099 list_del(&kvreg->link);
1100 mutex_unlock(&the_gang->krait_power_vregs_lock);
1101
1102 platform_set_drvdata(pdev, NULL);
1103 return rc;
1104}
1105
1106static int __devexit krait_power_remove(struct platform_device *pdev)
1107{
1108 struct krait_power_vreg *kvreg = platform_get_drvdata(pdev);
1109 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
1110
1111 mutex_lock(&pvreg->krait_power_vregs_lock);
1112 list_del(&kvreg->link);
1113 mutex_unlock(&pvreg->krait_power_vregs_lock);
1114
1115 regulator_unregister(kvreg->rdev);
1116 platform_set_drvdata(pdev, NULL);
1117 return 0;
1118}
1119
1120static struct of_device_id krait_power_match_table[] = {
1121 { .compatible = "qcom,krait-regulator", },
1122 {}
1123};
1124
1125static struct platform_driver krait_power_driver = {
1126 .probe = krait_power_probe,
1127 .remove = __devexit_p(krait_power_remove),
1128 .driver = {
1129 .name = KRAIT_REGULATOR_DRIVER_NAME,
1130 .of_match_table = krait_power_match_table,
1131 .owner = THIS_MODULE,
1132 },
1133};
1134
1135int __init krait_power_init(void)
1136{
1137 return platform_driver_register(&krait_power_driver);
1138}
1139
1140static void __exit krait_power_exit(void)
1141{
1142 platform_driver_unregister(&krait_power_driver);
1143}
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001144module_exit(krait_power_exit);
1145
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001146void secondary_cpu_hs_init(void *base_ptr)
1147{
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001148 /* Turn on the BHS, turn off LDO Bypass and power down LDO */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001149 writel_relaxed(
1150 BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
1151 | LDO_PWR_DWN_MASK
1152 | CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
1153 | BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
1154 | BHS_EN_MASK,
1155 base_ptr + APC_PWR_GATE_CTL);
1156
1157 /* complete the above write before the delay */
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001158 mb();
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001159
1160 /*
1161 * wait for the bhs to settle
1162 */
1163 udelay(BHS_SETTLING_DELAY_US);
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001164
1165 /* Finally turn on the bypass so that BHS supplies power */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001166 writel_relaxed(
1167 BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
1168 | LDO_PWR_DWN_MASK
1169 | CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
1170 | LDO_BYP_MASK
1171 | BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
1172 | BHS_EN_MASK,
1173 base_ptr + APC_PWR_GATE_CTL);
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001174}
1175
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001176MODULE_LICENSE("GPL v2");
1177MODULE_DESCRIPTION("KRAIT POWER regulator driver");
1178MODULE_VERSION("1.0");
1179MODULE_ALIAS("platform:"KRAIT_REGULATOR_DRIVER_NAME);