]> nv-tegra.nvidia Code Review - linux-3.10.git/blob - arch/arm/mach-tegra/powerdetect.c
arm: tegra: user interface for voltage limiting
[linux-3.10.git] / arch / arm / mach-tegra / powerdetect.c
1 /*
2  * arch/arm/mach-tegra/powerdetect.c
3  *
4  * Copyright (c) 2011, NVIDIA Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19
20 #include <linux/kernel.h>
21 #include <linux/delay.h>
22 #include <linux/spinlock.h>
23 #include <linux/io.h>
24 #include <linux/err.h>
25 #include <linux/notifier.h>
26 #include <linux/regulator/consumer.h>
27 #include <linux/module.h>
28
29 #include "board.h"
30 #include "fuse.h"
31 #include "iomap.h"
32
33 #define PMC_PWR_IO_DISABLE      0x44
34 #define PMC_PWR_DET_ENABLE      0x48
35 #define PMC_PWR_DET_LATCH       0x4C
36 #define PMC_PWR_DET_VAL         0xE4
37
38 struct pwr_detect_cell {
39         const char              *reg_id;
40         u32                     pwrdet_mask;
41         u32                     pwrio_mask;
42         u32                     package_mask;
43
44         struct notifier_block   regulator_nb;
45 };
46
47 static bool pwrdet_rails_found;
48 static bool pwrdet_always_on;
49 static bool pwrio_always_on;
50 static u32 pwrdet_val;
51 static u32 pwrio_val;
52 static u32 pwrio_disabled_mask;
53
54 static DEFINE_SPINLOCK(pwr_lock);
55
56 static void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
57
58 static inline void pmc_writel(u32 val, unsigned long addr)
59 {
60         writel(val, pmc_base + addr);
61 }
62 static inline u32 pmc_readl(unsigned long addr)
63 {
64         return readl(pmc_base + addr);
65 }
66
67
68 #define POWER_CELL(_reg_id, _pwrdet_mask, _pwrio_mask, _package_mask)   \
69         {                                                               \
70                 .reg_id = _reg_id,                                      \
71                 .pwrdet_mask = _pwrdet_mask,                            \
72                 .pwrio_mask = _pwrio_mask,                              \
73                 .package_mask = _package_mask,                          \
74         }
75
76 /* Some IO pads does not have power detect cells, but still can/should be
77  * turned off when no power - set pwrdet_mask=0 for such pads */
78 static struct pwr_detect_cell pwr_detect_cells[] = {
79         POWER_CELL("pwrdet_nand",       (0x1 <<  1), (0x1 <<  1), 0xFFFFFFFF),
80         POWER_CELL("pwrdet_uart",       (0x1 <<  2), (0x1 <<  2), 0xFFFFFFFF),
81         POWER_CELL("pwrdet_bb",         (0x1 <<  3), (0x1 <<  3), 0xFFFFFFFF),
82 #ifdef  CONFIG_ARCH_TEGRA_2x_SOC
83         POWER_CELL("pwrdet_vi",                   0, (0x1 <<  4), 0xFFFFFFFF),
84 #else
85         /* Tegra3 VI is connected on MID package only (id = 1, mask = 0x2) */
86         POWER_CELL("pwrdet_vi",                   0, (0x1 <<  4), 0x00000002),
87 #endif
88         POWER_CELL("pwrdet_audio",      (0x1 <<  5), (0x1 <<  5), 0xFFFFFFFF),
89 #if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
90         POWER_CELL("pwrdet_lcd",        (0x1 <<  6), (0x1 <<  6), 0xFFFFFFFF),
91 #endif
92 #ifdef  CONFIG_ARCH_TEGRA_2x_SOC
93         POWER_CELL("pwrdet_sd",                   0, (0x1 <<  8), 0xFFFFFFFF),
94 #endif
95         POWER_CELL("pwrdet_mipi",                 0, (0x1 <<  9), 0xFFFFFFFF),
96 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
97         POWER_CELL("pwrdet_cam",        (0x1 << 10), (0x1 << 10), 0xFFFFFFFF),
98 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
99         POWER_CELL("pwrdet_pex_ctl",    (0x1 << 11), (0x1 << 11), 0xFFFFFFFF),
100 #endif
101         POWER_CELL("pwrdet_sdmmc1",     (0x1 << 12), (0x1 << 12), 0xFFFFFFFF),
102         POWER_CELL("pwrdet_sdmmc3",     (0x1 << 13), (0x1 << 13), 0xFFFFFFFF),
103         POWER_CELL("pwrdet_sdmmc4",               0, (0x1 << 14), 0xFFFFFFFF),
104 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
105         POWER_CELL("pwrdet_hv",         (0x1 << 15), (0x1 << 15), 0xFFFFFFFF),
106 #endif
107 #endif
108 };
109
110 static void pwr_detect_reset(u32 pwrdet_mask)
111 {
112         pmc_writel(pwrdet_mask, PMC_PWR_DET_ENABLE);
113         barrier();
114         pmc_writel(pwrdet_mask, PMC_PWR_DET_VAL);
115
116         pmc_readl(PMC_PWR_DET_VAL);
117         pmc_writel(0, PMC_PWR_DET_ENABLE);
118 }
119
120 static void pwr_detect_start(u32 pwrdet_mask)
121 {
122         pmc_writel(pwrdet_mask, PMC_PWR_DET_ENABLE);
123         udelay(4);
124
125         pmc_writel(1, PMC_PWR_DET_LATCH);
126         pmc_readl(PMC_PWR_DET_LATCH);
127 }
128
129 static void pwr_detect_latch(void)
130 {
131         pmc_writel(0, PMC_PWR_DET_LATCH);
132
133         pmc_readl(PMC_PWR_DET_VAL);
134         pmc_writel(0, PMC_PWR_DET_ENABLE);
135 }
136
137 static void pwr_io_enable(u32 pwrio_mask)
138 {
139         u32 val = pmc_readl(PMC_PWR_IO_DISABLE);
140         val &= ~pwrio_mask;
141         pmc_writel(val, PMC_PWR_IO_DISABLE);
142 }
143
144 static void pwr_io_disable(u32 pwrio_mask)
145 {
146         u32 val = pmc_readl(PMC_PWR_IO_DISABLE);
147         val |= pwrio_mask;
148         pmc_writel(val, PMC_PWR_IO_DISABLE);
149 }
150
151 static int pwrdet_always_on_set(const char *arg, const struct kernel_param *kp)
152 {
153         int ret;
154         unsigned long flags;
155
156         spin_lock_irqsave(&pwr_lock, flags);
157
158         ret = param_set_bool(arg, kp);
159         if (ret) {
160                 spin_unlock_irqrestore(&pwr_lock, flags);
161                 return ret;
162         }
163
164         if (pwrdet_always_on)
165                 pwr_detect_start(0xFFFFFFFF);
166         else
167                 pwr_detect_latch();
168
169         spin_unlock_irqrestore(&pwr_lock, flags);
170         return 0;
171 }
172
173 static int pwrio_always_on_set(const char *arg, const struct kernel_param *kp)
174 {
175         int ret;
176         unsigned long flags;
177
178         spin_lock_irqsave(&pwr_lock, flags);
179
180         ret = param_set_bool(arg, kp);
181         if (ret) {
182                 spin_unlock_irqrestore(&pwr_lock, flags);
183                 return ret;
184         }
185
186         if (pwrio_always_on)
187                 pwr_io_enable(0xFFFFFFFF);
188         else
189                 pwr_io_disable(pwrio_disabled_mask);
190
191         spin_unlock_irqrestore(&pwr_lock, flags);
192         return 0;
193 }
194
195 static int pwrdet_always_on_get(char *buffer, const struct kernel_param *kp)
196 {
197         return param_get_bool(buffer, kp);
198 }
199
200 static struct kernel_param_ops pwrdet_always_on_ops = {
201         .set = pwrdet_always_on_set,
202         .get = pwrdet_always_on_get,
203 };
204 static struct kernel_param_ops pwrio_always_on_ops = {
205         .set = pwrio_always_on_set,
206         .get = pwrdet_always_on_get,
207 };
208 module_param_cb(pwrdet_always_on, &pwrdet_always_on_ops,
209         &pwrdet_always_on, 0644);
210 module_param_cb(pwrio_always_on, &pwrio_always_on_ops,
211         &pwrio_always_on, 0644);
212
213 static int pwrdet_val_get(char *buffer, const struct kernel_param *kp)
214 {
215         pwrdet_val = pmc_readl(PMC_PWR_DET_VAL);
216         return param_get_ulong(buffer, kp);
217 }
218 static struct kernel_param_ops pwrdet_val_ops = {
219         .get = pwrdet_val_get,
220 };
221 module_param_cb(pwrdet_val, &pwrdet_val_ops, &pwrdet_val, 0444);
222
223 static int pwrio_val_get(char *buffer, const struct kernel_param *kp)
224 {
225         pwrio_val = pmc_readl(PMC_PWR_IO_DISABLE);
226         return param_get_ulong(buffer, kp);
227 }
228 static struct kernel_param_ops pwrio_val_ops = {
229         .get = pwrio_val_get,
230 };
231 module_param_cb(pwrio_val, &pwrio_val_ops, &pwrio_val, 0444);
232
233
234 static int pwrdet_notify_cb(
235         struct notifier_block *nb, unsigned long event, void *v)
236 {
237         unsigned long flags;
238         struct pwr_detect_cell *cell;
239
240         if (!pwrdet_rails_found)
241                 return NOTIFY_OK;
242
243         cell = container_of(nb, struct pwr_detect_cell, regulator_nb);
244
245         spin_lock_irqsave(&pwr_lock, flags);
246
247         if (event & REGULATOR_EVENT_PRE_ENABLE) {
248                 pwrio_disabled_mask &= ~cell->pwrio_mask;
249                 if (!pwrio_always_on)
250                         pwr_io_enable(cell->pwrio_mask);
251         }
252         if (event & (REGULATOR_EVENT_PRE_ENABLE |
253                      REGULATOR_EVENT_OUT_PRECHANGE)) {
254                 if (!pwrdet_always_on && cell->pwrdet_mask)
255                         pwr_detect_reset(cell->pwrdet_mask);
256         }
257         if (event & (REGULATOR_EVENT_POST_ENABLE |
258                      REGULATOR_EVENT_OUT_POSTCHANGE)) {
259                 if (!pwrdet_always_on && cell->pwrdet_mask) {
260                         pwr_detect_start(cell->pwrdet_mask);
261                         pwr_detect_latch();
262                 }
263         }
264         if (event & (REGULATOR_EVENT_DISABLE |
265                      REGULATOR_EVENT_FORCE_DISABLE)) {
266                 pwrio_disabled_mask |= cell->pwrio_mask;
267                 if (!pwrio_always_on)
268                         pwr_io_disable(cell->pwrio_mask);
269         }
270
271         pr_debug("tegra: %s: event %lu, pwrdet 0x%x, pwrio 0x%x\n",
272                 cell->reg_id, event,
273                 pmc_readl(PMC_PWR_DET_VAL), pmc_readl(PMC_PWR_IO_DISABLE));
274         spin_unlock_irqrestore(&pwr_lock, flags);
275
276         return NOTIFY_OK;
277 }
278
279 static int __init pwr_detect_cell_init_one(
280         struct pwr_detect_cell *cell, u32 *disabled_mask)
281 {
282         int ret;
283         struct regulator *regulator = regulator_get(NULL, cell->reg_id);
284
285         if (IS_ERR(regulator))
286                 return PTR_ERR(regulator);
287
288         cell->regulator_nb.notifier_call = pwrdet_notify_cb;
289         ret = regulator_register_notifier(regulator, &cell->regulator_nb);
290         if (ret) {
291                 regulator_put(regulator);
292                 return ret;
293         }
294
295         if (!regulator_is_enabled(regulator))
296                 *disabled_mask |= cell->pwrio_mask;
297
298         regulator_put(regulator);
299         return 0;
300 }
301
302 int __init tegra_pwr_detect_cell_init(void)
303 {
304         int i, ret;
305         u32 package_mask;
306         unsigned long flags;
307         bool rails_found = true;
308
309         i = tegra_package_id();
310         if ((i != -1) && (i & (~0x1F))) {
311                 pr_err("tegra: not supported package id %d - io power detection"
312                        " is left always on\n", i);
313                 return 0;
314         }
315         package_mask = (i == -1) ? i : (0x1 << i);
316
317         for (i = 0; i < ARRAY_SIZE(pwr_detect_cells); i++) {
318                 struct pwr_detect_cell *cell = &pwr_detect_cells[i];
319
320                 if (!(cell->package_mask & package_mask)) {
321                         pwrio_disabled_mask |= cell->pwrio_mask;
322                         continue;
323                 }
324
325                 ret = pwr_detect_cell_init_one(cell, &pwrio_disabled_mask);
326                 if (ret) {
327                         pr_err("tegra: failed to map regulator to power detect"
328                                " cell %s(%d)\n", cell->reg_id, ret);
329                         rails_found = false;
330                 }
331         }
332
333         if (!rails_found) {
334                 pr_err("tegra: failed regulators mapping - io power detection"
335                        " is left always on\n");
336                 return 0;
337         }
338         pwrdet_rails_found = true;
339
340         /* Latch initial i/o power levels, disable all detection cells
341            and not powered interfaces */
342         spin_lock_irqsave(&pwr_lock, flags);
343         if (!pwrdet_always_on)
344                 pwr_detect_latch();
345         if (!pwrio_always_on)
346                 pwr_io_disable(pwrio_disabled_mask);
347         spin_unlock_irqrestore(&pwr_lock, flags);
348
349         pr_info("tegra: started io power detection dynamic control\n");
350         pr_info("tegra: NO_IO_POWER setting 0x%x\n", pwrio_disabled_mask);
351
352         return 0;
353 }
354
355 fs_initcall(tegra_pwr_detect_cell_init);