Allows drivers to request the Configuration image be loaded from dma-able continuous buffer to avoid needless memory pressure and delays due to multiple copies. Signed-off-by: Nava kishore Manne <nava.manne@xxxxxxxxxx> --- drivers/fpga/zynqmp-fpga.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/fpga/zynqmp-fpga.c b/drivers/fpga/zynqmp-fpga.c index 125743c9797f..3bb6bd520d71 100644 --- a/drivers/fpga/zynqmp-fpga.c +++ b/drivers/fpga/zynqmp-fpga.c @@ -66,6 +66,40 @@ static int zynqmp_fpga_ops_write(struct fpga_manager *mgr, return ret; } +static unsigned long zynqmp_fpga_get_contiguous_size(struct sg_table *sgt) +{ + dma_addr_t expected = sg_dma_address(sgt->sgl); + unsigned long size = 0; + struct scatterlist *s; + unsigned int i; + + for_each_sg(sgt->sgl, s, sgt->nents, i) { + if (sg_dma_address(s) != expected) + break; + expected = sg_dma_address(s) + sg_dma_len(s); + size += sg_dma_len(s); + } + + return size; +} + +static int zynqmp_fpga_ops_write_sg(struct fpga_manager *mgr, + struct sg_table *sgt) +{ + struct zynqmp_fpga_priv *priv; + unsigned long contig_size; + dma_addr_t dma_addr; + u32 eemi_flags = 0; + + priv = mgr->priv; + dma_addr = sg_dma_address(sgt->sgl); + contig_size = zynqmp_fpga_get_contiguous_size(sgt); + if (priv->flags & FPGA_MGR_PARTIAL_RECONFIG) + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_PARTIAL; + + return zynqmp_pm_fpga_load(dma_addr, contig_size, eemi_flags); +} + static int zynqmp_fpga_ops_write_complete(struct fpga_manager *mgr, struct fpga_image_info *info) { @@ -87,6 +121,7 @@ static const struct fpga_manager_ops zynqmp_fpga_ops = { .state = zynqmp_fpga_ops_state, .write_init = zynqmp_fpga_ops_write_init, .write = zynqmp_fpga_ops_write, + .write_sg = zynqmp_fpga_ops_write_sg, .write_complete = zynqmp_fpga_ops_write_complete, }; -- 2.18.0