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
67 changes: 35 additions & 32 deletions drivers/accel/amdxdna/amdxdna_aux_drv.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2022-2026, Advanced Micro Devices, Inc.
* Copyright (C) 2026, Advanced Micro Devices, Inc.
*
* Auxiliary-bus attachment for AMD XDNA / AIE-backed devices. This file is
* backend-agnostic: each auxiliary_device_id entry binds a firmware-visible
* auxiliary name to a const struct amdxdna_dev_info (via .driver_data).
* Add a row (and matching dev_info / ops in a veN_aux.c) when a new aux
* hardware generation is supported.
*/

#include <drm/drm_drv.h>
Expand All @@ -12,21 +18,18 @@
#include "amdxdna_drv.h"
#include "ve2_aux.h"

const struct amdxdna_dev_info dev_ve2_info = {
.device_type = 0,
.dev_priv = NULL,
.ops = &ve2_ops,
};

static const struct auxiliary_device_id amdxdna_ve2_aux_id_table[] = {
{ .name = "xilinx_aie.amdxdna" },
static const struct auxiliary_device_id amdxdna_aux_id_table[] = {
{
.name = "xilinx_aie.amdxdna",
.driver_data = (kernel_ulong_t)&dev_ve2_info,
},
{}
};

MODULE_DEVICE_TABLE(auxiliary, amdxdna_ve2_aux_id_table);
MODULE_DEVICE_TABLE(auxiliary, amdxdna_aux_id_table);

static int amdxdna_ve2_aux_probe(struct auxiliary_device *auxdev,
const struct auxiliary_device_id *id)
static int amdxdna_aux_probe(struct auxiliary_device *auxdev,
const struct auxiliary_device_id *id)
{
struct device *dev = &auxdev->dev;
struct amdxdna_dev *xdna;
Expand All @@ -36,16 +39,14 @@ static int amdxdna_ve2_aux_probe(struct auxiliary_device *auxdev,
if (IS_ERR(xdna))
return PTR_ERR(xdna);

xdna->dev_info = &dev_ve2_info;
if (!xdna->dev_info)
return -ENODEV;
xdna->dev_info = (const struct amdxdna_dev_info *)id->driver_data;
if (!xdna->dev_info || !xdna->dev_info->ops) {
XDNA_WARN(xdna, "No matching aux device found");
return -EINVAL;
}

auxiliary_set_drvdata(auxdev, xdna);

ret = amdxdna_dev_init(xdna);
if (ret)
return ret;

if (!dev->dma_mask) {
dev->coherent_dma_mask = DMA_BIT_MASK(64);
dev->dma_mask = &dev->coherent_dma_mask;
Expand All @@ -55,33 +56,35 @@ static int amdxdna_ve2_aux_probe(struct auxiliary_device *auxdev,
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
if (ret) {
XDNA_ERR(xdna, "DMA mask set failed (64 and 32 bit), ret %d", ret);
goto failed_dev_cleanup;
return ret;
}
XDNA_WARN(xdna, "DMA configuration downgraded to 32bit Mask\n");
XDNA_WARN(xdna, "DMA configuration downgraded to 32bit mask");
}

return 0;
ret = amdxdna_dev_init(xdna);
if (ret) {
XDNA_ERR(xdna, "amdxdna dev init failed with ret %d", ret);
return ret;
}

failed_dev_cleanup:
amdxdna_dev_cleanup(xdna);
return ret;
return 0;
}

static void amdxdna_ve2_aux_remove(struct auxiliary_device *auxdev)
static void amdxdna_aux_remove(struct auxiliary_device *auxdev)
{
struct amdxdna_dev *xdna = auxiliary_get_drvdata(auxdev);

amdxdna_dev_cleanup(xdna);
}

static struct auxiliary_driver amdxdna_ve2_aux_driver = {
.name = "amdxdna",
.probe = amdxdna_ve2_aux_probe,
.remove = amdxdna_ve2_aux_remove,
.id_table = amdxdna_ve2_aux_id_table,
static struct auxiliary_driver amdxdna_aux_driver = {
.name = KBUILD_MODNAME,
.probe = amdxdna_aux_probe,
.remove = amdxdna_aux_remove,
.id_table = amdxdna_aux_id_table,
};

module_auxiliary_driver(amdxdna_ve2_aux_driver);
module_auxiliary_driver(amdxdna_aux_driver);

MODULE_LICENSE(AMDXDNA_MODULE_LICENSE);
MODULE_AUTHOR(AMDXDNA_MODULE_AUTHOR);
Expand Down
83 changes: 55 additions & 28 deletions drivers/accel/amdxdna/amdxdna_pci_drv.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2022-2026, Advanced Micro Devices, Inc.
*
* PCI attachment for AMD XDNA devices. Board identity comes from the PCI id
* table: each entry's .driver_data points at a null-terminated table of
* (revision, dev_info) rows so one PCI device ID can map to several NPU
* profiles (e.g. 0x17f0 revisions -> NPU4/5/6). Add a new pci_device_id row
* and revision map when a new PCI device is supported; keep AIE2/AIE4
* implementation in aie2_pci.c / aie4_pci.c and npu*_regs.c.
*/

#include "drm/amdxdna_accel.h"
Expand Down Expand Up @@ -32,41 +39,61 @@ MODULE_FIRMWARE("amdnpu/1502_00/npu_7.sbin");
MODULE_FIRMWARE("amdnpu/17f0_10/npu_7.sbin");
MODULE_FIRMWARE("amdnpu/17f0_11/npu_7.sbin");

/*
* Bind the driver base on (vendor_id, device_id) pair and later use the
* (device_id, rev_id) pair as a key to select the devices. The devices with
* same device_id have very similar interface to host driver.
/**
* struct amdxdna_pci_rev_map - Map PCI revision to &struct amdxdna_dev_info.
* Tables are null-terminated with an entry where %dev_info is NULL.
*/
static const struct pci_device_id pci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1502) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x17f0) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x17f2) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1B0B) },
{0}
struct amdxdna_pci_rev_map {
u8 revision;
const struct amdxdna_dev_info *dev_info;
};

