[RFC PATCH Xilinx Alveo 2/6] Global data structures shared between xocl and xmgmt drivers

From: sonal.santan
Date: Tue Mar 19 2019 - 17:54:40 EST


From: Sonal Santan <sonal.santan@xxxxxxxxxx>

Signed-off-by: Sonal Santan <sonal.santan@xxxxxxxxxx>
---
drivers/gpu/drm/xocl/devices.h | 954 +++++++++++++++++++++++++++++
drivers/gpu/drm/xocl/ert.h | 385 ++++++++++++
drivers/gpu/drm/xocl/version.h | 22 +
drivers/gpu/drm/xocl/xclbin.h | 314 ++++++++++
drivers/gpu/drm/xocl/xclfeatures.h | 107 ++++
drivers/gpu/drm/xocl/xocl_ctx.c | 196 ++++++
drivers/gpu/drm/xocl/xocl_drm.h | 91 +++
drivers/gpu/drm/xocl/xocl_drv.h | 783 +++++++++++++++++++++++
drivers/gpu/drm/xocl/xocl_subdev.c | 540 ++++++++++++++++
drivers/gpu/drm/xocl/xocl_thread.c | 64 ++
10 files changed, 3456 insertions(+)
create mode 100644 drivers/gpu/drm/xocl/devices.h
create mode 100644 drivers/gpu/drm/xocl/ert.h
create mode 100644 drivers/gpu/drm/xocl/version.h
create mode 100644 drivers/gpu/drm/xocl/xclbin.h
create mode 100644 drivers/gpu/drm/xocl/xclfeatures.h
create mode 100644 drivers/gpu/drm/xocl/xocl_ctx.c
create mode 100644 drivers/gpu/drm/xocl/xocl_drm.h
create mode 100644 drivers/gpu/drm/xocl/xocl_drv.h
create mode 100644 drivers/gpu/drm/xocl/xocl_subdev.c
create mode 100644 drivers/gpu/drm/xocl/xocl_thread.c

