gsc-me.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
  4. *
  5. * Intel Management Engine Interface (Intel MEI) Linux driver
  6. */
  7. #include <linux/module.h>
  8. #include <linux/mei_aux.h>
  9. #include <linux/device.h>
  10. #include <linux/irqreturn.h>
  11. #include <linux/jiffies.h>
  12. #include <linux/ktime.h>
  13. #include <linux/delay.h>
  14. #include <linux/pm_runtime.h>
  15. #include <linux/kthread.h>
  16. #include "mei_dev.h"
  17. #include "hw-me.h"
  18. #include "hw-me-regs.h"
  19. #include "mei-trace.h"
  20. #define MEI_GSC_RPM_TIMEOUT 500
  21. static int mei_gsc_read_hfs(const struct mei_device *dev, int where, u32 *val)
  22. {
  23. struct mei_me_hw *hw = to_me_hw(dev);
  24. *val = ioread32(hw->mem_addr + where + 0xC00);
  25. return 0;
  26. }
  27. static void mei_gsc_set_ext_op_mem(const struct mei_me_hw *hw, struct resource *mem)
  28. {
  29. u32 low = lower_32_bits(mem->start);
  30. u32 hi = upper_32_bits(mem->start);
  31. u32 limit = (resource_size(mem) / SZ_4K) | GSC_EXT_OP_MEM_VALID;
  32. iowrite32(low, hw->mem_addr + H_GSC_EXT_OP_MEM_BASE_ADDR_LO_REG);
  33. iowrite32(hi, hw->mem_addr + H_GSC_EXT_OP_MEM_BASE_ADDR_HI_REG);
  34. iowrite32(limit, hw->mem_addr + H_GSC_EXT_OP_MEM_LIMIT_REG);
  35. }
  36. static int mei_gsc_probe(struct auxiliary_device *aux_dev,
  37. const struct auxiliary_device_id *aux_dev_id)
  38. {
  39. struct mei_aux_device *adev = auxiliary_dev_to_mei_aux_dev(aux_dev);
  40. struct mei_device *dev;
  41. struct mei_me_hw *hw;
  42. struct device *device;
  43. const struct mei_cfg *cfg;
  44. int ret;
  45. cfg = mei_me_get_cfg(aux_dev_id->driver_data);
  46. if (!cfg)
  47. return -ENODEV;
  48. device = &aux_dev->dev;
  49. dev = mei_me_dev_init(device, cfg, adev->slow_firmware);
  50. if (!dev) {
  51. ret = -ENOMEM;
  52. goto err;
  53. }
  54. hw = to_me_hw(dev);
  55. hw->mem_addr = devm_ioremap_resource(device, &adev->bar);
  56. if (IS_ERR(hw->mem_addr)) {
  57. ret = PTR_ERR(hw->mem_addr);
  58. goto err;
  59. }
  60. hw->irq = adev->irq;
  61. hw->read_fws = mei_gsc_read_hfs;
  62. dev_set_drvdata(device, dev);
  63. if (adev->ext_op_mem.start) {
  64. mei_gsc_set_ext_op_mem(hw, &adev->ext_op_mem);
  65. dev->pxp_mode = MEI_DEV_PXP_INIT;
  66. }
  67. /* use polling */
  68. if (mei_me_hw_use_polling(hw)) {
  69. mei_disable_interrupts(dev);
  70. mei_clear_interrupts(dev);
  71. init_waitqueue_head(&hw->wait_active);
  72. hw->is_active = true; /* start in active mode for initialization */
  73. hw->polling_thread = kthread_run(mei_me_polling_thread, dev,
  74. "kmegscirqd/%s", dev_name(device));
  75. if (IS_ERR(hw->polling_thread)) {
  76. ret = PTR_ERR(hw->polling_thread);
  77. dev_err(device, "unable to create kernel thread: %d\n", ret);
  78. goto err;
  79. }
  80. } else {
  81. ret = devm_request_threaded_irq(device, hw->irq,
  82. mei_me_irq_quick_handler,
  83. mei_me_irq_thread_handler,
  84. IRQF_ONESHOT, KBUILD_MODNAME, dev);
  85. if (ret) {
  86. dev_err(device, "irq register failed %d\n", ret);
  87. goto err;
  88. }
  89. }
  90. ret = mei_register(dev, device);
  91. if (ret)
  92. goto deinterrupt;
  93. pm_runtime_get_noresume(device);
  94. pm_runtime_set_active(device);
  95. pm_runtime_enable(device);
  96. /* Continue in spite of firmware handshake failure.
  97. * In order to provide access to the firmware status registers to the user
  98. * space via sysfs.
  99. */
  100. if (mei_start(dev))
  101. dev_warn(device, "init hw failure.\n");
  102. pm_runtime_set_autosuspend_delay(device, MEI_GSC_RPM_TIMEOUT);
  103. pm_runtime_use_autosuspend(device);
  104. pm_runtime_put_noidle(device);
  105. return 0;
  106. deinterrupt:
  107. if (!mei_me_hw_use_polling(hw))
  108. devm_free_irq(device, hw->irq, dev);
  109. err:
  110. dev_err(device, "probe failed: %d\n", ret);
  111. dev_set_drvdata(device, NULL);
  112. return ret;
  113. }
  114. static void mei_gsc_remove(struct auxiliary_device *aux_dev)
  115. {
  116. struct mei_device *dev;
  117. struct mei_me_hw *hw;
  118. dev = dev_get_drvdata(&aux_dev->dev);
  119. hw = to_me_hw(dev);
  120. mei_stop(dev);
  121. hw = to_me_hw(dev);
  122. if (mei_me_hw_use_polling(hw))
  123. kthread_stop(hw->polling_thread);
  124. pm_runtime_disable(&aux_dev->dev);
  125. mei_disable_interrupts(dev);
  126. if (!mei_me_hw_use_polling(hw))
  127. devm_free_irq(&aux_dev->dev, hw->irq, dev);
  128. mei_deregister(dev);
  129. }
  130. static int __maybe_unused mei_gsc_pm_suspend(struct device *device)
  131. {
  132. struct mei_device *dev = dev_get_drvdata(device);
  133. mei_stop(dev);
  134. mei_disable_interrupts(dev);
  135. return 0;
  136. }
  137. static int __maybe_unused mei_gsc_pm_resume(struct device *device)
  138. {
  139. struct mei_device *dev = dev_get_drvdata(device);
  140. struct auxiliary_device *aux_dev;
  141. struct mei_aux_device *adev;
  142. int err;
  143. struct mei_me_hw *hw;
  144. hw = to_me_hw(dev);
  145. aux_dev = to_auxiliary_dev(device);
  146. adev = auxiliary_dev_to_mei_aux_dev(aux_dev);
  147. if (adev->ext_op_mem.start) {
  148. mei_gsc_set_ext_op_mem(hw, &adev->ext_op_mem);
  149. dev->pxp_mode = MEI_DEV_PXP_INIT;
  150. }
  151. err = mei_restart(dev);
  152. if (err)
  153. return err;
  154. /* Start timer if stopped in suspend */
  155. schedule_delayed_work(&dev->timer_work, HZ);
  156. return 0;
  157. }
  158. static int __maybe_unused mei_gsc_pm_runtime_idle(struct device *device)
  159. {
  160. struct mei_device *dev = dev_get_drvdata(device);
  161. if (mei_write_is_idle(dev))
  162. pm_runtime_autosuspend(device);
  163. return -EBUSY;
  164. }
  165. static int __maybe_unused mei_gsc_pm_runtime_suspend(struct device *device)
  166. {
  167. struct mei_device *dev = dev_get_drvdata(device);
  168. struct mei_me_hw *hw;
  169. int ret;
  170. mutex_lock(&dev->device_lock);
  171. if (mei_write_is_idle(dev)) {
  172. hw = to_me_hw(dev);
  173. hw->pg_state = MEI_PG_ON;
  174. if (mei_me_hw_use_polling(hw))
  175. hw->is_active = false;
  176. ret = 0;
  177. } else {
  178. ret = -EAGAIN;
  179. }
  180. mutex_unlock(&dev->device_lock);
  181. return ret;
  182. }
  183. static int __maybe_unused mei_gsc_pm_runtime_resume(struct device *device)
  184. {
  185. struct mei_device *dev = dev_get_drvdata(device);
  186. struct mei_me_hw *hw;
  187. irqreturn_t irq_ret;
  188. mutex_lock(&dev->device_lock);
  189. hw = to_me_hw(dev);
  190. hw->pg_state = MEI_PG_OFF;
  191. if (mei_me_hw_use_polling(hw)) {
  192. hw->is_active = true;
  193. wake_up(&hw->wait_active);
  194. }
  195. mutex_unlock(&dev->device_lock);
  196. irq_ret = mei_me_irq_thread_handler(1, dev);
  197. if (irq_ret != IRQ_HANDLED)
  198. dev_err(&dev->dev, "thread handler fail %d\n", irq_ret);
  199. return 0;
  200. }
  201. static const struct dev_pm_ops mei_gsc_pm_ops = {
  202. SET_SYSTEM_SLEEP_PM_OPS(mei_gsc_pm_suspend,
  203. mei_gsc_pm_resume)
  204. SET_RUNTIME_PM_OPS(mei_gsc_pm_runtime_suspend,
  205. mei_gsc_pm_runtime_resume,
  206. mei_gsc_pm_runtime_idle)
  207. };
  208. static const struct auxiliary_device_id mei_gsc_id_table[] = {
  209. {
  210. .name = "i915.mei-gsc",
  211. .driver_data = MEI_ME_GSC_CFG,
  212. },
  213. {
  214. .name = "i915.mei-gscfi",
  215. .driver_data = MEI_ME_GSCFI_CFG,
  216. },
  217. {
  218. .name = "xe.mei-gscfi",
  219. .driver_data = MEI_ME_GSCFI_CFG,
  220. },
  221. {
  222. /* sentinel */
  223. }
  224. };
  225. MODULE_DEVICE_TABLE(auxiliary, mei_gsc_id_table);
  226. static struct auxiliary_driver mei_gsc_driver = {
  227. .probe = mei_gsc_probe,
  228. .remove = mei_gsc_remove,
  229. .driver = {
  230. /* auxiliary_driver_register() sets .name to be the modname */
  231. .pm = &mei_gsc_pm_ops,
  232. },
  233. .id_table = mei_gsc_id_table
  234. };
  235. module_auxiliary_driver(mei_gsc_driver);
  236. MODULE_AUTHOR("Intel Corporation");
  237. MODULE_ALIAS("auxiliary:i915.mei-gsc");
  238. MODULE_ALIAS("auxiliary:i915.mei-gscfi");
  239. MODULE_ALIAS("auxiliary:xe.mei-gscfi");
  240. MODULE_DESCRIPTION("Intel(R) Graphics System Controller");
  241. MODULE_LICENSE("GPL");