// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2017 DENX Software Engineering
 * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
 */

#include <common.h>
#include <dm.h>
#include <fdt_support.h>
#include <init.h>
#include <log.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/iomux.h>
#include <asm/arch/mx6-pins.h>
#include <asm/arch/mx6-ddr.h>
#include <asm/arch/sys_proto.h>
#include <env.h>
#include <errno.h>
#include <asm/gpio.h>
#include <malloc.h>
#include <asm/mach-imx/iomux-v3.h>
#include <asm/mach-imx/boot_mode.h>
#include <miiphy.h>
#include <netdev.h>
#include <i2c.h>
#include <linux/delay.h>

#include <dm.h>
#include <dm/platform_data/serial_mxc.h>
#include <dm/platdata.h>

#include "common.h"

DECLARE_GLOBAL_DATA_PTR;

static bool hw_ids_valid;
static bool sw_ids_valid;
static u32 cpu_id;
static u32 unit_id;

const char *gpio_table_sw_names[] = {
	"GPIO2_4", "GPIO2_5", "GPIO2_6", "GPIO2_7"
};

const char *gpio_table_sw_ids_names[] = {
	"sw0", "sw1", "sw2", "sw3"
};

const char *gpio_table_hw_names[] = {
	"GPIO6_7", "GPIO6_9", "GPIO6_10", "GPIO6_11",
	"GPIO4_7", "GPIO4_11", "GPIO4_13", "GPIO4_15"
};

const char *gpio_table_hw_ids_names[] = {
	"hw0", "hw1", "hw2", "hw3", "hw4", "hw5", "hw6", "hw7"
};

static int get_board_id(const char **pin_names, const char **ids_names,
			int size, bool *valid, u32 *id)
{
	struct gpio_desc desc;
	int i, ret, val;

	*valid = false;

	for (i = 0; i < size; i++) {
		memset(&desc, 0, sizeof(desc));

		ret = dm_gpio_lookup_name(pin_names[i], &desc);
		if (ret) {
			printf("Can't lookup request SWx gpios\n");
			return ret;
		}

		ret = dm_gpio_request(&desc, ids_names[i]);
		if (ret) {
			printf("Can't lookup request SWx gpios\n");
			return ret;
		}

		dm_gpio_set_dir_flags(&desc, GPIOD_IS_IN);

		val = dm_gpio_get_value(&desc);
		if (val < 0) {
			printf("Can't get SW%d ID\n", i);
			*id = 0;
			return val;
		}
		*id |= val << i;
	}
	*valid = true;

	return 0;
}

int dram_init(void)
{
	gd->ram_size = imx_ddr_size();

	return 0;
}

iomux_v3_cfg_t const misc_pads[] = {
	/* Prod ID GPIO pins */
	MX6_PAD_NANDF_D4__GPIO2_IO04    | MUX_PAD_CTRL(NO_PAD_CTRL),
	MX6_PAD_NANDF_D5__GPIO2_IO05    | MUX_PAD_CTRL(NO_PAD_CTRL),
	MX6_PAD_NANDF_D6__GPIO2_IO06    | MUX_PAD_CTRL(NO_PAD_CTRL),
	MX6_PAD_NANDF_D7__GPIO2_IO07    | MUX_PAD_CTRL(NO_PAD_CTRL),

	/* HW revision GPIO pins */
	MX6_PAD_NANDF_CLE__GPIO6_IO07   | MUX_PAD_CTRL(NO_PAD_CTRL),
	MX6_PAD_NANDF_WP_B__GPIO6_IO09  | MUX_PAD_CTRL(NO_PAD_CTRL),
	MX6_PAD_NANDF_RB0__GPIO6_IO10   | MUX_PAD_CTRL(NO_PAD_CTRL),
	MX6_PAD_NANDF_CS0__GPIO6_IO11   | MUX_PAD_CTRL(NO_PAD_CTRL),
	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
	MX6_PAD_KEY_ROW2__GPIO4_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
	MX6_PAD_KEY_ROW3__GPIO4_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL),
	MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),

	/* XTALOSC */
	MX6_PAD_GPIO_3__XTALOSC_REF_CLK_24M | MUX_PAD_CTRL(NO_PAD_CTRL),

	/* Emergency recovery pin */
	MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
};

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

