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