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