Re: [PATCH V4 XRT Alveo 11/20] fpga: xrt: fpga-mgr and region implementation for xclbin download

2021-04-07 Thread Lizhi Hou

Hi Tom,


On 04/01/2021 07:43 AM, Tom Rix wrote:

small alloc's should use kzalloc.

On 3/23/21 10:29 PM, Lizhi Hou wrote:

fpga-mgr and region implementation for xclbin download which will be
called from main platform driver

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/mgmt/fmgr-drv.c| 191 +++
  drivers/fpga/xrt/mgmt/fmgr.h|  19 ++
  drivers/fpga/xrt/mgmt/main-region.c | 483 
  3 files changed, 693 insertions(+)
  create mode 100644 drivers/fpga/xrt/mgmt/fmgr-drv.c
  create mode 100644 drivers/fpga/xrt/mgmt/fmgr.h

a better file name would be xrt-mgr.*

Will change file name to xrt-mgr.*

  create mode 100644 drivers/fpga/xrt/mgmt/main-region.c

diff --git a/drivers/fpga/xrt/mgmt/fmgr-drv.c b/drivers/fpga/xrt/mgmt/fmgr-drv.c
new file mode 100644
index ..12e1cc788ad9
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/fmgr-drv.c
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * FPGA Manager Support for Xilinx Alveo Management Function Driver

Since there is only one fpga mgr for xrt, this could be shortened to

* FPGA Manager Support for Xilinx Alevo

Sure.



+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors: sonal.san...@xilinx.com
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "xclbin-helper.h"
+#include "xleaf.h"
+#include "fmgr.h"
+#include "xleaf/axigate.h"
+#include "xleaf/icap.h"
+#include "xmgnt.h"
+
+struct xfpga_class {
+ const struct platform_device *pdev;
+ char  name[64];
+};
+
+/*
+ * xclbin download plumbing -- find the download subsystem, ICAP and
+ * pass the xclbin for heavy lifting
+ */
+static int xmgmt_download_bitstream(struct platform_device *pdev,
+ const struct axlf *xclbin)
+
+{
+ struct xclbin_bit_head_info bit_header = { 0 };
+ struct platform_device *icap_leaf = NULL;
+ struct xrt_icap_wr arg;
+ char *bitstream = NULL;
+ u64 bit_len;
+ int ret;
+
+ ret = xrt_xclbin_get_section(DEV(pdev), xclbin, BITSTREAM, (void 
**), _len);
+ if (ret) {
+ xrt_err(pdev, "bitstream not found");
+ return -ENOENT;
+ }
+ ret = xrt_xclbin_parse_bitstream_header(DEV(pdev), bitstream,
+ XCLBIN_HWICAP_BITFILE_BUF_SZ,
+ _header);
+ if (ret) {
+ ret = -EINVAL;
+ xrt_err(pdev, "invalid bitstream header");
+ goto fail;
+ }
+ if (bit_header.header_length + bit_header.bitstream_length > bit_len) {
+ ret = -EINVAL;
+ xrt_err(pdev, "invalid bitstream length. header %d, bitstream %d, 
section len %lld",
+ bit_header.header_length, bit_header.bitstream_length, 
bit_len);
+ goto fail;
+ }
+
+ icap_leaf = xleaf_get_leaf_by_id(pdev, XRT_SUBDEV_ICAP, 
PLATFORM_DEVID_NONE);
+ if (!icap_leaf) {
+ ret = -ENODEV;
+ xrt_err(pdev, "icap does not exist");
+ goto fail;
+ }
+ arg.xiiw_bit_data = bitstream + bit_header.header_length;
+ arg.xiiw_data_len = bit_header.bitstream_length;
+ ret = xleaf_call(icap_leaf, XRT_ICAP_WRITE, );
+ if (ret) {
+ xrt_err(pdev, "write bitstream failed, ret = %d", ret);
+ xleaf_put_leaf(pdev, icap_leaf);
+ goto fail;
+ }

ok, free_header removed

+
+ xleaf_put_leaf(pdev, icap_leaf);
+ vfree(bitstream);
+
+ return 0;
+
+fail:
+ vfree(bitstream);
+
+ return ret;
+}
+
+/*
+ * There is no HW prep work we do here since we need the full
+ * xclbin for its sanity check.
+ */
+static int xmgmt_pr_write_init(struct fpga_manager *mgr,
+struct fpga_image_info *info,
+const char *buf, size_t count)
+{
+ const struct axlf *bin = (const struct axlf *)buf;
+ struct xfpga_class *obj = mgr->priv;
+
+ if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
+ xrt_info(obj->pdev, "%s only supports partial reconfiguration\n", 
obj->name);
+ return -EINVAL;
+ }
+
+ if (count < sizeof(struct axlf))
+ return -EINVAL;
+
+ if (count > bin->header.length)
+ return -EINVAL;
+
+ xrt_info(obj->pdev, "Prepare download of xclbin %pUb of length %lld B",
+  >header.uuid, bin->header.length);
+
+ return 0;
+}
+
+/*
+ * The implementation requries full xclbin image before we can start
+ * programming the hardware via ICAP subsystem. The full image is required

ok

+ * for checking the validity of xclbin and walking the sections to
+ * discover the bitstream.
+ */
+static int xmgmt_pr_write(struct fpga_man

Re: [PATCH V4 XRT Alveo 10/20] fpga: xrt: main platform driver for management function device

2021-04-07 Thread Lizhi Hou

Hi Tom,


On 04/01/2021 07:07 AM, Tom Rix wrote:


On 3/23/21 10:29 PM, Lizhi Hou wrote:

platform driver that handles IOCTLs, such as hot reset and xclbin download.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xmgmt-main.h |  34 ++
  drivers/fpga/xrt/mgmt/main.c  | 670 ++
  drivers/fpga/xrt/mgmt/xmgnt.h |  34 ++
  include/uapi/linux/xrt/xmgmt-ioctl.h  |  46 ++
  4 files changed, 784 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xmgmt-main.h
  create mode 100644 drivers/fpga/xrt/mgmt/main.c

'main' is generic, how about xmgnt-main ?

Sure. Will change to xmgnt-main

  create mode 100644 drivers/fpga/xrt/mgmt/xmgnt.h
  create mode 100644 include/uapi/linux/xrt/xmgmt-ioctl.h

diff --git a/drivers/fpga/xrt/include/xmgmt-main.h 
b/drivers/fpga/xrt/include/xmgmt-main.h
new file mode 100644
index ..dce9f0d1a0dc
--- /dev/null
+++ b/drivers/fpga/xrt/include/xmgmt-main.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Cheng Zhen 
+ */
+
+#ifndef _XMGMT_MAIN_H_
+#define _XMGMT_MAIN_H_
+
+#include 
+#include "xleaf.h"
+
+enum xrt_mgmt_main_leaf_cmd {
+ XRT_MGMT_MAIN_GET_AXLF_SECTION = XRT_XLEAF_CUSTOM_BASE, /* See comments 
in xleaf.h */
+ XRT_MGMT_MAIN_GET_VBNV,
+};
+
+/* There are three kind of partitions. Each of them is programmed 
independently. */
+enum provider_kind {
+ XMGMT_BLP, /* Base Logic Partition */
+ XMGMT_PLP, /* Provider Logic Partition */
+ XMGMT_ULP, /* User Logic Partition */

ok

+};
+
+struct xrt_mgmt_main_get_axlf_section {
+ enum provider_kind xmmigas_axlf_kind;
+ enum axlf_section_kind xmmigas_section_kind;
+ void *xmmigas_section;
+ u64 xmmigas_section_size;
+};
+
+#endif   /* _XMGMT_MAIN_H_ */
diff --git a/drivers/fpga/xrt/mgmt/main.c b/drivers/fpga/xrt/mgmt/main.c
new file mode 100644
index ..f3b46e1fd78b
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/main.c
@@ -0,0 +1,670 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA MGMT PF entry point driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Sonal Santan 
+ */
+
+#include 
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+#include "xleaf.h"
+#include 
+#include "xleaf/devctl.h"
+#include "xmgmt-main.h"
+#include "fmgr.h"
+#include "xleaf/icap.h"
+#include "xleaf/axigate.h"
+#include "xmgnt.h"
+
+#define XMGMT_MAIN "xmgmt_main"
+#define XMGMT_SUPP_XCLBIN_MAJOR 2
+
+#define XMGMT_FLAG_FLASH_READY   1
+#define XMGMT_FLAG_DEVCTL_READY  2
+
+#define XMGMT_UUID_STR_LEN   80
+
+struct xmgmt_main {
+ struct platform_device *pdev;
+ struct axlf *firmware_blp;
+ struct axlf *firmware_plp;
+ struct axlf *firmware_ulp;
+ u32 flags;

ok

+ struct fpga_manager *fmgr;
+ struct mutex lock; /* busy lock */

ok

+

do not need this nl

Will remove.

+ uuid_t *blp_interface_uuids;
+ u32 blp_interface_uuid_num;

ok

+};
+
+/*
+ * VBNV stands for Vendor, BoardID, Name, Version. It is a string
+ * which describes board and shell.
+ *
+ * Caller is responsible for freeing the returned string.

ok

+ */
+char *xmgmt_get_vbnv(struct platform_device *pdev)
+{
+ struct xmgmt_main *xmm = platform_get_drvdata(pdev);
+ const char *vbnv;
+ char *ret;
+ int i;
+
+ if (xmm->firmware_plp)
+ vbnv = xmm->firmware_plp->header.platform_vbnv;
+ else if (xmm->firmware_blp)
+ vbnv = xmm->firmware_blp->header.platform_vbnv;
+ else
+ return NULL;
+
+ ret = kstrdup(vbnv, GFP_KERNEL);
+ if (!ret)
+ return NULL;
+
+ for (i = 0; i < strlen(ret); i++) {
+ if (ret[i] == ':' || ret[i] == '.')
+ ret[i] = '_';
+ }
+ return ret;
+}
+
+static int get_dev_uuid(struct platform_device *pdev, char *uuidstr, size_t 
len)
+{
+ struct xrt_devctl_rw devctl_arg = { 0 };
+ struct platform_device *devctl_leaf;
+ char uuid_buf[UUID_SIZE];
+ uuid_t uuid;
+ int err;
+
+ devctl_leaf = xleaf_get_leaf_by_epname(pdev, XRT_MD_NODE_BLP_ROM);
+ if (!devctl_leaf) {
+ xrt_err(pdev, "can not get %s", XRT_MD_NODE_BLP_ROM);
+ return -EINVAL;
+ }
+
+ devctl_arg.xdr_id = XRT_DEVCTL_ROM_UUID;
+ devctl_arg.xdr_buf = uuid_buf;
+ devctl_arg.xdr_len = sizeof(uuid_buf);
+ devctl_arg.xdr_offset = 0;
+ err = xleaf_call(devctl_leaf, XRT_DEVCTL_READ, _arg);
+ xleaf_put_leaf(pdev, devctl_leaf);
+ if (err) {
+ xrt_err(pdev, "can not get uuid: %d", err);
+ return err;
+ }
+ import_uuid(, uuid_buf);

ok

+ xrt_md_trans_uuid2str(, uuidstr);
+
+ return 0;
+}
+
+int xmgmt_hot_reset(stru

Re: [PATCH V4 XRT Alveo 20/20] fpga: xrt: Kconfig and Makefile updates for XRT drivers

2021-04-06 Thread Lizhi Hou

Hi Tom,


On 04/06/2021 02:00 PM, Tom Rix wrote:


On 3/23/21 10:29 PM, Lizhi Hou wrote:

Update fpga Kconfig/Makefile and add Kconfig/Makefile for new drivers.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  MAINTAINERS| 11 +++
  drivers/Makefile   |  1 +
  drivers/fpga/Kconfig   |  2 ++
  drivers/fpga/Makefile  |  5 +
  drivers/fpga/xrt/Kconfig   |  8 
  drivers/fpga/xrt/lib/Kconfig   | 17 +
  drivers/fpga/xrt/lib/Makefile  | 30 ++
  drivers/fpga/xrt/metadata/Kconfig  | 12 
  drivers/fpga/xrt/metadata/Makefile | 16 
  drivers/fpga/xrt/mgmt/Kconfig  | 15 +++
  drivers/fpga/xrt/mgmt/Makefile | 19 +++
  11 files changed, 136 insertions(+)
  create mode 100644 drivers/fpga/xrt/Kconfig
  create mode 100644 drivers/fpga/xrt/lib/Kconfig
  create mode 100644 drivers/fpga/xrt/lib/Makefile
  create mode 100644 drivers/fpga/xrt/metadata/Kconfig
  create mode 100644 drivers/fpga/xrt/metadata/Makefile
  create mode 100644 drivers/fpga/xrt/mgmt/Kconfig
  create mode 100644 drivers/fpga/xrt/mgmt/Makefile

diff --git a/MAINTAINERS b/MAINTAINERS
index aa84121c5611..44ccc52987ac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7009,6 +7009,17 @@ F: Documentation/fpga/
  F:  drivers/fpga/
  F:  include/linux/fpga/

+FPGA XRT DRIVERS
+M:   Lizhi Hou 
+R:   Max Zhen 
+R:   Sonal Santan 
+L:   linux-f...@vger.kernel.org
+S:   Maintained

Should this be 'Supported' ?

Sure.

+W:   https://github.com/Xilinx/XRT
+F:   Documentation/fpga/xrt.rst
+F:   drivers/fpga/xrt/
+F:   include/uapi/linux/xrt/
+
  FPU EMULATOR
  M:  Bill Metzenthen 
  S:  Maintained
diff --git a/drivers/Makefile b/drivers/Makefile
index 6fba7daba591..dbb3b727fc7a 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -179,6 +179,7 @@ obj-$(CONFIG_STM) += hwtracing/stm/
  obj-$(CONFIG_ANDROID)   += android/
  obj-$(CONFIG_NVMEM) += nvmem/
  obj-$(CONFIG_FPGA)  += fpga/
+obj-$(CONFIG_FPGA_XRT_METADATA) += fpga/

CONFIG_FPGA_XRT_METADATA is only defined when CONFIG_FPGA is, so i don't
think this line is needed.

CONFIG_FPGA could be 'm'.
And as we discussed before, CONFIG_FPGA_XRT_METADATA extending fdt_* can 
be only build in kernel ('y'). Maybe it can not rely on CONFIG_FPGA?

  obj-$(CONFIG_FSI)   += fsi/
  obj-$(CONFIG_TEE)   += tee/
  obj-$(CONFIG_MULTIPLEXER)   += mux/
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 5ff9438b7b46..01410ff000b9 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -227,4 +227,6 @@ config FPGA_MGR_ZYNQMP_FPGA
to configure the programmable logic(PL) through PS
on ZynqMP SoC.

+source "drivers/fpga/xrt/Kconfig"
+
  endif # FPGA

This is where it is defined..

diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 18dc9885883a..4b887bf95cb3 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -48,3 +48,8 @@ obj-$(CONFIG_FPGA_DFL_NIOS_INTEL_PAC_N3000) += 
dfl-n3000-nios.o


  # Drivers for FPGAs which implement DFL
  obj-$(CONFIG_FPGA_DFL_PCI)  += dfl-pci.o
+
+# XRT drivers for Alveo
+obj-$(CONFIG_FPGA_XRT_METADATA)  += xrt/metadata/
+obj-$(CONFIG_FPGA_XRT_LIB)   += xrt/lib/
+obj-$(CONFIG_FPGA_XRT_XMGMT) += xrt/mgmt/
diff --git a/drivers/fpga/xrt/Kconfig b/drivers/fpga/xrt/Kconfig
new file mode 100644
index ..0e2c59589ddd
--- /dev/null
+++ b/drivers/fpga/xrt/Kconfig
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Xilinx Alveo FPGA device configuration
+#
+
+source "drivers/fpga/xrt/metadata/Kconfig"
+source "drivers/fpga/xrt/lib/Kconfig"
+source "drivers/fpga/xrt/mgmt/Kconfig"
diff --git a/drivers/fpga/xrt/lib/Kconfig b/drivers/fpga/xrt/lib/Kconfig
new file mode 100644
index ..935369fad570
--- /dev/null
+++ b/drivers/fpga/xrt/lib/Kconfig
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# XRT Alveo FPGA device configuration
+#
+
+config FPGA_XRT_LIB
+ tristate "XRT Alveo Driver Library"
+ depends on HWMON && PCI && HAS_IOMEM
+ select FPGA_XRT_METADATA
+ select REGMAP_MMIO
+ help
+   Select this option to enable Xilinx XRT Alveo driver library. 
This

+   library is core infrastructure of XRT Alveo FPGA drivers which
+   provides functions for working with device nodes, iteration and
+   lookup of platform devices, common interfaces for platform 
devices,
+   plumbing of function call and ioctls between platform devices 
and

+   parent partitions.
diff --git a/drivers/fpga/xrt/lib/Makefile 
b/drivers/fpga/xrt/lib/Makefile

new file mode 100644
index ..58563416efbf
--- /dev/null
+++ b/drivers/fpga/xrt/lib/Makefile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-

Re: [PATCH V4 XRT Alveo 14/20] fpga: xrt: ICAP platform driver

2021-04-06 Thread Lizhi Hou

Hi Tom,


On 04/06/2021 06:50 AM, Tom Rix wrote:



On 3/23/21 10:29 PM, Lizhi Hou wrote:

ICAP stands for Hardware Internal Configuration Access Port. ICAP is
discovered by walking firmware metadata. A platform device node will be

by walking the firmware

Sure.

created for it. FPGA bitstream is written to hardware through ICAP.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xleaf/icap.h |  27 ++
  drivers/fpga/xrt/lib/xleaf/icap.c | 344 ++
  2 files changed, 371 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xleaf/icap.h
  create mode 100644 drivers/fpga/xrt/lib/xleaf/icap.c

diff --git a/drivers/fpga/xrt/include/xleaf/icap.h 
b/drivers/fpga/xrt/include/xleaf/icap.h

new file mode 100644
index ..96d39a8934fa
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/icap.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Lizhi Hou 
+ */
+
+#ifndef _XRT_ICAP_H_
+#define _XRT_ICAP_H_
+
+#include "xleaf.h"
+
+/*
+ * ICAP driver leaf calls.
+ */
+enum xrt_icap_leaf_cmd {
+ XRT_ICAP_WRITE = XRT_XLEAF_CUSTOM_BASE, /* See comments in 
xleaf.h */

+ XRT_ICAP_GET_IDCODE,

ok

+};
+
+struct xrt_icap_wr {
+ void*xiiw_bit_data;
+ u32 xiiw_data_len;
+};
+
+#endif   /* _XRT_ICAP_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/icap.c 
b/drivers/fpga/xrt/lib/xleaf/icap.c

new file mode 100644
index ..13db2b759138
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/icap.c
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA ICAP Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ *  Sonal Santan 
+ *  Max Zhen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/icap.h"
+#include "xclbin-helper.h"
+
+#define XRT_ICAP "xrt_icap"
+
+#define ICAP_ERR(icap, fmt, arg...)  \
+ xrt_err((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_WARN(icap, fmt, arg...) \
+ xrt_warn((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_INFO(icap, fmt, arg...) \
+ xrt_info((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_DBG(icap, fmt, arg...)  \
+ xrt_dbg((icap)->pdev, fmt "\n", ##arg)
+
+/*
+ * AXI-HWICAP IP register layout. Please see
+ * 
https://www.xilinx.com/support/documentation/ip_documentation/axi_hwicap/v3_0/pg134-axi-hwicap.pdf

url works, looks good

+ */
+#define ICAP_REG_GIER0x1C
+#define ICAP_REG_ISR 0x20
+#define ICAP_REG_IER 0x28
+#define ICAP_REG_WF  0x100
+#define ICAP_REG_RF  0x104
+#define ICAP_REG_SZ  0x108
+#define ICAP_REG_CR  0x10C
+#define ICAP_REG_SR  0x110
+#define ICAP_REG_WFV 0x114
+#define ICAP_REG_RFO 0x118
+#define ICAP_REG_ASR 0x11C
+
+#define ICAP_STATUS_EOS  0x4
+#define ICAP_STATUS_DONE 0x1
+
+/*
+ * Canned command sequence to obtain IDCODE of the FPGA
+ */
+static const u32 idcode_stream[] = {
+ /* dummy word */
+ cpu_to_be32(0x),
+ /* sync word */
+ cpu_to_be32(0xaa995566),
+ /* NOP word */
+ cpu_to_be32(0x2000),
+ /* NOP word */
+ cpu_to_be32(0x2000),
+ /* ID code */
+ cpu_to_be32(0x28018001),
+ /* NOP word */
+ cpu_to_be32(0x2000),
+ /* NOP word */
+ cpu_to_be32(0x2000),
+};
+
+static const struct regmap_config icap_regmap_config = {

ok

+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = 0x1000,
+};
+
+struct icap {
+ struct platform_device  *pdev;
+ struct regmap   *regmap;
+ struct mutexicap_lock; /* icap dev lock */
+

whitespace, remove extra nl

Sure.

Thanks,
Lizhi

+ u32 idcode;
+};
+
+static int wait_for_done(const struct icap *icap)
+{
+ int i = 0;
+ int ret;
+ u32 w;
+
+ for (i = 0; i < 10; i++) {
+ /*
+  * it requires few micro seconds for ICAP to process 
incoming data.

+  * Polling every 5us for 10 times would be good enough.

ok

+  */
+ udelay(5);
+ ret = regmap_read(icap->regmap, ICAP_REG_SR, );
+ if (ret)
+ return ret;
+ ICAP_INFO(icap, "XHWICAP_SR: %x", w);
+ if (w & (ICAP_STATUS_EOS | ICAP_STATUS_DONE))

ok

+ return 0;
+ }
+
+ ICAP_ERR(icap, "bitstream download timeout");
+ return -ETIMEDOUT;
+}
+
+static int icap_write(const struct icap *icap, const u32 *word_buf, 
int size)

+{
+ u32 value = 0;
+ int ret;
+ int i;
+
+ for (i = 0; i < size; i++) {
+ value = be32_to_cpu(word_buf[i]);

Re: [PATCH V4 XRT Alveo 12/20] fpga: xrt: VSEC platform driver

2021-04-06 Thread Lizhi Hou




On 04/02/2021 07:12 AM, Tom Rix wrote:

CAUTION: This message has originated from an External Source. Please use proper 
judgment and caution when opening attachments, clicking links, or responding to 
this email.


local use of 'regmap' conflicts with global meaning.

reword local regmap to something else.

Will change local regmap to 'compat'.


On 3/23/21 10:29 PM, Lizhi Hou wrote:

Add VSEC driver. VSEC is a hardware function discovered by walking
PCI Express configure space. A platform device node will be created
for it. VSEC provides board logic UUID and few offset of other hardware
functions.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/lib/xleaf/vsec.c | 388 ++
  1 file changed, 388 insertions(+)
  create mode 100644 drivers/fpga/xrt/lib/xleaf/vsec.c

diff --git a/drivers/fpga/xrt/lib/xleaf/vsec.c 
b/drivers/fpga/xrt/lib/xleaf/vsec.c
new file mode 100644
index ..8595d23f5710
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/vsec.c
@@ -0,0 +1,388 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA VSEC Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+
+#define XRT_VSEC "xrt_vsec"
+
+#define VSEC_TYPE_UUID   0x50
+#define VSEC_TYPE_FLASH  0x51
+#define VSEC_TYPE_PLATINFO   0x52
+#define VSEC_TYPE_MAILBOX0x53
+#define VSEC_TYPE_END0xff
+
+#define VSEC_UUID_LEN16
+
+#define VSEC_REG_FORMAT  0x0
+#define VSEC_REG_LENGTH  0x4
+#define VSEC_REG_ENTRY   0x8
+
+struct xrt_vsec_header {
+ u32 format;
+ u32 length;
+ u32 entry_sz;
+ u32 rsvd;
+} __packed;
+
+struct xrt_vsec_entry {
+ u8  type;
+ u8  bar_rev;
+ u16 off_lo;
+ u32 off_hi;
+ u8  ver_type;
+ u8  minor;
+ u8  major;
+ u8  rsvd0;
+ u32 rsvd1;
+} __packed;
+
+struct vsec_device {
+ u8  type;
+ char*ep_name;
+ ulong   size;
+ char*regmap;

This element should be 'char *name;' as regmap is a different thing.

Will change to 'compat'.



+};
+
+static struct vsec_device vsec_devs[] = {
+ {
+ .type = VSEC_TYPE_UUID,
+ .ep_name = XRT_MD_NODE_BLP_ROM,
+ .size = VSEC_UUID_LEN,
+ .regmap = "vsec-uuid",
+ },
+ {
+ .type = VSEC_TYPE_FLASH,
+ .ep_name = XRT_MD_NODE_FLASH_VSEC,
+ .size = 4096,
+ .regmap = "vsec-flash",
+ },
+ {
+ .type = VSEC_TYPE_PLATINFO,
+ .ep_name = XRT_MD_NODE_PLAT_INFO,
+ .size = 4,
+ .regmap = "vsec-platinfo",
+ },
+ {
+ .type = VSEC_TYPE_MAILBOX,
+ .ep_name = XRT_MD_NODE_MAILBOX_VSEC,
+ .size = 48,
+ .regmap = "vsec-mbx",
+ },
+};
+
+static const struct regmap_config vsec_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = 0x1000,

At least 0x1000 could be #define, maybe all.

Will #define all of them.

+};
+
+struct xrt_vsec {
+ struct platform_device  *pdev;
+ struct regmap   *regmap;
+ u32 length;
+
+ char*metadata;
+ charuuid[VSEC_UUID_LEN];
+ int group;
+};
+
+static inline int vsec_read_entry(struct xrt_vsec *vsec, u32 index, struct 
xrt_vsec_entry *entry)
+{
+ int ret;
+
+ ret = regmap_bulk_read(vsec->regmap, sizeof(struct xrt_vsec_header) +
+index * sizeof(struct xrt_vsec_entry), entry,
+sizeof(struct xrt_vsec_entry) /
+vsec_regmap_config.reg_stride);
+
+ return ret;
+}
+
+static inline u32 vsec_get_bar(struct xrt_vsec_entry *entry)
+{
+ return ((entry)->bar_rev >> 4) & 0xf;

The extra () were needed when this was a macro, they aren't now.

remove here and the next 2 functions.

will remove ().



+}
+
+static inline u64 vsec_get_bar_off(struct xrt_vsec_entry *entry)
+{
+ return (entry)->off_lo | ((u64)(entry)->off_hi << 16);
+}
+
+static inline u32 vsec_get_rev(struct xrt_vsec_entry *entry)
+{
+ return (entry)->bar_rev & 0xf;
+}
+
+static char *type2epname(u32 type)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vsec_devs); i++) {
+ if (vsec_devs[i].type == type)
+ return (vsec_devs[i].ep_name);
+ }
+
+ return NULL;
+}
+
+static ulong type2size(u32 type)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(

Re: [PATCH V4 XRT Alveo 03/20] fpga: xrt: xclbin file helper functions

2021-04-06 Thread Lizhi Hou

Hi Tom,


On 03/29/2021 10:12 AM, Tom Rix wrote:

On 3/23/21 10:29 PM, Lizhi Hou wrote:

Alveo FPGA firmware and partial reconfigure file are in xclbin format. This
code enumerates and extracts sections from xclbin files. xclbin.h is cross
platform and used across all platforms and OS.

ok

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xclbin-helper.h |  48 +++
  drivers/fpga/xrt/lib/xclbin.c| 369 
  include/uapi/linux/xrt/xclbin.h  | 409 +++
  3 files changed, 826 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xclbin-helper.h
  create mode 100644 drivers/fpga/xrt/lib/xclbin.c
  create mode 100644 include/uapi/linux/xrt/xclbin.h

diff --git a/drivers/fpga/xrt/include/xclbin-helper.h 
b/drivers/fpga/xrt/include/xclbin-helper.h
new file mode 100644
index ..382b1de97b0a
--- /dev/null
+++ b/drivers/fpga/xrt/include/xclbin-helper.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *David Zhang 
+ *Sonal Santan 
+ */
+
+#ifndef _XCLBIN_HELPER_H_
+#define _XCLBIN_HELPER_H_

ok

+
+#include 
+#include 
+#include 
+
+#define XCLBIN_VERSION2  "xclbin2"
+#define XCLBIN_HWICAP_BITFILE_BUF_SZ 1024
+#define XCLBIN_MAX_SIZE (1024 * 1024 * 1024) /* Assuming xclbin <= 1G, always 
*/

ok

+
+enum axlf_section_kind;
+struct axlf;
+
+/**
+ * Bitstream header information as defined by Xilinx tools.
+ * Please note that this struct definition is not owned by the driver.
+ */
+struct xclbin_bit_head_info {
+ u32 header_length;  /* Length of header in 32 bit words */
+ u32 bitstream_length;   /* Length of bitstream to read in bytes */
+ const unchar *design_name;  /* Design name get from bitstream */
+ const unchar *part_name;/* Part name read from bitstream */
+ const unchar *date; /* Date read from bitstream header */
+ const unchar *time; /* Bitstream creation time */
+ u32 magic_length;   /* Length of the magic numbers */
+ const unchar *version;  /* Version string */
+};
+

ok, bit removed.

+/* caller must free the allocated memory for **data. len could be NULL. */
+int xrt_xclbin_get_section(struct device *dev,  const struct axlf *xclbin,
+enum axlf_section_kind kind, void **data,
+uint64_t *len);

need to add comment that user must free data

need to add comment that len is optional

It sounds the comment above the function.

/* caller must free the allocated memory for **data. len could be NULL. 
*/

Do you mean I need to add more detail or format the comment in different way?




+int xrt_xclbin_get_metadata(struct device *dev, const struct axlf *xclbin, 
char **dtb);
+int xrt_xclbin_parse_bitstream_header(struct device *dev, const unchar *data,
+   u32 size, struct xclbin_bit_head_info 
*head_info);
+const char *xrt_clock_type2epname(enum XCLBIN_CLOCK_TYPE type);

ok

+
+#endif /* _XCLBIN_HELPER_H_ */
diff --git a/drivers/fpga/xrt/lib/xclbin.c b/drivers/fpga/xrt/lib/xclbin.c
new file mode 100644
index ..31b363c014a3
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xclbin.c
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Driver XCLBIN parser
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors: David Zhang 
+ */
+
+#include 
+#include 
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+
+/* Used for parsing bitstream header */
+#define BITSTREAM_EVEN_MAGIC_BYTE0x0f
+#define BITSTREAM_ODD_MAGIC_BYTE 0xf0

ok

+
+static int xrt_xclbin_get_section_hdr(const struct axlf *xclbin,
+   enum axlf_section_kind kind,
+   const struct axlf_section_header **header)
+{
+ const struct axlf_section_header *phead = NULL;
+ u64 xclbin_len;
+ int i;
+
+ *header = NULL;
+ for (i = 0; i < xclbin->header.num_sections; i++) {
+ if (xclbin->sections[i].section_kind == kind) {
+ phead = >sections[i];
+ break;
+ }
+ }
+
+ if (!phead)
+ return -ENOENT;
+
+ xclbin_len = xclbin->header.length;
+ if (xclbin_len > XCLBIN_MAX_SIZE ||
+ phead->section_offset + phead->section_size > xclbin_len)
+ return -EINVAL;
+
+ *header = phead;
+ return 0;
+}
+
+static int xrt_xclbin_section_info(const struct axlf *xclbin,
+enum axlf_section_kind kind,
+u64 *offset, u64 *size)
+{
+ const struct axlf_section_header *mem_header = NULL;
+ int rc;
+
+ rc = xrt_xclbin_get_section_hdr(xclbin, kind, _header);
+ if (rc)
+ return r

Re: [PATCH V4 XRT Alveo 02/20] fpga: xrt: driver metadata helper functions

2021-04-05 Thread Lizhi Hou

Hi Tom,


On 03/28/2021 08:30 AM, Tom Rix wrote:

Do not reorder function definitions, this makes comparing changes from the 
previous patchset difficult.

A general issue with returning consistent error codes.  There are several cases 
where fdt_* code are not translated.

Sure. Will fix.


On 3/23/21 10:29 PM, Lizhi Hou wrote:

XRT drivers use device tree as metadata format to discover HW subsystems
behind PCIe BAR. Thus libfdt functions are called for the driver to parse
device tree blob.

to parse the device

Will fix

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/metadata.h  | 233 
  drivers/fpga/xrt/metadata/metadata.c | 545 +++
  2 files changed, 778 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/metadata.h
  create mode 100644 drivers/fpga/xrt/metadata/metadata.c

diff --git a/drivers/fpga/xrt/include/metadata.h 
b/drivers/fpga/xrt/include/metadata.h
new file mode 100644
index ..479e47960c61
--- /dev/null
+++ b/drivers/fpga/xrt/include/metadata.h
@@ -0,0 +1,233 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou 
+ */
+
+#ifndef _XRT_METADATA_H
+#define _XRT_METADATA_H
+
+#include 
+#include 
+#include 
+
+#define XRT_MD_INVALID_LENGTH (~0UL)
+
+/* metadata properties */
+#define XRT_MD_PROP_BAR_IDX "pcie_bar_mapping"
+#define XRT_MD_PROP_COMPATIBLE "compatible"
+#define XRT_MD_PROP_HWICAP "axi_hwicap"
+#define XRT_MD_PROP_INTERFACE_UUID "interface_uuid"
+#define XRT_MD_PROP_INTERRUPTS "interrupts"
+#define XRT_MD_PROP_IO_OFFSET "reg"
+#define XRT_MD_PROP_LOGIC_UUID "logic_uuid"
+#define XRT_MD_PROP_PDI_CONFIG "pdi_config_mem"
+#define XRT_MD_PROP_PF_NUM "pcie_physical_function"
+#define XRT_MD_PROP_VERSION_MAJOR "firmware_version_major"
+
+/* non IP nodes */
+#define XRT_MD_NODE_ENDPOINTS "addressable_endpoints"
+#define XRT_MD_NODE_FIRMWARE "firmware"
+#define XRT_MD_NODE_INTERFACES "interfaces"
+#define XRT_MD_NODE_PARTITION_INFO "partition_info"
+
+/*
+ * IP nodes
+ * AF:  AXI Firewall
+ * CMC: Card Management Controller
+ * ERT: Embedded Runtime

* EP: End Point

Will add

+ * PLP: Provider Reconfigurable Partition
+ * ULP: User Reconfigurable Partition
+ */
+#define XRT_MD_NODE_ADDR_TRANSLATOR "ep_remap_data_c2h_00"
+#define XRT_MD_NODE_AF_BLP_CTRL_MGMT "ep_firewall_blp_ctrl_mgmt_00"
+#define XRT_MD_NODE_AF_BLP_CTRL_USER "ep_firewall_blp_ctrl_user_00"
+#define XRT_MD_NODE_AF_CTRL_DEBUG "ep_firewall_ctrl_debug_00"
+#define XRT_MD_NODE_AF_CTRL_MGMT "ep_firewall_ctrl_mgmt_00"
+#define XRT_MD_NODE_AF_CTRL_USER "ep_firewall_ctrl_user_00"
+#define XRT_MD_NODE_AF_DATA_C2H "ep_firewall_data_c2h_00"

c2h ?

Card to host. I will add a comment.

+#define XRT_MD_NODE_AF_DATA_H2C "ep_firewall_data_h2c_00"
+#define XRT_MD_NODE_AF_DATA_M2M "ep_firewall_data_m2m_00"
+#define XRT_MD_NODE_AF_DATA_P2P "ep_firewall_data_p2p_00"
+#define XRT_MD_NODE_CLKFREQ_HBM "ep_freq_cnt_aclk_hbm_00"
+#define XRT_MD_NODE_CLKFREQ_K1 "ep_freq_cnt_aclk_kernel_00"
+#define XRT_MD_NODE_CLKFREQ_K2 "ep_freq_cnt_aclk_kernel_01"
+#define XRT_MD_NODE_CLK_KERNEL1 "ep_aclk_kernel_00"
+#define XRT_MD_NODE_CLK_KERNEL2 "ep_aclk_kernel_01"
+#define XRT_MD_NODE_CLK_KERNEL3 "ep_aclk_hbm_00"

hbm ?

unusual acronyms should be documented.

High bandwidth memory. I will add a comment.



+#define XRT_MD_NODE_CLK_SHUTDOWN "ep_aclk_shutdown_00"
+#define XRT_MD_NODE_CMC_FW_MEM "ep_cmc_firmware_mem_00"
+#define XRT_MD_NODE_CMC_MUTEX "ep_cmc_mutex_00"
+#define XRT_MD_NODE_CMC_REG "ep_cmc_regmap_00"
+#define XRT_MD_NODE_CMC_RESET "ep_cmc_reset_00"
+#define XRT_MD_NODE_DDR_CALIB "ep_ddr_mem_calib_00"
+#define XRT_MD_NODE_DDR4_RESET_GATE "ep_ddr_mem_srsr_gate_00"
+#define XRT_MD_NODE_ERT_BASE "ep_ert_base_address_00"
+#define XRT_MD_NODE_ERT_CQ_MGMT "ep_ert_command_queue_mgmt_00"
+#define XRT_MD_NODE_ERT_CQ_USER "ep_ert_command_queue_user_00"
+#define XRT_MD_NODE_ERT_FW_MEM "ep_ert_firmware_mem_00"
+#define XRT_MD_NODE_ERT_RESET "ep_ert_reset_00"
+#define XRT_MD_NODE_ERT_SCHED "ep_ert_sched_00"
+#define XRT_MD_NODE_FLASH "ep_card_flash_program_00"
+#define XRT_MD_NODE_FPGA_CONFIG "ep_fpga_configuration_00"
+#define XRT_MD_NODE_GAPPING "ep_gapping_demand_00"
+#define XRT_MD_NODE_GATE_PLP "ep_pr_isolate_plp_00"
+#define XRT_MD_NODE_GATE_ULP "ep_pr_isolate_ulp_00"
+#define XRT_MD_NODE_KDMA_CTRL "ep_kdma_ctrl_00"
+#define XRT_MD_NODE_MAILBOX_MGMT "ep_mailbox_mgmt_00&

[PATCH V4 XRT Alveo 20/20] fpga: xrt: Kconfig and Makefile updates for XRT drivers

2021-03-23 Thread Lizhi Hou
Update fpga Kconfig/Makefile and add Kconfig/Makefile for new drivers.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 MAINTAINERS| 11 +++
 drivers/Makefile   |  1 +
 drivers/fpga/Kconfig   |  2 ++
 drivers/fpga/Makefile  |  5 +
 drivers/fpga/xrt/Kconfig   |  8 
 drivers/fpga/xrt/lib/Kconfig   | 17 +
 drivers/fpga/xrt/lib/Makefile  | 30 ++
 drivers/fpga/xrt/metadata/Kconfig  | 12 
 drivers/fpga/xrt/metadata/Makefile | 16 
 drivers/fpga/xrt/mgmt/Kconfig  | 15 +++
 drivers/fpga/xrt/mgmt/Makefile | 19 +++
 11 files changed, 136 insertions(+)
 create mode 100644 drivers/fpga/xrt/Kconfig
 create mode 100644 drivers/fpga/xrt/lib/Kconfig
 create mode 100644 drivers/fpga/xrt/lib/Makefile
 create mode 100644 drivers/fpga/xrt/metadata/Kconfig
 create mode 100644 drivers/fpga/xrt/metadata/Makefile
 create mode 100644 drivers/fpga/xrt/mgmt/Kconfig
 create mode 100644 drivers/fpga/xrt/mgmt/Makefile

diff --git a/MAINTAINERS b/MAINTAINERS
index aa84121c5611..44ccc52987ac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7009,6 +7009,17 @@ F:   Documentation/fpga/
 F: drivers/fpga/
 F: include/linux/fpga/
 
+FPGA XRT DRIVERS
+M: Lizhi Hou 
+R: Max Zhen 
+R: Sonal Santan 
+L: linux-f...@vger.kernel.org
+S: Maintained
+W: https://github.com/Xilinx/XRT
+F: Documentation/fpga/xrt.rst
+F: drivers/fpga/xrt/
+F: include/uapi/linux/xrt/
+
 FPU EMULATOR
 M: Bill Metzenthen 
 S: Maintained
diff --git a/drivers/Makefile b/drivers/Makefile
index 6fba7daba591..dbb3b727fc7a 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -179,6 +179,7 @@ obj-$(CONFIG_STM)   += hwtracing/stm/
 obj-$(CONFIG_ANDROID)  += android/
 obj-$(CONFIG_NVMEM)+= nvmem/
 obj-$(CONFIG_FPGA) += fpga/
+obj-$(CONFIG_FPGA_XRT_METADATA) += fpga/
 obj-$(CONFIG_FSI)  += fsi/
 obj-$(CONFIG_TEE)  += tee/
 obj-$(CONFIG_MULTIPLEXER)  += mux/
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 5ff9438b7b46..01410ff000b9 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -227,4 +227,6 @@ config FPGA_MGR_ZYNQMP_FPGA
  to configure the programmable logic(PL) through PS
  on ZynqMP SoC.
 
+source "drivers/fpga/xrt/Kconfig"
+
 endif # FPGA
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 18dc9885883a..4b887bf95cb3 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -48,3 +48,8 @@ obj-$(CONFIG_FPGA_DFL_NIOS_INTEL_PAC_N3000)   += 
dfl-n3000-nios.o
 
 # Drivers for FPGAs which implement DFL
 obj-$(CONFIG_FPGA_DFL_PCI) += dfl-pci.o
+
+# XRT drivers for Alveo
+obj-$(CONFIG_FPGA_XRT_METADATA)+= xrt/metadata/
+obj-$(CONFIG_FPGA_XRT_LIB) += xrt/lib/
+obj-$(CONFIG_FPGA_XRT_XMGMT)   += xrt/mgmt/
diff --git a/drivers/fpga/xrt/Kconfig b/drivers/fpga/xrt/Kconfig
new file mode 100644
index ..0e2c59589ddd
--- /dev/null
+++ b/drivers/fpga/xrt/Kconfig
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Xilinx Alveo FPGA device configuration
+#
+
+source "drivers/fpga/xrt/metadata/Kconfig"
+source "drivers/fpga/xrt/lib/Kconfig"
+source "drivers/fpga/xrt/mgmt/Kconfig"
diff --git a/drivers/fpga/xrt/lib/Kconfig b/drivers/fpga/xrt/lib/Kconfig
new file mode 100644
index ..935369fad570
--- /dev/null
+++ b/drivers/fpga/xrt/lib/Kconfig
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# XRT Alveo FPGA device configuration
+#
+
+config FPGA_XRT_LIB
+   tristate "XRT Alveo Driver Library"
+   depends on HWMON && PCI && HAS_IOMEM
+   select FPGA_XRT_METADATA
+   select REGMAP_MMIO
+   help
+ Select this option to enable Xilinx XRT Alveo driver library. This
+ library is core infrastructure of XRT Alveo FPGA drivers which
+ provides functions for working with device nodes, iteration and
+ lookup of platform devices, common interfaces for platform devices,
+ plumbing of function call and ioctls between platform devices and
+ parent partitions.
diff --git a/drivers/fpga/xrt/lib/Makefile b/drivers/fpga/xrt/lib/Makefile
new file mode 100644
index ..58563416efbf
--- /dev/null
+++ b/drivers/fpga/xrt/lib/Makefile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2020-2021 Xilinx, Inc. All rights reserved.
+#
+# Authors: sonal.san...@xilinx.com
+#
+
+FULL_XRT_PATH=$(srctree)/$(src)/..
+FULL_DTC_PATH=$(srctree)/scripts/dtc/libfdt
+
+obj-$(CONFIG_FPGA_XRT_LIB) += xrt-lib.o
+
+xrt-lib-objs :=\
+   lib-drv.o   \
+   xroot.o \
+   xclbin.o

[PATCH V4 XRT Alveo 18/20] fpga: xrt: DDR calibration platform driver

2021-03-23 Thread Lizhi Hou
Add DDR calibration driver. DDR calibration is a hardware function
discovered by walking firmware metadata. A platform device node will
be created for it. Hardware provides DDR calibration status through
this function.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 .../fpga/xrt/include/xleaf/ddr_calibration.h  |  28 +++
 drivers/fpga/xrt/lib/xleaf/ddr_calibration.c  | 226 ++
 2 files changed, 254 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/ddr_calibration.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/ddr_calibration.c

diff --git a/drivers/fpga/xrt/include/xleaf/ddr_calibration.h 
b/drivers/fpga/xrt/include/xleaf/ddr_calibration.h
new file mode 100644
index ..878740c26ca2
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/ddr_calibration.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_DDR_CALIBRATION_H_
+#define _XRT_DDR_CALIBRATION_H_
+
+#include "xleaf.h"
+#include 
+
+/*
+ * Memory calibration driver leaf calls.
+ */
+enum xrt_calib_results {
+   XRT_CALIB_UNKNOWN = 0,
+   XRT_CALIB_SUCCEEDED,
+   XRT_CALIB_FAILED,
+};
+
+enum xrt_calib_leaf_cmd {
+   XRT_CALIB_RESULT = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+};
+
+#endif /* _XRT_DDR_CALIBRATION_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/ddr_calibration.c 
b/drivers/fpga/xrt/lib/xleaf/ddr_calibration.c
new file mode 100644
index ..5a9fa82946cb
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/ddr_calibration.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA memory calibration driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * memory calibration
+ *
+ * Authors:
+ *      Lizhi Hou
+ */
+#include 
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+#include "xleaf/ddr_calibration.h"
+
+#define XRT_CALIB  "xrt_calib"
+
+#define XRT_CALIB_STATUS_REG   0
+#define XRT_CALIB_READ_RETRIES 20
+#define XRT_CALIB_READ_INTERVAL500 /* ms */
+
+static const struct regmap_config calib_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+struct calib_cache {
+   struct list_headlink;
+   const char  *ep_name;
+   char*data;
+   u32 data_size;
+};
+
+struct calib {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   struct mutexlock; /* calibration dev lock */
+   struct list_headcache_list;
+   u32 cache_num;
+   enum xrt_calib_results  result;
+};
+
+static void __calib_cache_clean_nolock(struct calib *calib)
+{
+   struct calib_cache *cache, *temp;
+
+   list_for_each_entry_safe(cache, temp, >cache_list, link) {
+   vfree(cache->data);
+   list_del(>link);
+   vfree(cache);
+   }
+   calib->cache_num = 0;
+}
+
+static void calib_cache_clean(struct calib *calib)
+{
+   mutex_lock(>lock);
+   __calib_cache_clean_nolock(calib);
+   mutex_unlock(>lock);
+}
+
+static int calib_calibration(struct calib *calib)
+{
+   u32 times = XRT_CALIB_READ_RETRIES;
+   u32 status;
+   int ret;
+
+   while (times != 0) {
+   ret = regmap_read(calib->regmap, XRT_CALIB_STATUS_REG, );
+   if (ret) {
+   xrt_err(calib->pdev, "failed to read status reg %d", 
ret);
+   return ret;
+   }
+
+   if (status & BIT(0))
+   break;
+   msleep(XRT_CALIB_READ_INTERVAL);
+   times--;
+   }
+
+   if (!times) {
+   xrt_err(calib->pdev,
+   "MIG calibration timeout after bitstream download");
+   return -ETIMEDOUT;
+   }
+
+   xrt_info(calib->pdev, "took %dms", (XRT_CALIB_READ_RETRIES - times) *
+XRT_CALIB_READ_INTERVAL);
+   return 0;
+}
+
+static void xrt_calib_event_cb(struct platform_device *pdev, void *arg)
+{
+   struct calib *calib = platform_get_drvdata(pdev);
+   struct xrt_event *evt = (struct xrt_event *)arg;
+   enum xrt_events e = evt->xe_evt;
+   enum xrt_subdev_id id;
+   int ret;
+
+   id = evt->xe_subdev.xevt_subdev_id;
+
+   switch (e) {
+   case XRT_EVENT_POST_CREATION:
+   if (id == XRT_SUBDEV_UCS) {
+   ret = calib_calibration(calib);
+   if (ret)
+   calib->result = XRT_CALIB_FAILED;
+   else
+   calib->result = XRT_CALIB_SUCCEEDED;
+  

[PATCH V4 XRT Alveo 17/20] fpga: xrt: clock frequency counter platform driver

2021-03-23 Thread Lizhi Hou
Add clock frequency counter driver. Clock frequency counter is
a hardware function discovered by walking xclbin metadata. A platform
device node will be created for it. Other part of driver can read the
actual clock frequency through clock frequency counter driver.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/clkfreq.h |  21 ++
 drivers/fpga/xrt/lib/xleaf/clkfreq.c | 240 +++
 2 files changed, 261 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/clkfreq.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/clkfreq.c

diff --git a/drivers/fpga/xrt/include/xleaf/clkfreq.h 
b/drivers/fpga/xrt/include/xleaf/clkfreq.h
new file mode 100644
index ..005441d5df78
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/clkfreq.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_CLKFREQ_H_
+#define _XRT_CLKFREQ_H_
+
+#include "xleaf.h"
+
+/*
+ * CLKFREQ driver leaf calls.
+ */
+enum xrt_clkfreq_leaf_cmd {
+   XRT_CLKFREQ_READ = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+};
+
+#endif /* _XRT_CLKFREQ_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/clkfreq.c 
b/drivers/fpga/xrt/lib/xleaf/clkfreq.c
new file mode 100644
index ..49473adde3fd
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/clkfreq.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Clock Frequency Counter Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/clkfreq.h"
+
+#define CLKFREQ_ERR(clkfreq, fmt, arg...)   \
+   xrt_err((clkfreq)->pdev, fmt "\n", ##arg)
+#define CLKFREQ_WARN(clkfreq, fmt, arg...)  \
+   xrt_warn((clkfreq)->pdev, fmt "\n", ##arg)
+#define CLKFREQ_INFO(clkfreq, fmt, arg...)  \
+   xrt_info((clkfreq)->pdev, fmt "\n", ##arg)
+#define CLKFREQ_DBG(clkfreq, fmt, arg...)   \
+   xrt_dbg((clkfreq)->pdev, fmt "\n", ##arg)
+
+#define XRT_CLKFREQ"xrt_clkfreq"
+
+#define XRT_CLKFREQ_CONTROL_STATUS_MASK0x
+
+#define XRT_CLKFREQ_CONTROL_START  0x1
+#define XRT_CLKFREQ_CONTROL_DONE   0x2
+#define XRT_CLKFREQ_V5_CLK0_ENABLED0x1
+
+#define XRT_CLKFREQ_CONTROL_REG0
+#define XRT_CLKFREQ_COUNT_REG  0x8
+#define XRT_CLKFREQ_V5_COUNT_REG   0x10
+
+#define XRT_CLKFREQ_READ_RETRIES   10
+
+static const struct regmap_config clkfreq_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+struct clkfreq {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   const char  *clkfreq_ep_name;
+   struct mutexclkfreq_lock; /* clock counter dev lock */
+};
+
+static int clkfreq_read(struct clkfreq *clkfreq, u32 *freq)
+{
+   int times = XRT_CLKFREQ_READ_RETRIES;
+   u32 status;
+   int ret;
+
+   *freq = 0;
+   mutex_lock(>clkfreq_lock);
+   ret = regmap_write(clkfreq->regmap, XRT_CLKFREQ_CONTROL_REG, 
XRT_CLKFREQ_CONTROL_START);
+   if (ret) {
+   CLKFREQ_INFO(clkfreq, "write start to control reg failed %d", 
ret);
+   goto failed;
+   }
+   while (times != 0) {
+   ret = regmap_read(clkfreq->regmap, XRT_CLKFREQ_CONTROL_REG, 
);
+   if (ret) {
+   CLKFREQ_INFO(clkfreq, "read control reg failed %d", 
ret);
+   goto failed;
+   }
+   if ((status & XRT_CLKFREQ_CONTROL_STATUS_MASK) == 
XRT_CLKFREQ_CONTROL_DONE)
+   break;
+   mdelay(1);
+   times--;
+   };
+
+   if (!times) {
+   ret = -ETIMEDOUT;
+   goto failed;
+   }
+
+   if (status & XRT_CLKFREQ_V5_CLK0_ENABLED)
+   ret = regmap_read(clkfreq->regmap, XRT_CLKFREQ_V5_COUNT_REG, 
freq);
+   else
+   ret = regmap_read(clkfreq->regmap, XRT_CLKFREQ_COUNT_REG, freq);
+   if (ret) {
+   CLKFREQ_INFO(clkfreq, "read count failed %d", ret);
+   goto failed;
+   }
+
+   mutex_unlock(>clkfreq_lock);
+
+   return 0;
+
+failed:
+   mutex_unlock(>clkfreq_lock);
+
+   return ret;
+}
+
+static ssize_t freq_show(struct device *dev, struct device_attribute *attr, 
char *buf)
+{
+   struct clkfreq *clkfreq = platform_get_drvdata(to_platform_device(dev));
+   ssize_t count;
+   u32 freq;
+
+   if (clkfreq_read(clkfreq, ))
+   return -EINVAL;
+
+   count = snprintf(buf, 

[PATCH V4 XRT Alveo 19/20] fpga: xrt: partition isolation platform driver

2021-03-23 Thread Lizhi Hou
Add partition isolation platform driver. partition isolation is
a hardware function discovered by walking firmware metadata.
A platform device node will be created for it. Partition isolation
function isolate the different fpga regions

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/axigate.h |  23 ++
 drivers/fpga/xrt/lib/xleaf/axigate.c | 342 +++
 2 files changed, 365 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/axigate.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/axigate.c

diff --git a/drivers/fpga/xrt/include/xleaf/axigate.h 
b/drivers/fpga/xrt/include/xleaf/axigate.h
new file mode 100644
index ..58f32c76dca1
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/axigate.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_AXIGATE_H_
+#define _XRT_AXIGATE_H_
+
+#include "xleaf.h"
+#include "metadata.h"
+
+/*
+ * AXIGATE driver leaf calls.
+ */
+enum xrt_axigate_leaf_cmd {
+   XRT_AXIGATE_CLOSE = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+   XRT_AXIGATE_OPEN,
+};
+
+#endif /* _XRT_AXIGATE_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/axigate.c 
b/drivers/fpga/xrt/lib/xleaf/axigate.c
new file mode 100644
index ..231bb0335278
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/axigate.c
@@ -0,0 +1,342 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA AXI Gate Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/axigate.h"
+
+#define XRT_AXIGATE "xrt_axigate"
+
+#define XRT_AXIGATE_WRITE_REG  0
+#define XRT_AXIGATE_READ_REG   8
+
+#define XRT_AXIGATE_CTRL_CLOSE 0
+#define XRT_AXIGATE_CTRL_OPEN_BIT0 1
+#define XRT_AXIGATE_CTRL_OPEN_BIT1 2
+
+#define XRT_AXIGATE_INTERVAL   500 /* ns */
+
+struct xrt_axigate {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   struct mutexgate_lock; /* gate dev lock */
+
+   void*evt_hdl;
+   const char  *ep_name;
+
+   boolgate_closed;
+};
+
+static const struct regmap_config axigate_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+/* the ep names are in the order of hardware layers */
+static const char * const xrt_axigate_epnames[] = {
+   XRT_MD_NODE_GATE_PLP, /* PLP: Provider Logic Partition */
+   XRT_MD_NODE_GATE_ULP  /* ULP: User Logic Partition */
+};
+
+static inline int close_gate(struct xrt_axigate *gate)
+{
+   u32 val;
+   int ret;
+
+   ret = regmap_write(gate->regmap, XRT_AXIGATE_WRITE_REG, 
XRT_AXIGATE_CTRL_CLOSE);
+   if (ret) {
+   xrt_err(gate->pdev, "write gate failed %d", ret);
+   return ret;
+   }
+   ndelay(XRT_AXIGATE_INTERVAL);
+   /*
+* Legacy hardware requires extra read work properly.
+* This is not on critical path, thus the extra read should not impact 
performance much.
+*/
+   ret = regmap_read(gate->regmap, XRT_AXIGATE_READ_REG, );
+   if (ret) {
+   xrt_err(gate->pdev, "read gate failed %d", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+static inline int open_gate(struct xrt_axigate *gate)
+{
+   u32 val;
+   int ret;
+
+   ret = regmap_write(gate->regmap, XRT_AXIGATE_WRITE_REG, 
XRT_AXIGATE_CTRL_OPEN_BIT1);
+   if (ret) {
+   xrt_err(gate->pdev, "write 2 failed %d", ret);
+   return ret;
+   }
+   ndelay(XRT_AXIGATE_INTERVAL);
+   /*
+* Legacy hardware requires extra read work properly.
+* This is not on critical path, thus the extra read should not impact 
performance much.
+*/
+   ret = regmap_read(gate->regmap, XRT_AXIGATE_READ_REG, );
+   if (ret) {
+   xrt_err(gate->pdev, "read 2 failed %d", ret);
+   return ret;
+   }
+   ret = regmap_write(gate->regmap, XRT_AXIGATE_WRITE_REG,
+  XRT_AXIGATE_CTRL_OPEN_BIT0 | 
XRT_AXIGATE_CTRL_OPEN_BIT1);
+   if (ret) {
+   xrt_err(gate->pdev, "write 3 failed %d", ret);
+   return ret;
+   }
+   ndelay(XRT_AXIGATE_INTERVAL);
+   ret = regmap_read(gate->regmap, XRT_AXIGATE_READ_REG, );
+   if (ret) {
+   xrt_err(gate->pdev, "read 3 failed %d", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int xrt_axigate_epname_idx(struct 

[PATCH V4 XRT Alveo 15/20] fpga: xrt: devctl platform driver

2021-03-23 Thread Lizhi Hou
Add devctl driver. devctl is a type of hardware function which only has
few registers to read or write. They are discovered by walking firmware
metadata. A platform device node will be created for them.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/devctl.h |  40 ++
 drivers/fpga/xrt/lib/xleaf/devctl.c | 183 
 2 files changed, 223 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/devctl.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/devctl.c

diff --git a/drivers/fpga/xrt/include/xleaf/devctl.h 
b/drivers/fpga/xrt/include/xleaf/devctl.h
new file mode 100644
index ..b97f3b6d9326
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/devctl.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_DEVCTL_H_
+#define _XRT_DEVCTL_H_
+
+#include "xleaf.h"
+
+/*
+ * DEVCTL driver leaf calls.
+ */
+enum xrt_devctl_leaf_cmd {
+   XRT_DEVCTL_READ = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+};
+
+enum xrt_devctl_id {
+   XRT_DEVCTL_ROM_UUID = 0,
+   XRT_DEVCTL_DDR_CALIB,
+   XRT_DEVCTL_GOLDEN_VER,
+   XRT_DEVCTL_MAX
+};
+
+struct xrt_devctl_rw {
+   u32 xdr_id;
+   void*xdr_buf;
+   u32 xdr_len;
+   u32 xdr_offset;
+};
+
+struct xrt_devctl_intf_uuid {
+   u32 uuid_num;
+   uuid_t  *uuids;
+};
+
+#endif /* _XRT_DEVCTL_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/devctl.c 
b/drivers/fpga/xrt/lib/xleaf/devctl.c
new file mode 100644
index ..ae086d7c431d
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/devctl.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA devctl Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/devctl.h"
+
+#define XRT_DEVCTL "xrt_devctl"
+
+struct xrt_name_id {
+   char *ep_name;
+   int id;
+};
+
+static struct xrt_name_id name_id[XRT_DEVCTL_MAX] = {
+   { XRT_MD_NODE_BLP_ROM, XRT_DEVCTL_ROM_UUID },
+   { XRT_MD_NODE_GOLDEN_VER, XRT_DEVCTL_GOLDEN_VER },
+};
+
+static const struct regmap_config devctl_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+};
+
+struct xrt_devctl {
+   struct platform_device  *pdev;
+   struct regmap   *regmap[XRT_DEVCTL_MAX];
+   ulong   sizes[XRT_DEVCTL_MAX];
+};
+
+static int xrt_devctl_name2id(struct xrt_devctl *devctl, const char *name)
+{
+   int i;
+
+   for (i = 0; i < XRT_DEVCTL_MAX && name_id[i].ep_name; i++) {
+   if (!strncmp(name_id[i].ep_name, name, 
strlen(name_id[i].ep_name) + 1))
+   return name_id[i].id;
+   }
+
+   return -EINVAL;
+}
+
+static int
+xrt_devctl_leaf_call(struct platform_device *pdev, u32 cmd, void *arg)
+{
+   struct xrt_devctl *devctl;
+   int ret = 0;
+
+   devctl = platform_get_drvdata(pdev);
+
+   switch (cmd) {
+   case XRT_XLEAF_EVENT:
+   /* Does not handle any event. */
+   break;
+   case XRT_DEVCTL_READ: {
+   struct xrt_devctl_rw *rw_arg = arg;
+
+   if (rw_arg->xdr_len & 0x3) {
+   xrt_err(pdev, "invalid len %d", rw_arg->xdr_len);
+   return -EINVAL;
+   }
+
+   if (rw_arg->xdr_id >= XRT_DEVCTL_MAX) {
+   xrt_err(pdev, "invalid id %d", rw_arg->xdr_id);
+   return -EINVAL;
+   }
+
+   if (!devctl->regmap[rw_arg->xdr_id]) {
+   xrt_err(pdev, "io not found, id %d",
+   rw_arg->xdr_id);
+   return -EINVAL;
+   }
+
+   ret = regmap_bulk_read(devctl->regmap[rw_arg->xdr_id], 
rw_arg->xdr_offset,
+  rw_arg->xdr_buf,
+  rw_arg->xdr_len / 
devctl_regmap_config.reg_stride);
+   break;
+   }
+   default:
+   xrt_err(pdev, "unsupported cmd %d", cmd);
+   return -EINVAL;
+   }
+
+   return ret;
+}
+
+static int xrt_devctl_probe(struct platform_device *pdev)
+{
+   struct xrt_devctl *devctl = NULL;
+   void __iomem *base = NULL;
+   struct resource *res;
+   int i, id, ret = 0;
+
+   devctl = devm_kzalloc(>dev, sizeof(*devctl), GFP_KERNEL);
+   if (!devctl)
+   return -ENOMEM;
+
+   devctl->pdev = pdev;
+   platform_set_drvdata(pdev, devctl);
+
+   xrt_info(pdev, "probing..."

[PATCH V4 XRT Alveo 16/20] fpga: xrt: clock platform driver

2021-03-23 Thread Lizhi Hou
Add clock driver. Clock is a hardware function discovered by walking
xclbin metadata. A platform device node will be created for it. Other
part of driver configures clock through clock driver.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/clock.h |  29 ++
 drivers/fpga/xrt/lib/xleaf/clock.c | 669 +
 2 files changed, 698 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/clock.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/clock.c

diff --git a/drivers/fpga/xrt/include/xleaf/clock.h 
b/drivers/fpga/xrt/include/xleaf/clock.h
new file mode 100644
index ..6858473fd096
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/clock.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_CLOCK_H_
+#define _XRT_CLOCK_H_
+
+#include "xleaf.h"
+#include 
+
+/*
+ * CLOCK driver leaf calls.
+ */
+enum xrt_clock_leaf_cmd {
+   XRT_CLOCK_SET = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+   XRT_CLOCK_GET,
+   XRT_CLOCK_VERIFY,
+};
+
+struct xrt_clock_get {
+   u16 freq;
+   u32 freq_cnter;
+};
+
+#endif /* _XRT_CLOCK_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/clock.c 
b/drivers/fpga/xrt/lib/xleaf/clock.c
new file mode 100644
index ..071485e4bf65
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/clock.c
@@ -0,0 +1,669 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Clock Wizard Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ *  Sonal Santan 
+ *  David Zhang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/clock.h"
+#include "xleaf/clkfreq.h"
+
+/* XRT_CLOCK_MAX_NUM_CLOCKS should be a concept from XCLBIN_ in the future */
+#define XRT_CLOCK_MAX_NUM_CLOCKS   4
+#define XRT_CLOCK_STATUS_MASK  0x
+#define XRT_CLOCK_STATUS_MEASURE_START 0x1
+#define XRT_CLOCK_STATUS_MEASURE_DONE  0x2
+
+#define XRT_CLOCK_STATUS_REG   0x4
+#define XRT_CLOCK_CLKFBOUT_REG 0x200
+#define XRT_CLOCK_CLKOUT0_REG  0x208
+#define XRT_CLOCK_LOAD_SADDR_SEN_REG   0x25C
+#define XRT_CLOCK_DEFAULT_EXPIRE_SECS  1
+
+#define CLOCK_ERR(clock, fmt, arg...)  \
+   xrt_err((clock)->pdev, fmt "\n", ##arg)
+#define CLOCK_WARN(clock, fmt, arg...) \
+   xrt_warn((clock)->pdev, fmt "\n", ##arg)
+#define CLOCK_INFO(clock, fmt, arg...) \
+   xrt_info((clock)->pdev, fmt "\n", ##arg)
+#define CLOCK_DBG(clock, fmt, arg...)  \
+   xrt_dbg((clock)->pdev, fmt "\n", ##arg)
+
+#define XRT_CLOCK  "xrt_clock"
+
+static const struct regmap_config clock_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+struct clock {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   struct mutexclock_lock; /* clock dev lock */
+
+   const char  *clock_ep_name;
+};
+
+/*
+ * Precomputed table with config0 and config2 register values together with
+ * target frequency. The steps are approximately 5 MHz apart. Table is
+ * generated by platform creation tool.
+ */
+static const struct xmgmt_ocl_clockwiz {
+   /* target frequency */
+   u16 ocl;
+   /* config0 register */
+   u32 config0;
+   /* config2 register */
+   u32 config2;
+} frequency_table[] = {
+   /*1275.000*/ { 10, 0x02EE0C01, 0x0001F47F },
+   /*1575.000*/ { 15, 0x02EE0F01, 0x0069},
+   /*1600.000*/ { 20, 0x1001, 0x0050},
+   /*1600.000*/ { 25, 0x1001, 0x0040},
+   /*1575.000*/ { 30, 0x02EE0F01, 0x0001F434},
+   /*1575.000*/ { 35, 0x02EE0F01, 0x002D},
+   /*1600.000*/ { 40, 0x1001, 0x0028},
+   /*1575.000*/ { 45, 0x02EE0F01, 0x0023},
+   /*1600.000*/ { 50, 0x1001, 0x0020},
+   /*1512.500*/ { 55, 0x007D0F01, 0x0001F41B},
+   /*1575.000*/ { 60, 0x02EE0F01, 0xFA1A},
+   /*1462.500*/ { 65, 0x02710E01, 0x0001F416},
+   /*1575.000*/ { 70, 0x02EE0F01, 0x0001F416},
+   /*1575.000*/ { 75, 0x02EE0F01, 0x0015},
+   /*1600.000*/ { 80, 0x1001, 0x0014},
+   /*1487.500*/ { 85, 0x036B0E01, 0x0001F411},
+   /*1575.000*/ { 90, 0x02EE0F01, 0x0001F411},
+   /*1425.000*/ { 95, 0x00FA0E01, 0x000F},
+   /*1600.000*/ { 100, 0x1001, 0x0010},
+   /*1575.000*/ { 105, 0x02EE0F01, 0x000F},
+   /*1512.500*/ { 110, 0x007D0F01, 0x0002EE0D},
+   /*1437.500*/ { 115, 0x01770E01, 0x0001F40C},
+   /*1575.000*/ { 120, 0x02EE0F01, 0x7D0D},
+   /*1562.500*/ { 125, 0x02710F01, 0x0001F40C},
+   /*1462.500*/ { 130, 0x02710E01, 0xFA0B},
+   /*13

[PATCH V4 XRT Alveo 13/20] fpga: xrt: User Clock Subsystem platform driver

2021-03-23 Thread Lizhi Hou
Add User Clock Subsystem (UCS) driver. UCS is a hardware function
discovered by walking xclbin metadata. A platform device node will be
created for it.  UCS enables/disables the dynamic region clocks.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/lib/xleaf/ucs.c | 167 +++
 1 file changed, 167 insertions(+)
 create mode 100644 drivers/fpga/xrt/lib/xleaf/ucs.c

diff --git a/drivers/fpga/xrt/lib/xleaf/ucs.c b/drivers/fpga/xrt/lib/xleaf/ucs.c
new file mode 100644
index ..d91ee229e7cb
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/ucs.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA UCS Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/clock.h"
+
+#define UCS_ERR(ucs, fmt, arg...)   \
+   xrt_err((ucs)->pdev, fmt "\n", ##arg)
+#define UCS_WARN(ucs, fmt, arg...)  \
+   xrt_warn((ucs)->pdev, fmt "\n", ##arg)
+#define UCS_INFO(ucs, fmt, arg...)  \
+   xrt_info((ucs)->pdev, fmt "\n", ##arg)
+#define UCS_DBG(ucs, fmt, arg...)   \
+   xrt_dbg((ucs)->pdev, fmt "\n", ##arg)
+
+#define XRT_UCS"xrt_ucs"
+
+#define XRT_UCS_CHANNEL1_REG   0
+#define XRT_UCS_CHANNEL2_REG   8
+
+#define CLK_MAX_VALUE  6400
+
+static const struct regmap_config ucs_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+struct xrt_ucs {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   struct mutexucs_lock; /* ucs dev lock */
+};
+
+static void xrt_ucs_event_cb(struct platform_device *pdev, void *arg)
+{
+   struct xrt_event *evt = (struct xrt_event *)arg;
+   enum xrt_events e = evt->xe_evt;
+   struct platform_device *leaf;
+   enum xrt_subdev_id id;
+   int instance;
+
+   id = evt->xe_subdev.xevt_subdev_id;
+   instance = evt->xe_subdev.xevt_subdev_instance;
+
+   if (e != XRT_EVENT_POST_CREATION) {
+   xrt_dbg(pdev, "ignored event %d", e);
+   return;
+   }
+
+   if (id != XRT_SUBDEV_CLOCK)
+   return;
+
+   leaf = xleaf_get_leaf_by_id(pdev, XRT_SUBDEV_CLOCK, instance);
+   if (!leaf) {
+   xrt_err(pdev, "does not get clock subdev");
+   return;
+   }
+
+   xleaf_call(leaf, XRT_CLOCK_VERIFY, NULL);
+   xleaf_put_leaf(pdev, leaf);
+}
+
+static int ucs_enable(struct xrt_ucs *ucs)
+{
+   int ret;
+
+   mutex_lock(>ucs_lock);
+   ret = regmap_write(ucs->regmap, XRT_UCS_CHANNEL2_REG, 1);
+   mutex_unlock(>ucs_lock);
+
+   return ret;
+}
+
+static int
+xrt_ucs_leaf_call(struct platform_device *pdev, u32 cmd, void *arg)
+{
+   switch (cmd) {
+   case XRT_XLEAF_EVENT:
+   xrt_ucs_event_cb(pdev, arg);
+   break;
+   default:
+   xrt_err(pdev, "unsupported cmd %d", cmd);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int ucs_probe(struct platform_device *pdev)
+{
+   struct xrt_ucs *ucs = NULL;
+   void __iomem *base = NULL;
+   struct resource *res;
+
+   ucs = devm_kzalloc(>dev, sizeof(*ucs), GFP_KERNEL);
+   if (!ucs)
+   return -ENOMEM;
+
+   platform_set_drvdata(pdev, ucs);
+   ucs->pdev = pdev;
+   mutex_init(>ucs_lock);
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (!res)
+   return -EINVAL;
+
+   base = devm_ioremap_resource(>dev, res);
+   if (IS_ERR(base))
+   return PTR_ERR(base);
+
+   ucs->regmap = devm_regmap_init_mmio(>dev, base, 
_regmap_config);
+   if (IS_ERR(ucs->regmap)) {
+   UCS_ERR(ucs, "map base %pR failed", res);
+   return PTR_ERR(ucs->regmap);
+   }
+   ucs_enable(ucs);
+
+   return 0;
+}
+
+static struct xrt_subdev_endpoints xrt_ucs_endpoints[] = {
+   {
+   .xse_names = (struct xrt_subdev_ep_names[]) {
+   { .ep_name = XRT_MD_NODE_UCS_CONTROL_STATUS },
+   { NULL },
+   },
+   .xse_min_ep = 1,
+   },
+   { 0 },
+};
+
+static struct xrt_subdev_drvdata xrt_ucs_data = {
+   .xsd_dev_ops = {
+   .xsd_leaf_call = xrt_ucs_leaf_call,
+   },
+};
+
+static const struct platform_device_id xrt_ucs_table[] = {
+   { XRT_UCS, (kernel_ulong_t)_ucs_data },
+   { },
+};
+
+static struct platform_driver xrt_ucs_driver = {
+   .driver = {
+   .name = XRT_UCS,
+   },
+   .probe = ucs_probe,
+   .id_table = xrt_ucs_table,
+};
+
+XRT_LEAF_INIT_FINI_FUNC(XRT_SUBDEV_UCS, ucs);
-- 
2.27.0



[PATCH V4 XRT Alveo 14/20] fpga: xrt: ICAP platform driver

2021-03-23 Thread Lizhi Hou
ICAP stands for Hardware Internal Configuration Access Port. ICAP is
discovered by walking firmware metadata. A platform device node will be
created for it. FPGA bitstream is written to hardware through ICAP.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/icap.h |  27 ++
 drivers/fpga/xrt/lib/xleaf/icap.c | 344 ++
 2 files changed, 371 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/icap.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/icap.c

diff --git a/drivers/fpga/xrt/include/xleaf/icap.h 
b/drivers/fpga/xrt/include/xleaf/icap.h
new file mode 100644
index ..96d39a8934fa
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/icap.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_ICAP_H_
+#define _XRT_ICAP_H_
+
+#include "xleaf.h"
+
+/*
+ * ICAP driver leaf calls.
+ */
+enum xrt_icap_leaf_cmd {
+   XRT_ICAP_WRITE = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+   XRT_ICAP_GET_IDCODE,
+};
+
+struct xrt_icap_wr {
+   void*xiiw_bit_data;
+   u32 xiiw_data_len;
+};
+
+#endif /* _XRT_ICAP_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/icap.c 
b/drivers/fpga/xrt/lib/xleaf/icap.c
new file mode 100644
index ..13db2b759138
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/icap.c
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA ICAP Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ *  Sonal Santan 
+ *  Max Zhen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/icap.h"
+#include "xclbin-helper.h"
+
+#define XRT_ICAP "xrt_icap"
+
+#define ICAP_ERR(icap, fmt, arg...)\
+   xrt_err((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_WARN(icap, fmt, arg...)   \
+   xrt_warn((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_INFO(icap, fmt, arg...)   \
+   xrt_info((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_DBG(icap, fmt, arg...)\
+   xrt_dbg((icap)->pdev, fmt "\n", ##arg)
+
+/*
+ * AXI-HWICAP IP register layout. Please see
+ * 
https://www.xilinx.com/support/documentation/ip_documentation/axi_hwicap/v3_0/pg134-axi-hwicap.pdf
+ */
+#define ICAP_REG_GIER  0x1C
+#define ICAP_REG_ISR   0x20
+#define ICAP_REG_IER   0x28
+#define ICAP_REG_WF0x100
+#define ICAP_REG_RF0x104
+#define ICAP_REG_SZ0x108
+#define ICAP_REG_CR0x10C
+#define ICAP_REG_SR0x110
+#define ICAP_REG_WFV   0x114
+#define ICAP_REG_RFO   0x118
+#define ICAP_REG_ASR   0x11C
+
+#define ICAP_STATUS_EOS0x4
+#define ICAP_STATUS_DONE   0x1
+
+/*
+ * Canned command sequence to obtain IDCODE of the FPGA
+ */
+static const u32 idcode_stream[] = {
+   /* dummy word */
+   cpu_to_be32(0x),
+   /* sync word */
+   cpu_to_be32(0xaa995566),
+   /* NOP word */
+   cpu_to_be32(0x2000),
+   /* NOP word */
+   cpu_to_be32(0x2000),
+   /* ID code */
+   cpu_to_be32(0x28018001),
+   /* NOP word */
+   cpu_to_be32(0x2000),
+   /* NOP word */
+   cpu_to_be32(0x2000),
+};
+
+static const struct regmap_config icap_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+struct icap {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   struct mutexicap_lock; /* icap dev lock */
+
+   u32 idcode;
+};
+
+static int wait_for_done(const struct icap *icap)
+{
+   int i = 0;
+   int ret;
+   u32 w;
+
+   for (i = 0; i < 10; i++) {
+   /*
+* it requires few micro seconds for ICAP to process incoming 
data.
+* Polling every 5us for 10 times would be good enough.
+*/
+   udelay(5);
+   ret = regmap_read(icap->regmap, ICAP_REG_SR, );
+   if (ret)
+   return ret;
+   ICAP_INFO(icap, "XHWICAP_SR: %x", w);
+   if (w & (ICAP_STATUS_EOS | ICAP_STATUS_DONE))
+   return 0;
+   }
+
+   ICAP_ERR(icap, "bitstream download timeout");
+   return -ETIMEDOUT;
+}
+
+static int icap_write(const struct icap *icap, const u32 *word_buf, int size)
+{
+   u32 value = 0;
+   int ret;
+   int i;
+
+   for (i = 0; i < size; i++) {
+   value = be32_to_cpu(word_buf[i]);
+   ret = regmap_write(icap->regmap, ICAP_REG_WF, value);
+   if (ret)
+  

[PATCH V4 XRT Alveo 12/20] fpga: xrt: VSEC platform driver

2021-03-23 Thread Lizhi Hou
Add VSEC driver. VSEC is a hardware function discovered by walking
PCI Express configure space. A platform device node will be created
for it. VSEC provides board logic UUID and few offset of other hardware
functions.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/lib/xleaf/vsec.c | 388 ++
 1 file changed, 388 insertions(+)
 create mode 100644 drivers/fpga/xrt/lib/xleaf/vsec.c

diff --git a/drivers/fpga/xrt/lib/xleaf/vsec.c 
b/drivers/fpga/xrt/lib/xleaf/vsec.c
new file mode 100644
index ..8595d23f5710
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/vsec.c
@@ -0,0 +1,388 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA VSEC Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+
+#define XRT_VSEC "xrt_vsec"
+
+#define VSEC_TYPE_UUID 0x50
+#define VSEC_TYPE_FLASH0x51
+#define VSEC_TYPE_PLATINFO 0x52
+#define VSEC_TYPE_MAILBOX  0x53
+#define VSEC_TYPE_END  0xff
+
+#define VSEC_UUID_LEN  16
+
+#define VSEC_REG_FORMAT0x0
+#define VSEC_REG_LENGTH0x4
+#define VSEC_REG_ENTRY 0x8
+
+struct xrt_vsec_header {
+   u32 format;
+   u32 length;
+   u32 entry_sz;
+   u32 rsvd;
+} __packed;
+
+struct xrt_vsec_entry {
+   u8  type;
+   u8  bar_rev;
+   u16 off_lo;
+   u32 off_hi;
+   u8  ver_type;
+   u8  minor;
+   u8  major;
+   u8  rsvd0;
+   u32 rsvd1;
+} __packed;
+
+struct vsec_device {
+   u8  type;
+   char*ep_name;
+   ulong   size;
+   char*regmap;
+};
+
+static struct vsec_device vsec_devs[] = {
+   {
+   .type = VSEC_TYPE_UUID,
+   .ep_name = XRT_MD_NODE_BLP_ROM,
+   .size = VSEC_UUID_LEN,
+   .regmap = "vsec-uuid",
+   },
+   {
+   .type = VSEC_TYPE_FLASH,
+   .ep_name = XRT_MD_NODE_FLASH_VSEC,
+   .size = 4096,
+   .regmap = "vsec-flash",
+   },
+   {
+   .type = VSEC_TYPE_PLATINFO,
+   .ep_name = XRT_MD_NODE_PLAT_INFO,
+   .size = 4,
+   .regmap = "vsec-platinfo",
+   },
+   {
+   .type = VSEC_TYPE_MAILBOX,
+   .ep_name = XRT_MD_NODE_MAILBOX_VSEC,
+   .size = 48,
+   .regmap = "vsec-mbx",
+   },
+};
+
+static const struct regmap_config vsec_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .max_register = 0x1000,
+};
+
+struct xrt_vsec {
+   struct platform_device  *pdev;
+   struct regmap   *regmap;
+   u32 length;
+
+   char*metadata;
+   charuuid[VSEC_UUID_LEN];
+   int group;
+};
+
+static inline int vsec_read_entry(struct xrt_vsec *vsec, u32 index, struct 
xrt_vsec_entry *entry)
+{
+   int ret;
+
+   ret = regmap_bulk_read(vsec->regmap, sizeof(struct xrt_vsec_header) +
+  index * sizeof(struct xrt_vsec_entry), entry,
+  sizeof(struct xrt_vsec_entry) /
+  vsec_regmap_config.reg_stride);
+
+   return ret;
+}
+
+static inline u32 vsec_get_bar(struct xrt_vsec_entry *entry)
+{
+   return ((entry)->bar_rev >> 4) & 0xf;
+}
+
+static inline u64 vsec_get_bar_off(struct xrt_vsec_entry *entry)
+{
+   return (entry)->off_lo | ((u64)(entry)->off_hi << 16);
+}
+
+static inline u32 vsec_get_rev(struct xrt_vsec_entry *entry)
+{
+   return (entry)->bar_rev & 0xf;
+}
+
+static char *type2epname(u32 type)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(vsec_devs); i++) {
+   if (vsec_devs[i].type == type)
+   return (vsec_devs[i].ep_name);
+   }
+
+   return NULL;
+}
+
+static ulong type2size(u32 type)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(vsec_devs); i++) {
+   if (vsec_devs[i].type == type)
+   return (vsec_devs[i].size);
+   }
+
+   return 0;
+}
+
+static char *type2regmap(u32 type)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(vsec_devs); i++) {
+   if (vsec_devs[i].type == type)
+   return (vsec_devs[i].regmap);
+   }
+
+   return NULL;
+}
+
+static int xrt_vsec_add_node(struct xrt_vsec *vsec,
+void *md_blob, struct xrt_vsec_entry *p_entry)
+{
+   struct xrt_md_endpoint e

[PATCH V4 XRT Alveo 11/20] fpga: xrt: fpga-mgr and region implementation for xclbin download

2021-03-23 Thread Lizhi Hou
fpga-mgr and region implementation for xclbin download which will be
called from main platform driver

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/mgmt/fmgr-drv.c| 191 +++
 drivers/fpga/xrt/mgmt/fmgr.h|  19 ++
 drivers/fpga/xrt/mgmt/main-region.c | 483 
 3 files changed, 693 insertions(+)
 create mode 100644 drivers/fpga/xrt/mgmt/fmgr-drv.c
 create mode 100644 drivers/fpga/xrt/mgmt/fmgr.h
 create mode 100644 drivers/fpga/xrt/mgmt/main-region.c

diff --git a/drivers/fpga/xrt/mgmt/fmgr-drv.c b/drivers/fpga/xrt/mgmt/fmgr-drv.c
new file mode 100644
index ..12e1cc788ad9
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/fmgr-drv.c
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * FPGA Manager Support for Xilinx Alveo Management Function Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors: sonal.san...@xilinx.com
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "xclbin-helper.h"
+#include "xleaf.h"
+#include "fmgr.h"
+#include "xleaf/axigate.h"
+#include "xleaf/icap.h"
+#include "xmgnt.h"
+
+struct xfpga_class {
+   const struct platform_device *pdev;
+   char  name[64];
+};
+
+/*
+ * xclbin download plumbing -- find the download subsystem, ICAP and
+ * pass the xclbin for heavy lifting
+ */
+static int xmgmt_download_bitstream(struct platform_device *pdev,
+   const struct axlf *xclbin)
+
+{
+   struct xclbin_bit_head_info bit_header = { 0 };
+   struct platform_device *icap_leaf = NULL;
+   struct xrt_icap_wr arg;
+   char *bitstream = NULL;
+   u64 bit_len;
+   int ret;
+
+   ret = xrt_xclbin_get_section(DEV(pdev), xclbin, BITSTREAM, (void 
**), _len);
+   if (ret) {
+   xrt_err(pdev, "bitstream not found");
+   return -ENOENT;
+   }
+   ret = xrt_xclbin_parse_bitstream_header(DEV(pdev), bitstream,
+   XCLBIN_HWICAP_BITFILE_BUF_SZ,
+   _header);
+   if (ret) {
+   ret = -EINVAL;
+   xrt_err(pdev, "invalid bitstream header");
+   goto fail;
+   }
+   if (bit_header.header_length + bit_header.bitstream_length > bit_len) {
+   ret = -EINVAL;
+   xrt_err(pdev, "invalid bitstream length. header %d, bitstream 
%d, section len %lld",
+   bit_header.header_length, bit_header.bitstream_length, 
bit_len);
+   goto fail;
+   }
+
+   icap_leaf = xleaf_get_leaf_by_id(pdev, XRT_SUBDEV_ICAP, 
PLATFORM_DEVID_NONE);
+   if (!icap_leaf) {
+   ret = -ENODEV;
+   xrt_err(pdev, "icap does not exist");
+   goto fail;
+   }
+   arg.xiiw_bit_data = bitstream + bit_header.header_length;
+   arg.xiiw_data_len = bit_header.bitstream_length;
+   ret = xleaf_call(icap_leaf, XRT_ICAP_WRITE, );
+   if (ret) {
+   xrt_err(pdev, "write bitstream failed, ret = %d", ret);
+   xleaf_put_leaf(pdev, icap_leaf);
+   goto fail;
+   }
+
+   xleaf_put_leaf(pdev, icap_leaf);
+   vfree(bitstream);
+
+   return 0;
+
+fail:
+   vfree(bitstream);
+
+   return ret;
+}
+
+/*
+ * There is no HW prep work we do here since we need the full
+ * xclbin for its sanity check.
+ */
+static int xmgmt_pr_write_init(struct fpga_manager *mgr,
+  struct fpga_image_info *info,
+  const char *buf, size_t count)
+{
+   const struct axlf *bin = (const struct axlf *)buf;
+   struct xfpga_class *obj = mgr->priv;
+
+   if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
+   xrt_info(obj->pdev, "%s only supports partial 
reconfiguration\n", obj->name);
+   return -EINVAL;
+   }
+
+   if (count < sizeof(struct axlf))
+   return -EINVAL;
+
+   if (count > bin->header.length)
+   return -EINVAL;
+
+   xrt_info(obj->pdev, "Prepare download of xclbin %pUb of length %lld B",
+>header.uuid, bin->header.length);
+
+   return 0;
+}
+
+/*
+ * The implementation requries full xclbin image before we can start
+ * programming the hardware via ICAP subsystem. The full image is required
+ * for checking the validity of xclbin and walking the sections to
+ * discover the bitstream.
+ */
+static int xmgmt_pr_write(struct fpga_manager *mgr,
+ const char *buf, size_t count)
+{
+   const struct axlf *bin = (const struct axlf *)buf;
+   struct xfpga_class *obj = mgr->priv;
+
+   if (bin->header.length !

[PATCH V4 XRT Alveo 09/20] fpga: xrt: management physical function driver (root)

2021-03-23 Thread Lizhi Hou
The PCIE device driver which attaches to management function on Alveo
devices. It instantiates one or more group drivers which, in turn,
instantiate platform drivers. The instantiation of group and platform
drivers is completely dtb driven.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/mgmt/root.c | 333 +++
 1 file changed, 333 insertions(+)
 create mode 100644 drivers/fpga/xrt/mgmt/root.c

diff --git a/drivers/fpga/xrt/mgmt/root.c b/drivers/fpga/xrt/mgmt/root.c
new file mode 100644
index ..f97f92807c01
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/root.c
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo Management Function Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "xroot.h"
+#include "xmgnt.h"
+#include "metadata.h"
+
+#define XMGMT_MODULE_NAME  "xrt-mgmt"
+#define XMGMT_DRIVER_VERSION   "4.0.0"
+
+#define XMGMT_PDEV(xm) ((xm)->pdev)
+#define XMGMT_DEV(xm)  (&(XMGMT_PDEV(xm)->dev))
+#define xmgmt_err(xm, fmt, args...)\
+   dev_err(XMGMT_DEV(xm), "%s: " fmt, __func__, ##args)
+#define xmgmt_warn(xm, fmt, args...)   \
+   dev_warn(XMGMT_DEV(xm), "%s: " fmt, __func__, ##args)
+#define xmgmt_info(xm, fmt, args...)   \
+   dev_info(XMGMT_DEV(xm), "%s: " fmt, __func__, ##args)
+#define xmgmt_dbg(xm, fmt, args...)\
+   dev_dbg(XMGMT_DEV(xm), "%s: " fmt, __func__, ##args)
+#define XMGMT_DEV_ID(_pcidev)  \
+   ({ typeof(_pcidev) (pcidev) = (_pcidev);\
+   ((pci_domain_nr((pcidev)->bus) << 16) | \
+   PCI_DEVID((pcidev)->bus->number, 0)); })
+
+static struct class *xmgmt_class;
+
+/* PCI Device IDs */
+#define PCI_DEVICE_ID_U50_GOLDEN   0xD020
+#define PCI_DEVICE_ID_U50  0x5020
+static const struct pci_device_id xmgmt_pci_ids[] = {
+   { PCI_DEVICE(PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_U50_GOLDEN), }, /* 
Alveo U50 (golden) */
+   { PCI_DEVICE(PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_U50), }, /* Alveo U50 
*/
+   { 0, }
+};
+
+struct xmgmt {
+   struct pci_dev *pdev;
+   void *root;
+
+   bool ready;
+};
+
+static int xmgmt_config_pci(struct xmgmt *xm)
+{
+   struct pci_dev *pdev = XMGMT_PDEV(xm);
+   int rc;
+
+   rc = pcim_enable_device(pdev);
+   if (rc < 0) {
+   xmgmt_err(xm, "failed to enable device: %d", rc);
+   return rc;
+   }
+
+   rc = pci_enable_pcie_error_reporting(pdev);
+   if (rc)
+   xmgmt_warn(xm, "failed to enable AER: %d", rc);
+
+   pci_set_master(pdev);
+
+   rc = pcie_get_readrq(pdev);
+   if (rc > 512)
+   pcie_set_readrq(pdev, 512);
+   return 0;
+}
+
+static int xmgmt_match_slot_and_save(struct device *dev, void *data)
+{
+   struct xmgmt *xm = data;
+   struct pci_dev *pdev = to_pci_dev(dev);
+
+   if (XMGMT_DEV_ID(pdev) == XMGMT_DEV_ID(xm->pdev)) {
+   pci_cfg_access_lock(pdev);
+   pci_save_state(pdev);
+   }
+
+   return 0;
+}
+
+static void xmgmt_pci_save_config_all(struct xmgmt *xm)
+{
+   bus_for_each_dev(_bus_type, NULL, xm, xmgmt_match_slot_and_save);
+}
+
+static int xmgmt_match_slot_and_restore(struct device *dev, void *data)
+{
+   struct xmgmt *xm = data;
+   struct pci_dev *pdev = to_pci_dev(dev);
+
+   if (XMGMT_DEV_ID(pdev) == XMGMT_DEV_ID(xm->pdev)) {
+   pci_restore_state(pdev);
+   pci_cfg_access_unlock(pdev);
+   }
+
+   return 0;
+}
+
+static void xmgmt_pci_restore_config_all(struct xmgmt *xm)
+{
+   bus_for_each_dev(_bus_type, NULL, xm, xmgmt_match_slot_and_restore);
+}
+
+static void xmgmt_root_hot_reset(struct pci_dev *pdev)
+{
+   struct xmgmt *xm = pci_get_drvdata(pdev);
+   struct pci_bus *bus;
+   u8 pci_bctl;
+   u16 pci_cmd, devctl;
+   int i, ret;
+
+   xmgmt_info(xm, "hot reset start");
+
+   xmgmt_pci_save_config_all(xm);
+
+   pci_disable_device(pdev);
+
+   bus = pdev->bus;
+
+   /*
+* When flipping the SBR bit, device can fall off the bus. This is
+* usually no problem at all so long as drivers are working properly
+* after SBR. However, some systems complain bitterly when the device
+* falls off the bus.
+* The quick solution is to temporarily disable the SERR reporting of
+* switch port during SBR.
+*/
+
+   pci_read_config_word(bus->self, PCI_COMMAND, _cmd);
+   pci_write_config_word(bus->self, PCI_COMMAND, (pci_cmd & 
~PCI_COMMAND_SERR));
+   pcie_capability_read_word(bus->self, PCI_EXP_DEVCTL, );
+   pcie_capability_write_w

[PATCH V4 XRT Alveo 10/20] fpga: xrt: main platform driver for management function device

2021-03-23 Thread Lizhi Hou
platform driver that handles IOCTLs, such as hot reset and xclbin download.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xmgmt-main.h |  34 ++
 drivers/fpga/xrt/mgmt/main.c  | 670 ++
 drivers/fpga/xrt/mgmt/xmgnt.h |  34 ++
 include/uapi/linux/xrt/xmgmt-ioctl.h  |  46 ++
 4 files changed, 784 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xmgmt-main.h
 create mode 100644 drivers/fpga/xrt/mgmt/main.c
 create mode 100644 drivers/fpga/xrt/mgmt/xmgnt.h
 create mode 100644 include/uapi/linux/xrt/xmgmt-ioctl.h

diff --git a/drivers/fpga/xrt/include/xmgmt-main.h 
b/drivers/fpga/xrt/include/xmgmt-main.h
new file mode 100644
index ..dce9f0d1a0dc
--- /dev/null
+++ b/drivers/fpga/xrt/include/xmgmt-main.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XMGMT_MAIN_H_
+#define _XMGMT_MAIN_H_
+
+#include 
+#include "xleaf.h"
+
+enum xrt_mgmt_main_leaf_cmd {
+   XRT_MGMT_MAIN_GET_AXLF_SECTION = XRT_XLEAF_CUSTOM_BASE, /* See comments 
in xleaf.h */
+   XRT_MGMT_MAIN_GET_VBNV,
+};
+
+/* There are three kind of partitions. Each of them is programmed 
independently. */
+enum provider_kind {
+   XMGMT_BLP, /* Base Logic Partition */
+   XMGMT_PLP, /* Provider Logic Partition */
+   XMGMT_ULP, /* User Logic Partition */
+};
+
+struct xrt_mgmt_main_get_axlf_section {
+   enum provider_kind xmmigas_axlf_kind;
+   enum axlf_section_kind xmmigas_section_kind;
+   void *xmmigas_section;
+   u64 xmmigas_section_size;
+};
+
+#endif /* _XMGMT_MAIN_H_ */
diff --git a/drivers/fpga/xrt/mgmt/main.c b/drivers/fpga/xrt/mgmt/main.c
new file mode 100644
index ..f3b46e1fd78b
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/main.c
@@ -0,0 +1,670 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA MGMT PF entry point driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Sonal Santan 
+ */
+
+#include 
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+#include "xleaf.h"
+#include 
+#include "xleaf/devctl.h"
+#include "xmgmt-main.h"
+#include "fmgr.h"
+#include "xleaf/icap.h"
+#include "xleaf/axigate.h"
+#include "xmgnt.h"
+
+#define XMGMT_MAIN "xmgmt_main"
+#define XMGMT_SUPP_XCLBIN_MAJOR 2
+
+#define XMGMT_FLAG_FLASH_READY 1
+#define XMGMT_FLAG_DEVCTL_READY2
+
+#define XMGMT_UUID_STR_LEN 80
+
+struct xmgmt_main {
+   struct platform_device *pdev;
+   struct axlf *firmware_blp;
+   struct axlf *firmware_plp;
+   struct axlf *firmware_ulp;
+   u32 flags;
+   struct fpga_manager *fmgr;
+   struct mutex lock; /* busy lock */
+
+   uuid_t *blp_interface_uuids;
+   u32 blp_interface_uuid_num;
+};
+
+/*
+ * VBNV stands for Vendor, BoardID, Name, Version. It is a string
+ * which describes board and shell.
+ *
+ * Caller is responsible for freeing the returned string.
+ */
+char *xmgmt_get_vbnv(struct platform_device *pdev)
+{
+   struct xmgmt_main *xmm = platform_get_drvdata(pdev);
+   const char *vbnv;
+   char *ret;
+   int i;
+
+   if (xmm->firmware_plp)
+   vbnv = xmm->firmware_plp->header.platform_vbnv;
+   else if (xmm->firmware_blp)
+   vbnv = xmm->firmware_blp->header.platform_vbnv;
+   else
+   return NULL;
+
+   ret = kstrdup(vbnv, GFP_KERNEL);
+   if (!ret)
+   return NULL;
+
+   for (i = 0; i < strlen(ret); i++) {
+   if (ret[i] == ':' || ret[i] == '.')
+   ret[i] = '_';
+   }
+   return ret;
+}
+
+static int get_dev_uuid(struct platform_device *pdev, char *uuidstr, size_t 
len)
+{
+   struct xrt_devctl_rw devctl_arg = { 0 };
+   struct platform_device *devctl_leaf;
+   char uuid_buf[UUID_SIZE];
+   uuid_t uuid;
+   int err;
+
+   devctl_leaf = xleaf_get_leaf_by_epname(pdev, XRT_MD_NODE_BLP_ROM);
+   if (!devctl_leaf) {
+   xrt_err(pdev, "can not get %s", XRT_MD_NODE_BLP_ROM);
+   return -EINVAL;
+   }
+
+   devctl_arg.xdr_id = XRT_DEVCTL_ROM_UUID;
+   devctl_arg.xdr_buf = uuid_buf;
+   devctl_arg.xdr_len = sizeof(uuid_buf);
+   devctl_arg.xdr_offset = 0;
+   err = xleaf_call(devctl_leaf, XRT_DEVCTL_READ, _arg);
+   xleaf_put_leaf(pdev, devctl_leaf);
+   if (err) {
+   xrt_err(pdev, "can not get uuid: %d", err);
+   return err;
+   }
+   import_uuid(, uuid_buf);
+   xrt_md_trans_uuid2str(, uuidstr);
+
+   return 0;
+}
+
+int xmgmt_hot_reset(struct platform_device *pdev)
+{
+   int ret = xleaf_broadcast_event(pdev, XRT_EVENT_PRE_HOT_RESET, false);
+
+   

[PATCH V4 XRT Alveo 06/20] fpga: xrt: char dev node helper functions

2021-03-23 Thread Lizhi Hou
Helper functions for char device node creation / removal for platform
drivers. This is part of platform driver infrastructure.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/lib/cdev.c | 232 
 1 file changed, 232 insertions(+)
 create mode 100644 drivers/fpga/xrt/lib/cdev.c

diff --git a/drivers/fpga/xrt/lib/cdev.c b/drivers/fpga/xrt/lib/cdev.c
new file mode 100644
index ..38efd24b6e10
--- /dev/null
+++ b/drivers/fpga/xrt/lib/cdev.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA device node helper functions.
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#include "xleaf.h"
+
+extern struct class *xrt_class;
+
+#define XRT_CDEV_DIR   "xfpga"
+#define INODE2PDATA(inode) \
+   container_of((inode)->i_cdev, struct xrt_subdev_platdata, xsp_cdev)
+#define INODE2PDEV(inode)  \
+   to_platform_device(kobj_to_dev((inode)->i_cdev->kobj.parent))
+#define CDEV_NAME(sysdev)  (strchr((sysdev)->kobj.name, '!') + 1)
+
+/* Allow it to be accessed from cdev. */
+static void xleaf_devnode_allowed(struct platform_device *pdev)
+{
+   struct xrt_subdev_platdata *pdata = DEV_PDATA(pdev);
+
+   /* Allow new opens. */
+   mutex_lock(>xsp_devnode_lock);
+   pdata->xsp_devnode_online = true;
+   mutex_unlock(>xsp_devnode_lock);
+}
+
+/* Turn off access from cdev and wait for all existing user to go away. */
+static int xleaf_devnode_disallowed(struct platform_device *pdev)
+{
+   int ret = 0;
+   struct xrt_subdev_platdata *pdata = DEV_PDATA(pdev);
+
+   mutex_lock(>xsp_devnode_lock);
+
+   /* Prevent new opens. */
+   pdata->xsp_devnode_online = false;
+   /* Wait for existing user to close. */
+   while (!ret && pdata->xsp_devnode_ref) {
+   int rc;
+
+   mutex_unlock(>xsp_devnode_lock);
+   rc = wait_for_completion_killable(>xsp_devnode_comp);
+   mutex_lock(>xsp_devnode_lock);
+
+   if (rc == -ERESTARTSYS) {
+   /* Restore online state. */
+   pdata->xsp_devnode_online = true;
+   xrt_err(pdev, "%s is in use, ref=%d",
+   CDEV_NAME(pdata->xsp_sysdev),
+   pdata->xsp_devnode_ref);
+   ret = -EBUSY;
+   }
+   }
+
+   mutex_unlock(>xsp_devnode_lock);
+
+   return ret;
+}
+
+static struct platform_device *
+__xleaf_devnode_open(struct inode *inode, bool excl)
+{
+   struct xrt_subdev_platdata *pdata = INODE2PDATA(inode);
+   struct platform_device *pdev = INODE2PDEV(inode);
+   bool opened = false;
+
+   mutex_lock(>xsp_devnode_lock);
+
+   if (pdata->xsp_devnode_online) {
+   if (excl && pdata->xsp_devnode_ref) {
+   xrt_err(pdev, "%s has already been opened exclusively",
+   CDEV_NAME(pdata->xsp_sysdev));
+   } else if (!excl && pdata->xsp_devnode_excl) {
+   xrt_err(pdev, "%s has been opened exclusively",
+   CDEV_NAME(pdata->xsp_sysdev));
+   } else {
+   pdata->xsp_devnode_ref++;
+   pdata->xsp_devnode_excl = excl;
+   opened = true;
+   xrt_info(pdev, "opened %s, ref=%d",
+CDEV_NAME(pdata->xsp_sysdev),
+pdata->xsp_devnode_ref);
+   }
+   } else {
+   xrt_err(pdev, "%s is offline", CDEV_NAME(pdata->xsp_sysdev));
+   }
+
+   mutex_unlock(>xsp_devnode_lock);
+
+   pdev = opened ? pdev : NULL;
+   return pdev;
+}
+
+struct platform_device *
+xleaf_devnode_open_excl(struct inode *inode)
+{
+   return __xleaf_devnode_open(inode, true);
+}
+
+struct platform_device *
+xleaf_devnode_open(struct inode *inode)
+{
+   return __xleaf_devnode_open(inode, false);
+}
+EXPORT_SYMBOL_GPL(xleaf_devnode_open);
+
+void xleaf_devnode_close(struct inode *inode)
+{
+   struct xrt_subdev_platdata *pdata = INODE2PDATA(inode);
+   struct platform_device *pdev = INODE2PDEV(inode);
+   bool notify = false;
+
+   mutex_lock(>xsp_devnode_lock);
+
+   WARN_ON(pdata->xsp_devnode_ref == 0);
+   pdata->xsp_devnode_ref--;
+   if (pdata->xsp_devnode_ref == 0) {
+   pdata->xsp_devnode_excl = false;
+   notify = true;
+   }
+   if (notify) {
+   xrt_info(pdev, "closed %s, ref=%d",
+CDEV_NAME(pdata->xsp_sysdev), pdata->xsp_devnode_re

[PATCH V4 XRT Alveo 07/20] fpga: xrt: root driver infrastructure

2021-03-23 Thread Lizhi Hou
Contains common code for all root drivers and handles root calls from
platform drivers. This is part of root driver infrastructure.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/events.h  |  45 +++
 drivers/fpga/xrt/include/xroot.h   | 117 ++
 drivers/fpga/xrt/lib/subdev_pool.h |  53 +++
 drivers/fpga/xrt/lib/xroot.c   | 589 +
 4 files changed, 804 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/events.h
 create mode 100644 drivers/fpga/xrt/include/xroot.h
 create mode 100644 drivers/fpga/xrt/lib/subdev_pool.h
 create mode 100644 drivers/fpga/xrt/lib/xroot.c

diff --git a/drivers/fpga/xrt/include/events.h 
b/drivers/fpga/xrt/include/events.h
new file mode 100644
index ..775171a47c8e
--- /dev/null
+++ b/drivers/fpga/xrt/include/events.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_EVENTS_H_
+#define _XRT_EVENTS_H_
+
+#include "subdev_id.h"
+
+/*
+ * Event notification.
+ */
+enum xrt_events {
+   XRT_EVENT_TEST = 0, /* for testing */
+   /*
+* Events related to specific subdev
+* Callback arg: struct xrt_event_arg_subdev
+*/
+   XRT_EVENT_POST_CREATION,
+   XRT_EVENT_PRE_REMOVAL,
+   /*
+* Events related to change of the whole board
+* Callback arg: 
+*/
+   XRT_EVENT_PRE_HOT_RESET,
+   XRT_EVENT_POST_HOT_RESET,
+   XRT_EVENT_PRE_GATE_CLOSE,
+   XRT_EVENT_POST_GATE_OPEN,
+};
+
+struct xrt_event_arg_subdev {
+   enum xrt_subdev_id xevt_subdev_id;
+   int xevt_subdev_instance;
+};
+
+struct xrt_event {
+   enum xrt_events xe_evt;
+   struct xrt_event_arg_subdev xe_subdev;
+};
+
+#endif /* _XRT_EVENTS_H_ */
diff --git a/drivers/fpga/xrt/include/xroot.h b/drivers/fpga/xrt/include/xroot.h
new file mode 100644
index ..91c0aeb30bf8
--- /dev/null
+++ b/drivers/fpga/xrt/include/xroot.h
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_ROOT_H_
+#define _XRT_ROOT_H_
+
+#include 
+#include 
+#include "subdev_id.h"
+#include "events.h"
+
+typedef bool (*xrt_subdev_match_t)(enum xrt_subdev_id,
+   struct platform_device *, void *);
+#define XRT_SUBDEV_MATCH_PREV  ((xrt_subdev_match_t)-1)
+#define XRT_SUBDEV_MATCH_NEXT  ((xrt_subdev_match_t)-2)
+
+/*
+ * Root calls.
+ */
+enum xrt_root_cmd {
+   /* Leaf actions. */
+   XRT_ROOT_GET_LEAF = 0,
+   XRT_ROOT_PUT_LEAF,
+   XRT_ROOT_GET_LEAF_HOLDERS,
+
+   /* Group actions. */
+   XRT_ROOT_CREATE_GROUP,
+   XRT_ROOT_REMOVE_GROUP,
+   XRT_ROOT_LOOKUP_GROUP,
+   XRT_ROOT_WAIT_GROUP_BRINGUP,
+
+   /* Event actions. */
+   XRT_ROOT_EVENT_SYNC,
+   XRT_ROOT_EVENT_ASYNC,
+
+   /* Device info. */
+   XRT_ROOT_GET_RESOURCE,
+   XRT_ROOT_GET_ID,
+
+   /* Misc. */
+   XRT_ROOT_HOT_RESET,
+   XRT_ROOT_HWMON,
+};
+
+struct xrt_root_get_leaf {
+   struct platform_device *xpigl_caller_pdev;
+   xrt_subdev_match_t xpigl_match_cb;
+   void *xpigl_match_arg;
+   struct platform_device *xpigl_tgt_pdev;
+};
+
+struct xrt_root_put_leaf {
+   struct platform_device *xpipl_caller_pdev;
+   struct platform_device *xpipl_tgt_pdev;
+};
+
+struct xrt_root_lookup_group {
+   struct platform_device *xpilp_pdev; /* caller's pdev */
+   xrt_subdev_match_t xpilp_match_cb;
+   void *xpilp_match_arg;
+   int xpilp_grp_inst;
+};
+
+struct xrt_root_get_holders {
+   struct platform_device *xpigh_pdev; /* caller's pdev */
+   char *xpigh_holder_buf;
+   size_t xpigh_holder_buf_len;
+};
+
+struct xrt_root_get_res {
+   struct resource *xpigr_res;
+};
+
+struct xrt_root_get_id {
+   unsigned short  xpigi_vendor_id;
+   unsigned short  xpigi_device_id;
+   unsigned short  xpigi_sub_vendor_id;
+   unsigned short  xpigi_sub_device_id;
+};
+
+struct xrt_root_hwmon {
+   bool xpih_register;
+   const char *xpih_name;
+   void *xpih_drvdata;
+   const struct attribute_group **xpih_groups;
+   struct device *xpih_hwmon_dev;
+};
+
+/*
+ * Callback for leaf to make a root request. Arguments are: parent device, 
parent cookie, req,
+ * and arg.
+ */
+typedef int (*xrt_subdev_root_cb_t)(struct device *, void *, u32, void *);
+int xrt_subdev_root_request(struct platform_device *self, u32 cmd, void *arg);
+
+/*
+ * Defines physical function (MPF / UPF) specific operations
+ * needed in common root driver.
+ */
+struct xroot_physical_function_callback {
+   void (*xpc_hot_reset)(struct pci_dev *pdev);
+};
+
+int xroot_probe(struct pci_dev *pdev, struct xroot_physical_function_callback 
*cb, void **root);
+void xroot_remove(void *root);
+bool xroot_wait_for_bringup(void *root);

[PATCH V4 XRT Alveo 08/20] fpga: xrt: platform driver infrastructure

2021-03-23 Thread Lizhi Hou
Infrastructure code providing APIs for managing leaf driver instance
groups, facilitating inter-leaf driver calls and root calls.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/lib/subdev.c | 865 ++
 1 file changed, 865 insertions(+)
 create mode 100644 drivers/fpga/xrt/lib/subdev.c

diff --git a/drivers/fpga/xrt/lib/subdev.c b/drivers/fpga/xrt/lib/subdev.c
new file mode 100644
index ..6428b183fee3
--- /dev/null
+++ b/drivers/fpga/xrt/lib/subdev.c
@@ -0,0 +1,865 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#include 
+#include 
+#include 
+#include "xleaf.h"
+#include "subdev_pool.h"
+#include "lib-drv.h"
+#include "metadata.h"
+
+#define IS_ROOT_DEV(dev) ((dev)->bus == _bus_type)
+static inline struct device *find_root(struct platform_device *pdev)
+{
+   struct device *d = DEV(pdev);
+
+   while (!IS_ROOT_DEV(d))
+   d = d->parent;
+   return d;
+}
+
+/*
+ * It represents a holder of a subdev. One holder can repeatedly hold a subdev
+ * as long as there is a unhold corresponding to a hold.
+ */
+struct xrt_subdev_holder {
+   struct list_head xsh_holder_list;
+   struct device *xsh_holder;
+   int xsh_count;
+   struct kref xsh_kref;
+};
+
+/*
+ * It represents a specific instance of platform driver for a subdev, which
+ * provides services to its clients (another subdev driver or root driver).
+ */
+struct xrt_subdev {
+   struct list_head xs_dev_list;
+   struct list_head xs_holder_list;
+   enum xrt_subdev_id xs_id;   /* type of subdev */
+   struct platform_device *xs_pdev;/* a particular subdev inst */
+   struct completion xs_holder_comp;
+};
+
+static struct xrt_subdev *xrt_subdev_alloc(void)
+{
+   struct xrt_subdev *sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
+
+   if (!sdev)
+   return NULL;
+
+   INIT_LIST_HEAD(>xs_dev_list);
+   INIT_LIST_HEAD(>xs_holder_list);
+   init_completion(>xs_holder_comp);
+   return sdev;
+}
+
+static void xrt_subdev_free(struct xrt_subdev *sdev)
+{
+   kfree(sdev);
+}
+
+int xrt_subdev_root_request(struct platform_device *self, u32 cmd, void *arg)
+{
+   struct device *dev = DEV(self);
+   struct xrt_subdev_platdata *pdata = DEV_PDATA(self);
+
+   WARN_ON(!pdata->xsp_root_cb);
+   return (*pdata->xsp_root_cb)(dev->parent, pdata->xsp_root_cb_arg, cmd, 
arg);
+}
+
+/*
+ * Subdev common sysfs nodes.
+ */
+static ssize_t holders_show(struct device *dev, struct device_attribute *attr, 
char *buf)
+{
+   ssize_t len;
+   struct platform_device *pdev = to_platform_device(dev);
+   struct xrt_root_get_holders holders = { pdev, buf, 1024 };
+
+   len = xrt_subdev_root_request(pdev, XRT_ROOT_GET_LEAF_HOLDERS, 
);
+   if (len >= holders.xpigh_holder_buf_len)
+   return len;
+   buf[len] = '\n';
+   return len + 1;
+}
+static DEVICE_ATTR_RO(holders);
+
+static struct attribute *xrt_subdev_attrs[] = {
+   _attr_holders.attr,
+   NULL,
+};
+
+static ssize_t metadata_output(struct file *filp, struct kobject *kobj,
+  struct bin_attribute *attr, char *buf, loff_t 
off, size_t count)
+{
+   struct device *dev = kobj_to_dev(kobj);
+   struct platform_device *pdev = to_platform_device(dev);
+   struct xrt_subdev_platdata *pdata = DEV_PDATA(pdev);
+   unsigned char *blob;
+   unsigned long  size;
+   ssize_t ret = 0;
+
+   blob = pdata->xsp_dtb;
+   size = xrt_md_size(dev, blob);
+   if (size == XRT_MD_INVALID_LENGTH) {
+   ret = -EINVAL;
+   goto failed;
+   }
+
+   if (off >= size)
+   goto failed;
+
+   if (off + count > size)
+   count = size - off;
+   memcpy(buf, blob + off, count);
+
+   ret = count;
+failed:
+   return ret;
+}
+
+static struct bin_attribute meta_data_attr = {
+   .attr = {
+   .name = "metadata",
+   .mode = 0400
+   },
+   .read = metadata_output,
+   .size = 0
+};
+
+static struct bin_attribute  *xrt_subdev_bin_attrs[] = {
+   _data_attr,
+   NULL,
+};
+
+static const struct attribute_group xrt_subdev_attrgroup = {
+   .attrs = xrt_subdev_attrs,
+   .bin_attrs = xrt_subdev_bin_attrs,
+};
+
+/*
+ * Given the device metadata, parse it to get IO ranges and construct
+ * resource array.
+ */
+static int
+xrt_subdev_getres(struct device *parent, enum xrt_subdev_id id,
+ char *dtb, struct resource **res, int *res_num)
+{
+   struct xrt_subdev_platdata *pdata;
+   struct resource *pci_res = NULL;
+   const u64 *bar_range;
+   const u32 *bar_idx;
+   char *ep_name = NULL, *reg

[PATCH V4 XRT Alveo 04/20] fpga: xrt: xrt-lib platform driver manager

2021-03-23 Thread Lizhi Hou
xrt-lib kernel module infrastructure code to register and manage all
leaf driver modules.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/subdev_id.h |  38 
 drivers/fpga/xrt/include/xleaf.h | 264 +
 drivers/fpga/xrt/lib/lib-drv.c   | 277 +++
 drivers/fpga/xrt/lib/lib-drv.h   |  17 ++
 4 files changed, 596 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/subdev_id.h
 create mode 100644 drivers/fpga/xrt/include/xleaf.h
 create mode 100644 drivers/fpga/xrt/lib/lib-drv.c
 create mode 100644 drivers/fpga/xrt/lib/lib-drv.h

diff --git a/drivers/fpga/xrt/include/subdev_id.h 
b/drivers/fpga/xrt/include/subdev_id.h
new file mode 100644
index ..42fbd6f5e80a
--- /dev/null
+++ b/drivers/fpga/xrt/include/subdev_id.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_SUBDEV_ID_H_
+#define _XRT_SUBDEV_ID_H_
+
+/*
+ * Every subdev driver has an ID for others to refer to it. There can be 
multiple number of
+ * instances of a subdev driver. A  tuple is a 
unique identification
+ * of a specific instance of a subdev driver.
+ */
+enum xrt_subdev_id {
+   XRT_SUBDEV_GRP = 0,
+   XRT_SUBDEV_VSEC = 1,
+   XRT_SUBDEV_VSEC_GOLDEN = 2,
+   XRT_SUBDEV_DEVCTL = 3,
+   XRT_SUBDEV_AXIGATE = 4,
+   XRT_SUBDEV_ICAP = 5,
+   XRT_SUBDEV_TEST = 6,
+   XRT_SUBDEV_MGMT_MAIN = 7,
+   XRT_SUBDEV_QSPI = 8,
+   XRT_SUBDEV_MAILBOX = 9,
+   XRT_SUBDEV_CMC = 10,
+   XRT_SUBDEV_CALIB = 11,
+   XRT_SUBDEV_CLKFREQ = 12,
+   XRT_SUBDEV_CLOCK = 13,
+   XRT_SUBDEV_SRSR = 14,
+   XRT_SUBDEV_UCS = 15,
+   XRT_SUBDEV_NUM = 16, /* Total number of subdevs. */
+   XRT_ROOT = -1, /* Special ID for root driver. */
+};
+
+#endif /* _XRT_SUBDEV_ID_H_ */
diff --git a/drivers/fpga/xrt/include/xleaf.h b/drivers/fpga/xrt/include/xleaf.h
new file mode 100644
index ..acb500df04b0
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf.h
@@ -0,0 +1,264 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *Cheng Zhen 
+ *Sonal Santan 
+ */
+
+#ifndef _XRT_XLEAF_H_
+#define _XRT_XLEAF_H_
+
+#include 
+#include 
+#include 
+#include "subdev_id.h"
+#include "xroot.h"
+#include "events.h"
+
+/* All subdev drivers should use below common routines to print out msg. */
+#define DEV(pdev)  (&(pdev)->dev)
+#define DEV_PDATA(pdev)\
+   ((struct xrt_subdev_platdata *)dev_get_platdata(DEV(pdev)))
+#define DEV_DRVDATA(pdev)  \
+   ((struct xrt_subdev_drvdata *)  \
+   platform_get_device_id(pdev)->driver_data)
+#define FMT_PRT(prt_fn, pdev, fmt, args...)\
+   ({typeof(pdev) (_pdev) = (pdev);\
+   prt_fn(DEV(_pdev), "%s %s: " fmt,   \
+   DEV_PDATA(_pdev)->xsp_root_name, __func__, ##args); })
+#define xrt_err(pdev, fmt, args...) FMT_PRT(dev_err, pdev, fmt, ##args)
+#define xrt_warn(pdev, fmt, args...) FMT_PRT(dev_warn, pdev, fmt, ##args)
+#define xrt_info(pdev, fmt, args...) FMT_PRT(dev_info, pdev, fmt, ##args)
+#define xrt_dbg(pdev, fmt, args...) FMT_PRT(dev_dbg, pdev, fmt, ##args)
+
+enum {
+   /* Starting cmd for common leaf cmd implemented by all leaves. */
+   XRT_XLEAF_COMMON_BASE = 0,
+   /* Starting cmd for leaves' specific leaf cmds. */
+   XRT_XLEAF_CUSTOM_BASE = 64,
+};
+
+enum xrt_xleaf_common_leaf_cmd {
+   XRT_XLEAF_EVENT = XRT_XLEAF_COMMON_BASE,
+};
+
+/*
+ * If populated by subdev driver, infra will handle the mechanics of
+ * char device (un)registration.
+ */
+enum xrt_subdev_file_mode {
+   /* Infra create cdev, default file name */
+   XRT_SUBDEV_FILE_DEFAULT = 0,
+   /* Infra create cdev, need to encode inst num in file name */
+   XRT_SUBDEV_FILE_MULTI_INST,
+   /* No auto creation of cdev by infra, leaf handles it by itself */
+   XRT_SUBDEV_FILE_NO_AUTO,
+};
+
+struct xrt_subdev_file_ops {
+   const struct file_operations xsf_ops;
+   dev_t xsf_dev_t;
+   const char *xsf_dev_name;
+   enum xrt_subdev_file_mode xsf_mode;
+};
+
+/*
+ * Subdev driver callbacks populated by subdev driver.
+ */
+struct xrt_subdev_drv_ops {
+   /*
+* Per driver instance callback. The pdev points to the instance.
+* If defined, these are called by other leaf drivers.
+* Note that root driver may call into xsd_leaf_call of a group driver.
+*/
+   int (*xsd_leaf_call)(struct platform_device *pdev, u32 cmd, void *arg);
+};
+
+/*
+ * Defined and populated by subdev driver, exported as driver_data in
+ * struct platform_device_id.
+ */
+struct xrt_subdev_drvdata {
+   struct xrt_subdev_fil

[PATCH V4 XRT Alveo 05/20] fpga: xrt: group platform driver

2021-03-23 Thread Lizhi Hou
group driver that manages life cycle of a bunch of leaf driver instances
and bridges them with root.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/group.h |  25 +++
 drivers/fpga/xrt/lib/group.c | 286 +++
 2 files changed, 311 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/group.h
 create mode 100644 drivers/fpga/xrt/lib/group.c

diff --git a/drivers/fpga/xrt/include/group.h b/drivers/fpga/xrt/include/group.h
new file mode 100644
index ..09e9d03f53fe
--- /dev/null
+++ b/drivers/fpga/xrt/include/group.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_GROUP_H_
+#define _XRT_GROUP_H_
+
+#include "xleaf.h"
+
+/*
+ * Group driver leaf calls.
+ */
+enum xrt_group_leaf_cmd {
+   XRT_GROUP_GET_LEAF = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h 
*/
+   XRT_GROUP_PUT_LEAF,
+   XRT_GROUP_INIT_CHILDREN,
+   XRT_GROUP_FINI_CHILDREN,
+   XRT_GROUP_TRIGGER_EVENT,
+};
+
+#endif /* _XRT_GROUP_H_ */
diff --git a/drivers/fpga/xrt/lib/group.c b/drivers/fpga/xrt/lib/group.c
new file mode 100644
index ..7b8716569641
--- /dev/null
+++ b/drivers/fpga/xrt/lib/group.c
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Group Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#include 
+#include 
+#include "xleaf.h"
+#include "subdev_pool.h"
+#include "group.h"
+#include "metadata.h"
+#include "lib-drv.h"
+
+#define XRT_GRP "xrt_group"
+
+struct xrt_group {
+   struct platform_device *pdev;
+   struct xrt_subdev_pool leaves;
+   bool leaves_created;
+   struct mutex lock; /* lock for group */
+};
+
+static int xrt_grp_root_cb(struct device *dev, void *parg,
+  enum xrt_root_cmd cmd, void *arg)
+{
+   int rc;
+   struct platform_device *pdev =
+   container_of(dev, struct platform_device, dev);
+   struct xrt_group *xg = (struct xrt_group *)parg;
+
+   switch (cmd) {
+   case XRT_ROOT_GET_LEAF_HOLDERS: {
+   struct xrt_root_get_holders *holders =
+   (struct xrt_root_get_holders *)arg;
+   rc = xrt_subdev_pool_get_holders(>leaves,
+holders->xpigh_pdev,
+holders->xpigh_holder_buf,
+holders->xpigh_holder_buf_len);
+   break;
+   }
+   default:
+   /* Forward parent call to root. */
+   rc = xrt_subdev_root_request(pdev, cmd, arg);
+   break;
+   }
+
+   return rc;
+}
+
+/*
+ * Cut subdev's dtb from group's dtb based on passed-in endpoint descriptor.
+ * Return the subdev's dtb through dtbp, if found.
+ */
+static int xrt_grp_cut_subdev_dtb(struct xrt_group *xg, struct 
xrt_subdev_endpoints *eps,
+ char *grp_dtb, char **dtbp)
+{
+   int ret, i, ep_count = 0;
+   char *dtb = NULL;
+
+   ret = xrt_md_create(DEV(xg->pdev), );
+   if (ret)
+   return ret;
+
+   for (i = 0; eps->xse_names[i].ep_name || eps->xse_names[i].regmap_name; 
i++) {
+   const char *ep_name = eps->xse_names[i].ep_name;
+   const char *reg_name = eps->xse_names[i].regmap_name;
+
+   if (!ep_name)
+   xrt_md_get_compatible_endpoint(DEV(xg->pdev), grp_dtb, 
reg_name, _name);
+   if (!ep_name)
+   continue;
+
+   ret = xrt_md_copy_endpoint(DEV(xg->pdev), dtb, grp_dtb, 
ep_name, reg_name, NULL);
+   if (ret)
+   continue;
+   xrt_md_del_endpoint(DEV(xg->pdev), grp_dtb, ep_name, reg_name);
+   ep_count++;
+   }
+   /* Found enough endpoints, return the subdev's dtb. */
+   if (ep_count >= eps->xse_min_ep) {
+   *dtbp = dtb;
+   return 0;
+   }
+
+   /* Cleanup - Restore all endpoints that has been deleted, if any. */
+   if (ep_count > 0) {
+   xrt_md_copy_endpoint(DEV(xg->pdev), grp_dtb, dtb,
+XRT_MD_NODE_ENDPOINTS, NULL, NULL);
+   }
+   vfree(dtb);
+   *dtbp = NULL;
+   return 0;
+}
+
+static int xrt_grp_create_leaves(struct xrt_group *xg)
+{
+   struct xrt_subdev_platdata *pdata = DEV_PDATA(xg->pdev);
+   struct xrt_subdev_endpoints *eps = NULL;
+   int ret = 0, failed = 0;
+   enum xrt_subdev_id did;
+   char *grp_dtb = NULL;
+   unsigned long mlen;
+
+   if (!pdata)
+   return -EINVAL;
+
+   mlen = xrt_md_size(DEV(xg->

[PATCH V4 XRT Alveo 02/20] fpga: xrt: driver metadata helper functions

2021-03-23 Thread Lizhi Hou
XRT drivers use device tree as metadata format to discover HW subsystems
behind PCIe BAR. Thus libfdt functions are called for the driver to parse
device tree blob.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/metadata.h  | 233 
 drivers/fpga/xrt/metadata/metadata.c | 545 +++
 2 files changed, 778 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/metadata.h
 create mode 100644 drivers/fpga/xrt/metadata/metadata.c

diff --git a/drivers/fpga/xrt/include/metadata.h 
b/drivers/fpga/xrt/include/metadata.h
new file mode 100644
index ..479e47960c61
--- /dev/null
+++ b/drivers/fpga/xrt/include/metadata.h
@@ -0,0 +1,233 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou 
+ */
+
+#ifndef _XRT_METADATA_H
+#define _XRT_METADATA_H
+
+#include 
+#include 
+#include 
+
+#define XRT_MD_INVALID_LENGTH (~0UL)
+
+/* metadata properties */
+#define XRT_MD_PROP_BAR_IDX "pcie_bar_mapping"
+#define XRT_MD_PROP_COMPATIBLE "compatible"
+#define XRT_MD_PROP_HWICAP "axi_hwicap"
+#define XRT_MD_PROP_INTERFACE_UUID "interface_uuid"
+#define XRT_MD_PROP_INTERRUPTS "interrupts"
+#define XRT_MD_PROP_IO_OFFSET "reg"
+#define XRT_MD_PROP_LOGIC_UUID "logic_uuid"
+#define XRT_MD_PROP_PDI_CONFIG "pdi_config_mem"
+#define XRT_MD_PROP_PF_NUM "pcie_physical_function"
+#define XRT_MD_PROP_VERSION_MAJOR "firmware_version_major"
+
+/* non IP nodes */
+#define XRT_MD_NODE_ENDPOINTS "addressable_endpoints"
+#define XRT_MD_NODE_FIRMWARE "firmware"
+#define XRT_MD_NODE_INTERFACES "interfaces"
+#define XRT_MD_NODE_PARTITION_INFO "partition_info"
+
+/*
+ * IP nodes
+ * AF:  AXI Firewall
+ * CMC: Card Management Controller
+ * ERT: Embedded Runtime
+ * PLP: Provider Reconfigurable Partition
+ * ULP: User Reconfigurable Partition
+ */
+#define XRT_MD_NODE_ADDR_TRANSLATOR "ep_remap_data_c2h_00"
+#define XRT_MD_NODE_AF_BLP_CTRL_MGMT "ep_firewall_blp_ctrl_mgmt_00"
+#define XRT_MD_NODE_AF_BLP_CTRL_USER "ep_firewall_blp_ctrl_user_00"
+#define XRT_MD_NODE_AF_CTRL_DEBUG "ep_firewall_ctrl_debug_00"
+#define XRT_MD_NODE_AF_CTRL_MGMT "ep_firewall_ctrl_mgmt_00"
+#define XRT_MD_NODE_AF_CTRL_USER "ep_firewall_ctrl_user_00"
+#define XRT_MD_NODE_AF_DATA_C2H "ep_firewall_data_c2h_00"
+#define XRT_MD_NODE_AF_DATA_H2C "ep_firewall_data_h2c_00"
+#define XRT_MD_NODE_AF_DATA_M2M "ep_firewall_data_m2m_00"
+#define XRT_MD_NODE_AF_DATA_P2P "ep_firewall_data_p2p_00"
+#define XRT_MD_NODE_CLKFREQ_HBM "ep_freq_cnt_aclk_hbm_00"
+#define XRT_MD_NODE_CLKFREQ_K1 "ep_freq_cnt_aclk_kernel_00"
+#define XRT_MD_NODE_CLKFREQ_K2 "ep_freq_cnt_aclk_kernel_01"
+#define XRT_MD_NODE_CLK_KERNEL1 "ep_aclk_kernel_00"
+#define XRT_MD_NODE_CLK_KERNEL2 "ep_aclk_kernel_01"
+#define XRT_MD_NODE_CLK_KERNEL3 "ep_aclk_hbm_00"
+#define XRT_MD_NODE_CLK_SHUTDOWN "ep_aclk_shutdown_00"
+#define XRT_MD_NODE_CMC_FW_MEM "ep_cmc_firmware_mem_00"
+#define XRT_MD_NODE_CMC_MUTEX "ep_cmc_mutex_00"
+#define XRT_MD_NODE_CMC_REG "ep_cmc_regmap_00"
+#define XRT_MD_NODE_CMC_RESET "ep_cmc_reset_00"
+#define XRT_MD_NODE_DDR_CALIB "ep_ddr_mem_calib_00"
+#define XRT_MD_NODE_DDR4_RESET_GATE "ep_ddr_mem_srsr_gate_00"
+#define XRT_MD_NODE_ERT_BASE "ep_ert_base_address_00"
+#define XRT_MD_NODE_ERT_CQ_MGMT "ep_ert_command_queue_mgmt_00"
+#define XRT_MD_NODE_ERT_CQ_USER "ep_ert_command_queue_user_00"
+#define XRT_MD_NODE_ERT_FW_MEM "ep_ert_firmware_mem_00"
+#define XRT_MD_NODE_ERT_RESET "ep_ert_reset_00"
+#define XRT_MD_NODE_ERT_SCHED "ep_ert_sched_00"
+#define XRT_MD_NODE_FLASH "ep_card_flash_program_00"
+#define XRT_MD_NODE_FPGA_CONFIG "ep_fpga_configuration_00"
+#define XRT_MD_NODE_GAPPING "ep_gapping_demand_00"
+#define XRT_MD_NODE_GATE_PLP "ep_pr_isolate_plp_00"
+#define XRT_MD_NODE_GATE_ULP "ep_pr_isolate_ulp_00"
+#define XRT_MD_NODE_KDMA_CTRL "ep_kdma_ctrl_00"
+#define XRT_MD_NODE_MAILBOX_MGMT "ep_mailbox_mgmt_00"
+#define XRT_MD_NODE_MAILBOX_USER "ep_mailbox_user_00"
+#define XRT_MD_NODE_MAILBOX_XRT "ep_mailbox_user_to_ert_00"
+#define XRT_MD_NODE_MSIX "ep_msix_00"
+#define XRT_MD_NODE_P2P "ep_p2p_00"
+#define XRT_MD_NODE_PCIE_MON "ep_pcie_link_mon_00"
+#define XRT_MD_NODE_PMC_INTR   "ep_pmc_intr_00"
+#define XRT_MD_NODE_PMC_MUX"ep_pmc_mux_00"
+#define XRT_MD_NODE_QDMA "ep_qdma_00"
+#define XRT_MD_NODE_QDMA4 "ep_qdma4_00"
+#define XRT_MD_NODE_REMAP_P2P

[PATCH V4 XRT Alveo 03/20] fpga: xrt: xclbin file helper functions

2021-03-23 Thread Lizhi Hou
Alveo FPGA firmware and partial reconfigure file are in xclbin format. This
code enumerates and extracts sections from xclbin files. xclbin.h is cross
platform and used across all platforms and OS.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xclbin-helper.h |  48 +++
 drivers/fpga/xrt/lib/xclbin.c| 369 
 include/uapi/linux/xrt/xclbin.h  | 409 +++
 3 files changed, 826 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xclbin-helper.h
 create mode 100644 drivers/fpga/xrt/lib/xclbin.c
 create mode 100644 include/uapi/linux/xrt/xclbin.h

diff --git a/drivers/fpga/xrt/include/xclbin-helper.h 
b/drivers/fpga/xrt/include/xclbin-helper.h
new file mode 100644
index ..382b1de97b0a
--- /dev/null
+++ b/drivers/fpga/xrt/include/xclbin-helper.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *David Zhang 
+ *Sonal Santan 
+ */
+
+#ifndef _XCLBIN_HELPER_H_
+#define _XCLBIN_HELPER_H_
+
+#include 
+#include 
+#include 
+
+#define XCLBIN_VERSION2"xclbin2"
+#define XCLBIN_HWICAP_BITFILE_BUF_SZ 1024
+#define XCLBIN_MAX_SIZE (1024 * 1024 * 1024) /* Assuming xclbin <= 1G, always 
*/
+
+enum axlf_section_kind;
+struct axlf;
+
+/**
+ * Bitstream header information as defined by Xilinx tools.
+ * Please note that this struct definition is not owned by the driver.
+ */
+struct xclbin_bit_head_info {
+   u32 header_length;  /* Length of header in 32 bit words */
+   u32 bitstream_length;   /* Length of bitstream to read in bytes 
*/
+   const unchar *design_name;  /* Design name get from bitstream */
+   const unchar *part_name;/* Part name read from bitstream */
+   const unchar *date; /* Date read from bitstream header */
+   const unchar *time; /* Bitstream creation time */
+   u32 magic_length;   /* Length of the magic numbers */
+   const unchar *version;  /* Version string */
+};
+
+/* caller must free the allocated memory for **data. len could be NULL. */
+int xrt_xclbin_get_section(struct device *dev,  const struct axlf *xclbin,
+  enum axlf_section_kind kind, void **data,
+  uint64_t *len);
+int xrt_xclbin_get_metadata(struct device *dev, const struct axlf *xclbin, 
char **dtb);
+int xrt_xclbin_parse_bitstream_header(struct device *dev, const unchar *data,
+ u32 size, struct xclbin_bit_head_info 
*head_info);
+const char *xrt_clock_type2epname(enum XCLBIN_CLOCK_TYPE type);
+
+#endif /* _XCLBIN_HELPER_H_ */
diff --git a/drivers/fpga/xrt/lib/xclbin.c b/drivers/fpga/xrt/lib/xclbin.c
new file mode 100644
index ..31b363c014a3
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xclbin.c
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Driver XCLBIN parser
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors: David Zhang 
+ */
+
+#include 
+#include 
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+
+/* Used for parsing bitstream header */
+#define BITSTREAM_EVEN_MAGIC_BYTE  0x0f
+#define BITSTREAM_ODD_MAGIC_BYTE   0xf0
+
+static int xrt_xclbin_get_section_hdr(const struct axlf *xclbin,
+ enum axlf_section_kind kind,
+ const struct axlf_section_header **header)
+{
+   const struct axlf_section_header *phead = NULL;
+   u64 xclbin_len;
+   int i;
+
+   *header = NULL;
+   for (i = 0; i < xclbin->header.num_sections; i++) {
+   if (xclbin->sections[i].section_kind == kind) {
+   phead = >sections[i];
+   break;
+   }
+   }
+
+   if (!phead)
+   return -ENOENT;
+
+   xclbin_len = xclbin->header.length;
+   if (xclbin_len > XCLBIN_MAX_SIZE ||
+   phead->section_offset + phead->section_size > xclbin_len)
+   return -EINVAL;
+
+   *header = phead;
+   return 0;
+}
+
+static int xrt_xclbin_section_info(const struct axlf *xclbin,
+  enum axlf_section_kind kind,
+  u64 *offset, u64 *size)
+{
+   const struct axlf_section_header *mem_header = NULL;
+   int rc;
+
+   rc = xrt_xclbin_get_section_hdr(xclbin, kind, _header);
+   if (rc)
+   return rc;
+
+   *offset = mem_header->section_offset;
+   *size = mem_header->section_size;
+
+   return 0;
+}
+
+/* caller must free the allocated memory for **data */
+int xrt_xclbin_get_section(struct device *dev,
+  const struct axlf *buf,
+  enum axlf_section_kind kind,
+   

[PATCH V4 XRT Alveo 01/20] Documentation: fpga: Add a document describing XRT Alveo drivers

2021-03-23 Thread Lizhi Hou
Describe XRT driver architecture and provide basic overview of
Xilinx Alveo platform.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 Documentation/fpga/index.rst |   1 +
 Documentation/fpga/xrt.rst   | 844 +++
 2 files changed, 845 insertions(+)
 create mode 100644 Documentation/fpga/xrt.rst

diff --git a/Documentation/fpga/index.rst b/Documentation/fpga/index.rst
index f80f95667ca2..30134357b70d 100644
--- a/Documentation/fpga/index.rst
+++ b/Documentation/fpga/index.rst
@@ -8,6 +8,7 @@ fpga
 :maxdepth: 1
 
 dfl
+xrt
 
 .. only::  subproject and html
 
diff --git a/Documentation/fpga/xrt.rst b/Documentation/fpga/xrt.rst
new file mode 100644
index ..0f7977464270
--- /dev/null
+++ b/Documentation/fpga/xrt.rst
@@ -0,0 +1,844 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==
+XRTV2 Linux Kernel Driver Overview
+==
+
+Authors:
+
+* Sonal Santan 
+* Max Zhen 
+* Lizhi Hou 
+
+XRTV2 drivers are second generation `XRT <https://github.com/Xilinx/XRT>`_
+drivers which support `Alveo 
<https://www.xilinx.com/products/boards-and-kits/alveo.html>`_
+PCIe platforms from Xilinx.
+
+XRTV2 drivers support *subsystem* style data driven platforms where driver's
+configuration and behavior is determined by meta data provided by the platform
+(in *device tree* format). Primary management physical function (MPF) driver
+is called **xmgmt**. Primary user physical function (UPF) driver is called
+**xuser** and is under development. xrt driver framework and HW subsystem
+drivers are packaged into a library module called **xrt-lib**, which is
+shared by **xmgmt** and **xuser** (under development). The xrt driver framework
+implements a pseudo-bus which is used to discover HW subsystems and facilitate
+inter HW subsystem interaction.
+
+Driver Modules
+==
+
+xrt-lib.ko
+--
+
+Repository of all subsystem drivers and pure software modules that can 
potentially
+be shared between xmgmt and xuser. All these drivers are structured as Linux
+*platform driver* and are instantiated by xmgmt (or xuser under development) 
based
+on meta data associated with the hardware. The metadata is in the form of a 
device
+tree as mentioned before. Each platform driver statically defines a subsystem 
node
+array by using node name or a string in its ``compatible`` property. And this
+array is eventually translated to IOMEM resources of the platform device.
+
+The xrt-lib core infrastructure provides hooks to platform drivers for device 
node
+management, user file operations and ioctl callbacks. The core infrastructure 
also
+provides pseudo-bus functionality for platform driver registration, discovery 
and
+inter platform driver ioctl calls.
+
+.. note::
+   See code in ``include/xleaf.h``
+
+
+xmgmt.ko
+
+
+The xmgmt driver is a PCIe device driver driving MPF found on Xilinx's Alveo
+PCIE device. It consists of one *root* driver, one or more *group* drivers
+and one or more *xleaf* drivers. The root and MPF specific xleaf drivers are
+in xmgmt.ko. The group driver and other xleaf drivers are in xrt-lib.ko.
+
+The instantiation of specific group driver or xleaf driver is completely data
+driven based on meta data (mostly in device tree format) found through VSEC
+capability and inside firmware files, such as platform xsabin or user xclbin 
file.
+The root driver manages the life cycle of multiple group drivers, which, in 
turn,
+manages multiple xleaf drivers. This allows a single set of drivers to support
+all kinds of subsystems exposed by different shells. The difference among all
+these subsystems will be handled in xleaf drivers with root and group drivers
+being part of the infrastructure and provide common services for all leaves
+found on all platforms.
+
+The driver object model looks like the following::
+
++---+
+|   xroot   |
++-+-+
+  |
+  +---+---+
+  |   |
+  v   v
++---+  +---+
+|   group   |...   |   group   |
++-+-+  +--++
+  |   |
+  |   |
++-+++-++
+|  ||  |
+v  vv  v
++---+  +---++---+  +---+
+| xleaf |..| xleaf || xleaf |..| xleaf |
++---+  +---++---+  +---+
+
+As an example for Xilinx Alveo U50 before user xclbin download, the tree
+looks like the following::
+
++---+
+ 

[PATCH V4 XRT Alveo 00/20] XRT Alveo driver overview

2021-03-23 Thread Lizhi Hou
nel.org/lkml/20210218064019.29189-14-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-15-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-16-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-17-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-18-liz...@xilinx.com
https://lore.kernel.org/lkml/20210218064019.29189-19-liz...@xilinx.com

Lizhi Hou (20):
  Documentation: fpga: Add a document describing XRT Alveo drivers
  fpga: xrt: driver metadata helper functions
  fpga: xrt: xclbin file helper functions
  fpga: xrt: xrt-lib platform driver manager
  fpga: xrt: group platform driver
  fpga: xrt: char dev node helper functions
  fpga: xrt: root driver infrastructure
  fpga: xrt: platform driver infrastructure
  fpga: xrt: management physical function driver (root)
  fpga: xrt: main platform driver for management function device
  fpga: xrt: fpga-mgr and region implementation for xclbin download
  fpga: xrt: VSEC platform driver
  fpga: xrt: User Clock Subsystem platform driver
  fpga: xrt: ICAP platform driver
  fpga: xrt: devctl platform driver
  fpga: xrt: clock platform driver
  fpga: xrt: clock frequency counter platform driver
  fpga: xrt: DDR calibration platform driver
  fpga: xrt: partition isolation platform driver
  fpga: xrt: Kconfig and Makefile updates for XRT drivers

 Documentation/fpga/index.rst  |   1 +
 Documentation/fpga/xrt.rst| 844 +
 MAINTAINERS   |  11 +
 drivers/Makefile  |   1 +
 drivers/fpga/Kconfig  |   2 +
 drivers/fpga/Makefile |   5 +
 drivers/fpga/xrt/Kconfig  |   8 +
 drivers/fpga/xrt/include/events.h |  45 +
 drivers/fpga/xrt/include/group.h  |  25 +
 drivers/fpga/xrt/include/metadata.h   | 233 +
 drivers/fpga/xrt/include/subdev_id.h  |  38 +
 drivers/fpga/xrt/include/xclbin-helper.h  |  48 +
 drivers/fpga/xrt/include/xleaf.h  | 264 ++
 drivers/fpga/xrt/include/xleaf/axigate.h  |  23 +
 drivers/fpga/xrt/include/xleaf/clkfreq.h  |  21 +
 drivers/fpga/xrt/include/xleaf/clock.h|  29 +
 .../fpga/xrt/include/xleaf/ddr_calibration.h  |  28 +
 drivers/fpga/xrt/include/xleaf/devctl.h   |  40 +
 drivers/fpga/xrt/include/xleaf/icap.h |  27 +
 drivers/fpga/xrt/include/xmgmt-main.h |  34 +
 drivers/fpga/xrt/include/xroot.h  | 117 +++
 drivers/fpga/xrt/lib/Kconfig  |  17 +
 drivers/fpga/xrt/lib/Makefile |  30 +
 drivers/fpga/xrt/lib/cdev.c   | 232 +
 drivers/fpga/xrt/lib/group.c  | 286 ++
 drivers/fpga/xrt/lib/lib-drv.c| 277 ++
 drivers/fpga/xrt/lib/lib-drv.h|  17 +
 drivers/fpga/xrt/lib/subdev.c | 865 ++
 drivers/fpga/xrt/lib/subdev_pool.h|  53 ++
 drivers/fpga/xrt/lib/xclbin.c | 369 
 drivers/fpga/xrt/lib/xleaf/axigate.c  | 342 +++
 drivers/fpga/xrt/lib/xleaf/clkfreq.c  | 240 +
 drivers/fpga/xrt/lib/xleaf/clock.c| 669 ++
 drivers/fpga/xrt/lib/xleaf/ddr_calibration.c  | 226 +
 drivers/fpga/xrt/lib/xleaf/devctl.c   | 183 
 drivers/fpga/xrt/lib/xleaf/icap.c | 344 +++
 drivers/fpga/xrt/lib/xleaf/ucs.c  | 167 
 drivers/fpga/xrt/lib/xleaf/vsec.c | 388 
 drivers/fpga/xrt/lib/xroot.c  | 589 
 drivers/fpga/xrt/metadata/Kconfig |  12 +
 drivers/fpga/xrt/metadata/Makefile|  16 +
 drivers/fpga/xrt/metadata/metadata.c  | 545 +++
 drivers/fpga/xrt/mgmt/Kconfig |  15 +
 drivers/fpga/xrt/mgmt/Makefile|  19 +
 drivers/fpga/xrt/mgmt/fmgr-drv.c  | 191 
 drivers/fpga/xrt/mgmt/fmgr.h  |  19 +
 drivers/fpga/xrt/mgmt/main-region.c   | 483 ++
 drivers/fpga/xrt/mgmt/main.c  | 670 ++
 drivers/fpga/xrt/mgmt/root.c  | 333 +++
 drivers/fpga/xrt/mgmt/xmgnt.h |  34 +
 include/uapi/linux/xrt/xclbin.h   | 409 +
 include/uapi/linux/xrt/xmgmt-ioctl.h  |  46 +
 52 files changed, 9930 insertions(+)
 create mode 100644 Documentation/fpga/xrt.rst
 create mode 100644 drivers/fpga/xrt/Kconfig
 create mode 100644 drivers/fpga/xrt/include/events.h
 create mode 100644 drivers/fpga/xrt/include/group.h
 create mode 100644 drivers/fpga/xrt/include/metadata.h
 create mode 100644 drivers/fpga/xrt/include/subdev_id.h
 create mode 100644 drivers/fpga/xrt/include/xclbin-helper.h
 create mode 100644 drivers/fpga/xrt/include/xleaf.h
 create mode 100644 drivers/fpga/xrt/include/xleaf/axigate.h
 create mode 100644 drivers/fpga/xrt/include/xleaf/clkfreq.h
 create mode 10

Re: [PATCH V3 XRT Alveo 12/18] fpga: xrt: ICAP platform driver

2021-03-17 Thread Lizhi Hou

Hi Tom,


On 03/03/2021 07:12 AM, Tom Rix wrote:

On 2/17/21 10:40 PM, Lizhi Hou wrote:

Add ICAP driver. ICAP is a hardware function discovered by walking

What does ICAP stand for ?
ICAP stands for Hardware Internal Configuration Access Port. I will add 
this.

firmware metadata. A platform device node will be created for it.
FPGA bitstream is written to hardware through ICAP.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xleaf/icap.h |  29 +++
  drivers/fpga/xrt/lib/xleaf/icap.c | 317 ++
  2 files changed, 346 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xleaf/icap.h
  create mode 100644 drivers/fpga/xrt/lib/xleaf/icap.c

diff --git a/drivers/fpga/xrt/include/xleaf/icap.h 
b/drivers/fpga/xrt/include/xleaf/icap.h
new file mode 100644
index ..a14fc0ffa78f
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/icap.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT ICAP Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Lizhi Hou 
+ */
+
+#ifndef _XRT_ICAP_H_
+#define _XRT_ICAP_H_
+
+#include "xleaf.h"
+
+/*
+ * ICAP driver IOCTL calls.
+ */
+enum xrt_icap_ioctl_cmd {
+ XRT_ICAP_WRITE = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */

maybe XRT_ICAP_GET_IDCODE

Sure.

+ XRT_ICAP_IDCODE,
+};
+
+struct xrt_icap_ioctl_wr {
+ void*xiiw_bit_data;
+ u32 xiiw_data_len;
+};
+
+#endif   /* _XRT_ICAP_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/icap.c 
b/drivers/fpga/xrt/lib/xleaf/icap.c
new file mode 100644
index ..0500a97bdef9
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/icap.c
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA ICAP Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ *  Sonal Santan 
+ *  Max Zhen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/icap.h"
+#include "xclbin-helper.h"
+
+#define XRT_ICAP "xrt_icap"
+
+#define ICAP_ERR(icap, fmt, arg...)  \
+ xrt_err((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_WARN(icap, fmt, arg...) \
+ xrt_warn((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_INFO(icap, fmt, arg...) \
+ xrt_info((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_DBG(icap, fmt, arg...)  \
+ xrt_dbg((icap)->pdev, fmt "\n", ##arg)
+
+/*
+ * AXI-HWICAP IP register layout
+ */
+struct icap_reg {
+ u32 ir_rsvd1[7];
+ u32 ir_gier;
+ u32 ir_isr;
+ u32 ir_rsvd2;
+ u32 ir_ier;
+ u32 ir_rsvd3[53];
+ u32 ir_wf;
+ u32 ir_rf;
+ u32 ir_sz;
+ u32 ir_cr;
+ u32 ir_sr;
+ u32 ir_wfv;
+ u32 ir_rfo;
+ u32 ir_asr;
+} __packed;
+
+struct icap {
+ struct platform_device  *pdev;
+ struct icap_reg *icap_regs;
+ struct mutexicap_lock; /* icap dev lock */
+
+ unsigned intidcode;

returned as a 64 bit value, but could be stored as 32 bit

Will change return to u32.

+};
+
+static inline u32 reg_rd(void __iomem *reg)
+{
+ if (!reg)
+ return -1;
+
+ return ioread32(reg);

Look at converting the io access to using regmap* api

Will change it.

+}
+
+static inline void reg_wr(void __iomem *reg, u32 val)
+{
+ if (!reg)
+ return;
+
+ iowrite32(val, reg);
+}
+
+static int wait_for_done(struct icap *icap)
+{
+ u32 w;
+ int i = 0;
+
+ WARN_ON(!mutex_is_locked(>icap_lock));

is this needed ? wait_for_done is only called in one place.

Will remove it.

+ for (i = 0; i < 10; i++) {
+ udelay(5);

comment on delay.

+ w = reg_rd(>icap_regs->ir_sr);
+ ICAP_INFO(icap, "XHWICAP_SR: %x", w);
+ if (w & 0x5)

0x5 is a magic number, should be #defined

Sure.

+ return 0;
+ }
+
+ ICAP_ERR(icap, "bitstream download timeout");
+ return -ETIMEDOUT;
+}
+
+static int icap_write(struct icap *icap, const u32 *word_buf, int size)
+{
+ int i;
+ u32 value = 0;
+
+ for (i = 0; i < size; i++) {
+ value = be32_to_cpu(word_buf[i]);
+ reg_wr(>icap_regs->ir_wf, value);
+ }
+
+ reg_wr(>icap_regs->ir_cr, 0x1);
+
+ for (i = 0; i < 20; i++) {
+ value = reg_rd(>icap_regs->ir_cr);
+ if ((value & 0x1) == 0)
+ return 0;
+ ndelay(50);
+ }
+
+ ICAP_ERR(icap, "writing %d dwords timeout", size);
+ return -EIO;
+}
+
+static int bitstream_helper(struct icap *icap, const u32 *word_buffer,
+ u32 word_count)
+{
+ u32 remain_word;
+ u32 word_written = 0;
+ 

Re: [PATCH V3 XRT Alveo 13/18] fpga: xrt: devctl platform driver

2021-03-16 Thread Lizhi Hou




On 03/04/2021 05:39 AM, Tom Rix wrote:

CAUTION: This message has originated from an External Source. Please use proper 
judgment and caution when opening attachments, clicking links, or responding to 
this email.


On 2/17/21 10:40 PM, Lizhi Hou wrote:

Add devctl driver. devctl is a type of hardware function which only has
few registers to read or write. They are discovered by walking firmware
metadata. A platform device node will be created for them.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xleaf/devctl.h |  43 +
  drivers/fpga/xrt/lib/xleaf/devctl.c | 206 
  2 files changed, 249 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xleaf/devctl.h
  create mode 100644 drivers/fpga/xrt/lib/xleaf/devctl.c

diff --git a/drivers/fpga/xrt/include/xleaf/devctl.h 
b/drivers/fpga/xrt/include/xleaf/devctl.h
new file mode 100644
index ..96a40e066f83
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/devctl.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT DEVCTL Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Lizhi Hou 
+ */
+
+#ifndef _XRT_DEVCTL_H_
+#define _XRT_DEVCTL_H_
+
+#include "xleaf.h"
+
+/*
+ * DEVCTL driver IOCTL calls.
+ */
+enum xrt_devctl_ioctl_cmd {
+ XRT_DEVCTL_READ = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+ XRT_DEVCTL_WRITE,
+};
+
+enum xrt_devctl_id {
+ XRT_DEVCTL_ROM_UUID,

Assumes 0, should make this explicit and initialize to 0

Sure.

+ XRT_DEVCTL_DDR_CALIB,
+ XRT_DEVCTL_GOLDEN_VER,
+ XRT_DEVCTL_MAX
+};
+
+struct xrt_devctl_ioctl_rw {
+ u32 xgir_id;
+ void*xgir_buf;
+ u32 xgir_len;
+ u32 xgir_offset;

similar to other patches, the xgir_ prefix is not needed

+};
+
+struct xrt_devctl_ioctl_intf_uuid {
+ u32 xgir_uuid_num;
+ uuid_t  *xgir_uuids;
+};
+
+#endif   /* _XRT_DEVCTL_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/devctl.c 
b/drivers/fpga/xrt/lib/xleaf/devctl.c
new file mode 100644
index ..caf8c6569f0f
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/devctl.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA devctl Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/devctl.h"
+
+#define XRT_DEVCTL "xrt_devctl"
+
+struct xrt_name_id {
+ char *ep_name;
+ int id;
+};
+
+static struct xrt_name_id name_id[XRT_DEVCTL_MAX] = {
+ { XRT_MD_NODE_BLP_ROM, XRT_DEVCTL_ROM_UUID },
+ { XRT_MD_NODE_GOLDEN_VER, XRT_DEVCTL_GOLDEN_VER },

DDR_CALIB is unused ?
Not sure if I understand the question correctly. ddr_calib will have 
more things need to handle other than just read/write.

+};
+
+struct xrt_devctl {
+ struct platform_device  *pdev;
+ void__iomem *base_addrs[XRT_DEVCTL_MAX];
+ ulong   sizes[XRT_DEVCTL_MAX];
+};

similar to other patches, why not use regmap ?

Will change to regmap.

+
+static int xrt_devctl_name2id(struct xrt_devctl *devctl, const char *name)
+{
+ int i;
+
+ for (i = 0; i < XRT_DEVCTL_MAX && name_id[i].ep_name; i++) {
+ if (!strncmp(name_id[i].ep_name, name, strlen(name_id[i].ep_name) 
+ 1))
+ return name_id[i].id;
+ }
+
+ return -EINVAL;
+}
+
+static int
+xrt_devctl_leaf_ioctl(struct platform_device *pdev, u32 cmd, void *arg)
+{
+ struct xrt_devctl   *devctl;
+ int ret = 0;
+
+ devctl = platform_get_drvdata(pdev);
+
+ switch (cmd) {
+ case XRT_XLEAF_EVENT:
+ /* Does not handle any event. */
+ break;
+ case XRT_DEVCTL_READ: {
+ struct xrt_devctl_ioctl_rw  *rw_arg = arg;
+ u32 *p_src, *p_dst, i;
+
+ if (rw_arg->xgir_len & 0x3) {
+ xrt_err(pdev, "invalid len %d", rw_arg->xgir_len);
+ return -EINVAL;
+ }
+
+ if (rw_arg->xgir_id >= XRT_DEVCTL_MAX) {
+ xrt_err(pdev, "invalid id %d", rw_arg->xgir_id);
+ return -EINVAL;
+ }

needs a < 0 check ?

change xgir_id to u32.

+
+ p_src = devctl->base_addrs[rw_arg->xgir_id];
+ if (!p_src) {
+ xrt_err(pdev, "io not found, id %d",
+ rw_arg->xgir_id);
+ return -EINVAL;
+ }
+ if (rw_arg->xgir_offset + rw_arg->xgir_len >
+ devctl->sizes[rw_arg->xgir_id]) {
+ xrt_err(pdev, "invalid argument, off %d, len %d",
+  

Re: [PATCH V3 XRT Alveo 08/18] fpga: xrt: main platform driver for management function device

2021-03-16 Thread Lizhi Hou

Hi Tom,


On 02/26/2021 09:22 AM, Tom Rix wrote:

On 2/17/21 10:40 PM, Lizhi Hou wrote:

platform driver that handles IOCTLs, such as hot reset and xclbin download.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xmgmt-main.h |  37 ++
  drivers/fpga/xrt/mgmt/main-impl.h |  37 ++
  drivers/fpga/xrt/mgmt/main.c  | 693 ++
  include/uapi/linux/xrt/xmgmt-ioctl.h  |  46 ++
  4 files changed, 813 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xmgmt-main.h
  create mode 100644 drivers/fpga/xrt/mgmt/main-impl.h
  create mode 100644 drivers/fpga/xrt/mgmt/main.c
  create mode 100644 include/uapi/linux/xrt/xmgmt-ioctl.h

diff --git a/drivers/fpga/xrt/include/xmgmt-main.h 
b/drivers/fpga/xrt/include/xmgmt-main.h
new file mode 100644
index ..1216d1881f8e
--- /dev/null
+++ b/drivers/fpga/xrt/include/xmgmt-main.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Runtime (XRT) driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Cheng Zhen 
+ */
+
+#ifndef _XMGMT_MAIN_H_
+#define _XMGMT_MAIN_H_
+
+#include 
+#include "xleaf.h"
+
+enum xrt_mgmt_main_ioctl_cmd {
+ /* section needs to be vfree'd by caller */
+ XRT_MGMT_MAIN_GET_AXLF_SECTION = XRT_XLEAF_CUSTOM_BASE, /* See comments 
in xleaf.h */

the must free instructions should go with the pointer needing freeing

Sure. Will move the free instructions.

+ /* vbnv needs to be kfree'd by caller */
+ XRT_MGMT_MAIN_GET_VBNV,
+};
+
+enum provider_kind {
+ XMGMT_BLP,
+ XMGMT_PLP,
+ XMGMT_ULP,

what do these three mean ?

Will add comment

/* There are three kind of partitions. Each of them is programmed 
independently. */

enum provider_kind {
XMGMT_BLP, /* Base Logic Partition */
XMGMT_PLP, /* Provider Logic Partition */
XMGMT_ULP, /* User Logic Partition */
};


+};
+
+struct xrt_mgmt_main_ioctl_get_axlf_section {
+ enum provider_kind xmmigas_axlf_kind;
+ enum axlf_section_kind xmmigas_section_kind;
+ void *xmmigas_section;
+ u64 xmmigas_section_size;
+};
+
+#endif   /* _XMGMT_MAIN_H_ */
diff --git a/drivers/fpga/xrt/mgmt/main-impl.h 
b/drivers/fpga/xrt/mgmt/main-impl.h

 From prefix used in the functions, a better name for this file would be xmgnt.h

Will change.

new file mode 100644
index ..dd1b3e3773cc
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/main-impl.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Alveo Management Function Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Lizhi Hou 
+ *   Cheng Zhen 
+ */
+
+#ifndef _XMGMT_MAIN_IMPL_H_
+#define _XMGMT_MAIN_IMPL_H_
+
+#include 
+#include "xmgmt-main.h"
+
+struct fpga_manager;
+int xmgmt_process_xclbin(struct platform_device *pdev,
+  struct fpga_manager *fmgr,
+  const struct axlf *xclbin,
+  enum provider_kind kind);
+void xmgmt_region_cleanup_all(struct platform_device *pdev);
+
+int bitstream_axlf_mailbox(struct platform_device *pdev, const void *xclbin);

the prefix should be consistent

Will fix this.

+int xmgmt_hot_reset(struct platform_device *pdev);
+
+/* Getting dtb for specified group. Caller should vfree returned dtb .*/
+char *xmgmt_get_dtb(struct platform_device *pdev, enum provider_kind kind);
+char *xmgmt_get_vbnv(struct platform_device *pdev);
+int xmgmt_get_provider_uuid(struct platform_device *pdev,
+ enum provider_kind kind, uuid_t *uuid);
+
+int xmgmt_main_register_leaf(void);
+void xmgmt_main_unregister_leaf(void);

is _main_ needed ?

Will remove.

+
+#endif   /* _XMGMT_MAIN_IMPL_H_ */
diff --git a/drivers/fpga/xrt/mgmt/main.c b/drivers/fpga/xrt/mgmt/main.c
new file mode 100644
index ..66ffb4e7029d
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/main.c
@@ -0,0 +1,693 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA MGMT PF entry point driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Sonal Santan 
+ */
+
+#include 
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+#include "xleaf.h"
+#include 
+#include "xleaf/devctl.h"
+#include "xmgmt-main.h"
+#include "fmgr.h"
+#include "xleaf/icap.h"
+#include "xleaf/axigate.h"
+#include "main-impl.h"
+
+#define XMGMT_MAIN "xmgmt_main"
+
+struct xmgmt_main {
+ struct platform_device *pdev;
+ struct axlf *firmware_blp;
+ struct axlf *firmware_plp;
+ struct axlf *firmware_ulp;
+ bool flash_ready;
+ bool devctl_ready;

could combine in a bitfield

Will change.

+ struct fpga_manager *fmgr;
+ struct mutex busy_mutex; /* busy lock */

busy_mutex ? maybe just call this 'lock'

Will change.

+
+ uuid_t *blp_intf_uuids;
+ u32 blp

Re: [PATCH V3 XRT Alveo 17/18] fpga: xrt: partition isolation platform driver

2021-03-16 Thread Lizhi Hou

Hi Moritz,


On 02/21/2021 12:36 PM, Moritz Fischer wrote:


On Wed, Feb 17, 2021 at 10:40:18PM -0800, Lizhi Hou wrote:

Add partition isolation platform driver. partition isolation is
a hardware function discovered by walking firmware metadata.
A platform device node will be created for it. Partition isolation
function isolate the different fpga regions

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xleaf/axigate.h |  25 ++
  drivers/fpga/xrt/lib/xleaf/axigate.c | 298 +++
  2 files changed, 323 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xleaf/axigate.h
  create mode 100644 drivers/fpga/xrt/lib/xleaf/axigate.c

diff --git a/drivers/fpga/xrt/include/xleaf/axigate.h 
b/drivers/fpga/xrt/include/xleaf/axigate.h
new file mode 100644
index ..2cef71e13b30
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/axigate.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT Axigate Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Lizhi Hou 
+ */
+
+#ifndef _XRT_AXIGATE_H_
+#define _XRT_AXIGATE_H_
+
+#include "xleaf.h"
+#include "metadata.h"
+
+/*
+ * AXIGATE driver IOCTL calls.
+ */
+enum xrt_axigate_ioctl_cmd {
+ XRT_AXIGATE_FREEZE = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+ XRT_AXIGATE_FREE,
+};
+
+#endif   /* _XRT_AXIGATE_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/axigate.c 
b/drivers/fpga/xrt/lib/xleaf/axigate.c
new file mode 100644
index ..382969f9925f
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/axigate.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA AXI Gate Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/axigate.h"
+
+#define XRT_AXIGATE "xrt_axigate"
+
+struct axigate_regs {
+ u32 iag_wr;
+ u32 iag_rvsd;
+ u32 iag_rd;
+} __packed;

Just make them #defines, even more so if there are only 3 of them.

We will use #define and regmap.

+
+struct xrt_axigate {
+ struct platform_device  *pdev;
+ void*base;
+ struct mutexgate_lock; /* gate dev lock */
+
+ void*evt_hdl;
+ const char  *ep_name;
+
+ boolgate_freezed;
+};
+
+/* the ep names are in the order of hardware layers */
+static const char * const xrt_axigate_epnames[] = {
+ XRT_MD_NODE_GATE_PLP,
+ XRT_MD_NODE_GATE_ULP,
+ NULL
+};
+
+#define reg_rd(g, r) \
+ ioread32((void *)(g)->base + offsetof(struct axigate_regs, r))
+#define reg_wr(g, v, r)  \
+ iowrite32(v, (void *)(g)->base + offsetof(struct axigate_regs, r))
+
+static inline void freeze_gate(struct xrt_axigate *gate)
+{
+ reg_wr(gate, 0, iag_wr);
+ ndelay(500);
+ reg_rd(gate, iag_rd);
+}
+
+static inline void free_gate(struct xrt_axigate *gate)
+{
+ reg_wr(gate, 0x2, iag_wr);
+ ndelay(500);

Magic constants?

Will use #define for 500

+ (void)reg_rd(gate, iag_rd);

At the very least add a comment on why? Is this for PCI synchronization
reasons?
Will add comment. Some old board requires this extra read and it will 
not hurt performance.



+ reg_wr(gate, 0x3, iag_wr);
+ ndelay(500);

Magic constants?

+ reg_rd(gate, iag_rd);

Does it nead a (void) or not? Be consistent, again, why do we read here
at all?

+}
+
+static int xrt_axigate_epname_idx(struct platform_device *pdev)
+{
+ int i;
+ int ret;
+ struct resource *res;

Nope. Indents:

struct resource *res;
int, i, ret;

Will change this.



+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ xrt_err(pdev, "Empty Resource!");
+ return -EINVAL;
+ }
+
+ for (i = 0; xrt_axigate_epnames[i]; i++) {
+ ret = strncmp(xrt_axigate_epnames[i], res->name,
+   strlen(xrt_axigate_epnames[i]) + 1);
+ if (!ret)
+ break;
+ }
+
+ ret = (xrt_axigate_epnames[i]) ? i : -EINVAL;

Why not just:

 if (xrt_axigate_epnames[i])
 return i;

 return -EINVAL;

Will change this.

+ return ret;
+}
+
+static void xrt_axigate_freeze(struct platform_device *pdev)
+{
+ struct xrt_axigate  *gate;
+ u32 freeze = 0;

Indents. Fix everywhere.

Will fix this.

+
+ gate = platform_get_drvdata(pdev);
+
+ mutex_lock(>gate_lock);
+ freeze = reg_rd(gate, iag_rd);
+ if (freeze) {   /* gate is opened */
+ xleaf_broa

Re: [PATCH V3 XRT Alveo 17/18] fpga: xrt: partition isolation platform driver

2021-03-12 Thread Lizhi Hou

Hi Tom,

On 03/06/2021 07:54 AM, Tom Rix wrote:

On 2/17/21 10:40 PM, Lizhi Hou wrote:

Add partition isolation platform driver. partition isolation is
a hardware function discovered by walking firmware metadata.
A platform device node will be created for it. Partition isolation
function isolate the different fpga regions

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xleaf/axigate.h |  25 ++
  drivers/fpga/xrt/lib/xleaf/axigate.c | 298 +++
  2 files changed, 323 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xleaf/axigate.h
  create mode 100644 drivers/fpga/xrt/lib/xleaf/axigate.c

diff --git a/drivers/fpga/xrt/include/xleaf/axigate.h 
b/drivers/fpga/xrt/include/xleaf/axigate.h
new file mode 100644
index ..2cef71e13b30
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/axigate.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT Axigate Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Lizhi Hou 
+ */
+
+#ifndef _XRT_AXIGATE_H_
+#define _XRT_AXIGATE_H_
+
+#include "xleaf.h"
+#include "metadata.h"
+
+/*
+ * AXIGATE driver IOCTL calls.
+ */
+enum xrt_axigate_ioctl_cmd {
+ XRT_AXIGATE_FREEZE = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+ XRT_AXIGATE_FREE,

These are substrings, could change suffix to make it harder for developer to 
mix up.

Will change 'freeze' to 'close', 'free' to 'open'.

+};
+
+#endif   /* _XRT_AXIGATE_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/axigate.c 
b/drivers/fpga/xrt/lib/xleaf/axigate.c
new file mode 100644
index ..382969f9925f
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/axigate.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA AXI Gate Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/axigate.h"
+
+#define XRT_AXIGATE "xrt_axigate"
+
+struct axigate_regs {
+ u32 iag_wr;
+ u32 iag_rvsd;
+ u32 iag_rd;
+} __packed;

similar to other patches, prefix of element is not needed.

Will remove this and use #define and regmap.

+
+struct xrt_axigate {
+ struct platform_device  *pdev;
+ void*base;
+ struct mutexgate_lock; /* gate dev lock */
+
+ void*evt_hdl;
+ const char  *ep_name;
+
+ boolgate_freezed;
+};
+
+/* the ep names are in the order of hardware layers */
+static const char * const xrt_axigate_epnames[] = {
+ XRT_MD_NODE_GATE_PLP,
+ XRT_MD_NODE_GATE_ULP,

what are plp, ulp ? it is helpful to comment or expand acronyms
plp stands for  provider logic partition and ulp stands for user logic 
partition. Will add comment.

+ NULL
+};
+
+#define reg_rd(g, r) \
+ ioread32((void *)(g)->base + offsetof(struct axigate_regs, r))
+#define reg_wr(g, v, r)  \
+ iowrite32(v, (void *)(g)->base + offsetof(struct axigate_regs, r))
+
+static inline void freeze_gate(struct xrt_axigate *gate)
+{
+ reg_wr(gate, 0, iag_wr);

The values written here and below are magic, the need to have #defines

Will add #defines

+ ndelay(500);
+ reg_rd(gate, iag_rd);
+}
+
+static inline void free_gate(struct xrt_axigate *gate)
+{
+ reg_wr(gate, 0x2, iag_wr);
+ ndelay(500);
+ (void)reg_rd(gate, iag_rd);
+ reg_wr(gate, 0x3, iag_wr);
+ ndelay(500);
+ reg_rd(gate, iag_rd);
+}
+
+static int xrt_axigate_epname_idx(struct platform_device *pdev)
+{
+ int i;
+ int ret;

int i, ret;

sure.

+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ xrt_err(pdev, "Empty Resource!");
+ return -EINVAL;
+ }
+
+ for (i = 0; xrt_axigate_epnames[i]; i++) {

null guarded array is useful with the size isn't know,

in this case it is, so covert loop to using ARRAY_SIZE

Will use ARRAY_SIZE.



+ ret = strncmp(xrt_axigate_epnames[i], res->name,
+   strlen(xrt_axigate_epnames[i]) + 1);

needs a strlen check in case res->name is just a substring

'strlen() + 1' is used, thus the comparing covers substring as well.

+ if (!ret)
+ break;
+ }
+
+ ret = (xrt_axigate_epnames[i]) ? i : -EINVAL;
+ return ret;
+}
+
+static void xrt_axigate_freeze(struct platform_device *pdev)
+{
+ struct xrt_axigate  *gate;
+ u32 freeze = 0;
+
+ gate = platform_get_drvdata(pdev);
+
+ mutex_lock(>gate_lock);

Re: [PATCH V3 XRT Alveo 16/18] fpga: xrt: DDR calibration platform driver

2021-03-12 Thread Lizhi Hou

Hi Tom,


On 03/06/2021 07:34 AM, Tom Rix wrote:

On 2/17/21 10:40 PM, Lizhi Hou wrote:

Add DDR calibration driver. DDR calibration is a hardware function
discovered by walking firmware metadata. A platform device node will
be created for it. Hardware provides DDR calibration status through
this function.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xleaf/calib.h |  30 
  drivers/fpga/xrt/lib/xleaf/calib.c | 226 +
  2 files changed, 256 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xleaf/calib.h
  create mode 100644 drivers/fpga/xrt/lib/xleaf/calib.c

calib is not descriptive, change filename to ddr_calibration

Sure.

diff --git a/drivers/fpga/xrt/include/xleaf/calib.h 
b/drivers/fpga/xrt/include/xleaf/calib.h
new file mode 100644
index ..f8aba4594c58
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/calib.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT DDR Calibration Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Cheng Zhen 
+ */
+
+#ifndef _XRT_CALIB_H_
+#define _XRT_CALIB_H_
+
+#include "xleaf.h"
+#include 
+
+/*
+ * Memory calibration driver IOCTL calls.
+ */
+enum xrt_calib_results {
+ XRT_CALIB_UNKNOWN,

Initialize ?

Will fix.

+ XRT_CALIB_SUCCEEDED,
+ XRT_CALIB_FAILED,
+};
+
+enum xrt_calib_ioctl_cmd {
+ XRT_CALIB_RESULT = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+};
+
+#endif   /* _XRT_CALIB_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/calib.c 
b/drivers/fpga/xrt/lib/xleaf/calib.c
new file mode 100644
index ..fbb813636e76
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/calib.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA memory calibration driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * memory calibration
+ *
+ * Authors:
+ *      Lizhi Hou
+ */
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+#include "xleaf/calib.h"
+
+#define XRT_CALIB"xrt_calib"
+
+struct calib_cache {
+ struct list_headlink;
+ const char  *ep_name;
+ char*data;
+ u32 data_size;
+};
+
+struct calib {
+ struct platform_device  *pdev;
+ void*calib_base;
+ struct mutexlock; /* calibration dev lock */
+ struct list_headcache_list;
+ u32 cache_num;
+ enum xrt_calib_results  result;
+};
+
+#define CALIB_DONE(calib)\
+ (ioread32((calib)->calib_base) & BIT(0))
+
+static void calib_cache_clean_nolock(struct calib *calib)
+{
+ struct calib_cache *cache, *temp;
+
+ list_for_each_entry_safe(cache, temp, >cache_list, link) {
+ vfree(cache->data);
+ list_del(>link);
+ vfree(cache);
+ }
+ calib->cache_num = 0;
+}
+
+static void calib_cache_clean(struct calib *calib)
+{
+ mutex_lock(>lock);
+ calib_cache_clean_nolock(calib);

No lock functions (i believe) should be prefixed with '__'

Will change.

+ mutex_unlock(>lock);
+}
+
+static int calib_srsr(struct calib *calib, struct platform_device *srsr_leaf)

what is srsr ?

Why a noop function ?
srsr is save-restore and self-refresh. It will not be supported in this 
patch set. I will remove this function.



+{
+ return -EOPNOTSUPP;
+}
+
+static int calib_calibration(struct calib *calib)
+{
+ int i;
+
+ for (i = 0; i < 20; i++) {

20 is a config parameter so should have a #define

There a couple of busy wait blocks in xrt/ some count up, some count down.

It would be good if they were consistent.

Will change these.



+ if (CALIB_DONE(calib))
+ break;
+ msleep(500);

500 is another config

Will define.

Thanks,
Lizhi


Tom


+ }
+
+ if (i == 20) {
+ xrt_err(calib->pdev,
+ "MIG calibration timeout after bitstream download");
+ return -ETIMEDOUT;
+ }
+
+ xrt_info(calib->pdev, "took %dms", i * 500);
+ return 0;
+}
+
+static void xrt_calib_event_cb(struct platform_device *pdev, void *arg)
+{
+ struct calib *calib = platform_get_drvdata(pdev);
+ struct xrt_event *evt = (struct xrt_event *)arg;
+ enum xrt_events e = evt->xe_evt;
+ enum xrt_subdev_id id = evt->xe_subdev.xevt_subdev_id;
+ int instance = evt->xe_subdev.xevt_subdev_instance;
+ struct platform_device *leaf;
+ int ret;
+
+ switch (e) {
+ case XRT_EVENT_POST_CREATION: {
+ if (id == XRT_SUBDEV_SRSR) {
+ leaf = xleaf_get_leaf_by_id(pdev,
+ XRT_SUBDEV_SRSR,
+ in

Re: [PATCH V3 XRT Alveo 15/18] fpga: xrt: clock frequence counter platform driver

2021-03-12 Thread Lizhi Hou

Hi Tom,


On 03/06/2021 07:25 AM, Tom Rix wrote:

On 2/17/21 10:40 PM, Lizhi Hou wrote:

Add clock frequence counter driver. Clock frequence counter is
a hardware function discovered by walking xclbin metadata. A platform
device node will be created for it. Other part of driver can read the
actual clock frequence through clock frequence counter driver.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xleaf/clkfreq.h |  23 +++
  drivers/fpga/xrt/lib/xleaf/clkfreq.c | 221 +++
  2 files changed, 244 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xleaf/clkfreq.h
  create mode 100644 drivers/fpga/xrt/lib/xleaf/clkfreq.c

diff --git a/drivers/fpga/xrt/include/xleaf/clkfreq.h 
b/drivers/fpga/xrt/include/xleaf/clkfreq.h
new file mode 100644
index ..29fc45e8a31b
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/clkfreq.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT Clock Counter Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Lizhi Hou 
+ */
+
+#ifndef _XRT_CLKFREQ_H_
+#define _XRT_CLKFREQ_H_
+
+#include "xleaf.h"
+
+/*
+ * CLKFREQ driver IOCTL calls.
+ */
+enum xrt_clkfreq_ioctl_cmd {
+ XRT_CLKFREQ_READ = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+};
+
+#endif   /* _XRT_CLKFREQ_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/clkfreq.c 
b/drivers/fpga/xrt/lib/xleaf/clkfreq.c
new file mode 100644
index ..2482dd2cff47
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/clkfreq.c
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Clock Frequency Counter Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/clkfreq.h"
+
+#define CLKFREQ_ERR(clkfreq, fmt, arg...)   \
+ xrt_err((clkfreq)->pdev, fmt "\n", ##arg)
+#define CLKFREQ_WARN(clkfreq, fmt, arg...)  \
+ xrt_warn((clkfreq)->pdev, fmt "\n", ##arg)
+#define CLKFREQ_INFO(clkfreq, fmt, arg...)  \
+ xrt_info((clkfreq)->pdev, fmt "\n", ##arg)
+#define CLKFREQ_DBG(clkfreq, fmt, arg...)   \
+ xrt_dbg((clkfreq)->pdev, fmt "\n", ##arg)
+
+#define XRT_CLKFREQ  "xrt_clkfreq"
+
+#define OCL_CLKWIZ_STATUS_MASK   0x
+
+#define OCL_CLKWIZ_STATUS_MEASURE_START  0x1
+#define OCL_CLKWIZ_STATUS_MEASURE_DONE   0x2
+#define OCL_CLK_FREQ_COUNTER_OFFSET  0x8
+#define OCL_CLK_FREQ_V5_COUNTER_OFFSET   0x10
+#define OCL_CLK_FREQ_V5_CLK0_ENABLED 0x1

Similar to earlier, OCL -> XRT_CLKFREQ

Use regmap

Will change this.



+
+struct clkfreq {
+ struct platform_device  *pdev;
+ void __iomem*clkfreq_base;
+ const char  *clkfreq_ep_name;
+ struct mutexclkfreq_lock; /* clock counter dev lock */
+};
+
+static inline u32 reg_rd(struct clkfreq *clkfreq, u32 offset)
+{
+ return ioread32(clkfreq->clkfreq_base + offset);
+}
+
+static inline void reg_wr(struct clkfreq *clkfreq, u32 val, u32 offset)
+{
+ iowrite32(val, clkfreq->clkfreq_base + offset);
+}
+
+static u32 clkfreq_read(struct clkfreq *clkfreq)
+{

failure returns 0, it would be better if -EINVAL or similar was returned.

and u32 *freq added as a function parameter

Will change this.



+ u32 freq = 0, status;
+ int times = 10;

10 is a config parameter, should be a #define

Sure.

+
+ mutex_lock(>clkfreq_lock);
+ reg_wr(clkfreq, OCL_CLKWIZ_STATUS_MEASURE_START, 0);
+ while (times != 0) {
+ status = reg_rd(clkfreq, 0);
+ if ((status & OCL_CLKWIZ_STATUS_MASK) ==
+ OCL_CLKWIZ_STATUS_MEASURE_DONE)
+ break;
+ mdelay(1);
+ times--;
+ };
+ if (times > 0) {

I do not like tristate setting, convert to if-else

Will change this.

+ freq = (status & OCL_CLK_FREQ_V5_CLK0_ENABLED) ?
+ reg_rd(clkfreq, OCL_CLK_FREQ_V5_COUNTER_OFFSET) :
+ reg_rd(clkfreq, OCL_CLK_FREQ_COUNTER_OFFSET);
+ }
+ mutex_unlock(>clkfreq_lock);
+
+ return freq;
+}
+
+static ssize_t freq_show(struct device *dev, struct device_attribute *attr, 
char *buf)
+{
+ struct clkfreq *clkfreq = platform_get_drvdata(to_platform_device(dev));
+ u32 freq;
+ ssize_t count;
+
+ freq = clkfreq_read(clkfreq);

unchecked error

Will add check.

+ count = snprintf(buf, 64, "%d\n", freq);

%u

Sure.

+
+ return count;
+}
+static DEVICE_ATTR_RO(freq);
+
+static struct attribute *clkfreq_attrs[] = {
+ _attr_freq.attr,
+ NULL,
+};
+
+static struct attribute_group clkfreq_attr_group = {
+ .attrs = clkfreq_attrs,
+};
+
+static int
+xrt_clkfreq_leaf_ioctl(struct pl

Re: [PATCH V3 XRT Alveo 14/18] fpga: xrt: clock platform driver

2021-03-10 Thread Lizhi Hou

Hi Tom,


On 03/05/2021 07:23 AM, Tom Rix wrote:

why are clock and clkfeq separated ?
clock and clkfreq are two different IPs. clkfreq is a simple counter to 
confirm the clock output is expected.


On 2/17/21 10:40 PM, Lizhi Hou wrote:

Add clock driver. Clock is a hardware function discovered by walking
xclbin metadata. A platform device node will be created for it. Other
part of driver configures clock through clock driver.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xleaf/clock.h |  31 ++
  drivers/fpga/xrt/lib/xleaf/clock.c | 648 +
  2 files changed, 679 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xleaf/clock.h
  create mode 100644 drivers/fpga/xrt/lib/xleaf/clock.c

diff --git a/drivers/fpga/xrt/include/xleaf/clock.h 
b/drivers/fpga/xrt/include/xleaf/clock.h
new file mode 100644
index ..a2da59b32551
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/clock.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT Clock Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Lizhi Hou 
+ */
+
+#ifndef _XRT_CLOCK_H_
+#define _XRT_CLOCK_H_
+
+#include "xleaf.h"
+#include 
+
+/*
+ * CLOCK driver IOCTL calls.
+ */
+enum xrt_clock_ioctl_cmd {
+ XRT_CLOCK_SET = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+ XRT_CLOCK_GET,
+ XRT_CLOCK_VERIFY,
+};
+
+struct xrt_clock_ioctl_get {
+ u16 freq;
+ u32 freq_cnter;
+};
+
+#endif   /* _XRT_CLOCK_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/clock.c 
b/drivers/fpga/xrt/lib/xleaf/clock.c
new file mode 100644
index ..a067b501a607
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/clock.c
@@ -0,0 +1,648 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Clock Wizard Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ *  Sonal Santan 
+ *  David Zhang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/clock.h"
+#include "xleaf/clkfreq.h"
+
+/* CLOCK_MAX_NUM_CLOCKS should be a concept from XCLBIN_ in the future */
+#define CLOCK_MAX_NUM_CLOCKS 4
+#define OCL_CLKWIZ_STATUS_OFFSET 0x4

OCL_CLKWIZ does not match the name of this file, change to something like 
XRT_CLOCK

Will change to XRT_CLOCK_

+#define OCL_CLKWIZ_STATUS_MASK   0x
+#define OCL_CLKWIZ_STATUS_MEASURE_START  0x1
+#define OCL_CLKWIZ_STATUS_MEASURE_DONE   0x2
+#define OCL_CLKWIZ_CONFIG_OFFSET(n)  (0x200 + 4 * (n))

This should be expanded to logical names of the registers.

It's use below has a magic indexes.

Will change it.



+#define CLOCK_DEFAULT_EXPIRE_SECS1
+
+#define CLOCK_ERR(clock, fmt, arg...)\
+ xrt_err((clock)->pdev, fmt "\n", ##arg)
+#define CLOCK_WARN(clock, fmt, arg...)   \
+ xrt_warn((clock)->pdev, fmt "\n", ##arg)
+#define CLOCK_INFO(clock, fmt, arg...)   \
+ xrt_info((clock)->pdev, fmt "\n", ##arg)
+#define CLOCK_DBG(clock, fmt, arg...)\
+ xrt_dbg((clock)->pdev, fmt "\n", ##arg)
+
+#define XRT_CLOCK"xrt_clock"
+
+struct clock {
+ struct platform_device  *pdev;
+ void __iomem*clock_base;
+ struct mutexclock_lock; /* clock dev lock */
+
+ const char  *clock_ep_name;
+};
+
+/*
+ * Precomputed table with config0 and config2 register values together with
+ * target frequency. The steps are approximately 5 MHz apart. Table is
+ * generated by wiz.pl.

where is wiz.pl ? include the script
wiz.pl may not be a accurate  anymore. I will change the comment to " 
Table is generated by platform creation tool. These are the only known 
good values which have been validated on real hardware hence a fixed 
table. Please see 
https://www.xilinx.com/support/documentation/ip_documentation/clk_wiz/v6_0/pg065-clk-wiz.pdf 
for programming guide.

+ */
+static const struct xmgmt_ocl_clockwiz {
+ /* target frequency */
+ unsigned short ocl;
+ /* config0 register */
+ unsigned long config0;

Should be u32

Will change.

+ /* config2 register */
+ unsigned int config2;
+} frequency_table[] = {
+ {/*1275.000*/   10.000, 0x02EE0C01, 0x0001F47F},

Could clean up this table, to use spaces instead of tabs, move the comment out 
of branches

/* freq */ { ocl, config0, config2 },

Sure



+ {/*1575.000*/   15.000, 0x02EE0F01, 0x0069},

ocl is short, the data if float, change the generator output an integer

Will fix.

+ {/*1600.000*/   20.000, 0x1001, 0x0050},
+ {/*1600.000*/   25.000, 0x1001, 0x0040},
+ {/*1575.000*/   30.000, 0x02EE0F01, 0x0001F434},
+ {/*1575.000*/   35.000, 0x02EE0

Re: [PATCH V3 XRT Alveo 11/18] fpga: xrt: UCS platform driver

2021-03-10 Thread Lizhi Hou

Hi Tom,


On 03/02/2021 08:09 AM, Tom Rix wrote:

On 2/17/21 10:40 PM, Lizhi Hou wrote:

Add UCS driver. UCS is a hardware function discovered by walking xclbin

What does UCS stand for ? add to commit log

UCS stands for User Clock Subsystem. I will add it to log.

metadata. A platform device node will be created for it.
UCS enables/disables the dynamic region clocks.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xleaf/ucs.h |  24 +++
  drivers/fpga/xrt/lib/xleaf/ucs.c | 235 +++
  2 files changed, 259 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xleaf/ucs.h
  create mode 100644 drivers/fpga/xrt/lib/xleaf/ucs.c

diff --git a/drivers/fpga/xrt/include/xleaf/ucs.h 
b/drivers/fpga/xrt/include/xleaf/ucs.h
new file mode 100644
index ..a5ef0e100e12
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/ucs.h

This header is only used by ucs.c, so is it needed ?

could the enum be defined in ucs.c ?

It will be used in the future. I will remove it.



@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT UCS Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Lizhi Hou 
+ */
+
+#ifndef _XRT_UCS_H_
+#define _XRT_UCS_H_
+
+#include "xleaf.h"
+
+/*
+ * UCS driver IOCTL calls.
+ */
+enum xrt_ucs_ioctl_cmd {
+ XRT_UCS_CHECK = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+ XRT_UCS_ENABLE,

no disable ?
It does not need to disable because reset the fpga bridge will disable 
it. I will remove ucs.h because it is not used in this patchset.

+};
+
+#endif   /* _XRT_UCS_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/ucs.c b/drivers/fpga/xrt/lib/xleaf/ucs.c
new file mode 100644
index ..ae762c8fddbb
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/ucs.c
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA UCS Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/ucs.h"
+#include "xleaf/clock.h"
+
+#define UCS_ERR(ucs, fmt, arg...)   \
+ xrt_err((ucs)->pdev, fmt "\n", ##arg)
+#define UCS_WARN(ucs, fmt, arg...)  \
+ xrt_warn((ucs)->pdev, fmt "\n", ##arg)
+#define UCS_INFO(ucs, fmt, arg...)  \
+ xrt_info((ucs)->pdev, fmt "\n", ##arg)
+#define UCS_DBG(ucs, fmt, arg...)   \
+ xrt_dbg((ucs)->pdev, fmt "\n", ##arg)
+
+#define XRT_UCS  "xrt_ucs"
+
+#define CHANNEL1_OFFSET  0
+#define CHANNEL2_OFFSET  8
+
+#define CLK_MAX_VALUE6400
+
+struct ucs_control_status_ch1 {
+ unsigned int shutdown_clocks_latched:1;
+ unsigned int reserved1:15;
+ unsigned int clock_throttling_average:14;
+ unsigned int reserved2:2;
+};

Likely needs to be packed and/or the unsigned int changed to u32

Will remove this structure because it is not used in this patch set.

+
+struct xrt_ucs {
+ struct platform_device  *pdev;
+ void __iomem*ucs_base;
+ struct mutexucs_lock; /* ucs dev lock */
+};
+
+static inline u32 reg_rd(struct xrt_ucs *ucs, u32 offset)
+{
+ return ioread32(ucs->ucs_base + offset);
+}
+
+static inline void reg_wr(struct xrt_ucs *ucs, u32 val, u32 offset)
+{
+ iowrite32(val, ucs->ucs_base + offset);
+}
+
+static void xrt_ucs_event_cb(struct platform_device *pdev, void *arg)
+{
+ struct platform_device  *leaf;
+ struct xrt_event *evt = (struct xrt_event *)arg;
+ enum xrt_events e = evt->xe_evt;
+ enum xrt_subdev_id id = evt->xe_subdev.xevt_subdev_id;
+ int instance = evt->xe_subdev.xevt_subdev_instance;
+
+ switch (e) {
+ case XRT_EVENT_POST_CREATION:
+ break;
+ default:
+ xrt_dbg(pdev, "ignored event %d", e);
+ return;
+ }

this switch is a noop, remove

Will change to if (e != XRT_EVENT_POST_CREATION) return -EINVAL

+
+ if (id != XRT_SUBDEV_CLOCK)
+ return;
+
+ leaf = xleaf_get_leaf_by_id(pdev, XRT_SUBDEV_CLOCK, instance);
+ if (!leaf) {
+ xrt_err(pdev, "does not get clock subdev");
+ return;
+ }
+
+ xleaf_ioctl(leaf, XRT_CLOCK_VERIFY, NULL);
+ xleaf_put_leaf(pdev, leaf);
+}
+
+static void ucs_check(struct xrt_ucs *ucs, bool *latched)
+{

checking but not returning status, change to returning int.

this function is called but xrt_ucs_leaf_ioctl which does return status.

Will remove ucs_check() because it is not used in this patch set.



+ struct ucs_control_status_ch1 *ucs_status_ch1;
+ u32 status;
+
+ mutex_lock(>ucs_lock);
+ status = reg_rd(ucs, CHANNEL1_OFFSET);
+ ucs_status_ch1 = (struct ucs_control_status_ch1

Re: [PATCH V3 XRT Alveo 03/18] fpga: xrt: xclbin file helper functions

2021-03-05 Thread Lizhi Hou

Hi Moritz,


On 02/21/2021 10:33 AM, Moritz Fischer wrote:

On Sun, Feb 21, 2021 at 09:12:37AM -0800, Tom Rix wrote:

On 2/17/21 10:40 PM, Lizhi Hou wrote:

Alveo FPGA firmware and partial reconfigure file are in xclbin format.

This code enumerates and extracts

  Add
code to enumerate and extract sections from xclbin files. xclbin.h is cross
platform and used across all platforms and OS

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xclbin-helper.h |  52 +++
  drivers/fpga/xrt/lib/xclbin.c| 394 ++
  include/uapi/linux/xrt/xclbin.h  | 408 +++
  3 files changed, 854 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xclbin-helper.h
  create mode 100644 drivers/fpga/xrt/lib/xclbin.c
  create mode 100644 include/uapi/linux/xrt/xclbin.h

diff --git a/drivers/fpga/xrt/include/xclbin-helper.h 
b/drivers/fpga/xrt/include/xclbin-helper.h
new file mode 100644
index ..68218efc9d0b
--- /dev/null
+++ b/drivers/fpga/xrt/include/xclbin-helper.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Runtime (XRT) driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *David Zhang 
+ *Sonal Santan 
+ */
+
+#ifndef _XRT_XCLBIN_H
+#define _XRT_XCLBIN_H

The header guard should match the filename.


+
+#include 
+#include 
+#include 
+
+#define ICAP_XCLBIN_V2 "xclbin2"
+#define DMA_HWICAP_BITFILE_BUFFER_SIZE 1024
+#define MAX_XCLBIN_SIZE (1024 * 1024 * 1024) /* Assuming xclbin <= 1G, always 
*/

#defines should have a prefix, maybe XRT_ or XCLBIN_

+
+enum axlf_section_kind;
+struct axlf;
+
+/**
+ * Bitstream header information as defined by Xilinx tools.
+ * Please note that this struct definition is not owned by the driver.
+ */
+struct hw_icap_bit_header {

File headers usually have fixed length fields like uint32_t

Is this a structure the real header is converted into ?


+   unsigned int header_length; /* Length of header in 32 bit words */
+   unsigned int bitstream_length;  /* Length of bitstream to read in bytes*/
+   unsigned char *design_name; /* Design name get from bitstream */
+   unsigned char *part_name;   /* Part name read from bitstream */
+   unsigned char *date;   /* Date read from bitstream header */
+   unsigned char *time;   /* Bitstream creation time */
+   unsigned int magic_length;  /* Length of the magic numbers */
+   unsigned char *version; /* Version string */
+};
+
+const char *xrt_xclbin_kind_to_string(enum axlf_section_kind kind);

Only add decl's that are using in multiple files.

This is only defined in xclbin.c, why does it need to be in the header ?


+int xrt_xclbin_get_section(const struct axlf *xclbin,
+  enum axlf_section_kind kind, void **data,
+  uint64_t *len);
+int xrt_xclbin_get_metadata(struct device *dev, const struct axlf *xclbin, 
char **dtb);
+int xrt_xclbin_parse_bitstream_header(const unsigned char *data,
+ unsigned int size,
+ struct hw_icap_bit_header *header);
+void xrt_xclbin_free_header(struct hw_icap_bit_header *header);
+const char *xrt_clock_type2epname(enum CLOCK_TYPE type);

CLOCK_TYPE needs a prefix, something like XCLBIN_CLOCK_TYPE

+
+#endif /* _XRT_XCLBIN_H */
diff --git a/drivers/fpga/xrt/lib/xclbin.c b/drivers/fpga/xrt/lib/xclbin.c
new file mode 100644
index ..47dc6ca25c1b
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xclbin.c
@@ -0,0 +1,394 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Driver XCLBIN parser
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors: David Zhang 
+ */
+
+#include 
+#include 
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+

What is XHI ?  Maybe expand this, at the lease should comment

+/* Used for parsing bitstream header */
+#define XHI_EVEN_MAGIC_BYTE 0x0f
+#define XHI_ODD_MAGIC_BYTE  0xf0
+
+/* Extra mode for IDLE */
+#define XHI_OP_IDLE  -1
+#define XHI_BIT_HEADER_FAILURE -1
+
+/* The imaginary module length register */
+#define XHI_MLR  15
+
+static inline unsigned char xhi_data_and_inc(const unsigned char *d, int *i, 
int sz)

could move to the *.h

+{_
+   unsigned char data;
+
+   if (*i >= sz)
+   return -1;

The return value of this funtion is not always checked, at the least add a 
dev_err here

+
+   data = d[*i];
+   (*i)++;
+
+   return data;
+}
+
+static const struct axlf_section_header *
+xrt_xclbin_get_section_hdr(const struct axlf *xclbin,
+  enum axlf_section_kind kind)
+{
+   int i = 0;
+
+   for (i = 0; i < xclbin->m_header.m_numSections; i++) {
+   if (xclbin->m_sections[i].m_sectionKind == kind)
+   return >m_sections[i];
+   }
+
+   return NULL;
+}
+
+static int
+xrt_xclbin_check_sect

Re: [PATCH V3 XRT Alveo 10/18] fpga: xrt: VSEC platform driver

2021-03-05 Thread Lizhi Hou

Hi Tom,


On 03/01/2021 11:01 AM, Tom Rix wrote:

On 2/17/21 10:40 PM, Lizhi Hou wrote:

Add VSEC driver. VSEC is a hardware function discovered by walking
PCI Express configure space. A platform device node will be created
for it. VSEC provides board logic UUID and few offset of other hardware
functions.

Is this vsec walking infra or is a general find a list of mmio regions that 
need to be mapped in and do the mapping in as a set of platform drivers ?
vsec is pointed by PCIe vender-specific capability. And vsec itself 
locates on PCI BAR. vsec has a list of minimum IPs (mmio regions) 
required for driver to load firmware and communicate with the other pcie 
function. After firmware is loaded, xrt will look into the fireware 
metadata to get the information of rest IPs.
vsec  driver notifies the root driver for the list of minimum IPs been 
discovered. Then the root driver will create platform device nodes and 
bring up drivers based on vsec's notification.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/lib/xleaf/vsec.c | 359 ++
  1 file changed, 359 insertions(+)
  create mode 100644 drivers/fpga/xrt/lib/xleaf/vsec.c

diff --git a/drivers/fpga/xrt/lib/xleaf/vsec.c 
b/drivers/fpga/xrt/lib/xleaf/vsec.c
new file mode 100644
index ..8e5cb22522ec
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/vsec.c
@@ -0,0 +1,359 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA VSEC Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+
+#define XRT_VSEC "xrt_vsec"
+
+#define VSEC_TYPE_UUID   0x50
+#define VSEC_TYPE_FLASH  0x51
+#define VSEC_TYPE_PLATINFO   0x52
+#define VSEC_TYPE_MAILBOX0x53
+#define VSEC_TYPE_END0xff

Type of devices, this list can not grow much.
Because vsec only contains minimum required IPs for loading firmware and 
communication. The list will only change when there is major hardware 
change.

+
+#define VSEC_UUID_LEN16
+
+struct xrt_vsec_header {
+ u32 format;
+ u32 length;
+ u32 entry_sz;
+ u32 rsvd;
+} __packed;
+
+#define head_rd(g, r)\
+ ioread32((void *)(g)->base + offsetof(struct xrt_vsec_header, r))
+
+#define GET_BAR(entry)   (((entry)->bar_rev >> 4) & 0xf)
+#define GET_BAR_OFF(_entry)  \
+ ({ typeof(_entry) entry = (_entry); \
+  ((entry)->off_lo | ((u64)(entry)->off_hi << 16)); })

A 48 bit value stored in xrt_md_endpoint.bar_off (long)

bar_off should be u64

Will fix this.



+#define GET_REV(entry)   ((entry)->bar_rev & 0xf)
+

I prefer functions over macros.

Will change to inline function.

+struct xrt_vsec_entry {
+ u8  type;
+ u8  bar_rev;
+ u16 off_lo;
+ u32 off_hi;
+ u8  ver_type;
+ u8  minor;
+ u8  major;
+ u8  rsvd0;
+ u32 rsvd1;
+} __packed;
+
+#define read_entry(g, i, e)  \
+ do {\
+ u32 *p = (u32 *)((g)->base +\
+ sizeof(struct xrt_vsec_header) +\
+ (i) * sizeof(struct xrt_vsec_entry));   \
+ u32 off;\
+ for (off = 0;   \
+ off < sizeof(struct xrt_vsec_entry) / 4;\
+ off++)  \
+ *((u32 *)(e) + off) = ioread32(p + off);\
+ } while (0)

This could be a static inline func.

Will change to inline function.

+
+struct vsec_device {
+ u8  type;
+ char*ep_name;
+ ulong   size;
+ char*regmap;
+};
+
+static struct vsec_device vsec_devs[] = {
+ {
+ .type = VSEC_TYPE_UUID,
+ .ep_name = XRT_MD_NODE_BLP_ROM,
+ .size = VSEC_UUID_LEN,
+ .regmap = "vsec-uuid",
+ },
+ {
+ .type = VSEC_TYPE_FLASH,
+ .ep_name = XRT_MD_NODE_FLASH_VSEC,
+ .size = 4096,
+ .regmap = "vsec-flash",
+ },
+ {
+ .type = VSEC_TYPE_PLATINFO,
+ .ep_name = XRT_MD_NODE_PLAT_INFO,
+ .size = 4,
+ .regmap = "vsec-platinfo",
+ },
+ {
+ .type = VSEC_TYPE_MAILBOX,
+ .ep_name = XRT_MD_NODE_MAILBOX_VSEC,
+ .size = 48,
+ .regmap = "vsec-mbx",
+ },

This is a static list, how would a new type be added to this ?
Because the list will only 

Re: [PATCH V3 XRT Alveo 03/18] fpga: xrt: xclbin file helper functions

2021-03-04 Thread Lizhi Hou

Hi Moritz,


On 03/02/2021 07:14 AM, Moritz Fischer wrote:


On Mon, Mar 01, 2021 at 04:25:37PM -0800, Lizhi Hou wrote:

Hi Tom,


On 02/28/2021 08:54 AM, Tom Rix wrote:

CAUTION: This message has originated from an External Source. Please use proper 
judgment and caution when opening attachments, clicking links, or responding to 
this email.


On 2/26/21 1:23 PM, Lizhi Hou wrote:

Hi Tom,



snip


I also do not see a pragma pack, usually this is set of 1 so the compiler does 
not shuffle elements, increase size etc.

This data structure is shared with other tools. And the structure is well 
defined with reasonable alignment. It is compatible with all compilers we have 
tested. So pragma pack is not necessary.

You can not have possibly tested all the configurations since the kernel 
supports many arches and compilers.

If the tested existing alignment is ok, pragma pack should be a noop on your 
tested configurations.

And help cover the untested configurations.

Got it. I will add pragma pack(1).

Please do not use pragma pack(), add __packed to the structs in
question.

Ok, I will use __packed.

Thanks,
Lizhi


- Moritz




Re: [PATCH V3 XRT Alveo 09/18] fpga: xrt: fpga-mgr and region implementation for xclbin download

2021-03-04 Thread Lizhi Hou

Hi Tom,


On 02/28/2021 08:36 AM, Tom Rix wrote:


On 2/17/21 10:40 PM, Lizhi Hou wrote:

fpga-mgr and region implementation for xclbin download which will be
called from main platform driver

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/mgmt/fmgr-drv.c| 187 +++
  drivers/fpga/xrt/mgmt/fmgr.h|  28 ++
  drivers/fpga/xrt/mgmt/main-region.c | 471 
  3 files changed, 686 insertions(+)
  create mode 100644 drivers/fpga/xrt/mgmt/fmgr-drv.c
  create mode 100644 drivers/fpga/xrt/mgmt/fmgr.h
  create mode 100644 drivers/fpga/xrt/mgmt/main-region.c

diff --git a/drivers/fpga/xrt/mgmt/fmgr-drv.c b/drivers/fpga/xrt/mgmt/fmgr-drv.c
new file mode 100644
index ..a44d35ecdb60
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/fmgr-drv.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * FPGA Manager Support for Xilinx Alveo Management Function Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors: sonal.san...@xilinx.com
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "xclbin-helper.h"
+#include "xleaf.h"
+#include "fmgr.h"
+#include "xleaf/axigate.h"
+#include "xleaf/icap.h"
+#include "main-impl.h"
+
+struct xfpga_class {
+ const struct platform_device *pdev;
+ char  name[64];
+};
+
+/*
+ * xclbin download plumbing -- find the download subsystem, ICAP and
+ * pass the xclbin for heavy lifting
+ */
+static int xmgmt_download_bitstream(struct platform_device *pdev,
+ const struct axlf *xclbin)
+
+{
+ struct hw_icap_bit_header bit_header = { 0 };
+ struct platform_device *icap_leaf = NULL;
+ struct xrt_icap_ioctl_wr arg;
+ char *bitstream = NULL;
+ u64 bit_len;
+ int ret;
+
+ ret = xrt_xclbin_get_section(xclbin, BITSTREAM, (void **), 
_len);
+ if (ret || !bitstream) {

!bitstream check is unneeded

Will fix.

+ xrt_err(pdev, "bitstream not found");
+ return -ENOENT;
+ }
+ ret = xrt_xclbin_parse_bitstream_header(bitstream,
+ DMA_HWICAP_BITFILE_BUFFER_SIZE,
+ _header);
+ if (ret) {
+ ret = -EINVAL;
+ xrt_err(pdev, "invalid bitstream header");
+ goto done;
+ }
+ if (bit_header.header_length + bit_header.bitstream_length > bit_len) {
+ ret = -EINVAL;
+ xrt_err(pdev, "invalid bitstream length. header %d, bitstream %d, 
section len %lld",
+ bit_header.header_length, bit_header.bitstream_length, 
bit_len);
+ goto done;
+ }
+
+ icap_leaf = xleaf_get_leaf_by_id(pdev, XRT_SUBDEV_ICAP, 
PLATFORM_DEVID_NONE);
+ if (!icap_leaf) {
+ ret = -ENODEV;
+ xrt_err(pdev, "icap does not exist");
+ xrt_xclbin_free_header(_header);
+ goto done;
+ }
+ arg.xiiw_bit_data = bitstream + bit_header.header_length;
+ arg.xiiw_data_len = bit_header.bitstream_length;
+ ret = xleaf_ioctl(icap_leaf, XRT_ICAP_WRITE, );
+ if (ret)
+ xrt_err(pdev, "write bitstream failed, ret = %d", ret);
+
+ xrt_xclbin_free_header(_header);

memory leak when something fails and goto done's
Based on comments of previous patch, it does not need allocating extra 
memory in header parsing function. xrt_xclbin_free_header() will be removed.

+done:

previous general problem, use mutliple label in error handling blocks

Will fix this.

+ if (icap_leaf)
+ xleaf_put_leaf(pdev, icap_leaf);
+ vfree(bitstream);
+
+ return ret;
+}
+
+/*
+ * There is no HW prep work we do here since we need the full
+ * xclbin for its sanity check.
+ */
+static int xmgmt_pr_write_init(struct fpga_manager *mgr,
+struct fpga_image_info *info,
+const char *buf, size_t count)
+{
+ const struct axlf *bin = (const struct axlf *)buf;
+ struct xfpga_class *obj = mgr->priv;
+
+ if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
+ xrt_info(obj->pdev, "%s only supports partial reconfiguration\n", 
obj->name);
+ return -EINVAL;
+ }
+
+ if (count < sizeof(struct axlf))
+ return -EINVAL;
+
+ if (count > bin->m_header.m_length)
+ return -EINVAL;
+
+ xrt_info(obj->pdev, "Prepare download of xclbin %pUb of length %lld B",
+  >m_header.uuid, bin->m_header.m_length);
+
+ return 0;
+}
+
+/*
+ * The implementation requries full xclbin image before we can start
+ * programming the hardware via ICAP subsystem. Full image is required

The full image

Will fix this.

+ * for checking the validity of xclbin and walking the 

Re: [PATCH V3 XRT Alveo 12/18] fpga: xrt: ICAP platform driver

2021-03-02 Thread Lizhi Hou

Hi Moritz,



On 02/21/2021 12:24 PM, Moritz Fischer wrote:

On Wed, Feb 17, 2021 at 10:40:13PM -0800, Lizhi Hou wrote:

Add ICAP driver. ICAP is a hardware function discovered by walking
firmware metadata. A platform device node will be created for it.
FPGA bitstream is written to hardware through ICAP.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xleaf/icap.h |  29 +++
  drivers/fpga/xrt/lib/xleaf/icap.c | 317 ++
  2 files changed, 346 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xleaf/icap.h
  create mode 100644 drivers/fpga/xrt/lib/xleaf/icap.c

diff --git a/drivers/fpga/xrt/include/xleaf/icap.h 
b/drivers/fpga/xrt/include/xleaf/icap.h
new file mode 100644
index ..a14fc0ffa78f
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/icap.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT ICAP Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *   Lizhi Hou 
+ */
+
+#ifndef _XRT_ICAP_H_
+#define _XRT_ICAP_H_
+
+#include "xleaf.h"
+
+/*
+ * ICAP driver IOCTL calls.
+ */
+enum xrt_icap_ioctl_cmd {
+ XRT_ICAP_WRITE = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+ XRT_ICAP_IDCODE,
+};
+
+struct xrt_icap_ioctl_wr {
+ void*xiiw_bit_data;
+ u32 xiiw_data_len;
+};
+
+#endif   /* _XRT_ICAP_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/icap.c 
b/drivers/fpga/xrt/lib/xleaf/icap.c
new file mode 100644
index ..0500a97bdef9
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/icap.c
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA ICAP Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ *  Sonal Santan 
+ *  Max Zhen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/icap.h"
+#include "xclbin-helper.h"
+
+#define XRT_ICAP "xrt_icap"
+
+#define ICAP_ERR(icap, fmt, arg...)  \
+ xrt_err((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_WARN(icap, fmt, arg...) \
+ xrt_warn((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_INFO(icap, fmt, arg...) \
+ xrt_info((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_DBG(icap, fmt, arg...)  \
+ xrt_dbg((icap)->pdev, fmt "\n", ##arg)

Do we really need two layers of indirection here? What's wrong with
dev_{info,dbg,...} ?
In case that we would change the massage 'fmt' in the future we can 
change it at one place. And it does not expose any interface or 
introduce performance issue. Could we just keep these Macros?

+
+/*
+ * AXI-HWICAP IP register layout
+ */
+struct icap_reg {
+ u32 ir_rsvd1[7];
+ u32 ir_gier;
+ u32 ir_isr;
+ u32 ir_rsvd2;
+ u32 ir_ier;
+ u32 ir_rsvd3[53];
+ u32 ir_wf;
+ u32 ir_rf;
+ u32 ir_sz;
+ u32 ir_cr;
+ u32 ir_sr;
+ u32 ir_wfv;
+ u32 ir_rfo;
+ u32 ir_asr;
+} __packed;

Can we make those #define and just use writel/readl() ? If you want more
abstraction, use regmap

Sure, we will use #define as below and use writel/readl to access them.
  #define ICAP_REG_ISR(base)((base) + 0x20)
  

+
+struct icap {
+ struct platform_device  *pdev;
+ struct icap_reg *icap_regs;
+ struct mutexicap_lock; /* icap dev lock */
+
+ unsigned intidcode;
+};
+
+static inline u32 reg_rd(void __iomem *reg)
+{
+ if (!reg)
+ return -1;
+
+ return ioread32(reg);
+}
+
+static inline void reg_wr(void __iomem *reg, u32 val)
+{
+ if (!reg)
+ return;
+
+ iowrite32(val, reg);
+}
+
+static int wait_for_done(struct icap *icap)
+{
+ u32 w;
+ int i = 0;
+
+ WARN_ON(!mutex_is_locked(>icap_lock));
+ for (i = 0; i < 10; i++) {
+ udelay(5);
+ w = reg_rd(>icap_regs->ir_sr);
+ ICAP_INFO(icap, "XHWICAP_SR: %x", w);
+ if (w & 0x5)
+ return 0;
+ }
+
+ ICAP_ERR(icap, "bitstream download timeout");
+ return -ETIMEDOUT;
+}
+
+static int icap_write(struct icap *icap, const u32 *word_buf, int size)
+{
+ int i;
+ u32 value = 0;
+
+ for (i = 0; i < size; i++) {
+ value = be32_to_cpu(word_buf[i]);
+ reg_wr(>icap_regs->ir_wf, value);
+ }
+
+ reg_wr(>icap_regs->ir_cr, 0x1);
+
+ for (i = 0; i < 20; i++) {
+ value = reg_rd(>icap_regs->ir_cr);
+ if ((value & 0x1) == 0)
+ return 0;
+ ndelay(50);
+ }
+
+ ICAP_ERR(icap, "writing %d dwords timeout", size);
+ return -EIO;
+}
+
+static int bitstream_helper(struct icap *icap, const u32 *word_

Re: [PATCH V3 XRT Alveo 03/18] fpga: xrt: xclbin file helper functions

2021-03-01 Thread Lizhi Hou

Hi Tom,


On 02/28/2021 08:54 AM, Tom Rix wrote:

CAUTION: This message has originated from an External Source. Please use proper 
judgment and caution when opening attachments, clicking links, or responding to 
this email.


On 2/26/21 1:23 PM, Lizhi Hou wrote:

Hi Tom,



snip


I also do not see a pragma pack, usually this is set of 1 so the compiler does 
not shuffle elements, increase size etc.

This data structure is shared with other tools. And the structure is well 
defined with reasonable alignment. It is compatible with all compilers we have 
tested. So pragma pack is not necessary.

You can not have possibly tested all the configurations since the kernel 
supports many arches and compilers.

If the tested existing alignment is ok, pragma pack should be a noop on your 
tested configurations.

And help cover the untested configurations.

Got it. I will add pragma pack(1).

Lizhi


Tom





Re: [PATCH V3 XRT Alveo 00/18] XRT Alveo driver overview

2021-03-01 Thread Lizhi Hou

Hi Moritz,


On 02/21/2021 12:43 PM, Moritz Fischer wrote:

Lizhi,

On Wed, Feb 17, 2021 at 10:40:01PM -0800, Lizhi Hou wrote:

Hello,

This is V3 of patch series which adds management physical function driver for 
Xilinx
Alveo PCIe accelerator cards, 
https://www.xilinx.com/products/boards-and-kits/alveo.html
This driver is part of Xilinx Runtime (XRT) open source stack.

XILINX ALVEO PLATFORM ARCHITECTURE

Alveo PCIe FPGA based platforms have a static *shell* partition and a partial
re-configurable *user* partition. The shell partition is automatically loaded 
from
flash when host is booted and PCIe is enumerated by BIOS. Shell cannot be 
changed
till the next cold reboot. The shell exposes two PCIe physical functions:

1. management physical function
2. user physical function

The patch series includes Documentation/xrt.rst which describes Alveo platform,
XRT driver architecture and deployment model in more detail.

Users compile their high level design in C/C++/OpenCL or RTL into FPGA image 
using
Vitis https://www.xilinx.com/products/design-tools/vitis/vitis-platform.html
tools. The compiled image is packaged as xclbin which contains partial bitstream
for the user partition and necessary metadata. Users can dynamically swap the 
image
running on the user partition in order to switch between different workloads by
loading different xclbins.

XRT DRIVERS FOR XILINX ALVEO

XRT Linux kernel driver *xmgmt* binds to management physical function of Alveo
platform. The modular driver framework is organized into several platform 
drivers
which primarily handle the following functionality:

1.  Loading firmware container also called xsabin at driver attach time
2.  Loading of user compiled xclbin with FPGA Manager integration
3.  Clock scaling of image running on user partition
4.  In-band sensors: temp, voltage, power, etc.
5.  Device reset and rescan

The platform drivers are packaged into *xrt-lib* helper module with well
defined interfaces. The module provides a pseudo-bus implementation for the
platform drivers. More details on the driver model can be found in
Documentation/xrt.rst.

User physical function driver is not included in this patch series.

LIBFDT REQUIREMENT

XRT driver infrastructure uses Device Tree as a metadata format to discover
HW subsystems in the Alveo PCIe device. The Device Tree schema used by XRT
is documented in Documentation/xrt.rst. Unlike previous V1 and V2 version
of patch series, V3 version does not require export of libfdt symbols.

TESTING AND VALIDATION

xmgmt driver can be tested with full XRT open source stack which includes user
space libraries, board utilities and (out of tree) first generation user 
physical
function driver xocl. XRT open source runtime stack is available at
https://github.com/Xilinx/XRT

Complete documentation for XRT open source stack including sections on Alveo/XRT
security and platform architecture can be found here:

https://xilinx.github.io/XRT/master/html/index.html
https://xilinx.github.io/XRT/master/html/security.html
https://xilinx.github.io/XRT/master/html/platforms_partitions.html

Changes since v2:
- Streamlined the driver framework into *xleaf*, *group* and *xroot*
- Updated documentation to show the driver model with examples
- Addressed kernel test robot errors
- Added a selftest for basic driver framework
- Documented device tree schema
- Removed need to export libfdt symbols

Changes since v1:
- Updated the driver to use fpga_region and fpga_bridge for FPGA
   programming
- Dropped platform drivers not related to PR programming to focus on XRT
   core framework
- Updated Documentation/fpga/xrt.rst with information on XRT core framework
- Addressed checkpatch issues
- Dropped xrt- prefix from some header files

For reference V1 version of patch series can be found here:

https://lore.kernel.org/lkml/20201217075046.28553-1-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-2-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-3-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-4-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-5-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-6-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-7-son...@xilinx.com/

Lizhi Hou (18):
   Documentation: fpga: Add a document describing XRT Alveo drivers
   fpga: xrt: driver metadata helper functions
   fpga: xrt: xclbin file helper functions
   fpga: xrt: xrt-lib platform driver manager
   fpga: xrt: group platform driver
   fpga: xrt: platform driver infrastructure
   fpga: xrt: management physical function driver (root)
   fpga: xrt: main platform driver for management function device
   fpga: xrt: fpga-mgr and region implementation for xclbin download
   fpga: xrt: VSEC platform driver
   fpga: xrt: UCS platform driver
   fpga: xrt: ICAP platform driver
   fpga: xrt: devctl platform driver
   fpga: xrt: clock platform driver
   fpga: xrt

Re: [PATCH V3 XRT Alveo 03/18] fpga: xrt: xclbin file helper functions

2021-02-26 Thread Lizhi Hou

Hi Tom,


On 02/21/2021 09:12 AM, Tom Rix wrote:

On 2/17/21 10:40 PM, Lizhi Hou wrote:

Alveo FPGA firmware and partial reconfigure file are in xclbin format.

This code enumerates and extracts

Will change this to

Alveo FPGA firmware and partial reconfigure file are in xclbin format. This
code enumerates and extracts sections from xclbin files. xclbin.h is cross
platform and used across all platforms and OS.

  Add
code to enumerate and extract sections from xclbin files. xclbin.h is cross
platform and used across all platforms and OS

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/xclbin-helper.h |  52 +++
  drivers/fpga/xrt/lib/xclbin.c| 394 ++
  include/uapi/linux/xrt/xclbin.h  | 408 +++
  3 files changed, 854 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/xclbin-helper.h
  create mode 100644 drivers/fpga/xrt/lib/xclbin.c
  create mode 100644 include/uapi/linux/xrt/xclbin.h

diff --git a/drivers/fpga/xrt/include/xclbin-helper.h 
b/drivers/fpga/xrt/include/xclbin-helper.h
new file mode 100644
index ..68218efc9d0b
--- /dev/null
+++ b/drivers/fpga/xrt/include/xclbin-helper.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Runtime (XRT) driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *David Zhang 
+ *Sonal Santan 
+ */
+
+#ifndef _XRT_XCLBIN_H
+#define _XRT_XCLBIN_H

The header guard should match the filename.

will fix this.



+
+#include 
+#include 
+#include 
+
+#define ICAP_XCLBIN_V2   "xclbin2"
+#define DMA_HWICAP_BITFILE_BUFFER_SIZE 1024
+#define MAX_XCLBIN_SIZE (1024 * 1024 * 1024) /* Assuming xclbin <= 1G, always 
*/

#defines should have a prefix, maybe XRT_ or XCLBIN_

Will add prefix XCLBIN_

+
+enum axlf_section_kind;
+struct axlf;
+
+/**
+ * Bitstream header information as defined by Xilinx tools.
+ * Please note that this struct definition is not owned by the driver.
+ */
+struct hw_icap_bit_header {

File headers usually have fixed length fields like uint32_t

Is this a structure the real header is converted into ?
This is not real header. This structure saves the information extracted 
from bitstream header.



+ unsigned int header_length; /* Length of header in 32 bit words */
+ unsigned int bitstream_length;  /* Length of bitstream to read in bytes*/
+ unsigned char *design_name; /* Design name get from bitstream */
+ unsigned char *part_name;   /* Part name read from bitstream */
+ unsigned char *date;   /* Date read from bitstream header */
+ unsigned char *time;   /* Bitstream creation time */
+ unsigned int magic_length;  /* Length of the magic numbers */
+ unsigned char *version; /* Version string */
+};
+
+const char *xrt_xclbin_kind_to_string(enum axlf_section_kind kind);

Only add decl's that are using in multiple files.

This is only defined in xclbin.c, why does it need to be in the header ?

Will remove this.



+int xrt_xclbin_get_section(const struct axlf *xclbin,
+enum axlf_section_kind kind, void **data,
+uint64_t *len);
+int xrt_xclbin_get_metadata(struct device *dev, const struct axlf *xclbin, 
char **dtb);
+int xrt_xclbin_parse_bitstream_header(const unsigned char *data,
+   unsigned int size,
+   struct hw_icap_bit_header *header);
+void xrt_xclbin_free_header(struct hw_icap_bit_header *header);
+const char *xrt_clock_type2epname(enum CLOCK_TYPE type);

CLOCK_TYPE needs a prefix, something like XCLBIN_CLOCK_TYPE

Will change to XCLBIN_CLOCK_TYPE.

+
+#endif /* _XRT_XCLBIN_H */
diff --git a/drivers/fpga/xrt/lib/xclbin.c b/drivers/fpga/xrt/lib/xclbin.c
new file mode 100644
index ..47dc6ca25c1b
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xclbin.c
@@ -0,0 +1,394 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Driver XCLBIN parser
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors: David Zhang 
+ */
+
+#include 
+#include 
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+

What is XHI ?  Maybe expand this, at the lease should comment

Will use BITSTREAM_ instead.

+/* Used for parsing bitstream header */
+#define XHI_EVEN_MAGIC_BYTE 0x0f
+#define XHI_ODD_MAGIC_BYTE  0xf0
+
+/* Extra mode for IDLE */
+#define XHI_OP_IDLE  -1
+#define XHI_BIT_HEADER_FAILURE -1
+
+/* The imaginary module length register */
+#define XHI_MLR  15
+
+static inline unsigned char xhi_data_and_inc(const unsigned char *d, int *i, 
int sz)

could move to the *.h
I will restructure caller function xrt_xclbin_parse_bitstream_header() 
and remove xhi_data_and_inc().

+{_
+ unsigned char data;
+
+ if (*i >= sz)
+ return -1;

The return value of this funtion is not always 

Re: [PATCH V3 XRT Alveo 02/18] fpga: xrt: driver metadata helper functions

2021-02-25 Thread Lizhi Hou

Hi Fernando,


On 02/22/2021 05:23 PM, Fernando Pacheco wrote:

On Wed, Feb 17, 2021 at 10:40:03PM -0800, Lizhi Hou wrote:

XRT drivers use device tree as metadata format to discover HW subsystems
behind PCIe BAR. Thus libfdt functions are called for driver to parse
device tree blob.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/metadata.h  | 229 
  drivers/fpga/xrt/metadata/metadata.c | 524 +++
  2 files changed, 753 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/metadata.h
  create mode 100644 drivers/fpga/xrt/metadata/metadata.c

diff --git a/drivers/fpga/xrt/include/metadata.h 
b/drivers/fpga/xrt/include/metadata.h
new file mode 100644
index ..b929bc469b73
--- /dev/null
+++ b/drivers/fpga/xrt/include/metadata.h
@@ -0,0 +1,229 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Runtime (XRT) driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou 
+ */
+
+#ifndef _XRT_METADATA_H
+#define _XRT_METADATA_H
+
+#include 
+#include 
+#include 
+
+#define XRT_MD_INVALID_LENGTH (~0UL)
+
+#define XRT_MD_PROP_COMPATIBLE "compatible"
+#define XRT_MD_PROP_PF_NUM "pcie_physical_function"
+#define XRT_MD_PROP_BAR_IDX "pcie_bar_mapping"
+#define XRT_MD_PROP_IO_OFFSET "reg"
+#define XRT_MD_PROP_INTERRUPTS "interrupts"
+#define XRT_MD_PROP_INTERFACE_UUID "interface_uuid"
+#define XRT_MD_PROP_LOGIC_UUID "logic_uuid"
+#define XRT_MD_PROP_VERSION_MAJOR "firmware_version_major"
+
+#define XRT_MD_PROP_HWICAP "axi_hwicap"
+#define XRT_MD_PROP_PDI_CONFIG "pdi_config_mem"
+
+#define XRT_MD_NODE_ENDPOINTS "addressable_endpoints"
+#define XRT_MD_INTERFACES_PATH "/interfaces"
+
+#define XRT_MD_NODE_FIRMWARE "firmware"
+#define XRT_MD_NODE_INTERFACES "interfaces"
+#define XRT_MD_NODE_PARTITION_INFO "partition_info"
+
+#define XRT_MD_NODE_FLASH "ep_card_flash_program_00"
+#define XRT_MD_NODE_XVC_PUB "ep_debug_bscan_user_00"
+#define XRT_MD_NODE_XVC_PRI "ep_debug_bscan_mgmt_00"
+#define XRT_MD_NODE_SYSMON "ep_cmp_sysmon_00"
+#define XRT_MD_NODE_AF_BLP_CTRL_MGMT "ep_firewall_blp_ctrl_mgmt_00"
+#define XRT_MD_NODE_AF_BLP_CTRL_USER "ep_firewall_blp_ctrl_user_00"
+#define XRT_MD_NODE_AF_CTRL_MGMT "ep_firewall_ctrl_mgmt_00"
+#define XRT_MD_NODE_AF_CTRL_USER "ep_firewall_ctrl_user_00"
+#define XRT_MD_NODE_AF_CTRL_DEBUG "ep_firewall_ctrl_debug_00"
+#define XRT_MD_NODE_AF_DATA_H2C "ep_firewall_data_h2c_00"
+#define XRT_MD_NODE_AF_DATA_C2H "ep_firewall_data_c2h_00"
+#define XRT_MD_NODE_AF_DATA_P2P "ep_firewall_data_p2p_00"
+#define XRT_MD_NODE_AF_DATA_M2M "ep_firewall_data_m2m_00"
+#define XRT_MD_NODE_CMC_REG "ep_cmc_regmap_00"
+#define XRT_MD_NODE_CMC_RESET "ep_cmc_reset_00"
+#define XRT_MD_NODE_CMC_MUTEX "ep_cmc_mutex_00"
+#define XRT_MD_NODE_CMC_FW_MEM "ep_cmc_firmware_mem_00"
+#define XRT_MD_NODE_ERT_FW_MEM "ep_ert_firmware_mem_00"
+#define XRT_MD_NODE_ERT_CQ_MGMT "ep_ert_command_queue_mgmt_00"
+#define XRT_MD_NODE_ERT_CQ_USER "ep_ert_command_queue_user_00"
+#define XRT_MD_NODE_MAILBOX_MGMT "ep_mailbox_mgmt_00"
+#define XRT_MD_NODE_MAILBOX_USER "ep_mailbox_user_00"
+#define XRT_MD_NODE_GATE_PLP "ep_pr_isolate_plp_00"
+#define XRT_MD_NODE_GATE_ULP "ep_pr_isolate_ulp_00"
+#define XRT_MD_NODE_PCIE_MON "ep_pcie_link_mon_00"
+#define XRT_MD_NODE_DDR_CALIB "ep_ddr_mem_calib_00"
+#define XRT_MD_NODE_CLK_KERNEL1 "ep_aclk_kernel_00"
+#define XRT_MD_NODE_CLK_KERNEL2 "ep_aclk_kernel_01"
+#define XRT_MD_NODE_CLK_KERNEL3 "ep_aclk_hbm_00"
+#define XRT_MD_NODE_KDMA_CTRL "ep_kdma_ctrl_00"
+#define XRT_MD_NODE_FPGA_CONFIG "ep_fpga_configuration_00"
+#define XRT_MD_NODE_ERT_SCHED "ep_ert_sched_00"
+#define XRT_MD_NODE_XDMA "ep_xdma_00"
+#define XRT_MD_NODE_MSIX "ep_msix_00"
+#define XRT_MD_NODE_QDMA "ep_qdma_00"
+#define XRT_MD_XRT_MD_NODE_QDMA4 "ep_qdma4_00"
+#define XRT_MD_NODE_STM "ep_stream_traffic_manager_00"
+#define XRT_MD_NODE_STM4 "ep_stream_traffic_manager4_00"
+#define XRT_MD_NODE_CLK_SHUTDOWN "ep_aclk_shutdown_00"
+#define XRT_MD_NODE_ERT_BASE "ep_ert_base_address_00"
+#define XRT_MD_NODE_ERT_RESET "ep_ert_reset_00"
+#define XRT_MD_NODE_CLKFREQ_K1 "ep_freq_cnt_aclk_kernel_00"
+#define XRT_MD_NODE_CLKFREQ_K2 "ep_freq_cnt_aclk_kernel_01"
+#define XRT_MD_NODE_CLKFREQ_HBM "ep_freq_cnt_aclk_hbm_00"
+#define XRT_MD_NODE_GAPPING "ep_gapping_demand_00"
+#define XRT_MD_NODE_UCS_

Re: [PATCH V3 XRT Alveo 02/18] fpga: xrt: driver metadata helper functions

2021-02-22 Thread Lizhi Hou

Hi Tom,


On 02/20/2021 09:07 AM, Tom Rix wrote:

On 2/17/21 10:40 PM, Lizhi Hou wrote:

XRT drivers use device tree as metadata format to discover HW subsystems
behind PCIe BAR. Thus libfdt functions are called for driver to parse

for the driver to parse the

will fix.

device tree blob.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
  drivers/fpga/xrt/include/metadata.h  | 229 
  drivers/fpga/xrt/metadata/metadata.c | 524 +++
  2 files changed, 753 insertions(+)
  create mode 100644 drivers/fpga/xrt/include/metadata.h
  create mode 100644 drivers/fpga/xrt/metadata/metadata.c

diff --git a/drivers/fpga/xrt/include/metadata.h 
b/drivers/fpga/xrt/include/metadata.h
new file mode 100644
index ..b929bc469b73
--- /dev/null
+++ b/drivers/fpga/xrt/include/metadata.h
@@ -0,0 +1,229 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Runtime (XRT) driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou 
+ */
+
+#ifndef _XRT_METADATA_H
+#define _XRT_METADATA_H
+
+#include 
+#include 
+#include 
+
+#define XRT_MD_INVALID_LENGTH (~0UL)
+

These #defines could be in alphabetical order

Some #define with embedded acronyms could be expanded

ex/ XRT_MD_NODE_CMC_REG , what is CMC ?
Will reorder. Expanding might make macro name too long. I will add 
comment as below:

/*
* IP nodes
* AF: AXI Firewall
* CMC: Card Management Controller
* ERT: Embedded Runtime
* PLP: Provider Reconfigurable Partition
* ULP: User Reconfigurable Partition
*/



+#define XRT_MD_PROP_COMPATIBLE "compatible"
+#define XRT_MD_PROP_PF_NUM "pcie_physical_function"
+#define XRT_MD_PROP_BAR_IDX "pcie_bar_mapping"
+#define XRT_MD_PROP_IO_OFFSET "reg"
+#define XRT_MD_PROP_INTERRUPTS "interrupts"
+#define XRT_MD_PROP_INTERFACE_UUID "interface_uuid"
+#define XRT_MD_PROP_LOGIC_UUID "logic_uuid"
+#define XRT_MD_PROP_VERSION_MAJOR "firmware_version_major"
+
+#define XRT_MD_PROP_HWICAP "axi_hwicap"
+#define XRT_MD_PROP_PDI_CONFIG "pdi_config_mem"
+
+#define XRT_MD_NODE_ENDPOINTS "addressable_endpoints"
+#define XRT_MD_INTERFACES_PATH "/interfaces"
+
+#define XRT_MD_NODE_FIRMWARE "firmware"
+#define XRT_MD_NODE_INTERFACES "interfaces"
+#define XRT_MD_NODE_PARTITION_INFO "partition_info"
+
+#define XRT_MD_NODE_FLASH "ep_card_flash_program_00"
+#define XRT_MD_NODE_XVC_PUB "ep_debug_bscan_user_00"
+#define XRT_MD_NODE_XVC_PRI "ep_debug_bscan_mgmt_00"
+#define XRT_MD_NODE_SYSMON "ep_cmp_sysmon_00"
+#define XRT_MD_NODE_AF_BLP_CTRL_MGMT "ep_firewall_blp_ctrl_mgmt_00"
+#define XRT_MD_NODE_AF_BLP_CTRL_USER "ep_firewall_blp_ctrl_user_00"
+#define XRT_MD_NODE_AF_CTRL_MGMT "ep_firewall_ctrl_mgmt_00"
+#define XRT_MD_NODE_AF_CTRL_USER "ep_firewall_ctrl_user_00"
+#define XRT_MD_NODE_AF_CTRL_DEBUG "ep_firewall_ctrl_debug_00"
+#define XRT_MD_NODE_AF_DATA_H2C "ep_firewall_data_h2c_00"
+#define XRT_MD_NODE_AF_DATA_C2H "ep_firewall_data_c2h_00"
+#define XRT_MD_NODE_AF_DATA_P2P "ep_firewall_data_p2p_00"
+#define XRT_MD_NODE_AF_DATA_M2M "ep_firewall_data_m2m_00"
+#define XRT_MD_NODE_CMC_REG "ep_cmc_regmap_00"
+#define XRT_MD_NODE_CMC_RESET "ep_cmc_reset_00"
+#define XRT_MD_NODE_CMC_MUTEX "ep_cmc_mutex_00"
+#define XRT_MD_NODE_CMC_FW_MEM "ep_cmc_firmware_mem_00"
+#define XRT_MD_NODE_ERT_FW_MEM "ep_ert_firmware_mem_00"
+#define XRT_MD_NODE_ERT_CQ_MGMT "ep_ert_command_queue_mgmt_00"
+#define XRT_MD_NODE_ERT_CQ_USER "ep_ert_command_queue_user_00"
+#define XRT_MD_NODE_MAILBOX_MGMT "ep_mailbox_mgmt_00"
+#define XRT_MD_NODE_MAILBOX_USER "ep_mailbox_user_00"
+#define XRT_MD_NODE_GATE_PLP "ep_pr_isolate_plp_00"
+#define XRT_MD_NODE_GATE_ULP "ep_pr_isolate_ulp_00"
+#define XRT_MD_NODE_PCIE_MON "ep_pcie_link_mon_00"
+#define XRT_MD_NODE_DDR_CALIB "ep_ddr_mem_calib_00"
+#define XRT_MD_NODE_CLK_KERNEL1 "ep_aclk_kernel_00"
+#define XRT_MD_NODE_CLK_KERNEL2 "ep_aclk_kernel_01"
+#define XRT_MD_NODE_CLK_KERNEL3 "ep_aclk_hbm_00"
+#define XRT_MD_NODE_KDMA_CTRL "ep_kdma_ctrl_00"
+#define XRT_MD_NODE_FPGA_CONFIG "ep_fpga_configuration_00"
+#define XRT_MD_NODE_ERT_SCHED "ep_ert_sched_00"
+#define XRT_MD_NODE_XDMA "ep_xdma_00"
+#define XRT_MD_NODE_MSIX "ep_msix_00"
+#define XRT_MD_NODE_QDMA "ep_qdma_00"
+#define XRT_MD_XRT_MD_NODE_QDMA4 "ep_qdma4_00"
+#define XRT_MD_NODE_STM "ep_stream_traffic_manager_00"
+#define XRT_MD_NODE_STM4 "ep_stream_traffic_manager4_00"
+#define XRT_MD_NODE_CLK_SHUTDOWN "ep_aclk_shutdown_00"
+#define XR

Re: [PATCH V3 XRT Alveo 00/18] XRT Alveo driver overview

2021-02-18 Thread Lizhi Hou




On 02/18/2021 05:52 AM, Tom Rix wrote:

On 2/17/21 10:40 PM, Lizhi Hou wrote:

Hello,

This is V3 of patch series which adds management physical function driver for 
Xilinx
Alveo PCIe accelerator cards, 
https://www.xilinx.com/products/boards-and-kits/alveo.html
This driver is part of Xilinx Runtime (XRT) open source stack.

XILINX ALVEO PLATFORM ARCHITECTURE

Thanks for refreshing this patchset.

It will take me a while to do the full review, so I thought I would give some 
early feed back.

It applies to char-misc-next, but will have conflicts with in-flight patches 
around the MAINTAINERS file. This is not a big deal.

The checkpatch is much better over v2, the complaints are

WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#21:
new file mode 100644

WARNING: From:/Signed-off-by: email address mismatch: 'From: Lizhi Hou 
' != 'Signed-off-by: Lizhi Hou '

MAINTAINERS warning i believe you address in the last patch.

In the next revisions, please fix the signoff.

The test robot is complaining about hppa64.  While it may be an unlikely 
config, it would be best to fix it.
Thanks for reviewing. I will fix signoff, hppa64 and arm build issue 
reported by robot in next revision.


Tom


Alveo PCIe FPGA based platforms have a static *shell* partition and a partial
re-configurable *user* partition. The shell partition is automatically loaded 
from
flash when host is booted and PCIe is enumerated by BIOS. Shell cannot be 
changed
till the next cold reboot. The shell exposes two PCIe physical functions:

1. management physical function
2. user physical function

The patch series includes Documentation/xrt.rst which describes Alveo platform,
XRT driver architecture and deployment model in more detail.

Users compile their high level design in C/C++/OpenCL or RTL into FPGA image 
using
Vitis https://www.xilinx.com/products/design-tools/vitis/vitis-platform.html
tools. The compiled image is packaged as xclbin which contains partial bitstream
for the user partition and necessary metadata. Users can dynamically swap the 
image
running on the user partition in order to switch between different workloads by
loading different xclbins.

XRT DRIVERS FOR XILINX ALVEO

XRT Linux kernel driver *xmgmt* binds to management physical function of Alveo
platform. The modular driver framework is organized into several platform 
drivers
which primarily handle the following functionality:

1.  Loading firmware container also called xsabin at driver attach time
2.  Loading of user compiled xclbin with FPGA Manager integration
3.  Clock scaling of image running on user partition
4.  In-band sensors: temp, voltage, power, etc.
5.  Device reset and rescan

The platform drivers are packaged into *xrt-lib* helper module with well
defined interfaces. The module provides a pseudo-bus implementation for the
platform drivers. More details on the driver model can be found in
Documentation/xrt.rst.

User physical function driver is not included in this patch series.

LIBFDT REQUIREMENT

XRT driver infrastructure uses Device Tree as a metadata format to discover
HW subsystems in the Alveo PCIe device. The Device Tree schema used by XRT
is documented in Documentation/xrt.rst. Unlike previous V1 and V2 version
of patch series, V3 version does not require export of libfdt symbols.

TESTING AND VALIDATION

xmgmt driver can be tested with full XRT open source stack which includes user
space libraries, board utilities and (out of tree) first generation user 
physical
function driver xocl. XRT open source runtime stack is available at
https://github.com/Xilinx/XRT

Complete documentation for XRT open source stack including sections on Alveo/XRT
security and platform architecture can be found here:

https://xilinx.github.io/XRT/master/html/index.html
https://xilinx.github.io/XRT/master/html/security.html
https://xilinx.github.io/XRT/master/html/platforms_partitions.html

Changes since v2:
- Streamlined the driver framework into *xleaf*, *group* and *xroot*
- Updated documentation to show the driver model with examples
- Addressed kernel test robot errors
- Added a selftest for basic driver framework
- Documented device tree schema
- Removed need to export libfdt symbols

Changes since v1:
- Updated the driver to use fpga_region and fpga_bridge for FPGA
   programming
- Dropped platform drivers not related to PR programming to focus on XRT
   core framework
- Updated Documentation/fpga/xrt.rst with information on XRT core framework
- Addressed checkpatch issues
- Dropped xrt- prefix from some header files

For reference V1 version of patch series can be found here:

https://lore.kernel.org/lkml/20201217075046.28553-1-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-2-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-3-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-4-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-5-son...@xilinx.com/
https

[PATCH V3 XRT Alveo 10/18] fpga: xrt: VSEC platform driver

2021-02-17 Thread Lizhi Hou
Add VSEC driver. VSEC is a hardware function discovered by walking
PCI Express configure space. A platform device node will be created
for it. VSEC provides board logic UUID and few offset of other hardware
functions.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/lib/xleaf/vsec.c | 359 ++
 1 file changed, 359 insertions(+)
 create mode 100644 drivers/fpga/xrt/lib/xleaf/vsec.c

diff --git a/drivers/fpga/xrt/lib/xleaf/vsec.c 
b/drivers/fpga/xrt/lib/xleaf/vsec.c
new file mode 100644
index ..8e5cb22522ec
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/vsec.c
@@ -0,0 +1,359 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA VSEC Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+
+#define XRT_VSEC "xrt_vsec"
+
+#define VSEC_TYPE_UUID 0x50
+#define VSEC_TYPE_FLASH0x51
+#define VSEC_TYPE_PLATINFO 0x52
+#define VSEC_TYPE_MAILBOX  0x53
+#define VSEC_TYPE_END  0xff
+
+#define VSEC_UUID_LEN  16
+
+struct xrt_vsec_header {
+   u32 format;
+   u32 length;
+   u32 entry_sz;
+   u32 rsvd;
+} __packed;
+
+#define head_rd(g, r)  \
+   ioread32((void *)(g)->base + offsetof(struct xrt_vsec_header, r))
+
+#define GET_BAR(entry) (((entry)->bar_rev >> 4) & 0xf)
+#define GET_BAR_OFF(_entry)\
+   ({ typeof(_entry) entry = (_entry); \
+((entry)->off_lo | ((u64)(entry)->off_hi << 16)); })
+#define GET_REV(entry) ((entry)->bar_rev & 0xf)
+
+struct xrt_vsec_entry {
+   u8  type;
+   u8  bar_rev;
+   u16 off_lo;
+   u32 off_hi;
+   u8  ver_type;
+   u8  minor;
+   u8  major;
+   u8  rsvd0;
+   u32 rsvd1;
+} __packed;
+
+#define read_entry(g, i, e)\
+   do {\
+   u32 *p = (u32 *)((g)->base +\
+   sizeof(struct xrt_vsec_header) +\
+   (i) * sizeof(struct xrt_vsec_entry));   \
+   u32 off;\
+   for (off = 0;   \
+   off < sizeof(struct xrt_vsec_entry) / 4;\
+   off++)  \
+   *((u32 *)(e) + off) = ioread32(p + off);\
+   } while (0)
+
+struct vsec_device {
+   u8  type;
+   char*ep_name;
+   ulong   size;
+   char*regmap;
+};
+
+static struct vsec_device vsec_devs[] = {
+   {
+   .type = VSEC_TYPE_UUID,
+   .ep_name = XRT_MD_NODE_BLP_ROM,
+   .size = VSEC_UUID_LEN,
+   .regmap = "vsec-uuid",
+   },
+   {
+   .type = VSEC_TYPE_FLASH,
+   .ep_name = XRT_MD_NODE_FLASH_VSEC,
+   .size = 4096,
+   .regmap = "vsec-flash",
+   },
+   {
+   .type = VSEC_TYPE_PLATINFO,
+   .ep_name = XRT_MD_NODE_PLAT_INFO,
+   .size = 4,
+   .regmap = "vsec-platinfo",
+   },
+   {
+   .type = VSEC_TYPE_MAILBOX,
+   .ep_name = XRT_MD_NODE_MAILBOX_VSEC,
+   .size = 48,
+   .regmap = "vsec-mbx",
+   },
+};
+
+struct xrt_vsec {
+   struct platform_device  *pdev;
+   void*base;
+   ulong   length;
+
+   char*metadata;
+   charuuid[VSEC_UUID_LEN];
+};
+
+static char *type2epname(u32 type)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(vsec_devs); i++) {
+   if (vsec_devs[i].type == type)
+   return (vsec_devs[i].ep_name);
+   }
+
+   return NULL;
+}
+
+static ulong type2size(u32 type)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(vsec_devs); i++) {
+   if (vsec_devs[i].type == type)
+   return (vsec_devs[i].size);
+   }
+
+   return 0;
+}
+
+static char *type2regmap(u32 type)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(vsec_devs); i++) {
+   if (vsec_devs[i].type == type)
+   return (vsec_devs[i].regmap);
+   }
+
+   return NULL;
+}
+
+static int xrt_vsec_add_node(struct xrt_vsec *vsec,
+void *md_blob, struct xrt_vsec_entry *p_entry)
+{
+   struct xrt_md_endpoint ep;
+   char regmap_ver[64];
+   int ret;
+
+ 

[PATCH V3 XRT Alveo 13/18] fpga: xrt: devctl platform driver

2021-02-17 Thread Lizhi Hou
Add devctl driver. devctl is a type of hardware function which only has
few registers to read or write. They are discovered by walking firmware
metadata. A platform device node will be created for them.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/devctl.h |  43 +
 drivers/fpga/xrt/lib/xleaf/devctl.c | 206 
 2 files changed, 249 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/devctl.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/devctl.c

diff --git a/drivers/fpga/xrt/include/xleaf/devctl.h 
b/drivers/fpga/xrt/include/xleaf/devctl.h
new file mode 100644
index ..96a40e066f83
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/devctl.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT DEVCTL Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_DEVCTL_H_
+#define _XRT_DEVCTL_H_
+
+#include "xleaf.h"
+
+/*
+ * DEVCTL driver IOCTL calls.
+ */
+enum xrt_devctl_ioctl_cmd {
+   XRT_DEVCTL_READ = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+   XRT_DEVCTL_WRITE,
+};
+
+enum xrt_devctl_id {
+   XRT_DEVCTL_ROM_UUID,
+   XRT_DEVCTL_DDR_CALIB,
+   XRT_DEVCTL_GOLDEN_VER,
+   XRT_DEVCTL_MAX
+};
+
+struct xrt_devctl_ioctl_rw {
+   u32 xgir_id;
+   void*xgir_buf;
+   u32 xgir_len;
+   u32 xgir_offset;
+};
+
+struct xrt_devctl_ioctl_intf_uuid {
+   u32 xgir_uuid_num;
+   uuid_t  *xgir_uuids;
+};
+
+#endif /* _XRT_DEVCTL_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/devctl.c 
b/drivers/fpga/xrt/lib/xleaf/devctl.c
new file mode 100644
index ..caf8c6569f0f
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/devctl.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA devctl Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/devctl.h"
+
+#define XRT_DEVCTL "xrt_devctl"
+
+struct xrt_name_id {
+   char *ep_name;
+   int id;
+};
+
+static struct xrt_name_id name_id[XRT_DEVCTL_MAX] = {
+   { XRT_MD_NODE_BLP_ROM, XRT_DEVCTL_ROM_UUID },
+   { XRT_MD_NODE_GOLDEN_VER, XRT_DEVCTL_GOLDEN_VER },
+};
+
+struct xrt_devctl {
+   struct platform_device  *pdev;
+   void__iomem *base_addrs[XRT_DEVCTL_MAX];
+   ulong   sizes[XRT_DEVCTL_MAX];
+};
+
+static int xrt_devctl_name2id(struct xrt_devctl *devctl, const char *name)
+{
+   int i;
+
+   for (i = 0; i < XRT_DEVCTL_MAX && name_id[i].ep_name; i++) {
+   if (!strncmp(name_id[i].ep_name, name, 
strlen(name_id[i].ep_name) + 1))
+   return name_id[i].id;
+   }
+
+   return -EINVAL;
+}
+
+static int
+xrt_devctl_leaf_ioctl(struct platform_device *pdev, u32 cmd, void *arg)
+{
+   struct xrt_devctl   *devctl;
+   int ret = 0;
+
+   devctl = platform_get_drvdata(pdev);
+
+   switch (cmd) {
+   case XRT_XLEAF_EVENT:
+   /* Does not handle any event. */
+   break;
+   case XRT_DEVCTL_READ: {
+   struct xrt_devctl_ioctl_rw  *rw_arg = arg;
+   u32 *p_src, *p_dst, i;
+
+   if (rw_arg->xgir_len & 0x3) {
+   xrt_err(pdev, "invalid len %d", rw_arg->xgir_len);
+   return -EINVAL;
+   }
+
+   if (rw_arg->xgir_id >= XRT_DEVCTL_MAX) {
+   xrt_err(pdev, "invalid id %d", rw_arg->xgir_id);
+   return -EINVAL;
+   }
+
+   p_src = devctl->base_addrs[rw_arg->xgir_id];
+   if (!p_src) {
+   xrt_err(pdev, "io not found, id %d",
+   rw_arg->xgir_id);
+   return -EINVAL;
+   }
+   if (rw_arg->xgir_offset + rw_arg->xgir_len >
+   devctl->sizes[rw_arg->xgir_id]) {
+   xrt_err(pdev, "invalid argument, off %d, len %d",
+   rw_arg->xgir_offset, rw_arg->xgir_len);
+   return -EINVAL;
+   }
+   p_dst = rw_arg->xgir_buf;
+   for (i = 0; i < rw_arg->xgir_len / sizeof(u32); i++) {
+   u32 val = ioread32(p_src + rw_arg->xgir_offset + i);
+
+   memcpy(p_dst + i, , sizeof(u32));
+   }
+   break;
+   }
+   default:
+   xrt_err(pdev, "unsupported cmd %d", cmd);
+   return -EINVAL;
+ 

[PATCH V3 XRT Alveo 11/18] fpga: xrt: UCS platform driver

2021-02-17 Thread Lizhi Hou
Add UCS driver. UCS is a hardware function discovered by walking xclbin
metadata. A platform device node will be created for it.
UCS enables/disables the dynamic region clocks.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/ucs.h |  24 +++
 drivers/fpga/xrt/lib/xleaf/ucs.c | 235 +++
 2 files changed, 259 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/ucs.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/ucs.c

diff --git a/drivers/fpga/xrt/include/xleaf/ucs.h 
b/drivers/fpga/xrt/include/xleaf/ucs.h
new file mode 100644
index ..a5ef0e100e12
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/ucs.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT UCS Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_UCS_H_
+#define _XRT_UCS_H_
+
+#include "xleaf.h"
+
+/*
+ * UCS driver IOCTL calls.
+ */
+enum xrt_ucs_ioctl_cmd {
+   XRT_UCS_CHECK = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+   XRT_UCS_ENABLE,
+};
+
+#endif /* _XRT_UCS_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/ucs.c b/drivers/fpga/xrt/lib/xleaf/ucs.c
new file mode 100644
index ..ae762c8fddbb
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/ucs.c
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA UCS Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/ucs.h"
+#include "xleaf/clock.h"
+
+#define UCS_ERR(ucs, fmt, arg...)   \
+   xrt_err((ucs)->pdev, fmt "\n", ##arg)
+#define UCS_WARN(ucs, fmt, arg...)  \
+   xrt_warn((ucs)->pdev, fmt "\n", ##arg)
+#define UCS_INFO(ucs, fmt, arg...)  \
+   xrt_info((ucs)->pdev, fmt "\n", ##arg)
+#define UCS_DBG(ucs, fmt, arg...)   \
+   xrt_dbg((ucs)->pdev, fmt "\n", ##arg)
+
+#define XRT_UCS"xrt_ucs"
+
+#define CHANNEL1_OFFSET0
+#define CHANNEL2_OFFSET8
+
+#define CLK_MAX_VALUE  6400
+
+struct ucs_control_status_ch1 {
+   unsigned int shutdown_clocks_latched:1;
+   unsigned int reserved1:15;
+   unsigned int clock_throttling_average:14;
+   unsigned int reserved2:2;
+};
+
+struct xrt_ucs {
+   struct platform_device  *pdev;
+   void __iomem*ucs_base;
+   struct mutexucs_lock; /* ucs dev lock */
+};
+
+static inline u32 reg_rd(struct xrt_ucs *ucs, u32 offset)
+{
+   return ioread32(ucs->ucs_base + offset);
+}
+
+static inline void reg_wr(struct xrt_ucs *ucs, u32 val, u32 offset)
+{
+   iowrite32(val, ucs->ucs_base + offset);
+}
+
+static void xrt_ucs_event_cb(struct platform_device *pdev, void *arg)
+{
+   struct platform_device  *leaf;
+   struct xrt_event *evt = (struct xrt_event *)arg;
+   enum xrt_events e = evt->xe_evt;
+   enum xrt_subdev_id id = evt->xe_subdev.xevt_subdev_id;
+   int instance = evt->xe_subdev.xevt_subdev_instance;
+
+   switch (e) {
+   case XRT_EVENT_POST_CREATION:
+   break;
+   default:
+   xrt_dbg(pdev, "ignored event %d", e);
+   return;
+   }
+
+   if (id != XRT_SUBDEV_CLOCK)
+   return;
+
+   leaf = xleaf_get_leaf_by_id(pdev, XRT_SUBDEV_CLOCK, instance);
+   if (!leaf) {
+   xrt_err(pdev, "does not get clock subdev");
+   return;
+   }
+
+   xleaf_ioctl(leaf, XRT_CLOCK_VERIFY, NULL);
+   xleaf_put_leaf(pdev, leaf);
+}
+
+static void ucs_check(struct xrt_ucs *ucs, bool *latched)
+{
+   struct ucs_control_status_ch1 *ucs_status_ch1;
+   u32 status;
+
+   mutex_lock(>ucs_lock);
+   status = reg_rd(ucs, CHANNEL1_OFFSET);
+   ucs_status_ch1 = (struct ucs_control_status_ch1 *)
+   if (ucs_status_ch1->shutdown_clocks_latched) {
+   UCS_ERR(ucs,
+   "Critical temperature or power event, kernel clocks 
have been stopped.");
+   UCS_ERR(ucs,
+   "run 'xbutil valiate -q' to continue. See AR 73398 for 
more details.");
+   /* explicitly indicate reset should be latched */
+   *latched = true;
+   } else if (ucs_status_ch1->clock_throttling_average >
+   CLK_MAX_VALUE) {
+   UCS_ERR(ucs, "kernel clocks %d exceeds expected maximum value 
%d.",
+   ucs_status_ch1->clock_throttling_average,
+   CLK_MAX_VALUE);
+   } else if (ucs_status_ch1->clock_throttling_average) {
+   UCS_ERR(ucs, "kernel clocks

[PATCH V3 XRT Alveo 16/18] fpga: xrt: DDR calibration platform driver

2021-02-17 Thread Lizhi Hou
Add DDR calibration driver. DDR calibration is a hardware function
discovered by walking firmware metadata. A platform device node will
be created for it. Hardware provides DDR calibration status through
this function.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/calib.h |  30 
 drivers/fpga/xrt/lib/xleaf/calib.c | 226 +
 2 files changed, 256 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/calib.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/calib.c

diff --git a/drivers/fpga/xrt/include/xleaf/calib.h 
b/drivers/fpga/xrt/include/xleaf/calib.h
new file mode 100644
index ..f8aba4594c58
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/calib.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT DDR Calibration Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_CALIB_H_
+#define _XRT_CALIB_H_
+
+#include "xleaf.h"
+#include 
+
+/*
+ * Memory calibration driver IOCTL calls.
+ */
+enum xrt_calib_results {
+   XRT_CALIB_UNKNOWN,
+   XRT_CALIB_SUCCEEDED,
+   XRT_CALIB_FAILED,
+};
+
+enum xrt_calib_ioctl_cmd {
+   XRT_CALIB_RESULT = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+};
+
+#endif /* _XRT_CALIB_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/calib.c 
b/drivers/fpga/xrt/lib/xleaf/calib.c
new file mode 100644
index ..fbb813636e76
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/calib.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA memory calibration driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * memory calibration
+ *
+ * Authors:
+ *      Lizhi Hou
+ */
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+#include "xleaf/calib.h"
+
+#define XRT_CALIB  "xrt_calib"
+
+struct calib_cache {
+   struct list_headlink;
+   const char  *ep_name;
+   char*data;
+   u32 data_size;
+};
+
+struct calib {
+   struct platform_device  *pdev;
+   void*calib_base;
+   struct mutexlock; /* calibration dev lock */
+   struct list_headcache_list;
+   u32 cache_num;
+   enum xrt_calib_results  result;
+};
+
+#define CALIB_DONE(calib)  \
+   (ioread32((calib)->calib_base) & BIT(0))
+
+static void calib_cache_clean_nolock(struct calib *calib)
+{
+   struct calib_cache *cache, *temp;
+
+   list_for_each_entry_safe(cache, temp, >cache_list, link) {
+   vfree(cache->data);
+   list_del(>link);
+   vfree(cache);
+   }
+   calib->cache_num = 0;
+}
+
+static void calib_cache_clean(struct calib *calib)
+{
+   mutex_lock(>lock);
+   calib_cache_clean_nolock(calib);
+   mutex_unlock(>lock);
+}
+
+static int calib_srsr(struct calib *calib, struct platform_device *srsr_leaf)
+{
+   return -EOPNOTSUPP;
+}
+
+static int calib_calibration(struct calib *calib)
+{
+   int i;
+
+   for (i = 0; i < 20; i++) {
+   if (CALIB_DONE(calib))
+   break;
+   msleep(500);
+   }
+
+   if (i == 20) {
+   xrt_err(calib->pdev,
+   "MIG calibration timeout after bitstream download");
+   return -ETIMEDOUT;
+   }
+
+   xrt_info(calib->pdev, "took %dms", i * 500);
+   return 0;
+}
+
+static void xrt_calib_event_cb(struct platform_device *pdev, void *arg)
+{
+   struct calib *calib = platform_get_drvdata(pdev);
+   struct xrt_event *evt = (struct xrt_event *)arg;
+   enum xrt_events e = evt->xe_evt;
+   enum xrt_subdev_id id = evt->xe_subdev.xevt_subdev_id;
+   int instance = evt->xe_subdev.xevt_subdev_instance;
+   struct platform_device *leaf;
+   int ret;
+
+   switch (e) {
+   case XRT_EVENT_POST_CREATION: {
+   if (id == XRT_SUBDEV_SRSR) {
+   leaf = xleaf_get_leaf_by_id(pdev,
+   XRT_SUBDEV_SRSR,
+   instance);
+   if (!leaf) {
+   xrt_err(pdev, "does not get SRSR subdev");
+   return;
+   }
+   ret = calib_srsr(calib, leaf);
+   xleaf_put_leaf(pdev, leaf);
+   calib->result =
+   ret ? XRT_CALIB_FAILED : XRT_CALIB_SUCCEEDED;
+   } else if (id == XRT_SUBDEV_UCS) {
+   ret = calib_calibration(calib);
+   calib->result =
+  

[PATCH V3 XRT Alveo 17/18] fpga: xrt: partition isolation platform driver

2021-02-17 Thread Lizhi Hou
Add partition isolation platform driver. partition isolation is
a hardware function discovered by walking firmware metadata.
A platform device node will be created for it. Partition isolation
function isolate the different fpga regions

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/axigate.h |  25 ++
 drivers/fpga/xrt/lib/xleaf/axigate.c | 298 +++
 2 files changed, 323 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/axigate.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/axigate.c

diff --git a/drivers/fpga/xrt/include/xleaf/axigate.h 
b/drivers/fpga/xrt/include/xleaf/axigate.h
new file mode 100644
index ..2cef71e13b30
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/axigate.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT Axigate Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_AXIGATE_H_
+#define _XRT_AXIGATE_H_
+
+#include "xleaf.h"
+#include "metadata.h"
+
+/*
+ * AXIGATE driver IOCTL calls.
+ */
+enum xrt_axigate_ioctl_cmd {
+   XRT_AXIGATE_FREEZE = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h 
*/
+   XRT_AXIGATE_FREE,
+};
+
+#endif /* _XRT_AXIGATE_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/axigate.c 
b/drivers/fpga/xrt/lib/xleaf/axigate.c
new file mode 100644
index ..382969f9925f
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/axigate.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA AXI Gate Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/axigate.h"
+
+#define XRT_AXIGATE "xrt_axigate"
+
+struct axigate_regs {
+   u32 iag_wr;
+   u32 iag_rvsd;
+   u32 iag_rd;
+} __packed;
+
+struct xrt_axigate {
+   struct platform_device  *pdev;
+   void*base;
+   struct mutexgate_lock; /* gate dev lock */
+
+   void*evt_hdl;
+   const char  *ep_name;
+
+   boolgate_freezed;
+};
+
+/* the ep names are in the order of hardware layers */
+static const char * const xrt_axigate_epnames[] = {
+   XRT_MD_NODE_GATE_PLP,
+   XRT_MD_NODE_GATE_ULP,
+   NULL
+};
+
+#define reg_rd(g, r)   \
+   ioread32((void *)(g)->base + offsetof(struct axigate_regs, r))
+#define reg_wr(g, v, r)\
+   iowrite32(v, (void *)(g)->base + offsetof(struct axigate_regs, r))
+
+static inline void freeze_gate(struct xrt_axigate *gate)
+{
+   reg_wr(gate, 0, iag_wr);
+   ndelay(500);
+   reg_rd(gate, iag_rd);
+}
+
+static inline void free_gate(struct xrt_axigate *gate)
+{
+   reg_wr(gate, 0x2, iag_wr);
+   ndelay(500);
+   (void)reg_rd(gate, iag_rd);
+   reg_wr(gate, 0x3, iag_wr);
+   ndelay(500);
+   reg_rd(gate, iag_rd);
+}
+
+static int xrt_axigate_epname_idx(struct platform_device *pdev)
+{
+   int i;
+   int ret;
+   struct resource *res;
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (!res) {
+   xrt_err(pdev, "Empty Resource!");
+   return -EINVAL;
+   }
+
+   for (i = 0; xrt_axigate_epnames[i]; i++) {
+   ret = strncmp(xrt_axigate_epnames[i], res->name,
+ strlen(xrt_axigate_epnames[i]) + 1);
+   if (!ret)
+   break;
+   }
+
+   ret = (xrt_axigate_epnames[i]) ? i : -EINVAL;
+   return ret;
+}
+
+static void xrt_axigate_freeze(struct platform_device *pdev)
+{
+   struct xrt_axigate  *gate;
+   u32 freeze = 0;
+
+   gate = platform_get_drvdata(pdev);
+
+   mutex_lock(>gate_lock);
+   freeze = reg_rd(gate, iag_rd);
+   if (freeze) {   /* gate is opened */
+   xleaf_broadcast_event(pdev, XRT_EVENT_PRE_GATE_CLOSE, false);
+   freeze_gate(gate);
+   }
+
+   gate->gate_freezed = true;
+   mutex_unlock(>gate_lock);
+
+   xrt_info(pdev, "freeze gate %s", gate->ep_name);
+}
+
+static void xrt_axigate_free(struct platform_device *pdev)
+{
+   struct xrt_axigate  *gate;
+   u32 freeze;
+
+   gate = platform_get_drvdata(pdev);
+
+   mutex_lock(>gate_lock);
+   freeze = reg_rd(gate, iag_rd);
+   if (!freeze) {  /* gate is closed */
+   free_gate(gate);
+   xleaf_broadcast_event(pdev, XRT_EVENT_POST_GATE_OPEN, true);
+   /* x

[PATCH V3 XRT Alveo 15/18] fpga: xrt: clock frequence counter platform driver

2021-02-17 Thread Lizhi Hou
Add clock frequence counter driver. Clock frequence counter is
a hardware function discovered by walking xclbin metadata. A platform
device node will be created for it. Other part of driver can read the
actual clock frequence through clock frequence counter driver.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/clkfreq.h |  23 +++
 drivers/fpga/xrt/lib/xleaf/clkfreq.c | 221 +++
 2 files changed, 244 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/clkfreq.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/clkfreq.c

diff --git a/drivers/fpga/xrt/include/xleaf/clkfreq.h 
b/drivers/fpga/xrt/include/xleaf/clkfreq.h
new file mode 100644
index ..29fc45e8a31b
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/clkfreq.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT Clock Counter Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_CLKFREQ_H_
+#define _XRT_CLKFREQ_H_
+
+#include "xleaf.h"
+
+/*
+ * CLKFREQ driver IOCTL calls.
+ */
+enum xrt_clkfreq_ioctl_cmd {
+   XRT_CLKFREQ_READ = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+};
+
+#endif /* _XRT_CLKFREQ_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/clkfreq.c 
b/drivers/fpga/xrt/lib/xleaf/clkfreq.c
new file mode 100644
index ..2482dd2cff47
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/clkfreq.c
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Clock Frequency Counter Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/clkfreq.h"
+
+#define CLKFREQ_ERR(clkfreq, fmt, arg...)   \
+   xrt_err((clkfreq)->pdev, fmt "\n", ##arg)
+#define CLKFREQ_WARN(clkfreq, fmt, arg...)  \
+   xrt_warn((clkfreq)->pdev, fmt "\n", ##arg)
+#define CLKFREQ_INFO(clkfreq, fmt, arg...)  \
+   xrt_info((clkfreq)->pdev, fmt "\n", ##arg)
+#define CLKFREQ_DBG(clkfreq, fmt, arg...)   \
+   xrt_dbg((clkfreq)->pdev, fmt "\n", ##arg)
+
+#define XRT_CLKFREQ"xrt_clkfreq"
+
+#define OCL_CLKWIZ_STATUS_MASK 0x
+
+#define OCL_CLKWIZ_STATUS_MEASURE_START0x1
+#define OCL_CLKWIZ_STATUS_MEASURE_DONE 0x2
+#define OCL_CLK_FREQ_COUNTER_OFFSET0x8
+#define OCL_CLK_FREQ_V5_COUNTER_OFFSET 0x10
+#define OCL_CLK_FREQ_V5_CLK0_ENABLED   0x1
+
+struct clkfreq {
+   struct platform_device  *pdev;
+   void __iomem*clkfreq_base;
+   const char  *clkfreq_ep_name;
+   struct mutexclkfreq_lock; /* clock counter dev lock */
+};
+
+static inline u32 reg_rd(struct clkfreq *clkfreq, u32 offset)
+{
+   return ioread32(clkfreq->clkfreq_base + offset);
+}
+
+static inline void reg_wr(struct clkfreq *clkfreq, u32 val, u32 offset)
+{
+   iowrite32(val, clkfreq->clkfreq_base + offset);
+}
+
+static u32 clkfreq_read(struct clkfreq *clkfreq)
+{
+   u32 freq = 0, status;
+   int times = 10;
+
+   mutex_lock(>clkfreq_lock);
+   reg_wr(clkfreq, OCL_CLKWIZ_STATUS_MEASURE_START, 0);
+   while (times != 0) {
+   status = reg_rd(clkfreq, 0);
+   if ((status & OCL_CLKWIZ_STATUS_MASK) ==
+   OCL_CLKWIZ_STATUS_MEASURE_DONE)
+   break;
+   mdelay(1);
+   times--;
+   };
+   if (times > 0) {
+   freq = (status & OCL_CLK_FREQ_V5_CLK0_ENABLED) ?
+   reg_rd(clkfreq, OCL_CLK_FREQ_V5_COUNTER_OFFSET) :
+   reg_rd(clkfreq, OCL_CLK_FREQ_COUNTER_OFFSET);
+   }
+   mutex_unlock(>clkfreq_lock);
+
+   return freq;
+}
+
+static ssize_t freq_show(struct device *dev, struct device_attribute *attr, 
char *buf)
+{
+   struct clkfreq *clkfreq = platform_get_drvdata(to_platform_device(dev));
+   u32 freq;
+   ssize_t count;
+
+   freq = clkfreq_read(clkfreq);
+   count = snprintf(buf, 64, "%d\n", freq);
+
+   return count;
+}
+static DEVICE_ATTR_RO(freq);
+
+static struct attribute *clkfreq_attrs[] = {
+   _attr_freq.attr,
+   NULL,
+};
+
+static struct attribute_group clkfreq_attr_group = {
+   .attrs = clkfreq_attrs,
+};
+
+static int
+xrt_clkfreq_leaf_ioctl(struct platform_device *pdev, u32 cmd, void *arg)
+{
+   struct clkfreq  *clkfreq;
+   int ret = 0;
+
+   clkfreq = platform_get_drvdata(pdev);
+
+   switch (cmd) {
+   case XRT_XLEAF_EVENT:
+   /* Does not handle any event. */
+   break;
+   case XRT_CLKFREQ_READ: {
+   *(u32 *)arg = clkfreq_read(clkfreq);
+   break;
+   }
+ 

[PATCH V3 XRT Alveo 12/18] fpga: xrt: ICAP platform driver

2021-02-17 Thread Lizhi Hou
Add ICAP driver. ICAP is a hardware function discovered by walking
firmware metadata. A platform device node will be created for it.
FPGA bitstream is written to hardware through ICAP.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/icap.h |  29 +++
 drivers/fpga/xrt/lib/xleaf/icap.c | 317 ++
 2 files changed, 346 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/icap.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/icap.c

diff --git a/drivers/fpga/xrt/include/xleaf/icap.h 
b/drivers/fpga/xrt/include/xleaf/icap.h
new file mode 100644
index ..a14fc0ffa78f
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/icap.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT ICAP Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_ICAP_H_
+#define _XRT_ICAP_H_
+
+#include "xleaf.h"
+
+/*
+ * ICAP driver IOCTL calls.
+ */
+enum xrt_icap_ioctl_cmd {
+   XRT_ICAP_WRITE = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+   XRT_ICAP_IDCODE,
+};
+
+struct xrt_icap_ioctl_wr {
+   void*xiiw_bit_data;
+   u32 xiiw_data_len;
+};
+
+#endif /* _XRT_ICAP_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/icap.c 
b/drivers/fpga/xrt/lib/xleaf/icap.c
new file mode 100644
index ..0500a97bdef9
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/icap.c
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA ICAP Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ *  Sonal Santan 
+ *  Max Zhen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/icap.h"
+#include "xclbin-helper.h"
+
+#define XRT_ICAP "xrt_icap"
+
+#define ICAP_ERR(icap, fmt, arg...)\
+   xrt_err((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_WARN(icap, fmt, arg...)   \
+   xrt_warn((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_INFO(icap, fmt, arg...)   \
+   xrt_info((icap)->pdev, fmt "\n", ##arg)
+#define ICAP_DBG(icap, fmt, arg...)\
+   xrt_dbg((icap)->pdev, fmt "\n", ##arg)
+
+/*
+ * AXI-HWICAP IP register layout
+ */
+struct icap_reg {
+   u32 ir_rsvd1[7];
+   u32 ir_gier;
+   u32 ir_isr;
+   u32 ir_rsvd2;
+   u32 ir_ier;
+   u32 ir_rsvd3[53];
+   u32 ir_wf;
+   u32 ir_rf;
+   u32 ir_sz;
+   u32 ir_cr;
+   u32 ir_sr;
+   u32 ir_wfv;
+   u32 ir_rfo;
+   u32 ir_asr;
+} __packed;
+
+struct icap {
+   struct platform_device  *pdev;
+   struct icap_reg *icap_regs;
+   struct mutexicap_lock; /* icap dev lock */
+
+   unsigned intidcode;
+};
+
+static inline u32 reg_rd(void __iomem *reg)
+{
+   if (!reg)
+   return -1;
+
+   return ioread32(reg);
+}
+
+static inline void reg_wr(void __iomem *reg, u32 val)
+{
+   if (!reg)
+   return;
+
+   iowrite32(val, reg);
+}
+
+static int wait_for_done(struct icap *icap)
+{
+   u32 w;
+   int i = 0;
+
+   WARN_ON(!mutex_is_locked(>icap_lock));
+   for (i = 0; i < 10; i++) {
+   udelay(5);
+   w = reg_rd(>icap_regs->ir_sr);
+   ICAP_INFO(icap, "XHWICAP_SR: %x", w);
+   if (w & 0x5)
+   return 0;
+   }
+
+   ICAP_ERR(icap, "bitstream download timeout");
+   return -ETIMEDOUT;
+}
+
+static int icap_write(struct icap *icap, const u32 *word_buf, int size)
+{
+   int i;
+   u32 value = 0;
+
+   for (i = 0; i < size; i++) {
+   value = be32_to_cpu(word_buf[i]);
+   reg_wr(>icap_regs->ir_wf, value);
+   }
+
+   reg_wr(>icap_regs->ir_cr, 0x1);
+
+   for (i = 0; i < 20; i++) {
+   value = reg_rd(>icap_regs->ir_cr);
+   if ((value & 0x1) == 0)
+   return 0;
+   ndelay(50);
+   }
+
+   ICAP_ERR(icap, "writing %d dwords timeout", size);
+   return -EIO;
+}
+
+static int bitstream_helper(struct icap *icap, const u32 *word_buffer,
+   u32 word_count)
+{
+   u32 remain_word;
+   u32 word_written = 0;
+   int wr_fifo_vacancy = 0;
+   int err = 0;
+
+   WARN_ON(!mutex_is_locked(>icap_lock));
+   for (remain_word = word_count; remain_word > 0;
+   remain_word -= word_written, word_buffer += word_written) {
+   wr_fifo_vacancy = reg_rd(>icap_regs->ir_wfv);
+   if (wr_fifo_vacancy <= 0) {
+   ICAP_ERR(icap, "no vacancy: %d&quo

[PATCH V3 XRT Alveo 18/18] fpga: xrt: Kconfig and Makefile updates for XRT drivers

2021-02-17 Thread Lizhi Hou
Update fpga Kconfig/Makefile and add Kconfig/Makefile for new drivers.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 MAINTAINERS| 11 +++
 drivers/Makefile   |  1 +
 drivers/fpga/Kconfig   |  2 ++
 drivers/fpga/Makefile  |  4 
 drivers/fpga/xrt/Kconfig   |  8 
 drivers/fpga/xrt/lib/Kconfig   | 16 
 drivers/fpga/xrt/lib/Makefile  | 30 ++
 drivers/fpga/xrt/metadata/Kconfig  | 12 
 drivers/fpga/xrt/metadata/Makefile | 16 
 drivers/fpga/xrt/mgmt/Kconfig  | 15 +++
 drivers/fpga/xrt/mgmt/Makefile | 19 +++
 11 files changed, 134 insertions(+)
 create mode 100644 drivers/fpga/xrt/Kconfig
 create mode 100644 drivers/fpga/xrt/lib/Kconfig
 create mode 100644 drivers/fpga/xrt/lib/Makefile
 create mode 100644 drivers/fpga/xrt/metadata/Kconfig
 create mode 100644 drivers/fpga/xrt/metadata/Makefile
 create mode 100644 drivers/fpga/xrt/mgmt/Kconfig
 create mode 100644 drivers/fpga/xrt/mgmt/Makefile

diff --git a/MAINTAINERS b/MAINTAINERS
index d3e847f7f3dc..e6e147c2454c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6973,6 +6973,17 @@ F:   Documentation/fpga/
 F: drivers/fpga/
 F: include/linux/fpga/
 
+FPGA XRT DRIVERS
+M: Lizhi Hou 
+R: Max Zhen 
+R: Sonal Santan 
+L: linux-f...@vger.kernel.org
+S: Maintained
+W: https://github.com/Xilinx/XRT
+F: Documentation/fpga/xrt.rst
+F: drivers/fpga/xrt/
+F: include/uapi/linux/xrt/
+
 FPU EMULATOR
 M: Bill Metzenthen 
 S: Maintained
diff --git a/drivers/Makefile b/drivers/Makefile
index fd11b9ac4cc3..e03912af8e48 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -178,6 +178,7 @@ obj-$(CONFIG_STM)   += hwtracing/stm/
 obj-$(CONFIG_ANDROID)  += android/
 obj-$(CONFIG_NVMEM)+= nvmem/
 obj-$(CONFIG_FPGA) += fpga/
+obj-y  += fpga/xrt/metadata/
 obj-$(CONFIG_FSI)  += fsi/
 obj-$(CONFIG_TEE)  += tee/
 obj-$(CONFIG_MULTIPLEXER)  += mux/
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 5645226ca3ce..aeca635b1f25 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -216,4 +216,6 @@ config FPGA_MGR_ZYNQMP_FPGA
  to configure the programmable logic(PL) through PS
  on ZynqMP SoC.
 
+source "drivers/fpga/xrt/Kconfig"
+
 endif # FPGA
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index d8e21dfc6778..2b4453ff7c52 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -46,3 +46,7 @@ dfl-afu-objs += dfl-afu-error.o
 
 # Drivers for FPGAs which implement DFL
 obj-$(CONFIG_FPGA_DFL_PCI) += dfl-pci.o
+
+# XRT drivers for Alveo
+obj-$(CONFIG_FPGA_XRT_LIB) += xrt/lib/
+obj-$(CONFIG_FPGA_XRT_XMGMT)   += xrt/mgmt/
diff --git a/drivers/fpga/xrt/Kconfig b/drivers/fpga/xrt/Kconfig
new file mode 100644
index ..0e2c59589ddd
--- /dev/null
+++ b/drivers/fpga/xrt/Kconfig
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Xilinx Alveo FPGA device configuration
+#
+
+source "drivers/fpga/xrt/metadata/Kconfig"
+source "drivers/fpga/xrt/lib/Kconfig"
+source "drivers/fpga/xrt/mgmt/Kconfig"
diff --git a/drivers/fpga/xrt/lib/Kconfig b/drivers/fpga/xrt/lib/Kconfig
new file mode 100644
index ..eed5cb73f5e2
--- /dev/null
+++ b/drivers/fpga/xrt/lib/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# XRT Alveo FPGA device configuration
+#
+
+config FPGA_XRT_LIB
+   tristate "XRT Alveo Driver Library"
+   depends on HWMON && PCI && HAS_IOMEM
+   select FPGA_XRT_METADATA
+   help
+ Select this option to enable Xilinx XRT Alveo driver library. This
+ library is core infrastructure of XRT Alveo FPGA drivers which
+ provides functions for working with device nodes, iteration and
+ lookup of platform devices, common interfaces for platform devices,
+ plumbing of function call and ioctls between platform devices and
+ parent partitions.
diff --git a/drivers/fpga/xrt/lib/Makefile b/drivers/fpga/xrt/lib/Makefile
new file mode 100644
index ..5641231b2a36
--- /dev/null
+++ b/drivers/fpga/xrt/lib/Makefile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2020-2021 Xilinx, Inc. All rights reserved.
+#
+# Authors: sonal.san...@xilinx.com
+#
+
+FULL_XRT_PATH=$(srctree)/$(src)/..
+FULL_DTC_PATH=$(srctree)/scripts/dtc/libfdt
+
+obj-$(CONFIG_FPGA_XRT_LIB) += xrt-lib.o
+
+xrt-lib-objs :=\
+   main.o  \
+   xroot.o \
+   xclbin.o\
+   subdev.o\
+   cdev.o  \
+   group.o \
+   xleaf/vsec.o

[PATCH V3 XRT Alveo 14/18] fpga: xrt: clock platform driver

2021-02-17 Thread Lizhi Hou
Add clock driver. Clock is a hardware function discovered by walking
xclbin metadata. A platform device node will be created for it. Other
part of driver configures clock through clock driver.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xleaf/clock.h |  31 ++
 drivers/fpga/xrt/lib/xleaf/clock.c | 648 +
 2 files changed, 679 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/clock.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/clock.c

diff --git a/drivers/fpga/xrt/include/xleaf/clock.h 
b/drivers/fpga/xrt/include/xleaf/clock.h
new file mode 100644
index ..a2da59b32551
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/clock.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for XRT Clock Leaf Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Lizhi Hou 
+ */
+
+#ifndef _XRT_CLOCK_H_
+#define _XRT_CLOCK_H_
+
+#include "xleaf.h"
+#include 
+
+/*
+ * CLOCK driver IOCTL calls.
+ */
+enum xrt_clock_ioctl_cmd {
+   XRT_CLOCK_SET = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+   XRT_CLOCK_GET,
+   XRT_CLOCK_VERIFY,
+};
+
+struct xrt_clock_ioctl_get {
+   u16 freq;
+   u32 freq_cnter;
+};
+
+#endif /* _XRT_CLOCK_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/clock.c 
b/drivers/fpga/xrt/lib/xleaf/clock.c
new file mode 100644
index ..a067b501a607
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/clock.c
@@ -0,0 +1,648 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Clock Wizard Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou
+ *  Sonal Santan 
+ *  David Zhang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/clock.h"
+#include "xleaf/clkfreq.h"
+
+/* CLOCK_MAX_NUM_CLOCKS should be a concept from XCLBIN_ in the future */
+#define CLOCK_MAX_NUM_CLOCKS   4
+#define OCL_CLKWIZ_STATUS_OFFSET   0x4
+#define OCL_CLKWIZ_STATUS_MASK 0x
+#define OCL_CLKWIZ_STATUS_MEASURE_START0x1
+#define OCL_CLKWIZ_STATUS_MEASURE_DONE 0x2
+#define OCL_CLKWIZ_CONFIG_OFFSET(n)(0x200 + 4 * (n))
+#define CLOCK_DEFAULT_EXPIRE_SECS  1
+
+#define CLOCK_ERR(clock, fmt, arg...)  \
+   xrt_err((clock)->pdev, fmt "\n", ##arg)
+#define CLOCK_WARN(clock, fmt, arg...) \
+   xrt_warn((clock)->pdev, fmt "\n", ##arg)
+#define CLOCK_INFO(clock, fmt, arg...) \
+   xrt_info((clock)->pdev, fmt "\n", ##arg)
+#define CLOCK_DBG(clock, fmt, arg...)  \
+   xrt_dbg((clock)->pdev, fmt "\n", ##arg)
+
+#define XRT_CLOCK  "xrt_clock"
+
+struct clock {
+   struct platform_device  *pdev;
+   void __iomem*clock_base;
+   struct mutexclock_lock; /* clock dev lock */
+
+   const char  *clock_ep_name;
+};
+
+/*
+ * Precomputed table with config0 and config2 register values together with
+ * target frequency. The steps are approximately 5 MHz apart. Table is
+ * generated by wiz.pl.
+ */
+static const struct xmgmt_ocl_clockwiz {
+   /* target frequency */
+   unsigned short ocl;
+   /* config0 register */
+   unsigned long config0;
+   /* config2 register */
+   unsigned int config2;
+} frequency_table[] = {
+   {/*1275.000*/   10.000, 0x02EE0C01, 0x0001F47F},
+   {/*1575.000*/   15.000, 0x02EE0F01, 0x0069},
+   {/*1600.000*/   20.000, 0x1001, 0x0050},
+   {/*1600.000*/   25.000, 0x1001, 0x0040},
+   {/*1575.000*/   30.000, 0x02EE0F01, 0x0001F434},
+   {/*1575.000*/   35.000, 0x02EE0F01, 0x002D},
+   {/*1600.000*/   40.000, 0x1001, 0x0028},
+   {/*1575.000*/   45.000, 0x02EE0F01, 0x0023},
+   {/*1600.000*/   50.000, 0x1001, 0x0020},
+   {/*1512.500*/   55.000, 0x007D0F01, 0x0001F41B},
+   {/*1575.000*/   60.000, 0x02EE0F01, 0xFA1A},
+   {/*1462.500*/   65.000, 0x02710E01, 0x0001F416},
+   {/*1575.000*/   70.000, 0x02EE0F01, 0x0001F416},
+   {/*1575.000*/   75.000, 0x02EE0F01, 0x0015},
+   {/*1600.000*/   80.000, 0x1001, 0x0014},
+   {/*1487.500*/   85.000, 0x036B0E01, 0x0001F411},
+   {/*1575.000*/   90.000, 0x02EE0F01, 0x0001F411},
+   {/*1425.000*/   95.000, 0x00FA0E01, 0x000F},
+   {/*1600.000*/   100.000,0x1001, 0x0010},
+   {/*1575.000*/   105.000,0x02EE0F01, 0x000F},
+   {/*1512.500*/   110.000,0x007D0F01, 0x0002EE0D},
+   {/*1437.500*/   115.000,0x01770E01, 0

[PATCH V3 XRT Alveo 09/18] fpga: xrt: fpga-mgr and region implementation for xclbin download

2021-02-17 Thread Lizhi Hou
fpga-mgr and region implementation for xclbin download which will be
called from main platform driver

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/mgmt/fmgr-drv.c| 187 +++
 drivers/fpga/xrt/mgmt/fmgr.h|  28 ++
 drivers/fpga/xrt/mgmt/main-region.c | 471 
 3 files changed, 686 insertions(+)
 create mode 100644 drivers/fpga/xrt/mgmt/fmgr-drv.c
 create mode 100644 drivers/fpga/xrt/mgmt/fmgr.h
 create mode 100644 drivers/fpga/xrt/mgmt/main-region.c

diff --git a/drivers/fpga/xrt/mgmt/fmgr-drv.c b/drivers/fpga/xrt/mgmt/fmgr-drv.c
new file mode 100644
index ..a44d35ecdb60
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/fmgr-drv.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * FPGA Manager Support for Xilinx Alveo Management Function Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors: sonal.san...@xilinx.com
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "xclbin-helper.h"
+#include "xleaf.h"
+#include "fmgr.h"
+#include "xleaf/axigate.h"
+#include "xleaf/icap.h"
+#include "main-impl.h"
+
+struct xfpga_class {
+   const struct platform_device *pdev;
+   char  name[64];
+};
+
+/*
+ * xclbin download plumbing -- find the download subsystem, ICAP and
+ * pass the xclbin for heavy lifting
+ */
+static int xmgmt_download_bitstream(struct platform_device *pdev,
+   const struct axlf *xclbin)
+
+{
+   struct hw_icap_bit_header bit_header = { 0 };
+   struct platform_device *icap_leaf = NULL;
+   struct xrt_icap_ioctl_wr arg;
+   char *bitstream = NULL;
+   u64 bit_len;
+   int ret;
+
+   ret = xrt_xclbin_get_section(xclbin, BITSTREAM, (void **), 
_len);
+   if (ret || !bitstream) {
+   xrt_err(pdev, "bitstream not found");
+   return -ENOENT;
+   }
+   ret = xrt_xclbin_parse_bitstream_header(bitstream,
+   DMA_HWICAP_BITFILE_BUFFER_SIZE,
+   _header);
+   if (ret) {
+   ret = -EINVAL;
+   xrt_err(pdev, "invalid bitstream header");
+   goto done;
+   }
+   if (bit_header.header_length + bit_header.bitstream_length > bit_len) {
+   ret = -EINVAL;
+   xrt_err(pdev, "invalid bitstream length. header %d, bitstream 
%d, section len %lld",
+   bit_header.header_length, bit_header.bitstream_length, 
bit_len);
+   goto done;
+   }
+
+   icap_leaf = xleaf_get_leaf_by_id(pdev, XRT_SUBDEV_ICAP, 
PLATFORM_DEVID_NONE);
+   if (!icap_leaf) {
+   ret = -ENODEV;
+   xrt_err(pdev, "icap does not exist");
+   xrt_xclbin_free_header(_header);
+   goto done;
+   }
+   arg.xiiw_bit_data = bitstream + bit_header.header_length;
+   arg.xiiw_data_len = bit_header.bitstream_length;
+   ret = xleaf_ioctl(icap_leaf, XRT_ICAP_WRITE, );
+   if (ret)
+   xrt_err(pdev, "write bitstream failed, ret = %d", ret);
+
+   xrt_xclbin_free_header(_header);
+done:
+   if (icap_leaf)
+   xleaf_put_leaf(pdev, icap_leaf);
+   vfree(bitstream);
+
+   return ret;
+}
+
+/*
+ * There is no HW prep work we do here since we need the full
+ * xclbin for its sanity check.
+ */
+static int xmgmt_pr_write_init(struct fpga_manager *mgr,
+  struct fpga_image_info *info,
+  const char *buf, size_t count)
+{
+   const struct axlf *bin = (const struct axlf *)buf;
+   struct xfpga_class *obj = mgr->priv;
+
+   if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
+   xrt_info(obj->pdev, "%s only supports partial 
reconfiguration\n", obj->name);
+   return -EINVAL;
+   }
+
+   if (count < sizeof(struct axlf))
+   return -EINVAL;
+
+   if (count > bin->m_header.m_length)
+   return -EINVAL;
+
+   xrt_info(obj->pdev, "Prepare download of xclbin %pUb of length %lld B",
+>m_header.uuid, bin->m_header.m_length);
+
+   return 0;
+}
+
+/*
+ * The implementation requries full xclbin image before we can start
+ * programming the hardware via ICAP subsystem. Full image is required
+ * for checking the validity of xclbin and walking the sections to
+ * discover the bitstream.
+ */
+static int xmgmt_pr_write(struct fpga_manager *mgr,
+ const char *buf, size_t count)
+{
+   const struct axlf *bin = (const struct axlf *)buf;
+   struct xfpga_class *obj = mgr->priv;
+
+   if (bin->m_header.m_length !

[PATCH V3 XRT Alveo 07/18] fpga: xrt: management physical function driver (root)

2021-02-17 Thread Lizhi Hou
The PCIE device driver which attaches to management function on Alveo
devices. It instantiates one or more partition drivers which in turn
instantiate platform drivers. The instantiation of partition and platform
drivers is completely data driven.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xroot.h | 114 +++
 drivers/fpga/xrt/mgmt/root.c | 342 +++
 2 files changed, 456 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xroot.h
 create mode 100644 drivers/fpga/xrt/mgmt/root.c

diff --git a/drivers/fpga/xrt/include/xroot.h b/drivers/fpga/xrt/include/xroot.h
new file mode 100644
index ..752e10daa85e
--- /dev/null
+++ b/drivers/fpga/xrt/include/xroot.h
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Runtime (XRT) driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_ROOT_H_
+#define _XRT_ROOT_H_
+
+#include 
+#include "subdev_id.h"
+#include "events.h"
+
+typedef bool (*xrt_subdev_match_t)(enum xrt_subdev_id,
+   struct platform_device *, void *);
+#define XRT_SUBDEV_MATCH_PREV  ((xrt_subdev_match_t)-1)
+#define XRT_SUBDEV_MATCH_NEXT  ((xrt_subdev_match_t)-2)
+
+/*
+ * Root IOCTL calls.
+ */
+enum xrt_root_ioctl_cmd {
+   /* Leaf actions. */
+   XRT_ROOT_GET_LEAF = 0,
+   XRT_ROOT_PUT_LEAF,
+   XRT_ROOT_GET_LEAF_HOLDERS,
+
+   /* Group actions. */
+   XRT_ROOT_CREATE_GROUP,
+   XRT_ROOT_REMOVE_GROUP,
+   XRT_ROOT_LOOKUP_GROUP,
+   XRT_ROOT_WAIT_GROUP_BRINGUP,
+
+   /* Event actions. */
+   XRT_ROOT_EVENT,
+   XRT_ROOT_EVENT_ASYNC,
+
+   /* Device info. */
+   XRT_ROOT_GET_RESOURCE,
+   XRT_ROOT_GET_ID,
+
+   /* Misc. */
+   XRT_ROOT_HOT_RESET,
+   XRT_ROOT_HWMON,
+};
+
+struct xrt_root_ioctl_get_leaf {
+   struct platform_device *xpigl_pdev; /* caller's pdev */
+   xrt_subdev_match_t xpigl_match_cb;
+   void *xpigl_match_arg;
+   struct platform_device *xpigl_leaf; /* target leaf pdev */
+};
+
+struct xrt_root_ioctl_put_leaf {
+   struct platform_device *xpipl_pdev; /* caller's pdev */
+   struct platform_device *xpipl_leaf; /* target's pdev */
+};
+
+struct xrt_root_ioctl_lookup_group {
+   struct platform_device *xpilp_pdev; /* caller's pdev */
+   xrt_subdev_match_t xpilp_match_cb;
+   void *xpilp_match_arg;
+   int xpilp_grp_inst;
+};
+
+struct xrt_root_ioctl_get_holders {
+   struct platform_device *xpigh_pdev; /* caller's pdev */
+   char *xpigh_holder_buf;
+   size_t xpigh_holder_buf_len;
+};
+
+struct xrt_root_ioctl_get_res {
+   struct resource *xpigr_res;
+};
+
+struct xrt_root_ioctl_get_id {
+   unsigned short  xpigi_vendor_id;
+   unsigned short  xpigi_device_id;
+   unsigned short  xpigi_sub_vendor_id;
+   unsigned short  xpigi_sub_device_id;
+};
+
+struct xrt_root_ioctl_hwmon {
+   bool xpih_register;
+   const char *xpih_name;
+   void *xpih_drvdata;
+   const struct attribute_group **xpih_groups;
+   struct device *xpih_hwmon_dev;
+};
+
+typedef int (*xrt_subdev_root_cb_t)(struct device *, void *, u32, void *);
+int xrt_subdev_root_request(struct platform_device *self, u32 cmd, void *arg);
+
+/*
+ * Defines physical function (MPF / UPF) specific operations
+ * needed in common root driver.
+ */
+struct xroot_pf_cb {
+   void (*xpc_hot_reset)(struct pci_dev *pdev);
+};
+
+int xroot_probe(struct pci_dev *pdev, struct xroot_pf_cb *cb, void **root);
+void xroot_remove(void *root);
+bool xroot_wait_for_bringup(void *root);
+int xroot_add_vsec_node(void *root, char *dtb);
+int xroot_create_group(void *xr, char *dtb);
+int xroot_add_simple_node(void *root, char *dtb, const char *endpoint);
+void xroot_broadcast(void *root, enum xrt_events evt);
+
+#endif /* _XRT_ROOT_H_ */
diff --git a/drivers/fpga/xrt/mgmt/root.c b/drivers/fpga/xrt/mgmt/root.c
new file mode 100644
index ..583a37c9d30c
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/root.c
@@ -0,0 +1,342 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo Management Function Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "xroot.h"
+#include "main-impl.h"
+#include "metadata.h"
+
+#define XMGMT_MODULE_NAME  "xmgmt"
+#define XMGMT_DRIVER_VERSION   "4.0.0"
+
+#define XMGMT_PDEV(xm) ((xm)->pdev)
+#define XMGMT_DEV(xm)  (&(XMGMT_PDEV(xm)->dev))
+#define xmgmt_err(xm, fmt, args...)\
+   dev_err(XMGMT_DEV(xm), "%s: " fmt, __func__, ##args)
+#define xmgmt_warn(xm, fmt, args...)   \
+   dev_warn(XMGMT_DEV(xm), "%s: " fmt, __func__, ##args)
+#define xmgmt_info(xm, fmt, args...)   \
+   dev_info(XMGMT_DEV(xm), 

[PATCH V3 XRT Alveo 06/18] fpga: xrt: platform driver infrastructure

2021-02-17 Thread Lizhi Hou
infrastructure code providing APIs for managing leaf driver instance
groups, facilitating inter-leaf driver calls and root calls, managing leaf
driver device nodes.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/events.h|  48 ++
 drivers/fpga/xrt/include/subdev_id.h |  43 ++
 drivers/fpga/xrt/include/xleaf.h | 276 +
 drivers/fpga/xrt/lib/cdev.c  | 231 +++
 drivers/fpga/xrt/lib/subdev.c| 871 +++
 drivers/fpga/xrt/lib/subdev_pool.h   |  53 ++
 drivers/fpga/xrt/lib/xroot.c | 598 ++
 7 files changed, 2120 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/events.h
 create mode 100644 drivers/fpga/xrt/include/subdev_id.h
 create mode 100644 drivers/fpga/xrt/include/xleaf.h
 create mode 100644 drivers/fpga/xrt/lib/cdev.c
 create mode 100644 drivers/fpga/xrt/lib/subdev.c
 create mode 100644 drivers/fpga/xrt/lib/subdev_pool.h
 create mode 100644 drivers/fpga/xrt/lib/xroot.c

diff --git a/drivers/fpga/xrt/include/events.h 
b/drivers/fpga/xrt/include/events.h
new file mode 100644
index ..2a9aae8bceb4
--- /dev/null
+++ b/drivers/fpga/xrt/include/events.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Runtime (XRT) driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_EVENTS_H_
+#define _XRT_EVENTS_H_
+
+#include 
+#include "subdev_id.h"
+
+/*
+ * Event notification.
+ */
+enum xrt_events {
+   XRT_EVENT_TEST = 0, /* for testing */
+   /*
+* Events related to specific subdev
+* Callback arg: struct xrt_event_arg_subdev
+*/
+   XRT_EVENT_POST_CREATION,
+   XRT_EVENT_PRE_REMOVAL,
+   /*
+* Events related to change of the whole board
+* Callback arg: 
+*/
+   XRT_EVENT_PRE_HOT_RESET,
+   XRT_EVENT_POST_HOT_RESET,
+   XRT_EVENT_PRE_GATE_CLOSE,
+   XRT_EVENT_POST_GATE_OPEN,
+};
+
+struct xrt_event_arg_subdev {
+   enum xrt_subdev_id xevt_subdev_id;
+   int xevt_subdev_instance;
+};
+
+struct xrt_event {
+   enum xrt_events xe_evt;
+   struct xrt_event_arg_subdev xe_subdev;
+};
+
+#endif /* _XRT_EVENTS_H_ */
diff --git a/drivers/fpga/xrt/include/subdev_id.h 
b/drivers/fpga/xrt/include/subdev_id.h
new file mode 100644
index ..6205a9f26196
--- /dev/null
+++ b/drivers/fpga/xrt/include/subdev_id.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Runtime (XRT) driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_SUBDEV_ID_H_
+#define _XRT_SUBDEV_ID_H_
+
+/*
+ * Every subdev driver should have an ID for others to refer to it.
+ * There can be unlimited number of instances of a subdev driver. A
+ *  tuple should be a unique identification of
+ * a specific instance of a subdev driver.
+ * NOTE: PLEASE do not change the order of IDs. Sub devices in the same
+ * group are initialized by this order.
+ */
+enum xrt_subdev_id {
+   XRT_SUBDEV_GRP = 0,
+   XRT_SUBDEV_VSEC = 1,
+   XRT_SUBDEV_VSEC_GOLDEN = 2,
+   XRT_SUBDEV_DEVCTL = 3,
+   XRT_SUBDEV_AXIGATE = 4,
+   XRT_SUBDEV_ICAP = 5,
+   XRT_SUBDEV_TEST = 6,
+   XRT_SUBDEV_MGMT_MAIN = 7,
+   XRT_SUBDEV_QSPI = 8,
+   XRT_SUBDEV_MAILBOX = 9,
+   XRT_SUBDEV_CMC = 10,
+   XRT_SUBDEV_CALIB = 11,
+   XRT_SUBDEV_CLKFREQ = 12,
+   XRT_SUBDEV_CLOCK = 13,
+   XRT_SUBDEV_SRSR = 14,
+   XRT_SUBDEV_UCS = 15,
+   XRT_SUBDEV_NUM = 16, /* Total number of subdevs. */
+   XRT_ROOT = -1, /* Special ID for root driver. */
+};
+
+#endif /* _XRT_SUBDEV_ID_H_ */
diff --git a/drivers/fpga/xrt/include/xleaf.h b/drivers/fpga/xrt/include/xleaf.h
new file mode 100644
index ..10215a75d474
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf.h
@@ -0,0 +1,276 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Runtime (XRT) driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *Cheng Zhen 
+ *Sonal Santan 
+ */
+
+#ifndef _XRT_XLEAF_H_
+#define _XRT_XLEAF_H_
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "libfdt.h"
+#include "subdev_id.h"
+#include "xroot.h"
+#include "events.h"
+
+/* All subdev drivers should use below common routines to print out msg. */
+#define DEV(pdev)  (&(pdev)->dev)
+#define DEV_PDATA(pdev)\
+   ((struct xrt_subdev_platdata *)dev_get_platdata(DEV(pdev)))
+#define DEV_DRVDATA(pdev)  \
+   ((struct xrt_subdev_drvdata *)  \
+   platform_get_device_id(pdev)->driver_data)
+#define FMT_PRT(prt_fn, pdev, fmt, args...)\
+   ({typeof(pdev) (_pdev) = (pdev);\
+   prt_fn(DEV(_p

[PATCH V3 XRT Alveo 08/18] fpga: xrt: main platform driver for management function device

2021-02-17 Thread Lizhi Hou
platform driver that handles IOCTLs, such as hot reset and xclbin download.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xmgmt-main.h |  37 ++
 drivers/fpga/xrt/mgmt/main-impl.h |  37 ++
 drivers/fpga/xrt/mgmt/main.c  | 693 ++
 include/uapi/linux/xrt/xmgmt-ioctl.h  |  46 ++
 4 files changed, 813 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xmgmt-main.h
 create mode 100644 drivers/fpga/xrt/mgmt/main-impl.h
 create mode 100644 drivers/fpga/xrt/mgmt/main.c
 create mode 100644 include/uapi/linux/xrt/xmgmt-ioctl.h

diff --git a/drivers/fpga/xrt/include/xmgmt-main.h 
b/drivers/fpga/xrt/include/xmgmt-main.h
new file mode 100644
index ..1216d1881f8e
--- /dev/null
+++ b/drivers/fpga/xrt/include/xmgmt-main.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Runtime (XRT) driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XMGMT_MAIN_H_
+#define _XMGMT_MAIN_H_
+
+#include 
+#include "xleaf.h"
+
+enum xrt_mgmt_main_ioctl_cmd {
+   /* section needs to be vfree'd by caller */
+   XRT_MGMT_MAIN_GET_AXLF_SECTION = XRT_XLEAF_CUSTOM_BASE, /* See comments 
in xleaf.h */
+   /* vbnv needs to be kfree'd by caller */
+   XRT_MGMT_MAIN_GET_VBNV,
+};
+
+enum provider_kind {
+   XMGMT_BLP,
+   XMGMT_PLP,
+   XMGMT_ULP,
+};
+
+struct xrt_mgmt_main_ioctl_get_axlf_section {
+   enum provider_kind xmmigas_axlf_kind;
+   enum axlf_section_kind xmmigas_section_kind;
+   void *xmmigas_section;
+   u64 xmmigas_section_size;
+};
+
+#endif /* _XMGMT_MAIN_H_ */
diff --git a/drivers/fpga/xrt/mgmt/main-impl.h 
b/drivers/fpga/xrt/mgmt/main-impl.h
new file mode 100644
index ..dd1b3e3773cc
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/main-impl.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Alveo Management Function Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *     Lizhi Hou 
+ * Cheng Zhen 
+ */
+
+#ifndef _XMGMT_MAIN_IMPL_H_
+#define _XMGMT_MAIN_IMPL_H_
+
+#include 
+#include "xmgmt-main.h"
+
+struct fpga_manager;
+int xmgmt_process_xclbin(struct platform_device *pdev,
+struct fpga_manager *fmgr,
+const struct axlf *xclbin,
+enum provider_kind kind);
+void xmgmt_region_cleanup_all(struct platform_device *pdev);
+
+int bitstream_axlf_mailbox(struct platform_device *pdev, const void *xclbin);
+int xmgmt_hot_reset(struct platform_device *pdev);
+
+/* Getting dtb for specified group. Caller should vfree returned dtb .*/
+char *xmgmt_get_dtb(struct platform_device *pdev, enum provider_kind kind);
+char *xmgmt_get_vbnv(struct platform_device *pdev);
+int xmgmt_get_provider_uuid(struct platform_device *pdev,
+   enum provider_kind kind, uuid_t *uuid);
+
+int xmgmt_main_register_leaf(void);
+void xmgmt_main_unregister_leaf(void);
+
+#endif /* _XMGMT_MAIN_IMPL_H_ */
diff --git a/drivers/fpga/xrt/mgmt/main.c b/drivers/fpga/xrt/mgmt/main.c
new file mode 100644
index ..66ffb4e7029d
--- /dev/null
+++ b/drivers/fpga/xrt/mgmt/main.c
@@ -0,0 +1,693 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA MGMT PF entry point driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Sonal Santan 
+ */
+
+#include 
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+#include "xleaf.h"
+#include 
+#include "xleaf/devctl.h"
+#include "xmgmt-main.h"
+#include "fmgr.h"
+#include "xleaf/icap.h"
+#include "xleaf/axigate.h"
+#include "main-impl.h"
+
+#define XMGMT_MAIN "xmgmt_main"
+
+struct xmgmt_main {
+   struct platform_device *pdev;
+   struct axlf *firmware_blp;
+   struct axlf *firmware_plp;
+   struct axlf *firmware_ulp;
+   bool flash_ready;
+   bool devctl_ready;
+   struct fpga_manager *fmgr;
+   struct mutex busy_mutex; /* busy lock */
+
+   uuid_t *blp_intf_uuids;
+   u32 blp_intf_uuid_num;
+};
+
+/* Caller should be responsible for freeing the returned string. */
+char *xmgmt_get_vbnv(struct platform_device *pdev)
+{
+   struct xmgmt_main *xmm = platform_get_drvdata(pdev);
+   const char *vbnv;
+   char *ret;
+   int i;
+
+   if (xmm->firmware_plp)
+   vbnv = xmm->firmware_plp->m_header.m_platformVBNV;
+   else if (xmm->firmware_blp)
+   vbnv = xmm->firmware_blp->m_header.m_platformVBNV;
+   else
+   return NULL;
+
+   ret = kstrdup(vbnv, GFP_KERNEL);
+   if (!ret)
+   return NULL;
+
+   for (i = 0; i < strlen(ret); i++) {
+   if (ret[i] == ':' || ret[i] == '.')
+   ret[i]

[PATCH V3 XRT Alveo 05/18] fpga: xrt: group platform driver

2021-02-17 Thread Lizhi Hou
group driver that manages life cycle of a bunch of leaf driver instances
and bridges them with root.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/group.h |  27 
 drivers/fpga/xrt/lib/group.c | 265 +++
 2 files changed, 292 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/group.h
 create mode 100644 drivers/fpga/xrt/lib/group.c

diff --git a/drivers/fpga/xrt/include/group.h b/drivers/fpga/xrt/include/group.h
new file mode 100644
index ..1874cdd5120d
--- /dev/null
+++ b/drivers/fpga/xrt/include/group.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Runtime (XRT) driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#ifndef _XRT_GROUP_H_
+#define _XRT_GROUP_H_
+
+#include "xleaf.h"
+
+/*
+ * Group driver IOCTL calls.
+ */
+enum xrt_group_ioctl_cmd {
+   XRT_GROUP_GET_LEAF = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h 
*/
+   XRT_GROUP_PUT_LEAF,
+   XRT_GROUP_INIT_CHILDREN,
+   XRT_GROUP_FINI_CHILDREN,
+   XRT_GROUP_TRIGGER_EVENT,
+};
+
+#endif /* _XRT_GROUP_H_ */
diff --git a/drivers/fpga/xrt/lib/group.c b/drivers/fpga/xrt/lib/group.c
new file mode 100644
index ..6ba56eea479b
--- /dev/null
+++ b/drivers/fpga/xrt/lib/group.c
@@ -0,0 +1,265 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Group Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#include 
+#include 
+#include "xleaf.h"
+#include "subdev_pool.h"
+#include "group.h"
+#include "metadata.h"
+#include "main.h"
+
+#define XRT_GRP "xrt_group"
+
+struct xrt_group {
+   struct platform_device *pdev;
+   struct xrt_subdev_pool leaves;
+   bool leaves_created;
+   struct mutex lock; /* lock for group */
+};
+
+static int xrt_grp_root_cb(struct device *dev, void *parg,
+  u32 cmd, void *arg)
+{
+   int rc;
+   struct platform_device *pdev =
+   container_of(dev, struct platform_device, dev);
+   struct xrt_group *xg = (struct xrt_group *)parg;
+
+   switch (cmd) {
+   case XRT_ROOT_GET_LEAF_HOLDERS: {
+   struct xrt_root_ioctl_get_holders *holders =
+   (struct xrt_root_ioctl_get_holders *)arg;
+   rc = xrt_subdev_pool_get_holders(>leaves,
+holders->xpigh_pdev,
+holders->xpigh_holder_buf,
+holders->xpigh_holder_buf_len);
+   break;
+   }
+   default:
+   /* Forward parent call to root. */
+   rc = xrt_subdev_root_request(pdev, cmd, arg);
+   break;
+   }
+
+   return rc;
+}
+
+static int xrt_grp_create_leaves(struct xrt_group *xg)
+{
+   struct xrt_subdev_platdata *pdata = DEV_PDATA(xg->pdev);
+   enum xrt_subdev_id did;
+   struct xrt_subdev_endpoints *eps = NULL;
+   int ep_count = 0, i, ret = 0, failed = 0;
+   unsigned long mlen;
+   char *dtb, *grp_dtb = NULL;
+   const char *ep_name;
+
+   mutex_lock(>lock);
+
+   if (xg->leaves_created) {
+   mutex_unlock(>lock);
+   return -EEXIST;
+   }
+
+   xrt_info(xg->pdev, "bringing up leaves...");
+
+   /* Create all leaves based on dtb. */
+   if (!pdata)
+   goto bail;
+
+   mlen = xrt_md_size(DEV(xg->pdev), pdata->xsp_dtb);
+   if (mlen == XRT_MD_INVALID_LENGTH) {
+   xrt_err(xg->pdev, "invalid dtb, len %ld", mlen);
+   goto bail;
+   }
+
+   grp_dtb = vmalloc(mlen);
+   if (!grp_dtb)
+   goto bail;
+
+   memcpy(grp_dtb, pdata->xsp_dtb, mlen);
+   for (did = 0; did < XRT_SUBDEV_NUM;) {
+   eps = eps ? eps + 1 : xrt_drv_get_endpoints(did);
+   if (!eps || !eps->xse_names) {
+   did++;
+   eps = NULL;
+   continue;
+   }
+   ret = xrt_md_create(DEV(xg->pdev), );
+   if (ret) {
+   xrt_err(xg->pdev, "create md failed, drv %s",
+   xrt_drv_name(did));
+   failed++;
+   continue;
+   }
+   for (i = 0; eps->xse_names[i].ep_name ||
+eps->xse_names[i].regmap_name; i++) {
+   ep_name = (char *)eps->xse_names[i].ep_name;
+   if (!ep_name) {
+   xrt_md_get_compatible_endpoint(DEV(xg->pdev),
+  grp_dtb,

[PATCH V3 XRT Alveo 04/18] fpga: xrt: xrt-lib platform driver manager

2021-02-17 Thread Lizhi Hou
xrt-lib kernel module infrastructure code to register and manage all
leaf driver modules.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/lib/main.c | 274 
 drivers/fpga/xrt/lib/main.h |  17 +++
 2 files changed, 291 insertions(+)
 create mode 100644 drivers/fpga/xrt/lib/main.c
 create mode 100644 drivers/fpga/xrt/lib/main.h

diff --git a/drivers/fpga/xrt/lib/main.c b/drivers/fpga/xrt/lib/main.c
new file mode 100644
index ..36fb62710843
--- /dev/null
+++ b/drivers/fpga/xrt/lib/main.c
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Xilinx Alveo FPGA Support
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ * Cheng Zhen 
+ */
+
+#include 
+#include "xleaf.h"
+#include "xroot.h"
+#include "main.h"
+
+#define XRT_IPLIB_MODULE_NAME  "xrt-lib"
+#define XRT_IPLIB_MODULE_VERSION   "4.0.0"
+#define XRT_MAX_DEVICE_NODES   128
+#define XRT_DRVNAME(drv)   ((drv)->driver.name)
+
+/*
+ * Subdev driver is known by ID to others. We map the ID to it's
+ * struct platform_driver, which contains it's binding name and driver/file 
ops.
+ * We also map it to the endpoint name in DTB as well, if it's different
+ * than the driver's binding name.
+ */
+struct xrt_drv_map {
+   struct list_head list;
+   enum xrt_subdev_id id;
+   struct platform_driver *drv;
+   struct xrt_subdev_endpoints *eps;
+   struct ida ida; /* manage driver instance and char dev minor */
+};
+
+static DEFINE_MUTEX(xrt_lib_lock); /* global lock protecting xrt_drv_maps list 
*/
+static LIST_HEAD(xrt_drv_maps);
+struct class *xrt_class;
+
+static inline struct xrt_subdev_drvdata *
+xrt_drv_map2drvdata(struct xrt_drv_map *map)
+{
+   return (struct xrt_subdev_drvdata *)map->drv->id_table[0].driver_data;
+}
+
+static struct xrt_drv_map *
+xrt_drv_find_map_by_id_nolock(enum xrt_subdev_id id)
+{
+   const struct list_head *ptr;
+
+   list_for_each(ptr, _drv_maps) {
+   struct xrt_drv_map *tmap = list_entry(ptr, struct xrt_drv_map, 
list);
+
+   if (tmap->id == id)
+   return tmap;
+   }
+   return NULL;
+}
+
+static struct xrt_drv_map *
+xrt_drv_find_map_by_id(enum xrt_subdev_id id)
+{
+   struct xrt_drv_map *map;
+
+   mutex_lock(_lib_lock);
+   map = xrt_drv_find_map_by_id_nolock(id);
+   mutex_unlock(_lib_lock);
+   /*
+* map should remain valid even after lock is dropped since a registered
+* driver should only be unregistered when driver module is being 
unloaded,
+* which means that the driver should not be used by then.
+*/
+   return map;
+}
+
+static int xrt_drv_register_driver(struct xrt_drv_map *map)
+{
+   struct xrt_subdev_drvdata *drvdata;
+   int rc = 0;
+   const char *drvname = XRT_DRVNAME(map->drv);
+
+   rc = platform_driver_register(map->drv);
+   if (rc) {
+   pr_err("register %s platform driver failed\n", drvname);
+   return rc;
+   }
+
+   drvdata = xrt_drv_map2drvdata(map);
+   if (drvdata) {
+   /* Initialize dev_t for char dev node. */
+   if (xleaf_devnode_enabled(drvdata)) {
+   rc = 
alloc_chrdev_region(>xsd_file_ops.xsf_dev_t, 0,
+XRT_MAX_DEVICE_NODES, drvname);
+   if (rc) {
+   platform_driver_unregister(map->drv);
+   pr_err("failed to alloc dev minor for %s: 
%d\n", drvname, rc);
+   return rc;
+   }
+   } else {
+   drvdata->xsd_file_ops.xsf_dev_t = (dev_t)-1;
+   }
+   }
+
+   ida_init(>ida);
+
+   pr_info("%s registered successfully\n", drvname);
+
+   return 0;
+}
+
+static void xrt_drv_unregister_driver(struct xrt_drv_map *map)
+{
+   const char *drvname = XRT_DRVNAME(map->drv);
+   struct xrt_subdev_drvdata *drvdata;
+
+   ida_destroy(>ida);
+
+   drvdata = xrt_drv_map2drvdata(map);
+   if (drvdata && drvdata->xsd_file_ops.xsf_dev_t != (dev_t)-1) {
+   unregister_chrdev_region(drvdata->xsd_file_ops.xsf_dev_t,
+XRT_MAX_DEVICE_NODES);
+   }
+
+   platform_driver_unregister(map->drv);
+
+   pr_info("%s unregistered successfully\n", drvname);
+}
+
+int xleaf_register_driver(enum xrt_subdev_id id,
+ struct platform_driver *drv,
+ struct xrt_subdev_endpoints *eps)
+{
+   struct xrt_drv_map *map;
+
+   mutex_lock(_lib_lock);
+
+   map = xrt_drv_find_map_by_id_nolock(id);
+   if (map) {
+

[PATCH V3 XRT Alveo 03/18] fpga: xrt: xclbin file helper functions

2021-02-17 Thread Lizhi Hou
Alveo FPGA firmware and partial reconfigure file are in xclbin format. Add
code to enumerate and extract sections from xclbin files. xclbin.h is cross
platform and used across all platforms and OS

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/xclbin-helper.h |  52 +++
 drivers/fpga/xrt/lib/xclbin.c| 394 ++
 include/uapi/linux/xrt/xclbin.h  | 408 +++
 3 files changed, 854 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xclbin-helper.h
 create mode 100644 drivers/fpga/xrt/lib/xclbin.c
 create mode 100644 include/uapi/linux/xrt/xclbin.h

diff --git a/drivers/fpga/xrt/include/xclbin-helper.h 
b/drivers/fpga/xrt/include/xclbin-helper.h
new file mode 100644
index ..68218efc9d0b
--- /dev/null
+++ b/drivers/fpga/xrt/include/xclbin-helper.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Runtime (XRT) driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *David Zhang 
+ *Sonal Santan 
+ */
+
+#ifndef _XRT_XCLBIN_H
+#define _XRT_XCLBIN_H
+
+#include 
+#include 
+#include 
+
+#define ICAP_XCLBIN_V2 "xclbin2"
+#define DMA_HWICAP_BITFILE_BUFFER_SIZE 1024
+#define MAX_XCLBIN_SIZE (1024 * 1024 * 1024) /* Assuming xclbin <= 1G, always 
*/
+
+enum axlf_section_kind;
+struct axlf;
+
+/**
+ * Bitstream header information as defined by Xilinx tools.
+ * Please note that this struct definition is not owned by the driver.
+ */
+struct hw_icap_bit_header {
+   unsigned int header_length; /* Length of header in 32 bit words */
+   unsigned int bitstream_length;  /* Length of bitstream to read in 
bytes*/
+   unsigned char *design_name; /* Design name get from bitstream */
+   unsigned char *part_name;   /* Part name read from bitstream */
+   unsigned char *date;   /* Date read from bitstream header */
+   unsigned char *time;   /* Bitstream creation time */
+   unsigned int magic_length;  /* Length of the magic numbers */
+   unsigned char *version; /* Version string */
+};
+
+const char *xrt_xclbin_kind_to_string(enum axlf_section_kind kind);
+int xrt_xclbin_get_section(const struct axlf *xclbin,
+  enum axlf_section_kind kind, void **data,
+  uint64_t *len);
+int xrt_xclbin_get_metadata(struct device *dev, const struct axlf *xclbin, 
char **dtb);
+int xrt_xclbin_parse_bitstream_header(const unsigned char *data,
+ unsigned int size,
+ struct hw_icap_bit_header *header);
+void xrt_xclbin_free_header(struct hw_icap_bit_header *header);
+const char *xrt_clock_type2epname(enum CLOCK_TYPE type);
+
+#endif /* _XRT_XCLBIN_H */
diff --git a/drivers/fpga/xrt/lib/xclbin.c b/drivers/fpga/xrt/lib/xclbin.c
new file mode 100644
index ..47dc6ca25c1b
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xclbin.c
@@ -0,0 +1,394 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Driver XCLBIN parser
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors: David Zhang 
+ */
+
+#include 
+#include 
+#include 
+#include "xclbin-helper.h"
+#include "metadata.h"
+
+/* Used for parsing bitstream header */
+#define XHI_EVEN_MAGIC_BYTE 0x0f
+#define XHI_ODD_MAGIC_BYTE  0xf0
+
+/* Extra mode for IDLE */
+#define XHI_OP_IDLE  -1
+#define XHI_BIT_HEADER_FAILURE -1
+
+/* The imaginary module length register */
+#define XHI_MLR  15
+
+static inline unsigned char xhi_data_and_inc(const unsigned char *d, int *i, 
int sz)
+{
+   unsigned char data;
+
+   if (*i >= sz)
+   return -1;
+
+   data = d[*i];
+   (*i)++;
+
+   return data;
+}
+
+static const struct axlf_section_header *
+xrt_xclbin_get_section_hdr(const struct axlf *xclbin,
+  enum axlf_section_kind kind)
+{
+   int i = 0;
+
+   for (i = 0; i < xclbin->m_header.m_numSections; i++) {
+   if (xclbin->m_sections[i].m_sectionKind == kind)
+   return >m_sections[i];
+   }
+
+   return NULL;
+}
+
+static int
+xrt_xclbin_check_section_hdr(const struct axlf_section_header *header,
+u64 xclbin_len)
+{
+   int ret;
+
+   ret = (header->m_sectionOffset + header->m_sectionSize) > xclbin_len ? 
-EINVAL : 0;
+
+   return ret;
+}
+
+static int xrt_xclbin_section_info(const struct axlf *xclbin,
+  enum axlf_section_kind kind,
+  u64 *offset, u64 *size)
+{
+   const struct axlf_section_header *mem_header = NULL;
+   u64 xclbin_len;
+   int err = 0;
+
+   mem_header = xrt_xclbin_get_section_hdr(xclbin, kind);
+   if (!mem_header)
+   return -EINVAL;
+
+   xclbin_len = xclbin->

[PATCH V3 XRT Alveo 02/18] fpga: xrt: driver metadata helper functions

2021-02-17 Thread Lizhi Hou
XRT drivers use device tree as metadata format to discover HW subsystems
behind PCIe BAR. Thus libfdt functions are called for driver to parse
device tree blob.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 drivers/fpga/xrt/include/metadata.h  | 229 
 drivers/fpga/xrt/metadata/metadata.c | 524 +++
 2 files changed, 753 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/metadata.h
 create mode 100644 drivers/fpga/xrt/metadata/metadata.c

diff --git a/drivers/fpga/xrt/include/metadata.h 
b/drivers/fpga/xrt/include/metadata.h
new file mode 100644
index ..b929bc469b73
--- /dev/null
+++ b/drivers/fpga/xrt/include/metadata.h
@@ -0,0 +1,229 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Header file for Xilinx Runtime (XRT) driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *  Lizhi Hou 
+ */
+
+#ifndef _XRT_METADATA_H
+#define _XRT_METADATA_H
+
+#include 
+#include 
+#include 
+
+#define XRT_MD_INVALID_LENGTH (~0UL)
+
+#define XRT_MD_PROP_COMPATIBLE "compatible"
+#define XRT_MD_PROP_PF_NUM "pcie_physical_function"
+#define XRT_MD_PROP_BAR_IDX "pcie_bar_mapping"
+#define XRT_MD_PROP_IO_OFFSET "reg"
+#define XRT_MD_PROP_INTERRUPTS "interrupts"
+#define XRT_MD_PROP_INTERFACE_UUID "interface_uuid"
+#define XRT_MD_PROP_LOGIC_UUID "logic_uuid"
+#define XRT_MD_PROP_VERSION_MAJOR "firmware_version_major"
+
+#define XRT_MD_PROP_HWICAP "axi_hwicap"
+#define XRT_MD_PROP_PDI_CONFIG "pdi_config_mem"
+
+#define XRT_MD_NODE_ENDPOINTS "addressable_endpoints"
+#define XRT_MD_INTERFACES_PATH "/interfaces"
+
+#define XRT_MD_NODE_FIRMWARE "firmware"
+#define XRT_MD_NODE_INTERFACES "interfaces"
+#define XRT_MD_NODE_PARTITION_INFO "partition_info"
+
+#define XRT_MD_NODE_FLASH "ep_card_flash_program_00"
+#define XRT_MD_NODE_XVC_PUB "ep_debug_bscan_user_00"
+#define XRT_MD_NODE_XVC_PRI "ep_debug_bscan_mgmt_00"
+#define XRT_MD_NODE_SYSMON "ep_cmp_sysmon_00"
+#define XRT_MD_NODE_AF_BLP_CTRL_MGMT "ep_firewall_blp_ctrl_mgmt_00"
+#define XRT_MD_NODE_AF_BLP_CTRL_USER "ep_firewall_blp_ctrl_user_00"
+#define XRT_MD_NODE_AF_CTRL_MGMT "ep_firewall_ctrl_mgmt_00"
+#define XRT_MD_NODE_AF_CTRL_USER "ep_firewall_ctrl_user_00"
+#define XRT_MD_NODE_AF_CTRL_DEBUG "ep_firewall_ctrl_debug_00"
+#define XRT_MD_NODE_AF_DATA_H2C "ep_firewall_data_h2c_00"
+#define XRT_MD_NODE_AF_DATA_C2H "ep_firewall_data_c2h_00"
+#define XRT_MD_NODE_AF_DATA_P2P "ep_firewall_data_p2p_00"
+#define XRT_MD_NODE_AF_DATA_M2M "ep_firewall_data_m2m_00"
+#define XRT_MD_NODE_CMC_REG "ep_cmc_regmap_00"
+#define XRT_MD_NODE_CMC_RESET "ep_cmc_reset_00"
+#define XRT_MD_NODE_CMC_MUTEX "ep_cmc_mutex_00"
+#define XRT_MD_NODE_CMC_FW_MEM "ep_cmc_firmware_mem_00"
+#define XRT_MD_NODE_ERT_FW_MEM "ep_ert_firmware_mem_00"
+#define XRT_MD_NODE_ERT_CQ_MGMT "ep_ert_command_queue_mgmt_00"
+#define XRT_MD_NODE_ERT_CQ_USER "ep_ert_command_queue_user_00"
+#define XRT_MD_NODE_MAILBOX_MGMT "ep_mailbox_mgmt_00"
+#define XRT_MD_NODE_MAILBOX_USER "ep_mailbox_user_00"
+#define XRT_MD_NODE_GATE_PLP "ep_pr_isolate_plp_00"
+#define XRT_MD_NODE_GATE_ULP "ep_pr_isolate_ulp_00"
+#define XRT_MD_NODE_PCIE_MON "ep_pcie_link_mon_00"
+#define XRT_MD_NODE_DDR_CALIB "ep_ddr_mem_calib_00"
+#define XRT_MD_NODE_CLK_KERNEL1 "ep_aclk_kernel_00"
+#define XRT_MD_NODE_CLK_KERNEL2 "ep_aclk_kernel_01"
+#define XRT_MD_NODE_CLK_KERNEL3 "ep_aclk_hbm_00"
+#define XRT_MD_NODE_KDMA_CTRL "ep_kdma_ctrl_00"
+#define XRT_MD_NODE_FPGA_CONFIG "ep_fpga_configuration_00"
+#define XRT_MD_NODE_ERT_SCHED "ep_ert_sched_00"
+#define XRT_MD_NODE_XDMA "ep_xdma_00"
+#define XRT_MD_NODE_MSIX "ep_msix_00"
+#define XRT_MD_NODE_QDMA "ep_qdma_00"
+#define XRT_MD_XRT_MD_NODE_QDMA4 "ep_qdma4_00"
+#define XRT_MD_NODE_STM "ep_stream_traffic_manager_00"
+#define XRT_MD_NODE_STM4 "ep_stream_traffic_manager4_00"
+#define XRT_MD_NODE_CLK_SHUTDOWN "ep_aclk_shutdown_00"
+#define XRT_MD_NODE_ERT_BASE "ep_ert_base_address_00"
+#define XRT_MD_NODE_ERT_RESET "ep_ert_reset_00"
+#define XRT_MD_NODE_CLKFREQ_K1 "ep_freq_cnt_aclk_kernel_00"
+#define XRT_MD_NODE_CLKFREQ_K2 "ep_freq_cnt_aclk_kernel_01"
+#define XRT_MD_NODE_CLKFREQ_HBM "ep_freq_cnt_aclk_hbm_00"
+#define XRT_MD_NODE_GAPPING "ep_gapping_demand_00"
+#define XRT_MD_NODE_UCS_CONTROL_STATUS "ep_ucs_control_status_00"
+#define XRT_MD_NODE_P2P "ep_p2p_00"
+#define XRT_MD_NODE_REMAP_P2P &quo

[PATCH V3 XRT Alveo 01/18] Documentation: fpga: Add a document describing XRT Alveo drivers

2021-02-17 Thread Lizhi Hou
Describe XRT driver architecture and provide basic overview of
Xilinx Alveo platform.

Signed-off-by: Sonal Santan 
Signed-off-by: Max Zhen 
Signed-off-by: Lizhi Hou 
---
 Documentation/fpga/index.rst |   1 +
 Documentation/fpga/xrt.rst   | 842 +++
 2 files changed, 843 insertions(+)
 create mode 100644 Documentation/fpga/xrt.rst

diff --git a/Documentation/fpga/index.rst b/Documentation/fpga/index.rst
index f80f95667ca2..30134357b70d 100644
--- a/Documentation/fpga/index.rst
+++ b/Documentation/fpga/index.rst
@@ -8,6 +8,7 @@ fpga
 :maxdepth: 1
 
 dfl
+xrt
 
 .. only::  subproject and html
 
diff --git a/Documentation/fpga/xrt.rst b/Documentation/fpga/xrt.rst
new file mode 100644
index ..9bc2d2785cb9
--- /dev/null
+++ b/Documentation/fpga/xrt.rst
@@ -0,0 +1,842 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==
+XRTV2 Linux Kernel Driver Overview
+==
+
+Authors:
+
+* Sonal Santan 
+* Max Zhen 
+* Lizhi Hou 
+
+XRTV2 drivers are second generation `XRT <https://github.com/Xilinx/XRT>`_
+drivers which support `Alveo 
<https://www.xilinx.com/products/boards-and-kits/alveo.html>`_
+PCIe platforms from Xilinx.
+
+XRTV2 drivers support *subsystem* style data driven platforms where driver's
+configuration and behavior is determined by meta data provided by the platform
+(in *device tree* format). Primary management physical function (MPF) driver
+is called **xmgmt**. Primary user physical function (UPF) driver is called
+**xuser** and is under development. xrt driver framework and HW subsystem
+drivers are packaged into a library module called **xrt-lib**, which is
+shared by **xmgmt** and **xuser** (under development). The xrt driver framework
+implements a pseudo-bus which is used to discover HW subsystems and facilitate
+inter HW subsystem interaction.
+
+Driver Modules
+==
+
+xrt-lib.ko
+--
+
+Repository of all subsystem drivers and pure software modules that can 
potentially
+be shared between xmgmt and xuser. All these drivers are structured as Linux
+*platform driver* and are instantiated by xmgmt (or xuser under development) 
based
+on meta data associated with hardware. The metadata is in the form of device 
tree
+as mentioned before. Each platform driver statically defines a subsystem node
+array by using node name or a string in its ``compatible`` property. And this
+array is eventually translated to IOMEM resources of the platform device.
+
+The xrt-lib core infrastructure provides hooks to platform drivers for device 
node
+management, user file operations and ioctl callbacks. The core also provides 
pseudo-bus
+functionality for platform driver registration, discovery and inter platform 
driver
+ioctl calls.
+
+.. note::
+   See code in ``include/xleaf.h``
+
+
+xmgmt.ko
+
+
+The xmgmt driver is a PCIe device driver driving MPF found on Xilinx's Alveo
+PCIE device. It consists of one *root* driver, one or more *group* drivers
+and one or more *xleaf* drivers. The root and MPF specific xleaf drivers are
+in xmgmt.ko. The group driver and other xleaf drivers are in xrt-lib.ko.
+
+The instantiation of specific group driver or xleaf driver is completely data
+driven based on meta data (mostly in device tree format) found through VSEC
+capability and inside firmware files, such as platform xsabin or user xclbin 
file.
+The root driver manages life cycle of multiple group drivers, which, in turn,
+manages multiple xleaf drivers. This allows a single set of driver code to 
support
+all kinds of subsystems exposed by different shells. The difference among all
+these subsystems will be handled in xleaf drivers with root and group drivers
+being part of the infrastructure and provide common services for all leaves
+found on all platforms.
+
+The driver object model looks like the following::
+
++---+
+|   xroot   |
++-+-+
+  |
+  +---+---+
+  |   |
+  v   v
++---+  +---+
+|   group   |...   |   group   |
++-+-+  +--++
+  |   |
+  |   |
++-+++-++
+|  ||  |
+v  vv  v
++---+  +---++---+  +---+
+| xleaf |..| xleaf || xleaf |..| xleaf |
++---+  +---++---+  +---+
+
+As an example for Xilinx Alveo U50 before user xclbin download, the tree
+looks like the following::
+
++---+
+ 

[PATCH V3 XRT Alveo 00/18] XRT Alveo driver overview

2021-02-17 Thread Lizhi Hou
Hello,

This is V3 of patch series which adds management physical function driver for 
Xilinx
Alveo PCIe accelerator cards, 
https://www.xilinx.com/products/boards-and-kits/alveo.html
This driver is part of Xilinx Runtime (XRT) open source stack.

XILINX ALVEO PLATFORM ARCHITECTURE

Alveo PCIe FPGA based platforms have a static *shell* partition and a partial
re-configurable *user* partition. The shell partition is automatically loaded 
from
flash when host is booted and PCIe is enumerated by BIOS. Shell cannot be 
changed
till the next cold reboot. The shell exposes two PCIe physical functions:

1. management physical function
2. user physical function

The patch series includes Documentation/xrt.rst which describes Alveo platform,
XRT driver architecture and deployment model in more detail.

Users compile their high level design in C/C++/OpenCL or RTL into FPGA image 
using
Vitis https://www.xilinx.com/products/design-tools/vitis/vitis-platform.html
tools. The compiled image is packaged as xclbin which contains partial bitstream
for the user partition and necessary metadata. Users can dynamically swap the 
image
running on the user partition in order to switch between different workloads by
loading different xclbins.

XRT DRIVERS FOR XILINX ALVEO

XRT Linux kernel driver *xmgmt* binds to management physical function of Alveo
platform. The modular driver framework is organized into several platform 
drivers
which primarily handle the following functionality:

1.  Loading firmware container also called xsabin at driver attach time
2.  Loading of user compiled xclbin with FPGA Manager integration
3.  Clock scaling of image running on user partition
4.  In-band sensors: temp, voltage, power, etc.
5.  Device reset and rescan

The platform drivers are packaged into *xrt-lib* helper module with well
defined interfaces. The module provides a pseudo-bus implementation for the
platform drivers. More details on the driver model can be found in
Documentation/xrt.rst.

User physical function driver is not included in this patch series.

LIBFDT REQUIREMENT

XRT driver infrastructure uses Device Tree as a metadata format to discover
HW subsystems in the Alveo PCIe device. The Device Tree schema used by XRT
is documented in Documentation/xrt.rst. Unlike previous V1 and V2 version
of patch series, V3 version does not require export of libfdt symbols.

TESTING AND VALIDATION

xmgmt driver can be tested with full XRT open source stack which includes user
space libraries, board utilities and (out of tree) first generation user 
physical
function driver xocl. XRT open source runtime stack is available at
https://github.com/Xilinx/XRT

Complete documentation for XRT open source stack including sections on Alveo/XRT
security and platform architecture can be found here:

https://xilinx.github.io/XRT/master/html/index.html
https://xilinx.github.io/XRT/master/html/security.html
https://xilinx.github.io/XRT/master/html/platforms_partitions.html

Changes since v2:
- Streamlined the driver framework into *xleaf*, *group* and *xroot*
- Updated documentation to show the driver model with examples
- Addressed kernel test robot errors
- Added a selftest for basic driver framework
- Documented device tree schema
- Removed need to export libfdt symbols

Changes since v1:
- Updated the driver to use fpga_region and fpga_bridge for FPGA
  programming
- Dropped platform drivers not related to PR programming to focus on XRT
  core framework
- Updated Documentation/fpga/xrt.rst with information on XRT core framework
- Addressed checkpatch issues
- Dropped xrt- prefix from some header files

For reference V1 version of patch series can be found here:

https://lore.kernel.org/lkml/20201217075046.28553-1-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-2-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-3-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-4-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-5-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-6-son...@xilinx.com/
https://lore.kernel.org/lkml/20201217075046.28553-7-son...@xilinx.com/

Lizhi Hou (18):
  Documentation: fpga: Add a document describing XRT Alveo drivers
  fpga: xrt: driver metadata helper functions
  fpga: xrt: xclbin file helper functions
  fpga: xrt: xrt-lib platform driver manager
  fpga: xrt: group platform driver
  fpga: xrt: platform driver infrastructure
  fpga: xrt: management physical function driver (root)
  fpga: xrt: main platform driver for management function device
  fpga: xrt: fpga-mgr and region implementation for xclbin download
  fpga: xrt: VSEC platform driver
  fpga: xrt: UCS platform driver
  fpga: xrt: ICAP platform driver
  fpga: xrt: devctl platform driver
  fpga: xrt: clock platform driver
  fpga: xrt: clock frequence counter platform driver
  fpga: xrt: DDR calibration platform driver
  fpga: xrt: partition isolation platform driver
  fpga: xrt