sahara.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */
  3. #include <linux/firmware.h>
  4. #include <linux/limits.h>
  5. #include <linux/mhi.h>
  6. #include <linux/minmax.h>
  7. #include <linux/mod_devicetable.h>
  8. #include <linux/overflow.h>
  9. #include <linux/types.h>
  10. #include <linux/workqueue.h>
  11. #include "sahara.h"
  12. #define SAHARA_HELLO_CMD 0x1 /* Min protocol version 1.0 */
  13. #define SAHARA_HELLO_RESP_CMD 0x2 /* Min protocol version 1.0 */
  14. #define SAHARA_READ_DATA_CMD 0x3 /* Min protocol version 1.0 */
  15. #define SAHARA_END_OF_IMAGE_CMD 0x4 /* Min protocol version 1.0 */
  16. #define SAHARA_DONE_CMD 0x5 /* Min protocol version 1.0 */
  17. #define SAHARA_DONE_RESP_CMD 0x6 /* Min protocol version 1.0 */
  18. #define SAHARA_RESET_CMD 0x7 /* Min protocol version 1.0 */
  19. #define SAHARA_RESET_RESP_CMD 0x8 /* Min protocol version 1.0 */
  20. #define SAHARA_MEM_DEBUG_CMD 0x9 /* Min protocol version 2.0 */
  21. #define SAHARA_MEM_READ_CMD 0xa /* Min protocol version 2.0 */
  22. #define SAHARA_CMD_READY_CMD 0xb /* Min protocol version 2.1 */
  23. #define SAHARA_SWITCH_MODE_CMD 0xc /* Min protocol version 2.1 */
  24. #define SAHARA_EXECUTE_CMD 0xd /* Min protocol version 2.1 */
  25. #define SAHARA_EXECUTE_RESP_CMD 0xe /* Min protocol version 2.1 */
  26. #define SAHARA_EXECUTE_DATA_CMD 0xf /* Min protocol version 2.1 */
  27. #define SAHARA_MEM_DEBUG64_CMD 0x10 /* Min protocol version 2.5 */
  28. #define SAHARA_MEM_READ64_CMD 0x11 /* Min protocol version 2.5 */
  29. #define SAHARA_READ_DATA64_CMD 0x12 /* Min protocol version 2.8 */
  30. #define SAHARA_RESET_STATE_CMD 0x13 /* Min protocol version 2.9 */
  31. #define SAHARA_WRITE_DATA_CMD 0x14 /* Min protocol version 3.0 */
  32. #define SAHARA_PACKET_MAX_SIZE 0xffffU /* MHI_MAX_MTU */
  33. #define SAHARA_TRANSFER_MAX_SIZE 0x80000
  34. #define SAHARA_NUM_TX_BUF DIV_ROUND_UP(SAHARA_TRANSFER_MAX_SIZE,\
  35. SAHARA_PACKET_MAX_SIZE)
  36. #define SAHARA_IMAGE_ID_NONE U32_MAX
  37. #define SAHARA_VERSION 2
  38. #define SAHARA_SUCCESS 0
  39. #define SAHARA_MODE_IMAGE_TX_PENDING 0x0
  40. #define SAHARA_MODE_IMAGE_TX_COMPLETE 0x1
  41. #define SAHARA_MODE_MEMORY_DEBUG 0x2
  42. #define SAHARA_MODE_COMMAND 0x3
  43. #define SAHARA_HELLO_LENGTH 0x30
  44. #define SAHARA_READ_DATA_LENGTH 0x14
  45. #define SAHARA_END_OF_IMAGE_LENGTH 0x10
  46. #define SAHARA_DONE_LENGTH 0x8
  47. #define SAHARA_RESET_LENGTH 0x8
  48. struct sahara_packet {
  49. __le32 cmd;
  50. __le32 length;
  51. union {
  52. struct {
  53. __le32 version;
  54. __le32 version_compat;
  55. __le32 max_length;
  56. __le32 mode;
  57. } hello;
  58. struct {
  59. __le32 version;
  60. __le32 version_compat;
  61. __le32 status;
  62. __le32 mode;
  63. } hello_resp;
  64. struct {
  65. __le32 image;
  66. __le32 offset;
  67. __le32 length;
  68. } read_data;
  69. struct {
  70. __le32 image;
  71. __le32 status;
  72. } end_of_image;
  73. };
  74. };
  75. struct sahara_context {
  76. struct sahara_packet *tx[SAHARA_NUM_TX_BUF];
  77. struct sahara_packet *rx;
  78. struct work_struct work;
  79. struct mhi_device *mhi_dev;
  80. const char **image_table;
  81. u32 table_size;
  82. u32 active_image_id;
  83. const struct firmware *firmware;
  84. };
  85. static const char *aic100_image_table[] = {
  86. [1] = "qcom/aic100/fw1.bin",
  87. [2] = "qcom/aic100/fw2.bin",
  88. [4] = "qcom/aic100/fw4.bin",
  89. [5] = "qcom/aic100/fw5.bin",
  90. [6] = "qcom/aic100/fw6.bin",
  91. [8] = "qcom/aic100/fw8.bin",
  92. [9] = "qcom/aic100/fw9.bin",
  93. [10] = "qcom/aic100/fw10.bin",
  94. };
  95. static int sahara_find_image(struct sahara_context *context, u32 image_id)
  96. {
  97. int ret;
  98. if (image_id == context->active_image_id)
  99. return 0;
  100. if (context->active_image_id != SAHARA_IMAGE_ID_NONE) {
  101. dev_err(&context->mhi_dev->dev, "image id %d is not valid as %d is active\n",
  102. image_id, context->active_image_id);
  103. return -EINVAL;
  104. }
  105. if (image_id >= context->table_size || !context->image_table[image_id]) {
  106. dev_err(&context->mhi_dev->dev, "request for unknown image: %d\n", image_id);
  107. return -EINVAL;
  108. }
  109. /*
  110. * This image might be optional. The device may continue without it.
  111. * Only the device knows. Suppress error messages that could suggest an
  112. * a problem when we were actually able to continue.
  113. */
  114. ret = firmware_request_nowarn(&context->firmware,
  115. context->image_table[image_id],
  116. &context->mhi_dev->dev);
  117. if (ret) {
  118. dev_dbg(&context->mhi_dev->dev, "request for image id %d / file %s failed %d\n",
  119. image_id, context->image_table[image_id], ret);
  120. return ret;
  121. }
  122. context->active_image_id = image_id;
  123. return 0;
  124. }
  125. static void sahara_release_image(struct sahara_context *context)
  126. {
  127. if (context->active_image_id != SAHARA_IMAGE_ID_NONE)
  128. release_firmware(context->firmware);
  129. context->active_image_id = SAHARA_IMAGE_ID_NONE;
  130. }
  131. static void sahara_send_reset(struct sahara_context *context)
  132. {
  133. int ret;
  134. context->tx[0]->cmd = cpu_to_le32(SAHARA_RESET_CMD);
  135. context->tx[0]->length = cpu_to_le32(SAHARA_RESET_LENGTH);
  136. ret = mhi_queue_buf(context->mhi_dev, DMA_TO_DEVICE, context->tx[0],
  137. SAHARA_RESET_LENGTH, MHI_EOT);
  138. if (ret)
  139. dev_err(&context->mhi_dev->dev, "Unable to send reset response %d\n", ret);
  140. }
  141. static void sahara_hello(struct sahara_context *context)
  142. {
  143. int ret;
  144. dev_dbg(&context->mhi_dev->dev,
  145. "HELLO cmd received. length:%d version:%d version_compat:%d max_length:%d mode:%d\n",
  146. le32_to_cpu(context->rx->length),
  147. le32_to_cpu(context->rx->hello.version),
  148. le32_to_cpu(context->rx->hello.version_compat),
  149. le32_to_cpu(context->rx->hello.max_length),
  150. le32_to_cpu(context->rx->hello.mode));
  151. if (le32_to_cpu(context->rx->length) != SAHARA_HELLO_LENGTH) {
  152. dev_err(&context->mhi_dev->dev, "Malformed hello packet - length %d\n",
  153. le32_to_cpu(context->rx->length));
  154. return;
  155. }
  156. if (le32_to_cpu(context->rx->hello.version) != SAHARA_VERSION) {
  157. dev_err(&context->mhi_dev->dev, "Unsupported hello packet - version %d\n",
  158. le32_to_cpu(context->rx->hello.version));
  159. return;
  160. }
  161. if (le32_to_cpu(context->rx->hello.mode) != SAHARA_MODE_IMAGE_TX_PENDING &&
  162. le32_to_cpu(context->rx->hello.mode) != SAHARA_MODE_IMAGE_TX_COMPLETE) {
  163. dev_err(&context->mhi_dev->dev, "Unsupported hello packet - mode %d\n",
  164. le32_to_cpu(context->rx->hello.mode));
  165. return;
  166. }
  167. context->tx[0]->cmd = cpu_to_le32(SAHARA_HELLO_RESP_CMD);
  168. context->tx[0]->length = cpu_to_le32(SAHARA_HELLO_LENGTH);
  169. context->tx[0]->hello_resp.version = cpu_to_le32(SAHARA_VERSION);
  170. context->tx[0]->hello_resp.version_compat = cpu_to_le32(SAHARA_VERSION);
  171. context->tx[0]->hello_resp.status = cpu_to_le32(SAHARA_SUCCESS);
  172. context->tx[0]->hello_resp.mode = context->rx->hello_resp.mode;
  173. ret = mhi_queue_buf(context->mhi_dev, DMA_TO_DEVICE, context->tx[0],
  174. SAHARA_HELLO_LENGTH, MHI_EOT);
  175. if (ret)
  176. dev_err(&context->mhi_dev->dev, "Unable to send hello response %d\n", ret);
  177. }
  178. static void sahara_read_data(struct sahara_context *context)
  179. {
  180. u32 image_id, data_offset, data_len, pkt_data_len;
  181. int ret;
  182. int i;
  183. dev_dbg(&context->mhi_dev->dev,
  184. "READ_DATA cmd received. length:%d image:%d offset:%d data_length:%d\n",
  185. le32_to_cpu(context->rx->length),
  186. le32_to_cpu(context->rx->read_data.image),
  187. le32_to_cpu(context->rx->read_data.offset),
  188. le32_to_cpu(context->rx->read_data.length));
  189. if (le32_to_cpu(context->rx->length) != SAHARA_READ_DATA_LENGTH) {
  190. dev_err(&context->mhi_dev->dev, "Malformed read_data packet - length %d\n",
  191. le32_to_cpu(context->rx->length));
  192. return;
  193. }
  194. image_id = le32_to_cpu(context->rx->read_data.image);
  195. data_offset = le32_to_cpu(context->rx->read_data.offset);
  196. data_len = le32_to_cpu(context->rx->read_data.length);
  197. ret = sahara_find_image(context, image_id);
  198. if (ret) {
  199. sahara_send_reset(context);
  200. return;
  201. }
  202. /*
  203. * Image is released when the device is done with it via
  204. * SAHARA_END_OF_IMAGE_CMD. sahara_send_reset() will either cause the
  205. * device to retry the operation with a modification, or decide to be
  206. * done with the image and trigger SAHARA_END_OF_IMAGE_CMD.
  207. * release_image() is called from SAHARA_END_OF_IMAGE_CMD. processing
  208. * and is not needed here on error.
  209. */
  210. if (data_len > SAHARA_TRANSFER_MAX_SIZE) {
  211. dev_err(&context->mhi_dev->dev, "Malformed read_data packet - data len %d exceeds max xfer size %d\n",
  212. data_len, SAHARA_TRANSFER_MAX_SIZE);
  213. sahara_send_reset(context);
  214. return;
  215. }
  216. if (data_offset >= context->firmware->size) {
  217. dev_err(&context->mhi_dev->dev, "Malformed read_data packet - data offset %d exceeds file size %zu\n",
  218. data_offset, context->firmware->size);
  219. sahara_send_reset(context);
  220. return;
  221. }
  222. if (size_add(data_offset, data_len) > context->firmware->size) {
  223. dev_err(&context->mhi_dev->dev, "Malformed read_data packet - data offset %d and length %d exceeds file size %zu\n",
  224. data_offset, data_len, context->firmware->size);
  225. sahara_send_reset(context);
  226. return;
  227. }
  228. for (i = 0; i < SAHARA_NUM_TX_BUF && data_len; ++i) {
  229. pkt_data_len = min(data_len, SAHARA_PACKET_MAX_SIZE);
  230. memcpy(context->tx[i], &context->firmware->data[data_offset], pkt_data_len);
  231. data_offset += pkt_data_len;
  232. data_len -= pkt_data_len;
  233. ret = mhi_queue_buf(context->mhi_dev, DMA_TO_DEVICE,
  234. context->tx[i], pkt_data_len,
  235. !data_len ? MHI_EOT : MHI_CHAIN);
  236. if (ret) {
  237. dev_err(&context->mhi_dev->dev, "Unable to send read_data response %d\n",
  238. ret);
  239. return;
  240. }
  241. }
  242. }
  243. static void sahara_end_of_image(struct sahara_context *context)
  244. {
  245. int ret;
  246. dev_dbg(&context->mhi_dev->dev,
  247. "END_OF_IMAGE cmd received. length:%d image:%d status:%d\n",
  248. le32_to_cpu(context->rx->length),
  249. le32_to_cpu(context->rx->end_of_image.image),
  250. le32_to_cpu(context->rx->end_of_image.status));
  251. if (le32_to_cpu(context->rx->length) != SAHARA_END_OF_IMAGE_LENGTH) {
  252. dev_err(&context->mhi_dev->dev, "Malformed end_of_image packet - length %d\n",
  253. le32_to_cpu(context->rx->length));
  254. return;
  255. }
  256. if (context->active_image_id != SAHARA_IMAGE_ID_NONE &&
  257. le32_to_cpu(context->rx->end_of_image.image) != context->active_image_id) {
  258. dev_err(&context->mhi_dev->dev, "Malformed end_of_image packet - image %d is not the active image\n",
  259. le32_to_cpu(context->rx->end_of_image.image));
  260. return;
  261. }
  262. sahara_release_image(context);
  263. if (le32_to_cpu(context->rx->end_of_image.status))
  264. return;
  265. context->tx[0]->cmd = cpu_to_le32(SAHARA_DONE_CMD);
  266. context->tx[0]->length = cpu_to_le32(SAHARA_DONE_LENGTH);
  267. ret = mhi_queue_buf(context->mhi_dev, DMA_TO_DEVICE, context->tx[0],
  268. SAHARA_DONE_LENGTH, MHI_EOT);
  269. if (ret)
  270. dev_dbg(&context->mhi_dev->dev, "Unable to send done response %d\n", ret);
  271. }
  272. static void sahara_processing(struct work_struct *work)
  273. {
  274. struct sahara_context *context = container_of(work, struct sahara_context, work);
  275. int ret;
  276. switch (le32_to_cpu(context->rx->cmd)) {
  277. case SAHARA_HELLO_CMD:
  278. sahara_hello(context);
  279. break;
  280. case SAHARA_READ_DATA_CMD:
  281. sahara_read_data(context);
  282. break;
  283. case SAHARA_END_OF_IMAGE_CMD:
  284. sahara_end_of_image(context);
  285. break;
  286. case SAHARA_DONE_RESP_CMD:
  287. /* Intentional do nothing as we don't need to exit an app */
  288. break;
  289. default:
  290. dev_err(&context->mhi_dev->dev, "Unknown command %d\n",
  291. le32_to_cpu(context->rx->cmd));
  292. break;
  293. }
  294. ret = mhi_queue_buf(context->mhi_dev, DMA_FROM_DEVICE, context->rx,
  295. SAHARA_PACKET_MAX_SIZE, MHI_EOT);
  296. if (ret)
  297. dev_err(&context->mhi_dev->dev, "Unable to requeue rx buf %d\n", ret);
  298. }
  299. static int sahara_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id)
  300. {
  301. struct sahara_context *context;
  302. int ret;
  303. int i;
  304. context = devm_kzalloc(&mhi_dev->dev, sizeof(*context), GFP_KERNEL);
  305. if (!context)
  306. return -ENOMEM;
  307. context->rx = devm_kzalloc(&mhi_dev->dev, SAHARA_PACKET_MAX_SIZE, GFP_KERNEL);
  308. if (!context->rx)
  309. return -ENOMEM;
  310. /*
  311. * AIC100 defines SAHARA_TRANSFER_MAX_SIZE as the largest value it
  312. * will request for READ_DATA. This is larger than
  313. * SAHARA_PACKET_MAX_SIZE, and we need 9x SAHARA_PACKET_MAX_SIZE to
  314. * cover SAHARA_TRANSFER_MAX_SIZE. When the remote side issues a
  315. * READ_DATA, it requires a transfer of the exact size requested. We
  316. * can use MHI_CHAIN to link multiple buffers into a single transfer
  317. * but the remote side will not consume the buffers until it sees an
  318. * EOT, thus we need to allocate enough buffers to put in the tx fifo
  319. * to cover an entire READ_DATA request of the max size.
  320. */
  321. for (i = 0; i < SAHARA_NUM_TX_BUF; ++i) {
  322. context->tx[i] = devm_kzalloc(&mhi_dev->dev, SAHARA_PACKET_MAX_SIZE, GFP_KERNEL);
  323. if (!context->tx[i])
  324. return -ENOMEM;
  325. }
  326. context->mhi_dev = mhi_dev;
  327. INIT_WORK(&context->work, sahara_processing);
  328. context->image_table = aic100_image_table;
  329. context->table_size = ARRAY_SIZE(aic100_image_table);
  330. context->active_image_id = SAHARA_IMAGE_ID_NONE;
  331. dev_set_drvdata(&mhi_dev->dev, context);
  332. ret = mhi_prepare_for_transfer(mhi_dev);
  333. if (ret)
  334. return ret;
  335. ret = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, context->rx, SAHARA_PACKET_MAX_SIZE, MHI_EOT);
  336. if (ret) {
  337. mhi_unprepare_from_transfer(mhi_dev);
  338. return ret;
  339. }
  340. return 0;
  341. }
  342. static void sahara_mhi_remove(struct mhi_device *mhi_dev)
  343. {
  344. struct sahara_context *context = dev_get_drvdata(&mhi_dev->dev);
  345. cancel_work_sync(&context->work);
  346. sahara_release_image(context);
  347. mhi_unprepare_from_transfer(mhi_dev);
  348. }
  349. static void sahara_mhi_ul_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result)
  350. {
  351. }
  352. static void sahara_mhi_dl_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result)
  353. {
  354. struct sahara_context *context = dev_get_drvdata(&mhi_dev->dev);
  355. if (!mhi_result->transaction_status)
  356. schedule_work(&context->work);
  357. }
  358. static const struct mhi_device_id sahara_mhi_match_table[] = {
  359. { .chan = "QAIC_SAHARA", },
  360. {},
  361. };
  362. static struct mhi_driver sahara_mhi_driver = {
  363. .id_table = sahara_mhi_match_table,
  364. .remove = sahara_mhi_remove,
  365. .probe = sahara_mhi_probe,
  366. .ul_xfer_cb = sahara_mhi_ul_xfer_cb,
  367. .dl_xfer_cb = sahara_mhi_dl_xfer_cb,
  368. .driver = {
  369. .name = "sahara",
  370. },
  371. };
  372. int sahara_register(void)
  373. {
  374. return mhi_driver_register(&sahara_mhi_driver);
  375. }
  376. void sahara_unregister(void)
  377. {
  378. mhi_driver_unregister(&sahara_mhi_driver);
  379. }