ARM: tegra: power gate skip update
[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_DISA,
1101                 TEGRA_POWERGATE_DISB,
1102                 TEGRA_POWERGATE_XUSBA,
1103                 TEGRA_POWERGATE_XUSBB,
1104                 TEGRA_POWERGATE_XUSBC,
1105         };
1106         int i;
1107
1108         /*
1109          * skip unnecessary multiple calls e.g. powergate call when
1110          * partition is already powered-off or vice-versa
1111          */
1112         if ((tegra_powergate_is_powered(id) &&
1113                 is_unpowergate) ||
1114                 (!(tegra_powergate_is_powered(id)) &&
1115                 (!is_unpowergate))) {
1116                 pr_err("Partition %s already powered-%s and %spowergate skipped\n",
1117                         tegra_powergate_get_name(id),
1118                         (tegra_powergate_is_powered(id)) ?
1119                         "on" : "off",
1120                         (is_unpowergate) ? "un" : "");
1121                 return true;
1122         }
1123         /* unpowergate is allowed for all partitions */
1124         if (!tegra_powergate_is_powered(id) &&
1125                 is_unpowergate)
1126                 return false;
1127         for (i = 0; i < tegra_num_powerdomains; i++) {
1128                 if (id == skip_pg_t11x_list[i]) {
1129                         pr_err("Partition %s %spowergate skipped\n",
1130                                 tegra_powergate_get_name(id),
1131                                 (is_unpowergate) ? "un" : "");
1132                         return true;
1133                 }
1134         }
1135
1136         return false;
1137 }
1138 #endif
1139
1140 /*
1141  * Must be called with clk disabled, and returns with clk disabled
1142  * Drivers should enable clks for partition. Unpowergates only the
1143  * partition.
1144  */
1145 int tegra_unpowergate_partition(int id)
1146 {
1147         int ret;
1148 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1149         bool is_pg_skip;
1150
1151         is_pg_skip = skip_pg_check(id, true);
1152         if (is_pg_skip)
1153                 return 0;
1154         ret = tegra11x_check_partition_pug_seq(id);
1155         if (ret)
1156                 return ret;
1157
1158         ret = tegra11x_unpowergate(id);
1159         return ret;
1160 #else
1161         /* FIXME: not changing previous chip's power-ungate implementation */
1162
1163         /* If first clk_ptr is null, fill clk info for the partition */
1164         if (!powergate_partition_info[id].clk_info[0].clk_ptr)
1165                 get_clk_info(id);
1166
1167         if (tegra_powergate_is_powered(id))
1168                 return tegra_powergate_reset_module(id);
1169
1170         ret = unpowergate_module(id);
1171         if (ret)
1172                 goto err_power;
1173
1174         powergate_partition_assert_reset(id);
1175
1176         /* Un-Powergating fails if all clks are not enabled */
1177         ret = partition_clk_enable(id);
1178         if (ret)
1179                 goto err_clk_on;
1180
1181         udelay(10);
1182
1183         ret = tegra_powergate_remove_clamping(id);
1184         if (ret)
1185                 goto err_clamp;
1186
1187         udelay(10);
1188
1189         powergate_partition_deassert_reset(id);
1190
1191         mc_flush_done(id);
1192
1193         /* Disable all clks enabled earlier. Drivers should enable clks */
1194         partition_clk_disable(id);
1195
1196         return 0;
1197
1198 err_clamp:
1199         partition_clk_disable(id);
1200 err_clk_on:
1201         powergate_module(id);
1202 err_power:
1203         WARN(1, "Could not Un-Powergate %d", id);
1204         return ret;
1205 #endif
1206 }
1207
1208 int tegra_cpu_powergate_id(int cpuid)
1209 {
1210         if (cpuid > 0 && cpuid < tegra_num_cpu_domains)
1211                 return tegra_cpu_domains[cpuid];
1212
1213         return -EINVAL;
1214 }
1215
1216 int __init tegra_powergate_init(void)
1217 {
1218         switch (tegra_chip_id) {
1219         case TEGRA20:
1220                 tegra_num_powerdomains = 7;
1221                 break;
1222         case TEGRA30:
1223                 tegra_num_powerdomains = 14;
1224                 tegra_num_cpu_domains = 4;
1225                 tegra_cpu_domains = tegra_quad_cpu_domains;
1226                 break;
1227         case TEGRA11X:
1228                 tegra_num_powerdomains = 23;
1229                 tegra_num_cpu_domains = 4;
1230                 tegra_cpu_domains = tegra_quad_cpu_domains;
1231                 break;
1232         default:
1233                 /* Unknown Tegra variant. Disable powergating */
1234                 tegra_num_powerdomains = 0;
1235                 break;
1236         }
1237
1238 #if defined(DEBUG_T11x_POWERGATE)
1239         test_powergate_parts();
1240 #endif
1241 #if defined(DEBUG_T11x_POWERUNGATE)
1242         test_unpowergate_parts();
1243 #endif
1244 #if defined(DEBUG_T11x_POWERGATE_CLK_OFF)
1245         test_powergate_clk_off_parts();
1246 #endif
1247 #if defined(DEBUG_T11x_POWERUNGATE_CLK_ON)
1248         test_unpowergate_clk_on_parts();
1249 #endif
1250         return 0;
1251 }
1252
1253 /*
1254  * Must be called with clk disabled, and returns with clk enabled
1255  * Unpowergates the partition and enables all required clks.
1256  */
1257 int tegra_unpowergate_partition_with_clk_on(int id)
1258 {
1259         int ret = 0;
1260 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1261         bool is_pg_skip;
1262
1263         is_pg_skip = skip_pg_check(id, true);
1264         if (is_pg_skip)
1265                 return 0;
1266 #endif
1267 #if defined(CONFIG_ARCH_TEGRA_3x_SOC)
1268         /* Restrict this functions use to few partitions */
1269         BUG_ON(id != TEGRA_POWERGATE_SATA && id != TEGRA_POWERGATE_PCIE);
1270 #elif defined(CONFIG_ARCH_TEGRA_2x_SOC)
1271         /* Restrict this functions use to few partitions */
1272         BUG_ON(id != TEGRA_POWERGATE_PCIE);
1273 #endif
1274
1275         ret = tegra_unpowergate_partition(id);
1276         if (ret)
1277                 goto err_unpowergating;
1278
1279         /* Enable clks for the partition */
1280         ret = partition_clk_enable(id);
1281         if (ret)
1282                 goto err_unpowergate_clk;
1283
1284         return ret;
1285
1286 err_unpowergate_clk:
1287         tegra_powergate_partition(id);
1288         WARN(1, "Could not Un-Powergate %d, err in enabling clk", id);
1289 err_unpowergating:
1290         WARN(1, "Could not Un-Powergate %d", id);
1291         return ret;
1292 }
1293
1294 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1295 static int tegra11x_powergate_set(int id, bool new_state)
1296 {
1297 #ifndef CONFIG_TEGRA_SIMULATION_PLATFORM
1298         bool status;
1299         unsigned long flags;
1300         /* 10us timeout for toggle operation if it takes affect*/
1301         int toggle_timeout = 10;
1302         /* 100 * 10 = 1000us timeout for toggle command to take affect in case
1303            of contention with h/w initiated CPU power gating */
1304         int contention_timeout = 100;
1305
1306         spin_lock_irqsave(&tegra_powergate_lock, flags);
1307
1308         status = !!(pmc_read(PWRGATE_STATUS) & (1 << id));
1309
1310         if (status == new_state) {
1311                 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
1312                 return 0;
1313         }
1314
1315         pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
1316         do {
1317                 do {
1318                         udelay(1);
1319                         status = !!(pmc_read(PWRGATE_STATUS) & (1 << id));
1320
1321                         toggle_timeout--;
1322                 } while ((status != new_state) && (toggle_timeout > 0));
1323
1324                 contention_timeout--;
1325         } while ((status != new_state) && (contention_timeout > 0));
1326
1327         spin_unlock_irqrestore(&tegra_powergate_lock, flags);
1328
1329         if (status != new_state) {
1330                 WARN(1, "Could not set powergate %d to %d", id, new_state);
1331                 return -EBUSY;
1332         }
1333
1334         trace_power_domain_target(powergate_partition_info[id].name, new_state,
1335                         smp_processor_id());
1336 #endif
1337
1338         return 0;
1339 }
1340
1341 static int tegra11x_powergate(int id)
1342 {
1343         int ret;
1344
1345         /* If first clk_ptr is null, fill clk info for the partition */
1346         if (powergate_partition_info[id].clk_info[0].clk_ptr)
1347                 get_clk_info(id);
1348
1349         ret = partition_clk_enable(id);
1350         if (ret)
1351                 WARN(1, "Couldn't enable clock");
1352
1353         udelay(10);
1354
1355         mc_flush(id);
1356
1357         udelay(10);
1358
1359         powergate_partition_assert_reset(id);
1360
1361         udelay(10);
1362
1363         /* Powergating is done only if refcnt of all clks is 0 */
1364         partition_clk_disable(id);
1365
1366         udelay(10);
1367
1368         ret = tegra11x_powergate_set(id, false);
1369         if (ret)
1370                 goto err_power_off;
1371
1372         return 0;
1373
1374 err_power_off:
1375         WARN(1, "Could not Powergate Partition %d", id);
1376         return ret;
1377 }
1378
1379 static int tegra11x_unpowergate(int id)
1380 {
1381         int ret;
1382         /* If first clk_ptr is null, fill clk info for the partition */
1383         if (!powergate_partition_info[id].clk_info[0].clk_ptr)
1384                 get_clk_info(id);
1385
1386         if (tegra_powergate_is_powered(id))
1387                 return tegra_powergate_reset_module(id);
1388
1389         ret = tegra11x_powergate_set(id, true);
1390         if (ret)
1391                 goto err_power;
1392
1393         udelay(10);
1394
1395         /* Un-Powergating fails if all clks are not enabled */
1396         ret = partition_clk_enable(id);
1397         if (ret)
1398                 goto err_clk_on;
1399
1400         udelay(10);
1401
1402         ret = tegra_powergate_remove_clamping(id);
1403         if (ret)
1404                 goto err_clamp;
1405
1406         udelay(10);
1407
1408 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1409         tegra11x_mipical_calibrate(id);
1410 #endif
1411         powergate_partition_deassert_reset(id);
1412
1413         udelay(10);
1414
1415         mc_flush_done(id);
1416
1417         udelay(10);
1418
1419         /* Disable all clks enabled earlier. Drivers should enable clks */
1420         partition_clk_disable(id);
1421
1422         return 0;
1423
1424 err_clamp:
1425         partition_clk_disable(id);
1426 err_clk_on:
1427         powergate_module(id);
1428 err_power:
1429         WARN(1, "Could not Un-Powergate %d", id);
1430         return ret;
1431 }
1432
1433 static int tegra11x_powergate_partition(int id)
1434 {
1435         int ret;
1436
1437         if (tegra_powergate_is_powered(id)) {
1438                 ret = is_partition_clk_disabled(id);
1439                 if (ret < 0) {
1440                         /* clock enabled */
1441                         ret = tegra_powergate_partition_with_clk_off(id);
1442                         if (ret < 0)
1443                                 return ret;
1444                 } else {
1445                         ret = tegra_powergate_partition(id);
1446                         if (ret < 0)
1447                                 return ret;
1448                 }
1449         }
1450         return 0;
1451 }
1452
1453 static int tegra11x_unpowergate_partition(int id)
1454 {
1455         int ret;
1456
1457         if (!tegra_powergate_is_powered(id)) {
1458                 ret = is_partition_clk_disabled(id);
1459                 if (ret) {
1460                         /* clock disabled */
1461                         ret = tegra_unpowergate_partition_with_clk_on(id);
1462                         if (ret < 0)
1463                                 return ret;
1464                 } else {
1465                         ret = tegra_unpowergate_partition(id);
1466                         if (ret < 0)
1467                                 return ret;
1468                 }
1469         }
1470         return 0;
1471 }
1472
1473 /*
1474  * Tegra11x has powergate dependencies between partitions.
1475  * This function captures the dependencies.
1476  */
1477 static int tegra11x_check_partition_pg_seq(int id)
1478 {
1479         int ret;
1480
1481         switch (id) {
1482         case TEGRA_POWERGATE_DISA:
1483                 ret = tegra11x_powergate_partition(TEGRA_POWERGATE_VENC);
1484                 if (ret < 0)
1485                         return ret;
1486                 ret = tegra11x_powergate_partition(TEGRA_POWERGATE_DISB);
1487                 if (ret < 0)
1488                         return ret;
1489                 break;
1490         }
1491         return 0;
1492 }
1493
1494 /*
1495  * This function captures power-ungate dependencies between tegra11x partitions
1496  */
1497 static int tegra11x_check_partition_pug_seq(int id)
1498 {
1499         int ret;
1500
1501         switch (id) {
1502         case TEGRA_POWERGATE_DISB:
1503         case TEGRA_POWERGATE_VENC:
1504                 ret = tegra11x_unpowergate_partition(TEGRA_POWERGATE_DISA);
1505                 if (ret < 0)
1506                         return ret;
1507
1508                 break;
1509         }
1510         return 0;
1511 }
1512 #endif
1513
1514 /*
1515  * Must be called with clk disabled. Powergates the partition only
1516  */
1517 int tegra_powergate_partition(int id)
1518 {
1519         int ret;
1520 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1521         bool is_pg_skip;
1522
1523         is_pg_skip = skip_pg_check(id, false);
1524         if (is_pg_skip)
1525                 return 0;
1526
1527         ret = tegra11x_check_partition_pg_seq(id);
1528         if (ret)
1529                 return ret;
1530
1531         /* All Tegra11x partition powergate */
1532         ret = tegra11x_powergate(id);
1533         return ret;
1534 #else
1535         /* FIXME: not changing previous chip's powergate implementation */
1536
1537         /* If first clk_ptr is null, fill clk info for the partition */
1538         if (powergate_partition_info[id].clk_info[0].clk_ptr)
1539                 get_clk_info(id);
1540
1541         powergate_partition_assert_reset(id);
1542
1543         /* Powergating is done only if refcnt of all clks is 0 */
1544         ret = is_partition_clk_disabled(id);
1545         if (ret)
1546                 goto err_clk_off;
1547
1548         ret = powergate_module(id);
1549         if (ret)
1550                 goto err_power_off;
1551
1552         return 0;
1553
1554 err_power_off:
1555         WARN(1, "Could not Powergate Partition %d", id);
1556 err_clk_off:
1557         WARN(1, "Could not Powergate Partition %d, all clks not disabled", id);
1558         return ret;
1559 #endif
1560 }
1561
1562 int tegra_powergate_partition_with_clk_off(int id)
1563 {
1564         int ret = 0;
1565 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
1566         bool is_pg_skip;
1567
1568         is_pg_skip = skip_pg_check(id, false);
1569         if (is_pg_skip)
1570                 return 0;
1571 #endif
1572 #if defined(CONFIG_ARCH_TEGRA_3x_SOC)
1573         /* Restrict functions use to selected partitions */
1574         BUG_ON(id != TEGRA_POWERGATE_PCIE && id != TEGRA_POWERGATE_SATA);
1575 #elif defined(CONFIG_ARCH_TEGRA_2x_SOC)
1576         /* Restrict functions use to selected partitions */
1577         BUG_ON(id != TEGRA_POWERGATE_PCIE);
1578 #endif
1579         /* Disable clks for the partition */
1580         partition_clk_disable(id);
1581
1582         ret = is_partition_clk_disabled(id);
1583         if (ret)
1584                 goto err_powergate_clk;
1585
1586         ret = tegra_powergate_partition(id);
1587         if (ret)
1588                 goto err_powergating;
1589
1590         return ret;
1591
1592 err_powergate_clk:
1593         WARN(1, "Could not Powergate Partition %d, all clks not disabled", id);
1594 err_powergating:
1595         partition_clk_enable(id);
1596         WARN(1, "Could not Powergate Partition %d", id);
1597         return ret;
1598 }
1599
1600 #if defined(DEBUG_T11x_POWERGATE)
1601 static void test_powergate_parts(void)
1602 {
1603         int i;
1604
1605         for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
1606                 tegra_powergate_partition(i);
1607 }
1608 #endif
1609
1610 #if defined(DEBUG_T11x_POWERUNGATE)
1611 static void test_powerungate_parts(void)
1612 {
1613         int i;
1614
1615         for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
1616                 tegra_unpowergate_partition(i);
1617 }
1618 #endif
1619
1620 #if defined(DEBUG_T11x_POWERGATE_CLK_OFF)
1621 static void test_powergate_clk_off_parts(void)
1622 {
1623         int i;
1624
1625         for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
1626                 tegra_powergate_partition_with_clk_off(i);
1627 }
1628 #endif
1629
1630 #if defined(DEBUG_T11x_POWERUNGATE_CLK_OFF)
1631 static void test_unpowergate_clk_on_parts(void)
1632 {
1633         int i;
1634
1635         for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
1636                 tegra_unpowergate_partition_with_clk_on(i);
1637 }
1638 #endif
1639
1640 const char *tegra_powergate_get_name(int id)
1641 {
1642         if (id < 0 || id >= TEGRA_NUM_POWERGATE)
1643                 return "invalid";
1644
1645         return powergate_partition_info[id].name;
1646 }
1647
1648 #ifdef CONFIG_DEBUG_FS
1649
1650 static int powergate_show(struct seq_file *s, void *data)
1651 {
1652         int i;
1653         const char *name;
1654
1655         seq_printf(s, " powergate powered\n");
1656         seq_printf(s, "------------------\n");
1657
1658         for (i = 0; i < tegra_num_powerdomains; i++) {
1659                 name = tegra_powergate_get_name(i);
1660                 if (name)
1661                         seq_printf(s, " %9s %7s\n", name,
1662                                 tegra_powergate_is_powered(i) ? "yes" : "no");
1663         }
1664
1665         return 0;
1666 }
1667
1668 static int powergate_open(struct inode *inode, struct file *file)
1669 {
1670         return single_open(file, powergate_show, inode->i_private);
1671 }
1672
1673 static const struct file_operations powergate_fops = {
1674         .open           = powergate_open,
1675         .read           = seq_read,
1676         .llseek         = seq_lseek,
1677         .release        = single_release,
1678 };
1679
1680 int __init tegra_powergate_debugfs_init(void)
1681 {
1682         struct dentry *d;
1683
1684         if (powergate_name) {
1685                 d = debugfs_create_file("powergate", S_IRUGO, NULL, NULL,
1686                         &powergate_fops);
1687                 if (!d)
1688                         return -ENOMEM;
1689         }
1690
1691         return 0;
1692 }
1693
1694 #endif