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

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

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

DECLARE_GLOBAL_DATA_PTR;

#ifdef CONFIG_FSL_ESDHC_IMX
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_IMX
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_env_set_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;
}
