// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2021 Gateworks Corporation
 */

#include <fdt_support.h>
#include <init.h>
#include <led.h>
#include <mmc.h>
#include <miiphy.h>
#include <mmc.h>
#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
#include <asm/mach-imx/boot_mode.h>

#include "eeprom.h"

int board_phys_sdram_size(phys_size_t *size)
{
	if (!size)
		return -EINVAL;

	*size = get_ram_size((void *)PHYS_SDRAM, (long)PHYS_SDRAM_SIZE + (long)PHYS_SDRAM_2_SIZE);

	return 0;
}

int board_fit_config_name_match(const char *path)
{
	const char *name = path + strlen("freescale/");
	static char init;
	const char *dtb;
	char buf[32];
	int i  = 0;

	do {
		dtb = eeprom_get_dtb_name(i++, buf, sizeof(buf));
		if (!strcmp(dtb, name)) {
			if (!init++)
				printf("DTB     : %s\n", name);
			return 0;
		}
	} while (dtb);

	return -1;
}

#if (IS_ENABLED(CONFIG_NET))
int board_phy_config(struct phy_device *phydev)
{
	unsigned short val;

	switch (phydev->phy_id) {
	case 0x2000a231: /* TI DP83867 GbE PHY */
		puts("DP83867 ");
		/* LED configuration */
		val = 0;
		val |= 0x5 << 4; /* LED1(Amber;Speed)   : 1000BT link */
		val |= 0xb << 8; /* LED2(Green;Link/Act): blink for TX/RX act */
		phy_write(phydev, MDIO_DEVAD_NONE, 24, val);
		break;
	case 0xd565a401: /* MaxLinear GPY111 */
		puts("GPY111 ");
		break;
	}

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

	return 0;
}
#endif // IS_ENABLED(CONFIG_NET)

int board_init(void)
{
	venice_eeprom_init(1);

	return 0;
}

int board_late_init(void)
{
	const char *str;
	struct mmc *mmc = NULL;
	char env[32];
	int ret, i;
	u8 enetaddr[6];
	char fdt[64];
	int bootdev;

	/* Set board serial/model */
	if (!env_get("serial#"))
		env_set_ulong("serial#", eeprom_get_serial());
	env_set("model", eeprom_get_model());

	/* Set fdt_file vars */
	i = 0;
	do {
		str = eeprom_get_dtb_name(i, fdt, sizeof(fdt));
		if (str) {
			sprintf(env, "fdt_file%d", i + 1);
			strcat(fdt, ".dtb");
			env_set(env, fdt);
		}
		i++;
	} while (str);

	/* Set mac addrs */
	i = 0;
	do {
		if (i)
			sprintf(env, "eth%daddr", i);
		else
			sprintf(env, "ethaddr");
		str = env_get(env);
		if (!str) {
			ret = eeprom_getmac(i, enetaddr);
			if (!ret)
				eth_env_set_enetaddr(env, enetaddr);
		}
		i++;
	} while (!ret);

	/*
	 * set bootdev/bootblk/bootpart (used in firmware_update script)
	 * dynamically depending on boot device and SoC
	 */
	bootdev = -1;
	switch (get_boot_device()) {
	case SD1_BOOT:
	case MMC1_BOOT: /* SDHC1 */
		bootdev = 0;
		break;
	case SD2_BOOT:
	case MMC2_BOOT: /* SDHC2 */
		bootdev = 1;
		break;
	case SD3_BOOT:
	case MMC3_BOOT: /* SDHC3 */
		bootdev = 2;
		break;
	default:
		bootdev = 2; /* assume SDHC3 (eMMC) if booting over SDP */
		break;
	}
	if (bootdev != -1)
		mmc = find_mmc_device(bootdev);
	if (mmc) {
		int bootblk;

		if (IS_ENABLED(CONFIG_IMX8MN) || IS_ENABLED(CONFIG_IMX8MP))
			bootblk = 32 * SZ_1K / 512;
		else
			bootblk = 33 * SZ_1K / 512;
		mmc_init(mmc);
		if (!IS_SD(mmc)) {
			int bootpart;

			switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
			case 1: /* boot0 */
				bootpart = 1;
				break;
			case 2: /* boot1 */
				bootpart = 2;
				break;
			case 7: /* user */
			default:
				bootpart = 0;
				break;
			}
			/* IMX8MP/IMX8MN BOOTROM v2 uses offset=0 for boot parts */
			if ((IS_ENABLED(CONFIG_IMX8MN) || IS_ENABLED(CONFIG_IMX8MP)) &&
			    (bootpart == 1 || bootpart == 2))
				bootblk = 0;
			env_set_hex("bootpart", bootpart);
			env_set_hex("bootblk", bootblk);
		} else { /* SD */
			env_set("bootpart", "");
			env_set_hex("bootblk", bootblk);
		}
		env_set_hex("dev", bootdev);
	}

	/* override soc=imx8m to provide a more specific soc name */
	if (IS_ENABLED(CONFIG_IMX8MN))
		env_set("soc", "imx8mn");
	else if (IS_ENABLED(CONFIG_IMX8MP))
		env_set("soc", "imx8mp");
	else if (IS_ENABLED(CONFIG_IMX8MM))
		env_set("soc", "imx8mm");

	return 0;
}

int board_mmc_get_env_dev(int devno)
{
	return devno;
}

uint mmc_get_env_part(struct mmc *mmc)
{
	if (!IS_SD(mmc)) {
		switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
		case 1:
			return 1;
		case 2:
			return 2;
		}
	}

	return 0;
}

int ft_board_setup(void *fdt, struct bd_info *bd)
{
	const char *base_model = eeprom_get_baseboard_model();
	const char *path;
	char pcbrev;
	int off;

	/* set board model dt prop */
	fdt_setprop_string(fdt, 0, "board", eeprom_get_model());

	if (!strncmp(base_model, "GW73", 4)) {
		pcbrev = get_pcb_rev(base_model);
		path = fdt_get_alias(fdt, "ethernet1");

		if (pcbrev > 'B' && pcbrev < 'E' && path && !strncmp(path, "/soc@0/pcie@", 12)) {
			printf("adjusting %s pcie\n", base_model);
			/*
			 * revC/D/E has PCIe 4-port switch which changes
			 * ethernet1 PCIe GbE:
			 * from: pcie@0,0/pcie@1,0/pcie@2,4/pcie@6.0
			 *   to: pcie@0,0/pcie@1,0/pcie@2,3/pcie@5.0
			 */
			off = fdt_path_offset(fdt, "ethernet1");
			if (off > 0) {
				u32 reg[5];

				fdt_set_name(fdt, off, "pcie@5,0");
				off = fdt_parent_offset(fdt, off);
				fdt_set_name(fdt, off, "pcie@2,3");
				memset(reg, 0, sizeof(reg));
				reg[0] = cpu_to_fdt32(PCI_DEVFN(3, 0));
				fdt_setprop(fdt, off, "reg", reg, sizeof(reg));
			}
		}
	}

	return 0;
}
