/*
 * (C) Copyright 2015 Savoir-faire Linux Inc.
 *
 * Derived from MX51EVK code by
 *   Freescale Semiconductor, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/iomux-mx51.h>
#include <linux/errno.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/crm_regs.h>
#include <asm/arch/clock.h>
#include <asm/imx-common/mx5_video.h>
#include <mmc.h>
#include <fsl_esdhc.h>
#include <mc13892.h>

#include <malloc.h>
#include <netdev.h>
#include <phy.h>
#include "ts4800.h"

DECLARE_GLOBAL_DATA_PTR;

#ifdef CONFIG_FSL_ESDHC
struct fsl_esdhc_cfg esdhc_cfg[2] = {
	{MMC_SDHC1_BASE_ADDR},
	{MMC_SDHC2_BASE_ADDR},
};
#endif

int dram_init(void)
{
	/* dram_init must store complete ramsize in gd->ram_size */
	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
				PHYS_SDRAM_1_SIZE);
	return 0;
}

u32 get_board_rev(void)
{
	u32 rev = get_cpu_rev();
	if (!gpio_get_value(IMX_GPIO_NR(1, 22)))
		rev |= BOARD_REV_2_0 << BOARD_VER_OFFSET;
	return rev;
}

#define UART_PAD_CTRL	(PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_DSE_HIGH)

static void setup_iomux_uart(void)
{
	static const iomux_v3_cfg_t uart_pads[] = {
		MX51_PAD_UART1_RXD__UART1_RXD,
		MX51_PAD_UART1_TXD__UART1_TXD,
		NEW_PAD_CTRL(MX51_PAD_UART1_RTS__UART1_RTS, UART_PAD_CTRL),
		NEW_PAD_CTRL(MX51_PAD_UART1_CTS__UART1_CTS, UART_PAD_CTRL),
	};

	imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
}

static void setup_iomux_fec(void)
{
	static const iomux_v3_cfg_t fec_pads[] = {
		NEW_PAD_CTRL(MX51_PAD_EIM_EB2__FEC_MDIO,
				PAD_CTL_HYS |
				PAD_CTL_PUS_22K_UP |
				PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST),
		MX51_PAD_EIM_EB3__FEC_RDATA1,
		NEW_PAD_CTRL(MX51_PAD_EIM_CS2__FEC_RDATA2, PAD_CTL_HYS),
		MX51_PAD_EIM_CS3__FEC_RDATA3,
		MX51_PAD_NANDF_CS2__FEC_TX_ER,
		MX51_PAD_EIM_CS5__FEC_CRS,
		MX51_PAD_EIM_CS4__FEC_RX_ER,
		/* PAD used on TS4800 */
		MX51_PAD_DI2_PIN2__FEC_MDC,
		MX51_PAD_DISP2_DAT14__FEC_RDAT0,
		MX51_PAD_DISP2_DAT10__FEC_COL,
		MX51_PAD_DISP2_DAT11__FEC_RXCLK,
		MX51_PAD_DISP2_DAT15__FEC_TDAT0,
		MX51_PAD_DISP2_DAT6__FEC_TDAT1,
		MX51_PAD_DISP2_DAT7__FEC_TDAT2,
		MX51_PAD_DISP2_DAT8__FEC_TDAT3,
		MX51_PAD_DISP2_DAT9__FEC_TX_EN,
		MX51_PAD_DISP2_DAT13__FEC_TX_CLK,
		MX51_PAD_DISP2_DAT12__FEC_RX_DV,
	};

	imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads));
}

#ifdef CONFIG_FSL_ESDHC
int board_mmc_getcd(struct mmc *mmc)
{
	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
	int ret;

	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_GPIO1_0__GPIO1_0,
						NO_PAD_CTRL));
	gpio_direction_input(IMX_GPIO_NR(1, 0));
	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_GPIO1_6__GPIO1_6,
						NO_PAD_CTRL));
	gpio_direction_input(IMX_GPIO_NR(1, 6));

	if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
		ret = !gpio_get_value(IMX_GPIO_NR(1, 0));
	else
		ret = !gpio_get_value(IMX_GPIO_NR(1, 6));

	return ret;
}

