X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Ffpga%2Fzynqmppl.c;h=d129b5459c005db9e46c7d856f8c574f06c0a3f6;hb=3a79c6052ac82f9b5c554858a0215aa061ef03ec;hp=57a4e6c88e7a122483f29d016dff67eba2371267;hpb=784667d7f9452780966dd0b400ef516f14f14c26;p=oweals%2Fu-boot.git diff --git a/drivers/fpga/zynqmppl.c b/drivers/fpga/zynqmppl.c index 57a4e6c88e..d129b5459c 100644 --- a/drivers/fpga/zynqmppl.c +++ b/drivers/fpga/zynqmppl.c @@ -1,16 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 /* * (C) Copyright 2015 - 2016, Xilinx, Inc, * Michal Simek * Siva Durga Prasad - * - * SPDX-License-Identifier: GPL-2.0 */ #include #include #include +#include #include #include +#include #define DUMMY_WORD 0xffffffff @@ -150,9 +151,10 @@ static ulong zynqmp_align_dma_buffer(u32 *buf, u32 len, u32 swap) new_buf[i] = load_word(&buf[i], swap); buf = new_buf; - } else if (swap != SWAP_DONE) { + } else if ((swap != SWAP_DONE) && + (zynqmp_firmware_version() <= PMUFW_V1_0)) { /* For bitstream which are aligned */ - u32 *new_buf = (u32 *)buf; + new_buf = buf; printf("%s: Bitstream is not swapped(%d) - swap it\n", __func__, swap); @@ -195,35 +197,112 @@ static int zynqmp_validate_bitstream(xilinx_desc *desc, const void *buf, static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize, bitstream_type bstype) { - u32 swap; + ALLOC_CACHE_ALIGN_BUFFER(u32, bsizeptr, 1); + u32 swap = 0; ulong bin_buf; int ret; u32 buf_lo, buf_hi; u32 ret_payload[PAYLOAD_ARG_CNT]; - - if (zynqmp_validate_bitstream(desc, buf, bsize, bsize, &swap)) - return FPGA_FAIL; + bool xilfpga_old = false; + + if (zynqmp_firmware_version() <= PMUFW_V1_0) { + puts("WARN: PMUFW v1.0 or less is detected\n"); + puts("WARN: Not all bitstream formats are supported\n"); + puts("WARN: Please upgrade PMUFW\n"); + xilfpga_old = true; + if (zynqmp_validate_bitstream(desc, buf, bsize, bsize, &swap)) + return FPGA_FAIL; + bsizeptr = (u32 *)&bsize; + flush_dcache_range((ulong)bsizeptr, + (ulong)bsizeptr + sizeof(size_t)); + bstype |= BIT(ZYNQMP_FPGA_BIT_NS); + } bin_buf = zynqmp_align_dma_buffer((u32 *)buf, bsize, swap); debug("%s called!\n", __func__); flush_dcache_range(bin_buf, bin_buf + bsize); - if (bsize % 4) - bsize = bsize / 4 + 1; - else - bsize = bsize / 4; - buf_lo = (u32)bin_buf; buf_hi = upper_32_bits(bin_buf); - ret = invoke_smc(ZYNQMP_SIP_SVC_PM_FPGA_LOAD, buf_lo, buf_hi, bsize, - bstype, ret_payload); + + if (xilfpga_old) + ret = xilinx_pm_request(ZYNQMP_SIP_SVC_PM_FPGA_LOAD, buf_lo, + buf_hi, (u32)(uintptr_t)bsizeptr, + bstype, ret_payload); + else + ret = xilinx_pm_request(ZYNQMP_SIP_SVC_PM_FPGA_LOAD, buf_lo, + buf_hi, (u32)bsize, 0, ret_payload); + + if (ret) + puts("PL FPGA LOAD fail\n"); + + return ret; +} + +#if defined(CONFIG_CMD_FPGA_LOAD_SECURE) && !defined(CONFIG_SPL_BUILD) +static int zynqmp_loads(xilinx_desc *desc, const void *buf, size_t bsize, + struct fpga_secure_info *fpga_sec_info) +{ + int ret; + u32 buf_lo, buf_hi; + u32 ret_payload[PAYLOAD_ARG_CNT]; + u8 flag = 0; + + flush_dcache_range((ulong)buf, (ulong)buf + + ALIGN(bsize, CONFIG_SYS_CACHELINE_SIZE)); + + if (!fpga_sec_info->encflag) + flag |= BIT(ZYNQMP_FPGA_BIT_ENC_DEV_KEY); + + if (fpga_sec_info->userkey_addr && + fpga_sec_info->encflag == FPGA_ENC_USR_KEY) { + flush_dcache_range((ulong)fpga_sec_info->userkey_addr, + (ulong)fpga_sec_info->userkey_addr + + ALIGN(KEY_PTR_LEN, + CONFIG_SYS_CACHELINE_SIZE)); + flag |= BIT(ZYNQMP_FPGA_BIT_ENC_USR_KEY); + } + + if (!fpga_sec_info->authflag) + flag |= BIT(ZYNQMP_FPGA_BIT_AUTH_OCM); + + if (fpga_sec_info->authflag == ZYNQMP_FPGA_AUTH_DDR) + flag |= BIT(ZYNQMP_FPGA_BIT_AUTH_DDR); + + buf_lo = lower_32_bits((ulong)buf); + buf_hi = upper_32_bits((ulong)buf); + + ret = xilinx_pm_request(ZYNQMP_SIP_SVC_PM_FPGA_LOAD, buf_lo, + buf_hi, + (u32)(uintptr_t)fpga_sec_info->userkey_addr, + flag, ret_payload); if (ret) - debug("PL FPGA LOAD fail\n"); + puts("PL FPGA LOAD fail\n"); + else + puts("Bitstream successfully loaded\n"); + + return ret; +} +#endif + +static int zynqmp_pcap_info(xilinx_desc *desc) +{ + int ret; + u32 ret_payload[PAYLOAD_ARG_CNT]; + + ret = xilinx_pm_request(ZYNQMP_SIP_SVC_PM_FPGA_STATUS, 0, 0, 0, + 0, ret_payload); + if (!ret) + printf("PCAP status\t0x%x\n", ret_payload[1]); return ret; } struct xilinx_fpga_op zynqmp_op = { .load = zynqmp_load, +#if defined CONFIG_CMD_FPGA_LOAD_SECURE + .loads = zynqmp_loads, +#endif + .info = zynqmp_pcap_info, };