// SPDX-License-Identifier: GPL-2.0+
/*
 * Library to support early TI EVM EEPROM handling
 *
 * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
 *	Lokesh Vutla
 *	Steve Kipisz
 */

#include <common.h>
#include <asm/arch/hardware.h>
#include <asm/omap_common.h>
#include <dm/uclass.h>
#include <env.h>
#include <i2c.h>

#include "board_detect.h"

#if !defined(CONFIG_DM_I2C)
/**
 * ti_i2c_eeprom_init - Initialize an i2c bus and probe for a device
 * @i2c_bus: i2c bus number to initialize
 * @dev_addr: Device address to probe for
 *
 * Return: 0 on success or corresponding error on failure.
 */
static int __maybe_unused ti_i2c_eeprom_init(int i2c_bus, int dev_addr)
{
	int rc;

	if (i2c_bus >= 0) {
		rc = i2c_set_bus_num(i2c_bus);
		if (rc)
			return rc;
	}

	return i2c_probe(dev_addr);
}

/**
 * ti_i2c_eeprom_read - Read data from an EEPROM
 * @dev_addr: The device address of the EEPROM
 * @offset: Offset to start reading in the EEPROM
 * @ep: Pointer to a buffer to read into
 * @epsize: Size of buffer
 *
 * Return: 0 on success or corresponding result of i2c_read
 */
static int __maybe_unused ti_i2c_eeprom_read(int dev_addr, int offset,
					     uchar *ep, int epsize)
{
	return i2c_read(dev_addr, offset, 2, ep, epsize);
}
#endif

/**
 * ti_eeprom_string_cleanup() - Handle eeprom programming errors
 * @s:	eeprom string (should be NULL terminated)
 *
 * Some Board manufacturers do not add a NULL termination at the
 * end of string, instead some binary information is kludged in, hence
 * convert the string to just printable characters of ASCII chart.
 */
static void __maybe_unused ti_eeprom_string_cleanup(char *s)
{
	int i, l;

	l = strlen(s);
	for (i = 0; i < l; i++, s++)
		if (*s < ' ' || *s > '~') {
			*s = 0;
			break;
		}
}

__weak void gpi2c_init(void)
{
}

static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
					    u32 header, u32 size, uint8_t *ep)
{
	u32 hdr_read;
	int rc;

#if defined(CONFIG_DM_I2C)
	struct udevice *dev;
	struct udevice *bus;

	rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
	if (rc)
		return rc;
	rc = i2c_get_chip(bus, dev_addr, 1, &dev);
	if (rc)
		return rc;

	/*
	 * Read the header first then only read the other contents.
	 */
	rc = i2c_set_chip_offset_len(dev, 2);
	if (rc)
		return rc;

	rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
	if (rc)
		return rc;

	/* Corrupted data??? */
	if (hdr_read != header) {
		rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
		/*
		 * read the eeprom header using i2c again, but use only a
		 * 1 byte address (some legacy boards need this..)
		 */
		if (rc) {
			rc =  i2c_set_chip_offset_len(dev, 1);
			if (rc)
				return rc;

			rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
		}
		if (rc)
			return rc;
	}
	if (hdr_read != header)
		return -1;

	rc = dm_i2c_read(dev, 0, ep, size);
	if (rc)
		return rc;
#else
	u32 byte;

	gpi2c_init();
	rc = ti_i2c_eeprom_init(bus_addr, dev_addr);
	if (rc)
		return rc;

	/*
	 * Read the header first then only read the other contents.
	 */
	byte = 2;

	rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4);
	if (rc)
		return rc;

	/* Corrupted data??? */
	if (hdr_read != header) {
		rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4);
		/*
		 * read the eeprom header using i2c again, but use only a
		 * 1 byte address (some legacy boards need this..)
		 */
		byte = 1;
		if (rc) {
			rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read,
				      4);
		}
		if (rc)
			return rc;
	}
	if (hdr_read != header)
		return -1;

	rc = i2c_read(dev_addr, 0x0, byte, ep, size);
	if (rc)
		return rc;
#endif
	return 0;
}

