X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Ffpga%2Fzynqpl.c;h=68fe0f3b03afb99085fada927806cbe7afca6407;hb=230fe9b202ff0ca396ad9a564816cc87d42daa6e;hp=c066f21d79f323f17227b4001fa55358f9b14735;hpb=31081859855e606ca06131c3a14e099e043d39f0;p=u-boot diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index c066f21d79..68fe0f3b03 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -194,7 +195,7 @@ static int zynq_dma_transfer(u32 srcbuf, u32 srclen, u32 dstbuf, u32 dstlen) return FPGA_SUCCESS; } -static int zynq_dma_xfer_init(u32 partialbit) +static int zynq_dma_xfer_init(bitstream_type bstype) { u32 status, control, isr_status; unsigned long ts; @@ -202,7 +203,7 @@ static int zynq_dma_xfer_init(u32 partialbit) /* Clear loopback bit */ clrbits_le32(&devcfg_base->mctrl, DEVCFG_MCTRL_PCAP_LPBK); - if (!partialbit) { + if (bstype != BIT_PARTIAL) { zynq_slcr_devcfg_disable(); /* Setting PCFG_PROG_B signal to high */ @@ -322,16 +323,11 @@ static u32 *zynq_align_dma_buffer(u32 *buf, u32 len, u32 swap) static int zynq_validate_bitstream(xilinx_desc *desc, const void *buf, size_t bsize, u32 blocksize, u32 *swap, - u32 *partialbit) + bitstream_type *bstype) { u32 *buf_start; u32 diff; - /* Detect if we are going working with partial or full bitstream */ - if (bsize != desc->size) { - printf("%s: Working with partial bitstream\n", __func__); - *partialbit = 1; - } buf_start = check_data((u8 *)buf, blocksize, swap); if (!buf_start) @@ -351,17 +347,16 @@ static int zynq_validate_bitstream(xilinx_desc *desc, const void *buf, return FPGA_FAIL; } - if (zynq_dma_xfer_init(*partialbit)) + if (zynq_dma_xfer_init(*bstype)) return FPGA_FAIL; return 0; } - -static int zynq_load(xilinx_desc *desc, const void *buf, size_t bsize) +static int zynq_load(xilinx_desc *desc, const void *buf, size_t bsize, + bitstream_type bstype) { unsigned long ts; /* Timestamp */ - u32 partialbit = 0; u32 isr_status, swap; /* @@ -369,7 +364,7 @@ static int zynq_load(xilinx_desc *desc, const void *buf, size_t bsize) * in chunks */ if (zynq_validate_bitstream(desc, buf, bsize, bsize, &swap, - &partialbit)) + &bstype)) return FPGA_FAIL; buf = zynq_align_dma_buffer((u32 *)buf, bsize, swap); @@ -398,11 +393,92 @@ static int zynq_load(xilinx_desc *desc, const void *buf, size_t bsize) debug("%s: FPGA config done\n", __func__); + if (bstype != BIT_PARTIAL) + zynq_slcr_devcfg_enable(); + + 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; + u32 blocksize; + u32 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) < 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) < 0) + return FPGA_FAIL; + } else { + if (fs_read(filename, (u32) buf, pos, bsize) < 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) { @@ -411,6 +487,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, };