Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Main test pr #234

Open
wants to merge 9 commits into
base: pr-test
Choose a base branch
from
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Test PR trigger

# AMD XDNA™️ Driver for Linux®️
This repository is for the AMD XDNA™️ Driver (amdxdna.ko) for Linux®️ and XRT SHIM library development.

Expand Down
10 changes: 5 additions & 5 deletions src/driver/amdxdna/aie2_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,8 @@ aie2_sched_notify(struct amdxdna_sched_job *job)
struct dma_fence *fence = job->fence;

job->hwctx->completed++;
trace_xdna_job(&job->base, job->hwctx->name, "signale fence", job->seq);
dma_fence_signal(fence);
trace_xdna_job(&job->base, job->hwctx->name, "signaled fence", job->seq);
dma_fence_put(fence);
mmput(job->mm);
amdxdna_job_put(job);
Expand Down Expand Up @@ -928,7 +928,7 @@ int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
job->out_fence = dma_fence_get(&job->base.s_fence->finished);

retry:
ret = drm_gem_lock_reservations(job->bos, job->bo_cnt, &acquire_ctx);
ret = amdxdna_lock_objects(job, &acquire_ctx);
if (ret) {
XDNA_WARN(xdna, "Failed to reverve fence, ret %d", ret);
goto put_fence;
Expand All @@ -937,7 +937,7 @@ int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
for (i = 0; i < job->bo_cnt; i++) {
abo = to_xdna_obj(job->bos[i]);
if (abo->mem.map_invalid) {
drm_gem_unlock_reservations(job->bos, job->bo_cnt, &acquire_ctx);
amdxdna_unlock_objects(job, &acquire_ctx);
if (!timeout) {
timeout = jiffies +
msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
Expand All @@ -955,14 +955,14 @@ int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
ret = dma_resv_reserve_fences(job->bos[i]->resv, 1);
if (ret) {
XDNA_WARN(xdna, "Failed to reserve fences %d", ret);
drm_gem_unlock_reservations(job->bos, job->bo_cnt, &acquire_ctx);
amdxdna_unlock_objects(job, &acquire_ctx);
goto put_fence;
}
}

for (i = 0; i < job->bo_cnt; i++)
dma_resv_add_fence(job->bos[i]->resv, job->out_fence, DMA_RESV_USAGE_WRITE);
drm_gem_unlock_reservations(job->bos, job->bo_cnt, &acquire_ctx);
amdxdna_unlock_objects(job, &acquire_ctx);

mutex_lock(&hwctx->priv->io_lock);
ret = aie2_hwctx_add_job(hwctx, job);
Expand Down
15 changes: 3 additions & 12 deletions src/driver/amdxdna/aie2_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,9 @@ int aie2_check_protocol_version(struct amdxdna_dev_hdl *ndev)
return ret;
}

if (resp.major != ndev->priv->protocol_major) {
XDNA_ERR(xdna, "Incompatible firmware protocol version major %d minor %d",
resp.major, resp.minor);
return -EINVAL;
}

/*
* Greater protocol minor version means new messages/status/emun are
* added into the firmware interface protocol.
*/
if (resp.minor < ndev->priv->protocol_minor) {
XDNA_ERR(xdna, "Firmware minor version smaller than supported");
ret = aie2_check_protocol(ndev, resp.major, resp.minor);
if (ret) {
XDNA_ERR(xdna, "Failed check protocol %d.%d", resp.major, resp.minor);
return -EINVAL;
}

Expand Down
84 changes: 75 additions & 9 deletions src/driver/amdxdna/aie2_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,16 @@ MODULE_PARM_DESC(aie2_max_col, "Maximum column could be used");
* The management mailbox channel is allocated by firmware.
* The related register and ring buffer information is on SRAM BAR.
* This struct is the register layout.
*
* Mgmt channel info query flow:
* 1. Poll alive pointer register until it is non zero
* 2. The alive pointer pointing to Mgmt Mbox Info on SRAM bar
* 4. Read x2i_* and i2x_*
* 3. If magic number MGMT_MBOX_MAGIC not presented, done;
* Otherwise, read msi_id, major, minor etc..
*/
#define MGMT_MBOX_MAGIC 0x55504e5f /* _NPU */
#define MAGIC_OFFSET offsetof(struct mgmt_mbox_chann_info, magic[0])
struct mgmt_mbox_chann_info {
u32 x2i_tail;
u32 x2i_head;
Expand All @@ -39,8 +48,45 @@ struct mgmt_mbox_chann_info {
u32 i2x_head;
u32 i2x_buf;
u32 i2x_buf_sz;
u32 magic;
u32 msi_id;
u32 prot_major;
u32 prot_minor;
u32 rsvd[4];
};

int aie2_check_protocol(struct amdxdna_dev_hdl *ndev, u32 fw_major, u32 fw_minor)
{
struct amdxdna_dev *xdna = ndev->xdna;

/*
* The driver supported mailbox behavior is defined by
* ndev->priv->protocol_major and protocol_minor.
*
* When major different, it means incompatible behavior.
* When only minor different, the greater minor means more opcode etc.
*
* Thus,
* 1. driver and fw major must be the same
* 2. driver minor must smaller than or equal to fw minor
*/
if (ndev->priv->protocol_major != fw_major) {
XDNA_ERR(xdna, "Incompatible firmware protocol major %d minor %d",
fw_major, fw_minor);
return -EINVAL;
}

/*
* Greater protocol minor version means new messages/status/emun are
* added into the firmware interface protocol.
*/
if (ndev->priv->protocol_minor > fw_minor) {
XDNA_ERR(xdna, "Firmware minor version smaller than supported");
return -EINVAL;
}
return 0;
}

static inline void aie2_dump_chann_info_debug(struct amdxdna_dev_hdl *ndev)
{
struct amdxdna_dev *xdna = ndev->xdna;
Expand All @@ -54,6 +100,11 @@ static inline void aie2_dump_chann_info_debug(struct amdxdna_dev_hdl *ndev)
XDNA_DBG(xdna, "x2i ringbuf 0x%x", ndev->mgmt_x2i.rb_start_addr);
XDNA_DBG(xdna, "x2i rsize 0x%x", ndev->mgmt_x2i.rb_size);
XDNA_DBG(xdna, "x2i chann index 0x%x", ndev->mgmt_chan_idx);
if (!ndev->mgmt_prot_major)
return;

XDNA_DBG(xdna, "mailbox protocol major 0x%x", ndev->mgmt_prot_major);
XDNA_DBG(xdna, "mailbox protocol minor 0x%x", ndev->mgmt_prot_minor);
}

static int aie2_get_mgmt_chann_info(struct amdxdna_dev_hdl *ndev)
Expand Down Expand Up @@ -96,14 +147,25 @@ static int aie2_get_mgmt_chann_info(struct amdxdna_dev_hdl *ndev)
x2i->mb_tail_ptr_reg = AIE2_MBOX_OFF(ndev, info_regs.x2i_tail);
x2i->rb_start_addr = AIE2_SRAM_OFF(ndev, info_regs.x2i_buf);
x2i->rb_size = info_regs.x2i_buf_sz;
ndev->mgmt_chan_idx = CHANN_INDEX(ndev, x2i->rb_start_addr);

if (info_regs.magic != MGMT_MBOX_MAGIC) {
ndev->mgmt_chan_idx = CHANN_INDEX(ndev, x2i->rb_start_addr);
goto done;
}

ndev->mgmt_chan_idx = info_regs.msi_id;
ndev->mgmt_prot_major = info_regs.prot_major;
ndev->mgmt_prot_minor = info_regs.prot_minor;
if (aie2_check_protocol(ndev, ndev->mgmt_prot_major, ndev->mgmt_prot_minor))
ret = -EINVAL;

done:
aie2_dump_chann_info_debug(ndev);

/* Must clear address at FW_ALIVE_OFF */
writel(0, SRAM_GET_ADDR(ndev, FW_ALIVE_OFF));

return 0;
return ret;
}

static int aie2_runtime_cfg(struct amdxdna_dev_hdl *ndev)
Expand Down Expand Up @@ -165,10 +227,12 @@ static int aie2_mgmt_fw_init(struct amdxdna_dev_hdl *ndev)
{
int ret;

ret = aie2_check_protocol_version(ndev);
if (ret) {
XDNA_ERR(ndev->xdna, "Check header hash failed");
return ret;
if (!ndev->mgmt_prot_major) {
ret = aie2_check_protocol_version(ndev);
if (ret) {
XDNA_ERR(ndev->xdna, "Check protocol version failed");
return ret;
}
}

ret = aie2_runtime_cfg(ndev);
Expand Down Expand Up @@ -297,8 +361,10 @@ static void aie2_hw_stop(struct amdxdna_dev *xdna)
xdna_mailbox_stop_channel(ndev->mgmt_chann);
xdna_mailbox_destroy_channel(ndev->mgmt_chann);
ndev->mgmt_chann = NULL;
xdna_mailbox_destroy(ndev->mbox);
ndev->mbox = NULL;
if (ndev->mbox) {
xdna_mailbox_destroy(ndev->mbox);
ndev->mbox = NULL;
}
aie2_psp_stop(ndev->psp_hdl);
aie2_smu_stop(ndev);
pci_clear_master(pdev);
Expand Down Expand Up @@ -334,7 +400,7 @@ static int aie2_hw_start(struct amdxdna_dev *xdna)

ret = aie2_get_mgmt_chann_info(ndev);
if (ret) {
XDNA_ERR(xdna, "firmware is not alive");
XDNA_ERR(xdna, "firmware mgmt info ret %d", ret);
goto stop_psp;
}

Expand Down
3 changes: 3 additions & 0 deletions src/driver/amdxdna/aie2_pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ struct amdxdna_dev_hdl {
struct xdna_mailbox_chann_res mgmt_x2i;
struct xdna_mailbox_chann_res mgmt_i2x;
u32 mgmt_chan_idx;
u32 mgmt_prot_major;
u32 mgmt_prot_minor;

u32 total_col;
u32 smu_curr_dpm_level;
Expand Down Expand Up @@ -279,6 +281,7 @@ struct amdxdna_dev_priv {

/* aie2_pci.c */
extern const struct amdxdna_dev_ops aie2_ops;
int aie2_check_protocol(struct amdxdna_dev_hdl *ndev, u32 fw_major, u32 fw_minor);

/* aie2_smu.c */
void aie2_smu_setup(struct amdxdna_dev_hdl *ndev);
Expand Down
75 changes: 73 additions & 2 deletions src/driver/amdxdna/amdxdna_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ amdxdna_arg_bos_lookup(struct amdxdna_client *client,
abo = to_xdna_obj(gobj);

mutex_lock(&abo->lock);
if (abo->pinned) {
if (abo->flags & BO_SUBMIT_PINNED) {
mutex_unlock(&abo->lock);
job->bos[i] = gobj;
continue;
Expand All @@ -345,7 +345,7 @@ amdxdna_arg_bos_lookup(struct amdxdna_client *client,
drm_gem_object_put(gobj);
goto put_arg_bos;
}
abo->pinned = true;
abo->flags |= BO_SUBMIT_PINNED;
mutex_unlock(&abo->lock);

job->bos[i] = gobj;
Expand Down Expand Up @@ -375,6 +375,77 @@ void amdxdna_job_put(struct amdxdna_sched_job *job)
kref_put(&job->refcnt, amdxdna_sched_job_release);
}

int amdxdna_lock_objects(struct amdxdna_sched_job *job, struct ww_acquire_ctx *ctx)
{
struct amdxdna_dev *xdna = job->hwctx->client->xdna;
struct amdxdna_gem_obj *abo;
int contended = -1, i, ret;

ww_acquire_init(ctx, &reservation_ww_class);

retry:
if (contended != -1) {
ret = dma_resv_lock_slow_interruptible(job->bos[contended]->resv, ctx);
if (ret) {
ww_acquire_fini(ctx);
return ret;
}
abo->flags |= BO_SUBMIT_LOCKED;
}

for (i = 0; i < job->bo_cnt; i++) {
abo = to_xdna_obj(job->bos[i]);
if (abo->flags & BO_SUBMIT_LOCKED)
continue;

ret = dma_resv_lock_interruptible(job->bos[i]->resv, ctx);
if (ret) {
int j;

for (j = 0; j < i; j++) {
abo = to_xdna_obj(job->bos[j]);
dma_resv_unlock(job->bos[j]->resv);
abo->flags &= ~BO_SUBMIT_LOCKED;
}

if (contended != -1 && contended >= i)
dma_resv_unlock(job->bos[contended]->resv);

if (ret == -EDEADLK) {
contended = i;
goto retry;
}

ww_acquire_fini(ctx);

XDNA_ERR(xdna, "Lock BO failed, ret %d", ret);
return ret;
}
abo->flags |= BO_SUBMIT_LOCKED;
}

ww_acquire_done(ctx);

return 0;
}

void amdxdna_unlock_objects(struct amdxdna_sched_job *job, struct ww_acquire_ctx *ctx)
{
struct amdxdna_gem_obj *abo;
int i;

for (i = 0; i < job->bo_cnt; i++) {
abo = to_xdna_obj(job->bos[i]);
if (!(abo->flags & BO_SUBMIT_LOCKED))
continue;

dma_resv_unlock(job->bos[i]->resv);
abo->flags &= ~BO_SUBMIT_LOCKED;
}

ww_acquire_fini(ctx);
}

int amdxdna_cmd_submit(struct amdxdna_client *client, u32 opcode,
u32 cmd_bo_hdl, u32 *arg_bo_hdls, u32 arg_bo_cnt,
u32 hwctx_hdl, u64 *seq)
Expand Down
2 changes: 2 additions & 0 deletions src/driver/amdxdna/amdxdna_ctx.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ void amdxdna_hwctx_remove_all(struct amdxdna_client *client);
void amdxdna_hwctx_suspend(struct amdxdna_client *client);
void amdxdna_hwctx_resume(struct amdxdna_client *client);

int amdxdna_lock_objects(struct amdxdna_sched_job *job, struct ww_acquire_ctx *ctx);
void amdxdna_unlock_objects(struct amdxdna_sched_job *job, struct ww_acquire_ctx *ctx);
int amdxdna_cmd_submit(struct amdxdna_client *client, u32 opcode,
u32 cmd_bo_hdls, u32 *arg_bo_hdls, u32 arg_bo_cnt,
u32 hwctx_hdl, u64 *seq);
Expand Down
3 changes: 3 additions & 0 deletions src/driver/amdxdna/amdxdna_devel.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ void amdxdna_bo_dma_unmap(struct amdxdna_gem_obj *abo)
struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev);

XDNA_DBG(xdna, "BO type %d dma_addr 0x%llx", abo->type, abo->mem.dma_addr);
if (is_import_bo(abo))
return;

drm_gem_shmem_put_pages(&abo->base);
}
#else
Expand Down
2 changes: 1 addition & 1 deletion src/driver/amdxdna/amdxdna_drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ const struct drm_driver amdxdna_drm_drv = {
/* For shmem object create */
.gem_create_object = amdxdna_gem_create_object_cb,
#ifdef AMDXDNA_SHMEM
.gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table,
.gem_prime_import = amdxdna_gem_prime_import,
#else
.gem_prime_import_sg_table = drm_gem_dma_prime_import_sg_table,
#endif
Expand Down
Loading