/*
 * (C) Copyright 2009
 * Marvell Semiconductor <www.marvell.com>
 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <config.h>
#include <common.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/soc.h>

#if defined(CONFIG_ARCH_MVEBU)
/* Use common XOR definitions for A3x and AXP */
#include "../../../drivers/ddr/marvell/axp/xor.h"
#include "../../../drivers/ddr/marvell/axp/xor_regs.h"
#endif

DECLARE_GLOBAL_DATA_PTR;

struct sdram_bank {
	u32	win_bar;
	u32	win_sz;
};

struct sdram_addr_dec {
	struct sdram_bank sdram_bank[4];
};

#define REG_CPUCS_WIN_ENABLE		(1 << 0)
#define REG_CPUCS_WIN_WR_PROTECT	(1 << 1)
#define REG_CPUCS_WIN_WIN0_CS(x)	(((x) & 0x3) << 2)
#define REG_CPUCS_WIN_SIZE(x)		(((x) & 0xff) << 24)

#define SDRAM_SIZE_MAX			0xc0000000

#define SCRUB_MAGIC		0xbeefdead

#define SCRB_XOR_UNIT		0
#define SCRB_XOR_CHAN		1
#define SCRB_XOR_WIN		0

#define XEBARX_BASE_OFFS	16

/*
 * mvebu_sdram_bar - reads SDRAM Base Address Register
 */
u32 mvebu_sdram_bar(enum memory_bank bank)
{
	struct sdram_addr_dec *base =
		(struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
	u32 result = 0;
	u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz);

	if ((!enable) || (bank > BANK3))
		return 0;

	result = readl(&base->sdram_bank[bank].win_bar);
	return result;
}

/*
 * mvebu_sdram_bs_set - writes SDRAM Bank size
 */
static void mvebu_sdram_bs_set(enum memory_bank bank, u32 size)
{
	struct sdram_addr_dec *base =
		(struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
	/* Read current register value */
	u32 reg = readl(&base->sdram_bank[bank].win_sz);

	/* Clear window size */
	reg &= ~REG_CPUCS_WIN_SIZE(0xFF);

	/* Set new window size */
	reg |= REG_CPUCS_WIN_SIZE((size - 1) >> 24);

	writel(reg, &base->sdram_bank[bank].win_sz);
}

/*
 * mvebu_sdram_bs - reads SDRAM Bank size
 */
u32 mvebu_sdram_bs(enum memory_bank bank)
{
	struct sdram_addr_dec *base =
		(struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
	u32 result = 0;
	u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz);

	if ((!enable) || (bank > BANK3))
		return 0;
	result = 0xff000000 & readl(&base->sdram_bank[bank].win_sz);
	result += 0x01000000;
	return result;
}

void mvebu_sdram_size_adjust(enum memory_bank bank)
{
	u32 size;

	/* probe currently equipped RAM size */
	size = get_ram_size((void *)mvebu_sdram_bar(bank),
			    mvebu_sdram_bs(bank));

	/* adjust SDRAM window size accordingly */
	mvebu_sdram_bs_set(bank, size);
}

#if defined(CONFIG_ARCH_MVEBU)
static u32 xor_ctrl_save;
static u32 xor_base_save;
static u32 xor_mask_save;

static void mv_xor_init2(u32 cs)
{
	u32 reg, base, size, base2;
	u32 bank_attr[4] = { 0xe00, 0xd00, 0xb00, 0x700 };

	xor_ctrl_save = reg_read(XOR_WINDOW_CTRL_REG(SCRB_XOR_UNIT,
						     SCRB_XOR_CHAN));
	xor_base_save = reg_read(XOR_BASE_ADDR_REG(SCRB_XOR_UNIT,
						   SCRB_XOR_WIN));
	xor_mask_save = reg_read(XOR_SIZE_MASK_REG(SCRB_XOR_UNIT,
						   SCRB_XOR_WIN));

	/* Enable Window x for each CS */
	reg = 0x1;
	reg |= (0x3 << 16);
	reg_write(XOR_WINDOW_CTRL_REG(SCRB_XOR_UNIT, SCRB_XOR_CHAN), reg);

	base = 0;
	size = mvebu_sdram_bs(cs) - 1;
	if (size) {
		base2 = ((base / (64 << 10)) << XEBARX_BASE_OFFS) |
			bank_attr[cs];
		reg_write(XOR_BASE_ADDR_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN),
			  base2);

		base += size + 1;
		size = (size / (64 << 10)) << 16;
		/* Window x - size - 256 MB */
		reg_write(XOR_SIZE_MASK_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN), size);
	}

	mv_xor_hal_init(0);

	return;
}