int board_mmc_init(bd_t *bis)
{
	static const iomux_v3_cfg_t sd1_pads[] = {
		NEW_PAD_CTRL(MX51_PAD_SD1_CMD__SD1_CMD, PAD_CTL_DSE_MAX |
			PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST),
		NEW_PAD_CTRL(MX51_PAD_SD1_CLK__SD1_CLK, PAD_CTL_DSE_MAX |
			PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST),
		NEW_PAD_CTRL(MX51_PAD_SD1_DATA0__SD1_DATA0, PAD_CTL_DSE_MAX |
			PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST),
		NEW_PAD_CTRL(MX51_PAD_SD1_DATA1__SD1_DATA1, PAD_CTL_DSE_MAX |
			PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST),
		NEW_PAD_CTRL(MX51_PAD_SD1_DATA2__SD1_DATA2, PAD_CTL_DSE_MAX |
			PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST),
		NEW_PAD_CTRL(MX51_PAD_SD1_DATA3__SD1_DATA3, PAD_CTL_DSE_MAX |
			PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_SRE_FAST),
		NEW_PAD_CTRL(MX51_PAD_GPIO1_0__SD1_CD, PAD_CTL_HYS),
		NEW_PAD_CTRL(MX51_PAD_GPIO1_1__SD1_WP, PAD_CTL_HYS),
	};

	esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);

	imx_iomux_v3_setup_multiple_pads(sd1_pads, ARRAY_SIZE(sd1_pads));

	return fsl_esdhc_initialize(bis, &esdhc_cfg[0]);
}
#endif

int board_early_init_f(void)
{
	setup_iomux_uart();
	setup_iomux_fec();

	return 0;
}

int board_init(void)
{
	/* address of boot parameters */
	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;

	return 0;
}

/*
 * Read the MAC address from FEC's registers PALR PAUR.
 * User is supposed to configure these registers when MAC address is known
 * from another source (fuse), but on TS4800, MAC address is not fused and
 * the bootrom configure these registers on startup.
 */
static int fec_get_mac_from_register(uint32_t base_addr)
{
	unsigned char ethaddr[6];
	u32 reg_mac[2];
	int i;

	reg_mac[0] = in_be32(base_addr + 0xE4);
	reg_mac[1] = in_be32(base_addr + 0xE8);

	for(i = 0; i < 6; i++)
		ethaddr[i] = (reg_mac[i / 4] >> ((i % 4) * 8)) & 0xFF;

	if (is_valid_ethaddr(ethaddr)) {
		eth_setenv_enetaddr("ethaddr", ethaddr);
		return 0;
	}

	return -1;
}

#define TS4800_GPIO_FEC_PHY_RES         IMX_GPIO_NR(2, 14)
int board_eth_init(bd_t *bd)
{
	int dev_id = -1;
	int phy_id = 0xFF;
	uint32_t addr = IMX_FEC_BASE;

	uint32_t base_mii;
	struct mii_dev *bus = NULL;
	struct phy_device *phydev = NULL;
	int ret;

	/* reset FEC phy */
	imx_iomux_v3_setup_pad(MX51_PAD_EIM_A20__GPIO2_14);
	gpio_direction_output(TS4800_GPIO_FEC_PHY_RES, 0);
	mdelay(1);
	gpio_set_value(TS4800_GPIO_FEC_PHY_RES, 1);
	mdelay(1);

	base_mii = addr;
	debug("eth_init: fec_probe(bd, %i, %i) @ %08x\n", dev_id, phy_id, addr);
	bus = fec_get_miibus(base_mii, dev_id);
	if (!bus)
		return -ENOMEM;

	phydev = phy_find_by_mask(bus, phy_id, PHY_INTERFACE_MODE_MII);
	if (!phydev) {
		free(bus);
		return -ENOMEM;
	}

	if (fec_get_mac_from_register(addr))
		printf("eth_init: failed to get MAC address\n");

	ret = fec_probe(bd, dev_id, addr, bus, phydev);
	if (ret) {
		free(phydev);
		free(bus);
	}

	return ret;
}

/*
 * Do not overwrite the console
 * Use always serial for U-Boot console
 */
int overwrite_console(void)
{
	return 1;
}

int checkboard(void)
{
	puts("Board: TS4800\n");

	return 0;
}

void hw_watchdog_reset(void)
{
	struct ts4800_wtd_regs *wtd = (struct ts4800_wtd_regs *) (TS4800_SYSCON_BASE + 0xE);
	/* feed the watchdog for another 10s */
	writew(0x2, &wtd->feed);
}

void hw_watchdog_init(void)
{
	return;
}
