/*
 * (C) Copyright 2010
 * ISEE 2007 SL, <www.iseebcn.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */
#include <common.h>
#include <status_led.h>
#include <dm.h>
#include <ns16550.h>
#include <twl4030.h>
#include <netdev.h>
#include <spl.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/mem.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/mux.h>
#include <asm/arch/sys_proto.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/onenand.h>
#include <jffs2/load_kernel.h>
#include <mtd_node.h>
#include <fdt_support.h>
#include "igep00x0.h"

static const struct ns16550_platdata igep_serial = {
	.base = OMAP34XX_UART3,
	.reg_shift = 2,
	.clock = V_NS16550_CLK,
	.fcr = UART_FCR_DEFVAL,
};

U_BOOT_DEVICE(igep_uart) = {
	"ns16550_serial",
	&igep_serial
};

/*
 * Routine: get_board_revision
 * Description: GPIO_28 and GPIO_129 are used to read board and revision from
 * IGEP00x0 boards. First of all, it is necessary to reset USB transceiver from
 * IGEP0030 in order to read GPIO_IGEP00X0_BOARD_DETECTION correctly, because
 * this functionality is shared by USB HOST.
 * Once USB reset is applied, U-boot configures these pins as input pullup to
 * detect board and revision:
 * IGEP0020-RF = 0b00
 * IGEP0020-RC = 0b01
 * IGEP0030-RG = 0b10
 * IGEP0030-RE = 0b11
 */
static int get_board_revision(void)
{
	int revision;

	gpio_request(IGEP0030_USB_TRANSCEIVER_RESET,
				"igep0030_usb_transceiver_reset");
	gpio_direction_output(IGEP0030_USB_TRANSCEIVER_RESET, 0);

	gpio_request(GPIO_IGEP00X0_BOARD_DETECTION, "igep00x0_board_detection");
	gpio_direction_input(GPIO_IGEP00X0_BOARD_DETECTION);
	revision = 2 * gpio_get_value(GPIO_IGEP00X0_BOARD_DETECTION);
	gpio_free(GPIO_IGEP00X0_BOARD_DETECTION);

	gpio_request(GPIO_IGEP00X0_REVISION_DETECTION,
				"igep00x0_revision_detection");
	gpio_direction_input(GPIO_IGEP00X0_REVISION_DETECTION);
	revision = revision + gpio_get_value(GPIO_IGEP00X0_REVISION_DETECTION);
	gpio_free(GPIO_IGEP00X0_REVISION_DETECTION);

	gpio_free(IGEP0030_USB_TRANSCEIVER_RESET);

	return revision;
}

int onenand_board_init(struct mtd_info *mtd)
{
	if (gpmc_cs0_flash == MTD_DEV_TYPE_ONENAND) {
		struct onenand_chip *this = mtd->priv;
		this->base = (void *)CONFIG_SYS_ONENAND_BASE;
		return 0;
	}
	return 1;
}

#if defined(CONFIG_CMD_NET)
static void reset_net_chip(int gpio)
{
	if (!gpio_request(gpio, "eth nrst")) {
		gpio_direction_output(gpio, 1);
		udelay(1);
		gpio_set_value(gpio, 0);
		udelay(40);
		gpio_set_value(gpio, 1);
		mdelay(10);
	}
}

/*
 * Routine: setup_net_chip
 * Description: Setting up the configuration GPMC registers specific to the
 *		Ethernet hardware.
 */
static void setup_net_chip(void)
{
	struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE;
	static const u32 gpmc_lan_config[] = {
		NET_LAN9221_GPMC_CONFIG1,
		NET_LAN9221_GPMC_CONFIG2,
		NET_LAN9221_GPMC_CONFIG3,
		NET_LAN9221_GPMC_CONFIG4,
		NET_LAN9221_GPMC_CONFIG5,
		NET_LAN9221_GPMC_CONFIG6,
	};

	enable_gpmc_cs_config(gpmc_lan_config, &gpmc_cfg->cs[5],
			CONFIG_SMC911X_BASE, GPMC_SIZE_16M);

	/* Enable off mode for NWE in PADCONF_GPMC_NWE register */
	writew(readw(&ctrl_base->gpmc_nwe) | 0x0E00, &ctrl_base->gpmc_nwe);
	/* Enable off mode for NOE in PADCONF_GPMC_NADV_ALE register */
	writew(readw(&ctrl_base->gpmc_noe) | 0x0E00, &ctrl_base->gpmc_noe);
	/* Enable off mode for ALE in PADCONF_GPMC_NADV_ALE register */
	writew(readw(&ctrl_base->gpmc_nadv_ale) | 0x0E00,
		&ctrl_base->gpmc_nadv_ale);

	reset_net_chip(64);
}

