blob: 953f941dbbd772aa380e7f6dfaaca7c8fcf700c4 [file] [log] [blame]
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -08001/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -080013#define pr_fmt(fmt) "PDN %s: " fmt, __func__
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070014
15#include <linux/err.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/slab.h>
21#include <linux/string.h>
22#include <linux/io.h>
23#include <linux/of.h>
24#include <linux/of_device.h>
25#include <linux/platform_device.h>
26#include <linux/regulator/driver.h>
27#include <linux/regulator/machine.h>
28#include <linux/regulator/of_regulator.h>
29#include <linux/regulator/krait-regulator.h>
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -080030#include <linux/debugfs.h>
Abhijeet Dharmapurikarc8605a62013-03-11 21:24:25 -070031#include <linux/syscore_ops.h>
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -070032#include <mach/msm_iomap.h>
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070033
34#include "spm.h"
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -080035#include "pm.h"
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070036
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070037/*
38 * supply
39 * from
40 * pmic
41 * gang
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -080042 * |
43 * |________________________________
44 * | | |
45 * ___|___ | |
46 * | | | |
47 * | | / /
48 * | LDO | / /LDO BYP [6]
49 * | | / BHS[6] /(bypass is a weak BHS
50 * |_______| | | needs to be on when in
51 * | | | BHS mode)
52 * |________________|_______________|
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070053 * |
54 * ________|________
55 * | |
56 * | KRAIT |
57 * |_________________|
58 */
59
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070060#define PMIC_VOLTAGE_MIN 350000
61#define PMIC_VOLTAGE_MAX 1355000
62#define LV_RANGE_STEP 5000
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070063
Willie Ruan3fe734a2013-04-17 12:28:25 -070064#define LOAD_PER_PHASE 3200000
65
66#define CORE_VOLTAGE_MIN 900000
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -070067
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070068#define KRAIT_LDO_VOLTAGE_MIN 465000
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -070069#define KRAIT_LDO_VOLTAGE_OFFSET 465000
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070070#define KRAIT_LDO_STEP 5000
71
72#define BHS_SETTLING_DELAY_US 1
73#define LDO_SETTLING_DELAY_US 1
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -080074#define MDD_SETTLING_DELAY_US 5
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070075
76#define _KRAIT_MASK(BITS, POS) (((u32)(1 << (BITS)) - 1) << POS)
77#define KRAIT_MASK(LEFT_BIT_POS, RIGHT_BIT_POS) \
78 _KRAIT_MASK(LEFT_BIT_POS - RIGHT_BIT_POS + 1, RIGHT_BIT_POS)
79
80#define APC_SECURE 0x00000000
81#define CPU_PWR_CTL 0x00000004
82#define APC_PWR_STATUS 0x00000008
83#define APC_TEST_BUS_SEL 0x0000000C
84#define CPU_TRGTD_DBG_RST 0x00000010
85#define APC_PWR_GATE_CTL 0x00000014
86#define APC_LDO_VREF_SET 0x00000018
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -070087#define APC_PWR_GATE_MODE 0x0000001C
88#define APC_PWR_GATE_DLY 0x00000020
89
90#define PWR_GATE_CONFIG 0x00000044
91#define VERSION 0x00000FD0
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070092
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -080093/* MDD register group */
94#define MDD_CONFIG_CTL 0x00000000
95#define MDD_MODE 0x00000010
96
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -070097/* bit definitions for APC_PWR_GATE_CTL */
98#define BHS_CNT_BIT_POS 24
99#define BHS_CNT_MASK KRAIT_MASK(31, 24)
100#define BHS_CNT_DEFAULT 64
101
102#define CLK_SRC_SEL_BIT_POS 15
103#define CLK_SRC_SEL_MASK KRAIT_MASK(15, 15)
104#define CLK_SRC_DEFAULT 0
105
106#define LDO_PWR_DWN_BIT_POS 16
107#define LDO_PWR_DWN_MASK KRAIT_MASK(21, 16)
108
109#define LDO_BYP_BIT_POS 8
110#define LDO_BYP_MASK KRAIT_MASK(13, 8)
111
112#define BHS_SEG_EN_BIT_POS 1
113#define BHS_SEG_EN_MASK KRAIT_MASK(6, 1)
114#define BHS_SEG_EN_DEFAULT 0x3F
115
116#define BHS_EN_BIT_POS 0
117#define BHS_EN_MASK KRAIT_MASK(0, 0)
118
119/* bit definitions for APC_LDO_VREF_SET register */
120#define VREF_RET_POS 8
121#define VREF_RET_MASK KRAIT_MASK(14, 8)
122
123#define VREF_LDO_BIT_POS 0
124#define VREF_LDO_MASK KRAIT_MASK(6, 0)
125
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800126#define LDO_HDROOM_MIN 50000
127#define LDO_HDROOM_MAX 250000
128
129#define LDO_UV_MIN 465000
130#define LDO_UV_MAX 750000
131
132#define LDO_TH_MIN 600000
133#define LDO_TH_MAX 900000
134
135#define LDO_DELTA_MIN 10000
136#define LDO_DELTA_MAX 100000
137
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700138/**
139 * struct pmic_gang_vreg -
140 * @name: the string used to represent the gang
141 * @pmic_vmax_uV: the current pmic gang voltage
142 * @pmic_phase_count: the number of phases turned on in the gang
143 * @krait_power_vregs: a list of krait consumers this gang supplies to
144 * @krait_power_vregs_lock: lock to prevent simultaneous access to the list
145 * and its nodes. This needs to be taken by each
146 * regulator's callback functions to prevent
147 * simultaneous updates to the pmic's phase
148 * voltage.
Willie Ruan3fe734a2013-04-17 12:28:25 -0700149 * @apcs_gcc_base virtual address of the APCS GCC registers
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700150 */
151struct pmic_gang_vreg {
152 const char *name;
153 int pmic_vmax_uV;
154 int pmic_phase_count;
155 struct list_head krait_power_vregs;
156 struct mutex krait_power_vregs_lock;
Abhijeet Dharmapurikar6a42ef82012-10-18 19:37:36 -0700157 bool pfm_mode;
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -0800158 int pmic_min_uV_for_retention;
159 bool retention_enabled;
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -0800160 bool use_phase_switching;
Stepan Moskovchenko7663b782013-03-08 20:13:06 -0800161 void __iomem *apcs_gcc_base;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700162};
163
164static struct pmic_gang_vreg *the_gang;
165
166enum krait_supply_mode {
167 HS_MODE = REGULATOR_MODE_NORMAL,
168 LDO_MODE = REGULATOR_MODE_IDLE,
169};
170
171struct krait_power_vreg {
172 struct list_head link;
173 struct regulator_desc desc;
174 struct regulator_dev *rdev;
175 const char *name;
176 struct pmic_gang_vreg *pvreg;
177 int uV;
Willie Ruan3fe734a2013-04-17 12:28:25 -0700178 int load_uA;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700179 enum krait_supply_mode mode;
180 void __iomem *reg_base;
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800181 void __iomem *mdd_base;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700182 int ldo_default_uV;
183 int retention_uV;
184 int headroom_uV;
185 int ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800186 int ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800187 int cpu_num;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800188 bool online;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700189};
190
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800191DEFINE_PER_CPU(struct krait_power_vreg *, krait_vregs);
192
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700193static u32 version;
194
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800195static int is_between(int left, int right, int value)
196{
197 if (left >= right && left >= value && value >= right)
198 return 1;
199 if (left <= right && left <= value && value <= right)
200 return 1;
201 return 0;
202}
203
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700204static void krait_masked_write(struct krait_power_vreg *kvreg,
205 int reg, uint32_t mask, uint32_t val)
206{
207 uint32_t reg_val;
208
209 reg_val = readl_relaxed(kvreg->reg_base + reg);
210 reg_val &= ~mask;
211 reg_val |= (val & mask);
212 writel_relaxed(reg_val, kvreg->reg_base + reg);
213
214 /*
215 * Barrier to ensure that the reads and writes from
216 * other regulator regions (they are 1k apart) execute in
217 * order to the above write.
218 */
219 mb();
220}
221
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800222static int get_krait_retention_ldo_uv(struct krait_power_vreg *kvreg)
223{
224 uint32_t reg_val;
225 int uV;
226
227 reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
228 reg_val &= VREF_RET_MASK;
229 reg_val >>= VREF_RET_POS;
230
231 if (reg_val == 0)
232 uV = 0;
233 else
234 uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
235
236 return uV;
237}
238
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700239static int get_krait_ldo_uv(struct krait_power_vreg *kvreg)
240{
241 uint32_t reg_val;
242 int uV;
243
244 reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
245 reg_val &= VREF_LDO_MASK;
246 reg_val >>= VREF_LDO_BIT_POS;
247
248 if (reg_val == 0)
249 uV = 0;
250 else
251 uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
252
253 return uV;
254}
255
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700256static int set_krait_retention_uv(struct krait_power_vreg *kvreg, int uV)
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700257{
258 uint32_t reg_val;
259
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700260 reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
261 krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_RET_MASK,
262 reg_val << VREF_RET_POS);
263
264 return 0;
265}
266
267static int set_krait_ldo_uv(struct krait_power_vreg *kvreg, int uV)
268{
269 uint32_t reg_val;
270
271 reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700272 krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_LDO_MASK,
273 reg_val << VREF_LDO_BIT_POS);
274
275 return 0;
276}
277
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800278static int __krait_power_mdd_enable(struct krait_power_vreg *kvreg, bool on)
279{
280 if (on) {
281 writel_relaxed(0x00000002, kvreg->mdd_base + MDD_MODE);
282 /* complete the above write before the delay */
283 mb();
284 udelay(MDD_SETTLING_DELAY_US);
285 } else {
286 writel_relaxed(0x00000000, kvreg->mdd_base + MDD_MODE);
287 /*
288 * complete the above write before other accesses
289 * to krait regulator
290 */
291 mb();
292 }
293 return 0;
294}
295
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700296static int switch_to_using_hs(struct krait_power_vreg *kvreg)
297{
298 if (kvreg->mode == HS_MODE)
299 return 0;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700300 /* enable bhs */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800301 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
302 BHS_SEG_EN_MASK | BHS_EN_MASK,
303 BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS | BHS_EN_MASK);
304
305 /* complete the above write before the delay */
306 mb();
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700307
308 /*
309 * wait for the bhs to settle - note that
310 * after the voltage has settled both BHS and LDO are supplying power
311 * to the krait. This avoids glitches during switching
312 */
313 udelay(BHS_SETTLING_DELAY_US);
314
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800315 /*
316 * enable ldo bypass - the krait is powered still by LDO since
317 * LDO is enabled
318 */
319 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_BYP_MASK, LDO_BYP_MASK);
320
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700321 /* disable ldo - only the BHS provides voltage to the cpu after this */
322 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
323 LDO_PWR_DWN_MASK, LDO_PWR_DWN_MASK);
324
325 kvreg->mode = HS_MODE;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800326 pr_debug("%s using BHS\n", kvreg->name);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700327 return 0;
328}
329
330static int switch_to_using_ldo(struct krait_power_vreg *kvreg)
331{
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800332 if (kvreg->mode == LDO_MODE
333 && get_krait_ldo_uv(kvreg) == kvreg->uV - kvreg->ldo_delta_uV)
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700334 return 0;
335
336 /*
337 * if the krait is in ldo mode and a voltage change is requested on the
338 * ldo switch to using hs before changing ldo voltage
339 */
340 if (kvreg->mode == LDO_MODE)
341 switch_to_using_hs(kvreg);
342
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800343 set_krait_ldo_uv(kvreg, kvreg->uV - kvreg->ldo_delta_uV);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700344
345 /*
346 * enable ldo - note that both LDO and BHS are are supplying voltage to
347 * the cpu after this. This avoids glitches during switching from BHS
348 * to LDO.
349 */
350 krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_PWR_DWN_MASK, 0);
351
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800352 /* complete the writes before the delay */
353 mb();
354
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700355 /* wait for the ldo to settle */
356 udelay(LDO_SETTLING_DELAY_US);
357
358 /*
359 * disable BHS and disable LDO bypass seperate from enabling
360 * the LDO above.
361 */
362 krait_masked_write(kvreg, APC_PWR_GATE_CTL,
363 BHS_EN_MASK | LDO_BYP_MASK, 0);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800364 krait_masked_write(kvreg, APC_PWR_GATE_CTL, BHS_SEG_EN_MASK, 0);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700365
366 kvreg->mode = LDO_MODE;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800367 pr_debug("%s using LDO\n", kvreg->name);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700368 return 0;
369}
370
Willie Ruan3fe734a2013-04-17 12:28:25 -0700371static int set_pmic_gang_phases(struct pmic_gang_vreg *pvreg, int phase_count)
372{
373 pr_debug("programming phase_count = %d\n", phase_count);
374 if (pvreg->use_phase_switching)
375 /*
376 * note the PMIC sets the phase count to one more than
377 * the value in the register - hence subtract 1 from it
378 */
379 return msm_spm_apcs_set_phase(phase_count - 1);
380 else
381 return 0;
382}
383
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800384static int set_pmic_gang_voltage(struct pmic_gang_vreg *pvreg, int uV)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700385{
386 int setpoint;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800387 int rc;
388
389 if (pvreg->pmic_vmax_uV == uV)
390 return 0;
391
392 pr_debug("%d\n", uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700393
394 if (uV < PMIC_VOLTAGE_MIN) {
395 pr_err("requested %d < %d, restricting it to %d\n",
396 uV, PMIC_VOLTAGE_MIN, PMIC_VOLTAGE_MIN);
397 uV = PMIC_VOLTAGE_MIN;
398 }
399 if (uV > PMIC_VOLTAGE_MAX) {
400 pr_err("requested %d > %d, restricting it to %d\n",
401 uV, PMIC_VOLTAGE_MAX, PMIC_VOLTAGE_MAX);
402 uV = PMIC_VOLTAGE_MAX;
403 }
404
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -0800405 if (uV < pvreg->pmic_min_uV_for_retention) {
406 if (pvreg->retention_enabled) {
407 pr_debug("Disabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
408 uV, pvreg->pmic_min_uV_for_retention);
409 msm_pm_enable_retention(false);
410 pvreg->retention_enabled = false;
411 }
412 } else {
413 if (!pvreg->retention_enabled) {
414 pr_debug("Enabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
415 uV, pvreg->pmic_min_uV_for_retention);
416 msm_pm_enable_retention(true);
417 pvreg->retention_enabled = true;
418 }
419 }
420
Abhijeet Dharmapurikard4f38da2012-08-08 21:42:06 -0700421 setpoint = DIV_ROUND_UP(uV, LV_RANGE_STEP);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800422
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800423 rc = msm_spm_apcs_set_vdd(setpoint);
424 if (rc < 0)
425 pr_err("could not set %duV setpt = 0x%x rc = %d\n",
426 uV, setpoint, rc);
427 else
428 pvreg->pmic_vmax_uV = uV;
429
430 return rc;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700431}
432
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800433static int configure_ldo_or_hs_all(struct krait_power_vreg *from, int vmax)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700434{
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700435 struct pmic_gang_vreg *pvreg = from->pvreg;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700436 struct krait_power_vreg *kvreg;
437 int rc = 0;
438
439 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800440 if (!kvreg->online)
441 continue;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800442 if (kvreg->uV <= kvreg->ldo_threshold_uV
443 && kvreg->uV - kvreg->ldo_delta_uV + kvreg->headroom_uV
444 <= vmax) {
445 rc = switch_to_using_ldo(kvreg);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700446 if (rc < 0) {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800447 pr_err("could not switch %s to ldo rc = %d\n",
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700448 kvreg->name, rc);
449 return rc;
450 }
451 } else {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800452 rc = switch_to_using_hs(kvreg);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700453 if (rc < 0) {
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800454 pr_err("could not switch %s to hs rc = %d\n",
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700455 kvreg->name, rc);
456 return rc;
457 }
458 }
459 }
460
461 return rc;
462}
463
464#define SLEW_RATE 2994
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800465static int krait_voltage_increase(struct krait_power_vreg *from,
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700466 int vmax)
467{
468 struct pmic_gang_vreg *pvreg = from->pvreg;
469 int rc = 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700470 int settling_us;
471
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700472 /*
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800473 * since krait voltage is increasing set the gang voltage
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700474 * prior to changing ldo/hs states of the requesting krait
475 */
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800476 rc = set_pmic_gang_voltage(pvreg, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700477 if (rc < 0) {
478 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
479 pvreg->name, vmax, rc);
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800480 return rc;
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700481 }
482
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800483
484 /* complete the above writes before the delay */
485 mb();
486
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700487 /* delay until the voltage is settled when it is raised */
488 settling_us = DIV_ROUND_UP(vmax - pvreg->pmic_vmax_uV, SLEW_RATE);
489 udelay(settling_us);
490
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800491 rc = configure_ldo_or_hs_all(from, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700492 if (rc < 0) {
493 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
494 pvreg->name, vmax, rc);
495 }
496
497 return rc;
498}
499
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800500static int krait_voltage_decrease(struct krait_power_vreg *from,
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700501 int vmax)
502{
503 struct pmic_gang_vreg *pvreg = from->pvreg;
504 int rc = 0;
505
506 /*
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800507 * since krait voltage is decreasing ldos might get out of their
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700508 * operating range. Hence configure such kraits to be in hs mode prior
509 * to setting the pmic gang voltage
510 */
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800511 rc = configure_ldo_or_hs_all(from, vmax);
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700512 if (rc < 0) {
513 dev_err(&from->rdev->dev, "%s failed ldo/hs conf %d rc = %d\n",
514 pvreg->name, vmax, rc);
515 return rc;
516 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700517
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800518 rc = set_pmic_gang_voltage(pvreg, vmax);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700519 if (rc < 0) {
520 dev_err(&from->rdev->dev, "%s failed set voltage %d rc = %d\n",
521 pvreg->name, vmax, rc);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700522 }
523
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700524 return rc;
525}
526
Willie Ruan3fe734a2013-04-17 12:28:25 -0700527#define PHASE_SETTLING_TIME_US 10
528static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
529 int load_uA)
530{
531 struct pmic_gang_vreg *pvreg = from->pvreg;
532 int phase_count = DIV_ROUND_UP(load_uA, LOAD_PER_PHASE);
533 int rc = 0;
534
535 if (phase_count <= 0)
536 phase_count = 1;
537
538 /* Increase phases if it is less than the number of cpus online */
539 if (phase_count < num_online_cpus()) {
540 phase_count = num_online_cpus();
541 }
542
543 if (phase_count != pvreg->pmic_phase_count) {
544 rc = set_pmic_gang_phases(pvreg, phase_count);
545 if (rc < 0) {
546 dev_err(&from->rdev->dev,
547 "%s failed set phase %d rc = %d\n",
548 pvreg->name, phase_count, rc);
549 return rc;
550 }
551
552 /* complete the writes before the delay */
553 mb();
554
555 /*
556 * delay until the phases are settled when
557 * the count is raised
558 */
559 if (phase_count > pvreg->pmic_phase_count)
560 udelay(PHASE_SETTLING_TIME_US);
561
562 pvreg->pmic_phase_count = phase_count;
563 }
564 return rc;
565}
566
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700567static int krait_power_get_voltage(struct regulator_dev *rdev)
568{
569 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
570
571 return kvreg->uV;
572}
573
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800574static int get_vmax(struct pmic_gang_vreg *pvreg)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700575{
576 int vmax = 0;
577 int v;
578 struct krait_power_vreg *kvreg;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700579
580 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800581 if (!kvreg->online)
582 continue;
583
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700584 v = kvreg->uV;
585
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700586 if (vmax < v)
587 vmax = v;
588 }
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800589
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700590 return vmax;
591}
592
Willie Ruan3fe734a2013-04-17 12:28:25 -0700593static int get_total_load(struct krait_power_vreg *from)
594{
595 int load_total = 0;
596 struct krait_power_vreg *kvreg;
597 struct pmic_gang_vreg *pvreg = from->pvreg;
598
599 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
600 if (!kvreg->online)
601 continue;
602 load_total += kvreg->load_uA;
603 }
604
605 return load_total;
606}
607
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700608#define ROUND_UP_VOLTAGE(v, res) (DIV_ROUND_UP(v, res) * res)
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800609static int _set_voltage(struct regulator_dev *rdev,
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800610 int orig_krait_uV, int requested_uV)
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700611{
612 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
613 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
614 int rc;
615 int vmax;
616
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800617 pr_debug("%s: %d to %d\n", kvreg->name, orig_krait_uV, requested_uV);
618 /*
619 * Assign the voltage before updating the gang voltage as we iterate
620 * over all the core voltages and choose HS or LDO for each of them
621 */
622 kvreg->uV = requested_uV;
623
624 vmax = get_vmax(pvreg);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800625
626 /* round up the pmic voltage as per its resolution */
627 vmax = ROUND_UP_VOLTAGE(vmax, LV_RANGE_STEP);
628
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800629 if (requested_uV > orig_krait_uV)
630 rc = krait_voltage_increase(kvreg, vmax);
631 else
632 rc = krait_voltage_decrease(kvreg, vmax);
633
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800634 if (rc < 0) {
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800635 dev_err(&rdev->dev, "%s failed to set %duV from %duV rc = %d\n",
636 kvreg->name, requested_uV, orig_krait_uV, rc);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800637 }
638
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800639 return rc;
640}
641
642static int krait_power_set_voltage(struct regulator_dev *rdev,
643 int min_uV, int max_uV, unsigned *selector)
644{
645 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
646 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
647 int rc;
648
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700649 /*
650 * if the voltage requested is below LDO_THRESHOLD this cpu could
651 * switch to LDO mode. Hence round the voltage as per the LDO
652 * resolution
653 */
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700654 if (min_uV < kvreg->ldo_threshold_uV) {
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700655 if (min_uV < KRAIT_LDO_VOLTAGE_MIN)
656 min_uV = KRAIT_LDO_VOLTAGE_MIN;
657 min_uV = ROUND_UP_VOLTAGE(min_uV, KRAIT_LDO_STEP);
658 }
659
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700660 mutex_lock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800661 if (!kvreg->online) {
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800662 kvreg->uV = min_uV;
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800663 mutex_unlock(&pvreg->krait_power_vregs_lock);
664 return 0;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700665 }
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700666
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800667 rc = _set_voltage(rdev, kvreg->uV, min_uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700668 mutex_unlock(&pvreg->krait_power_vregs_lock);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800669
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700670 return rc;
671}
672
Willie Ruan3fe734a2013-04-17 12:28:25 -0700673#define PMIC_FTS_MODE_PFM 0x00
674#define PMIC_FTS_MODE_PWM 0x80
675#define PFM_LOAD_UA 500000
676static unsigned int _get_optimum_mode(struct regulator_dev *rdev,
677 int input_uV, int output_uV, int load_uA)
678{
679 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
680 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
681 int rc;
682 int load_total_uA;
683
684 load_total_uA = get_total_load(kvreg);
685
686 if (load_total_uA < PFM_LOAD_UA) {
687 if (!pvreg->pfm_mode) {
688 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PFM);
689 if (rc) {
690 dev_err(&rdev->dev,
691 "%s enter PFM failed load %d rc = %d\n",
692 kvreg->name, load_total_uA, rc);
693 goto out;
694 } else {
695 pvreg->pfm_mode = true;
696 }
697 }
698 return kvreg->mode;
699 }
700
701 if (pvreg->pfm_mode) {
702 rc = msm_spm_enable_fts_lpm(PMIC_FTS_MODE_PWM);
703 if (rc) {
704 dev_err(&rdev->dev,
705 "%s exit PFM failed load %d rc = %d\n",
706 kvreg->name, load_total_uA, rc);
707 goto out;
708 } else {
709 pvreg->pfm_mode = false;
710 }
711 }
712
713 rc = pmic_gang_set_phases(kvreg, load_total_uA);
714 if (rc < 0) {
715 dev_err(&rdev->dev, "%s failed set mode %d rc = %d\n",
716 kvreg->name, load_total_uA, rc);
717 goto out;
718 }
719
720out:
721 return kvreg->mode;
722}
723
724static unsigned int krait_power_get_optimum_mode(struct regulator_dev *rdev,
725 int input_uV, int output_uV, int load_uA)
726{
727 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
728 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
729 int rc;
730
731 mutex_lock(&pvreg->krait_power_vregs_lock);
732 kvreg->load_uA = load_uA;
733 if (!kvreg->online) {
734 mutex_unlock(&pvreg->krait_power_vregs_lock);
735 return kvreg->mode;
736 }
737
738 rc = _get_optimum_mode(rdev, input_uV, output_uV, load_uA);
739 mutex_unlock(&pvreg->krait_power_vregs_lock);
740
741 return rc;
742}
743
744static int krait_power_set_mode(struct regulator_dev *rdev, unsigned int mode)
745{
746 return 0;
747}
748
749static unsigned int krait_power_get_mode(struct regulator_dev *rdev)
750{
751 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
752
753 return kvreg->mode;
754}
755
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800756static int krait_power_is_enabled(struct regulator_dev *rdev)
757{
758 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
759
760 return kvreg->online;
761}
762
763static int krait_power_enable(struct regulator_dev *rdev)
764{
765 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
766 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
767 int rc;
768
769 mutex_lock(&pvreg->krait_power_vregs_lock);
Abhijeet Dharmapurikarc8605a62013-03-11 21:24:25 -0700770 __krait_power_mdd_enable(kvreg, true);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800771 kvreg->online = true;
Willie Ruan3fe734a2013-04-17 12:28:25 -0700772 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV, kvreg->load_uA);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800773 if (rc < 0)
774 goto en_err;
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800775 /*
776 * since the core is being enabled, behave as if it is increasing
777 * the core voltage
778 */
779 rc = _set_voltage(rdev, 0, kvreg->uV);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800780en_err:
781 mutex_unlock(&pvreg->krait_power_vregs_lock);
782 return rc;
783}
784
785static int krait_power_disable(struct regulator_dev *rdev)
786{
787 struct krait_power_vreg *kvreg = rdev_get_drvdata(rdev);
788 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
789 int rc;
790
791 mutex_lock(&pvreg->krait_power_vregs_lock);
792 kvreg->online = false;
793
Willie Ruan3fe734a2013-04-17 12:28:25 -0700794 rc = _get_optimum_mode(rdev, kvreg->uV, kvreg->uV,
795 kvreg->load_uA);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800796 if (rc < 0)
797 goto dis_err;
798
Abhijeet Dharmapurikarfe1306b2012-11-15 18:09:31 -0800799 rc = _set_voltage(rdev, kvreg->uV, kvreg->uV);
Abhijeet Dharmapurikarc8605a62013-03-11 21:24:25 -0700800 __krait_power_mdd_enable(kvreg, false);
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800801dis_err:
802 mutex_unlock(&pvreg->krait_power_vregs_lock);
803 return rc;
804}
805
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700806static struct regulator_ops krait_power_ops = {
807 .get_voltage = krait_power_get_voltage,
808 .set_voltage = krait_power_set_voltage,
809 .get_optimum_mode = krait_power_get_optimum_mode,
810 .set_mode = krait_power_set_mode,
811 .get_mode = krait_power_get_mode,
Michael Bohanb5d1cdb2012-11-08 18:09:52 -0800812 .enable = krait_power_enable,
813 .disable = krait_power_disable,
814 .is_enabled = krait_power_is_enabled,
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700815};
816
Abhijeet Dharmapurikar37c47a82013-01-08 18:44:21 -0800817static struct dentry *dent;
818static int get_retention_dbg_uV(void *data, u64 *val)
819{
820 struct pmic_gang_vreg *pvreg = data;
821 struct krait_power_vreg *kvreg;
822
823 mutex_lock(&pvreg->krait_power_vregs_lock);
824 if (!list_empty(&pvreg->krait_power_vregs)) {
825 /* return the retention voltage on just the first cpu */
826 kvreg = list_entry((&pvreg->krait_power_vregs)->next,
827 typeof(*kvreg), link);
828 *val = get_krait_retention_ldo_uv(kvreg);
829 }
830 mutex_unlock(&pvreg->krait_power_vregs_lock);
831 return 0;
832}
833
834static int set_retention_dbg_uV(void *data, u64 val)
835{
836 struct pmic_gang_vreg *pvreg = data;
837 struct krait_power_vreg *kvreg;
838 int retention_uV = val;
839
840 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV))
841 return -EINVAL;
842
843 mutex_lock(&pvreg->krait_power_vregs_lock);
844 list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
845 kvreg->retention_uV = retention_uV;
846 set_krait_retention_uv(kvreg, retention_uV);
847 }
848 mutex_unlock(&pvreg->krait_power_vregs_lock);
849 return 0;
850}
851DEFINE_SIMPLE_ATTRIBUTE(retention_fops,
852 get_retention_dbg_uV, set_retention_dbg_uV, "%llu\n");
853
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700854static void kvreg_hw_init(struct krait_power_vreg *kvreg)
855{
856 /*
857 * bhs_cnt value sets the ramp-up time from power collapse,
858 * initialize the ramp up time
859 */
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700860 set_krait_retention_uv(kvreg, kvreg->retention_uV);
861 set_krait_ldo_uv(kvreg, kvreg->ldo_default_uV);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800862
863 /* setup the bandgap that configures the reference to the LDO */
864 writel_relaxed(0x00000190, kvreg->mdd_base + MDD_CONFIG_CTL);
Abhijeet Dharmapurikarc8605a62013-03-11 21:24:25 -0700865 /* Enable MDD */
866 writel_relaxed(0x00000002, kvreg->mdd_base + MDD_MODE);
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800867 mb();
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -0700868}
869
Stepan Moskovchenko7663b782013-03-08 20:13:06 -0800870static void glb_init(void __iomem *apcs_gcc_base)
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700871{
872 /* configure bi-modal switch */
Stepan Moskovchenko7663b782013-03-08 20:13:06 -0800873 writel_relaxed(0x0008736E, apcs_gcc_base + PWR_GATE_CONFIG);
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700874 /* read kpss version */
Stepan Moskovchenko7663b782013-03-08 20:13:06 -0800875 version = readl_relaxed(apcs_gcc_base + VERSION);
Abhijeet Dharmapurikar3ff7cba2012-10-10 17:48:29 -0700876 pr_debug("version= 0x%x\n", version);
877}
878
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700879static int __devinit krait_power_probe(struct platform_device *pdev)
880{
881 struct krait_power_vreg *kvreg;
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800882 struct resource *res, *res_mdd;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700883 struct regulator_init_data *init_data = pdev->dev.platform_data;
884 int rc = 0;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700885 int headroom_uV, retention_uV, ldo_default_uV, ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800886 int ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800887 int cpu_num;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700888
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700889 if (pdev->dev.of_node) {
890 /* Get init_data from device tree. */
891 init_data = of_get_regulator_init_data(&pdev->dev,
892 pdev->dev.of_node);
893 init_data->constraints.valid_ops_mask
894 |= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_DRMS
895 | REGULATOR_CHANGE_MODE;
896 init_data->constraints.valid_modes_mask
897 |= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE
898 | REGULATOR_MODE_FAST;
899 init_data->constraints.input_uV = init_data->constraints.max_uV;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -0700900 rc = of_property_read_u32(pdev->dev.of_node,
901 "qcom,headroom-voltage",
902 &headroom_uV);
903 if (rc < 0) {
904 pr_err("headroom-voltage missing rc=%d\n", rc);
905 return rc;
906 }
907 if (!is_between(LDO_HDROOM_MIN, LDO_HDROOM_MAX, headroom_uV)) {
908 pr_err("bad headroom-voltage = %d specified\n",
909 headroom_uV);
910 return -EINVAL;
911 }
912
913 rc = of_property_read_u32(pdev->dev.of_node,
914 "qcom,retention-voltage",
915 &retention_uV);
916 if (rc < 0) {
917 pr_err("retention-voltage missing rc=%d\n", rc);
918 return rc;
919 }
920 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV)) {
921 pr_err("bad retention-voltage = %d specified\n",
922 retention_uV);
923 return -EINVAL;
924 }
925
926 rc = of_property_read_u32(pdev->dev.of_node,
927 "qcom,ldo-default-voltage",
928 &ldo_default_uV);
929 if (rc < 0) {
930 pr_err("ldo-default-voltage missing rc=%d\n", rc);
931 return rc;
932 }
933 if (!is_between(LDO_UV_MIN, LDO_UV_MAX, ldo_default_uV)) {
934 pr_err("bad ldo-default-voltage = %d specified\n",
935 ldo_default_uV);
936 return -EINVAL;
937 }
938
939 rc = of_property_read_u32(pdev->dev.of_node,
940 "qcom,ldo-threshold-voltage",
941 &ldo_threshold_uV);
942 if (rc < 0) {
943 pr_err("ldo-threshold-voltage missing rc=%d\n", rc);
944 return rc;
945 }
946 if (!is_between(LDO_TH_MIN, LDO_TH_MAX, ldo_threshold_uV)) {
947 pr_err("bad ldo-threshold-voltage = %d specified\n",
948 ldo_threshold_uV);
949 return -EINVAL;
950 }
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -0800951
952 rc = of_property_read_u32(pdev->dev.of_node,
953 "qcom,ldo-delta-voltage",
954 &ldo_delta_uV);
955 if (rc < 0) {
956 pr_err("ldo-delta-voltage missing rc=%d\n", rc);
957 return rc;
958 }
959 if (!is_between(LDO_DELTA_MIN, LDO_DELTA_MAX, ldo_delta_uV)) {
960 pr_err("bad ldo-delta-voltage = %d specified\n",
961 ldo_delta_uV);
962 return -EINVAL;
963 }
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -0800964 rc = of_property_read_u32(pdev->dev.of_node,
965 "qcom,cpu-num",
966 &cpu_num);
967 if (cpu_num > num_possible_cpus()) {
968 pr_err("bad cpu-num= %d specified\n", cpu_num);
969 return -EINVAL;
970 }
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700971 }
972
973 if (!init_data) {
974 dev_err(&pdev->dev, "init data required.\n");
975 return -EINVAL;
976 }
977
978 if (!init_data->constraints.name) {
979 dev_err(&pdev->dev,
980 "regulator name must be specified in constraints.\n");
981 return -EINVAL;
982 }
983
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800984 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acs");
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700985 if (!res) {
986 dev_err(&pdev->dev, "missing physical register addresses\n");
987 return -EINVAL;
988 }
989
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -0800990 res_mdd = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mdd");
991 if (!res_mdd) {
992 dev_err(&pdev->dev, "missing mdd register addresses\n");
993 return -EINVAL;
994 }
995
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -0700996 kvreg = devm_kzalloc(&pdev->dev,
997 sizeof(struct krait_power_vreg), GFP_KERNEL);
998 if (!kvreg) {
999 dev_err(&pdev->dev, "kzalloc failed.\n");
1000 return -ENOMEM;
1001 }
1002
1003 kvreg->reg_base = devm_ioremap(&pdev->dev,
1004 res->start, resource_size(res));
1005
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001006 kvreg->mdd_base = devm_ioremap(&pdev->dev,
1007 res_mdd->start, resource_size(res));
1008
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -07001009 kvreg->pvreg = the_gang;
1010 kvreg->name = init_data->constraints.name;
1011 kvreg->desc.name = kvreg->name;
1012 kvreg->desc.ops = &krait_power_ops;
1013 kvreg->desc.type = REGULATOR_VOLTAGE;
1014 kvreg->desc.owner = THIS_MODULE;
Willie Ruan3fe734a2013-04-17 12:28:25 -07001015 kvreg->uV = CORE_VOLTAGE_MIN;
Abhijeet Dharmapurikar34f0d642012-10-25 12:35:23 -07001016 kvreg->mode = HS_MODE;
1017 kvreg->desc.ops = &krait_power_ops;
1018 kvreg->headroom_uV = headroom_uV;
1019 kvreg->retention_uV = retention_uV;
1020 kvreg->ldo_default_uV = ldo_default_uV;
1021 kvreg->ldo_threshold_uV = ldo_threshold_uV;
Abhijeet Dharmapurikar2269db02012-12-05 15:49:20 -08001022 kvreg->ldo_delta_uV = ldo_delta_uV;
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001023 kvreg->cpu_num = cpu_num;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001024
1025 platform_set_drvdata(pdev, kvreg);
1026
1027 mutex_lock(&the_gang->krait_power_vregs_lock);
Abhijeet Dharmapurikar295c4dc2013-01-08 12:59:01 -08001028 the_gang->pmic_min_uV_for_retention
1029 = min(the_gang->pmic_min_uV_for_retention,
1030 kvreg->retention_uV + kvreg->headroom_uV);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001031 list_add_tail(&kvreg->link, &the_gang->krait_power_vregs);
1032 mutex_unlock(&the_gang->krait_power_vregs_lock);
1033
1034 kvreg->rdev = regulator_register(&kvreg->desc, &pdev->dev, init_data,
1035 kvreg, pdev->dev.of_node);
1036 if (IS_ERR(kvreg->rdev)) {
1037 rc = PTR_ERR(kvreg->rdev);
1038 pr_err("regulator_register failed, rc=%d.\n", rc);
1039 goto out;
1040 }
1041
Abhijeet Dharmapurikar152a7082012-05-14 20:25:59 -07001042 kvreg_hw_init(kvreg);
Abhijeet Dharmapurikare8f83852013-02-06 18:57:17 -08001043 per_cpu(krait_vregs, cpu_num) = kvreg;
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001044 dev_dbg(&pdev->dev, "id=%d, name=%s\n", pdev->id, kvreg->name);
1045
1046 return 0;
1047out:
1048 mutex_lock(&the_gang->krait_power_vregs_lock);
1049 list_del(&kvreg->link);
1050 mutex_unlock(&the_gang->krait_power_vregs_lock);
1051
1052 platform_set_drvdata(pdev, NULL);
1053 return rc;
1054}
1055
1056static int __devexit krait_power_remove(struct platform_device *pdev)
1057{
1058 struct krait_power_vreg *kvreg = platform_get_drvdata(pdev);
1059 struct pmic_gang_vreg *pvreg = kvreg->pvreg;
1060
1061 mutex_lock(&pvreg->krait_power_vregs_lock);
1062 list_del(&kvreg->link);
1063 mutex_unlock(&pvreg->krait_power_vregs_lock);
1064
1065 regulator_unregister(kvreg->rdev);
1066 platform_set_drvdata(pdev, NULL);
1067 return 0;
1068}
1069
1070static struct of_device_id krait_power_match_table[] = {
1071 { .compatible = "qcom,krait-regulator", },
1072 {}
1073};
1074
1075static struct platform_driver krait_power_driver = {
1076 .probe = krait_power_probe,
1077 .remove = __devexit_p(krait_power_remove),
1078 .driver = {
1079 .name = KRAIT_REGULATOR_DRIVER_NAME,
1080 .of_match_table = krait_power_match_table,
1081 .owner = THIS_MODULE,
1082 },
1083};
1084
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001085static struct of_device_id krait_pdn_match_table[] = {
1086 { .compatible = "qcom,krait-pdn", },
1087 {}
1088};
1089
Abhijeet Dharmapurikarc8605a62013-03-11 21:24:25 -07001090static int boot_cpu_mdd_off(void)
1091{
1092 struct krait_power_vreg *kvreg = per_cpu(krait_vregs, 0);
1093
1094 __krait_power_mdd_enable(kvreg, false);
1095 return 0;
1096}
1097
1098static void boot_cpu_mdd_on(void)
1099{
1100 struct krait_power_vreg *kvreg = per_cpu(krait_vregs, 0);
1101
1102 __krait_power_mdd_enable(kvreg, true);
1103}
1104
1105static struct syscore_ops boot_cpu_mdd_ops = {
1106 .suspend = boot_cpu_mdd_off,
1107 .resume = boot_cpu_mdd_on,
1108};
1109
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001110static int __devinit krait_pdn_probe(struct platform_device *pdev)
1111{
1112 int rc;
1113 bool use_phase_switching = false;
1114 struct device *dev = &pdev->dev;
1115 struct device_node *node = dev->of_node;
1116 struct pmic_gang_vreg *pvreg;
Stepan Moskovchenko7663b782013-03-08 20:13:06 -08001117 struct resource *res;
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001118
1119 if (!dev->of_node) {
1120 dev_err(dev, "device tree information missing\n");
1121 return -ENODEV;
1122 }
1123
1124 use_phase_switching = of_property_read_bool(node,
1125 "qcom,use-phase-switching");
1126 pvreg = devm_kzalloc(&pdev->dev,
1127 sizeof(struct pmic_gang_vreg), GFP_KERNEL);
1128 if (!pvreg) {
1129 pr_err("kzalloc failed.\n");
1130 return 0;
1131 }
1132
Stepan Moskovchenko7663b782013-03-08 20:13:06 -08001133 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apcs_gcc");
1134 if (!res) {
1135 dev_err(&pdev->dev, "missing apcs gcc base addresses\n");
1136 return -EINVAL;
1137 }
1138
1139 pvreg->apcs_gcc_base = devm_ioremap(&pdev->dev, res->start,
1140 resource_size(res));
1141
1142 if (pvreg->apcs_gcc_base == NULL)
1143 return -ENOMEM;
1144
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001145 pvreg->name = "pmic_gang";
1146 pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
1147 pvreg->pmic_phase_count = -EINVAL;
1148 pvreg->retention_enabled = true;
1149 pvreg->pmic_min_uV_for_retention = INT_MAX;
1150 pvreg->use_phase_switching = use_phase_switching;
1151
1152 mutex_init(&pvreg->krait_power_vregs_lock);
1153 INIT_LIST_HEAD(&pvreg->krait_power_vregs);
1154 the_gang = pvreg;
1155
1156 pr_debug("name=%s inited\n", pvreg->name);
1157
1158 /* global initializtion */
Stepan Moskovchenko7663b782013-03-08 20:13:06 -08001159 glb_init(pvreg->apcs_gcc_base);
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001160
1161 rc = of_platform_populate(node, NULL, NULL, dev);
1162 if (rc) {
1163 dev_err(dev, "failed to add child nodes, rc=%d\n", rc);
1164 return rc;
1165 }
1166
1167 dent = debugfs_create_dir(KRAIT_REGULATOR_DRIVER_NAME, NULL);
1168 debugfs_create_file("retention_uV",
1169 0644, dent, the_gang, &retention_fops);
Abhijeet Dharmapurikarc8605a62013-03-11 21:24:25 -07001170 register_syscore_ops(&boot_cpu_mdd_ops);
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001171 return 0;
1172}
1173
1174static int __devexit krait_pdn_remove(struct platform_device *pdev)
1175{
1176 the_gang = NULL;
1177 debugfs_remove_recursive(dent);
1178 return 0;
1179}
1180
1181static struct platform_driver krait_pdn_driver = {
1182 .probe = krait_pdn_probe,
1183 .remove = __devexit_p(krait_pdn_remove),
1184 .driver = {
1185 .name = KRAIT_PDN_DRIVER_NAME,
1186 .of_match_table = krait_pdn_match_table,
1187 .owner = THIS_MODULE,
1188 },
1189};
1190
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001191int __init krait_power_init(void)
1192{
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001193 int rc = platform_driver_register(&krait_power_driver);
1194 if (rc) {
1195 pr_err("failed to add %s driver rc = %d\n",
1196 KRAIT_REGULATOR_DRIVER_NAME, rc);
1197 return rc;
1198 }
1199 return platform_driver_register(&krait_pdn_driver);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001200}
1201
1202static void __exit krait_power_exit(void)
1203{
1204 platform_driver_unregister(&krait_power_driver);
Abhijeet Dharmapurikar46a7ad32013-02-23 12:50:19 -08001205 platform_driver_unregister(&krait_pdn_driver);
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001206}
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001207module_exit(krait_power_exit);
1208
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001209void secondary_cpu_hs_init(void *base_ptr)
1210{
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001211 /* Turn on the BHS, turn off LDO Bypass and power down LDO */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001212 writel_relaxed(
1213 BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
1214 | LDO_PWR_DWN_MASK
1215 | CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
1216 | BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
1217 | BHS_EN_MASK,
1218 base_ptr + APC_PWR_GATE_CTL);
1219
1220 /* complete the above write before the delay */
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001221 mb();
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001222
1223 /*
1224 * wait for the bhs to settle
1225 */
1226 udelay(BHS_SETTLING_DELAY_US);
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001227
1228 /* Finally turn on the bypass so that BHS supplies power */
Abhijeet Dharmapurikar749ecd42012-11-08 17:29:04 -08001229 writel_relaxed(
1230 BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
1231 | LDO_PWR_DWN_MASK
1232 | CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
1233 | LDO_BYP_MASK
1234 | BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
1235 | BHS_EN_MASK,
1236 base_ptr + APC_PWR_GATE_CTL);
Abhijeet Dharmapurikare8571ef2012-08-14 20:44:58 -07001237}
1238
Abhijeet Dharmapurikar00269e52012-05-14 17:59:10 -07001239MODULE_LICENSE("GPL v2");
1240MODULE_DESCRIPTION("KRAIT POWER regulator driver");
1241MODULE_VERSION("1.0");
1242MODULE_ALIAS("platform:"KRAIT_REGULATOR_DRIVER_NAME);