static void mv_xor_finish2(void)
{
	reg_write(XOR_WINDOW_CTRL_REG(SCRB_XOR_UNIT, SCRB_XOR_CHAN),
		  xor_ctrl_save);
	reg_write(XOR_BASE_ADDR_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN),
		  xor_base_save);
	reg_write(XOR_SIZE_MASK_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN),
		  xor_mask_save);
}

static void dram_ecc_scrubbing(void)
{
	int cs;
	u32 size, temp;
	u32 total_mem = 0;
	u64 total;
	u32 start_addr;

	/*
	 * The DDR training code from the bin_hdr / SPL already
	 * scrubbed the DDR till 0x1000000. And the main U-Boot
	 * is loaded to an address < 0x1000000. So we need to
	 * skip this range to not re-scrub this area again.
	 */
	temp = reg_read(REG_SDRAM_CONFIG_ADDR);
	temp |= (1 << REG_SDRAM_CONFIG_IERR_OFFS);
	reg_write(REG_SDRAM_CONFIG_ADDR, temp);

	for (cs = 0; cs < CONFIG_NR_DRAM_BANKS; cs++) {
		size = mvebu_sdram_bs(cs) - 1;
		if (size == 0)
			continue;

		total = (u64)size + 1;
		total_mem += (u32)(total / (1 << 30));
		start_addr = 0;
		mv_xor_init2(cs);

		/* Skip first 16 MiB */
		if (0 == cs) {
			start_addr = 0x1000000;
			size -= start_addr;
		}

		mv_xor_mem_init(SCRB_XOR_CHAN, start_addr, size,
				SCRUB_MAGIC, SCRUB_MAGIC);

		/* Wait for previous transfer completion */
		while (mv_xor_state_get(SCRB_XOR_CHAN) != MV_IDLE)
			;

		mv_xor_finish2();
	}

	temp = reg_read(REG_SDRAM_CONFIG_ADDR);
	temp &= ~(1 << REG_SDRAM_CONFIG_IERR_OFFS);
	reg_write(REG_SDRAM_CONFIG_ADDR, temp);
}

static int ecc_enabled(void)
{
	if (reg_read(REG_SDRAM_CONFIG_ADDR) & (1 << REG_SDRAM_CONFIG_ECC_OFFS))
		return 1;

	return 0;
}
#else
static void dram_ecc_scrubbing(void)
{
}

static int ecc_enabled(void)
{
	return 0;
}
#endif

int dram_init(void)
{
	u64 size = 0;
	int i;

	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
		/*
		 * It is assumed that all memory banks are consecutive
		 * and without gaps.
		 * If the gap is found, ram_size will be reported for
		 * consecutive memory only
		 */
		if (mvebu_sdram_bar(i) != size)
			break;

		/*
		 * Don't report more than 3GiB of SDRAM, otherwise there is no
		 * address space left for the internal registers etc.
		 */
		size += mvebu_sdram_bs(i);
		if (size > SDRAM_SIZE_MAX)
			size = SDRAM_SIZE_MAX;
	}

	for (; i < CONFIG_NR_DRAM_BANKS; i++) {
		/* If above loop terminated prematurely, we need to set
		 * remaining banks' start address & size as 0. Otherwise other
		 * u-boot functions and Linux kernel gets wrong values which
		 * could result in crash */
		gd->bd->bi_dram[i].start = 0;
		gd->bd->bi_dram[i].size = 0;
	}


	if (ecc_enabled())
		dram_ecc_scrubbing();

	gd->ram_size = size;

	return 0;
}

/*
 * If this function is not defined here,
 * board.c alters dram bank zero configuration defined above.
 */
void dram_init_banksize(void)
{
	u64 size = 0;
	int i;

	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
		gd->bd->bi_dram[i].start = mvebu_sdram_bar(i);
		gd->bd->bi_dram[i].size = mvebu_sdram_bs(i);

		/* Clip the banksize to 1GiB if it exceeds the max size */
		size += gd->bd->bi_dram[i].size;
		if (size > SDRAM_SIZE_MAX)
			mvebu_sdram_bs_set(i, 0x40000000);
	}
}

#if defined(CONFIG_ARCH_MVEBU)
void board_add_ram_info(int use_default)
{
	struct sar_freq_modes sar_freq;

	get_sar_freq(&sar_freq);
	printf(" (%d MHz, ", sar_freq.d_clk);

	if (ecc_enabled())
		printf("ECC");
	else
		printf("ECC not");
	printf(" enabled)");
}
#endif