int __maybe_unused ti_i2c_eeprom_am_set(const char *name, const char *rev)
{
	struct ti_common_eeprom *ep;

	if (!name || !rev)
		return -1;

	ep = TI_EEPROM_DATA;
	if (ep->header == TI_EEPROM_HEADER_MAGIC)
		goto already_set;

	/* Set to 0 all fields */
	memset(ep, 0, sizeof(*ep));
	strncpy(ep->name, name, TI_EEPROM_HDR_NAME_LEN);
	strncpy(ep->version, rev, TI_EEPROM_HDR_REV_LEN);
	/* Some dummy serial number to identify the platform */
	strncpy(ep->serial, "0000", TI_EEPROM_HDR_SERIAL_LEN);
	/* Mark it with a valid header */
	ep->header = TI_EEPROM_HEADER_MAGIC;

already_set:
	return 0;
}

int __maybe_unused ti_i2c_eeprom_am_get(int bus_addr, int dev_addr)
{
	int rc;
	struct ti_am_eeprom am_ep;
	struct ti_common_eeprom *ep;

	ep = TI_EEPROM_DATA;
#ifndef CONFIG_SPL_BUILD
	if (ep->header == TI_EEPROM_HEADER_MAGIC)
		return 0; /* EEPROM has already been read */
#endif

	/* Initialize with a known bad marker for i2c fails.. */
	ep->header = TI_DEAD_EEPROM_MAGIC;
	ep->name[0] = 0x0;
	ep->version[0] = 0x0;
	ep->serial[0] = 0x0;
	ep->config[0] = 0x0;

	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC,
			       sizeof(am_ep), (uint8_t *)&am_ep);
	if (rc)
		return rc;

	ep->header = am_ep.header;
	strlcpy(ep->name, am_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
	ti_eeprom_string_cleanup(ep->name);

	/* BeagleBone Green '1' eeprom, board_rev: 0x1a 0x00 0x00 0x00 */
	if (am_ep.version[0] == 0x1a && am_ep.version[1] == 0x00 &&
	    am_ep.version[2] == 0x00 && am_ep.version[3] == 0x00)
		strlcpy(ep->version, "BBG1", TI_EEPROM_HDR_REV_LEN + 1);
	else
		strlcpy(ep->version, am_ep.version, TI_EEPROM_HDR_REV_LEN + 1);
	ti_eeprom_string_cleanup(ep->version);
	strlcpy(ep->serial, am_ep.serial, TI_EEPROM_HDR_SERIAL_LEN + 1);
	ti_eeprom_string_cleanup(ep->serial);
	strlcpy(ep->config, am_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
	ti_eeprom_string_cleanup(ep->config);

	memcpy(ep->mac_addr, am_ep.mac_addr,
	       TI_EEPROM_HDR_NO_OF_MAC_ADDR * TI_EEPROM_HDR_ETH_ALEN);

	return 0;
}

int __maybe_unused ti_i2c_eeprom_dra7_get(int bus_addr, int dev_addr)
{
	int rc, offset = 0;
	struct dra7_eeprom dra7_ep;
	struct ti_common_eeprom *ep;

	ep = TI_EEPROM_DATA;
#ifndef CONFIG_SPL_BUILD
	if (ep->header == DRA7_EEPROM_HEADER_MAGIC)
		return 0; /* EEPROM has already been read */
#endif

	/* Initialize with a known bad marker for i2c fails.. */
	ep->header = TI_DEAD_EEPROM_MAGIC;
	ep->name[0] = 0x0;
	ep->version[0] = 0x0;
	ep->serial[0] = 0x0;
	ep->config[0] = 0x0;
	ep->emif1_size = 0;
	ep->emif2_size = 0;

	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, DRA7_EEPROM_HEADER_MAGIC,
			       sizeof(dra7_ep), (uint8_t *)&dra7_ep);
	if (rc)
		return rc;

	ep->header = dra7_ep.header;
	strlcpy(ep->name, dra7_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
	ti_eeprom_string_cleanup(ep->name);

	offset = dra7_ep.version_major - 1;

	/* Rev F is skipped */
	if (offset >= 5)
		offset = offset + 1;
	snprintf(ep->version, TI_EEPROM_HDR_REV_LEN + 1, "%c.%d",
		 'A' + offset, dra7_ep.version_minor);
	ti_eeprom_string_cleanup(ep->version);
	ep->emif1_size = (u64)dra7_ep.emif1_size;
	ep->emif2_size = (u64)dra7_ep.emif2_size;
	strlcpy(ep->config, dra7_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
	ti_eeprom_string_cleanup(ep->config);

	return 0;
}

static int ti_i2c_eeprom_am6_parse_record(struct ti_am6_eeprom_record *record,
					  struct ti_am6_eeprom *ep,
					  char **mac_addr,
					  u8 mac_addr_max_cnt,
					  u8 *mac_addr_cnt)
{
	switch (record->header.id) {
	case TI_AM6_EEPROM_RECORD_BOARD_INFO:
		if (record->header.len != sizeof(record->data.board_info))
			return -EINVAL;

		if (!ep)
			break;

		/* Populate (and clean, if needed) the board name */
		strlcpy(ep->name, record->data.board_info.name,
			sizeof(ep->name));
		ti_eeprom_string_cleanup(ep->name);

		/* Populate selected other fields from the board info record */
		strlcpy(ep->version, record->data.board_info.version,
			sizeof(ep->version));
		strlcpy(ep->software_revision,
			record->data.board_info.software_revision,
			sizeof(ep->software_revision));
		strlcpy(ep->serial, record->data.board_info.serial,
			sizeof(ep->serial));
		break;
	case TI_AM6_EEPROM_RECORD_MAC_INFO:
		if (record->header.len != sizeof(record->data.mac_info))
			return -EINVAL;

		if (!mac_addr || !mac_addr_max_cnt)
			break;

		*mac_addr_cnt = ((record->data.mac_info.mac_control &
				 TI_AM6_EEPROM_MAC_ADDR_COUNT_MASK) >>
				 TI_AM6_EEPROM_MAC_ADDR_COUNT_SHIFT) + 1;

		/*
		 * The EEPROM can (but may not) hold a very large amount
		 * of MAC addresses, by far exceeding what we want/can store
		 * in the common memory array, so only grab what we can fit.
		 * Note that a value of 0 means 1 MAC address, and so on.
		 */
		*mac_addr_cnt = min(*mac_addr_cnt, mac_addr_max_cnt);

		memcpy(mac_addr, record->data.mac_info.mac_addr,
		       *mac_addr_cnt * TI_EEPROM_HDR_ETH_ALEN);
		break;
	case 0x00:
		/* Illegal value... Fall through... */
	case 0xFF:
		/* Illegal value... Something went horribly wrong... */
		return -EINVAL;
	default:
		pr_warn("%s: Ignoring record id %u\n", __func__,
			record->header.id);
	}

	return 0;
}

int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr,
					 struct ti_am6_eeprom *ep,
					 char **mac_addr,
					 u8 mac_addr_max_cnt,
					 u8 *mac_addr_cnt)
{
	struct udevice *dev;
	struct udevice *bus;
	unsigned int eeprom_addr;
	struct ti_am6_eeprom_record_board_id board_id;
	struct ti_am6_eeprom_record record;
	int rc;

	/* Initialize with a known bad marker for i2c fails.. */
	memset(ep, 0, sizeof(*ep));
	ep->header = TI_DEAD_EEPROM_MAGIC;

	/* Read the board ID record which is always the first EEPROM record */
	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC,
			       sizeof(board_id), (uint8_t *)&board_id);
	if (rc)
		return rc;

	if (board_id.header.id != TI_AM6_EEPROM_RECORD_BOARD_ID) {
		pr_err("%s: Invalid board ID record!\n", __func__);
		return -EINVAL;
	}

	/* Establish DM handle to board config EEPROM */
	rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
	if (rc)
		return rc;
	rc = i2c_get_chip(bus, dev_addr, 1, &dev);
	if (rc)
		return rc;

	ep->header = TI_EEPROM_HEADER_MAGIC;

	/* Ready to parse TLV structure. Initialize variables... */
	*mac_addr_cnt = 0;

	/*
	 * After the all-encompassing board ID record all other records follow
	 * a TLV-type scheme. Point to the first such record and then start
	 * parsing those one by one.
	 */
	eeprom_addr = sizeof(board_id);

	while (true) {
		rc = dm_i2c_read(dev, eeprom_addr, (uint8_t *)&record.header,
				 sizeof(record.header));
		if (rc)
			return rc;

		/*
		 * Check for end of list marker. If we reached it don't go
		 * any further and stop parsing right here.
		 */
		if (record.header.id == TI_AM6_EEPROM_RECORD_END_LIST)
			break;

		eeprom_addr += sizeof(record.header);

		debug("%s: dev_addr=0x%02x header.id=%u header.len=%u\n",
		      __func__, dev_addr, record.header.id,
		      record.header.len);

		/* Read record into memory if it fits */
		if (record.header.len <= sizeof(record.data)) {
			rc = dm_i2c_read(dev, eeprom_addr,
					 (uint8_t *)&record.data,
					 record.header.len);
			if (rc)
				return rc;

			/* Process record */
			rc = ti_i2c_eeprom_am6_parse_record(&record, ep,
							    mac_addr,
							    mac_addr_max_cnt,
							    mac_addr_cnt);
			if (rc) {
				pr_err("%s: EEPROM parsing error!\n", __func__);
				return rc;
			}
		} else {
			/*
			 * We may get here in case of larger records which
			 * are not yet understood.
			 */
			pr_err("%s: Ignoring record id %u\n", __func__,
			       record.header.id);
		}

		eeprom_addr += record.header.len;
	}

	return 0;
}

int __maybe_unused ti_i2c_eeprom_am6_get_base(int bus_addr, int dev_addr)
{
	struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
	int ret;

	/*
	 * Always execute EEPROM read by not allowing to bypass it during the
	 * first invocation of SPL which happens on the R5 core.
	 */
#if !(defined(CONFIG_SPL_BUILD) && defined(CONFIG_CPU_V7R))
	if (ep->header == TI_EEPROM_HEADER_MAGIC) {
		debug("%s: EEPROM has already been read\n", __func__);
		return 0;
	}
#endif

	ret = ti_i2c_eeprom_am6_get(bus_addr, dev_addr, ep,
				    (char **)ep->mac_addr,
				    AM6_EEPROM_HDR_NO_OF_MAC_ADDR,
				    &ep->mac_addr_cnt);
	return ret;
}

bool __maybe_unused board_ti_is(char *name_tag)
{
	struct ti_common_eeprom *ep = TI_EEPROM_DATA;

	if (ep->header == TI_DEAD_EEPROM_MAGIC)
		return false;
	return !strncmp(ep->name, name_tag, TI_EEPROM_HDR_NAME_LEN);
}

bool __maybe_unused board_ti_rev_is(char *rev_tag, int cmp_len)
{
	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
	int l;

	if (ep->header == TI_DEAD_EEPROM_MAGIC)
		return false;

	l = cmp_len > TI_EEPROM_HDR_REV_LEN ? TI_EEPROM_HDR_REV_LEN : cmp_len;
	return !strncmp(ep->version, rev_tag, l);
}

