hif_runtime_pm.h 9.5 KB

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