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 "aie.h" 20 #include "aie2_msg_priv.h" 21 #include "aie2_pci.h" 22 #include "amdxdna_ctx.h" 23 #include "amdxdna_gem.h" 24 #include "amdxdna_mailbox.h" 25 #include "amdxdna_mailbox_helper.h" 26 #include "amdxdna_pci_drv.h" 27 28 #define EXEC_MSG_OPS(xdna) ((xdna)->dev_handle->exec_msg_ops) 29 30 int aie2_suspend_fw(struct amdxdna_dev_hdl *ndev) 31 { 32 DECLARE_AIE_MSG(suspend, MSG_OP_SUSPEND); 33 int ret; 34 35 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 36 if (ret) { 37 XDNA_ERR(ndev->aie.xdna, "Failed to suspend fw, ret %d", ret); 38 return ret; 39 } 40 41 return aie_psp_waitmode_poll(ndev->aie.psp_hdl); 42 } 43 44 int aie2_resume_fw(struct amdxdna_dev_hdl *ndev) 45 { 46 DECLARE_AIE_MSG(suspend, MSG_OP_RESUME); 47 48 return aie_send_mgmt_msg_wait(&ndev->aie, &msg); 49 } 50 51 int aie2_set_runtime_cfg(struct amdxdna_dev_hdl *ndev, u32 type, u64 value) 52 { 53 DECLARE_AIE_MSG(set_runtime_cfg, MSG_OP_SET_RUNTIME_CONFIG); 54 int ret; 55 56 req.type = type; 57 req.value = value; 58 59 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 60 if (ret) { 61 XDNA_ERR(ndev->aie.xdna, "Failed to set runtime config, ret %d", ret); 62 return ret; 63 } 64 65 return 0; 66 } 67 68 int aie2_get_runtime_cfg(struct amdxdna_dev_hdl *ndev, u32 type, u64 *value) 69 { 70 DECLARE_AIE_MSG(get_runtime_cfg, MSG_OP_GET_RUNTIME_CONFIG); 71 int ret; 72 73 req.type = type; 74 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 75 if (ret) { 76 XDNA_ERR(ndev->aie.xdna, "Failed to get runtime config, ret %d", ret); 77 return ret; 78 } 79 80 *value = resp.value; 81 return 0; 82 } 83 84 int aie2_assign_mgmt_pasid(struct amdxdna_dev_hdl *ndev, u16 pasid) 85 { 86 DECLARE_AIE_MSG(assign_mgmt_pasid, MSG_OP_ASSIGN_MGMT_PASID); 87 88 req.pasid = pasid; 89 90 return aie_send_mgmt_msg_wait(&ndev->aie, &msg); 91 } 92 93 int aie2_query_aie_version(struct amdxdna_dev_hdl *ndev, 94 struct amdxdna_drm_query_aie_version *version) 95 { 96 DECLARE_AIE_MSG(aie_version_info, MSG_OP_QUERY_AIE_VERSION); 97 struct amdxdna_dev *xdna = ndev->aie.xdna; 98 int ret; 99 100 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 101 if (ret) 102 return ret; 103 104 XDNA_DBG(xdna, "Query AIE version - major: %u minor: %u completed", 105 resp.major, resp.minor); 106 107 version->major = resp.major; 108 version->minor = resp.minor; 109 110 return 0; 111 } 112 113 int aie2_query_aie_metadata(struct amdxdna_dev_hdl *ndev, 114 struct amdxdna_drm_query_aie_metadata *metadata) 115 { 116 DECLARE_AIE_MSG(aie_tile_info, MSG_OP_QUERY_AIE_TILE_INFO); 117 int ret; 118 119 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 120 if (ret) 121 return ret; 122 123 metadata->col_size = resp.info.size; 124 metadata->cols = resp.info.cols; 125 metadata->rows = resp.info.rows; 126 127 metadata->version.major = resp.info.major; 128 metadata->version.minor = resp.info.minor; 129 130 metadata->core.row_count = resp.info.core_rows; 131 metadata->core.row_start = resp.info.core_row_start; 132 metadata->core.dma_channel_count = resp.info.core_dma_channels; 133 metadata->core.lock_count = resp.info.core_locks; 134 metadata->core.event_reg_count = resp.info.core_events; 135 136 metadata->mem.row_count = resp.info.mem_rows; 137 metadata->mem.row_start = resp.info.mem_row_start; 138 metadata->mem.dma_channel_count = resp.info.mem_dma_channels; 139 metadata->mem.lock_count = resp.info.mem_locks; 140 metadata->mem.event_reg_count = resp.info.mem_events; 141 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 148 return 0; 149 } 150 151 int aie2_query_firmware_version(struct amdxdna_dev_hdl *ndev, 152 struct amdxdna_fw_ver *fw_ver) 153 { 154 DECLARE_AIE_MSG(firmware_version, MSG_OP_GET_FIRMWARE_VERSION); 155 int ret; 156 157 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 158 if (ret) 159 return ret; 160 161 fw_ver->major = resp.major; 162 fw_ver->minor = resp.minor; 163 fw_ver->sub = resp.sub; 164 fw_ver->build = resp.build; 165 166 return 0; 167 } 168 169 static int aie2_destroy_context_req(struct amdxdna_dev_hdl *ndev, u32 id) 170 { 171 DECLARE_AIE_MSG(destroy_ctx, MSG_OP_DESTROY_CONTEXT); 172 struct amdxdna_dev *xdna = ndev->aie.xdna; 173 int ret; 174 175 req.context_id = id; 176 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 177 if (ret && ret != -ENODEV) 178 XDNA_WARN(xdna, "Destroy context failed, ret %d", ret); 179 else if (ret == -ENODEV) 180 XDNA_DBG(xdna, "Destroy context: device already stopped"); 181 182 return ret; 183 } 184 185 static u32 aie2_get_context_priority(struct amdxdna_dev_hdl *ndev, 186 struct amdxdna_hwctx *hwctx) 187 { 188 if (!AIE_FEATURE_ON(&ndev->aie, AIE2_PREEMPT)) 189 return PRIORITY_HIGH; 190 191 switch (hwctx->qos.priority) { 192 case AMDXDNA_QOS_REALTIME_PRIORITY: 193 return PRIORITY_REALTIME; 194 case AMDXDNA_QOS_HIGH_PRIORITY: 195 return PRIORITY_HIGH; 196 case AMDXDNA_QOS_NORMAL_PRIORITY: 197 return PRIORITY_NORMAL; 198 case AMDXDNA_QOS_LOW_PRIORITY: 199 return PRIORITY_LOW; 200 default: 201 return PRIORITY_HIGH; 202 } 203 } 204 205 int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx) 206 { 207 DECLARE_AIE_MSG(create_ctx, MSG_OP_CREATE_CONTEXT); 208 struct amdxdna_dev *xdna = ndev->aie.xdna; 209 struct xdna_mailbox_chann_res x2i; 210 struct xdna_mailbox_chann_res i2x; 211 struct cq_pair *cq_pair; 212 u32 intr_reg; 213 int ret; 214 215 req.aie_type = 1; 216 req.start_col = hwctx->start_col; 217 req.num_col = hwctx->num_col; 218 req.num_unused_col = hwctx->num_unused_col; 219 req.num_cq_pairs_requested = 1; 220 req.pasid = amdxdna_pasid_on(hwctx->client) ? hwctx->client->pasid : 0; 221 req.context_priority = aie2_get_context_priority(ndev, hwctx); 222 223 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 224 if (ret) 225 return ret; 226 227 hwctx->fw_ctx_id = resp.context_id; 228 if (WARN_ON_ONCE(hwctx->fw_ctx_id == -1)) 229 return -EINVAL; 230 231 if (ndev->force_preempt_enabled) { 232 ret = aie2_runtime_cfg(ndev, AIE2_RT_CFG_FORCE_PREEMPT, &hwctx->fw_ctx_id); 233 if (ret) { 234 XDNA_ERR(xdna, "failed to enable force preempt %d", ret); 235 goto del_ctx_req; 236 } 237 } 238 239 cq_pair = &resp.cq_pair[0]; 240 x2i.mb_head_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->x2i_q.head_addr); 241 x2i.mb_tail_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->x2i_q.tail_addr); 242 x2i.rb_start_addr = AIE2_SRAM_OFF(ndev, cq_pair->x2i_q.buf_addr); 243 x2i.rb_size = cq_pair->x2i_q.buf_size; 244 245 i2x.mb_head_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->i2x_q.head_addr); 246 i2x.mb_tail_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->i2x_q.tail_addr); 247 i2x.rb_start_addr = AIE2_SRAM_OFF(ndev, cq_pair->i2x_q.buf_addr); 248 i2x.rb_size = cq_pair->i2x_q.buf_size; 249 250 ret = pci_irq_vector(to_pci_dev(xdna->ddev.dev), resp.msix_id); 251 if (ret == -EINVAL) { 252 XDNA_ERR(xdna, "Alloc IRQ failed %d", ret); 253 goto del_ctx_req; 254 } 255 256 intr_reg = i2x.mb_head_ptr_reg + 4; 257 hwctx->priv->mbox_chann = xdna_mailbox_alloc_channel(ndev->mbox); 258 if (!hwctx->priv->mbox_chann) { 259 XDNA_ERR(xdna, "Not able to create channel"); 260 ret = -EINVAL; 261 goto del_ctx_req; 262 } 263 264 ret = xdna_mailbox_start_channel(hwctx->priv->mbox_chann, &x2i, &i2x, 265 intr_reg, ret); 266 if (ret) { 267 XDNA_ERR(xdna, "Not able to create channel"); 268 ret = -EINVAL; 269 goto free_channel; 270 } 271 ndev->hwctx_num++; 272 273 XDNA_DBG(xdna, "Mailbox channel irq: %d, msix_id: %d", ret, resp.msix_id); 274 XDNA_DBG(xdna, "Created fw ctx %d pasid %d", hwctx->fw_ctx_id, hwctx->client->pasid); 275 276 return 0; 277 278 free_channel: 279 xdna_mailbox_free_channel(hwctx->priv->mbox_chann); 280 del_ctx_req: 281 aie2_destroy_context_req(ndev, hwctx->fw_ctx_id); 282 return ret; 283 } 284 285 int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx) 286 { 287 struct amdxdna_dev *xdna = ndev->aie.xdna; 288 int ret; 289 290 if (!hwctx->priv->mbox_chann) 291 return 0; 292 293 xdna_mailbox_stop_channel(hwctx->priv->mbox_chann); 294 ret = aie2_destroy_context_req(ndev, hwctx->fw_ctx_id); 295 xdna_mailbox_free_channel(hwctx->priv->mbox_chann); 296 XDNA_DBG(xdna, "Destroyed fw ctx %d", hwctx->fw_ctx_id); 297 hwctx->priv->mbox_chann = NULL; 298 hwctx->fw_ctx_id = -1; 299 ndev->hwctx_num--; 300 301 return ret; 302 } 303 304 int aie2_map_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u64 size) 305 { 306 DECLARE_AIE_MSG(map_host_buffer, MSG_OP_MAP_HOST_BUFFER); 307 struct amdxdna_dev *xdna = ndev->aie.xdna; 308 int ret; 309 310 req.context_id = context_id; 311 req.buf_addr = addr; 312 req.buf_size = size; 313 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 314 if (ret) 315 return ret; 316 317 XDNA_DBG(xdna, "fw ctx %d map host buf addr 0x%llx size 0x%llx", 318 context_id, addr, size); 319 320 return 0; 321 } 322 323 static int amdxdna_hwctx_col_map(struct amdxdna_hwctx *hwctx, void *arg) 324 { 325 u32 *bitmap = arg; 326 327 *bitmap |= GENMASK(hwctx->start_col + hwctx->num_col - 1, hwctx->start_col); 328 329 return 0; 330 } 331 332 int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf, 333 u32 size, u32 *cols_filled) 334 { 335 DECLARE_AIE_MSG(aie_column_info, MSG_OP_QUERY_COL_STATUS); 336 struct amdxdna_dev *xdna = ndev->aie.xdna; 337 u32 buf_sz, aie_bitmap = 0; 338 struct amdxdna_client *client; 339 dma_addr_t dma_addr; 340 u8 *buff_addr; 341 int ret; 342 343 buf_sz = ndev->aie.metadata.cols * ndev->aie.metadata.col_size; 344 buff_addr = amdxdna_alloc_msg_buffer(xdna, &buf_sz, &dma_addr); 345 if (IS_ERR(buff_addr)) 346 return PTR_ERR(buff_addr); 347 348 /* Go through each hardware context and mark the AIE columns that are active */ 349 list_for_each_entry(client, &xdna->client_list, node) 350 amdxdna_hwctx_walk(client, &aie_bitmap, amdxdna_hwctx_col_map); 351 352 *cols_filled = 0; 353 req.dump_buff_addr = dma_addr; 354 req.dump_buff_size = buf_sz; 355 req.num_cols = hweight32(aie_bitmap); 356 req.aie_bitmap = aie_bitmap; 357 358 drm_clflush_virt_range(buff_addr, req.dump_buff_size); /* device can access */ 359 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 360 if (ret) { 361 XDNA_ERR(xdna, "Error during NPU query, status %d", ret); 362 goto fail; 363 } 364 365 XDNA_DBG(xdna, "Query NPU status completed"); 366 367 if (buf_sz < resp.size) { 368 ret = -EINVAL; 369 XDNA_ERR(xdna, "Bad buffer size. Available: %u. Needs: %u", buf_sz, resp.size); 370 goto fail; 371 } 372 373 size = min(size, resp.size); 374 if (copy_to_user(buf, buff_addr, size)) { 375 ret = -EFAULT; 376 XDNA_ERR(xdna, "Failed to copy NPU status to user space"); 377 goto fail; 378 } 379 380 *cols_filled = aie_bitmap; 381 382 fail: 383 amdxdna_free_msg_buffer(xdna, buf_sz, buff_addr, dma_addr); 384 return ret; 385 } 386 387 int aie2_query_telemetry(struct amdxdna_dev_hdl *ndev, 388 char __user *buf, u32 size, 389 struct amdxdna_drm_query_telemetry_header *header) 390 { 391 DECLARE_AIE_MSG(get_telemetry, MSG_OP_GET_TELEMETRY); 392 struct amdxdna_dev *xdna = ndev->aie.xdna; 393 dma_addr_t dma_addr; 394 u32 buf_sz; 395 u8 *addr; 396 int ret; 397 398 if (header->type >= MAX_TELEMETRY_TYPE) 399 return -EINVAL; 400 401 buf_sz = min(size, SZ_4M); 402 addr = amdxdna_alloc_msg_buffer(xdna, &buf_sz, &dma_addr); 403 if (IS_ERR(addr)) 404 return PTR_ERR(addr); 405 406 req.buf_addr = dma_addr; 407 req.buf_size = buf_sz; 408 req.type = header->type; 409 410 drm_clflush_virt_range(addr, req.buf_size); /* device can access */ 411 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 412 if (ret) { 413 XDNA_ERR(xdna, "Query telemetry failed, status %d", ret); 414 goto free_buf; 415 } 416 417 if (buf_sz < resp.size) { 418 ret = -EINVAL; 419 XDNA_ERR(xdna, "Bad buffer size. Available: %u. Needs: %u", buf_sz, resp.size); 420 goto free_buf; 421 } 422 423 size = min(size, resp.size); 424 if (copy_to_user(buf, addr, size)) { 425 ret = -EFAULT; 426 XDNA_ERR(xdna, "Failed to copy telemetry to user space"); 427 goto free_buf; 428 } 429 430 header->major = resp.major; 431 header->minor = resp.minor; 432 433 free_buf: 434 amdxdna_free_msg_buffer(xdna, buf_sz, addr, dma_addr); 435 return ret; 436 } 437 438 int aie2_register_asyn_event_msg(struct amdxdna_dev_hdl *ndev, dma_addr_t addr, u32 size, 439 void *handle, int (*cb)(void*, void __iomem *, size_t)) 440 { 441 struct async_event_msg_req req = { 0 }; 442 struct xdna_mailbox_msg msg = { 443 .send_data = (u8 *)&req, 444 .send_size = sizeof(req), 445 .handle = handle, 446 .opcode = MSG_OP_REGISTER_ASYNC_EVENT_MSG, 447 .notify_cb = cb, 448 }; 449 450 req.buf_addr = addr; 451 req.buf_size = size; 452 453 XDNA_DBG(ndev->aie.xdna, "Register addr 0x%llx size 0x%x", addr, size); 454 return xdna_mailbox_send_msg(ndev->aie.mgmt_chann, &msg, TX_TIMEOUT); 455 } 456 457 int aie2_config_cu(struct amdxdna_hwctx *hwctx, 458 int (*notify_cb)(void *, void __iomem *, size_t)) 459 { 460 struct mailbox_channel *chann = hwctx->priv->mbox_chann; 461 struct amdxdna_dev *xdna = hwctx->client->xdna; 462 u32 shift = xdna->dev_info->dev_mem_buf_shift; 463 struct config_cu_req req = { 0 }; 464 struct xdna_mailbox_msg msg; 465 struct drm_gem_object *gobj; 466 struct amdxdna_gem_obj *abo; 467 int i; 468 469 if (!chann) 470 return -ENODEV; 471 472 if (!hwctx->cus) 473 return 0; 474 475 if (hwctx->cus->num_cus > MAX_NUM_CUS) { 476 XDNA_DBG(xdna, "Exceed maximum CU %d", MAX_NUM_CUS); 477 return -EINVAL; 478 } 479 480 for (i = 0; i < hwctx->cus->num_cus; i++) { 481 struct amdxdna_cu_config *cu = &hwctx->cus->cu_configs[i]; 482 483 if (XDNA_MBZ_DBG(xdna, cu->pad, sizeof(cu->pad))) 484 return -EINVAL; 485 486 gobj = drm_gem_object_lookup(hwctx->client->filp, cu->cu_bo); 487 if (!gobj) { 488 XDNA_ERR(xdna, "Lookup GEM object failed"); 489 return -EINVAL; 490 } 491 abo = to_xdna_obj(gobj); 492 493 if (abo->type != AMDXDNA_BO_DEV) { 494 drm_gem_object_put(gobj); 495 XDNA_ERR(xdna, "Invalid BO type"); 496 return -EINVAL; 497 } 498 499 req.cfgs[i] = FIELD_PREP(AIE2_MSG_CFG_CU_PDI_ADDR, 500 amdxdna_gem_dev_addr(abo) >> shift); 501 req.cfgs[i] |= FIELD_PREP(AIE2_MSG_CFG_CU_FUNC, cu->cu_func); 502 XDNA_DBG(xdna, "CU %d full addr 0x%llx, cfg 0x%x", i, 503 amdxdna_gem_dev_addr(abo), req.cfgs[i]); 504 drm_gem_object_put(gobj); 505 } 506 req.num_cus = hwctx->cus->num_cus; 507 508 msg.send_data = (u8 *)&req; 509 msg.send_size = sizeof(req); 510 msg.handle = hwctx; 511 msg.opcode = MSG_OP_CONFIG_CU; 512 msg.notify_cb = notify_cb; 513 return xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT); 514 } 515 516 static int aie2_init_exec_cu_req(struct amdxdna_gem_obj *cmd_bo, void *req, 517 size_t *size, u32 *msg_op) 518 { 519 struct execute_buffer_req *cu_req = req; 520 u32 cmd_len; 521 void *cmd; 522 523 cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); 524 if (cmd_len > sizeof(cu_req->payload)) 525 return -EINVAL; 526 527 cu_req->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); 528 if (cu_req->cu_idx == INVALID_CU_IDX) 529 return -EINVAL; 530 531 memcpy(cu_req->payload, cmd, cmd_len); 532 533 *size = sizeof(*cu_req); 534 *msg_op = MSG_OP_EXECUTE_BUFFER_CF; 535 return 0; 536 } 537 538 static int aie2_init_exec_dpu_req(struct amdxdna_gem_obj *cmd_bo, void *req, 539 size_t *size, u32 *msg_op) 540 { 541 struct exec_dpu_req *dpu_req = req; 542 struct amdxdna_cmd_start_npu *sn; 543 u32 cmd_len; 544 545 sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); 546 if (cmd_len - sizeof(*sn) > sizeof(dpu_req->payload)) 547 return -EINVAL; 548 549 dpu_req->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); 550 if (dpu_req->cu_idx == INVALID_CU_IDX) 551 return -EINVAL; 552 553 dpu_req->inst_buf_addr = sn->buffer; 554 dpu_req->inst_size = sn->buffer_size; 555 dpu_req->inst_prop_cnt = sn->prop_count; 556 memcpy(dpu_req->payload, sn->prop_args, cmd_len - sizeof(*sn)); 557 558 *size = sizeof(*dpu_req); 559 *msg_op = MSG_OP_EXEC_DPU; 560 return 0; 561 } 562 563 static void aie2_init_exec_chain_req(void *req, u64 slot_addr, size_t size, u32 cmd_cnt) 564 { 565 struct cmd_chain_req *chain_req = req; 566 567 chain_req->buf_addr = slot_addr; 568 chain_req->buf_size = size; 569 chain_req->count = cmd_cnt; 570 } 571 572 static void aie2_init_npu_chain_req(void *req, u64 slot_addr, size_t size, u32 cmd_cnt) 573 { 574 struct cmd_chain_npu_req *npu_chain_req = req; 575 576 npu_chain_req->flags = 0; 577 npu_chain_req->reserved = 0; 578 npu_chain_req->buf_addr = slot_addr; 579 npu_chain_req->buf_size = size; 580 npu_chain_req->count = cmd_cnt; 581 } 582 583 static int 584 aie2_cmdlist_fill_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) 585 { 586 struct cmd_chain_slot_execbuf_cf *cf_slot = slot; 587 u32 cmd_len; 588 void *cmd; 589 590 cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); 591 if (*size < sizeof(*cf_slot) + cmd_len) 592 return -EINVAL; 593 594 cf_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); 595 if (cf_slot->cu_idx == INVALID_CU_IDX) 596 return -EINVAL; 597 598 cf_slot->arg_cnt = cmd_len / sizeof(u32); 599 memcpy(cf_slot->args, cmd, cmd_len); 600 /* Accurate slot size to hint firmware to do necessary copy */ 601 *size = sizeof(*cf_slot) + cmd_len; 602 return 0; 603 } 604 605 static int 606 aie2_cmdlist_fill_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) 607 { 608 struct cmd_chain_slot_dpu *dpu_slot = slot; 609 struct amdxdna_cmd_start_npu *sn; 610 u32 cmd_len; 611 u32 arg_sz; 612 613 sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); 614 arg_sz = cmd_len - sizeof(*sn); 615 if (cmd_len < sizeof(*sn) || arg_sz > MAX_DPU_ARGS_SIZE) 616 return -EINVAL; 617 618 if (*size < sizeof(*dpu_slot) + arg_sz) 619 return -EINVAL; 620 621 dpu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); 622 if (dpu_slot->cu_idx == INVALID_CU_IDX) 623 return -EINVAL; 624 625 dpu_slot->inst_buf_addr = sn->buffer; 626 dpu_slot->inst_size = sn->buffer_size; 627 dpu_slot->inst_prop_cnt = sn->prop_count; 628 dpu_slot->arg_cnt = arg_sz / sizeof(u32); 629 memcpy(dpu_slot->args, sn->prop_args, arg_sz); 630 631 /* Accurate slot size to hint firmware to do necessary copy */ 632 *size = sizeof(*dpu_slot) + arg_sz; 633 return 0; 634 } 635 636 static int aie2_cmdlist_unsupp(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) 637 { 638 return -EOPNOTSUPP; 639 } 640 641 static u32 aie2_get_chain_msg_op(u32 cmd_op) 642 { 643 switch (cmd_op) { 644 case ERT_START_CU: 645 return MSG_OP_CHAIN_EXEC_BUFFER_CF; 646 case ERT_START_NPU: 647 return MSG_OP_CHAIN_EXEC_DPU; 648 default: 649 break; 650 } 651 652 return MSG_OP_MAX_OPCODE; 653 } 654 655 static struct aie2_exec_msg_ops legacy_exec_message_ops = { 656 .init_cu_req = aie2_init_exec_cu_req, 657 .init_dpu_req = aie2_init_exec_dpu_req, 658 .init_chain_req = aie2_init_exec_chain_req, 659 .fill_cf_slot = aie2_cmdlist_fill_cf, 660 .fill_dpu_slot = aie2_cmdlist_fill_dpu, 661 .fill_preempt_slot = aie2_cmdlist_unsupp, 662 .fill_elf_slot = aie2_cmdlist_unsupp, 663 .get_chain_msg_op = aie2_get_chain_msg_op, 664 }; 665 666 static int 667 aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) 668 { 669 struct cmd_chain_slot_npu *npu_slot = slot; 670 u32 cmd_len; 671 void *cmd; 672 673 cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); 674 if (*size < sizeof(*npu_slot) + cmd_len) 675 return -EINVAL; 676 677 memset(npu_slot, 0, sizeof(*npu_slot)); 678 npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); 679 if (npu_slot->cu_idx == INVALID_CU_IDX) 680 return -EINVAL; 681 682 npu_slot->type = EXEC_NPU_TYPE_NON_ELF; 683 npu_slot->arg_cnt = cmd_len / sizeof(u32); 684 memcpy(npu_slot->args, cmd, cmd_len); 685 686 *size = sizeof(*npu_slot) + cmd_len; 687 return 0; 688 } 689 690 static int 691 aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) 692 { 693 struct cmd_chain_slot_npu *npu_slot = slot; 694 struct amdxdna_cmd_start_npu *sn; 695 u32 cmd_len; 696 u32 arg_sz; 697 698 sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); 699 arg_sz = cmd_len - sizeof(*sn); 700 if (cmd_len < sizeof(*sn) || arg_sz > MAX_NPU_ARGS_SIZE) 701 return -EINVAL; 702 703 if (*size < sizeof(*npu_slot) + arg_sz) 704 return -EINVAL; 705 706 memset(npu_slot, 0, sizeof(*npu_slot)); 707 npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); 708 if (npu_slot->cu_idx == INVALID_CU_IDX) 709 return -EINVAL; 710 711 npu_slot->type = EXEC_NPU_TYPE_PARTIAL_ELF; 712 npu_slot->inst_buf_addr = sn->buffer; 713 npu_slot->inst_size = sn->buffer_size; 714 npu_slot->inst_prop_cnt = sn->prop_count; 715 npu_slot->arg_cnt = arg_sz / sizeof(u32); 716 memcpy(npu_slot->args, sn->prop_args, arg_sz); 717 718 *size = sizeof(*npu_slot) + arg_sz; 719 return 0; 720 } 721 722 static int 723 aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) 724 { 725 struct cmd_chain_slot_npu *npu_slot = slot; 726 struct amdxdna_cmd_preempt_data *pd; 727 u32 cmd_len; 728 u32 arg_sz; 729 730 pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); 731 arg_sz = cmd_len - sizeof(*pd); 732 if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE) 733 return -EINVAL; 734 735 if (*size < sizeof(*npu_slot) + arg_sz) 736 return -EINVAL; 737 738 memset(npu_slot, 0, sizeof(*npu_slot)); 739 npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); 740 if (npu_slot->cu_idx == INVALID_CU_IDX) 741 return -EINVAL; 742 743 npu_slot->type = EXEC_NPU_TYPE_PREEMPT; 744 npu_slot->inst_buf_addr = pd->inst_buf; 745 npu_slot->save_buf_addr = pd->save_buf; 746 npu_slot->restore_buf_addr = pd->restore_buf; 747 npu_slot->inst_size = pd->inst_size; 748 npu_slot->save_size = pd->save_size; 749 npu_slot->restore_size = pd->restore_size; 750 npu_slot->inst_prop_cnt = pd->inst_prop_cnt; 751 npu_slot->arg_cnt = arg_sz / sizeof(u32); 752 memcpy(npu_slot->args, pd->prop_args, arg_sz); 753 754 *size = sizeof(*npu_slot) + arg_sz; 755 return 0; 756 } 757 758 static int 759 aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size) 760 { 761 struct cmd_chain_slot_npu *npu_slot = slot; 762 struct amdxdna_cmd_preempt_data *pd; 763 u32 cmd_len; 764 u32 arg_sz; 765 766 pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); 767 arg_sz = cmd_len - sizeof(*pd); 768 if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE) 769 return -EINVAL; 770 771 if (*size < sizeof(*npu_slot) + arg_sz) 772 return -EINVAL; 773 774 memset(npu_slot, 0, sizeof(*npu_slot)); 775 npu_slot->type = EXEC_NPU_TYPE_ELF; 776 npu_slot->inst_buf_addr = pd->inst_buf; 777 npu_slot->save_buf_addr = pd->save_buf; 778 npu_slot->restore_buf_addr = pd->restore_buf; 779 npu_slot->inst_size = pd->inst_size; 780 npu_slot->save_size = pd->save_size; 781 npu_slot->restore_size = pd->restore_size; 782 npu_slot->inst_prop_cnt = pd->inst_prop_cnt; 783 npu_slot->arg_cnt = 1; 784 npu_slot->args[0] = AIE2_EXEC_BUFFER_KERNEL_OP_TXN; 785 786 *size = struct_size(npu_slot, args, npu_slot->arg_cnt); 787 return 0; 788 } 789 790 static u32 aie2_get_npu_chain_msg_op(u32 cmd_op) 791 { 792 return MSG_OP_CHAIN_EXEC_NPU; 793 } 794 795 static struct aie2_exec_msg_ops npu_exec_message_ops = { 796 .init_cu_req = aie2_init_exec_cu_req, 797 .init_dpu_req = aie2_init_exec_dpu_req, 798 .init_chain_req = aie2_init_npu_chain_req, 799 .fill_cf_slot = aie2_cmdlist_fill_npu_cf, 800 .fill_dpu_slot = aie2_cmdlist_fill_npu_dpu, 801 .fill_preempt_slot = aie2_cmdlist_fill_npu_preempt, 802 .fill_elf_slot = aie2_cmdlist_fill_npu_elf, 803 .get_chain_msg_op = aie2_get_npu_chain_msg_op, 804 }; 805 806 static int aie2_init_exec_req(void *req, struct amdxdna_gem_obj *cmd_abo, 807 size_t *size, u32 *msg_op) 808 { 809 struct amdxdna_dev *xdna = cmd_abo->client->xdna; 810 int ret; 811 u32 op; 812 813 op = amdxdna_cmd_get_op(cmd_abo); 814 switch (op) { 815 case ERT_START_CU: 816 ret = EXEC_MSG_OPS(xdna)->init_cu_req(cmd_abo, req, size, msg_op); 817 if (ret) { 818 XDNA_DBG(xdna, "Init CU req failed ret %d", ret); 819 return ret; 820 } 821 break; 822 case ERT_START_NPU: 823 ret = EXEC_MSG_OPS(xdna)->init_dpu_req(cmd_abo, req, size, msg_op); 824 if (ret) { 825 XDNA_DBG(xdna, "Init DPU req failed ret %d", ret); 826 return ret; 827 } 828 829 break; 830 default: 831 XDNA_ERR(xdna, "Unsupported op %d", op); 832 ret = -EOPNOTSUPP; 833 break; 834 } 835 836 return ret; 837 } 838 839 static int 840 aie2_cmdlist_fill_slot(void *slot, struct amdxdna_gem_obj *cmd_abo, 841 size_t *size, u32 *cmd_op) 842 { 843 struct amdxdna_dev *xdna = cmd_abo->client->xdna; 844 int ret; 845 u32 op; 846 847 op = amdxdna_cmd_get_op(cmd_abo); 848 if (*cmd_op == ERT_INVALID_CMD) 849 *cmd_op = op; 850 else if (op != *cmd_op) 851 return -EINVAL; 852 853 switch (op) { 854 case ERT_START_CU: 855 ret = EXEC_MSG_OPS(xdna)->fill_cf_slot(cmd_abo, slot, size); 856 break; 857 case ERT_START_NPU: 858 ret = EXEC_MSG_OPS(xdna)->fill_dpu_slot(cmd_abo, slot, size); 859 break; 860 case ERT_START_NPU_PREEMPT: 861 if (!AIE_FEATURE_ON(&xdna->dev_handle->aie, AIE2_PREEMPT)) 862 return -EOPNOTSUPP; 863 ret = EXEC_MSG_OPS(xdna)->fill_preempt_slot(cmd_abo, slot, size); 864 break; 865 case ERT_START_NPU_PREEMPT_ELF: 866 if (!AIE_FEATURE_ON(&xdna->dev_handle->aie, AIE2_PREEMPT)) 867 return -EOPNOTSUPP; 868 ret = EXEC_MSG_OPS(xdna)->fill_elf_slot(cmd_abo, slot, size); 869 break; 870 default: 871 XDNA_INFO(xdna, "Unsupported op %d", op); 872 ret = -EOPNOTSUPP; 873 break; 874 } 875 876 return ret; 877 } 878 879 void aie2_msg_init(struct amdxdna_dev_hdl *ndev) 880 { 881 if (AIE_FEATURE_ON(&ndev->aie, AIE2_NPU_COMMAND)) 882 ndev->exec_msg_ops = &npu_exec_message_ops; 883 else 884 ndev->exec_msg_ops = &legacy_exec_message_ops; 885 } 886 887 static inline struct amdxdna_gem_obj * 888 aie2_cmdlist_get_cmd_buf(struct amdxdna_sched_job *job) 889 { 890 int idx = get_job_idx(job->seq); 891 892 return job->hwctx->priv->cmd_buf[idx]; 893 } 894 895 int aie2_execbuf(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, 896 int (*notify_cb)(void *, void __iomem *, size_t)) 897 { 898 struct mailbox_channel *chann = hwctx->priv->mbox_chann; 899 struct amdxdna_dev *xdna = hwctx->client->xdna; 900 struct amdxdna_gem_obj *cmd_abo = job->cmd_bo; 901 struct xdna_mailbox_msg msg; 902 union exec_req req; 903 int ret; 904 905 if (!chann) 906 return -ENODEV; 907 908 ret = aie2_init_exec_req(&req, cmd_abo, &msg.send_size, &msg.opcode); 909 if (ret) 910 return ret; 911 912 msg.handle = job; 913 msg.notify_cb = notify_cb; 914 msg.send_data = (u8 *)&req; 915 print_hex_dump_debug("cmd: ", DUMP_PREFIX_OFFSET, 16, 4, &req, 916 0x40, false); 917 918 ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT); 919 if (ret) { 920 XDNA_ERR(xdna, "Send message failed"); 921 return ret; 922 } 923 924 return 0; 925 } 926 927 int aie2_cmdlist_multi_execbuf(struct amdxdna_hwctx *hwctx, 928 struct amdxdna_sched_job *job, 929 int (*notify_cb)(void *, void __iomem *, size_t)) 930 { 931 struct amdxdna_gem_obj *cmdbuf_abo = aie2_cmdlist_get_cmd_buf(job); 932 struct mailbox_channel *chann = hwctx->priv->mbox_chann; 933 struct amdxdna_client *client = hwctx->client; 934 struct amdxdna_gem_obj *cmd_abo = job->cmd_bo; 935 void *cmd_buf = amdxdna_gem_vmap(cmdbuf_abo); 936 struct amdxdna_dev *xdna = client->xdna; 937 struct amdxdna_cmd_chain *payload; 938 struct xdna_mailbox_msg msg; 939 union exec_chain_req req; 940 u32 payload_len, ccnt; 941 u32 offset = 0; 942 size_t size; 943 int ret; 944 u32 op; 945 u32 i; 946 947 if (!cmd_buf) 948 return -ENOMEM; 949 950 op = amdxdna_cmd_get_op(cmd_abo); 951 payload = amdxdna_cmd_get_payload(cmd_abo, &payload_len); 952 if (op != ERT_CMD_CHAIN) { 953 XDNA_DBG(xdna, "Invalid op code %d", op); 954 return -EINVAL; 955 } 956 957 if (!payload) { 958 XDNA_DBG(xdna, "Failed to get command payload"); 959 return -EINVAL; 960 } 961 962 ccnt = payload->command_count; 963 if (payload_len < struct_size(payload, data, ccnt)) { 964 XDNA_DBG(xdna, "Invalid command count %d", ccnt); 965 return -EINVAL; 966 } 967 968 op = ERT_INVALID_CMD; 969 for (i = 0; i < ccnt; i++) { 970 u32 boh = (u32)(payload->data[i]); 971 struct amdxdna_gem_obj *abo; 972 973 abo = amdxdna_gem_get_obj(client, boh, AMDXDNA_BO_SHARE); 974 if (!abo) { 975 XDNA_ERR(xdna, "Failed to find cmd BO %d", boh); 976 return -ENOENT; 977 } 978 979 size = cmdbuf_abo->mem.size - offset; 980 ret = aie2_cmdlist_fill_slot(cmd_buf + offset, abo, &size, &op); 981 amdxdna_gem_put_obj(abo); 982 if (ret) 983 return ret; 984 985 offset += size; 986 } 987 988 XDNA_DBG(xdna, "Total %d commands:", ccnt); 989 print_hex_dump_debug("cmdbufs: ", DUMP_PREFIX_OFFSET, 16, 4, 990 cmd_buf, offset, false); 991 992 msg.opcode = EXEC_MSG_OPS(xdna)->get_chain_msg_op(op); 993 if (msg.opcode == MSG_OP_MAX_OPCODE) 994 return -EOPNOTSUPP; 995 996 /* The offset is the accumulated total size of the cmd buffer */ 997 EXEC_MSG_OPS(xdna)->init_chain_req(&req, amdxdna_gem_dev_addr(cmdbuf_abo), 998 offset, ccnt); 999 drm_clflush_virt_range(cmd_buf, offset); 1000 1001 msg.handle = job; 1002 msg.notify_cb = notify_cb; 1003 msg.send_data = (u8 *)&req; 1004 msg.send_size = sizeof(req); 1005 print_hex_dump_debug("cmdlist msg: ", DUMP_PREFIX_OFFSET, 16, 4, 1006 &req, msg.send_size, false); 1007 ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT); 1008 if (ret) { 1009 XDNA_ERR(xdna, "Send message failed"); 1010 return ret; 1011 } 1012 1013 return 0; 1014 } 1015 1016 int aie2_cmdlist_single_execbuf(struct amdxdna_hwctx *hwctx, 1017 struct amdxdna_sched_job *job, 1018 int (*notify_cb)(void *, void __iomem *, size_t)) 1019 { 1020 struct amdxdna_gem_obj *cmdbuf_abo = aie2_cmdlist_get_cmd_buf(job); 1021 struct mailbox_channel *chann = hwctx->priv->mbox_chann; 1022 struct amdxdna_dev *xdna = hwctx->client->xdna; 1023 struct amdxdna_gem_obj *cmd_abo = job->cmd_bo; 1024 void *cmd_buf = amdxdna_gem_vmap(cmdbuf_abo); 1025 struct xdna_mailbox_msg msg; 1026 union exec_chain_req req; 1027 u32 op = ERT_INVALID_CMD; 1028 size_t size; 1029 int ret; 1030 1031 if (!cmd_buf) 1032 return -ENOMEM; 1033 1034 size = cmdbuf_abo->mem.size; 1035 ret = aie2_cmdlist_fill_slot(cmd_buf, cmd_abo, &size, &op); 1036 if (ret) 1037 return ret; 1038 1039 print_hex_dump_debug("cmdbuf: ", DUMP_PREFIX_OFFSET, 16, 4, cmd_buf, size, false); 1040 1041 msg.opcode = EXEC_MSG_OPS(xdna)->get_chain_msg_op(op); 1042 if (msg.opcode == MSG_OP_MAX_OPCODE) 1043 return -EOPNOTSUPP; 1044 1045 EXEC_MSG_OPS(xdna)->init_chain_req(&req, amdxdna_gem_dev_addr(cmdbuf_abo), size, 1); 1046 drm_clflush_virt_range(cmd_buf, size); 1047 1048 msg.handle = job; 1049 msg.notify_cb = notify_cb; 1050 msg.send_data = (u8 *)&req; 1051 msg.send_size = sizeof(req); 1052 print_hex_dump_debug("cmdlist msg: ", DUMP_PREFIX_OFFSET, 16, 4, 1053 &req, msg.send_size, false); 1054 ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT); 1055 if (ret) { 1056 XDNA_ERR(hwctx->client->xdna, "Send message failed"); 1057 return ret; 1058 } 1059 1060 return 0; 1061 } 1062 1063 int aie2_sync_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, 1064 int (*notify_cb)(void *, void __iomem *, size_t)) 1065 { 1066 struct mailbox_channel *chann = hwctx->priv->mbox_chann; 1067 struct amdxdna_gem_obj *abo = to_xdna_obj(job->bos[0]); 1068 struct amdxdna_dev *xdna = hwctx->client->xdna; 1069 struct xdna_mailbox_msg msg; 1070 struct sync_bo_req req; 1071 int ret = 0; 1072 1073 req.src_addr = 0; 1074 req.dst_addr = amdxdna_dev_bo_offset(abo); 1075 req.size = abo->mem.size; 1076 1077 /* Device to Host */ 1078 req.type = FIELD_PREP(AIE2_MSG_SYNC_BO_SRC_TYPE, SYNC_BO_DEV_MEM) | 1079 FIELD_PREP(AIE2_MSG_SYNC_BO_DST_TYPE, SYNC_BO_HOST_MEM); 1080 1081 XDNA_DBG(xdna, "sync %d bytes src(0x%llx) to dst(0x%llx) completed", 1082 req.size, req.src_addr, req.dst_addr); 1083 1084 msg.handle = job; 1085 msg.notify_cb = notify_cb; 1086 msg.send_data = (u8 *)&req; 1087 msg.send_size = sizeof(req); 1088 msg.opcode = MSG_OP_SYNC_BO; 1089 1090 ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT); 1091 if (ret) { 1092 XDNA_ERR(xdna, "Send message failed"); 1093 return ret; 1094 } 1095 1096 return 0; 1097 } 1098 1099 int aie2_config_debug_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, 1100 int (*notify_cb)(void *, void __iomem *, size_t)) 1101 { 1102 struct mailbox_channel *chann = hwctx->priv->mbox_chann; 1103 struct amdxdna_gem_obj *abo = to_xdna_obj(job->bos[0]); 1104 struct amdxdna_dev *xdna = hwctx->client->xdna; 1105 struct config_debug_bo_req req; 1106 struct xdna_mailbox_msg msg; 1107 1108 if (job->drv_cmd->opcode == ATTACH_DEBUG_BO) 1109 req.config = DEBUG_BO_REGISTER; 1110 else 1111 req.config = DEBUG_BO_UNREGISTER; 1112 1113 req.offset = amdxdna_dev_bo_offset(abo); 1114 req.size = abo->mem.size; 1115 1116 XDNA_DBG(xdna, "offset 0x%llx size 0x%llx config %d", 1117 req.offset, req.size, req.config); 1118 1119 msg.handle = job; 1120 msg.notify_cb = notify_cb; 1121 msg.send_data = (u8 *)&req; 1122 msg.send_size = sizeof(req); 1123 msg.opcode = MSG_OP_CONFIG_DEBUG_BO; 1124 1125 return xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT); 1126 } 1127 1128 int aie2_query_app_health(struct amdxdna_dev_hdl *ndev, u32 context_id, 1129 struct app_health_report *report) 1130 { 1131 DECLARE_AIE_MSG(get_app_health, MSG_OP_GET_APP_HEALTH); 1132 struct amdxdna_dev *xdna = ndev->aie.xdna; 1133 struct app_health_report *buf; 1134 dma_addr_t dma_addr; 1135 u32 buf_size; 1136 int ret; 1137 1138 if (!AIE_FEATURE_ON(&ndev->aie, AIE2_APP_HEALTH)) { 1139 XDNA_DBG(xdna, "App health feature not supported"); 1140 return -EOPNOTSUPP; 1141 } 1142 1143 buf_size = sizeof(*report); 1144 buf = amdxdna_alloc_msg_buffer(xdna, &buf_size, &dma_addr); 1145 if (IS_ERR(buf)) { 1146 XDNA_ERR(xdna, "Failed to allocate buffer for app health"); 1147 return PTR_ERR(buf); 1148 } 1149 1150 req.buf_addr = dma_addr; 1151 req.context_id = context_id; 1152 req.buf_size = buf_size; 1153 1154 drm_clflush_virt_range(buf, req.buf_size); 1155 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 1156 if (ret) { 1157 XDNA_ERR(xdna, "Get app health failed, ret %d status 0x%x", ret, resp.status); 1158 goto free_buf; 1159 } 1160 1161 /* Copy the report to caller's buffer */ 1162 memcpy(report, buf, sizeof(*report)); 1163 1164 free_buf: 1165 amdxdna_free_msg_buffer(xdna, buf_size, buf, dma_addr); 1166 return ret; 1167 } 1168 1169 static int 1170 aie2_runtime_update_ctx_prop(struct amdxdna_dev_hdl *ndev, 1171 struct amdxdna_hwctx *ctx, u32 type, u32 value) 1172 { 1173 DECLARE_AIE_MSG(update_property, MSG_OP_UPDATE_PROPERTY); 1174 struct amdxdna_dev *xdna = ndev->aie.xdna; 1175 int ret; 1176 1177 if (!AIE_FEATURE_ON(&ndev->aie, AIE2_UPDATE_PROPERTY)) 1178 return -EOPNOTSUPP; 1179 1180 if (ctx) 1181 req.context_id = ctx->fw_ctx_id; 1182 else 1183 req.context_id = AIE2_UPDATE_PROPERTY_ALL_CTX; 1184 1185 req.time_quota_us = value; 1186 req.type = type; 1187 1188 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 1189 if (ret) { 1190 XDNA_ERR(xdna, "%s update property failed, type %d ret %d", 1191 ctx ? ctx->name : "ctx.all", type, ret); 1192 return ret; 1193 } 1194 1195 return 0; 1196 } 1197 1198 int aie2_update_prop_time_quota(struct amdxdna_dev_hdl *ndev, u32 us) 1199 { 1200 struct amdxdna_dev *xdna = ndev->aie.xdna; 1201 int ret; 1202 1203 ret = aie2_runtime_update_ctx_prop(ndev, NULL, UPDATE_PROPERTY_TIME_QUOTA, us); 1204 if (ret == -EOPNOTSUPP) { 1205 XDNA_DBG(xdna, "update time quota not support, skipped"); 1206 ret = 0; 1207 } else if (!ret) { 1208 XDNA_DBG(xdna, "Ctx exec time quantum updated to %u us", us); 1209 } 1210 return ret; 1211 } 1212 1213 int aie2_get_dev_revision(struct amdxdna_dev_hdl *ndev, enum aie2_dev_revision *rev) 1214 { 1215 DECLARE_AIE_MSG(get_dev_revision, MSG_OP_GET_DEV_REVISION); 1216 struct amdxdna_dev *xdna = ndev->aie.xdna; 1217 int ret; 1218 1219 if (!AIE_FEATURE_ON(&ndev->aie, AIE2_GET_DEV_REVISION)) 1220 return -EOPNOTSUPP; 1221 1222 ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); 1223 if (ret) 1224 return ret; 1225 1226 *rev = resp.rev; 1227 1228 if (*rev < AIE2_DEV_REVISION_STXA || *rev >= AIE2_DEV_REVISION_UNKN) { 1229 XDNA_ERR(xdna, "Unknown device revision: %d (raw fuse: 0x%x)", 1230 *rev, resp.raw_fuse_data); 1231 return -EINVAL; 1232 } 1233 1234 XDNA_DBG(xdna, "Device revision: %d (raw fuse: 0x%x)", *rev, resp.raw_fuse_data); 1235 return 0; 1236 } 1237