aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/fpga
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/fpga')
-rw-r--r--drivers/fpga/Kconfig20
-rw-r--r--drivers/fpga/Makefile2
-rw-r--r--drivers/fpga/altera-cvp.c500
-rw-r--r--drivers/fpga/altera-hps2fpga.c12
-rw-r--r--drivers/fpga/altera-ps-spi.c308
-rw-r--r--drivers/fpga/fpga-region.c4
6 files changed, 835 insertions, 11 deletions
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 161ba9dccede..ad5448f718b3 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -2,9 +2,7 @@
2# FPGA framework configuration 2# FPGA framework configuration
3# 3#
4 4
5menu "FPGA Configuration Support" 5menuconfig FPGA
6
7config FPGA
8 tristate "FPGA Configuration Framework" 6 tristate "FPGA Configuration Framework"
9 help 7 help
10 Say Y here if you want support for configuring FPGAs from the 8 Say Y here if you want support for configuring FPGAs from the
@@ -26,6 +24,20 @@ config FPGA_MGR_ICE40_SPI
26 help 24 help
27 FPGA manager driver support for Lattice iCE40 FPGAs over SPI. 25 FPGA manager driver support for Lattice iCE40 FPGAs over SPI.
28 26
27config FPGA_MGR_ALTERA_CVP
28 tristate "Altera Arria-V/Cyclone-V/Stratix-V CvP FPGA Manager"
29 depends on PCI
30 help
31 FPGA manager driver support for Arria-V, Cyclone-V, Stratix-V
32 and Arria 10 Altera FPGAs using the CvP interface over PCIe.
33
34config FPGA_MGR_ALTERA_PS_SPI
35 tristate "Altera FPGA Passive Serial over SPI"
36 depends on SPI
37 help
38 FPGA manager driver support for Altera Arria/Cyclone/Stratix
39 using the passive serial interface over SPI.
40
29config FPGA_MGR_SOCFPGA 41config FPGA_MGR_SOCFPGA
30 tristate "Altera SOCFPGA FPGA Manager" 42 tristate "Altera SOCFPGA FPGA Manager"
31 depends on ARCH_SOCFPGA || COMPILE_TEST 43 depends on ARCH_SOCFPGA || COMPILE_TEST
@@ -106,5 +118,3 @@ config XILINX_PR_DECOUPLER
106 being reprogrammed during partial reconfig. 118 being reprogrammed during partial reconfig.
107 119
108endif # FPGA 120endif # FPGA
109
110endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 2a4f0218145c..e09895f0525b 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -6,6 +6,8 @@
6obj-$(CONFIG_FPGA) += fpga-mgr.o 6obj-$(CONFIG_FPGA) += fpga-mgr.o
7 7
8# FPGA Manager Drivers 8# FPGA Manager Drivers
9obj-$(CONFIG_FPGA_MGR_ALTERA_CVP) += altera-cvp.o
10obj-$(CONFIG_FPGA_MGR_ALTERA_PS_SPI) += altera-ps-spi.o
9obj-$(CONFIG_FPGA_MGR_ICE40_SPI) += ice40-spi.o 11obj-$(CONFIG_FPGA_MGR_ICE40_SPI) += ice40-spi.o
10obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o 12obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
11obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o 13obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o
diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
new file mode 100644
index 000000000000..08629ee69d11
--- /dev/null
+++ b/drivers/fpga/altera-cvp.c
@@ -0,0 +1,500 @@
1/*
2 * FPGA Manager Driver for Altera Arria/Cyclone/Stratix CvP
3 *
4 * Copyright (C) 2017 DENX Software Engineering
5 *
6 * Anatolij Gustschin <agust@denx.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * Manage Altera FPGA firmware using PCIe CvP.
18 * Firmware must be in binary "rbf" format.
19 */
20
21#include <linux/delay.h>
22#include <linux/device.h>
23#include <linux/fpga/fpga-mgr.h>
24#include <linux/module.h>
25#include <linux/pci.h>
26#include <linux/sizes.h>
27
28#define CVP_BAR 0 /* BAR used for data transfer in memory mode */
29#define CVP_DUMMY_WR 244 /* dummy writes to clear CvP state machine */
30#define TIMEOUT_US 2000 /* CVP STATUS timeout for USERMODE polling */
31
32/* Vendor Specific Extended Capability Registers */
33#define VSE_PCIE_EXT_CAP_ID 0x200
34#define VSE_PCIE_EXT_CAP_ID_VAL 0x000b /* 16bit */
35
36#define VSE_CVP_STATUS 0x21c /* 32bit */
37#define VSE_CVP_STATUS_CFG_RDY BIT(18) /* CVP_CONFIG_READY */
38#define VSE_CVP_STATUS_CFG_ERR BIT(19) /* CVP_CONFIG_ERROR */
39#define VSE_CVP_STATUS_CVP_EN BIT(20) /* ctrl block is enabling CVP */
40#define VSE_CVP_STATUS_USERMODE BIT(21) /* USERMODE */
41#define VSE_CVP_STATUS_CFG_DONE BIT(23) /* CVP_CONFIG_DONE */
42#define VSE_CVP_STATUS_PLD_CLK_IN_USE BIT(24) /* PLD_CLK_IN_USE */
43
44#define VSE_CVP_MODE_CTRL 0x220 /* 32bit */
45#define VSE_CVP_MODE_CTRL_CVP_MODE BIT(0) /* CVP (1) or normal mode (0) */
46#define VSE_CVP_MODE_CTRL_HIP_CLK_SEL BIT(1) /* PMA (1) or fabric clock (0) */
47#define VSE_CVP_MODE_CTRL_NUMCLKS_OFF 8 /* NUMCLKS bits offset */
48#define VSE_CVP_MODE_CTRL_NUMCLKS_MASK GENMASK(15, 8)
49
50#define VSE_CVP_DATA 0x228 /* 32bit */
51#define VSE_CVP_PROG_CTRL 0x22c /* 32bit */
52#define VSE_CVP_PROG_CTRL_CONFIG BIT(0)
53#define VSE_CVP_PROG_CTRL_START_XFER BIT(1)
54
55#define VSE_UNCOR_ERR_STATUS 0x234 /* 32bit */
56#define VSE_UNCOR_ERR_CVP_CFG_ERR BIT(5) /* CVP_CONFIG_ERROR_LATCHED */
57
58#define DRV_NAME "altera-cvp"
59#define ALTERA_CVP_MGR_NAME "Altera CvP FPGA Manager"
60
61/* Optional CvP config error status check for debugging */
62static bool altera_cvp_chkcfg;
63
64struct altera_cvp_conf {
65 struct fpga_manager *mgr;
66 struct pci_dev *pci_dev;
67 void __iomem *map;
68 void (*write_data)(struct altera_cvp_conf *, u32);
69 char mgr_name[64];
70 u8 numclks;
71};
72
73static enum fpga_mgr_states altera_cvp_state(struct fpga_manager *mgr)
74{
75 struct altera_cvp_conf *conf = mgr->priv;
76 u32 status;
77
78 pci_read_config_dword(conf->pci_dev, VSE_CVP_STATUS, &status);
79
80 if (status & VSE_CVP_STATUS_CFG_DONE)
81 return FPGA_MGR_STATE_OPERATING;
82
83 if (status & VSE_CVP_STATUS_CVP_EN)
84 return FPGA_MGR_STATE_POWER_UP;
85
86 return FPGA_MGR_STATE_UNKNOWN;
87}
88
89static void altera_cvp_write_data_iomem(struct altera_cvp_conf *conf, u32 val)
90{
91 writel(val, conf->map);
92}
93
94static void altera_cvp_write_data_config(struct altera_cvp_conf *conf, u32 val)
95{
96 pci_write_config_dword(conf->pci_dev, VSE_CVP_DATA, val);
97}
98
99/* switches between CvP clock and internal clock */
100static void altera_cvp_dummy_write(struct altera_cvp_conf *conf)
101{
102 unsigned int i;
103 u32 val;
104
105 /* set 1 CVP clock cycle for every CVP Data Register Write */
106 pci_read_config_dword(conf->pci_dev, VSE_CVP_MODE_CTRL, &val);
107 val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK;
108 val |= 1 << VSE_CVP_MODE_CTRL_NUMCLKS_OFF;
109 pci_write_config_dword(conf->pci_dev, VSE_CVP_MODE_CTRL, val);
110
111 for (i = 0; i < CVP_DUMMY_WR; i++)
112 conf->write_data(conf, 0); /* dummy data, could be any value */
113}
114
115static int altera_cvp_wait_status(struct altera_cvp_conf *conf, u32 status_mask,
116 u32 status_val, int timeout_us)
117{
118 unsigned int retries;
119 u32 val;
120
121 retries = timeout_us / 10;
122 if (timeout_us % 10)
123 retries++;
124
125 do {
126 pci_read_config_dword(conf->pci_dev, VSE_CVP_STATUS, &val);
127 if ((val & status_mask) == status_val)
128 return 0;
129
130 /* use small usleep value to re-check and break early */
131 usleep_range(10, 11);
132 } while (--retries);
133
134 return -ETIMEDOUT;
135}
136
137static int altera_cvp_teardown(struct fpga_manager *mgr,
138 struct fpga_image_info *info)
139{
140 struct altera_cvp_conf *conf = mgr->priv;
141 struct pci_dev *pdev = conf->pci_dev;
142 int ret;
143 u32 val;
144
145 /* STEP 12 - reset START_XFER bit */
146 pci_read_config_dword(pdev, VSE_CVP_PROG_CTRL, &val);
147 val &= ~VSE_CVP_PROG_CTRL_START_XFER;
148 pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val);
149
150 /* STEP 13 - reset CVP_CONFIG bit */
151 val &= ~VSE_CVP_PROG_CTRL_CONFIG;
152 pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val);
153
154 /*
155 * STEP 14
156 * - set CVP_NUMCLKS to 1 and then issue CVP_DUMMY_WR dummy
157 * writes to the HIP
158 */
159 altera_cvp_dummy_write(conf); /* from CVP clock to internal clock */
160
161 /* STEP 15 - poll CVP_CONFIG_READY bit for 0 with 10us timeout */
162 ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY, 0, 10);
163 if (ret)
164 dev_err(&mgr->dev, "CFG_RDY == 0 timeout\n");
165
166 return ret;
167}
168
169static int altera_cvp_write_init(struct fpga_manager *mgr,
170 struct fpga_image_info *info,
171 const char *buf, size_t count)
172{
173 struct altera_cvp_conf *conf = mgr->priv;
174 struct pci_dev *pdev = conf->pci_dev;
175 u32 iflags, val;
176 int ret;
177
178 iflags = info ? info->flags : 0;
179
180 if (iflags & FPGA_MGR_PARTIAL_RECONFIG) {
181 dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
182 return -EINVAL;
183 }
184
185 /* Determine allowed clock to data ratio */
186 if (iflags & FPGA_MGR_COMPRESSED_BITSTREAM)
187 conf->numclks = 8; /* ratio for all compressed images */
188 else if (iflags & FPGA_MGR_ENCRYPTED_BITSTREAM)
189 conf->numclks = 4; /* for uncompressed and encrypted images */
190 else
191 conf->numclks = 1; /* for uncompressed and unencrypted images */
192
193 /* STEP 1 - read CVP status and check CVP_EN flag */
194 pci_read_config_dword(pdev, VSE_CVP_STATUS, &val);
195 if (!(val & VSE_CVP_STATUS_CVP_EN)) {
196 dev_err(&mgr->dev, "CVP mode off: 0x%04x\n", val);
197 return -ENODEV;
198 }
199
200 if (val & VSE_CVP_STATUS_CFG_RDY) {
201 dev_warn(&mgr->dev, "CvP already started, teardown first\n");
202 ret = altera_cvp_teardown(mgr, info);
203 if (ret)
204 return ret;
205 }
206
207 /*
208 * STEP 2
209 * - set HIP_CLK_SEL and CVP_MODE (must be set in the order mentioned)
210 */
211 /* switch from fabric to PMA clock */
212 pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val);
213 val |= VSE_CVP_MODE_CTRL_HIP_CLK_SEL;
214 pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val);
215
216 /* set CVP mode */
217 pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val);
218 val |= VSE_CVP_MODE_CTRL_CVP_MODE;
219 pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val);
220
221 /*
222 * STEP 3
223 * - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP
224 */
225 altera_cvp_dummy_write(conf);
226
227 /* STEP 4 - set CVP_CONFIG bit */
228 pci_read_config_dword(pdev, VSE_CVP_PROG_CTRL, &val);
229 /* request control block to begin transfer using CVP */
230 val |= VSE_CVP_PROG_CTRL_CONFIG;
231 pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val);
232
233 /* STEP 5 - poll CVP_CONFIG READY for 1 with 10us timeout */
234 ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY,
235 VSE_CVP_STATUS_CFG_RDY, 10);
236 if (ret) {
237 dev_warn(&mgr->dev, "CFG_RDY == 1 timeout\n");
238 return ret;
239 }
240
241 /*
242 * STEP 6
243 * - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP
244 */
245 altera_cvp_dummy_write(conf);
246
247 /* STEP 7 - set START_XFER */
248 pci_read_config_dword(pdev, VSE_CVP_PROG_CTRL, &val);
249 val |= VSE_CVP_PROG_CTRL_START_XFER;
250 pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val);
251
252 /* STEP 8 - start transfer (set CVP_NUMCLKS for bitstream) */
253 pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val);
254 val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK;
255 val |= conf->numclks << VSE_CVP_MODE_CTRL_NUMCLKS_OFF;
256 pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val);
257
258 return 0;
259}
260
261static inline int altera_cvp_chk_error(struct fpga_manager *mgr, size_t bytes)
262{
263 struct altera_cvp_conf *conf = mgr->priv;
264 u32 val;
265
266 /* STEP 10 (optional) - check CVP_CONFIG_ERROR flag */
267 pci_read_config_dword(conf->pci_dev, VSE_CVP_STATUS, &val);
268 if (val & VSE_CVP_STATUS_CFG_ERR) {
269 dev_err(&mgr->dev, "CVP_CONFIG_ERROR after %zu bytes!\n",
270 bytes);
271 return -EPROTO;
272 }
273 return 0;
274}
275
276static int altera_cvp_write(struct fpga_manager *mgr, const char *buf,
277 size_t count)
278{
279 struct altera_cvp_conf *conf = mgr->priv;
280 const u32 *data;
281 size_t done, remaining;
282 int status = 0;
283 u32 mask;
284
285 /* STEP 9 - write 32-bit data from RBF file to CVP data register */
286 data = (u32 *)buf;
287 remaining = count;
288 done = 0;
289
290 while (remaining >= 4) {
291 conf->write_data(conf, *data++);
292 done += 4;
293 remaining -= 4;
294
295 /*
296 * STEP 10 (optional) and STEP 11
297 * - check error flag
298 * - loop until data transfer completed
299 * Config images can be huge (more than 40 MiB), so
300 * only check after a new 4k data block has been written.
301 * This reduces the number of checks and speeds up the
302 * configuration process.
303 */
304 if (altera_cvp_chkcfg && !(done % SZ_4K)) {
305 status = altera_cvp_chk_error(mgr, done);
306 if (status < 0)
307 return status;
308 }
309 }
310
311 /* write up to 3 trailing bytes, if any */
312 mask = BIT(remaining * 8) - 1;
313 if (mask)
314 conf->write_data(conf, *data & mask);
315
316 if (altera_cvp_chkcfg)
317 status = altera_cvp_chk_error(mgr, count);
318
319 return status;
320}
321
322static int altera_cvp_write_complete(struct fpga_manager *mgr,
323 struct fpga_image_info *info)
324{
325 struct altera_cvp_conf *conf = mgr->priv;
326 struct pci_dev *pdev = conf->pci_dev;
327 int ret;
328 u32 mask;
329 u32 val;
330
331 ret = altera_cvp_teardown(mgr, info);
332 if (ret)
333 return ret;
334
335 /* STEP 16 - check CVP_CONFIG_ERROR_LATCHED bit */
336 pci_read_config_dword(pdev, VSE_UNCOR_ERR_STATUS, &val);
337 if (val & VSE_UNCOR_ERR_CVP_CFG_ERR) {
338 dev_err(&mgr->dev, "detected CVP_CONFIG_ERROR_LATCHED!\n");
339 return -EPROTO;
340 }
341
342 /* STEP 17 - reset CVP_MODE and HIP_CLK_SEL bit */
343 pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val);
344 val &= ~VSE_CVP_MODE_CTRL_HIP_CLK_SEL;
345 val &= ~VSE_CVP_MODE_CTRL_CVP_MODE;
346 pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val);
347
348 /* STEP 18 - poll PLD_CLK_IN_USE and USER_MODE bits */
349 mask = VSE_CVP_STATUS_PLD_CLK_IN_USE | VSE_CVP_STATUS_USERMODE;
350 ret = altera_cvp_wait_status(conf, mask, mask, TIMEOUT_US);
351 if (ret)
352 dev_err(&mgr->dev, "PLD_CLK_IN_USE|USERMODE timeout\n");
353
354 return ret;
355}
356
357static const struct fpga_manager_ops altera_cvp_ops = {
358 .state = altera_cvp_state,
359 .write_init = altera_cvp_write_init,
360 .write = altera_cvp_write,
361 .write_complete = altera_cvp_write_complete,
362};
363
364static ssize_t show_chkcfg(struct device_driver *dev, char *buf)
365{
366 return snprintf(buf, 3, "%d\n", altera_cvp_chkcfg);
367}
368
369static ssize_t store_chkcfg(struct device_driver *drv, const char *buf,
370 size_t count)
371{
372 int ret;
373
374 ret = kstrtobool(buf, &altera_cvp_chkcfg);
375 if (ret)
376 return ret;
377
378 return count;
379}
380
381static DRIVER_ATTR(chkcfg, 0600, show_chkcfg, store_chkcfg);
382
383static int altera_cvp_probe(struct pci_dev *pdev,
384 const struct pci_device_id *dev_id);
385static void altera_cvp_remove(struct pci_dev *pdev);
386
387#define PCI_VENDOR_ID_ALTERA 0x1172
388
389static struct pci_device_id altera_cvp_id_tbl[] = {
390 { PCI_VDEVICE(ALTERA, PCI_ANY_ID) },
391 { }
392};
393MODULE_DEVICE_TABLE(pci, altera_cvp_id_tbl);
394
395static struct pci_driver altera_cvp_driver = {
396 .name = DRV_NAME,
397 .id_table = altera_cvp_id_tbl,
398 .probe = altera_cvp_probe,
399 .remove = altera_cvp_remove,
400};
401
402static int altera_cvp_probe(struct pci_dev *pdev,
403 const struct pci_device_id *dev_id)
404{
405 struct altera_cvp_conf *conf;
406 u16 cmd, val;
407 int ret;
408
409 /*
410 * First check if this is the expected FPGA device. PCI config
411 * space access works without enabling the PCI device, memory
412 * space access is enabled further down.
413 */
414 pci_read_config_word(pdev, VSE_PCIE_EXT_CAP_ID, &val);
415 if (val != VSE_PCIE_EXT_CAP_ID_VAL) {
416 dev_err(&pdev->dev, "Wrong EXT_CAP_ID value 0x%x\n", val);
417 return -ENODEV;
418 }
419
420 conf = devm_kzalloc(&pdev->dev, sizeof(*conf), GFP_KERNEL);
421 if (!conf)
422 return -ENOMEM;
423
424 /*
425 * Enable memory BAR access. We cannot use pci_enable_device() here
426 * because it will make the driver unusable with FPGA devices that
427 * have additional big IOMEM resources (e.g. 4GiB BARs) on 32-bit
428 * platform. Such BARs will not have an assigned address range and
429 * pci_enable_device() will fail, complaining about not claimed BAR,
430 * even if the concerned BAR is not needed for FPGA configuration
431 * at all. Thus, enable the device via PCI config space command.
432 */
433 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
434 if (!(cmd & PCI_COMMAND_MEMORY)) {
435 cmd |= PCI_COMMAND_MEMORY;
436 pci_write_config_word(pdev, PCI_COMMAND, cmd);
437 }
438
439 ret = pci_request_region(pdev, CVP_BAR, "CVP");
440 if (ret) {
441 dev_err(&pdev->dev, "Requesting CVP BAR region failed\n");
442 goto err_disable;
443 }
444
445 conf->pci_dev = pdev;
446 conf->write_data = altera_cvp_write_data_iomem;
447
448 conf->map = pci_iomap(pdev, CVP_BAR, 0);
449 if (!conf->map) {
450 dev_warn(&pdev->dev, "Mapping CVP BAR failed\n");
451 conf->write_data = altera_cvp_write_data_config;
452 }
453
454 snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s @%s",
455 ALTERA_CVP_MGR_NAME, pci_name(pdev));
456
457 ret = fpga_mgr_register(&pdev->dev, conf->mgr_name,
458 &altera_cvp_ops, conf);
459 if (ret)
460 goto err_unmap;
461
462 ret = driver_create_file(&altera_cvp_driver.driver,
463 &driver_attr_chkcfg);
464 if (ret) {
465 dev_err(&pdev->dev, "Can't create sysfs chkcfg file\n");
466 fpga_mgr_unregister(&pdev->dev);
467 goto err_unmap;
468 }
469
470 return 0;
471
472err_unmap:
473 pci_iounmap(pdev, conf->map);
474 pci_release_region(pdev, CVP_BAR);
475err_disable:
476 cmd &= ~PCI_COMMAND_MEMORY;
477 pci_write_config_word(pdev, PCI_COMMAND, cmd);
478 return ret;
479}
480
481static void altera_cvp_remove(struct pci_dev *pdev)
482{
483 struct fpga_manager *mgr = pci_get_drvdata(pdev);
484 struct altera_cvp_conf *conf = mgr->priv;
485 u16 cmd;
486
487 driver_remove_file(&altera_cvp_driver.driver, &driver_attr_chkcfg);
488 fpga_mgr_unregister(&pdev->dev);
489 pci_iounmap(pdev, conf->map);
490 pci_release_region(pdev, CVP_BAR);
491 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
492 cmd &= ~PCI_COMMAND_MEMORY;
493 pci_write_config_word(pdev, PCI_COMMAND, cmd);
494}
495
496module_pci_driver(altera_cvp_driver);
497
498MODULE_LICENSE("GPL v2");
499MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
500MODULE_DESCRIPTION("Module to load Altera FPGA over CvP");
diff --git a/drivers/fpga/altera-hps2fpga.c b/drivers/fpga/altera-hps2fpga.c
index 3066b805f2d0..406d2f10741f 100644
--- a/drivers/fpga/altera-hps2fpga.c
+++ b/drivers/fpga/altera-hps2fpga.c
@@ -66,7 +66,7 @@ static int alt_hps2fpga_enable_show(struct fpga_bridge *bridge)
66 66
67/* The L3 REMAP register is write only, so keep a cached value. */ 67/* The L3 REMAP register is write only, so keep a cached value. */
68static unsigned int l3_remap_shadow; 68static unsigned int l3_remap_shadow;
69static spinlock_t l3_remap_lock; 69static DEFINE_SPINLOCK(l3_remap_lock);
70 70
71static int _alt_hps2fpga_enable_set(struct altera_hps2fpga_data *priv, 71static int _alt_hps2fpga_enable_set(struct altera_hps2fpga_data *priv,
72 bool enable) 72 bool enable)
@@ -143,9 +143,15 @@ static int alt_fpga_bridge_probe(struct platform_device *pdev)
143 int ret; 143 int ret;
144 144
145 of_id = of_match_device(altera_fpga_of_match, dev); 145 of_id = of_match_device(altera_fpga_of_match, dev);
146 if (!of_id) {
147 dev_err(dev, "failed to match device\n");
148 return -ENODEV;
149 }
150
146 priv = (struct altera_hps2fpga_data *)of_id->data; 151 priv = (struct altera_hps2fpga_data *)of_id->data;
147 152
148 priv->bridge_reset = of_reset_control_get_by_index(dev->of_node, 0); 153 priv->bridge_reset = of_reset_control_get_exclusive_by_index(dev->of_node,
154 0);
149 if (IS_ERR(priv->bridge_reset)) { 155 if (IS_ERR(priv->bridge_reset)) {
150 dev_err(dev, "Could not get %s reset control\n", priv->name); 156 dev_err(dev, "Could not get %s reset control\n", priv->name);
151 return PTR_ERR(priv->bridge_reset); 157 return PTR_ERR(priv->bridge_reset);
@@ -171,8 +177,6 @@ static int alt_fpga_bridge_probe(struct platform_device *pdev)
171 return -EBUSY; 177 return -EBUSY;
172 } 178 }
173 179
174 spin_lock_init(&l3_remap_lock);
175
176 if (!of_property_read_u32(dev->of_node, "bridge-enable", &enable)) { 180 if (!of_property_read_u32(dev->of_node, "bridge-enable", &enable)) {
177 if (enable > 1) { 181 if (enable > 1) {
178 dev_warn(dev, "invalid bridge-enable %u > 1\n", enable); 182 dev_warn(dev, "invalid bridge-enable %u > 1\n", enable);
diff --git a/drivers/fpga/altera-ps-spi.c b/drivers/fpga/altera-ps-spi.c
new file mode 100644
index 000000000000..14f14efdf0d5
--- /dev/null
+++ b/drivers/fpga/altera-ps-spi.c
@@ -0,0 +1,308 @@
1/*
2 * Altera Passive Serial SPI Driver
3 *
4 * Copyright (c) 2017 United Western Technologies, Corporation
5 *
6 * Joshua Clayton <stillcompiling@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * Manage Altera FPGA firmware that is loaded over SPI using the passive
13 * serial configuration method.
14 * Firmware must be in binary "rbf" format.
15 * Works on Arria 10, Cyclone V and Stratix V. Should work on Cyclone series.
16 * May work on other Altera FPGAs.
17 */
18
19#include <linux/bitrev.h>
20#include <linux/delay.h>
21#include <linux/fpga/fpga-mgr.h>
22#include <linux/gpio/consumer.h>
23#include <linux/module.h>
24#include <linux/of_gpio.h>
25#include <linux/of_device.h>
26#include <linux/spi/spi.h>
27#include <linux/sizes.h>
28
29enum altera_ps_devtype {
30 CYCLONE5,
31 ARRIA10,
32};
33
34struct altera_ps_data {
35 enum altera_ps_devtype devtype;
36 int status_wait_min_us;
37 int status_wait_max_us;
38 int t_cfg_us;
39 int t_st2ck_us;
40};
41
42struct altera_ps_conf {
43 struct gpio_desc *config;
44 struct gpio_desc *confd;
45 struct gpio_desc *status;
46 struct spi_device *spi;
47 const struct altera_ps_data *data;
48 u32 info_flags;
49 char mgr_name[64];
50};
51
52/* | Arria 10 | Cyclone5 | Stratix5 |
53 * t_CF2ST0 | [; 600] | [; 600] | [; 600] |ns
54 * t_CFG | [2;] | [2;] | [2;] |µs
55 * t_STATUS | [268; 3000] | [268; 1506] | [268; 1506] |µs
56 * t_CF2ST1 | [; 3000] | [; 1506] | [; 1506] |µs
57 * t_CF2CK | [3010;] | [1506;] | [1506;] |µs
58 * t_ST2CK | [10;] | [2;] | [2;] |µs
59 * t_CD2UM | [175; 830] | [175; 437] | [175; 437] |µs
60 */
61static struct altera_ps_data c5_data = {
62 /* these values for Cyclone5 are compatible with Stratix5 */
63 .devtype = CYCLONE5,
64 .status_wait_min_us = 268,
65 .status_wait_max_us = 1506,
66 .t_cfg_us = 2,
67 .t_st2ck_us = 2,
68};
69
70static struct altera_ps_data a10_data = {
71 .devtype = ARRIA10,
72 .status_wait_min_us = 268, /* min(t_STATUS) */
73 .status_wait_max_us = 3000, /* max(t_CF2ST1) */
74 .t_cfg_us = 2, /* max { min(t_CFG), max(tCF2ST0) } */
75 .t_st2ck_us = 10, /* min(t_ST2CK) */
76};
77
78static const struct of_device_id of_ef_match[] = {
79 { .compatible = "altr,fpga-passive-serial", .data = &c5_data },
80 { .compatible = "altr,fpga-arria10-passive-serial", .data = &a10_data },
81 {}
82};
83MODULE_DEVICE_TABLE(of, of_ef_match);
84
85static enum fpga_mgr_states altera_ps_state(struct fpga_manager *mgr)
86{
87 struct altera_ps_conf *conf = mgr->priv;
88
89 if (gpiod_get_value_cansleep(conf->status))
90 return FPGA_MGR_STATE_RESET;
91
92 return FPGA_MGR_STATE_UNKNOWN;
93}
94
95static inline void altera_ps_delay(int delay_us)
96{
97 if (delay_us > 10)
98 usleep_range(delay_us, delay_us + 5);
99 else
100 udelay(delay_us);
101}
102
103static int altera_ps_write_init(struct fpga_manager *mgr,
104 struct fpga_image_info *info,
105 const char *buf, size_t count)
106{
107 struct altera_ps_conf *conf = mgr->priv;
108 int min, max, waits;
109 int i;
110
111 conf->info_flags = info->flags;
112
113 if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
114 dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
115 return -EINVAL;
116 }
117
118 gpiod_set_value_cansleep(conf->config, 1);
119
120 /* wait min reset pulse time */
121 altera_ps_delay(conf->data->t_cfg_us);
122
123 if (!gpiod_get_value_cansleep(conf->status)) {
124 dev_err(&mgr->dev, "Status pin failed to show a reset\n");
125 return -EIO;
126 }
127
128 gpiod_set_value_cansleep(conf->config, 0);
129
130 min = conf->data->status_wait_min_us;
131 max = conf->data->status_wait_max_us;
132 waits = max / min;
133 if (max % min)
134 waits++;
135
136 /* wait for max { max(t_STATUS), max(t_CF2ST1) } */
137 for (i = 0; i < waits; i++) {
138 usleep_range(min, min + 10);
139 if (!gpiod_get_value_cansleep(conf->status)) {
140 /* wait for min(t_ST2CK)*/
141 altera_ps_delay(conf->data->t_st2ck_us);
142 return 0;
143 }
144 }
145
146 dev_err(&mgr->dev, "Status pin not ready.\n");
147 return -EIO;
148}
149
150static void rev_buf(char *buf, size_t len)
151{
152 u32 *fw32 = (u32 *)buf;
153 size_t extra_bytes = (len & 0x03);
154 const u32 *fw_end = (u32 *)(buf + len - extra_bytes);
155
156 /* set buffer to lsb first */
157 while (fw32 < fw_end) {
158 *fw32 = bitrev8x4(*fw32);
159 fw32++;
160 }
161
162 if (extra_bytes) {
163 buf = (char *)fw_end;
164 while (extra_bytes) {
165 *buf = bitrev8(*buf);
166 buf++;
167 extra_bytes--;
168 }
169 }
170}
171
172static int altera_ps_write(struct fpga_manager *mgr, const char *buf,
173 size_t count)
174{
175 struct altera_ps_conf *conf = mgr->priv;
176 const char *fw_data = buf;
177 const char *fw_data_end = fw_data + count;
178
179 while (fw_data < fw_data_end) {
180 int ret;
181 size_t stride = min_t(size_t, fw_data_end - fw_data, SZ_4K);
182
183 if (!(conf->info_flags & FPGA_MGR_BITSTREAM_LSB_FIRST))
184 rev_buf((char *)fw_data, stride);
185
186 ret = spi_write(conf->spi, fw_data, stride);
187 if (ret) {
188 dev_err(&mgr->dev, "spi error in firmware write: %d\n",
189 ret);
190 return ret;
191 }
192 fw_data += stride;
193 }
194
195 return 0;
196}
197
198static int altera_ps_write_complete(struct fpga_manager *mgr,
199 struct fpga_image_info *info)
200{
201 struct altera_ps_conf *conf = mgr->priv;
202 const char dummy[] = {0};
203 int ret;
204
205 if (gpiod_get_value_cansleep(conf->status)) {
206 dev_err(&mgr->dev, "Error during configuration.\n");
207 return -EIO;
208 }
209
210 if (!IS_ERR(conf->confd)) {
211 if (!gpiod_get_raw_value_cansleep(conf->confd)) {
212 dev_err(&mgr->dev, "CONF_DONE is inactive!\n");
213 return -EIO;
214 }
215 }
216
217 /*
218 * After CONF_DONE goes high, send two additional falling edges on DCLK
219 * to begin initialization and enter user mode
220 */
221 ret = spi_write(conf->spi, dummy, 1);
222 if (ret) {
223 dev_err(&mgr->dev, "spi error during end sequence: %d\n", ret);
224 return ret;
225 }
226
227 return 0;
228}
229
230static const struct fpga_manager_ops altera_ps_ops = {
231 .state = altera_ps_state,
232 .write_init = altera_ps_write_init,
233 .write = altera_ps_write,
234 .write_complete = altera_ps_write_complete,
235};
236
237static int altera_ps_probe(struct spi_device *spi)
238{
239 struct altera_ps_conf *conf;
240 const struct of_device_id *of_id;
241
242 conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL);
243 if (!conf)
244 return -ENOMEM;
245
246 of_id = of_match_device(of_ef_match, &spi->dev);
247 if (!of_id)
248 return -ENODEV;
249
250 conf->data = of_id->data;
251 conf->spi = spi;
252 conf->config = devm_gpiod_get(&spi->dev, "nconfig", GPIOD_OUT_HIGH);
253 if (IS_ERR(conf->config)) {
254 dev_err(&spi->dev, "Failed to get config gpio: %ld\n",
255 PTR_ERR(conf->config));
256 return PTR_ERR(conf->config);
257 }
258
259 conf->status = devm_gpiod_get(&spi->dev, "nstat", GPIOD_IN);
260 if (IS_ERR(conf->status)) {
261 dev_err(&spi->dev, "Failed to get status gpio: %ld\n",
262 PTR_ERR(conf->status));
263 return PTR_ERR(conf->status);
264 }
265
266 conf->confd = devm_gpiod_get(&spi->dev, "confd", GPIOD_IN);
267 if (IS_ERR(conf->confd)) {
268 dev_warn(&spi->dev, "Not using confd gpio: %ld\n",
269 PTR_ERR(conf->confd));
270 }
271
272 /* Register manager with unique name */
273 snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s %s",
274 dev_driver_string(&spi->dev), dev_name(&spi->dev));
275
276 return fpga_mgr_register(&spi->dev, conf->mgr_name,
277 &altera_ps_ops, conf);
278}
279
280static int altera_ps_remove(struct spi_device *spi)
281{
282 fpga_mgr_unregister(&spi->dev);
283
284 return 0;
285}
286
287static const struct spi_device_id altera_ps_spi_ids[] = {
288 {"cyclone-ps-spi", 0},
289 {}
290};
291MODULE_DEVICE_TABLE(spi, altera_ps_spi_ids);
292
293static struct spi_driver altera_ps_driver = {
294 .driver = {
295 .name = "altera-ps-spi",
296 .owner = THIS_MODULE,
297 .of_match_table = of_match_ptr(of_ef_match),
298 },
299 .id_table = altera_ps_spi_ids,
300 .probe = altera_ps_probe,
301 .remove = altera_ps_remove,
302};
303
304module_spi_driver(altera_ps_driver)
305
306MODULE_LICENSE("GPL v2");
307MODULE_AUTHOR("Joshua Clayton <stillcompiling@gmail.com>");
308MODULE_DESCRIPTION("Module to load Altera FPGA firmware over SPI");
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 3b6b2f4182a1..d9ab7c75b14f 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -319,8 +319,8 @@ static int child_regions_with_firmware(struct device_node *overlay)
319 of_node_put(child_region); 319 of_node_put(child_region);
320 320
321 if (ret) 321 if (ret)
322 pr_err("firmware-name not allowed in child FPGA region: %s", 322 pr_err("firmware-name not allowed in child FPGA region: %pOF",
323 child_region->full_name); 323 child_region);
324 324
325 return ret; 325 return ret;
326} 326}