platform-vsc.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2023, Intel Corporation.
  4. * Intel Visual Sensing Controller Interface Linux driver
  5. */
  6. #include <linux/align.h>
  7. #include <linux/cache.h>
  8. #include <linux/cleanup.h>
  9. #include <linux/iopoll.h>
  10. #include <linux/list.h>
  11. #include <linux/mei.h>
  12. #include <linux/module.h>
  13. #include <linux/mutex.h>
  14. #include <linux/overflow.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/pm_runtime.h>
  17. #include <linux/timekeeping.h>
  18. #include <linux/types.h>
  19. #include <asm-generic/bug.h>
  20. #include <linux/unaligned.h>
  21. #include "mei_dev.h"
  22. #include "vsc-tp.h"
  23. #define MEI_VSC_DRV_NAME "intel_vsc"
  24. #define MEI_VSC_MAX_MSG_SIZE 512
  25. #define MEI_VSC_POLL_DELAY_US (100 * USEC_PER_MSEC)
  26. #define MEI_VSC_POLL_TIMEOUT_US (400 * USEC_PER_MSEC)
  27. #define mei_dev_to_vsc_hw(dev) ((struct mei_vsc_hw *)((dev)->hw))
  28. struct mei_vsc_host_timestamp {
  29. u64 realtime;
  30. u64 boottime;
  31. };
  32. struct mei_vsc_hw {
  33. struct vsc_tp *tp;
  34. bool fw_ready;
  35. bool host_ready;
  36. atomic_t write_lock_cnt;
  37. u32 rx_len;
  38. u32 rx_hdr;
  39. /* buffer for tx */
  40. char tx_buf[MEI_VSC_MAX_MSG_SIZE + sizeof(struct mei_msg_hdr)] ____cacheline_aligned;
  41. /* buffer for rx */
  42. char rx_buf[MEI_VSC_MAX_MSG_SIZE + sizeof(struct mei_msg_hdr)] ____cacheline_aligned;
  43. };
  44. static int mei_vsc_read_helper(struct mei_vsc_hw *hw, u8 *buf,
  45. u32 max_len)
  46. {
  47. struct mei_vsc_host_timestamp ts = {
  48. .realtime = ktime_to_ns(ktime_get_real()),
  49. .boottime = ktime_to_ns(ktime_get_boottime()),
  50. };
  51. return vsc_tp_xfer(hw->tp, VSC_TP_CMD_READ, &ts, sizeof(ts),
  52. buf, max_len);
  53. }
  54. static int mei_vsc_write_helper(struct mei_vsc_hw *hw, u8 *buf, u32 len)
  55. {
  56. u8 status;
  57. return vsc_tp_xfer(hw->tp, VSC_TP_CMD_WRITE, buf, len, &status,
  58. sizeof(status));
  59. }
  60. static int mei_vsc_fw_status(struct mei_device *mei_dev,
  61. struct mei_fw_status *fw_status)
  62. {
  63. if (!fw_status)
  64. return -EINVAL;
  65. fw_status->count = 0;
  66. return 0;
  67. }
  68. static inline enum mei_pg_state mei_vsc_pg_state(struct mei_device *mei_dev)
  69. {
  70. return MEI_PG_OFF;
  71. }
  72. static void mei_vsc_intr_enable(struct mei_device *mei_dev)
  73. {
  74. struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
  75. vsc_tp_intr_enable(hw->tp);
  76. }
  77. static void mei_vsc_intr_disable(struct mei_device *mei_dev)
  78. {
  79. struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
  80. vsc_tp_intr_disable(hw->tp);
  81. }
  82. /* mei framework requires this ops */
  83. static void mei_vsc_intr_clear(struct mei_device *mei_dev)
  84. {
  85. }
  86. /* wait for pending irq handler */
  87. static void mei_vsc_synchronize_irq(struct mei_device *mei_dev)
  88. {
  89. struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
  90. vsc_tp_intr_synchronize(hw->tp);
  91. }
  92. static int mei_vsc_hw_config(struct mei_device *mei_dev)
  93. {
  94. return 0;
  95. }
  96. static bool mei_vsc_host_is_ready(struct mei_device *mei_dev)
  97. {
  98. struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
  99. return hw->host_ready;
  100. }
  101. static bool mei_vsc_hw_is_ready(struct mei_device *mei_dev)
  102. {
  103. struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
  104. return hw->fw_ready;
  105. }
  106. static int mei_vsc_hw_start(struct mei_device *mei_dev)
  107. {
  108. struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
  109. int ret, rlen;
  110. u8 buf;
  111. hw->host_ready = true;
  112. vsc_tp_intr_enable(hw->tp);
  113. ret = read_poll_timeout(mei_vsc_read_helper, rlen,
  114. rlen >= 0, MEI_VSC_POLL_DELAY_US,
  115. MEI_VSC_POLL_TIMEOUT_US, true,
  116. hw, &buf, sizeof(buf));
  117. if (ret) {
  118. dev_err(&mei_dev->dev, "wait fw ready failed: %d\n", ret);
  119. return ret;
  120. }
  121. hw->fw_ready = true;
  122. return 0;
  123. }
  124. static bool mei_vsc_hbuf_is_ready(struct mei_device *mei_dev)
  125. {
  126. struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
  127. return atomic_read(&hw->write_lock_cnt) == 0;
  128. }
  129. static int mei_vsc_hbuf_empty_slots(struct mei_device *mei_dev)
  130. {
  131. return MEI_VSC_MAX_MSG_SIZE / MEI_SLOT_SIZE;
  132. }
  133. static u32 mei_vsc_hbuf_depth(const struct mei_device *mei_dev)
  134. {
  135. return MEI_VSC_MAX_MSG_SIZE / MEI_SLOT_SIZE;
  136. }
  137. static int mei_vsc_write(struct mei_device *mei_dev,
  138. const void *hdr, size_t hdr_len,
  139. const void *data, size_t data_len)
  140. {
  141. struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
  142. char *buf = hw->tx_buf;
  143. int ret;
  144. if (WARN_ON(!hdr || !IS_ALIGNED(hdr_len, 4)))
  145. return -EINVAL;
  146. if (!data || data_len > MEI_VSC_MAX_MSG_SIZE)
  147. return -EINVAL;
  148. atomic_inc(&hw->write_lock_cnt);
  149. memcpy(buf, hdr, hdr_len);
  150. memcpy(buf + hdr_len, data, data_len);
  151. ret = mei_vsc_write_helper(hw, buf, hdr_len + data_len);
  152. atomic_dec_if_positive(&hw->write_lock_cnt);
  153. return ret < 0 ? ret : 0;
  154. }
  155. static inline u32 mei_vsc_read(const struct mei_device *mei_dev)
  156. {
  157. struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
  158. int ret;
  159. ret = mei_vsc_read_helper(hw, hw->rx_buf, sizeof(hw->rx_buf));
  160. if (ret < 0 || ret < sizeof(u32))
  161. return 0;
  162. hw->rx_len = ret;
  163. hw->rx_hdr = get_unaligned_le32(hw->rx_buf);
  164. return hw->rx_hdr;
  165. }
  166. static int mei_vsc_count_full_read_slots(struct mei_device *mei_dev)
  167. {
  168. return MEI_VSC_MAX_MSG_SIZE / MEI_SLOT_SIZE;
  169. }
  170. static int mei_vsc_read_slots(struct mei_device *mei_dev, unsigned char *buf,
  171. unsigned long len)
  172. {
  173. struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
  174. struct mei_msg_hdr *hdr;
  175. hdr = (struct mei_msg_hdr *)&hw->rx_hdr;
  176. if (len != hdr->length || hdr->length + sizeof(*hdr) != hw->rx_len)
  177. return -EINVAL;
  178. memcpy(buf, hw->rx_buf + sizeof(*hdr), len);
  179. return 0;
  180. }
  181. static bool mei_vsc_pg_in_transition(struct mei_device *mei_dev)
  182. {
  183. return mei_dev->pg_event >= MEI_PG_EVENT_WAIT &&
  184. mei_dev->pg_event <= MEI_PG_EVENT_INTR_WAIT;
  185. }
  186. static bool mei_vsc_pg_is_enabled(struct mei_device *mei_dev)
  187. {
  188. return false;
  189. }
  190. static int mei_vsc_hw_reset(struct mei_device *mei_dev, bool intr_enable)
  191. {
  192. struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
  193. vsc_tp_reset(hw->tp);
  194. if (!intr_enable)
  195. return 0;
  196. return vsc_tp_init(hw->tp, mei_dev->parent);
  197. }
  198. static const struct mei_hw_ops mei_vsc_hw_ops = {
  199. .fw_status = mei_vsc_fw_status,
  200. .pg_state = mei_vsc_pg_state,
  201. .host_is_ready = mei_vsc_host_is_ready,
  202. .hw_is_ready = mei_vsc_hw_is_ready,
  203. .hw_reset = mei_vsc_hw_reset,
  204. .hw_config = mei_vsc_hw_config,
  205. .hw_start = mei_vsc_hw_start,
  206. .pg_in_transition = mei_vsc_pg_in_transition,
  207. .pg_is_enabled = mei_vsc_pg_is_enabled,
  208. .intr_clear = mei_vsc_intr_clear,
  209. .intr_enable = mei_vsc_intr_enable,
  210. .intr_disable = mei_vsc_intr_disable,
  211. .synchronize_irq = mei_vsc_synchronize_irq,
  212. .hbuf_free_slots = mei_vsc_hbuf_empty_slots,
  213. .hbuf_is_ready = mei_vsc_hbuf_is_ready,
  214. .hbuf_depth = mei_vsc_hbuf_depth,
  215. .write = mei_vsc_write,
  216. .rdbuf_full_slots = mei_vsc_count_full_read_slots,
  217. .read_hdr = mei_vsc_read,
  218. .read = mei_vsc_read_slots,
  219. };
  220. static void mei_vsc_event_cb(void *context)
  221. {
  222. struct mei_device *mei_dev = context;
  223. struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
  224. struct list_head cmpl_list;
  225. s32 slots;
  226. int ret;
  227. if (mei_dev->dev_state == MEI_DEV_RESETTING ||
  228. mei_dev->dev_state == MEI_DEV_INITIALIZING)
  229. return;
  230. INIT_LIST_HEAD(&cmpl_list);
  231. guard(mutex)(&mei_dev->device_lock);
  232. while (vsc_tp_need_read(hw->tp)) {
  233. /* check slots available for reading */
  234. slots = mei_count_full_read_slots(mei_dev);
  235. ret = mei_irq_read_handler(mei_dev, &cmpl_list, &slots);
  236. if (ret) {
  237. if (ret != -ENODATA) {
  238. if (mei_dev->dev_state != MEI_DEV_RESETTING &&
  239. mei_dev->dev_state != MEI_DEV_POWER_DOWN)
  240. schedule_work(&mei_dev->reset_work);
  241. }
  242. return;
  243. }
  244. }
  245. mei_dev->hbuf_is_ready = mei_hbuf_is_ready(mei_dev);
  246. ret = mei_irq_write_handler(mei_dev, &cmpl_list);
  247. if (ret)
  248. dev_err(&mei_dev->dev, "dispatch write request failed: %d\n", ret);
  249. mei_dev->hbuf_is_ready = mei_hbuf_is_ready(mei_dev);
  250. mei_irq_compl_handler(mei_dev, &cmpl_list);
  251. }
  252. static int mei_vsc_probe(struct platform_device *pdev)
  253. {
  254. struct device *dev = &pdev->dev;
  255. struct mei_device *mei_dev;
  256. struct mei_vsc_hw *hw;
  257. struct vsc_tp *tp;
  258. int ret;
  259. tp = *(struct vsc_tp **)dev_get_platdata(dev);
  260. if (!tp)
  261. return dev_err_probe(dev, -ENODEV, "no platform data\n");
  262. mei_dev = kzalloc(size_add(sizeof(*mei_dev), sizeof(*hw)), GFP_KERNEL);
  263. if (!mei_dev)
  264. return -ENOMEM;
  265. mei_device_init(mei_dev, dev, false, &mei_vsc_hw_ops);
  266. mei_dev->fw_f_fw_ver_supported = 0;
  267. mei_dev->kind = "ivsc";
  268. hw = mei_dev_to_vsc_hw(mei_dev);
  269. atomic_set(&hw->write_lock_cnt, 0);
  270. hw->tp = tp;
  271. platform_set_drvdata(pdev, mei_dev);
  272. vsc_tp_register_event_cb(tp, mei_vsc_event_cb, mei_dev);
  273. ret = mei_register(mei_dev, dev);
  274. if (ret)
  275. goto err;
  276. ret = mei_start(mei_dev);
  277. if (ret) {
  278. dev_err_probe(dev, ret, "init hw failed\n");
  279. goto err;
  280. }
  281. pm_runtime_enable(mei_dev->parent);
  282. return 0;
  283. err:
  284. mei_cancel_work(mei_dev);
  285. vsc_tp_register_event_cb(tp, NULL, NULL);
  286. mei_disable_interrupts(mei_dev);
  287. mei_deregister(mei_dev);
  288. return ret;
  289. }
  290. static void mei_vsc_remove(struct platform_device *pdev)
  291. {
  292. struct mei_device *mei_dev = platform_get_drvdata(pdev);
  293. struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
  294. pm_runtime_disable(mei_dev->parent);
  295. mei_stop(mei_dev);
  296. vsc_tp_register_event_cb(hw->tp, NULL, NULL);
  297. mei_disable_interrupts(mei_dev);
  298. mei_deregister(mei_dev);
  299. }
  300. static int mei_vsc_suspend(struct device *dev)
  301. {
  302. struct mei_device *mei_dev;
  303. int ret = 0;
  304. mei_dev = dev_get_drvdata(dev);
  305. if (!mei_dev)
  306. return -ENODEV;
  307. mutex_lock(&mei_dev->device_lock);
  308. if (!mei_write_is_idle(mei_dev))
  309. ret = -EAGAIN;
  310. mutex_unlock(&mei_dev->device_lock);
  311. return ret;
  312. }
  313. static int mei_vsc_resume(struct device *dev)
  314. {
  315. struct mei_device *mei_dev;
  316. mei_dev = dev_get_drvdata(dev);
  317. if (!mei_dev)
  318. return -ENODEV;
  319. return 0;
  320. }
  321. static DEFINE_SIMPLE_DEV_PM_OPS(mei_vsc_pm_ops, mei_vsc_suspend, mei_vsc_resume);
  322. static const struct platform_device_id mei_vsc_id_table[] = {
  323. { MEI_VSC_DRV_NAME },
  324. { /* sentinel */ }
  325. };
  326. MODULE_DEVICE_TABLE(platform, mei_vsc_id_table);
  327. static struct platform_driver mei_vsc_drv = {
  328. .probe = mei_vsc_probe,
  329. .remove = mei_vsc_remove,
  330. .id_table = mei_vsc_id_table,
  331. .driver = {
  332. .name = MEI_VSC_DRV_NAME,
  333. .pm = &mei_vsc_pm_ops,
  334. .probe_type = PROBE_PREFER_ASYNCHRONOUS,
  335. },
  336. };
  337. module_platform_driver(mei_vsc_drv);
  338. MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>");
  339. MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>");
  340. MODULE_DESCRIPTION("Intel Visual Sensing Controller Interface");
  341. MODULE_LICENSE("GPL");
  342. MODULE_IMPORT_NS("VSC_TP");