Skip to content

Commit c8b2e21

Browse files
committed
accel/amdxdna: add DRAM work buffer support for AIE4 devices
NPU firmware requires a host-allocated DRAM work buffer before any hardware contexts can be created. Allocate a 4 MB (power-of-2 aligned) buffer during device init via the common amdxdna_alloc_msg_buffer() helper and attach it to firmware after mailbox init. The firmware releases the buffer internally during its suspend sequence, so no explicit detach is needed from the driver. Add the attach_work_buffer mailbox message, using GENMASK/FIELD_PREP for PASID register encoding. Signed-off-by: Nishad Saraf <nishads@amd.com>
1 parent ee8ea3e commit c8b2e21

File tree

4 files changed

+99
-2
lines changed

4 files changed

+99
-2
lines changed

drivers/accel/amdxdna/aie4_message.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,23 @@ int aie4_suspend_fw(struct amdxdna_dev_hdl *ndev)
2525

2626
return ret;
2727
}
28+
29+
int aie4_attach_work_buffer(struct amdxdna_dev_hdl *ndev, u32 pasid,
30+
dma_addr_t addr, u32 size)
31+
{
32+
DECLARE_AIE_MSG(aie4_msg_attach_work_buffer, AIE4_MSG_OP_ATTACH_WORK_BUFFER);
33+
struct amdxdna_dev *xdna = ndev->aie.xdna;
34+
int ret;
35+
36+
req.buff_addr = addr;
37+
req.buff_size = size;
38+
req.pasid = FIELD_PREP(AIE4_MSG_PASID_MASK, pasid);
39+
if (pasid)
40+
req.pasid |= AIE4_MSG_PASID_VLD;
41+
42+
ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg);
43+
if (ret)
44+
XDNA_ERR(xdna, "Failed to attach work buffer, ret %d", ret);
45+
46+
return ret;
47+
}

drivers/accel/amdxdna/aie4_msg_priv.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
#ifndef _AIE4_MSG_PRIV_H_
77
#define _AIE4_MSG_PRIV_H_
88

9+
#include <linux/bitfield.h>
10+
#include <linux/sizes.h>
911
#include <linux/types.h>
1012

1113
enum aie4_msg_opcode {
1214
AIE4_MSG_OP_SUSPEND = 0x10003,
13-
15+
AIE4_MSG_OP_ATTACH_WORK_BUFFER = 0x1000D,
1416
AIE4_MSG_OP_CREATE_VFS = 0x20001,
1517
AIE4_MSG_OP_DESTROY_VFS = 0x20002,
1618
};
@@ -46,4 +48,19 @@ struct aie4_msg_destroy_vfs_resp {
4648
enum aie4_msg_status status;
4749
} __packed;
4850

51+
#define AIE4_MSG_PASID_MASK GENMASK(19, 0)
52+
#define AIE4_MSG_PASID_VLD BIT(31)
53+
54+
#define AIE4_WORK_BUFFER_MIN_SIZE SZ_4M
55+
56+
struct aie4_msg_attach_work_buffer_req {
57+
__u64 buff_addr;
58+
__u32 pasid;
59+
__u32 buff_size;
60+
} __packed;
61+
62+
struct aie4_msg_attach_work_buffer_resp {
63+
enum aie4_msg_status status;
64+
} __packed;
65+
4966
#endif /* _AIE4_MSG_PRIV_H_ */

drivers/accel/amdxdna/aie4_pci.c

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
#include "drm/amdxdna_accel.h"
77
#include <drm/drm_managed.h>
88
#include <drm/drm_print.h>
9+
#include <linux/dma-mapping.h>
910
#include <linux/firmware.h>
1011
#include <linux/sizes.h>
1112

13+
#include "aie4_msg_priv.h"
1214
#include "aie4_pci.h"
1315
#include "amdxdna_pci_drv.h"
1416

@@ -234,6 +236,40 @@ static int aie4_fw_load(struct amdxdna_dev_hdl *ndev)
234236
return ret;
235237
}
236238

