// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2020 BayLibre, SAS
 * Author: Neil Armstrong <narmstrong@baylibre.com>
 */

#include <dm.h>
#include <env_internal.h>
#include <init.h>
#include <net.h>
#include <asm/io.h>
#include <asm/arch/boot.h>
#include <asm/arch/eth.h>
#include <asm/arch/sm.h>
#include <asm/global_data.h>
#include <i2c.h>
#include "khadas-mcu.h"

int mmc_get_env_dev(void)
{
	switch (meson_get_boot_device()) {
	case BOOT_DEVICE_EMMC:
		return 2;
	case BOOT_DEVICE_SD:
		return 1;
	default:
		/* boot device is not EMMC|SD */
		return -1;
	}
}

/*
 * The VIM3 on-board  MCU can mux the PCIe/USB3.0 shared differential
 * lines using a FUSB340TMX USB 3.1 SuperSpeed Data Switch between
 * an USB3.0 Type A connector and a M.2 Key M slot.
 * The PHY driving these differential lines is shared between
 * the USB3.0 controller and the PCIe Controller, thus only
 * a single controller can use it.
 */
int meson_ft_board_setup(void *blob, struct bd_info *bd)
{
	struct udevice *bus, *dev;
	int node, i2c_node, ret;
	unsigned int i2c_addr;
	u32 *val;

	/* Find I2C device */
	node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "khadas,mcu");
	if (node < 0) {
		printf("vim3: cannot find khadas,mcu node\n");
		return 0;
	}

	/* Get addr */
	val = (u32 *)fdt_getprop(gd->fdt_blob, node, "reg", NULL);
	if (!val) {
		printf("vim3: cannot find khadas,mcu node i2c addr\n");
		return 0;
	}
	i2c_addr = fdt32_to_cpu(*val);

	/* Get i2c device */
	i2c_node = fdt_parent_offset(gd->fdt_blob, node);
	if (node < 0) {
		printf("vim3: cannot find khadas,mcu i2c node\n");
		return 0;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_I2C, i2c_node, &bus);
	if (ret < 0) {
		printf("vim3: cannot find i2c bus (%d)\n", ret);
		return 0;
	}

	ret = i2c_get_chip(bus, i2c_addr, 1, &dev);
	if (ret < 0) {
		printf("vim3: cannot find i2c chip (%d)\n", ret);
		return 0;
	}

	/* Read USB_PCIE_SWITCH_REG */
	ret = dm_i2c_reg_read(dev, KHADAS_MCU_USB_PCIE_SWITCH_REG);
	if (ret < 0) {
		printf("vim3: failed to read i2c reg (%d)\n", ret);
		return 0;
	}
	debug("MCU_USB_PCIE_SWITCH_REG: %d\n", ret);

	/*
	 * If in PCIe mode, alter DT
	 * 0: Enable USB3.0, Disable PCIE, 1: Disable USB3.0, Enable PCIE
	 */
	if (ret > 0) {
		static char data[32] __aligned(4);
		const void *ptmp;
		int len;

		/* Find USB node */
		node = fdt_node_offset_by_compatible(blob, -1, "amlogic,meson-g12a-usb-ctrl");
		if (node < 0) {
			printf("vim3: cannot find amlogic,meson-g12a-usb-ctrl node\n");
			return 0;
		}

		/* Update PHY names (mandatory to disable USB3.0) */
		len = strlcpy(data, "usb2-phy0", 32) + 1;
		len += strlcpy(&data[len], "usb2-phy1", 32 - len) + 1;
		ret = fdt_setprop(blob, node, "phy-names", data, len);
		if (ret < 0) {
			printf("vim3: failed to update usb phy names property (%d)\n", ret);
			return 0;
		}

		/* Update PHY list, by keeping the 2 first entries (optional) */
		ptmp = fdt_getprop(blob, node, "phys", &len);
		if (ptmp) {
			memcpy(data, ptmp, min_t(unsigned int, 2 * sizeof(u32), len));

			ret = fdt_setprop(blob, node, "phys", data,
					  min_t(unsigned int, 2 * sizeof(u32), len));
			if (ret < 0)
				printf("vim3: failed to update usb phys property (%d)\n", ret);
		} else
			printf("vim3: cannot find usb node phys property\n");

		/* Find PCIe node */
		node = fdt_node_offset_by_compatible(blob, -1, "amlogic,g12a-pcie");
		if (node < 0) {
			printf("vim3: cannot find amlogic,g12a-pcie node\n");
			return 0;
		}

		/* Enable PCIe */
		len = strlcpy(data, "okay", 32) + 1;
		ret = fdt_setprop(blob, node, "status", data, len);
		if (ret < 0) {
			printf("vim3: failed to enable pcie node (%d)\n", ret);
			return 0;
		}

		printf("vim3: successfully enabled PCIe\n");
	}

	return 0;
}

#define EFUSE_MAC_OFFSET	0
#define EFUSE_MAC_SIZE		12
#define MAC_ADDR_LEN		6

int misc_init_r(void)
{
	u8 mac_addr[MAC_ADDR_LEN + 1];
	char efuse_mac_addr[EFUSE_MAC_SIZE], tmp[3];
	char serial_string[EFUSE_MAC_SIZE + 1];
	ssize_t len;

	if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
		len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
					  efuse_mac_addr, EFUSE_MAC_SIZE);
		if (len != EFUSE_MAC_SIZE)
			return 0;

		/* MAC is stored in ASCII format, 1bytes = 2characters */
		for (int i = 0; i < 6; i++) {
			tmp[0] = efuse_mac_addr[i * 2];
			tmp[1] = efuse_mac_addr[i * 2 + 1];
			tmp[2] = '\0';
			mac_addr[i] = hextoul(tmp, NULL);
		}
		mac_addr[MAC_ADDR_LEN] = '\0';

		if (is_valid_ethaddr(mac_addr))
			eth_env_set_enetaddr("ethaddr", mac_addr);
		else
			meson_generate_serial_ethaddr();

		eth_env_get_enetaddr("ethaddr", mac_addr);
	}

	if (!env_get("serial#")) {
		eth_env_get_enetaddr("ethaddr", mac_addr);
		sprintf(serial_string, "%02X%02X%02X%02X%02X%02X",
			mac_addr[0], mac_addr[1], mac_addr[2],
			mac_addr[3], mac_addr[4], mac_addr[5]);
		env_set("serial#", serial_string);
	}

	return 0;
}
