aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/fpga
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/fpga')
-rw-r--r--drivers/fpga/Kconfig39
-rw-r--r--drivers/fpga/Makefile9
-rw-r--r--drivers/fpga/altera-fpga2sdram.c180
-rw-r--r--drivers/fpga/altera-freeze-bridge.c273
-rw-r--r--drivers/fpga/altera-hps2fpga.c222
-rw-r--r--drivers/fpga/fpga-bridge.c395
-rw-r--r--drivers/fpga/fpga-mgr.c97
-rw-r--r--drivers/fpga/fpga-region.c603
-rw-r--r--drivers/fpga/socfpga-a10.c557
-rw-r--r--drivers/fpga/socfpga.c7
-rw-r--r--drivers/fpga/zynq-fpga.c56
11 files changed, 2376 insertions, 62 deletions
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index cd84934774cc..ce861a2853a4 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -13,12 +13,26 @@ config FPGA
13 13
14if FPGA 14if FPGA
15 15
16config FPGA_REGION
17 tristate "FPGA Region"
18 depends on OF && FPGA_BRIDGE
19 help
20 FPGA Regions allow loading FPGA images under control of
21 the Device Tree.
22
16config FPGA_MGR_SOCFPGA 23config FPGA_MGR_SOCFPGA
17 tristate "Altera SOCFPGA FPGA Manager" 24 tristate "Altera SOCFPGA FPGA Manager"
18 depends on ARCH_SOCFPGA 25 depends on ARCH_SOCFPGA || COMPILE_TEST
19 help 26 help
20 FPGA manager driver support for Altera SOCFPGA. 27 FPGA manager driver support for Altera SOCFPGA.
21 28
29config FPGA_MGR_SOCFPGA_A10
30 tristate "Altera SoCFPGA Arria10"
31 depends on ARCH_SOCFPGA || COMPILE_TEST
32 select REGMAP_MMIO
33 help
34 FPGA manager driver support for Altera Arria10 SoCFPGA.
35
22config FPGA_MGR_ZYNQ_FPGA 36config FPGA_MGR_ZYNQ_FPGA
23 tristate "Xilinx Zynq FPGA" 37 tristate "Xilinx Zynq FPGA"
24 depends on ARCH_ZYNQ || COMPILE_TEST 38 depends on ARCH_ZYNQ || COMPILE_TEST
@@ -26,6 +40,29 @@ config FPGA_MGR_ZYNQ_FPGA
26 help 40 help
27 FPGA manager driver support for Xilinx Zynq FPGAs. 41 FPGA manager driver support for Xilinx Zynq FPGAs.
28 42
43config FPGA_BRIDGE
44 tristate "FPGA Bridge Framework"
45 depends on OF
46 help
47 Say Y here if you want to support bridges connected between host
48 processors and FPGAs or between FPGAs.
49
50config SOCFPGA_FPGA_BRIDGE
51 tristate "Altera SoCFPGA FPGA Bridges"
52 depends on ARCH_SOCFPGA && FPGA_BRIDGE
53 help
54 Say Y to enable drivers for FPGA bridges for Altera SOCFPGA
55 devices.
56
57config ALTERA_FREEZE_BRIDGE
58 tristate "Altera FPGA Freeze Bridge"
59 depends on ARCH_SOCFPGA && FPGA_BRIDGE
60 help
61 Say Y to enable drivers for Altera FPGA Freeze bridges. A
62 freeze bridge is a bridge that exists in the FPGA fabric to
63 isolate one region of the FPGA from the busses while that
64 region is being reprogrammed.
65
29endif # FPGA 66endif # FPGA
30 67
31endmenu 68endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 8d83fc6b1613..8df07bcf42a6 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -7,4 +7,13 @@ obj-$(CONFIG_FPGA) += fpga-mgr.o
7 7
8# FPGA Manager Drivers 8# FPGA Manager Drivers
9obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o 9obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
10obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o
10obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o 11obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o
12
13# FPGA Bridge Drivers
14obj-$(CONFIG_FPGA_BRIDGE) += fpga-bridge.o
15obj-$(CONFIG_SOCFPGA_FPGA_BRIDGE) += altera-hps2fpga.o altera-fpga2sdram.o
16obj-$(CONFIG_ALTERA_FREEZE_BRIDGE) += altera-freeze-bridge.o
17
18# High Level Interfaces
19obj-$(CONFIG_FPGA_REGION) += fpga-region.o
diff --git a/drivers/fpga/altera-fpga2sdram.c b/drivers/fpga/altera-fpga2sdram.c
new file mode 100644
index 000000000000..d4eeb74388da
--- /dev/null
+++ b/drivers/fpga/altera-fpga2sdram.c
@@ -0,0 +1,180 @@
1/*
2 * FPGA to SDRAM Bridge Driver for Altera SoCFPGA Devices
3 *
4 * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/*
20 * This driver manages a bridge between an FPGA and the SDRAM used by the ARM
21 * host processor system (HPS).
22 *
23 * The bridge contains 4 read ports, 4 write ports, and 6 command ports.
24 * Reconfiguring these ports requires that no SDRAM transactions occur during
25 * reconfiguration. The code reconfiguring the ports cannot run out of SDRAM
26 * nor can the FPGA access the SDRAM during reconfiguration. This driver does
27 * not support reconfiguring the ports. The ports are configured by code
28 * running out of on chip ram before Linux is started and the configuration
29 * is passed in a handoff register in the system manager.
30 *
31 * This driver supports enabling and disabling of the configured ports, which
32 * allows for safe reprogramming of the FPGA, assuming that the new FPGA image
33 * uses the same port configuration. Bridges must be disabled before
34 * reprogramming the FPGA and re-enabled after the FPGA has been programmed.
35 */
36
37#include <linux/fpga/fpga-bridge.h>
38#include <linux/kernel.h>
39#include <linux/mfd/syscon.h>
40#include <linux/module.h>
41#include <linux/of_platform.h>
42#include <linux/regmap.h>
43
44#define ALT_SDR_CTL_FPGAPORTRST_OFST 0x80
45#define ALT_SDR_CTL_FPGAPORTRST_PORTRSTN_MSK 0x00003fff
46#define ALT_SDR_CTL_FPGAPORTRST_RD_SHIFT 0
47#define ALT_SDR_CTL_FPGAPORTRST_WR_SHIFT 4
48#define ALT_SDR_CTL_FPGAPORTRST_CTRL_SHIFT 8
49
50/*
51 * From the Cyclone V HPS Memory Map document:
52 * These registers are used to store handoff information between the
53 * preloader and the OS. These 8 registers can be used to store any
54 * information. The contents of these registers have no impact on
55 * the state of the HPS hardware.
56 */
57#define SYSMGR_ISWGRP_HANDOFF3 (0x8C)
58
59#define F2S_BRIDGE_NAME "fpga2sdram"
60
61struct alt_fpga2sdram_data {
62 struct device *dev;
63 struct regmap *sdrctl;
64 int mask;
65};
66
67static int alt_fpga2sdram_enable_show(struct fpga_bridge *bridge)
68{
69 struct alt_fpga2sdram_data *priv = bridge->priv;
70 int value;
71
72 regmap_read(priv->sdrctl, ALT_SDR_CTL_FPGAPORTRST_OFST, &value);
73
74 return (value & priv->mask) == priv->mask;
75}
76
77static inline int _alt_fpga2sdram_enable_set(struct alt_fpga2sdram_data *priv,
78 bool enable)
79{
80 return regmap_update_bits(priv->sdrctl, ALT_SDR_CTL_FPGAPORTRST_OFST,
81 priv->mask, enable ? priv->mask : 0);
82}
83
84static int alt_fpga2sdram_enable_set(struct fpga_bridge *bridge, bool enable)
85{
86 return _alt_fpga2sdram_enable_set(bridge->priv, enable);
87}
88
89struct prop_map {
90 char *prop_name;
91 u32 *prop_value;
92 u32 prop_max;
93};
94
95static const struct fpga_bridge_ops altera_fpga2sdram_br_ops = {
96 .enable_set = alt_fpga2sdram_enable_set,
97 .enable_show = alt_fpga2sdram_enable_show,
98};
99
100static const struct of_device_id altera_fpga_of_match[] = {
101 { .compatible = "altr,socfpga-fpga2sdram-bridge" },
102 {},
103};
104
105static int alt_fpga_bridge_probe(struct platform_device *pdev)
106{
107 struct device *dev = &pdev->dev;
108 struct alt_fpga2sdram_data *priv;
109 u32 enable;
110 struct regmap *sysmgr;
111 int ret = 0;
112
113 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
114 if (!priv)
115 return -ENOMEM;
116
117 priv->dev = dev;
118
119 priv->sdrctl = syscon_regmap_lookup_by_compatible("altr,sdr-ctl");
120 if (IS_ERR(priv->sdrctl)) {
121 dev_err(dev, "regmap for altr,sdr-ctl lookup failed.\n");
122 return PTR_ERR(priv->sdrctl);
123 }
124
125 sysmgr = syscon_regmap_lookup_by_compatible("altr,sys-mgr");
126 if (IS_ERR(sysmgr)) {
127 dev_err(dev, "regmap for altr,sys-mgr lookup failed.\n");
128 return PTR_ERR(sysmgr);
129 }
130
131 /* Get f2s bridge configuration saved in handoff register */
132 regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, &priv->mask);
133
134 ret = fpga_bridge_register(dev, F2S_BRIDGE_NAME,
135 &altera_fpga2sdram_br_ops, priv);
136 if (ret)
137 return ret;
138
139 dev_info(dev, "driver initialized with handoff %08x\n", priv->mask);
140
141 if (!of_property_read_u32(dev->of_node, "bridge-enable", &enable)) {
142 if (enable > 1) {
143 dev_warn(dev, "invalid bridge-enable %u > 1\n", enable);
144 } else {
145 dev_info(dev, "%s bridge\n",
146 (enable ? "enabling" : "disabling"));
147 ret = _alt_fpga2sdram_enable_set(priv, enable);
148 if (ret) {
149 fpga_bridge_unregister(&pdev->dev);
150 return ret;
151 }
152 }
153 }
154
155 return ret;
156}
157
158static int alt_fpga_bridge_remove(struct platform_device *pdev)
159{
160 fpga_bridge_unregister(&pdev->dev);
161
162 return 0;
163}
164
165MODULE_DEVICE_TABLE(of, altera_fpga_of_match);
166
167static struct platform_driver altera_fpga_driver = {
168 .probe = alt_fpga_bridge_probe,
169 .remove = alt_fpga_bridge_remove,
170 .driver = {
171 .name = "altera_fpga2sdram_bridge",
172 .of_match_table = of_match_ptr(altera_fpga_of_match),
173 },
174};
175
176module_platform_driver(altera_fpga_driver);
177
178MODULE_DESCRIPTION("Altera SoCFPGA FPGA to SDRAM Bridge");
179MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
180MODULE_LICENSE("GPL v2");
diff --git a/drivers/fpga/altera-freeze-bridge.c b/drivers/fpga/altera-freeze-bridge.c
new file mode 100644
index 000000000000..8dcd9fb22cb9
--- /dev/null
+++ b/drivers/fpga/altera-freeze-bridge.c
@@ -0,0 +1,273 @@
1/*
2 * FPGA Freeze Bridge Controller
3 *
4 * Copyright (C) 2016 Altera Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/delay.h>
19#include <linux/io.h>
20#include <linux/kernel.h>
21#include <linux/of_device.h>
22#include <linux/module.h>
23#include <linux/fpga/fpga-bridge.h>
24
25#define FREEZE_CSR_STATUS_OFFSET 0
26#define FREEZE_CSR_CTRL_OFFSET 4
27#define FREEZE_CSR_ILLEGAL_REQ_OFFSET 8
28#define FREEZE_CSR_REG_VERSION 12
29
30#define FREEZE_CSR_SUPPORTED_VERSION 2
31
32#define FREEZE_CSR_STATUS_FREEZE_REQ_DONE BIT(0)
33#define FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE BIT(1)
34
35#define FREEZE_CSR_CTRL_FREEZE_REQ BIT(0)
36#define FREEZE_CSR_CTRL_RESET_REQ BIT(1)
37#define FREEZE_CSR_CTRL_UNFREEZE_REQ BIT(2)
38
39#define FREEZE_BRIDGE_NAME "freeze"
40
41struct altera_freeze_br_data {
42 struct device *dev;
43 void __iomem *base_addr;
44 bool enable;
45};
46
47/*
48 * Poll status until status bit is set or we have a timeout.
49 */
50static int altera_freeze_br_req_ack(struct altera_freeze_br_data *priv,
51 u32 timeout, u32 req_ack)
52{
53 struct device *dev = priv->dev;
54 void __iomem *csr_illegal_req_addr = priv->base_addr +
55 FREEZE_CSR_ILLEGAL_REQ_OFFSET;
56 u32 status, illegal, ctrl;
57 int ret = -ETIMEDOUT;
58
59 do {
60 illegal = readl(csr_illegal_req_addr);
61 if (illegal) {
62 dev_err(dev, "illegal request detected 0x%x", illegal);
63
64 writel(1, csr_illegal_req_addr);
65
66 illegal = readl(csr_illegal_req_addr);
67 if (illegal)
68 dev_err(dev, "illegal request not cleared 0x%x",
69 illegal);
70
71 ret = -EINVAL;
72 break;
73 }
74
75 status = readl(priv->base_addr + FREEZE_CSR_STATUS_OFFSET);
76 dev_dbg(dev, "%s %x %x\n", __func__, status, req_ack);
77 status &= req_ack;
78 if (status) {
79 ctrl = readl(priv->base_addr + FREEZE_CSR_CTRL_OFFSET);
80 dev_dbg(dev, "%s request %x acknowledged %x %x\n",
81 __func__, req_ack, status, ctrl);
82 ret = 0;
83 break;
84 }
85
86 udelay(1);
87 } while (timeout--);
88
89 if (ret == -ETIMEDOUT)
90 dev_err(dev, "%s timeout waiting for 0x%x\n",
91 __func__, req_ack);
92
93 return ret;
94}
95
96static int altera_freeze_br_do_freeze(struct altera_freeze_br_data *priv,
97 u32 timeout)
98{
99 struct device *dev = priv->dev;
100 void __iomem *csr_ctrl_addr = priv->base_addr +
101 FREEZE_CSR_CTRL_OFFSET;
102 u32 status;
103 int ret;
104
105 status = readl(priv->base_addr + FREEZE_CSR_STATUS_OFFSET);
106
107 dev_dbg(dev, "%s %d %d\n", __func__, status, readl(csr_ctrl_addr));
108
109 if (status & FREEZE_CSR_STATUS_FREEZE_REQ_DONE) {
110 dev_dbg(dev, "%s bridge already disabled %d\n",
111 __func__, status);
112 return 0;
113 } else if (!(status & FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE)) {
114 dev_err(dev, "%s bridge not enabled %d\n", __func__, status);
115 return -EINVAL;
116 }
117
118 writel(FREEZE_CSR_CTRL_FREEZE_REQ, csr_ctrl_addr);
119
120 ret = altera_freeze_br_req_ack(priv, timeout,
121 FREEZE_CSR_STATUS_FREEZE_REQ_DONE);
122
123 if (ret)
124 writel(0, csr_ctrl_addr);
125 else
126 writel(FREEZE_CSR_CTRL_RESET_REQ, csr_ctrl_addr);
127
128 return ret;
129}
130
131static int altera_freeze_br_do_unfreeze(struct altera_freeze_br_data *priv,
132 u32 timeout)
133{
134 struct device *dev = priv->dev;
135 void __iomem *csr_ctrl_addr = priv->base_addr +
136 FREEZE_CSR_CTRL_OFFSET;
137 u32 status;
138 int ret;
139
140 writel(0, csr_ctrl_addr);
141
142 status = readl(priv->base_addr + FREEZE_CSR_STATUS_OFFSET);
143
144 dev_dbg(dev, "%s %d %d\n", __func__, status, readl(csr_ctrl_addr));
145
146 if (status & FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE) {
147 dev_dbg(dev, "%s bridge already enabled %d\n",
148 __func__, status);
149 return 0;
150 } else if (!(status & FREEZE_CSR_STATUS_FREEZE_REQ_DONE)) {
151 dev_err(dev, "%s bridge not frozen %d\n", __func__, status);
152 return -EINVAL;
153 }
154
155 writel(FREEZE_CSR_CTRL_UNFREEZE_REQ, csr_ctrl_addr);
156
157 ret = altera_freeze_br_req_ack(priv, timeout,
158 FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE);
159
160 status = readl(priv->base_addr + FREEZE_CSR_STATUS_OFFSET);
161
162 dev_dbg(dev, "%s %d %d\n", __func__, status, readl(csr_ctrl_addr));
163
164 writel(0, csr_ctrl_addr);
165
166 return ret;
167}
168
169/*
170 * enable = 1 : allow traffic through the bridge
171 * enable = 0 : disable traffic through the bridge
172 */
173static int altera_freeze_br_enable_set(struct fpga_bridge *bridge,
174 bool enable)
175{
176 struct altera_freeze_br_data *priv = bridge->priv;
177 struct fpga_image_info *info = bridge->info;
178 u32 timeout = 0;
179 int ret;
180
181 if (enable) {
182 if (info)
183 timeout = info->enable_timeout_us;
184
185 ret = altera_freeze_br_do_unfreeze(bridge->priv, timeout);
186 } else {
187 if (info)
188 timeout = info->disable_timeout_us;
189
190 ret = altera_freeze_br_do_freeze(bridge->priv, timeout);
191 }
192
193 if (!ret)
194 priv->enable = enable;
195
196 return ret;
197}
198
199static int altera_freeze_br_enable_show(struct fpga_bridge *bridge)
200{
201 struct altera_freeze_br_data *priv = bridge->priv;
202
203 return priv->enable;
204}
205
206static struct fpga_bridge_ops altera_freeze_br_br_ops = {
207 .enable_set = altera_freeze_br_enable_set,
208 .enable_show = altera_freeze_br_enable_show,
209};
210
211static const struct of_device_id altera_freeze_br_of_match[] = {
212 { .compatible = "altr,freeze-bridge-controller", },
213 {},
214};
215MODULE_DEVICE_TABLE(of, altera_freeze_br_of_match);
216
217static int altera_freeze_br_probe(struct platform_device *pdev)
218{
219 struct device *dev = &pdev->dev;
220 struct device_node *np = pdev->dev.of_node;
221 struct altera_freeze_br_data *priv;
222 struct resource *res;
223 u32 status, revision;
224
225 if (!np)
226 return -ENODEV;
227
228 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
229 if (!priv)
230 return -ENOMEM;
231
232 priv->dev = dev;
233
234 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
235 priv->base_addr = devm_ioremap_resource(dev, res);
236 if (IS_ERR(priv->base_addr))
237 return PTR_ERR(priv->base_addr);
238
239 status = readl(priv->base_addr + FREEZE_CSR_STATUS_OFFSET);
240 if (status & FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE)
241 priv->enable = 1;
242
243 revision = readl(priv->base_addr + FREEZE_CSR_REG_VERSION);
244 if (revision != FREEZE_CSR_SUPPORTED_VERSION)
245 dev_warn(dev,
246 "%s Freeze Controller unexpected revision %d != %d\n",
247 __func__, revision, FREEZE_CSR_SUPPORTED_VERSION);
248
249 return fpga_bridge_register(dev, FREEZE_BRIDGE_NAME,
250 &altera_freeze_br_br_ops, priv);
251}
252
253static int altera_freeze_br_remove(struct platform_device *pdev)
254{
255 fpga_bridge_unregister(&pdev->dev);
256
257 return 0;
258}
259
260static struct platform_driver altera_freeze_br_driver = {
261 .probe = altera_freeze_br_probe,
262 .remove = altera_freeze_br_remove,
263 .driver = {
264 .name = "altera_freeze_br",
265 .of_match_table = of_match_ptr(altera_freeze_br_of_match),
266 },
267};
268
269module_platform_driver(altera_freeze_br_driver);
270
271MODULE_DESCRIPTION("Altera Freeze Bridge");
272MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
273MODULE_LICENSE("GPL v2");
diff --git a/drivers/fpga/altera-hps2fpga.c b/drivers/fpga/altera-hps2fpga.c
new file mode 100644
index 000000000000..4b354c79be31
--- /dev/null
+++ b/drivers/fpga/altera-hps2fpga.c
@@ -0,0 +1,222 @@
1/*
2 * FPGA to/from HPS Bridge Driver for Altera SoCFPGA Devices
3 *
4 * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
5 *
6 * Includes this patch from the mailing list:
7 * fpga: altera-hps2fpga: fix HPS2FPGA bridge visibility to L3 masters
8 * Signed-off-by: Anatolij Gustschin <agust@denx.de>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms and conditions of the GNU General Public License,
12 * version 2, as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * This driver manages bridges on a Altera SOCFPGA between the ARM host
25 * processor system (HPS) and the embedded FPGA.
26 *
27 * This driver supports enabling and disabling of the configured ports, which
28 * allows for safe reprogramming of the FPGA, assuming that the new FPGA image
29 * uses the same port configuration. Bridges must be disabled before
30 * reprogramming the FPGA and re-enabled after the FPGA has been programmed.
31 */
32
33#include <linux/clk.h>
34#include <linux/fpga/fpga-bridge.h>
35#include <linux/kernel.h>
36#include <linux/mfd/syscon.h>
37#include <linux/module.h>
38#include <linux/of_platform.h>
39#include <linux/regmap.h>
40#include <linux/reset.h>
41#include <linux/spinlock.h>
42
43#define ALT_L3_REMAP_OFST 0x0
44#define ALT_L3_REMAP_MPUZERO_MSK 0x00000001
45#define ALT_L3_REMAP_H2F_MSK 0x00000008
46#define ALT_L3_REMAP_LWH2F_MSK 0x00000010
47
48#define HPS2FPGA_BRIDGE_NAME "hps2fpga"
49#define LWHPS2FPGA_BRIDGE_NAME "lwhps2fpga"
50#define FPGA2HPS_BRIDGE_NAME "fpga2hps"
51
52struct altera_hps2fpga_data {
53 const char *name;
54 struct reset_control *bridge_reset;
55 struct regmap *l3reg;
56 unsigned int remap_mask;
57 struct clk *clk;
58};
59
60static int alt_hps2fpga_enable_show(struct fpga_bridge *bridge)
61{
62 struct altera_hps2fpga_data *priv = bridge->priv;
63
64 return reset_control_status(priv->bridge_reset);
65}
66
67/* The L3 REMAP register is write only, so keep a cached value. */
68static unsigned int l3_remap_shadow;
69static spinlock_t l3_remap_lock;
70
71static int _alt_hps2fpga_enable_set(struct altera_hps2fpga_data *priv,
72 bool enable)
73{
74 unsigned long flags;
75 int ret;
76
77 /* bring bridge out of reset */
78 if (enable)
79 ret = reset_control_deassert(priv->bridge_reset);
80 else
81 ret = reset_control_assert(priv->bridge_reset);
82 if (ret)
83 return ret;
84
85 /* Allow bridge to be visible to L3 masters or not */
86 if (priv->remap_mask) {
87 spin_lock_irqsave(&l3_remap_lock, flags);
88 l3_remap_shadow |= ALT_L3_REMAP_MPUZERO_MSK;
89
90 if (enable)
91 l3_remap_shadow |= priv->remap_mask;
92 else
93 l3_remap_shadow &= ~priv->remap_mask;
94
95 ret = regmap_write(priv->l3reg, ALT_L3_REMAP_OFST,
96 l3_remap_shadow);
97 spin_unlock_irqrestore(&l3_remap_lock, flags);
98 }
99
100 return ret;
101}
102
103static int alt_hps2fpga_enable_set(struct fpga_bridge *bridge, bool enable)
104{
105 return _alt_hps2fpga_enable_set(bridge->priv, enable);
106}
107
108static const struct fpga_bridge_ops altera_hps2fpga_br_ops = {
109 .enable_set = alt_hps2fpga_enable_set,
110 .enable_show = alt_hps2fpga_enable_show,
111};
112
113static struct altera_hps2fpga_data hps2fpga_data = {
114 .name = HPS2FPGA_BRIDGE_NAME,
115 .remap_mask = ALT_L3_REMAP_H2F_MSK,
116};
117
118static struct altera_hps2fpga_data lwhps2fpga_data = {
119 .name = LWHPS2FPGA_BRIDGE_NAME,
120 .remap_mask = ALT_L3_REMAP_LWH2F_MSK,
121};
122
123static struct altera_hps2fpga_data fpga2hps_data = {
124 .name = FPGA2HPS_BRIDGE_NAME,
125};
126
127static const struct of_device_id altera_fpga_of_match[] = {
128 { .compatible = "altr,socfpga-hps2fpga-bridge",
129 .data = &hps2fpga_data },
130 { .compatible = "altr,socfpga-lwhps2fpga-bridge",
131 .data = &lwhps2fpga_data },
132 { .compatible = "altr,socfpga-fpga2hps-bridge",
133 .data = &fpga2hps_data },
134 {},
135};
136
137static int alt_fpga_bridge_probe(struct platform_device *pdev)
138{
139 struct device *dev = &pdev->dev;
140 struct altera_hps2fpga_data *priv;
141 const struct of_device_id *of_id;
142 u32 enable;
143 int ret;
144
145 of_id = of_match_device(altera_fpga_of_match, dev);
146 priv = (struct altera_hps2fpga_data *)of_id->data;
147
148 priv->bridge_reset = of_reset_control_get_by_index(dev->of_node, 0);
149 if (IS_ERR(priv->bridge_reset)) {
150 dev_err(dev, "Could not get %s reset control\n", priv->name);
151 return PTR_ERR(priv->bridge_reset);
152 }
153
154 if (priv->remap_mask) {
155 priv->l3reg = syscon_regmap_lookup_by_compatible("altr,l3regs");
156 if (IS_ERR(priv->l3reg)) {
157 dev_err(dev, "regmap for altr,l3regs lookup failed\n");
158 return PTR_ERR(priv->l3reg);
159 }
160 }
161
162 priv->clk = devm_clk_get(dev, NULL);
163 if (IS_ERR(priv->clk)) {
164 dev_err(dev, "no clock specified\n");
165 return PTR_ERR(priv->clk);
166 }
167
168 ret = clk_prepare_enable(priv->clk);
169 if (ret) {
170 dev_err(dev, "could not enable clock\n");
171 return -EBUSY;
172 }
173
174 spin_lock_init(&l3_remap_lock);
175
176 if (!of_property_read_u32(dev->of_node, "bridge-enable", &enable)) {
177 if (enable > 1) {
178 dev_warn(dev, "invalid bridge-enable %u > 1\n", enable);
179 } else {
180 dev_info(dev, "%s bridge\n",
181 (enable ? "enabling" : "disabling"));
182
183 ret = _alt_hps2fpga_enable_set(priv, enable);
184 if (ret) {
185 fpga_bridge_unregister(&pdev->dev);
186 return ret;
187 }
188 }
189 }
190
191 return fpga_bridge_register(dev, priv->name, &altera_hps2fpga_br_ops,
192 priv);
193}
194
195static int alt_fpga_bridge_remove(struct platform_device *pdev)
196{
197 struct fpga_bridge *bridge = platform_get_drvdata(pdev);
198 struct altera_hps2fpga_data *priv = bridge->priv;
199
200 fpga_bridge_unregister(&pdev->dev);
201
202 clk_disable_unprepare(priv->clk);
203
204 return 0;
205}
206
207MODULE_DEVICE_TABLE(of, altera_fpga_of_match);
208
209static struct platform_driver alt_fpga_bridge_driver = {
210 .probe = alt_fpga_bridge_probe,
211 .remove = alt_fpga_bridge_remove,
212 .driver = {
213 .name = "altera_hps2fpga_bridge",
214 .of_match_table = of_match_ptr(altera_fpga_of_match),
215 },
216};
217
218module_platform_driver(alt_fpga_bridge_driver);
219
220MODULE_DESCRIPTION("Altera SoCFPGA HPS to FPGA Bridge");
221MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
222MODULE_LICENSE("GPL v2");
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
new file mode 100644
index 000000000000..33ee83e6373c
--- /dev/null
+++ b/drivers/fpga/fpga-bridge.c
@@ -0,0 +1,395 @@
1/*
2 * FPGA Bridge Framework Driver
3 *
4 * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/fpga/fpga-bridge.h>
19#include <linux/idr.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/of_platform.h>
23#include <linux/slab.h>
24#include <linux/spinlock.h>
25
26static DEFINE_IDA(fpga_bridge_ida);
27static struct class *fpga_bridge_class;
28
29/* Lock for adding/removing bridges to linked lists*/
30spinlock_t bridge_list_lock;
31
32static int fpga_bridge_of_node_match(struct device *dev, const void *data)
33{
34 return dev->of_node == data;
35}
36
37/**
38 * fpga_bridge_enable - Enable transactions on the bridge
39 *
40 * @bridge: FPGA bridge
41 *
42 * Return: 0 for success, error code otherwise.
43 */
44int fpga_bridge_enable(struct fpga_bridge *bridge)
45{
46 dev_dbg(&bridge->dev, "enable\n");
47
48 if (bridge->br_ops && bridge->br_ops->enable_set)
49 return bridge->br_ops->enable_set(bridge, 1);
50
51 return 0;
52}
53EXPORT_SYMBOL_GPL(fpga_bridge_enable);
54
55/**
56 * fpga_bridge_disable - Disable transactions on the bridge
57 *
58 * @bridge: FPGA bridge
59 *
60 * Return: 0 for success, error code otherwise.
61 */
62int fpga_bridge_disable(struct fpga_bridge *bridge)
63{
64 dev_dbg(&bridge->dev, "disable\n");
65
66 if (bridge->br_ops && bridge->br_ops->enable_set)
67 return bridge->br_ops->enable_set(bridge, 0);
68
69 return 0;
70}
71EXPORT_SYMBOL_GPL(fpga_bridge_disable);
72
73/**
74 * of_fpga_bridge_get - get an exclusive reference to a fpga bridge
75 *
76 * @np: node pointer of a FPGA bridge
77 * @info: fpga image specific information
78 *
79 * Return fpga_bridge struct if successful.
80 * Return -EBUSY if someone already has a reference to the bridge.
81 * Return -ENODEV if @np is not a FPGA Bridge.
82 */
83struct fpga_bridge *of_fpga_bridge_get(struct device_node *np,
84 struct fpga_image_info *info)
85
86{
87 struct device *dev;
88 struct fpga_bridge *bridge;
89 int ret = -ENODEV;
90
91 dev = class_find_device(fpga_bridge_class, NULL, np,
92 fpga_bridge_of_node_match);
93 if (!dev)
94 goto err_dev;
95
96 bridge = to_fpga_bridge(dev);
97 if (!bridge)
98 goto err_dev;
99
100 bridge->info = info;
101
102 if (!mutex_trylock(&bridge->mutex)) {
103 ret = -EBUSY;
104 goto err_dev;
105 }
106
107 if (!try_module_get(dev->parent->driver->owner))
108 goto err_ll_mod;
109
110 dev_dbg(&bridge->dev, "get\n");
111
112 return bridge;
113
114err_ll_mod:
115 mutex_unlock(&bridge->mutex);
116err_dev:
117 put_device(dev);
118 return ERR_PTR(ret);
119}
120EXPORT_SYMBOL_GPL(of_fpga_bridge_get);
121
122/**
123 * fpga_bridge_put - release a reference to a bridge
124 *
125 * @bridge: FPGA bridge
126 */
127void fpga_bridge_put(struct fpga_bridge *bridge)
128{
129 dev_dbg(&bridge->dev, "put\n");
130
131 bridge->info = NULL;
132 module_put(bridge->dev.parent->driver->owner);
133 mutex_unlock(&bridge->mutex);
134 put_device(&bridge->dev);
135}
136EXPORT_SYMBOL_GPL(fpga_bridge_put);
137
138/**
139 * fpga_bridges_enable - enable bridges in a list
140 * @bridge_list: list of FPGA bridges
141 *
142 * Enable each bridge in the list. If list is empty, do nothing.
143 *
144 * Return 0 for success or empty bridge list; return error code otherwise.
145 */
146int fpga_bridges_enable(struct list_head *bridge_list)
147{
148 struct fpga_bridge *bridge;
149 struct list_head *node;
150 int ret;
151
152 list_for_each(node, bridge_list) {
153 bridge = list_entry(node, struct fpga_bridge, node);
154 ret = fpga_bridge_enable(bridge);
155 if (ret)
156 return ret;
157 }
158
159 return 0;
160}
161EXPORT_SYMBOL_GPL(fpga_bridges_enable);
162
163/**
164 * fpga_bridges_disable - disable bridges in a list
165 *
166 * @bridge_list: list of FPGA bridges
167 *
168 * Disable each bridge in the list. If list is empty, do nothing.
169 *
170 * Return 0 for success or empty bridge list; return error code otherwise.
171 */
172int fpga_bridges_disable(struct list_head *bridge_list)
173{
174 struct fpga_bridge *bridge;
175 struct list_head *node;
176 int ret;
177
178 list_for_each(node, bridge_list) {
179 bridge = list_entry(node, struct fpga_bridge, node);
180 ret = fpga_bridge_disable(bridge);
181 if (ret)
182 return ret;
183 }
184
185 return 0;
186}
187EXPORT_SYMBOL_GPL(fpga_bridges_disable);
188
189/**
190 * fpga_bridges_put - put bridges
191 *
192 * @bridge_list: list of FPGA bridges
193 *
194 * For each bridge in the list, put the bridge and remove it from the list.
195 * If list is empty, do nothing.
196 */
197void fpga_bridges_put(struct list_head *bridge_list)
198{
199 struct fpga_bridge *bridge;
200 struct list_head *node, *next;
201 unsigned long flags;
202
203 list_for_each_safe(node, next, bridge_list) {
204 bridge = list_entry(node, struct fpga_bridge, node);
205
206 fpga_bridge_put(bridge);
207
208 spin_lock_irqsave(&bridge_list_lock, flags);
209 list_del(&bridge->node);
210 spin_unlock_irqrestore(&bridge_list_lock, flags);
211 }
212}
213EXPORT_SYMBOL_GPL(fpga_bridges_put);
214
215/**
216 * fpga_bridges_get_to_list - get a bridge, add it to a list
217 *
218 * @np: node pointer of a FPGA bridge
219 * @info: fpga image specific information
220 * @bridge_list: list of FPGA bridges
221 *
222 * Get an exclusive reference to the bridge and and it to the list.
223 *
224 * Return 0 for success, error code from of_fpga_bridge_get() othewise.
225 */
226int fpga_bridge_get_to_list(struct device_node *np,
227 struct fpga_image_info *info,
228 struct list_head *bridge_list)
229{
230 struct fpga_bridge *bridge;
231 unsigned long flags;
232
233 bridge = of_fpga_bridge_get(np, info);
234 if (IS_ERR(bridge))
235 return PTR_ERR(bridge);
236
237 spin_lock_irqsave(&bridge_list_lock, flags);
238 list_add(&bridge->node, bridge_list);
239 spin_unlock_irqrestore(&bridge_list_lock, flags);
240
241 return 0;
242}
243EXPORT_SYMBOL_GPL(fpga_bridge_get_to_list);
244
245static ssize_t name_show(struct device *dev,
246 struct device_attribute *attr, char *buf)
247{
248 struct fpga_bridge *bridge = to_fpga_bridge(dev);
249
250 return sprintf(buf, "%s\n", bridge->name);
251}
252
253static ssize_t state_show(struct device *dev,
254 struct device_attribute *attr, char *buf)
255{
256 struct fpga_bridge *bridge = to_fpga_bridge(dev);
257 int enable = 1;
258
259 if (bridge->br_ops && bridge->br_ops->enable_show)
260 enable = bridge->br_ops->enable_show(bridge);
261
262 return sprintf(buf, "%s\n", enable ? "enabled" : "disabled");
263}
264
265static DEVICE_ATTR_RO(name);
266static DEVICE_ATTR_RO(state);
267
268static struct attribute *fpga_bridge_attrs[] = {
269 &dev_attr_name.attr,
270 &dev_attr_state.attr,
271 NULL,
272};
273ATTRIBUTE_GROUPS(fpga_bridge);
274
275/**
276 * fpga_bridge_register - register a fpga bridge driver
277 * @dev: FPGA bridge device from pdev
278 * @name: FPGA bridge name
279 * @br_ops: pointer to structure of fpga bridge ops
280 * @priv: FPGA bridge private data
281 *
282 * Return: 0 for success, error code otherwise.
283 */
284int fpga_bridge_register(struct device *dev, const char *name,
285 const struct fpga_bridge_ops *br_ops, void *priv)
286{
287 struct fpga_bridge *bridge;
288 int id, ret = 0;
289
290 if (!name || !strlen(name)) {
291 dev_err(dev, "Attempt to register with no name!\n");
292 return -EINVAL;
293 }
294
295 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
296 if (!bridge)
297 return -ENOMEM;
298
299 id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL);
300 if (id < 0) {
301 ret = id;
302 goto error_kfree;
303 }
304
305 mutex_init(&bridge->mutex);
306 INIT_LIST_HEAD(&bridge->node);
307
308 bridge->name = name;
309 bridge->br_ops = br_ops;
310 bridge->priv = priv;
311
312 device_initialize(&bridge->dev);
313 bridge->dev.class = fpga_bridge_class;
314 bridge->dev.parent = dev;
315 bridge->dev.of_node = dev->of_node;
316 bridge->dev.id = id;
317 dev_set_drvdata(dev, bridge);
318
319 ret = dev_set_name(&bridge->dev, "br%d", id);
320 if (ret)
321 goto error_device;
322
323 ret = device_add(&bridge->dev);
324 if (ret)
325 goto error_device;
326
327 of_platform_populate(dev->of_node, NULL, NULL, dev);
328
329 dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n",
330 bridge->name);
331
332 return 0;
333
334error_device:
335 ida_simple_remove(&fpga_bridge_ida, id);
336error_kfree:
337 kfree(bridge);
338
339 return ret;
340}
341EXPORT_SYMBOL_GPL(fpga_bridge_register);
342
343/**
344 * fpga_bridge_unregister - unregister a fpga bridge driver
345 * @dev: FPGA bridge device from pdev
346 */
347void fpga_bridge_unregister(struct device *dev)
348{
349 struct fpga_bridge *bridge = dev_get_drvdata(dev);
350
351 /*
352 * If the low level driver provides a method for putting bridge into
353 * a desired state upon unregister, do it.
354 */
355 if (bridge->br_ops && bridge->br_ops->fpga_bridge_remove)
356 bridge->br_ops->fpga_bridge_remove(bridge);
357
358 device_unregister(&bridge->dev);
359}
360EXPORT_SYMBOL_GPL(fpga_bridge_unregister);
361
362static void fpga_bridge_dev_release(struct device *dev)
363{
364 struct fpga_bridge *bridge = to_fpga_bridge(dev);
365
366 ida_simple_remove(&fpga_bridge_ida, bridge->dev.id);
367 kfree(bridge);
368}
369
370static int __init fpga_bridge_dev_init(void)
371{
372 spin_lock_init(&bridge_list_lock);
373
374 fpga_bridge_class = class_create(THIS_MODULE, "fpga_bridge");
375 if (IS_ERR(fpga_bridge_class))
376 return PTR_ERR(fpga_bridge_class);
377
378 fpga_bridge_class->dev_groups = fpga_bridge_groups;
379 fpga_bridge_class->dev_release = fpga_bridge_dev_release;
380
381 return 0;
382}
383
384static void __exit fpga_bridge_dev_exit(void)
385{
386 class_destroy(fpga_bridge_class);
387 ida_destroy(&fpga_bridge_ida);
388}
389
390MODULE_DESCRIPTION("FPGA Bridge Driver");
391MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
392MODULE_LICENSE("GPL v2");
393
394subsys_initcall(fpga_bridge_dev_init);
395module_exit(fpga_bridge_dev_exit);
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index 953dc9195937..f0a69d3e60a5 100644
--- a/drivers/fpga/fpga-mgr.c
+++ b/drivers/fpga/fpga-mgr.c
@@ -32,19 +32,20 @@ static struct class *fpga_mgr_class;
32/** 32/**
33 * fpga_mgr_buf_load - load fpga from image in buffer 33 * fpga_mgr_buf_load - load fpga from image in buffer
34 * @mgr: fpga manager 34 * @mgr: fpga manager
35 * @flags: flags setting fpga confuration modes 35 * @info: fpga image specific information
36 * @buf: buffer contain fpga image 36 * @buf: buffer contain fpga image
37 * @count: byte count of buf 37 * @count: byte count of buf
38 * 38 *
39 * Step the low level fpga manager through the device-specific steps of getting 39 * Step the low level fpga manager through the device-specific steps of getting
40 * an FPGA ready to be configured, writing the image to it, then doing whatever 40 * an FPGA ready to be configured, writing the image to it, then doing whatever
41 * post-configuration steps necessary. This code assumes the caller got the 41 * post-configuration steps necessary. This code assumes the caller got the
42 * mgr pointer from of_fpga_mgr_get() and checked that it is not an error code. 42 * mgr pointer from of_fpga_mgr_get() or fpga_mgr_get() and checked that it is
43 * not an error code.
43 * 44 *
44 * Return: 0 on success, negative error code otherwise. 45 * Return: 0 on success, negative error code otherwise.
45 */ 46 */
46int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, const char *buf, 47int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info,
47 size_t count) 48 const char *buf, size_t count)
48{ 49{
49 struct device *dev = &mgr->dev; 50 struct device *dev = &mgr->dev;
50 int ret; 51 int ret;
@@ -52,10 +53,12 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, const char *buf,
52 /* 53 /*
53 * Call the low level driver's write_init function. This will do the 54 * Call the low level driver's write_init function. This will do the
54 * device-specific things to get the FPGA into the state where it is 55 * device-specific things to get the FPGA into the state where it is
55 * ready to receive an FPGA image. 56 * ready to receive an FPGA image. The low level driver only gets to
57 * see the first initial_header_size bytes in the buffer.
56 */ 58 */
57 mgr->state = FPGA_MGR_STATE_WRITE_INIT; 59 mgr->state = FPGA_MGR_STATE_WRITE_INIT;
58 ret = mgr->mops->write_init(mgr, flags, buf, count); 60 ret = mgr->mops->write_init(mgr, info, buf,
61 min(mgr->mops->initial_header_size, count));
59 if (ret) { 62 if (ret) {
60 dev_err(dev, "Error preparing FPGA for writing\n"); 63 dev_err(dev, "Error preparing FPGA for writing\n");
61 mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR; 64 mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR;
@@ -78,7 +81,7 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, const char *buf,
78 * steps to finish and set the FPGA into operating mode. 81 * steps to finish and set the FPGA into operating mode.
79 */ 82 */
80 mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE; 83 mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE;
81 ret = mgr->mops->write_complete(mgr, flags); 84 ret = mgr->mops->write_complete(mgr, info);
82 if (ret) { 85 if (ret) {
83 dev_err(dev, "Error after writing image data to FPGA\n"); 86 dev_err(dev, "Error after writing image data to FPGA\n");
84 mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR; 87 mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
@@ -93,17 +96,19 @@ EXPORT_SYMBOL_GPL(fpga_mgr_buf_load);
93/** 96/**
94 * fpga_mgr_firmware_load - request firmware and load to fpga 97 * fpga_mgr_firmware_load - request firmware and load to fpga
95 * @mgr: fpga manager 98 * @mgr: fpga manager
96 * @flags: flags setting fpga confuration modes 99 * @info: fpga image specific information
97 * @image_name: name of image file on the firmware search path 100 * @image_name: name of image file on the firmware search path
98 * 101 *
99 * Request an FPGA image using the firmware class, then write out to the FPGA. 102 * Request an FPGA image using the firmware class, then write out to the FPGA.
100 * Update the state before each step to provide info on what step failed if 103 * Update the state before each step to provide info on what step failed if
101 * there is a failure. This code assumes the caller got the mgr pointer 104 * there is a failure. This code assumes the caller got the mgr pointer
102 * from of_fpga_mgr_get() and checked that it is not an error code. 105 * from of_fpga_mgr_get() or fpga_mgr_get() and checked that it is not an error
106 * code.
103 * 107 *
104 * Return: 0 on success, negative error code otherwise. 108 * Return: 0 on success, negative error code otherwise.
105 */ 109 */
106int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags, 110int fpga_mgr_firmware_load(struct fpga_manager *mgr,
111 struct fpga_image_info *info,
107 const char *image_name) 112 const char *image_name)
108{ 113{
109 struct device *dev = &mgr->dev; 114 struct device *dev = &mgr->dev;
@@ -121,7 +126,7 @@ int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags,
121 return ret; 126 return ret;
122 } 127 }
123 128
124 ret = fpga_mgr_buf_load(mgr, flags, fw->data, fw->size); 129 ret = fpga_mgr_buf_load(mgr, info, fw->data, fw->size);
125 130
126 release_firmware(fw); 131 release_firmware(fw);
127 132
@@ -181,30 +186,11 @@ static struct attribute *fpga_mgr_attrs[] = {
181}; 186};
182ATTRIBUTE_GROUPS(fpga_mgr); 187ATTRIBUTE_GROUPS(fpga_mgr);
183 188
184static int fpga_mgr_of_node_match(struct device *dev, const void *data) 189struct fpga_manager *__fpga_mgr_get(struct device *dev)
185{
186 return dev->of_node == data;
187}
188
189/**
190 * of_fpga_mgr_get - get an exclusive reference to a fpga mgr
191 * @node: device node
192 *
193 * Given a device node, get an exclusive reference to a fpga mgr.
194 *
195 * Return: fpga manager struct or IS_ERR() condition containing error code.
196 */
197struct fpga_manager *of_fpga_mgr_get(struct device_node *node)
198{ 190{
199 struct fpga_manager *mgr; 191 struct fpga_manager *mgr;
200 struct device *dev;
201 int ret = -ENODEV; 192 int ret = -ENODEV;
202 193
203 dev = class_find_device(fpga_mgr_class, NULL, node,
204 fpga_mgr_of_node_match);
205 if (!dev)
206 return ERR_PTR(-ENODEV);
207
208 mgr = to_fpga_manager(dev); 194 mgr = to_fpga_manager(dev);
209 if (!mgr) 195 if (!mgr)
210 goto err_dev; 196 goto err_dev;
@@ -226,6 +212,55 @@ err_dev:
226 put_device(dev); 212 put_device(dev);
227 return ERR_PTR(ret); 213 return ERR_PTR(ret);
228} 214}
215
216static int fpga_mgr_dev_match(struct device *dev, const void *data)
217{
218 return dev->parent == data;
219}
220
221/**
222 * fpga_mgr_get - get an exclusive reference to a fpga mgr
223 * @dev: parent device that fpga mgr was registered with
224 *
225 * Given a device, get an exclusive reference to a fpga mgr.
226 *
227 * Return: fpga manager struct or IS_ERR() condition containing error code.
228 */
229struct fpga_manager *fpga_mgr_get(struct device *dev)
230{
231 struct device *mgr_dev = class_find_device(fpga_mgr_class, NULL, dev,
232 fpga_mgr_dev_match);
233 if (!mgr_dev)
234 return ERR_PTR(-ENODEV);
235
236 return __fpga_mgr_get(mgr_dev);
237}
238EXPORT_SYMBOL_GPL(fpga_mgr_get);
239
240static int fpga_mgr_of_node_match(struct device *dev, const void *data)
241{
242 return dev->of_node == data;
243}
244
245/**
246 * of_fpga_mgr_get - get an exclusive reference to a fpga mgr
247 * @node: device node
248 *
249 * Given a device node, get an exclusive reference to a fpga mgr.
250 *
251 * Return: fpga manager struct or IS_ERR() condition containing error code.
252 */
253struct fpga_manager *of_fpga_mgr_get(struct device_node *node)
254{
255 struct device *dev;
256
257 dev = class_find_device(fpga_mgr_class, NULL, node,
258 fpga_mgr_of_node_match);
259 if (!dev)
260 return ERR_PTR(-ENODEV);
261
262 return __fpga_mgr_get(dev);
263}
229EXPORT_SYMBOL_GPL(of_fpga_mgr_get); 264EXPORT_SYMBOL_GPL(of_fpga_mgr_get);
230 265
231/** 266/**
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
new file mode 100644
index 000000000000..3222fdbad75a
--- /dev/null
+++ b/drivers/fpga/fpga-region.c
@@ -0,0 +1,603 @@
1/*
2 * FPGA Region - Device Tree support for FPGA programming under Linux
3 *
4 * Copyright (C) 2013-2016 Altera Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/fpga/fpga-bridge.h>
20#include <linux/fpga/fpga-mgr.h>
21#include <linux/idr.h>
22#include <linux/kernel.h>
23#include <linux/list.h>
24#include <linux/module.h>
25#include <linux/of_platform.h>
26#include <linux/slab.h>
27#include <linux/spinlock.h>
28
29/**
30 * struct fpga_region - FPGA Region structure
31 * @dev: FPGA Region device
32 * @mutex: enforces exclusive reference to region
33 * @bridge_list: list of FPGA bridges specified in region
34 * @info: fpga image specific information
35 */
36struct fpga_region {
37 struct device dev;
38 struct mutex mutex; /* for exclusive reference to region */
39 struct list_head bridge_list;
40 struct fpga_image_info *info;
41};
42
43#define to_fpga_region(d) container_of(d, struct fpga_region, dev)
44
45static DEFINE_IDA(fpga_region_ida);
46static struct class *fpga_region_class;
47
48static const struct of_device_id fpga_region_of_match[] = {
49 { .compatible = "fpga-region", },
50 {},
51};
52MODULE_DEVICE_TABLE(of, fpga_region_of_match);
53
54static int fpga_region_of_node_match(struct device *dev, const void *data)
55{
56 return dev->of_node == data;
57}
58
59/**
60 * fpga_region_find - find FPGA region
61 * @np: device node of FPGA Region
62 * Caller will need to put_device(&region->dev) when done.
63 * Returns FPGA Region struct or NULL
64 */
65static struct fpga_region *fpga_region_find(struct device_node *np)
66{
67 struct device *dev;
68
69 dev = class_find_device(fpga_region_class, NULL, np,
70 fpga_region_of_node_match);
71 if (!dev)
72 return NULL;
73
74 return to_fpga_region(dev);
75}
76
77/**
78 * fpga_region_get - get an exclusive reference to a fpga region
79 * @region: FPGA Region struct
80 *
81 * Caller should call fpga_region_put() when done with region.
82 *
83 * Return fpga_region struct if successful.
84 * Return -EBUSY if someone already has a reference to the region.
85 * Return -ENODEV if @np is not a FPGA Region.
86 */
87static struct fpga_region *fpga_region_get(struct fpga_region *region)
88{
89 struct device *dev = &region->dev;
90
91 if (!mutex_trylock(&region->mutex)) {
92 dev_dbg(dev, "%s: FPGA Region already in use\n", __func__);
93 return ERR_PTR(-EBUSY);
94 }
95
96 get_device(dev);
97 of_node_get(dev->of_node);
98 if (!try_module_get(dev->parent->driver->owner)) {
99 of_node_put(dev->of_node);
100 put_device(dev);
101 mutex_unlock(&region->mutex);
102 return ERR_PTR(-ENODEV);
103 }
104
105 dev_dbg(&region->dev, "get\n");
106
107 return region;
108}
109
110/**
111 * fpga_region_put - release a reference to a region
112 *
113 * @region: FPGA region
114 */
115static void fpga_region_put(struct fpga_region *region)
116{
117 struct device *dev = &region->dev;
118
119 dev_dbg(&region->dev, "put\n");
120
121 module_put(dev->parent->driver->owner);
122 of_node_put(dev->of_node);
123 put_device(dev);
124 mutex_unlock(&region->mutex);
125}
126
127/**
128 * fpga_region_get_manager - get exclusive reference for FPGA manager
129 * @region: FPGA region
130 *
131 * Get FPGA Manager from "fpga-mgr" property or from ancestor region.
132 *
133 * Caller should call fpga_mgr_put() when done with manager.
134 *
135 * Return: fpga manager struct or IS_ERR() condition containing error code.
136 */
137static struct fpga_manager *fpga_region_get_manager(struct fpga_region *region)
138{
139 struct device *dev = &region->dev;
140 struct device_node *np = dev->of_node;
141 struct device_node *mgr_node;
142 struct fpga_manager *mgr;
143
144 of_node_get(np);
145 while (np) {
146 if (of_device_is_compatible(np, "fpga-region")) {
147 mgr_node = of_parse_phandle(np, "fpga-mgr", 0);
148 if (mgr_node) {
149 mgr = of_fpga_mgr_get(mgr_node);
150 of_node_put(np);
151 return mgr;
152 }
153 }
154 np = of_get_next_parent(np);
155 }
156 of_node_put(np);
157
158 return ERR_PTR(-EINVAL);
159}
160
161/**
162 * fpga_region_get_bridges - create a list of bridges
163 * @region: FPGA region
164 * @overlay: device node of the overlay
165 *
166 * Create a list of bridges including the parent bridge and the bridges
167 * specified by "fpga-bridges" property. Note that the
168 * fpga_bridges_enable/disable/put functions are all fine with an empty list
169 * if that happens.
170 *
171 * Caller should call fpga_bridges_put(&region->bridge_list) when
172 * done with the bridges.
173 *
174 * Return 0 for success (even if there are no bridges specified)
175 * or -EBUSY if any of the bridges are in use.
176 */
177static int fpga_region_get_bridges(struct fpga_region *region,
178 struct device_node *overlay)
179{
180 struct device *dev = &region->dev;
181 struct device_node *region_np = dev->of_node;
182 struct device_node *br, *np, *parent_br = NULL;
183 int i, ret;
184
185 /* If parent is a bridge, add to list */
186 ret = fpga_bridge_get_to_list(region_np->parent, region->info,
187 &region->bridge_list);
188 if (ret == -EBUSY)
189 return ret;
190
191 if (!ret)
192 parent_br = region_np->parent;
193
194 /* If overlay has a list of bridges, use it. */
195 if (of_parse_phandle(overlay, "fpga-bridges", 0))
196 np = overlay;
197 else
198 np = region_np;
199
200 for (i = 0; ; i++) {
201 br = of_parse_phandle(np, "fpga-bridges", i);
202 if (!br)
203 break;
204
205 /* If parent bridge is in list, skip it. */
206 if (br == parent_br)
207 continue;
208
209 /* If node is a bridge, get it and add to list */
210 ret = fpga_bridge_get_to_list(br, region->info,
211 &region->bridge_list);
212
213 /* If any of the bridges are in use, give up */
214 if (ret == -EBUSY) {
215 fpga_bridges_put(&region->bridge_list);
216 return -EBUSY;
217 }
218 }
219
220 return 0;
221}
222
223/**
224 * fpga_region_program_fpga - program FPGA
225 * @region: FPGA region
226 * @firmware_name: name of FPGA image firmware file
227 * @overlay: device node of the overlay
228 * Program an FPGA using information in the device tree.
229 * Function assumes that there is a firmware-name property.
230 * Return 0 for success or negative error code.
231 */
232static int fpga_region_program_fpga(struct fpga_region *region,
233 const char *firmware_name,
234 struct device_node *overlay)
235{
236 struct fpga_manager *mgr;
237 int ret;
238
239 region = fpga_region_get(region);
240 if (IS_ERR(region)) {
241 pr_err("failed to get fpga region\n");
242 return PTR_ERR(region);
243 }
244
245 mgr = fpga_region_get_manager(region);
246 if (IS_ERR(mgr)) {
247 pr_err("failed to get fpga region manager\n");
248 return PTR_ERR(mgr);
249 }
250
251 ret = fpga_region_get_bridges(region, overlay);
252 if (ret) {
253 pr_err("failed to get fpga region bridges\n");
254 goto err_put_mgr;
255 }
256
257 ret = fpga_bridges_disable(&region->bridge_list);
258 if (ret) {
259 pr_err("failed to disable region bridges\n");
260 goto err_put_br;
261 }
262
263 ret = fpga_mgr_firmware_load(mgr, region->info, firmware_name);
264 if (ret) {
265 pr_err("failed to load fpga image\n");
266 goto err_put_br;
267 }
268
269 ret = fpga_bridges_enable(&region->bridge_list);
270 if (ret) {
271 pr_err("failed to enable region bridges\n");
272 goto err_put_br;
273 }
274
275 fpga_mgr_put(mgr);
276 fpga_region_put(region);
277
278 return 0;
279
280err_put_br:
281 fpga_bridges_put(&region->bridge_list);
282err_put_mgr:
283 fpga_mgr_put(mgr);
284 fpga_region_put(region);
285
286 return ret;
287}
288
289/**
290 * child_regions_with_firmware
291 * @overlay: device node of the overlay
292 *
293 * If the overlay adds child FPGA regions, they are not allowed to have
294 * firmware-name property.
295 *
296 * Return 0 for OK or -EINVAL if child FPGA region adds firmware-name.
297 */
298static int child_regions_with_firmware(struct device_node *overlay)
299{
300 struct device_node *child_region;
301 const char *child_firmware_name;
302 int ret = 0;
303
304 of_node_get(overlay);
305
306 child_region = of_find_matching_node(overlay, fpga_region_of_match);
307 while (child_region) {
308 if (!of_property_read_string(child_region, "firmware-name",
309 &child_firmware_name)) {
310 ret = -EINVAL;
311 break;
312 }
313 child_region = of_find_matching_node(child_region,
314 fpga_region_of_match);
315 }
316
317 of_node_put(child_region);
318
319 if (ret)
320 pr_err("firmware-name not allowed in child FPGA region: %s",
321 child_region->full_name);
322
323 return ret;
324}
325
326/**
327 * fpga_region_notify_pre_apply - pre-apply overlay notification
328 *
329 * @region: FPGA region that the overlay was applied to
330 * @nd: overlay notification data
331 *
332 * Called after when an overlay targeted to a FPGA Region is about to be
333 * applied. Function will check the properties that will be added to the FPGA
334 * region. If the checks pass, it will program the FPGA.
335 *
336 * The checks are:
337 * The overlay must add either firmware-name or external-fpga-config property
338 * to the FPGA Region.
339 *
340 * firmware-name : program the FPGA
341 * external-fpga-config : FPGA is already programmed
342 *
343 * The overlay can add other FPGA regions, but child FPGA regions cannot have a
344 * firmware-name property since those regions don't exist yet.
345 *
346 * If the overlay that breaks the rules, notifier returns an error and the
347 * overlay is rejected before it goes into the main tree.
348 *
349 * Returns 0 for success or negative error code for failure.
350 */
351static int fpga_region_notify_pre_apply(struct fpga_region *region,
352 struct of_overlay_notify_data *nd)
353{
354 const char *firmware_name = NULL;
355 struct fpga_image_info *info;
356 int ret;
357
358 info = devm_kzalloc(&region->dev, sizeof(*info), GFP_KERNEL);
359 if (!info)
360 return -ENOMEM;
361
362 region->info = info;
363
364 /* Reject overlay if child FPGA Regions have firmware-name property */
365 ret = child_regions_with_firmware(nd->overlay);
366 if (ret)
367 return ret;
368
369 /* Read FPGA region properties from the overlay */
370 if (of_property_read_bool(nd->overlay, "partial-fpga-config"))
371 info->flags |= FPGA_MGR_PARTIAL_RECONFIG;
372
373 if (of_property_read_bool(nd->overlay, "external-fpga-config"))
374 info->flags |= FPGA_MGR_EXTERNAL_CONFIG;
375
376 of_property_read_string(nd->overlay, "firmware-name", &firmware_name);
377
378 of_property_read_u32(nd->overlay, "region-unfreeze-timeout-us",
379 &info->enable_timeout_us);
380
381 of_property_read_u32(nd->overlay, "region-freeze-timeout-us",
382 &info->disable_timeout_us);
383
384 /* If FPGA was externally programmed, don't specify firmware */
385 if ((info->flags & FPGA_MGR_EXTERNAL_CONFIG) && firmware_name) {
386 pr_err("error: specified firmware and external-fpga-config");
387 return -EINVAL;
388 }
389
390 /* FPGA is already configured externally. We're done. */
391 if (info->flags & FPGA_MGR_EXTERNAL_CONFIG)
392 return 0;
393
394 /* If we got this far, we should be programming the FPGA */
395 if (!firmware_name) {
396 pr_err("should specify firmware-name or external-fpga-config\n");
397 return -EINVAL;
398 }
399
400 return fpga_region_program_fpga(region, firmware_name, nd->overlay);
401}
402
403/**
404 * fpga_region_notify_post_remove - post-remove overlay notification
405 *
406 * @region: FPGA region that was targeted by the overlay that was removed
407 * @nd: overlay notification data
408 *
409 * Called after an overlay has been removed if the overlay's target was a
410 * FPGA region.
411 */
412static void fpga_region_notify_post_remove(struct fpga_region *region,
413 struct of_overlay_notify_data *nd)
414{
415 fpga_bridges_disable(&region->bridge_list);
416 fpga_bridges_put(&region->bridge_list);
417 devm_kfree(&region->dev, region->info);
418 region->info = NULL;
419}
420
421/**
422 * of_fpga_region_notify - reconfig notifier for dynamic DT changes
423 * @nb: notifier block
424 * @action: notifier action
425 * @arg: reconfig data
426 *
427 * This notifier handles programming a FPGA when a "firmware-name" property is
428 * added to a fpga-region.
429 *
430 * Returns NOTIFY_OK or error if FPGA programming fails.
431 */
432static int of_fpga_region_notify(struct notifier_block *nb,
433 unsigned long action, void *arg)
434{
435 struct of_overlay_notify_data *nd = arg;
436 struct fpga_region *region;
437 int ret;
438
439 switch (action) {
440 case OF_OVERLAY_PRE_APPLY:
441 pr_debug("%s OF_OVERLAY_PRE_APPLY\n", __func__);
442 break;
443 case OF_OVERLAY_POST_APPLY:
444 pr_debug("%s OF_OVERLAY_POST_APPLY\n", __func__);
445 return NOTIFY_OK; /* not for us */
446 case OF_OVERLAY_PRE_REMOVE:
447 pr_debug("%s OF_OVERLAY_PRE_REMOVE\n", __func__);
448 return NOTIFY_OK; /* not for us */
449 case OF_OVERLAY_POST_REMOVE:
450 pr_debug("%s OF_OVERLAY_POST_REMOVE\n", __func__);
451 break;
452 default: /* should not happen */
453 return NOTIFY_OK;
454 }
455
456 region = fpga_region_find(nd->target);
457 if (!region)
458 return NOTIFY_OK;
459
460 ret = 0;
461 switch (action) {
462 case OF_OVERLAY_PRE_APPLY:
463 ret = fpga_region_notify_pre_apply(region, nd);
464 break;
465
466 case OF_OVERLAY_POST_REMOVE:
467 fpga_region_notify_post_remove(region, nd);
468 break;
469 }
470
471 put_device(&region->dev);
472
473 if (ret)
474 return notifier_from_errno(ret);
475
476 return NOTIFY_OK;
477}
478
479static struct notifier_block fpga_region_of_nb = {
480 .notifier_call = of_fpga_region_notify,
481};
482
483static int fpga_region_probe(struct platform_device *pdev)
484{
485 struct device *dev = &pdev->dev;
486 struct device_node *np = dev->of_node;
487 struct fpga_region *region;
488 int id, ret = 0;
489
490 region = kzalloc(sizeof(*region), GFP_KERNEL);
491 if (!region)
492 return -ENOMEM;
493
494 id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL);
495 if (id < 0) {
496 ret = id;
497 goto err_kfree;
498 }
499
500 mutex_init(&region->mutex);
501 INIT_LIST_HEAD(&region->bridge_list);
502
503 device_initialize(&region->dev);
504 region->dev.class = fpga_region_class;
505 region->dev.parent = dev;
506 region->dev.of_node = np;
507 region->dev.id = id;
508 dev_set_drvdata(dev, region);
509
510 ret = dev_set_name(&region->dev, "region%d", id);
511 if (ret)
512 goto err_remove;
513
514 ret = device_add(&region->dev);
515 if (ret)
516 goto err_remove;
517
518 of_platform_populate(np, fpga_region_of_match, NULL, &region->dev);
519
520 dev_info(dev, "FPGA Region probed\n");
521
522 return 0;
523
524err_remove:
525 ida_simple_remove(&fpga_region_ida, id);
526err_kfree:
527 kfree(region);
528
529 return ret;
530}
531
532static int fpga_region_remove(struct platform_device *pdev)
533{
534 struct fpga_region *region = platform_get_drvdata(pdev);
535
536 device_unregister(&region->dev);
537
538 return 0;
539}
540
541static struct platform_driver fpga_region_driver = {
542 .probe = fpga_region_probe,
543 .remove = fpga_region_remove,
544 .driver = {
545 .name = "fpga-region",
546 .of_match_table = of_match_ptr(fpga_region_of_match),
547 },
548};
549
550static void fpga_region_dev_release(struct device *dev)
551{
552 struct fpga_region *region = to_fpga_region(dev);
553
554 ida_simple_remove(&fpga_region_ida, region->dev.id);
555 kfree(region);
556}
557
558/**
559 * fpga_region_init - init function for fpga_region class
560 * Creates the fpga_region class and registers a reconfig notifier.
561 */
562static int __init fpga_region_init(void)
563{
564 int ret;
565
566 fpga_region_class = class_create(THIS_MODULE, "fpga_region");
567 if (IS_ERR(fpga_region_class))
568 return PTR_ERR(fpga_region_class);
569
570 fpga_region_class->dev_release = fpga_region_dev_release;
571
572 ret = of_overlay_notifier_register(&fpga_region_of_nb);
573 if (ret)
574 goto err_class;
575
576 ret = platform_driver_register(&fpga_region_driver);
577 if (ret)
578 goto err_plat;
579
580 return 0;
581
582err_plat:
583 of_overlay_notifier_unregister(&fpga_region_of_nb);
584err_class:
585 class_destroy(fpga_region_class);
586 ida_destroy(&fpga_region_ida);
587 return ret;
588}
589
590static void __exit fpga_region_exit(void)
591{
592 platform_driver_unregister(&fpga_region_driver);
593 of_overlay_notifier_unregister(&fpga_region_of_nb);
594 class_destroy(fpga_region_class);
595 ida_destroy(&fpga_region_ida);
596}
597
598subsys_initcall(fpga_region_init);
599module_exit(fpga_region_exit);
600
601MODULE_DESCRIPTION("FPGA Region");
602MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
603MODULE_LICENSE("GPL v2");
diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c
new file mode 100644
index 000000000000..f8770af0f6b5
--- /dev/null
+++ b/drivers/fpga/socfpga-a10.c
@@ -0,0 +1,557 @@
1/*
2 * FPGA Manager Driver for Altera Arria10 SoCFPGA
3 *
4 * Copyright (C) 2015-2016 Altera Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/clk.h>
20#include <linux/device.h>
21#include <linux/delay.h>
22#include <linux/fpga/fpga-mgr.h>
23#include <linux/io.h>
24#include <linux/module.h>
25#include <linux/of_address.h>
26#include <linux/regmap.h>
27
28#define A10_FPGAMGR_DCLKCNT_OFST 0x08
29#define A10_FPGAMGR_DCLKSTAT_OFST 0x0c
30#define A10_FPGAMGR_IMGCFG_CTL_00_OFST 0x70
31#define A10_FPGAMGR_IMGCFG_CTL_01_OFST 0x74
32#define A10_FPGAMGR_IMGCFG_CTL_02_OFST 0x78
33#define A10_FPGAMGR_IMGCFG_STAT_OFST 0x80
34
35#define A10_FPGAMGR_DCLKSTAT_DCLKDONE BIT(0)
36
37#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG BIT(0)
38#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS BIT(1)
39#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE BIT(2)
40#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG BIT(8)
41#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NSTATUS_OE BIT(16)
42#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_CONDONE_OE BIT(24)
43
44#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG BIT(0)
45#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST BIT(16)
46#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE BIT(24)
47
48#define A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL BIT(0)
49#define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK (BIT(16) | BIT(17))
50#define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT 16
51#define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH BIT(24)
52#define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT 24
53
54#define A10_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR BIT(0)
55#define A10_FPGAMGR_IMGCFG_STAT_F2S_EARLY_USERMODE BIT(1)
56#define A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE BIT(2)
57#define A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN BIT(4)
58#define A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN BIT(6)
59#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY BIT(9)
60#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE BIT(10)
61#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR BIT(11)
62#define A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN BIT(12)
63#define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK (BIT(16) | BIT(17) | BIT(18))
64#define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT 16
65
66/* FPGA CD Ratio Value */
67#define CDRATIO_x1 0x0
68#define CDRATIO_x2 0x1
69#define CDRATIO_x4 0x2
70#define CDRATIO_x8 0x3
71
72/* Configuration width 16/32 bit */
73#define CFGWDTH_32 1
74#define CFGWDTH_16 0
75
76/*
77 * struct a10_fpga_priv - private data for fpga manager
78 * @regmap: regmap for register access
79 * @fpga_data_addr: iomap for single address data register to FPGA
80 * @clk: clock
81 */
82struct a10_fpga_priv {
83 struct regmap *regmap;
84 void __iomem *fpga_data_addr;
85 struct clk *clk;
86};
87
88static bool socfpga_a10_fpga_writeable_reg(struct device *dev, unsigned int reg)
89{
90 switch (reg) {
91 case A10_FPGAMGR_DCLKCNT_OFST:
92 case A10_FPGAMGR_DCLKSTAT_OFST:
93 case A10_FPGAMGR_IMGCFG_CTL_00_OFST:
94 case A10_FPGAMGR_IMGCFG_CTL_01_OFST:
95 case A10_FPGAMGR_IMGCFG_CTL_02_OFST:
96 return true;
97 }
98 return false;
99}
100
101static bool socfpga_a10_fpga_readable_reg(struct device *dev, unsigned int reg)
102{
103 switch (reg) {
104 case A10_FPGAMGR_DCLKCNT_OFST:
105 case A10_FPGAMGR_DCLKSTAT_OFST:
106 case A10_FPGAMGR_IMGCFG_CTL_00_OFST:
107 case A10_FPGAMGR_IMGCFG_CTL_01_OFST:
108 case A10_FPGAMGR_IMGCFG_CTL_02_OFST:
109 case A10_FPGAMGR_IMGCFG_STAT_OFST:
110 return true;
111 }
112 return false;
113}
114
115static const struct regmap_config socfpga_a10_fpga_regmap_config = {
116 .reg_bits = 32,
117 .reg_stride = 4,
118 .val_bits = 32,
119 .writeable_reg = socfpga_a10_fpga_writeable_reg,
120 .readable_reg = socfpga_a10_fpga_readable_reg,
121 .max_register = A10_FPGAMGR_IMGCFG_STAT_OFST,
122 .cache_type = REGCACHE_NONE,
123};
124
125/*
126 * from the register map description of cdratio in imgcfg_ctrl_02:
127 * Normal Configuration : 32bit Passive Parallel
128 * Partial Reconfiguration : 16bit Passive Parallel
129 */
130static void socfpga_a10_fpga_set_cfg_width(struct a10_fpga_priv *priv,
131 int width)
132{
133 width <<= A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT;
134
135 regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
136 A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH, width);
137}
138
139static void socfpga_a10_fpga_generate_dclks(struct a10_fpga_priv *priv,
140 u32 count)
141{
142 u32 val;
143
144 /* Clear any existing DONE status. */
145 regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST,
146 A10_FPGAMGR_DCLKSTAT_DCLKDONE);
147
148 /* Issue the DCLK regmap. */
149 regmap_write(priv->regmap, A10_FPGAMGR_DCLKCNT_OFST, count);
150
151 /* wait till the dclkcnt done */
152 regmap_read_poll_timeout(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST, val,
153 val, 1, 100);
154
155 /* Clear DONE status. */
156 regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST,
157 A10_FPGAMGR_DCLKSTAT_DCLKDONE);
158}
159
160#define RBF_ENCRYPTION_MODE_OFFSET 69
161#define RBF_DECOMPRESS_OFFSET 229
162
163static int socfpga_a10_fpga_encrypted(u32 *buf32, size_t buf32_size)
164{
165 if (buf32_size < RBF_ENCRYPTION_MODE_OFFSET + 1)
166 return -EINVAL;
167
168 /* Is the bitstream encrypted? */
169 return ((buf32[RBF_ENCRYPTION_MODE_OFFSET] >> 2) & 3) != 0;
170}
171
172static int socfpga_a10_fpga_compressed(u32 *buf32, size_t buf32_size)
173{
174 if (buf32_size < RBF_DECOMPRESS_OFFSET + 1)
175 return -EINVAL;
176
177 /* Is the bitstream compressed? */
178 return !((buf32[RBF_DECOMPRESS_OFFSET] >> 1) & 1);
179}
180
181static unsigned int socfpga_a10_fpga_get_cd_ratio(unsigned int cfg_width,
182 bool encrypt, bool compress)
183{
184 unsigned int cd_ratio;
185
186 /*
187 * cd ratio is dependent on cfg width and whether the bitstream
188 * is encrypted and/or compressed.
189 *
190 * | width | encr. | compr. | cd ratio |
191 * | 16 | 0 | 0 | 1 |
192 * | 16 | 0 | 1 | 4 |
193 * | 16 | 1 | 0 | 2 |
194 * | 16 | 1 | 1 | 4 |
195 * | 32 | 0 | 0 | 1 |
196 * | 32 | 0 | 1 | 8 |
197 * | 32 | 1 | 0 | 4 |
198 * | 32 | 1 | 1 | 8 |
199 */
200 if (!compress && !encrypt)
201 return CDRATIO_x1;
202
203 if (compress)
204 cd_ratio = CDRATIO_x4;
205 else
206 cd_ratio = CDRATIO_x2;
207
208 /* If 32 bit, double the cd ratio by incrementing the field */
209 if (cfg_width == CFGWDTH_32)
210 cd_ratio += 1;
211
212 return cd_ratio;
213}
214
215static int socfpga_a10_fpga_set_cdratio(struct fpga_manager *mgr,
216 unsigned int cfg_width,
217 const char *buf, size_t count)
218{
219 struct a10_fpga_priv *priv = mgr->priv;
220 unsigned int cd_ratio;
221 int encrypt, compress;
222
223 encrypt = socfpga_a10_fpga_encrypted((u32 *)buf, count / 4);
224 if (encrypt < 0)
225 return -EINVAL;
226
227 compress = socfpga_a10_fpga_compressed((u32 *)buf, count / 4);
228 if (compress < 0)
229 return -EINVAL;
230
231 cd_ratio = socfpga_a10_fpga_get_cd_ratio(cfg_width, encrypt, compress);
232
233 regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
234 A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK,
235 cd_ratio << A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT);
236
237 return 0;
238}
239
240static u32 socfpga_a10_fpga_read_stat(struct a10_fpga_priv *priv)
241{
242 u32 val;
243
244 regmap_read(priv->regmap, A10_FPGAMGR_IMGCFG_STAT_OFST, &val);
245
246 return val;
247}
248
249static int socfpga_a10_fpga_wait_for_pr_ready(struct a10_fpga_priv *priv)
250{
251 u32 reg, i;
252
253 for (i = 0; i < 10 ; i++) {
254 reg = socfpga_a10_fpga_read_stat(priv);
255
256 if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR)
257 return -EINVAL;
258
259 if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY)
260 return 0;
261 }
262
263 return -ETIMEDOUT;
264}
265
266static int socfpga_a10_fpga_wait_for_pr_done(struct a10_fpga_priv *priv)
267{
268 u32 reg, i;
269
270 for (i = 0; i < 10 ; i++) {
271 reg = socfpga_a10_fpga_read_stat(priv);
272
273 if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR)
274 return -EINVAL;
275
276 if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE)
277 return 0;
278 }
279
280 return -ETIMEDOUT;
281}
282
283/* Start the FPGA programming by initialize the FPGA Manager */
284static int socfpga_a10_fpga_write_init(struct fpga_manager *mgr,
285 struct fpga_image_info *info,
286 const char *buf, size_t count)
287{
288 struct a10_fpga_priv *priv = mgr->priv;
289 unsigned int cfg_width;
290 u32 msel, stat, mask;
291 int ret;
292
293 if (info->flags & FPGA_MGR_PARTIAL_RECONFIG)
294 cfg_width = CFGWDTH_16;
295 else
296 return -EINVAL;
297
298 /* Check for passive parallel (msel == 000 or 001) */
299 msel = socfpga_a10_fpga_read_stat(priv);
300 msel &= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK;
301 msel >>= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT;
302 if ((msel != 0) && (msel != 1)) {
303 dev_dbg(&mgr->dev, "Fail: invalid msel=%d\n", msel);
304 return -EINVAL;
305 }
306
307 /* Make sure no external devices are interfering */
308 stat = socfpga_a10_fpga_read_stat(priv);
309 mask = A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN |
310 A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN;
311 if ((stat & mask) != mask)
312 return -EINVAL;
313
314 /* Set cfg width */
315 socfpga_a10_fpga_set_cfg_width(priv, cfg_width);
316
317 /* Determine cd ratio from bitstream header and set cd ratio */
318 ret = socfpga_a10_fpga_set_cdratio(mgr, cfg_width, buf, count);
319 if (ret)
320 return ret;
321
322 /*
323 * Clear s2f_nce to enable chip select. Leave pr_request
324 * unasserted and override disabled.
325 */
326 regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
327 A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG);
328
329 /* Set cfg_ctrl to enable s2f dclk and data */
330 regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
331 A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL,
332 A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL);
333
334 /*
335 * Disable overrides not needed for pr.
336 * s2f_config==1 leaves reset deasseted.
337 */
338 regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_00_OFST,
339 A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG |
340 A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS |
341 A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE |
342 A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG);
343
344 /* Enable override for data, dclk, nce, and pr_request to CSS */
345 regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
346 A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG, 0);
347
348 /* Send some clocks to clear out any errors */
349 socfpga_a10_fpga_generate_dclks(priv, 256);
350
351 /* Assert pr_request */
352 regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
353 A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST,
354 A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST);
355
356 /* Provide 2048 DCLKs before starting the config data streaming. */
357 socfpga_a10_fpga_generate_dclks(priv, 0x7ff);
358
359 /* Wait for pr_ready */
360 return socfpga_a10_fpga_wait_for_pr_ready(priv);
361}
362
363/*
364 * write data to the FPGA data register
365 */
366static int socfpga_a10_fpga_write(struct fpga_manager *mgr, const char *buf,
367 size_t count)
368{
369 struct a10_fpga_priv *priv = mgr->priv;
370 u32 *buffer_32 = (u32 *)buf;
371 size_t i = 0;
372
373 if (count <= 0)
374 return -EINVAL;
375
376 /* Write out the complete 32-bit chunks */
377 while (count >= sizeof(u32)) {
378 writel(buffer_32[i++], priv->fpga_data_addr);
379 count -= sizeof(u32);
380 }
381
382 /* Write out remaining non 32-bit chunks */
383 switch (count) {
384 case 3:
385 writel(buffer_32[i++] & 0x00ffffff, priv->fpga_data_addr);
386 break;
387 case 2:
388 writel(buffer_32[i++] & 0x0000ffff, priv->fpga_data_addr);
389 break;
390 case 1:
391 writel(buffer_32[i++] & 0x000000ff, priv->fpga_data_addr);
392 break;
393 case 0:
394 break;
395 default:
396 /* This will never happen */
397 return -EFAULT;
398 }
399
400 return 0;
401}
402
403static int socfpga_a10_fpga_write_complete(struct fpga_manager *mgr,
404 struct fpga_image_info *info)
405{
406 struct a10_fpga_priv *priv = mgr->priv;
407 u32 reg;
408 int ret;
409
410 /* Wait for pr_done */
411 ret = socfpga_a10_fpga_wait_for_pr_done(priv);
412
413 /* Clear pr_request */
414 regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
415 A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST, 0);
416
417 /* Send some clocks to clear out any errors */
418 socfpga_a10_fpga_generate_dclks(priv, 256);
419
420 /* Disable s2f dclk and data */
421 regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
422 A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL, 0);
423
424 /* Deassert chip select */
425 regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
426 A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE,
427 A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE);
428
429 /* Disable data, dclk, nce, and pr_request override to CSS */
430 regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
431 A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG,
432 A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG);
433
434 /* Return any errors regarding pr_done or pr_error */
435 if (ret)
436 return ret;
437
438 /* Final check */
439 reg = socfpga_a10_fpga_read_stat(priv);
440
441 if (((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE) == 0) ||
442 ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN) == 0) ||
443 ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0)) {
444 dev_dbg(&mgr->dev,
445 "Timeout in final check. Status=%08xf\n", reg);
446 return -ETIMEDOUT;
447 }
448
449 return 0;
450}
451
452static enum fpga_mgr_states socfpga_a10_fpga_state(struct fpga_manager *mgr)
453{
454 struct a10_fpga_priv *priv = mgr->priv;
455 u32 reg = socfpga_a10_fpga_read_stat(priv);
456
457 if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE)
458 return FPGA_MGR_STATE_OPERATING;
459
460 if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY)
461 return FPGA_MGR_STATE_WRITE;
462
463 if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR)
464 return FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
465
466 if ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0)
467 return FPGA_MGR_STATE_RESET;
468
469 return FPGA_MGR_STATE_UNKNOWN;
470}
471
472static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = {
473 .initial_header_size = (RBF_DECOMPRESS_OFFSET + 1) * 4,
474 .state = socfpga_a10_fpga_state,
475 .write_init = socfpga_a10_fpga_write_init,
476 .write = socfpga_a10_fpga_write,
477 .write_complete = socfpga_a10_fpga_write_complete,
478};
479
480static int socfpga_a10_fpga_probe(struct platform_device *pdev)
481{
482 struct device *dev = &pdev->dev;
483 struct a10_fpga_priv *priv;
484 void __iomem *reg_base;
485 struct resource *res;
486 int ret;
487
488 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
489 if (!priv)
490 return -ENOMEM;
491
492 /* First mmio base is for register access */
493 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
494 reg_base = devm_ioremap_resource(dev, res);
495 if (IS_ERR(reg_base))
496 return PTR_ERR(reg_base);
497
498 /* Second mmio base is for writing FPGA image data */
499 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
500 priv->fpga_data_addr = devm_ioremap_resource(dev, res);
501 if (IS_ERR(priv->fpga_data_addr))
502 return PTR_ERR(priv->fpga_data_addr);
503
504 /* regmap for register access */
505 priv->regmap = devm_regmap_init_mmio(dev, reg_base,
506 &socfpga_a10_fpga_regmap_config);
507 if (IS_ERR(priv->regmap))
508 return -ENODEV;
509
510 priv->clk = devm_clk_get(dev, NULL);
511 if (IS_ERR(priv->clk)) {
512 dev_err(dev, "no clock specified\n");
513 return PTR_ERR(priv->clk);
514 }
515
516 ret = clk_prepare_enable(priv->clk);
517 if (ret) {
518 dev_err(dev, "could not enable clock\n");
519 return -EBUSY;
520 }
521
522 return fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager",
523 &socfpga_a10_fpga_mgr_ops, priv);
524}
525
526static int socfpga_a10_fpga_remove(struct platform_device *pdev)
527{
528 struct fpga_manager *mgr = platform_get_drvdata(pdev);
529 struct a10_fpga_priv *priv = mgr->priv;
530
531 fpga_mgr_unregister(&pdev->dev);
532 clk_disable_unprepare(priv->clk);
533
534 return 0;
535}
536
537static const struct of_device_id socfpga_a10_fpga_of_match[] = {
538 { .compatible = "altr,socfpga-a10-fpga-mgr", },
539 {},
540};
541
542MODULE_DEVICE_TABLE(of, socfpga_a10_fpga_of_match);
543
544static struct platform_driver socfpga_a10_fpga_driver = {
545 .probe = socfpga_a10_fpga_probe,
546 .remove = socfpga_a10_fpga_remove,
547 .driver = {
548 .name = "socfpga_a10_fpga_manager",
549 .of_match_table = socfpga_a10_fpga_of_match,
550 },
551};
552
553module_platform_driver(socfpga_a10_fpga_driver);
554
555MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
556MODULE_DESCRIPTION("SoCFPGA Arria10 FPGA Manager");
557MODULE_LICENSE("GPL v2");
diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c
index 27d2ff28132c..b6672e66cda6 100644
--- a/drivers/fpga/socfpga.c
+++ b/drivers/fpga/socfpga.c
@@ -407,13 +407,14 @@ static int socfpga_fpga_reset(struct fpga_manager *mgr)
407/* 407/*
408 * Prepare the FPGA to receive the configuration data. 408 * Prepare the FPGA to receive the configuration data.
409 */ 409 */
410static int socfpga_fpga_ops_configure_init(struct fpga_manager *mgr, u32 flags, 410static int socfpga_fpga_ops_configure_init(struct fpga_manager *mgr,
411 struct fpga_image_info *info,
411 const char *buf, size_t count) 412 const char *buf, size_t count)
412{ 413{
413 struct socfpga_fpga_priv *priv = mgr->priv; 414 struct socfpga_fpga_priv *priv = mgr->priv;
414 int ret; 415 int ret;
415 416
416 if (flags & FPGA_MGR_PARTIAL_RECONFIG) { 417 if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
417 dev_err(&mgr->dev, "Partial reconfiguration not supported.\n"); 418 dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
418 return -EINVAL; 419 return -EINVAL;
419 } 420 }
@@ -478,7 +479,7 @@ static int socfpga_fpga_ops_configure_write(struct fpga_manager *mgr,
478} 479}
479 480
480static int socfpga_fpga_ops_configure_complete(struct fpga_manager *mgr, 481static int socfpga_fpga_ops_configure_complete(struct fpga_manager *mgr,
481 u32 flags) 482 struct fpga_image_info *info)
482{ 483{
483 struct socfpga_fpga_priv *priv = mgr->priv; 484 struct socfpga_fpga_priv *priv = mgr->priv;
484 u32 status; 485 u32 status;
diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c
index c2fb4120bd62..1812bf7614e1 100644
--- a/drivers/fpga/zynq-fpga.c
+++ b/drivers/fpga/zynq-fpga.c
@@ -118,7 +118,6 @@
118#define FPGA_RST_NONE_MASK 0x0 118#define FPGA_RST_NONE_MASK 0x0
119 119
120struct zynq_fpga_priv { 120struct zynq_fpga_priv {
121 struct device *dev;
122 int irq; 121 int irq;
123 struct clk *clk; 122 struct clk *clk;
124 123
@@ -175,7 +174,8 @@ static irqreturn_t zynq_fpga_isr(int irq, void *data)
175 return IRQ_HANDLED; 174 return IRQ_HANDLED;
176} 175}
177 176
178static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags, 177static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
178 struct fpga_image_info *info,
179 const char *buf, size_t count) 179 const char *buf, size_t count)
180{ 180{
181 struct zynq_fpga_priv *priv; 181 struct zynq_fpga_priv *priv;
@@ -189,7 +189,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags,
189 return err; 189 return err;
190 190
191 /* don't globally reset PL if we're doing partial reconfig */ 191 /* don't globally reset PL if we're doing partial reconfig */
192 if (!(flags & FPGA_MGR_PARTIAL_RECONFIG)) { 192 if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
193 /* assert AXI interface resets */ 193 /* assert AXI interface resets */
194 regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET, 194 regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET,
195 FPGA_RST_ALL_MASK); 195 FPGA_RST_ALL_MASK);
@@ -217,7 +217,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags,
217 INIT_POLL_DELAY, 217 INIT_POLL_DELAY,
218 INIT_POLL_TIMEOUT); 218 INIT_POLL_TIMEOUT);
219 if (err) { 219 if (err) {
220 dev_err(priv->dev, "Timeout waiting for PCFG_INIT"); 220 dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n");
221 goto out_err; 221 goto out_err;
222 } 222 }
223 223
@@ -231,7 +231,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags,
231 INIT_POLL_DELAY, 231 INIT_POLL_DELAY,
232 INIT_POLL_TIMEOUT); 232 INIT_POLL_TIMEOUT);
233 if (err) { 233 if (err) {
234 dev_err(priv->dev, "Timeout waiting for !PCFG_INIT"); 234 dev_err(&mgr->dev, "Timeout waiting for !PCFG_INIT\n");
235 goto out_err; 235 goto out_err;
236 } 236 }
237 237
@@ -245,7 +245,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags,
245 INIT_POLL_DELAY, 245 INIT_POLL_DELAY,
246 INIT_POLL_TIMEOUT); 246 INIT_POLL_TIMEOUT);
247 if (err) { 247 if (err) {
248 dev_err(priv->dev, "Timeout waiting for PCFG_INIT"); 248 dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n");
249 goto out_err; 249 goto out_err;
250 } 250 }
251 } 251 }
@@ -262,7 +262,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags,
262 /* check that we have room in the command queue */ 262 /* check that we have room in the command queue */
263 status = zynq_fpga_read(priv, STATUS_OFFSET); 263 status = zynq_fpga_read(priv, STATUS_OFFSET);
264 if (status & STATUS_DMA_Q_F) { 264 if (status & STATUS_DMA_Q_F) {
265 dev_err(priv->dev, "DMA command queue full"); 265 dev_err(&mgr->dev, "DMA command queue full\n");
266 err = -EBUSY; 266 err = -EBUSY;
267 goto out_err; 267 goto out_err;
268 } 268 }
@@ -295,7 +295,8 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr,
295 in_count = count; 295 in_count = count;
296 priv = mgr->priv; 296 priv = mgr->priv;
297 297
298 kbuf = dma_alloc_coherent(priv->dev, count, &dma_addr, GFP_KERNEL); 298 kbuf =
299 dma_alloc_coherent(mgr->dev.parent, count, &dma_addr, GFP_KERNEL);
299 if (!kbuf) 300 if (!kbuf)
300 return -ENOMEM; 301 return -ENOMEM;
301 302
@@ -331,19 +332,19 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr,
331 zynq_fpga_write(priv, INT_STS_OFFSET, intr_status); 332 zynq_fpga_write(priv, INT_STS_OFFSET, intr_status);
332 333
333 if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) { 334 if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) {
334 dev_err(priv->dev, "Error configuring FPGA"); 335 dev_err(&mgr->dev, "Error configuring FPGA\n");
335 err = -EFAULT; 336 err = -EFAULT;
336 } 337 }
337 338
338 clk_disable(priv->clk); 339 clk_disable(priv->clk);
339 340
340out_free: 341out_free:
341 dma_free_coherent(priv->dev, in_count, kbuf, dma_addr); 342 dma_free_coherent(mgr->dev.parent, count, kbuf, dma_addr);
342
343 return err; 343 return err;
344} 344}
345 345
346static int zynq_fpga_ops_write_complete(struct fpga_manager *mgr, u32 flags) 346static int zynq_fpga_ops_write_complete(struct fpga_manager *mgr,
347 struct fpga_image_info *info)
347{ 348{
348 struct zynq_fpga_priv *priv = mgr->priv; 349 struct zynq_fpga_priv *priv = mgr->priv;
349 int err; 350 int err;
@@ -364,7 +365,7 @@ static int zynq_fpga_ops_write_complete(struct fpga_manager *mgr, u32 flags)
364 return err; 365 return err;
365 366
366 /* for the partial reconfig case we didn't touch the level shifters */ 367 /* for the partial reconfig case we didn't touch the level shifters */
367 if (!(flags & FPGA_MGR_PARTIAL_RECONFIG)) { 368 if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
368 /* enable level shifters from PL to PS */ 369 /* enable level shifters from PL to PS */
369 regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET, 370 regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET,
370 LVL_SHFTR_ENABLE_PL_TO_PS); 371 LVL_SHFTR_ENABLE_PL_TO_PS);
@@ -416,8 +417,6 @@ static int zynq_fpga_probe(struct platform_device *pdev)
416 if (!priv) 417 if (!priv)
417 return -ENOMEM; 418 return -ENOMEM;
418 419
419 priv->dev = dev;
420
421 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 420 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
422 priv->io_base = devm_ioremap_resource(dev, res); 421 priv->io_base = devm_ioremap_resource(dev, res);
423 if (IS_ERR(priv->io_base)) 422 if (IS_ERR(priv->io_base))
@@ -426,7 +425,7 @@ static int zynq_fpga_probe(struct platform_device *pdev)
426 priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node, 425 priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node,
427 "syscon"); 426 "syscon");
428 if (IS_ERR(priv->slcr)) { 427 if (IS_ERR(priv->slcr)) {
429 dev_err(dev, "unable to get zynq-slcr regmap"); 428 dev_err(dev, "unable to get zynq-slcr regmap\n");
430 return PTR_ERR(priv->slcr); 429 return PTR_ERR(priv->slcr);
431 } 430 }
432 431
@@ -434,38 +433,41 @@ static int zynq_fpga_probe(struct platform_device *pdev)
434 433
435 priv->irq = platform_get_irq(pdev, 0); 434 priv->irq = platform_get_irq(pdev, 0);
436 if (priv->irq < 0) { 435 if (priv->irq < 0) {
437 dev_err(dev, "No IRQ available"); 436 dev_err(dev, "No IRQ available\n");
438 return priv->irq; 437 return priv->irq;
439 } 438 }
440 439
441 err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0,
442 dev_name(dev), priv);
443 if (err) {
444 dev_err(dev, "unable to request IRQ");
445 return err;
446 }
447
448 priv->clk = devm_clk_get(dev, "ref_clk"); 440 priv->clk = devm_clk_get(dev, "ref_clk");
449 if (IS_ERR(priv->clk)) { 441 if (IS_ERR(priv->clk)) {
450 dev_err(dev, "input clock not found"); 442 dev_err(dev, "input clock not found\n");
451 return PTR_ERR(priv->clk); 443 return PTR_ERR(priv->clk);
452 } 444 }
453 445
454 err = clk_prepare_enable(priv->clk); 446 err = clk_prepare_enable(priv->clk);
455 if (err) { 447 if (err) {
456 dev_err(dev, "unable to enable clock"); 448 dev_err(dev, "unable to enable clock\n");
457 return err; 449 return err;
458 } 450 }
459 451
460 /* unlock the device */ 452 /* unlock the device */
461 zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK); 453 zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK);
462 454
455 zynq_fpga_write(priv, INT_MASK_OFFSET, 0xFFFFFFFF);
456 zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK);
457 err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0, dev_name(dev),
458 priv);
459 if (err) {
460 dev_err(dev, "unable to request IRQ\n");
461 clk_disable_unprepare(priv->clk);
462 return err;
463 }
464
463 clk_disable(priv->clk); 465 clk_disable(priv->clk);
464 466
465 err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager", 467 err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager",
466 &zynq_fpga_ops, priv); 468 &zynq_fpga_ops, priv);
467 if (err) { 469 if (err) {
468 dev_err(dev, "unable to register FPGA manager"); 470 dev_err(dev, "unable to register FPGA manager\n");
469 clk_unprepare(priv->clk); 471 clk_unprepare(priv->clk);
470 return err; 472 return err;
471 } 473 }