/*
 * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
 * Based on:
 * U-Boot:board/davinci/da8xxevm/da850evm.c
 *
 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
 *
 * Based on da830evm.c. Original Copyrights follow:
 *
 * Copyright (C) 2009 Nick Thompson, GE Fanuc, Ltd. <nick.thompson@gefanuc.com>
 * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <i2c.h>
#include <net.h>
#include <netdev.h>
#include <spi.h>
#include <spi_flash.h>
#include <asm/arch/hardware.h>
#include <asm/ti-common/davinci_nand.h>
#include <asm/arch/emac_defs.h>
#include <asm/arch/pinmux_defs.h>
#include <asm/io.h>
#include <asm/arch/davinci_misc.h>
#include <linux/errno.h>
#include <asm/gpio.h>
#include <hwconfig.h>
#include <bootstage.h>

DECLARE_GLOBAL_DATA_PTR;

#ifdef CONFIG_DRIVER_TI_EMAC
#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII
#define HAS_RMII 1
#else
#define HAS_RMII 0
#endif
#endif /* CONFIG_DRIVER_TI_EMAC */

void dsp_lpsc_on(unsigned domain, unsigned int id)
{
	dv_reg_p mdstat, mdctl, ptstat, ptcmd;
	struct davinci_psc_regs *psc_regs;

	psc_regs = davinci_psc0_regs;
	mdstat = &psc_regs->psc0.mdstat[id];
	mdctl = &psc_regs->psc0.mdctl[id];
	ptstat = &psc_regs->ptstat;
	ptcmd = &psc_regs->ptcmd;

	while (*ptstat & (0x1 << domain))
		;

	if ((*mdstat & 0x1f) == 0x03)
		return;                 /* Already on and enabled */

	*mdctl |= 0x03;

	*ptcmd = 0x1 << domain;

	while (*ptstat & (0x1 << domain))
		;
	while ((*mdstat & 0x1f) != 0x03)
		;		/* Probably an overkill... */
}

static void dspwake(void)
{
	unsigned *resetvect = (unsigned *)DAVINCI_L3CBARAM_BASE;
	u32 val;

	/* if the device is ARM only, return */
	if ((readl(CHIP_REV_ID_REG) & 0x3f) == 0x10)
		return;

	if (hwconfig_subarg_cmp_f("dsp", "wake", "no", NULL))
		return;

	*resetvect++ = 0x1E000; /* DSP Idle */
	/* clear out the next 10 words as NOP */
	memset(resetvect, 0, sizeof(unsigned) * 10);

	/* setup the DSP reset vector */
	writel(DAVINCI_L3CBARAM_BASE, HOST1CFG);

	dsp_lpsc_on(1, DAVINCI_LPSC_GEM);
	val = readl(PSC0_MDCTL + (15 * 4));
	val |= 0x100;
	writel(val, (PSC0_MDCTL + (15 * 4)));
}

int misc_init_r(void)
{
	dspwake();
	return 0;
}

static const struct pinmux_config gpio_pins[] = {
	/* GP7[14] selects bootmode*/
	{ pinmux(16), 8, 3 },	/* GP7[14] */
};

const struct pinmux_resource pinmuxes[] = {
#ifdef CONFIG_DRIVER_TI_EMAC
	PINMUX_ITEM(emac_pins_mdio),
#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII
	PINMUX_ITEM(emac_pins_rmii),
#else
	PINMUX_ITEM(emac_pins_mii),
#endif
#endif
	PINMUX_ITEM(uart2_pins_txrx),
	PINMUX_ITEM(uart2_pins_rtscts),
	PINMUX_ITEM(uart0_pins_txrx),
	PINMUX_ITEM(uart0_pins_rtscts),
#ifdef CONFIG_NAND_DAVINCI
	PINMUX_ITEM(emifa_pins_cs3),
	PINMUX_ITEM(emifa_pins_nand),
#endif
	PINMUX_ITEM(gpio_pins),
};

const int pinmuxes_size = ARRAY_SIZE(pinmuxes);

const struct lpsc_resource lpsc[] = {
	{ DAVINCI_LPSC_AEMIF },	/* NAND, NOR */
	{ DAVINCI_LPSC_EMAC },	/* image download */
	{ DAVINCI_LPSC_UART2 },	/* console */
	{ DAVINCI_LPSC_UART0 },	/* console */
	{ DAVINCI_LPSC_GPIO },
};

const int lpsc_size = ARRAY_SIZE(lpsc);

#ifndef CONFIG_DA850_EVM_MAX_CPU_CLK
#define CONFIG_DA850_EVM_MAX_CPU_CLK	300000000
#endif

#define REV_AM18X_EVM		0x100

/*
 * get_board_rev() - setup to pass kernel board revision information
 * Returns:
 * bit[0-3]	Maximum cpu clock rate supported by onboard SoC
 *		0000b - 300 MHz
 *		0001b - 372 MHz
 *		0010b - 408 MHz
 *		0011b - 456 MHz
 */
u32 get_board_rev(void)
{
	char *s;
	u32 maxcpuclk = CONFIG_DA850_EVM_MAX_CPU_CLK;
	u32 rev = 0;

	s = getenv("maxcpuclk");
	if (s)
		maxcpuclk = simple_strtoul(s, NULL, 10);

	if (maxcpuclk >= 456000000)
		rev = 3;
	else if (maxcpuclk >= 408000000)
		rev = 2;
	else if (maxcpuclk >= 372000000)
		rev = 1;
#ifdef CONFIG_DA850_AM18X_EVM
	rev |= REV_AM18X_EVM;
#endif
	return rev;
}

