diff options
Diffstat (limited to 'drivers/fpga')
-rw-r--r-- | drivers/fpga/Kconfig | 39 | ||||
-rw-r--r-- | drivers/fpga/Makefile | 9 | ||||
-rw-r--r-- | drivers/fpga/altera-fpga2sdram.c | 180 | ||||
-rw-r--r-- | drivers/fpga/altera-freeze-bridge.c | 273 | ||||
-rw-r--r-- | drivers/fpga/altera-hps2fpga.c | 222 | ||||
-rw-r--r-- | drivers/fpga/fpga-bridge.c | 395 | ||||
-rw-r--r-- | drivers/fpga/fpga-mgr.c | 319 | ||||
-rw-r--r-- | drivers/fpga/fpga-region.c | 603 | ||||
-rw-r--r-- | drivers/fpga/socfpga-a10.c | 557 | ||||
-rw-r--r-- | drivers/fpga/socfpga.c | 7 | ||||
-rw-r--r-- | drivers/fpga/zynq-fpga.c | 277 |
11 files changed, 2749 insertions, 132 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 | ||
14 | if FPGA | 14 | if FPGA |
15 | 15 | ||
16 | config 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 | |||
16 | config FPGA_MGR_SOCFPGA | 23 | config 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 | ||
29 | config 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 | |||
22 | config FPGA_MGR_ZYNQ_FPGA | 36 | config 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 | ||
43 | config 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 | |||
50 | config 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 | |||
57 | config 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 | |||
29 | endif # FPGA | 66 | endif # FPGA |
30 | 67 | ||
31 | endmenu | 68 | endmenu |
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 |
9 | obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o | 9 | obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o |
10 | obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o | ||
10 | obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o | 11 | obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o |
12 | |||
13 | # FPGA Bridge Drivers | ||
14 | obj-$(CONFIG_FPGA_BRIDGE) += fpga-bridge.o | ||
15 | obj-$(CONFIG_SOCFPGA_FPGA_BRIDGE) += altera-hps2fpga.o altera-fpga2sdram.o | ||
16 | obj-$(CONFIG_ALTERA_FREEZE_BRIDGE) += altera-freeze-bridge.o | ||
17 | |||
18 | # High Level Interfaces | ||
19 | obj-$(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 | |||
61 | struct alt_fpga2sdram_data { | ||
62 | struct device *dev; | ||
63 | struct regmap *sdrctl; | ||
64 | int mask; | ||
65 | }; | ||
66 | |||
67 | static 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 | |||
77 | static 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 | |||
84 | static int alt_fpga2sdram_enable_set(struct fpga_bridge *bridge, bool enable) | ||
85 | { | ||
86 | return _alt_fpga2sdram_enable_set(bridge->priv, enable); | ||
87 | } | ||
88 | |||
89 | struct prop_map { | ||
90 | char *prop_name; | ||
91 | u32 *prop_value; | ||
92 | u32 prop_max; | ||
93 | }; | ||
94 | |||
95 | static 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 | |||
100 | static const struct of_device_id altera_fpga_of_match[] = { | ||
101 | { .compatible = "altr,socfpga-fpga2sdram-bridge" }, | ||
102 | {}, | ||
103 | }; | ||
104 | |||
105 | static 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 | |||
158 | static int alt_fpga_bridge_remove(struct platform_device *pdev) | ||
159 | { | ||
160 | fpga_bridge_unregister(&pdev->dev); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | MODULE_DEVICE_TABLE(of, altera_fpga_of_match); | ||
166 | |||
167 | static 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 | |||
176 | module_platform_driver(altera_fpga_driver); | ||
177 | |||
178 | MODULE_DESCRIPTION("Altera SoCFPGA FPGA to SDRAM Bridge"); | ||
179 | MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); | ||
180 | MODULE_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 | |||
41 | struct 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 | */ | ||
50 | static 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 | |||
96 | static 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 | |||
131 | static 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 | */ | ||
173 | static 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 | |||
199 | static 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 | |||
206 | static 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 | |||
211 | static const struct of_device_id altera_freeze_br_of_match[] = { | ||
212 | { .compatible = "altr,freeze-bridge-controller", }, | ||
213 | {}, | ||
214 | }; | ||
215 | MODULE_DEVICE_TABLE(of, altera_freeze_br_of_match); | ||
216 | |||
217 | static 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 | |||
253 | static int altera_freeze_br_remove(struct platform_device *pdev) | ||
254 | { | ||
255 | fpga_bridge_unregister(&pdev->dev); | ||
256 | |||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | static 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 | |||
269 | module_platform_driver(altera_freeze_br_driver); | ||
270 | |||
271 | MODULE_DESCRIPTION("Altera Freeze Bridge"); | ||
272 | MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); | ||
273 | MODULE_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 | |||
52 | struct 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 | |||
60 | static 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. */ | ||
68 | static unsigned int l3_remap_shadow; | ||
69 | static spinlock_t l3_remap_lock; | ||
70 | |||
71 | static 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 | |||
103 | static int alt_hps2fpga_enable_set(struct fpga_bridge *bridge, bool enable) | ||
104 | { | ||
105 | return _alt_hps2fpga_enable_set(bridge->priv, enable); | ||
106 | } | ||
107 | |||
108 | static 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 | |||
113 | static struct altera_hps2fpga_data hps2fpga_data = { | ||
114 | .name = HPS2FPGA_BRIDGE_NAME, | ||
115 | .remap_mask = ALT_L3_REMAP_H2F_MSK, | ||
116 | }; | ||
117 | |||
118 | static struct altera_hps2fpga_data lwhps2fpga_data = { | ||
119 | .name = LWHPS2FPGA_BRIDGE_NAME, | ||
120 | .remap_mask = ALT_L3_REMAP_LWH2F_MSK, | ||
121 | }; | ||
122 | |||
123 | static struct altera_hps2fpga_data fpga2hps_data = { | ||
124 | .name = FPGA2HPS_BRIDGE_NAME, | ||
125 | }; | ||
126 | |||
127 | static 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 | |||
137 | static 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 | |||
195 | static 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 | |||
207 | MODULE_DEVICE_TABLE(of, altera_fpga_of_match); | ||
208 | |||
209 | static 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 | |||
218 | module_platform_driver(alt_fpga_bridge_driver); | ||
219 | |||
220 | MODULE_DESCRIPTION("Altera SoCFPGA HPS to FPGA Bridge"); | ||
221 | MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); | ||
222 | MODULE_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 | |||
26 | static DEFINE_IDA(fpga_bridge_ida); | ||
27 | static struct class *fpga_bridge_class; | ||
28 | |||
29 | /* Lock for adding/removing bridges to linked lists*/ | ||
30 | spinlock_t bridge_list_lock; | ||
31 | |||
32 | static 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 | */ | ||
44 | int 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 | } | ||
53 | EXPORT_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 | */ | ||
62 | int 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 | } | ||
71 | EXPORT_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 | */ | ||
83 | struct 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 | |||
114 | err_ll_mod: | ||
115 | mutex_unlock(&bridge->mutex); | ||
116 | err_dev: | ||
117 | put_device(dev); | ||
118 | return ERR_PTR(ret); | ||
119 | } | ||
120 | EXPORT_SYMBOL_GPL(of_fpga_bridge_get); | ||
121 | |||
122 | /** | ||
123 | * fpga_bridge_put - release a reference to a bridge | ||
124 | * | ||
125 | * @bridge: FPGA bridge | ||
126 | */ | ||
127 | void 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 | } | ||
136 | EXPORT_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 | */ | ||
146 | int 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 | } | ||
161 | EXPORT_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 | */ | ||
172 | int 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 | } | ||
187 | EXPORT_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 | */ | ||
197 | void 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 | } | ||
213 | EXPORT_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 | */ | ||
226 | int 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 | } | ||
243 | EXPORT_SYMBOL_GPL(fpga_bridge_get_to_list); | ||
244 | |||
245 | static 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 | |||
253 | static 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 | |||
265 | static DEVICE_ATTR_RO(name); | ||
266 | static DEVICE_ATTR_RO(state); | ||
267 | |||
268 | static struct attribute *fpga_bridge_attrs[] = { | ||
269 | &dev_attr_name.attr, | ||
270 | &dev_attr_state.attr, | ||
271 | NULL, | ||
272 | }; | ||
273 | ATTRIBUTE_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 | */ | ||
284 | int 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 | |||
334 | error_device: | ||
335 | ida_simple_remove(&fpga_bridge_ida, id); | ||
336 | error_kfree: | ||
337 | kfree(bridge); | ||
338 | |||
339 | return ret; | ||
340 | } | ||
341 | EXPORT_SYMBOL_GPL(fpga_bridge_register); | ||
342 | |||
343 | /** | ||
344 | * fpga_bridge_unregister - unregister a fpga bridge driver | ||
345 | * @dev: FPGA bridge device from pdev | ||
346 | */ | ||
347 | void 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 | } | ||
360 | EXPORT_SYMBOL_GPL(fpga_bridge_unregister); | ||
361 | |||
362 | static 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 | |||
370 | static 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 | |||
384 | static void __exit fpga_bridge_dev_exit(void) | ||
385 | { | ||
386 | class_destroy(fpga_bridge_class); | ||
387 | ida_destroy(&fpga_bridge_ida); | ||
388 | } | ||
389 | |||
390 | MODULE_DESCRIPTION("FPGA Bridge Driver"); | ||
391 | MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); | ||
392 | MODULE_LICENSE("GPL v2"); | ||
393 | |||
394 | subsys_initcall(fpga_bridge_dev_init); | ||
395 | module_exit(fpga_bridge_dev_exit); | ||
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c index 953dc9195937..86d2cb203533 100644 --- a/drivers/fpga/fpga-mgr.c +++ b/drivers/fpga/fpga-mgr.c | |||
@@ -25,85 +25,265 @@ | |||
25 | #include <linux/of.h> | 25 | #include <linux/of.h> |
26 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/scatterlist.h> | ||
29 | #include <linux/highmem.h> | ||
28 | 30 | ||
29 | static DEFINE_IDA(fpga_mgr_ida); | 31 | static DEFINE_IDA(fpga_mgr_ida); |
30 | static struct class *fpga_mgr_class; | 32 | static struct class *fpga_mgr_class; |
31 | 33 | ||
34 | /* | ||
35 | * Call the low level driver's write_init function. This will do the | ||
36 | * device-specific things to get the FPGA into the state where it is ready to | ||
37 | * receive an FPGA image. The low level driver only gets to see the first | ||
38 | * initial_header_size bytes in the buffer. | ||
39 | */ | ||
40 | static int fpga_mgr_write_init_buf(struct fpga_manager *mgr, | ||
41 | struct fpga_image_info *info, | ||
42 | const char *buf, size_t count) | ||
43 | { | ||
44 | int ret; | ||
45 | |||
46 | mgr->state = FPGA_MGR_STATE_WRITE_INIT; | ||
47 | if (!mgr->mops->initial_header_size) | ||
48 | ret = mgr->mops->write_init(mgr, info, NULL, 0); | ||
49 | else | ||
50 | ret = mgr->mops->write_init( | ||
51 | mgr, info, buf, min(mgr->mops->initial_header_size, count)); | ||
52 | |||
53 | if (ret) { | ||
54 | dev_err(&mgr->dev, "Error preparing FPGA for writing\n"); | ||
55 | mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR; | ||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static int fpga_mgr_write_init_sg(struct fpga_manager *mgr, | ||
63 | struct fpga_image_info *info, | ||
64 | struct sg_table *sgt) | ||
65 | { | ||
66 | struct sg_mapping_iter miter; | ||
67 | size_t len; | ||
68 | char *buf; | ||
69 | int ret; | ||
70 | |||
71 | if (!mgr->mops->initial_header_size) | ||
72 | return fpga_mgr_write_init_buf(mgr, info, NULL, 0); | ||
73 | |||
74 | /* | ||
75 | * First try to use miter to map the first fragment to access the | ||
76 | * header, this is the typical path. | ||
77 | */ | ||
78 | sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG); | ||
79 | if (sg_miter_next(&miter) && | ||
80 | miter.length >= mgr->mops->initial_header_size) { | ||
81 | ret = fpga_mgr_write_init_buf(mgr, info, miter.addr, | ||
82 | miter.length); | ||
83 | sg_miter_stop(&miter); | ||
84 | return ret; | ||
85 | } | ||
86 | sg_miter_stop(&miter); | ||
87 | |||
88 | /* Otherwise copy the fragments into temporary memory. */ | ||
89 | buf = kmalloc(mgr->mops->initial_header_size, GFP_KERNEL); | ||
90 | if (!buf) | ||
91 | return -ENOMEM; | ||
92 | |||
93 | len = sg_copy_to_buffer(sgt->sgl, sgt->nents, buf, | ||
94 | mgr->mops->initial_header_size); | ||
95 | ret = fpga_mgr_write_init_buf(mgr, info, buf, len); | ||
96 | |||
97 | kfree(buf); | ||
98 | |||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * After all the FPGA image has been written, do the device specific steps to | ||
104 | * finish and set the FPGA into operating mode. | ||
105 | */ | ||
106 | static int fpga_mgr_write_complete(struct fpga_manager *mgr, | ||
107 | struct fpga_image_info *info) | ||
108 | { | ||
109 | int ret; | ||
110 | |||
111 | mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE; | ||
112 | ret = mgr->mops->write_complete(mgr, info); | ||
113 | if (ret) { | ||
114 | dev_err(&mgr->dev, "Error after writing image data to FPGA\n"); | ||
115 | mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR; | ||
116 | return ret; | ||
117 | } | ||
118 | mgr->state = FPGA_MGR_STATE_OPERATING; | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
32 | /** | 123 | /** |
33 | * fpga_mgr_buf_load - load fpga from image in buffer | 124 | * fpga_mgr_buf_load_sg - load fpga from image in buffer from a scatter list |
34 | * @mgr: fpga manager | 125 | * @mgr: fpga manager |
35 | * @flags: flags setting fpga confuration modes | 126 | * @info: fpga image specific information |
36 | * @buf: buffer contain fpga image | 127 | * @sgt: scatterlist table |
37 | * @count: byte count of buf | ||
38 | * | 128 | * |
39 | * Step the low level fpga manager through the device-specific steps of getting | 129 | * 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 | 130 | * 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 | 131 | * 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. | 132 | * mgr pointer from of_fpga_mgr_get() or fpga_mgr_get() and checked that it is |
133 | * not an error code. | ||
134 | * | ||
135 | * This is the preferred entry point for FPGA programming, it does not require | ||
136 | * any contiguous kernel memory. | ||
43 | * | 137 | * |
44 | * Return: 0 on success, negative error code otherwise. | 138 | * Return: 0 on success, negative error code otherwise. |
45 | */ | 139 | */ |
46 | int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, const char *buf, | 140 | int fpga_mgr_buf_load_sg(struct fpga_manager *mgr, struct fpga_image_info *info, |
47 | size_t count) | 141 | struct sg_table *sgt) |
48 | { | 142 | { |
49 | struct device *dev = &mgr->dev; | ||
50 | int ret; | 143 | int ret; |
51 | 144 | ||
52 | /* | 145 | ret = fpga_mgr_write_init_sg(mgr, info, sgt); |
53 | * Call the low level driver's write_init function. This will do the | 146 | if (ret) |
54 | * device-specific things to get the FPGA into the state where it is | 147 | return ret; |
55 | * ready to receive an FPGA image. | 148 | |
56 | */ | 149 | /* Write the FPGA image to the FPGA. */ |
57 | mgr->state = FPGA_MGR_STATE_WRITE_INIT; | 150 | mgr->state = FPGA_MGR_STATE_WRITE; |
58 | ret = mgr->mops->write_init(mgr, flags, buf, count); | 151 | if (mgr->mops->write_sg) { |
152 | ret = mgr->mops->write_sg(mgr, sgt); | ||
153 | } else { | ||
154 | struct sg_mapping_iter miter; | ||
155 | |||
156 | sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG); | ||
157 | while (sg_miter_next(&miter)) { | ||
158 | ret = mgr->mops->write(mgr, miter.addr, miter.length); | ||
159 | if (ret) | ||
160 | break; | ||
161 | } | ||
162 | sg_miter_stop(&miter); | ||
163 | } | ||
164 | |||
59 | if (ret) { | 165 | if (ret) { |
60 | dev_err(dev, "Error preparing FPGA for writing\n"); | 166 | dev_err(&mgr->dev, "Error while writing image data to FPGA\n"); |
61 | mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR; | 167 | mgr->state = FPGA_MGR_STATE_WRITE_ERR; |
62 | return ret; | 168 | return ret; |
63 | } | 169 | } |
64 | 170 | ||
171 | return fpga_mgr_write_complete(mgr, info); | ||
172 | } | ||
173 | EXPORT_SYMBOL_GPL(fpga_mgr_buf_load_sg); | ||
174 | |||
175 | static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr, | ||
176 | struct fpga_image_info *info, | ||
177 | const char *buf, size_t count) | ||
178 | { | ||
179 | int ret; | ||
180 | |||
181 | ret = fpga_mgr_write_init_buf(mgr, info, buf, count); | ||
182 | if (ret) | ||
183 | return ret; | ||
184 | |||
65 | /* | 185 | /* |
66 | * Write the FPGA image to the FPGA. | 186 | * Write the FPGA image to the FPGA. |
67 | */ | 187 | */ |
68 | mgr->state = FPGA_MGR_STATE_WRITE; | 188 | mgr->state = FPGA_MGR_STATE_WRITE; |
69 | ret = mgr->mops->write(mgr, buf, count); | 189 | ret = mgr->mops->write(mgr, buf, count); |
70 | if (ret) { | 190 | if (ret) { |
71 | dev_err(dev, "Error while writing image data to FPGA\n"); | 191 | dev_err(&mgr->dev, "Error while writing image data to FPGA\n"); |
72 | mgr->state = FPGA_MGR_STATE_WRITE_ERR; | 192 | mgr->state = FPGA_MGR_STATE_WRITE_ERR; |
73 | return ret; | 193 | return ret; |
74 | } | 194 | } |
75 | 195 | ||
196 | return fpga_mgr_write_complete(mgr, info); | ||
197 | } | ||
198 | |||
199 | /** | ||
200 | * fpga_mgr_buf_load - load fpga from image in buffer | ||
201 | * @mgr: fpga manager | ||
202 | * @flags: flags setting fpga confuration modes | ||
203 | * @buf: buffer contain fpga image | ||
204 | * @count: byte count of buf | ||
205 | * | ||
206 | * Step the low level fpga manager through the device-specific steps of getting | ||
207 | * an FPGA ready to be configured, writing the image to it, then doing whatever | ||
208 | * post-configuration steps necessary. This code assumes the caller got the | ||
209 | * mgr pointer from of_fpga_mgr_get() and checked that it is not an error code. | ||
210 | * | ||
211 | * Return: 0 on success, negative error code otherwise. | ||
212 | */ | ||
213 | int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info, | ||
214 | const char *buf, size_t count) | ||
215 | { | ||
216 | struct page **pages; | ||
217 | struct sg_table sgt; | ||
218 | const void *p; | ||
219 | int nr_pages; | ||
220 | int index; | ||
221 | int rc; | ||
222 | |||
76 | /* | 223 | /* |
77 | * After all the FPGA image has been written, do the device specific | 224 | * This is just a fast path if the caller has already created a |
78 | * steps to finish and set the FPGA into operating mode. | 225 | * contiguous kernel buffer and the driver doesn't require SG, non-SG |
226 | * drivers will still work on the slow path. | ||
79 | */ | 227 | */ |
80 | mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE; | 228 | if (mgr->mops->write) |
81 | ret = mgr->mops->write_complete(mgr, flags); | 229 | return fpga_mgr_buf_load_mapped(mgr, info, buf, count); |
82 | if (ret) { | 230 | |
83 | dev_err(dev, "Error after writing image data to FPGA\n"); | 231 | /* |
84 | mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR; | 232 | * Convert the linear kernel pointer into a sg_table of pages for use |
85 | return ret; | 233 | * by the driver. |
234 | */ | ||
235 | nr_pages = DIV_ROUND_UP((unsigned long)buf + count, PAGE_SIZE) - | ||
236 | (unsigned long)buf / PAGE_SIZE; | ||
237 | pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL); | ||
238 | if (!pages) | ||
239 | return -ENOMEM; | ||
240 | |||
241 | p = buf - offset_in_page(buf); | ||
242 | for (index = 0; index < nr_pages; index++) { | ||
243 | if (is_vmalloc_addr(p)) | ||
244 | pages[index] = vmalloc_to_page(p); | ||
245 | else | ||
246 | pages[index] = kmap_to_page((void *)p); | ||
247 | if (!pages[index]) { | ||
248 | kfree(pages); | ||
249 | return -EFAULT; | ||
250 | } | ||
251 | p += PAGE_SIZE; | ||
86 | } | 252 | } |
87 | mgr->state = FPGA_MGR_STATE_OPERATING; | ||
88 | 253 | ||
89 | return 0; | 254 | /* |
255 | * The temporary pages list is used to code share the merging algorithm | ||
256 | * in sg_alloc_table_from_pages | ||
257 | */ | ||
258 | rc = sg_alloc_table_from_pages(&sgt, pages, index, offset_in_page(buf), | ||
259 | count, GFP_KERNEL); | ||
260 | kfree(pages); | ||
261 | if (rc) | ||
262 | return rc; | ||
263 | |||
264 | rc = fpga_mgr_buf_load_sg(mgr, info, &sgt); | ||
265 | sg_free_table(&sgt); | ||
266 | |||
267 | return rc; | ||
90 | } | 268 | } |
91 | EXPORT_SYMBOL_GPL(fpga_mgr_buf_load); | 269 | EXPORT_SYMBOL_GPL(fpga_mgr_buf_load); |
92 | 270 | ||
93 | /** | 271 | /** |
94 | * fpga_mgr_firmware_load - request firmware and load to fpga | 272 | * fpga_mgr_firmware_load - request firmware and load to fpga |
95 | * @mgr: fpga manager | 273 | * @mgr: fpga manager |
96 | * @flags: flags setting fpga confuration modes | 274 | * @info: fpga image specific information |
97 | * @image_name: name of image file on the firmware search path | 275 | * @image_name: name of image file on the firmware search path |
98 | * | 276 | * |
99 | * Request an FPGA image using the firmware class, then write out to the FPGA. | 277 | * 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 | 278 | * 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 | 279 | * 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. | 280 | * from of_fpga_mgr_get() or fpga_mgr_get() and checked that it is not an error |
281 | * code. | ||
103 | * | 282 | * |
104 | * Return: 0 on success, negative error code otherwise. | 283 | * Return: 0 on success, negative error code otherwise. |
105 | */ | 284 | */ |
106 | int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags, | 285 | int fpga_mgr_firmware_load(struct fpga_manager *mgr, |
286 | struct fpga_image_info *info, | ||
107 | const char *image_name) | 287 | const char *image_name) |
108 | { | 288 | { |
109 | struct device *dev = &mgr->dev; | 289 | struct device *dev = &mgr->dev; |
@@ -121,7 +301,7 @@ int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags, | |||
121 | return ret; | 301 | return ret; |
122 | } | 302 | } |
123 | 303 | ||
124 | ret = fpga_mgr_buf_load(mgr, flags, fw->data, fw->size); | 304 | ret = fpga_mgr_buf_load(mgr, info, fw->data, fw->size); |
125 | 305 | ||
126 | release_firmware(fw); | 306 | release_firmware(fw); |
127 | 307 | ||
@@ -181,30 +361,11 @@ static struct attribute *fpga_mgr_attrs[] = { | |||
181 | }; | 361 | }; |
182 | ATTRIBUTE_GROUPS(fpga_mgr); | 362 | ATTRIBUTE_GROUPS(fpga_mgr); |
183 | 363 | ||
184 | static int fpga_mgr_of_node_match(struct device *dev, const void *data) | 364 | struct 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 | */ | ||
197 | struct fpga_manager *of_fpga_mgr_get(struct device_node *node) | ||
198 | { | 365 | { |
199 | struct fpga_manager *mgr; | 366 | struct fpga_manager *mgr; |
200 | struct device *dev; | ||
201 | int ret = -ENODEV; | 367 | int ret = -ENODEV; |
202 | 368 | ||
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); | 369 | mgr = to_fpga_manager(dev); |
209 | if (!mgr) | 370 | if (!mgr) |
210 | goto err_dev; | 371 | goto err_dev; |
@@ -226,6 +387,55 @@ err_dev: | |||
226 | put_device(dev); | 387 | put_device(dev); |
227 | return ERR_PTR(ret); | 388 | return ERR_PTR(ret); |
228 | } | 389 | } |
390 | |||
391 | static int fpga_mgr_dev_match(struct device *dev, const void *data) | ||
392 | { | ||
393 | return dev->parent == data; | ||
394 | } | ||
395 | |||
396 | /** | ||
397 | * fpga_mgr_get - get an exclusive reference to a fpga mgr | ||
398 | * @dev: parent device that fpga mgr was registered with | ||
399 | * | ||
400 | * Given a device, get an exclusive reference to a fpga mgr. | ||
401 | * | ||
402 | * Return: fpga manager struct or IS_ERR() condition containing error code. | ||
403 | */ | ||
404 | struct fpga_manager *fpga_mgr_get(struct device *dev) | ||
405 | { | ||
406 | struct device *mgr_dev = class_find_device(fpga_mgr_class, NULL, dev, | ||
407 | fpga_mgr_dev_match); | ||
408 | if (!mgr_dev) | ||
409 | return ERR_PTR(-ENODEV); | ||
410 | |||
411 | return __fpga_mgr_get(mgr_dev); | ||
412 | } | ||
413 | EXPORT_SYMBOL_GPL(fpga_mgr_get); | ||
414 | |||
415 | static int fpga_mgr_of_node_match(struct device *dev, const void *data) | ||
416 | { | ||
417 | return dev->of_node == data; | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * of_fpga_mgr_get - get an exclusive reference to a fpga mgr | ||
422 | * @node: device node | ||
423 | * | ||
424 | * Given a device node, get an exclusive reference to a fpga mgr. | ||
425 | * | ||
426 | * Return: fpga manager struct or IS_ERR() condition containing error code. | ||
427 | */ | ||
428 | struct fpga_manager *of_fpga_mgr_get(struct device_node *node) | ||
429 | { | ||
430 | struct device *dev; | ||
431 | |||
432 | dev = class_find_device(fpga_mgr_class, NULL, node, | ||
433 | fpga_mgr_of_node_match); | ||
434 | if (!dev) | ||
435 | return ERR_PTR(-ENODEV); | ||
436 | |||
437 | return __fpga_mgr_get(dev); | ||
438 | } | ||
229 | EXPORT_SYMBOL_GPL(of_fpga_mgr_get); | 439 | EXPORT_SYMBOL_GPL(of_fpga_mgr_get); |
230 | 440 | ||
231 | /** | 441 | /** |
@@ -256,8 +466,9 @@ int fpga_mgr_register(struct device *dev, const char *name, | |||
256 | struct fpga_manager *mgr; | 466 | struct fpga_manager *mgr; |
257 | int id, ret; | 467 | int id, ret; |
258 | 468 | ||
259 | if (!mops || !mops->write_init || !mops->write || | 469 | if (!mops || !mops->write_complete || !mops->state || |
260 | !mops->write_complete || !mops->state) { | 470 | !mops->write_init || (!mops->write && !mops->write_sg) || |
471 | (mops->write && mops->write_sg)) { | ||
261 | dev_err(dev, "Attempt to register without fpga_manager_ops\n"); | 472 | dev_err(dev, "Attempt to register without fpga_manager_ops\n"); |
262 | return -EINVAL; | 473 | return -EINVAL; |
263 | } | 474 | } |
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 | */ | ||
36 | struct 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 | |||
45 | static DEFINE_IDA(fpga_region_ida); | ||
46 | static struct class *fpga_region_class; | ||
47 | |||
48 | static const struct of_device_id fpga_region_of_match[] = { | ||
49 | { .compatible = "fpga-region", }, | ||
50 | {}, | ||
51 | }; | ||
52 | MODULE_DEVICE_TABLE(of, fpga_region_of_match); | ||
53 | |||
54 | static 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(®ion->dev) when done. | ||
63 | * Returns FPGA Region struct or NULL | ||
64 | */ | ||
65 | static 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 | */ | ||
87 | static struct fpga_region *fpga_region_get(struct fpga_region *region) | ||
88 | { | ||
89 | struct device *dev = ®ion->dev; | ||
90 | |||
91 | if (!mutex_trylock(®ion->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(®ion->mutex); | ||
102 | return ERR_PTR(-ENODEV); | ||
103 | } | ||
104 | |||
105 | dev_dbg(®ion->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 | */ | ||
115 | static void fpga_region_put(struct fpga_region *region) | ||
116 | { | ||
117 | struct device *dev = ®ion->dev; | ||
118 | |||
119 | dev_dbg(®ion->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(®ion->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 | */ | ||
137 | static struct fpga_manager *fpga_region_get_manager(struct fpga_region *region) | ||
138 | { | ||
139 | struct device *dev = ®ion->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(®ion->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 | */ | ||
177 | static int fpga_region_get_bridges(struct fpga_region *region, | ||
178 | struct device_node *overlay) | ||
179 | { | ||
180 | struct device *dev = ®ion->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 | ®ion->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 | ®ion->bridge_list); | ||
212 | |||
213 | /* If any of the bridges are in use, give up */ | ||
214 | if (ret == -EBUSY) { | ||
215 | fpga_bridges_put(®ion->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 | */ | ||
232 | static 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(®ion->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(®ion->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 | |||
280 | err_put_br: | ||
281 | fpga_bridges_put(®ion->bridge_list); | ||
282 | err_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 | */ | ||
298 | static 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 | */ | ||
351 | static 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(®ion->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 | */ | ||
412 | static void fpga_region_notify_post_remove(struct fpga_region *region, | ||
413 | struct of_overlay_notify_data *nd) | ||
414 | { | ||
415 | fpga_bridges_disable(®ion->bridge_list); | ||
416 | fpga_bridges_put(®ion->bridge_list); | ||
417 | devm_kfree(®ion->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 | */ | ||
432 | static 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(®ion->dev); | ||
472 | |||
473 | if (ret) | ||
474 | return notifier_from_errno(ret); | ||
475 | |||
476 | return NOTIFY_OK; | ||
477 | } | ||
478 | |||
479 | static struct notifier_block fpga_region_of_nb = { | ||
480 | .notifier_call = of_fpga_region_notify, | ||
481 | }; | ||
482 | |||
483 | static 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(®ion->mutex); | ||
501 | INIT_LIST_HEAD(®ion->bridge_list); | ||
502 | |||
503 | device_initialize(®ion->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(®ion->dev, "region%d", id); | ||
511 | if (ret) | ||
512 | goto err_remove; | ||
513 | |||
514 | ret = device_add(®ion->dev); | ||
515 | if (ret) | ||
516 | goto err_remove; | ||
517 | |||
518 | of_platform_populate(np, fpga_region_of_match, NULL, ®ion->dev); | ||
519 | |||
520 | dev_info(dev, "FPGA Region probed\n"); | ||
521 | |||
522 | return 0; | ||
523 | |||
524 | err_remove: | ||
525 | ida_simple_remove(&fpga_region_ida, id); | ||
526 | err_kfree: | ||
527 | kfree(region); | ||
528 | |||
529 | return ret; | ||
530 | } | ||
531 | |||
532 | static int fpga_region_remove(struct platform_device *pdev) | ||
533 | { | ||
534 | struct fpga_region *region = platform_get_drvdata(pdev); | ||
535 | |||
536 | device_unregister(®ion->dev); | ||
537 | |||
538 | return 0; | ||
539 | } | ||
540 | |||
541 | static 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 | |||
550 | static 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 | */ | ||
562 | static 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 | |||
582 | err_plat: | ||
583 | of_overlay_notifier_unregister(&fpga_region_of_nb); | ||
584 | err_class: | ||
585 | class_destroy(fpga_region_class); | ||
586 | ida_destroy(&fpga_region_ida); | ||
587 | return ret; | ||
588 | } | ||
589 | |||
590 | static 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 | |||
598 | subsys_initcall(fpga_region_init); | ||
599 | module_exit(fpga_region_exit); | ||
600 | |||
601 | MODULE_DESCRIPTION("FPGA Region"); | ||
602 | MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); | ||
603 | MODULE_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 | */ | ||
82 | struct a10_fpga_priv { | ||
83 | struct regmap *regmap; | ||
84 | void __iomem *fpga_data_addr; | ||
85 | struct clk *clk; | ||
86 | }; | ||
87 | |||
88 | static 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 | |||
101 | static 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 | |||
115 | static 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 | */ | ||
130 | static 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 | |||
139 | static 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 | |||
163 | static 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 | |||
172 | static 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 | |||
181 | static 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 | |||
215 | static 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 | |||
240 | static 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 | |||
249 | static 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 | |||
266 | static 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 */ | ||
284 | static 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 | */ | ||
366 | static 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 | |||
403 | static 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 | |||
452 | static 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 | |||
472 | static 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 | |||
480 | static 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 | |||
526 | static 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 | |||
537 | static const struct of_device_id socfpga_a10_fpga_of_match[] = { | ||
538 | { .compatible = "altr,socfpga-a10-fpga-mgr", }, | ||
539 | {}, | ||
540 | }; | ||
541 | |||
542 | MODULE_DEVICE_TABLE(of, socfpga_a10_fpga_of_match); | ||
543 | |||
544 | static 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 | |||
553 | module_platform_driver(socfpga_a10_fpga_driver); | ||
554 | |||
555 | MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); | ||
556 | MODULE_DESCRIPTION("SoCFPGA Arria10 FPGA Manager"); | ||
557 | MODULE_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 | */ |
410 | static int socfpga_fpga_ops_configure_init(struct fpga_manager *mgr, u32 flags, | 410 | static 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 | ||
480 | static int socfpga_fpga_ops_configure_complete(struct fpga_manager *mgr, | 481 | static 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..34cb98139442 100644 --- a/drivers/fpga/zynq-fpga.c +++ b/drivers/fpga/zynq-fpga.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/pm.h> | 30 | #include <linux/pm.h> |
31 | #include <linux/regmap.h> | 31 | #include <linux/regmap.h> |
32 | #include <linux/string.h> | 32 | #include <linux/string.h> |
33 | #include <linux/scatterlist.h> | ||
33 | 34 | ||
34 | /* Offsets into SLCR regmap */ | 35 | /* Offsets into SLCR regmap */ |
35 | 36 | ||
@@ -80,6 +81,7 @@ | |||
80 | 81 | ||
81 | /* FPGA init status */ | 82 | /* FPGA init status */ |
82 | #define STATUS_DMA_Q_F BIT(31) | 83 | #define STATUS_DMA_Q_F BIT(31) |
84 | #define STATUS_DMA_Q_E BIT(30) | ||
83 | #define STATUS_PCFG_INIT_MASK BIT(4) | 85 | #define STATUS_PCFG_INIT_MASK BIT(4) |
84 | 86 | ||
85 | /* Interrupt Status/Mask Register Bit definitions */ | 87 | /* Interrupt Status/Mask Register Bit definitions */ |
@@ -89,7 +91,7 @@ | |||
89 | #define IXR_D_P_DONE_MASK BIT(12) | 91 | #define IXR_D_P_DONE_MASK BIT(12) |
90 | /* FPGA programmed */ | 92 | /* FPGA programmed */ |
91 | #define IXR_PCFG_DONE_MASK BIT(2) | 93 | #define IXR_PCFG_DONE_MASK BIT(2) |
92 | #define IXR_ERROR_FLAGS_MASK 0x00F0F860 | 94 | #define IXR_ERROR_FLAGS_MASK 0x00F0C860 |
93 | #define IXR_ALL_MASK 0xF8F7F87F | 95 | #define IXR_ALL_MASK 0xF8F7F87F |
94 | 96 | ||
95 | /* Miscellaneous constant values */ | 97 | /* Miscellaneous constant values */ |
@@ -98,12 +100,16 @@ | |||
98 | #define DMA_INVALID_ADDRESS GENMASK(31, 0) | 100 | #define DMA_INVALID_ADDRESS GENMASK(31, 0) |
99 | /* Used to unlock the dev */ | 101 | /* Used to unlock the dev */ |
100 | #define UNLOCK_MASK 0x757bdf0d | 102 | #define UNLOCK_MASK 0x757bdf0d |
101 | /* Timeout for DMA to complete */ | ||
102 | #define DMA_DONE_TIMEOUT msecs_to_jiffies(1000) | ||
103 | /* Timeout for polling reset bits */ | 103 | /* Timeout for polling reset bits */ |
104 | #define INIT_POLL_TIMEOUT 2500000 | 104 | #define INIT_POLL_TIMEOUT 2500000 |
105 | /* Delay for polling reset bits */ | 105 | /* Delay for polling reset bits */ |
106 | #define INIT_POLL_DELAY 20 | 106 | #define INIT_POLL_DELAY 20 |
107 | /* Signal this is the last DMA transfer, wait for the AXI and PCAP before | ||
108 | * interrupting | ||
109 | */ | ||
110 | #define DMA_SRC_LAST_TRANSFER 1 | ||
111 | /* Timeout for DMA completion */ | ||
112 | #define DMA_TIMEOUT_MS 5000 | ||
107 | 113 | ||
108 | /* Masks for controlling stuff in SLCR */ | 114 | /* Masks for controlling stuff in SLCR */ |
109 | /* Disable all Level shifters */ | 115 | /* Disable all Level shifters */ |
@@ -118,13 +124,17 @@ | |||
118 | #define FPGA_RST_NONE_MASK 0x0 | 124 | #define FPGA_RST_NONE_MASK 0x0 |
119 | 125 | ||
120 | struct zynq_fpga_priv { | 126 | struct zynq_fpga_priv { |
121 | struct device *dev; | ||
122 | int irq; | 127 | int irq; |
123 | struct clk *clk; | 128 | struct clk *clk; |
124 | 129 | ||
125 | void __iomem *io_base; | 130 | void __iomem *io_base; |
126 | struct regmap *slcr; | 131 | struct regmap *slcr; |
127 | 132 | ||
133 | spinlock_t dma_lock; | ||
134 | unsigned int dma_elm; | ||
135 | unsigned int dma_nelms; | ||
136 | struct scatterlist *cur_sg; | ||
137 | |||
128 | struct completion dma_done; | 138 | struct completion dma_done; |
129 | }; | 139 | }; |
130 | 140 | ||
@@ -144,38 +154,106 @@ static inline u32 zynq_fpga_read(const struct zynq_fpga_priv *priv, | |||
144 | readl_poll_timeout(priv->io_base + addr, val, cond, sleep_us, \ | 154 | readl_poll_timeout(priv->io_base + addr, val, cond, sleep_us, \ |
145 | timeout_us) | 155 | timeout_us) |
146 | 156 | ||
147 | static void zynq_fpga_mask_irqs(struct zynq_fpga_priv *priv) | 157 | /* Cause the specified irq mask bits to generate IRQs */ |
158 | static inline void zynq_fpga_set_irq(struct zynq_fpga_priv *priv, u32 enable) | ||
148 | { | 159 | { |
149 | u32 intr_mask; | 160 | zynq_fpga_write(priv, INT_MASK_OFFSET, ~enable); |
150 | |||
151 | intr_mask = zynq_fpga_read(priv, INT_MASK_OFFSET); | ||
152 | zynq_fpga_write(priv, INT_MASK_OFFSET, | ||
153 | intr_mask | IXR_DMA_DONE_MASK | IXR_ERROR_FLAGS_MASK); | ||
154 | } | 161 | } |
155 | 162 | ||
156 | static void zynq_fpga_unmask_irqs(struct zynq_fpga_priv *priv) | 163 | /* Must be called with dma_lock held */ |
164 | static void zynq_step_dma(struct zynq_fpga_priv *priv) | ||
157 | { | 165 | { |
158 | u32 intr_mask; | 166 | u32 addr; |
167 | u32 len; | ||
168 | bool first; | ||
169 | |||
170 | first = priv->dma_elm == 0; | ||
171 | while (priv->cur_sg) { | ||
172 | /* Feed the DMA queue until it is full. */ | ||
173 | if (zynq_fpga_read(priv, STATUS_OFFSET) & STATUS_DMA_Q_F) | ||
174 | break; | ||
175 | |||
176 | addr = sg_dma_address(priv->cur_sg); | ||
177 | len = sg_dma_len(priv->cur_sg); | ||
178 | if (priv->dma_elm + 1 == priv->dma_nelms) { | ||
179 | /* The last transfer waits for the PCAP to finish too, | ||
180 | * notice this also changes the irq_mask to ignore | ||
181 | * IXR_DMA_DONE_MASK which ensures we do not trigger | ||
182 | * the completion too early. | ||
183 | */ | ||
184 | addr |= DMA_SRC_LAST_TRANSFER; | ||
185 | priv->cur_sg = NULL; | ||
186 | } else { | ||
187 | priv->cur_sg = sg_next(priv->cur_sg); | ||
188 | priv->dma_elm++; | ||
189 | } | ||
190 | |||
191 | zynq_fpga_write(priv, DMA_SRC_ADDR_OFFSET, addr); | ||
192 | zynq_fpga_write(priv, DMA_DST_ADDR_OFFSET, DMA_INVALID_ADDRESS); | ||
193 | zynq_fpga_write(priv, DMA_SRC_LEN_OFFSET, len / 4); | ||
194 | zynq_fpga_write(priv, DMA_DEST_LEN_OFFSET, 0); | ||
195 | } | ||
159 | 196 | ||
160 | intr_mask = zynq_fpga_read(priv, INT_MASK_OFFSET); | 197 | /* Once the first transfer is queued we can turn on the ISR, future |
161 | zynq_fpga_write(priv, INT_MASK_OFFSET, | 198 | * calls to zynq_step_dma will happen from the ISR context. The |
162 | intr_mask | 199 | * dma_lock spinlock guarentees this handover is done coherently, the |
163 | & ~(IXR_D_P_DONE_MASK | IXR_ERROR_FLAGS_MASK)); | 200 | * ISR enable is put at the end to avoid another CPU spinning in the |
201 | * ISR on this lock. | ||
202 | */ | ||
203 | if (first && priv->cur_sg) { | ||
204 | zynq_fpga_set_irq(priv, | ||
205 | IXR_DMA_DONE_MASK | IXR_ERROR_FLAGS_MASK); | ||
206 | } else if (!priv->cur_sg) { | ||
207 | /* The last transfer changes to DMA & PCAP mode since we do | ||
208 | * not want to continue until everything has been flushed into | ||
209 | * the PCAP. | ||
210 | */ | ||
211 | zynq_fpga_set_irq(priv, | ||
212 | IXR_D_P_DONE_MASK | IXR_ERROR_FLAGS_MASK); | ||
213 | } | ||
164 | } | 214 | } |
165 | 215 | ||
166 | static irqreturn_t zynq_fpga_isr(int irq, void *data) | 216 | static irqreturn_t zynq_fpga_isr(int irq, void *data) |
167 | { | 217 | { |
168 | struct zynq_fpga_priv *priv = data; | 218 | struct zynq_fpga_priv *priv = data; |
219 | u32 intr_status; | ||
169 | 220 | ||
170 | /* disable DMA and error IRQs */ | 221 | /* If anything other than DMA completion is reported stop and hand |
171 | zynq_fpga_mask_irqs(priv); | 222 | * control back to zynq_fpga_ops_write, something went wrong, |
223 | * otherwise progress the DMA. | ||
224 | */ | ||
225 | spin_lock(&priv->dma_lock); | ||
226 | intr_status = zynq_fpga_read(priv, INT_STS_OFFSET); | ||
227 | if (!(intr_status & IXR_ERROR_FLAGS_MASK) && | ||
228 | (intr_status & IXR_DMA_DONE_MASK) && priv->cur_sg) { | ||
229 | zynq_fpga_write(priv, INT_STS_OFFSET, IXR_DMA_DONE_MASK); | ||
230 | zynq_step_dma(priv); | ||
231 | spin_unlock(&priv->dma_lock); | ||
232 | return IRQ_HANDLED; | ||
233 | } | ||
234 | spin_unlock(&priv->dma_lock); | ||
172 | 235 | ||
236 | zynq_fpga_set_irq(priv, 0); | ||
173 | complete(&priv->dma_done); | 237 | complete(&priv->dma_done); |
174 | 238 | ||
175 | return IRQ_HANDLED; | 239 | return IRQ_HANDLED; |
176 | } | 240 | } |
177 | 241 | ||
178 | static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags, | 242 | /* Sanity check the proposed bitstream. It must start with the sync word in |
243 | * the correct byte order, and be dword aligned. The input is a Xilinx .bin | ||
244 | * file with every 32 bit quantity swapped. | ||
245 | */ | ||
246 | static bool zynq_fpga_has_sync(const u8 *buf, size_t count) | ||
247 | { | ||
248 | for (; count >= 4; buf += 4, count -= 4) | ||
249 | if (buf[0] == 0x66 && buf[1] == 0x55 && buf[2] == 0x99 && | ||
250 | buf[3] == 0xaa) | ||
251 | return true; | ||
252 | return false; | ||
253 | } | ||
254 | |||
255 | static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, | ||
256 | struct fpga_image_info *info, | ||
179 | const char *buf, size_t count) | 257 | const char *buf, size_t count) |
180 | { | 258 | { |
181 | struct zynq_fpga_priv *priv; | 259 | struct zynq_fpga_priv *priv; |
@@ -189,7 +267,14 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags, | |||
189 | return err; | 267 | return err; |
190 | 268 | ||
191 | /* don't globally reset PL if we're doing partial reconfig */ | 269 | /* don't globally reset PL if we're doing partial reconfig */ |
192 | if (!(flags & FPGA_MGR_PARTIAL_RECONFIG)) { | 270 | if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) { |
271 | if (!zynq_fpga_has_sync(buf, count)) { | ||
272 | dev_err(&mgr->dev, | ||
273 | "Invalid bitstream, could not find a sync word. Bitstream must be a byte swapped .bin file\n"); | ||
274 | err = -EINVAL; | ||
275 | goto out_err; | ||
276 | } | ||
277 | |||
193 | /* assert AXI interface resets */ | 278 | /* assert AXI interface resets */ |
194 | regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET, | 279 | regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET, |
195 | FPGA_RST_ALL_MASK); | 280 | FPGA_RST_ALL_MASK); |
@@ -217,7 +302,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags, | |||
217 | INIT_POLL_DELAY, | 302 | INIT_POLL_DELAY, |
218 | INIT_POLL_TIMEOUT); | 303 | INIT_POLL_TIMEOUT); |
219 | if (err) { | 304 | if (err) { |
220 | dev_err(priv->dev, "Timeout waiting for PCFG_INIT"); | 305 | dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n"); |
221 | goto out_err; | 306 | goto out_err; |
222 | } | 307 | } |
223 | 308 | ||
@@ -231,7 +316,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags, | |||
231 | INIT_POLL_DELAY, | 316 | INIT_POLL_DELAY, |
232 | INIT_POLL_TIMEOUT); | 317 | INIT_POLL_TIMEOUT); |
233 | if (err) { | 318 | if (err) { |
234 | dev_err(priv->dev, "Timeout waiting for !PCFG_INIT"); | 319 | dev_err(&mgr->dev, "Timeout waiting for !PCFG_INIT\n"); |
235 | goto out_err; | 320 | goto out_err; |
236 | } | 321 | } |
237 | 322 | ||
@@ -245,7 +330,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags, | |||
245 | INIT_POLL_DELAY, | 330 | INIT_POLL_DELAY, |
246 | INIT_POLL_TIMEOUT); | 331 | INIT_POLL_TIMEOUT); |
247 | if (err) { | 332 | if (err) { |
248 | dev_err(priv->dev, "Timeout waiting for PCFG_INIT"); | 333 | dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n"); |
249 | goto out_err; | 334 | goto out_err; |
250 | } | 335 | } |
251 | } | 336 | } |
@@ -259,10 +344,11 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags, | |||
259 | zynq_fpga_write(priv, CTRL_OFFSET, | 344 | zynq_fpga_write(priv, CTRL_OFFSET, |
260 | (CTRL_PCAP_PR_MASK | CTRL_PCAP_MODE_MASK | ctrl)); | 345 | (CTRL_PCAP_PR_MASK | CTRL_PCAP_MODE_MASK | ctrl)); |
261 | 346 | ||
262 | /* check that we have room in the command queue */ | 347 | /* We expect that the command queue is empty right now. */ |
263 | status = zynq_fpga_read(priv, STATUS_OFFSET); | 348 | status = zynq_fpga_read(priv, STATUS_OFFSET); |
264 | if (status & STATUS_DMA_Q_F) { | 349 | if ((status & STATUS_DMA_Q_F) || |
265 | dev_err(priv->dev, "DMA command queue full"); | 350 | (status & STATUS_DMA_Q_E) != STATUS_DMA_Q_E) { |
351 | dev_err(&mgr->dev, "DMA command queue not right\n"); | ||
266 | err = -EBUSY; | 352 | err = -EBUSY; |
267 | goto out_err; | 353 | goto out_err; |
268 | } | 354 | } |
@@ -281,25 +367,36 @@ out_err: | |||
281 | return err; | 367 | return err; |
282 | } | 368 | } |
283 | 369 | ||
284 | static int zynq_fpga_ops_write(struct fpga_manager *mgr, | 370 | static int zynq_fpga_ops_write(struct fpga_manager *mgr, struct sg_table *sgt) |
285 | const char *buf, size_t count) | ||
286 | { | 371 | { |
287 | struct zynq_fpga_priv *priv; | 372 | struct zynq_fpga_priv *priv; |
373 | const char *why; | ||
288 | int err; | 374 | int err; |
289 | char *kbuf; | ||
290 | size_t in_count; | ||
291 | dma_addr_t dma_addr; | ||
292 | u32 transfer_length; | ||
293 | u32 intr_status; | 375 | u32 intr_status; |
376 | unsigned long timeout; | ||
377 | unsigned long flags; | ||
378 | struct scatterlist *sg; | ||
379 | int i; | ||
294 | 380 | ||
295 | in_count = count; | ||
296 | priv = mgr->priv; | 381 | priv = mgr->priv; |
297 | 382 | ||
298 | kbuf = dma_alloc_coherent(priv->dev, count, &dma_addr, GFP_KERNEL); | 383 | /* The hardware can only DMA multiples of 4 bytes, and it requires the |
299 | if (!kbuf) | 384 | * starting addresses to be aligned to 64 bits (UG585 pg 212). |
300 | return -ENOMEM; | 385 | */ |
386 | for_each_sg(sgt->sgl, sg, sgt->nents, i) { | ||
387 | if ((sg->offset % 8) || (sg->length % 4)) { | ||
388 | dev_err(&mgr->dev, | ||
389 | "Invalid bitstream, chunks must be aligned\n"); | ||
390 | return -EINVAL; | ||
391 | } | ||
392 | } | ||
301 | 393 | ||
302 | memcpy(kbuf, buf, count); | 394 | priv->dma_nelms = |
395 | dma_map_sg(mgr->dev.parent, sgt->sgl, sgt->nents, DMA_TO_DEVICE); | ||
396 | if (priv->dma_nelms == 0) { | ||
397 | dev_err(&mgr->dev, "Unable to DMA map (TO_DEVICE)\n"); | ||
398 | return -ENOMEM; | ||
399 | } | ||
303 | 400 | ||
304 | /* enable clock */ | 401 | /* enable clock */ |
305 | err = clk_enable(priv->clk); | 402 | err = clk_enable(priv->clk); |
@@ -307,43 +404,72 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, | |||
307 | goto out_free; | 404 | goto out_free; |
308 | 405 | ||
309 | zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK); | 406 | zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK); |
310 | |||
311 | reinit_completion(&priv->dma_done); | 407 | reinit_completion(&priv->dma_done); |
312 | 408 | ||
313 | /* enable DMA and error IRQs */ | 409 | /* zynq_step_dma will turn on interrupts */ |
314 | zynq_fpga_unmask_irqs(priv); | 410 | spin_lock_irqsave(&priv->dma_lock, flags); |
411 | priv->dma_elm = 0; | ||
412 | priv->cur_sg = sgt->sgl; | ||
413 | zynq_step_dma(priv); | ||
414 | spin_unlock_irqrestore(&priv->dma_lock, flags); | ||
315 | 415 | ||
316 | /* the +1 in the src addr is used to hold off on DMA_DONE IRQ | 416 | timeout = wait_for_completion_timeout(&priv->dma_done, |
317 | * until both AXI and PCAP are done ... | 417 | msecs_to_jiffies(DMA_TIMEOUT_MS)); |
318 | */ | ||
319 | zynq_fpga_write(priv, DMA_SRC_ADDR_OFFSET, (u32)(dma_addr) + 1); | ||
320 | zynq_fpga_write(priv, DMA_DST_ADDR_OFFSET, (u32)DMA_INVALID_ADDRESS); | ||
321 | 418 | ||
322 | /* convert #bytes to #words */ | 419 | spin_lock_irqsave(&priv->dma_lock, flags); |
323 | transfer_length = (count + 3) / 4; | 420 | zynq_fpga_set_irq(priv, 0); |
421 | priv->cur_sg = NULL; | ||
422 | spin_unlock_irqrestore(&priv->dma_lock, flags); | ||
324 | 423 | ||
325 | zynq_fpga_write(priv, DMA_SRC_LEN_OFFSET, transfer_length); | 424 | intr_status = zynq_fpga_read(priv, INT_STS_OFFSET); |
326 | zynq_fpga_write(priv, DMA_DEST_LEN_OFFSET, 0); | 425 | zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK); |
327 | 426 | ||
328 | wait_for_completion(&priv->dma_done); | 427 | /* There doesn't seem to be a way to force cancel any DMA, so if |
428 | * something went wrong we are relying on the hardware to have halted | ||
429 | * the DMA before we get here, if there was we could use | ||
430 | * wait_for_completion_interruptible too. | ||
431 | */ | ||
329 | 432 | ||
330 | intr_status = zynq_fpga_read(priv, INT_STS_OFFSET); | 433 | if (intr_status & IXR_ERROR_FLAGS_MASK) { |
331 | zynq_fpga_write(priv, INT_STS_OFFSET, intr_status); | 434 | why = "DMA reported error"; |
435 | err = -EIO; | ||
436 | goto out_report; | ||
437 | } | ||
332 | 438 | ||
333 | if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) { | 439 | if (priv->cur_sg || |
334 | dev_err(priv->dev, "Error configuring FPGA"); | 440 | !((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) { |
335 | err = -EFAULT; | 441 | if (timeout == 0) |
442 | why = "DMA timed out"; | ||
443 | else | ||
444 | why = "DMA did not complete"; | ||
445 | err = -EIO; | ||
446 | goto out_report; | ||
336 | } | 447 | } |
337 | 448 | ||
449 | err = 0; | ||
450 | goto out_clk; | ||
451 | |||
452 | out_report: | ||
453 | dev_err(&mgr->dev, | ||
454 | "%s: INT_STS:0x%x CTRL:0x%x LOCK:0x%x INT_MASK:0x%x STATUS:0x%x MCTRL:0x%x\n", | ||
455 | why, | ||
456 | intr_status, | ||
457 | zynq_fpga_read(priv, CTRL_OFFSET), | ||
458 | zynq_fpga_read(priv, LOCK_OFFSET), | ||
459 | zynq_fpga_read(priv, INT_MASK_OFFSET), | ||
460 | zynq_fpga_read(priv, STATUS_OFFSET), | ||
461 | zynq_fpga_read(priv, MCTRL_OFFSET)); | ||
462 | |||
463 | out_clk: | ||
338 | clk_disable(priv->clk); | 464 | clk_disable(priv->clk); |
339 | 465 | ||
340 | out_free: | 466 | out_free: |
341 | dma_free_coherent(priv->dev, in_count, kbuf, dma_addr); | 467 | dma_unmap_sg(mgr->dev.parent, sgt->sgl, sgt->nents, DMA_TO_DEVICE); |
342 | |||
343 | return err; | 468 | return err; |
344 | } | 469 | } |
345 | 470 | ||
346 | static int zynq_fpga_ops_write_complete(struct fpga_manager *mgr, u32 flags) | 471 | static int zynq_fpga_ops_write_complete(struct fpga_manager *mgr, |
472 | struct fpga_image_info *info) | ||
347 | { | 473 | { |
348 | struct zynq_fpga_priv *priv = mgr->priv; | 474 | struct zynq_fpga_priv *priv = mgr->priv; |
349 | int err; | 475 | int err; |
@@ -364,7 +490,7 @@ static int zynq_fpga_ops_write_complete(struct fpga_manager *mgr, u32 flags) | |||
364 | return err; | 490 | return err; |
365 | 491 | ||
366 | /* for the partial reconfig case we didn't touch the level shifters */ | 492 | /* for the partial reconfig case we didn't touch the level shifters */ |
367 | if (!(flags & FPGA_MGR_PARTIAL_RECONFIG)) { | 493 | if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) { |
368 | /* enable level shifters from PL to PS */ | 494 | /* enable level shifters from PL to PS */ |
369 | regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET, | 495 | regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET, |
370 | LVL_SHFTR_ENABLE_PL_TO_PS); | 496 | LVL_SHFTR_ENABLE_PL_TO_PS); |
@@ -399,9 +525,10 @@ static enum fpga_mgr_states zynq_fpga_ops_state(struct fpga_manager *mgr) | |||
399 | } | 525 | } |
400 | 526 | ||
401 | static const struct fpga_manager_ops zynq_fpga_ops = { | 527 | static const struct fpga_manager_ops zynq_fpga_ops = { |
528 | .initial_header_size = 128, | ||
402 | .state = zynq_fpga_ops_state, | 529 | .state = zynq_fpga_ops_state, |
403 | .write_init = zynq_fpga_ops_write_init, | 530 | .write_init = zynq_fpga_ops_write_init, |
404 | .write = zynq_fpga_ops_write, | 531 | .write_sg = zynq_fpga_ops_write, |
405 | .write_complete = zynq_fpga_ops_write_complete, | 532 | .write_complete = zynq_fpga_ops_write_complete, |
406 | }; | 533 | }; |
407 | 534 | ||
@@ -415,8 +542,7 @@ static int zynq_fpga_probe(struct platform_device *pdev) | |||
415 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | 542 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
416 | if (!priv) | 543 | if (!priv) |
417 | return -ENOMEM; | 544 | return -ENOMEM; |
418 | 545 | spin_lock_init(&priv->dma_lock); | |
419 | priv->dev = dev; | ||
420 | 546 | ||
421 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 547 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
422 | priv->io_base = devm_ioremap_resource(dev, res); | 548 | priv->io_base = devm_ioremap_resource(dev, res); |
@@ -426,7 +552,7 @@ static int zynq_fpga_probe(struct platform_device *pdev) | |||
426 | priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node, | 552 | priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node, |
427 | "syscon"); | 553 | "syscon"); |
428 | if (IS_ERR(priv->slcr)) { | 554 | if (IS_ERR(priv->slcr)) { |
429 | dev_err(dev, "unable to get zynq-slcr regmap"); | 555 | dev_err(dev, "unable to get zynq-slcr regmap\n"); |
430 | return PTR_ERR(priv->slcr); | 556 | return PTR_ERR(priv->slcr); |
431 | } | 557 | } |
432 | 558 | ||
@@ -434,38 +560,41 @@ static int zynq_fpga_probe(struct platform_device *pdev) | |||
434 | 560 | ||
435 | priv->irq = platform_get_irq(pdev, 0); | 561 | priv->irq = platform_get_irq(pdev, 0); |
436 | if (priv->irq < 0) { | 562 | if (priv->irq < 0) { |
437 | dev_err(dev, "No IRQ available"); | 563 | dev_err(dev, "No IRQ available\n"); |
438 | return priv->irq; | 564 | return priv->irq; |
439 | } | 565 | } |
440 | 566 | ||
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"); | 567 | priv->clk = devm_clk_get(dev, "ref_clk"); |
449 | if (IS_ERR(priv->clk)) { | 568 | if (IS_ERR(priv->clk)) { |
450 | dev_err(dev, "input clock not found"); | 569 | dev_err(dev, "input clock not found\n"); |
451 | return PTR_ERR(priv->clk); | 570 | return PTR_ERR(priv->clk); |
452 | } | 571 | } |
453 | 572 | ||
454 | err = clk_prepare_enable(priv->clk); | 573 | err = clk_prepare_enable(priv->clk); |
455 | if (err) { | 574 | if (err) { |
456 | dev_err(dev, "unable to enable clock"); | 575 | dev_err(dev, "unable to enable clock\n"); |
457 | return err; | 576 | return err; |
458 | } | 577 | } |
459 | 578 | ||
460 | /* unlock the device */ | 579 | /* unlock the device */ |
461 | zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK); | 580 | zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK); |
462 | 581 | ||
582 | zynq_fpga_set_irq(priv, 0); | ||
583 | zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK); | ||
584 | err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0, dev_name(dev), | ||
585 | priv); | ||
586 | if (err) { | ||
587 | dev_err(dev, "unable to request IRQ\n"); | ||
588 | clk_disable_unprepare(priv->clk); | ||
589 | return err; | ||
590 | } | ||
591 | |||
463 | clk_disable(priv->clk); | 592 | clk_disable(priv->clk); |
464 | 593 | ||
465 | err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager", | 594 | err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager", |
466 | &zynq_fpga_ops, priv); | 595 | &zynq_fpga_ops, priv); |
467 | if (err) { | 596 | if (err) { |
468 | dev_err(dev, "unable to register FPGA manager"); | 597 | dev_err(dev, "unable to register FPGA manager\n"); |
469 | clk_unprepare(priv->clk); | 598 | clk_unprepare(priv->clk); |
470 | return err; | 599 | return err; |
471 | } | 600 | } |