char * __maybe_unused board_ti_get_rev(void)
{
	struct ti_common_eeprom *ep = TI_EEPROM_DATA;

	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
	return ep->version;
}

char * __maybe_unused board_ti_get_config(void)
{
	struct ti_common_eeprom *ep = TI_EEPROM_DATA;

	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
	return ep->config;
}

char * __maybe_unused board_ti_get_name(void)
{
	struct ti_common_eeprom *ep = TI_EEPROM_DATA;

	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
	return ep->name;
}

void __maybe_unused
board_ti_get_eth_mac_addr(int index,
			  u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])
{
	struct ti_common_eeprom *ep = TI_EEPROM_DATA;

	if (ep->header == TI_DEAD_EEPROM_MAGIC)
		goto fail;

	if (index < 0 || index >= TI_EEPROM_HDR_NO_OF_MAC_ADDR)
		goto fail;

	memcpy(mac_addr, ep->mac_addr[index], TI_EEPROM_HDR_ETH_ALEN);
	return;

fail:
	memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
}

void __maybe_unused
board_ti_am6_get_eth_mac_addr(int index,
			      u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])
{
	struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;

	if (ep->header == TI_DEAD_EEPROM_MAGIC)
		goto fail;

	if (index < 0 || index >= ep->mac_addr_cnt)
		goto fail;

	memcpy(mac_addr, ep->mac_addr[index], TI_EEPROM_HDR_ETH_ALEN);
	return;

fail:
	memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
}

