2778e8c5cfab009e3344bc336742c5978131d50b
[linux-3.10.git] / arch / arm / mach-tegra / powergate.c
1 /*
2  * arch/arm/mach-tegra/powergate.c
3  *
4  * Copyright (c) 2010 Google, Inc
5  * Copyright (c) 2011 - 2014, NVIDIA CORPORATION.  All rights reserved.
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/clk/tegra.h>
25 #include <linux/string.h>
26 #include <linux/debugfs.h>
27 #include <linux/delay.h>
28 #include <linux/err.h>
29 #include <linux/init.h>
30 #include <linux/io.h>
31 #include <linux/seq_file.h>
32 #include <linux/spinlock.h>
33 #include <linux/clk/tegra.h>
34 #include <linux/tegra-powergate.h>
35 #include <linux/tegra-soc.h>
36 #include <trace/events/power.h>
37 #include <asm/atomic.h>
38
39 #include "clock.h"
40 #include "iomap.h"
41 #include "powergate-priv.h"
42 #include "common.h"
43
44 static struct powergate_ops *pg_ops;
45
46 static spinlock_t *tegra_get_powergate_lock(void)
47 {
48         if (pg_ops && pg_ops->get_powergate_lock)
49                 return pg_ops->get_powergate_lock();
50         else
51                 WARN_ON_ONCE("This SOC does not export powergate lock");
52
53         return NULL;
54 }
55
56 int tegra_powergate_set(int id, bool new_state)
57 {
58         bool status;
59         unsigned long flags;
60         spinlock_t *lock;
61         u32 reg;
62
63         /* 10us timeout for toggle operation if it takes affect*/
64         int toggle_timeout = 10;
65
66         /* 100 * 10 = 1000us timeout for toggle command to take affect in case
67            of contention with h/w initiated CPU power gating */
68         int contention_timeout = 100;
69
70         if (tegra_cpu_is_asim())
71                 return 0;
72
73         lock = tegra_get_powergate_lock();
74
75         spin_lock_irqsave(lock, flags);
76
77         status = !!(pmc_read(PWRGATE_STATUS) & (1 << id));
78
79         if (status == new_state) {
80                 spin_unlock_irqrestore(lock, flags);
81                 return 0;
82         }
83
84         if (TEGRA_IS_CPU_POWERGATE_ID(id)) {
85                 /* CPU ungated in s/w only during boot/resume with outer
86                    waiting loop and no contention from other CPUs */
87                 pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
88                 spin_unlock_irqrestore(lock, flags);
89                 return 0;
90         }
91
92 #if !defined(CONFIG_ARCH_TEGRA_3x_SOC)
93         /* Wait if PMC is already processing some other power gating request */
94         do {
95                 udelay(1);
96                 reg = pmc_read(PWRGATE_TOGGLE);
97                 contention_timeout--;
98         } while ((contention_timeout > 0) && (reg & PWRGATE_TOGGLE_START));
99
100         if (contention_timeout <= 0)
101                 pr_err(" Timed out waiting for PMC to submit \
102                                 new power gate request \n");
103         contention_timeout = 100;
104 #endif
105
106         /* Submit power gate request */
107         pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
108
109 #if !defined(CONFIG_ARCH_TEGRA_3x_SOC)
110         /* Wait while PMC accepts the request */
111         do {
112                 udelay(1);
113                 reg = pmc_read(PWRGATE_TOGGLE);
114                 contention_timeout--;
115         } while ((contention_timeout > 0) && (reg & PWRGATE_TOGGLE_START));
116
117         if (contention_timeout <= 0)
118                 pr_err(" Timed out waiting for PMC to accept \
119                                 new power gate request \n");
120         contention_timeout = 100;
121 #endif
122
123         /* Check power gate status */
124         do {
125                 do {
126                         udelay(1);
127                         status = !!(pmc_read(PWRGATE_STATUS) & (1 << id));
128
129                         toggle_timeout--;
130                 } while ((status != new_state) && (toggle_timeout > 0));
131
132                 contention_timeout--;
133         } while ((status != new_state) && (contention_timeout > 0));
134
135         spin_unlock_irqrestore(lock, flags);
136
137         if (status != new_state) {
138                 WARN(1, "Could not set powergate %d to %d", id, new_state);
139                 return -EBUSY;
140         }
141
142         trace_power_domain_target(tegra_powergate_get_name(id), new_state,
143                         raw_smp_processor_id());
144
145         return 0;
146 }
147
148 int is_partition_clk_disabled(struct powergate_partition_info *pg_info)
149 {
150         u32 idx;
151         struct clk *clk;
152         struct partition_clk_info *clk_info;
153         int ret = 0;
154
155         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
156                 clk_info = &pg_info->clk_info[idx];
157                 clk = clk_info->clk_ptr;
158
159                 if (!clk)
160                         break;
161
162                 if (clk_info->clk_type != RST_ONLY) {
163                         if (tegra_is_clk_enabled(clk)) {
164                                 ret = -1;
165                                 break;
166                         }
167                 }
168         }
169
170         return ret;
171 }
172
173 int powergate_module(int id)
174 {
175         if (!pg_ops) {
176                 pr_info("This SOC doesn't support powergating\n");
177                 return -EINVAL;
178         }
179
180         if (id < 0 || id >= pg_ops->num_powerdomains)
181                 return -EINVAL;
182
183         tegra_powergate_mc_flush(id);
184
185         return tegra_powergate_set(id, false);
186 }
187
188 int unpowergate_module(int id)
189 {
190         if (!pg_ops) {
191                 pr_info("This SOC doesn't support powergating\n");
192                 return -EINVAL;
193         }
194
195         if (id < 0 || id >= pg_ops->num_powerdomains)
196                 return -EINVAL;
197
198         return tegra_powergate_set(id, true);
199 }
200
201 int partition_clk_enable(struct powergate_partition_info *pg_info)
202 {
203         int ret;
204         u32 idx;
205         struct clk *clk;
206         struct partition_clk_info *clk_info;
207
208         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
209                 clk_info = &pg_info->clk_info[idx];
210                 clk = clk_info->clk_ptr;
211                 if (!clk)
212                         break;
213
214                 if (clk_info->clk_type != RST_ONLY) {
215                         ret = tegra_clk_prepare_enable(clk);
216                         if (ret)
217                                 goto err_clk_en;
218                 }
219         }
220
221         return 0;
222
223 err_clk_en:
224         WARN(1, "Could not enable clk %s, error %d", clk->name, ret);
225         while (idx--) {
226                 clk_info = &pg_info->clk_info[idx];
227                 if (clk_info->clk_type != RST_ONLY)
228                         tegra_clk_disable_unprepare(clk_info->clk_ptr);
229         }
230
231         return ret;
232 }
233
234 void partition_clk_disable(struct powergate_partition_info *pg_info)
235 {
236         u32 idx;
237         struct clk *clk;
238         struct partition_clk_info *clk_info;
239
240         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
241                 clk_info = &pg_info->clk_info[idx];
242                 clk = clk_info->clk_ptr;
243
244                 if (!clk)
245                         break;
246
247                 if (clk_info->clk_type != RST_ONLY)
248                         tegra_clk_disable_unprepare(clk);
249         }
250 }
251
252 void get_clk_info(struct powergate_partition_info *pg_info)
253 {
254         int idx;
255
256         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
257                 if (!pg_info->clk_info[idx].clk_name)
258                         break;
259
260                 pg_info->clk_info[idx].clk_ptr = tegra_get_clock_by_name(
261                         pg_info->clk_info[idx].clk_name);
262         }
263 }
264
265 void powergate_partition_assert_reset(struct powergate_partition_info *pg_info)
266 {
267         u32 idx;
268         struct clk *clk_ptr;
269         struct partition_clk_info *clk_info;
270
271         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
272                 clk_info = &pg_info->clk_info[idx];
273                 clk_ptr = clk_info->clk_ptr;
274
275                 if (!clk_ptr)
276                         break;
277
278                 if (clk_info->clk_type != CLK_ONLY)
279                         tegra_periph_reset_assert(clk_ptr);
280         }
281 }
282
283 void powergate_partition_deassert_reset(struct powergate_partition_info *pg_info)
284 {
285         u32 idx;
286         struct clk *clk_ptr;
287         struct partition_clk_info *clk_info;
288
289         for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
290                 clk_info = &pg_info->clk_info[idx];
291                 clk_ptr = clk_info->clk_ptr;
292
293                 if (!clk_ptr)
294                         break;
295
296                 if (clk_info->clk_type != CLK_ONLY)
297                         tegra_periph_reset_deassert(clk_ptr);
298         }
299 }
300
301 int tegra_powergate_reset_module(struct powergate_partition_info *pg_info)
302 {
303         int ret;
304
305         powergate_partition_assert_reset(pg_info);
306
307         udelay(10);
308
309         ret = partition_clk_enable(pg_info);
310         if (ret)
311                 return ret;
312
313         udelay(10);
314
315         powergate_partition_deassert_reset(pg_info);
316
317         partition_clk_disable(pg_info);
318
319         return 0;
320 }
321
322 bool tegra_powergate_check_clamping(int id)
323 {
324         if (!pg_ops || !pg_ops->powergate_check_clamping) {
325                 pr_info("This SOC can't check clamping status\n");
326                 return -EINVAL;
327         }
328
329         if (id < 0 || id >= pg_ops->num_powerdomains)
330                 return -EINVAL;
331
332         return pg_ops->powergate_check_clamping(id);
333 }
334
335 int tegra_powergate_remove_clamping(int id)
336 {
337         u32 mask;
338         int contention_timeout = 100;
339
340         if (!pg_ops) {
341                 pr_info("This SOC doesn't support powergating\n");
342                 return -EINVAL;
343         }
344
345         if (id < 0 || id >= pg_ops->num_powerdomains)
346                 return -EINVAL;
347
348         /*
349          * PCIE and VDE clamping masks are swapped with respect to their
350          * partition ids
351          */
352         if (id ==  TEGRA_POWERGATE_VDEC)
353                 mask = (1 << TEGRA_POWERGATE_PCIE);
354         else if (id == TEGRA_POWERGATE_PCIE)
355                 mask = (1 << TEGRA_POWERGATE_VDEC);
356         else
357                 mask = (1 << id);
358
359         pmc_write(mask, REMOVE_CLAMPING);
360         /* Wait until clamp is removed */
361         do {
362                 udelay(1);
363                 contention_timeout--;
364         } while ((contention_timeout > 0)
365                         && (pmc_read(PWRGATE_CLAMP_STATUS) & BIT(id)));
366
367         WARN(contention_timeout <= 0, "Couldn't remove clamping");
368
369         return 0;
370 }
371
372 static inline bool tegra_powergate_check_skip_list(int id)
373 {
374         return pg_ops->powergate_skip ?
375                 pg_ops->powergate_skip(id) : false;
376 }
377
378 /* EXTERNALY VISIBLE APIS */
379
380 bool tegra_powergate_is_powered(int id)
381 {
382         u32 status;
383
384         if (!pg_ops) {
385                 pr_debug("This SOC doesn't support powergating\n");
386                 return -EINVAL;
387         }
388
389         if (id < 0 || id >= pg_ops->num_powerdomains)
390                 return -EINVAL;
391
392         if (pg_ops->powergate_is_powered)
393                 return pg_ops->powergate_is_powered(id);
394         else
395                 status = pmc_read(PWRGATE_STATUS) & (1 << id);
396
397         status = pmc_read(PWRGATE_STATUS) & (1 << id);
398
399         return !!status;
400 }
401 EXPORT_SYMBOL(tegra_powergate_is_powered);
402
403 int tegra_cpu_powergate_id(int cpuid)
404 {
405         if (!pg_ops) {
406                 pr_info("This SOC doesn't support powergating\n");
407                 return -EINVAL;
408         }
409
410         if (cpuid < 0 || cpuid >= pg_ops->num_cpu_domains) {
411                 pr_info("%s: invalid powergate id\n", __func__);
412                 return -EINVAL;
413         }
414
415         if (pg_ops->cpu_domains)
416                 return pg_ops->cpu_domains[cpuid];
417         else
418                 WARN_ON_ONCE("This SOC does not support CPU powergate\n");
419
420         return -EINVAL;
421 }
422 EXPORT_SYMBOL(tegra_cpu_powergate_id);
423
424 int tegra_powergate_partition(int id)
425 {
426         if (!pg_ops) {
427                 pr_info("This SOC doesn't support powergating\n");
428                 return -EINVAL;
429         }
430
431         if (id < 0 || id >= pg_ops->num_powerdomains) {
432                 pr_info("%s: invalid powergate id\n", __func__);
433                 return -EINVAL;
434         }
435
436         if (tegra_powergate_check_skip_list(id))
437                 printk_once("%s: %s is in powergate skip list\n", __func__,
438                         tegra_powergate_get_name(id));
439
440         if (pg_ops->powergate_partition)
441                 return pg_ops->powergate_partition(id);
442         else
443                 WARN_ON_ONCE("This SOC doesn't support powergating");
444
445         return -EINVAL;
446 }
447 EXPORT_SYMBOL(tegra_powergate_partition);
448
449 int tegra_unpowergate_partition(int id)
450 {
451         if (!pg_ops) {
452                 pr_info("This SOC doesn't support powergating\n");
453                 return -EINVAL;
454         }
455
456         if (id < 0 || id >= pg_ops->num_powerdomains) {
457                 pr_info("%s: invalid powergate id\n", __func__);
458                 return -EINVAL;
459         }
460
461         if (tegra_powergate_check_skip_list(id))
462                 printk_once("%s: %s is in powergate skip list\n", __func__,
463                         tegra_powergate_get_name(id));
464
465         if (pg_ops->unpowergate_partition)
466                 return pg_ops->unpowergate_partition(id);
467         else
468                 WARN_ON_ONCE("This SOC doesn't support un-powergating");
469
470         return -EINVAL;
471 }
472 EXPORT_SYMBOL(tegra_unpowergate_partition);
473
474 int tegra_powergate_partition_with_clk_off(int id)
475 {
476         if (!pg_ops) {
477                 pr_info("This SOC doesn't support powergating\n");
478                 return -EINVAL;
479         }
480
481         if (id < 0 || id >= pg_ops->num_powerdomains) {
482                 pr_info("%s: invalid powergate id\n", __func__);
483                 return -EINVAL;
484         }
485
486         if (tegra_powergate_check_skip_list(id))
487                 printk_once("%s: %s is in powergate skip list\n", __func__,
488                         tegra_powergate_get_name(id));
489
490         if (pg_ops->powergate_partition_with_clk_off)
491                 return pg_ops->powergate_partition_with_clk_off(id);
492         else
493                 WARN_ON_ONCE("This SOC doesn't support powergating with clk off");
494
495         return -EINVAL;
496 }
497 EXPORT_SYMBOL(tegra_powergate_partition_with_clk_off);
498
499 int tegra_unpowergate_partition_with_clk_on(int id)
500 {
501         if (!pg_ops) {
502                 pr_info("This SOC doesn't support powergating\n");
503                 return -EINVAL;
504         }
505
506         if (id < 0 || id >= pg_ops->num_powerdomains) {
507                 pr_info("%s: invalid powergate id\n", __func__);
508                 return -EINVAL;
509         }
510
511         if (tegra_powergate_check_skip_list(id))
512                 printk_once("%s: %s is in powergate skip list\n", __func__,
513                         tegra_powergate_get_name(id));
514
515         if (pg_ops->unpowergate_partition_with_clk_on)
516                 return pg_ops->unpowergate_partition_with_clk_on(id);
517         else
518                 WARN_ON_ONCE("This SOC doesn't support power un-gating with clk on");
519
520         return -EINVAL;
521 }
522 EXPORT_SYMBOL(tegra_unpowergate_partition_with_clk_on);
523
524 int tegra_powergate_mc_enable(int id)
525 {
526         if (!pg_ops) {
527                 pr_info("This SOC doesn't support powergating\n");
528                 return -EINVAL;
529         }
530
531         if (id < 0 || id >= pg_ops->num_powerdomains) {
532                 pr_info("%s: invalid powergate id\n", __func__);
533                 return -EINVAL;
534         }
535
536         if (pg_ops->powergate_mc_enable)
537                 return pg_ops->powergate_mc_enable(id);
538         else
539                 WARN_ON_ONCE("This SOC does not support powergate mc enable");
540
541         return -EINVAL;
542 }
543 EXPORT_SYMBOL(tegra_powergate_mc_enable);
544
545 int tegra_powergate_mc_disable(int id)
546 {
547         if (!pg_ops) {
548                 pr_info("This SOC doesn't support powergating\n");
549                 return -EINVAL;
550         }
551
552         if (id < 0 || id >= pg_ops->num_powerdomains) {
553                 pr_info("%s: invalid powergate id\n", __func__);
554                 return -EINVAL;
555         }
556
557         if (pg_ops->powergate_mc_disable)
558                 return pg_ops->powergate_mc_disable(id);
559         else
560                 WARN_ON_ONCE("This SOC does not support powergate mc disable");
561
562         return -EINVAL;
563 }
564 EXPORT_SYMBOL(tegra_powergate_mc_disable);
565
566 int tegra_powergate_mc_flush(int id)
567 {
568         if (!pg_ops) {
569                 pr_info("This SOC doesn't support powergating\n");
570                 return -EINVAL;
571         }
572
573         if (id < 0 || id >= pg_ops->num_powerdomains) {
574                 pr_info("%s: invalid powergate id\n", __func__);
575                 return -EINVAL;
576         }
577
578         if (pg_ops->powergate_mc_flush)
579                 return pg_ops->powergate_mc_flush(id);
580         else
581                 WARN_ON_ONCE("This SOC does not support powergate mc flush");
582
583         return -EINVAL;
584 }
585 EXPORT_SYMBOL(tegra_powergate_mc_flush);
586
587 int tegra_powergate_mc_flush_done(int id)
588 {
589         if (!pg_ops) {
590                 pr_info("This SOC doesn't support powergating\n");
591                 return -EINVAL;
592         }
593
594         if (id < 0 || id >= pg_ops->num_powerdomains) {
595                 pr_info("%s: invalid powergate id\n", __func__);
596                 return -EINVAL;
597         }
598
599         if (pg_ops->powergate_mc_flush_done)
600                 return pg_ops->powergate_mc_flush_done(id);
601         else
602                 WARN_ON_ONCE("This SOC does not support powergate mc flush done");
603
604         return -EINVAL;
605 }
606 EXPORT_SYMBOL(tegra_powergate_mc_flush_done);
607
608 const char *tegra_powergate_get_name(int id)
609 {
610         if (!pg_ops) {
611                 pr_info("This SOC doesn't support powergating\n");
612                 return NULL;
613         }
614
615         if (id < 0 || id >= pg_ops->num_powerdomains) {
616                 pr_info("invalid powergate id\n");
617                 return "invalid";
618         }
619
620         if (pg_ops->get_powergate_domain_name)
621                 return pg_ops->get_powergate_domain_name(id);
622         else
623                 WARN_ON_ONCE("This SOC does not support CPU powergate");
624
625         return "invalid";
626 }
627 EXPORT_SYMBOL(tegra_powergate_get_name);
628
629 int tegra_powergate_init_refcount(void)
630 {
631         if ((!pg_ops) || (!pg_ops->powergate_init_refcount))
632                 return 0;
633
634         return pg_ops->powergate_init_refcount();
635 }
636
637 int __init tegra_powergate_init(void)
638 {
639         switch (tegra_get_chip_id()) {
640                 case TEGRA_CHIPID_TEGRA2:
641                         pg_ops = tegra2_powergate_init_chip_support();
642                         break;
643
644                 case TEGRA_CHIPID_TEGRA3:
645                         pg_ops = tegra3_powergate_init_chip_support();
646                         break;
647
648                 case TEGRA_CHIPID_TEGRA11:
649                         pg_ops = tegra11x_powergate_init_chip_support();
650                         break;
651
652                 case TEGRA_CHIPID_TEGRA14:
653                         pg_ops = tegra14x_powergate_init_chip_support();
654                         break;
655
656                 case TEGRA_CHIPID_TEGRA12:
657                         pg_ops = tegra12x_powergate_init_chip_support();
658                         break;
659
660                 default:
661                         pg_ops = NULL;
662                         pr_info("%s: Unknown Tegra variant. Disabling powergate\n", __func__);
663                         break;
664         }
665
666         tegra_powergate_init_refcount();
667
668         pr_info("%s: DONE\n", __func__);
669
670         return (pg_ops ? 0 : -EINVAL);
671 }
672
673 #ifdef CONFIG_DEBUG_FS
674
675 static int powergate_show(struct seq_file *s, void *data)
676 {
677         int i;
678         const char *name;
679         bool is_pg_skip;
680
681         if (!pg_ops) {
682                 seq_printf(s, "This SOC doesn't support powergating\n");
683                 return -EINVAL;
684         }
685
686         seq_printf(s, " powergate powered\n");
687         seq_printf(s, "------------------\n");
688
689         for (i = 0; i < pg_ops->num_powerdomains; i++) {
690                 name = tegra_powergate_get_name(i);
691                 if (name) {
692                         is_pg_skip = tegra_powergate_check_skip_list(i);
693                         seq_printf(s, " %9s %7s\n", name,
694                                 (is_pg_skip ? "skip" : \
695                                 (tegra_powergate_is_powered(i) ? \
696                                 "yes" : "no")));
697                 }
698         }
699
700         return 0;
701 }
702
703 static int powergate_open(struct inode *inode, struct file *file)
704 {
705         return single_open(file, powergate_show, inode->i_private);
706 }
707
708 static const struct file_operations powergate_fops = {
709         .open           = powergate_open,
710         .read           = seq_read,
711         .llseek         = seq_lseek,
712         .release        = single_release,
713 };
714
715 int __init tegra_powergate_debugfs_init(void)
716 {
717         struct dentry *d;
718
719         d = debugfs_create_file("powergate", S_IRUGO, NULL, NULL,
720                 &powergate_fops);
721         if (!d)
722                 return -ENOMEM;
723
724         return 0;
725 }
726
727 #endif