// 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(void)
{
	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 const struct mbus_win windows[] = {
	/* Window 0: PCIE MEM address space */
	{ KW_DEFADR_PCI_MEM, KW_DEFADR_PCI_MEM_SIZE,
	  KWCPU_TARGET_PCIE, KWCPU_ATTR_PCIE_MEM },

	/* Window 1: PCIE IO address space */
	{ KW_DEFADR_PCI_IO, KW_DEFADR_PCI_IO_SIZE,
	  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)dectoul(s, NULL);

	/* 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;

	/* 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
