Commit e0734629 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'fpga-for-greg-20161129' of...

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
parents 31114fa9 e4998077
...@@ -169,7 +169,10 @@ The programming sequence is: ...@@ -169,7 +169,10 @@ The programming sequence is:
2. .write (may be called once or multiple times) 2. .write (may be called once or multiple times)
3. .write_complete 3. .write_complete
The .write_init function will prepare the FPGA to receive the image data. The .write_init function will prepare the FPGA to receive the image data. The
buffer passed into .write_init will be atmost .initial_header_size bytes long,
if the whole bitstream is not immediately available then the core code will
buffer up at least this much before starting.
The .write function writes a buffer to the FPGA. The buffer may be contain the The .write function writes a buffer to the FPGA. The buffer may be contain the
whole FPGA image or may be a smaller chunk of an FPGA image. In the latter whole FPGA image or may be a smaller chunk of an FPGA image. In the latter
......
...@@ -4958,6 +4958,7 @@ M: Alan Tull <atull@opensource.altera.com> ...@@ -4958,6 +4958,7 @@ M: Alan Tull <atull@opensource.altera.com>
R: Moritz Fischer <moritz.fischer@ettus.com> R: Moritz Fischer <moritz.fischer@ettus.com>
L: linux-fpga@vger.kernel.org L: linux-fpga@vger.kernel.org
S: Maintained S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git
F: drivers/fpga/ F: drivers/fpga/
F: include/linux/fpga/fpga-mgr.h F: include/linux/fpga/fpga-mgr.h
W: http://www.rocketboards.org W: http://www.rocketboards.org
......
...@@ -22,13 +22,14 @@ config FPGA_REGION ...@@ -22,13 +22,14 @@ config FPGA_REGION
config FPGA_MGR_SOCFPGA config FPGA_MGR_SOCFPGA
tristate "Altera SOCFPGA FPGA Manager" tristate "Altera SOCFPGA FPGA Manager"
depends on ARCH_SOCFPGA depends on ARCH_SOCFPGA || COMPILE_TEST
help help
FPGA manager driver support for Altera SOCFPGA. FPGA manager driver support for Altera SOCFPGA.
config FPGA_MGR_SOCFPGA_A10 config FPGA_MGR_SOCFPGA_A10
tristate "Altera SoCFPGA Arria10" tristate "Altera SoCFPGA Arria10"
depends on ARCH_SOCFPGA depends on ARCH_SOCFPGA || COMPILE_TEST
select REGMAP_MMIO
help help
FPGA manager driver support for Altera Arria10 SoCFPGA. FPGA manager driver support for Altera Arria10 SoCFPGA.
......
...@@ -53,10 +53,12 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info, ...@@ -53,10 +53,12 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info,
/* /*
* Call the low level driver's write_init function. This will do the * Call the low level driver's write_init function. This will do the
* device-specific things to get the FPGA into the state where it is * device-specific things to get the FPGA into the state where it is
* ready to receive an FPGA image. * ready to receive an FPGA image. The low level driver only gets to
* see the first initial_header_size bytes in the buffer.
*/ */
mgr->state = FPGA_MGR_STATE_WRITE_INIT; mgr->state = FPGA_MGR_STATE_WRITE_INIT;
ret = mgr->mops->write_init(mgr, info, buf, count); ret = mgr->mops->write_init(mgr, info, buf,
min(mgr->mops->initial_header_size, count));
if (ret) { if (ret) {
dev_err(dev, "Error preparing FPGA for writing\n"); dev_err(dev, "Error preparing FPGA for writing\n");
mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR; mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR;
......
...@@ -470,6 +470,7 @@ static enum fpga_mgr_states socfpga_a10_fpga_state(struct fpga_manager *mgr) ...@@ -470,6 +470,7 @@ static enum fpga_mgr_states socfpga_a10_fpga_state(struct fpga_manager *mgr)
} }
static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = { static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = {
.initial_header_size = (RBF_DECOMPRESS_OFFSET + 1) * 4,
.state = socfpga_a10_fpga_state, .state = socfpga_a10_fpga_state,
.write_init = socfpga_a10_fpga_write_init, .write_init = socfpga_a10_fpga_write_init,
.write = socfpga_a10_fpga_write, .write = socfpga_a10_fpga_write,
......
...@@ -118,7 +118,6 @@ ...@@ -118,7 +118,6 @@
#define FPGA_RST_NONE_MASK 0x0 #define FPGA_RST_NONE_MASK 0x0
struct zynq_fpga_priv { struct zynq_fpga_priv {
struct device *dev;
int irq; int irq;
struct clk *clk; struct clk *clk;
...@@ -218,7 +217,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, ...@@ -218,7 +217,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
INIT_POLL_DELAY, INIT_POLL_DELAY,
INIT_POLL_TIMEOUT); INIT_POLL_TIMEOUT);
if (err) { if (err) {
dev_err(priv->dev, "Timeout waiting for PCFG_INIT"); dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n");
goto out_err; goto out_err;
} }
...@@ -232,7 +231,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, ...@@ -232,7 +231,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
INIT_POLL_DELAY, INIT_POLL_DELAY,
INIT_POLL_TIMEOUT); INIT_POLL_TIMEOUT);
if (err) { if (err) {
dev_err(priv->dev, "Timeout waiting for !PCFG_INIT"); dev_err(&mgr->dev, "Timeout waiting for !PCFG_INIT\n");
goto out_err; goto out_err;
} }
...@@ -246,7 +245,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, ...@@ -246,7 +245,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
INIT_POLL_DELAY, INIT_POLL_DELAY,
INIT_POLL_TIMEOUT); INIT_POLL_TIMEOUT);
if (err) { if (err) {
dev_err(priv->dev, "Timeout waiting for PCFG_INIT"); dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n");
goto out_err; goto out_err;
} }
} }
...@@ -263,7 +262,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, ...@@ -263,7 +262,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
/* check that we have room in the command queue */ /* check that we have room in the command queue */
status = zynq_fpga_read(priv, STATUS_OFFSET); status = zynq_fpga_read(priv, STATUS_OFFSET);
if (status & STATUS_DMA_Q_F) { if (status & STATUS_DMA_Q_F) {
dev_err(priv->dev, "DMA command queue full"); dev_err(&mgr->dev, "DMA command queue full\n");
err = -EBUSY; err = -EBUSY;
goto out_err; goto out_err;
} }
...@@ -296,7 +295,8 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, ...@@ -296,7 +295,8 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr,
in_count = count; in_count = count;
priv = mgr->priv; priv = mgr->priv;
kbuf = dma_alloc_coherent(priv->dev, count, &dma_addr, GFP_KERNEL); kbuf =
dma_alloc_coherent(mgr->dev.parent, count, &dma_addr, GFP_KERNEL);
if (!kbuf) if (!kbuf)
return -ENOMEM; return -ENOMEM;
...@@ -332,15 +332,14 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, ...@@ -332,15 +332,14 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr,
zynq_fpga_write(priv, INT_STS_OFFSET, intr_status); zynq_fpga_write(priv, INT_STS_OFFSET, intr_status);
if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) { if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) {
dev_err(priv->dev, "Error configuring FPGA"); dev_err(&mgr->dev, "Error configuring FPGA\n");
err = -EFAULT; err = -EFAULT;
} }
clk_disable(priv->clk); clk_disable(priv->clk);
out_free: out_free:
dma_free_coherent(priv->dev, in_count, kbuf, dma_addr); dma_free_coherent(mgr->dev.parent, count, kbuf, dma_addr);
return err; return err;
} }
...@@ -418,8 +417,6 @@ static int zynq_fpga_probe(struct platform_device *pdev) ...@@ -418,8 +417,6 @@ static int zynq_fpga_probe(struct platform_device *pdev)
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
priv->dev = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->io_base = devm_ioremap_resource(dev, res); priv->io_base = devm_ioremap_resource(dev, res);
if (IS_ERR(priv->io_base)) if (IS_ERR(priv->io_base))
...@@ -428,7 +425,7 @@ static int zynq_fpga_probe(struct platform_device *pdev) ...@@ -428,7 +425,7 @@ static int zynq_fpga_probe(struct platform_device *pdev)
priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node, priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node,
"syscon"); "syscon");
if (IS_ERR(priv->slcr)) { if (IS_ERR(priv->slcr)) {
dev_err(dev, "unable to get zynq-slcr regmap"); dev_err(dev, "unable to get zynq-slcr regmap\n");
return PTR_ERR(priv->slcr); return PTR_ERR(priv->slcr);
} }
...@@ -436,38 +433,41 @@ static int zynq_fpga_probe(struct platform_device *pdev) ...@@ -436,38 +433,41 @@ static int zynq_fpga_probe(struct platform_device *pdev)
priv->irq = platform_get_irq(pdev, 0); priv->irq = platform_get_irq(pdev, 0);
if (priv->irq < 0) { if (priv->irq < 0) {
dev_err(dev, "No IRQ available"); dev_err(dev, "No IRQ available\n");
return priv->irq; return priv->irq;
} }
err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0,
dev_name(dev), priv);
if (err) {
dev_err(dev, "unable to request IRQ");
return err;
}
priv->clk = devm_clk_get(dev, "ref_clk"); priv->clk = devm_clk_get(dev, "ref_clk");
if (IS_ERR(priv->clk)) { if (IS_ERR(priv->clk)) {
dev_err(dev, "input clock not found"); dev_err(dev, "input clock not found\n");
return PTR_ERR(priv->clk); return PTR_ERR(priv->clk);
} }
err = clk_prepare_enable(priv->clk); err = clk_prepare_enable(priv->clk);
if (err) { if (err) {
dev_err(dev, "unable to enable clock"); dev_err(dev, "unable to enable clock\n");
return err; return err;
} }
/* unlock the device */ /* unlock the device */
zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK); zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK);
zynq_fpga_write(priv, INT_MASK_OFFSET, 0xFFFFFFFF);
zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK);
err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0, dev_name(dev),
priv);
if (err) {
dev_err(dev, "unable to request IRQ\n");
clk_disable_unprepare(priv->clk);
return err;
}
clk_disable(priv->clk); clk_disable(priv->clk);
err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager", err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager",
&zynq_fpga_ops, priv); &zynq_fpga_ops, priv);
if (err) { if (err) {
dev_err(dev, "unable to register FPGA manager"); dev_err(dev, "unable to register FPGA manager\n");
clk_unprepare(priv->clk); clk_unprepare(priv->clk);
return err; return err;
} }
......
...@@ -84,6 +84,7 @@ struct fpga_image_info { ...@@ -84,6 +84,7 @@ struct fpga_image_info {
/** /**
* struct fpga_manager_ops - ops for low level fpga manager drivers * struct fpga_manager_ops - ops for low level fpga manager drivers
* @initial_header_size: Maximum number of bytes that should be passed into write_init
* @state: returns an enum value of the FPGA's state * @state: returns an enum value of the FPGA's state
* @write_init: prepare the FPGA to receive confuration data * @write_init: prepare the FPGA to receive confuration data
* @write: write count bytes of configuration data to the FPGA * @write: write count bytes of configuration data to the FPGA
...@@ -95,6 +96,7 @@ struct fpga_image_info { ...@@ -95,6 +96,7 @@ struct fpga_image_info {
* called, so leaving them out is fine. * called, so leaving them out is fine.
*/ */
struct fpga_manager_ops { struct fpga_manager_ops {
size_t initial_header_size;
enum fpga_mgr_states (*state)(struct fpga_manager *mgr); enum fpga_mgr_states (*state)(struct fpga_manager *mgr);
int (*write_init)(struct fpga_manager *mgr, int (*write_init)(struct fpga_manager *mgr,
struct fpga_image_info *info, struct fpga_image_info *info,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment