/*
 * (C) Copyright 2007
 * Developed for DENX Software Engineering GmbH.
 *
 * Author: Pavel Kolesnikov <concord@emcraft.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/* define DEBUG for debugging output (obviously ;-)) */
#if 0
#define DEBUG
#endif

#include <common.h>
#include <watchdog.h>

#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)

#include <post.h>

#if CONFIG_POST & CONFIG_SYS_POST_ECC

/*
 * MEMORY ECC test
 *
 * This test performs the checks ECC facility of memory.
 */
#include <asm/processor.h>
#include <asm/mmu.h>
#include <asm/io.h>
#include <asm/ppc440.h>

DECLARE_GLOBAL_DATA_PTR;

#if defined(DEBUG)
const static uint8_t syndrome_codes[] = {
	0xF4, 0XF1, 0XEC, 0XEA, 0XE9, 0XE6, 0XE5, 0XE3,
	0XDC, 0XDA, 0XD9, 0XD6, 0XD5, 0XD3, 0XCE, 0XCB,
	0xB5, 0XB0, 0XAD, 0XAB, 0XA8, 0XA7, 0XA4, 0XA2,
	0X9D, 0X9B, 0X98, 0X97, 0X94, 0X92, 0X8F, 0X8A,
	0x75, 0x70, 0X6D, 0X6B, 0X68, 0X67, 0X64, 0X62,
	0X5E, 0X5B, 0X58, 0X57, 0X54, 0X52, 0X4F, 0X4A,
	0x34, 0x31, 0X2C, 0X2A, 0X29, 0X26, 0X25, 0X23,
	0X1C, 0X1A, 0X19, 0X16, 0X15, 0X13, 0X0E, 0X0B,
	0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
};
#endif

#define ECC_START_ADDR		0x10
#define ECC_STOP_ADDR		0x2000
#define ECC_PATTERN		0x01010101
#define ECC_PATTERN_CORR	0x11010101
#define ECC_PATTERN_UNCORR	0x61010101

inline static void disable_ecc(void)
{
	uint32_t value;

	sync(); /* Wait for any pending memory accesses to complete. */
	mfsdram(DDR0_22, value);
	mtsdram(DDR0_22, (value & ~DDR0_22_CTRL_RAW_MASK)
		| DDR0_22_CTRL_RAW_ECC_DISABLE);
}

inline static void clear_and_enable_ecc(void)
{
	uint32_t value;

	sync(); /* Wait for any pending memory accesses to complete. */
	mfsdram(DDR0_00, value);
	mtsdram(DDR0_00, value | DDR0_00_INT_ACK_ALL);
	mfsdram(DDR0_22, value);
	mtsdram(DDR0_22, (value & ~DDR0_22_CTRL_RAW_MASK)
		| DDR0_22_CTRL_RAW_ECC_ENABLE);
}

static uint32_t get_ecc_status(void)
{
	uint32_t int_status;
#if defined(DEBUG)
	uint8_t syndrome;
	uint32_t hdata, ldata, haddr, laddr;
	uint32_t value;
#endif

	mfsdram(DDR0_00, int_status);
	int_status &= DDR0_00_INT_STATUS_MASK;

#if defined(DEBUG)
	if (int_status & (DDR0_00_INT_STATUS_BIT0 | DDR0_00_INT_STATUS_BIT1)) {
		mfsdram(DDR0_32, laddr);
		mfsdram(DDR0_33, haddr);
		haddr &= 0x00000001;
		if (int_status & DDR0_00_INT_STATUS_BIT1)
			debug("Multiple accesses");
		else
			debug("A single access");

		debug(" outside the defined physical memory space detected\n"
		      "        addr = 0x%01x%08x\n", haddr, laddr);
	}
	if (int_status & (DDR0_00_INT_STATUS_BIT2 | DDR0_00_INT_STATUS_BIT3)) {
		unsigned int bit;

		mfsdram(DDR0_23, value);
		syndrome = (value >> 16) & 0xff;
		for (bit = 0; bit < sizeof(syndrome_codes); bit++)
			if (syndrome_codes[bit] == syndrome)
				break;

		mfsdram(DDR0_38, laddr);
		mfsdram(DDR0_39, haddr);
		haddr &= 0x00000001;
		mfsdram(DDR0_40, ldata);
		mfsdram(DDR0_41, hdata);
		if (int_status & DDR0_00_INT_STATUS_BIT3)
			debug("Multiple correctable ECC events");
		else
			debug("Single correctable ECC event");

		debug(" detected\n        0x%01x%08x - 0x%08x%08x, bit - %d\n",
		      haddr, laddr, hdata, ldata, bit);
	}
	if (int_status & (DDR0_00_INT_STATUS_BIT4 | DDR0_00_INT_STATUS_BIT5)) {
		mfsdram(DDR0_23, value);
		syndrome = (value >> 8) & 0xff;
		mfsdram(DDR0_34, laddr);
		mfsdram(DDR0_35, haddr);
		haddr &= 0x00000001;
		mfsdram(DDR0_36, ldata);
		mfsdram(DDR0_37, hdata);
		if (int_status & DDR0_00_INT_STATUS_BIT5)
			debug("Multiple uncorrectable ECC events");
		else
			debug("Single uncorrectable ECC event");

		debug(" detected\n        0x%01x%08x - 0x%08x%08x, "
		      "syndrome - 0x%02x\n",
		      haddr, laddr, hdata, ldata, syndrome);
	}
	if (int_status & DDR0_00_INT_STATUS_BIT6)
		debug("DRAM initialization complete\n");
#endif /* defined(DEBUG) */

	return int_status;
}

