/* * arch/arm/mach-tegra/power.h * * Declarations for power state transition code * * Copyright (c) 2010-2011, NVIDIA Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __MACH_TEGRA_POWER_H #define __MACH_TEGRA_POWER_H #include #include #define SANITY_CHECK_ARM_ERRATA_FIXES 1 #define TEGRA_POWER_PWRREQ_POLARITY 0x1 /* core power request polarity */ #define TEGRA_POWER_PWRREQ_OE 0x2 /* core power request enable */ #define TEGRA_POWER_SYSCLK_POLARITY 0x4 /* sys clk polarity */ #define TEGRA_POWER_SYSCLK_OE 0x8 /* system clock enable */ #define TEGRA_POWER_PWRGATE_DIS 0x10 /* power gate disabled */ #define TEGRA_POWER_EFFECT_LP0 0x40 /* enter LP0 when CPU pwr gated */ #define TEGRA_POWER_CPU_PWRREQ_POLARITY 0x80 /* CPU power request polarity */ #define TEGRA_POWER_CPU_PWRREQ_OE 0x100 /* CPU power request enable */ #define TEGRA_POWER_PMC_SHIFT 8 #define TEGRA_POWER_PMC_MASK 0x1ff #define TEGRA_POWER_SDRAM_SELFREFRESH 0x400 /* SDRAM is in self-refresh */ #define TEGRA_POWER_HOTPLUG_SHUTDOWN 0x800 /* Hotplug shutdown */ #define TEGRA_POWER_CLUSTER_G 0x1000 /* G CPU */ #define TEGRA_POWER_CLUSTER_LP 0x2000 /* LP CPU */ #define TEGRA_POWER_CLUSTER_MASK 0x3000 #define TEGRA_POWER_CLUSTER_IMMEDIATE 0x4000 /* Immediate wake */ #define TEGRA_POWER_CLUSTER_FORCE 0x8000 /* Force switch */ /* CPU Context area (1KB per CPU) */ #define CONTEXT_SIZE_BYTES_SHIFT 10 #define CONTEXT_SIZE_BYTES (1<> 3) & 3) static inline void flowctrl_writel(unsigned long val, void __iomem *addr) { writel(val, addr); #ifdef CONFIG_ARCH_TEGRA_2x_SOC wmb(); #endif (void)__raw_readl(addr); } extern void *tegra_context_area; #ifdef CONFIG_SMP extern bool tegra_all_cpus_booted __read_mostly; #else #define tegra_all_cpus_booted (true) #endif struct cpuidle_device; struct cpuidle_state; u64 tegra_rtc_read_ms(void); void tegra_lp2_set_trigger(unsigned long cycles); void tegra_lp2_in_idle(bool enable); unsigned long tegra_lp2_timer_remain(void); void __cortex_a9_save(unsigned int mode); void __cortex_a9_restore(void); void __shut_off_mmu(void); void tegra_secondary_startup(void); void tegra_lp2_startup(void); void tegra_hotplug_startup(void); void tegra_flow_wfi(struct cpuidle_device *dev); unsigned int tegra_suspend_lp2(unsigned int us, unsigned int flags); void tegra_idle_stats_lp2_ready(unsigned int cpu); void tegra_idle_stats_lp2_time(unsigned int cpu, s64 us); void tegra_idle_enter_lp2_cpu_0(struct cpuidle_device *dev, struct cpuidle_state *state); void tegra_idle_enter_lp2_cpu_n(struct cpuidle_device *dev, struct cpuidle_state *state); void tegra_cpu_dynamic_power_init(void); #ifdef CONFIG_ARCH_TEGRA_2x_SOC #define INSTRUMENT_CLUSTER_SWITCH 0 /* Must be zero for ARCH_TEGRA_2x_SOC */ #define DEBUG_CLUSTER_SWITCH 0 /* Must be zero for ARCH_TEGRA_2x_SOC */ #define PARAMETERIZE_CLUSTER_SWITCH 0 /* Must be zero for ARCH_TEGRA_2x_SOC */ static inline int tegra_cluster_control(unsigned int us, unsigned int flags) { return -EPERM; } #define tegra_cluster_switch_prolog(flags) do {} while (0) #define tegra_cluster_switch_epilog(flags) do {} while (0) static inline bool is_g_cluster_present(void) { return true; } static inline unsigned int is_lp_cluster(void) { return 0; } int tegra_cpudile_init_soc(void); static inline bool tegra_lp2_is_allowed(struct cpuidle_device *dev, struct cpuidle_state *state) { return true; } #define tegra_lp0_suspend_mc() do {} while (0) #define tegra_lp0_resume_mc() do {} while (0) #define tegra_lp0_cpu_mode(enter) do {} while (0) #else #define INSTRUMENT_CLUSTER_SWITCH 1 /* Should be zero for shipping code */ #define DEBUG_CLUSTER_SWITCH 1 /* Should be zero for shipping code */ #define PARAMETERIZE_CLUSTER_SWITCH 1 /* Should be zero for shipping code */ int tegra_cluster_control(unsigned int us, unsigned int flags); void tegra_cluster_switch_prolog(unsigned int flags); void tegra_cluster_switch_epilog(unsigned int flags); static inline bool is_g_cluster_present(void) { u32 fuse_sku = readl(FUSE_SKU_DIRECT_CONFIG); if (fuse_sku & FUSE_SKU_DISABLE_ALL_CPUS) return false; return true; } static inline unsigned int is_lp_cluster(void) { unsigned int reg; reg = readl(FLOW_CTRL_CLUSTER_CONTROL); return (reg & 1); /* 0 == G, 1 == LP*/ } int tegra_cpudile_init_soc(void); bool tegra_lp2_is_allowed(struct cpuidle_device *dev, struct cpuidle_state *state); void tegra_lp0_suspend_mc(void); void tegra_lp0_resume_mc(void); void tegra_lp0_cpu_mode(bool enter); #endif #if DEBUG_CLUSTER_SWITCH extern unsigned int tegra_cluster_debug; #define DEBUG_CLUSTER(x) do { if (tegra_cluster_debug) printk x; } while (0) #else #define DEBUG_CLUSTER(x) do { } while (0) #endif #if PARAMETERIZE_CLUSTER_SWITCH void tegra_cluster_switch_set_parameters(unsigned int us, unsigned int flags); #else static inline void tegra_cluster_switch_set_parameters( unsigned int us, unsigned int flags) { } #endif #endif #endif