vlv_iosf_sb.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // SPDX-License-Identifier: MIT
  2. /*
  3. * Copyright © 2013-2021 Intel Corporation
  4. */
  5. #include <drm/drm_print.h>
  6. #include "i915_drv.h"
  7. #include "i915_iosf_mbi.h"
  8. #include "i915_reg.h"
  9. #include "vlv_iosf_sb.h"
  10. /*
  11. * IOSF sideband, see VLV2_SidebandMsg_HAS.docx and
  12. * VLV_VLV2_PUNIT_HAS_0.8.docx
  13. */
  14. /* Standard MMIO read, non-posted */
  15. #define SB_MRD_NP 0x00
  16. /* Standard MMIO write, non-posted */
  17. #define SB_MWR_NP 0x01
  18. /* Private register read, double-word addressing, non-posted */
  19. #define SB_CRRDDA_NP 0x06
  20. /* Private register write, double-word addressing, non-posted */
  21. #define SB_CRWRDA_NP 0x07
  22. static void ping(void *info)
  23. {
  24. }
  25. static void __vlv_punit_get(struct drm_i915_private *i915)
  26. {
  27. iosf_mbi_punit_acquire();
  28. /*
  29. * Prevent the cpu from sleeping while we use this sideband, otherwise
  30. * the punit may cause a machine hang. The issue appears to be isolated
  31. * with changing the power state of the CPU package while changing
  32. * the power state via the punit, and we have only observed it
  33. * reliably on 4-core Baytail systems suggesting the issue is in the
  34. * power delivery mechanism and likely to be board/function
  35. * specific. Hence we presume the workaround needs only be applied
  36. * to the Valleyview P-unit and not all sideband communications.
  37. */
  38. if (IS_VALLEYVIEW(i915)) {
  39. cpu_latency_qos_update_request(&i915->vlv_iosf_sb.qos, 0);
  40. on_each_cpu(ping, NULL, 1);
  41. }
  42. }
  43. static void __vlv_punit_put(struct drm_i915_private *i915)
  44. {
  45. if (IS_VALLEYVIEW(i915))
  46. cpu_latency_qos_update_request(&i915->vlv_iosf_sb.qos,
  47. PM_QOS_DEFAULT_VALUE);
  48. iosf_mbi_punit_release();
  49. }
  50. void vlv_iosf_sb_get(struct drm_device *drm, unsigned long unit_mask)
  51. {
  52. struct drm_i915_private *i915 = to_i915(drm);
  53. if (unit_mask & BIT(VLV_IOSF_SB_PUNIT))
  54. __vlv_punit_get(i915);
  55. mutex_lock(&i915->vlv_iosf_sb.lock);
  56. i915->vlv_iosf_sb.locked_unit_mask |= unit_mask;
  57. }
  58. void vlv_iosf_sb_put(struct drm_device *drm, unsigned long unit_mask)
  59. {
  60. struct drm_i915_private *i915 = to_i915(drm);
  61. i915->vlv_iosf_sb.locked_unit_mask &= ~unit_mask;
  62. drm_WARN_ON(drm, i915->vlv_iosf_sb.locked_unit_mask);
  63. mutex_unlock(&i915->vlv_iosf_sb.lock);
  64. if (unit_mask & BIT(VLV_IOSF_SB_PUNIT))
  65. __vlv_punit_put(i915);
  66. }
  67. static int vlv_sideband_rw(struct drm_i915_private *i915,
  68. u32 devfn, u32 port, u32 opcode,
  69. u32 addr, u32 *val)
  70. {
  71. struct intel_uncore *uncore = &i915->uncore;
  72. const bool is_read = (opcode == SB_MRD_NP || opcode == SB_CRRDDA_NP);
  73. int err;
  74. lockdep_assert_held(&i915->vlv_iosf_sb.lock);
  75. if (port == IOSF_PORT_PUNIT)
  76. iosf_mbi_assert_punit_acquired();
  77. /* Flush the previous comms, just in case it failed last time. */
  78. if (intel_wait_for_register(uncore,
  79. VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0,
  80. 5)) {
  81. drm_dbg(&i915->drm, "IOSF sideband idle wait (%s) timed out\n",
  82. is_read ? "read" : "write");
  83. return -EAGAIN;
  84. }
  85. preempt_disable();
  86. intel_uncore_write_fw(uncore, VLV_IOSF_ADDR, addr);
  87. intel_uncore_write_fw(uncore, VLV_IOSF_DATA, is_read ? 0 : *val);
  88. intel_uncore_write_fw(uncore, VLV_IOSF_DOORBELL_REQ,
  89. (devfn << IOSF_DEVFN_SHIFT) |
  90. (opcode << IOSF_OPCODE_SHIFT) |
  91. (port << IOSF_PORT_SHIFT) |
  92. (0xf << IOSF_BYTE_ENABLES_SHIFT) |
  93. (0 << IOSF_BAR_SHIFT) |
  94. IOSF_SB_BUSY);
  95. if (__intel_wait_for_register_fw(uncore,
  96. VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0,
  97. 10000, 0, NULL) == 0) {
  98. if (is_read)
  99. *val = intel_uncore_read_fw(uncore, VLV_IOSF_DATA);
  100. err = 0;
  101. } else {
  102. drm_dbg(&i915->drm, "IOSF sideband finish wait (%s) timed out\n",
  103. is_read ? "read" : "write");
  104. err = -ETIMEDOUT;
  105. }
  106. preempt_enable();
  107. return err;
  108. }
  109. static u32 unit_to_devfn(enum vlv_iosf_sb_unit unit)
  110. {
  111. if (unit == VLV_IOSF_SB_DPIO || unit == VLV_IOSF_SB_DPIO_2 ||
  112. unit == VLV_IOSF_SB_FLISDSI)
  113. return DPIO_DEVFN;
  114. else
  115. return PCI_DEVFN(0, 0);
  116. }
  117. static u32 unit_to_port(enum vlv_iosf_sb_unit unit)
  118. {
  119. switch (unit) {
  120. case VLV_IOSF_SB_BUNIT:
  121. return IOSF_PORT_BUNIT;
  122. case VLV_IOSF_SB_CCK:
  123. return IOSF_PORT_CCK;
  124. case VLV_IOSF_SB_CCU:
  125. return IOSF_PORT_CCU;
  126. case VLV_IOSF_SB_DPIO:
  127. return IOSF_PORT_DPIO;
  128. case VLV_IOSF_SB_DPIO_2:
  129. return IOSF_PORT_DPIO_2;
  130. case VLV_IOSF_SB_FLISDSI:
  131. return IOSF_PORT_FLISDSI;
  132. case VLV_IOSF_SB_GPIO:
  133. return 0; /* FIXME: unused */
  134. case VLV_IOSF_SB_NC:
  135. return IOSF_PORT_NC;
  136. case VLV_IOSF_SB_PUNIT:
  137. return IOSF_PORT_PUNIT;
  138. default:
  139. return 0;
  140. }
  141. }
  142. static u32 unit_to_opcode(enum vlv_iosf_sb_unit unit, bool write)
  143. {
  144. if (unit == VLV_IOSF_SB_DPIO || unit == VLV_IOSF_SB_DPIO_2)
  145. return write ? SB_MWR_NP : SB_MRD_NP;
  146. else
  147. return write ? SB_CRWRDA_NP : SB_CRRDDA_NP;
  148. }
  149. u32 vlv_iosf_sb_read(struct drm_device *drm, enum vlv_iosf_sb_unit unit, u32 addr)
  150. {
  151. struct drm_i915_private *i915 = to_i915(drm);
  152. u32 devfn, port, opcode, val = 0;
  153. devfn = unit_to_devfn(unit);
  154. port = unit_to_port(unit);
  155. opcode = unit_to_opcode(unit, false);
  156. if (drm_WARN_ONCE(&i915->drm, !port, "invalid unit %d\n", unit))
  157. return 0;
  158. drm_WARN_ON(&i915->drm, !(i915->vlv_iosf_sb.locked_unit_mask & BIT(unit)));
  159. vlv_sideband_rw(i915, devfn, port, opcode, addr, &val);
  160. return val;
  161. }
  162. int vlv_iosf_sb_write(struct drm_device *drm, enum vlv_iosf_sb_unit unit, u32 addr, u32 val)
  163. {
  164. struct drm_i915_private *i915 = to_i915(drm);
  165. u32 devfn, port, opcode;
  166. devfn = unit_to_devfn(unit);
  167. port = unit_to_port(unit);
  168. opcode = unit_to_opcode(unit, true);
  169. if (drm_WARN_ONCE(&i915->drm, !port, "invalid unit %d\n", unit))
  170. return -EINVAL;
  171. drm_WARN_ON(&i915->drm, !(i915->vlv_iosf_sb.locked_unit_mask & BIT(unit)));
  172. return vlv_sideband_rw(i915, devfn, port, opcode, addr, &val);
  173. }
  174. void vlv_iosf_sb_init(struct drm_i915_private *i915)
  175. {
  176. if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
  177. mutex_init(&i915->vlv_iosf_sb.lock);
  178. if (IS_VALLEYVIEW(i915))
  179. cpu_latency_qos_add_request(&i915->vlv_iosf_sb.qos, PM_QOS_DEFAULT_VALUE);
  180. }
  181. void vlv_iosf_sb_fini(struct drm_i915_private *i915)
  182. {
  183. if (IS_VALLEYVIEW(i915))
  184. cpu_latency_qos_remove_request(&i915->vlv_iosf_sb.qos);
  185. if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
  186. mutex_destroy(&i915->vlv_iosf_sb.lock);
  187. }