Re: [PATCH V4 XRT Alveo 19/20] fpga: xrt: partition isolation platform driver
On 3/23/21 10:29 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 | 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, ok +}; + +#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; white space, extra nl's are not needed +}; + +static const struct regmap_config axigate_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 0x1000, ok +}; + +/* 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 */ ok +}; + +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); ok, regs defined + 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, &val); + 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, &val); + 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, &val); + if (ret) { + xrt_err(gate->pdev, "read 3 failed %d", ret); + return ret; + } + + return 0; +} + +static int xrt_axigate_epname_idx(struct platform_device *pdev) +{ + st
[PATCH V4 XRT Alveo 19/20] fpga: xrt: partition isolation platform driver
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, &val); + 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, &val); + 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, &val); + if (ret) { + xrt_err(gate->pdev, "read 3 failed %d", ret); + return ret; + } + + return 0; +} + +static int xrt_axigate_epname_idx(struct platform_device *pdev) +{ + struct resource *res; + int ret, i; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res)