// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2010
 * ISEE 2007 SL, <www.iseebcn.com>
 */
#include <config.h>
#include <env.h>
#include <init.h>
#include <malloc.h>
#include <net.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/delay.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_plat igep_serial = {
	.base = OMAP34XX_UART3,
	.reg_shift = 2,
	.clock = V_NS16550_CLK,
	.fcr = UART_FCR_DEFVAL,
};

U_BOOT_DRVINFO(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 *)CFG_SYS_ONENAND_BASE;
		return 0;
	}
	return 1;
}

#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, struct bd_info *bd)
{
#ifdef CONFIG_FDT_FIXUP_PARTITIONS
	static const 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);

	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;
	}
}
