arm: tegra: pluto: enable powergate for ve
[linux-3.10.git] / arch / arm / mach-tegra / powergate.c
1 /*
2  * drivers/powergate/tegra-powergate.c
3  *
4  * Copyright (c) 2010 Google, Inc
5  * Copyright (C) 2011-2012 NVIDIA Corporation.
6  *
7  * Author:
8  *      Colin Cross <ccross@google.com>
9  *
10  * This software is licensed under the terms of the GNU General Public
11  * License version 2, as published by the Free Software Foundation, and
12  * may be copied, distributed, and modified under those terms.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  */
20
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/clk.h>
24 #include <linux/string.h>
25 #include <linux/debugfs.h>
26 #include <linux/delay.h>
27 #include <linux/err.h>
28 #include <linux/init.h>
29 #include <linux/io.h>
30 #include <linux/seq_file.h>
31 #include <linux/spinlock.h>
32 #include <linux/clk/tegra.h>
33 #include <trace/events/power.h>
34
35 #include <mach/powergate.h>
36
37 #include "clock.h"
38 #include "fuse.h"
39 #include "iomap.h"
40
41 #if defined(DEBUG_T11x_POWERGATE)
42 static void test_powergate_parts(void);
43 #endif
44 #if defined(DEBUG_T11x_POWERUNGATE)
45 static void test_powerungate_parts(void);
46 #endif
47 #if defined(DEBUG_T11x_POWERGATE_CLK_OFF)
48 static void test_powergate_clk_off_parts(void);
49 #endif
50 #if defined(DEBUG_T11x_POWERUNGATE_CLK_OFF)
51 static void test_unpowergate_clk_on_parts(void);
52 #endif
53
54 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
55 static int tegra11x_check_partition_pug_seq(int id);
56 static int tegra11x_unpowergate(int id);
57 #endif
58
59 #define PWRGATE_TOGGLE          0x30
60 #define PWRGATE_TOGGLE_START    (1 << 8)
61
62 #define REMOVE_CLAMPING         0x34
63
64 #define PWRGATE_STATUS          0x38
65
66 #if defined(CONFIG_ARCH_TEGRA_3x_SOC)
67 enum mc_client {
68         MC_CLIENT_AFI           = 0,
69         MC_CLIENT_AVPC          = 1,
70         MC_CLIENT_DC            = 2,
71         MC_CLIENT_DCB           = 3,
72         MC_CLIENT_EPP           = 4,
73         MC_CLIENT_G2            = 5,
74         MC_CLIENT_HC            = 6,
75         MC_CLIENT_HDA           = 7,
76         MC_CLIENT_ISP           = 8,
77         MC_CLIENT_MPCORE        = 9,
78         MC_CLIENT_MPCORELP      = 10,
79         MC_CLIENT_MPE           = 11,
80         MC_CLIENT_NV            = 12,
81         MC_CLIENT_NV2           = 13,
82         MC_CLIENT_PPCS          = 14,
83         MC_CLIENT_SATA          = 15,
84         MC_CLIENT_VDE           = 16,
85         MC_CLIENT_VI            = 17,
86         MC_CLIENT_LAST          = -1,
87 };
88 #elif defined(CONFIG_ARCH_TEGRA_2x_SOC)
89 enum mc_client {
90         MC_CLIENT_AVPC          = 0,
91         MC_CLIENT_DC            = 1,
92         MC_CLIENT_DCB           = 2,
93         MC_CLIENT_EPP           = 3,
94         MC_CLIENT_G2            = 4,
95         MC_CLIENT_HC            = 5,
96         MC_CLIENT_ISP           = 6,
97         MC_CLIENT_MPCORE        = 7,
98         MC_CLIENT_MPEA          = 8,
99         MC_CLIENT_MPEB          = 9,
100         MC_CLIENT_MPEC          = 10,
101         MC_CLIENT_NV            = 11,
102         MC_CLIENT_PPCS          = 12,
103         MC_CLIENT_VDE           = 13,
104         MC_CLIENT_VI            = 14,
105         MC_CLIENT_LAST          = -1,
106         MC_CLIENT_AFI           = MC_CLIENT_LAST,
107 };
108 #else
109 /* bit positions are specific to chip */
110 enum mc_client {
111         MC_CLIENT_AVPC          = 1,
112         MC_CLIENT_DC            = 2,
113         MC_CLIENT_DCB           = 3,
114         MC_CLIENT_EPP           = 4,
115         MC_CLIENT_G2            = 5,
116         MC_CLIENT_HC            = 6,
117         MC_CLIENT_HDA           = 7,
118         MC_CLIENT_ISP           = 8,
119         MC_CLIENT_MPCORE        = 9,
120         MC_CLIENT_MPCORELP      = 10,
121         MC_CLIENT_MSENC         = 11,
122         MC_CLIENT_NV            = 12,
123         MC_CLIENT_PPCS          = 14,
124         MC_CLIENT_VDE           = 16,
125         MC_CLIENT_VI            = 17,
126         MC_CLIENT_XUSB_HOST     = 19,
127         MC_CLIENT_XUSB_DEV      = 20,
128         MC_CLIENT_EMUCIF        = 21,
129         MC_CLIENT_TSEC          = 22,
130         MC_CLIENT_LAST          = -1,
131         MC_CLIENT_AFI           = MC_CLIENT_LAST,
132         MC_CLIENT_MPE           = MC_CLIENT_LAST,
133         MC_CLIENT_NV2           = MC_CLIENT_LAST,
134         MC_CLIENT_SATA          = MC_CLIENT_LAST,
135 };
136 #endif
137
138 #define MAX_CLK_EN_NUM                  9
139
140 static int tegra_num_powerdomains;
141 static int tegra_num_cpu_domains;
142 static u8 *tegra_cpu_domains;
143 static u8 tegra_quad_cpu_domains[] = {
144         TEGRA_POWERGATE_CPU0,
145         TEGRA_POWERGATE_CPU1,
146         TEGRA_POWERGATE_CPU2,
147         TEGRA_POWERGATE_CPU3,
148 };
149
150 static DEFINE_SPINLOCK(tegra_powergate_lock);
151
152 #define MAX_HOTRESET_CLIENT_NUM         4
153
154 enum clk_type {
155         CLK_AND_RST,
156         RST_ONLY,
157         CLK_ONLY,
158 };
159
160 struct partition_clk_info {
161         const char *clk_name;
162         enum clk_type clk_type;
163         /* true if clk is only used in assert/deassert reset and not while enable-den*/
164         struct clk *clk_ptr;
165 };
166
167 struct powergate_partition {
168         const char *name;
169         enum mc_client hot_reset_clients[MAX_HOTRESET_CLIENT_NUM];
170         struct partition_clk_info clk_info[MAX_CLK_EN_NUM];
171 };
172
173 static struct powergate_partition powergate_partition_info[TEGRA_NUM_POWERGATE] = {
174         [TEGRA_POWERGATE_CPU]   = { "cpu0",     {MC_CLIENT_LAST}, },
175 #if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
176         [TEGRA_POWERGATE_L2]    = { "l2",       {MC_CLIENT_LAST}, },
177         [TEGRA_POWERGATE_3D]    = { "3d0",
178 #else
179         [TEGRA_POWERGATE_3D]    = { "3d",
180 #endif
181                                                 {MC_CLIENT_NV, MC_CLIENT_LAST},
182                                                 {{"3d", CLK_AND_RST} }, },
183 /* T11x does not have pcie */
184 #if !defined(CONFIG_ARCH_TEGRA_11x_SOC)
185 #ifdef CONFIG_ARCH_TEGRA_HAS_PCIE
186         [TEGRA_POWERGATE_PCIE]  = { "pcie",
187                                                 {MC_CLIENT_AFI, MC_CLIENT_LAST},
188                                                 {{"afi", CLK_AND_RST},
189                                                 {"pcie", CLK_AND_RST},
190 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
191                                                 {"cml0", CLK_ONLY},
192 #endif
193                                                 {"pciex", RST_ONLY} }, },
194 #endif
195 #endif
196         [TEGRA_POWERGATE_VDEC]  = { "vde",
197                                                 {MC_CLIENT_VDE, MC_CLIENT_LAST},
198                                                 {{"vde", CLK_AND_RST} }, },
199         [TEGRA_POWERGATE_MPE]   = { "mpe",
200 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
201                                         {
202                                                 MC_CLIENT_MPE,
203                                                 MC_CLIENT_LAST
204                                         },
205 #elif defined(CONFIG_ARCH_TEGRA_2x_SOC)
206                                                 {MC_CLIENT_MPEA, MC_CLIENT_MPEB,
207                                                  MC_CLIENT_MPEC, MC_CLIENT_LAST},
208 #else
209                                         {
210                                                 MC_CLIENT_MSENC,
211                                                 MC_CLIENT_LAST
212                                         },
213 #endif
214 #if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
215                                         {
216                                                 {"mpe", CLK_AND_RST}
217                                         },
218 #else
219                                         {
220                                                 {"msenc.cbus", CLK_AND_RST}
221                                         },
222 #endif
223                                 },
224         [TEGRA_POWERGATE_VENC]  = { "ve",
225                                         {
226                                                 MC_CLIENT_ISP,
227                                                 MC_CLIENT_VI,
228                                                 MC_CLIENT_LAST
229                                         },
230                                         {
231                                                 {"isp", CLK_AND_RST},
232                                                 {"vi", CLK_AND_RST},
233                                                 {"csi", CLK_AND_RST}
234                                         },
235                                 },
236 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
237         [TEGRA_POWERGATE_CPU1]  = { "cpu1",     {MC_CLIENT_LAST}, },
238         [TEGRA_POWERGATE_CPU2]  = { "cpu2",     {MC_CLIENT_LAST}, },
239         [TEGRA_POWERGATE_CPU3]  = { "cpu3",     {MC_CLIENT_LAST}, },
240         [TEGRA_POWERGATE_CELP]  = { "celp",     {MC_CLIENT_LAST}, },
241 #if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
242 #ifdef CONFIG_ARCH_TEGRA_HAS_SATA
243         [TEGRA_POWERGATE_SATA]  = { "sata",     {MC_CLIENT_SATA, MC_CLIENT_LAST},
244                                                 {{"sata", CLK_AND_RST},
245                                                 {"sata_oob", CLK_AND_RST},
246                                                 {"cml1", CLK_ONLY},
247                                                 {"sata_cold", RST_ONLY} }, },
248 #endif
249 #ifdef CONFIG_ARCH_TEGRA_HAS_DUAL_3D
250         [TEGRA_POWERGATE_3D1]   = { "3d1",
251                                                 {MC_CLIENT_NV2, MC_CLIENT_LAST},
252                                                 {{"3d2", CLK_AND_RST} }, },
253 #endif
254 #endif
255         [TEGRA_POWERGATE_HEG]   = { "heg",
256                                         {
257                                                 MC_CLIENT_G2,
258                                                 MC_CLIENT_EPP,
259 #if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
260                                                 MC_CLIENT_HC,
261 #endif
262                                                 MC_CLIENT_LAST
263                                         },
264                                         {
265                                                 {"2d", CLK_AND_RST},
266                                                 {"epp", CLK_AND_RST},
267 #if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
268                                                 {"host1x", CLK_AND_RST},
269                                                 {"3d", RST_ONLY}
270 #endif
271                                         },
272                                 },
273 #endif
274 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
275         [TEGRA_POWERGATE_CRAIL] = { "crail",    {MC_CLIENT_LAST}, },
276         [TEGRA_POWERGATE_C0NC]  = { "c0nc",     {MC_CLIENT_LAST}, },
277         [TEGRA_POWERGATE_C1NC]  = { "c1nc",     {MC_CLIENT_LAST}, },
278         [TEGRA_POWERGATE_DISA]  = { "disa",
279                                         {
280                                                 MC_CLIENT_DC,
281                                                 MC_CLIENT_LAST
282                                         },
283                                         {
284                                                 {"disp1", CLK_AND_RST},
285                                                 {"dsia", CLK_AND_RST},
286                                                 {"dsib", CLK_AND_RST},
287                                                 {"csi", CLK_AND_RST},
288                                                 {"mipi-cal", CLK_AND_RST}
289                                         },
290                                 },
291         [TEGRA_POWERGATE_DISB]  = { "disb",
292                                         {
293                                                 MC_CLIENT_DCB,
294                                                 MC_CLIENT_LAST
295                                         },
296                                         {
297                                                 {"disp2", CLK_AND_RST},
298                                                 {"hdmi", CLK_AND_RST}
299                                         },
300                                 },
301         [TEGRA_POWERGATE_XUSBA] = { "xusba",
302                                         { MC_CLIENT_LAST },
303                                         {
304                                                 {"xusb_ss", CLK_AND_RST}
305                                         },
306                                 },
307         [TEGRA_POWERGATE_XUSBB] = { "xusbb",
308                                         {
309                                                 MC_CLIENT_XUSB_DEV,
310                                                 MC_CLIENT_LAST
311                                         },
312                                         {
313                                                 {"xusb_dev", CLK_AND_RST},
314                                         },
315                                 },
316         [TEGRA_POWERGATE_XUSBC] = { "xusbc",
317                                         {
318                                                 MC_CLIENT_XUSB_HOST,
319                                                 MC_CLIENT_LAST
320                                         },
321                                         {
322                                                 {"xusb_host", CLK_AND_RST},
323                                         },
324                                 },
325 #endif
326
327 };
328
329 static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
330
331 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
332 static void __iomem *mipi_cal = IO_ADDRESS(TEGRA_MIPI_CAL_BASE);
333
334 static u32 mipi_cal_read(unsigned long reg)
335 {
336         return readl(mipi_cal + reg);
337 }
338
339 static void mipi_cal_write(u32 val, unsigned long reg)
340 {
341         writel(val, mipi_cal + reg);
342 }
343
344 static void __iomem *clk_rst = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
345
346 static u32 clk_rst_read(unsigned long reg)
347 {
348         return readl(clk_rst + reg);
349 }
350 #endif
351
352 static u32 pmc_read(unsigned long reg)
353 {
354         return readl(pmc + reg);
355 }
356
357 static void pmc_write(u32 val, unsigned long reg)
358 {
359         writel(val, pmc + reg);
360 }
361
362 static void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE);
363
364 static u32 mc_read(unsigned long reg)
365 {
366         return readl(mc + reg);
367 }
368
369 static void mc_write(u32 val, unsigned long reg)
370 {
371         writel(val, mc + reg);
372 }
373
374 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && \
375         !defined(CONFIG_TEGRA_SIMULATION_PLATFORM)
376
377 #define MC_CLIENT_HOTRESET_CTRL 0x200
378 #define MC_CLIENT_HOTRESET_STAT 0x204
379
380 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && \
381         !defined(CONFIG_ARCH_TEGRA_3x_SOC)
382 /* FIXME: this is sw workaround for unstable hotreset status
383  * for T11x.
384  */
385 #define HOTRESET_READ_COUNT 5
386 static bool tegra11x_stable_hotreset_check(u32 *stat)
387 {
388         int i;
389         u32 cur_stat;
390         u32 prv_stat;
391         unsigned long flags;
392
393         spin_lock_irqsave(&tegra_powergate_lock, flags);
394         prv_stat = mc_read(MC_CLIENT_HOTRESET_STAT);
395         for (i = 0; i < HOTRESET_READ_COUNT; i++) {
396                 cur_stat = mc_read(MC_CLIENT_HOTRESET_STAT);
397                 if (cur_stat != prv_stat) {
398                         spin_unlock_irqrestore(&tegra_powergate_lock, flags);
399                         return false;
400                 }
401         }
402         *stat = cur_stat;
403         spin_unlock_irqrestore(&tegra_powergate_lock, flags);
404         return true;
405 }
406 #endif
407
408 static void mc_flush(int id)
409 {
410         u32 idx, rst_ctrl, rst_stat;
411         enum mc_client mcClientBit;
412         unsigned long flags;
413 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && \
414         !defined(CONFIG_ARCH_TEGRA_3x_SOC)
415         bool ret;
416 #endif
417
418         BUG_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
419
420         for (idx = 0; idx < MAX_HOTRESET_CLIENT_NUM; idx++) {
421                 mcClientBit =
422                         powergate_partition_info[id].hot_reset_clients[idx];
423                 if (mcClientBit == MC_CLIENT_LAST)
424                         break;
425
426                 spin_lock_irqsave(&tegra_powergate_lock, flags);
427                 rst_ctrl = mc_read(MC_CLIENT_HOTRESET_CTRL);
428                 rst_ctrl |= (1 << mcClientBit);
429                 mc_write(rst_ctrl, MC_CLIENT_HOTRESET_CTRL);
430
431                 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
432
433                 do {
434                         udelay(10);
435 #if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
436                         rst_stat = mc_read(MC_CLIENT_HOTRESET_STAT);
437 #else
438                         rst_stat = 0;
439                         ret = tegra11x_stable_hotreset_check(&rst_stat);
440                         if (!ret)
441                                 continue;
442 #endif
443                 } while (!(rst_stat & (1 << mcClientBit)));
444         }
445 }
446
447 static void mc_flush_done(int id)
448 {
449         u32 idx, rst_ctrl;
450         enum mc_client mcClientBit;
451         unsigned long flags;
452
453         BUG_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
454
455         for (idx = 0; idx < MAX_HOTRESET_CLIENT_NUM; idx++) {
456                 mcClientBit =
457                         powergate_partition_info[id].hot_reset_clients[idx];
458                 if (mcClientBit == MC_CLIENT_LAST)
459                         break;
460
461                 spin_lock_irqsave(&tegra_powergate_lock, flags);
462
463                 rst_ctrl = mc_read(MC_CLIENT_HOTRESET_CTRL);
464                 rst_ctrl &= ~(1 << mcClientBit);
465                 mc_write(rst_ctrl, MC_CLIENT_HOTRESET_CTRL);
466
467                 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
468         }
469
470         wmb();
471 }
472
473 int tegra_powergate_mc_flush(int id)
474 {
475         if (id < 0 || id >= TEGRA_NUM_POWERGATE)
476                 return -EINVAL;
477         mc_flush(id);
478         return 0;
479 }
480
481 int tegra_powergate_mc_flush_done(int id)
482 {
483         if (id < 0 || id >= TEGRA_NUM_POWERGATE)
484                 return -EINVAL;
485         mc_flush_done(id);
486         return 0;
487 }
488
489 int tegra_powergate_mc_disable(int id)
490 {
491         return 0;
492 }
493
494 int tegra_powergate_mc_enable(int id)
495 {
496         return 0;
497 }
498
499 #else
500
501 #define MC_CLIENT_CTRL          0x100
502 #define MC_CLIENT_HOTRESETN     0x104
503 #define MC_CLIENT_ORRC_BASE     0x140
504
505 int tegra_powergate_mc_disable(int id)
506 {
507         u32 idx, clt_ctrl, orrc_reg;
508         enum mc_client mcClientBit;
509         unsigned long flags;
510
511         if (id < 0 || id >= TEGRA_NUM_POWERGATE) {
512                 WARN_ON(1);
513                 return -EINVAL;
514         }
515
516         for (idx = 0; idx < MAX_HOTRESET_CLIENT_NUM; idx++) {
517                 mcClientBit =
518                         powergate_partition_info[id].hot_reset_clients[idx];
519                 if (mcClientBit == MC_CLIENT_LAST)
520                         break;
521
522                 spin_lock_irqsave(&tegra_powergate_lock, flags);
523
524                 /* clear client enable bit */
525                 clt_ctrl = mc_read(MC_CLIENT_CTRL);
526                 clt_ctrl &= ~(1 << mcClientBit);
527                 mc_write(clt_ctrl, MC_CLIENT_CTRL);
528
529                 /* read back to flush write */
530                 clt_ctrl = mc_read(MC_CLIENT_CTRL);
531
532                 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
533
534                 /* wait for outstanding requests to reach 0 */
535                 orrc_reg = MC_CLIENT_ORRC_BASE + (mcClientBit * 4);
536                 while (mc_read(orrc_reg) != 0)
537                         udelay(10);
538         }
539         return 0;
540 }
541
542 int tegra_powergate_mc_flush(int id)
543 {
544         u32 idx, hot_rstn;
545         enum mc_client mcClientBit;
546         unsigned long flags;
547
548         if (id < 0 || id >= TEGRA_NUM_POWERGATE) {
549                 WARN_ON(1);
550                 return -EINVAL;
551         }
552
553         for (idx = 0; idx < MAX_HOTRESET_CLIENT_NUM; idx++) {
554                 mcClientBit =
555                         powergate_partition_info[id].hot_reset_clients[idx];
556                 if (mcClientBit == MC_CLIENT_LAST)
557                         break;
558
559                 spin_lock_irqsave(&tegra_powergate_lock, flags);
560
561                 /* assert hotreset (client module is currently in reset) */
562                 hot_rstn = mc_read(MC_CLIENT_HOTRESETN);
563                 hot_rstn &= ~(1 << mcClientBit);
564                 mc_write(hot_rstn, MC_CLIENT_HOTRESETN);
565
566                 /* read back to flush write */
567                 hot_rstn = mc_read(MC_CLIENT_HOTRESETN);
568
569                 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
570         }
571         return 0;
572 }
573
574 int tegra_powergate_mc_flush_done(int id)
575 {
576         u32 idx, hot_rstn;
577         enum mc_client mcClientBit;
578         unsigned long flags;
579
580         if (id < 0 || id >= TEGRA_NUM_POWERGATE) {
581                 WARN_ON(1);
582                 return -EINVAL;
583         }
584
585         for (idx = 0; idx < MAX_HOTRESET_CLIENT_NUM; idx++) {
586                 mcClientBit =
587                         powergate_partition_info[id].hot_reset_clients[idx];
588                 if (mcClientBit == MC_CLIENT_LAST)
589                         break;
590
591                 spin_lock_irqsave(&tegra_powergate_lock, flags);
592
593                 /* deassert hotreset */
594                 hot_rstn = mc_read(MC_CLIENT_HOTRESETN);
595                 hot_rstn |= (1 << mcClientBit);
596                 mc_write(hot_rstn, MC_CLIENT_HOTRESETN);
597
598                 /* read back to flush write */
599                 hot_rstn = mc_read(MC_CLIENT_HOTRESETN);
600
601                 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
602         }
603         return 0;
604 }
605
606 int tegra_powergate_mc_enable(int id)
607 {
608         u32 idx, clt_ctrl;
609         enum mc_client mcClientBit;
610         unsigned long flags;
611
612         if (id < 0 || id >= TEGRA_NUM_POWERGATE) {
613                 WARN_ON(1);
614                 return -EINVAL;
615         }
616
617         for (idx = 0; idx < MAX_HOTRESET_CLIENT_NUM; idx++) {
618                 mcClientBit =
619                         powergate_partition_info[id].hot_reset_clients[idx];
620                 if (mcClientBit == MC_CLIENT_LAST)
621                         break;
622
623                 spin_lock_irqsave(&tegra_powergate_lock, flags);
624
625                 /* enable client */
626                 clt_ctrl = mc_read(MC_CLIENT_CTRL);
627                 clt_ctrl |= (1 << mcClientBit);
628                 mc_write(clt_ctrl, MC_CLIENT_CTRL);
629
630                 /* read back to flush write */
631                 clt_ctrl = mc_read(MC_CLIENT_CTRL);
632
633                 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
634         }
635         return 0;
636 }
637
638 static void mc_flush(int id) {}
639 static void mc_flush_done(int id) {}
640 #endif
641
642 static int tegra_powergate_set(int id, bool new_state)
643 {
644 #ifndef CONFIG_TEGRA_SIMULATION_PLATFORM
645         bool status;
646         unsigned long flags;
647         /* 10us timeout for toggle operation if it takes affect*/
648         int toggle_timeout = 10;
649         /* 100 * 10 = 1000us timeout for toggle command to take affect in case
650            of contention with h/w initiated CPU power gating */
651         int contention_timeout = 100;
652
653         spin_lock_irqsave(&tegra_powergate_lock, flags);
654
655         status = !!(pmc_read(PWRGATE_STATUS) & (1 << id));
656
657         if (status == new_state) {
658                 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
659                 return 0;
660         }
661
662         if (TEGRA_IS_CPU_POWERGATE_ID(id)) {
663                 /* CPU ungated in s/w only during boot/resume with outer
664                    waiting loop and no contention from other CPUs */
665                 pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
666                 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
667                 return 0;
668         }
669
670         do {
671                 pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
672                 do {
673                         udelay(1);
674                         status = !!(pmc_read(PWRGATE_STATUS) & (1 << id));
675
676                         toggle_timeout--;
677                 } while ((status != new_state) && (toggle_timeout > 0));
678
679                 contention_timeout--;
680         } while ((status != new_state) && (contention_timeout > 0));
681
682         spin_unlock_irqrestore(&tegra_powergate_lock, flags);
683
684         if (status != new_state) {
685                 WARN(1, "Could not set powergate %d to %d", id, new_state);
686                 return -EBUSY;
687         }
688
689         trace_power_domain_target(powergate_partition_info[id].name, new_state,
690                         smp_processor_id());
691 #endif
692
693         return 0;
694 }
695
696 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
697 static bool tegra11x_check_plld_plld2_disable(void)
698 {
699         /* FIXME:
700          * add check for plld and plld2 disable
701          */
702 #define CLK_RST_CONTROLLER_PLLD_BASE_0 0xd0
703 #define CLK_RST_CONTROLLER_PLLD_BASE_0_PLLD_ENABLE_LSB 30
704 #define CLK_RST_CONTROLLER_PLLD2_BASE_0 0x4b8
705 #define CLK_RST_CONTROLLER_PLLD2_BASE_0_PLLD2_ENABLE_LSB 30
706         u32 status;
707         status = clk_rst_read(CLK_RST_CONTROLLER_PLLD_BASE_0);
708         if (status & (1 << CLK_RST_CONTROLLER_PLLD_BASE_0_PLLD_ENABLE_LSB))
709                 return false;
710         status = clk_rst_read(CLK_RST_CONTROLLER_PLLD2_BASE_0);
711         if (status & (1 << CLK_RST_CONTROLLER_PLLD2_BASE_0_PLLD2_ENABLE_LSB))
712                 return false;
713         return true;
714 }
715
716 static bool tegra11x_pg_sw_war_missing(int id)
717 {
718         bool ret;
719
720         switch (id) {
721         case TEGRA_POWERGATE_DISA:
722                 /* FIXME:
723                  * [SW WAR bug 954988]:
724                  * Disable PLLD and PLLD2 by clearing bits:
725 a.      CLK_RST_CONTROLLER_PLLD_BASE_0_PLLD_ENABLE
726 b.      CLK_RST_CONTROLLER_PLLD2_BASE_0_PLLD2_ENABLE
727                  * We should not need to disable PLLD and PLLD2
728                  * for linux/android implementation
729                  * adding check in case PLLD or PLLD2 is/are ON
730                  */
731                 ret = tegra11x_check_plld_plld2_disable();
732                 if (!ret)
733                         return true;
734
735                 break;
736         }
737         return false;
738 }
739 #endif
740
741 #if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
742 static int unpowergate_module(int id)
743 {
744         if (id < 0 || id >= tegra_num_powerdomains)
745                 return -EINVAL;
746         return tegra_powergate_set(id, true);
747 }
748 #endif
749
750 static int powergate_module(int id)
751 {
752 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
753         bool need_sw_war;
754 #endif
755         if (id < 0 || id >= tegra_num_powerdomains)
756                 return -EINVAL;
757
758         mc_flush(id);
759 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
760         need_sw_war = tegra11x_pg_sw_war_missing(id);
761         if (need_sw_war) {
762                 pr_err("Error: missing powergate sw war in file: %s, func: %s, line=%d\n",
763                 __FILE__, __func__, __LINE__);
764                 return -1;
765         }
766 #endif
767         return tegra_powergate_set(id, false);
768 }
769
770 bool tegra_powergate_is_powered(int id)
771 {
772         u32 status;
773
774         if (id < 0 || id >= tegra_num_powerdomains)
775                 return -EINVAL;
776
777         status = pmc_read(PWRGATE_STATUS) & (1 << id);
778         return !!status;
779 }
780 EXPORT_SYMBOL(tegra_powergate_is_powered);
781
782 int tegra_powergate_remove_clamping(int id)
783 {
784         u32 mask;
785         int contention_timeout = 100;
786
787         if (id < 0 || id >= tegra_num_powerdomains)
788                 return -EINVAL;
789
790         /*
791          * PCIE and VDE clamping masks are swapped with respect to their
792          * partition ids
793          */
794         if (id ==  TEGRA_POWERGATE_VDEC)
795                 mask = (1 << TEGRA_POWERGATE_PCIE);
796         else if (id == TEGRA_POWERGATE_PCIE)
797                 mask = (1 << TEGRA_POWERGATE_VDEC);
798         else
799                 mask = (1 << id);
800
801         pmc_write(mask, REMOVE_CLAMPING);
802         /* Wait until clamp is removed */
803         do {
804                 udelay(1);
805                 contention_timeout--;
806         } while ((contention_timeout > 0)
807                         && (pmc_read(REMOVE_CLAMPING) & mask));
808
809         WARN(contention_timeout <= 0, "Couldn't remove clamping");
810
811         return 0;
812 }
813
814 static void get_clk_info(int id)
815 {
816         int idx;
817
818         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
819                 if (!powergate_partition_info[id].clk_info[idx].clk_name)
820                         break;
821                 powergate_partition_info[id].
822                                 clk_info[idx].clk_ptr =
823                                         tegra_get_clock_by_name(
824                         powergate_partition_info[id].clk_info[idx].clk_name);
825         }
826 }
827
828 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
829 static bool tegra11x_pug_clk_n_rst_skip(int id, u32 idx)
830 {
831         switch (id) {
832         case TEGRA_POWERGATE_VENC:
833                 if ((powergate_partition_info[id].clk_info[idx].clk_name) &&
834                         (!(strncmp("csi",
835                         powergate_partition_info[id].clk_info[idx].clk_name,
836                         3)))) {
837                                 /* DIS powered ON then do clk enable CSI */
838                                 if (!tegra_powergate_is_powered(
839                                                 TEGRA_POWERGATE_DISA))
840                                         return true;
841                 }
842                 break;
843         case TEGRA_POWERGATE_DISA:
844                 if ((powergate_partition_info[id].clk_info[idx].clk_name) &&
845                         (!(strncmp("csi",
846                         powergate_partition_info[id].clk_info[idx].clk_name,
847                         3)))) {
848                                 /* DIS powered ON then do clk enable CSI */
849                                 if (!tegra_powergate_is_powered(
850                                                 TEGRA_POWERGATE_VENC))
851                                         return true;
852                 }
853                 break;
854         }
855         return false;
856 }
857 #endif
858
859 static int partition_clk_enable(int id)
860 {
861         int ret;
862         u32 idx;
863         struct clk *clk;
864         struct partition_clk_info *clk_info;
865 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
866         bool skip_enable;
867 #endif
868
869         BUG_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
870
871         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
872 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
873                 skip_enable = tegra11x_pug_clk_n_rst_skip(id, idx);
874                 if (skip_enable)
875                         continue;
876 #endif
877                 clk_info = &powergate_partition_info[id].clk_info[idx];
878                 clk = clk_info->clk_ptr;
879                 if (!clk)
880                         break;
881
882                 if (clk_info->clk_type != RST_ONLY) {
883                         ret = tegra_clk_prepare_enable(clk);
884                         if (ret)
885                                 goto err_clk_en;
886                 }
887         }
888
889         return 0;
890
891 err_clk_en:
892         WARN(1, "Could not enable clk %s", clk->name);
893         while (idx--) {
894                 clk_info = &powergate_partition_info[id].clk_info[idx];
895                 if (clk_info->clk_type != RST_ONLY)
896                         tegra_clk_disable_unprepare(clk_info->clk_ptr);
897         }
898
899         return ret;
900 }
901
902 static int is_partition_clk_disabled(int id)
903 {
904         u32 idx;
905         struct clk *clk;
906         struct partition_clk_info *clk_info;
907         int ret = 0;
908
909         BUG_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
910
911         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
912                 clk_info = &powergate_partition_info[id].clk_info[idx];
913                 clk = clk_info->clk_ptr;
914                 if (!clk)
915                         break;
916
917                 if (clk_info->clk_type != RST_ONLY) {
918                         if (tegra_is_clk_enabled(clk)) {
919                                 ret = -1;
920                                 break;
921                         }
922                 }
923         }
924
925         return ret;
926 }
927
928 static void partition_clk_disable(int id)
929 {
930         u32 idx;
931         struct clk *clk;
932         struct partition_clk_info *clk_info;
933 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
934         bool skip_disable;
935 #endif
936
937         BUG_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
938
939         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
940 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
941                 if (id == TEGRA_POWERGATE_DISA) {
942                         skip_disable = tegra11x_pug_clk_n_rst_skip(id, idx);
943                         if (skip_disable)
944                                 continue;
945                 }
946 #endif
947                 clk_info = &powergate_partition_info[id].clk_info[idx];
948                 clk = clk_info->clk_ptr;
949                 if (!clk)
950                         break;
951
952                 if (clk_info->clk_type != RST_ONLY)
953                         tegra_clk_disable_unprepare(clk);
954         }
955 }
956
957 static void powergate_partition_assert_reset(int id)
958 {
959         u32 idx;
960         struct clk *clk_ptr;
961         struct partition_clk_info *clk_info;
962 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
963         bool skip_reset;
964 #endif
965
966         BUG_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
967
968         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
969 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
970                 if (id == TEGRA_POWERGATE_DISA) {
971                         skip_reset = tegra11x_pug_clk_n_rst_skip(id, idx);
972                         if (skip_reset)
973                                 continue;
974                 }
975 #endif
976                 clk_info = &powergate_partition_info[id].clk_info[idx];
977                 clk_ptr = clk_info->clk_ptr;
978                 if (!clk_ptr)
979                         break;
980                 if (clk_info->clk_type != CLK_ONLY)
981                         tegra_periph_reset_assert(clk_ptr);
982         }
983 }
984
985 static void powergate_partition_deassert_reset(int id)
986 {
987         u32 idx;
988         struct clk *clk_ptr;
989         struct partition_clk_info *clk_info;
990 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
991         bool skip_reset;
992 #endif
993
994         BUG_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
995
996         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
997 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
998                 skip_reset = tegra11x_pug_clk_n_rst_skip(id, idx);
999                 if (skip_reset)
1000                         continue;
1001 #endif
1002                 clk_info = &powergate_partition_info[id].clk_info[idx];
1003                 clk_ptr = clk_info->clk_ptr;
1004                 if (!clk_ptr)
1005                         break;
1006                 if (clk_info->clk_type != CLK_ONLY)
1007                         tegra_periph_reset_deassert(clk_ptr);
1008         }
1009 }
1010
1011 /* Must be called with clk disabled, and returns with clk disabled */
1012 static int tegra_powergate_reset_module(int id)
1013 {
1014         int ret;
1015
1016         powergate_partition_assert_reset(id);
1017
1018         udelay(10);
1019
1020         ret = partition_clk_enable(id);
1021         if (ret)
1022                 return ret;
1023
1024         udelay(10);
1025
1026         powergate_partition_deassert_reset(id);
1027
1028         partition_clk_disable(id);
1029
1030         return 0;
1031 }
1032
1033 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1034 /*
1035  * FIXME: sw war for mipi-cal calibration when unpowergating DISA partition
1036  */
1037 static void tegra11x_mipical_calibrate(int id)
1038 {
1039         struct reg_offset_val {
1040                 u32 offset;
1041                 u32 por_value;
1042         };
1043         u32 status;
1044         unsigned long flags;
1045 #define MIPI_CAL_MIPI_CAL_CTRL_0 0x0
1046 #define MIPI_CAL_CIL_MIPI_CAL_STATUS_0 0x8
1047 #define MIPI_CAL_CILA_MIPI_CAL_CONFIG_0 0x14
1048 #define MIPI_CAL_CILB_MIPI_CAL_CONFIG_0 0x18
1049 #define MIPI_CAL_CILC_MIPI_CAL_CONFIG_0 0x1c
1050 #define MIPI_CAL_CILD_MIPI_CAL_CONFIG_0 0x20
1051 #define MIPI_CAL_CILE_MIPI_CAL_CONFIG_0 0x24
1052 #define MIPI_CAL_DSIA_MIPI_CAL_CONFIG_0 0x38
1053 #define MIPI_CAL_DSIB_MIPI_CAL_CONFIG_0 0x3c
1054 #define MIPI_CAL_DSIC_MIPI_CAL_CONFIG_0 0x40
1055 #define MIPI_CAL_DSID_MIPI_CAL_CONFIG_0 0x44
1056         static struct reg_offset_val mipi_cal_por_values[] = {
1057                 { MIPI_CAL_MIPI_CAL_CTRL_0, 0x2a000000 },
1058                 { MIPI_CAL_CILA_MIPI_CAL_CONFIG_0, 0x00200000 },
1059                 { MIPI_CAL_CILB_MIPI_CAL_CONFIG_0, 0x00200000 },
1060                 { MIPI_CAL_CILC_MIPI_CAL_CONFIG_0, 0x00200000 },
1061                 { MIPI_CAL_CILD_MIPI_CAL_CONFIG_0, 0x00200000 },
1062                 { MIPI_CAL_CILE_MIPI_CAL_CONFIG_0, 0x00000000 },
1063                 { MIPI_CAL_DSIA_MIPI_CAL_CONFIG_0, 0x00200000 },
1064                 { MIPI_CAL_DSIB_MIPI_CAL_CONFIG_0, 0x00200000 },
1065                 { MIPI_CAL_DSIC_MIPI_CAL_CONFIG_0, 0x00200000 },
1066                 { MIPI_CAL_DSID_MIPI_CAL_CONFIG_0, 0x00200000 },
1067         };
1068         int i;
1069
1070         if (id != TEGRA_POWERGATE_DISA)
1071                 return;
1072         spin_lock_irqsave(&tegra_powergate_lock, flags);
1073         /* mipi cal por restore */
1074         for (i = 0; i < ARRAY_SIZE(mipi_cal_por_values); i++) {
1075                 mipi_cal_write(mipi_cal_por_values[i].por_value,
1076                         mipi_cal_por_values[i].offset);
1077         }
1078         /* mipi cal status clear */
1079         status = mipi_cal_read(MIPI_CAL_CIL_MIPI_CAL_STATUS_0);
1080         mipi_cal_write(status, MIPI_CAL_CIL_MIPI_CAL_STATUS_0);
1081         /* mipi cal status read - to flush writes */
1082         status = mipi_cal_read(MIPI_CAL_CIL_MIPI_CAL_STATUS_0);
1083         spin_unlock_irqrestore(&tegra_powergate_lock, flags);
1084 }
1085 #endif
1086
1087 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1088 static bool skip_pg_check(int id, bool is_unpowergate)
1089 {
1090         /*
1091          * FIXME: need to stress test partition power gating before
1092          * enabling power gating for T11x
1093          * List of T11x partition id which skip power gating
1094          */
1095         static int skip_pg_t11x_list[] = {
1096                 /*
1097                  * CPU and 3D partitions enable/disable
1098                  * is managed by respective modules
1099                  */
1100                 TEGRA_POWERGATE_MPE,
1101                 TEGRA_POWERGATE_DISA,
1102                 TEGRA_POWERGATE_DISB,
1103                 TEGRA_POWERGATE_XUSBA,
1104                 TEGRA_POWERGATE_XUSBB,
1105                 TEGRA_POWERGATE_XUSBC,
1106         };
1107         int i;
1108
1109         /*
1110          * skip unnecessary multiple calls e.g. powergate call when
1111          * partition is already powered-off or vice-versa
1112          */
1113         if ((tegra_powergate_is_powered(id) &&
1114                 is_unpowergate) ||
1115                 (!(tegra_powergate_is_powered(id)) &&
1116                 (!is_unpowergate))) {
1117                 pr_err("Partition %s already powered-%s and %spowergate skipped\n",
1118                         tegra_powergate_get_name(id),
1119                         (tegra_powergate_is_powered(id)) ?
1120                         "on" : "off",
1121                         (is_unpowergate) ? "un" : "");
1122                 return true;
1123         }
1124         /* unpowergate is allowed for all partitions */
1125         if (!tegra_powergate_is_powered(id) &&
1126                 is_unpowergate)
1127                 return false;
1128         for (i = 0; i < tegra_num_powerdomains; i++) {
1129                 if (id == skip_pg_t11x_list[i]) {
1130                         pr_err("Partition %s %spowergate skipped\n",
1131                                 tegra_powergate_get_name(id),
1132                                 (is_unpowergate) ? "un" : "");
1133                         return true;
1134                 }
1135         }
1136
1137         return false;
1138 }
1139 #endif
1140
1141 /*
1142  * Must be called with clk disabled, and returns with clk disabled
1143  * Drivers should enable clks for partition. Unpowergates only the
1144  * partition.
1145  */
1146 int tegra_unpowergate_partition(int id)
1147 {
1148         int ret;
1149 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1150         bool is_pg_skip;
1151
1152         is_pg_skip = skip_pg_check(id, true);
1153         if (is_pg_skip)
1154                 return 0;
1155         ret = tegra11x_check_partition_pug_seq(id);
1156         if (ret)
1157                 return ret;
1158
1159         ret = tegra11x_unpowergate(id);
1160         return ret;
1161 #else
1162         /* FIXME: not changing previous chip's power-ungate implementation */
1163
1164         /* If first clk_ptr is null, fill clk info for the partition */
1165         if (!powergate_partition_info[id].clk_info[0].clk_ptr)
1166                 get_clk_info(id);
1167
1168         if (tegra_powergate_is_powered(id))
1169                 return tegra_powergate_reset_module(id);
1170
1171         ret = unpowergate_module(id);
1172         if (ret)
1173                 goto err_power;
1174
1175         powergate_partition_assert_reset(id);
1176
1177         /* Un-Powergating fails if all clks are not enabled */
1178         ret = partition_clk_enable(id);
1179         if (ret)
1180                 goto err_clk_on;
1181
1182         udelay(10);
1183
1184         ret = tegra_powergate_remove_clamping(id);
1185         if (ret)
1186                 goto err_clamp;
1187
1188         udelay(10);
1189
1190         powergate_partition_deassert_reset(id);
1191
1192         mc_flush_done(id);
1193
1194         /* Disable all clks enabled earlier. Drivers should enable clks */
1195         partition_clk_disable(id);
1196
1197         return 0;
1198
1199 err_clamp:
1200         partition_clk_disable(id);
1201 err_clk_on:
1202         powergate_module(id);
1203 err_power:
1204         WARN(1, "Could not Un-Powergate %d", id);
1205         return ret;
1206 #endif
1207 }
1208
1209 int tegra_cpu_powergate_id(int cpuid)
1210 {
1211         if (cpuid > 0 && cpuid < tegra_num_cpu_domains)
1212                 return tegra_cpu_domains[cpuid];
1213
1214         return -EINVAL;
1215 }
1216
1217 int __init tegra_powergate_init(void)
1218 {
1219         switch (tegra_chip_id) {
1220         case TEGRA20:
1221                 tegra_num_powerdomains = 7;
1222                 break;
1223         case TEGRA30:
1224                 tegra_num_powerdomains = 14;
1225                 tegra_num_cpu_domains = 4;
1226                 tegra_cpu_domains = tegra_quad_cpu_domains;
1227                 break;
1228         case TEGRA11X:
1229                 tegra_num_powerdomains = 23;
1230                 tegra_num_cpu_domains = 4;
1231                 tegra_cpu_domains = tegra_quad_cpu_domains;
1232                 break;
1233         default:
1234                 /* Unknown Tegra variant. Disable powergating */
1235                 tegra_num_powerdomains = 0;
1236                 break;
1237         }
1238
1239 #if defined(DEBUG_T11x_POWERGATE)
1240         test_powergate_parts();
1241 #endif
1242 #if defined(DEBUG_T11x_POWERUNGATE)
1243         test_unpowergate_parts();
1244 #endif
1245 #if defined(DEBUG_T11x_POWERGATE_CLK_OFF)
1246         test_powergate_clk_off_parts();
1247 #endif
1248 #if defined(DEBUG_T11x_POWERUNGATE_CLK_ON)
1249         test_unpowergate_clk_on_parts();
1250 #endif
1251         return 0;
1252 }
1253
1254 /*
1255  * Must be called with clk disabled, and returns with clk enabled
1256  * Unpowergates the partition and enables all required clks.
1257  */
1258 int tegra_unpowergate_partition_with_clk_on(int id)
1259 {
1260         int ret = 0;
1261 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1262         bool is_pg_skip;
1263
1264         is_pg_skip = skip_pg_check(id, true);
1265         if (is_pg_skip)
1266                 return 0;
1267 #endif
1268 #if defined(CONFIG_ARCH_TEGRA_3x_SOC)
1269         /* Restrict this functions use to few partitions */
1270         BUG_ON(id != TEGRA_POWERGATE_SATA && id != TEGRA_POWERGATE_PCIE);
1271 #elif defined(CONFIG_ARCH_TEGRA_2x_SOC)
1272         /* Restrict this functions use to few partitions */
1273         BUG_ON(id != TEGRA_POWERGATE_PCIE);
1274 #endif
1275
1276         ret = tegra_unpowergate_partition(id);
1277         if (ret)
1278                 goto err_unpowergating;
1279
1280         /* Enable clks for the partition */
1281         ret = partition_clk_enable(id);
1282         if (ret)
1283                 goto err_unpowergate_clk;
1284
1285         return ret;
1286
1287 err_unpowergate_clk:
1288         tegra_powergate_partition(id);
1289         WARN(1, "Could not Un-Powergate %d, err in enabling clk", id);
1290 err_unpowergating:
1291         WARN(1, "Could not Un-Powergate %d", id);
1292         return ret;
1293 }
1294
1295 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1296 static int tegra11x_powergate_set(int id, bool new_state)
1297 {
1298 #ifndef CONFIG_TEGRA_SIMULATION_PLATFORM
1299         bool status;
1300         unsigned long flags;
1301         /* 10us timeout for toggle operation if it takes affect*/
1302         int toggle_timeout = 10;
1303         /* 100 * 10 = 1000us timeout for toggle command to take affect in case
1304            of contention with h/w initiated CPU power gating */
1305         int contention_timeout = 100;
1306
1307         spin_lock_irqsave(&tegra_powergate_lock, flags);
1308
1309         status = !!(pmc_read(PWRGATE_STATUS) & (1 << id));
1310
1311         if (status == new_state) {
1312                 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
1313                 return 0;
1314         }
1315
1316         pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
1317         do {
1318                 do {
1319                         udelay(1);
1320                         status = !!(pmc_read(PWRGATE_STATUS) & (1 << id));
1321
1322                         toggle_timeout--;
1323                 } while ((status != new_state) && (toggle_timeout > 0));
1324
1325                 contention_timeout--;
1326         } while ((status != new_state) && (contention_timeout > 0));
1327
1328         spin_unlock_irqrestore(&tegra_powergate_lock, flags);
1329
1330         if (status != new_state) {
1331                 WARN(1, "Could not set powergate %d to %d", id, new_state);
1332                 return -EBUSY;
1333         }
1334
1335         trace_power_domain_target(powergate_partition_info[id].name, new_state,
1336                         smp_processor_id());
1337 #endif
1338
1339         return 0;
1340 }
1341
1342 static int tegra11x_powergate(int id)
1343 {
1344         int ret;
1345
1346         /* If first clk_ptr is null, fill clk info for the partition */
1347         if (powergate_partition_info[id].clk_info[0].clk_ptr)
1348                 get_clk_info(id);
1349
1350         ret = partition_clk_enable(id);
1351         if (ret)
1352                 WARN(1, "Couldn't enable clock");
1353
1354         udelay(10);
1355
1356         mc_flush(id);
1357
1358         udelay(10);
1359
1360         powergate_partition_assert_reset(id);
1361
1362         udelay(10);
1363
1364         /* Powergating is done only if refcnt of all clks is 0 */
1365         partition_clk_disable(id);
1366
1367         udelay(10);
1368
1369         ret = tegra11x_powergate_set(id, false);
1370         if (ret)
1371                 goto err_power_off;
1372
1373         return 0;
1374
1375 err_power_off:
1376         WARN(1, "Could not Powergate Partition %d", id);
1377         return ret;
1378 }
1379
1380 static int tegra11x_unpowergate(int id)
1381 {
1382         int ret;
1383         /* If first clk_ptr is null, fill clk info for the partition */
1384         if (!powergate_partition_info[id].clk_info[0].clk_ptr)
1385                 get_clk_info(id);
1386
1387         if (tegra_powergate_is_powered(id))
1388                 return tegra_powergate_reset_module(id);
1389
1390         ret = tegra11x_powergate_set(id, true);
1391         if (ret)
1392                 goto err_power;
1393
1394         udelay(10);
1395
1396         /* Un-Powergating fails if all clks are not enabled */
1397         ret = partition_clk_enable(id);
1398         if (ret)
1399                 goto err_clk_on;
1400
1401         udelay(10);
1402
1403         ret = tegra_powergate_remove_clamping(id);
1404         if (ret)
1405                 goto err_clamp;
1406
1407         udelay(10);
1408
1409 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1410         tegra11x_mipical_calibrate(id);
1411 #endif
1412         powergate_partition_deassert_reset(id);
1413
1414         udelay(10);
1415
1416         mc_flush_done(id);
1417
1418         udelay(10);
1419
1420         /* Disable all clks enabled earlier. Drivers should enable clks */
1421         partition_clk_disable(id);
1422
1423         return 0;
1424
1425 err_clamp:
1426         partition_clk_disable(id);
1427 err_clk_on:
1428         powergate_module(id);
1429 err_power:
1430         WARN(1, "Could not Un-Powergate %d", id);
1431         return ret;
1432 }
1433
1434 static int tegra11x_powergate_partition(int id)
1435 {
1436         int ret;
1437
1438         if (tegra_powergate_is_powered(id)) {
1439                 ret = is_partition_clk_disabled(id);
1440                 if (ret < 0) {
1441                         /* clock enabled */
1442                         ret = tegra_powergate_partition_with_clk_off(id);
1443                         if (ret < 0)
1444                                 return ret;
1445                 } else {
1446                         ret = tegra_powergate_partition(id);
1447                         if (ret < 0)
1448                                 return ret;
1449                 }
1450         }
1451         return 0;
1452 }
1453
1454 static int tegra11x_unpowergate_partition(int id)
1455 {
1456         int ret;
1457
1458         if (!tegra_powergate_is_powered(id)) {
1459                 ret = is_partition_clk_disabled(id);
1460                 if (ret) {
1461                         /* clock disabled */
1462                         ret = tegra_unpowergate_partition_with_clk_on(id);
1463                         if (ret < 0)
1464                                 return ret;
1465                 } else {
1466                         ret = tegra_unpowergate_partition(id);
1467                         if (ret < 0)
1468                                 return ret;
1469                 }
1470         }
1471         return 0;
1472 }
1473
1474 /*
1475  * Tegra11x has powergate dependencies between partitions.
1476  * This function captures the dependencies.
1477  */
1478 static int tegra11x_check_partition_pg_seq(int id)
1479 {
1480         int ret;
1481
1482         switch (id) {
1483         case TEGRA_POWERGATE_DISA:
1484                 ret = tegra11x_powergate_partition(TEGRA_POWERGATE_VENC);
1485                 if (ret < 0)
1486                         return ret;
1487                 ret = tegra11x_powergate_partition(TEGRA_POWERGATE_DISB);
1488                 if (ret < 0)
1489                         return ret;
1490                 break;
1491         }
1492         return 0;
1493 }
1494
1495 /*
1496  * This function captures power-ungate dependencies between tegra11x partitions
1497  */
1498 static int tegra11x_check_partition_pug_seq(int id)
1499 {
1500         int ret;
1501
1502         switch (id) {
1503         case TEGRA_POWERGATE_DISB:
1504         case TEGRA_POWERGATE_VENC:
1505                 ret = tegra11x_unpowergate_partition(TEGRA_POWERGATE_DISA);
1506                 if (ret < 0)
1507                         return ret;
1508
1509                 break;
1510         }
1511         return 0;
1512 }
1513 #endif
1514
1515 /*
1516  * Must be called with clk disabled. Powergates the partition only
1517  */
1518 int tegra_powergate_partition(int id)
1519 {
1520         int ret;
1521 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1522         bool is_pg_skip;
1523
1524         is_pg_skip = skip_pg_check(id, false);
1525         if (is_pg_skip)
1526                 return 0;
1527
1528         ret = tegra11x_check_partition_pg_seq(id);
1529         if (ret)
1530                 return ret;
1531
1532         /* All Tegra11x partition powergate */
1533         ret = tegra11x_powergate(id);
1534         return ret;
1535 #else
1536         /* FIXME: not changing previous chip's powergate implementation */
1537
1538         /* If first clk_ptr is null, fill clk info for the partition */
1539         if (powergate_partition_info[id].clk_info[0].clk_ptr)
1540                 get_clk_info(id);
1541
1542         powergate_partition_assert_reset(id);
1543
1544         /* Powergating is done only if refcnt of all clks is 0 */
1545         ret = is_partition_clk_disabled(id);
1546         if (ret)
1547                 goto err_clk_off;
1548
1549         ret = powergate_module(id);
1550         if (ret)
1551                 goto err_power_off;
1552
1553         return 0;
1554
1555 err_power_off:
1556         WARN(1, "Could not Powergate Partition %d", id);
1557 err_clk_off:
1558         WARN(1, "Could not Powergate Partition %d, all clks not disabled", id);
1559         return ret;
1560 #endif
1561 }
1562
1563 int tegra_powergate_partition_with_clk_off(int id)
1564 {
1565         int ret = 0;
1566 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1567         bool is_pg_skip;
1568
1569         is_pg_skip = skip_pg_check(id, false);
1570         if (is_pg_skip)
1571                 return 0;
1572 #endif
1573 #if defined(CONFIG_ARCH_TEGRA_3x_SOC)
1574         /* Restrict functions use to selected partitions */
1575         BUG_ON(id != TEGRA_POWERGATE_PCIE && id != TEGRA_POWERGATE_SATA);
1576 #elif defined(CONFIG_ARCH_TEGRA_2x_SOC)
1577         /* Restrict functions use to selected partitions */
1578         BUG_ON(id != TEGRA_POWERGATE_PCIE);
1579 #endif
1580         /* Disable clks for the partition */
1581         partition_clk_disable(id);
1582
1583         ret = is_partition_clk_disabled(id);
1584         if (ret)
1585                 goto err_powergate_clk;
1586
1587         ret = tegra_powergate_partition(id);
1588         if (ret)
1589                 goto err_powergating;
1590
1591         return ret;
1592
1593 err_powergate_clk:
1594         WARN(1, "Could not Powergate Partition %d, all clks not disabled", id);
1595 err_powergating:
1596         partition_clk_enable(id);
1597         WARN(1, "Could not Powergate Partition %d", id);
1598         return ret;
1599 }
1600
1601 #if defined(DEBUG_T11x_POWERGATE)
1602 static void test_powergate_parts(void)
1603 {
1604         int i;
1605
1606         for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
1607                 tegra_powergate_partition(i);
1608 }
1609 #endif
1610
1611 #if defined(DEBUG_T11x_POWERUNGATE)
1612 static void test_powerungate_parts(void)
1613 {
1614         int i;
1615
1616         for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
1617                 tegra_unpowergate_partition(i);
1618 }
1619 #endif
1620
1621 #if defined(DEBUG_T11x_POWERGATE_CLK_OFF)
1622 static void test_powergate_clk_off_parts(void)
1623 {
1624         int i;
1625
1626         for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
1627                 tegra_powergate_partition_with_clk_off(i);
1628 }
1629 #endif
1630
1631 #if defined(DEBUG_T11x_POWERUNGATE_CLK_OFF)
1632 static void test_unpowergate_clk_on_parts(void)
1633 {
1634         int i;
1635
1636         for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
1637                 tegra_unpowergate_partition_with_clk_on(i);
1638 }
1639 #endif
1640
1641 const char *tegra_powergate_get_name(int id)
1642 {
1643         if (id < 0 || id >= TEGRA_NUM_POWERGATE)
1644                 return "invalid";
1645
1646         return powergate_partition_info[id].name;
1647 }
1648
1649 #ifdef CONFIG_DEBUG_FS
1650
1651 static int powergate_show(struct seq_file *s, void *data)
1652 {
1653         int i;
1654         const char *name;
1655
1656         seq_printf(s, " powergate powered\n");
1657         seq_printf(s, "------------------\n");
1658
1659         for (i = 0; i < tegra_num_powerdomains; i++) {
1660                 name = tegra_powergate_get_name(i);
1661                 if (name)
1662                         seq_printf(s, " %9s %7s\n", name,
1663                                 tegra_powergate_is_powered(i) ? "yes" : "no");
1664         }
1665
1666         return 0;
1667 }
1668
1669 static int powergate_open(struct inode *inode, struct file *file)
1670 {
1671         return single_open(file, powergate_show, inode->i_private);
1672 }
1673
1674 static const struct file_operations powergate_fops = {
1675         .open           = powergate_open,
1676         .read           = seq_read,
1677         .llseek         = seq_lseek,
1678         .release        = single_release,
1679 };
1680
1681 int __init tegra_powergate_debugfs_init(void)
1682 {
1683         struct dentry *d;
1684
1685         if (powergate_name) {
1686                 d = debugfs_create_file("powergate", S_IRUGO, NULL, NULL,
1687                         &powergate_fops);
1688                 if (!d)
1689                         return -ENOMEM;
1690         }
1691
1692         return 0;
1693 }
1694
1695 #endif