diff --git a/MAINTAINERS b/MAINTAINERS
index 17daa9ee9384..302c10004c5d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1194,6 +1194,12 @@ L:	linux-spi@vger.kernel.org
 S:	Supported
 F:	drivers/spi/spi-amd.c
 
+AMD VERSAL PCI DRIVER
+M:	Yidong Zhang <yidong.zhang@amd.com>
+L:	linux-fpga@vger.kernel.org
+S:	Supported
+F:	drivers/fpga/amd/
+
 AMD XGBE DRIVER
 M:	"Shyam Sundar S K" <Shyam-sundar.S-k@amd.com>
 L:	netdev@vger.kernel.org
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 37b35f58f0df..dce060a7bd8f 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -290,4 +290,7 @@ config FPGA_MGR_LATTICE_SYSCONFIG_SPI
 
 source "drivers/fpga/tests/Kconfig"
 
+# Driver files
+source "drivers/fpga/amd/Kconfig"
+
 endif # FPGA
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index aeb89bb13517..8412f3e211cc 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -58,5 +58,8 @@ obj-$(CONFIG_FPGA_DFL_NIOS_INTEL_PAC_N3000)	+= dfl-n3000-nios.o
 # Drivers for FPGAs which implement DFL
 obj-$(CONFIG_FPGA_DFL_PCI)		+= dfl-pci.o
 
+# AMD PCIe Versal Management Driver
+obj-$(CONFIG_AMD_VERSAL_PCI)		+= amd/
+
 # KUnit tests
 obj-$(CONFIG_FPGA_KUNIT_TESTS)		+= tests/
