Skip to content

Commit ac49797

Browse files
houlz0507quic-jhugo
authored andcommitted
accel/amdxdna: Add GEM buffer object management
There different types of BOs are supported: - shmem A user application uses shmem BOs as input/output for its workload running on NPU. - device memory heap The fixed size buffer dedicated to the device. - device buffer The buffer object allocated from device memory heap. - command buffer The buffer object created for delivering commands. The command buffer object is small and pinned on creation. New IOCTLs are added: CREATE_BO, GET_BO_INFO, SYNC_BO. SYNC_BO is used to explicitly flush CPU cache for BO memory. Co-developed-by: Min Ma <min.ma@amd.com> Signed-off-by: Min Ma <min.ma@amd.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241118172942.2014541-7-lizhi.hou@amd.com
1 parent be462c9 commit ac49797

File tree

10 files changed

+959
-1
lines changed

10 files changed

+959
-1
lines changed

drivers/accel/amdxdna/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ amdxdna-y := \
88
aie2_smu.o \
99
aie2_solver.o \
1010
amdxdna_ctx.o \
11+
amdxdna_gem.o \
1112
amdxdna_mailbox.o \
1213
amdxdna_mailbox_helper.o \
1314
amdxdna_pci_drv.o \

drivers/accel/amdxdna/aie2_ctx.c

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55

66
#include <drm/amdxdna_accel.h>
77
#include <drm/drm_device.h>
8+
#include <drm/drm_gem.h>
9+
#include <drm/drm_gem_shmem_helper.h>
810
#include <drm/drm_print.h>
911
#include <linux/types.h>
1012

1113
#include "aie2_pci.h"
1214
#include "aie2_solver.h"
1315
#include "amdxdna_ctx.h"
16+
#include "amdxdna_gem.h"
1417
#include "amdxdna_mailbox.h"
1518
#include "amdxdna_pci_drv.h"
1619

@@ -128,17 +131,36 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)
128131
struct amdxdna_client *client = hwctx->client;
129132
struct amdxdna_dev *xdna = client->xdna;
130133
struct amdxdna_hwctx_priv *priv;
134+
struct amdxdna_gem_obj *heap;
131135
int ret;
132136

133137
priv = kzalloc(sizeof(*hwctx->priv), GFP_KERNEL);
134138
if (!priv)
135139
return -ENOMEM;
136140
hwctx->priv = priv;
137141

142+
mutex_lock(&client->mm_lock);
143+
heap = client->dev_heap;
144+
if (!heap) {
145+
XDNA_ERR(xdna, "The client dev heap object not exist");
146+
mutex_unlock(&client->mm_lock);
147+
ret = -ENOENT;
148+
goto free_priv;
149+
}
150+
drm_gem_object_get(to_gobj(heap));
151+
mutex_unlock(&client->mm_lock);
152+
priv->heap = heap;
153+
154+
ret = amdxdna_gem_pin(heap);
155+
if (ret) {
156+
XDNA_ERR(xdna, "Dev heap pin failed, ret %d", ret);
157+
goto put_heap;
158+
}
159+
138160
ret = aie2_hwctx_col_list(hwctx);
139161
if (ret) {
140162
XDNA_ERR(xdna, "Create col list failed, ret %d", ret);
141-
goto free_priv;
163+
goto unpin;
142164
}
143165

144166
ret = aie2_alloc_resource(hwctx);
@@ -147,14 +169,26 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)
147169
goto free_col_list;
148170
}
149171

172+
ret = aie2_map_host_buf(xdna->dev_handle, hwctx->fw_ctx_id,
173+
heap->mem.userptr, heap->mem.size);
174+
if (ret) {
175+
XDNA_ERR(xdna, "Map host buffer failed, ret %d", ret);
176+
goto release_resource;
177+
}
150178
hwctx->status = HWCTX_STAT_INIT;
151179

152180
XDNA_DBG(xdna, "hwctx %s init completed", hwctx->name);
153181

154182
return 0;
155183

