blob: 8fe69d99653d65ece280c8853318ad864d425723 [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.
Stepan Moskovchenko7663b782013-03-08 20:13:06 -0800148 * @apcs_gcc_base virtual address of the APCS GCC registers
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700149 */
150struct pmic_gang_vreg {
151 const char *name;
152 int pmic_vmax_uV;
153 int pmic_phase_count;
154 struct list_head krait_power_vregs;
155 struct mutex krait_power_vregs_lock;
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700156 bool pfm_mode;
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -0800157 int pmic_min_uV_for_retention;
158 bool retention_enabled;
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800159 bool use_phase_switching;
Stepan Moskovchenko7663b782013-03-08 20:13:06 -0800160 void __iomem *apcs_gcc_base;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700161};
162
163static struct pmic_gang_vreg *the_gang;
164
165enum krait_supply_mode {
166 HS_MODE = REGULATOR_MODE_NORMAL,
167 LDO_MODE = REGULATOR_MODE_IDLE,
168};
169
170struct krait_power_vreg {
171 struct list_head link;
172 struct regulator_desc desc;
173 struct regulator_dev *rdev;
174 const char *name;
175 struct pmic_gang_vreg *pvreg;
176 int uV;
177 int load_uA;
178 enum krait_supply_mode mode;
179 void __iomem *reg_base;
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800180 void __iomem *mdd_base;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700181 int ldo_default_uV;
182 int retention_uV;
183 int headroom_uV;
184 int ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800185 int ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800186 int cpu_num;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800187 bool online;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700188};
189
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800190DEFINE_PER_CPU(struct krait_power_vreg *, krait_vregs);
191
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700192static u32 version;
193
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800194static int is_between(int left, int right, int value)
195{
196 if (left >= right && left >= value && value >= right)
197 return 1;
198 if (left <= right && left <= value && value <= right)
199 return 1;
200 return 0;
201}
202
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700203static void krait_masked_write(struct krait_power_vreg *kvreg,
204 int reg, uint32_t mask, uint32_t val)
205{
206 uint32_t reg_val;
207
208 reg_val = readl_relaxed(kvreg->reg_base + reg);
209 reg_val &= ~mask;
210 reg_val |= (val & mask);
211 writel_relaxed(reg_val, kvreg->reg_base + reg);
212
213 /*
214 * Barrier to ensure that the reads and writes from
215 * other regulator regions (they are 1k apart) execute in
216 * order to the above write.
217 */
218 mb();
219}
220
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800221static int get_krait_retention_ldo_uv(struct krait_power_vreg *kvreg)
222{
223 uint32_t reg_val;
224 int uV;
225
226 reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
227 reg_val &= VREF_RET_MASK;
228 reg_val >>= VREF_RET_POS;
229
230 if (reg_val == 0)
231 uV = 0;
232 else
233 uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
234
235 return uV;
236}
237
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700238static int get_krait_ldo_uv(struct krait_power_vreg *kvreg)
239{
240 uint32_t reg_val;
241 int uV;
242
243 reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
244 reg_val &= VREF_LDO_MASK;
245 reg_val >>= VREF_LDO_BIT_POS;
246
247 if (reg_val == 0)
248 uV = 0;
249 else
250 uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
251
252 return uV;
253}
254
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700255static int set_krait_retention_uv(struct krait_power_vreg *kvreg, int uV)
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700256{
257 uint32_t reg_val;
258
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700259 reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
260 krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_RET_MASK,
261 reg_val << VREF_RET_POS);
262
263 return 0;
264}
265
266static int set_krait_ldo_uv(struct krait_power_vreg *kvreg, int uV)
267{
268 uint32_t reg_val;
269
270 reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700271 krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_LDO_MASK,
272 reg_val << VREF_LDO_BIT_POS);
273
274 return 0;
275}
276
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800277static int __krait_power_mdd_enable(struct krait_power_vreg *kvreg, bool on)
278{
279 if (on) {
280 writel_relaxed(0x00000002, kvreg->mdd_base + MDD_MODE);
281 /* complete the above write before the delay */
282 mb();
283 udelay(MDD_SETTLING_DELAY_US);
284 } else {
285 writel_relaxed(0x00000000, kvreg->mdd_base + MDD_MODE);
286 /*
287 * complete the above write before other accesses
288 * to krait regulator
289 */
290 mb();
291 }
292 return 0;
293}
294
295int krait_power_mdd_enable(int cpu_num, bool on)
296{
Abhijeet Dharmapurikarc962e092013-02-20 00:57:21 -0800297 /*
298 * Expected to be called when the cpu goes to retention mode as a part
299 * of idle power collapse. IT is guaranteed that cpu won't be put in
300 * retention while being hotplugged out
301 */
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800302 struct krait_power_vreg *kvreg = per_cpu(krait_vregs, cpu_num);
303
304 if (!on && kvreg->mode == LDO_MODE) {
305 pr_debug("%s using LDO - cannot turn off MDD\n", kvreg->name);
306 return -EINVAL;
307 }
308
Abhijeet Dharmapurikarc962e092013-02-20 00:57:21 -0800309 if (on && kvreg->mode == LDO_MODE)
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800310 return 0;
311
312 __krait_power_mdd_enable(kvreg, on);
313 return 0;
314}
315
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700316static int switch_to_using_hs(struct krait_power_vreg *kvreg)
317{
318 if (kvreg->mode == HS_MODE)
319 return 0;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700320 /* enable bhs */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800321 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
322 BHS_SEG_EN_MASK | BHS_EN_MASK,
323 BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS | BHS_EN_MASK);
324
325 /* complete the above write before the delay */
326 mb();
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700327
328 /*
329 * wait for the bhs to settle - note that
330 * after the voltage has settled both BHS and LDO are supplying power
331 * to the krait. This avoids glitches during switching
332 */
333 udelay(BHS_SETTLING_DELAY_US);
334
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800335 /*
336 * enable ldo bypass - the krait is powered still by LDO since
337 * LDO is enabled
338 */
339 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_BYP_MASK, LDO_BYP_MASK);
340
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700341 /* disable ldo - only the BHS provides voltage to the cpu after this */
342 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
343 LDO_PWR_DWN_MASK, LDO_PWR_DWN_MASK);
344
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800345 /* turn off MDD since LDO is not used */
346 __krait_power_mdd_enable(kvreg, false);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700347 kvreg->mode = HS_MODE;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800348 pr_debug("%s using BHS\n", kvreg->name);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700349 return 0;
350}
351
352static int switch_to_using_ldo(struct krait_power_vreg *kvreg)
353{
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800354 if (kvreg->mode == LDO_MODE
355 && get_krait_ldo_uv(kvreg) == kvreg->uV - kvreg->ldo_delta_uV)
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700356 return 0;
357
358 /*
359 * if the krait is in ldo mode and a voltage change is requested on the
360 * ldo switch to using hs before changing ldo voltage
361 */
362 if (kvreg->mode == LDO_MODE)
363 switch_to_using_hs(kvreg);
364
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800365 /* turn on MDD since LDO is being turned on */
366 __krait_power_mdd_enable(kvreg, true);
367
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800368 set_krait_ldo_uv(kvreg, kvreg->uV - kvreg->ldo_delta_uV);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700369
370 /*
371 * enable ldo - note that both LDO and BHS are are supplying voltage to
372 * the cpu after this. This avoids glitches during switching from BHS
373 * to LDO.
374 */
375 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_PWR_DWN_MASK, 0);
376
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800377 /* complete the writes before the delay */
378 mb();
379
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700380 /* wait for the ldo to settle */
381 udelay(LDO_SETTLING_DELAY_US);
382
383 /*
384 * disable BHS and disable LDO bypass seperate from enabling
385 * the LDO above.
386 */
387 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
388 BHS_EN_MASK | LDO_BYP_MASK, 0);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800389 krait_masked_write(kvreg, APC_PWR_GATE_CTL, BHS_SEG_EN_MASK, 0);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700390
391 kvreg->mode = LDO_MODE;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800392 pr_debug("%s using LDO\n", kvreg->name);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700393 return 0;
394}
395
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800396static int set_pmic_gang_phases(struct pmic_gang_vreg *pvreg, int phase_count)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700397{
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800398 pr_debug("programming phase_count = %d\n", phase_count);
399 if (pvreg->use_phase_switching)
400 /*
401 * note the PMIC sets the phase count to one more than
402 * the value in the register - hence subtract 1 from it
403 */
404 return msm_spm_apcs_set_phase(phase_count - 1);
405 else
406 return 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700407}
408
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800409static int set_pmic_gang_voltage(struct pmic_gang_vreg *pvreg, int uV)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700410{
411 int setpoint;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800412 int rc;
413
414 if (pvreg->pmic_vmax_uV == uV)
415 return 0;
416
417 pr_debug("%d\n", uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700418
419 if (uV < PMIC_VOLTAGE_MIN) {
420 pr_err("requested %d < %d, restricting it to %d\n",
421 uV, PMIC_VOLTAGE_MIN, PMIC_VOLTAGE_MIN);
422 uV = PMIC_VOLTAGE_MIN;
423 }
424 if (uV > PMIC_VOLTAGE_MAX) {
425 pr_err("requested %d > %d, restricting it to %d\n",
426 uV, PMIC_VOLTAGE_MAX, PMIC_VOLTAGE_MAX);
427 uV = PMIC_VOLTAGE_MAX;
428 }
429
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -0800430 if (uV < pvreg->pmic_min_uV_for_retention) {
431 if (pvreg->retention_enabled) {
432 pr_debug("Disabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
433 uV, pvreg->pmic_min_uV_for_retention);
434 msm_pm_enable_retention(false);
435 pvreg->retention_enabled = false;
436 }
437 } else {
438 if (!pvreg->retention_enabled) {
439 pr_debug("Enabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
440 uV, pvreg->pmic_min_uV_for_retention);
441 msm_pm_enable_retention(true);
442 pvreg->retention_enabled = true;
443 }
444 }
445
Abhijeet Dharmapurikard4f38da2012-08-08 21:42:06 -0700446 setpoint = DIV_ROUND_UP(uV, LV_RANGE_STEP);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800447
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800448 rc = msm_spm_apcs_set_vdd(setpoint);
449 if (rc < 0)
450 pr_err("could not set %duV setpt = 0x%x rc = %d\n",
451 uV, setpoint, rc);
452 else
453 pvreg->pmic_vmax_uV = uV;
454
455 return rc;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700456}
457
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800458static int configure_ldo_or_hs_all(struct krait_power_vreg *from, int vmax)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700459{
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700460 struct pmic_gang_vreg *pvreg = from->pvreg;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700461 struct krait_power_vreg *kvreg;
462 int rc = 0;
463
464 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800465 if (!kvreg->online)
466 continue;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800467 if (kvreg->uV <= kvreg->ldo_threshold_uV
468 && kvreg->uV - kvreg->ldo_delta_uV + kvreg->headroom_uV
469 <= vmax) {
470 rc = switch_to_using_ldo(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 ldo rc = %d\n",
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700473 kvreg->name, rc);
474 return rc;
475 }
476 } else {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800477 rc = switch_to_using_hs(kvreg);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700478 if (rc < 0) {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800479 pr_err("could not switch %s to hs rc = %d\n",
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700480 kvreg->name, rc);
481 return rc;
482 }
483 }
484 }
485
486 return rc;
487}
488
489#define SLEW_RATE 2994
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800490static int krait_voltage_increase(struct krait_power_vreg *from,
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700491 int vmax)
492{
493 struct pmic_gang_vreg *pvreg = from->pvreg;
494 int rc = 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700495 int settling_us;
496
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700497 /*
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800498 * since krait voltage is increasing set the gang voltage
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700499 * prior to changing ldo/hs states of the requesting krait
500 */
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800501 rc = set_pmic_gang_voltage(pvreg, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700502 if (rc < 0) {
503 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
504 pvreg->name, vmax, rc);
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800505 return rc;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700506 }
507
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800508
509 /* complete the above writes before the delay */
510 mb();
511
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700512 /* delay until the voltage is settled when it is raised */
513 settling_us = DIV_ROUND_UP(vmax - pvreg->pmic_vmax_uV, SLEW_RATE);
514 udelay(settling_us);
515
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800516 rc = configure_ldo_or_hs_all(from, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700517 if (rc < 0) {
518 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
519 pvreg->name, vmax, rc);
520 }
521
522 return rc;
523}
524
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800525static int krait_voltage_decrease(struct krait_power_vreg *from,
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700526 int vmax)
527{
528 struct pmic_gang_vreg *pvreg = from->pvreg;
529 int rc = 0;
530
531 /*
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800532 * since krait voltage is decreasing ldos might get out of their
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700533 * operating range. Hence configure such kraits to be in hs mode prior
534 * to setting the pmic gang voltage
535 */
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800536 rc = configure_ldo_or_hs_all(from, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700537 if (rc < 0) {
538 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
539 pvreg->name, vmax, rc);
540 return rc;
541 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700542
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800543 rc = set_pmic_gang_voltage(pvreg, vmax);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700544 if (rc < 0) {
545 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
546 pvreg->name, vmax, rc);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700547 }
548
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700549 return rc;
550}
551
552#define PHASE_SETTLING_TIME_US 10
553static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
554 int load_uA)
555{
556 struct pmic_gang_vreg *pvreg = from->pvreg;
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800557 int phase_count = DIV_ROUND_UP(load_uA, LOAD_PER_PHASE);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700558 int rc = 0;
559
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800560 if (phase_count <= 0)
561 phase_count = 1;
562
563 /* Increase phases if it is less than the number of cpus online */
564 if (phase_count < num_online_cpus()) {
565 phase_count = num_online_cpus();
566 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700567
568 if (phase_count != pvreg->pmic_phase_count) {
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800569 rc = set_pmic_gang_phases(pvreg, phase_count);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700570 if (rc < 0) {
571 dev_err(&from->rdev->dev,
572 "%s failed set phase %d rc = %d\n",
573 pvreg->name, phase_count, rc);
574 return rc;
575 }
576
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800577 /* complete the writes before the delay */
578 mb();
579
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700580 /*
581 * delay until the phases are settled when
582 * the count is raised
583 */
584 if (phase_count > pvreg->pmic_phase_count)
585 udelay(PHASE_SETTLING_TIME_US);
586
587 pvreg->pmic_phase_count = phase_count;
588 }
589 return rc;
590}
591
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700592static int krait_power_get_voltage(struct regulator_dev *rdev)
593{
594 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
595
596 return kvreg->uV;
597}
598
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800599static int get_vmax(struct pmic_gang_vreg *pvreg)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700600{
601 int vmax = 0;
602 int v;
603 struct krait_power_vreg *kvreg;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700604
605 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800606 if (!kvreg->online)
607 continue;
608
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700609 v = kvreg->uV;
610
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700611 if (vmax < v)
612 vmax = v;
613 }
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800614
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700615 return vmax;
616}
617
618static int get_total_load(struct krait_power_vreg *from)
619{
620 int load_total = 0;
621 struct krait_power_vreg *kvreg;
622 struct pmic_gang_vreg *pvreg = from->pvreg;
623
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800624 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
625 if (!kvreg->online)
626 continue;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700627 load_total += kvreg->load_uA;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800628 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700629
630 return load_total;
631}
632
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700633#define ROUND_UP_VOLTAGE(v, res) (DIV_ROUND_UP(v, res) * res)
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800634static int _set_voltage(struct regulator_dev *rdev,
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800635 int orig_krait_uV, int requested_uV)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700636{
637 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
638 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
639 int rc;
640 int vmax;
641
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800642 pr_debug("%s: %d to %d\n", kvreg->name, orig_krait_uV, requested_uV);
643 /*
644 * Assign the voltage before updating the gang voltage as we iterate
645 * over all the core voltages and choose HS or LDO for each of them
646 */
647 kvreg->uV = requested_uV;
648
649 vmax = get_vmax(pvreg);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800650
651 /* round up the pmic voltage as per its resolution */
652 vmax = ROUND_UP_VOLTAGE(vmax, LV_RANGE_STEP);
653
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800654 if (requested_uV > orig_krait_uV)
655 rc = krait_voltage_increase(kvreg, vmax);
656 else
657 rc = krait_voltage_decrease(kvreg, vmax);
658
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800659 if (rc < 0) {
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800660 dev_err(&rdev->dev, "%s failed to set %duV from %duV rc = %d\n",
661 kvreg->name, requested_uV, orig_krait_uV, rc);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800662 }
663
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800664 return rc;
665}
666
667static int krait_power_set_voltage(struct regulator_dev *rdev,
668 int min_uV, int max_uV, unsigned *selector)
669{
670 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
671 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
672 int rc;
673
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700674 /*
675 * if the voltage requested is below LDO_THRESHOLD this cpu could
676 * switch to LDO mode. Hence round the voltage as per the LDO
677 * resolution
678 */
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700679 if (min_uV < kvreg->ldo_threshold_uV) {
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700680 if (min_uV < KRAIT_LDO_VOLTAGE_MIN)
681 min_uV = KRAIT_LDO_VOLTAGE_MIN;
682 min_uV = ROUND_UP_VOLTAGE(min_uV, KRAIT_LDO_STEP);
683 }
684
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700685 mutex_lock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800686 if (!kvreg->online) {
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800687 kvreg->uV = min_uV;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800688 mutex_unlock(&pvreg->krait_power_vregs_lock);
689 return 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700690 }
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700691
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800692 rc = _set_voltage(rdev, kvreg->uV, min_uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700693 mutex_unlock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800694
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700695 return rc;
696}
697
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700698#define PMIC_FTS_MODE_PFM 0x00
699#define PMIC_FTS_MODE_PWM 0x80
700#define PFM_LOAD_UA 500000
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800701static unsigned int _get_optimum_mode(struct regulator_dev *rdev,
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700702 int input_uV, int output_uV, int load_uA)
703{
704 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
705 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
706 int rc;
707 int load_total_uA;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700708
709 load_total_uA = get_total_load(kvreg);
710
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700711 if (load_total_uA < PFM_LOAD_UA) {
712 if (!pvreg->pfm_mode) {
713 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PFM);
714 if (rc) {
715 dev_err(&rdev->dev,
716 "%s enter PFM failed load %d rc = %d\n",
717 kvreg->name, load_total_uA, rc);
718 goto out;
719 } else {
720 pvreg->pfm_mode = true;
721 }
722 }
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800723 return kvreg->mode;
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700724 }
725
726 if (pvreg->pfm_mode) {
727 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PWM);
728 if (rc) {
729 dev_err(&rdev->dev,
730 "%s exit PFM failed load %d rc = %d\n",
731 kvreg->name, load_total_uA, rc);
732 goto out;
733 } else {
734 pvreg->pfm_mode = false;
735 }
736 }
737
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700738 rc = pmic_gang_set_phases(kvreg, load_total_uA);
739 if (rc < 0) {
740 dev_err(&rdev->dev, "%s failed set mode %d rc = %d\n",
741 kvreg->name, load_total_uA, rc);
742 goto out;
743 }
744
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700745out:
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800746 return kvreg->mode;
747}
748
749static unsigned int krait_power_get_optimum_mode(struct regulator_dev *rdev,
750 int input_uV, int output_uV, int load_uA)
751{
752 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
753 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
754 int rc;
755
756 mutex_lock(&pvreg->krait_power_vregs_lock);
757 kvreg->load_uA = load_uA;
758 if (!kvreg->online) {
759 mutex_unlock(&pvreg->krait_power_vregs_lock);
760 return kvreg->mode;
761 }
762
763 rc = _get_optimum_mode(rdev, input_uV, output_uV, load_uA);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700764 mutex_unlock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800765
766 return rc;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700767}
768
769static int krait_power_set_mode(struct regulator_dev *rdev, unsigned int mode)
770{
771 return 0;
772}
773
774static unsigned int krait_power_get_mode(struct regulator_dev *rdev)
775{
776 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
777
778 return kvreg->mode;
779}
780
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800781static int krait_power_is_enabled(struct regulator_dev *rdev)
782{
783 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
784
785 return kvreg->online;
786}
787
788static int krait_power_enable(struct regulator_dev *rdev)
789{
790 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
791 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
792 int rc;
793
794 mutex_lock(&pvreg->krait_power_vregs_lock);
Abhijeet Dharmapurikarc962e092013-02-20 00:57:21 -0800795 if (kvreg->mode == LDO_MODE)
796 __krait_power_mdd_enable(kvreg, true);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800797 kvreg->online = true;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800798 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV, kvreg->load_uA);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800799 if (rc < 0)
800 goto en_err;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800801 /*
802 * since the core is being enabled, behave as if it is increasing
803 * the core voltage
804 */
805 rc = _set_voltage(rdev, 0, kvreg->uV);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800806en_err:
807 mutex_unlock(&pvreg->krait_power_vregs_lock);
808 return rc;
809}
810
811static int krait_power_disable(struct regulator_dev *rdev)
812{
813 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
814 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
815 int rc;
816
817 mutex_lock(&pvreg->krait_power_vregs_lock);
818 kvreg->online = false;
819
820 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV,
821 kvreg->load_uA);
822 if (rc < 0)
823 goto dis_err;
824
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800825 rc = _set_voltage(rdev, kvreg->uV, kvreg->uV);
Abhijeet Dharmapurikarc962e092013-02-20 00:57:21 -0800826 if (kvreg->mode == LDO_MODE)
827 __krait_power_mdd_enable(kvreg, false);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800828dis_err:
829 mutex_unlock(&pvreg->krait_power_vregs_lock);
830 return rc;
831}
832
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700833static struct regulator_ops krait_power_ops = {
834 .get_voltage = krait_power_get_voltage,
835 .set_voltage = krait_power_set_voltage,
836 .get_optimum_mode = krait_power_get_optimum_mode,
837 .set_mode = krait_power_set_mode,
838 .get_mode = krait_power_get_mode,
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800839 .enable = krait_power_enable,
840 .disable = krait_power_disable,
841 .is_enabled = krait_power_is_enabled,
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700842};
843
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800844static struct dentry *dent;
845static int get_retention_dbg_uV(void *data, u64 *val)
846{
847 struct pmic_gang_vreg *pvreg = data;
848 struct krait_power_vreg *kvreg;
849
850 mutex_lock(&pvreg->krait_power_vregs_lock);
851 if (!list_empty(&pvreg->krait_power_vregs)) {
852 /* return the retention voltage on just the first cpu */
853 kvreg = list_entry((&pvreg->krait_power_vregs)->next,
854 typeof(*kvreg), link);
855 *val = get_krait_retention_ldo_uv(kvreg);
856 }
857 mutex_unlock(&pvreg->krait_power_vregs_lock);
858 return 0;
859}
860
861static int set_retention_dbg_uV(void *data, u64 val)
862{
863 struct pmic_gang_vreg *pvreg = data;
864 struct krait_power_vreg *kvreg;
865 int retention_uV = val;
866
867 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV))
868 return -EINVAL;
869
870 mutex_lock(&pvreg->krait_power_vregs_lock);
871 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
872 kvreg->retention_uV = retention_uV;
873 set_krait_retention_uv(kvreg, retention_uV);
874 }
875 mutex_unlock(&pvreg->krait_power_vregs_lock);
876 return 0;
877}
878DEFINE_SIMPLE_ATTRIBUTE(retention_fops,
879 get_retention_dbg_uV, set_retention_dbg_uV, "%llu\n");
880
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700881static void kvreg_hw_init(struct krait_power_vreg *kvreg)
882{
883 /*
884 * bhs_cnt value sets the ramp-up time from power collapse,
885 * initialize the ramp up time
886 */
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700887 set_krait_retention_uv(kvreg, kvreg->retention_uV);
888 set_krait_ldo_uv(kvreg, kvreg->ldo_default_uV);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800889
890 /* setup the bandgap that configures the reference to the LDO */
891 writel_relaxed(0x00000190, kvreg->mdd_base + MDD_CONFIG_CTL);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800892 mb();
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700893}
894
Stepan Moskovchenko7663b782013-03-08 20:13:06 -0800895static void glb_init(void __iomem *apcs_gcc_base)
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700896{
897 /* configure bi-modal switch */
Stepan Moskovchenko7663b782013-03-08 20:13:06 -0800898 writel_relaxed(0x0008736E, apcs_gcc_base + PWR_GATE_CONFIG);
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700899 /* read kpss version */
Stepan Moskovchenko7663b782013-03-08 20:13:06 -0800900 version = readl_relaxed(apcs_gcc_base + VERSION);
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700901 pr_debug("version= 0x%x\n", version);
902}
903
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700904static int __devinit krait_power_probe(struct platform_device *pdev)
905{
906 struct krait_power_vreg *kvreg;
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800907 struct resource *res, *res_mdd;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700908 struct regulator_init_data *init_data = pdev->dev.platform_data;
909 int rc = 0;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700910 int headroom_uV, retention_uV, ldo_default_uV, ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800911 int ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800912 int cpu_num;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700913
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700914 if (pdev->dev.of_node) {
915 /* Get init_data from device tree. */
916 init_data = of_get_regulator_init_data(&pdev->dev,
917 pdev->dev.of_node);
918 init_data->constraints.valid_ops_mask
919 |= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_DRMS
920 | REGULATOR_CHANGE_MODE;
921 init_data->constraints.valid_modes_mask
922 |= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE
923 | REGULATOR_MODE_FAST;
924 init_data->constraints.input_uV = init_data->constraints.max_uV;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700925 rc = of_property_read_u32(pdev->dev.of_node,
926 "qcom,headroom-voltage",
927 &headroom_uV);
928 if (rc < 0) {
929 pr_err("headroom-voltage missing rc=%d\n", rc);
930 return rc;
931 }
932 if (!is_between(LDO_HDROOM_MIN, LDO_HDROOM_MAX, headroom_uV)) {
933 pr_err("bad headroom-voltage = %d specified\n",
934 headroom_uV);
935 return -EINVAL;
936 }
937
938 rc = of_property_read_u32(pdev->dev.of_node,
939 "qcom,retention-voltage",
940 &retention_uV);
941 if (rc < 0) {
942 pr_err("retention-voltage missing rc=%d\n", rc);
943 return rc;
944 }
945 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV)) {
946 pr_err("bad retention-voltage = %d specified\n",
947 retention_uV);
948 return -EINVAL;
949 }
950
951 rc = of_property_read_u32(pdev->dev.of_node,
952 "qcom,ldo-default-voltage",
953 &ldo_default_uV);
954 if (rc < 0) {
955 pr_err("ldo-default-voltage missing rc=%d\n", rc);
956 return rc;
957 }
958 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, ldo_default_uV)) {
959 pr_err("bad ldo-default-voltage = %d specified\n",
960 ldo_default_uV);
961 return -EINVAL;
962 }
963
964 rc = of_property_read_u32(pdev->dev.of_node,
965 "qcom,ldo-threshold-voltage",
966 &ldo_threshold_uV);
967 if (rc < 0) {
968 pr_err("ldo-threshold-voltage missing rc=%d\n", rc);
969 return rc;
970 }
971 if (!is_between(LDO_TH_MIN, LDO_TH_MAX, ldo_threshold_uV)) {
972 pr_err("bad ldo-threshold-voltage = %d specified\n",
973 ldo_threshold_uV);
974 return -EINVAL;
975 }
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800976
977 rc = of_property_read_u32(pdev->dev.of_node,
978 "qcom,ldo-delta-voltage",
979 &ldo_delta_uV);
980 if (rc < 0) {
981 pr_err("ldo-delta-voltage missing rc=%d\n", rc);
982 return rc;
983 }
984 if (!is_between(LDO_DELTA_MIN, LDO_DELTA_MAX, ldo_delta_uV)) {
985 pr_err("bad ldo-delta-voltage = %d specified\n",
986 ldo_delta_uV);
987 return -EINVAL;
988 }
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800989 rc = of_property_read_u32(pdev->dev.of_node,
990 "qcom,cpu-num",
991 &cpu_num);
992 if (cpu_num > num_possible_cpus()) {
993 pr_err("bad cpu-num= %d specified\n", cpu_num);
994 return -EINVAL;
995 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700996 }
997
998 if (!init_data) {
999 dev_err(&pdev->dev, "init data required.\n");
1000 return -EINVAL;
1001 }
1002
1003 if (!init_data->constraints.name) {
1004 dev_err(&pdev->dev,
1005 "regulator name must be specified in constraints.\n");
1006 return -EINVAL;
1007 }
1008
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001009 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acs");
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001010 if (!res) {
1011 dev_err(&pdev->dev, "missing physical register addresses\n");
1012 return -EINVAL;
1013 }
1014
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001015 res_mdd = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mdd");
1016 if (!res_mdd) {
1017 dev_err(&pdev->dev, "missing mdd register addresses\n");
1018 return -EINVAL;
1019 }
1020
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001021 kvreg = devm_kzalloc(&pdev->dev,
1022 sizeof(struct krait_power_vreg), GFP_KERNEL);
1023 if (!kvreg) {
1024 dev_err(&pdev->dev, "kzalloc failed.\n");
1025 return -ENOMEM;
1026 }
1027
1028 kvreg->reg_base = devm_ioremap(&pdev->dev,
1029 res->start, resource_size(res));
1030
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001031 kvreg->mdd_base = devm_ioremap(&pdev->dev,
1032 res_mdd->start, resource_size(res));
1033
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -07001034 kvreg->pvreg = the_gang;
1035 kvreg->name = init_data->constraints.name;
1036 kvreg->desc.name = kvreg->name;
1037 kvreg->desc.ops = &krait_power_ops;
1038 kvreg->desc.type = REGULATOR_VOLTAGE;
1039 kvreg->desc.owner = THIS_MODULE;
1040 kvreg->uV = CORE_VOLTAGE_MIN;
1041 kvreg->mode = HS_MODE;
1042 kvreg->desc.ops = &krait_power_ops;
1043 kvreg->headroom_uV = headroom_uV;
1044 kvreg->retention_uV = retention_uV;
1045 kvreg->ldo_default_uV = ldo_default_uV;
1046 kvreg->ldo_threshold_uV = ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -08001047 kvreg->ldo_delta_uV = ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001048 kvreg->cpu_num = cpu_num;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001049
1050 platform_set_drvdata(pdev, kvreg);
1051
1052 mutex_lock(&the_gang->krait_power_vregs_lock);
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -08001053 the_gang->pmic_min_uV_for_retention
1054 = min(the_gang->pmic_min_uV_for_retention,
1055 kvreg->retention_uV + kvreg->headroom_uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001056 list_add_tail(&kvreg->link, &the_gang->krait_power_vregs);
1057 mutex_unlock(&the_gang->krait_power_vregs_lock);
1058
1059 kvreg->rdev = regulator_register(&kvreg->desc, &pdev->dev, init_data,
1060 kvreg, pdev->dev.of_node);
1061 if (IS_ERR(kvreg->rdev)) {
1062 rc = PTR_ERR(kvreg->rdev);
1063 pr_err("regulator_register failed, rc=%d.\n", rc);
1064 goto out;
1065 }
1066
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -07001067 kvreg_hw_init(kvreg);
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001068 per_cpu(krait_vregs, cpu_num) = kvreg;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001069 dev_dbg(&pdev->dev, "id=%d, name=%s\n", pdev->id, kvreg->name);
1070
1071 return 0;
1072out:
1073 mutex_lock(&the_gang->krait_power_vregs_lock);
1074 list_del(&kvreg->link);
1075 mutex_unlock(&the_gang->krait_power_vregs_lock);
1076
1077 platform_set_drvdata(pdev, NULL);
1078 return rc;
1079}
1080
1081static int __devexit krait_power_remove(struct platform_device *pdev)
1082{
1083 struct krait_power_vreg *kvreg = platform_get_drvdata(pdev);
1084 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
1085
1086 mutex_lock(&pvreg->krait_power_vregs_lock);
1087 list_del(&kvreg->link);
1088 mutex_unlock(&pvreg->krait_power_vregs_lock);
1089
1090 regulator_unregister(kvreg->rdev);
1091 platform_set_drvdata(pdev, NULL);
1092 return 0;
1093}
1094
1095static struct of_device_id krait_power_match_table[] = {
1096 { .compatible = "qcom,krait-regulator", },
1097 {}
1098};
1099
1100static struct platform_driver krait_power_driver = {
1101 .probe = krait_power_probe,
1102 .remove = __devexit_p(krait_power_remove),
1103 .driver = {
1104 .name = KRAIT_REGULATOR_DRIVER_NAME,
1105 .of_match_table = krait_power_match_table,
1106 .owner = THIS_MODULE,
1107 },
1108};
1109
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001110static struct of_device_id krait_pdn_match_table[] = {
1111 { .compatible = "qcom,krait-pdn", },
1112 {}
1113};
1114
1115static int __devinit krait_pdn_probe(struct platform_device *pdev)
1116{
1117 int rc;
1118 bool use_phase_switching = false;
1119 struct device *dev = &pdev->dev;
1120 struct device_node *node = dev->of_node;
1121 struct pmic_gang_vreg *pvreg;
Stepan Moskovchenko7663b782013-03-08 20:13:06 -08001122 struct resource *res;
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001123
1124 if (!dev->of_node) {
1125 dev_err(dev, "device tree information missing\n");
1126 return -ENODEV;
1127 }
1128
1129 use_phase_switching = of_property_read_bool(node,
1130 "qcom,use-phase-switching");
1131 pvreg = devm_kzalloc(&pdev->dev,
1132 sizeof(struct pmic_gang_vreg), GFP_KERNEL);
1133 if (!pvreg) {
1134 pr_err("kzalloc failed.\n");
1135 return 0;
1136 }
1137
Stepan Moskovchenko7663b782013-03-08 20:13:06 -08001138 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apcs_gcc");
1139 if (!res) {
1140 dev_err(&pdev->dev, "missing apcs gcc base addresses\n");
1141 return -EINVAL;
1142 }
1143
1144 pvreg->apcs_gcc_base = devm_ioremap(&pdev->dev, res->start,
1145 resource_size(res));
1146
1147 if (pvreg->apcs_gcc_base == NULL)
1148 return -ENOMEM;
1149
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001150 pvreg->name = "pmic_gang";
1151 pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
1152 pvreg->pmic_phase_count = -EINVAL;
1153 pvreg->retention_enabled = true;
1154 pvreg->pmic_min_uV_for_retention = INT_MAX;
1155 pvreg->use_phase_switching = use_phase_switching;
1156
1157 mutex_init(&pvreg->krait_power_vregs_lock);
1158 INIT_LIST_HEAD(&pvreg->krait_power_vregs);
1159 the_gang = pvreg;
1160
1161 pr_debug("name=%s inited\n", pvreg->name);
1162
1163 /* global initializtion */
Stepan Moskovchenko7663b782013-03-08 20:13:06 -08001164 glb_init(pvreg->apcs_gcc_base);
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001165
1166 rc = of_platform_populate(node, NULL, NULL, dev);
1167 if (rc) {
1168 dev_err(dev, "failed to add child nodes, rc=%d\n", rc);
1169 return rc;
1170 }
1171
1172 dent = debugfs_create_dir(KRAIT_REGULATOR_DRIVER_NAME, NULL);
1173 debugfs_create_file("retention_uV",
1174 0644, dent, the_gang, &retention_fops);
1175 return 0;
1176}
1177
1178static int __devexit krait_pdn_remove(struct platform_device *pdev)
1179{
1180 the_gang = NULL;
1181 debugfs_remove_recursive(dent);
1182 return 0;
1183}
1184
1185static struct platform_driver krait_pdn_driver = {
1186 .probe = krait_pdn_probe,
1187 .remove = __devexit_p(krait_pdn_remove),
1188 .driver = {
1189 .name = KRAIT_PDN_DRIVER_NAME,
1190 .of_match_table = krait_pdn_match_table,
1191 .owner = THIS_MODULE,
1192 },
1193};
1194
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001195int __init krait_power_init(void)
1196{
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001197 int rc = platform_driver_register(&krait_power_driver);
1198 if (rc) {
1199 pr_err("failed to add %s driver rc = %d\n",
1200 KRAIT_REGULATOR_DRIVER_NAME, rc);
1201 return rc;
1202 }
1203 return platform_driver_register(&krait_pdn_driver);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001204}
1205
1206static void __exit krait_power_exit(void)
1207{
1208 platform_driver_unregister(&krait_power_driver);
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001209 platform_driver_unregister(&krait_pdn_driver);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001210}
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001211module_exit(krait_power_exit);
1212
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001213void secondary_cpu_hs_init(void *base_ptr)
1214{
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001215 /* Turn on the BHS, turn off LDO Bypass and power down LDO */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001216 writel_relaxed(
1217 BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
1218 | LDO_PWR_DWN_MASK
1219 | CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
1220 | BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
1221 | BHS_EN_MASK,
1222 base_ptr + APC_PWR_GATE_CTL);
1223
1224 /* complete the above write before the delay */
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001225 mb();
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001226
1227 /*
1228 * wait for the bhs to settle
1229 */
1230 udelay(BHS_SETTLING_DELAY_US);
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001231
1232 /* Finally turn on the bypass so that BHS supplies power */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001233 writel_relaxed(
1234 BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
1235 | LDO_PWR_DWN_MASK
1236 | CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
1237 | LDO_BYP_MASK
1238 | BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
1239 | BHS_EN_MASK,
1240 base_ptr + APC_PWR_GATE_CTL);
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001241}
1242
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001243MODULE_LICENSE("GPL v2");
1244MODULE_DESCRIPTION("KRAIT POWER regulator driver");
1245MODULE_VERSION("1.0");
1246MODULE_ALIAS("platform:"KRAIT_REGULATOR_DRIVER_NAME);