u64 __maybe_unused board_ti_get_emif1_size(void)
{
	struct ti_common_eeprom *ep = TI_EEPROM_DATA;

	if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
		return 0;

	return ep->emif1_size;
}

u64 __maybe_unused board_ti_get_emif2_size(void)
{
	struct ti_common_eeprom *ep = TI_EEPROM_DATA;

	if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
		return 0;

	return ep->emif2_size;
}

void __maybe_unused set_board_info_env(char *name)
{
	char *unknown = "unknown";
	struct ti_common_eeprom *ep = TI_EEPROM_DATA;

	if (name)
		env_set("board_name", name);
	else if (ep->name)
		env_set("board_name", ep->name);
	else
		env_set("board_name", unknown);

	if (ep->version)
		env_set("board_rev", ep->version);
	else
		env_set("board_rev", unknown);

	if (ep->serial)
		env_set("board_serial", ep->serial);
	else
		env_set("board_serial", unknown);
}

void __maybe_unused set_board_info_env_am6(char *name)
{
	char *unknown = "unknown";
	struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;

	if (name)
		env_set("board_name", name);
	else if (ep->name)
		env_set("board_name", ep->name);
	else
		env_set("board_name", unknown);

	if (ep->version)
		env_set("board_rev", ep->version);
	else
		env_set("board_rev", unknown);

	if (ep->software_revision)
		env_set("board_software_revision", ep->software_revision);
	else
		env_set("board_software_revision", unknown);

	if (ep->serial)
		env_set("board_serial", ep->serial);
	else
		env_set("board_serial", unknown);
}

static u64 mac_to_u64(u8 mac[6])
{
	int i;
	u64 addr = 0;

	for (i = 0; i < 6; i++) {
		addr <<= 8;
		addr |= mac[i];
	}

	return addr;
}

static void u64_to_mac(u64 addr, u8 mac[6])
{
	mac[5] = addr;
	mac[4] = addr >> 8;
	mac[3] = addr >> 16;
	mac[2] = addr >> 24;
	mac[1] = addr >> 32;
	mac[0] = addr >> 40;
}

void board_ti_set_ethaddr(int index)
{
	uint8_t mac_addr[6];
	int i;
	u64 mac1, mac2;
	u8 mac_addr1[6], mac_addr2[6];
	int num_macs;
	/*
	 * Export any Ethernet MAC addresses from EEPROM.
	 * The 2 MAC addresses in EEPROM define the address range.
	 */
	board_ti_get_eth_mac_addr(0, mac_addr1);
	board_ti_get_eth_mac_addr(1, mac_addr2);

	if (is_valid_ethaddr(mac_addr1) && is_valid_ethaddr(mac_addr2)) {
		mac1 = mac_to_u64(mac_addr1);
		mac2 = mac_to_u64(mac_addr2);

		/* must contain an address range */
		num_macs = mac2 - mac1 + 1;
		if (num_macs <= 0)
			return;

		if (num_macs > 50) {
			printf("%s: Too many MAC addresses: %d. Limiting to 50\n",
			       __func__, num_macs);
			num_macs = 50;
		}

		for (i = 0; i < num_macs; i++) {
			u64_to_mac(mac1 + i, mac_addr);
			if (is_valid_ethaddr(mac_addr)) {
				eth_env_set_enetaddr_by_index("eth", i + index,
							      mac_addr);
			}
		}
	}
}

void board_ti_am6_set_ethaddr(int index, int count)
{
	u8 mac_addr[6];
	int i;

	for (i = 0; i < count; i++) {
		board_ti_am6_get_eth_mac_addr(i, mac_addr);
		if (is_valid_ethaddr(mac_addr))
			eth_env_set_enetaddr_by_index("eth", i + index,
						      mac_addr);
	}
}

bool __maybe_unused board_ti_was_eeprom_read(void)
{
	struct ti_common_eeprom *ep = TI_EEPROM_DATA;

	if (ep->header == TI_EEPROM_HEADER_MAGIC)
		return true;
	else
		return false;
}
