1 /*
2 * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #ifndef __HIF_RUNTIME_PM_H__
19 #define __HIF_RUNTIME_PM_H__
20
21 /**
22 * enum hif_rtpm_fill_type - Caller type for Runtime PM stats fill
23 * @HIF_RTPM_FILL_TYPE_SYSFS: Sysfs is caller for Runtime PM stats
24 * @HIF_RTPM_FILL_TYPE_DEBUGFS: Debugfs is caller for Runtime PM stats
25 * @HIF_RTPM_FILL_TYPE_MAX: max value
26 */
27 enum hif_rtpm_fill_type {
28 HIF_RTPM_FILL_TYPE_SYSFS,
29 HIF_RTPM_FILL_TYPE_DEBUGFS,
30 HIF_RTPM_FILL_TYPE_MAX,
31 };
32
33 #ifdef FEATURE_RUNTIME_PM
34 #include <linux/pm_runtime.h>
35
36 /**
37 * enum hif_rtpm_state - Driver States for Runtime Power Management
38 * @HIF_RTPM_STATE_NONE: runtime pm is off
39 * @HIF_RTPM_STATE_ON: runtime pm is active and link is active
40 * @HIF_RTPM_STATE_RESUMING: a runtime resume is in progress
41 * @HIF_RTPM_STATE_RESUMING_LINKUP: Link is up during resume
42 * @HIF_RTPM_STATE_SUSPENDING: a runtime suspend is in progress
43 * @HIF_RTPM_STATE_SUSPENDED: the driver is runtime suspended
44 */
45 enum hif_rtpm_state {
46 HIF_RTPM_STATE_NONE,
47 HIF_RTPM_STATE_ON,
48 HIF_RTPM_STATE_RESUMING_LINKUP,
49 HIF_RTPM_STATE_RESUMING,
50 HIF_RTPM_STATE_SUSPENDING,
51 HIF_RTPM_STATE_SUSPENDED,
52 };
53
54 /**
55 * struct hif_rtpm_state_stats - Runtime PM stats
56 * @resume_count: count of resume calls done
57 * @suspend_count: count of suspend calls done
58 * @suspend_err_count: count of suspend calls failed
59 * @resume_ts: Last resume call timestamp
60 * @suspend_ts: Last suspend call timestamp
61 * @suspend_err_ts: Last suspend call fail timestamp
62 * @last_busy_ts: Last busy timestamp marked
63 * @last_busy_id:
64 * @last_busy_marker:
65 * @request_resume_ts: Last request resume done timestamp
66 * @request_resume_id: Client ID requesting resume
67 * @prevent_suspend:
68 * @allow_suspend:
69 * @runtime_get_err:
70 */
71 struct hif_rtpm_state_stats {
72 uint32_t resume_count;
73 uint32_t suspend_count;
74 uint32_t suspend_err_count;
75 uint64_t resume_ts;
76 uint64_t suspend_ts;
77 uint64_t suspend_err_ts;
78 uint64_t last_busy_ts;
79 uint32_t last_busy_id;
80 void *last_busy_marker;
81 uint64_t request_resume_ts;
82 uint64_t request_resume_id;
83 uint32_t prevent_suspend;
84 uint32_t allow_suspend;
85 uint32_t runtime_get_err;
86 };
87
88 #define HIF_RTPM_BUSY_HIST_MAX 16
89 #define HIF_RTPM_BUSY_HIST_MASK (HIF_RTPM_BUSY_HIST_MAX - 1)
90
91 /**
92 * struct hif_rtpm_last_busy_hist - Runtime last busy hist
93 * @last_busy_cnt: count of last busy mark
94 * @last_busy_idx: last busy history index
95 * @last_busy_ts: last busy marked timestamp
96 */
97 struct hif_rtpm_last_busy_hist {
98 unsigned long last_busy_cnt;
99 unsigned long last_busy_idx;
100 uint64_t last_busy_ts[HIF_RTPM_BUSY_HIST_MAX];
101 };
102
103 /**
104 * struct hif_rtpm_client - Runtime PM client structure
105 * @hif_rtpm_cbk: Callback during resume if get called at suspend and failed
106 * @active_count: current active status of client
107 * @get_count: count of get calls by this client
108 * @put_count: count of put calls by this client
109 * @last_busy_cnt:
110 * @get_ts: Last get called timestamp
111 * @put_ts: Last put called timestamp
112 * @last_busy_ts:
113 */
114 struct hif_rtpm_client {
115 void (*hif_rtpm_cbk)(void);
116 qdf_atomic_t active_count;
117 qdf_atomic_t get_count;
118 qdf_atomic_t put_count;
119 uint32_t last_busy_cnt;
120 uint64_t get_ts;
121 uint64_t put_ts;
122 uint64_t last_busy_ts;
123 };
124
125 /**
126 * struct hif_rtpm_ctx - Runtime power management context
127 * @enable_rpm:
128 * @dev:
129 * @runtime_lock: Lock to sync state changes with get calls
130 * @runtime_suspend_lock: Suspend lock
131 * @client_count: Number of clients currently registered
132 * @clients: clients registered to use runtime PM module
133 * @prevent_list_lock:
134 * @prevent_list:
135 * @prevent_cnt:
136 * @pm_state: Current runtime pm state
137 * @pending_job: bitmap to set the client job to be called at resume
138 * @monitor_wake_intr: Monitor waking MSI for runtime PM
139 * @stats: Runtime PM stats
140 * @pm_dentry: debug fs entry
141 * @cfg_delay:
142 * @delay:
143 * @busy_hist: busy histogram
144 */
145 struct hif_rtpm_ctx {
146 bool enable_rpm;
147 struct device *dev;
148 qdf_spinlock_t runtime_lock;
149 qdf_spinlock_t runtime_suspend_lock;
150 unsigned int client_count;
151 struct hif_rtpm_client *clients[HIF_RTPM_ID_MAX];
152 qdf_spinlock_t prevent_list_lock;
153 struct list_head prevent_list;
154 uint32_t prevent_cnt;
155 qdf_atomic_t pm_state;
156 unsigned long pending_job;
157 qdf_atomic_t monitor_wake_intr;
158 struct hif_rtpm_state_stats stats;
159 struct dentry *pm_dentry;
160 int cfg_delay;
161 int delay;
162 struct hif_rtpm_last_busy_hist *busy_hist[CE_COUNT_MAX];
163 };
164
165 #define HIF_RTPM_DELAY_MIN 100
166 #define HIF_RTPM_DELAY_MAX 10000
167
168 /**
169 * __hif_rtpm_enabled() - Check if runtime pm is enabled from kernel
170 * @dev: device structure
171 *
172 * Return: true if enabled.
173 */
__hif_rtpm_enabled(struct device * dev)174 static inline bool __hif_rtpm_enabled(struct device *dev)
175 {
176 return pm_runtime_enabled(dev);
177 }
178
179 /**
180 * __hif_rtpm_get() - Increment dev usage count and call resume function
181 * @dev: device structure
182 *
183 * Increments usage count and internally queue resume work
184 *
185 * Return: 1 if state is active. 0 if resume is requested. Error otherwise.
186 */
__hif_rtpm_get(struct device * dev)187 static inline int __hif_rtpm_get(struct device *dev)
188 {
189 return pm_runtime_get(dev);
190 }
191
192 /**
193 * __hif_rtpm_get_noresume() - Only increment dev usage count
194 * @dev: device structure
195 *
196 * Return: Void
197 */
__hif_rtpm_get_noresume(struct device * dev)198 static inline void __hif_rtpm_get_noresume(struct device *dev)
199 {
200 pm_runtime_get_noresume(dev);
201 }
202
203 /**
204 * __hif_rtpm_get_sync() - Increment usage count and set state to active
205 * @dev: device structure
206 *
207 * Return: 1 if state is already active, 0 if state active was done.
208 * Error otherwise.
209 */
__hif_rtpm_get_sync(struct device * dev)210 static inline int __hif_rtpm_get_sync(struct device *dev)
211 {
212 return pm_runtime_get_sync(dev);
213 }
214
215 /**
216 * __hif_rtpm_put_auto() - Decrement usage count and call suspend function
217 * @dev: device structure
218 *
219 * Decrements usage count and queue suspend work if usage count is 0
220 *
221 * Return: 0 if success. Error otherwise.
222 */
__hif_rtpm_put_auto(struct device * dev)223 static inline int __hif_rtpm_put_auto(struct device *dev)
224 {
225 return pm_runtime_put_autosuspend(dev);
226 }
227
228 /**
229 * __hif_rtpm_put_noidle() - Decrement usage count
230 * @dev: device structure
231 *
232 * Return: void
233 */
__hif_rtpm_put_noidle(struct device * dev)234 static inline void __hif_rtpm_put_noidle(struct device *dev)
235 {
236 pm_runtime_put_noidle(dev);
237 }
238
239 /**
240 * __hif_rtpm_put_sync_suspend() - Decrement usage count
241 * @dev: device structure
242 *
243 * Decrement usage_count of device and if 0 synchrounsly call suspend function
244 *
245 * Return: 0 if success. Error otherwise
246 */
__hif_rtpm_put_sync_suspend(struct device * dev)247 static inline int __hif_rtpm_put_sync_suspend(struct device *dev)
248 {
249 return pm_runtime_put_sync_suspend(dev);
250 }
251
252 /**
253 * __hif_rtpm_set_autosuspend_delay() - Set delay to trigger RTPM suspend
254 * @dev: device structure
255 * @delay: delay in ms to be set
256 *
257 * Return: None
258 */
259 static inline
__hif_rtpm_set_autosuspend_delay(struct device * dev,int delay)260 void __hif_rtpm_set_autosuspend_delay(struct device *dev, int delay)
261 {
262 pm_runtime_set_autosuspend_delay(dev, delay);
263 }
264
265 /**
266 * __hif_rtpm_mark_last_busy() - Mark last busy timestamp
267 * @dev: device structure
268 *
269 * Return: Void
270 */
__hif_rtpm_mark_last_busy(struct device * dev)271 static inline void __hif_rtpm_mark_last_busy(struct device *dev)
272 {
273 pm_runtime_mark_last_busy(dev);
274 }
275
276 /**
277 * __hif_rtpm_resume() - Do Runtime PM Resume of bus
278 * @dev: device structure
279 *
280 * Return: 0 if success. Error otherwise
281 */
__hif_rtpm_resume(struct device * dev)282 static inline int __hif_rtpm_resume(struct device *dev)
283 {
284 return pm_runtime_resume(dev);
285 }
286
287 /**
288 * __hif_rtpm_request_resume() - Queue resume work
289 * @dev: device structure
290 *
291 * Return: 1 if already active. 0 if successfully queued. Error otherwise
292 */
__hif_rtpm_request_resume(struct device * dev)293 static inline int __hif_rtpm_request_resume(struct device *dev)
294 {
295 return pm_request_resume(dev);
296 }
297
298 /**
299 * hif_rtpm_open() - initialize runtime pm
300 * @scn: hif ctx
301 *
302 * Return: None
303 */
304 void hif_rtpm_open(struct hif_softc *scn);
305
306 /**
307 * hif_rtpm_close() - close runtime pm
308 * @scn: hif ctx
309 *
310 * ensure runtime_pm is stopped before closing the driver
311 *
312 * Return: None
313 */
314 void hif_rtpm_close(struct hif_softc *scn);
315
316 /**
317 * hif_rtpm_start() - start the runtime pm
318 * @scn: hif context
319 *
320 * After this call, runtime pm will be active.
321 *
322 * Return: None
323 */
324 void hif_rtpm_start(struct hif_softc *scn);
325
326 /**
327 * hif_rtpm_stop() - stop runtime pm
328 * @scn: hif context
329 *
330 * Turns off runtime pm and frees corresponding resources
331 * that were acquired by hif_rtpm_start().
332 *
333 * Return: None
334 */
335 void hif_rtpm_stop(struct hif_softc *scn);
336
337 /**
338 * hif_rtpm_log_debug_stats() - fill buffer with runtime pm stats
339 * @s: pointer to buffer to fill status
340 * @type: type of caller
341 *
342 * Fills input buffer with runtime pm stats depending on caller type.
343 *
344 * Return: Num of bytes filled if caller type requires, else 0.
345 */
346 int hif_rtpm_log_debug_stats(void *s, enum hif_rtpm_fill_type type);
347
348 #else
hif_rtpm_open(struct hif_softc * scn)349 static inline void hif_rtpm_open(struct hif_softc *scn) {}
hif_rtpm_close(struct hif_softc * scn)350 static inline void hif_rtpm_close(struct hif_softc *scn) {}
hif_rtpm_start(struct hif_softc * scn)351 static inline void hif_rtpm_start(struct hif_softc *scn) {}
hif_rtpm_stop(struct hif_softc * scn)352 static inline void hif_rtpm_stop(struct hif_softc *scn) {}
hif_rtpm_log_debug_stats(void * s,enum hif_rtpm_fill_type type)353 static inline int hif_rtpm_log_debug_stats(void *s,
354 enum hif_rtpm_fill_type type)
355 {
356 return 0;
357 }
358 #endif /* FEATURE_RUNTIME_PM */
359 #endif /* __HIF_RUNTIME_PM_H__ */
360