/*
 * (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
 *
 * Developed for DENX Software Engineering GmbH
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */
#include <common.h>

/* This test performs testing of FPGA SCRATCH register,
 * gets FPGA version and run get_ram_size() on FPGA memory
 */

#include <post.h>
#include <watchdog.h>
#include <asm/io.h>

DECLARE_GLOBAL_DATA_PTR;

#define FPGA_SCRATCH_REG	0xC4000050
#define FPGA_VERSION_REG	0xC4000040
#define FPGA_RAM_START		0xC4200000
#define FPGA_RAM_END		0xC4203FFF
#define FPGA_STAT		0xC400000C
#define FPGA_BUFFER		0x00800000
#define FPGA_RAM_SIZE		(FPGA_RAM_END - FPGA_RAM_START + 1)

#if CONFIG_POST & CONFIG_SYS_POST_BSPEC3

const static unsigned long pattern[] = {
	0xffffffff,
	0xaaaaaaaa,
	0xcccccccc,
	0xf0f0f0f0,
	0xff00ff00,
	0xffff0000,
	0x0000ffff,
	0x00ff00ff,
	0x0f0f0f0f,
	0x33333333,
	0x55555555,
	0x00000000,
};

const static unsigned long otherpattern = 0x01234567;

static int one_scratch_test(uint value)
{
	uint read_value;
	int ret = 0;

	out_be32((void *)FPGA_SCRATCH_REG, value);
	/* read other location (protect against data lines capacity) */
	ret = in_be16((void *)FPGA_VERSION_REG);
	/* verify test pattern */
	read_value = in_be32((void *)FPGA_SCRATCH_REG);
	if (read_value != value) {
		post_log("FPGA SCRATCH test failed write %08X, read %08X\n",
			 value, read_value);
		ret = -1;
	}

	return ret;
}

static int fpga_post_test1(ulong *start, ulong size, ulong val)
{
	int ret = 0;
	ulong i = 0;
	ulong *mem = start;
	ulong readback;

	for (i = 0; i < size / sizeof(ulong); i++) {
		mem[i] = val;
		if (i % 1024 == 0)
			WATCHDOG_RESET();
	}

	for (i = 0; i < size / sizeof(ulong); i++) {
		readback = mem[i];
		if (readback != val) {
			post_log("FPGA Memory error at %08x, "
				 "wrote %08x, read %08x !\n",
				 mem + i, val, readback);
			ret = -1;
			break;
		}
		if (i % 1024 == 0)
			WATCHDOG_RESET();
	}
	return ret;
}

static int fpga_post_test2(ulong *start, ulong size)
{
	int ret = 0;
	ulong i = 0;
	ulong *mem = start;
	ulong readback;

	for (i = 0; i < size / sizeof(ulong); i++) {
		mem[i] = 1 << (i % 32);
		if (i % 1024 == 0)
			WATCHDOG_RESET();
	}

	for (i = 0; i < size / sizeof(ulong); i++) {
		readback = mem[i];
		if (readback != 1 << (i % 32)) {
			post_log("FPGA Memory error at %08x, "
				 "wrote %08x, read %08x !\n",
				 mem + i, 1 << (i % 32), readback);
			ret = -1;
			break;
		}
		if (i % 1024 == 0)
			WATCHDOG_RESET();
	}

	return ret;
}

static int fpga_post_test3(ulong *start, ulong size)
{
	int ret = 0;
	ulong i = 0;
	ulong *mem = start;
	ulong readback;

	for (i = 0; i < size / sizeof(ulong); i++) {
		mem[i] = i;
		if (i % 1024 == 0)
			WATCHDOG_RESET();
	}

	for (i = 0; i < size / sizeof(ulong); i++) {
		readback = mem[i];
		if (readback != i) {
			post_log("FPGA Memory error at %08x, "
				 "wrote %08x, read %08x !\n",
				 mem + i, i, readback);
			ret = -1;
			break;
		}
		if (i % 1024 == 0)
			WATCHDOG_RESET();
	}

	return ret;
}

static int fpga_post_test4(ulong *start, ulong size)
{
	int ret = 0;
	ulong i = 0;
	ulong *mem = start;
	ulong readback;

	for (i = 0; i < size / sizeof(ulong); i++) {
		mem[i] = ~i;
		if (i % 1024 == 0)
			WATCHDOG_RESET();
	}

	for (i = 0; i < size / sizeof(ulong); i++) {
		readback = mem[i];
		if (readback != ~i) {
			post_log("FPGA Memory error at %08x, "
				 "wrote %08x, read %08x !\n",
				 mem + i, ~i, readback);
			ret = -1;
			break;
		}
		if (i % 1024 == 0)
			WATCHDOG_RESET();
	}

	return ret;
}

