blob: 0aa9677ce7fd80055d525a62f456b753b350bf99 [file] [log] [blame]
Sameer Thalappilf106a682013-02-16 20:41:11 -08001/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
Sameer Thalappil8d686d42012-08-24 10:07:31 -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#include <linux/module.h>
13#include <linux/slab.h>
14#include <linux/err.h>
15#include <linux/io.h>
16#include <linux/gpio.h>
17#include <linux/delay.h>
18#include <linux/regulator/consumer.h>
19#include <linux/mfd/pm8xxx/pm8921.h>
20#include <linux/mfd/pm8xxx/gpio.h>
21#include <linux/wcnss_wlan.h>
22#include <linux/semaphore.h>
23#include <linux/list.h>
24#include <linux/slab.h>
25#include <linux/clk.h>
26#include <mach/msm_xo.h>
27#include <mach/msm_iomap.h>
28
29
30static void __iomem *msm_wcnss_base;
31static struct msm_xo_voter *wlan_clock;
32static const char *id = "WLAN";
33static LIST_HEAD(power_on_lock_list);
34static DEFINE_MUTEX(list_lock);
35static DEFINE_SEMAPHORE(wcnss_power_on_lock);
36
37#define MSM_RIVA_PHYS 0x03204000
38#define MSM_PRONTO_PHYS 0xfb21b000
39
40#define RIVA_PMU_OFFSET 0x28
41#define PRONTO_PMU_OFFSET 0x1004
42
Sameer Thalappilf106a682013-02-16 20:41:11 -080043#define RIVA_SPARE_OFFSET 0x0b4
44#define PRONTO_SPARE_OFFSET 0x1088
45#define NVBIN_DLND_BIT BIT(25)
46
Sameer Thalappil8d686d42012-08-24 10:07:31 -070047#define WCNSS_PMU_CFG_IRIS_XO_CFG BIT(3)
48#define WCNSS_PMU_CFG_IRIS_XO_EN BIT(4)
49#define WCNSS_PMU_CFG_GC_BUS_MUX_SEL_TOP BIT(5)
50#define WCNSS_PMU_CFG_IRIS_XO_CFG_STS BIT(6) /* 1: in progress, 0: done */
51
52#define WCNSS_PMU_CFG_IRIS_XO_MODE 0x6
53#define WCNSS_PMU_CFG_IRIS_XO_MODE_48 (3 << 1)
54
55#define VREG_NULL_CONFIG 0x0000
56#define VREG_GET_REGULATOR_MASK 0x0001
57#define VREG_SET_VOLTAGE_MASK 0x0002
58#define VREG_OPTIMUM_MODE_MASK 0x0004
59#define VREG_ENABLE_MASK 0x0008
60
61struct vregs_info {
62 const char * const name;
63 int state;
64 const int nominal_min;
65 const int low_power_min;
66 const int max_voltage;
67 const int uA_load;
68 struct regulator *regulator;
69};
70
71/* IRIS regulators for Riva hardware */
72static struct vregs_info iris_vregs_riva[] = {
73 {"iris_vddxo", VREG_NULL_CONFIG, 1800000, 0, 1800000, 10000, NULL},
74 {"iris_vddrfa", VREG_NULL_CONFIG, 1300000, 0, 1300000, 100000, NULL},
75 {"iris_vddpa", VREG_NULL_CONFIG, 2900000, 0, 3000000, 515000, NULL},
76 {"iris_vdddig", VREG_NULL_CONFIG, 1200000, 0, 1225000, 10000, NULL},
77};
78
79/* WCNSS regulators for Riva hardware */
80static struct vregs_info riva_vregs[] = {
81 /* Riva */
82 {"riva_vddmx", VREG_NULL_CONFIG, 1050000, 0, 1150000, 0, NULL},
83 {"riva_vddcx", VREG_NULL_CONFIG, 1050000, 0, 1150000, 0, NULL},
84 {"riva_vddpx", VREG_NULL_CONFIG, 1800000, 0, 1800000, 0, NULL},
85};
86
87/* IRIS regulators for Pronto hardware */
88static struct vregs_info iris_vregs_pronto[] = {
89 {"qcom,iris-vddxo", VREG_NULL_CONFIG, 1800000, 0,
90 1800000, 10000, NULL},
91 {"qcom,iris-vddrfa", VREG_NULL_CONFIG, 1300000, 0,
92 1300000, 100000, NULL},
93 {"qcom,iris-vddpa", VREG_NULL_CONFIG, 2900000, 0,
94 3000000, 515000, NULL},
95 {"qcom,iris-vdddig", VREG_NULL_CONFIG, 1225000, 0,
96 1225000, 10000, NULL},
97};
98
99/* WCNSS regulators for Pronto hardware */
100static struct vregs_info pronto_vregs[] = {
101 {"qcom,pronto-vddmx", VREG_NULL_CONFIG, 950000, 0,
102 1150000, 0, NULL},
103 {"qcom,pronto-vddcx", VREG_NULL_CONFIG, 900000, 0,
104 1150000, 0, NULL},
105 {"qcom,pronto-vddpx", VREG_NULL_CONFIG, 1800000, 0,
106 1800000, 0, NULL},
107};
108
109
110struct host_driver {
111 char name[20];
112 struct list_head list;
113};
114
115
116static int configure_iris_xo(struct device *dev, bool use_48mhz_xo, int on)
117{
118 u32 reg = 0;
119 int rc = 0;
120 int size = 0;
121 int pmu_offset = 0;
Sameer Thalappilf106a682013-02-16 20:41:11 -0800122 int spare_offset = 0;
Sameer Thalappil8d686d42012-08-24 10:07:31 -0700123 unsigned long wcnss_phys_addr;
124 void __iomem *pmu_conf_reg;
Sameer Thalappilf106a682013-02-16 20:41:11 -0800125 void __iomem *spare_reg;
Sameer Thalappil8d686d42012-08-24 10:07:31 -0700126 struct clk *clk;
127
128 if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
129 wcnss_phys_addr = MSM_PRONTO_PHYS;
130 pmu_offset = PRONTO_PMU_OFFSET;
Sameer Thalappilf106a682013-02-16 20:41:11 -0800131 spare_offset = PRONTO_SPARE_OFFSET;
Sameer Thalappil8d686d42012-08-24 10:07:31 -0700132 size = 0x3000;
133
134 clk = clk_get(dev, "xo");
135 if (IS_ERR(clk)) {
136 pr_err("Couldn't get xo clock\n");
137 return PTR_ERR(clk);
138 }
139 } else {
140 wcnss_phys_addr = MSM_RIVA_PHYS;
141 pmu_offset = RIVA_PMU_OFFSET;
Sameer Thalappilf106a682013-02-16 20:41:11 -0800142 spare_offset = RIVA_SPARE_OFFSET;
Sameer Thalappil8d686d42012-08-24 10:07:31 -0700143 size = SZ_256;
144
145 clk = clk_get(dev, "cxo");
146 if (IS_ERR(clk)) {
147 pr_err("Couldn't get cxo clock\n");
148 return PTR_ERR(clk);
149 }
150 }
151
152 if (on) {
153 msm_wcnss_base = ioremap(wcnss_phys_addr, size);
154 if (!msm_wcnss_base) {
155 pr_err("ioremap wcnss physical failed\n");
156 goto fail;
157 }
Sameer Thalappilf106a682013-02-16 20:41:11 -0800158
Sameer Thalappile7d58e92013-03-06 14:45:58 -0800159 /* Enable IRIS XO */
160 rc = clk_prepare_enable(clk);
161 if (rc) {
162 pr_err("clk enable failed\n");
163 goto fail;
164 }
165 /* NV bit is set to indicate that platform driver is capable
166 * of doing NV download. SSR should not set NV bit; during
167 * SSR NV bin is downloaded by WLAN driver.
Sameer Thalappilcf566bb2013-02-26 17:10:25 -0800168 */
169 if (!wcnss_cold_boot_done()) {
170 pr_debug("wcnss: Indicate NV bin download\n");
171 spare_reg = msm_wcnss_base + spare_offset;
172 reg = readl_relaxed(spare_reg);
173 reg |= NVBIN_DLND_BIT;
174 writel_relaxed(reg, spare_reg);
175 }
Sameer Thalappilf106a682013-02-16 20:41:11 -0800176
Sameer Thalappil8d686d42012-08-24 10:07:31 -0700177 pmu_conf_reg = msm_wcnss_base + pmu_offset;
Sameer Thalappil8d686d42012-08-24 10:07:31 -0700178 writel_relaxed(0, pmu_conf_reg);
179 reg = readl_relaxed(pmu_conf_reg);
180 reg |= WCNSS_PMU_CFG_GC_BUS_MUX_SEL_TOP |
181 WCNSS_PMU_CFG_IRIS_XO_EN;
182 writel_relaxed(reg, pmu_conf_reg);
183
184 /* Clear XO_MODE[b2:b1] bits. Clear implies 19.2 MHz TCXO */
185 reg &= ~(WCNSS_PMU_CFG_IRIS_XO_MODE);
186
187 if (use_48mhz_xo)
188 reg |= WCNSS_PMU_CFG_IRIS_XO_MODE_48;
189
190 writel_relaxed(reg, pmu_conf_reg);
191
192 /* Start IRIS XO configuration */
193 reg |= WCNSS_PMU_CFG_IRIS_XO_CFG;
194 writel_relaxed(reg, pmu_conf_reg);
195
196 /* Wait for XO configuration to finish */
197 while (readl_relaxed(pmu_conf_reg) &
198 WCNSS_PMU_CFG_IRIS_XO_CFG_STS)
199 cpu_relax();
200
201 /* Stop IRIS XO configuration */
202 reg &= ~(WCNSS_PMU_CFG_GC_BUS_MUX_SEL_TOP |
203 WCNSS_PMU_CFG_IRIS_XO_CFG);
204 writel_relaxed(reg, pmu_conf_reg);
205 clk_disable_unprepare(clk);
206
207 if (!use_48mhz_xo) {
208 wlan_clock = msm_xo_get(MSM_XO_TCXO_A2, id);
209 if (IS_ERR(wlan_clock)) {
210 rc = PTR_ERR(wlan_clock);
211 pr_err("Failed to get MSM_XO_TCXO_A2 voter (%d)\n",
212 rc);
213 goto fail;
214 }
215
216 rc = msm_xo_mode_vote(wlan_clock, MSM_XO_MODE_ON);
217 if (rc < 0) {
218 pr_err("Configuring MSM_XO_MODE_ON failed (%d)\n",
219 rc);
220 goto msm_xo_vote_fail;
221 }
222 }
223 } else {
224 if (wlan_clock != NULL && !use_48mhz_xo) {
225 rc = msm_xo_mode_vote(wlan_clock, MSM_XO_MODE_OFF);
226 if (rc < 0)
227 pr_err("Configuring MSM_XO_MODE_OFF failed (%d)\n",
228 rc);
229 }
230 }
231
232 /* Add some delay for XO to settle */
233 msleep(20);
234
235 clk_put(clk);
236 return rc;
237
238msm_xo_vote_fail:
239 msm_xo_put(wlan_clock);
240
241fail:
242 clk_put(clk);
243 return rc;
244}
245
246/* Helper routine to turn off all WCNSS & IRIS vregs */
247static void wcnss_vregs_off(struct vregs_info regulators[], uint size)
248{
249 int i, rc = 0;
250
251 /* Regulators need to be turned off in the reverse order */
252 for (i = (size-1); i >= 0; i--) {
253 if (regulators[i].state == VREG_NULL_CONFIG)
254 continue;
255
256 /* Remove PWM mode */
257 if (regulators[i].state & VREG_OPTIMUM_MODE_MASK) {
258 rc = regulator_set_optimum_mode(
259 regulators[i].regulator, 0);
260 if (rc < 0)
261 pr_err("regulator_set_optimum_mode(%s) failed (%d)\n",
262 regulators[i].name, rc);
263 }
264
265 /* Set voltage to lowest level */
266 if (regulators[i].state & VREG_SET_VOLTAGE_MASK) {
267 rc = regulator_set_voltage(regulators[i].regulator,
268 regulators[i].low_power_min,
269 regulators[i].max_voltage);
270 if (rc)
271 pr_err("regulator_set_voltage(%s) failed (%d)\n",
272 regulators[i].name, rc);
273 }
274
275 /* Disable regulator */
276 if (regulators[i].state & VREG_ENABLE_MASK) {
277 rc = regulator_disable(regulators[i].regulator);
278 if (rc < 0)
279 pr_err("vreg %s disable failed (%d)\n",
280 regulators[i].name, rc);
281 }
282
283 /* Free the regulator source */
284 if (regulators[i].state & VREG_GET_REGULATOR_MASK)
285 regulator_put(regulators[i].regulator);
286
287 regulators[i].state = VREG_NULL_CONFIG;
288 }
289}
290
291/* Common helper routine to turn on all WCNSS & IRIS vregs */
292static int wcnss_vregs_on(struct device *dev,
293 struct vregs_info regulators[], uint size)
294{
295 int i, rc = 0, reg_cnt;
296
297 for (i = 0; i < size; i++) {
298 /* Get regulator source */
299 regulators[i].regulator =
300 regulator_get(dev, regulators[i].name);
301 if (IS_ERR(regulators[i].regulator)) {
302 rc = PTR_ERR(regulators[i].regulator);
303 pr_err("regulator get of %s failed (%d)\n",
304 regulators[i].name, rc);
305 goto fail;
306 }
307 regulators[i].state |= VREG_GET_REGULATOR_MASK;
308 reg_cnt = regulator_count_voltages(regulators[i].regulator);
309 /* Set voltage to nominal. Exclude swtiches e.g. LVS */
310 if ((regulators[i].nominal_min || regulators[i].max_voltage)
311 && (reg_cnt > 0)) {
312 rc = regulator_set_voltage(regulators[i].regulator,
313 regulators[i].nominal_min,
314 regulators[i].max_voltage);
315 if (rc) {
316 pr_err("regulator_set_voltage(%s) failed (%d)\n",
317 regulators[i].name, rc);
318 goto fail;
319 }
320 regulators[i].state |= VREG_SET_VOLTAGE_MASK;
321 }
322
323 /* Vote for PWM/PFM mode if needed */
324 if (regulators[i].uA_load && (reg_cnt > 0)) {
325 rc = regulator_set_optimum_mode(regulators[i].regulator,
326 regulators[i].uA_load);
327 if (rc < 0) {
328 pr_err("regulator_set_optimum_mode(%s) failed (%d)\n",
329 regulators[i].name, rc);
330 goto fail;
331 }
332 regulators[i].state |= VREG_OPTIMUM_MODE_MASK;
333 }
334
335 /* Enable the regulator */
336 rc = regulator_enable(regulators[i].regulator);
337 if (rc) {
338 pr_err("vreg %s enable failed (%d)\n",
339 regulators[i].name, rc);
340 goto fail;
341 }
342 regulators[i].state |= VREG_ENABLE_MASK;
343 }
344
345 return rc;
346
347fail:
348 wcnss_vregs_off(regulators, size);
349 return rc;
350
351}
352
353static void wcnss_iris_vregs_off(enum wcnss_hw_type hw_type)
354{
355 switch (hw_type) {
356 case WCNSS_RIVA_HW:
357 wcnss_vregs_off(iris_vregs_riva, ARRAY_SIZE(iris_vregs_riva));
358 break;
359 case WCNSS_PRONTO_HW:
360 wcnss_vregs_off(iris_vregs_pronto,
361 ARRAY_SIZE(iris_vregs_pronto));
362 break;
363 default:
364 pr_err("%s invalid hardware %d\n", __func__, hw_type);
365
366 }
367}
368
369static int wcnss_iris_vregs_on(struct device *dev, enum wcnss_hw_type hw_type)
370{
371 int ret = -1;
372
373 switch (hw_type) {
374 case WCNSS_RIVA_HW:
375 ret = wcnss_vregs_on(dev, iris_vregs_riva,
376 ARRAY_SIZE(iris_vregs_riva));
377 break;
378 case WCNSS_PRONTO_HW:
379 ret = wcnss_vregs_on(dev, iris_vregs_pronto,
380 ARRAY_SIZE(iris_vregs_pronto));
381 break;
382 default:
383 pr_err("%s invalid hardware %d\n", __func__, hw_type);
384 }
385 return ret;
386}
387
388static void wcnss_core_vregs_off(enum wcnss_hw_type hw_type)
389{
390 switch (hw_type) {
391 case WCNSS_RIVA_HW:
392 wcnss_vregs_off(riva_vregs, ARRAY_SIZE(riva_vregs));
393 break;
394 case WCNSS_PRONTO_HW:
395 wcnss_vregs_off(pronto_vregs, ARRAY_SIZE(pronto_vregs));
396 break;
397 default:
398 pr_err("%s invalid hardware %d\n", __func__, hw_type);
399 }
400
401}
402
403static int wcnss_core_vregs_on(struct device *dev, enum wcnss_hw_type hw_type)
404{
405 int ret = -1;
406
407 switch (hw_type) {
408 case WCNSS_RIVA_HW:
409 ret = wcnss_vregs_on(dev, riva_vregs, ARRAY_SIZE(riva_vregs));
410 break;
411 case WCNSS_PRONTO_HW:
412 ret = wcnss_vregs_on(dev, pronto_vregs,
413 ARRAY_SIZE(pronto_vregs));
414 break;
415 default:
416 pr_err("%s invalid hardware %d\n", __func__, hw_type);
417 }
418
419 return ret;
420
421}
422
423int wcnss_wlan_power(struct device *dev,
424 struct wcnss_wlan_config *cfg,
425 enum wcnss_opcode on)
426{
427 int rc = 0;
428 enum wcnss_hw_type hw_type = wcnss_hardware_type();
429
430 if (on) {
431 down(&wcnss_power_on_lock);
432 /* RIVA regulator settings */
433 rc = wcnss_core_vregs_on(dev, hw_type);
434 if (rc)
435 goto fail_wcnss_on;
436
437 /* IRIS regulator settings */
438 rc = wcnss_iris_vregs_on(dev, hw_type);
439 if (rc)
440 goto fail_iris_on;
441
442 /* Configure IRIS XO */
443 rc = configure_iris_xo(dev, cfg->use_48mhz_xo,
444 WCNSS_WLAN_SWITCH_ON);
445 if (rc)
446 goto fail_iris_xo;
447 up(&wcnss_power_on_lock);
448
449 } else {
450 configure_iris_xo(dev, cfg->use_48mhz_xo,
451 WCNSS_WLAN_SWITCH_OFF);
452 wcnss_iris_vregs_off(hw_type);
453 wcnss_core_vregs_off(hw_type);
454 }
455
456 return rc;
457
458fail_iris_xo:
459 wcnss_iris_vregs_off(hw_type);
460
461fail_iris_on:
462 wcnss_core_vregs_off(hw_type);
463
464fail_wcnss_on:
465 up(&wcnss_power_on_lock);
466 return rc;
467}
468EXPORT_SYMBOL(wcnss_wlan_power);
469
470/*
471 * During SSR WCNSS should not be 'powered on' until all the host drivers
472 * finish their shutdown routines. Host drivers use below APIs to
473 * synchronize power-on. WCNSS will not be 'powered on' until all the
474 * requests(to lock power-on) are freed.
475 */
476int wcnss_req_power_on_lock(char *driver_name)
477{
478 struct host_driver *node;
479
480 if (!driver_name)
481 goto err;
482
483 node = kmalloc(sizeof(struct host_driver), GFP_KERNEL);
484 if (!node)
485 goto err;
486 strlcpy(node->name, driver_name, sizeof(node->name));
487
488 mutex_lock(&list_lock);
489 /* Lock when the first request is added */
490 if (list_empty(&power_on_lock_list))
491 down(&wcnss_power_on_lock);
492 list_add(&node->list, &power_on_lock_list);
493 mutex_unlock(&list_lock);
494
495 return 0;
496
497err:
498 return -EINVAL;
499}
500EXPORT_SYMBOL(wcnss_req_power_on_lock);
501
502int wcnss_free_power_on_lock(char *driver_name)
503{
504 int ret = -1;
505 struct host_driver *node;
506
507 mutex_lock(&list_lock);
508 list_for_each_entry(node, &power_on_lock_list, list) {
509 if (!strncmp(node->name, driver_name, sizeof(node->name))) {
510 list_del(&node->list);
511 kfree(node);
512 ret = 0;
513 break;
514 }
515 }
516 /* unlock when the last host driver frees the lock */
517 if (list_empty(&power_on_lock_list))
518 up(&wcnss_power_on_lock);
519 mutex_unlock(&list_lock);
520
521 return ret;
522}
523EXPORT_SYMBOL(wcnss_free_power_on_lock);