static int test_ecc(uint32_t ecc_addr)
{
	uint32_t value;
	volatile uint32_t *const ecc_mem = (volatile uint32_t *)ecc_addr;
	int ret = 0;

	WATCHDOG_RESET();

	debug("Entering test_ecc(0x%08x)\n", ecc_addr);
	/* Set up correct ECC in memory */
	disable_ecc();
	clear_and_enable_ecc();
	out_be32(ecc_mem, ECC_PATTERN);
	out_be32(ecc_mem + 1, ECC_PATTERN);
	ppcDcbf((u32)ecc_mem);

	/* Verify no ECC error reading back */
	value = in_be32(ecc_mem);
	disable_ecc();
	if (ECC_PATTERN != value) {
		debug("Data read error (no-error case): "
		      "expected 0x%08x, read 0x%08x\n", ECC_PATTERN, value);
		ret = 1;
	}
	value = get_ecc_status();
	if (0x00000000 != value) {
		/* Expected no ECC status reported */
		debug("get_ecc_status(): expected 0x%08x, got 0x%08x\n",
		      0x00000000, value);
		ret = 1;
	}

	/* Test for correctable error by creating a one-bit error */
	out_be32(ecc_mem, ECC_PATTERN_CORR);
	ppcDcbf((u32)ecc_mem);
	clear_and_enable_ecc();
	value = in_be32(ecc_mem);
	disable_ecc();
	/* Test that the corrected data was read */
	if (ECC_PATTERN != value) {
		debug("Data read error (correctable-error case): "
		      "expected 0x%08x, read 0x%08x\n", ECC_PATTERN, value);
		ret = 1;
	}
	value = get_ecc_status();
	if ((DDR0_00_INT_STATUS_BIT2 | DDR0_00_INT_STATUS_BIT7) != value) {
		/* Expected a single correctable error reported */
		debug("get_ecc_status(): expected 0x%08x, got 0x%08x\n",
		      DDR0_00_INT_STATUS_BIT2, value);
		ret = 1;
	}

	/* Test for uncorrectable error by creating a two-bit error */
	out_be32(ecc_mem, ECC_PATTERN_UNCORR);
	ppcDcbf((u32)ecc_mem);
	clear_and_enable_ecc();
	value = in_be32(ecc_mem);
	disable_ecc();
	/* Test that the corrected data was read */
	if (ECC_PATTERN_UNCORR != value) {
		debug("Data read error (uncorrectable-error case): "
		      "expected 0x%08x, read 0x%08x\n", ECC_PATTERN_UNCORR,
		      value);
		ret = 1;
	}
	value = get_ecc_status();
	if ((DDR0_00_INT_STATUS_BIT4 | DDR0_00_INT_STATUS_BIT7) != value) {
		/* Expected a single uncorrectable error reported */
		debug("get_ecc_status(): expected 0x%08x, got 0x%08x\n",
		      DDR0_00_INT_STATUS_BIT4, value);
		ret = 1;
	}

	/* Remove error from SDRAM and enable ECC. */
	out_be32(ecc_mem, ECC_PATTERN);
	ppcDcbf((u32)ecc_mem);
	clear_and_enable_ecc();

	return ret;
}

int ecc_post_test(int flags)
{
	int ret = 0;
	uint32_t value;
	uint32_t iaddr;

	mfsdram(DDR0_22, value);
	if (0x3 != DDR0_22_CTRL_RAW_DECODE(value)) {
		debug("SDRAM ECC not enabled, skipping ECC POST.\n");
		return 0;
	}

	/* Mask all interrupts. */
	mfsdram(DDR0_01, value);
	mtsdram(DDR0_01, (value & ~DDR0_01_INT_MASK_MASK)
		| DDR0_01_INT_MASK_ALL_OFF);

	for (iaddr = ECC_START_ADDR; iaddr <= ECC_STOP_ADDR; iaddr += iaddr) {
		ret = test_ecc(iaddr);
		if (ret)
			break;
	}
	/*
	 * Clear possible errors resulting from ECC testing.  (If not done, we
	 * we could get an interrupt later on when exceptions are enabled.)
	 */
	set_mcsr(get_mcsr());
	debug("ecc_post_test() returning %d\n", ret);
	return ret;
}
#endif /* CONFIG_POST & CONFIG_SYS_POST_ECC */
#endif /* defined(CONFIG_440EPX) || defined(CONFIG_440GRX) */