/* FPGA Memory-pattern-test */
static int fpga_mem_test(void)
{
	int ret = 0;
	ulong* start = (ulong *)FPGA_RAM_START;
	ulong  size  = FPGA_RAM_SIZE;

	if (ret == 0)
		ret = fpga_post_test1(start, size, 0x00000000);

	if (ret == 0)
		ret = fpga_post_test1(start, size, 0xffffffff);

	if (ret == 0)
		ret = fpga_post_test1(start, size, 0x55555555);

	if (ret == 0)
		ret = fpga_post_test1(start, size, 0xaaaaaaaa);

	WATCHDOG_RESET();

	if (ret == 0)
		ret = fpga_post_test2(start, size);

	if (ret == 0)
		ret = fpga_post_test3(start, size);

	if (ret == 0)
		ret = fpga_post_test4(start, size);

	return ret;
}

/* Verify FPGA addresslines */
static int fpga_post_addrline(ulong *address, ulong *base, ulong size)
{
	unsigned long *target;
	unsigned long *end;
	unsigned long readback;
	unsigned long xor;
	int ret = 0;

	end = (ulong *)((ulong)base + size);
	xor = 0;

	for (xor = sizeof(ulong); xor > 0; xor <<= 1) {
		target = (ulong*)((ulong)address ^ xor);
		if ((target >= base) && (target < end)) {
			*address = ~*target;
			readback = *target;

			if (readback == *address) {
				post_log("Memory (address line) error at %08x"
					 "XOR value %08x !\n",
					 address, target, xor);
				ret = -1;
				break;
			}
		}
	}

	return ret;
}

/* Verify FPGA addresslines */
static int fpga_post_dataline(ulong *address)
{
	unsigned long temp32 = 0;
	int i = 0;
	int ret = 0;

	for (i = 0; i < ARRAY_SIZE(pattern); i++) {
		*address = pattern[i];
		/*
		 * Put a different pattern on the data lines: otherwise they
		 * may float long enough to read back what we wrote.
		 */
		*(address + 1) = otherpattern;
		temp32 = *address;

		if (temp32 != pattern[i]){
			post_log("Memory (date line) error at %08x, "
				 "wrote %08x, read %08x !\n",
				 address, pattern[i], temp32);
			ret = 1;
		}
	}

	return ret;
}

/* Verify FPGA, get version & memory size */
int fpga_post_test(int flags)
{
	uint   old_value;
	uint   version;
	uint   read_value;
	int    ret = 0;

	post_log("\n");
	old_value = in_be32((void *)FPGA_SCRATCH_REG);

	if (one_scratch_test(0x55555555))
		ret = 1;
	if (one_scratch_test(0xAAAAAAAA))
		ret = 1;

	out_be32((void *)FPGA_SCRATCH_REG, old_value);

	version = in_be32((void *)FPGA_VERSION_REG);
	post_log("FPGA version %u.%u\n",
		 (version >> 8) & 0xFF, version & 0xFF);

	/* Enable write to FPGA RAM */
	out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) | 0x1000);

	/* get RAM size */
	read_value = get_ram_size((void *)CONFIG_SYS_FPGA_BASE_1, FPGA_RAM_SIZE);
	post_log("FPGA RAM size %d bytes\n", read_value);
	WATCHDOG_RESET();

	/* copy fpga memory to DDR2 RAM*/
	memcpy((void *)FPGA_BUFFER,(void *)FPGA_RAM_START, FPGA_RAM_SIZE);
	WATCHDOG_RESET();

	/* Test datalines */
	if (fpga_post_dataline((ulong *)FPGA_RAM_START)) {
		ret = 1;
		goto out;
	}
	WATCHDOG_RESET();

	/* Test addresslines */
	if (fpga_post_addrline((ulong *)FPGA_RAM_START,
			       (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
		ret = 1;
		goto out;
	}
	WATCHDOG_RESET();
	if (fpga_post_addrline((ulong *)FPGA_RAM_END - sizeof(long),
			       (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
		ret = 1;
		goto out;
	}
	WATCHDOG_RESET();

	/* Memory Pattern Test */
	if (fpga_mem_test()) {
		ret = 1;
		goto out;
	}
	WATCHDOG_RESET();

	/* restore memory */
	memcpy((void *)FPGA_RAM_START,(void *)FPGA_BUFFER, FPGA_RAM_SIZE);
	WATCHDOG_RESET();

out:
	/* Disable write to RAM */
	out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) & 0xEFFF);
	return ret;
}

#endif /* CONFIG_POST & CONFIG_SYS_POST_BSPEC3 */
