blob: 58d011e5477f66d8311315b8682402ce592ff392 [file] [log] [blame]
Mahesh Sivasubramanianc2ea76f2016-02-01 10:40:26 -07001/*
2 * Copyright (C) 2007 Google, Inc.
Mahesh Sivasubramanian060f60c2017-06-02 16:55:51 -06003 * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
Mahesh Sivasubramanianc2ea76f2016-02-01 10:40:26 -07004 * Author: San Mehat <san@android.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef __ARCH_ARM_MACH_MSM_PM_H
18#define __ARCH_ARM_MACH_MSM_PM_H
19
20#include <linux/types.h>
21#include <linux/cpuidle.h>
22#include <asm/smp_plat.h>
23#include <asm/barrier.h>
24#include <dt-bindings/msm/pm.h>
25
26#if !defined(CONFIG_SMP)
27#define msm_secondary_startup NULL
28#elif defined(CONFIG_CPU_V7)
29#define msm_secondary_startup secondary_startup
30#else
31#define msm_secondary_startup secondary_holding_pen
32#endif
33
34enum msm_pm_sleep_mode {
35 MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT,
36 MSM_PM_SLEEP_MODE_RETENTION,
37 MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE,
38 MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
39 MSM_PM_SLEEP_MODE_FASTPC,
40 MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND,
41 MSM_PM_SLEEP_MODE_NR,
42 MSM_PM_SLEEP_MODE_NOT_SELECTED,
43};
44
45enum msm_pm_l2_scm_flag {
46 MSM_SCM_L2_ON = 0,
47 MSM_SCM_L2_OFF = 1,
48 MSM_SCM_L2_GDHS = 3,
49 MSM_SCM_L3_PC_OFF = 4,
50};
51
52#define MSM_PM_MODE(cpu, mode_nr) ((cpu) *MSM_PM_SLEEP_MODE_NR + (mode_nr))
53
54struct msm_pm_time_params {
55 uint32_t latency_us;
56 uint32_t sleep_us;
57 uint32_t next_event_us;
58 uint32_t modified_time_us;
59};
60
61struct msm_pm_sleep_status_data {
62 void *base_addr;
63 uint32_t mask;
64};
65
66struct latency_level {
67 int affinity_level;
68 int reset_level;
69 const char *level_name;
70};
71
72/**
Mahesh Sivasubramanianc2ea76f2016-02-01 10:40:26 -070073 * msm_pm_sleep_mode_allow() - API to determine if sleep mode is allowed.
74 * @cpu: CPU on which to check for the sleep mode.
75 * @mode: Sleep Mode to check for.
76 * @idle: Idle or Suspend Sleep Mode.
77 *
78 * Helper function to determine if a Idle or Suspend
79 * Sleep mode is allowed for a specific CPU.
80 *
81 * Return: 1 for allowed; 0 if not allowed.
82 */
83int msm_pm_sleep_mode_allow(unsigned int cpu, unsigned int mode, bool idle);
84
85/**
86 * msm_pm_sleep_mode_supported() - API to determine if sleep mode is
87 * supported.
88 * @cpu: CPU on which to check for the sleep mode.
89 * @mode: Sleep Mode to check for.
90 * @idle: Idle or Suspend Sleep Mode.
91 *
92 * Helper function to determine if a Idle or Suspend
93 * Sleep mode is allowed and enabled for a specific CPU.
94 *
95 * Return: 1 for supported; 0 if not supported.
96 */
97int msm_pm_sleep_mode_supported(unsigned int cpu, unsigned int mode, bool idle);
98
99struct msm_pm_cpr_ops {
100 void (*cpr_suspend)(void);
101 void (*cpr_resume)(void);
102};
103
104void __init msm_pm_set_tz_retention_flag(unsigned int flag);
105void msm_pm_enable_retention(bool enable);
106bool msm_pm_retention_enabled(void);
107bool msm_cpu_pm_enter_sleep(enum msm_pm_sleep_mode mode, bool from_idle);
108static inline void msm_arch_idle(void)
109{
110 mb(); /* Flush */
111 wfi();
112}
113
114#ifdef CONFIG_MSM_PM
115
116void msm_pm_set_rpm_wakeup_irq(unsigned int irq);
117int msm_pm_wait_cpu_shutdown(unsigned int cpu);
118int __init msm_pm_sleep_status_init(void);
119void lpm_cpu_hotplug_enter(unsigned int cpu);
120s32 msm_cpuidle_get_deep_idle_latency(void);
121int msm_pm_collapse(unsigned long unused);
122
123/**
124 * lpm_get_latency() - API to get latency for a low power mode
125 * @latency_level: pointer to structure with below elements
126 * affinity_level: The level (CPU/L2/CCI etc.) for which the
127 * latency is required.
128 * LPM_AFF_LVL_CPU : CPU level
129 * LPM_AFF_LVL_L2 : L2 level
130 * LPM_AFF_LVL_CCI : CCI level
131 * reset_level: Can be passed "LPM_RESET_LVL_GDHS" for
132 * low power mode with control logic power collapse or
133 * "LPM_RESET_LVL_PC" for low power mode with control and
134 * memory logic power collapse or "LPM_RESET_LVL_RET" for
135 * retention mode.
136 * level_name: Pointer to the cluster name for which the latency
137 * is required or NULL if the minimum value out of all the
138 * clusters is to be returned. For CPU level, the name of the
139 * L2 cluster to be passed. For CCI it has no effect.
140 * @latency: address to get the latency value.
141 *
142 * latency value will be for the particular cluster or the minimum
143 * value out of all the clusters at the particular affinity_level
144 * and reset_level.
145 *
146 * Return: 0 for success; Error number for failure.
147 */
148int lpm_get_latency(struct latency_level *level, uint32_t *latency);
149
150#else
151static inline void msm_pm_set_rpm_wakeup_irq(unsigned int irq) {}
152static inline int msm_pm_wait_cpu_shutdown(unsigned int cpu) { return 0; }
153static inline int msm_pm_sleep_status_init(void) { return 0; };
154
155static inline void lpm_cpu_hotplug_enter(unsigned int cpu)
156{
157 msm_arch_idle();
158};
159
160static inline s32 msm_cpuidle_get_deep_idle_latency(void) { return 0; }
161#define msm_pm_collapse NULL
162
163static inline int lpm_get_latency(struct latency_level *level,
164 uint32_t *latency)
165{
166 return 0;
167}
168#endif
169
170#ifdef CONFIG_HOTPLUG_CPU
171int msm_platform_secondary_init(unsigned int cpu);
172#else
173static inline int msm_platform_secondary_init(unsigned int cpu) { return 0; }
174#endif
175
176enum msm_pm_time_stats_id {
177 MSM_PM_STAT_REQUESTED_IDLE = 0,
178 MSM_PM_STAT_IDLE_SPIN,
179 MSM_PM_STAT_IDLE_WFI,
180 MSM_PM_STAT_RETENTION,
181 MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE,
182 MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE,
183 MSM_PM_STAT_IDLE_POWER_COLLAPSE,
184 MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE,
185 MSM_PM_STAT_SUSPEND,
186 MSM_PM_STAT_FAILED_SUSPEND,
187 MSM_PM_STAT_NOT_IDLE,
188 MSM_PM_STAT_COUNT
189};
190
191#ifdef CONFIG_MSM_IDLE_STATS
192void msm_pm_add_stats(enum msm_pm_time_stats_id *enable_stats, int size);
193void msm_pm_add_stat(enum msm_pm_time_stats_id id, int64_t t);
194void msm_pm_l2_add_stat(uint32_t id, int64_t t);
195#else
196static inline void msm_pm_add_stats(enum msm_pm_time_stats_id *enable_stats,
197 int size) {}
198static inline void msm_pm_add_stat(enum msm_pm_time_stats_id id, int64_t t) {}
199static inline void msm_pm_l2_add_stat(uint32_t id, int64_t t) {}
200#endif
201
202void msm_pm_set_cpr_ops(struct msm_pm_cpr_ops *ops);
203extern dma_addr_t msm_pc_debug_counters_phys;
204#endif /* __ARCH_ARM_MACH_MSM_PM_H */