+// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2012-2013, Xilinx, Michal Simek
*
* (C) Copyright 2012
* Joe Hershberger <joe.hershberger@ni.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <console.h>
+#include <cpu_func.h>
#include <asm/io.h>
#include <fs.h>
#include <zynqpl.h>
#include <asm/arch/sys_proto.h>
#define DEVCFG_CTRL_PCFG_PROG_B 0x40000000
+#define DEVCFG_CTRL_PCFG_AES_EFUSE_MASK 0x00001000
+#define DEVCFG_CTRL_PCAP_RATE_EN_MASK 0x02000000
#define DEVCFG_ISR_FATAL_ERROR_MASK 0x00740040
#define DEVCFG_ISR_ERROR_FLAGS_MASK 0x00340840
#define DEVCFG_ISR_RX_FIFO_OV 0x00040000
#define CONFIG_SYS_FPGA_PROG_TIME (CONFIG_SYS_HZ * 4) /* 4 s */
#endif
-static int zynq_info(xilinx_desc *desc)
-{
- return FPGA_SUCCESS;
-}
-
#define DUMMY_WORD 0xffffffff
/* Xilinx binary format header */
/* Setting PCFG_PROG_B signal to high */
control = readl(&devcfg_base->ctrl);
writel(control | DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl);
+
+ /*
+ * Delay is required if AES efuse is selected as
+ * key source.
+ */
+ if (control & DEVCFG_CTRL_PCFG_AES_EFUSE_MASK)
+ mdelay(5);
+
/* Setting PCFG_PROG_B signal to low */
writel(control & ~DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl);
+ /*
+ * Delay is required if AES efuse is selected as
+ * key source.
+ */
+ if (control & DEVCFG_CTRL_PCFG_AES_EFUSE_MASK)
+ mdelay(5);
+
/* Polling the PCAP_INIT status for Reset */
ts = get_timer(0);
while (readl(&devcfg_base->status) & DEVCFG_STATUS_PCFG_INIT) {
if (bstype != BIT_PARTIAL)
zynq_slcr_devcfg_enable();
+ puts("INFO:post config was not run, please run manually if needed\n");
+
return FPGA_SUCCESS;
}
-#if defined(CONFIG_CMD_FPGA_LOADFS)
+#if defined(CONFIG_CMD_FPGA_LOADFS) && !defined(CONFIG_SPL_BUILD)
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;
+ loff_t blocksize, actread;
+ loff_t pos = 0;
int fstype;
- char *interface, *dev_part, *filename;
+ char *interface, *dev_part;
+ const char *filename;
blocksize = fsinfo->blocksize;
interface = fsinfo->interface;
if (fs_set_blk_dev(interface, dev_part, fstype))
return FPGA_FAIL;
- if (fs_read(filename, (u32) buf, pos, blocksize) < 0)
+ if (fs_read(filename, (u32) buf, pos, blocksize, &actread) < 0)
return FPGA_FAIL;
if (zynq_validate_bitstream(desc, buf, bsize, blocksize, &swap,
return FPGA_FAIL;
if (bsize > blocksize) {
- if (fs_read(filename, (u32) buf, pos, blocksize) < 0)
+ if (fs_read(filename, (u32) buf, pos, blocksize, &actread) < 0)
return FPGA_FAIL;
} else {
- if (fs_read(filename, (u32) buf, pos, bsize) < 0)
+ if (fs_read(filename, (u32) buf, pos, bsize, &actread) < 0)
return FPGA_FAIL;
}
} while (bsize > blocksize);
}
#endif
-static int zynq_dump(xilinx_desc *desc, const void *buf, size_t bsize)
-{
- return FPGA_FAIL;
-}
-
struct xilinx_fpga_op zynq_op = {
.load = zynq_load,
-#if defined(CONFIG_CMD_FPGA_LOADFS)
+#if defined(CONFIG_CMD_FPGA_LOADFS) && !defined(CONFIG_SPL_BUILD)
.loadfs = zynq_loadfs,
#endif
- .dump = zynq_dump,
- .info = zynq_info,
};
+
+#ifdef CONFIG_CMD_ZYNQ_AES
+/*
+ * Load the encrypted image from src addr and decrypt the image and
+ * place it back the decrypted image into dstaddr.
+ */
+int zynq_decrypt_load(u32 srcaddr, u32 srclen, u32 dstaddr, u32 dstlen)
+{
+ if (srcaddr < SZ_1M || dstaddr < SZ_1M) {
+ printf("%s: src and dst addr should be > 1M\n",
+ __func__);
+ return FPGA_FAIL;
+ }
+
+ if (zynq_dma_xfer_init(BIT_NONE)) {
+ printf("%s: zynq_dma_xfer_init FAIL\n", __func__);
+ return FPGA_FAIL;
+ }
+
+ writel((readl(&devcfg_base->ctrl) | DEVCFG_CTRL_PCAP_RATE_EN_MASK),
+ &devcfg_base->ctrl);
+
+ debug("%s: Source = 0x%08X\n", __func__, (u32)srcaddr);
+ debug("%s: Size = %zu\n", __func__, srclen);
+
+ /* flush(clean & invalidate) d-cache range buf */
+ flush_dcache_range((u32)srcaddr, (u32)srcaddr +
+ roundup(srclen << 2, ARCH_DMA_MINALIGN));
+ /*
+ * Flush destination address range only if image is not
+ * bitstream.
+ */
+ flush_dcache_range((u32)dstaddr, (u32)dstaddr +
+ roundup(dstlen << 2, ARCH_DMA_MINALIGN));
+
+ if (zynq_dma_transfer(srcaddr | 1, srclen, dstaddr | 1, dstlen))
+ return FPGA_FAIL;
+
+ writel((readl(&devcfg_base->ctrl) & ~DEVCFG_CTRL_PCAP_RATE_EN_MASK),
+ &devcfg_base->ctrl);
+
+ return FPGA_SUCCESS;
+}
+#endif