MODULE_DEVICE_TABLE(pci, pci_ids);
static const struct amdxdna_pci_rev_map amdxdna_pci_1502[] = {
{ 0x00, &dev_npu1_info },
{ }
};

static const struct amdxdna_pci_rev_map amdxdna_pci_17f0[] = {
{ 0x10, &dev_npu4_info },
{ 0x11, &dev_npu5_info },
{ 0x20, &dev_npu6_info },
{ }
};

static const struct amdxdna_pci_rev_map amdxdna_pci_17f2[] = {
{ 0x10, &dev_npu3_pf_info },
{ }
};

static const struct amdxdna_device_id amdxdna_ids[] = {
{ 0x1502, 0x0, &dev_npu1_info },
{ 0x17f0, 0x10, &dev_npu4_info },
{ 0x17f0, 0x11, &dev_npu5_info },
{ 0x17f0, 0x20, &dev_npu6_info },
{ 0x17f2, 0x10, &dev_npu3_pf_info },
{ 0x1B0B, 0x10, &dev_npu3_pf_info },
{0}
static const struct amdxdna_pci_rev_map amdxdna_pci_1b0b[] = {
{ 0x10, &dev_npu3_pf_info },
{ }
};

static const struct pci_device_id pci_ids[] = {
{ PCI_VDEVICE(AMD, 0x1502), .driver_data = (kernel_ulong_t)amdxdna_pci_1502 },
{ PCI_VDEVICE(AMD, 0x17f0), .driver_data = (kernel_ulong_t)amdxdna_pci_17f0 },
{ PCI_VDEVICE(AMD, 0x17f2), .driver_data = (kernel_ulong_t)amdxdna_pci_17f2 },
{ PCI_VDEVICE(AMD, 0x1b0b), .driver_data = (kernel_ulong_t)amdxdna_pci_1b0b },
{ }
};

MODULE_DEVICE_TABLE(pci, pci_ids);

static const struct amdxdna_dev_info *
amdxdna_get_dev_info(struct pci_dev *pdev)
amdxdna_pci_match_dev_info(struct pci_dev *pdev, const struct pci_device_id *id)
{
int i;
const struct amdxdna_pci_rev_map *row =
(const struct amdxdna_pci_rev_map *)id->driver_data;

if (!row)
return NULL;

for (i = 0; i < ARRAY_SIZE(amdxdna_ids); i++) {
if (pdev->device == amdxdna_ids[i].device &&
pdev->revision == amdxdna_ids[i].revision)
return amdxdna_ids[i].dev_info;
for (; row->dev_info; row++) {
if (pdev->revision == row->revision)
return row->dev_info;
}

return NULL;
}

Expand All @@ -80,8 +107,8 @@ static int amdxdna_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (IS_ERR(xdna))
return PTR_ERR(xdna);

xdna->dev_info = amdxdna_get_dev_info(pdev);
if (!xdna->dev_info)
xdna->dev_info = amdxdna_pci_match_dev_info(pdev, id);
if (!xdna->dev_info || !xdna->dev_info->ops)
return -ENODEV;

pci_set_drvdata(pdev, xdna);
Expand All @@ -98,7 +125,7 @@ static int amdxdna_probe(struct pci_dev *pdev, const struct pci_device_id *id)
fs_reclaim_release(GFP_KERNEL);
}

xdna->notifier_wq = alloc_ordered_workqueue("notifier_wq", WQ_MEM_RECLAIM);
xdna->notifier_wq = alloc_ordered_workqueue("amdxdna_pci_notifier", WQ_MEM_RECLAIM);
if (!xdna->notifier_wq) {
ret = -ENOMEM;
goto failed_iommu_fini;
Expand Down
Loading