Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 107 additions & 33 deletions drivers/accel/amdxdna/aie2_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,86 @@ static void aie2_hwctx_stop(struct amdxdna_dev *xdna, struct amdxdna_hwctx *hwct
#endif
}

static void aie2_hwctx_release_heap(struct amdxdna_hwctx *hwctx)
{
struct amdxdna_client *client = hwctx->client;
struct amdxdna_hwctx_priv *priv = hwctx->priv;
struct amdxdna_gem_obj *chunk;

if (!priv->last_heap_chunk_added)
return;

drm_WARN_ON(&client->xdna->ddev, !mutex_is_locked(&client->mm_lock));
list_for_each_entry(chunk, &client->dev_heap_chunks, heap_chunk_node) {
amdxdna_gem_unpin(chunk);
drm_gem_object_put(to_gobj(chunk));
if (chunk == priv->last_heap_chunk_added)
break;
}
priv->last_heap_chunk_added = NULL;
}

static int aie2_hwctx_map_heap(struct amdxdna_hwctx *hwctx, bool map_all)
{
struct amdxdna_client *client = hwctx->client;
struct amdxdna_dev *xdna = client->xdna;
struct amdxdna_gem_obj *last = hwctx->priv->last_heap_chunk_added;
struct amdxdna_gem_obj *chunk;
bool need_ref = !last;
u64 offset = 0;
u64 addr;
int ret;

drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&client->mm_lock));

list_for_each_entry(chunk, &client->dev_heap_chunks, heap_chunk_node) {
if (!need_ref && chunk == list_next_entry(last, heap_chunk_node))
need_ref = true;

if (need_ref) {
ret = amdxdna_gem_pin(chunk);
if (ret) {
XDNA_ERR(xdna, "Pin chunk for hwctx %d failed, ret %d",
hwctx->fw_ctx_id, ret);
return ret;
}
drm_gem_object_get(to_gobj(chunk));
}

if (map_all || need_ref) {
addr = amdxdna_obj_dma_addr(chunk);

if (!offset)
ret = aie2_map_host_buf(xdna->dev_handle,
hwctx->fw_ctx_id,
addr, chunk->mem.size);
else
ret = aie2_add_host_buf(xdna->dev_handle,
hwctx->fw_ctx_id,
addr, chunk->mem.size);
if (ret) {
XDNA_ERR(xdna,
"Notify FW hwctx %d chunk offset 0x%llx failed, ret %d",
hwctx->fw_ctx_id, offset, ret);
if (need_ref) {
amdxdna_gem_unpin(chunk);
drm_gem_object_put(to_gobj(chunk));
}
return ret;
}
}

offset += chunk->mem.size;
hwctx->priv->last_heap_chunk_added = chunk;
}

return 0;
}

static int aie2_hwctx_restart(struct amdxdna_dev *xdna, struct amdxdna_hwctx *hwctx)
{
struct amdxdna_gem_obj *heap = hwctx->priv->heap;
struct amdxdna_client *client = hwctx->client;
int ret;

ret = aie2_create_context(xdna->dev_handle, hwctx);
Expand All @@ -112,9 +189,9 @@ static int aie2_hwctx_restart(struct amdxdna_dev *xdna, struct amdxdna_hwctx *hw
goto out;
}

ret = aie2_map_host_buf(xdna->dev_handle, hwctx->fw_ctx_id,
amdxdna_obj_dma_addr(heap),
heap->mem.size);
mutex_lock(&client->mm_lock);
ret = aie2_hwctx_map_heap(hwctx, true);
mutex_unlock(&client->mm_lock);
if (ret) {
XDNA_ERR(xdna, "Map host buf failed, ret %d", ret);
goto out;
Expand Down Expand Up @@ -690,33 +767,15 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)
#endif
struct drm_gpu_scheduler *sched;
struct amdxdna_hwctx_priv *priv;
struct amdxdna_gem_obj *heap;
int i, ret;

priv = kzalloc_obj(*hwctx->priv);
if (!priv)
return -ENOMEM;
hwctx->priv = priv;

mutex_lock(&client->mm_lock);
heap = client->dev_heap;
if (!heap) {
XDNA_ERR(xdna, "The client dev heap object not exist");
mutex_unlock(&client->mm_lock);
ret = -ENOENT;
goto free_priv;
}
drm_gem_object_get(to_gobj(heap));
mutex_unlock(&client->mm_lock);
priv->heap = heap;
sema_init(&priv->job_sem, HWCTX_MAX_CMDS);

ret = amdxdna_gem_pin(heap);
if (ret) {
XDNA_ERR(xdna, "Dev heap pin failed, ret %d", ret);
goto put_heap;
}

for (i = 0; i < ARRAY_SIZE(priv->cmd_buf); i++) {
struct amdxdna_gem_obj *abo;
struct amdxdna_drm_create_bo args = {
Expand Down Expand Up @@ -778,18 +837,25 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)
goto suspend_put;
}

ret = aie2_map_host_buf(xdna->dev_handle, hwctx->fw_ctx_id,
amdxdna_obj_dma_addr(heap),
heap->mem.size);
mutex_lock(&client->mm_lock);
if (list_empty(&client->dev_heap_chunks)) {
XDNA_ERR(xdna, "The client dev heap doesn't exist");
mutex_unlock(&client->mm_lock);
ret = -ENOENT;
goto release_resource;
}

ret = aie2_hwctx_map_heap(hwctx, true);
mutex_unlock(&client->mm_lock);
if (ret) {
XDNA_ERR(xdna, "Map host buffer failed, ret %d", ret);
goto release_resource;
goto release_heap_chunks;
}

ret = aie2_ctx_syncobj_create(hwctx);
if (ret) {
XDNA_ERR(xdna, "Create syncobj failed, ret %d", ret);
goto release_resource;
goto release_heap_chunks;
}
amdxdna_pm_suspend_put(xdna);

Expand All @@ -799,6 +865,10 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)