184+
release_resource:
185+
aie2_release_resource(hwctx);
156186
free_col_list:
157187
kfree(hwctx->col_list);
188+
unpin:
189+
amdxdna_gem_unpin(heap);
190+
put_heap:
191+
drm_gem_object_put(to_gobj(heap));
158192
free_priv:
159193
kfree(priv);
160194
return ret;
@@ -164,18 +198,67 @@ void aie2_hwctx_fini(struct amdxdna_hwctx *hwctx)
164198
{
165199
aie2_release_resource(hwctx);
166200

201+
amdxdna_gem_unpin(hwctx->priv->heap);
202+
drm_gem_object_put(to_gobj(hwctx->priv->heap));
203+
167204
kfree(hwctx->col_list);
168205
kfree(hwctx->priv);
169206
kfree(hwctx->cus);
170207
}
171208

209+
static int aie2_hwctx_cu_config(struct amdxdna_hwctx *hwctx, void *buf, u32 size)
210+
{
211+
struct amdxdna_hwctx_param_config_cu *config = buf;
212+
struct amdxdna_dev *xdna = hwctx->client->xdna;
213+
u32 total_size;
214+
int ret;
215+
216+
XDNA_DBG(xdna, "Config %d CU to %s", config->num_cus, hwctx->name);
217+
if (hwctx->status != HWCTX_STAT_INIT) {
218+
XDNA_ERR(xdna, "Not support re-config CU");
219+
return -EINVAL;
220+
}
221+
222+
if (!config->num_cus) {
223+
XDNA_ERR(xdna, "Number of CU is zero");
224+
return -EINVAL;
225+
}
226+
227+
total_size = struct_size(config, cu_configs, config->num_cus);
228+
if (total_size > size) {
229+
XDNA_ERR(xdna, "CU config larger than size");
230+
return -EINVAL;
231+
}
232+
233+
hwctx->cus = kmemdup(config, total_size, GFP_KERNEL);
234+
if (!hwctx->cus)
235+
return -ENOMEM;
236+
237+
ret = aie2_config_cu(hwctx);
238+
if (ret) {
239+
XDNA_ERR(xdna, "Config CU to firmware failed, ret %d", ret);
240+
goto free_cus;
241+
}
242+
243+
wmb(); /* To avoid locking in command submit when check status */
244+
hwctx->status = HWCTX_STAT_READY;
245+
246+
return 0;
247+
248+
free_cus:
249+
kfree(hwctx->cus);
250+
hwctx->cus = NULL;
251+
return ret;
252+
}
253+
172254
int aie2_hwctx_config(struct amdxdna_hwctx *hwctx, u32 type, u64 value, void *buf, u32 size)
173255
{
174256
struct amdxdna_dev *xdna = hwctx->client->xdna;
175257

176258
drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
177259
switch (type) {
178260
case DRM_AMDXDNA_HWCTX_CONFIG_CU:
261+
return aie2_hwctx_cu_config(hwctx, buf, size);
179262
case DRM_AMDXDNA_HWCTX_ASSIGN_DBG_BUF:
180263
case DRM_AMDXDNA_HWCTX_REMOVE_DBG_BUF:
181264
return -EOPNOTSUPP;

drivers/accel/amdxdna/aie2_message.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@
55

66
#include <drm/amdxdna_accel.h>
77
#include <drm/drm_device.h>
8+
#include <drm/drm_gem.h>
9+
#include <drm/drm_gem_shmem_helper.h>
810
#include <drm/drm_print.h>
11+
#include <linux/bitfield.h>
912
#include <linux/errno.h>
1013
#include <linux/pci.h>
1114
#include <linux/types.h>
1215

1316
#include "aie2_msg_priv.h"
1417
#include "aie2_pci.h"
1518
#include "amdxdna_ctx.h"
19+
#include "amdxdna_gem.h"
1620
#include "amdxdna_mailbox.h"
1721
#include "amdxdna_mailbox_helper.h"
1822
#include "amdxdna_pci_drv.h"
@@ -282,3 +286,79 @@ int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwc
282286

283287
return ret;
284288
}
289+
290+
int aie2_map_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u64 size)
291+
{
292+
DECLARE_AIE2_MSG(map_host_buffer, MSG_OP_MAP_HOST_BUFFER);
293+
struct amdxdna_dev *xdna = ndev->xdna;
294+
int ret;
295+
296+
req.context_id = context_id;
297+
req.buf_addr = addr;
298+
req.buf_size = size;
299+
ret = aie2_send_mgmt_msg_wait(ndev, &msg);
300+
if (ret)
301+
return ret;
302+
303+
XDNA_DBG(xdna, "fw ctx %d map host buf addr 0x%llx size 0x%llx",
304+
context_id, addr, size);
305+
306+
return 0;
307+
}
308+
309+
int aie2_config_cu(struct amdxdna_hwctx *hwctx)
310+
{
311+
struct mailbox_channel *chann = hwctx->priv->mbox_chann;
312+
struct amdxdna_dev *xdna = hwctx->client->xdna;
313+
u32 shift = xdna->dev_info->dev_mem_buf_shift;
314+
DECLARE_AIE2_MSG(config_cu, MSG_OP_CONFIG_CU);
315+
struct drm_gem_object *gobj;
316+
struct amdxdna_gem_obj *abo;
317+
int ret, i;
318+
319+
if (!chann)
320+
return -ENODEV;
321+
322+
if (hwctx->cus->num_cus > MAX_NUM_CUS) {
323+
XDNA_DBG(xdna, "Exceed maximum CU %d", MAX_NUM_CUS);
324+
return -EINVAL;
325+
}
326+
327+
for (i = 0; i < hwctx->cus->num_cus; i++) {
328+
struct amdxdna_cu_config *cu = &hwctx->cus->cu_configs[i];
329+
330+
gobj = drm_gem_object_lookup(hwctx->client->filp, cu->cu_bo);
331+
if (!gobj) {
332+
XDNA_ERR(xdna, "Lookup GEM object failed");
333+
return -EINVAL;
334+
}
335+
abo = to_xdna_obj(gobj);
336+
337+
if (abo->type != AMDXDNA_BO_DEV) {
338+
drm_gem_object_put(gobj);
339+
XDNA_ERR(xdna, "Invalid BO type");
340+
return -EINVAL;
341+
}
342+
343+
req.cfgs[i] = FIELD_PREP(AIE2_MSG_CFG_CU_PDI_ADDR,
344+
abo->mem.dev_addr >> shift);
345+
req.cfgs[i] |= FIELD_PREP(AIE2_MSG_CFG_CU_FUNC, cu->cu_func);
346+
XDNA_DBG(xdna, "CU %d full addr 0x%llx, cfg 0x%x", i,
347+
abo->mem.dev_addr, req.cfgs[i]);
348+
drm_gem_object_put(gobj);
349+
}
350+
req.num_cus = hwctx->cus->num_cus;
351+
352+
ret = xdna_send_msg_wait(xdna, chann, &msg);
353+
if (ret == -ETIME)
354+
aie2_destroy_context(xdna->dev_handle, hwctx);
355+
356+
if (resp.status == AIE2_STATUS_SUCCESS) {
357+
XDNA_DBG(xdna, "Configure %d CUs, ret %d", req.num_cus, ret);
358+
return 0;
359+
}
360+
361+
XDNA_ERR(xdna, "Command opcode 0x%x failed, status 0x%x ret %d",
362+
msg.opcode, resp.status, ret);
363+
return ret;
364+
}