239+
static int aie4_alloc_work_buffer(struct amdxdna_dev_hdl *ndev)
240+
{
241+
struct amdxdna_dev *xdna = ndev->aie.xdna;
242+
u32 buf_size = AIE4_WORK_BUFFER_MIN_SIZE;
243+
244+
ndev->work_buf = amdxdna_alloc_msg_buffer(xdna, &buf_size,
245+
&ndev->work_buf_addr);
246+
if (IS_ERR(ndev->work_buf)) {
247+
int ret = PTR_ERR(ndev->work_buf);
248+
249+
XDNA_ERR(xdna, "Failed to alloc work buffer, size 0x%x",
250+
AIE4_WORK_BUFFER_MIN_SIZE);
251+
ndev->work_buf = NULL;
252+
return ret;
253+
}
254+
255+
ndev->work_buf_size = buf_size;
256+
XDNA_DBG(xdna, "Work buffer allocated: size 0x%x", buf_size);
257+
258+
return 0;
259+
}
260+
261+
static void aie4_free_work_buffer(struct amdxdna_dev_hdl *ndev)
262+
{
263+
struct amdxdna_dev *xdna = ndev->aie.xdna;
264+
265+
if (!ndev->work_buf)
266+
return;
267+
268+
amdxdna_free_msg_buffer(xdna, ndev->work_buf_size,
269+
ndev->work_buf, ndev->work_buf_addr);
270+
ndev->work_buf = NULL;
271+
}
272+
237273
static int aie4_hw_start(struct amdxdna_dev *xdna)
238274
{
239275
struct amdxdna_dev_hdl *ndev = xdna->dev_handle;
@@ -247,8 +283,18 @@ static int aie4_hw_start(struct amdxdna_dev *xdna)
247283
if (ret)
248284
goto fw_unload;
249285

286+
if (ndev->work_buf) {
287+
/* Firmware releases the DRAM work buffer internally during suspend */
288+
ret = aie4_attach_work_buffer(ndev, 0, ndev->work_buf_addr,
289+
ndev->work_buf_size);
290+
if (ret)
291+
goto mbox_fini;
292+
}
293+
250294
return 0;
251295

296+
mbox_fini:
297+
aie4_mailbox_fini(ndev);
252298
fw_unload:
253299
aie4_fw_unload(ndev);
254300

@@ -459,6 +505,7 @@ static void aie4_fini(struct amdxdna_dev *xdna)
459505

460506
aie4_sriov_stop(ndev);
461507
aie4_pcidev_fini(ndev);
508+
aie4_free_work_buffer(ndev);
462509
}
463510

464511
static int aie4_init(struct amdxdna_dev *xdna)
@@ -474,15 +521,23 @@ static int aie4_init(struct amdxdna_dev *xdna)
474521
ndev->aie.xdna = xdna;
475522
xdna->dev_handle = ndev;
476523

524+
ret = aie4_alloc_work_buffer(ndev);
525+
if (ret)
526+
return ret;
527+
477528
ret = aie4_pcidev_init(ndev);
478529
if (ret) {
479530
XDNA_ERR(xdna, "Setup PCI device failed, ret %d", ret);
480-
return ret;
531+
goto free_work_buf;
481532
}
482533

483534
amdxdna_vbnv_init(xdna);
484535
XDNA_DBG(xdna, "aie4 init finished");
485536
return 0;
537+
538+
free_work_buf:
539+
aie4_free_work_buffer(ndev);
540+
return ret;
486541
}
487542

488543
const struct amdxdna_dev_ops aie4_ops = {

drivers/accel/amdxdna/aie4_pci.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,15 @@ struct amdxdna_dev_hdl {
3131
void __iomem *rbuf_base;
3232

3333
struct mailbox *mbox;
34+
void *work_buf;
35+
dma_addr_t work_buf_addr;
36+
u32 work_buf_size;
3437
};
3538

3639
/* aie4_message.c */
3740
int aie4_suspend_fw(struct amdxdna_dev_hdl *ndev);
41+
int aie4_attach_work_buffer(struct amdxdna_dev_hdl *ndev, u32 pasid,
42+
dma_addr_t addr, u32 size);
3843

3944
/* aie4_sriov.c */
4045
#if IS_ENABLED(CONFIG_PCI_IOV)

0 commit comments

Comments
 (0)