#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
int ft_board_setup(void *blob, bd_t *bd)
{
	fdt_fixup_ethernet(blob);
	return 0;
}
#endif

int board_phy_config(struct phy_device *phydev)
{
	/* display5 due to PCB routing can only work with 100 Mbps */
	phydev->advertising &= ~(ADVERTISED_1000baseX_Half |
				 ADVERTISED_1000baseX_Full |
				 SUPPORTED_1000baseT_Half |
				 SUPPORTED_1000baseT_Full);

	if (phydev->drv->config)
		return phydev->drv->config(phydev);

	return 0;
}

int board_init(void)
{
	struct gpio_desc phy_int_gbe, spi2_wp;
	int ret;

	debug("board init\n");
	/* address of boot parameters */
	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;

	/* Setup misc (application specific) stuff */
	SETUP_IOMUX_PADS(misc_pads);

	get_board_id(gpio_table_sw_names, &gpio_table_sw_ids_names[0],
		     ARRAY_SIZE(gpio_table_sw_names), &sw_ids_valid, &unit_id);
	debug("SWx unit_id 0x%x\n", unit_id);

	get_board_id(gpio_table_hw_names, &gpio_table_hw_ids_names[0],
		     ARRAY_SIZE(gpio_table_hw_names), &hw_ids_valid, &cpu_id);
	debug("HWx cpu_id 0x%x\n", cpu_id);

	if (hw_ids_valid && sw_ids_valid)
		printf("ID:    unit type 0x%x rev 0x%x\n", unit_id, cpu_id);

	udelay(25);

	/* Setup low level FEC (ETH) */
	ret = dm_gpio_lookup_name("GPIO1_28", &phy_int_gbe);
	if (ret) {
		printf("Cannot get GPIO1_28\n");
	} else {
		ret = dm_gpio_request(&phy_int_gbe, "INT_GBE");
		if (!ret)
			dm_gpio_set_dir_flags(&phy_int_gbe, GPIOD_IS_IN);
	}

	iomuxc_set_rgmii_io_voltage(DDR_SEL_1P5V_IO);
	enable_fec_anatop_clock(0, ENET_125MHZ);

	/* Setup #WP for SPI-NOR memory */
	ret = dm_gpio_lookup_name("GPIO7_0", &spi2_wp);
	if (ret) {
		printf("Cannot get GPIO7_0\n");
	} else {
		ret = dm_gpio_request(&spi2_wp, "spi2_#wp");
		if (!ret)
			dm_gpio_set_dir_flags(&spi2_wp, GPIOD_IS_OUT |
					      GPIOD_IS_OUT_ACTIVE);
	}

	return 0;
}

#ifdef CONFIG_CMD_BMODE
static const struct boot_mode board_boot_modes[] = {
	/* eMMC, USDHC-4, 8-bit bus width */
	/* SPI-NOR, ECSPI-2 SS0, 3-bytes addressing */
	{"emmc",    MAKE_CFGVAL(0x60, 0x58, 0x00, 0x00)},
	{"spinor",  MAKE_CFGVAL(0x30, 0x00, 0x00, 0x09)},
	{NULL,	0},
};

static void setup_boot_modes(void)
{
	add_board_boot_modes(board_boot_modes);
}
#else
static inline void setup_boot_modes(void) {}
#endif

int misc_init_r(void)
{
	struct gpio_desc em_pad;
	int ret;

	setup_boot_modes();

	ret = dm_gpio_lookup_name("GPIO3_29", &em_pad);
	if (ret) {
		printf("Can't find emergency PAD gpio\n");
		return ret;
	}

	ret = dm_gpio_request(&em_pad, "Emergency_PAD");
	if (ret) {
		printf("Can't request emergency PAD gpio\n");
		return ret;
	}

	dm_gpio_set_dir_flags(&em_pad, GPIOD_IS_IN);

	return 0;
}
