aie2_message.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2023-2024, Advanced Micro Devices, Inc.
  4. */
  5. #include <drm/amdxdna_accel.h>
  6. #include <drm/drm_cache.h>
  7. #include <drm/drm_device.h>
  8. #include <drm/drm_gem.h>
  9. #include <drm/drm_gem_shmem_helper.h>
  10. #include <drm/drm_print.h>
  11. #include <drm/gpu_scheduler.h>
  12. #include <linux/bitfield.h>
  13. #include <linux/errno.h>
  14. #include <linux/pci.h>
  15. #include <linux/types.h>
  16. #include <linux/xarray.h>
  17. #include "aie2_msg_priv.h"
  18. #include "aie2_pci.h"
  19. #include "amdxdna_ctx.h"
  20. #include "amdxdna_gem.h"
  21. #include "amdxdna_mailbox.h"
  22. #include "amdxdna_mailbox_helper.h"
  23. #include "amdxdna_pci_drv.h"
  24. #define DECLARE_AIE2_MSG(name, op) \
  25. DECLARE_XDNA_MSG_COMMON(name, op, MAX_AIE2_STATUS_CODE)
  26. #define EXEC_MSG_OPS(xdna) ((xdna)->dev_handle->exec_msg_ops)
  27. static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev,
  28. struct xdna_mailbox_msg *msg)
  29. {
  30. struct amdxdna_dev *xdna = ndev->xdna;
  31. struct xdna_notify *hdl = msg->handle;
  32. int ret;
  33. if (!ndev->mgmt_chann)
  34. return -ENODEV;
  35. ret = xdna_send_msg_wait(xdna, ndev->mgmt_chann, msg);
  36. if (ret == -ETIME)
  37. aie2_destroy_mgmt_chann(ndev);
  38. if (!ret && *hdl->status != AIE2_STATUS_SUCCESS) {
  39. XDNA_ERR(xdna, "command opcode 0x%x failed, status 0x%x",
  40. msg->opcode, *hdl->data);
  41. ret = -EINVAL;
  42. }
  43. return ret;
  44. }
  45. void *aie2_alloc_msg_buffer(struct amdxdna_dev_hdl *ndev, u32 *size,
  46. dma_addr_t *dma_addr)
  47. {
  48. struct amdxdna_dev *xdna = ndev->xdna;
  49. int order;
  50. *size = max(*size, SZ_8K);
  51. order = get_order(*size);
  52. if (order > MAX_PAGE_ORDER)
  53. return NULL;
  54. *size = PAGE_SIZE << order;
  55. return dma_alloc_noncoherent(xdna->ddev.dev, *size, dma_addr,
  56. DMA_FROM_DEVICE, GFP_KERNEL);
  57. }
  58. int aie2_suspend_fw(struct amdxdna_dev_hdl *ndev)
  59. {
  60. DECLARE_AIE2_MSG(suspend, MSG_OP_SUSPEND);
  61. int ret;
  62. ret = aie2_send_mgmt_msg_wait(ndev, &msg);
  63. if (ret) {
  64. XDNA_ERR(ndev->xdna, "Failed to suspend fw, ret %d", ret);
  65. return ret;
  66. }
  67. return aie2_psp_waitmode_poll(ndev->psp_hdl);
  68. }
  69. int aie2_resume_fw(struct amdxdna_dev_hdl *ndev)
  70. {
  71. DECLARE_AIE2_MSG(suspend, MSG_OP_RESUME);
  72. return aie2_send_mgmt_msg_wait(ndev, &msg);
  73. }
  74. int aie2_set_runtime_cfg(struct amdxdna_dev_hdl *ndev, u32 type, u64 value)
  75. {
  76. DECLARE_AIE2_MSG(set_runtime_cfg, MSG_OP_SET_RUNTIME_CONFIG);
  77. int ret;
  78. req.type = type;
  79. req.value = value;
  80. ret = aie2_send_mgmt_msg_wait(ndev, &msg);
  81. if (ret) {
  82. XDNA_ERR(ndev->xdna, "Failed to set runtime config, ret %d", ret);
  83. return ret;
  84. }
  85. return 0;
  86. }
  87. int aie2_get_runtime_cfg(struct amdxdna_dev_hdl *ndev, u32 type, u64 *value)
  88. {
  89. DECLARE_AIE2_MSG(get_runtime_cfg, MSG_OP_GET_RUNTIME_CONFIG);
  90. int ret;
  91. req.type = type;
  92. ret = aie2_send_mgmt_msg_wait(ndev, &msg);
  93. if (ret) {
  94. XDNA_ERR(ndev->xdna, "Failed to get runtime config, ret %d", ret);
  95. return ret;
  96. }
  97. *value = resp.value;
  98. return 0;
  99. }
  100. int aie2_assign_mgmt_pasid(struct amdxdna_dev_hdl *ndev, u16 pasid)
  101. {
  102. DECLARE_AIE2_MSG(assign_mgmt_pasid, MSG_OP_ASSIGN_MGMT_PASID);
  103. req.pasid = pasid;
  104. return aie2_send_mgmt_msg_wait(ndev, &msg);
  105. }
  106. int aie2_query_aie_version(struct amdxdna_dev_hdl *ndev, struct aie_version *version)
  107. {
  108. DECLARE_AIE2_MSG(aie_version_info, MSG_OP_QUERY_AIE_VERSION);
  109. struct amdxdna_dev *xdna = ndev->xdna;
  110. int ret;
  111. ret = aie2_send_mgmt_msg_wait(ndev, &msg);
  112. if (ret)
  113. return ret;
  114. XDNA_DBG(xdna, "Query AIE version - major: %u minor: %u completed",
  115. resp.major, resp.minor);
  116. version->major = resp.major;
  117. version->minor = resp.minor;
  118. return 0;
  119. }
  120. int aie2_query_aie_metadata(struct amdxdna_dev_hdl *ndev, struct aie_metadata *metadata)
  121. {
  122. DECLARE_AIE2_MSG(aie_tile_info, MSG_OP_QUERY_AIE_TILE_INFO);
  123. int ret;
  124. ret = aie2_send_mgmt_msg_wait(ndev, &msg);
  125. if (ret)
  126. return ret;
  127. metadata->size = resp.info.size;
  128. metadata->cols = resp.info.cols;
  129. metadata->rows = resp.info.rows;
  130. metadata->version.major = resp.info.major;
  131. metadata->version.minor = resp.info.minor;
  132. metadata->core.row_count = resp.info.core_rows;
  133. metadata->core.row_start = resp.info.core_row_start;
  134. metadata->core.dma_channel_count = resp.info.core_dma_channels;
  135. metadata->core.lock_count = resp.info.core_locks;
  136. metadata->core.event_reg_count = resp.info.core_events;
  137. metadata->mem.row_count = resp.info.mem_rows;
  138. metadata->mem.row_start = resp.info.mem_row_start;
  139. metadata->mem.dma_channel_count = resp.info.mem_dma_channels;
  140. metadata->mem.lock_count = resp.info.mem_locks;
  141. metadata->mem.event_reg_count = resp.info.mem_events;
  142. metadata->shim.row_count = resp.info.shim_rows;
  143. metadata->shim.row_start = resp.info.shim_row_start;
  144. metadata->shim.dma_channel_count = resp.info.shim_dma_channels;
  145. metadata->shim.lock_count = resp.info.shim_locks;
  146. metadata->shim.event_reg_count = resp.info.shim_events;
  147. return 0;
  148. }
  149. int aie2_query_firmware_version(struct amdxdna_dev_hdl *ndev,
  150. struct amdxdna_fw_ver *fw_ver)
  151. {
  152. DECLARE_AIE2_MSG(firmware_version, MSG_OP_GET_FIRMWARE_VERSION);
  153. int ret;
  154. ret = aie2_send_mgmt_msg_wait(ndev, &msg);
  155. if (ret)
  156. return ret;
  157. fw_ver->major = resp.major;
  158. fw_ver->minor = resp.minor;
  159. fw_ver->sub = resp.sub;
  160. fw_ver->build = resp.build;
  161. return 0;
  162. }
  163. static int aie2_destroy_context_req(struct amdxdna_dev_hdl *ndev, u32 id)
  164. {
  165. DECLARE_AIE2_MSG(destroy_ctx, MSG_OP_DESTROY_CONTEXT);
  166. struct amdxdna_dev *xdna = ndev->xdna;
  167. int ret;
  168. req.context_id = id;
  169. ret = aie2_send_mgmt_msg_wait(ndev, &msg);
  170. if (ret && ret != -ENODEV)
  171. XDNA_WARN(xdna, "Destroy context failed, ret %d", ret);
  172. else if (ret == -ENODEV)
  173. XDNA_DBG(xdna, "Destroy context: device already stopped");
  174. return ret;
  175. }
  176. static u32 aie2_get_context_priority(struct amdxdna_dev_hdl *ndev,
  177. struct amdxdna_hwctx *hwctx)
  178. {
  179. if (!AIE2_FEATURE_ON(ndev, AIE2_PREEMPT))
  180. return PRIORITY_HIGH;
  181. switch (hwctx->qos.priority) {
  182. case AMDXDNA_QOS_REALTIME_PRIORITY:
  183. return PRIORITY_REALTIME;
  184. case AMDXDNA_QOS_HIGH_PRIORITY:
  185. return PRIORITY_HIGH;
  186. case AMDXDNA_QOS_NORMAL_PRIORITY:
  187. return PRIORITY_NORMAL;
  188. case AMDXDNA_QOS_LOW_PRIORITY:
  189. return PRIORITY_LOW;
  190. default:
  191. return PRIORITY_HIGH;
  192. }
  193. }
  194. int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx)
  195. {
  196. DECLARE_AIE2_MSG(create_ctx, MSG_OP_CREATE_CONTEXT);
  197. struct amdxdna_dev *xdna = ndev->xdna;
  198. struct xdna_mailbox_chann_res x2i;
  199. struct xdna_mailbox_chann_res i2x;
  200. struct cq_pair *cq_pair;
  201. u32 intr_reg;
  202. int ret;
  203. req.aie_type = 1;
  204. req.start_col = hwctx->start_col;
  205. req.num_col = hwctx->num_col;
  206. req.num_unused_col = hwctx->num_unused_col;
  207. req.num_cq_pairs_requested = 1;
  208. req.pasid = hwctx->client->pasid;
  209. req.context_priority = aie2_get_context_priority(ndev, hwctx);
  210. ret = aie2_send_mgmt_msg_wait(ndev, &msg);
  211. if (ret)
  212. return ret;
  213. hwctx->fw_ctx_id = resp.context_id;
  214. if (WARN_ON_ONCE(hwctx->fw_ctx_id == -1))
  215. return -EINVAL;
  216. if (ndev->force_preempt_enabled) {
  217. ret = aie2_runtime_cfg(ndev, AIE2_RT_CFG_FORCE_PREEMPT, &hwctx->fw_ctx_id);
  218. if (ret) {
  219. XDNA_ERR(xdna, "failed to enable force preempt %d", ret);
  220. goto del_ctx_req;
  221. }
  222. }
  223. cq_pair = &resp.cq_pair[0];
  224. x2i.mb_head_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->x2i_q.head_addr);
  225. x2i.mb_tail_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->x2i_q.tail_addr);
  226. x2i.rb_start_addr = AIE2_SRAM_OFF(ndev, cq_pair->x2i_q.buf_addr);
  227. x2i.rb_size = cq_pair->x2i_q.buf_size;
  228. i2x.mb_head_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->i2x_q.head_addr);
  229. i2x.mb_tail_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->i2x_q.tail_addr);
  230. i2x.rb_start_addr = AIE2_SRAM_OFF(ndev, cq_pair->i2x_q.buf_addr);
  231. i2x.rb_size = cq_pair->i2x_q.buf_size;
  232. ret = pci_irq_vector(to_pci_dev(xdna->ddev.dev), resp.msix_id);
  233. if (ret == -EINVAL) {
  234. XDNA_ERR(xdna, "Alloc IRQ failed %d", ret);
  235. goto del_ctx_req;
  236. }
  237. intr_reg = i2x.mb_head_ptr_reg + 4;
  238. hwctx->priv->mbox_chann = xdna_mailbox_alloc_channel(ndev->mbox);
  239. if (!hwctx->priv->mbox_chann) {
  240. XDNA_ERR(xdna, "Not able to create channel");
  241. ret = -EINVAL;
  242. goto del_ctx_req;
  243. }
  244. ret = xdna_mailbox_start_channel(hwctx->priv->mbox_chann, &x2i, &i2x,
  245. intr_reg, ret);
  246. if (ret) {
  247. XDNA_ERR(xdna, "Not able to create channel");
  248. ret = -EINVAL;
  249. goto free_channel;
  250. }
  251. ndev->hwctx_num++;
  252. XDNA_DBG(xdna, "Mailbox channel irq: %d, msix_id: %d", ret, resp.msix_id);
  253. XDNA_DBG(xdna, "Created fw ctx %d pasid %d", hwctx->fw_ctx_id, hwctx->client->pasid);
  254. return 0;
  255. free_channel:
  256. xdna_mailbox_free_channel(hwctx->priv->mbox_chann);
  257. del_ctx_req:
  258. aie2_destroy_context_req(ndev, hwctx->fw_ctx_id);
  259. return ret;
  260. }
  261. int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx)
  262. {
  263. struct amdxdna_dev *xdna = ndev->xdna;
  264. int ret;
  265. if (!hwctx->priv->mbox_chann)
  266. return 0;
  267. xdna_mailbox_stop_channel(hwctx->priv->mbox_chann);
  268. ret = aie2_destroy_context_req(ndev, hwctx->fw_ctx_id);
  269. xdna_mailbox_free_channel(hwctx->priv->mbox_chann);
  270. XDNA_DBG(xdna, "Destroyed fw ctx %d", hwctx->fw_ctx_id);
  271. hwctx->priv->mbox_chann = NULL;
  272. hwctx->fw_ctx_id = -1;
  273. ndev->hwctx_num--;
  274. return ret;
  275. }
  276. int aie2_map_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u64 size)
  277. {
  278. DECLARE_AIE2_MSG(map_host_buffer, MSG_OP_MAP_HOST_BUFFER);
  279. struct amdxdna_dev *xdna = ndev->xdna;
  280. int ret;
  281. req.context_id = context_id;
  282. req.buf_addr = addr;
  283. req.buf_size = size;
  284. ret = aie2_send_mgmt_msg_wait(ndev, &msg);
  285. if (ret)
  286. return ret;
  287. XDNA_DBG(xdna, "fw ctx %d map host buf addr 0x%llx size 0x%llx",
  288. context_id, addr, size);
  289. return 0;
  290. }
  291. static int amdxdna_hwctx_col_map(struct amdxdna_hwctx *hwctx, void *arg)
  292. {
  293. u32 *bitmap = arg;
  294. *bitmap |= GENMASK(hwctx->start_col + hwctx->num_col - 1, hwctx->start_col);
  295. return 0;
  296. }
  297. int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf,
  298. u32 size, u32 *cols_filled)
  299. {
  300. DECLARE_AIE2_MSG(aie_column_info, MSG_OP_QUERY_COL_STATUS);
  301. struct amdxdna_dev *xdna = ndev->xdna;
  302. u32 buf_sz = size, aie_bitmap = 0;
  303. struct amdxdna_client *client;
  304. dma_addr_t dma_addr;
  305. u8 *buff_addr;
  306. int ret;
  307. buff_addr = aie2_alloc_msg_buffer(ndev, &buf_sz, &dma_addr);
  308. if (!buff_addr)
  309. return -ENOMEM;
  310. /* Go through each hardware context and mark the AIE columns that are active */
  311. list_for_each_entry(client, &xdna->client_list, node)
  312. amdxdna_hwctx_walk(client, &aie_bitmap, amdxdna_hwctx_col_map);
  313. *cols_filled = 0;
  314. req.dump_buff_addr = dma_addr;
  315. req.dump_buff_size = buf_sz;
  316. req.num_cols = hweight32(aie_bitmap);
  317. req.aie_bitmap = aie_bitmap;
  318. drm_clflush_virt_range(buff_addr, size); /* device can access */
  319. ret = aie2_send_mgmt_msg_wait(ndev, &msg);
  320. if (ret) {
  321. XDNA_ERR(xdna, "Error during NPU query, status %d", ret);
  322. goto fail;
  323. }
  324. XDNA_DBG(xdna, "Query NPU status completed");
  325. if (size < resp.size) {
  326. ret = -EINVAL;
  327. XDNA_ERR(xdna, "Bad buffer size. Available: %u. Needs: %u", size, resp.size);
  328. goto fail;
  329. }
  330. if (copy_to_user(buf, buff_addr, resp.size)) {
  331. ret = -EFAULT;
  332. XDNA_ERR(xdna, "Failed to copy NPU status to user space");
  333. goto fail;
  334. }
  335. *cols_filled = aie_bitmap;
  336. fail:
  337. aie2_free_msg_buffer(ndev, buf_sz, buff_addr, dma_addr);
  338. return ret;
  339. }
  340. int aie2_query_telemetry(struct amdxdna_dev_hdl *ndev,
  341. char __user *buf, u32 size,
  342. struct amdxdna_drm_query_telemetry_header *header)
  343. {
  344. DECLARE_AIE2_MSG(get_telemetry, MSG_OP_GET_TELEMETRY);
  345. struct amdxdna_dev *xdna = ndev->xdna;
  346. dma_addr_t dma_addr;
  347. u32 buf_sz = size;
  348. u8 *addr;
  349. int ret;
  350. if (header->type >= MAX_TELEMETRY_TYPE)
  351. return -EINVAL;
  352. addr = aie2_alloc_msg_buffer(ndev, &buf_sz, &dma_addr);
  353. if (!addr)
  354. return -ENOMEM;
  355. req.buf_addr = dma_addr;
  356. req.buf_size = buf_sz;
  357. req.type = header->type;
  358. drm_clflush_virt_range(addr, size); /* device can access */
  359. ret = aie2_send_mgmt_msg_wait(ndev, &msg);
  360. if (ret) {
  361. XDNA_ERR(xdna, "Query telemetry failed, status %d", ret);
  362. goto free_buf;
  363. }
  364. if (size < resp.size) {
  365. ret = -EINVAL;
  366. XDNA_ERR(xdna, "Bad buffer size. Available: %u. Needs: %u", size, resp.size);
  367. goto free_buf;
  368. }
  369. if (copy_to_user(buf, addr, resp.size)) {
  370. ret = -EFAULT;
  371. XDNA_ERR(xdna, "Failed to copy telemetry to user space");
  372. goto free_buf;
  373. }
  374. header->major = resp.major;
  375. header->minor = resp.minor;
  376. free_buf:
  377. aie2_free_msg_buffer(ndev, buf_sz, addr, dma_addr);
  378. return ret;
  379. }
  380. int aie2_register_asyn_event_msg(struct amdxdna_dev_hdl *ndev, dma_addr_t addr, u32 size,
  381. void *handle, int (*cb)(void*, void __iomem *, size_t))
  382. {
  383. struct async_event_msg_req req = { 0 };
  384. struct xdna_mailbox_msg msg = {
  385. .send_data = (u8 *)&req,
  386. .send_size = sizeof(req),
  387. .handle = handle,
  388. .opcode = MSG_OP_REGISTER_ASYNC_EVENT_MSG,
  389. .notify_cb = cb,
  390. };
  391. req.buf_addr = addr;
  392. req.buf_size = size;
  393. XDNA_DBG(ndev->xdna, "Register addr 0x%llx size 0x%x", addr, size);
  394. return xdna_mailbox_send_msg(ndev->mgmt_chann, &msg, TX_TIMEOUT);
  395. }
  396. int aie2_config_cu(struct amdxdna_hwctx *hwctx,
  397. int (*notify_cb)(void *, void __iomem *, size_t))
  398. {
  399. struct mailbox_channel *chann = hwctx->priv->mbox_chann;
  400. struct amdxdna_dev *xdna = hwctx->client->xdna;
  401. u32 shift = xdna->dev_info->dev_mem_buf_shift;
  402. struct config_cu_req req = { 0 };
  403. struct xdna_mailbox_msg msg;
  404. struct drm_gem_object *gobj;
  405. struct amdxdna_gem_obj *abo;
  406. int i;
  407. if (!chann)
  408. return -ENODEV;
  409. if (!hwctx->cus)
  410. return 0;
  411. if (hwctx->cus->num_cus > MAX_NUM_CUS) {
  412. XDNA_DBG(xdna, "Exceed maximum CU %d", MAX_NUM_CUS);
  413. return -EINVAL;
  414. }
  415. for (i = 0; i < hwctx->cus->num_cus; i++) {
  416. struct amdxdna_cu_config *cu = &hwctx->cus->cu_configs[i];
  417. if (XDNA_MBZ_DBG(xdna, cu->pad, sizeof(cu->pad)))
  418. return -EINVAL;
  419. gobj = drm_gem_object_lookup(hwctx->client->filp, cu->cu_bo);
  420. if (!gobj) {
  421. XDNA_ERR(xdna, "Lookup GEM object failed");
  422. return -EINVAL;
  423. }
  424. abo = to_xdna_obj(gobj);
  425. if (abo->type != AMDXDNA_BO_DEV) {
  426. drm_gem_object_put(gobj);
  427. XDNA_ERR(xdna, "Invalid BO type");
  428. return -EINVAL;
  429. }
  430. req.cfgs[i] = FIELD_PREP(AIE2_MSG_CFG_CU_PDI_ADDR,
  431. abo->mem.dev_addr >> shift);
  432. req.cfgs[i] |= FIELD_PREP(AIE2_MSG_CFG_CU_FUNC, cu->cu_func);
  433. XDNA_DBG(xdna, "CU %d full addr 0x%llx, cfg 0x%x", i,
  434. abo->mem.dev_addr, req.cfgs[i]);
  435. drm_gem_object_put(gobj);
  436. }
  437. req.num_cus = hwctx->cus->num_cus;
  438. msg.send_data = (u8 *)&req;
  439. msg.send_size = sizeof(req);
  440. msg.handle = hwctx;
  441. msg.opcode = MSG_OP_CONFIG_CU;
  442. msg.notify_cb = notify_cb;
  443. return xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
  444. }
  445. static int aie2_init_exec_cu_req(struct amdxdna_gem_obj *cmd_bo, void *req,
  446. size_t *size, u32 *msg_op)
  447. {
  448. struct execute_buffer_req *cu_req = req;
  449. u32 cmd_len;
  450. void *cmd;
  451. cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
  452. if (cmd_len > sizeof(cu_req->payload))
  453. return -EINVAL;
  454. cu_req->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
  455. if (cu_req->cu_idx == INVALID_CU_IDX)
  456. return -EINVAL;
  457. memcpy(cu_req->payload, cmd, cmd_len);
  458. *size = sizeof(*cu_req);
  459. *msg_op = MSG_OP_EXECUTE_BUFFER_CF;
  460. return 0;
  461. }
  462. static int aie2_init_exec_dpu_req(struct amdxdna_gem_obj *cmd_bo, void *req,
  463. size_t *size, u32 *msg_op)
  464. {
  465. struct exec_dpu_req *dpu_req = req;
  466. struct amdxdna_cmd_start_npu *sn;
  467. u32 cmd_len;
  468. sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
  469. if (cmd_len - sizeof(*sn) > sizeof(dpu_req->payload))
  470. return -EINVAL;
  471. dpu_req->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
  472. if (dpu_req->cu_idx == INVALID_CU_IDX)
  473. return -EINVAL;
  474. dpu_req->inst_buf_addr = sn->buffer;
  475. dpu_req->inst_size = sn->buffer_size;
  476. dpu_req->inst_prop_cnt = sn->prop_count;
  477. memcpy(dpu_req->payload, sn->prop_args, cmd_len - sizeof(*sn));
  478. *size = sizeof(*dpu_req);
  479. *msg_op = MSG_OP_EXEC_DPU;
  480. return 0;
  481. }
  482. static void aie2_init_exec_chain_req(void *req, u64 slot_addr, size_t size, u32 cmd_cnt)
  483. {
  484. struct cmd_chain_req *chain_req = req;
  485. chain_req->buf_addr = slot_addr;
  486. chain_req->buf_size = size;
  487. chain_req->count = cmd_cnt;
  488. }
  489. static void aie2_init_npu_chain_req(void *req, u64 slot_addr, size_t size, u32 cmd_cnt)
  490. {
  491. struct cmd_chain_npu_req *npu_chain_req = req;
  492. npu_chain_req->flags = 0;
  493. npu_chain_req->reserved = 0;
  494. npu_chain_req->buf_addr = slot_addr;
  495. npu_chain_req->buf_size = size;
  496. npu_chain_req->count = cmd_cnt;
  497. }
  498. static int
  499. aie2_cmdlist_fill_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
  500. {
  501. struct cmd_chain_slot_execbuf_cf *cf_slot = slot;
  502. u32 cmd_len;
  503. void *cmd;
  504. cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
  505. if (*size < sizeof(*cf_slot) + cmd_len)
  506. return -EINVAL;
  507. cf_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
  508. if (cf_slot->cu_idx == INVALID_CU_IDX)
  509. return -EINVAL;
  510. cf_slot->arg_cnt = cmd_len / sizeof(u32);
  511. memcpy(cf_slot->args, cmd, cmd_len);
  512. /* Accurate slot size to hint firmware to do necessary copy */
  513. *size = sizeof(*cf_slot) + cmd_len;
  514. return 0;
  515. }
  516. static int
  517. aie2_cmdlist_fill_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
  518. {
  519. struct cmd_chain_slot_dpu *dpu_slot = slot;
  520. struct amdxdna_cmd_start_npu *sn;
  521. u32 cmd_len;
  522. u32 arg_sz;
  523. sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
  524. arg_sz = cmd_len - sizeof(*sn);
  525. if (cmd_len < sizeof(*sn) || arg_sz > MAX_DPU_ARGS_SIZE)
  526. return -EINVAL;
  527. if (*size < sizeof(*dpu_slot) + arg_sz)
  528. return -EINVAL;
  529. dpu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
  530. if (dpu_slot->cu_idx == INVALID_CU_IDX)
  531. return -EINVAL;
  532. dpu_slot->inst_buf_addr = sn->buffer;
  533. dpu_slot->inst_size = sn->buffer_size;
  534. dpu_slot->inst_prop_cnt = sn->prop_count;
  535. dpu_slot->arg_cnt = arg_sz / sizeof(u32);
  536. memcpy(dpu_slot->args, sn->prop_args, arg_sz);
  537. /* Accurate slot size to hint firmware to do necessary copy */
  538. *size = sizeof(*dpu_slot) + arg_sz;
  539. return 0;
  540. }
  541. static int aie2_cmdlist_unsupp(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
  542. {
  543. return -EOPNOTSUPP;
  544. }
  545. static u32 aie2_get_chain_msg_op(u32 cmd_op)
  546. {
  547. switch (cmd_op) {
  548. case ERT_START_CU:
  549. return MSG_OP_CHAIN_EXEC_BUFFER_CF;
  550. case ERT_START_NPU:
  551. return MSG_OP_CHAIN_EXEC_DPU;
  552. default:
  553. break;
  554. }
  555. return MSG_OP_MAX_OPCODE;
  556. }
  557. static struct aie2_exec_msg_ops legacy_exec_message_ops = {
  558. .init_cu_req = aie2_init_exec_cu_req,
  559. .init_dpu_req = aie2_init_exec_dpu_req,
  560. .init_chain_req = aie2_init_exec_chain_req,
  561. .fill_cf_slot = aie2_cmdlist_fill_cf,
  562. .fill_dpu_slot = aie2_cmdlist_fill_dpu,
  563. .fill_preempt_slot = aie2_cmdlist_unsupp,
  564. .fill_elf_slot = aie2_cmdlist_unsupp,
  565. .get_chain_msg_op = aie2_get_chain_msg_op,
  566. };
  567. static int
  568. aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
  569. {
  570. struct cmd_chain_slot_npu *npu_slot = slot;
  571. u32 cmd_len;
  572. void *cmd;
  573. cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
  574. if (*size < sizeof(*npu_slot) + cmd_len)
  575. return -EINVAL;
  576. memset(npu_slot, 0, sizeof(*npu_slot));
  577. npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
  578. if (npu_slot->cu_idx == INVALID_CU_IDX)
  579. return -EINVAL;
  580. npu_slot->type = EXEC_NPU_TYPE_NON_ELF;
  581. npu_slot->arg_cnt = cmd_len / sizeof(u32);
  582. memcpy(npu_slot->args, cmd, cmd_len);
  583. *size = sizeof(*npu_slot) + cmd_len;
  584. return 0;
  585. }
  586. static int
  587. aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
  588. {
  589. struct cmd_chain_slot_npu *npu_slot = slot;
  590. struct amdxdna_cmd_start_npu *sn;
  591. u32 cmd_len;
  592. u32 arg_sz;
  593. sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
  594. arg_sz = cmd_len - sizeof(*sn);
  595. if (cmd_len < sizeof(*sn) || arg_sz > MAX_NPU_ARGS_SIZE)
  596. return -EINVAL;
  597. if (*size < sizeof(*npu_slot) + arg_sz)
  598. return -EINVAL;
  599. memset(npu_slot, 0, sizeof(*npu_slot));
  600. npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
  601. if (npu_slot->cu_idx == INVALID_CU_IDX)
  602. return -EINVAL;
  603. npu_slot->type = EXEC_NPU_TYPE_PARTIAL_ELF;
  604. npu_slot->inst_buf_addr = sn->buffer;
  605. npu_slot->inst_size = sn->buffer_size;
  606. npu_slot->inst_prop_cnt = sn->prop_count;
  607. npu_slot->arg_cnt = arg_sz / sizeof(u32);
  608. memcpy(npu_slot->args, sn->prop_args, arg_sz);
  609. *size = sizeof(*npu_slot) + arg_sz;
  610. return 0;
  611. }
  612. static int
  613. aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
  614. {
  615. struct cmd_chain_slot_npu *npu_slot = slot;
  616. struct amdxdna_cmd_preempt_data *pd;
  617. u32 cmd_len;
  618. u32 arg_sz;
  619. pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
  620. arg_sz = cmd_len - sizeof(*pd);
  621. if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
  622. return -EINVAL;
  623. if (*size < sizeof(*npu_slot) + arg_sz)
  624. return -EINVAL;
  625. memset(npu_slot, 0, sizeof(*npu_slot));
  626. npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
  627. if (npu_slot->cu_idx == INVALID_CU_IDX)
  628. return -EINVAL;
  629. npu_slot->type = EXEC_NPU_TYPE_PREEMPT;
  630. npu_slot->inst_buf_addr = pd->inst_buf;
  631. npu_slot->save_buf_addr = pd->save_buf;
  632. npu_slot->restore_buf_addr = pd->restore_buf;
  633. npu_slot->inst_size = pd->inst_size;
  634. npu_slot->save_size = pd->save_size;
  635. npu_slot->restore_size = pd->restore_size;
  636. npu_slot->inst_prop_cnt = pd->inst_prop_cnt;
  637. npu_slot->arg_cnt = arg_sz / sizeof(u32);
  638. memcpy(npu_slot->args, pd->prop_args, arg_sz);
  639. *size = sizeof(*npu_slot) + arg_sz;
  640. return 0;
  641. }
  642. static int
  643. aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
  644. {
  645. struct cmd_chain_slot_npu *npu_slot = slot;
  646. struct amdxdna_cmd_preempt_data *pd;
  647. u32 cmd_len;
  648. u32 arg_sz;
  649. pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
  650. arg_sz = cmd_len - sizeof(*pd);
  651. if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
  652. return -EINVAL;
  653. if (*size < sizeof(*npu_slot) + arg_sz)
  654. return -EINVAL;
  655. memset(npu_slot, 0, sizeof(*npu_slot));
  656. npu_slot->type = EXEC_NPU_TYPE_ELF;
  657. npu_slot->inst_buf_addr = pd->inst_buf;
  658. npu_slot->save_buf_addr = pd->save_buf;
  659. npu_slot->restore_buf_addr = pd->restore_buf;
  660. npu_slot->inst_size = pd->inst_size;
  661. npu_slot->save_size = pd->save_size;
  662. npu_slot->restore_size = pd->restore_size;
  663. npu_slot->inst_prop_cnt = pd->inst_prop_cnt;
  664. npu_slot->arg_cnt = 1;
  665. npu_slot->args[0] = AIE2_EXEC_BUFFER_KERNEL_OP_TXN;
  666. *size = struct_size(npu_slot, args, npu_slot->arg_cnt);
  667. return 0;
  668. }
  669. static u32 aie2_get_npu_chain_msg_op(u32 cmd_op)
  670. {
  671. return MSG_OP_CHAIN_EXEC_NPU;
  672. }
  673. static struct aie2_exec_msg_ops npu_exec_message_ops = {
  674. .init_cu_req = aie2_init_exec_cu_req,
  675. .init_dpu_req = aie2_init_exec_dpu_req,
  676. .init_chain_req = aie2_init_npu_chain_req,
  677. .fill_cf_slot = aie2_cmdlist_fill_npu_cf,
  678. .fill_dpu_slot = aie2_cmdlist_fill_npu_dpu,
  679. .fill_preempt_slot = aie2_cmdlist_fill_npu_preempt,
  680. .fill_elf_slot = aie2_cmdlist_fill_npu_elf,
  681. .get_chain_msg_op = aie2_get_npu_chain_msg_op,
  682. };
  683. static int aie2_init_exec_req(void *req, struct amdxdna_gem_obj *cmd_abo,
  684. size_t *size, u32 *msg_op)
  685. {
  686. struct amdxdna_dev *xdna = cmd_abo->client->xdna;
  687. int ret;
  688. u32 op;
  689. op = amdxdna_cmd_get_op(cmd_abo);
  690. switch (op) {
  691. case ERT_START_CU:
  692. ret = EXEC_MSG_OPS(xdna)->init_cu_req(cmd_abo, req, size, msg_op);
  693. if (ret) {
  694. XDNA_DBG(xdna, "Init CU req failed ret %d", ret);
  695. return ret;
  696. }
  697. break;
  698. case ERT_START_NPU:
  699. ret = EXEC_MSG_OPS(xdna)->init_dpu_req(cmd_abo, req, size, msg_op);
  700. if (ret) {
  701. XDNA_DBG(xdna, "Init DPU req failed ret %d", ret);
  702. return ret;
  703. }
  704. break;
  705. default:
  706. XDNA_ERR(xdna, "Unsupported op %d", op);
  707. ret = -EOPNOTSUPP;
  708. break;
  709. }
  710. return ret;
  711. }
  712. static int
  713. aie2_cmdlist_fill_slot(void *slot, struct amdxdna_gem_obj *cmd_abo,
  714. size_t *size, u32 *cmd_op)
  715. {
  716. struct amdxdna_dev *xdna = cmd_abo->client->xdna;
  717. int ret;
  718. u32 op;
  719. op = amdxdna_cmd_get_op(cmd_abo);
  720. if (*cmd_op == ERT_INVALID_CMD)
  721. *cmd_op = op;
  722. else if (op != *cmd_op)
  723. return -EINVAL;
  724. switch (op) {
  725. case ERT_START_CU:
  726. ret = EXEC_MSG_OPS(xdna)->fill_cf_slot(cmd_abo, slot, size);
  727. break;
  728. case ERT_START_NPU:
  729. ret = EXEC_MSG_OPS(xdna)->fill_dpu_slot(cmd_abo, slot, size);
  730. break;
  731. case ERT_START_NPU_PREEMPT:
  732. if (!AIE2_FEATURE_ON(xdna->dev_handle, AIE2_PREEMPT))
  733. return -EOPNOTSUPP;
  734. ret = EXEC_MSG_OPS(xdna)->fill_preempt_slot(cmd_abo, slot, size);
  735. break;
  736. case ERT_START_NPU_PREEMPT_ELF:
  737. if (!AIE2_FEATURE_ON(xdna->dev_handle, AIE2_PREEMPT))
  738. return -EOPNOTSUPP;
  739. ret = EXEC_MSG_OPS(xdna)->fill_elf_slot(cmd_abo, slot, size);
  740. break;
  741. default:
  742. XDNA_INFO(xdna, "Unsupported op %d", op);
  743. ret = -EOPNOTSUPP;
  744. break;
  745. }
  746. return ret;
  747. }
  748. void aie2_msg_init(struct amdxdna_dev_hdl *ndev)
  749. {
  750. if (AIE2_FEATURE_ON(ndev, AIE2_NPU_COMMAND))
  751. ndev->exec_msg_ops = &npu_exec_message_ops;
  752. else
  753. ndev->exec_msg_ops = &legacy_exec_message_ops;
  754. }
  755. void aie2_destroy_mgmt_chann(struct amdxdna_dev_hdl *ndev)
  756. {
  757. struct amdxdna_dev *xdna = ndev->xdna;
  758. drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
  759. if (!ndev->mgmt_chann)
  760. return;
  761. xdna_mailbox_stop_channel(ndev->mgmt_chann);
  762. xdna_mailbox_free_channel(ndev->mgmt_chann);
  763. ndev->mgmt_chann = NULL;
  764. }
  765. static inline struct amdxdna_gem_obj *
  766. aie2_cmdlist_get_cmd_buf(struct amdxdna_sched_job *job)
  767. {
  768. int idx = get_job_idx(job->seq);
  769. return job->hwctx->priv->cmd_buf[idx];
  770. }
  771. int aie2_execbuf(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
  772. int (*notify_cb)(void *, void __iomem *, size_t))
  773. {
  774. struct mailbox_channel *chann = hwctx->priv->mbox_chann;
  775. struct amdxdna_dev *xdna = hwctx->client->xdna;
  776. struct amdxdna_gem_obj *cmd_abo = job->cmd_bo;
  777. struct xdna_mailbox_msg msg;
  778. union exec_req req;
  779. int ret;
  780. if (!chann)
  781. return -ENODEV;
  782. ret = aie2_init_exec_req(&req, cmd_abo, &msg.send_size, &msg.opcode);
  783. if (ret)
  784. return ret;
  785. msg.handle = job;
  786. msg.notify_cb = notify_cb;
  787. msg.send_data = (u8 *)&req;
  788. print_hex_dump_debug("cmd: ", DUMP_PREFIX_OFFSET, 16, 4, &req,
  789. 0x40, false);
  790. ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
  791. if (ret) {
  792. XDNA_ERR(xdna, "Send message failed");
  793. return ret;
  794. }
  795. return 0;
  796. }
  797. int aie2_cmdlist_multi_execbuf(struct amdxdna_hwctx *hwctx,
  798. struct amdxdna_sched_job *job,
  799. int (*notify_cb)(void *, void __iomem *, size_t))
  800. {
  801. struct amdxdna_gem_obj *cmdbuf_abo = aie2_cmdlist_get_cmd_buf(job);
  802. struct mailbox_channel *chann = hwctx->priv->mbox_chann;
  803. struct amdxdna_client *client = hwctx->client;
  804. struct amdxdna_gem_obj *cmd_abo = job->cmd_bo;
  805. struct amdxdna_dev *xdna = client->xdna;
  806. struct amdxdna_cmd_chain *payload;
  807. struct xdna_mailbox_msg msg;
  808. union exec_chain_req req;
  809. u32 payload_len;
  810. u32 offset = 0;
  811. size_t size;
  812. int ret;
  813. u32 op;
  814. u32 i;
  815. op = amdxdna_cmd_get_op(cmd_abo);
  816. payload = amdxdna_cmd_get_payload(cmd_abo, &payload_len);
  817. if (op != ERT_CMD_CHAIN || !payload ||
  818. payload_len < struct_size(payload, data, payload->command_count))
  819. return -EINVAL;
  820. op = ERT_INVALID_CMD;
  821. for (i = 0; i < payload->command_count; i++) {
  822. u32 boh = (u32)(payload->data[i]);
  823. struct amdxdna_gem_obj *abo;
  824. abo = amdxdna_gem_get_obj(client, boh, AMDXDNA_BO_CMD);
  825. if (!abo) {
  826. XDNA_ERR(xdna, "Failed to find cmd BO %d", boh);
  827. return -ENOENT;
  828. }
  829. size = cmdbuf_abo->mem.size - offset;
  830. ret = aie2_cmdlist_fill_slot(cmdbuf_abo->mem.kva + offset,
  831. abo, &size, &op);
  832. amdxdna_gem_put_obj(abo);
  833. if (ret)
  834. return ret;
  835. offset += size;
  836. }
  837. msg.opcode = EXEC_MSG_OPS(xdna)->get_chain_msg_op(op);
  838. if (msg.opcode == MSG_OP_MAX_OPCODE)
  839. return -EOPNOTSUPP;
  840. /* The offset is the accumulated total size of the cmd buffer */
  841. EXEC_MSG_OPS(xdna)->init_chain_req(&req, cmdbuf_abo->mem.dev_addr,
  842. offset, payload->command_count);
  843. drm_clflush_virt_range(cmdbuf_abo->mem.kva, offset);
  844. msg.handle = job;
  845. msg.notify_cb = notify_cb;
  846. msg.send_data = (u8 *)&req;
  847. msg.send_size = sizeof(req);
  848. ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
  849. if (ret) {
  850. XDNA_ERR(xdna, "Send message failed");
  851. return ret;
  852. }
  853. return 0;
  854. }
  855. int aie2_cmdlist_single_execbuf(struct amdxdna_hwctx *hwctx,
  856. struct amdxdna_sched_job *job,
  857. int (*notify_cb)(void *, void __iomem *, size_t))
  858. {
  859. struct amdxdna_gem_obj *cmdbuf_abo = aie2_cmdlist_get_cmd_buf(job);
  860. struct mailbox_channel *chann = hwctx->priv->mbox_chann;
  861. struct amdxdna_dev *xdna = hwctx->client->xdna;
  862. struct amdxdna_gem_obj *cmd_abo = job->cmd_bo;
  863. struct xdna_mailbox_msg msg;
  864. union exec_chain_req req;
  865. u32 op = ERT_INVALID_CMD;
  866. size_t size;
  867. int ret;
  868. size = cmdbuf_abo->mem.size;
  869. ret = aie2_cmdlist_fill_slot(cmdbuf_abo->mem.kva, cmd_abo, &size, &op);
  870. if (ret)
  871. return ret;
  872. msg.opcode = EXEC_MSG_OPS(xdna)->get_chain_msg_op(op);
  873. if (msg.opcode == MSG_OP_MAX_OPCODE)
  874. return -EOPNOTSUPP;
  875. EXEC_MSG_OPS(xdna)->init_chain_req(&req, cmdbuf_abo->mem.dev_addr,
  876. size, 1);
  877. drm_clflush_virt_range(cmdbuf_abo->mem.kva, size);
  878. msg.handle = job;
  879. msg.notify_cb = notify_cb;
  880. msg.send_data = (u8 *)&req;
  881. msg.send_size = sizeof(req);
  882. ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
  883. if (ret) {
  884. XDNA_ERR(hwctx->client->xdna, "Send message failed");
  885. return ret;
  886. }
  887. return 0;
  888. }
  889. int aie2_sync_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
  890. int (*notify_cb)(void *, void __iomem *, size_t))
  891. {
  892. struct mailbox_channel *chann = hwctx->priv->mbox_chann;
  893. struct amdxdna_gem_obj *abo = to_xdna_obj(job->bos[0]);
  894. struct amdxdna_dev *xdna = hwctx->client->xdna;
  895. struct xdna_mailbox_msg msg;
  896. struct sync_bo_req req;
  897. int ret = 0;
  898. req.src_addr = 0;
  899. req.dst_addr = amdxdna_dev_bo_offset(abo);
  900. req.size = abo->mem.size;
  901. /* Device to Host */
  902. req.type = FIELD_PREP(AIE2_MSG_SYNC_BO_SRC_TYPE, SYNC_BO_DEV_MEM) |
  903. FIELD_PREP(AIE2_MSG_SYNC_BO_DST_TYPE, SYNC_BO_HOST_MEM);
  904. XDNA_DBG(xdna, "sync %d bytes src(0x%llx) to dst(0x%llx) completed",
  905. req.size, req.src_addr, req.dst_addr);
  906. msg.handle = job;
  907. msg.notify_cb = notify_cb;
  908. msg.send_data = (u8 *)&req;
  909. msg.send_size = sizeof(req);
  910. msg.opcode = MSG_OP_SYNC_BO;
  911. ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
  912. if (ret) {
  913. XDNA_ERR(xdna, "Send message failed");
  914. return ret;
  915. }
  916. return 0;
  917. }
  918. int aie2_config_debug_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
  919. int (*notify_cb)(void *, void __iomem *, size_t))
  920. {
  921. struct mailbox_channel *chann = hwctx->priv->mbox_chann;
  922. struct amdxdna_gem_obj *abo = to_xdna_obj(job->bos[0]);
  923. struct amdxdna_dev *xdna = hwctx->client->xdna;
  924. struct config_debug_bo_req req;
  925. struct xdna_mailbox_msg msg;
  926. if (job->drv_cmd->opcode == ATTACH_DEBUG_BO)
  927. req.config = DEBUG_BO_REGISTER;
  928. else
  929. req.config = DEBUG_BO_UNREGISTER;
  930. req.offset = amdxdna_dev_bo_offset(abo);
  931. req.size = abo->mem.size;
  932. XDNA_DBG(xdna, "offset 0x%llx size 0x%llx config %d",
  933. req.offset, req.size, req.config);
  934. msg.handle = job;
  935. msg.notify_cb = notify_cb;
  936. msg.send_data = (u8 *)&req;
  937. msg.send_size = sizeof(req);
  938. msg.opcode = MSG_OP_CONFIG_DEBUG_BO;
  939. return xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
  940. }