Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fpga: Add support for Xilinx DFX AXI Shutdown manager

This patch adds support for Xilinx Dynamic Function eXchange(DFX) AXI
shutdown manager IP. It can be used to safely handling the AXI traffic
on a Reconfigurable Partition when it is undergoing dynamic reconfiguration
and there by preventing system deadlock that may occur if AXI transactions
are interrupted during reconfiguration.

PR-Decoupler and AXI shutdown manager are completely different IPs.
But both the IP registers are compatible and also both belong to the
same sub-system (fpga-bridge).So using same driver for both IP's.

Signed-off-by: Nava kishore Manne <nava.manne@xilinx.com>
Reviewed-by: Tom Rix <trix@redhat.com>
Signed-off-by: Moritz Fischer <mdf@kernel.org>

authored by

Nava kishore Manne and committed by
Moritz Fischer
6f1e376c 71c3980b

+40 -6
+8 -1
drivers/fpga/Kconfig
··· 118 118 depends on FPGA_BRIDGE 119 119 depends on HAS_IOMEM 120 120 help 121 - Say Y to enable drivers for Xilinx LogiCORE PR Decoupler. 121 + Say Y to enable drivers for Xilinx LogiCORE PR Decoupler 122 + or Xilinx Dynamic Function eXchnage AIX Shutdown Manager. 122 123 The PR Decoupler exists in the FPGA fabric to isolate one 123 124 region of the FPGA from the busses while that region is 124 125 being reprogrammed during partial reconfig. 126 + The Dynamic Function eXchange AXI shutdown manager prevents 127 + AXI traffic from passing through the bridge. The controller 128 + safely handles AXI4MM and AXI4-Lite interfaces on a 129 + Reconfigurable Partition when it is undergoing dynamic 130 + reconfiguration, preventing the system deadlock that can 131 + occur if AXI transactions are interrupted by DFX. 125 132 126 133 config FPGA_REGION 127 134 tristate "FPGA Region"
+32 -5
drivers/fpga/xilinx-pr-decoupler.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (c) 2017, National Instruments Corp. 4 - * Copyright (c) 2017, Xilix Inc 4 + * Copyright (c) 2017, Xilinx Inc 5 5 * 6 6 * FPGA Bridge Driver for the Xilinx LogiCORE Partial Reconfiguration 7 7 * Decoupler IP Core. ··· 18 18 #define CTRL_CMD_COUPLE 0 19 19 #define CTRL_OFFSET 0 20 20 21 + struct xlnx_config_data { 22 + const char *name; 23 + }; 24 + 21 25 struct xlnx_pr_decoupler_data { 26 + const struct xlnx_config_data *ipconfig; 22 27 void __iomem *io_base; 23 28 struct clk *clk; 24 29 }; ··· 81 76 .enable_show = xlnx_pr_decoupler_enable_show, 82 77 }; 83 78 79 + static const struct xlnx_config_data decoupler_config = { 80 + .name = "Xilinx PR Decoupler", 81 + }; 82 + 83 + static const struct xlnx_config_data shutdown_config = { 84 + .name = "Xilinx DFX AXI Shutdown Manager", 85 + }; 86 + 84 87 static const struct of_device_id xlnx_pr_decoupler_of_match[] = { 85 - { .compatible = "xlnx,pr-decoupler-1.00", }, 86 - { .compatible = "xlnx,pr-decoupler", }, 88 + { .compatible = "xlnx,pr-decoupler-1.00", .data = &decoupler_config }, 89 + { .compatible = "xlnx,pr-decoupler", .data = &decoupler_config }, 90 + { .compatible = "xlnx,dfx-axi-shutdown-manager-1.00", 91 + .data = &shutdown_config }, 92 + { .compatible = "xlnx,dfx-axi-shutdown-manager", 93 + .data = &shutdown_config }, 87 94 {}, 88 95 }; 89 96 MODULE_DEVICE_TABLE(of, xlnx_pr_decoupler_of_match); 90 97 91 98 static int xlnx_pr_decoupler_probe(struct platform_device *pdev) 92 99 { 100 + struct device_node *np = pdev->dev.of_node; 93 101 struct xlnx_pr_decoupler_data *priv; 94 102 struct fpga_bridge *br; 95 103 int err; ··· 111 93 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 112 94 if (!priv) 113 95 return -ENOMEM; 96 + 97 + if (np) { 98 + const struct of_device_id *match; 99 + 100 + match = of_match_node(xlnx_pr_decoupler_of_match, np); 101 + if (match && match->data) 102 + priv->ipconfig = match->data; 103 + } 114 104 115 105 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 116 106 priv->io_base = devm_ioremap_resource(&pdev->dev, res); ··· 138 112 139 113 clk_disable(priv->clk); 140 114 141 - br = devm_fpga_bridge_create(&pdev->dev, "Xilinx PR Decoupler", 115 + br = devm_fpga_bridge_create(&pdev->dev, priv->ipconfig->name, 142 116 &xlnx_pr_decoupler_br_ops, priv); 143 117 if (!br) { 144 118 err = -ENOMEM; ··· 149 123 150 124 err = fpga_bridge_register(br); 151 125 if (err) { 152 - dev_err(&pdev->dev, "unable to register Xilinx PR Decoupler"); 126 + dev_err(&pdev->dev, "unable to register %s", 127 + priv->ipconfig->name); 153 128 goto err_clk; 154 129 } 155 130