return 0;

release_heap_chunks:
mutex_lock(&client->mm_lock);
aie2_hwctx_release_heap(hwctx);
mutex_unlock(&client->mm_lock);
release_resource:
aie2_release_resource(hwctx);
suspend_put:
Expand All @@ -815,10 +885,7 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)
continue;
drm_gem_object_put(to_gobj(priv->cmd_buf[i]));
}
amdxdna_gem_unpin(heap);
put_heap:
drm_gem_object_put(to_gobj(heap));
free_priv:

kfree(priv);
return ret;
}
Expand Down Expand Up @@ -858,8 +925,10 @@ void aie2_hwctx_fini(struct amdxdna_hwctx *hwctx)

for (idx = 0; idx < ARRAY_SIZE(hwctx->priv->cmd_buf); idx++)
drm_gem_object_put(to_gobj(hwctx->priv->cmd_buf[idx]));
amdxdna_gem_unpin(hwctx->priv->heap);
drm_gem_object_put(to_gobj(hwctx->priv->heap));

mutex_lock(&hwctx->client->mm_lock);
aie2_hwctx_release_heap(hwctx);
mutex_unlock(&hwctx->client->mm_lock);

mutex_destroy(&hwctx->priv->io_lock);
kfree(hwctx->col_list);
Expand Down Expand Up @@ -1211,6 +1280,11 @@ int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
return ret;
}

int aie2_hwctx_heap_change(struct amdxdna_hwctx *hwctx)
{
return aie2_hwctx_map_heap(hwctx, false);
}

void aie2_hmm_invalidate(struct amdxdna_gem_obj *abo,
unsigned long cur_seq)
{
Expand Down
52 changes: 41 additions & 11 deletions drivers/accel/amdxdna/aie2_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,25 +336,56 @@ int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwc
return ret;
}

int aie2_map_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u64 size)
static int aie2_send_host_buf_msgs(struct amdxdna_dev_hdl *ndev, u32 context_id,
u64 addr, u64 size, u32 initial_opcode)
{
DECLARE_AIE_MSG(map_host_buffer, MSG_OP_MAP_HOST_BUFFER);
struct amdxdna_dev *xdna = ndev->aie.xdna;
size_t chunk_size;
int ret;

req.context_id = context_id;
req.buf_addr = addr;
req.buf_size = size;
ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg);
if (ret)
return ret;
chunk_size = xdna->dev_info->dev_mem_size;
if (!size || !IS_ALIGNED(size, chunk_size)) {
XDNA_ERR(xdna, "Invalid size 0x%llx for chunk 0x%lx",
size, chunk_size);
return -EINVAL;
}

msg.opcode = initial_opcode;
do {
req.context_id = context_id;
req.buf_addr = addr;
req.buf_size = chunk_size;
ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg);
if (ret) {
XDNA_ERR(xdna, "fw ctx %d addr 0x%llx size 0x%lx",
context_id, addr, chunk_size);
return ret;
}

XDNA_DBG(xdna, "fw ctx %d host buf op 0x%x addr 0x%llx size 0x%lx",
context_id, msg.opcode, addr, chunk_size);

XDNA_DBG(xdna, "fw ctx %d map host buf addr 0x%llx size 0x%llx",
context_id, addr, size);
addr += chunk_size;
size -= chunk_size;
msg.opcode = MSG_OP_ADD_HOST_BUFFER;
} while (size);

return 0;
}

int aie2_map_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u64 size)
{
return aie2_send_host_buf_msgs(ndev, context_id, addr, size,
MSG_OP_MAP_HOST_BUFFER);
}

