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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJYPfiYAAoJENTMLwuu3eSiBBoQALoRFIn4g+t77TdeX3ai/mai 6p3csgxxz5u2Yv5Teb++yppumpVLnn4y2cLxiCbdEtnKzIhf6q8EVbS5go+q8fAC 83trWl1T++SPwsMWoOQCCCydhWufecEAz0G5GpSL8eOhqDPSQRK988FO/b+NjeHv FnQRL7DkDJByyCuv7+dSxJ4pHfLfHXntq+MnH96BlZUhPcA42PvhztQo831d8Zem vSzob/dqLHb8VWXfckMveqIniZ43bf/VPBIOD/bF5UDQjNl7tgOq4tm2/NFyjebT URyJc1zKFucDaHBeLfo6mqZSYWYWSmYPXcCG6rH1mgdzJxa9lIU0hzqOxPh3dhIA ZH8MfsAhoEX+h5eP+hWqAwQ2tbswJEaGvtzuB0DRrf3YGdYlj5lu6G6eA7PKbaVN DD+jaHcOoKZFaYowT17jp9SiSOUllL2bP1VH1LclQFPzdUUiwfVegQl8cmjIAjiV plvFg7VDfYz3U7cvLT/O7WlN2AIozsymeJZ6uogxZEE1YZYm671X7efYmo+2yism ttMqXAOPifDyyyWOKiyn2yyVYCXz3Hp+AJVIIZtHZvSCgLTZMRYsN5skBzavnimS 79Ay4KGEr4Zj1gZr2sqUBqjs/mKTm3zzxeqm+gZYjYhTH9ADhtl+OviH3BDqQPhu Q4y8GiBxA8MY/9Yzt3wl =n+ZG -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
e073462966
@ -169,7 +169,10 @@ The programming sequence is:
|
||||
2. .write (may be called once or multiple times)
|
||||
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
|
||||
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>
|
||||
R: Moritz Fischer <moritz.fischer@ettus.com>
|
||||
L: linux-fpga@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git
|
||||
F: drivers/fpga/
|
||||
F: include/linux/fpga/fpga-mgr.h
|
||||
W: http://www.rocketboards.org
|
||||
|
@ -22,13 +22,14 @@ config FPGA_REGION
|
||||
|
||||
config FPGA_MGR_SOCFPGA
|
||||
tristate "Altera SOCFPGA FPGA Manager"
|
||||
depends on ARCH_SOCFPGA
|
||||
depends on ARCH_SOCFPGA || COMPILE_TEST
|
||||
help
|
||||
FPGA manager driver support for Altera SOCFPGA.
|
||||
|
||||
config FPGA_MGR_SOCFPGA_A10
|
||||
tristate "Altera SoCFPGA Arria10"
|
||||
depends on ARCH_SOCFPGA
|
||||
depends on ARCH_SOCFPGA || COMPILE_TEST
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
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,
|
||||
/*
|
||||
* 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
|
||||
* 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;
|
||||
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) {
|
||||
dev_err(dev, "Error preparing FPGA for writing\n");
|
||||
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)
|
||||
}
|
||||
|
||||
static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = {
|
||||
.initial_header_size = (RBF_DECOMPRESS_OFFSET + 1) * 4,
|
||||
.state = socfpga_a10_fpga_state,
|
||||
.write_init = socfpga_a10_fpga_write_init,
|
||||
.write = socfpga_a10_fpga_write,
|
||||
|
@ -118,7 +118,6 @@
|
||||
#define FPGA_RST_NONE_MASK 0x0
|
||||
|
||||
struct zynq_fpga_priv {
|
||||
struct device *dev;
|
||||
int irq;
|
||||
struct clk *clk;
|
||||
|
||||
@ -218,7 +217,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
|
||||
INIT_POLL_DELAY,
|
||||
INIT_POLL_TIMEOUT);
|
||||
if (err) {
|
||||
dev_err(priv->dev, "Timeout waiting for PCFG_INIT");
|
||||
dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n");
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
@ -232,7 +231,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
|
||||
INIT_POLL_DELAY,
|
||||
INIT_POLL_TIMEOUT);
|
||||
if (err) {
|
||||
dev_err(priv->dev, "Timeout waiting for !PCFG_INIT");
|
||||
dev_err(&mgr->dev, "Timeout waiting for !PCFG_INIT\n");
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
@ -246,7 +245,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
|
||||
INIT_POLL_DELAY,
|
||||
INIT_POLL_TIMEOUT);
|
||||
if (err) {
|
||||
dev_err(priv->dev, "Timeout waiting for PCFG_INIT");
|
||||
dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n");
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
@ -263,7 +262,7 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
|
||||
/* check that we have room in the command queue */
|
||||
status = zynq_fpga_read(priv, STATUS_OFFSET);
|
||||
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;
|
||||
goto out_err;
|
||||
}
|
||||
@ -296,7 +295,8 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr,
|
||||
in_count = count;
|
||||
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)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -332,15 +332,14 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr,
|
||||
zynq_fpga_write(priv, INT_STS_OFFSET, intr_status);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
clk_disable(priv->clk);
|
||||
|
||||
out_free:
|
||||
dma_free_coherent(priv->dev, in_count, kbuf, dma_addr);
|
||||
|
||||
dma_free_coherent(mgr->dev.parent, count, kbuf, dma_addr);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -418,8 +417,6 @@ static int zynq_fpga_probe(struct platform_device *pdev)
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->dev = dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->io_base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(priv->io_base))
|
||||
@ -428,7 +425,7 @@ static int zynq_fpga_probe(struct platform_device *pdev)
|
||||
priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node,
|
||||
"syscon");
|
||||
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);
|
||||
}
|
||||
|
||||
@ -436,38 +433,41 @@ static int zynq_fpga_probe(struct platform_device *pdev)
|
||||
|
||||
priv->irq = platform_get_irq(pdev, 0);
|
||||
if (priv->irq < 0) {
|
||||
dev_err(dev, "No IRQ available");
|
||||
dev_err(dev, "No IRQ available\n");
|
||||
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");
|
||||
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);
|
||||
}
|
||||
|
||||
err = clk_prepare_enable(priv->clk);
|
||||
if (err) {
|
||||
dev_err(dev, "unable to enable clock");
|
||||
dev_err(dev, "unable to enable clock\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* unlock the device */
|
||||
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);
|
||||
|
||||
err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager",
|
||||
&zynq_fpga_ops, priv);
|
||||
if (err) {
|
||||
dev_err(dev, "unable to register FPGA manager");
|
||||
dev_err(dev, "unable to register FPGA manager\n");
|
||||
clk_unprepare(priv->clk);
|
||||
return err;
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ struct fpga_image_info {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @write_init: prepare the FPGA to receive confuration data
|
||||
* @write: write count bytes of configuration data to the FPGA
|
||||
@ -95,6 +96,7 @@ struct fpga_image_info {
|
||||
* called, so leaving them out is fine.
|
||||
*/
|
||||
struct fpga_manager_ops {
|
||||
size_t initial_header_size;
|
||||
enum fpga_mgr_states (*state)(struct fpga_manager *mgr);
|
||||
int (*write_init)(struct fpga_manager *mgr,
|
||||
struct fpga_image_info *info,
|
||||
|
Loading…
Reference in New Issue
Block a user