tegrakernel/kernel/nvidia/include/linux/tegra-pm.h

151 lines
4.9 KiB
C
Raw Permalink Normal View History

2022-02-16 09:13:02 -06:00
/*
* 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_ */