int board_eth_init(bd_t *bis)
{
#ifdef CONFIG_SMC911X
	return smc911x_initialize(0, CONFIG_SMC911X_BASE);
#else
	return 0;
#endif
}
#else
static inline void setup_net_chip(void) {}
#endif

#ifdef CONFIG_OF_BOARD_SETUP
static int ft_enable_by_compatible(void *blob, char *compat, int enable)
{
	int off = fdt_node_offset_by_compatible(blob, -1, compat);
	if (off < 0)
		return off;

	if (enable)
		fdt_status_okay(blob, off);
	else
		fdt_status_disabled(blob, off);

	return 0;
}

int ft_board_setup(void *blob, bd_t *bd)
{
#ifdef CONFIG_FDT_FIXUP_PARTITIONS
	static struct node_info nodes[] = {
		{ "ti,omap2-nand", MTD_DEV_TYPE_NAND, },
		{ "ti,omap2-onenand", MTD_DEV_TYPE_ONENAND, },
	};

	fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
#endif
	ft_enable_by_compatible(blob, "ti,omap2-nand",
				gpmc_cs0_flash == MTD_DEV_TYPE_NAND);
	ft_enable_by_compatible(blob, "ti,omap2-onenand",
				gpmc_cs0_flash == MTD_DEV_TYPE_ONENAND);

	return 0;
}
#endif

void set_led(void)
{
	switch (get_board_revision()) {
	case 0:
	case 1:
		gpio_request(IGEP0020_GPIO_LED, "igep0020_gpio_led");
		gpio_direction_output(IGEP0020_GPIO_LED, 1);
		break;
	case 2:
	case 3:
		gpio_request(IGEP0030_GPIO_LED, "igep0030_gpio_led");
		gpio_direction_output(IGEP0030_GPIO_LED, 0);
		break;
	default:
		/* Should not happen... */
		break;
	}
}

void set_boardname(void)
{
	char rev[5] = { 'F','C','G','E', };
	int i = get_board_revision();

	rev[i+1] = 0;
	env_set("board_rev", rev + i);
	env_set("board_name", i < 2 ? "igep0020" : "igep0030");
}

/*
 * Routine: misc_init_r
 * Description: Configure board specific parts
 */
int misc_init_r(void)
{
	t2_t *t2_base = (t2_t *)T2_BASE;
	u32 pbias_lite;

	twl4030_power_init();

	/* set VSIM to 1.8V */
	twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VSIM_DEDICATED,
				TWL4030_PM_RECEIVER_VSIM_VSEL_18,
				TWL4030_PM_RECEIVER_VSIM_DEV_GRP,
				TWL4030_PM_RECEIVER_DEV_GRP_P1);

	/* set up dual-voltage GPIOs to 1.8V */
	pbias_lite = readl(&t2_base->pbias_lite);
	pbias_lite &= ~PBIASLITEVMODE1;
	pbias_lite |= PBIASLITEPWRDNZ1;
	writel(pbias_lite, &t2_base->pbias_lite);
	if (get_cpu_family() == CPU_OMAP36XX)
		writel(readl(OMAP34XX_CTRL_WKUP_CTRL) |
					 OMAP34XX_CTRL_WKUP_CTRL_GPIO_IO_PWRDNZ,
					 OMAP34XX_CTRL_WKUP_CTRL);

	setup_net_chip();

	omap_die_id_display();

	set_led();

	set_boardname();

	return 0;
}

void board_mtdparts_default(const char **mtdids, const char **mtdparts)
{
	struct mtd_info *mtd = get_mtd_device(NULL, 0);
	if (mtd) {
		static char ids[24];
		static char parts[48];
		const char *linux_name = "omap2-nand";
		if (strncmp(mtd->name, "onenand0", 8) == 0)
			linux_name = "omap2-onenand";
		snprintf(ids, sizeof(ids), "%s=%s", mtd->name, linux_name);
		snprintf(parts, sizeof(parts), "mtdparts=%s:%dk(SPL),-(UBI)",
		         linux_name, 4 * mtd->erasesize >> 10);
		*mtdids = ids;
		*mtdparts = parts;
	}
}
