arm: tegra: ahci/sata: enable sata rails/partition at init
[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  *
6  * Author:
7  *      Colin Cross <ccross@google.com>
8  *
9  * This software is licensed under the terms of the GNU General Public
10  * License version 2, as published by the Free Software Foundation, and
11  * may be copied, distributed, and modified under those terms.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  */
19
20 #include <linux/kernel.h>
21 #include <linux/clk.h>
22 #include <linux/debugfs.h>
23 #include <linux/delay.h>
24 #include <linux/err.h>
25 #include <linux/init.h>
26 #include <linux/io.h>
27 #include <linux/seq_file.h>
28 #include <linux/spinlock.h>
29 #include <linux/clk/tegra.h>
30
31 #include <mach/powergate.h>
32
33 #include "clock.h"
34 #include "fuse.h"
35 #include "iomap.h"
36
37 #define PWRGATE_TOGGLE          0x30
38 #define PWRGATE_TOGGLE_START    (1 << 8)
39
40 #define REMOVE_CLAMPING         0x34
41
42 #define PWRGATE_STATUS          0x38
43
44 static int tegra_num_powerdomains;
45 static int tegra_num_cpu_domains;
46 static u8 *tegra_cpu_domains;
47 static u8 tegra30_cpu_domains[] = {
48         TEGRA_POWERGATE_CPU0,
49         TEGRA_POWERGATE_CPU1,
50         TEGRA_POWERGATE_CPU2,
51         TEGRA_POWERGATE_CPU3,
52 };
53
54 #define MC_CLIENT_HOTRESET_CTRL 0x200
55 #define MC_CLIENT_HOTRESET_STAT 0x204
56
57 enum mc_client {
58         MC_CLIENT_AFI   = 0,
59         MC_CLIENT_AVPC  = 1,
60         MC_CLIENT_DC    = 2,
61         MC_CLIENT_DCB   = 3,
62         MC_CLIENT_EPP   = 4,
63         MC_CLIENT_G2    = 5,
64         MC_CLIENT_HC    = 6,
65         MC_CLIENT_HDA   = 7,
66         MC_CLIENT_ISP   = 8,
67         MC_CLIENT_MPCORE        = 9,
68         MC_CLIENT_MPCORELP      = 10,
69         MC_CLIENT_MPE   = 11,
70         MC_CLIENT_NV    = 12,
71         MC_CLIENT_NV2   = 13,
72         MC_CLIENT_PPCS  = 14,
73         MC_CLIENT_SATA  = 15,
74         MC_CLIENT_VDE   = 16,
75         MC_CLIENT_VI    = 17,
76         MC_CLIENT_LAST  = -1,
77 };
78
79 #define MAX_CLK_EN_NUM                  4
80
81 static DEFINE_SPINLOCK(tegra_powergate_lock);
82
83 #define MAX_HOTRESET_CLIENT_NUM         3
84
85 enum clk_type {
86         CLK_AND_RST,
87         RST_ONLY,
88         CLK_ONLY,
89 };
90
91 struct partition_clk_info {
92         const char *clk_name;
93         enum clk_type clk_type;
94         /* true if clk is only used in assert/deassert reset and not while enable-den*/
95         struct clk *clk_ptr;
96 };
97
98 struct powergate_partition {
99         const char *name;
100         enum mc_client hot_reset_clients[MAX_HOTRESET_CLIENT_NUM];
101         struct partition_clk_info clk_info[MAX_CLK_EN_NUM];
102 };
103
104 static struct powergate_partition powergate_partition_info[] = {
105         [TEGRA_POWERGATE_CPU]   = { "cpu0",     {MC_CLIENT_LAST}, },
106         [TEGRA_POWERGATE_L2]    = { "l2",       {MC_CLIENT_LAST}, },
107         [TEGRA_POWERGATE_3D]    = { "3d0",
108                                                 {MC_CLIENT_NV, MC_CLIENT_LAST},
109                                                 {{"3d", CLK_AND_RST} }, },
110         [TEGRA_POWERGATE_PCIE]  = { "pcie",
111                                                 {MC_CLIENT_AFI, MC_CLIENT_LAST},
112                                                 {{"afi", CLK_AND_RST},
113                                                 {"pcie", CLK_AND_RST},
114                                                 {"pciex", RST_ONLY} }, },
115         [TEGRA_POWERGATE_VDEC]  = { "vde",
116                                                 {MC_CLIENT_VDE, MC_CLIENT_LAST},
117                                                 {{"vde", CLK_AND_RST} }, },
118         [TEGRA_POWERGATE_MPE]   = { "mpe",
119                                                 {MC_CLIENT_MPE, MC_CLIENT_LAST},
120                                                 {{"mpe", CLK_AND_RST} }, },
121         [TEGRA_POWERGATE_VENC]  = { "ve",
122                                                 {MC_CLIENT_ISP, MC_CLIENT_VI, MC_CLIENT_LAST},
123                                                 {{"isp", CLK_AND_RST},
124                                                 {"vi", CLK_AND_RST},
125                                                 {"csi", CLK_AND_RST} }, },
126         [TEGRA_POWERGATE_CPU1]  = { "cpu1",     {MC_CLIENT_LAST}, },
127         [TEGRA_POWERGATE_CPU2]  = { "cpu2",     {MC_CLIENT_LAST}, },
128         [TEGRA_POWERGATE_CPU3]  = { "cpu3",     {MC_CLIENT_LAST}, },
129         [TEGRA_POWERGATE_A9LP]  = { "a9lp",     {MC_CLIENT_LAST}, },
130         [TEGRA_POWERGATE_SATA]  = { "sata",     {MC_CLIENT_SATA, MC_CLIENT_LAST},
131                                                 {{"sata", CLK_AND_RST},
132                                                 {"sata_oob", CLK_AND_RST},
133                                                 {"cml1", CLK_ONLY},
134                                                 {"sata_cold", RST_ONLY} }, },
135         [TEGRA_POWERGATE_3D1]   = { "3d1",
136                                                 {MC_CLIENT_NV2, MC_CLIENT_LAST},
137                                                 {{"3d2", CLK_AND_RST} }, },
138         [TEGRA_POWERGATE_HEG]   = { "heg",
139                                                 {MC_CLIENT_G2, MC_CLIENT_EPP, MC_CLIENT_HC},
140                                                 {{"2d", CLK_AND_RST},
141                                                 {"epp", CLK_AND_RST},
142                                                 {"host1x", CLK_AND_RST},
143                                                 {"3d", RST_ONLY} }, },
144 };
145
146 static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
147
148 static u32 pmc_read(unsigned long reg)
149 {
150         return readl(pmc + reg);
151 }
152
153 static void pmc_write(u32 val, unsigned long reg)
154 {
155         writel(val, pmc + reg);
156 }
157
158 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
159 static void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE);
160
161 static u32 mc_read(unsigned long reg)
162 {
163         return readl(mc + reg);
164 }
165
166 static void mc_write(u32 val, unsigned long reg)
167 {
168         writel(val, mc + reg);
169 }
170
171 static void mc_flush(int id)
172 {
173         u32 idx, rst_ctrl, rst_stat;
174         enum mc_client mcClientBit;
175         unsigned long flags;
176
177         BUG_ON(id < 0 || id >= tegra_num_powerdomains);
178
179         for (idx = 0; idx < MAX_HOTRESET_CLIENT_NUM; idx++) {
180                 mcClientBit = powergate_partition_info[id].hot_reset_clients[idx];
181                 if (mcClientBit == MC_CLIENT_LAST)
182                         break;
183
184                 spin_lock_irqsave(&tegra_powergate_lock, flags);
185
186                 rst_ctrl = mc_read(MC_CLIENT_HOTRESET_CTRL);
187                 rst_ctrl |= (1 << mcClientBit);
188                 mc_write(rst_ctrl, MC_CLIENT_HOTRESET_CTRL);
189
190                 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
191
192                 do {
193                         udelay(10);
194                         rst_stat = mc_read(MC_CLIENT_HOTRESET_STAT);
195                 } while (!(rst_stat & (1 << mcClientBit)));
196         }
197 }
198
199 static void mc_flush_done(int id)
200 {
201         u32 idx, rst_ctrl;
202         enum mc_client mcClientBit;
203         unsigned long flags;
204
205         BUG_ON(id < 0 || id >= tegra_num_powerdomains);
206
207         for (idx = 0; idx < MAX_HOTRESET_CLIENT_NUM; idx++) {
208                 mcClientBit = powergate_partition_info[id].hot_reset_clients[idx];
209                 if (mcClientBit == MC_CLIENT_LAST)
210                         break;
211
212                 spin_lock_irqsave(&tegra_powergate_lock, flags);
213
214                 rst_ctrl = mc_read(MC_CLIENT_HOTRESET_CTRL);
215                 rst_ctrl &= ~(1 << mcClientBit);
216                 mc_write(rst_ctrl, MC_CLIENT_HOTRESET_CTRL);
217
218                 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
219         }
220
221         wmb();
222 }
223 #else
224 static void mc_flush(int id) {}
225 static void mc_flush_done(int id) {}
226 #endif
227
228 static int tegra_powergate_set(int id, bool new_state)
229 {
230         bool status;
231         unsigned long flags;
232
233         spin_lock_irqsave(&tegra_powergate_lock, flags);
234
235         status = !!(pmc_read(PWRGATE_STATUS) & (1 << id));
236
237         if (status == new_state) {
238                 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
239                 return -EINVAL;
240         }
241
242         pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
243
244         spin_unlock_irqrestore(&tegra_powergate_lock, flags);
245
246         return 0;
247 }
248
249 static int unpowergate_module(int id)
250 {
251         if (id < 0 || id >= tegra_num_powerdomains)
252                 return -EINVAL;
253         return tegra_powergate_set(id, true);
254 }
255
256 static int powergate_module(int id)
257 {
258         if (id < 0 || id >= tegra_num_powerdomains)
259                 return -EINVAL;
260
261         mc_flush(id);
262         return tegra_powergate_set(id, false);
263 }
264
265 int tegra_powergate_is_powered(int id)
266 {
267         u32 status;
268
269         if (id < 0 || id >= tegra_num_powerdomains)
270                 return -EINVAL;
271
272         status = pmc_read(PWRGATE_STATUS) & (1 << id);
273         return !!status;
274 }
275
276 int tegra_powergate_remove_clamping(int id)
277 {
278         u32 mask;
279         if (id < 0 || id >= tegra_num_powerdomains)
280                 return -EINVAL;
281
282         /*
283          * PCIE and VDE clamping masks are swapped with respect to their
284          * partition ids
285          */
286         if (id ==  TEGRA_POWERGATE_VDEC)
287                 mask = (1 << TEGRA_POWERGATE_PCIE);
288         else if (id == TEGRA_POWERGATE_PCIE)
289                 mask = (1 << TEGRA_POWERGATE_VDEC);
290         else
291                 mask = (1 << id);
292
293         pmc_write(mask, REMOVE_CLAMPING);
294
295         return 0;
296 }
297
298 static void get_clk_info(int id)
299 {
300         int idx;
301
302         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
303                 if (!powergate_partition_info[id].clk_info[idx].clk_name)
304                         break;
305                 powergate_partition_info[id].
306                                 clk_info[idx].clk_ptr =
307                                         tegra_get_clock_by_name(
308                         powergate_partition_info[id].clk_info[idx].clk_name);
309         }
310 }
311
312 static int partition_clk_enable(int id)
313 {
314         int ret;
315         u32 idx;
316         struct clk *clk;
317         struct partition_clk_info *clk_info;
318
319         BUG_ON(id < 0 || id >= tegra_num_powerdomains);
320
321         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
322                 clk_info = &powergate_partition_info[id].clk_info[idx];
323                 clk = clk_info->clk_ptr;
324                 if (!clk)
325                         break;
326
327                 if (clk_info->clk_type != RST_ONLY) {
328                         ret = clk_prepare_enable(clk);
329                         if (ret)
330                                 goto err_clk_en;
331                 }
332         }
333
334         return 0;
335
336 err_clk_en:
337         WARN(1, "Could not enable clk %s", clk->name);
338         while (idx--) {
339                 clk_info = &powergate_partition_info[id].clk_info[idx];
340                 if (clk_info->clk_type != RST_ONLY)
341                         clk_disable_unprepare(clk_info->clk_ptr);
342         }
343
344         return ret;
345 }
346
347 static int is_partition_clk_disabled(int id)
348 {
349         u32 idx;
350         struct clk *clk;
351         struct partition_clk_info *clk_info;
352         int ret = 0;
353
354         BUG_ON(id < 0 || id >= tegra_num_powerdomains);
355
356         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
357                 clk_info = &powergate_partition_info[id].clk_info[idx];
358                 clk = clk_info->clk_ptr;
359                 if (!clk)
360                         break;
361
362                 if (clk_info->clk_type != RST_ONLY) {
363                         if (tegra_is_clk_enabled(clk)) {
364                                 ret = -1;
365                                 break;
366                         }
367                 }
368         }
369
370         return ret;
371 }
372
373 static void partition_clk_disable(int id)
374 {
375         u32 idx;
376         struct clk *clk;
377         struct partition_clk_info *clk_info;
378
379         BUG_ON(id < 0 || id >= tegra_num_powerdomains);
380
381         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
382                 clk_info = &powergate_partition_info[id].clk_info[idx];
383                 clk = clk_info->clk_ptr;
384                 if (!clk)
385                         break;
386
387                 if (clk_info->clk_type != RST_ONLY)
388                         clk_disable_unprepare(clk);
389         }
390 }
391
392 static void powergate_partition_assert_reset(int id)
393 {
394         u32 idx;
395         struct clk *clk_ptr;
396         struct partition_clk_info *clk_info;
397
398         BUG_ON(id < 0 || id >= tegra_num_powerdomains);
399
400         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
401                 clk_info = &powergate_partition_info[id].clk_info[idx];
402                 clk_ptr = clk_info->clk_ptr;
403                 if (!clk_ptr)
404                         break;
405                 if (clk_info->clk_type != CLK_ONLY)
406                         tegra_periph_reset_assert(clk_ptr);
407         }
408 }
409
410 static void powergate_partition_deassert_reset(int id)
411 {
412         u32 idx;
413         struct clk *clk_ptr;
414         struct partition_clk_info *clk_info;
415
416         BUG_ON(id < 0 || id >= tegra_num_powerdomains);
417
418         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
419                 clk_info = &powergate_partition_info[id].clk_info[idx];
420                 clk_ptr = clk_info->clk_ptr;
421                 if (!clk_ptr)
422                         break;
423                 if (clk_info->clk_type != CLK_ONLY)
424                         tegra_periph_reset_deassert(clk_ptr);
425         }
426 }
427
428 /* Must be called with clk disabled, and returns with clk disabled */
429 static int tegra_powergate_reset_module(int id)
430 {
431         int ret;
432
433         powergate_partition_assert_reset(id);
434
435         udelay(10);
436
437         ret = partition_clk_enable(id);
438         if (ret)
439                 return ret;
440
441         udelay(10);
442
443         powergate_partition_deassert_reset(id);
444
445         partition_clk_disable(id);
446
447         return 0;
448 }
449
450 /*
451  * Must be called with clk disabled, and returns with clk disabled
452  * Drivers should enable clks for partition. Unpowergates only the
453  * partition.
454  */
455 int tegra_unpowergate_partition(int id)
456 {
457         int ret;
458
459         /* If first clk_ptr is null, fill clk info for the partition */
460         if (!powergate_partition_info[id].clk_info[0].clk_ptr)
461                 get_clk_info(id);
462
463         if (tegra_powergate_is_powered(id))
464                 return tegra_powergate_reset_module(id);
465
466         ret = unpowergate_module(id);
467         if (ret)
468                 goto err_power;
469
470         powergate_partition_assert_reset(id);
471
472         /* Un-Powergating fails if all clks are not enabled */
473         ret = partition_clk_enable(id);
474         if (ret)
475                 goto err_clk_on;
476
477         udelay(10);
478
479         ret = tegra_powergate_remove_clamping(id);
480         if (ret)
481                 goto err_clamp;
482
483         udelay(10);
484         powergate_partition_deassert_reset(id);
485
486         mc_flush_done(id);
487
488         /* Disable all clks enabled earlier. Drivers should enable clks */
489         partition_clk_disable(id);
490
491         return 0;
492
493 err_clamp:
494         partition_clk_disable(id);
495 err_clk_on:
496         powergate_module(id);
497 err_power:
498         WARN(1, "Could not Un-Powergate %d", id);
499         return ret;
500 }
501
502 /*
503  * Must be called with clk disabled, and returns with clk enabled
504  * Unpowergates the partition and enables all required clks.
505  */
506 int tegra_unpowergate_partition_with_clk_on(int id)
507 {
508         int ret = 0;
509
510 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
511         /* Restrict this functions use to few partitions */
512         BUG_ON(id != TEGRA_POWERGATE_SATA && id != TEGRA_POWERGATE_PCIE);
513 #else
514         /* Restrict this functions use to few partitions */
515         BUG_ON(id != TEGRA_POWERGATE_PCIE);
516 #endif
517
518         ret = tegra_unpowergate_partition(id);
519         if (ret)
520                 goto err_unpowergating;
521
522         /* Enable clks for the partition */
523         ret = partition_clk_enable(id);
524         if (ret)
525                 goto err_unpowergate_clk;
526
527         return ret;
528
529 err_unpowergate_clk:
530         tegra_powergate_partition(id);
531         WARN(1, "Could not Un-Powergate %d, err in enabling clk", id);
532 err_unpowergating:
533         WARN(1, "Could not Un-Powergate %d", id);
534         return ret;
535 }
536
537 /*
538  * Must be called with clk disabled. Powergates the partition only
539  */
540 int tegra_powergate_partition(int id)
541 {
542         int ret;
543
544         /* If first clk_ptr is null, fill clk info for the partition */
545         if (powergate_partition_info[id].clk_info[0].clk_ptr)
546                 get_clk_info(id);
547         powergate_partition_assert_reset(id);
548
549         /* Powergating is done only if refcnt of all clks is 0 */
550         ret = is_partition_clk_disabled(id);
551         if (ret)
552                 goto err_clk_off;
553
554         ret = powergate_module(id);
555         if (ret)
556                 goto err_power_off;
557
558         return 0;
559
560 err_power_off:
561         WARN(1, "Could not Powergate Partition %d", id);
562 err_clk_off:
563         WARN(1, "Could not Powergate Partition %d, all clks not disabled", id);
564         return ret;
565 }
566
567 int tegra_powergate_partition_with_clk_off(int id)
568 {
569         int ret = 0;
570
571 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
572         /* Restrict functions use to selected partitions */
573         BUG_ON(id != TEGRA_POWERGATE_PCIE && id != TEGRA_POWERGATE_SATA);
574 #else
575         /* Restrict functions use to selected partitions */
576         BUG_ON(id != TEGRA_POWERGATE_PCIE);
577 #endif
578         /* Disable clks for the partition */
579         partition_clk_disable(id);
580
581         ret = is_partition_clk_disabled(id);
582         if (ret)
583                 goto err_powergate_clk;
584
585         ret = tegra_powergate_partition(id);
586         if (ret)
587                 goto err_powergating;
588
589         return ret;
590
591 err_powergate_clk:
592         WARN(1, "Could not Powergate Partition %d, all clks not disabled", id);
593 err_powergating:
594         partition_clk_enable(id);
595         WARN(1, "Could not Powergate Partition %d", id);
596         return ret;
597 }
598
599 int tegra_cpu_powergate_id(int cpuid)
600 {
601         if (cpuid > 0 && cpuid < tegra_num_cpu_domains)
602                 return tegra_cpu_domains[cpuid];
603
604         return -EINVAL;
605 }
606
607 int __init tegra_powergate_init(void)
608 {
609         switch (tegra_chip_id) {
610         case TEGRA20:
611                 tegra_num_powerdomains = 7;
612                 break;
613         case TEGRA30:
614                 tegra_num_powerdomains = 14;
615                 tegra_num_cpu_domains = 4;
616                 tegra_cpu_domains = tegra30_cpu_domains;
617                 break;
618         default:
619                 /* Unknown Tegra variant. Disable powergating */
620                 tegra_num_powerdomains = 0;
621                 break;
622         }
623
624         return 0;
625 }
626
627 const char *tegra_powergate_get_name(int id)
628 {
629         if (id < 0 || id >= tegra_num_powerdomains)
630                 return "invalid";
631
632         return powergate_partition_info[id].name;
633 }
634
635 #ifdef CONFIG_DEBUG_FS
636
637 static int powergate_show(struct seq_file *s, void *data)
638 {
639         int i;
640
641         seq_printf(s, " powergate powered\n");
642         seq_printf(s, "------------------\n");
643
644         for (i = 0; i < tegra_num_powerdomains; i++)
645                 seq_printf(s, " %9s %7s\n", powergate_partition_info[i].name,
646                         tegra_powergate_is_powered(i) ? "yes" : "no");
647         return 0;
648 }
649
650 static int powergate_open(struct inode *inode, struct file *file)
651 {
652         return single_open(file, powergate_show, inode->i_private);
653 }
654
655 static const struct file_operations powergate_fops = {
656         .open           = powergate_open,
657         .read           = seq_read,
658         .llseek         = seq_lseek,
659         .release        = single_release,
660 };
661
662 int __init tegra_powergate_debugfs_init(void)
663 {
664         struct dentry *d;
665
666         if (powergate_name) {
667                 d = debugfs_create_file("powergate", S_IRUGO, NULL, NULL,
668                         &powergate_fops);
669                 if (!d)
670                         return -ENOMEM;
671         }
672
673         return 0;
674 }
675
676 #endif