ARM: tegra: pm: Fix DPD code offset for T11x
[linux-2.6.git] / arch / arm / mach-tegra / pm-t3.c
1 /*
2  * arch/arm/mach-tegra/pm-t3.c
3  *
4  * Tegra3 SOC-specific power and cluster management
5  *
6  * Copyright (c) 2009-2012, NVIDIA CORPORATION.  All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  */
18
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/io.h>
22 #include <linux/smp.h>
23 #include <linux/interrupt.h>
24 #include <linux/clk.h>
25 #include <linux/delay.h>
26 #include <linux/irq.h>
27 #include <linux/device.h>
28 #include <linux/module.h>
29 #include <linux/clockchips.h>
30 #include <linux/cpu_pm.h>
31
32 #include <mach/gpio.h>
33 #include <mach/iomap.h>
34 #include <mach/irqs.h>
35 #include <mach/io_dpd.h>
36
37 #include <asm/cputype.h>
38 #include <asm/hardware/gic.h>
39
40 #include <trace/events/power.h>
41
42 #include "clock.h"
43 #include "cpuidle.h"
44 #include "pm.h"
45 #include "sleep.h"
46 #include "tegra3_emc.h"
47 #include "dvfs.h"
48
49 #ifdef CONFIG_TEGRA_CLUSTER_CONTROL
50 #define CAR_CCLK_BURST_POLICY \
51         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x20)
52
53 #define CAR_SUPER_CCLK_DIVIDER \
54         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x24)
55
56 #define CAR_CCLKG_BURST_POLICY \
57         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x368)
58
59 #define CAR_SUPER_CCLKG_DIVIDER \
60         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x36C)
61
62 #define CAR_CCLKLP_BURST_POLICY \
63         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x370)
64 #define PLLX_DIV2_BYPASS_LP     (1<<16)
65
66 #define CAR_SUPER_CCLKLP_DIVIDER \
67         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x374)
68
69 #define CAR_BOND_OUT_V \
70         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x390)
71 #define CAR_BOND_OUT_V_CPU_G    (1<<0)
72 #define CAR_BOND_OUT_V_CPU_LP   (1<<1)
73
74 #define CAR_CLK_ENB_V_SET \
75         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x440)
76 #define CAR_CLK_ENB_V_CPU_G     (1<<0)
77 #define CAR_CLK_ENB_V_CPU_LP    (1<<1)
78
79 #define CAR_RST_CPUG_CMPLX_SET \
80         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x450)
81
82 #define CAR_RST_CPUG_CMPLX_CLR \
83         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x454)
84
85 #define CAR_RST_CPULP_CMPLX_SET \
86         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x458)
87
88 #define CAR_RST_CPULP_CMPLX_CLR \
89         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x45C)
90
91 #define CAR_CLK_CPUG_CMPLX_SET \
92         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x460)
93
94 #define CAR_CLK_CPUG_CMPLX_CLR \
95         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x464)
96
97 #define CAR_CLK_CPULP_CMPLX_SET \
98         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x468)
99
100 #define CAR_CLK_CPULP_CMPLX_CLR \
101         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x46C)
102
103 #define CPU_CLOCK(cpu)  (0x1<<(8+cpu))
104 #define CPU_RESET(cpu)  (0x1111ul<<(cpu))
105
106 #define PLLX_FO_G (1<<28)
107 #define PLLX_FO_LP (1<<29)
108
109 #define CLK_RST_CONTROLLER_PLLX_MISC_0 \
110         (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0xE4)
111
112 static int cluster_switch_prolog_clock(unsigned int flags)
113 {
114         u32 reg;
115         u32 CclkBurstPolicy;
116         u32 SuperCclkDivier;
117
118         /* Read the bond out register containing the G and LP CPUs. */
119         reg = readl(CAR_BOND_OUT_V);
120
121         /* Sync G-PLLX divider bypass with LP (no effect on G, just to prevent
122            LP settings overwrite by save/restore code */
123         CclkBurstPolicy = ~PLLX_DIV2_BYPASS_LP & readl(CAR_CCLKG_BURST_POLICY);
124         CclkBurstPolicy |= PLLX_DIV2_BYPASS_LP & readl(CAR_CCLKLP_BURST_POLICY);
125         writel(CclkBurstPolicy, CAR_CCLKG_BURST_POLICY);
126
127         /* Switching to G? */
128         if (flags & TEGRA_POWER_CLUSTER_G) {
129                 /* Do the G CPUs exist? */
130                 if (reg & CAR_BOND_OUT_V_CPU_G)
131                         return -ENXIO;
132
133                 /* Keep G CPU clock policy set by upper laayer, with the
134                    exception of the transition via LP1 */
135                 if (flags & TEGRA_POWER_SDRAM_SELFREFRESH) {
136                         /* In LP1 power mode come up on CLKM (oscillator) */
137                         CclkBurstPolicy = readl(CAR_CCLKG_BURST_POLICY);
138                         CclkBurstPolicy &= ~0xF;
139                         SuperCclkDivier = 0;
140
141                         writel(CclkBurstPolicy, CAR_CCLKG_BURST_POLICY);
142                         writel(SuperCclkDivier, CAR_SUPER_CCLKG_DIVIDER);
143                 }
144
145 #if defined(CONFIG_ARCH_TEGRA_3x_SOC)
146                 /* Hold G CPUs 1-3 in reset after the switch */
147                 reg = CPU_RESET(1) | CPU_RESET(2) | CPU_RESET(3);
148                 writel(reg, CAR_RST_CPUG_CMPLX_SET);
149
150                 /* Take G CPU 0 out of reset after the switch */
151                 reg = CPU_RESET(0);
152                 writel(reg, CAR_RST_CPUG_CMPLX_CLR);
153
154                 /* Disable the clocks on G CPUs 1-3 after the switch */
155                 reg = CPU_CLOCK(1) | CPU_CLOCK(2) | CPU_CLOCK(3);
156                 writel(reg, CAR_CLK_CPUG_CMPLX_SET);
157
158                 /* Enable the clock on G CPU 0 after the switch */
159                 reg = CPU_CLOCK(0);
160                 writel(reg, CAR_CLK_CPUG_CMPLX_CLR);
161
162                 /* Enable the G CPU complex clock after the switch */
163                 reg = CAR_CLK_ENB_V_CPU_G;
164                 writel(reg, CAR_CLK_ENB_V_SET);
165 #endif
166         }
167         /* Switching to LP? */
168         else if (flags & TEGRA_POWER_CLUSTER_LP) {
169                 /* Does the LP CPU exist? */
170                 if (reg & CAR_BOND_OUT_V_CPU_LP)
171                         return -ENXIO;
172
173                 /* Keep LP CPU clock policy set by upper layer, with the
174                    exception of the transition via LP1 */
175                 if (flags & TEGRA_POWER_SDRAM_SELFREFRESH) {
176                         /* In LP1 power mode come up on CLKM (oscillator) */
177                         CclkBurstPolicy = readl(CAR_CCLKLP_BURST_POLICY);
178                         CclkBurstPolicy &= ~0xF;
179                         SuperCclkDivier = 0;
180
181                         writel(CclkBurstPolicy, CAR_CCLKLP_BURST_POLICY);
182                         writel(SuperCclkDivier, CAR_SUPER_CCLKLP_DIVIDER);
183                 }
184
185 #if defined(CONFIG_ARCH_TEGRA_3x_SOC)
186                 /* Take the LP CPU ut of reset after the switch */
187                 reg = CPU_RESET(0);
188                 writel(reg, CAR_RST_CPULP_CMPLX_CLR);
189
190                 /* Enable the clock on the LP CPU after the switch */
191                 reg = CPU_CLOCK(0);
192                 writel(reg, CAR_CLK_CPULP_CMPLX_CLR);
193
194                 /* Enable the LP CPU complex clock after the switch */
195                 reg = CAR_CLK_ENB_V_CPU_LP;
196                 writel(reg, CAR_CLK_ENB_V_SET);
197 #endif
198         }
199
200         return 0;
201 }
202
203 static inline void enable_pllx_cluster_port(void)
204 {
205         u32 val = readl(CLK_RST_CONTROLLER_PLLX_MISC_0);
206         val &= (is_lp_cluster()?(~PLLX_FO_G):(~PLLX_FO_LP));
207         writel(val, CLK_RST_CONTROLLER_PLLX_MISC_0);
208 }
209
210 static inline void disable_pllx_cluster_port(void)
211 {
212         u32 val = readl(CLK_RST_CONTROLLER_PLLX_MISC_0);
213         val |= (is_lp_cluster()?PLLX_FO_G:PLLX_FO_LP);
214         writel(val, CLK_RST_CONTROLLER_PLLX_MISC_0);
215 }
216
217 void tegra_cluster_switch_prolog(unsigned int flags)
218 {
219         unsigned int target_cluster = flags & TEGRA_POWER_CLUSTER_MASK;
220         unsigned int current_cluster = is_lp_cluster()
221                                         ? TEGRA_POWER_CLUSTER_LP
222                                         : TEGRA_POWER_CLUSTER_G;
223         u32 reg;
224
225         /* Read the flow controler CSR register and clear the CPU switch
226            and immediate flags. If an actual CPU switch is to be performed,
227            re-write the CSR register with the desired values. */
228         reg = readl(FLOW_CTRL_CPU_CSR(0));
229         reg &= ~(FLOW_CTRL_CSR_IMMEDIATE_WAKE |
230                  FLOW_CTRL_CSR_SWITCH_CLUSTER);
231
232         /* Program flow controller for immediate wake if requested */
233         if (flags & TEGRA_POWER_CLUSTER_IMMEDIATE)
234                 reg |= FLOW_CTRL_CSR_IMMEDIATE_WAKE;
235
236         /* Do nothing if no switch actions requested */
237         if (!target_cluster)
238                 goto done;
239
240 #if defined(CONFIG_ARCH_TEGRA_HAS_SYMMETRIC_CPU_PWR_GATE)
241         reg &= ~FLOW_CTRL_CSR_ENABLE_EXT_MASK;
242         if ((flags & TEGRA_POWER_CLUSTER_PART_CRAIL) &&
243             ((flags & TEGRA_POWER_CLUSTER_PART_NONCPU) == 0) &&
244             (current_cluster == TEGRA_POWER_CLUSTER_LP))
245                 reg |= FLOW_CTRL_CSR_ENABLE_EXT_NCPU;
246         else if (flags & TEGRA_POWER_CLUSTER_PART_CRAIL)
247                 reg |= FLOW_CTRL_CSR_ENABLE_EXT_CRAIL;
248
249         if (flags & TEGRA_POWER_CLUSTER_PART_NONCPU)
250                 reg |= FLOW_CTRL_CSR_ENABLE_EXT_NCPU;
251 #endif
252
253         if ((current_cluster != target_cluster) ||
254                 (flags & TEGRA_POWER_CLUSTER_FORCE)) {
255                 if (current_cluster != target_cluster) {
256                         // Set up the clocks for the target CPU.
257                         if (cluster_switch_prolog_clock(flags)) {
258                                 /* The target CPU does not exist */
259                                 goto done;
260                         }
261
262                         /* Set up the flow controller to switch CPUs. */
263                         reg |= FLOW_CTRL_CSR_SWITCH_CLUSTER;
264
265                         /* Enable target port of PLL_X */
266                         enable_pllx_cluster_port();
267                 }
268         }
269
270 done:
271         writel(reg, FLOW_CTRL_CPU_CSR(0));
272 }
273
274
275 static void cluster_switch_epilog_actlr(void)
276 {
277         u32 actlr;
278
279         /*
280          * This is only needed for Cortex-A9, for Cortex-A15, do nothing!
281          *
282          * TLB maintenance broadcast bit (FW) is stubbed out on LP CPU (reads
283          * as zero, writes ignored). Hence, it is not preserved across G=>LP=>G
284          * switch by CPU save/restore code, but SMP bit is restored correctly.
285          * Synchronize these two bits here after LP=>G transition. Note that
286          * only CPU0 core is powered on before and after the switch. See also
287          * bug 807595.
288         */
289         if (((read_cpuid_id() >> 4) & 0xFFF) == 0xC0F)
290                 return;
291
292         __asm__("mrc p15, 0, %0, c1, c0, 1\n" : "=r" (actlr));
293
294         if (actlr & (0x1 << 6)) {
295                 actlr |= 0x1;
296                 __asm__("mcr p15, 0, %0, c1, c0, 1\n" : : "r" (actlr));
297         }
298 }
299
300 static void cluster_switch_epilog_gic(void)
301 {
302         unsigned int max_irq, i;
303         void __iomem *gic_base = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
304
305         /* Reprogram the interrupt affinity because the on the LP CPU,
306            the interrupt distributor affinity regsiters are stubbed out
307            by ARM (reads as zero, writes ignored). So when the LP CPU
308            context save code runs, the affinity registers will read
309            as all zero. This causes all interrupts to be effectively
310            disabled when back on the G CPU because they aren't routable
311            to any CPU. See bug 667720 for details. */
312
313         max_irq = readl(gic_base + GIC_DIST_CTR) & 0x1f;
314         max_irq = (max_irq + 1) * 32;
315
316         for (i = 32; i < max_irq; i += 4) {
317                 u32 val = 0x01010101;
318 #ifdef CONFIG_GIC_SET_MULTIPLE_CPUS
319                 unsigned int irq;
320                 for (irq = i; irq < (i + 4); irq++) {
321                         struct cpumask mask;
322                         struct irq_desc *desc = irq_to_desc(irq);
323
324                         if (desc && desc->affinity_hint) {
325                                 if (cpumask_and(&mask, desc->affinity_hint,
326                                                 desc->irq_data.affinity))
327                                         val |= (*cpumask_bits(&mask) & 0xff) <<
328                                                 ((irq & 3) * 8);
329                         }
330                 }
331 #endif
332                 writel(val, gic_base + GIC_DIST_TARGET + i * 4 / 4);
333         }
334 }
335
336 void tegra_cluster_switch_epilog(unsigned int flags)
337 {
338         u32 reg;
339
340         /* Make sure the switch and immediate flags are cleared in
341            the flow controller to prevent undesirable side-effects
342            for future users of the flow controller. */
343         reg = readl(FLOW_CTRL_CPU_CSR(0));
344         reg &= ~(FLOW_CTRL_CSR_IMMEDIATE_WAKE |
345                  FLOW_CTRL_CSR_SWITCH_CLUSTER);
346 #if defined(CONFIG_ARCH_TEGRA_HAS_SYMMETRIC_CPU_PWR_GATE)
347         reg &= ~FLOW_CTRL_CSR_ENABLE_EXT_MASK;
348 #endif
349         writel(reg, FLOW_CTRL_CPU_CSR(0));
350
351         /* Perform post-switch LP=>G clean-up */
352         if (!is_lp_cluster()) {
353                 cluster_switch_epilog_actlr();
354                 cluster_switch_epilog_gic();
355         }
356
357         /* Disable unused port of PLL_X */
358         disable_pllx_cluster_port();
359
360         #if DEBUG_CLUSTER_SWITCH
361         {
362                 /* FIXME: clock functions below are taking mutex */
363                 struct clk *c = tegra_get_clock_by_name(
364                         is_lp_cluster() ? "cpu_lp" : "cpu_g");
365                 DEBUG_CLUSTER(("%s: %s freq %lu\r\n", __func__,
366                         is_lp_cluster() ? "LP" : "G", clk_get_rate(c)));
367         }
368         #endif
369 }
370
371 int tegra_cluster_control(unsigned int us, unsigned int flags)
372 {
373         static ktime_t last_g2lp;
374
375         unsigned int target_cluster = flags & TEGRA_POWER_CLUSTER_MASK;
376         unsigned int current_cluster = is_lp_cluster()
377                                         ? TEGRA_POWER_CLUSTER_LP
378                                         : TEGRA_POWER_CLUSTER_G;
379         unsigned long irq_flags;
380
381         if ((target_cluster == TEGRA_POWER_CLUSTER_MASK) || !target_cluster)
382                 return -EINVAL;
383
384         if (num_online_cpus() > 1)
385                 return -EBUSY;
386
387         if ((current_cluster == target_cluster)
388         && !(flags & TEGRA_POWER_CLUSTER_FORCE))
389                 return -EEXIST;
390
391         if (target_cluster == TEGRA_POWER_CLUSTER_G)
392                 if (!is_g_cluster_present())
393                         return -EPERM;
394
395         trace_power_start(POWER_PSTATE, target_cluster, 0);
396
397         if (flags & TEGRA_POWER_CLUSTER_IMMEDIATE)
398                 us = 0;
399
400         DEBUG_CLUSTER(("%s(LP%d): %s->%s %s %s %d\r\n", __func__,
401                 (flags & TEGRA_POWER_SDRAM_SELFREFRESH) ? 1 : 2,
402                 is_lp_cluster() ? "LP" : "G",
403                 (target_cluster == TEGRA_POWER_CLUSTER_G) ? "G" : "LP",
404                 (flags & TEGRA_POWER_CLUSTER_IMMEDIATE) ? "immediate" : "",
405                 (flags & TEGRA_POWER_CLUSTER_FORCE) ? "force" : "",
406                 us));
407
408         local_irq_save(irq_flags);
409
410         if (current_cluster != target_cluster && !timekeeping_suspended) {
411                 ktime_t now = ktime_get();
412                 if (target_cluster == TEGRA_POWER_CLUSTER_G) {
413                         s64 t = ktime_to_us(ktime_sub(now, last_g2lp));
414                         s64 t_off = tegra_cpu_power_off_time();
415 #if defined(CONFIG_ARCH_TEGRA_11x_SOC)
416                         /* u32 reg; */
417 #endif
418                         if (t_off > t)
419                                 udelay((unsigned int)(t_off - t));
420
421                         tegra_dvfs_rail_on(tegra_cpu_rail, now);
422 #if defined(CONFIG_ARCH_TEGRA_11x_SOC)
423                         /*
424                          * comment out RAM repair as this seems impacting
425                          * cluster switch
426                          */
427                         /* enable RAM repair by flow controller */
428                         /*
429                         reg = readl(FLOW_CTRL_RAM_REPAIR);
430                         reg &= ~FLOW_CTRL_RAM_REPAIR_BYPASS_EN;
431                         writel(reg, FLOW_CTRL_RAM_REPAIR);
432                         */
433 #endif
434
435                 } else {
436                         last_g2lp = now;
437                         tegra_dvfs_rail_off(tegra_cpu_rail, now);
438                 }
439         }
440
441         if (flags & TEGRA_POWER_SDRAM_SELFREFRESH) {
442                 if (us)
443                         tegra_lp2_set_trigger(us);
444
445                 tegra_cluster_switch_prolog(flags);
446                 tegra_suspend_dram(TEGRA_SUSPEND_LP1, flags);
447                 tegra_cluster_switch_epilog(flags);
448
449                 if (us)
450                         tegra_lp2_set_trigger(0);
451         } else {
452                 int cpu = 0;
453
454                 tegra_set_cpu_in_lp2(0);
455                 cpu_pm_enter();
456                 if (!timekeeping_suspended)
457                         clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
458                                            &cpu);
459                 tegra_idle_lp2_last(0, flags);
460                 if (!timekeeping_suspended)
461                         clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
462                                            &cpu);
463                 cpu_pm_exit();
464                 tegra_clear_cpu_in_lp2(0);
465         }
466         local_irq_restore(irq_flags);
467
468         DEBUG_CLUSTER(("%s: %s\r\n", __func__, is_lp_cluster() ? "LP" : "G"));
469
470         return 0;
471 }
472 #endif
473
474 #ifdef CONFIG_PM_SLEEP
475
476 void tegra_lp0_suspend_mc(void)
477 {
478         /* Since memory frequency after LP0 is restored to boot rate
479            mc timing is saved during init, not on entry to LP0. Keep
480            this hook just in case, anyway */
481 }
482
483 void tegra_lp0_resume_mc(void)
484 {
485         tegra_mc_timing_restore();
486 }
487
488 void tegra_lp0_cpu_mode(bool enter)
489 {
490         static struct clk *cclk_lp;
491         static bool entered_on_g = false;
492         unsigned int flags;
493
494         if (!cclk_lp)
495                 cclk_lp = tegra_get_clock_by_name("cclk_lp");
496
497         if (enter)
498                 entered_on_g = !is_lp_cluster();
499
500         if (entered_on_g) {
501                 if (enter)
502                         clk_enable(cclk_lp);
503
504                 flags = enter ? TEGRA_POWER_CLUSTER_LP : TEGRA_POWER_CLUSTER_G;
505                 flags |= TEGRA_POWER_CLUSTER_IMMEDIATE;
506 #if defined(CONFIG_ARCH_TEGRA_HAS_SYMMETRIC_CPU_PWR_GATE)
507                 flags |= TEGRA_POWER_CLUSTER_PART_DEFAULT;
508 #endif
509                 if (!tegra_cluster_control(0, flags)) {
510                         if (!enter)
511                                 clk_disable(cclk_lp);
512                         pr_info("Tegra: switched to %s cluster\n",
513                                 enter ? "LP" : "G");
514                 }
515         }
516 }
517
518 #define IO_DPD_INFO(_name, _index, _bit) \
519         { \
520                 .name = _name, \
521                 .io_dpd_reg_index = _index, \
522                 .io_dpd_bit = _bit, \
523         }
524
525 /* PMC IO DPD register offsets */
526 #define APBDEV_PMC_IO_DPD_REQ_0         0x1b8
527 #define APBDEV_PMC_IO_DPD_STATUS_0      0x1bc
528 #define APBDEV_PMC_SEL_DPD_TIM_0        0x1c8
529 #define APBDEV_DPD_ENABLE_LSB           30
530 #if defined(CONFIG_ARCH_TEGRA_3x_SOC)
531 #define APBDEV_DPD2_ENABLE_LSB          5
532 #else
533 #define APBDEV_DPD2_ENABLE_LSB          30
534 #endif
535 #define PMC_DPD_SAMPLE                  0x20
536
537 static struct tegra_io_dpd tegra_list_io_dpd[] = {
538 #if defined(CONFIG_ARCH_TEGRA_3x_SOC) && defined(CONFIG_TEGRA_IO_DPD)
539         /* sd dpd bits in dpd2 register */
540         IO_DPD_INFO("sdhci-tegra.0",    1,      1), /* SDMMC1 */
541         IO_DPD_INFO("sdhci-tegra.2",    1,      2), /* SDMMC3 */
542         IO_DPD_INFO("sdhci-tegra.3",    1,      3), /* SDMMC4 */
543 #endif
544 };
545 #endif
546
547 /* we want to cleanup bootloader io dpd setting in kernel */
548 static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
549
550 #ifdef CONFIG_PM_SLEEP
551 struct tegra_io_dpd *tegra_io_dpd_get(struct device *dev)
552 {
553 #ifdef CONFIG_TEGRA_IO_DPD
554         int i;
555         const char *name = dev ? dev_name(dev) : NULL;
556         if (name) {
557                 for (i = 0; i < ARRAY_SIZE(tegra_list_io_dpd); i++) {
558                         if (!(strncmp(tegra_list_io_dpd[i].name, name,
559                                 strlen(name)))) {
560                                 return &tegra_list_io_dpd[i];
561                         }
562                 }
563         }
564         dev_info(dev, "Error: tegra3 io dpd not supported for %s\n",
565                 ((name) ? name : "NULL"));
566 #endif
567         return NULL;
568 }
569
570 static DEFINE_SPINLOCK(tegra_io_dpd_lock);
571
572 void tegra_io_dpd_enable(struct tegra_io_dpd *hnd)
573 {
574         unsigned int enable_mask;
575         unsigned int dpd_status;
576         unsigned int dpd_enable_lsb;
577
578         if ((!hnd)) {
579                 pr_warn("SD IO DPD handle NULL in %s\n", __func__);
580                 return;
581         }
582         spin_lock(&tegra_io_dpd_lock);
583         dpd_enable_lsb = (hnd->io_dpd_reg_index) ? APBDEV_DPD2_ENABLE_LSB :
584                                                 APBDEV_DPD_ENABLE_LSB;
585         writel(0x1, pmc + PMC_DPD_SAMPLE);
586         writel(0x10, pmc + APBDEV_PMC_SEL_DPD_TIM_0);
587         enable_mask = ((1 << hnd->io_dpd_bit) | (2 << dpd_enable_lsb));
588         writel(enable_mask, pmc + (APBDEV_PMC_IO_DPD_REQ_0 +
589                                         hnd->io_dpd_reg_index * 8));
590         udelay(1);
591         dpd_status = readl(pmc + (APBDEV_PMC_IO_DPD_STATUS_0 +
592                                         hnd->io_dpd_reg_index * 8));
593         if (!(dpd_status & (1 << hnd->io_dpd_bit))) {
594 #if !defined(CONFIG_TEGRA_FPGA_PLATFORM)
595                 pr_info("Error: dpd%d enable failed, status=%#x\n",
596                 (hnd->io_dpd_reg_index + 1), dpd_status);
597 #endif
598         }
599         /* Sample register must be reset before next sample operation */
600         writel(0x0, pmc + PMC_DPD_SAMPLE);
601         spin_unlock(&tegra_io_dpd_lock);
602         return;
603 }
604
605 void tegra_io_dpd_disable(struct tegra_io_dpd *hnd)
606 {
607         unsigned int enable_mask;
608         unsigned int dpd_status;
609         unsigned int dpd_enable_lsb;
610
611         if ((!hnd)) {
612                 pr_warn("SD IO DPD handle NULL in %s\n", __func__);
613                 return;
614         }
615         spin_lock(&tegra_io_dpd_lock);
616         dpd_enable_lsb = (hnd->io_dpd_reg_index) ? APBDEV_DPD2_ENABLE_LSB :
617                                                 APBDEV_DPD_ENABLE_LSB;
618         enable_mask = ((1 << hnd->io_dpd_bit) | (1 << dpd_enable_lsb));
619         writel(enable_mask, pmc + (APBDEV_PMC_IO_DPD_REQ_0 +
620                                         hnd->io_dpd_reg_index * 8));
621         dpd_status = readl(pmc + (APBDEV_PMC_IO_DPD_STATUS_0 +
622                                         hnd->io_dpd_reg_index * 8));
623         if (dpd_status & (1 << hnd->io_dpd_bit)) {
624 #if !defined(CONFIG_TEGRA_FPGA_PLATFORM)
625                 pr_info("Error: dpd%d disable failed, status=%#x\n",
626                 (hnd->io_dpd_reg_index + 1), dpd_status);
627 #endif
628         }
629         spin_unlock(&tegra_io_dpd_lock);
630         return;
631 }
632
633 static void tegra_io_dpd_delayed_disable(struct work_struct *work)
634 {
635         struct tegra_io_dpd *hnd = container_of(
636                 to_delayed_work(work), struct tegra_io_dpd, delay_dpd);
637         tegra_io_dpd_disable(hnd);
638         hnd->need_delay_dpd = 0;
639 }
640
641 int tegra_io_dpd_init(void)
642 {
643         int i;
644         for (i = 0;
645                 i < (sizeof(tegra_list_io_dpd) / sizeof(struct tegra_io_dpd));
646                 i++) {
647                         INIT_DELAYED_WORK(&(tegra_list_io_dpd[i].delay_dpd),
648                                 tegra_io_dpd_delayed_disable);
649                         mutex_init(&(tegra_list_io_dpd[i].delay_lock));
650                         tegra_list_io_dpd[i].need_delay_dpd = 0;
651         }
652         return 0;
653 }
654
655 #else
656
657 int tegra_io_dpd_init(void)
658 {
659         return 0;
660 }
661
662 void tegra_io_dpd_enable(struct tegra_io_dpd *hnd)
663 {
664 }
665
666 void tegra_io_dpd_disable(struct tegra_io_dpd *hnd)
667 {
668 }
669
670 struct tegra_io_dpd *tegra_io_dpd_get(struct device *dev)
671 {
672         return NULL;
673 }
674
675 #endif
676
677 EXPORT_SYMBOL(tegra_io_dpd_get);
678 EXPORT_SYMBOL(tegra_io_dpd_enable);
679 EXPORT_SYMBOL(tegra_io_dpd_disable);
680 EXPORT_SYMBOL(tegra_io_dpd_init);
681
682 struct io_dpd_reg_info {
683         u32 req_reg_off;
684         u8 dpd_code_lsb;
685 };
686
687 static struct io_dpd_reg_info t3_io_dpd_req_regs[] = {
688         {0x1b8, 30},
689         {0x1c0, 5},
690 };
691
692 /* io dpd off request code */
693 #define IO_DPD_CODE_OFF         1
694
695 /* cleans io dpd settings from bootloader during kernel init */
696 void tegra_bl_io_dpd_cleanup()
697 {
698         int i;
699         unsigned int dpd_mask;
700         unsigned int dpd_status;
701
702         pr_info("Clear bootloader IO dpd settings\n");
703         /* clear all dpd requests from bootloader */
704         for (i = 0; i < ARRAY_SIZE(t3_io_dpd_req_regs); i++) {
705                 dpd_mask = ((1 << t3_io_dpd_req_regs[i].dpd_code_lsb) - 1);
706                 dpd_mask |= (IO_DPD_CODE_OFF <<
707                         t3_io_dpd_req_regs[i].dpd_code_lsb);
708                 writel(dpd_mask, pmc + t3_io_dpd_req_regs[i].req_reg_off);
709                 /* dpd status register is next to req reg in tegra3 */
710                 dpd_status = readl(pmc +
711                         (t3_io_dpd_req_regs[i].req_reg_off + 4));
712         }
713         return;
714 }
715 EXPORT_SYMBOL(tegra_bl_io_dpd_cleanup);
716