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

#include <common.h>
#include <command.h>
#include <cpu_func.h>
#include <env.h>
#include <init.h>
#include <log.h>
#include <net.h>
#include <netdev.h>
#include <asm/cache.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/soc.h>
#include <mvebu_mmc.h>

void reset_cpu(unsigned long ignored)
{
	struct kwcpu_registers *cpureg =
	    (struct kwcpu_registers *)KW_CPU_REG_BASE;

	writel(readl(&cpureg->rstoutn_mask) | (1 << 2),
		&cpureg->rstoutn_mask);
	writel(readl(&cpureg->sys_soft_rst) | 1,
		&cpureg->sys_soft_rst);
	while (1) ;
}

/*
 * Window Size
 * Used with the Base register to set the address window size and location.
 * Must be programmed from LSB to MSB as sequence of ones followed by
 * sequence of zeros. The number of ones specifies the size of the window in
 * 64 KByte granularity (e.g., a value of 0x00FF specifies 256 = 16 MByte).
 * NOTE: A value of 0x0 specifies 64-KByte size.
 */
unsigned int kw_winctrl_calcsize(unsigned int sizeval)
{
	int i;
	unsigned int j = 0;
	u32 val = sizeval >> 1;

	for (i = 0; val >= 0x10000; i++) {
		j |= (1 << i);
		val = val >> 1;
	}
	return (0x0000ffff & j);
}

static struct mbus_win windows[] = {
	/* Window 0: PCIE MEM address space */
	{ KW_DEFADR_PCI_MEM, 1024 * 1024 * 256,
	  KWCPU_TARGET_PCIE, KWCPU_ATTR_PCIE_MEM },

	/* Window 1: PCIE IO address space */
	{ KW_DEFADR_PCI_IO, 1024 * 64,
	  KWCPU_TARGET_PCIE, KWCPU_ATTR_PCIE_IO },

	/* Window 2: NAND Flash address space */
	{ KW_DEFADR_NANDF, 1024 * 1024 * 128,
	  KWCPU_TARGET_MEMORY, KWCPU_ATTR_NANDFLASH },

	/* Window 3: SPI Flash address space */
	{ KW_DEFADR_SPIF, 1024 * 1024 * 128,
	  KWCPU_TARGET_MEMORY, KWCPU_ATTR_SPIFLASH },

	/* Window 4: BOOT Memory address space */
	{ KW_DEFADR_BOOTROM, 1024 * 1024 * 128,
	  KWCPU_TARGET_MEMORY, KWCPU_ATTR_BOOTROM },

	/* Window 5: Security SRAM address space */
	{ KW_DEFADR_SASRAM, 1024 * 64,
	  KWCPU_TARGET_SASRAM, KWCPU_ATTR_SASRAM },
};

/*
 * SYSRSTn Duration Counter Support
 *
 * Kirkwood SoC implements a hardware-based SYSRSTn duration counter.
 * When SYSRSTn is asserted low, a SYSRSTn duration counter is running.
 * The SYSRSTn duration counter is useful for implementing a manufacturer
 * or factory reset. Upon a long reset assertion that is greater than a
 * pre-configured environment variable value for sysrstdelay,
 * The counter value is stored in the SYSRSTn Length Counter Register
 * The counter is based on the 25-MHz reference clock (40ns)
 * It is a 29-bit counter, yielding a maximum counting duration of
 * 2^29/25 MHz (21.4 seconds). When the counter reach its maximum value,
 * it remains at this value until counter reset is triggered by setting
 * bit 31 of KW_REG_SYSRST_CNT
 */
static void kw_sysrst_action(void)
{
	int ret;
	char *s = env_get("sysrstcmd");

	if (!s) {
		debug("Error.. %s failed, check sysrstcmd\n",
			__FUNCTION__);
		return;
	}

	debug("Starting %s process...\n", __FUNCTION__);
	ret = run_command(s, 0);
	if (ret != 0)
		debug("Error.. %s failed\n", __FUNCTION__);
	else
		debug("%s process finished\n", __FUNCTION__);
}

static void kw_sysrst_check(void)
{
	u32 sysrst_cnt, sysrst_dly;
	char *s;

	/*
	 * no action if sysrstdelay environment variable is not defined
	 */
	s = env_get("sysrstdelay");
	if (s == NULL)
		return;

	/* read sysrstdelay value */
	sysrst_dly = (u32) simple_strtoul(s, NULL, 10);

	/* read SysRst Length counter register (bits 28:0) */
	sysrst_cnt = (0x1fffffff & readl(KW_REG_SYSRST_CNT));
	debug("H/w Rst hold time: %d.%d secs\n",
		sysrst_cnt / SYSRST_CNT_1SEC_VAL,
		sysrst_cnt % SYSRST_CNT_1SEC_VAL);

	/* clear the counter for next valid read*/
	writel(1 << 31, KW_REG_SYSRST_CNT);

	/*
	 * sysrst_action:
	 * if H/w Reset key is pressed and hold for time
	 * more than sysrst_dly in seconds
	 */
	if (sysrst_cnt >= SYSRST_CNT_1SEC_VAL * sysrst_dly)
		kw_sysrst_action();
}

