1fba772c0e665c4fa9bb97b0a88d0fa5353d7591
[linux-2.6.git] / arch / arm / mach-tegra / powergate-t11x.c
1 /*
2  * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  */
14
15 #include <linux/spinlock.h>
16 #include <linux/delay.h>
17
18 #include <asm/atomic.h>
19
20 #include <mach/powergate.h>
21
22 #include "powergate-priv.h"
23 #include "powergate-ops-txx.h"
24 #include "powergate-ops-t1xx.h"
25
26 enum mc_client {
27         MC_CLIENT_AVPC          = 1,
28         MC_CLIENT_DC            = 2,
29         MC_CLIENT_DCB           = 3,
30         MC_CLIENT_EPP           = 4,
31         MC_CLIENT_G2            = 5,
32         MC_CLIENT_HC            = 6,
33         MC_CLIENT_HDA           = 7,
34         MC_CLIENT_ISP           = 8,
35         MC_CLIENT_MPCORE        = 9,
36         MC_CLIENT_MPCORELP      = 10,
37         MC_CLIENT_MSENC         = 11,
38         MC_CLIENT_NV            = 12,
39         MC_CLIENT_PPCS          = 14,
40         MC_CLIENT_VDE           = 16,
41         MC_CLIENT_VI            = 17,
42         MC_CLIENT_XUSB_HOST     = 19,
43         MC_CLIENT_XUSB_DEV      = 20,
44         MC_CLIENT_EMUCIF        = 21,
45         MC_CLIENT_TSEC          = 22,
46         MC_CLIENT_LAST          = -1,
47         MC_CLIENT_AFI           = MC_CLIENT_LAST,
48         MC_CLIENT_MPE           = MC_CLIENT_LAST,
49         MC_CLIENT_NV2           = MC_CLIENT_LAST,
50         MC_CLIENT_SATA          = MC_CLIENT_LAST,
51 };
52
53 struct tegra11x_powergate_mc_client_info {
54         enum mc_client hot_reset_clients[MAX_HOTRESET_CLIENT_NUM];
55 };
56
57 static struct tegra11x_powergate_mc_client_info tegra11x_pg_mc_info[] = {
58         [TEGRA_POWERGATE_3D] = {
59                 .hot_reset_clients = {
60                         [0] = MC_CLIENT_NV,
61                         [1] = MC_CLIENT_LAST,
62                 },
63         },
64         [TEGRA_POWERGATE_VDEC] = {
65                 .hot_reset_clients = {
66                         [0] = MC_CLIENT_VDE,
67                         [1] = MC_CLIENT_LAST,
68                 },
69         },
70         [TEGRA_POWERGATE_MPE] = {
71                 .hot_reset_clients = {
72                         [0] = MC_CLIENT_MSENC,
73                         [1] = MC_CLIENT_LAST,
74                 },
75         },
76         [TEGRA_POWERGATE_VENC] = {
77                 .hot_reset_clients = {
78                         [0] = MC_CLIENT_ISP,
79                         [1] = MC_CLIENT_VI,
80                         [2] = MC_CLIENT_LAST,
81                 },
82         },
83         [TEGRA_POWERGATE_HEG] = {
84                 .hot_reset_clients = {
85                         [0] = MC_CLIENT_G2,
86                         [1] = MC_CLIENT_EPP,
87                         [2] = MC_CLIENT_LAST,
88                 },
89         },
90         [TEGRA_POWERGATE_DISA] = {
91                 .hot_reset_clients = {
92                         [0] = MC_CLIENT_DC,
93                         [1] = MC_CLIENT_LAST,
94                 },
95         },
96         [TEGRA_POWERGATE_DISB] = {
97                 .hot_reset_clients = {
98                         [0] = MC_CLIENT_DCB,
99                         [1] = MC_CLIENT_LAST,
100                 },
101         },
102         [TEGRA_POWERGATE_XUSBA] = {
103                 .hot_reset_clients = {
104                         [0] = MC_CLIENT_LAST,
105                 },
106         },
107         [TEGRA_POWERGATE_XUSBB] = {
108                 .hot_reset_clients = {
109                         [0] = MC_CLIENT_XUSB_DEV,
110                         [1] = MC_CLIENT_LAST
111                 },
112         },
113         [TEGRA_POWERGATE_XUSBC] = {
114                 .hot_reset_clients = {
115                         [0] = MC_CLIENT_XUSB_HOST,
116                         [1] = MC_CLIENT_LAST,
117                 },
118         },
119 };
120
121 static struct powergate_partition_info tegra11x_powergate_partition_info[] = {
122         [TEGRA_POWERGATE_3D] = {
123                 .name = "3d",
124                 .clk_info = {
125                         [0] = { .clk_name = "3d", .clk_type = CLK_AND_RST },
126                 },
127         },
128         [TEGRA_POWERGATE_VDEC] = {
129                 .name = "vde",
130                 .clk_info = {
131                         [0] = { .clk_name = "vde", .clk_type = CLK_AND_RST },
132                 },
133         },
134         [TEGRA_POWERGATE_MPE] = {
135                 .name = "mpe",
136                 .clk_info = {
137                         [0] = { .clk_name = "msenc.cbus", .clk_type = CLK_AND_RST },
138                 },
139         },
140         [TEGRA_POWERGATE_VENC] = {
141                 .name = "ve",
142                 .clk_info = {
143                         [0] = { .clk_name = "isp", .clk_type = CLK_AND_RST },
144                         [1] = { .clk_name = "vi", .clk_type = CLK_AND_RST },
145                         [2] = { .clk_name = "csi", .clk_type = CLK_AND_RST },
146                 },
147         },
148         [TEGRA_POWERGATE_HEG] = {
149                 .name = "heg",
150                 .clk_info = {
151                         [0] = { .clk_name = "2d.cbus", .clk_type = CLK_AND_RST },
152                         [1] = { .clk_name = "epp.cbus", .clk_type = CLK_AND_RST },
153                 },
154         },
155         [TEGRA_POWERGATE_DISA] = {
156                 .name = "disa",
157                 .clk_info = {
158                         [0] = { .clk_name = "disp1", .clk_type = CLK_AND_RST },
159                         [1] = { .clk_name = "dsia", .clk_type = CLK_AND_RST },
160                         [2] = { .clk_name = "dsib", .clk_type = CLK_AND_RST },
161                         [3] = { .clk_name = "csi", .clk_type = CLK_AND_RST },
162                         [4] = { .clk_name = "mipi-cal", .clk_type = CLK_AND_RST },
163                 },
164         },
165         [TEGRA_POWERGATE_DISB] = {
166                 .name = "disb",
167                 .clk_info = {
168                         [0] = { .clk_name = "disp2", .clk_type = CLK_AND_RST },
169                         [1] = { .clk_name = "hdmi", .clk_type = CLK_AND_RST },
170                 },
171         },
172         [TEGRA_POWERGATE_XUSBA] = {
173                 .name = "xusba",
174                 .clk_info = {
175                         [0] = { .clk_name = "xusb_ss", .clk_type = CLK_AND_RST },
176                 },
177         },
178         [TEGRA_POWERGATE_XUSBB] = {
179                 .name = "xusbb",
180                 .clk_info = {
181                         [0] = { .clk_name = "xusb_dev", .clk_type = CLK_AND_RST },
182                 },
183         },
184         [TEGRA_POWERGATE_XUSBC] = {
185                 .name = "xusbc",
186                 .clk_info = {
187                         [0] = { .clk_name = "xusb_host", .clk_type = CLK_AND_RST },
188                 },
189         },
190 };
191
192 static atomic_t ref_count_a = ATOMIC_INIT(1); /* for TEGRA_POWERGATE_DISA */
193 static atomic_t ref_count_b = ATOMIC_INIT(1); /* for TEGRA_POWERGATE_DISB */
194
195 static void __iomem *mipi_cal = IO_ADDRESS(TEGRA_MIPI_CAL_BASE);
196 static u32 mipi_cal_read(unsigned long reg)
197 {
198         return readl(mipi_cal + reg);
199 }
200
201 static void mipi_cal_write(u32 val, unsigned long reg)
202 {
203         writel_relaxed(val, mipi_cal + reg);
204 }
205
206 #define MC_CLIENT_HOTRESET_CTRL         0x200
207 #define MC_CLIENT_HOTRESET_STAT         0x204
208
209 static DEFINE_SPINLOCK(tegra11x_powergate_lock);
210
211 /* Forward Declarations */
212 int tegra11x_powergate_mc_flush(int id);
213 int tegra11x_powergate_mc_flush_done(int id);
214 int tegra11x_unpowergate_partition_with_clk_on(int id);
215 int tegra11x_powergate_partition_with_clk_off(int id);
216
217 static bool skip_pg_check(int id, bool is_unpowergate)
218 {
219         /*
220          * FIXME: need to stress test partition power gating before
221          * enabling power gating for T11x
222          * List of T11x partition id which skip power gating
223          */
224         static int skip_pg_t11x_list[] = {
225                 /*
226                  * CPU and 3D partitions enable/disable
227                  * is managed by respective modules
228                  */
229                 TEGRA_POWERGATE_DISA,
230                 TEGRA_POWERGATE_DISB
231         };
232         int i;
233
234         /*
235          * skip unnecessary multiple calls e.g. powergate call when
236          * partition is already powered-off or vice-versa
237          */
238         if ((tegra_powergate_is_powered(id) && is_unpowergate) ||
239             (!(tegra_powergate_is_powered(id)) && (!is_unpowergate))) {
240
241                 pr_err("Partition %s already powered-%s and %spowergate skipped\n",
242                         tegra_powergate_get_name(id),
243                         (tegra_powergate_is_powered(id)) ?
244                         "on" : "off",
245                         (is_unpowergate) ? "un" : "");
246
247                 return true;
248         }
249
250         /* unpowergate is allowed for all partitions */
251         if (!tegra_powergate_is_powered(id) && is_unpowergate)
252                 return false;
253
254         for (i = 0; i < ARRAY_SIZE(skip_pg_t11x_list); i++) {
255                 if (id == skip_pg_t11x_list[i]) {
256                         pr_err("Partition %s %spowergate skipped\n",
257                                 tegra_powergate_get_name(id),
258                                 (is_unpowergate) ? "un" : "");
259                         return true;
260                 }
261         }
262
263         return false;
264 }
265
266 #define HOTRESET_READ_COUNT     5
267 static bool tegra11x_stable_hotreset_check(u32 *stat)
268 {
269         int i;
270         u32 cur_stat;
271         u32 prv_stat;
272         unsigned long flags;
273
274         spin_lock_irqsave(&tegra11x_powergate_lock, flags);
275         prv_stat = mc_read(MC_CLIENT_HOTRESET_STAT);
276         for (i = 0; i < HOTRESET_READ_COUNT; i++) {
277                 cur_stat = mc_read(MC_CLIENT_HOTRESET_STAT);
278                 if (cur_stat != prv_stat) {
279                         spin_unlock_irqrestore(&tegra11x_powergate_lock, flags);
280                         return false;
281                 }
282         }
283         *stat = cur_stat;
284         spin_unlock_irqrestore(&tegra11x_powergate_lock, flags);
285         return true;
286 }
287
288 /*
289  * FIXME: sw war for mipi-cal calibration when unpowergating DISA partition
290  */
291 static void tegra11x_mipical_calibrate(int id)
292 {
293         struct reg_offset_val {
294                 u32 offset;
295                 u32 por_value;
296         };
297         u32 status;
298         unsigned long flags;
299
300 #define MIPI_CAL_MIPI_CAL_CTRL_0                0x0
301 #define MIPI_CAL_CIL_MIPI_CAL_STATUS_0          0x8
302 #define MIPI_CAL_CILA_MIPI_CAL_CONFIG_0         0x14
303 #define MIPI_CAL_CILB_MIPI_CAL_CONFIG_0         0x18
304 #define MIPI_CAL_CILC_MIPI_CAL_CONFIG_0         0x1c
305 #define MIPI_CAL_CILD_MIPI_CAL_CONFIG_0         0x20
306 #define MIPI_CAL_CILE_MIPI_CAL_CONFIG_0         0x24
307 #define MIPI_CAL_DSIA_MIPI_CAL_CONFIG_0         0x38
308 #define MIPI_CAL_DSIB_MIPI_CAL_CONFIG_0         0x3c
309 #define MIPI_CAL_DSIC_MIPI_CAL_CONFIG_0         0x40
310 #define MIPI_CAL_DSID_MIPI_CAL_CONFIG_0         0x44
311
312         static struct reg_offset_val mipi_cal_por_values[] = {
313                 { MIPI_CAL_MIPI_CAL_CTRL_0, 0x2a000000 },
314                 { MIPI_CAL_CILA_MIPI_CAL_CONFIG_0, 0x00200000 },
315                 { MIPI_CAL_CILB_MIPI_CAL_CONFIG_0, 0x00200000 },
316                 { MIPI_CAL_CILC_MIPI_CAL_CONFIG_0, 0x00200000 },
317                 { MIPI_CAL_CILD_MIPI_CAL_CONFIG_0, 0x00200000 },
318                 { MIPI_CAL_CILE_MIPI_CAL_CONFIG_0, 0x00000000 },
319                 { MIPI_CAL_DSIA_MIPI_CAL_CONFIG_0, 0x00200000 },
320                 { MIPI_CAL_DSIB_MIPI_CAL_CONFIG_0, 0x00200000 },
321                 { MIPI_CAL_DSIC_MIPI_CAL_CONFIG_0, 0x00200000 },
322                 { MIPI_CAL_DSID_MIPI_CAL_CONFIG_0, 0x00200000 },
323         };
324         int i;
325
326         if (id != TEGRA_POWERGATE_DISA)
327                 return;
328
329         spin_lock_irqsave(&tegra11x_powergate_lock, flags);
330
331         /* mipi cal por restore */
332         for (i = 0; i < ARRAY_SIZE(mipi_cal_por_values); i++) {
333                 mipi_cal_write(mipi_cal_por_values[i].por_value,
334                         mipi_cal_por_values[i].offset);
335         }
336
337         /* mipi cal status clear */
338         status = mipi_cal_read(MIPI_CAL_CIL_MIPI_CAL_STATUS_0);
339         mipi_cal_write(status, MIPI_CAL_CIL_MIPI_CAL_STATUS_0);
340
341         /* mipi cal status read - to flush writes */
342         status = mipi_cal_read(MIPI_CAL_CIL_MIPI_CAL_STATUS_0);
343
344         spin_unlock_irqrestore(&tegra11x_powergate_lock, flags);
345 }
346
347 static int tegra11x_powergate_partition_internal(int id,
348         struct powergate_partition_info *pg_info)
349 {
350         int ret;
351
352         if (tegra_powergate_is_powered(id)) {
353                 ret = is_partition_clk_disabled(pg_info);
354                 if (ret < 0) {
355                         /* clock enabled */
356                         ret = tegra11x_powergate_partition_with_clk_off(id);
357                         if (ret < 0)
358                                 return ret;
359                 } else {
360                         ret = tegra_powergate_partition(id);
361                         if (ret < 0)
362                                 return ret;
363                 }
364         }
365         return 0;
366 }
367
368 static int tegra11x_unpowergate_partition_internal(int id,
369         struct powergate_partition_info *pg_info)
370 {
371         int ret;
372
373         if (!tegra_powergate_is_powered(id)) {
374                 ret = is_partition_clk_disabled(pg_info);
375                 if (ret) {
376                         /* clock disabled */
377                         ret = tegra11x_unpowergate_partition_with_clk_on(id);
378                         if (ret < 0)
379                                 return ret;
380                 } else {
381                         ret = tegra_unpowergate_partition(id);
382                         if (ret < 0)
383                                 return ret;
384                 }
385         }
386         return 0;
387 }
388
389 /*
390  * Tegra11x has powergate dependencies between partitions.
391  * This function captures the dependencies.
392  */
393 static int tegra11x_check_partition_pg_seq(int id,
394         struct powergate_partition_info *pg_info)
395 {
396         int ret;
397
398         if (id == TEGRA_POWERGATE_DISA) {
399                 ret = tegra11x_powergate_partition_internal(TEGRA_POWERGATE_VENC,
400                         pg_info);
401                 if (ret < 0)
402                         return ret;
403
404                 ret = tegra11x_powergate_partition_internal(TEGRA_POWERGATE_DISB,
405                         pg_info);
406                 if (ret < 0)
407                         return ret;
408         }
409
410         return 0;
411 }
412
413 /*
414  * This function captures power-ungate dependencies between tegra11x partitions
415  */
416 static int tegra11x_check_partition_pug_seq(int id,
417         struct powergate_partition_info *pg_info)
418 {
419         int ret;
420
421         switch (id) {
422         case TEGRA_POWERGATE_DISB:
423         case TEGRA_POWERGATE_VENC:
424                 ret = tegra11x_unpowergate_partition_internal(TEGRA_POWERGATE_DISA,
425                         pg_info);
426                 if (ret < 0)
427                         return ret;
428
429                 break;
430         }
431         return 0;
432 }
433
434 int tegra11x_powergate_mc_enable(int id)
435 {
436         return 0;
437 }
438
439 int tegra11x_powergate_mc_disable(int id)
440 {
441         return 0;
442 }
443
444 int tegra11x_powergate_mc_flush(int id)
445 {
446         u32 idx, rst_ctrl, rst_stat;
447         enum mc_client mcClientBit;
448         unsigned long flags;
449         bool ret;
450
451         for (idx = 0; idx < MAX_HOTRESET_CLIENT_NUM; idx++) {
452                 mcClientBit =
453                         tegra11x_pg_mc_info[id].hot_reset_clients[idx];
454                 if (mcClientBit == MC_CLIENT_LAST)
455                         break;
456
457                 spin_lock_irqsave(&tegra11x_powergate_lock, flags);
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(&tegra11x_powergate_lock, flags);
463
464                 do {
465                         udelay(10);
466                         rst_stat = 0;
467                         ret = tegra11x_stable_hotreset_check(&rst_stat);
468                         if (!ret)
469                                 continue;
470                 } while (!(rst_stat & (1 << mcClientBit)));
471         }
472
473         return 0;
474 }
475
476 int tegra11x_powergate_mc_flush_done(int id)
477 {
478         u32 idx, rst_ctrl;
479         enum mc_client mcClientBit;
480         unsigned long flags;
481
482         for (idx = 0; idx < MAX_HOTRESET_CLIENT_NUM; idx++) {
483                 mcClientBit =
484                         tegra11x_pg_mc_info[id].hot_reset_clients[idx];
485                 if (mcClientBit == MC_CLIENT_LAST)
486                         break;
487
488                 spin_lock_irqsave(&tegra11x_powergate_lock, flags);
489
490                 rst_ctrl = mc_read(MC_CLIENT_HOTRESET_CTRL);
491                 rst_ctrl &= ~(1 << mcClientBit);
492                 mc_write(rst_ctrl, MC_CLIENT_HOTRESET_CTRL);
493
494                 spin_unlock_irqrestore(&tegra11x_powergate_lock, flags);
495         }
496
497         wmb();
498
499         return 0;
500 }
501
502 static int tegra11x_unpowergate(int id,
503         struct powergate_partition_info *pg_info)
504 {
505         int ret;
506
507         /* If first clk_ptr is null, fill clk info for the partition */
508         if (!pg_info->clk_info[0].clk_ptr)
509                 get_clk_info(pg_info);
510
511         if (tegra_powergate_is_powered(id))
512                 return tegra_powergate_reset_module(pg_info);
513
514         ret = tegra_powergate_set(id, true);
515         if (ret)
516                 goto err_power;
517
518         udelay(10);
519
520         /* Un-Powergating fails if all clks are not enabled */
521         ret = partition_clk_enable(pg_info);
522         if (ret)
523                 goto err_clk_on;
524
525         udelay(10);
526
527         ret = tegra_powergate_remove_clamping(id);
528         if (ret)
529                 goto err_clamp;
530
531         udelay(10);
532
533         tegra11x_mipical_calibrate(id);
534
535         powergate_partition_deassert_reset(pg_info);
536
537         udelay(10);
538
539         tegra_powergate_mc_flush_done(id);
540
541         udelay(10);
542
543         /* Disable all clks enabled earlier. Drivers should enable clks */
544         partition_clk_disable(pg_info);
545
546         return 0;
547
548 err_clamp:
549         partition_clk_disable(pg_info);
550 err_clk_on:
551         powergate_module(id);
552 err_power:
553         WARN(1, "Could not Un-Powergate %d", id);
554         return ret;
555 }
556
557 int tegra11x_powergate_partition(int id)
558 {
559         int ret;
560
561         WARN_ONCE(atomic_read(&ref_count_a) < 0, "ref count A underflow");
562         WARN_ONCE(atomic_read(&ref_count_b) < 0, "ref count B underflow");
563
564         if (id == TEGRA_POWERGATE_DISA && atomic_dec_return(&ref_count_a) != 0)
565                 return 0;
566         else if (id == TEGRA_POWERGATE_DISB &&
567                 atomic_dec_return(&ref_count_b) != 0)
568                 return 0;
569
570         if (skip_pg_check(id, false))
571                 return 0;
572
573         ret = tegra11x_check_partition_pg_seq(id,
574                 &tegra11x_powergate_partition_info[id]);
575         if (ret)
576                 return ret;
577
578         /* call common power-gate API for t1xx */
579         ret = tegra1xx_powergate(id,
580                 &tegra11x_powergate_partition_info[id]);
581
582         return ret;
583 }
584
585 int tegra11x_unpowergate_partition(int id)
586 {
587         int ret;
588
589         WARN_ONCE(atomic_read(&ref_count_a) < 0, "ref count A underflow");
590         WARN_ONCE(atomic_read(&ref_count_b) < 0, "ref count B underflow");
591
592         if (id == TEGRA_POWERGATE_DISA && atomic_inc_return(&ref_count_a) != 1)
593                 return 0;
594         else if (id == TEGRA_POWERGATE_DISB &&
595                 atomic_inc_return(&ref_count_b) != 1)
596                 return 0;
597
598         if (skip_pg_check(id, true))
599                 return 0;
600
601         ret = tegra11x_check_partition_pug_seq(id,
602                 &tegra11x_powergate_partition_info[id]);
603         if (ret)
604                 return ret;
605
606         /* t11x needs to calibrate mipi in un-power-gate sequence
607          * hence it cannot use common un-power-gate api tegra1xx_unpowergate */
608         ret = tegra11x_unpowergate(id,
609                 &tegra11x_powergate_partition_info[id]);
610
611         return ret;
612 }
613
614 int tegra11x_powergate_partition_with_clk_off(int id)
615 {
616         if (skip_pg_check(id, false))
617                 return 0;
618
619         return tegraxx_powergate_partition_with_clk_off(id,
620                 &tegra11x_powergate_partition_info[id]);
621 }
622
623 int tegra11x_unpowergate_partition_with_clk_on(int id)
624 {
625         if (skip_pg_check(id, true))
626                 return 0;
627
628         return tegraxx_unpowergate_partition_with_clk_on(id,
629                 &tegra11x_powergate_partition_info[id]);
630 }
631
632 const char *tegra11x_get_powergate_domain_name(int id)
633 {
634         return tegra11x_powergate_partition_info[id].name;
635 }
636
637 spinlock_t *tegra11x_get_powergate_lock(void)
638 {
639         return &tegra11x_powergate_lock;
640 }
641
642 static struct powergate_ops tegra11x_powergate_ops = {
643         .soc_name = "tegra11x",
644
645         .num_powerdomains = TEGRA_NUM_POWERGATE,
646
647         .get_powergate_lock = tegra11x_get_powergate_lock,
648         .get_powergate_domain_name = tegra11x_get_powergate_domain_name,
649
650         .powergate_partition = tegra11x_powergate_partition,
651         .unpowergate_partition = tegra11x_unpowergate_partition,
652
653         .powergate_partition_with_clk_off =  tegra11x_powergate_partition_with_clk_off,
654         .unpowergate_partition_with_clk_on = tegra11x_unpowergate_partition_with_clk_on,
655
656         .powergate_mc_enable = tegra11x_powergate_mc_enable,
657         .powergate_mc_disable = tegra11x_powergate_mc_disable,
658
659         .powergate_mc_flush = tegra11x_powergate_mc_flush,
660         .powergate_mc_flush_done = tegra11x_powergate_mc_flush_done,
661 };
662
663 struct powergate_ops *tegra11x_powergate_init_chip_support(void)
664 {
665         return &tegra11x_powergate_ops;
666 }