// SPDX-License-Identifier: GPL-2.0
/*
 * (C) Copyright 2015 - 2016, Xilinx, Inc,
 * Michal Simek <michal.simek@xilinx.com>
 * Siva Durga Prasad <siva.durga.paladugu@xilinx.com>
 */

#include <console.h>
#include <common.h>
#include <cpu_func.h>
#include <log.h>
#include <zynqmppl.h>
#include <zynqmp_firmware.h>
#include <asm/cache.h>
#include <linux/sizes.h>
#include <asm/arch/sys_proto.h>
#include <memalign.h>

#define DUMMY_WORD	0xffffffff

/* Xilinx binary format header */
static const u32 bin_format[] = {
	DUMMY_WORD, /* Dummy words */
	DUMMY_WORD,
	DUMMY_WORD,
	DUMMY_WORD,
	DUMMY_WORD,
	DUMMY_WORD,
	DUMMY_WORD,
	DUMMY_WORD,
	DUMMY_WORD,
	DUMMY_WORD,
	DUMMY_WORD,
	DUMMY_WORD,
	DUMMY_WORD,
	DUMMY_WORD,
	DUMMY_WORD,
	DUMMY_WORD,
	0x000000bb, /* Sync word */
	0x11220044, /* Sync word */
	DUMMY_WORD,
	DUMMY_WORD,
	0xaa995566, /* Sync word */
};

#define SWAP_NO		1
#define SWAP_DONE	2

/*
 * Load the whole word from unaligned buffer
 * Keep in your mind that it is byte loading on little-endian system
 */
static u32 load_word(const void *buf, u32 swap)
{
	u32 word = 0;
	u8 *bitc = (u8 *)buf;
	int p;

	if (swap == SWAP_NO) {
		for (p = 0; p < 4; p++) {
			word <<= 8;
			word |= bitc[p];
		}
	} else {
		for (p = 3; p >= 0; p--) {
			word <<= 8;
			word |= bitc[p];
		}
	}

	return word;
}

static u32 check_header(const void *buf)
{
	u32 i, pattern;
	int swap = SWAP_NO;
	u32 *test = (u32 *)buf;

	debug("%s: Let's check bitstream header\n", __func__);

	/* Checking that passing bin is not a bitstream */
	for (i = 0; i < ARRAY_SIZE(bin_format); i++) {
		pattern = load_word(&test[i], swap);

		/*
		 * Bitstreams in binary format are swapped
		 * compare to regular bistream.
		 * Do not swap dummy word but if swap is done assume
		 * that parsing buffer is binary format
		 */
		if ((__swab32(pattern) != DUMMY_WORD) &&
		    (__swab32(pattern) == bin_format[i])) {
			swap = SWAP_DONE;
			debug("%s: data swapped - let's swap\n", __func__);
		}

		debug("%s: %d/%px: pattern %x/%x bin_format\n", __func__, i,
		      &test[i], pattern, bin_format[i]);
	}
	debug("%s: Found bitstream header at %px %s swapinng\n", __func__,
	      buf, swap == SWAP_NO ? "without" : "with");

	return swap;
}

static void *check_data(u8 *buf, size_t bsize, u32 *swap)
{
	u32 word, p = 0; /* possition */

	/* Because buf doesn't need to be aligned let's read it by chars */
	for (p = 0; p < bsize; p++) {
		word = load_word(&buf[p], SWAP_NO);
		debug("%s: word %x %x/%px\n", __func__, word, p, &buf[p]);

		/* Find the first bitstream dummy word */
		if (word == DUMMY_WORD) {
			debug("%s: Found dummy word at position %x/%px\n",
			      __func__, p, &buf[p]);
			*swap = check_header(&buf[p]);
			if (*swap) {
				/* FIXME add full bitstream checking here */
				return &buf[p];
			}
		}
		/* Loop can be huge - support CTRL + C */
		if (ctrlc())
			return NULL;
	}
	return NULL;
}

static ulong zynqmp_align_dma_buffer(u32 *buf, u32 len, u32 swap)
{
	u32 *new_buf;
	u32 i;

	if ((ulong)buf != ALIGN((ulong)buf, ARCH_DMA_MINALIGN)) {
		new_buf = (u32 *)ALIGN((ulong)buf, ARCH_DMA_MINALIGN);

		/*
		 * This might be dangerous but permits to flash if
		 * ARCH_DMA_MINALIGN is greater than header size
		 */
		if (new_buf > (u32 *)buf) {
			debug("%s: Aligned buffer is after buffer start\n",
			      __func__);
			new_buf -= ARCH_DMA_MINALIGN;
		}
		printf("%s: Align buffer at %px to %px(swap %d)\n", __func__,
		       buf, new_buf, swap);

		for (i = 0; i < (len/4); i++)
			new_buf[i] = load_word(&buf[i], swap);

		buf = new_buf;
	} else if ((swap != SWAP_DONE) &&
		   (zynqmp_firmware_version() <= PMUFW_V1_0)) {
		/* For bitstream which are aligned */
		new_buf = buf;

		printf("%s: Bitstream is not swapped(%d) - swap it\n", __func__,
		       swap);

		for (i = 0; i < (len/4); i++)
			new_buf[i] = load_word(&buf[i], swap);
	}

	return (ulong)buf;
}

static int zynqmp_validate_bitstream(xilinx_desc *desc, const void *buf,
				   size_t bsize, u32 blocksize, u32 *swap)
{
	ulong *buf_start;
	ulong diff;

	buf_start = check_data((u8 *)buf, blocksize, swap);

	if (!buf_start)
		return FPGA_FAIL;

	/* Check if data is postpone from start */
	diff = (ulong)buf_start - (ulong)buf;
	if (diff) {
		printf("%s: Bitstream is not validated yet (diff %lx)\n",
		       __func__, diff);
		return FPGA_FAIL;
	}

	if ((ulong)buf < SZ_1M) {
		printf("%s: Bitstream has to be placed up to 1MB (%px)\n",
		       __func__, buf);
		return FPGA_FAIL;
	}

	return 0;
}

static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize,
		     bitstream_type bstype)
{
	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];
	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);

	buf_lo = (u32)bin_buf;
	buf_hi = upper_32_bits(bin_buf);

	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)
		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,
};