#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
	char *rev = "??";
	u16 devid = (readl(KW_REG_PCIE_DEVID) >> 16) & 0xffff;
	u8 revid = readl(KW_REG_PCIE_REVID) & 0xff;

	if ((readl(KW_REG_DEVICE_ID) & 0x03) > 2) {
		printf("Error.. %s:Unsupported Kirkwood SoC 88F%04x\n", __FUNCTION__, devid);
		return -1;
	}

	switch (revid) {
	case 0:
		if (devid == 0x6281)
			rev = "Z0";
		else if (devid == 0x6282)
			rev = "A0";
		break;
	case 1:
		rev = "A1";
		break;
	case 2:
		rev = "A0";
		break;
	case 3:
		rev = "A1";
		break;
	default:
		break;
	}

	printf("SoC:   Kirkwood 88F%04x_%s\n", devid, rev);
	return 0;
}
#endif /* CONFIG_DISPLAY_CPUINFO */

#ifdef CONFIG_ARCH_CPU_INIT
int arch_cpu_init(void)
{
	u32 reg;
	struct kwcpu_registers *cpureg =
		(struct kwcpu_registers *)KW_CPU_REG_BASE;

	/* Linux expects the internal registers to be at 0xf1000000 */
	writel(KW_REGS_PHY_BASE, KW_OFFSET_REG);

	/* Enable and invalidate L2 cache in write through mode */
	writel(readl(&cpureg->l2_cfg) | 0x18, &cpureg->l2_cfg);
	invalidate_l2_cache();

#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8
	/*
	 * Configures the I/O voltage of the pads connected to Egigabit
	 * Ethernet interface to 1.8V
	 * By default it is set to 3.3V
	 */
	reg = readl(KW_REG_MPP_OUT_DRV_REG);
	reg |= (1 << 7);
	writel(reg, KW_REG_MPP_OUT_DRV_REG);
#endif
#ifdef CONFIG_KIRKWOOD_EGIGA_INIT
	/*
	 * Set egiga port0/1 in normal functional mode
	 * This is required becasue on kirkwood by default ports are in reset mode
	 * OS egiga driver may not have provision to set them in normal mode
	 * and if u-boot is build without network support, network may fail at OS level
	 */
	reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(0));
	reg &= ~(1 << 4);	/* Clear PortReset Bit */
	writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(0)));
	reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(1));
	reg &= ~(1 << 4);	/* Clear PortReset Bit */
	writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(1)));
#endif
#ifdef CONFIG_KIRKWOOD_PCIE_INIT
	/*
	 * Enable PCI Express Port0
	 */
	reg = readl(&cpureg->ctrl_stat);
	reg |= (1 << 0);	/* Set PEX0En Bit */
	writel(reg, &cpureg->ctrl_stat);
#endif
	return 0;
}
#endif /* CONFIG_ARCH_CPU_INIT */

/*
 * SOC specific misc init
 */
#if defined(CONFIG_ARCH_MISC_INIT)
int arch_misc_init(void)
{
	volatile u32 temp;

	/*CPU streaming & write allocate */
	temp = readfr_extra_feature_reg();
	temp &= ~(1 << 28);	/* disable wr alloc */
	writefr_extra_feature_reg(temp);

	temp = readfr_extra_feature_reg();
	temp &= ~(1 << 29);	/* streaming disabled */
	writefr_extra_feature_reg(temp);

	/* L2Cache settings */
	temp = readfr_extra_feature_reg();
	/* Disable L2C pre fetch - Set bit 24 */
	temp |= (1 << 24);
	/* enable L2C - Set bit 22 */
	temp |= (1 << 22);
	writefr_extra_feature_reg(temp);

	/* Change reset vector to address 0x0 */
	temp = get_cr();
	set_cr(temp & ~CR_V);

	/* Configure mbus windows */
	mvebu_mbus_probe(windows, ARRAY_SIZE(windows));

	/* checks and execute resset to factory event */
	kw_sysrst_check();

	return 0;
}
#endif /* CONFIG_ARCH_MISC_INIT */

#ifdef CONFIG_MVGBE
int cpu_eth_init(struct bd_info *bis)
{
	mvgbe_initialize(bis);
	return 0;
}
#endif

#ifdef CONFIG_MVEBU_MMC
int board_mmc_init(struct bd_info *bis)
{
	mvebu_mmc_init(bis);
	return 0;
}
#endif /* CONFIG_MVEBU_MMC */
