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