int board_early_init_f(void)
{
	/*
	 * Power on required peripherals
	 * ARM does not have access by default to PSC0 and PSC1
	 * assuming here that the DSP bootloader has set the IOPU
	 * such that PSC access is available to ARM
	 */
	if (da8xx_configure_lpsc_items(lpsc, ARRAY_SIZE(lpsc)))
		return 1;

	return 0;
}

int board_init(void)
{
#ifndef CONFIG_USE_IRQ
	irq_init();
#endif

	/* arch number of the board */
	gd->bd->bi_arch_number = MACH_TYPE_DAVINCI_DA850_EVM;

	/* address of boot parameters */
	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;

	/* setup the SUSPSRC for ARM to control emulation suspend */
	writel(readl(&davinci_syscfg_regs->suspsrc) &
	       ~(DAVINCI_SYSCFG_SUSPSRC_EMAC | DAVINCI_SYSCFG_SUSPSRC_I2C |
		 DAVINCI_SYSCFG_SUSPSRC_SPI1 | DAVINCI_SYSCFG_SUSPSRC_TIMER0 |
		 DAVINCI_SYSCFG_SUSPSRC_UART0),
	       &davinci_syscfg_regs->suspsrc);

	/* configure pinmux settings */
	if (davinci_configure_pin_mux_items(pinmuxes, ARRAY_SIZE(pinmuxes)))
		return 1;

#ifdef CONFIG_DRIVER_TI_EMAC
	davinci_emac_mii_mode_sel(HAS_RMII);
#endif /* CONFIG_DRIVER_TI_EMAC */

	/* enable the console UART */
	writel((DAVINCI_UART_PWREMU_MGMT_FREE | DAVINCI_UART_PWREMU_MGMT_URRST |
		DAVINCI_UART_PWREMU_MGMT_UTRST),
#if (CONFIG_SYS_NS16550_COM1 == DAVINCI_UART0_BASE)
	       &davinci_uart0_ctrl_regs->pwremu_mgmt);
#else
	       &davinci_uart2_ctrl_regs->pwremu_mgmt);
#endif
	return 0;
}

#ifdef CONFIG_DRIVER_TI_EMAC
/*
 * Initializes on-board ethernet controllers.
 */
int board_eth_init(bd_t *bis)
{
	if (!davinci_emac_initialize()) {
		printf("Error: Ethernet init failed!\n");
		return -1;
	}

	return 0;
}
#endif /* CONFIG_DRIVER_TI_EMAC */

static int init_led(int gpio, char *name, int val)
{
	int ret;

	ret = gpio_request(gpio, name);
	if (ret)
		return -1;
	ret = gpio_direction_output(gpio, val);
	if (ret)
		return -1;

	return gpio;
}

#define LED_ON	0
#define LED_OFF	1

#if !defined(CONFIG_SPL_BUILD)
#ifdef CONFIG_SHOW_BOOT_PROGRESS
void show_boot_progress(int status)
{
	static int red;
	static int green;

	if (red == 0)
		red = init_led(CONFIG_IPAM390_GPIO_LED_RED, "red", LED_ON);
	if (red != CONFIG_IPAM390_GPIO_LED_RED)
		return;
	if (green == 0)
		green = init_led(CONFIG_IPAM390_GPIO_LED_GREEN, "green",
				 LED_OFF);
	if (green != CONFIG_IPAM390_GPIO_LED_GREEN)
		return;

	switch (status) {
	case BOOTSTAGE_ID_RUN_OS:
		/*
		 * set normal state
		 * LED Red  : on
		 * LED green: off
		 */
		gpio_set_value(red, LED_ON);
		gpio_set_value(green, LED_OFF);
		break;
	case BOOTSTAGE_ID_MAIN_LOOP:
		/*
		 * U-Boot operation
		 * LED Red  : on
		 * LED green: on
		 */
		gpio_set_value(red, LED_ON);
		gpio_set_value(green, LED_ON);
		break;
	}
}
#endif
#endif

#ifdef CONFIG_SPL_OS_BOOT
int spl_start_uboot(void)
{
	int ret;
	int bootmode = 0;

	/*
	 * GP7[14] selects bootmode:
	 * 1: boot linux
	 * 0: boot u-boot
	 * if error accessing gpio boot U-Boot
	 *
	 * SPL bootmode
	 * 0: boot linux
	 * 1: boot u-boot
	 */
	ret = gpio_request(CONFIG_IPAM390_GPIO_BOOTMODE , "bootmode");
	if (ret)
		bootmode = 1;
	if (!bootmode) {
		ret = gpio_direction_input(CONFIG_IPAM390_GPIO_BOOTMODE);
		if (ret)
			bootmode = 1;
	}
	if (!bootmode)
		ret = gpio_get_value(CONFIG_IPAM390_GPIO_BOOTMODE);
	if (!bootmode)
		if (ret == 0)
			bootmode = 1;
	/*
	 * LED red  : on
	 * LED green: off
	 */
	init_led(CONFIG_IPAM390_GPIO_LED_RED, "red", LED_ON);
	init_led(CONFIG_IPAM390_GPIO_LED_GREEN, "green", LED_OFF);
	return bootmode;
}
#endif
