151 lines
4.9 KiB
C
151 lines
4.9 KiB
C
/*
|
|
* include/linux/tegra-pm.h
|
|
*
|
|
* Copyright (c) 2013-2017, NVIDIA CORPORATION. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* 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 _LINUX_TEGRA_PM_H_
|
|
#define _LINUX_TEGRA_PM_H_
|
|
|
|
#include <linux/dcache.h>
|
|
|
|
/* Core state 0-9 */
|
|
#define TEGRA210_CPUIDLE_C4 4
|
|
#define TEGRA210_CPUIDLE_C7 7
|
|
|
|
/* Cluster states 10-19 */
|
|
#define TEGRA210_CPUIDLE_CC4 14
|
|
#define TEGRA210_CPUIDLE_CC6 16
|
|
#define TEGRA210_CPUIDLE_CC7 17
|
|
|
|
/* SoC states 20-29 */
|
|
#define TEGRA210_CPUIDLE_SC2 22
|
|
#define TEGRA210_CPUIDLE_SC3 23
|
|
#define TEGRA210_CPUIDLE_SC4 24
|
|
#define TEGRA210_CPUIDLE_SC7 27
|
|
|
|
#define TEGRA210_CLUSTER_SWITCH 31
|
|
|
|
#define TEGRA_PM_SUSPEND 0x0001
|
|
#define TEGRA_PM_RESUME 0x0002
|
|
|
|
#define NR_SMC_REGS 6
|
|
|
|
#ifdef CONFIG_PM
|
|
#define SMC_FAKE_SYS_SUSPEND 0xC2FFFE00
|
|
#define FAKE_SYSTEM_SUSPEND_MODE 3
|
|
#define FAKE_SYSTEM_SUSPEND_USER_ARG 7
|
|
#define SMC_ENUM_MAX 0xFF
|
|
|
|
#endif
|
|
|
|
struct pm_regs {
|
|
u64 args[NR_SMC_REGS];
|
|
};
|
|
|
|
enum tegra_suspend_mode {
|
|
TEGRA_SUSPEND_NONE = 0,
|
|
TEGRA_SUSPEND_LP2, /* CPU voltage off */
|
|
TEGRA_SUSPEND_LP1, /* CPU voltage off, DRAM self-refresh */
|
|
TEGRA_SUSPEND_LP0, /* CPU + core voltage off, DRAM self-refresh */
|
|
TEGRA_MAX_SUSPEND_MODE,
|
|
};
|
|
|
|
enum suspend_stage {
|
|
TEGRA_SUSPEND_BEFORE_PERIPHERAL,
|
|
TEGRA_SUSPEND_BEFORE_CPU,
|
|
};
|
|
|
|
enum resume_stage {
|
|
TEGRA_RESUME_AFTER_PERIPHERAL,
|
|
TEGRA_RESUME_AFTER_CPU,
|
|
};
|
|
|
|
struct tegra_suspend_platform_data {
|
|
unsigned long cpu_timer; /* CPU power good time in us, LP2/LP1 */
|
|
unsigned long cpu_off_timer; /* CPU power off time us, LP2/LP1 */
|
|
unsigned long core_timer; /* core power good time in ticks, LP0 */
|
|
unsigned long core_off_timer; /* core power off time ticks, LP0 */
|
|
unsigned int cpu_suspend_freq; /* cpu suspend/resume frequency in Hz */
|
|
bool corereq_high; /* Core power request active-high */
|
|
bool sysclkreq_high; /* System clock request is active-high */
|
|
bool sysclkreq_gpio; /* if System clock request is set to gpio */
|
|
bool combined_req; /* if core & CPU power requests are combined */
|
|
enum tegra_suspend_mode suspend_mode;
|
|
unsigned long cpu_lp2_min_residency; /* Min LP2 state residency in us */
|
|
void (*board_suspend)(int lp_state, enum suspend_stage stg);
|
|
/* lp_state = 0 for LP0 state, 1 for LP1 state, 2 for LP2 state */
|
|
void (*board_resume)(int lp_state, enum resume_stage stg);
|
|
unsigned int cpu_resume_boost; /* CPU frequency resume boost in kHz */
|
|
#ifdef CONFIG_TEGRA_LP1_LOW_COREVOLTAGE
|
|
bool lp1_lowvolt_support;
|
|
unsigned int i2c_base_addr;
|
|
unsigned int pmuslave_addr;
|
|
unsigned int core_reg_addr;
|
|
unsigned int lp1_core_volt_low_cold;
|
|
unsigned int lp1_core_volt_low;
|
|
unsigned int lp1_core_volt_high;
|
|
#endif
|
|
unsigned int lp1bb_core_volt_min;
|
|
unsigned long lp1bb_emc_rate_min;
|
|
unsigned long lp1bb_emc_rate_max;
|
|
#ifdef CONFIG_ARCH_TEGRA_HAS_SYMMETRIC_CPU_PWR_GATE
|
|
unsigned long min_residency_vmin_fmin;
|
|
unsigned long min_residency_ncpu_slow;
|
|
unsigned long min_residency_ncpu_fast;
|
|
unsigned long min_residency_crail;
|
|
bool crail_up_early;
|
|
#endif
|
|
unsigned long min_residency_mclk_stop;
|
|
bool usb_vbus_internal_wake; /* support for internal vbus wake */
|
|
bool usb_id_internal_wake; /* support for internal id wake */
|
|
|
|
void (*suspend_dfll_bypass)(void);
|
|
void (*resume_dfll_bypass)(void);
|
|
};
|
|
|
|
void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat);
|
|
|
|
#ifdef CONFIG_PM
|
|
int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags);
|
|
|
|
int tegra_register_pm_notifier(struct notifier_block *nb);
|
|
int tegra_unregister_pm_notifier(struct notifier_block *nb);
|
|
int tegra_pm_notifier_call_chain(unsigned int val);
|
|
void tegra_log_suspend_entry_time(void);
|
|
void tegra_log_resume_time(void);
|
|
struct dentry *return_system_states_dir(void);
|
|
int send_smc(u32 smc_func, struct pm_regs *regs);
|
|
|
|
#else
|
|
static inline int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags)
|
|
{ return 0; }
|
|
static inline int tegra_register_pm_notifier(struct notifier_block *nb)
|
|
{ return 0; }
|
|
static inline int tegra_unregister_pm_notifier(struct notifier_block *nb)
|
|
{ return 0; }
|
|
static inline int tegra_pm_notifier_call_chain(unsigned int val)
|
|
{ return 0; }
|
|
static inline void tegra_log_suspend_entry_time(void) { }
|
|
static inline void tegra_log_resume_time(void) { }
|
|
static struct dentry *return_system_state_debugfs(void)
|
|
{return NULL; }
|
|
static int send_smc(u32 smc_func, struct pm_regs *regs)
|
|
{return 0; }
|
|
#endif
|
|
|
|
#endif /* _LINUX_TEGRA_PM_H_ */
|