arm: imx: add i.MX53 Beckhoff CX9020 Embedded PC
[oweals/u-boot.git] / drivers / fpga / zynqpl.c
index 915f07735a8d2445bc5cdf3801d124e66c00a082..ef889ea4e66939359fef2d84be3f7254c9b39b84 100644 (file)
@@ -8,7 +8,9 @@
  */
 
 #include <common.h>
+#include <console.h>
 #include <asm/io.h>
+#include <fs.h>
 #include <zynqpl.h>
 #include <linux/sizes.h>
 #include <asm/arch/hardware.h>
@@ -398,6 +400,87 @@ static int zynq_load(xilinx_desc *desc, const void *buf, size_t bsize,
        return FPGA_SUCCESS;
 }
 
+#if defined(CONFIG_CMD_FPGA_LOADFS)
+static int zynq_loadfs(xilinx_desc *desc, const void *buf, size_t bsize,
+                      fpga_fs_info *fsinfo)
+{
+       unsigned long ts; /* Timestamp */
+       u32 isr_status, swap;
+       u32 partialbit = 0;
+       loff_t blocksize, actread;
+       loff_t pos = 0;
+       int fstype;
+       char *interface, *dev_part, *filename;
+
+       blocksize = fsinfo->blocksize;
+       interface = fsinfo->interface;
+       dev_part = fsinfo->dev_part;
+       filename = fsinfo->filename;
+       fstype = fsinfo->fstype;
+
+       if (fs_set_blk_dev(interface, dev_part, fstype))
+               return FPGA_FAIL;
+
+       if (fs_read(filename, (u32) buf, pos, blocksize, &actread) < 0)
+               return FPGA_FAIL;
+
+       if (zynq_validate_bitstream(desc, buf, bsize, blocksize, &swap,
+                                   &partialbit))
+               return FPGA_FAIL;
+
+       dcache_disable();
+
+       do {
+               buf = zynq_align_dma_buffer((u32 *)buf, blocksize, swap);
+
+               if (zynq_dma_transfer((u32)buf | 1, blocksize >> 2,
+                                     0xffffffff, 0))
+                       return FPGA_FAIL;
+
+               bsize -= blocksize;
+               pos   += blocksize;
+
+               if (fs_set_blk_dev(interface, dev_part, fstype))
+                       return FPGA_FAIL;
+
+               if (bsize > blocksize) {
+                       if (fs_read(filename, (u32) buf, pos, blocksize, &actread) < 0)
+                               return FPGA_FAIL;
+               } else {
+                       if (fs_read(filename, (u32) buf, pos, bsize, &actread) < 0)
+                               return FPGA_FAIL;
+               }
+       } while (bsize > blocksize);
+
+       buf = zynq_align_dma_buffer((u32 *)buf, blocksize, swap);
+
+       if (zynq_dma_transfer((u32)buf | 1, bsize >> 2, 0xffffffff, 0))
+               return FPGA_FAIL;
+
+       dcache_enable();
+
+       isr_status = readl(&devcfg_base->int_sts);
+
+       /* Check FPGA configuration completion */
+       ts = get_timer(0);
+       while (!(isr_status & DEVCFG_ISR_PCFG_DONE)) {
+               if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
+                       printf("%s: Timeout wait for FPGA to config\n",
+                              __func__);
+                       return FPGA_FAIL;
+               }
+               isr_status = readl(&devcfg_base->int_sts);
+       }
+
+       debug("%s: FPGA config done\n", __func__);
+
+       if (!partialbit)
+               zynq_slcr_devcfg_enable();
+
+       return FPGA_SUCCESS;
+}
+#endif
+
 static int zynq_dump(xilinx_desc *desc, const void *buf, size_t bsize)
 {
        return FPGA_FAIL;
@@ -405,6 +488,9 @@ static int zynq_dump(xilinx_desc *desc, const void *buf, size_t bsize)
 
 struct xilinx_fpga_op zynq_op = {
        .load = zynq_load,
+#if defined(CONFIG_CMD_FPGA_LOADFS)
+       .loadfs = zynq_loadfs,
+#endif
        .dump = zynq_dump,
        .info = zynq_info,
 };