intel_bus_common.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
  2. // Copyright(c) 2015-2023 Intel Corporation
  3. #include <linux/acpi.h>
  4. #include <linux/soundwire/sdw_registers.h>
  5. #include <linux/soundwire/sdw.h>
  6. #include <linux/soundwire/sdw_intel.h>
  7. #include "cadence_master.h"
  8. #include "bus.h"
  9. #include "intel.h"
  10. int intel_start_bus(struct sdw_intel *sdw)
  11. {
  12. struct device *dev = sdw->cdns.dev;
  13. struct sdw_cdns *cdns = &sdw->cdns;
  14. struct sdw_bus *bus = &cdns->bus;
  15. int ret;
  16. /*
  17. * follow recommended programming flows to avoid timeouts when
  18. * gsync is enabled
  19. */
  20. if (bus->multi_link)
  21. sdw_intel_sync_arm(sdw);
  22. ret = sdw_cdns_init(cdns);
  23. if (ret < 0) {
  24. dev_err(dev, "%s: unable to initialize Cadence IP: %d\n", __func__, ret);
  25. return ret;
  26. }
  27. sdw_cdns_config_update(cdns);
  28. if (bus->multi_link) {
  29. ret = sdw_intel_sync_go(sdw);
  30. if (ret < 0) {
  31. dev_err(dev, "%s: sync go failed: %d\n", __func__, ret);
  32. return ret;
  33. }
  34. }
  35. ret = sdw_cdns_config_update_set_wait(cdns);
  36. if (ret < 0) {
  37. dev_err(dev, "%s: CONFIG_UPDATE BIT still set\n", __func__);
  38. return ret;
  39. }
  40. ret = sdw_cdns_enable_interrupt(cdns, true);
  41. if (ret < 0) {
  42. dev_err(dev, "%s: cannot enable interrupts: %d\n", __func__, ret);
  43. return ret;
  44. }
  45. ret = sdw_cdns_exit_reset(cdns);
  46. if (ret < 0) {
  47. dev_err(dev, "%s: unable to exit bus reset sequence: %d\n", __func__, ret);
  48. return ret;
  49. }
  50. sdw_cdns_check_self_clearing_bits(cdns, __func__,
  51. true, INTEL_MASTER_RESET_ITERATIONS);
  52. schedule_delayed_work(&cdns->attach_dwork,
  53. msecs_to_jiffies(SDW_INTEL_DELAYED_ENUMERATION_MS));
  54. return 0;
  55. }
  56. int intel_start_bus_after_reset(struct sdw_intel *sdw)
  57. {
  58. struct device *dev = sdw->cdns.dev;
  59. struct sdw_cdns *cdns = &sdw->cdns;
  60. struct sdw_bus *bus = &cdns->bus;
  61. bool clock_stop0;
  62. int status;
  63. int ret;
  64. /*
  65. * An exception condition occurs for the CLK_STOP_BUS_RESET
  66. * case if one or more masters remain active. In this condition,
  67. * all the masters are powered on for they are in the same power
  68. * domain. Master can preserve its context for clock stop0, so
  69. * there is no need to clear slave status and reset bus.
  70. */
  71. clock_stop0 = sdw_cdns_is_clock_stop(&sdw->cdns);
  72. if (!clock_stop0) {
  73. /*
  74. * make sure all Slaves are tagged as UNATTACHED and
  75. * provide reason for reinitialization
  76. */
  77. status = SDW_UNATTACH_REQUEST_MASTER_RESET;
  78. sdw_clear_slave_status(bus, status);
  79. /*
  80. * follow recommended programming flows to avoid
  81. * timeouts when gsync is enabled
  82. */
  83. if (bus->multi_link)
  84. sdw_intel_sync_arm(sdw);
  85. /*
  86. * Re-initialize the IP since it was powered-off
  87. */
  88. sdw_cdns_init(&sdw->cdns);
  89. } else {
  90. ret = sdw_cdns_enable_interrupt(cdns, true);
  91. if (ret < 0) {
  92. dev_err(dev, "cannot enable interrupts during resume\n");
  93. return ret;
  94. }
  95. }
  96. ret = sdw_cdns_clock_restart(cdns, !clock_stop0);
  97. if (ret < 0) {
  98. dev_err(dev, "unable to restart clock during resume\n");
  99. if (!clock_stop0)
  100. sdw_cdns_enable_interrupt(cdns, false);
  101. return ret;
  102. }
  103. if (!clock_stop0) {
  104. sdw_cdns_config_update(cdns);
  105. if (bus->multi_link) {
  106. ret = sdw_intel_sync_go(sdw);
  107. if (ret < 0) {
  108. dev_err(sdw->cdns.dev, "sync go failed during resume\n");
  109. return ret;
  110. }
  111. }
  112. ret = sdw_cdns_config_update_set_wait(cdns);
  113. if (ret < 0) {
  114. dev_err(dev, "%s: CONFIG_UPDATE BIT still set\n", __func__);
  115. return ret;
  116. }
  117. ret = sdw_cdns_enable_interrupt(cdns, true);
  118. if (ret < 0) {
  119. dev_err(dev, "cannot enable interrupts during resume\n");
  120. return ret;
  121. }
  122. ret = sdw_cdns_exit_reset(cdns);
  123. if (ret < 0) {
  124. dev_err(dev, "unable to exit bus reset sequence during resume\n");
  125. return ret;
  126. }
  127. }
  128. sdw_cdns_check_self_clearing_bits(cdns, __func__, true, INTEL_MASTER_RESET_ITERATIONS);
  129. schedule_delayed_work(&cdns->attach_dwork,
  130. msecs_to_jiffies(SDW_INTEL_DELAYED_ENUMERATION_MS));
  131. return 0;
  132. }
  133. void intel_check_clock_stop(struct sdw_intel *sdw)
  134. {
  135. struct device *dev = sdw->cdns.dev;
  136. bool clock_stop0;
  137. clock_stop0 = sdw_cdns_is_clock_stop(&sdw->cdns);
  138. if (!clock_stop0)
  139. dev_err(dev, "%s: invalid configuration, clock was not stopped\n", __func__);
  140. }
  141. int intel_start_bus_after_clock_stop(struct sdw_intel *sdw)
  142. {
  143. struct device *dev = sdw->cdns.dev;
  144. struct sdw_cdns *cdns = &sdw->cdns;
  145. int ret;
  146. ret = sdw_cdns_clock_restart(cdns, false);
  147. if (ret < 0) {
  148. dev_err(dev, "%s: unable to restart clock: %d\n", __func__, ret);
  149. return ret;
  150. }
  151. ret = sdw_cdns_enable_interrupt(cdns, true);
  152. if (ret < 0) {
  153. dev_err(dev, "%s: cannot enable interrupts: %d\n", __func__, ret);
  154. return ret;
  155. }
  156. sdw_cdns_check_self_clearing_bits(cdns, __func__, true, INTEL_MASTER_RESET_ITERATIONS);
  157. schedule_delayed_work(&cdns->attach_dwork,
  158. msecs_to_jiffies(SDW_INTEL_DELAYED_ENUMERATION_MS));
  159. return 0;
  160. }
  161. int intel_stop_bus(struct sdw_intel *sdw, bool clock_stop)
  162. {
  163. struct device *dev = sdw->cdns.dev;
  164. struct sdw_cdns *cdns = &sdw->cdns;
  165. bool wake_enable = false;
  166. int ret;
  167. cancel_delayed_work_sync(&cdns->attach_dwork);
  168. if (clock_stop) {
  169. ret = sdw_cdns_clock_stop(cdns, true);
  170. if (ret < 0)
  171. dev_err(dev, "%s: cannot stop clock: %d\n", __func__, ret);
  172. else
  173. wake_enable = true;
  174. }
  175. ret = sdw_cdns_enable_interrupt(cdns, false);
  176. if (ret < 0) {
  177. dev_err(dev, "%s: cannot disable interrupts: %d\n", __func__, ret);
  178. return ret;
  179. }
  180. ret = sdw_intel_link_power_down(sdw);
  181. if (ret) {
  182. dev_err(dev, "%s: Link power down failed: %d\n", __func__, ret);
  183. return ret;
  184. }
  185. sdw_intel_shim_wake(sdw, wake_enable);
  186. return 0;
  187. }
  188. /*
  189. * bank switch routines
  190. */
  191. int intel_pre_bank_switch(struct sdw_intel *sdw)
  192. {
  193. struct sdw_cdns *cdns = &sdw->cdns;
  194. struct sdw_bus *bus = &cdns->bus;
  195. /* Write to register only for multi-link */
  196. if (!bus->multi_link)
  197. return 0;
  198. sdw_intel_sync_arm(sdw);
  199. return 0;
  200. }
  201. int intel_post_bank_switch(struct sdw_intel *sdw)
  202. {
  203. struct sdw_cdns *cdns = &sdw->cdns;
  204. struct sdw_bus *bus = &cdns->bus;
  205. int ret = 0;
  206. /* Write to register only for multi-link */
  207. if (!bus->multi_link)
  208. return 0;
  209. mutex_lock(sdw->link_res->shim_lock);
  210. /*
  211. * post_bank_switch() ops is called from the bus in loop for
  212. * all the Masters in the steam with the expectation that
  213. * we trigger the bankswitch for the only first Master in the list
  214. * and do nothing for the other Masters
  215. *
  216. * So, set the SYNCGO bit only if CMDSYNC bit is set for any Master.
  217. */
  218. if (sdw_intel_sync_check_cmdsync_unlocked(sdw))
  219. ret = sdw_intel_sync_go_unlocked(sdw);
  220. mutex_unlock(sdw->link_res->shim_lock);
  221. if (ret < 0)
  222. dev_err(sdw->cdns.dev, "Post bank switch failed: %d\n", ret);
  223. return ret;
  224. }