summaryrefslogtreecommitdiff
path: root/drivers/accel/amdxdna/aie2_message.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/accel/amdxdna/aie2_message.c')
-rw-r--r--drivers/accel/amdxdna/aie2_message.c128
1 files changed, 88 insertions, 40 deletions
diff --git a/drivers/accel/amdxdna/aie2_message.c b/drivers/accel/amdxdna/aie2_message.c
index d493bb1c3360..7d7dcfeaf794 100644
--- a/drivers/accel/amdxdna/aie2_message.c
+++ b/drivers/accel/amdxdna/aie2_message.c
@@ -39,7 +39,6 @@ static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev,
if (!ndev->mgmt_chann)
return -ENODEV;
- drm_WARN_ON(&xdna->ddev, xdna->rpm_on && !mutex_is_locked(&xdna->dev_lock));
ret = xdna_send_msg_wait(xdna, ndev->mgmt_chann, msg);
if (ret == -ETIME) {
xdna_mailbox_stop_channel(ndev->mgmt_chann);
@@ -56,11 +55,34 @@ static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev,
return ret;
}
+void *aie2_alloc_msg_buffer(struct amdxdna_dev_hdl *ndev, u32 *size,
+ dma_addr_t *dma_addr)
+{
+ struct amdxdna_dev *xdna = ndev->xdna;
+ int order;
+
+ *size = max(*size, SZ_8K);
+ order = get_order(*size);
+ if (order > MAX_PAGE_ORDER)
+ return NULL;
+ *size = PAGE_SIZE << order;
+
+ return dma_alloc_noncoherent(xdna->ddev.dev, *size, dma_addr,
+ DMA_FROM_DEVICE, GFP_KERNEL);
+}
+
int aie2_suspend_fw(struct amdxdna_dev_hdl *ndev)
{
DECLARE_AIE2_MSG(suspend, MSG_OP_SUSPEND);
+ int ret;
- return aie2_send_mgmt_msg_wait(ndev, &msg);
+ ret = aie2_send_mgmt_msg_wait(ndev, &msg);
+ if (ret) {
+ XDNA_ERR(ndev->xdna, "Failed to suspend fw, ret %d", ret);
+ return ret;
+ }
+
+ return aie2_psp_waitmode_poll(ndev->psp_hdl);
}
int aie2_resume_fw(struct amdxdna_dev_hdl *ndev)
@@ -186,6 +208,40 @@ int aie2_query_firmware_version(struct amdxdna_dev_hdl *ndev,
return 0;
}
+static int aie2_destroy_context_req(struct amdxdna_dev_hdl *ndev, u32 id)
+{
+ DECLARE_AIE2_MSG(destroy_ctx, MSG_OP_DESTROY_CONTEXT);
+ struct amdxdna_dev *xdna = ndev->xdna;
+ int ret;
+
+ req.context_id = id;
+ ret = aie2_send_mgmt_msg_wait(ndev, &msg);
+ if (ret)
+ XDNA_WARN(xdna, "Destroy context failed, ret %d", ret);
+
+ return ret;
+}
+
+static u32 aie2_get_context_priority(struct amdxdna_dev_hdl *ndev,
+ struct amdxdna_hwctx *hwctx)
+{
+ if (!AIE2_FEATURE_ON(ndev, AIE2_PREEMPT))
+ return PRIORITY_HIGH;
+
+ switch (hwctx->qos.priority) {
+ case AMDXDNA_QOS_REALTIME_PRIORITY:
+ return PRIORITY_REALTIME;
+ case AMDXDNA_QOS_HIGH_PRIORITY:
+ return PRIORITY_HIGH;
+ case AMDXDNA_QOS_NORMAL_PRIORITY:
+ return PRIORITY_NORMAL;
+ case AMDXDNA_QOS_LOW_PRIORITY:
+ return PRIORITY_LOW;
+ default:
+ return PRIORITY_HIGH;
+ }
+}
+
int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx)
{
DECLARE_AIE2_MSG(create_ctx, MSG_OP_CREATE_CONTEXT);
@@ -199,22 +255,24 @@ int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwct
req.aie_type = 1;
req.start_col = hwctx->start_col;
req.num_col = hwctx->num_col;
+ req.num_unused_col = hwctx->num_unused_col;
req.num_cq_pairs_requested = 1;
req.pasid = hwctx->client->pasid;
- req.context_priority = 2;
+ req.context_priority = aie2_get_context_priority(ndev, hwctx);
ret = aie2_send_mgmt_msg_wait(ndev, &msg);
if (ret)
return ret;
hwctx->fw_ctx_id = resp.context_id;
- WARN_ONCE(hwctx->fw_ctx_id == -1, "Unexpected context id");
+ if (WARN_ON_ONCE(hwctx->fw_ctx_id == -1))
+ return -EINVAL;
if (ndev->force_preempt_enabled) {
ret = aie2_runtime_cfg(ndev, AIE2_RT_CFG_FORCE_PREEMPT, &hwctx->fw_ctx_id);
if (ret) {
XDNA_ERR(xdna, "failed to enable force preempt %d", ret);
- return ret;
+ goto del_ctx_req;
}
}
@@ -231,51 +289,39 @@ int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwct
ret = pci_irq_vector(to_pci_dev(xdna->ddev.dev), resp.msix_id);
if (ret == -EINVAL) {
- XDNA_ERR(xdna, "not able to create channel");
- goto out_destroy_context;
+ XDNA_ERR(xdna, "Alloc IRQ failed %d", ret);
+ goto del_ctx_req;
}
intr_reg = i2x.mb_head_ptr_reg + 4;
hwctx->priv->mbox_chann = xdna_mailbox_create_channel(ndev->mbox, &x2i, &i2x,
intr_reg, ret);
if (!hwctx->priv->mbox_chann) {
- XDNA_ERR(xdna, "not able to create channel");
+ XDNA_ERR(xdna, "Not able to create channel");
ret = -EINVAL;
- goto out_destroy_context;
+ goto del_ctx_req;
}
ndev->hwctx_num++;
- XDNA_DBG(xdna, "%s mailbox channel irq: %d, msix_id: %d",
- hwctx->name, ret, resp.msix_id);
- XDNA_DBG(xdna, "%s created fw ctx %d pasid %d", hwctx->name,
- hwctx->fw_ctx_id, hwctx->client->pasid);
+ XDNA_DBG(xdna, "Mailbox channel irq: %d, msix_id: %d", ret, resp.msix_id);
+ XDNA_DBG(xdna, "Created fw ctx %d pasid %d", hwctx->fw_ctx_id, hwctx->client->pasid);
return 0;
-out_destroy_context:
- aie2_destroy_context(ndev, hwctx);
+del_ctx_req:
+ aie2_destroy_context_req(ndev, hwctx->fw_ctx_id);
return ret;
}
int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx)
{
- DECLARE_AIE2_MSG(destroy_ctx, MSG_OP_DESTROY_CONTEXT);
struct amdxdna_dev *xdna = ndev->xdna;
int ret;
- if (hwctx->fw_ctx_id == -1)
- return 0;
-
xdna_mailbox_stop_channel(hwctx->priv->mbox_chann);
-
- req.context_id = hwctx->fw_ctx_id;
- ret = aie2_send_mgmt_msg_wait(ndev, &msg);
- if (ret)
- XDNA_WARN(xdna, "%s destroy context failed, ret %d", hwctx->name, ret);
-
+ ret = aie2_destroy_context_req(ndev, hwctx->fw_ctx_id);
xdna_mailbox_destroy_channel(hwctx->priv->mbox_chann);
- XDNA_DBG(xdna, "%s destroyed fw ctx %d", hwctx->name,
- hwctx->fw_ctx_id);
+ XDNA_DBG(xdna, "Destroyed fw ctx %d", hwctx->fw_ctx_id);
hwctx->priv->mbox_chann = NULL;
hwctx->fw_ctx_id = -1;
ndev->hwctx_num--;
@@ -316,14 +362,13 @@ int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf,
{
DECLARE_AIE2_MSG(aie_column_info, MSG_OP_QUERY_COL_STATUS);
struct amdxdna_dev *xdna = ndev->xdna;
+ u32 buf_sz = size, aie_bitmap = 0;
struct amdxdna_client *client;
dma_addr_t dma_addr;
- u32 aie_bitmap = 0;
u8 *buff_addr;
int ret;
- buff_addr = dma_alloc_noncoherent(xdna->ddev.dev, size, &dma_addr,
- DMA_FROM_DEVICE, GFP_KERNEL);
+ buff_addr = aie2_alloc_msg_buffer(ndev, &buf_sz, &dma_addr);
if (!buff_addr)
return -ENOMEM;
@@ -333,7 +378,7 @@ int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf,
*cols_filled = 0;
req.dump_buff_addr = dma_addr;
- req.dump_buff_size = size;
+ req.dump_buff_size = buf_sz;
req.num_cols = hweight32(aie_bitmap);
req.aie_bitmap = aie_bitmap;
@@ -361,7 +406,7 @@ int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf,
*cols_filled = aie_bitmap;
fail:
- dma_free_noncoherent(xdna->ddev.dev, size, buff_addr, dma_addr, DMA_FROM_DEVICE);
+ aie2_free_msg_buffer(ndev, buf_sz, buff_addr, dma_addr);
return ret;
}
@@ -372,19 +417,19 @@ int aie2_query_telemetry(struct amdxdna_dev_hdl *ndev,
DECLARE_AIE2_MSG(get_telemetry, MSG_OP_GET_TELEMETRY);
struct amdxdna_dev *xdna = ndev->xdna;
dma_addr_t dma_addr;
+ u32 buf_sz = size;
u8 *addr;
int ret;
if (header->type >= MAX_TELEMETRY_TYPE)
return -EINVAL;
- addr = dma_alloc_noncoherent(xdna->ddev.dev, size, &dma_addr,
- DMA_FROM_DEVICE, GFP_KERNEL);
+ addr = aie2_alloc_msg_buffer(ndev, &buf_sz, &dma_addr);
if (!addr)
return -ENOMEM;
req.buf_addr = dma_addr;
- req.buf_size = size;
+ req.buf_size = buf_sz;
req.type = header->type;
drm_clflush_virt_range(addr, size); /* device can access */
@@ -410,7 +455,7 @@ int aie2_query_telemetry(struct amdxdna_dev_hdl *ndev,
header->minor = resp.minor;
free_buf:
- dma_free_noncoherent(xdna->ddev.dev, size, addr, dma_addr, DMA_FROM_DEVICE);
+ aie2_free_msg_buffer(ndev, buf_sz, addr, dma_addr);
return ret;
}
@@ -448,6 +493,9 @@ int aie2_config_cu(struct amdxdna_hwctx *hwctx,
if (!chann)
return -ENODEV;
+ if (!hwctx->cus)
+ return 0;
+
if (hwctx->cus->num_cus > MAX_NUM_CUS) {
XDNA_DBG(xdna, "Exceed maximum CU %d", MAX_NUM_CUS);
return -EINVAL;
@@ -646,6 +694,7 @@ aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *siz
u32 cmd_len;
void *cmd;
+ memset(npu_slot, 0, sizeof(*npu_slot));
cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
if (*size < sizeof(*npu_slot) + cmd_len)
return -EINVAL;
@@ -654,7 +703,6 @@ aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *siz
if (npu_slot->cu_idx == INVALID_CU_IDX)
return -EINVAL;
- memset(npu_slot, 0, sizeof(*npu_slot));
npu_slot->type = EXEC_NPU_TYPE_NON_ELF;
npu_slot->arg_cnt = cmd_len / sizeof(u32);
memcpy(npu_slot->args, cmd, cmd_len);
@@ -671,6 +719,7 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
u32 cmd_len;
u32 arg_sz;
+ memset(npu_slot, 0, sizeof(*npu_slot));
sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
arg_sz = cmd_len - sizeof(*sn);
if (cmd_len < sizeof(*sn) || arg_sz > MAX_NPU_ARGS_SIZE)
@@ -683,7 +732,6 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
if (npu_slot->cu_idx == INVALID_CU_IDX)
return -EINVAL;
- memset(npu_slot, 0, sizeof(*npu_slot));
npu_slot->type = EXEC_NPU_TYPE_PARTIAL_ELF;
npu_slot->inst_buf_addr = sn->buffer;
npu_slot->inst_size = sn->buffer_size;
@@ -703,6 +751,7 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t
u32 cmd_len;
u32 arg_sz;
+ memset(npu_slot, 0, sizeof(*npu_slot));
pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
arg_sz = cmd_len - sizeof(*pd);
if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
@@ -715,7 +764,6 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t
if (npu_slot->cu_idx == INVALID_CU_IDX)
return -EINVAL;
- memset(npu_slot, 0, sizeof(*npu_slot));
npu_slot->type = EXEC_NPU_TYPE_PREEMPT;
npu_slot->inst_buf_addr = pd->inst_buf;
npu_slot->save_buf_addr = pd->save_buf;
@@ -739,6 +787,7 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
u32 cmd_len;
u32 arg_sz;
+ memset(npu_slot, 0, sizeof(*npu_slot));
pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
arg_sz = cmd_len - sizeof(*pd);
if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
@@ -747,7 +796,6 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si
if (*size < sizeof(*npu_slot) + arg_sz)
return -EINVAL;
- memset(npu_slot, 0, sizeof(*npu_slot));
npu_slot->type = EXEC_NPU_TYPE_ELF;
npu_slot->inst_buf_addr = pd->inst_buf;
npu_slot->save_buf_addr = pd->save_buf;