diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-12-01 15:05:53 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-12-01 15:05:53 -0500 |
commit | e073462966b26977b26937c5fc93b4fb24f04fef (patch) | |
tree | 49221ed9ebf8e42ad5d80897e91286250f215e4a | |
parent | 31114fa95bdb815f52f0cb0fad1260bd91007563 (diff) | |
parent | e499807737b75387bcc9d146927dc36a0b7e4cff (diff) |
Merge tag 'fpga-for-greg-20161129' of git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga into char-misc-next
Alan writes:
fpga: Updates for 4.10
These are:
* Add git url to MAINTAINERS
* Allow write_init to specify how much buffer it needs
* Fixes for ISR state in zynq fpga manager driver
* Other small fixes for zynq
* Add Altera SoCFPGA drivers for COMPILE_TEST
-rw-r--r-- | Documentation/fpga/fpga-mgr.txt | 5 | ||||
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | drivers/fpga/Kconfig | 5 | ||||
-rw-r--r-- | drivers/fpga/fpga-mgr.c | 6 | ||||
-rw-r--r-- | drivers/fpga/socfpga-a10.c | 1 | ||||
-rw-r--r-- | drivers/fpga/zynq-fpga.c | 46 | ||||
-rw-r--r-- | include/linux/fpga/fpga-mgr.h | 2 |
7 files changed, 38 insertions, 28 deletions
diff --git a/Documentation/fpga/fpga-mgr.txt b/Documentation/fpga/fpga-mgr.txt index 087924f2b20c..86ee5078fd03 100644 --- a/Documentation/fpga/fpga-mgr.txt +++ b/Documentation/fpga/fpga-mgr.txt | |||
@@ -169,7 +169,10 @@ The programming sequence is: | |||
169 | 2. .write (may be called once or multiple times) | 169 | 2. .write (may be called once or multiple times) |
170 | 3. .write_complete | 170 | 3. .write_complete |
171 | 171 | ||
172 | The .write_init function will prepare the FPGA to receive the image data. | 172 | The .write_init function will prepare the FPGA to receive the image data. The |
173 | buffer passed into .write_init will be atmost .initial_header_size bytes long, | ||
174 | if the whole bitstream is not immediately available then the core code will | ||
175 | buffer up at least this much before starting. | ||
173 | 176 | ||
174 | The .write function writes a buffer to the FPGA. The buffer may be contain the | 177 | The .write function writes a buffer to the FPGA. The buffer may be contain the |
175 | whole FPGA image or may be a smaller chunk of an FPGA image. In the latter | 178 | whole FPGA image or may be a smaller chunk of an FPGA image. In the latter |
diff --git a/MAINTAINERS b/MAINTAINERS index 2f89c3be2a39..b0fee8c45135 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -4958,6 +4958,7 @@ M: Alan Tull <atull@opensource.altera.com> | |||
4958 | R: Moritz Fischer <moritz.fischer@ettus.com> | 4958 | R: Moritz Fischer <moritz.fischer@ettus.com> |
4959 | L: linux-fpga@vger.kernel.org | 4959 | L: linux-fpga@vger.kernel.org |
4960 | S: Maintained | 4960 | S: Maintained |
4961 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git | ||
4961 | F: drivers/fpga/ | 4962 | F: drivers/fpga/ |
4962 | F: include/linux/fpga/fpga-mgr.h | 4963 | F: include/linux/fpga/fpga-mgr.h |
4963 | W: http://www.rocketboards.org | 4964 | W: http://www.rocketboards.org |
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 889e4c398304..ce861a2853a4 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig | |||
@@ -22,13 +22,14 @@ config FPGA_REGION | |||
22 | 22 | ||
23 | config FPGA_MGR_SOCFPGA | 23 | config FPGA_MGR_SOCFPGA |
24 | tristate "Altera SOCFPGA FPGA Manager" | 24 | tristate "Altera SOCFPGA FPGA Manager" |
25 | depends on ARCH_SOCFPGA | 25 | depends on ARCH_SOCFPGA || COMPILE_TEST |
26 | help | 26 | help |
27 | FPGA manager driver support for Altera SOCFPGA. | 27 | FPGA manager driver support for Altera SOCFPGA. |
28 | 28 | ||
29 | config FPGA_MGR_SOCFPGA_A10 | 29 | config FPGA_MGR_SOCFPGA_A10 |
30 | tristate "Altera SoCFPGA Arria10" | 30 | tristate "Altera SoCFPGA Arria10" |
31 | depends on ARCH_SOCFPGA | 31 | depends on ARCH_SOCFPGA || COMPILE_TEST |
32 | select REGMAP_MMIO | ||
32 | help | 33 | help |
33 | FPGA manager driver support for Altera Arria10 SoCFPGA. | 34 | FPGA manager driver support for Altera Arria10 SoCFPGA. |
34 | 35 | ||
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c index 79ce2eea44db..f0a69d3e60a5 100644 --- a/drivers/fpga/fpga-mgr.c +++ b/drivers/fpga/fpga-mgr.c | |||
@@ -53,10 +53,12 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info, | |||
53 | /* | 53 | /* |
54 | * Call the low level driver's write_init function. This will do the | 54 | * Call the low level driver's write_init function. This will do the |
55 | * device-specific things to get the FPGA into the state where it is | 55 | * device-specific things to get the FPGA into the state where it is |
56 | * ready to receive an FPGA image. | 56 | * ready to receive an FPGA image. The low level driver only gets to |
57 | * see the first initial_header_size bytes in the buffer. | ||
57 | */ | 58 | */ |
58 | mgr->state = FPGA_MGR_STATE_WRITE_INIT; | 59 | mgr->state = FPGA_MGR_STATE_WRITE_INIT; |
59 | ret = mgr->mops->write_init(mgr, info, buf, count); | 60 | ret = mgr->mops->write_init(mgr, info, buf, |
61 | min(mgr->mops->initial_header_size, count)); | ||
60 | if (ret) { | 62 | if (ret) { |
61 | dev_err(dev, "Error preparing FPGA for writing\n"); | 63 | dev_err(dev, "Error preparing FPGA for writing\n"); |
62 | mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR; | 64 | mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR; |
diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c index ccd9fb23bd52..f8770af0f6b5 100644 --- a/drivers/fpga/socfpga-a10.c +++ b/drivers/fpga/socfpga-a10.c | |||
@@ -470,6 +470,7 @@ static enum fpga_mgr_states socfpga_a10_fpga_state(struct fpga_manager *mgr) | |||
470 | } | 470 | } |
471 | 471 | ||
472 | static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = { | 472 | static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = { |
473 | .initial_header_size = (RBF_DECOMPRESS_OFFSET + 1) * 4, | ||
473 | .state = socfpga_a10_fpga_state, | 474 | .state = socfpga_a10_fpga_state, |
474 | .write_init = socfpga_a10_fpga_write_init, | 475 | .write_init = socfpga_a10_fpga_write_init, |
475 | .write = socfpga_a10_fpga_write, | 476 | .write = socfpga_a10_fpga_write, |
diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c index 249682e92502..1812bf7614e1 100644 --- a/drivers/fpga/zynq-fpga.c +++ b/drivers/fpga/zynq-fpga.c | |||
@@ -118,7 +118,6 @@ | |||
118 | #define FPGA_RST_NONE_MASK 0x0 | 118 | #define FPGA_RST_NONE_MASK 0x0 |
119 | 119 | ||
120 | struct zynq_fpga_priv { | 120 | struct zynq_fpga_priv { |
121 | struct device *dev; | ||
122 | int irq; | 121 | int irq; |
123 | struct clk *clk; | 122 | struct clk *clk; |
124 | 123 | ||
@@ -218,7 +217,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, | |||
218 | INIT_POLL_DELAY, | 217 | INIT_POLL_DELAY, |
219 | INIT_POLL_TIMEOUT); | 218 | INIT_POLL_TIMEOUT); |
220 | if (err) { | 219 | if (err) { |
221 | dev_err(priv->dev, "Timeout waiting for PCFG_INIT"); | 220 | dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n"); |
222 | goto out_err; | 221 | goto out_err; |
223 | } | 222 | } |
224 | 223 | ||
@@ -232,7 +231,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, | |||
232 | INIT_POLL_DELAY, | 231 | INIT_POLL_DELAY, |
233 | INIT_POLL_TIMEOUT); | 232 | INIT_POLL_TIMEOUT); |
234 | if (err) { | 233 | if (err) { |
235 | dev_err(priv->dev, "Timeout waiting for !PCFG_INIT"); | 234 | dev_err(&mgr->dev, "Timeout waiting for !PCFG_INIT\n"); |
236 | goto out_err; | 235 | goto out_err; |
237 | } | 236 | } |
238 | 237 | ||
@@ -246,7 +245,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, | |||
246 | INIT_POLL_DELAY, | 245 | INIT_POLL_DELAY, |
247 | INIT_POLL_TIMEOUT); | 246 | INIT_POLL_TIMEOUT); |
248 | if (err) { | 247 | if (err) { |
249 | dev_err(priv->dev, "Timeout waiting for PCFG_INIT"); | 248 | dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n"); |
250 | goto out_err; | 249 | goto out_err; |
251 | } | 250 | } |
252 | } | 251 | } |
@@ -263,7 +262,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, | |||
263 | /* check that we have room in the command queue */ | 262 | /* check that we have room in the command queue */ |
264 | status = zynq_fpga_read(priv, STATUS_OFFSET); | 263 | status = zynq_fpga_read(priv, STATUS_OFFSET); |
265 | if (status & STATUS_DMA_Q_F) { | 264 | if (status & STATUS_DMA_Q_F) { |
266 | dev_err(priv->dev, "DMA command queue full"); | 265 | dev_err(&mgr->dev, "DMA command queue full\n"); |
267 | err = -EBUSY; | 266 | err = -EBUSY; |
268 | goto out_err; | 267 | goto out_err; |
269 | } | 268 | } |
@@ -296,7 +295,8 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, | |||
296 | in_count = count; | 295 | in_count = count; |
297 | priv = mgr->priv; | 296 | priv = mgr->priv; |
298 | 297 | ||
299 | kbuf = dma_alloc_coherent(priv->dev, count, &dma_addr, GFP_KERNEL); | 298 | kbuf = |
299 | dma_alloc_coherent(mgr->dev.parent, count, &dma_addr, GFP_KERNEL); | ||
300 | if (!kbuf) | 300 | if (!kbuf) |
301 | return -ENOMEM; | 301 | return -ENOMEM; |
302 | 302 | ||
@@ -332,15 +332,14 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, | |||
332 | zynq_fpga_write(priv, INT_STS_OFFSET, intr_status); | 332 | zynq_fpga_write(priv, INT_STS_OFFSET, intr_status); |
333 | 333 | ||
334 | if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) { | 334 | if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) { |
335 | dev_err(priv->dev, "Error configuring FPGA"); | 335 | dev_err(&mgr->dev, "Error configuring FPGA\n"); |
336 | err = -EFAULT; | 336 | err = -EFAULT; |
337 | } | 337 | } |
338 | 338 | ||
339 | clk_disable(priv->clk); | 339 | clk_disable(priv->clk); |
340 | 340 | ||
341 | out_free: | 341 | out_free: |
342 | dma_free_coherent(priv->dev, in_count, kbuf, dma_addr); | 342 | dma_free_coherent(mgr->dev.parent, count, kbuf, dma_addr); |
343 | |||
344 | return err; | 343 | return err; |
345 | } | 344 | } |
346 | 345 | ||
@@ -418,8 +417,6 @@ static int zynq_fpga_probe(struct platform_device *pdev) | |||
418 | if (!priv) | 417 | if (!priv) |
419 | return -ENOMEM; | 418 | return -ENOMEM; |
420 | 419 | ||
421 | priv->dev = dev; | ||
422 | |||
423 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 420 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
424 | priv->io_base = devm_ioremap_resource(dev, res); | 421 | priv->io_base = devm_ioremap_resource(dev, res); |
425 | if (IS_ERR(priv->io_base)) | 422 | if (IS_ERR(priv->io_base)) |
@@ -428,7 +425,7 @@ static int zynq_fpga_probe(struct platform_device *pdev) | |||
428 | priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node, | 425 | priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node, |
429 | "syscon"); | 426 | "syscon"); |
430 | if (IS_ERR(priv->slcr)) { | 427 | if (IS_ERR(priv->slcr)) { |
431 | dev_err(dev, "unable to get zynq-slcr regmap"); | 428 | dev_err(dev, "unable to get zynq-slcr regmap\n"); |
432 | return PTR_ERR(priv->slcr); | 429 | return PTR_ERR(priv->slcr); |
433 | } | 430 | } |
434 | 431 | ||
@@ -436,38 +433,41 @@ static int zynq_fpga_probe(struct platform_device *pdev) | |||
436 | 433 | ||
437 | priv->irq = platform_get_irq(pdev, 0); | 434 | priv->irq = platform_get_irq(pdev, 0); |
438 | if (priv->irq < 0) { | 435 | if (priv->irq < 0) { |
439 | dev_err(dev, "No IRQ available"); | 436 | dev_err(dev, "No IRQ available\n"); |
440 | return priv->irq; | 437 | return priv->irq; |
441 | } | 438 | } |
442 | 439 | ||
443 | err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0, | ||
444 | dev_name(dev), priv); | ||
445 | if (err) { | ||
446 | dev_err(dev, "unable to request IRQ"); | ||
447 | return err; | ||
448 | } | ||
449 | |||
450 | priv->clk = devm_clk_get(dev, "ref_clk"); | 440 | priv->clk = devm_clk_get(dev, "ref_clk"); |
451 | if (IS_ERR(priv->clk)) { | 441 | if (IS_ERR(priv->clk)) { |
452 | dev_err(dev, "input clock not found"); | 442 | dev_err(dev, "input clock not found\n"); |
453 | return PTR_ERR(priv->clk); | 443 | return PTR_ERR(priv->clk); |
454 | } | 444 | } |
455 | 445 | ||
456 | err = clk_prepare_enable(priv->clk); | 446 | err = clk_prepare_enable(priv->clk); |
457 | if (err) { | 447 | if (err) { |
458 | dev_err(dev, "unable to enable clock"); | 448 | dev_err(dev, "unable to enable clock\n"); |
459 | return err; | 449 | return err; |
460 | } | 450 | } |
461 | 451 | ||
462 | /* unlock the device */ | 452 | /* unlock the device */ |
463 | zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK); | 453 | zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK); |
464 | 454 | ||
455 | zynq_fpga_write(priv, INT_MASK_OFFSET, 0xFFFFFFFF); | ||
456 | zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK); | ||
457 | err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0, dev_name(dev), | ||
458 | priv); | ||
459 | if (err) { | ||
460 | dev_err(dev, "unable to request IRQ\n"); | ||
461 | clk_disable_unprepare(priv->clk); | ||
462 | return err; | ||
463 | } | ||
464 | |||
465 | clk_disable(priv->clk); | 465 | clk_disable(priv->clk); |
466 | 466 | ||
467 | err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager", | 467 | err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager", |
468 | &zynq_fpga_ops, priv); | 468 | &zynq_fpga_ops, priv); |
469 | if (err) { | 469 | if (err) { |
470 | dev_err(dev, "unable to register FPGA manager"); | 470 | dev_err(dev, "unable to register FPGA manager\n"); |
471 | clk_unprepare(priv->clk); | 471 | clk_unprepare(priv->clk); |
472 | return err; | 472 | return err; |
473 | } | 473 | } |
diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h index 96a1a3311649..16551d5eac36 100644 --- a/include/linux/fpga/fpga-mgr.h +++ b/include/linux/fpga/fpga-mgr.h | |||
@@ -84,6 +84,7 @@ struct fpga_image_info { | |||
84 | 84 | ||
85 | /** | 85 | /** |
86 | * struct fpga_manager_ops - ops for low level fpga manager drivers | 86 | * struct fpga_manager_ops - ops for low level fpga manager drivers |
87 | * @initial_header_size: Maximum number of bytes that should be passed into write_init | ||
87 | * @state: returns an enum value of the FPGA's state | 88 | * @state: returns an enum value of the FPGA's state |
88 | * @write_init: prepare the FPGA to receive confuration data | 89 | * @write_init: prepare the FPGA to receive confuration data |
89 | * @write: write count bytes of configuration data to the FPGA | 90 | * @write: write count bytes of configuration data to the FPGA |
@@ -95,6 +96,7 @@ struct fpga_image_info { | |||
95 | * called, so leaving them out is fine. | 96 | * called, so leaving them out is fine. |
96 | */ | 97 | */ |
97 | struct fpga_manager_ops { | 98 | struct fpga_manager_ops { |
99 | size_t initial_header_size; | ||
98 | enum fpga_mgr_states (*state)(struct fpga_manager *mgr); | 100 | enum fpga_mgr_states (*state)(struct fpga_manager *mgr); |
99 | int (*write_init)(struct fpga_manager *mgr, | 101 | int (*write_init)(struct fpga_manager *mgr, |
100 | struct fpga_image_info *info, | 102 | struct fpga_image_info *info, |