1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
/*
* 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_ */
|