int aie2_add_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u64 size)
{
return aie2_send_host_buf_msgs(ndev, context_id, addr, size,
MSG_OP_ADD_HOST_BUFFER);
}

static int amdxdna_hwctx_col_map(struct amdxdna_hwctx *hwctx, void *arg)
{
u32 *bitmap = arg;
Expand Down Expand Up @@ -1028,7 +1059,6 @@ int aie2_cmdlist_multi_execbuf(struct amdxdna_hwctx *hwctx,
if (msg.opcode == MSG_OP_MAX_OPCODE)
return -EOPNOTSUPP;

/* The offset is the accumulated total size of the cmd buffer */
EXEC_MSG_OPS(xdna)->init_chain_req(&req, amdxdna_gem_dev_addr(cmdbuf_abo),
offset, ccnt);
drm_clflush_virt_range(cmd_buf, offset);
Expand Down Expand Up @@ -1088,7 +1118,7 @@ int aie2_cmdlist_single_execbuf(struct amdxdna_hwctx *hwctx,
&req, msg.send_size, false);
ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
if (ret) {
XDNA_ERR(hwctx->client->xdna, "Send message failed");
XDNA_ERR(xdna, "Send message failed");
return ret;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/accel/amdxdna/aie2_msg_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ enum aie2_msg_opcode {
MSG_OP_REGISTER_ASYNC_EVENT_MSG = 0x10C,
MSG_OP_UPDATE_PROPERTY = 0x113,
MSG_OP_GET_APP_HEALTH = 0x114,
MSG_OP_ADD_HOST_BUFFER = 0x115,
MSG_OP_GET_DEV_REVISION = 0x117,
MSG_OP_MAX_DRV_OPCODE,
MSG_OP_GET_PROTOCOL_VERSION = 0x301,
Expand Down
1 change: 1 addition & 0 deletions drivers/accel/amdxdna/aie2_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1303,4 +1303,5 @@ const struct amdxdna_dev_ops aie2_ops = {
.hmm_invalidate = aie2_hmm_invalidate,
.get_array = aie2_get_array,
.get_dev_revision = aie2_get_dev_rev,
.hwctx_heap_change = aie2_hwctx_heap_change,
};
10 changes: 7 additions & 3 deletions drivers/accel/amdxdna/aie2_pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
#include "amdxdna_mailbox.h"

/* Firmware determines device memory base address and size */
#define AIE2_DEVM_BASE 0x4000000
#define AIE2_DEVM_SIZE SZ_64M
#define AIE2_DEVM_BASE 0x4000000
#define AIE2_DEVM_SIZE SZ_64M
#define AIE2_DEVM_MAX_SIZE SZ_512M

#define NDEV2PDEV(ndev) (to_pci_dev((ndev)->aie.xdna->ddev.dev))

Expand Down Expand Up @@ -129,7 +130,7 @@ struct dpm_clk_freq {
#define HWCTX_MAX_CMDS 4
#define get_job_idx(seq) ((seq) & (HWCTX_MAX_CMDS - 1))
struct amdxdna_hwctx_priv {
struct amdxdna_gem_obj *heap;
struct amdxdna_gem_obj *last_heap_chunk_added;
void *mbox_chann;

struct drm_gpu_scheduler sched;
Expand Down Expand Up @@ -234,6 +235,7 @@ enum aie2_fw_feature {
AIE2_PREEMPT,
AIE2_TEMPORAL_ONLY,
AIE2_APP_HEALTH,
AIE2_ADD_HOST_BUFFER,
AIE2_UPDATE_PROPERTY,
AIE2_GET_DEV_REVISION,
AIE2_FEATURE_MAX
Expand Down Expand Up @@ -304,6 +306,7 @@ int aie2_get_dev_revision(struct amdxdna_dev_hdl *ndev, enum aie2_dev_revision *
int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx);
int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx);
int aie2_map_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u64 size);
int aie2_add_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u64 size);
int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf, u32 size, u32 *cols_filled);
int aie2_query_telemetry(struct amdxdna_dev_hdl *ndev,
char __user *buf, u32 size,
Expand Down Expand Up @@ -338,6 +341,7 @@ int aie2_hwctx_sync_debug_bo(struct amdxdna_hwctx *hwctx, u32 debug_bo_hdl);
void aie2_hwctx_suspend(struct amdxdna_client *client);
int aie2_hwctx_resume(struct amdxdna_client *client);
int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job, u64 *seq);
int aie2_hwctx_heap_change(struct amdxdna_hwctx *hwctx);
void aie2_hmm_invalidate(struct amdxdna_gem_obj *abo, unsigned long cur_seq);

/* TDR APIs */
Expand Down
Loading