iosm_ipc_pm.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2020-21 Intel Corporation.
  4. */
  5. #include "iosm_ipc_protocol.h"
  6. /* Timeout value in MS for the PM to wait for device to reach active state */
  7. #define IPC_PM_ACTIVE_TIMEOUT_MS (500)
  8. /* Note that here "active" has the value 1, as compared to the enums
  9. * ipc_mem_host_pm_state or ipc_mem_dev_pm_state, where "active" is 0
  10. */
  11. #define IPC_PM_SLEEP (0)
  12. #define CONSUME_STATE (0)
  13. #define IPC_PM_ACTIVE (1)
  14. void ipc_pm_signal_hpda_doorbell(struct iosm_pm *ipc_pm, u32 identifier,
  15. bool host_slp_check)
  16. {
  17. if (host_slp_check && ipc_pm->host_pm_state != IPC_MEM_HOST_PM_ACTIVE &&
  18. ipc_pm->host_pm_state != IPC_MEM_HOST_PM_ACTIVE_WAIT) {
  19. ipc_pm->pending_hpda_update = true;
  20. dev_dbg(ipc_pm->dev,
  21. "Pend HPDA update set. Host PM_State: %d identifier:%d",
  22. ipc_pm->host_pm_state, identifier);
  23. return;
  24. }
  25. if (!ipc_pm_trigger(ipc_pm, IPC_PM_UNIT_IRQ, true)) {
  26. ipc_pm->pending_hpda_update = true;
  27. dev_dbg(ipc_pm->dev, "Pending HPDA update set. identifier:%d",
  28. identifier);
  29. return;
  30. }
  31. ipc_pm->pending_hpda_update = false;
  32. /* Trigger the irq towards CP */
  33. ipc_cp_irq_hpda_update(ipc_pm->pcie, identifier);
  34. ipc_pm_trigger(ipc_pm, IPC_PM_UNIT_IRQ, false);
  35. }
  36. /* Wake up the device if it is in low power mode. */
  37. static bool ipc_pm_link_activate(struct iosm_pm *ipc_pm)
  38. {
  39. if (ipc_pm->cp_state == IPC_MEM_DEV_PM_ACTIVE)
  40. return true;
  41. if (ipc_pm->cp_state == IPC_MEM_DEV_PM_SLEEP) {
  42. if (ipc_pm->ap_state == IPC_MEM_DEV_PM_SLEEP) {
  43. /* Wake up the device. */
  44. ipc_cp_irq_sleep_control(ipc_pm->pcie,
  45. IPC_MEM_DEV_PM_WAKEUP);
  46. ipc_pm->ap_state = IPC_MEM_DEV_PM_ACTIVE_WAIT;
  47. goto not_active;
  48. }
  49. if (ipc_pm->ap_state == IPC_MEM_DEV_PM_ACTIVE_WAIT)
  50. goto not_active;
  51. return true;
  52. }
  53. not_active:
  54. /* link is not ready */
  55. return false;
  56. }
  57. bool ipc_pm_wait_for_device_active(struct iosm_pm *ipc_pm)
  58. {
  59. bool ret_val = false;
  60. if (ipc_pm->ap_state != IPC_MEM_DEV_PM_ACTIVE) {
  61. /* Complete all memory stores before setting bit */
  62. smp_mb__before_atomic();
  63. /* Wait for IPC_PM_ACTIVE_TIMEOUT_MS for Device sleep state
  64. * machine to enter ACTIVE state.
  65. */
  66. set_bit(0, &ipc_pm->host_sleep_pend);
  67. /* Complete all memory stores after setting bit */
  68. smp_mb__after_atomic();
  69. if (!wait_for_completion_interruptible_timeout
  70. (&ipc_pm->host_sleep_complete,
  71. msecs_to_jiffies(IPC_PM_ACTIVE_TIMEOUT_MS))) {
  72. dev_err(ipc_pm->dev,
  73. "PM timeout. Expected State:%d. Actual: %d",
  74. IPC_MEM_DEV_PM_ACTIVE, ipc_pm->ap_state);
  75. goto active_timeout;
  76. }
  77. }
  78. ret_val = true;
  79. active_timeout:
  80. /* Complete all memory stores before clearing bit */
  81. smp_mb__before_atomic();
  82. /* Reset the atomic variable in any case as device sleep
  83. * state machine change is no longer of interest.
  84. */
  85. clear_bit(0, &ipc_pm->host_sleep_pend);
  86. /* Complete all memory stores after clearing bit */
  87. smp_mb__after_atomic();
  88. return ret_val;
  89. }
  90. static void ipc_pm_on_link_sleep(struct iosm_pm *ipc_pm)
  91. {
  92. /* pending sleep ack and all conditions are cleared
  93. * -> signal SLEEP__ACK to CP
  94. */
  95. ipc_pm->cp_state = IPC_MEM_DEV_PM_SLEEP;
  96. ipc_pm->ap_state = IPC_MEM_DEV_PM_SLEEP;
  97. ipc_cp_irq_sleep_control(ipc_pm->pcie, IPC_MEM_DEV_PM_SLEEP);
  98. }
  99. static void ipc_pm_on_link_wake(struct iosm_pm *ipc_pm, bool ack)
  100. {
  101. ipc_pm->ap_state = IPC_MEM_DEV_PM_ACTIVE;
  102. if (ack) {
  103. ipc_pm->cp_state = IPC_MEM_DEV_PM_ACTIVE;
  104. ipc_cp_irq_sleep_control(ipc_pm->pcie, IPC_MEM_DEV_PM_ACTIVE);
  105. /* check the consume state !!! */
  106. if (test_bit(CONSUME_STATE, &ipc_pm->host_sleep_pend))
  107. complete(&ipc_pm->host_sleep_complete);
  108. }
  109. /* Check for pending HPDA update.
  110. * Pending HP update could be because of sending message was
  111. * put on hold due to Device sleep state or due to TD update
  112. * which could be because of Device Sleep and Host Sleep
  113. * states.
  114. */
  115. if (ipc_pm->pending_hpda_update &&
  116. ipc_pm->host_pm_state == IPC_MEM_HOST_PM_ACTIVE)
  117. ipc_pm_signal_hpda_doorbell(ipc_pm, IPC_HP_PM_TRIGGER, true);
  118. }
  119. bool ipc_pm_trigger(struct iosm_pm *ipc_pm, enum ipc_pm_unit unit, bool active)
  120. {
  121. union ipc_pm_cond old_cond;
  122. union ipc_pm_cond new_cond;
  123. bool link_active;
  124. /* Save the current D3 state. */
  125. new_cond = ipc_pm->pm_cond;
  126. old_cond = ipc_pm->pm_cond;
  127. /* Calculate the power state only in the runtime phase. */
  128. switch (unit) {
  129. case IPC_PM_UNIT_IRQ: /* CP irq */
  130. new_cond.irq = active;
  131. break;
  132. case IPC_PM_UNIT_LINK: /* Device link state. */
  133. new_cond.link = active;
  134. break;
  135. case IPC_PM_UNIT_HS: /* Host sleep trigger requires Link. */
  136. new_cond.hs = active;
  137. break;
  138. default:
  139. break;
  140. }
  141. /* Something changed ? */
  142. if (old_cond.raw == new_cond.raw) {
  143. /* Stay in the current PM state. */
  144. link_active = old_cond.link == IPC_PM_ACTIVE;
  145. goto ret;
  146. }
  147. ipc_pm->pm_cond = new_cond;
  148. if (new_cond.link)
  149. ipc_pm_on_link_wake(ipc_pm, unit == IPC_PM_UNIT_LINK);
  150. else if (unit == IPC_PM_UNIT_LINK)
  151. ipc_pm_on_link_sleep(ipc_pm);
  152. if (old_cond.link == IPC_PM_SLEEP && new_cond.raw) {
  153. link_active = ipc_pm_link_activate(ipc_pm);
  154. goto ret;
  155. }
  156. link_active = old_cond.link == IPC_PM_ACTIVE;
  157. ret:
  158. return link_active;
  159. }
  160. bool ipc_pm_prepare_host_sleep(struct iosm_pm *ipc_pm)
  161. {
  162. /* suspend not allowed if host_pm_state is not IPC_MEM_HOST_PM_ACTIVE */
  163. if (ipc_pm->host_pm_state != IPC_MEM_HOST_PM_ACTIVE) {
  164. dev_err(ipc_pm->dev, "host_pm_state=%d\tExpected to be: %d",
  165. ipc_pm->host_pm_state, IPC_MEM_HOST_PM_ACTIVE);
  166. return false;
  167. }
  168. ipc_pm->host_pm_state = IPC_MEM_HOST_PM_SLEEP_WAIT_D3;
  169. return true;
  170. }
  171. bool ipc_pm_prepare_host_active(struct iosm_pm *ipc_pm)
  172. {
  173. if (ipc_pm->host_pm_state != IPC_MEM_HOST_PM_SLEEP) {
  174. dev_err(ipc_pm->dev, "host_pm_state=%d\tExpected to be: %d",
  175. ipc_pm->host_pm_state, IPC_MEM_HOST_PM_SLEEP);
  176. return false;
  177. }
  178. /* Sending Sleep Exit message to CP. Update the state */
  179. ipc_pm->host_pm_state = IPC_MEM_HOST_PM_ACTIVE_WAIT;
  180. return true;
  181. }
  182. void ipc_pm_set_s2idle_sleep(struct iosm_pm *ipc_pm, bool sleep)
  183. {
  184. if (sleep) {
  185. ipc_pm->ap_state = IPC_MEM_DEV_PM_SLEEP;
  186. ipc_pm->cp_state = IPC_MEM_DEV_PM_SLEEP;
  187. ipc_pm->device_sleep_notification = IPC_MEM_DEV_PM_SLEEP;
  188. } else {
  189. ipc_pm->ap_state = IPC_MEM_DEV_PM_ACTIVE;
  190. ipc_pm->cp_state = IPC_MEM_DEV_PM_ACTIVE;
  191. ipc_pm->device_sleep_notification = IPC_MEM_DEV_PM_ACTIVE;
  192. ipc_pm->pm_cond.link = IPC_PM_ACTIVE;
  193. }
  194. }
  195. bool ipc_pm_dev_slp_notification(struct iosm_pm *ipc_pm, u32 cp_pm_req)
  196. {
  197. if (cp_pm_req == ipc_pm->device_sleep_notification)
  198. return false;
  199. ipc_pm->device_sleep_notification = cp_pm_req;
  200. /* Evaluate the PM request. */
  201. switch (ipc_pm->cp_state) {
  202. case IPC_MEM_DEV_PM_ACTIVE:
  203. switch (cp_pm_req) {
  204. case IPC_MEM_DEV_PM_ACTIVE:
  205. break;
  206. case IPC_MEM_DEV_PM_SLEEP:
  207. /* Inform the PM that the device link can go down. */
  208. ipc_pm_trigger(ipc_pm, IPC_PM_UNIT_LINK, false);
  209. return true;
  210. default:
  211. dev_err(ipc_pm->dev,
  212. "loc-pm=%d active: confused req-pm=%d",
  213. ipc_pm->cp_state, cp_pm_req);
  214. break;
  215. }
  216. break;
  217. case IPC_MEM_DEV_PM_SLEEP:
  218. switch (cp_pm_req) {
  219. case IPC_MEM_DEV_PM_ACTIVE:
  220. /* Inform the PM that the device link is active. */
  221. ipc_pm_trigger(ipc_pm, IPC_PM_UNIT_LINK, true);
  222. break;
  223. case IPC_MEM_DEV_PM_SLEEP:
  224. break;
  225. default:
  226. dev_err(ipc_pm->dev,
  227. "loc-pm=%d sleep: confused req-pm=%d",
  228. ipc_pm->cp_state, cp_pm_req);
  229. break;
  230. }
  231. break;
  232. default:
  233. dev_err(ipc_pm->dev, "confused loc-pm=%d, req-pm=%d",
  234. ipc_pm->cp_state, cp_pm_req);
  235. break;
  236. }
  237. return false;
  238. }
  239. void ipc_pm_init(struct iosm_protocol *ipc_protocol)
  240. {
  241. struct iosm_imem *ipc_imem = ipc_protocol->imem;
  242. struct iosm_pm *ipc_pm = &ipc_protocol->pm;
  243. ipc_pm->pcie = ipc_imem->pcie;
  244. ipc_pm->dev = ipc_imem->dev;
  245. ipc_pm->pm_cond.irq = IPC_PM_SLEEP;
  246. ipc_pm->pm_cond.hs = IPC_PM_SLEEP;
  247. ipc_pm->pm_cond.link = IPC_PM_ACTIVE;
  248. ipc_pm->cp_state = IPC_MEM_DEV_PM_ACTIVE;
  249. ipc_pm->ap_state = IPC_MEM_DEV_PM_ACTIVE;
  250. ipc_pm->host_pm_state = IPC_MEM_HOST_PM_ACTIVE;
  251. /* Create generic wait-for-completion handler for Host Sleep
  252. * and device sleep coordination.
  253. */
  254. init_completion(&ipc_pm->host_sleep_complete);
  255. /* Complete all memory stores before clearing bit */
  256. smp_mb__before_atomic();
  257. clear_bit(0, &ipc_pm->host_sleep_pend);
  258. /* Complete all memory stores after clearing bit */
  259. smp_mb__after_atomic();
  260. }
  261. void ipc_pm_deinit(struct iosm_protocol *proto)
  262. {
  263. struct iosm_pm *ipc_pm = &proto->pm;
  264. complete(&ipc_pm->host_sleep_complete);
  265. }