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

#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)

#ifndef MVEBU_SDRAM_SIZE_MAX
#define MVEBU_SDRAM_SIZE_MAX		0xc0000000
#endif

#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);
		if (size == 0)
			continue;

		total = (u64)size;
		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 - 1,
				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;
}

/* Return the width of the DRAM bus, or 0 for unknown. */
static int bus_width(void)
{
	int full_width = 0;

	if (reg_read(REG_SDRAM_CONFIG_ADDR) & (1 << REG_SDRAM_CONFIG_WIDTH_OFFS))
		full_width = 1;

	switch (mvebu_soc_family()) {
	case MVEBU_SOC_AXP:
	    return full_width ? 64 : 32;
	    break;
	case MVEBU_SOC_A375:
	case MVEBU_SOC_A38X:
	case MVEBU_SOC_MSYS:
	    return full_width ? 32 : 16;
	default:
	    return 0;
	}
}

static int cycle_mode(void)
{
	int val = reg_read(REG_DUNIT_CTRL_LOW_ADDR);

	return (val >> REG_DUNIT_CTRL_LOW_2T_OFFS) & REG_DUNIT_CTRL_LOW_2T_MASK;
}

#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 > MVEBU_SDRAM_SIZE_MAX)
			size = MVEBU_SDRAM_SIZE_MAX;
	}

	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.
 */
int 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 > MVEBU_SDRAM_SIZE_MAX)
			mvebu_sdram_bs_set(i, 0x40000000);
	}

	return 0;
}

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

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

	width = bus_width();
	if (width)
		printf("%d-bit, ", width);

	mode = cycle_mode();
	/* Mode 0 = Single cycle
	 * Mode 1 = Two cycles   (2T)
	 * Mode 2 = Three cycles (3T)
	 */
	if (mode == 1)
		printf("2T, ");
	if (mode == 2)
		printf("3T, ");

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