drivers/accel/amdxdna/aie2_pci.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ struct rt_config {
119119
};
120120

121121
struct amdxdna_hwctx_priv {
122+
struct amdxdna_gem_obj *heap;
122123
void *mbox_chann;
123124
};
124125

@@ -196,6 +197,8 @@ int aie2_query_firmware_version(struct amdxdna_dev_hdl *ndev,
196197
struct amdxdna_fw_ver *fw_ver);
197198
int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx);
198199
int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx);
200+
int aie2_map_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u64 size);
201+
int aie2_config_cu(struct amdxdna_hwctx *hwctx);
199202

200203
/* aie2_hwctx.c */
201204
int aie2_hwctx_init(struct amdxdna_hwctx *hwctx);

drivers/accel/amdxdna/amdxdna_ctx.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66
#ifndef _AMDXDNA_CTX_H_
77
#define _AMDXDNA_CTX_H_
88

9+
/* Exec buffer command header format */
10+
#define AMDXDNA_CMD_STATE GENMASK(3, 0)
11+
#define AMDXDNA_CMD_EXTRA_CU_MASK GENMASK(11, 10)
12+
#define AMDXDNA_CMD_COUNT GENMASK(22, 12)
13+
#define AMDXDNA_CMD_OPCODE GENMASK(27, 23)
14+
struct amdxdna_cmd {
15+
u32 header;
16+
u32 data[];
17+
};
18+
919
struct amdxdna_hwctx {
1020
struct amdxdna_client *client;
1121
struct amdxdna_hwctx_priv *priv;

0 commit comments

Comments
 (0)