2 * arch/arm/mach-tegra/powergate.c
4 * Copyright (c) 2010 Google, Inc
5 * Copyright (c) 2011 - 2013, NVIDIA CORPORATION. All rights reserved.
8 * Colin Cross <ccross@google.com>
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.
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.
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>
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>
42 #include "powergate-priv.h"
44 static struct powergate_ops *pg_ops;
46 static spinlock_t *tegra_get_powergate_lock(void)
48 if (pg_ops && pg_ops->get_powergate_lock)
49 return pg_ops->get_powergate_lock();
51 WARN_ON_ONCE("This SOC does not export powergate lock");
56 int tegra_powergate_set(int id, bool new_state)
62 if (tegra_cpu_is_asim())
65 lock = tegra_get_powergate_lock();
66 /* 10us timeout for toggle operation if it takes affect*/
67 int toggle_timeout = 10;
69 /* 100 * 10 = 1000us timeout for toggle command to take affect in case
70 of contention with h/w initiated CPU power gating */
71 int contention_timeout = 100;
73 spin_lock_irqsave(lock, flags);
75 status = !!(pmc_read(PWRGATE_STATUS) & (1 << id));
77 if (status == new_state) {
78 spin_unlock_irqrestore(lock, flags);
82 if (TEGRA_IS_CPU_POWERGATE_ID(id)) {
83 /* CPU ungated in s/w only during boot/resume with outer
84 waiting loop and no contention from other CPUs */
85 pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
86 spin_unlock_irqrestore(lock, flags);
90 pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
94 status = !!(pmc_read(PWRGATE_STATUS) & (1 << id));
97 } while ((status != new_state) && (toggle_timeout > 0));
100 } while ((status != new_state) && (contention_timeout > 0));
102 spin_unlock_irqrestore(lock, flags);
104 if (status != new_state) {
105 WARN(1, "Could not set powergate %d to %d", id, new_state);
109 trace_power_domain_target(tegra_powergate_get_name(id), new_state,
110 raw_smp_processor_id());
115 int is_partition_clk_disabled(struct powergate_partition_info *pg_info)
119 struct partition_clk_info *clk_info;
122 for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
123 clk_info = &pg_info->clk_info[idx];
124 clk = clk_info->clk_ptr;
129 if (clk_info->clk_type != RST_ONLY) {
130 if (tegra_is_clk_enabled(clk)) {
140 int powergate_module(int id)
143 pr_info("This SOC doesn't support powergating\n");
147 if (id < 0 || id >= pg_ops->num_powerdomains)
150 tegra_powergate_mc_flush(id);
152 return tegra_powergate_set(id, false);
155 int unpowergate_module(int id)
158 pr_info("This SOC doesn't support powergating\n");
162 if (id < 0 || id >= pg_ops->num_powerdomains)
165 return tegra_powergate_set(id, true);
168 int partition_clk_enable(struct powergate_partition_info *pg_info)
173 struct partition_clk_info *clk_info;
175 for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
176 clk_info = &pg_info->clk_info[idx];
177 clk = clk_info->clk_ptr;
181 if (clk_info->clk_type != RST_ONLY) {
182 ret = tegra_clk_prepare_enable(clk);
191 WARN(1, "Could not enable clk %s, error %d", clk->name, ret);
193 clk_info = &pg_info->clk_info[idx];
194 if (clk_info->clk_type != RST_ONLY)
195 tegra_clk_disable_unprepare(clk_info->clk_ptr);
201 void partition_clk_disable(struct powergate_partition_info *pg_info)
205 struct partition_clk_info *clk_info;
207 for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
208 clk_info = &pg_info->clk_info[idx];
209 clk = clk_info->clk_ptr;
214 if (clk_info->clk_type != RST_ONLY)
215 tegra_clk_disable_unprepare(clk);
219 void get_clk_info(struct powergate_partition_info *pg_info)
223 for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
224 if (!pg_info->clk_info[idx].clk_name)
227 pg_info->clk_info[idx].clk_ptr = tegra_get_clock_by_name(
228 pg_info->clk_info[idx].clk_name);
232 void powergate_partition_assert_reset(struct powergate_partition_info *pg_info)
236 struct partition_clk_info *clk_info;
238 for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
239 clk_info = &pg_info->clk_info[idx];
240 clk_ptr = clk_info->clk_ptr;
245 if (clk_info->clk_type != CLK_ONLY)
246 tegra_periph_reset_assert(clk_ptr);
250 void powergate_partition_deassert_reset(struct powergate_partition_info *pg_info)
254 struct partition_clk_info *clk_info;
256 for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
257 clk_info = &pg_info->clk_info[idx];
258 clk_ptr = clk_info->clk_ptr;
263 if (clk_info->clk_type != CLK_ONLY)
264 tegra_periph_reset_deassert(clk_ptr);
268 int tegra_powergate_reset_module(struct powergate_partition_info *pg_info)
272 powergate_partition_assert_reset(pg_info);
276 ret = partition_clk_enable(pg_info);
282 powergate_partition_deassert_reset(pg_info);
284 partition_clk_disable(pg_info);
289 bool tegra_powergate_check_clamping(int id)
291 if (!pg_ops || !pg_ops->powergate_check_clamping) {
292 pr_info("This SOC can't check clamping status\n");
296 if (id < 0 || id >= pg_ops->num_powerdomains)
299 return pg_ops->powergate_check_clamping(id);
302 int tegra_powergate_remove_clamping(int id)
305 int contention_timeout = 100;
308 pr_info("This SOC doesn't support powergating\n");
312 if (id < 0 || id >= pg_ops->num_powerdomains)
316 * PCIE and VDE clamping masks are swapped with respect to their
319 if (id == TEGRA_POWERGATE_VDEC)
320 mask = (1 << TEGRA_POWERGATE_PCIE);
321 else if (id == TEGRA_POWERGATE_PCIE)
322 mask = (1 << TEGRA_POWERGATE_VDEC);
326 pmc_write(mask, REMOVE_CLAMPING);
327 /* Wait until clamp is removed */
330 contention_timeout--;
331 } while ((contention_timeout > 0)
332 && (pmc_read(REMOVE_CLAMPING) & mask));
334 WARN(contention_timeout <= 0, "Couldn't remove clamping");
339 static inline bool tegra_powergate_check_skip_list(int id)
341 return pg_ops->powergate_skip ?
342 pg_ops->powergate_skip(id) : false;
345 /* EXTERNALY VISIBLE APIS */
347 bool tegra_powergate_is_powered(int id)
352 pr_info("This SOC doesn't support powergating\n");
356 if (id < 0 || id >= pg_ops->num_powerdomains)
359 if (pg_ops->powergate_is_powered)
360 return pg_ops->powergate_is_powered(id);
362 status = pmc_read(PWRGATE_STATUS) & (1 << id);
364 status = pmc_read(PWRGATE_STATUS) & (1 << id);
368 EXPORT_SYMBOL(tegra_powergate_is_powered);
370 int tegra_cpu_powergate_id(int cpuid)
373 pr_info("This SOC doesn't support powergating\n");
377 if (cpuid < 0 || cpuid >= pg_ops->num_cpu_domains) {
378 pr_info("%s: invalid powergate id\n", __func__);
382 if (pg_ops->cpu_domains)
383 return pg_ops->cpu_domains[cpuid];
385 WARN_ON_ONCE("This SOC does not support CPU powergate\n");
389 EXPORT_SYMBOL(tegra_cpu_powergate_id);
391 int tegra_powergate_partition(int id)
394 pr_info("This SOC doesn't support powergating\n");
398 if (id < 0 || id >= pg_ops->num_powerdomains) {
399 pr_info("%s: invalid powergate id\n", __func__);
403 if (tegra_powergate_check_skip_list(id))
404 printk_once("%s: %s is in powergate skip list\n", __func__,
405 tegra_powergate_get_name(id));
407 if (pg_ops->powergate_partition)
408 return pg_ops->powergate_partition(id);
410 WARN_ON_ONCE("This SOC doesn't support powergating");
414 EXPORT_SYMBOL(tegra_powergate_partition);
416 int tegra_unpowergate_partition(int id)
419 pr_info("This SOC doesn't support powergating\n");
423 if (id < 0 || id >= pg_ops->num_powerdomains) {
424 pr_info("%s: invalid powergate id\n", __func__);
428 if (tegra_powergate_check_skip_list(id))
429 printk_once("%s: %s is in powergate skip list\n", __func__,
430 tegra_powergate_get_name(id));
432 if (pg_ops->unpowergate_partition)
433 return pg_ops->unpowergate_partition(id);
435 WARN_ON_ONCE("This SOC doesn't support un-powergating");
439 EXPORT_SYMBOL(tegra_unpowergate_partition);
441 int tegra_powergate_partition_with_clk_off(int id)
444 pr_info("This SOC doesn't support powergating\n");
448 if (id < 0 || id >= pg_ops->num_powerdomains) {
449 pr_info("%s: invalid powergate id\n", __func__);
453 if (tegra_powergate_check_skip_list(id))
454 printk_once("%s: %s is in powergate skip list\n", __func__,
455 tegra_powergate_get_name(id));
457 if (pg_ops->powergate_partition_with_clk_off)
458 return pg_ops->powergate_partition_with_clk_off(id);
460 WARN_ON_ONCE("This SOC doesn't support powergating with clk off");
464 EXPORT_SYMBOL(tegra_powergate_partition_with_clk_off);
466 int tegra_unpowergate_partition_with_clk_on(int id)
469 pr_info("This SOC doesn't support powergating\n");
473 if (id < 0 || id >= pg_ops->num_powerdomains) {
474 pr_info("%s: invalid powergate id\n", __func__);
478 if (tegra_powergate_check_skip_list(id))
479 printk_once("%s: %s is in powergate skip list\n", __func__,
480 tegra_powergate_get_name(id));
482 if (pg_ops->unpowergate_partition_with_clk_on)
483 return pg_ops->unpowergate_partition_with_clk_on(id);
485 WARN_ON_ONCE("This SOC doesn't support power un-gating with clk on");
489 EXPORT_SYMBOL(tegra_unpowergate_partition_with_clk_on);
491 int tegra_powergate_mc_enable(int id)
494 pr_info("This SOC doesn't support powergating\n");
498 if (id < 0 || id >= pg_ops->num_powerdomains) {
499 pr_info("%s: invalid powergate id\n", __func__);
503 if (pg_ops->powergate_mc_enable)
504 return pg_ops->powergate_mc_enable(id);
506 WARN_ON_ONCE("This SOC does not support powergate mc enable");
510 EXPORT_SYMBOL(tegra_powergate_mc_enable);
512 int tegra_powergate_mc_disable(int id)
515 pr_info("This SOC doesn't support powergating\n");
519 if (id < 0 || id >= pg_ops->num_powerdomains) {
520 pr_info("%s: invalid powergate id\n", __func__);
524 if (pg_ops->powergate_mc_disable)
525 return pg_ops->powergate_mc_disable(id);
527 WARN_ON_ONCE("This SOC does not support powergate mc disable");
531 EXPORT_SYMBOL(tegra_powergate_mc_disable);
533 int tegra_powergate_mc_flush(int id)
536 pr_info("This SOC doesn't support powergating\n");
540 if (id < 0 || id >= pg_ops->num_powerdomains) {
541 pr_info("%s: invalid powergate id\n", __func__);
545 if (pg_ops->powergate_mc_flush)
546 return pg_ops->powergate_mc_flush(id);
548 WARN_ON_ONCE("This SOC does not support powergate mc flush");
552 EXPORT_SYMBOL(tegra_powergate_mc_flush);
554 int tegra_powergate_mc_flush_done(int id)
557 pr_info("This SOC doesn't support powergating\n");
561 if (id < 0 || id >= pg_ops->num_powerdomains) {
562 pr_info("%s: invalid powergate id\n", __func__);
566 if (pg_ops->powergate_mc_flush_done)
567 return pg_ops->powergate_mc_flush_done(id);
569 WARN_ON_ONCE("This SOC does not support powergate mc flush done");
573 EXPORT_SYMBOL(tegra_powergate_mc_flush_done);
575 const char *tegra_powergate_get_name(int id)
578 pr_info("This SOC doesn't support powergating\n");
582 if (id < 0 || id >= pg_ops->num_powerdomains) {
583 pr_info("invalid powergate id\n");
587 if (pg_ops->get_powergate_domain_name)
588 return pg_ops->get_powergate_domain_name(id);
590 WARN_ON_ONCE("This SOC does not support CPU powergate");
594 EXPORT_SYMBOL(tegra_powergate_get_name);
596 int tegra_powergate_init_refcount(void)
598 if ((!pg_ops) || (!pg_ops->powergate_init_refcount))
601 return pg_ops->powergate_init_refcount();
604 int __init tegra_powergate_init(void)
606 switch (tegra_chip_id) {
607 case TEGRA_CHIPID_TEGRA2:
608 pg_ops = tegra2_powergate_init_chip_support();
611 case TEGRA_CHIPID_TEGRA3:
612 pg_ops = tegra3_powergate_init_chip_support();
615 case TEGRA_CHIPID_TEGRA11:
616 pg_ops = tegra11x_powergate_init_chip_support();
619 case TEGRA_CHIPID_TEGRA14:
620 pg_ops = tegra14x_powergate_init_chip_support();
623 case TEGRA_CHIPID_TEGRA12:
624 pg_ops = tegra12x_powergate_init_chip_support();
629 pr_info("%s: Unknown Tegra variant. Disabling powergate\n", __func__);
633 tegra_powergate_init_refcount();
635 pr_info("%s: DONE\n", __func__);
637 return (pg_ops ? 0 : -EINVAL);
640 #ifdef CONFIG_DEBUG_FS
642 static int powergate_show(struct seq_file *s, void *data)
649 seq_printf(s, "This SOC doesn't support powergating\n");
653 seq_printf(s, " powergate powered\n");
654 seq_printf(s, "------------------\n");
656 for (i = 0; i < pg_ops->num_powerdomains; i++) {
657 name = tegra_powergate_get_name(i);
659 is_pg_skip = tegra_powergate_check_skip_list(i);
660 seq_printf(s, " %9s %7s\n", name,
661 (is_pg_skip ? "skip" : \
662 (tegra_powergate_is_powered(i) ? \
670 static int powergate_open(struct inode *inode, struct file *file)
672 return single_open(file, powergate_show, inode->i_private);
675 static const struct file_operations powergate_fops = {
676 .open = powergate_open,
679 .release = single_release,
682 int __init tegra_powergate_debugfs_init(void)
686 d = debugfs_create_file("powergate", S_IRUGO, NULL, NULL,