ARM: tegra: power: Add package mask to IO pad control
[linux-2.6.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
28 #include <mach/iomap.h>
29
30 #include "board.h"
31 #include "fuse.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, (u32)pmc_base + addr);
61 }
62 static inline u32 pmc_readl(unsigned long addr)
63 {
64         return readl((u32)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_3x_SOC
83         /* Tegra3 VI is connected on MID package only (id = 1, mask = 0x2) */
84         POWER_CELL("pwrdet_vi",                   0, (0x1 <<  4), 0x00000002),
85 #else
86         POWER_CELL("pwrdet_vi",                   0, (0x1 <<  4), 0xFFFFFFFF),
87 #endif
88         POWER_CELL("pwrdet_audio",      (0x1 <<  5), (0x1 <<  5), 0xFFFFFFFF),
89         POWER_CELL("pwrdet_lcd",        (0x1 <<  6), (0x1 <<  6), 0xFFFFFFFF),
90 #ifdef  CONFIG_ARCH_TEGRA_2x_SOC
91         POWER_CELL("pwrdet_sd",                   0, (0x1 <<  8), 0xFFFFFFFF),
92 #endif
93         POWER_CELL("pwrdet_mipi",                 0, (0x1 <<  9), 0xFFFFFFFF),
94 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
95         POWER_CELL("pwrdet_cam",        (0x1 << 10), (0x1 << 10), 0xFFFFFFFF),
96         POWER_CELL("pwrdet_pex_ctl",    (0x1 << 11), (0x1 << 11), 0xFFFFFFFF),
97         POWER_CELL("pwrdet_sdmmc1",     (0x1 << 12), (0x1 << 12), 0xFFFFFFFF),
98         POWER_CELL("pwrdet_sdmmc3",     (0x1 << 13), (0x1 << 13), 0xFFFFFFFF),
99         POWER_CELL("pwrdet_sdmmc4",               0, (0x1 << 14), 0xFFFFFFFF),
100 #endif
101 };
102
103 static void pwr_detect_reset(u32 pwrdet_mask)
104 {
105         pmc_writel(pwrdet_mask, PMC_PWR_DET_ENABLE);
106         barrier();
107         pmc_writel(pwrdet_mask, PMC_PWR_DET_VAL);
108
109         pmc_readl(PMC_PWR_DET_VAL);
110         pmc_writel(0, PMC_PWR_DET_ENABLE);
111 }
112
113 static void pwr_detect_start(u32 pwrdet_mask)
114 {
115         pmc_writel(pwrdet_mask, PMC_PWR_DET_ENABLE);
116         udelay(4);
117
118         pmc_writel(1, PMC_PWR_DET_LATCH);
119         pmc_readl(PMC_PWR_DET_LATCH);
120 }
121
122 static void pwr_detect_latch(void)
123 {
124         pmc_writel(0, PMC_PWR_DET_LATCH);
125
126         pmc_readl(PMC_PWR_DET_VAL);
127         pmc_writel(0, PMC_PWR_DET_ENABLE);
128 }
129
130 static void pwr_io_enable(u32 pwrio_mask)
131 {
132         u32 val = pmc_readl(PMC_PWR_IO_DISABLE);
133         val &= ~pwrio_mask;
134         pmc_writel(val, PMC_PWR_IO_DISABLE);
135 }
136
137 static void pwr_io_disable(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 int pwrdet_always_on_set(const char *arg, const struct kernel_param *kp)
145 {
146         int ret;
147         unsigned long flags;
148
149         spin_lock_irqsave(&pwr_lock, flags);
150
151         ret = param_set_bool(arg, kp);
152         if (ret) {
153                 spin_unlock_irqrestore(&pwr_lock, flags);
154                 return ret;
155         }
156
157         if (pwrdet_always_on)
158                 pwr_detect_start(0xFFFFFFFF);
159         else
160                 pwr_detect_latch();
161
162         spin_unlock_irqrestore(&pwr_lock, flags);
163         return 0;
164 }
165
166 static int pwrio_always_on_set(const char *arg, const struct kernel_param *kp)
167 {
168         int ret;
169         unsigned long flags;
170
171         spin_lock_irqsave(&pwr_lock, flags);
172
173         ret = param_set_bool(arg, kp);
174         if (ret) {
175                 spin_unlock_irqrestore(&pwr_lock, flags);
176                 return ret;
177         }
178
179         if (pwrio_always_on)
180                 pwr_io_enable(0xFFFFFFFF);
181         else
182                 pwr_io_disable(pwrio_disabled_mask);
183
184         spin_unlock_irqrestore(&pwr_lock, flags);
185         return 0;
186 }
187
188 static int pwrdet_always_on_get(char *buffer, const struct kernel_param *kp)
189 {
190         return param_get_bool(buffer, kp);
191 }
192
193 static struct kernel_param_ops pwrdet_always_on_ops = {
194         .set = pwrdet_always_on_set,
195         .get = pwrdet_always_on_get,
196 };
197 static struct kernel_param_ops pwrio_always_on_ops = {
198         .set = pwrio_always_on_set,
199         .get = pwrdet_always_on_get,
200 };
201 module_param_cb(pwrdet_always_on, &pwrdet_always_on_ops,
202         &pwrdet_always_on, 0644);
203 module_param_cb(pwrio_always_on, &pwrio_always_on_ops,
204         &pwrio_always_on, 0644);
205
206 static int pwrdet_val_get(char *buffer, const struct kernel_param *kp)
207 {
208         pwrdet_val = pmc_readl(PMC_PWR_DET_VAL);
209         return param_get_ulong(buffer, kp);
210 }
211 static struct kernel_param_ops pwrdet_val_ops = {
212         .get = pwrdet_val_get,
213 };
214 module_param_cb(pwrdet_val, &pwrdet_val_ops, &pwrdet_val, 0444);
215
216 static int pwrio_val_get(char *buffer, const struct kernel_param *kp)
217 {
218         pwrio_val = pmc_readl(PMC_PWR_IO_DISABLE);
219         return param_get_ulong(buffer, kp);
220 }
221 static struct kernel_param_ops pwrio_val_ops = {
222         .get = pwrio_val_get,
223 };
224 module_param_cb(pwrio_val, &pwrio_val_ops, &pwrio_val, 0444);
225
226
227 static int pwrdet_notify_cb(
228         struct notifier_block *nb, unsigned long event, void *v)
229 {
230         unsigned long flags;
231         struct pwr_detect_cell *cell;
232
233         if (!pwrdet_rails_found)
234                 return NOTIFY_OK;
235
236         cell = container_of(nb, struct pwr_detect_cell, regulator_nb);
237
238         spin_lock_irqsave(&pwr_lock, flags);
239
240         switch (event) {
241         case REGULATOR_EVENT_PRE_ENABLE:
242                 pwrio_disabled_mask &= ~cell->pwrio_mask;
243                 if (!pwrio_always_on)
244                         pwr_io_enable(cell->pwrio_mask);
245                 /* fall thru */
246         case REGULATOR_EVENT_OUT_PRECHANGE:
247                 if (!pwrdet_always_on && cell->pwrdet_mask)
248                         pwr_detect_reset(cell->pwrdet_mask);
249                 break;
250
251         case REGULATOR_EVENT_POST_ENABLE:
252         case REGULATOR_EVENT_OUT_POSTCHANGE:
253                 if (!pwrdet_always_on && cell->pwrdet_mask) {
254                         pwr_detect_start(cell->pwrdet_mask);
255                         pwr_detect_latch();
256                 }
257                 break;
258
259         case REGULATOR_EVENT_DISABLE:
260         case REGULATOR_EVENT_FORCE_DISABLE:
261                 pwrio_disabled_mask |= cell->pwrio_mask;
262                 if (!pwrio_always_on)
263                         pwr_io_disable(cell->pwrio_mask);
264                 break;
265         }
266
267         pr_debug("tegra: %s: event %lu, pwrdet 0x%x, pwrio 0x%x\n",
268                 cell->reg_id, event,
269                 pmc_readl(PMC_PWR_DET_VAL), pmc_readl(PMC_PWR_IO_DISABLE));
270         spin_unlock_irqrestore(&pwr_lock, flags);
271
272         return NOTIFY_OK;
273 }
274
275 static int __init pwr_detect_cell_init_one(
276         struct pwr_detect_cell *cell, u32 *disabled_mask)
277 {
278         int ret;
279         struct regulator *regulator = regulator_get(NULL, cell->reg_id);
280
281         if (IS_ERR(regulator))
282                 return PTR_ERR(regulator);
283
284         cell->regulator_nb.notifier_call = pwrdet_notify_cb;
285         ret = regulator_register_notifier(regulator, &cell->regulator_nb);
286         if (ret) {
287                 regulator_put(regulator);
288                 return ret;
289         }
290
291         if (!regulator_is_enabled(regulator))
292                 *disabled_mask |= cell->pwrio_mask;
293
294         regulator_put(regulator);
295         return 0;
296 }
297
298 int __init tegra_pwr_detect_cell_init(void)
299 {
300         int i, ret;
301         u32 package_mask;
302         unsigned long flags;
303         bool rails_found = true;
304
305         i = tegra_package_id();
306         if ((i != -1) && (i & (~0x1F))) {
307                 pr_err("tegra: not supported package id %d - io power detection"
308                        " is left always on\n", i);
309                 return 0;
310         }
311         package_mask = (i == -1) ? i : (0x1 << i);
312
313         for (i = 0; i < ARRAY_SIZE(pwr_detect_cells); i++) {
314                 struct pwr_detect_cell *cell = &pwr_detect_cells[i];
315
316                 if (!(cell->package_mask & package_mask)) {
317                         pwrio_disabled_mask |= cell->pwrio_mask;
318                         continue;
319                 }
320
321                 ret = pwr_detect_cell_init_one(cell, &pwrio_disabled_mask);
322                 if (ret) {
323                         pr_err("tegra: failed to map regulator to power detect"
324                                " cell %s(%d)\n", cell->reg_id, ret);
325                         rails_found = false;
326                 }
327         }
328
329         if (!rails_found) {
330                 pr_err("tegra: failed regulators mapping - io power detection"
331                        " is left always on\n");
332                 return 0;
333         }
334         pwrdet_rails_found = true;
335
336         /* Latch initial i/o power levels, disable all detection cells
337            and not powered interfaces */
338         spin_lock_irqsave(&pwr_lock, flags);
339         if (!pwrdet_always_on)
340                 pwr_detect_latch();
341         if (!pwrio_always_on)
342                 pwr_io_disable(pwrio_disabled_mask);
343         spin_unlock_irqrestore(&pwr_lock, flags);
344
345         pr_info("tegra: started io power detection dynamic control\n");
346         pr_info("tegra: NO_IO_POWER setting 0x%x\n", pwrio_disabled_mask);
347
348         return 0;
349 }
350
351 fs_initcall(tegra_pwr_detect_cell_init);