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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 349 static inline void hif_rtpm_open(struct hif_softc *scn) {} 350 static inline void hif_rtpm_close(struct hif_softc *scn) {} 351 static inline void hif_rtpm_start(struct hif_softc *scn) {} 352 static inline void hif_rtpm_stop(struct hif_softc *scn) {} 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