diff --git a/drivers/fpga/amd/Kconfig b/drivers/fpga/amd/Kconfig
new file mode 100644
index 000000000000..b18a42a340ba
--- /dev/null
+++ b/drivers/fpga/amd/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config AMD_VERSAL_PCI
+	tristate "AMD Versal PCIe Management Driver"
+	select FW_LOADER
+	select FW_UPLOAD
+	depends on FPGA
+	depends on HAS_IOMEM
+	depends on PCI
+	help
+	  AMD Versal PCIe Management Driver provides management services to
+	  download firmware, program bitstream, and communicate with the User
+	  function.
+
+	  If "M" is selected, the driver module will be versal-pci
diff --git a/drivers/fpga/amd/Makefile b/drivers/fpga/amd/Makefile
new file mode 100644
index 000000000000..5d1ef04b5e80
--- /dev/null
+++ b/drivers/fpga/amd/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_AMD_VERSAL_PCI)			+= versal-pci.o
+
+versal-pci-$(CONFIG_AMD_VERSAL_PCI)		:= versal-pci-main.o
diff --git a/drivers/fpga/amd/versal-pci-main.c b/drivers/fpga/amd/versal-pci-main.c
new file mode 100644
index 000000000000..a10ccf86802b
--- /dev/null
+++ b/drivers/fpga/amd/versal-pci-main.c
@@ -0,0 +1,328 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Versal PCIe device
+ *
+ * Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ */
+
+#include <linux/pci.h>
+
+#include "versal-pci.h"
+
+#define DRV_NAME			"amd-versal-pci"
+
+#define PCI_DEVICE_ID_V70PQ2		0x50B0
+#define VERSAL_XCLBIN_MAGIC_ID		"xclbin2"
+
+static int versal_pci_fpga_write_init(struct fpga_manager *mgr, struct fpga_image_info *info,
+				      const char *buf, size_t count)
+{
+	/* TODO */
+	return 0;
+}
+
+static int versal_pci_fpga_write(struct fpga_manager *mgr, const char *buf,
+				 size_t count)
+{
+	/* TODO */
+	return 0;
+}
+
+static int versal_pci_fpga_write_complete(struct fpga_manager *mgr,
+					  struct fpga_image_info *info)
+{
+	/* TODO */
+	return 0;
+}
+
+static enum fpga_mgr_states versal_pci_fpga_state(struct fpga_manager *mgr)
+{
+	struct fpga_device *fdev = mgr->priv;
+
+	return fdev->state;
+}
+
+static const struct fpga_manager_ops versal_pci_fpga_ops = {
+	.write_init = versal_pci_fpga_write_init,
+	.write = versal_pci_fpga_write,
+	.write_complete = versal_pci_fpga_write_complete,
+	.state = versal_pci_fpga_state,
+};
+
+static void versal_pci_fpga_fini(struct fpga_device *fdev)
+{
+	fpga_mgr_unregister(fdev->mgr);
+}
+
+static void versal_pci_uuid_parse(struct versal_pci_device *vdev, uuid_t *uuid)
+{
+	char str[UUID_STRING_LEN];
+	u8 i, j;
+
+	/* parse uuid into a valid uuid string format */
+	for (i  = 0, j = 0; i < strlen(vdev->fw_id) && i < sizeof(str); i++) {
+		str[j++] = vdev->fw_id[i];
+		if (j == 8 || j == 13 || j == 18 || j == 23)
+			str[j++] = '-';
+	}
+
+	uuid_parse(str, uuid);
+	vdev_info(vdev, "Interface uuid %pU", uuid);
+}
+
+static struct fpga_device *versal_pci_fpga_init(struct versal_pci_device *vdev)
+{
+	struct device *dev = &vdev->pdev->dev;
+	struct fpga_manager_info info = { 0 };
+	struct fpga_device *fdev;
+	int ret;
+
+	fdev = devm_kzalloc(dev, sizeof(*fdev), GFP_KERNEL);
+	if (!fdev)
+		return ERR_PTR(-ENOMEM);
+
+	fdev->vdev = vdev;
+
+	info = (struct fpga_manager_info) {
+		.name = "AMD Versal FPGA Manager",
+		.mops = &versal_pci_fpga_ops,
+		.priv = fdev,
+	};
+
+	fdev->mgr = fpga_mgr_register_full(dev, &info);
+	if (IS_ERR(fdev->mgr)) {
+		ret = PTR_ERR(fdev->mgr);
+		vdev_err(vdev, "Failed to register FPGA manager, err %d", ret);
+		return ERR_PTR(ret);
+	}
+
+	/* Place holder for rm_queue_get_fw_id(vdev->rdev) */
+	versal_pci_uuid_parse(vdev, &vdev->intf_uuid);
+
+	return fdev;
+}
+
+static int versal_pci_program_axlf(struct versal_pci_device *vdev, char *data, size_t size)
+{
+	const struct axlf *axlf = (struct axlf *)data;
+	struct fpga_image_info *image_info;
+	int ret;
+
+	image_info = fpga_image_info_alloc(&vdev->pdev->dev);
+	if (!image_info)
+		return -ENOMEM;
+
+	image_info->count = axlf->header.length;
+	image_info->buf = (char *)axlf;
+
+	ret = fpga_mgr_load(vdev->fdev->mgr, image_info);
+	if (ret) {
+		vdev_err(vdev, "failed to load xclbin: %d", ret);
+		goto exit;
+	}
+
+	vdev_info(vdev, "Downloaded axlf %pUb of size %zu Bytes", &axlf->header.uuid, size);
+	uuid_copy(&vdev->xclbin_uuid, &axlf->header.uuid);
+
+exit:
+	fpga_image_info_free(image_info);
+
+	return ret;
+}
+
+int versal_pci_load_xclbin(struct versal_pci_device *vdev, uuid_t *xuuid)
+{
+	const char *xclbin_location = "xilinx/xclbins";
+	char fw_name[100];
+	const struct firmware *fw;
+	int ret;
+
+	snprintf(fw_name, sizeof(fw_name), "%s/%pUb_%s.xclbin",
+		 xclbin_location, xuuid, vdev->fw_id);
+
+	vdev_info(vdev, "trying to load %s", fw_name);
+	ret = request_firmware(&fw, fw_name, &vdev->pdev->dev);
+	if (ret) {
+		vdev_warn(vdev, "request xclbin fw %s failed %d", fw_name, ret);
+		return ret;
+	}
+	vdev_info(vdev, "loaded data size %zu", fw->size);
+
+	ret = versal_pci_program_axlf(vdev, (char *)fw->data, fw->size);
+	if (ret)
+		vdev_err(vdev, "program axlf %s failed %d", fw_name, ret);
+
+	release_firmware(fw);
+
+	return ret;
+}
+
+static enum fw_upload_err versal_pci_fw_prepare(struct fw_upload *fw_upload, const u8 *data,
+						u32 size)
+{
+	/* TODO */
+	return FW_UPLOAD_ERR_NONE;
+}
+
+static enum fw_upload_err versal_pci_fw_write(struct fw_upload *fw_upload, const u8 *data,
+					      u32 offset, u32 size, u32 *written)
+{
+	/* TODO */
+	return FW_UPLOAD_ERR_NONE;
+}
+
+static enum fw_upload_err versal_pci_fw_poll_complete(struct fw_upload *fw_upload)
+{
+	/* TODO */
+	return FW_UPLOAD_ERR_NONE;
+}
+
+static void versal_pci_fw_cancel(struct fw_upload *fw_upload)
+{
+	/* TODO */
+}
+
+static void versal_pci_fw_cleanup(struct fw_upload *fw_upload)
+{
+	/* TODO */
+}
+
+static const struct fw_upload_ops versal_pci_fw_ops = {
+	.prepare = versal_pci_fw_prepare,
+	.write = versal_pci_fw_write,
+	.poll_complete = versal_pci_fw_poll_complete,
+	.cancel = versal_pci_fw_cancel,
+	.cleanup = versal_pci_fw_cleanup,
+};
+
+static void versal_pci_fw_upload_fini(struct firmware_device *fwdev)
+{
+	firmware_upload_unregister(fwdev->fw);
+	kfree(fwdev->name);
+}
+
+static u32 versal_pci_devid(struct versal_pci_device *vdev)
+{
+	return ((pci_domain_nr(vdev->pdev->bus) << 16) |
+		PCI_DEVID(vdev->pdev->bus->number, vdev->pdev->devfn));
+}
+
+static struct firmware_device *versal_pci_fw_upload_init(struct versal_pci_device *vdev)
+{
+	struct device *dev = &vdev->pdev->dev;
+	struct firmware_device *fwdev;
+	u32 devid;
+
+	fwdev = devm_kzalloc(dev, sizeof(*fwdev), GFP_KERNEL);
+	if (!fwdev)
+		return ERR_PTR(-ENOMEM);
+
+	devid = versal_pci_devid(vdev);
+	fwdev->name = kasprintf(GFP_KERNEL, "%s%x", DRV_NAME, devid);
+	if (!fwdev->name)
+		return ERR_PTR(-ENOMEM);
+
+	fwdev->fw = firmware_upload_register(THIS_MODULE, dev, fwdev->name,
+					     &versal_pci_fw_ops, fwdev);
+	if (IS_ERR(fwdev->fw)) {
+		kfree(fwdev->name);
+		return ERR_CAST(fwdev->fw);
+	}
+
+	fwdev->vdev = vdev;
+
+	return fwdev;
+}
+
+static void versal_pci_device_teardown(struct versal_pci_device *vdev)
+{
+	versal_pci_fpga_fini(vdev->fdev);
+	versal_pci_fw_upload_fini(vdev->fwdev);
+}
+
+static int versal_pci_device_setup(struct versal_pci_device *vdev)
+{
+	int ret;
+
+	vdev->fwdev = versal_pci_fw_upload_init(vdev);
+	if (IS_ERR(vdev->fwdev)) {
+		ret = PTR_ERR(vdev->fwdev);
+		vdev_err(vdev, "Failed to init FW uploader, err %d", ret);
+		return ret;
+	}
+
+	vdev->fdev = versal_pci_fpga_init(vdev);
+	if (IS_ERR(vdev->fdev)) {
+		ret = PTR_ERR(vdev->fdev);
+		vdev_err(vdev, "Failed to init FPGA manager, err %d", ret);
+		goto upload_fini;
+	}
+
+	return 0;
+
+upload_fini:
+	versal_pci_fw_upload_fini(vdev->fwdev);
+
+	return ret;
+}
+
+static void versal_pci_remove(struct pci_dev *pdev)
+{
+	struct versal_pci_device *vdev = pci_get_drvdata(pdev);
+
+	versal_pci_device_teardown(vdev);
+}
+
+static int versal_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
+{
+	struct versal_pci_device *vdev;
+	int ret;
+
+	vdev = devm_kzalloc(&pdev->dev, sizeof(*vdev), GFP_KERNEL);
+	if (!vdev)
+		return -ENOMEM;
+
+	pci_set_drvdata(pdev, vdev);
+	vdev->pdev = pdev;
+
+	ret = pcim_enable_device(pdev);
+	if (ret) {
+		vdev_err(vdev, "Failed to enable device %d", ret);
+		return ret;
+	}
+
+	vdev->io_regs = pcim_iomap_region(vdev->pdev, MGMT_BAR, DRV_NAME);
+	if (IS_ERR(vdev->io_regs)) {
+		vdev_err(vdev, "Failed to map RM shared memory BAR%d", MGMT_BAR);
+		return PTR_ERR(vdev->io_regs);
+	}
+
+	ret = versal_pci_device_setup(vdev);
+	if (ret) {
+		vdev_err(vdev, "Failed to setup Versal device %d", ret);
+		return ret;
+	}
+
+	vdev_dbg(vdev, "Successfully probed %s driver!", DRV_NAME);
+	return 0;
+}
+
+static const struct pci_device_id versal_pci_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_V70PQ2), },
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, versal_pci_ids);
+
+static struct pci_driver versal_pci_driver = {
+	.name = DRV_NAME,
+	.id_table = versal_pci_ids,
+	.probe = versal_pci_probe,
+	.remove = versal_pci_remove,
+};
+
+module_pci_driver(versal_pci_driver);
+
+MODULE_DESCRIPTION("AMD Versal PCIe Management Driver");
+MODULE_AUTHOR("XRT Team <runtimeca39d@amd.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/fpga/amd/versal-pci.h b/drivers/fpga/amd/versal-pci.h
new file mode 100644
index 000000000000..1509bd0532ea
--- /dev/null
+++ b/drivers/fpga/amd/versal-pci.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Driver for Versal PCIe device
+ *
+ * Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ */
+
+#ifndef __VERSAL_PCI_H
+#define __VERSAL_PCI_H
+
+#include <linux/firmware.h>
+#include <linux/fpga/fpga-mgr.h>
+
+#define MGMT_BAR		0
+
+#define vdev_info(vdev, fmt, args...)					\
+	dev_info(&(vdev)->pdev->dev, "%s: "fmt, __func__, ##args)
+
+#define vdev_warn(vdev, fmt, args...)					\
+	dev_warn(&(vdev)->pdev->dev, "%s: "fmt, __func__, ##args)
+
+#define vdev_err(vdev, fmt, args...)					\
+	dev_err(&(vdev)->pdev->dev, "%s: "fmt, __func__, ##args)
+
+#define vdev_dbg(vdev, fmt, args...)					\
+	dev_dbg(&(vdev)->pdev->dev, fmt, ##args)
+
+struct versal_pci_device;
+
+struct axlf_header {
+	__u64				length;
+	__u8				reserved1[24];
+	uuid_t				rom_uuid;
+	__u8				reserved2[64];
+	uuid_t				uuid;
+	__u8				reserved3[24];
+} __packed;
+
+struct axlf {
+	__u8				magic[8];
+	__u8				reserved[296];
+	struct axlf_header		header;
+} __packed;
+
+struct fw_tnx {
+	struct rm_cmd			*cmd;
+	__u32				opcode;
+	__u32				id;
+};
+
+struct fpga_device {
+	enum fpga_mgr_states		state;
+	struct fpga_manager		*mgr;
+	struct versal_pci_device	*vdev;
+	struct fw_tnx			fw;
+};
+
+struct firmware_device {
+	struct versal_pci_device	*vdev;
+	struct fw_upload		*fw;
+	__u8				*name;
+	__u32				fw_name_id;
+	struct rm_cmd			*cmd;
+	__u32				id;
+	uuid_t				uuid;
+};
+
+struct versal_pci_device {
+	struct pci_dev			*pdev;
+
+	struct fpga_device		*fdev;
+	struct firmware_device		*fwdev;
+	struct device			*device;
+
+	void __iomem			*io_regs;
+	uuid_t				xclbin_uuid;
+	uuid_t				intf_uuid;
+	__u8				fw_id[UUID_STRING_LEN + 1];
+
+	__u8				*debugfs_root;
+};
+
+/* versal pci driver APIs */
+int versal_pci_load_xclbin(struct versal_pci_device *vdev, uuid_t *xclbin_uuid);
+
+#endif	/* __VERSAL_PCI_H */