diff --git a/drivers/gpu/drm/xocl/devices.h b/drivers/gpu/drm/xocl/devices.h
new file mode 100644
index 000000000000..3fc6f8ea6c9b
--- /dev/null
+++ b/drivers/gpu/drm/xocl/devices.h
@@ -0,0 +1,954 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Apache-2.0 */
+
+
+/*
+ * Copyright (C) 2018-2019, Xilinx Inc
+ *
+ */
+
+
+#ifndef _XCL_DEVICES_H_
+#define _XCL_DEVICES_H_
+
+/* board flags */
+enum {
+ XOCL_DSAFLAG_PCI_RESET_OFF = 0x01,
+ XOCL_DSAFLAG_MB_SCHE_OFF = 0x02,
+ XOCL_DSAFLAG_AXILITE_FLUSH = 0x04,
+ XOCL_DSAFLAG_SET_DSA_VER = 0x08,
+ XOCL_DSAFLAG_SET_XPR = 0x10,
+ XOCL_DSAFLAG_MFG = 0x20,
+};
+
+#define FLASH_TYPE_SPI "spi"
+#define FLASH_TYPE_QSPIPS "qspi_ps"
+
+struct xocl_subdev_info {
+ uint32_t id;
+ char *name;
+ struct resource *res;
+ int num_res;
+ void *priv_data;
+ int data_len;
+};
+
+struct xocl_board_private {
+ uint64_t flags;
+ struct xocl_subdev_info *subdev_info;
+ uint32_t subdev_num;
+ uint32_t dsa_ver;
+ bool xpr;
+ char *flash_type; /* used by xbflash */
+ char *board_name; /* used by xbflash */
+ bool mpsoc;
+};
+
+#ifdef __KERNEL__
+#define XOCL_PCI_DEVID(ven, dev, subsysid, priv) \
+ .vendor = ven, .device = dev, .subvendor = PCI_ANY_ID, \
+ .subdevice = subsysid, .driver_data = \
+ (kernel_ulong_t) &XOCL_BOARD_##priv
+
+struct xocl_dsa_vbnv_map {
+ uint16_t vendor;
+ uint16_t device;
+ uint16_t subdevice;
+ char *vbnv;
+ struct xocl_board_private *priv_data;
+};
+
+#else
+struct xocl_board_info {
+ uint16_t vendor;
+ uint16_t device;
+ uint16_t subdevice;
+ struct xocl_board_private *priv_data;
+};
+
+#define XOCL_PCI_DEVID(ven, dev, subsysid, priv) \
+ .vendor = ven, .device = dev, \
+ .subdevice = subsysid, .priv_data = &XOCL_BOARD_##priv
+
+struct resource {
+ size_t start;
+ size_t end;
+ unsigned long flags;
+};
+
+enum {
+ IORESOURCE_MEM,
+ IORESOURCE_IRQ,
+};
+
+#define PCI_ANY_ID -1
+#define SUBDEV_SUFFIX
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
+
+#endif
+
+#define MGMT_SUFFIX ".m"
+#define USER_SUFFIX ".u"
+
+#define XOCL_FEATURE_ROM_USER "rom" USER_SUFFIX
+#define XOCL_FEATURE_ROM "rom" SUBDEV_SUFFIX
+#define XOCL_XDMA "xdma" SUBDEV_SUFFIX
+#define XOCL_QDMA "qdma" SUBDEV_SUFFIX
+#define XOCL_MB_SCHEDULER "mb_scheduler" SUBDEV_SUFFIX
+#define XOCL_XVC_PUB "xvc_pub" SUBDEV_SUFFIX
+#define XOCL_XVC_PRI "xvc_pri" SUBDEV_SUFFIX
+#define XOCL_SYSMON "sysmon" SUBDEV_SUFFIX
+#define XOCL_FIREWALL "firewall" SUBDEV_SUFFIX
+#define XOCL_MB "microblaze" SUBDEV_SUFFIX
+#define XOCL_XIIC "xiic" SUBDEV_SUFFIX
+#define XOCL_MAILBOX "mailbox" SUBDEV_SUFFIX
+#define XOCL_ICAP "icap" SUBDEV_SUFFIX
+#define XOCL_MIG "mig" SUBDEV_SUFFIX
+#define XOCL_XMC "xmc" SUBDEV_SUFFIX
+#define XOCL_DNA "dna" SUBDEV_SUFFIX
+#define XOCL_FMGR "fmgr" SUBDEV_SUFFIX
+
+enum subdev_id {
+ XOCL_SUBDEV_FEATURE_ROM,
+ XOCL_SUBDEV_DMA,
+ XOCL_SUBDEV_MB_SCHEDULER,
+ XOCL_SUBDEV_XVC_PUB,
+ XOCL_SUBDEV_XVC_PRI,
+ XOCL_SUBDEV_SYSMON,
+ XOCL_SUBDEV_AF,
+ XOCL_SUBDEV_MIG,
+ XOCL_SUBDEV_MB,
+ XOCL_SUBDEV_XIIC,
+ XOCL_SUBDEV_MAILBOX,
+ XOCL_SUBDEV_ICAP,
+ XOCL_SUBDEV_XMC,
+ XOCL_SUBDEV_DNA,
+ XOCL_SUBDEV_FMGR,
+ XOCL_SUBDEV_NUM
+};
+
+#define XOCL_RES_FEATURE_ROM \
+ ((struct resource []) { \
+ { \
+ .start = 0xB0000, \
+ .end = 0xB0FFF, \
+ .flags = IORESOURCE_MEM, \
+ } \
+ })
+
+
+#define XOCL_DEVINFO_FEATURE_ROM \
+ { \
+ XOCL_SUBDEV_FEATURE_ROM, \
+ XOCL_FEATURE_ROM, \
+ XOCL_RES_FEATURE_ROM, \
+ ARRAY_SIZE(XOCL_RES_FEATURE_ROM), \
+ }
+
+#define XOCL_RES_SYSMON \
+ ((struct resource []) { \
+ { \
+ .start = 0xA0000, \
+ .end = 0xAFFFF, \
+ .flags = IORESOURCE_MEM, \
+ } \
+ })
+
+#define XOCL_DEVINFO_SYSMON \
+ { \
+ XOCL_SUBDEV_SYSMON, \
+ XOCL_SYSMON, \
+ XOCL_RES_SYSMON, \
+ ARRAY_SIZE(XOCL_RES_SYSMON), \
+ }
+
+/* Will be populated dynamically */
+#define XOCL_RES_MIG \
+ ((struct resource []) { \
+ { \
+ .start = 0x0, \
+ .end = 0x3FF, \
+ .flags = IORESOURCE_MEM, \
+ } \
+ })
+
+#define XOCL_DEVINFO_MIG \
+ { \
+ XOCL_SUBDEV_MIG, \
+ XOCL_MIG, \
+ XOCL_RES_MIG, \
+ ARRAY_SIZE(XOCL_RES_MIG), \
+ }
+
+
+#define XOCL_RES_AF \
+ ((struct resource []) { \
+ { \
+ .start = 0xD0000, \
+ .end = 0xDFFFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0xE0000, \
+ .end = 0xEFFFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0xF0000, \
+ .end = 0xFFFFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0x330000, \
+ .end = 0x330FFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ })
+
+#define XOCL_DEVINFO_AF \
+ { \
+ XOCL_SUBDEV_AF, \
+ XOCL_FIREWALL, \
+ XOCL_RES_AF, \
+ ARRAY_SIZE(XOCL_RES_AF), \
+ }
+
+#define XOCL_RES_AF_DSA52 \
+ ((struct resource []) { \
+ { \
+ .start = 0xD0000, \
+ .end = 0xDFFFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0xE0000, \
+ .end = 0xE0FFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0xE1000, \
+ .end = 0xE1FFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0xF0000, \
+ .end = 0xFFFFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0x330000, \
+ .end = 0x330FFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ })
+
+#define XOCL_DEVINFO_AF_DSA52 \
+ { \
+ XOCL_SUBDEV_AF, \
+ XOCL_FIREWALL, \
+ XOCL_RES_AF_DSA52, \
+ ARRAY_SIZE(XOCL_RES_AF_DSA52), \
+ }
+
+#define XOCL_RES_XVC_PUB \
+ ((struct resource []) { \
+ { \
+ .start = 0xC0000, \
+ .end = 0xCFFFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ })
+
+#define XOCL_DEVINFO_XVC_PUB \
+ { \
+ XOCL_SUBDEV_XVC_PUB, \
+ XOCL_XVC_PUB, \
+ XOCL_RES_XVC_PUB, \
+ ARRAY_SIZE(XOCL_RES_XVC_PUB), \
+ }
+
+#define XOCL_RES_XVC_PRI \
+ ((struct resource []) { \
+ { \
+ .start = 0x1C0000, \
+ .end = 0x1CFFFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ })
+
+#define XOCL_DEVINFO_XVC_PRI \
+ { \
+ XOCL_SUBDEV_XVC_PRI, \
+ XOCL_XVC_PRI, \
+ XOCL_RES_XVC_PRI, \
+ ARRAY_SIZE(XOCL_RES_XVC_PRI), \
+ }
+
+#define XOCL_RES_XIIC \
+ ((struct resource []) { \
+ { \
+ .start = 0x41000, \
+ .end = 0x41FFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ })
+
+#define XOCL_DEVINFO_XIIC \
+ { \
+ XOCL_SUBDEV_XIIC, \
+ XOCL_XIIC, \
+ XOCL_RES_XIIC, \
+ ARRAY_SIZE(XOCL_RES_XIIC), \
+ }
+
+
+/* Will be populated dynamically */
+#define XOCL_RES_DNA \
+ ((struct resource []) { \
+ { \
+ .start = 0x0, \
+ .end = 0xFFF, \
+ .flags = IORESOURCE_MEM, \
+ } \
+ })
+
+#define XOCL_DEVINFO_DNA \
+ { \
+ XOCL_SUBDEV_DNA, \
+ XOCL_DNA, \
+ XOCL_RES_DNA, \
+ ARRAY_SIZE(XOCL_RES_DNA), \
+ }
+
+#define XOCL_MAILBOX_OFFSET_MGMT 0x210000
+#define XOCL_RES_MAILBOX_MGMT \
+ ((struct resource []) { \
+ { \
+ .start = XOCL_MAILBOX_OFFSET_MGMT, \
+ .end = 0x21002F, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 11, \
+ .end = 11, \
+ .flags = IORESOURCE_IRQ, \
+ }, \
+ })
+
+#define XOCL_DEVINFO_MAILBOX_MGMT \
+ { \
+ XOCL_SUBDEV_MAILBOX, \
+ XOCL_MAILBOX, \
+ XOCL_RES_MAILBOX_MGMT, \
+ ARRAY_SIZE(XOCL_RES_MAILBOX_MGMT), \
+ }
+
+#define XOCL_MAILBOX_OFFSET_USER 0x200000
+#define XOCL_RES_MAILBOX_USER \
+ ((struct resource []) { \
+ { \
+ .start = XOCL_MAILBOX_OFFSET_USER, \
+ .end = 0x20002F, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 4, \
+ .end = 4, \
+ .flags = IORESOURCE_IRQ, \
+ }, \
+ })
+
+#define XOCL_DEVINFO_MAILBOX_USER \
+ { \
+ XOCL_SUBDEV_MAILBOX, \
+ XOCL_MAILBOX, \
+ XOCL_RES_MAILBOX_USER, \
+ ARRAY_SIZE(XOCL_RES_MAILBOX_USER), \
+ }
+
+#define XOCL_RES_ICAP_MGMT \
+ ((struct resource []) { \
+ /* HWICAP registers */ \
+ { \
+ .start = 0x020000, \
+ .end = 0x020119, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ /* GENERAL_STATUS_BASE */ \
+ { \
+ .start = 0x032000, \
+ .end = 0x032003, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ /* AXI Gate registers */ \
+ { \
+ .start = 0x030000, \
+ .end = 0x03000b, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ /* OCL_CLKWIZ0_BASE */ \
+ { \
+ .start = 0x050000, \
+ .end = 0x050fff, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ /* OCL_CLKWIZ1_BASE */ \
+ { \
+ .start = 0x051000, \
+ .end = 0x051fff, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ /* OCL_CLKFREQ_BASE */ \
+ { \
+ .start = 0x052000, \
+ .end = 0x052fff, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ })
+
+#define XOCL_DEVINFO_ICAP_MGMT \
+ { \
+ XOCL_SUBDEV_ICAP, \
+ XOCL_ICAP, \
+ XOCL_RES_ICAP_MGMT, \
+ ARRAY_SIZE(XOCL_RES_ICAP_MGMT), \
+ }
+
+#define XOCL_DEVINFO_ICAP_USER \
+ { \
+ XOCL_SUBDEV_ICAP, \
+ XOCL_ICAP, \
+ NULL, \
+ 0, \
+ }
+
+#define XOCL_RES_XMC \
+ ((struct resource []) { \
+ { \
+ .start = 0x120000, \
+ .end = 0x121FFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0x131000, \
+ .end = 0x131FFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0x140000, \
+ .end = 0x15FFFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0x160000, \
+ .end = 0x17FFFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0x190000, \
+ .end = 0x19FFFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ })
+
+#define XOCL_DEVINFO_XMC \
+ { \
+ XOCL_SUBDEV_XMC, \
+ XOCL_XMC, \
+ XOCL_RES_XMC, \
+ ARRAY_SIZE(XOCL_RES_XMC), \
+ }
+
+#define XOCL_DEVINFO_XMC_USER \
+ { \
+ XOCL_SUBDEV_XMC, \
+ XOCL_XMC, \
+ NULL, \
+ 0, \
+ }
+
+#define XOCL_RES_MB \
+ ((struct resource []) { \
+ { \
+ .start = 0x120000, \
+ .end = 0x121FFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0x131000, \
+ .end = 0x131FFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0x140000, \
+ .end = 0x15FFFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = 0x160000, \
+ .end = 0x17FFFF, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ })
+
+#define XOCL_DEVINFO_MB \
+ { \
+ XOCL_SUBDEV_MB, \
+ XOCL_MB, \
+ XOCL_RES_MB, \
+ ARRAY_SIZE(XOCL_RES_MB), \
+ }
+
+#define XOCL_DEVINFO_QDMA \
+ { \
+ XOCL_SUBDEV_DMA, \
+ XOCL_QDMA, \
+ NULL, \
+ 0, \
+ }
+
+#define XOCL_DEVINFO_XDMA \
+ { \
+ XOCL_SUBDEV_DMA, \
+ XOCL_XDMA, \
+ NULL, \
+ 0, \
+ }
+
+#define XOCL_RES_SCHEDULER \
+ ((struct resource []) { \
+ { \
+ .start = 0, \
+ .end = 3, \
+ .flags = IORESOURCE_IRQ, \
+ } \
+ })
+
+
+#define XOCL_DEVINFO_SCHEDULER \
+ { \
+ XOCL_SUBDEV_MB_SCHEDULER, \
+ XOCL_MB_SCHEDULER, \
+ XOCL_RES_SCHEDULER, \
+ ARRAY_SIZE(XOCL_RES_SCHEDULER), \
+ }
+
+#define XOCL_DEVINFO_FMGR \
+ { \
+ XOCL_SUBDEV_FMGR, \
+ XOCL_FMGR, \
+ NULL, \
+ 0, \
+ }
+
+
+/* user pf defines */
+#define USER_RES_QDMA \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_QDMA, \
+ XOCL_DEVINFO_SCHEDULER, \
+ XOCL_DEVINFO_XVC_PUB, \
+ XOCL_DEVINFO_ICAP_USER, \
+ })
+
+#define XOCL_BOARD_USER_QDMA \
+ (struct xocl_board_private){ \
+ .flags = XOCL_DSAFLAG_MB_SCHE_OFF, \
+ .subdev_info = USER_RES_QDMA, \
+ .subdev_num = ARRAY_SIZE(USER_RES_QDMA), \
+ }
+
+#define USER_RES_XDMA_DSA50 \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_XDMA, \
+ XOCL_DEVINFO_SCHEDULER, \
+ XOCL_DEVINFO_ICAP_USER, \
+ })
+
+#define USER_RES_XDMA \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_XDMA, \
+ XOCL_DEVINFO_SCHEDULER, \
+ XOCL_DEVINFO_MAILBOX_USER, \
+ XOCL_DEVINFO_ICAP_USER, \
+ })
+
+#define USER_RES_AWS \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_XDMA, \
+ XOCL_DEVINFO_SCHEDULER, \
+ XOCL_DEVINFO_ICAP_USER, \
+ })
+
+#define USER_RES_DSA52 \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_XDMA, \
+ XOCL_DEVINFO_SCHEDULER, \
+ XOCL_DEVINFO_MAILBOX_USER, \
+ XOCL_DEVINFO_XVC_PUB, \
+ XOCL_DEVINFO_ICAP_USER, \
+ XOCL_DEVINFO_XMC_USER, \
+ })
+
+#define XOCL_BOARD_USER_XDMA_DSA50 \
+ (struct xocl_board_private){ \
+ .flags = XOCL_DSAFLAG_MB_SCHE_OFF, \
+ .subdev_info = USER_RES_XDMA_DSA50, \
+ .subdev_num = ARRAY_SIZE(USER_RES_XDMA_DSA50), \
+ }
+
+#define XOCL_BOARD_USER_XDMA \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = USER_RES_XDMA, \
+ .subdev_num = ARRAY_SIZE(USER_RES_XDMA), \
+ }
+
+#define XOCL_BOARD_USER_XDMA_ERT_OFF \
+ (struct xocl_board_private){ \
+ .flags = XOCL_DSAFLAG_MB_SCHE_OFF, \
+ .subdev_info = USER_RES_XDMA, \
+ .subdev_num = ARRAY_SIZE(USER_RES_XDMA), \
+ }
+
+#define XOCL_BOARD_USER_AWS \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = USER_RES_AWS, \
+ .subdev_num = ARRAY_SIZE(USER_RES_AWS), \
+ }
+
+#define XOCL_BOARD_USER_DSA52 \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = USER_RES_DSA52, \
+ .subdev_num = ARRAY_SIZE(USER_RES_DSA52), \
+ }
+
+/* mgmt pf defines */
+#define MGMT_RES_DEFAULT \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_SYSMON, \
+ XOCL_DEVINFO_AF, \
+ XOCL_DEVINFO_MB, \
+ XOCL_DEVINFO_XVC_PUB, \
+ XOCL_DEVINFO_XIIC, \
+ XOCL_DEVINFO_MAILBOX_MGMT, \
+ XOCL_DEVINFO_ICAP_MGMT, \
+ XOCL_DEVINFO_FMGR, \
+ })
+
+#define MGMT_RES_DSA50 \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_SYSMON, \
+ XOCL_DEVINFO_AF, \
+ XOCL_DEVINFO_MB, \
+ XOCL_DEVINFO_XVC_PUB, \
+ XOCL_DEVINFO_XIIC, \
+ XOCL_DEVINFO_ICAP_MGMT, \
+ XOCL_DEVINFO_FMGR, \
+ })
+
+#define XOCL_BOARD_MGMT_DEFAULT \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = MGMT_RES_DEFAULT, \
+ .subdev_num = ARRAY_SIZE(MGMT_RES_DEFAULT), \
+ }
+
+#define XOCL_BOARD_MGMT_DSA50 \
+ (struct xocl_board_private){ \
+ .flags = XOCL_DSAFLAG_PCI_RESET_OFF | \
+ XOCL_DSAFLAG_AXILITE_FLUSH | \
+ XOCL_DSAFLAG_MB_SCHE_OFF, \
+ .subdev_info = MGMT_RES_DSA50, \
+ .subdev_num = ARRAY_SIZE(MGMT_RES_DSA50), \
+ }
+
+#define MGMT_RES_6A8F \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_SYSMON, \
+ XOCL_DEVINFO_AF, \
+ XOCL_DEVINFO_MB, \
+ XOCL_DEVINFO_XVC_PUB, \
+ XOCL_DEVINFO_MAILBOX_MGMT, \
+ XOCL_DEVINFO_ICAP_MGMT, \
+ XOCL_DEVINFO_FMGR, \
+ })
+
+#define MGMT_RES_6A8F_DSA50 \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_SYSMON, \
+ XOCL_DEVINFO_AF, \
+ XOCL_DEVINFO_MB, \
+ XOCL_DEVINFO_XVC_PUB, \
+ XOCL_DEVINFO_ICAP_MGMT, \
+ XOCL_DEVINFO_FMGR, \
+ })
+
+#define MGMT_RES_XBB_DSA51 \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_SYSMON, \
+ XOCL_DEVINFO_AF, \
+ XOCL_DEVINFO_XMC, \
+ XOCL_DEVINFO_XVC_PUB, \
+ XOCL_DEVINFO_MAILBOX_MGMT, \
+ XOCL_DEVINFO_ICAP_MGMT, \
+ XOCL_DEVINFO_FMGR, \
+ })
+
+#define XOCL_BOARD_MGMT_6A8F \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = MGMT_RES_6A8F, \
+ .subdev_num = ARRAY_SIZE(MGMT_RES_6A8F), \
+ }
+
+#define XOCL_BOARD_MGMT_XBB_DSA51 \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = MGMT_RES_XBB_DSA51, \
+ .subdev_num = ARRAY_SIZE(MGMT_RES_XBB_DSA51), \
+ .flash_type = FLASH_TYPE_SPI, \
+ }
+
+
+#define XOCL_BOARD_MGMT_888F XOCL_BOARD_MGMT_6A8F
+#define XOCL_BOARD_MGMT_898F XOCL_BOARD_MGMT_6A8F
+
+#define XOCL_BOARD_MGMT_6A8F_DSA50 \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = MGMT_RES_6A8F_DSA50, \
+ .subdev_num = ARRAY_SIZE(MGMT_RES_6A8F_DSA50), \
+ }
+
+#define MGMT_RES_QDMA \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_SYSMON, \
+ XOCL_DEVINFO_AF, \
+ XOCL_DEVINFO_MB, \
+ XOCL_DEVINFO_XVC_PRI, \
+ XOCL_DEVINFO_ICAP_MGMT, \
+ XOCL_DEVINFO_FMGR, \
+ })
+
+
+#define XOCL_BOARD_MGMT_QDMA \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = MGMT_RES_QDMA, \
+ .subdev_num = ARRAY_SIZE(MGMT_RES_QDMA), \
+ .flash_type = FLASH_TYPE_SPI \
+ }
+
+#define MGMT_RES_XBB_QDMA \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_SYSMON, \
+ XOCL_DEVINFO_AF_DSA52, \
+ XOCL_DEVINFO_XMC, \
+ XOCL_DEVINFO_XVC_PRI, \
+ XOCL_DEVINFO_ICAP_MGMT, \
+ })
+
+#define XOCL_BOARD_MGMT_XBB_QDMA \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = MGMT_RES_XBB_QDMA, \
+ .subdev_num = ARRAY_SIZE(MGMT_RES_XBB_QDMA), \
+ .flash_type = FLASH_TYPE_SPI \
+ }
+
+#define XOCL_BOARD_MGMT_6B0F XOCL_BOARD_MGMT_6A8F
+
+#define MGMT_RES_6A8F_DSA52 \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_SYSMON, \
+ XOCL_DEVINFO_AF_DSA52, \
+ XOCL_DEVINFO_MB, \
+ XOCL_DEVINFO_XVC_PRI, \
+ XOCL_DEVINFO_MAILBOX_MGMT, \
+ XOCL_DEVINFO_ICAP_MGMT, \
+ XOCL_DEVINFO_FMGR, \
+ })
+
+#define XOCL_BOARD_MGMT_6A8F_DSA52 \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = MGMT_RES_6A8F_DSA52, \
+ .subdev_num = ARRAY_SIZE(MGMT_RES_6A8F_DSA52), \
+ }
+
+#define MGMT_RES_XBB_DSA52 \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_SYSMON, \
+ XOCL_DEVINFO_AF_DSA52, \
+ XOCL_DEVINFO_XMC, \
+ XOCL_DEVINFO_XVC_PRI, \
+ XOCL_DEVINFO_MAILBOX_MGMT, \
+ XOCL_DEVINFO_ICAP_MGMT, \
+ XOCL_DEVINFO_FMGR, \
+ })
+
+#define XOCL_BOARD_MGMT_XBB_DSA52 \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = MGMT_RES_XBB_DSA52, \
+ .subdev_num = ARRAY_SIZE(MGMT_RES_XBB_DSA52), \
+ .flash_type = FLASH_TYPE_SPI, \
+ }
+
+#define MGMT_RES_6E8F_DSA52 \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_SYSMON, \
+ XOCL_DEVINFO_AF, \
+ XOCL_DEVINFO_MB, \
+ XOCL_DEVINFO_XVC_PRI, \
+ XOCL_DEVINFO_XIIC, \
+ XOCL_DEVINFO_MAILBOX_MGMT, \
+ XOCL_DEVINFO_ICAP_MGMT, \
+ XOCL_DEVINFO_FMGR, \
+ })
+
+#define XOCL_BOARD_MGMT_6E8F_DSA52 \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = MGMT_RES_6E8F_DSA52, \
+ .subdev_num = ARRAY_SIZE(MGMT_RES_6E8F_DSA52), \
+ }
+
+#define MGMT_RES_MPSOC \
+ ((struct xocl_subdev_info []) { \
+ XOCL_DEVINFO_FEATURE_ROM, \
+ XOCL_DEVINFO_SYSMON, \
+ XOCL_DEVINFO_XVC_PUB, \
+ XOCL_DEVINFO_MAILBOX_MGMT, \
+ XOCL_DEVINFO_ICAP_MGMT, \
+ XOCL_DEVINFO_FMGR, \
+ })
+
+#define XOCL_BOARD_MGMT_MPSOC \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = MGMT_RES_MPSOC, \
+ .subdev_num = ARRAY_SIZE(MGMT_RES_MPSOC), \
+ .mpsoc = true, \
+ .board_name = "samsung", \
+ .flash_type = FLASH_TYPE_QSPIPS, \
+ }
+
+#define XOCL_BOARD_USER_XDMA_MPSOC \
+ (struct xocl_board_private){ \
+ .flags = 0, \
+ .subdev_info = USER_RES_XDMA, \
+ .subdev_num = ARRAY_SIZE(USER_RES_XDMA), \
+ .mpsoc = true, \
+ }
+
+
+#define XOCL_BOARD_XBB_MFG(board) \
+ (struct xocl_board_private){ \
+ .flags = XOCL_DSAFLAG_MFG, \
+ .board_name = board, \
+ .flash_type = FLASH_TYPE_SPI, \
+ }
+
+#define XOCL_MGMT_PCI_IDS { \
+ { XOCL_PCI_DEVID(0x10EE, 0x4A47, PCI_ANY_ID, MGMT_DEFAULT) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x4A87, PCI_ANY_ID, MGMT_DEFAULT) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x4B47, PCI_ANY_ID, MGMT_DEFAULT) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x4B87, 0x4350, MGMT_DSA50) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x4B87, 0x4351, MGMT_DEFAULT) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x684F, PCI_ANY_ID, MGMT_DEFAULT) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0xA883, 0x1351, MGMT_MPSOC) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0xA983, 0x1351, MGMT_MPSOC) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x688F, PCI_ANY_ID, MGMT_DEFAULT) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x694F, PCI_ANY_ID, MGMT_DEFAULT) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x698F, PCI_ANY_ID, MGMT_DEFAULT) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6A4F, PCI_ANY_ID, MGMT_DEFAULT) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6A8F, 0x4350, MGMT_6A8F_DSA50) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6A8F, 0x4351, MGMT_6A8F) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6A8F, 0x4352, MGMT_6A8F_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6A9F, 0x4360, MGMT_QDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x5010, PCI_ANY_ID, MGMT_XBB_QDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6A9F, PCI_ANY_ID, MGMT_DEFAULT) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6E4F, PCI_ANY_ID, MGMT_DEFAULT) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6B0F, PCI_ANY_ID, MGMT_6B0F) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6E8F, 0x4352, MGMT_6E8F_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x888F, PCI_ANY_ID, MGMT_888F) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x898F, PCI_ANY_ID, MGMT_898F) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x788F, 0x4351, MGMT_XBB_DSA51) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x788F, 0x4352, MGMT_XBB_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x798F, 0x4352, MGMT_XBB_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6A8F, 0x4353, MGMT_6A8F_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x5000, PCI_ANY_ID, MGMT_XBB_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x5004, PCI_ANY_ID, MGMT_XBB_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x5008, PCI_ANY_ID, MGMT_XBB_DSA52) }, \
+ { XOCL_PCI_DEVID(0x13FE, 0x006C, PCI_ANY_ID, MGMT_6A8F) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0xD000, PCI_ANY_ID, XBB_MFG("u200")) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0xD004, PCI_ANY_ID, XBB_MFG("u250")) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0xD008, PCI_ANY_ID, XBB_MFG("u280-es1")) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0xD00C, PCI_ANY_ID, XBB_MFG("u280")) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0xEB10, PCI_ANY_ID, XBB_MFG("twitch")) }, \
+ { 0, } \
+}
+
+#define XOCL_USER_PCI_IDS { \
+ { XOCL_PCI_DEVID(0x10EE, 0x4A48, PCI_ANY_ID, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x4A88, PCI_ANY_ID, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x4B48, PCI_ANY_ID, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x4B88, 0x4350, USER_XDMA_DSA50) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x4B88, 0x4351, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6850, PCI_ANY_ID, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6890, PCI_ANY_ID, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6950, PCI_ANY_ID, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0xA884, 0x1351, USER_XDMA_MPSOC) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0xA984, 0x1351, USER_XDMA_MPSOC) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6990, PCI_ANY_ID, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6A50, PCI_ANY_ID, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6A90, 0x4350, USER_XDMA_DSA50) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6A90, 0x4351, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6A90, 0x4352, USER_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6A90, 0x4353, USER_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6E50, PCI_ANY_ID, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6B10, PCI_ANY_ID, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6E90, 0x4352, USER_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x8890, PCI_ANY_ID, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x8990, PCI_ANY_ID, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x7890, 0x4351, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x7890, 0x4352, USER_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x7990, 0x4352, USER_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x5001, PCI_ANY_ID, USER_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x5005, PCI_ANY_ID, USER_DSA52) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x5009, PCI_ANY_ID, USER_DSA52) }, \
+ { XOCL_PCI_DEVID(0x13FE, 0x0065, PCI_ANY_ID, USER_XDMA) }, \
+ { XOCL_PCI_DEVID(0x1D0F, 0x1042, PCI_ANY_ID, USER_AWS) }, \
+ { XOCL_PCI_DEVID(0x1D0F, 0xF000, PCI_ANY_ID, USER_AWS) }, \
+ { XOCL_PCI_DEVID(0x1D0F, 0xF010, PCI_ANY_ID, USER_AWS) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x6AA0, 0x4360, USER_QDMA) }, \
+ { XOCL_PCI_DEVID(0x10EE, 0x5011, PCI_ANY_ID, USER_QDMA) }, \
+ { 0, } \
+}
+
+#define XOCL_DSA_VBNV_MAP { \
+ { 0x10EE, 0x5001, PCI_ANY_ID, "xilinx_u200_xdma_201820_1", \
+ &XOCL_BOARD_USER_XDMA }, \
+ { 0x10EE, 0x5000, PCI_ANY_ID, "xilinx_u200_xdma_201820_1", \
+ &XOCL_BOARD_MGMT_XBB_DSA51 } \
+}
+
+#endif
diff --git a/drivers/gpu/drm/xocl/ert.h b/drivers/gpu/drm/xocl/ert.h
new file mode 100644
index 000000000000..2e94c5a63877
--- /dev/null
+++ b/drivers/gpu/drm/xocl/ert.h
@@ -0,0 +1,385 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Apache-2.0 */
+
+/**
+ * Copyright (C) 2017-2019, Xilinx Inc
+ * DOC: Xilinx SDAccel Embedded Runtime definition
+ *
+ * Header file *ert.h* defines data structures used by Emebdded Runtime (ERT) and
+ * XRT xclExecBuf() API.
+ */
+
+#ifndef _ERT_H_
+#define _ERT_H_
+
+#if defined(__KERNEL__)
+# include <linux/types.h>
+#else
+# include <stdint.h>
+#endif
+
+/**
+ * struct ert_packet: ERT generic packet format
+ *
+ * @state: [3-0] current state of a command
+ * @custom: [11-4] custom per specific commands
+ * @count: [22-12] number of words in payload (data)
+ * @opcode: [27-23] opcode identifying specific command
+ * @type: [31-28] type of command (currently 0)
+ * @data: count number of words representing packet payload
+ */
+struct ert_packet {
+ union {
+ struct {
+ uint32_t state:4; /* [3-0] */
+ uint32_t custom:8; /* [11-4] */
+ uint32_t count:11; /* [22-12] */
+ uint32_t opcode:5; /* [27-23] */
+ uint32_t type:4; /* [31-28] */
+ };
+ uint32_t header;
+ };
+ uint32_t data[1]; /* count number of words */
+};
+
+/**
+ * struct ert_start_kernel_cmd: ERT start kernel command format
+ *
+ * @state: [3-0] current state of a command
+ * @extra_cu_masks: [11-10] extra CU masks in addition to mandatory mask
+ * @count: [22-12] number of words following header
+ * @opcode: [27-23] 0, opcode for start_kernel
+ * @type: [31-27] 0, type of start_kernel
+ *
+ * @cu_mask: first mandatory CU mask
+ * @data: count-1 number of words representing interpreted payload
+ *
+ * The packet payload is comprised of reserved id field, a mandatory CU mask,
+ * and extra_cu_masks per header field, followed by a CU register map of size
+ * (count - (1 + extra_cu_masks)) uint32_t words.
+ */
+struct ert_start_kernel_cmd {
+ union {
+ struct {
+ uint32_t state:4; /* [3-0] */
+ uint32_t unused:6; /* [9-4] */
+ uint32_t extra_cu_masks:2; /* [11-10] */
+ uint32_t count:11; /* [22-12] */
+ uint32_t opcode:5; /* [27-23] */
+ uint32_t type:4; /* [31-27] */
+ };
+ uint32_t header;
+ };
+
+ /* payload */
+ uint32_t cu_mask; /* mandatory cu mask */
+ uint32_t data[1]; /* count-1 number of words */
+};
+
+#define COPYBO_UNIT 64 /* Limited by KDMA CU */
+struct ert_start_copybo_cmd {
+ uint32_t state:4; /* [3-0], must be ERT_CMD_STATE_NEW */
+ uint32_t unused:6; /* [9-4] */
+ uint32_t extra_cu_masks:2; /* [11-10], = 3 */
+ uint32_t count:11; /* [22-12], = sizeof(ert_start_copybo_cmd)-1 */
+ uint32_t opcode:5; /* [27-23], = ERT_START_COPYBO */
+ uint32_t type:4; /* [31-27], = ERT_DEFAULT */
+ uint32_t cu_mask[4]; /* mandatory cu masks */
+ uint32_t reserved[4]; /* for scheduler use */
+ uint32_t src_addr_lo; /* low 32 bit of src addr */
+ uint32_t src_addr_hi; /* high 32 bit of src addr */
+ uint32_t src_bo_hdl; /* src bo handle, cleared by driver */
+ uint32_t dst_addr_lo; /* low 32 bit of dst addr */
+ uint32_t dst_addr_hi; /* high 32 bit of dst addr */
+ uint32_t dst_bo_hdl; /* dst bo handle, cleared by driver */
+ uint32_t size; /* size in COPYBO_UNIT byte */
+};
+
+/**
+ * struct ert_configure_cmd: ERT configure command format
+ *
+ * @state: [3-0] current state of a command
+ * @count: [22-12] number of words in payload (5 + num_cus)
+ * @opcode: [27-23] 1, opcode for configure
+ * @type: [31-27] 0, type of configure
+ *
+ * @slot_size: command queue slot size
+ * @num_cus: number of compute units in program
+ * @cu_shift: shift value to convert CU idx to CU addr
+ * @cu_base_addr: base address to add to CU addr for actual physical address
+ *
+ * @ert:1 enable embedded HW scheduler
+ * @polling:1 poll for command completion
+ * @cu_dma:1 enable CUDMA custom module for HW scheduler
+ * @cu_isr:1 enable CUISR custom module for HW scheduler
+ * @cq_int:1 enable interrupt from host to HW scheduler
+ * @cdma:1 enable CDMA kernel
+ * @unused:25
+ * @dsa52:1 reserved for internal use
+ *
+ * @data: addresses of @num_cus CUs
+ */
+struct ert_configure_cmd {
+ union {
+ struct {
+ uint32_t state:4; /* [3-0] */
+ uint32_t unused:8; /* [11-4] */
+ uint32_t count:11; /* [22-12] */
+ uint32_t opcode:5; /* [27-23] */
+ uint32_t type:4; /* [31-27] */
+ };
+ uint32_t header;
+ };
+
+ /* payload */
+ uint32_t slot_size;
+ uint32_t num_cus;
+ uint32_t cu_shift;
+ uint32_t cu_base_addr;
+
+ /* features */
+ uint32_t ert:1;
+ uint32_t polling:1;
+ uint32_t cu_dma:1;
+ uint32_t cu_isr:1;
+ uint32_t cq_int:1;
+ uint32_t cdma:1;
+ uint32_t unusedf:25;
+ uint32_t dsa52:1;
+
+ /* cu address map size is num_cus */
+ uint32_t data[1];
+};
+
+/**
+ * struct ert_abort_cmd: ERT abort command format.
+ *
+ * @idx: The slot index of command to abort
+ */
+struct ert_abort_cmd {
+ union {
+ struct {
+ uint32_t state:4; /* [3-0] */
+ uint32_t unused:11; /* [14-4] */
+ uint32_t idx:8; /* [22-15] */
+ uint32_t opcode:5; /* [27-23] */
+ uint32_t type:4; /* [31-27] */
+ };
+ uint32_t header;
+ };
+};
+
+/**
+ * ERT command state
+ *
+ * @ERT_CMD_STATE_NEW: Set by host before submitting a command to scheduler
+ * @ERT_CMD_STATE_QUEUED: Internal scheduler state
+ * @ERT_CMD_STATE_SUBMITTED:Internal scheduler state
+ * @ERT_CMD_STATE_RUNNING: Internal scheduler state
+ * @ERT_CMD_STATE_COMPLETE: Set by scheduler when command completes
+ * @ERT_CMD_STATE_ERROR: Set by scheduler if command failed
+ * @ERT_CMD_STATE_ABORT: Set by scheduler if command abort
+ */
+enum ert_cmd_state {
+ ERT_CMD_STATE_NEW = 1,
+ ERT_CMD_STATE_QUEUED = 2,
+ ERT_CMD_STATE_RUNNING = 3,
+ ERT_CMD_STATE_COMPLETED = 4,
+ ERT_CMD_STATE_ERROR = 5,
+ ERT_CMD_STATE_ABORT = 6,
+ ERT_CMD_STATE_SUBMITTED = 7,
+};
+
+/**
+ * Opcode types for commands
+ *
+ * @ERT_START_CU: start a workgroup on a CU
+ * @ERT_START_KERNEL: currently aliased to ERT_START_CU
+ * @ERT_CONFIGURE: configure command scheduler
+ * @ERT_WRITE: write pairs of addr and value
+ * @ERT_CU_STAT: get stats about CU execution
+ * @ERT_START_COPYBO: start KDMA CU or P2P, may be converted to ERT_START_CU
+ * before cmd reach to scheduler, short-term hack
+ */
+enum ert_cmd_opcode {
+ ERT_START_CU = 0,
+ ERT_START_KERNEL = 0,
+ ERT_CONFIGURE = 2,
+ ERT_STOP = 3,
+ ERT_ABORT = 4,
+ ERT_WRITE = 5,
+ ERT_CU_STAT = 6,
+ ERT_START_COPYBO = 7,
+};
+
+/**
+ * Command types
+ *
+ * @ERT_DEFAULT: default command type
+ * @ERT_KDS_LOCAL: command processed by KDS locally
+ * @ERT_CTRL: control command uses reserved command queue slot
+ */
+enum ert_cmd_type {
+ ERT_DEFAULT = 0,
+ ERT_KDS_LOCAL = 1,
+ ERT_CTRL = 2,
+};
+
+/**
+ * Address constants per spec
+ */
+#define ERT_WORD_SIZE 4 /* 4 bytes */
+#define ERT_CQ_SIZE 0x10000 /* 64K */
+#define ERT_CQ_BASE_ADDR 0x190000
+#define ERT_CSR_ADDR 0x180000
+
+/**
+ * The STATUS REGISTER is for communicating completed CQ slot indices
+ * MicroBlaze write, host reads. MB(W) / HOST(COR)
+ */
+#define ERT_STATUS_REGISTER_ADDR (ERT_CSR_ADDR)
+#define ERT_STATUS_REGISTER_ADDR0 (ERT_CSR_ADDR)
+#define ERT_STATUS_REGISTER_ADDR1 (ERT_CSR_ADDR + 0x4)
+#define ERT_STATUS_REGISTER_ADDR2 (ERT_CSR_ADDR + 0x8)
+#define ERT_STATUS_REGISTER_ADDR3 (ERT_CSR_ADDR + 0xC)
+
+/**
+ * The CU DMA REGISTER is for communicating which CQ slot is to be started
+ * on a specific CU. MB selects a free CU on which the command can
+ * run, then writes the 1<<CU back to the command slot CU mask and
+ * writes the slot index to the CU DMA REGISTER. HW is notified when
+ * the register is written and now does the DMA transfer of CU regmap
+ * map from command to CU, while MB continues its work. MB(W) / HW(R)
+ */
+#define ERT_CU_DMA_ENABLE_ADDR (ERT_CSR_ADDR + 0x18)
+#define ERT_CU_DMA_REGISTER_ADDR (ERT_CSR_ADDR + 0x1C)
+#define ERT_CU_DMA_REGISTER_ADDR0 (ERT_CSR_ADDR + 0x1C)
+#define ERT_CU_DMA_REGISTER_ADDR1 (ERT_CSR_ADDR + 0x20)
+#define ERT_CU_DMA_REGISTER_ADDR2 (ERT_CSR_ADDR + 0x24)
+#define ERT_CU_DMA_REGISTER_ADDR3 (ERT_CSR_ADDR + 0x28)
+
+/**
+ * The SLOT SIZE is the size of slots in command queue, it is
+ * configurable per xclbin. MB(W) / HW(R)
+ */
+#define ERT_CQ_SLOT_SIZE_ADDR (ERT_CSR_ADDR + 0x2C)
+
+/**
+ * The CU_OFFSET is the size of a CU's address map in power of 2. For
+ * example a 64K regmap is 2^16 so 16 is written to the CU_OFFSET_ADDR.
+ * MB(W) / HW(R)
+ */
+#define ERT_CU_OFFSET_ADDR (ERT_CSR_ADDR + 0x30)
+
+/**
+ * The number of slots is command_queue_size / slot_size.
+ * MB(W) / HW(R)
+ */
+#define ERT_CQ_NUMBER_OF_SLOTS_ADDR (ERT_CSR_ADDR + 0x34)
+
+/**
+ * All CUs placed in same address space separated by CU_OFFSET. The
+ * CU_BASE_ADDRESS is the address of the first CU. MB(W) / HW(R)
+ */
+#define ERT_CU_BASE_ADDRESS_ADDR (ERT_CSR_ADDR + 0x38)
+
+/**
+ * The CQ_BASE_ADDRESS is the base address of the command queue.
+ * MB(W) / HW(R)
+ */
+#define ERT_CQ_BASE_ADDRESS_ADDR (ERT_CSR_ADDR + 0x3C)
+
+/**
+ * The CU_ISR_HANDLER_ENABLE (MB(W)/HW(R)) enables the HW handling of
+ * CU interrupts. When a CU interrupts (when done), hardware handles
+ * the interrupt and writes the index of the CU that completed into
+ * the CU_STATUS_REGISTER (HW(W)/MB(COR)) as a bitmask
+ */
+#define ERT_CU_ISR_HANDLER_ENABLE_ADDR (ERT_CSR_ADDR + 0x40)
+#define ERT_CU_STATUS_REGISTER_ADDR (ERT_CSR_ADDR + 0x44)
+#define ERT_CU_STATUS_REGISTER_ADDR0 (ERT_CSR_ADDR + 0x44)
+#define ERT_CU_STATUS_REGISTER_ADDR1 (ERT_CSR_ADDR + 0x48)
+#define ERT_CU_STATUS_REGISTER_ADDR2 (ERT_CSR_ADDR + 0x4C)
+#define ERT_CU_STATUS_REGISTER_ADDR3 (ERT_CSR_ADDR + 0x50)
+
+/**
+ * The CQ_STATUS_ENABLE (MB(W)/HW(R)) enables interrupts from HOST to
+ * MB to indicate the presense of a new command in some slot. The
+ * slot index is written to the CQ_STATUS_REGISTER (HOST(W)/MB(R))
+ */
+#define ERT_CQ_STATUS_ENABLE_ADDR (ERT_CSR_ADDR + 0x54)
+#define ERT_CQ_STATUS_REGISTER_ADDR (ERT_CSR_ADDR + 0x58)
+#define ERT_CQ_STATUS_REGISTER_ADDR0 (ERT_CSR_ADDR + 0x58)
+#define ERT_CQ_STATUS_REGISTER_ADDR1 (ERT_CSR_ADDR + 0x5C)
+#define ERT_CQ_STATUS_REGISTER_ADDR2 (ERT_CSR_ADDR + 0x60)
+#define ERT_CQ_STATUS_REGISTER_ADDR3 (ERT_CSR_ADDR + 0x64)
+
+/**
+ * The NUMBER_OF_CU (MB(W)/HW(R) is the number of CUs per current
+ * xclbin. This is an optimization that allows HW to only check CU
+ * completion on actual CUs.
+ */
+#define ERT_NUMBER_OF_CU_ADDR (ERT_CSR_ADDR + 0x68)
+
+/**
+ * Enable global interrupts from MB to HOST on command completion.
+ * When enabled writing to STATUS_REGISTER causes an interrupt in HOST.
+ * MB(W)
+ */
+#define ERT_HOST_INTERRUPT_ENABLE_ADDR (ERT_CSR_ADDR + 0x100)
+
+/**
+ * Interrupt controller base address
+ * This value is per hardware BSP (XPAR_INTC_SINGLE_BASEADDR)
+ */
+#define ERT_INTC_ADDR 0x41200000
+
+/**
+ * Look up table for CUISR for CU addresses
+ */
+#define ERT_CUISR_LUT_ADDR (ERT_CSR_ADDR + 0x400)
+
+/**
+ * ERT stop command/ack
+ */
+#define ERT_STOP_CMD ((ERT_STOP << 23) | ERT_CMD_STATE_NEW)
+#define ERT_STOP_ACK (ERT_CMD_STATE_COMPLETED)
+
+/**
+ * State machine for both CUDMA and CUISR modules
+ */
+#define ERT_HLS_MODULE_IDLE 0x1
+#define ERT_CUDMA_STATE (ERT_CSR_ADDR + 0x318)
+#define ERT_CUISR_STATE (ERT_CSR_ADDR + 0x328)
+
+/**
+ * Interrupt address masks written by MB when interrupts from
+ * CU are enabled
+ */
+#define ERT_INTC_IPR_ADDR (ERT_INTC_ADDR + 0x4) /* pending */
+#define ERT_INTC_IER_ADDR (ERT_INTC_ADDR + 0x8) /* enable */
+#define ERT_INTC_IAR_ADDR (ERT_INTC_ADDR + 0x0C) /* acknowledge */
+#define ERT_INTC_MER_ADDR (ERT_INTC_ADDR + 0x1C) /* master enable */
+
+static inline void
+ert_fill_copybo_cmd(struct ert_start_copybo_cmd *pkt, uint32_t src_bo,
+ uint32_t dst_bo, uint64_t src_offset, uint64_t dst_offset, uint64_t size)
+{
+ pkt->state = ERT_CMD_STATE_NEW;
+ pkt->extra_cu_masks = 3;
+ pkt->count = sizeof (struct ert_start_copybo_cmd) / 4 - 1;
+ pkt->opcode = ERT_START_COPYBO;
+ pkt->type = ERT_DEFAULT;
+ pkt->cu_mask[0] = 0;
+ pkt->cu_mask[1] = 0;
+ pkt->cu_mask[2] = 0;
+ pkt->cu_mask[3] = 0;
+ pkt->src_addr_lo = src_offset;
+ pkt->src_addr_hi = (src_offset >> 32) & 0xFFFFFFFF;
+ pkt->src_bo_hdl = src_bo;
+ pkt->dst_addr_lo = dst_offset;
+ pkt->dst_addr_hi = (dst_offset >> 32) & 0xFFFFFFFF;
+ pkt->dst_bo_hdl = dst_bo;
+ pkt->size = size / COPYBO_UNIT;
+}
+
+#endif
diff --git a/drivers/gpu/drm/xocl/version.h b/drivers/gpu/drm/xocl/version.h
new file mode 100644
index 000000000000..bdf3d2c6655a
--- /dev/null
+++ b/drivers/gpu/drm/xocl/version.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Apache-2.0 */
+
+#ifndef _XRT_VERSION_H_
+#define _XRT_VERSION_H_
+
+static const char xrt_build_version[] = "2.2.0";
+
+static const char xrt_build_version_branch[] = "master";
+
+static const char xrt_build_version_hash[] = "2de0f3707ba3b3f1a853006bfd8f75a118907021";
+
+static const char xrt_build_version_hash_date[] = "Mon, 4 Mar 2019 13:26:04 -0800";
+
+static const char xrt_build_version_date_rfc[] = "Mon, 04 Mar 2019 19:33:17 -0800";
+
+static const char xrt_build_version_date[] = "2019-03-04 19:33:17";
+
+static const char xrt_modified_files[] = "";
+
+#define XRT_DRIVER_VERSION "2.2.0,2de0f3707ba3b3f1a853006bfd8f75a118907021"
+
+#endif
diff --git a/drivers/gpu/drm/xocl/xclbin.h b/drivers/gpu/drm/xocl/xclbin.h
new file mode 100644
index 000000000000..4a40e9ab03e7
--- /dev/null
+++ b/drivers/gpu/drm/xocl/xclbin.h
@@ -0,0 +1,314 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Apache-2.0 */
+
+/* Copyright (C) 2015-2019, Xilinx Inc */
+
+#ifndef _XCLBIN_H_
+#define _XCLBIN_H_
+
+#if defined(__KERNEL__)
+#include <linux/types.h>
+#include <linux/uuid.h>
+#include <linux/version.h>
+#elif defined(__cplusplus)
+#include <cstdlib>
+#include <cstdint>
+#include <algorithm>
+#include <uuid/uuid.h>
+#else
+#include <stdlib.h>
+#include <stdint.h>
+#include <uuid/uuid.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /**
+ * Container format for Xilinx bitstreams, metadata and other
+ * binary blobs.
+ * Every segment must be aligned at 8 byte boundary with null byte padding
+ * between adjacent segments if required.
+ * For segements which are not present both offset and length must be 0 in
+ * the header.
+ * Currently only xclbin0\0 is recognized as file magic. In future if/when file
+ * format is updated the magic string will be changed to xclbin1\0 and so on.
+ */
+ enum XCLBIN_MODE {
+ XCLBIN_FLAT,
+ XCLBIN_PR,
+ XCLBIN_TANDEM_STAGE2,
+ XCLBIN_TANDEM_STAGE2_WITH_PR,
+ XCLBIN_HW_EMU,
+ XCLBIN_SW_EMU,
+ XCLBIN_MODE_MAX
+ };
+
+ /*
+ * AXLF LAYOUT
+ * -----------
+ *
+ * -----------------------------------------
+ * | Magic |
+ * -----------------------------------------
+ * | Header |
+ * -----------------------------------------
+ * | One or more section headers |
+ * -----------------------------------------
+ * | Matching number of sections with data |
+ * -----------------------------------------
+ *
+ */
+
+ enum axlf_section_kind {
+ BITSTREAM = 0,
+ CLEARING_BITSTREAM,
+ EMBEDDED_METADATA,
+ FIRMWARE,
+ DEBUG_DATA,
+ SCHED_FIRMWARE,
+ MEM_TOPOLOGY,
+ CONNECTIVITY,
+ IP_LAYOUT,
+ DEBUG_IP_LAYOUT,
+ DESIGN_CHECK_POINT,
+ CLOCK_FREQ_TOPOLOGY,
+ MCS,
+ BMC,
+ BUILD_METADATA,
+ KEYVALUE_METADATA,
+ USER_METADATA,
+ DNA_CERTIFICATE,
+ PDI,
+ BITSTREAM_PARTIAL_PDI
+ };
+
+ enum MEM_TYPE {
+ MEM_DDR3,
+ MEM_DDR4,
+ MEM_DRAM,
+ MEM_STREAMING,
+ MEM_PREALLOCATED_GLOB,
+ MEM_ARE, //Aurora
+ MEM_HBM,
+ MEM_BRAM,
+ MEM_URAM,
+ MEM_STREAMING_CONNECTION
+ };
+
+ enum IP_TYPE {
+ IP_MB = 0,
+ IP_KERNEL, //kernel instance
+ IP_DNASC,
+ IP_DDR4_CONTROLLER
+ };
+
+ struct axlf_section_header {
+ uint32_t m_sectionKind; /* Section type */
+ char m_sectionName[16]; /* Examples: "stage2", "clear1", "clear2", "ocl1", "ocl2, "ublaze", "sched" */
+ uint64_t m_sectionOffset; /* File offset of section data */
+ uint64_t m_sectionSize; /* Size of section data */
+ };
+
+ struct axlf_header {
+ uint64_t m_length; /* Total size of the xclbin file */
+ uint64_t m_timeStamp; /* Number of seconds since epoch when xclbin was created */
+ uint64_t m_featureRomTimeStamp; /* TimeSinceEpoch of the featureRom */
+ uint16_t m_versionPatch; /* Patch Version */
+ uint8_t m_versionMajor; /* Major Version - Version: 2.1.0*/
+ uint8_t m_versionMinor; /* Minor Version */
+ uint32_t m_mode; /* XCLBIN_MODE */
+ union {
+ struct {
+ uint64_t m_platformId; /* 64 bit platform ID: vendor-device-subvendor-subdev */
+ uint64_t m_featureId; /* 64 bit feature id */
+ } rom;
+ unsigned char rom_uuid[16]; /* feature ROM UUID for which this xclbin was generated */
+ };
+ unsigned char m_platformVBNV[64]; /* e.g. xilinx:xil-accel-rd-ku115:4ddr-xpr:3.4: null terminated */
+ union {
+ char m_next_axlf[16]; /* Name of next xclbin file in the daisy chain */
+ uuid_t uuid; /* uuid of this xclbin*/
+ };
+ char m_debug_bin[16]; /* Name of binary with debug information */
+ uint32_t m_numSections; /* Number of section headers */
+ };
+
+ struct axlf {
+ char m_magic[8]; /* Should be "xclbin2\0" */
+ unsigned char m_cipher[32]; /* Hmac output digest */
+ unsigned char m_keyBlock[256]; /* Signature for validation of binary */
+ uint64_t m_uniqueId; /* axlf's uniqueId, use it to skip redownload etc */
+ struct axlf_header m_header; /* Inline header */
+ struct axlf_section_header m_sections[1]; /* One or more section headers follow */
+ };
+
+ typedef struct axlf xclBin;
+
+ /**** BEGIN : Xilinx internal section *****/
+
+ /* bitstream information */
+ struct xlnx_bitstream {
+ uint8_t m_freq[8];
+ char bits[1];
+ };
+
+ /**** MEMORY TOPOLOGY SECTION ****/
+ struct mem_data {
+ uint8_t m_type; //enum corresponding to mem_type.
+ uint8_t m_used; //if 0 this bank is not present
+ union {
+ uint64_t m_size; //if mem_type DDR, then size in KB;
+ uint64_t route_id; //if streaming then "route_id"
+ };
+ union {
+ uint64_t m_base_address;//if DDR then the base address;
+ uint64_t flow_id; //if streaming then "flow id"
+ };
+ unsigned char m_tag[16]; //DDR: BANK0,1,2,3, has to be null terminated; if streaming then stream0, 1 etc
+ };
+
+ struct mem_topology {
+ int32_t m_count; //Number of mem_data
+ struct mem_data m_mem_data[1]; //Should be sorted on mem_type
+ };
+
+ /**** CONNECTIVITY SECTION ****/
+ /* Connectivity of each argument of Kernel. It will be in terms of argument
+ * index associated. For associating kernel instances with arguments and
+ * banks, start at the connectivity section. Using the m_ip_layout_index
+ * access the ip_data.m_name. Now we can associate this kernel instance
+ * with its original kernel name and get the connectivity as well. This
+ * enables us to form related groups of kernel instances.
+ */
+
+ struct connection {
+ int32_t arg_index; //From 0 to n, may not be contiguous as scalars skipped
+ int32_t m_ip_layout_index; //index into the ip_layout section. ip_layout.m_ip_data[index].m_type == IP_KERNEL
+ int32_t mem_data_index; //index of the m_mem_data . Flag error is m_used false.
+ };
+
+ struct connectivity {
+ int32_t m_count;
+ struct connection m_connection[1];
+ };
+
+
+ /**** IP_LAYOUT SECTION ****/
+ /* IPs on AXI lite - their types, names, and base addresses.*/
+ struct ip_data {
+ uint32_t m_type; //map to IP_TYPE enum
+ uint32_t properties; //32 bits to indicate ip specific property. eg if m_type == IP_KERNEL then bit 0 is for interrupt.
+ uint64_t m_base_address;
+ uint8_t m_name[64]; //eg Kernel name corresponding to KERNEL instance, can embed CU name in future.
+ };
+
+ struct ip_layout {
+ int32_t m_count;
+ struct ip_data m_ip_data[1]; //All the ip_data needs to be sorted by m_base_address.
+ };
+
+ /*** Debug IP section layout ****/
+ enum DEBUG_IP_TYPE {
+ UNDEFINED = 0,
+ LAPC,
+ ILA,
+ AXI_MM_MONITOR,
+ AXI_TRACE_FUNNEL,
+ AXI_MONITOR_FIFO_LITE,
+ AXI_MONITOR_FIFO_FULL,
+ ACCEL_MONITOR,
+ AXI_STREAM_MONITOR
+ };
+
+ struct debug_ip_data {
+ uint8_t m_type; // type of enum DEBUG_IP_TYPE
+ uint8_t m_index;
+ uint8_t m_properties;
+ uint8_t m_major;
+ uint8_t m_minor;
+ uint8_t m_reserved[3];
+ uint64_t m_base_address;
+ char m_name[128];
+ };
+
+ struct debug_ip_layout {
+ uint16_t m_count;
+ struct debug_ip_data m_debug_ip_data[1];
+ };
+
+ enum CLOCK_TYPE { /* Supported clock frequency types */
+ CT_UNUSED = 0, /* Initialized value */
+ CT_DATA = 1, /* Data clock */
+ CT_KERNEL = 2, /* Kernel clock */
+ CT_SYSTEM = 3 /* System Clock */
+ };
+
+ struct clock_freq { /* Clock Frequency Entry */
+ u_int16_t m_freq_Mhz; /* Frequency in MHz */
+ u_int8_t m_type; /* Clock type (enum CLOCK_TYPE) */
+ u_int8_t m_unused[5]; /* Not used - padding */
+ char m_name[128]; /* Clock Name */
+ };
+
+ struct clock_freq_topology { /* Clock frequency section */
+ int16_t m_count; /* Number of entries */
+ struct clock_freq m_clock_freq[1]; /* Clock array */
+ };
+
+ enum MCS_TYPE { /* Supported MCS file types */
+ MCS_UNKNOWN = 0, /* Initialized value */
+ MCS_PRIMARY = 1, /* The primary mcs file data */
+ MCS_SECONDARY = 2, /* The secondary mcs file data */
+ };
+
+ struct mcs_chunk { /* One chunk of MCS data */
+ uint8_t m_type; /* MCS data type */
+ uint8_t m_unused[7]; /* padding */
+ uint64_t m_offset; /* data offset from the start of the section */
+ uint64_t m_size; /* data size */
+ };
+
+ struct mcs { /* MCS data section */
+ int8_t m_count; /* Number of chunks */
+ int8_t m_unused[7]; /* padding */
+ struct mcs_chunk m_chunk[1]; /* MCS chunks followed by data */
+ };
+
+ struct bmc { /* bmc data section */
+ uint64_t m_offset; /* data offset from the start of the section */
+ uint64_t m_size; /* data size (bytes)*/
+ char m_image_name[64]; /* Name of the image (e.g., MSP432P401R) */
+ char m_device_name[64]; /* Device ID (e.g., VCU1525) */
+ char m_version[64];
+ char m_md5value[33]; /* MD5 Expected Value(e.g., 56027182079c0bd621761b7dab5a27ca)*/
+ char m_padding[7]; /* Padding */
+ };
+
+ enum CHECKSUM_TYPE
+ {
+ CST_UNKNOWN = 0,
+ CST_SDBM = 1,
+ CST_LAST
+ };
+
+ /**** END : Xilinx internal section *****/
+
+# ifdef __cplusplus
+ namespace xclbin {
+ inline const axlf_section_header*
+ get_axlf_section(const axlf* top, axlf_section_kind kind)
+ {
+ auto begin = top->m_sections;
+ auto end = begin + top->m_header.m_numSections;
+ auto itr = std::find_if(begin,end,[kind](const axlf_section_header& sec) { return sec.m_sectionKind==kind; });
+ return (itr!=end) ? &(*itr) : nullptr;
+ }
+ }
+# endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/gpu/drm/xocl/xclfeatures.h b/drivers/gpu/drm/xocl/xclfeatures.h
new file mode 100644
index 000000000000..3ef2616e061f
--- /dev/null
+++ b/drivers/gpu/drm/xocl/xclfeatures.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Apache-2.0 */
+
+/*
+ * Xilinx SDAccel FPGA BIOS definition
+ * Copyright (C) 2016-2019, Xilinx Inc
+ */
+
+#ifndef xclfeatures_h_
+#define xclfeatures_h_
+
+#define FEATURE_ROM_MAJOR_VERSION 10
+#define FEATURE_ROM_MINOR_VERSION 1
+
+//Layout: At address 0xB0000, we will have the FeatureRomHeader that comprises:
+//
+//1. First have FeatureRomHeader: 152 bytes of information followed by
+//2. Then, as a part of FeatureRomHeader we have the PRRegion struct(s).
+// The number of such structs will be same as OCLRegionCount.
+//3. After this the freq scaling table is laid out.
+//
+
+//#include <stdint.h>
+
+struct PartialRegion {
+ uint16_t clk[4];
+ uint8_t XPR; //0 : non-xpt, 1: xpr
+};
+
+// Each entry represents one row in freq scaling table.
+struct FreqScalingTableRow {
+ short config0;
+ short freq;
+ short config2;
+};
+
+enum PROMType {
+ BPI = 0,
+ SPI = 1
+ //room for 6 more types of flash devices.
+};
+
+enum DebugType {
+ DT_NIFD = 0x01,
+ DT_FIREWALL = 0x02
+ //There is room for future expansion upto 8 IPs
+};
+
+// This bit mask is used with the FeatureBitMap to calculate 64 bool features
+//
+// To test if a feature is provided:
+// FeatureRomHeader header;
+// if (FeatureBitMask::FBM_IS_UNIFIED & header.FeatureBitMap)
+// // it is supported
+// else
+// // it is not supported
+//
+// To set if a feature is provided:
+// header.FeatureBitMap = 0;
+// header.FeatureBitMap |= FeatureBitMask::FBM_IS_UNIFIED;
+//
+enum FeatureBitMask {
+ UNIFIED_PLATFORM = 0x0000000000000001 /* bit 1 : Unified platform */
+ , XARE_ENBLD = 0x0000000000000002 /* bit 2 : Aurora link enabled DSA */
+ , BOARD_MGMT_ENBLD = 0x0000000000000004 /* bit 3 : Has MB based power monitoring */
+ , MB_SCHEDULER = 0x0000000000000008 /* bit 4: Has MB based scheduler */
+ , PROM_MASK = 0x0000000000000070 /* bits 5,6 &7 : 3 bits for PROMType */
+ /** ------ Bit 8 unused **/
+ , DEBUG_MASK = 0x000000000000FF00 /* bits 9 through 16 : 8 bits for DebugType */
+ , PEER_TO_PEER = 0x0000000000010000 /* bits 17 : Bar 2 is a peer to peer bar */
+ , UUID = 0x0000000000020000 /* bits 18 : UUID enabled. uuid[16] field is valid */
+ , HBM = 0x0000000000040000 /* bits 19 : Device has HBM's. */
+ , CDMA = 0x0000000000080000 /* bits 21 : Device has CDMA*/
+ , QDMA = 0x0000000000100000 /* bits 20 : Device has QDMA*/
+
+ //....more
+};
+
+
+// In the following data structures, the EntryPointString, MajorVersion, and MinorVersion
+// values are all used in the Runtime to identify if the ROM is producing valid data, and
+// to pick the schema to read the rest of the data; Ergo, these values shall not change.
+
+/*
+ * Struct used for > 2017.2_sdx
+ * This struct should be used for version (==) 10.0 (Major: 10, Minor: 0)
+ */
+struct FeatureRomHeader {
+ unsigned char EntryPointString[4]; // This is "xlnx"
+ uint8_t MajorVersion; // Feature ROM's major version eg 1
+ uint8_t MinorVersion; // minor version eg 2.
+ // -- DO NOT CHANGE THE TYPES ABOVE THIS LINE --
+ uint32_t VivadoBuildID; // Vivado Software Build (e.g., 1761098 ). From ./vivado --version
+ uint32_t IPBuildID; // IP Build (e.g., 1759159 from abve)
+ uint64_t TimeSinceEpoch; // linux time(NULL) call, at write_dsa_rom invocation
+ unsigned char FPGAPartName[64]; // The hardware FPGA part. Null termninated
+ unsigned char VBNVName[64]; // eg : xilinx:xil-accel-rd-ku115:4ddr-xpr:3.4: null terminated
+ uint8_t DDRChannelCount; // 4 for TUL
+ uint8_t DDRChannelSize; // 4 (in GB)
+ uint64_t DRBaseAddress; // The Dynamic Range's (AppPF/CL/Userspace) Base Address
+ uint64_t FeatureBitMap; // Feature Bit Map, 64 different bool features, maps to enum FeatureBitMask
+ unsigned char uuid[16]; // UUID of the DSA.
+ uint8_t HBMCount; // Number of HBMs
+ uint8_t HBMSize; // Size of (each) HBM in GB
+ uint32_t CDMABaseAddress[4]; // CDMA base addresses
+};
+
+#endif // xclfeatures_h_
diff --git a/drivers/gpu/drm/xocl/xocl_ctx.c b/drivers/gpu/drm/xocl/xocl_ctx.c
new file mode 100644
index 000000000000..4a6c6045c827
--- /dev/null
+++ b/drivers/gpu/drm/xocl/xocl_ctx.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (C) 2018-2019 Xilinx, Inc. All rights reserved.
+ *
+ * Authors: Lizhi.Hou@xxxxxxxxxx
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include "xocl_drv.h"
+
+/*
+ * helper functions to protect driver private data
+ */
+DEFINE_MUTEX(xocl_drvinst_lock);
+struct xocl_drvinst *xocl_drvinst_array[XOCL_MAX_DEVICES * 10];
+
+void *xocl_drvinst_alloc(struct device *dev, u32 size)
+{
+ struct xocl_drvinst *drvinstp;
+ int inst;
+
+ mutex_lock(&xocl_drvinst_lock);
+ for (inst = 0; inst < ARRAY_SIZE(xocl_drvinst_array); inst++)
+ if (!xocl_drvinst_array[inst])
+ break;
+
+ if (inst == ARRAY_SIZE(xocl_drvinst_array))
+ goto failed;
+
+ drvinstp = kzalloc(size + sizeof(struct xocl_drvinst), GFP_KERNEL);
+ if (!drvinstp)
+ goto failed;
+
+ drvinstp->dev = dev;
+ drvinstp->size = size;
+ init_completion(&drvinstp->comp);
+ atomic_set(&drvinstp->ref, 1);
+ INIT_LIST_HEAD(&drvinstp->open_procs);
+
+ xocl_drvinst_array[inst] = drvinstp;
+
+ mutex_unlock(&xocl_drvinst_lock);
+
+ return drvinstp->data;
+
+failed:
+ mutex_unlock(&xocl_drvinst_lock);
+
+ kfree(drvinstp);
+ return NULL;
+}
+
+void xocl_drvinst_free(void *data)
+{
+ struct xocl_drvinst *drvinstp;
+ struct xocl_drvinst_proc *proc, *temp;
+ struct pid *p;
+ int inst;
+ int ret;
+
+ mutex_lock(&xocl_drvinst_lock);
+ drvinstp = container_of(data, struct xocl_drvinst, data);
+ for (inst = 0; inst < ARRAY_SIZE(xocl_drvinst_array); inst++) {
+ if (drvinstp == xocl_drvinst_array[inst])
+ break;
+ }
+
+ /* it must be created before */
+ BUG_ON(inst == ARRAY_SIZE(xocl_drvinst_array));
+
+ xocl_drvinst_array[inst] = NULL;
+ mutex_unlock(&xocl_drvinst_lock);
+
+ /* wait all opened instances to close */
+ if (!atomic_dec_and_test(&drvinstp->ref)) {
+ xocl_info(drvinstp->dev, "Wait for close %p\n",
+ &drvinstp->comp);
+ ret = wait_for_completion_killable(&drvinstp->comp);
+ if (ret == -ERESTARTSYS) {
+ list_for_each_entry_safe(proc, temp,
+ &drvinstp->open_procs, link) {
+ p = find_get_pid(proc->pid);
+ if (!p)
+ continue;
+ ret = kill_pid(p, SIGBUS, 1);
+ if (ret)
+ xocl_err(drvinstp->dev,
+ "kill %d failed",
+ proc->pid);
+ put_pid(p);
+ }
+ wait_for_completion(&drvinstp->comp);
+ }
+ }
+
+ kfree(drvinstp);
+}
+
+void xocl_drvinst_set_filedev(void *data, void *file_dev)
+{
+ struct xocl_drvinst *drvinstp;
+ int inst;
+
+ mutex_lock(&xocl_drvinst_lock);
+ drvinstp = container_of(data, struct xocl_drvinst, data);
+ for (inst = 0; inst < ARRAY_SIZE(xocl_drvinst_array); inst++) {
+ if (drvinstp == xocl_drvinst_array[inst])
+ break;
+ }
+
+ BUG_ON(inst == ARRAY_SIZE(xocl_drvinst_array));
+
+ drvinstp->file_dev = file_dev;
+ mutex_unlock(&xocl_drvinst_lock);
+}
+
+void *xocl_drvinst_open(void *file_dev)
+{
+ struct xocl_drvinst *drvinstp;
+ struct xocl_drvinst_proc *proc;
+ int inst;
+ u32 pid;
+
+ mutex_lock(&xocl_drvinst_lock);
+ for (inst = 0; inst < ARRAY_SIZE(xocl_drvinst_array); inst++) {
+ drvinstp = xocl_drvinst_array[inst];
+ if (drvinstp && file_dev == drvinstp->file_dev)
+ break;
+ }
+
+ if (inst == ARRAY_SIZE(xocl_drvinst_array)) {
+ mutex_unlock(&xocl_drvinst_lock);
+ return NULL;
+ }
+
+ pid = pid_nr(task_tgid(current));
+ list_for_each_entry(proc, &drvinstp->open_procs, link) {
+ if (proc->pid == pid)
+ break;
+ }
+ if (&proc->link == &drvinstp->open_procs) {
+ proc = kzalloc(sizeof(*proc), GFP_KERNEL);
+ if (!proc) {
+ mutex_unlock(&xocl_drvinst_lock);
+ return NULL;
+ }
+ proc->pid = pid;
+ list_add(&proc->link, &drvinstp->open_procs);
+ } else
+ proc->count++;
+ xocl_info(drvinstp->dev, "OPEN %d\n", drvinstp->ref.counter);
+
+ if (atomic_inc_return(&drvinstp->ref) == 2)
+ reinit_completion(&drvinstp->comp);
+
+
+ mutex_unlock(&xocl_drvinst_lock);
+
+ return drvinstp->data;
+}
+
+void xocl_drvinst_close(void *data)
+{
+ struct xocl_drvinst *drvinstp;
+ struct xocl_drvinst_proc *proc;
+ u32 pid;
+
+ mutex_lock(&xocl_drvinst_lock);
+ drvinstp = container_of(data, struct xocl_drvinst, data);
+
+ xocl_info(drvinstp->dev, "CLOSE %d\n", drvinstp->ref.counter);
+
+ pid = pid_nr(task_tgid(current));
+ list_for_each_entry(proc, &drvinstp->open_procs, link) {
+ if (proc->pid == pid)
+ break;
+ }
+
+ if (proc) {
+ proc->count--;
+ if (!proc->count) {
+ list_del(&proc->link);
+ kfree(proc);
+ }
+ }
+
+ if (atomic_dec_return(&drvinstp->ref) == 1) {
+ xocl_info(drvinstp->dev, "NOTIFY %p\n", &drvinstp->comp);
+ complete(&drvinstp->comp);
+ }
+
+ mutex_unlock(&xocl_drvinst_lock);
+}
diff --git a/drivers/gpu/drm/xocl/xocl_drm.h b/drivers/gpu/drm/xocl/xocl_drm.h
new file mode 100644
index 000000000000..de362ee062f6
--- /dev/null
+++ b/drivers/gpu/drm/xocl/xocl_drm.h
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * A GEM style device manager for PCIe based OpenCL accelerators.
+ *
+ * Copyright (C) 2016-2019 Xilinx, Inc. All rights reserved.
+ *
+ * Authors:
+ */
+
+#ifndef _XOCL_DRM_H
+#define _XOCL_DRM_H
+
+#include <linux/hashtable.h>
+
+/**
+ * struct drm_xocl_exec_metadata - Meta data for exec bo
+ *
+ * @state: State of exec buffer object
+ * @active: Reverse mapping to kds command object managed exclusively by kds
+ */
+struct drm_xocl_exec_metadata {
+ enum drm_xocl_execbuf_state state;
+ struct xocl_cmd *active;
+};
+
+struct xocl_drm {
+ xdev_handle_t xdev;
+ /* memory management */
+ struct drm_device *ddev;
+ /* Memory manager array, one per DDR channel */
+ struct drm_mm **mm;
+ struct mutex mm_lock;
+ struct drm_xocl_mm_stat **mm_usage_stat;
+ u64 *mm_p2p_off;
+ DECLARE_HASHTABLE(mm_range, 6);
+};
+
+struct drm_xocl_bo {
+ /* drm base object */
+ struct drm_gem_object base;
+ struct drm_mm_node *mm_node;
+ struct drm_xocl_exec_metadata metadata;
+ struct page **pages;
+ struct sg_table *sgt;
+ void *vmapping;
+ void *bar_vmapping;
+ struct dma_buf *dmabuf;
+ const struct vm_operations_struct *dmabuf_vm_ops;
+ unsigned int dma_nsg;
+ unsigned int flags;
+ unsigned int type;
+};
+
+struct drm_xocl_unmgd {
+ struct page **pages;
+ struct sg_table *sgt;
+ unsigned int npages;
+ unsigned int flags;
+};
+
+struct drm_xocl_bo *xocl_drm_create_bo(struct xocl_drm *drm_p, uint64_t unaligned_size,
+ unsigned int user_flags, unsigned int user_type);
+void xocl_drm_free_bo(struct drm_gem_object *obj);
+
+
+void xocl_mm_get_usage_stat(struct xocl_drm *drm_p, u32 ddr,
+ struct drm_xocl_mm_stat *pstat);
+void xocl_mm_update_usage_stat(struct xocl_drm *drm_p, u32 ddr,
+ u64 size, int count);
+int xocl_mm_insert_node(struct xocl_drm *drm_p, u32 ddr,
+ struct drm_mm_node *node, u64 size);
+void *xocl_drm_init(xdev_handle_t xdev);
+void xocl_drm_fini(struct xocl_drm *drm_p);
+uint32_t xocl_get_shared_ddr(struct xocl_drm *drm_p, struct mem_data *m_data);
+int xocl_init_mem(struct xocl_drm *drm_p);
+void xocl_cleanup_mem(struct xocl_drm *drm_p);
+int xocl_check_topology(struct xocl_drm *drm_p);
+
+int xocl_gem_fault(struct vm_fault *vmf);
+
+static inline struct drm_xocl_bo *to_xocl_bo(struct drm_gem_object *bo)
+{
+ return (struct drm_xocl_bo *)bo;
+}
+
+int xocl_init_unmgd(struct drm_xocl_unmgd *unmgd, uint64_t data_ptr,
+ uint64_t size, u32 write);
+void xocl_finish_unmgd(struct drm_xocl_unmgd *unmgd);
+
+#endif
diff --git a/drivers/gpu/drm/xocl/xocl_drv.h b/drivers/gpu/drm/xocl/xocl_drv.h
new file mode 100644
index 000000000000..c67f3f03feae
--- /dev/null
+++ b/drivers/gpu/drm/xocl/xocl_drv.h
@@ -0,0 +1,783 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * Copyright (C) 2016-2018 Xilinx, Inc. All rights reserved.
+ *
+ * Authors: Lizhi.Hou@xxxxxxxxxx
+ */
+
+#ifndef _XOCL_DRV_H_
+#define _XOCL_DRV_H_
+
+#include <linux/version.h>
+#include <drm/drmP.h>
+#include <drm/drm_gem.h>
+#include <drm/drm_mm.h>
+#include "xclbin.h"
+#include "devices.h"
+#include <drm/xocl_drm.h>
+#include <drm/xmgmt_drm.h>
+
+static inline void xocl_memcpy_fromio(void *buf, void *iomem, u32 size)
+{
+ int i;
+
+ BUG_ON(size & 0x3);
+
+ for (i = 0; i < size / 4; i++)
+ ((u32 *)buf)[i] = ioread32((char *)(iomem) + sizeof(u32) * i);
+}
+
+static inline void xocl_memcpy_toio(void *iomem, void *buf, u32 size)
+{
+ int i;
+
+ BUG_ON(size & 0x3);
+
+ for (i = 0; i < size / 4; i++)
+ iowrite32(((u32 *)buf)[i], ((char *)(iomem) + sizeof(u32) * i));
+}
+
+#define XOCL_MODULE_NAME "xocl"
+#define XCLMGMT_MODULE_NAME "xclmgmt"
+#define ICAP_XCLBIN_V2 "xclbin2"
+
+#define XOCL_MAX_DEVICES 16
+#define XOCL_EBUF_LEN 512
+#define xocl_sysfs_error(xdev, fmt, args...) \
+ snprintf(((struct xocl_dev_core *)xdev)->ebuf, XOCL_EBUF_LEN, \
+ fmt, ##args)
+#define MAX_M_COUNT 64
+
+#define XDEV2DEV(xdev) (&XDEV(xdev)->pdev->dev)
+
+#define xocl_err(dev, fmt, args...) \
+ dev_err(dev, "%s: "fmt, __func__, ##args)
+#define xocl_info(dev, fmt, args...) \
+ dev_info(dev, "%s: "fmt, __func__, ##args)
+#define xocl_dbg(dev, fmt, args...) \
+ dev_dbg(dev, "%s: "fmt, __func__, ##args)
+
+#define xocl_xdev_info(xdev, fmt, args...) \
+ xocl_info(XDEV2DEV(xdev), fmt, ##args)
+#define xocl_xdev_err(xdev, fmt, args...) \
+ xocl_err(XDEV2DEV(xdev), fmt, ##args)
+#define xocl_xdev_dbg(xdev, fmt, args...) \
+ xocl_dbg(XDEV2DEV(xdev), fmt, ##args)
+
+#define XOCL_DRV_VER_NUM(ma, mi, p) \
+ ((ma) * 1000 + (mi) * 100 + (p))
+
+#define XOCL_READ_REG32(addr) \
+ ioread32(addr)
+#define XOCL_WRITE_REG32(val, addr) \
+ iowrite32(val, addr)
+
+/* xclbin helpers */
+#define sizeof_sect(sect, data) \
+({ \
+ size_t ret; \
+ size_t data_size; \
+ data_size = (sect) ? sect->m_count * sizeof(typeof(sect->data)) : 0; \
+ ret = (sect) ? offsetof(typeof(*sect), data) + data_size : 0; \
+ (ret); \
+})
+
+#define XOCL_PL_TO_PCI_DEV(pldev) \
+ to_pci_dev(pldev->dev.parent)
+
+#define XOCL_PL_DEV_TO_XDEV(pldev) \
+ pci_get_drvdata(XOCL_PL_TO_PCI_DEV(pldev))
+
+#define XOCL_QDMA_USER_BAR 2
+#define XOCL_DSA_VERSION(xdev) \
+ (XDEV(xdev)->priv.dsa_ver)
+
+#define XOCL_DSA_IS_MPSOC(xdev) \
+ (XDEV(xdev)->priv.mpsoc)
+
+#define XOCL_DEV_ID(pdev) \
+ ((pci_domain_nr(pdev->bus) << 16) | \
+ PCI_DEVID(pdev->bus->number, pdev->devfn))
+
+#define XOCL_ARE_HOP 0x400000000ull
+
+#define XOCL_XILINX_VEN 0x10EE
+#define XOCL_CHARDEV_REG_COUNT 16
+
+#define INVALID_SUBDEVICE ~0U
+
+#define XOCL_INVALID_MINOR -1
+
+extern struct class *xrt_class;
+
+struct drm_xocl_bo;
+struct client_ctx;
+
+struct xocl_subdev {
+ struct platform_device *pldev;
+ void *ops;
+};
+
+struct xocl_subdev_private {
+ int id;
+ bool is_multi;
+ char priv_data[1];
+};
+
+#define XOCL_GET_SUBDEV_PRIV(dev) \
+ (((struct xocl_subdev_private *)dev_get_platdata(dev))->priv_data)
+
+typedef void *xdev_handle_t;
+
+struct xocl_pci_funcs {
+ int (*intr_config)(xdev_handle_t xdev, u32 intr, bool enable);
+ int (*intr_register)(xdev_handle_t xdev, u32 intr,
+ irq_handler_t handler, void *arg);
+ int (*reset)(xdev_handle_t xdev);
+};
+
+#define XDEV(dev) ((struct xocl_dev_core *)(dev))
+#define XDEV_PCIOPS(xdev) (XDEV(xdev)->pci_ops)
+
+#define xocl_user_interrupt_config(xdev, intr, en) \
+ XDEV_PCIOPS(xdev)->intr_config(xdev, intr, en)
+#define xocl_user_interrupt_reg(xdev, intr, handler, arg) \
+ XDEV_PCIOPS(xdev)->intr_register(xdev, intr, handler, arg)
+#define xocl_reset(xdev) \
+ (XDEV_PCIOPS(xdev)->reset ? XDEV_PCIOPS(xdev)->reset(xdev) : \
+ -ENODEV)
+
+struct xocl_health_thread_arg {
+ int (*health_cb)(void *arg);
+ void *arg;
+ u32 interval; /* ms */
+ struct device *dev;
+};
+
+struct xocl_drvinst_proc {
+ struct list_head link;
+ u32 pid;
+ u32 count;
+};
+
+struct xocl_drvinst {
+ struct device *dev;
+ u32 size;
+ atomic_t ref;
+ struct completion comp;
+ struct list_head open_procs;
+ void *file_dev;
+ char data[1];
+};
+
+struct xocl_dev_core {
+ struct pci_dev *pdev;
+ int dev_minor;
+ struct xocl_subdev subdevs[XOCL_SUBDEV_NUM];
+ u32 subdev_num;
+ struct xocl_pci_funcs *pci_ops;
+
+ u32 bar_idx;
+ void * __iomem bar_addr;
+ resource_size_t bar_size;
+ resource_size_t feature_rom_offset;
+
+ u32 intr_bar_idx;
+ void * __iomem intr_bar_addr;
+ resource_size_t intr_bar_size;
+
+ struct task_struct *health_thread;
+ struct xocl_health_thread_arg thread_arg;
+
+ struct xocl_board_private priv;
+
+ char ebuf[XOCL_EBUF_LEN + 1];
+
+ bool offline;
+};
+
+enum data_kind {
+ MIG_CALIB,
+ DIMM0_TEMP,
+ DIMM1_TEMP,
+ DIMM2_TEMP,
+ DIMM3_TEMP,
+ FPGA_TEMP,
+ VCC_BRAM,
+ CLOCK_FREQ_0,
+ CLOCK_FREQ_1,
+ FREQ_COUNTER_0,
+ FREQ_COUNTER_1,
+ VOL_12V_PEX,
+ VOL_12V_AUX,
+ CUR_12V_PEX,
+ CUR_12V_AUX,
+ SE98_TEMP0,
+ SE98_TEMP1,
+ SE98_TEMP2,
+ FAN_TEMP,
+ FAN_RPM,
+ VOL_3V3_PEX,
+ VOL_3V3_AUX,
+ VPP_BTM,
+ VPP_TOP,
+ VOL_5V5_SYS,
+ VOL_1V2_TOP,
+ VOL_1V2_BTM,
+ VOL_1V8,
+ VCC_0V9A,
+ VOL_12V_SW,
+ VTT_MGTA,
+ VOL_VCC_INT,
+ CUR_VCC_INT,
+ IDCODE,
+ IPLAYOUT_AXLF,
+ MEMTOPO_AXLF,
+ CONNECTIVITY_AXLF,
+ DEBUG_IPLAYOUT_AXLF,
+ PEER_CONN,
+ XCLBIN_UUID,
+};
+
+
+#define XOCL_DSA_PCI_RESET_OFF(xdev_hdl) \
+ (((struct xocl_dev_core *)xdev_hdl)->priv.flags & \
+ XOCL_DSAFLAG_PCI_RESET_OFF)
+#define XOCL_DSA_MB_SCHE_OFF(xdev_hdl) \
+ (((struct xocl_dev_core *)xdev_hdl)->priv.flags & \
+ XOCL_DSAFLAG_MB_SCHE_OFF)
+#define XOCL_DSA_AXILITE_FLUSH_REQUIRED(xdev_hdl) \
+ (((struct xocl_dev_core *)xdev_hdl)->priv.flags & \
+ XOCL_DSAFLAG_AXILITE_FLUSH)
+
+#define XOCL_DSA_XPR_ON(xdev_hdl) \
+ (((struct xocl_dev_core *)xdev_hdl)->priv.xpr)
+
+
+#define SUBDEV(xdev, id) \
+ (XDEV(xdev)->subdevs[id])
+
+/* rom callbacks */
+struct xocl_rom_funcs {
+ unsigned int (*dsa_version)(struct platform_device *pdev);
+ bool (*is_unified)(struct platform_device *pdev);
+ bool (*mb_mgmt_on)(struct platform_device *pdev);
+ bool (*mb_sched_on)(struct platform_device *pdev);
+ uint32_t* (*cdma_addr)(struct platform_device *pdev);
+ u16 (*get_ddr_channel_count)(struct platform_device *pdev);
+ u64 (*get_ddr_channel_size)(struct platform_device *pdev);
+ bool (*is_are)(struct platform_device *pdev);
+ bool (*is_aws)(struct platform_device *pdev);
+ bool (*verify_timestamp)(struct platform_device *pdev, u64 timestamp);
+ u64 (*get_timestamp)(struct platform_device *pdev);
+ void (*get_raw_header)(struct platform_device *pdev, void *header);
+};
+#define ROM_DEV(xdev) \
+ SUBDEV(xdev, XOCL_SUBDEV_FEATURE_ROM).pldev
+#define ROM_OPS(xdev) \
+ ((struct xocl_rom_funcs *)SUBDEV(xdev, XOCL_SUBDEV_FEATURE_ROM).ops)
+#define xocl_dsa_version(xdev) \
+ (ROM_DEV(xdev) ? ROM_OPS(xdev)->dsa_version(ROM_DEV(xdev)) : 0)
+#define xocl_is_unified(xdev) \
+ (ROM_DEV(xdev) ? ROM_OPS(xdev)->is_unified(ROM_DEV(xdev)) : true)
+#define xocl_mb_mgmt_on(xdev) \
+ (ROM_DEV(xdev) ? ROM_OPS(xdev)->mb_mgmt_on(ROM_DEV(xdev)) : false)
+#define xocl_mb_sched_on(xdev) \
+ (ROM_DEV(xdev) ? ROM_OPS(xdev)->mb_sched_on(ROM_DEV(xdev)) : false)
+#define xocl_cdma_addr(xdev) \
+ (ROM_DEV(xdev) ? ROM_OPS(xdev)->cdma_addr(ROM_DEV(xdev)) : 0)
+#define xocl_get_ddr_channel_count(xdev) \
+ (ROM_DEV(xdev) ? ROM_OPS(xdev)->get_ddr_channel_count(ROM_DEV(xdev)) :\
+ 0)
+#define xocl_get_ddr_channel_size(xdev) \
+ (ROM_DEV(xdev) ? ROM_OPS(xdev)->get_ddr_channel_size(ROM_DEV(xdev)) : 0)
+#define xocl_is_are(xdev) \
+ (ROM_DEV(xdev) ? ROM_OPS(xdev)->is_are(ROM_DEV(xdev)) : false)
+#define xocl_is_aws(xdev) \
+ (ROM_DEV(xdev) ? ROM_OPS(xdev)->is_aws(ROM_DEV(xdev)) : false)
+#define xocl_verify_timestamp(xdev, ts) \
+ (ROM_DEV(xdev) ? ROM_OPS(xdev)->verify_timestamp(ROM_DEV(xdev), ts) : \
+ false)
+#define xocl_get_timestamp(xdev) \
+ (ROM_DEV(xdev) ? ROM_OPS(xdev)->get_timestamp(ROM_DEV(xdev)) : 0)
+#define xocl_get_raw_header(xdev, header) \
+ (ROM_DEV(xdev) ? ROM_OPS(xdev)->get_raw_header(ROM_DEV(xdev), header) :\
+ NULL)
+
+/* dma callbacks */
+struct xocl_dma_funcs {
+ ssize_t (*migrate_bo)(struct platform_device *pdev,
+ struct sg_table *sgt, u32 dir, u64 paddr, u32 channel, u64 sz);
+ int (*ac_chan)(struct platform_device *pdev, u32 dir);
+ void (*rel_chan)(struct platform_device *pdev, u32 dir, u32 channel);
+ u32 (*get_chan_count)(struct platform_device *pdev);
+ u64 (*get_chan_stat)(struct platform_device *pdev, u32 channel,
+ u32 write);
+ u64 (*get_str_stat)(struct platform_device *pdev, u32 q_idx);
+ int (*user_intr_config)(struct platform_device *pdev, u32 intr, bool en);
+ int (*user_intr_register)(struct platform_device *pdev, u32 intr,
+ irq_handler_t handler, void *arg, int event_fd);
+ int (*user_intr_unreg)(struct platform_device *pdev, u32 intr);
+ void *(*get_drm_handle)(struct platform_device *pdev);
+};
+
+#define DMA_DEV(xdev) \
+ SUBDEV(xdev, XOCL_SUBDEV_DMA).pldev
+#define DMA_OPS(xdev) \
+ ((struct xocl_dma_funcs *)SUBDEV(xdev, XOCL_SUBDEV_DMA).ops)
+#define xocl_migrate_bo(xdev, sgt, write, paddr, chan, len) \
+ (DMA_DEV(xdev) ? DMA_OPS(xdev)->migrate_bo(DMA_DEV(xdev), \
+ sgt, write, paddr, chan, len) : 0)
+#define xocl_acquire_channel(xdev, dir) \
+ (DMA_DEV(xdev) ? DMA_OPS(xdev)->ac_chan(DMA_DEV(xdev), dir) : \
+ -ENODEV)
+#define xocl_release_channel(xdev, dir, chan) \
+ (DMA_DEV(xdev) ? DMA_OPS(xdev)->rel_chan(DMA_DEV(xdev), dir, \
+ chan) : NULL)
+#define xocl_get_chan_count(xdev) \
+ (DMA_DEV(xdev) ? DMA_OPS(xdev)->get_chan_count(DMA_DEV(xdev)) \
+ : 0)
+#define xocl_get_chan_stat(xdev, chan, write) \
+ (DMA_DEV(xdev) ? DMA_OPS(xdev)->get_chan_stat(DMA_DEV(xdev), \
+ chan, write) : 0)
+#define xocl_dma_intr_config(xdev, irq, en) \
+ (DMA_DEV(xdev) ? DMA_OPS(xdev)->user_intr_config(DMA_DEV(xdev), \
+ irq, en) : -ENODEV)
+#define xocl_dma_intr_register(xdev, irq, handler, arg, event_fd) \
+ (DMA_DEV(xdev) ? DMA_OPS(xdev)->user_intr_register(DMA_DEV(xdev), \
+ irq, handler, arg, event_fd) : -ENODEV)
+#define xocl_dma_intr_unreg(xdev, irq) \
+ (DMA_DEV(xdev) ? DMA_OPS(xdev)->user_intr_unreg(DMA_DEV(xdev), \
+ irq) : -ENODEV)
+#define xocl_dma_get_drm_handle(xdev) \
+ (DMA_DEV(xdev) ? DMA_OPS(xdev)->get_drm_handle(DMA_DEV(xdev)) : \
+ NULL)
+
+/* mb_scheduler callbacks */
+struct xocl_mb_scheduler_funcs {
+ int (*create_client)(struct platform_device *pdev, void **priv);
+ void (*destroy_client)(struct platform_device *pdev, void **priv);
+ uint (*poll_client)(struct platform_device *pdev, struct file *filp,
+ poll_table *wait, void *priv);
+ int (*client_ioctl)(struct platform_device *pdev, int op,
+ void *data, void *drm_filp);
+ int (*stop)(struct platform_device *pdev);
+ int (*reset)(struct platform_device *pdev);
+};
+#define MB_SCHEDULER_DEV(xdev) \
+ SUBDEV(xdev, XOCL_SUBDEV_MB_SCHEDULER).pldev
+#define MB_SCHEDULER_OPS(xdev) \
+ ((struct xocl_mb_scheduler_funcs *)SUBDEV(xdev, \
+ XOCL_SUBDEV_MB_SCHEDULER).ops)
+#define xocl_exec_create_client(xdev, priv) \
+ (MB_SCHEDULER_DEV(xdev) ? \
+ MB_SCHEDULER_OPS(xdev)->create_client(MB_SCHEDULER_DEV(xdev), priv) : \
+ -ENODEV)
+#define xocl_exec_destroy_client(xdev, priv) \
+ (MB_SCHEDULER_DEV(xdev) ? \
+ MB_SCHEDULER_OPS(xdev)->destroy_client(MB_SCHEDULER_DEV(xdev), priv) : \
+ NULL)
+#define xocl_exec_poll_client(xdev, filp, wait, priv) \
+ (MB_SCHEDULER_DEV(xdev) ? \
+ MB_SCHEDULER_OPS(xdev)->poll_client(MB_SCHEDULER_DEV(xdev), filp, \
+ wait, priv) : 0)
+#define xocl_exec_client_ioctl(xdev, op, data, drm_filp) \
+ (MB_SCHEDULER_DEV(xdev) ? \
+ MB_SCHEDULER_OPS(xdev)->client_ioctl(MB_SCHEDULER_DEV(xdev), \
+ op, data, drm_filp) : -ENODEV)
+#define xocl_exec_stop(xdev) \
+ (MB_SCHEDULER_DEV(xdev) ? \
+ MB_SCHEDULER_OPS(xdev)->stop(MB_SCHEDULER_DEV(xdev)) : \
+ -ENODEV)
+#define xocl_exec_reset(xdev) \
+ (MB_SCHEDULER_DEV(xdev) ? \
+ MB_SCHEDULER_OPS(xdev)->reset(MB_SCHEDULER_DEV(xdev)) : \
+ -ENODEV)
+
+#define XOCL_MEM_TOPOLOGY(xdev) \
+ ((struct mem_topology *) \
+ xocl_icap_get_data(xdev, MEMTOPO_AXLF))
+#define XOCL_IP_LAYOUT(xdev) \
+ ((struct ip_layout *) \
+ xocl_icap_get_data(xdev, IPLAYOUT_AXLF))
+
+#define XOCL_IS_DDR_USED(xdev, ddr) \
+ (XOCL_MEM_TOPOLOGY(xdev)->m_mem_data[ddr].m_used == 1)
+#define XOCL_DDR_COUNT_UNIFIED(xdev) \
+ (XOCL_MEM_TOPOLOGY(xdev) ? XOCL_MEM_TOPOLOGY(xdev)->m_count : 0)
+#define XOCL_DDR_COUNT(xdev) \
+ ((xocl_is_unified(xdev) ? XOCL_DDR_COUNT_UNIFIED(xdev) : \
+ xocl_get_ddr_channel_count(xdev)))
+
+/* sysmon callbacks */
+enum {
+ XOCL_SYSMON_PROP_TEMP,
+ XOCL_SYSMON_PROP_TEMP_MAX,
+ XOCL_SYSMON_PROP_TEMP_MIN,
+ XOCL_SYSMON_PROP_VCC_INT,
+ XOCL_SYSMON_PROP_VCC_INT_MAX,
+ XOCL_SYSMON_PROP_VCC_INT_MIN,
+ XOCL_SYSMON_PROP_VCC_AUX,
+ XOCL_SYSMON_PROP_VCC_AUX_MAX,
+ XOCL_SYSMON_PROP_VCC_AUX_MIN,
+ XOCL_SYSMON_PROP_VCC_BRAM,
+ XOCL_SYSMON_PROP_VCC_BRAM_MAX,
+ XOCL_SYSMON_PROP_VCC_BRAM_MIN,
+};
+struct xocl_sysmon_funcs {
+ int (*get_prop)(struct platform_device *pdev, u32 prop, void *val);
+};
+#define SYSMON_DEV(xdev) \
+ SUBDEV(xdev, XOCL_SUBDEV_SYSMON).pldev
+#define SYSMON_OPS(xdev) \
+ ((struct xocl_sysmon_funcs *)SUBDEV(xdev, \
+ XOCL_SUBDEV_SYSMON).ops)
+#define xocl_sysmon_get_prop(xdev, prop, val) \
+ (SYSMON_DEV(xdev) ? SYSMON_OPS(xdev)->get_prop(SYSMON_DEV(xdev), \
+ prop, val) : -ENODEV)
+
+/* firewall callbacks */
+enum {
+ XOCL_AF_PROP_TOTAL_LEVEL,
+ XOCL_AF_PROP_STATUS,
+ XOCL_AF_PROP_LEVEL,
+ XOCL_AF_PROP_DETECTED_STATUS,
+ XOCL_AF_PROP_DETECTED_LEVEL,
+ XOCL_AF_PROP_DETECTED_TIME,
+};
+struct xocl_firewall_funcs {
+ int (*get_prop)(struct platform_device *pdev, u32 prop, void *val);
+ int (*clear_firewall)(struct platform_device *pdev);
+ u32 (*check_firewall)(struct platform_device *pdev, int *level);
+};
+#define AF_DEV(xdev) \
+ SUBDEV(xdev, XOCL_SUBDEV_AF).pldev
+#define AF_OPS(xdev) \
+ ((struct xocl_firewall_funcs *)SUBDEV(xdev, \
+ XOCL_SUBDEV_AF).ops)
+#define xocl_af_get_prop(xdev, prop, val) \
+ (AF_DEV(xdev) ? AF_OPS(xdev)->get_prop(AF_DEV(xdev), prop, val) : \
+ -ENODEV)
+#define xocl_af_check(xdev, level) \
+ (AF_DEV(xdev) ? AF_OPS(xdev)->check_firewall(AF_DEV(xdev), level) : 0)
+#define xocl_af_clear(xdev) \
+ (AF_DEV(xdev) ? AF_OPS(xdev)->clear_firewall(AF_DEV(xdev)) : -ENODEV)
+
+/* microblaze callbacks */
+struct xocl_mb_funcs {
+ void (*reset)(struct platform_device *pdev);
+ int (*stop)(struct platform_device *pdev);
+ int (*load_mgmt_image)(struct platform_device *pdev, const char *buf,
+ u32 len);
+ int (*load_sche_image)(struct platform_device *pdev, const char *buf,
+ u32 len);
+ int (*get_data)(struct platform_device *pdev, enum data_kind kind);
+};
+
+struct xocl_dna_funcs {
+ u32 (*status)(struct platform_device *pdev);
+ u32 (*capability)(struct platform_device *pdev);
+ void (*write_cert)(struct platform_device *pdev, const uint32_t *buf, u32 len);
+};
+
+#define XMC_DEV(xdev) \
+ SUBDEV(xdev, XOCL_SUBDEV_XMC).pldev
+#define XMC_OPS(xdev) \
+ ((struct xocl_mb_funcs *)SUBDEV(xdev, \
+ XOCL_SUBDEV_XMC).ops)
+
+#define DNA_DEV(xdev) \
+ SUBDEV(xdev, XOCL_SUBDEV_DNA).pldev
+#define DNA_OPS(xdev) \
+ ((struct xocl_dna_funcs *)SUBDEV(xdev, \
+ XOCL_SUBDEV_DNA).ops)
+#define xocl_dna_status(xdev) \
+ (DNA_DEV(xdev) ? DNA_OPS(xdev)->status(DNA_DEV(xdev)) : 0)
+#define xocl_dna_capability(xdev) \
+ (DNA_DEV(xdev) ? DNA_OPS(xdev)->capability(DNA_DEV(xdev)) : 2)
+#define xocl_dna_write_cert(xdev, data, len) \
+ (DNA_DEV(xdev) ? DNA_OPS(xdev)->write_cert(DNA_DEV(xdev), data, len) : 0)
+
+#define MB_DEV(xdev) \
+ SUBDEV(xdev, XOCL_SUBDEV_MB).pldev
+#define MB_OPS(xdev) \
+ ((struct xocl_mb_funcs *)SUBDEV(xdev, \
+ XOCL_SUBDEV_MB).ops)
+#define xocl_mb_reset(xdev) \
+ (XMC_DEV(xdev) ? XMC_OPS(xdev)->reset(XMC_DEV(xdev)) : \
+ (MB_DEV(xdev) ? MB_OPS(xdev)->reset(MB_DEV(xdev)) : NULL))
+
+#define xocl_mb_stop(xdev) \
+ (XMC_DEV(xdev) ? XMC_OPS(xdev)->stop(XMC_DEV(xdev)) : \
+ (MB_DEV(xdev) ? MB_OPS(xdev)->stop(MB_DEV(xdev)) : -ENODEV))
+
+#define xocl_mb_load_mgmt_image(xdev, buf, len) \
+ (XMC_DEV(xdev) ? XMC_OPS(xdev)->load_mgmt_image(XMC_DEV(xdev), buf, len) :\
+ (MB_DEV(xdev) ? MB_OPS(xdev)->load_mgmt_image(MB_DEV(xdev), buf, len) :\
+ -ENODEV))
+#define xocl_mb_load_sche_image(xdev, buf, len) \
+ (XMC_DEV(xdev) ? XMC_OPS(xdev)->load_sche_image(XMC_DEV(xdev), buf, len) :\
+ (MB_DEV(xdev) ? MB_OPS(xdev)->load_sche_image(MB_DEV(xdev), buf, len) :\
+ -ENODEV))
+
+#define xocl_xmc_get_data(xdev, cmd) \
+ (XMC_DEV(xdev) ? XMC_OPS(xdev)->get_data(XMC_DEV(xdev), cmd) : -ENODEV)
+
+/*
+ * mailbox callbacks
+ */
+enum mailbox_request {
+ MAILBOX_REQ_UNKNOWN = 0,
+ MAILBOX_REQ_TEST_READY,
+ MAILBOX_REQ_TEST_READ,
+ MAILBOX_REQ_LOCK_BITSTREAM,
+ MAILBOX_REQ_UNLOCK_BITSTREAM,
+ MAILBOX_REQ_HOT_RESET,
+ MAILBOX_REQ_FIREWALL,
+ MAILBOX_REQ_GPCTL,
+ MAILBOX_REQ_LOAD_XCLBIN_KADDR,
+ MAILBOX_REQ_LOAD_XCLBIN,
+ MAILBOX_REQ_RECLOCK,
+ MAILBOX_REQ_PEER_DATA,
+ MAILBOX_REQ_CONN_EXPL,
+};
+
+enum mb_cmd_type {
+ MB_CMD_DEFAULT = 0,
+ MB_CMD_LOAD_XCLBIN,
+ MB_CMD_RECLOCK,
+ MB_CMD_CONN_EXPL,
+ MB_CMD_LOAD_XCLBIN_KADDR,
+ MB_CMD_READ_FROM_PEER,
+};
+struct mailbox_req_bitstream_lock {
+ pid_t pid;
+ uuid_t uuid;
+};
+
+struct mailbox_subdev_peer {
+ enum data_kind kind;
+};
+
+struct mailbox_bitstream_kaddr {
+ uint64_t addr;
+};
+
+struct mailbox_gpctl {
+ enum mb_cmd_type cmd_type;
+ uint32_t data_total_len;
+ uint64_t priv_data;
+ void *data_ptr;
+};
+
+
+struct mailbox_req {
+ enum mailbox_request req;
+ uint32_t data_total_len;
+ uint64_t flags;
+ char data[0];
+};
+
+#define MB_PROT_VER_MAJOR 0
+#define MB_PROT_VER_MINOR 5
+#define MB_PROTOCOL_VER ((MB_PROT_VER_MAJOR<<8) + MB_PROT_VER_MINOR)
+
+#define MB_PEER_CONNECTED 0x1
+#define MB_PEER_SAME_DOM 0x2
+#define MB_PEER_SAMEDOM_CONNECTED (MB_PEER_CONNECTED | MB_PEER_SAME_DOM)
+
+typedef void (*mailbox_msg_cb_t)(void *arg, void *data, size_t len,
+ u64 msgid, int err);
+struct xocl_mailbox_funcs {
+ int (*request)(struct platform_device *pdev, void *req,
+ size_t reqlen, void *resp, size_t *resplen,
+ mailbox_msg_cb_t cb, void *cbarg);
+ int (*post)(struct platform_device *pdev, u64 req_id,
+ void *resp, size_t len);
+ int (*listen)(struct platform_device *pdev,
+ mailbox_msg_cb_t cb, void *cbarg);
+ int (*reset)(struct platform_device *pdev, bool end_of_reset);
+ int (*get_data)(struct platform_device *pdev, enum data_kind kind);
+};
+#define MAILBOX_DEV(xdev) SUBDEV(xdev, XOCL_SUBDEV_MAILBOX).pldev
+#define MAILBOX_OPS(xdev) \
+ ((struct xocl_mailbox_funcs *)SUBDEV(xdev, XOCL_SUBDEV_MAILBOX).ops)
+#define MAILBOX_READY(xdev) (MAILBOX_DEV(xdev) && MAILBOX_OPS(xdev))
+#define xocl_peer_request(xdev, req, reqlen, resp, resplen, cb, cbarg) \
+ (MAILBOX_READY(xdev) ? MAILBOX_OPS(xdev)->request(MAILBOX_DEV(xdev), \
+ req, reqlen, resp, resplen, cb, cbarg) : -ENODEV)
+#define xocl_peer_response(xdev, reqid, buf, len) \
+ (MAILBOX_READY(xdev) ? MAILBOX_OPS(xdev)->post(MAILBOX_DEV(xdev), \
+ reqid, buf, len) : -ENODEV)
+#define xocl_peer_notify(xdev, req, reqlen) \
+ (MAILBOX_READY(xdev) ? MAILBOX_OPS(xdev)->post(MAILBOX_DEV(xdev), 0, \
+ req, reqlen) : -ENODEV)
+#define xocl_peer_listen(xdev, cb, cbarg) \
+ (MAILBOX_READY(xdev) ? MAILBOX_OPS(xdev)->listen(MAILBOX_DEV(xdev), \
+ cb, cbarg) : -ENODEV)
+#define xocl_mailbox_reset(xdev, end) \
+ (MAILBOX_READY(xdev) ? MAILBOX_OPS(xdev)->reset(MAILBOX_DEV(xdev), \
+ end) : -ENODEV)
+#define xocl_mailbox_get_data(xdev, kind) \
+ (MAILBOX_READY(xdev) ? MAILBOX_OPS(xdev)->get_data(MAILBOX_DEV(xdev), kind) \
+ : -ENODEV)
+
+struct xocl_icap_funcs {
+ void (*reset_axi_gate)(struct platform_device *pdev);
+ int (*reset_bitstream)(struct platform_device *pdev);
+ int (*download_bitstream_axlf)(struct platform_device *pdev,
+ const void __user *arg);
+ int (*download_boot_firmware)(struct platform_device *pdev);
+ int (*ocl_set_freq)(struct platform_device *pdev,
+ unsigned int region, unsigned short *freqs, int num_freqs);
+ int (*ocl_get_freq)(struct platform_device *pdev,
+ unsigned int region, unsigned short *freqs, int num_freqs);
+ int (*ocl_update_clock_freq_topology)(struct platform_device *pdev, struct xclmgmt_ioc_freqscaling *freqs);
+ int (*ocl_lock_bitstream)(struct platform_device *pdev,
+ const uuid_t *uuid, pid_t pid);
+ int (*ocl_unlock_bitstream)(struct platform_device *pdev,
+ const uuid_t *uuid, pid_t pid);
+ uint64_t (*get_data)(struct platform_device *pdev,
+ enum data_kind kind);
+};
+#define ICAP_DEV(xdev) SUBDEV(xdev, XOCL_SUBDEV_ICAP).pldev
+#define ICAP_OPS(xdev) \
+ ((struct xocl_icap_funcs *)SUBDEV(xdev, XOCL_SUBDEV_ICAP).ops)
+#define xocl_icap_reset_axi_gate(xdev) \
+ (ICAP_OPS(xdev) ? \
+ ICAP_OPS(xdev)->reset_axi_gate(ICAP_DEV(xdev)) : \
+ NULL)
+#define xocl_icap_reset_bitstream(xdev) \
+ (ICAP_OPS(xdev) ? \
+ ICAP_OPS(xdev)->reset_bitstream(ICAP_DEV(xdev)) : \
+ -ENODEV)
+#define xocl_icap_download_axlf(xdev, xclbin) \
+ (ICAP_OPS(xdev) ? \
+ ICAP_OPS(xdev)->download_bitstream_axlf(ICAP_DEV(xdev), xclbin) : \
+ -ENODEV)
+#define xocl_icap_download_boot_firmware(xdev) \
+ (ICAP_OPS(xdev) ? \
+ ICAP_OPS(xdev)->download_boot_firmware(ICAP_DEV(xdev)) : \
+ -ENODEV)
+#define xocl_icap_ocl_get_freq(xdev, region, freqs, num) \
+ (ICAP_OPS(xdev) ? \
+ ICAP_OPS(xdev)->ocl_get_freq(ICAP_DEV(xdev), region, freqs, num) : \
+ -ENODEV)
+#define xocl_icap_ocl_update_clock_freq_topology(xdev, freqs) \
+ (ICAP_OPS(xdev) ? \
+ ICAP_OPS(xdev)->ocl_update_clock_freq_topology(ICAP_DEV(xdev), freqs) : \
+ -ENODEV)
+#define xocl_icap_ocl_set_freq(xdev, region, freqs, num) \
+ (ICAP_OPS(xdev) ? \
+ ICAP_OPS(xdev)->ocl_set_freq(ICAP_DEV(xdev), region, freqs, num) : \
+ -ENODEV)
+#define xocl_icap_lock_bitstream(xdev, uuid, pid) \
+ (ICAP_OPS(xdev) ? \
+ ICAP_OPS(xdev)->ocl_lock_bitstream(ICAP_DEV(xdev), uuid, pid) : \
+ -ENODEV)
+#define xocl_icap_unlock_bitstream(xdev, uuid, pid) \
+ (ICAP_OPS(xdev) ? \
+ ICAP_OPS(xdev)->ocl_unlock_bitstream(ICAP_DEV(xdev), uuid, pid) : \
+ -ENODEV)
+#define xocl_icap_get_data(xdev, kind) \
+ (ICAP_OPS(xdev) ? \
+ ICAP_OPS(xdev)->get_data(ICAP_DEV(xdev), kind) : \
+ 0)
+
+/* helper functions */
+xdev_handle_t xocl_get_xdev(struct platform_device *pdev);
+void xocl_init_dsa_priv(xdev_handle_t xdev_hdl);
+
+/* subdev functions */
+int xocl_subdev_create_multi_inst(xdev_handle_t xdev_hdl,
+ struct xocl_subdev_info *sdev_info);
+int xocl_subdev_create_one(xdev_handle_t xdev_hdl,
+ struct xocl_subdev_info *sdev_info);
+int xocl_subdev_create_by_id(xdev_handle_t xdev_hdl, int id);
+int xocl_subdev_create_all(xdev_handle_t xdev_hdl,
+ struct xocl_subdev_info *sdev_info, u32 subdev_num);
+void xocl_subdev_destroy_one(xdev_handle_t xdev_hdl, u32 subdev_id);
+void xocl_subdev_destroy_all(xdev_handle_t xdev_hdl);
+void xocl_subdev_destroy_by_id(xdev_handle_t xdev_hdl, int id);
+
+int xocl_subdev_create_by_name(xdev_handle_t xdev_hdl, char *name);
+int xocl_subdev_destroy_by_name(xdev_handle_t xdev_hdl, char *name);
+
+int xocl_subdev_get_devinfo(uint32_t subdev_id,
+ struct xocl_subdev_info *subdev_info, struct resource *res);
+
+void xocl_subdev_register(struct platform_device *pldev, u32 id,
+ void *cb_funcs);
+void xocl_fill_dsa_priv(xdev_handle_t xdev_hdl, struct xocl_board_private *in);
+int xocl_xrt_version_check(xdev_handle_t xdev_hdl,
+ struct axlf *bin_obj, bool major_only);
+int xocl_alloc_dev_minor(xdev_handle_t xdev_hdl);
+void xocl_free_dev_minor(xdev_handle_t xdev_hdl);
+
+/* context helpers */
+extern struct mutex xocl_drvinst_mutex;
+extern struct xocl_drvinst *xocl_drvinst_array[XOCL_MAX_DEVICES * 10];
+
+void *xocl_drvinst_alloc(struct device *dev, u32 size);
+void xocl_drvinst_free(void *data);
+void *xocl_drvinst_open(void *file_dev);
+void xocl_drvinst_close(void *data);
+void xocl_drvinst_set_filedev(void *data, void *file_dev);
+
+/* health thread functions */
+int health_thread_start(xdev_handle_t xdev);
+int health_thread_stop(xdev_handle_t xdev);
+
+/* init functions */
+int __init xocl_init_userpf(void);
+void xocl_fini_fini_userpf(void);
+
+int __init xocl_init_drv_user_qdma(void);
+void xocl_fini_drv_user_qdma(void);
+
+int __init xocl_init_feature_rom(void);
+void xocl_fini_feature_rom(void);
+
+int __init xocl_init_xdma(void);
+void xocl_fini_xdma(void);
+
+int __init xocl_init_qdma(void);
+void xocl_fini_qdma(void);
+
+int __init xocl_init_mb_scheduler(void);
+void xocl_fini_mb_scheduler(void);
+
+int __init xocl_init_xvc(void);
+void xocl_fini_xvc(void);
+
+int __init xocl_init_firewall(void);
+void xocl_fini_firewall(void);
+
+int __init xocl_init_sysmon(void);
+void xocl_fini_sysmon(void);
+
+int __init xocl_init_mb(void);
+void xocl_fini_mb(void);
+
+int __init xocl_init_xiic(void);
+void xocl_fini_xiic(void);
+
+int __init xocl_init_mailbox(void);
+void xocl_fini_mailbox(void);
+
+int __init xocl_init_icap(void);
+void xocl_fini_icap(void);
+
+int __init xocl_init_mig(void);
+void xocl_fini_mig(void);
+
+int __init xocl_init_xmc(void);
+void xocl_fini_xmc(void);
+
+int __init xocl_init_dna(void);
+void xocl_fini_dna(void);
+
+int __init xocl_init_fmgr(void);
+void xocl_fini_fmgr(void);
+#endif
diff --git a/drivers/gpu/drm/xocl/xocl_subdev.c b/drivers/gpu/drm/xocl/xocl_subdev.c
new file mode 100644
index 000000000000..0ade2af180b0
--- /dev/null
+++ b/drivers/gpu/drm/xocl/xocl_subdev.c
@@ -0,0 +1,540 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (C) 2018-2019 Xilinx, Inc. All rights reserved.
+ *
+ * Authors:
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include "xclfeatures.h"
+#include "xocl_drv.h"
+#include "version.h"
+
+struct xocl_subdev_array {
+ xdev_handle_t xdev_hdl;
+ int id;
+ struct platform_device **pldevs;
+ int count;
+};
+
+static DEFINE_IDA(xocl_dev_minor_ida);
+
+static DEFINE_IDA(subdev_multi_inst_ida);
+static struct xocl_dsa_vbnv_map dsa_vbnv_map[] = XOCL_DSA_VBNV_MAP;
+
+static struct platform_device *xocl_register_subdev(xdev_handle_t xdev_hdl,
+ struct xocl_subdev_info *sdev_info, bool multi_inst)
+{
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+ struct platform_device *pldev;
+ struct xocl_subdev_private *priv;
+ resource_size_t iostart;
+ struct resource *res;
+ int sdev_id;
+ int i, retval;
+
+ if (multi_inst) {
+ sdev_id = ida_simple_get(&subdev_multi_inst_ida,
+ 0, 0, GFP_KERNEL);
+ if (sdev_id < 0)
+ return ERR_PTR(-ENOENT);
+ } else {
+ sdev_id = XOCL_DEV_ID(core->pdev);
+ }
+
+ xocl_info(&core->pdev->dev, "creating subdev %s", sdev_info->name);
+ pldev = platform_device_alloc(sdev_info->name, sdev_id);
+ if (!pldev) {
+ xocl_err(&core->pdev->dev, "failed to alloc device %s",
+ sdev_info->name);
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ /* user bar is determined dynamically */
+ iostart = pci_resource_start(core->pdev, core->bar_idx);
+
+ if (sdev_info->num_res > 0) {
+ res = devm_kzalloc(&pldev->dev, sizeof(*res) *
+ sdev_info->num_res, GFP_KERNEL);
+ if (!res) {
+ xocl_err(&pldev->dev, "out of memory");
+ retval = -ENOMEM;
+ goto error;
+ }
+ memcpy(res, sdev_info->res, sizeof(*res) * sdev_info->num_res);
+
+ for (i = 0; i < sdev_info->num_res; i++) {
+ if (sdev_info->res[i].flags & IORESOURCE_MEM) {
+ res[i].start += iostart;
+ res[i].end += iostart;
+ }
+ }
+
+ retval = platform_device_add_resources(pldev,
+ res, sdev_info->num_res);
+ devm_kfree(&pldev->dev, res);
+ if (retval) {
+ xocl_err(&pldev->dev, "failed to add res");
+ goto error;
+ }
+
+ priv = vzalloc(sizeof(*priv) + sdev_info->data_len);
+ if (sdev_info->data_len > 0 && sdev_info->priv_data) {
+ memcpy(priv->priv_data, sdev_info->priv_data,
+ sdev_info->data_len);
+ }
+ priv->id = sdev_info->id;
+ priv->is_multi = multi_inst;
+ retval = platform_device_add_data(pldev,
+ priv, sizeof(*priv) + sdev_info->data_len);
+ vfree(priv);
+ if (retval) {
+ xocl_err(&pldev->dev, "failed to add data");
+ goto error;
+ }
+ }
+
+ pldev->dev.parent = &core->pdev->dev;
+
+ retval = platform_device_add(pldev);
+ if (retval) {
+ xocl_err(&pldev->dev, "failed to add device");
+ goto error;
+ }
+
+ return pldev;
+
+error:
+ platform_device_put(pldev);
+ return NULL;
+}
+
+int xocl_subdev_get_devinfo(uint32_t subdev_id,
+ struct xocl_subdev_info *info, struct resource *res)
+{
+ switch (subdev_id) {
+ case XOCL_SUBDEV_DNA:
+ *info = (struct xocl_subdev_info)XOCL_DEVINFO_DNA;
+ break;
+ case XOCL_SUBDEV_MIG:
+ *info = (struct xocl_subdev_info)XOCL_DEVINFO_MIG;
+ break;
+ default:
+ return -ENODEV;
+ }
+ /* Only support retrieving subdev info with 1 base address and no irq */
+ if (info->num_res > 1)
+ return -EINVAL;
+ *res = *info->res;
+ info->res = res;
+ return 0;
+}
+
+/*
+ * Instantiating a subdevice instance that support > 1 instances.
+ * Restrictions:
+ * 1. it can't expose interfaces for other part of driver to call
+ * 2. one type of subdevice can either be created as single instance or multiple
+ * instance subdevices, but not both.
+ */
+int xocl_subdev_create_multi_inst(xdev_handle_t xdev_hdl,
+ struct xocl_subdev_info *sdev_info)
+{
+ int ret = 0;
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+ struct platform_device *pldev;
+
+ device_lock(&core->pdev->dev);
+ pldev = xocl_register_subdev(core, sdev_info, true);
+ if (!pldev) {
+ xocl_err(&core->pdev->dev,
+ "failed to reg multi instance subdev %s",
+ sdev_info->name);
+ ret = -ENOMEM;
+ }
+ device_unlock(&core->pdev->dev);
+
+ return ret;
+}
+
+int xocl_subdev_create_one(xdev_handle_t xdev_hdl,
+ struct xocl_subdev_info *sdev_info)
+{
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+ struct pci_dev *pdev = core->pdev;
+ u32 id = sdev_info->id;
+ int ret = 0;
+
+ if (core->subdevs[id].pldev)
+ return 0;
+
+ core->subdevs[id].pldev = xocl_register_subdev(core, sdev_info, false);
+ if (!core->subdevs[id].pldev) {
+ xocl_err(&pdev->dev, "failed to register subdev %s",
+ sdev_info->name);
+ ret = -EINVAL;
+ goto failed;
+ }
+ /*
+ * force probe to avoid dependence issue. if probing
+ * failed, it could be this device is not detected on the board.
+ * delete the device.
+ */
+ ret = device_attach(&core->subdevs[id].pldev->dev);
+ if (ret != 1) {
+ xocl_err(&pdev->dev, "failed to probe subdev %s, ret %d",
+ sdev_info->name, ret);
+ ret = -ENODEV;
+ goto failed;
+ }
+ xocl_info(&pdev->dev, "Created subdev %s", sdev_info->name);
+
+ return 0;
+
+failed:
+ return (ret);
+}
+
+int xocl_subdev_create_by_name(xdev_handle_t xdev_hdl, char *name)
+{
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+ int i, n;
+
+ for (i = 0; i < core->priv.subdev_num; i++) {
+ n = strlen(name);
+ if (name[n - 1] == '\n')
+ n--;
+ if (!strncmp(core->priv.subdev_info[i].name, name, n))
+ break;
+ }
+ if (i == core->priv.subdev_num)
+ return -ENODEV;
+
+ return xocl_subdev_create_one(xdev_hdl,
+ &core->priv.subdev_info[i]);
+}
+
+int xocl_subdev_destroy_by_name(xdev_handle_t xdev_hdl, char *name)
+{
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+ int i, n;
+
+ for (i = 0; i < core->priv.subdev_num; i++) {
+ n = strlen(name);
+ if (name[n - 1] == '\n')
+ n--;
+ if (!strncmp(core->priv.subdev_info[i].name, name, n))
+ break;
+ }
+ if (i == core->priv.subdev_num)
+ return -ENODEV;
+
+ xocl_subdev_destroy_one(xdev_hdl, core->priv.subdev_info[i].id);
+
+ return 0;
+}
+
+int xocl_subdev_create_by_id(xdev_handle_t xdev_hdl, int id)
+{
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+ int i;
+
+ for (i = 0; i < core->priv.subdev_num; i++)
+ if (core->priv.subdev_info[i].id == id)
+ break;
+ if (i == core->priv.subdev_num)
+ return -ENOENT;
+
+ return xocl_subdev_create_one(xdev_hdl,
+ &core->priv.subdev_info[i]);
+}
+
+int xocl_subdev_create_all(xdev_handle_t xdev_hdl,
+ struct xocl_subdev_info *sdev_info, u32 subdev_num)
+{
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+ struct FeatureRomHeader rom;
+ u32 id;
+ int i, ret = 0;
+
+ /* lookup update table */
+ ret = xocl_subdev_create_one(xdev_hdl,
+ &(struct xocl_subdev_info)XOCL_DEVINFO_FEATURE_ROM);
+ if (ret)
+ goto failed;
+
+ for (i = 0; i < ARRAY_SIZE(dsa_vbnv_map); i++) {
+ xocl_get_raw_header(core, &rom);
+ if ((core->pdev->vendor == dsa_vbnv_map[i].vendor ||
+ dsa_vbnv_map[i].vendor == (u16)PCI_ANY_ID) &&
+ (core->pdev->device == dsa_vbnv_map[i].device ||
+ dsa_vbnv_map[i].device == (u16)PCI_ANY_ID) &&
+ (core->pdev->subsystem_device ==
+ dsa_vbnv_map[i].subdevice ||
+ dsa_vbnv_map[i].subdevice == (u16)PCI_ANY_ID) &&
+ !strncmp(rom.VBNVName, dsa_vbnv_map[i].vbnv,
+ sizeof(rom.VBNVName))) {
+ sdev_info = dsa_vbnv_map[i].priv_data->subdev_info;
+ subdev_num = dsa_vbnv_map[i].priv_data->subdev_num;
+ xocl_fill_dsa_priv(xdev_hdl, dsa_vbnv_map[i].priv_data);
+ break;
+ }
+ }
+
+ core->subdev_num = subdev_num;
+
+ /* create subdevices */
+ for (i = 0; i < core->subdev_num; i++) {
+ id = sdev_info[i].id;
+ if (core->subdevs[id].pldev)
+ continue;
+
+ ret = xocl_subdev_create_one(xdev_hdl, &sdev_info[i]);
+ if (ret)
+ goto failed;
+ }
+
+ return 0;
+
+failed:
+ xocl_subdev_destroy_all(xdev_hdl);
+ return ret;
+}
+
+void xocl_subdev_destroy_one(xdev_handle_t xdev_hdl, uint32_t subdev_id)
+{
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+
+ if (subdev_id == INVALID_SUBDEVICE)
+ return;
+ if (core->subdevs[subdev_id].pldev) {
+ device_release_driver(&core->subdevs[subdev_id].pldev->dev);
+ platform_device_unregister(core->subdevs[subdev_id].pldev);
+ core->subdevs[subdev_id].pldev = NULL;
+ }
+}
+
+static int match_multi_inst_subdevs(struct device *dev, void *data)
+{
+ struct xocl_subdev_array *subdevs = (struct xocl_subdev_array *)data;
+ struct xocl_dev_core *core = (struct xocl_dev_core *)subdevs->xdev_hdl;
+ struct platform_device *pldev = to_platform_device(dev);
+ struct xocl_subdev_private *priv = dev_get_platdata(dev);
+
+ if (dev->parent == &core->pdev->dev &&
+ priv && priv->is_multi) {
+ if (subdevs->pldevs != NULL)
+ subdevs->pldevs[subdevs->count] = pldev;
+ subdevs->count++;
+ }
+
+ return 0;
+}
+
+static int match_subdev_by_id(struct device *dev, void *data)
+{
+ struct xocl_subdev_array *subdevs = (struct xocl_subdev_array *)data;
+ struct xocl_dev_core *core = (struct xocl_dev_core *)subdevs->xdev_hdl;
+ struct xocl_subdev_private *priv = dev_get_platdata(dev);
+
+ if (dev->parent == &core->pdev->dev &&
+ priv && priv->id == subdevs->id) {
+ if (subdevs->pldevs != NULL)
+ subdevs->pldevs[subdevs->count] =
+ to_platform_device(dev);
+ subdevs->count++;
+ }
+
+ return 0;
+}
+static void xocl_subdev_destroy_common(xdev_handle_t xdev_hdl,
+ int (*match)(struct device *dev, void *data),
+ struct xocl_subdev_array *subdevs)
+{
+ int i;
+ struct xocl_subdev_private *priv;
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+
+ bus_for_each_dev(&platform_bus_type, NULL, subdevs,
+ match);
+ if (subdevs->count == 0)
+ return;
+
+ subdevs->pldevs = vzalloc(sizeof(*subdevs->pldevs) * subdevs->count);
+ if (!subdevs->pldevs)
+ return;
+ subdevs->count = 0;
+
+ bus_for_each_dev(&platform_bus_type, NULL, subdevs,
+ match);
+
+ for (i = 0; i < subdevs->count; i++) {
+ priv = dev_get_platdata(&subdevs->pldevs[i]->dev);
+ if (priv->is_multi)
+ ida_simple_remove(&subdev_multi_inst_ida,
+ subdevs->pldevs[i]->id);
+ else
+ core->subdevs[subdevs->id].pldev = NULL;
+ device_release_driver(&subdevs->pldevs[i]->dev);
+ platform_device_unregister(subdevs->pldevs[i]);
+ }
+
+ vfree(subdevs->pldevs);
+}
+
+void xocl_subdev_destroy_by_id(xdev_handle_t xdev_hdl, int id)
+{
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+ struct xocl_subdev_array subdevs;
+
+ memset(&subdevs, 0, sizeof(subdevs));
+ subdevs.xdev_hdl = xdev_hdl;
+ subdevs.id = id;
+
+ device_lock(&core->pdev->dev);
+ xocl_subdev_destroy_common(xdev_hdl,
+ match_subdev_by_id, &subdevs);
+ device_unlock(&core->pdev->dev);
+}
+void xocl_subdev_destroy_all(xdev_handle_t xdev_hdl)
+{
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+ struct xocl_subdev_array subdevs;
+ int i;
+
+ memset(&subdevs, 0, sizeof(subdevs));
+ subdevs.xdev_hdl = xdev_hdl;
+
+ xocl_subdev_destroy_common(xdev_hdl,
+ match_multi_inst_subdevs, &subdevs);
+
+ for (i = ARRAY_SIZE(core->subdevs) - 1; i >= 0; i--)
+ xocl_subdev_destroy_one(xdev_hdl, i);
+
+ core->subdev_num = 0;
+}
+
+void xocl_subdev_register(struct platform_device *pldev, u32 id,
+ void *cb_funcs)
+{
+ struct xocl_dev_core *core;
+
+ BUG_ON(id >= XOCL_SUBDEV_NUM);
+ core = xocl_get_xdev(pldev);
+ BUG_ON(!core);
+
+ core->subdevs[id].ops = cb_funcs;
+}
+
+xdev_handle_t xocl_get_xdev(struct platform_device *pdev)
+{
+ struct device *dev;
+
+ dev = pdev->dev.parent;
+
+ return dev ? pci_get_drvdata(to_pci_dev(dev)) : NULL;
+}
+
+void xocl_fill_dsa_priv(xdev_handle_t xdev_hdl, struct xocl_board_private *in)
+{
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+ struct pci_dev *pdev = core->pdev;
+ unsigned int i;
+
+ memset(&core->priv, 0, sizeof(core->priv));
+ /*
+ * follow xilinx device id, subsystem id codeing rules to set dsa
+ * private data. And they can be overwrited in subdev header file
+ */
+ if ((pdev->device >> 5) & 0x1)
+ core->priv.xpr = true;
+
+ core->priv.dsa_ver = pdev->subsystem_device & 0xff;
+
+ /* data defined in subdev header */
+ core->priv.subdev_info = in->subdev_info;
+ core->priv.subdev_num = in->subdev_num;
+ core->priv.flags = in->flags;
+ core->priv.flash_type = in->flash_type;
+ core->priv.board_name = in->board_name;
+ core->priv.mpsoc = in->mpsoc;
+ if (in->flags & XOCL_DSAFLAG_SET_DSA_VER)
+ core->priv.dsa_ver = in->dsa_ver;
+ if (in->flags & XOCL_DSAFLAG_SET_XPR)
+ core->priv.xpr = in->xpr;
+
+ for (i = 0; i < in->subdev_num; i++) {
+ if (in->subdev_info[i].id == XOCL_SUBDEV_FEATURE_ROM) {
+ core->feature_rom_offset =
+ in->subdev_info[i].res[0].start;
+ break;
+ }
+ }
+}
+
+int xocl_xrt_version_check(xdev_handle_t xdev_hdl,
+ struct axlf *bin_obj, bool major_only)
+{
+ u32 major, minor, patch;
+ /* check runtime version:
+ * 1. if it is 0.0.xxxx, this implies old xclbin,
+ * we pass the check anyway.
+ * 2. compare major and minor, returns error if it does not match.
+ */
+ if (sscanf(xrt_build_version, "%d.%d.%d", &major, &minor, &patch) != 3)
+ return -ENODEV;
+
+ if (major != bin_obj->m_header.m_versionMajor &&
+ bin_obj->m_header.m_versionMajor != 0)
+ goto err;
+
+ if (major_only)
+ return 0;
+
+ if ((major != bin_obj->m_header.m_versionMajor ||
+ minor != bin_obj->m_header.m_versionMinor) &&
+ !(bin_obj->m_header.m_versionMajor == 0 &&
+ bin_obj->m_header.m_versionMinor == 0))
+ goto err;
+
+ return 0;
+
+err:
+ xocl_err(&XDEV(xdev_hdl)->pdev->dev,
+ "Mismatch xrt version, xrt %s, xclbin %d.%d.%d", xrt_build_version,
+ bin_obj->m_header.m_versionMajor,
+ bin_obj->m_header.m_versionMinor,
+ bin_obj->m_header.m_versionPatch);
+
+ return -EINVAL;
+}
+
+int xocl_alloc_dev_minor(xdev_handle_t xdev_hdl)
+{
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+
+ core->dev_minor = ida_simple_get(&xocl_dev_minor_ida,
+ 0, 0, GFP_KERNEL);
+
+ if (core->dev_minor < 0) {
+ xocl_err(&core->pdev->dev, "Failed to alloc dev minor");
+ core->dev_minor = XOCL_INVALID_MINOR;
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
+void xocl_free_dev_minor(xdev_handle_t xdev_hdl)
+{
+ struct xocl_dev_core *core = (struct xocl_dev_core *)xdev_hdl;
+
+ if (core->dev_minor != XOCL_INVALID_MINOR) {
+ ida_simple_remove(&xocl_dev_minor_ida, core->dev_minor);
+ core->dev_minor = XOCL_INVALID_MINOR;
+ }
+}
diff --git a/drivers/gpu/drm/xocl/xocl_thread.c b/drivers/gpu/drm/xocl/xocl_thread.c
new file mode 100644
index 000000000000..07cce3f5921b
--- /dev/null
+++ b/drivers/gpu/drm/xocl/xocl_thread.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (C) 2017 Xilinx, Inc. All rights reserved.
+ *
+ * Thread to check sysmon/firewall status for errors/issues
+ * Author: Lizhi.Hou@xxxxxxxxxx
+ *
+ */
+
+#include <linux/kthread.h>
+#include "xocl_drv.h"
+
+int health_thread(void *data)
+{
+ struct xocl_health_thread_arg *thread_arg = data;
+
+ while (!kthread_should_stop()) {
+ msleep_interruptible(thread_arg->interval);
+
+ thread_arg->health_cb(thread_arg->arg);
+ }
+ xocl_info(thread_arg->dev, "The health thread has terminated.");
+ return 0;
+}
+
+int health_thread_start(xdev_handle_t xdev)
+{
+ struct xocl_dev_core *core = XDEV(xdev);
+
+ xocl_info(&core->pdev->dev, "init_health_thread");
+ core->health_thread = kthread_run(health_thread, &core->thread_arg,
+ "xocl_health_thread");
+
+ if (IS_ERR(core->health_thread)) {
+ xocl_err(&core->pdev->dev, "ERROR! health thread init");
+ core->health_thread = NULL;
+ return -ENOMEM;
+ }
+
+ core->thread_arg.dev = &core->pdev->dev;
+
+ return 0;
+}
+
+int health_thread_stop(xdev_handle_t xdev)
+{
+ struct xocl_dev_core *core = XDEV(xdev);
+ int ret;
+
+ if (!core->health_thread)
+ return 0;
+
+ ret = kthread_stop(core->health_thread);
+ core->health_thread = NULL;
+
+ xocl_info(&core->pdev->dev, "fini_health_thread. ret = %d\n", ret);
+ if (ret != -EINTR) {
+ xocl_err(&core->pdev->dev, "The health thread has terminated");
+ ret = 0;
+ }
+
+ return ret;
+}
--
2.17.0