// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2023 StarFive Technology Co., Ltd.
 * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
 */

#include <command.h>
#include <env.h>
#include <i2c.h>
#include <init.h>
#include <u-boot/crc.h>
#include <linux/delay.h>

#define FORMAT_VERSION		0x2
#define PCB_VERSION		0xB1
#define BOM_VERSION		'A'
/*
 * BYTES_PER_EEPROM_PAGE: the 24FC04H datasheet says that data can
 * only be written in page mode, which means 16 bytes at a time:
 * 16-Byte Page Write Buffer
 */
#define BYTES_PER_EEPROM_PAGE		16

/*
 * EEPROM_WRITE_DELAY_MS: the 24FC04H datasheet says it takes up to
 * 5ms to complete a given write:
 * Write Cycle Time (byte or page) ro Page Write Time 5 ms, Maximum
 */
#define EEPROM_WRITE_DELAY_MS		5000
/*
 * StarFive OUI. Registration Date is 20xx-xx-xx
 */
#define STARFIVE_OUI_PREFIX		"6C:CF:39:"
#define STARFIVE_DEFAULT_MAC0		"6C:CF:39:6C:DE:AD"
#define STARFIVE_DEFAULT_MAC1		"6C:CF:39:6C:DE:AE"

/* Magic number at the first four bytes of EEPROM HATs */
#define STARFIVE_EEPROM_HATS_SIG	"SFVF" /* StarFive VisionFive */

#define STARFIVE_EEPROM_HATS_SIZE_MAX	256 /* Header + Atom1&4(v1) */
#define STARFIVE_EEPROM_WP_OFFSET	0 /* Read only field */
#define STARFIVE_EEPROM_ATOM1_PSTR	"VF7110A1-2228-D008E000-00000001\0"
#define STARFIVE_EEPROM_ATOM1_PSTR_SIZE	32
#define STARFIVE_EEPROM_ATOM1_SN_OFFSET	23
#define STARFIVE_EEPROM_ATOM1_VSTR	"StarFive Technology Co., Ltd.\0\0\0"
#define STARFIVE_EEPROM_ATOM1_VSTR_SIZE	32

#define MAGIC_NUMBER_BYTES	4
#define MAC_ADDR_BYTES		6
#define MAC_ADDR_STRLEN		17

/*
 * Atom Types
 * 0x0000 = invalid
 * 0x0001 = vendor info
 * 0x0002 = GPIO map
 * 0x0003 = Linux device tree blob
 * 0x0004 = manufacturer custom data
 * 0x0005-0xfffe = reserved for future use
 * 0xffff = invalid
 */

#define HATS_ATOM_INVALID	0x0000
#define HATS_ATOM_VENDOR	0x0001
#define HATS_ATOM_GPIO		0x0002
#define HATS_ATOM_DTB		0x0003
#define HATS_ATOM_CUSTOM	0x0004
#define HATS_ATOM_INVALID_END	0xffff

struct eeprom_header {
	char signature[MAGIC_NUMBER_BYTES];	/* ASCII table signature */
	u8 version;		/* EEPROM data format version */
				/* (0x00 reserved, 0x01 = first version) */
	u8 reversed;		/* 0x00, Reserved field */
	u16 numatoms;		/* total atoms in EEPROM */
	u32 eeplen;		/* total length in bytes of all eeprom data */
				/* (including this header) */
};

struct eeprom_atom_header {
	u16 type;
	u16 count;
	u32 dlen;
};

struct eeprom_atom1_data {
	u8 uuid[16];
	u16 pid;
	u16 pver;
	u8 vslen;
	u8 pslen;
	uchar vstr[STARFIVE_EEPROM_ATOM1_VSTR_SIZE];
	uchar pstr[STARFIVE_EEPROM_ATOM1_PSTR_SIZE]; /* product SN */
};

struct starfive_eeprom_atom1 {
	struct eeprom_atom_header header;
	struct eeprom_atom1_data data;
	u16 crc;
};

struct eeprom_atom4_data {
	u16 version;
	u8 pcb_revision;		/* PCB version */
	u8 bom_revision;		/* BOM version */
	u8 mac0_addr[MAC_ADDR_BYTES];	/* Ethernet0 MAC */
	u8 mac1_addr[MAC_ADDR_BYTES];	/* Ethernet1 MAC */
	u8 reserved[2];
};

struct starfive_eeprom_atom4 {
	struct eeprom_atom_header header;
	struct eeprom_atom4_data data;
	u16 crc;
};

struct starfive_eeprom {
	struct eeprom_header header;
	struct starfive_eeprom_atom1 atom1;
	struct starfive_eeprom_atom4 atom4;
};

static union {
	struct starfive_eeprom eeprom;
	uchar buf[STARFIVE_EEPROM_HATS_SIZE_MAX];
} pbuf __section(".data");

/* Set to 1 if we've read EEPROM into memory */
static int has_been_read __section(".data");

static inline int is_match_magic(void)
{
	return strncmp(pbuf.eeprom.header.signature, STARFIVE_EEPROM_HATS_SIG,
				MAGIC_NUMBER_BYTES);
}

/* Calculate the current CRC */
static inline u32 calculate_crc16(struct eeprom_atom_header *head)
{
	uint len = sizeof(struct eeprom_atom_header) + head->dlen - sizeof(u16);

	return crc16(0, (void *)head, len);
}

/* This function should be called after each update to the EEPROM structure */
static inline void update_crc(void)
{
	pbuf.eeprom.atom1.crc = calculate_crc16(&pbuf.eeprom.atom1.header);
	pbuf.eeprom.atom4.crc = calculate_crc16(&pbuf.eeprom.atom4.header);
}

static void dump_raw_eeprom(void)
{
	unsigned int i;
	u32 len;

	len = sizeof(struct starfive_eeprom);
	for (i = 0; i < len; i++) {
		if ((i % 16) == 0)
			printf("%02X: ", i);
		printf("%02X ", ((u8 *)pbuf.buf)[i]);
		if (((i % 16) == 15) || (i == len - 1))
			printf("\n");
	}
}

/**
 * show_eeprom - display the contents of the EEPROM
 */
static void show_eeprom(void)
{
	if (has_been_read != 1)
		return;

	printf("\n--------EEPROM INFO--------\n");
	printf("Vendor : %s\n", pbuf.eeprom.atom1.data.vstr);
	printf("Product full SN: %s\n", pbuf.eeprom.atom1.data.pstr);
	printf("data version: 0x%x\n", pbuf.eeprom.atom4.data.version);
	if (pbuf.eeprom.atom4.data.version == 2) {
		printf("PCB revision: 0x%x\n", pbuf.eeprom.atom4.data.pcb_revision);
		printf("BOM revision: %c\n", pbuf.eeprom.atom4.data.bom_revision);
		printf("Ethernet MAC0 address: %02x:%02x:%02x:%02x:%02x:%02x\n",
		       pbuf.eeprom.atom4.data.mac0_addr[0], pbuf.eeprom.atom4.data.mac0_addr[1],
		       pbuf.eeprom.atom4.data.mac0_addr[2], pbuf.eeprom.atom4.data.mac0_addr[3],
		       pbuf.eeprom.atom4.data.mac0_addr[4], pbuf.eeprom.atom4.data.mac0_addr[5]);
		printf("Ethernet MAC1 address: %02x:%02x:%02x:%02x:%02x:%02x\n",
		       pbuf.eeprom.atom4.data.mac1_addr[0], pbuf.eeprom.atom4.data.mac1_addr[1],
		       pbuf.eeprom.atom4.data.mac1_addr[2], pbuf.eeprom.atom4.data.mac1_addr[3],
		       pbuf.eeprom.atom4.data.mac1_addr[4], pbuf.eeprom.atom4.data.mac1_addr[5]);
	} else {
		printf("Custom data v%d is not Supported\n", pbuf.eeprom.atom4.data.version);
		dump_raw_eeprom();
	}
	printf("--------EEPROM INFO--------\n\n");
}

/**
 * set_mac_address() - stores a MAC address into the local EEPROM copy
 *
 * This function takes a pointer to MAC address string
 * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number),
 * stores it in the MAC address field of the EEPROM local copy, and
 * updates the local copy of the CRC.
 */
static void set_mac_address(char *string, int index)
{
	u8 i;
	u8 *mac;

	if (strncasecmp(STARFIVE_OUI_PREFIX, string,
			strlen(STARFIVE_OUI_PREFIX))) {
		printf("The MAC address doesn't match StarFive OUI %s\n",
		       STARFIVE_OUI_PREFIX);
		return;
	}
	mac = (index == 0) ? pbuf.eeprom.atom4.data.mac0_addr :
			pbuf.eeprom.atom4.data.mac1_addr;

	for (i = 0; *string && (i < MAC_ADDR_BYTES); i++) {
		mac[i] = hextoul(string, &string);

		if (*string == ':')
			string++;
	}

	update_crc();
}

/**
 * init_local_copy() - initialize the in-memory EEPROM copy
 *
 * Initialize the in-memory EEPROM copy with the magic number.  Must
 * be done when preparing to initialize a blank EEPROM, or overwrite
 * one with a corrupted magic number.
 */
static void init_local_copy(void)
{
	memset((void *)pbuf.buf, 0, sizeof(struct starfive_eeprom));
	memcpy(pbuf.eeprom.header.signature, STARFIVE_EEPROM_HATS_SIG,
	       strlen(STARFIVE_EEPROM_HATS_SIG));
	pbuf.eeprom.header.version = FORMAT_VERSION;
	pbuf.eeprom.header.numatoms = 2;
	pbuf.eeprom.header.eeplen = sizeof(struct starfive_eeprom);

	pbuf.eeprom.atom1.header.type = HATS_ATOM_VENDOR;
	pbuf.eeprom.atom1.header.count = 1;
	pbuf.eeprom.atom1.header.dlen = sizeof(struct eeprom_atom1_data) + sizeof(u16);
	pbuf.eeprom.atom1.data.vslen = STARFIVE_EEPROM_ATOM1_VSTR_SIZE;
	pbuf.eeprom.atom1.data.pslen = STARFIVE_EEPROM_ATOM1_PSTR_SIZE;
	memcpy(pbuf.eeprom.atom1.data.vstr, STARFIVE_EEPROM_ATOM1_VSTR,
	       strlen(STARFIVE_EEPROM_ATOM1_VSTR));
	memcpy(pbuf.eeprom.atom1.data.pstr, STARFIVE_EEPROM_ATOM1_PSTR,
	       strlen(STARFIVE_EEPROM_ATOM1_PSTR));

	pbuf.eeprom.atom4.header.type = HATS_ATOM_CUSTOM;
	pbuf.eeprom.atom4.header.count = 2;
	pbuf.eeprom.atom4.header.dlen = sizeof(struct eeprom_atom4_data) + sizeof(u16);
	pbuf.eeprom.atom4.data.version = FORMAT_VERSION;
	pbuf.eeprom.atom4.data.pcb_revision = PCB_VERSION;
	pbuf.eeprom.atom4.data.bom_revision = BOM_VERSION;
	set_mac_address(STARFIVE_DEFAULT_MAC0, 0);
	set_mac_address(STARFIVE_DEFAULT_MAC1, 1);
}

/**
 * prog_eeprom() - write the EEPROM from memory
 */
static int prog_eeprom(unsigned int size)
{
	unsigned int i;
	void *p;
	uchar tmp_buff[STARFIVE_EEPROM_HATS_SIZE_MAX];
	struct udevice *dev;
	int ret;

	if (is_match_magic()) {
		printf("MAGIC ERROR, Please check the data@%p.\n", pbuf.buf);
		return -1;
	}

	ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM,
				      CONFIG_SYS_I2C_EEPROM_ADDR,
				      CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
				      &dev);
	if (ret) {
		printf("Get i2c bus:%d addr:%d fail.\n", CONFIG_SYS_EEPROM_BUS_NUM,
		       CONFIG_SYS_I2C_EEPROM_ADDR);
		return ret;
	}

	for (i = 0, p = (u8 *)pbuf.buf; i < size; ) {
		if (!ret)
			ret = dm_i2c_write(dev, i, p, min((int)(size - i),
							  BYTES_PER_EEPROM_PAGE));
		if (ret)
			break;

		udelay(EEPROM_WRITE_DELAY_MS);
		i += BYTES_PER_EEPROM_PAGE;
		p += BYTES_PER_EEPROM_PAGE;
	}

	if (!ret) {
		/* Verify the write by reading back the EEPROM and comparing */
		ret = dm_i2c_read(dev,
				  STARFIVE_EEPROM_WP_OFFSET,
				  tmp_buff,
				  STARFIVE_EEPROM_HATS_SIZE_MAX);
		if (!ret && memcmp((void *)pbuf.buf, (void *)tmp_buff,
				   STARFIVE_EEPROM_HATS_SIZE_MAX))
			ret = -1;
	}

	if (ret) {
		has_been_read = -1;
		printf("Programming failed.\n");
		return -1;
	}

	printf("Programming passed.\n");
	return 0;
}

/**
 * read_eeprom() - read the EEPROM into memory, if it hasn't been read already
 */
static int read_eeprom(void)
{
	int ret;
	struct udevice *dev;

	if (has_been_read == 1)
		return 0;

	ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM,
				      CONFIG_SYS_I2C_EEPROM_ADDR, 1, &dev);
	if (!ret)
		ret = dm_i2c_read(dev, 0, (u8 *)pbuf.buf,
				  STARFIVE_EEPROM_HATS_SIZE_MAX);

	has_been_read = (ret == 0) ? 1 : 0;

	return ret;
}

/**
 * set_pcb_revision() - stores a StarFive PCB revision into the local EEPROM copy
 *
 * Takes a pointer to a string representing the numeric PCB revision in
 * decimal ("0" - "255"), stores it in the pcb_revision field of the
 * EEPROM local copy, and updates the CRC of the local copy.
 */
static void set_pcb_revision(char *string)
{
	u32 p;

	p = simple_strtoul(string, &string, 16);
	if (p > U8_MAX) {
		printf("%s must not be greater than %d\n", "PCB revision",
		       U8_MAX);
		return;
	}

	pbuf.eeprom.atom4.data.pcb_revision = p;

	update_crc();
}

/**
 * set_bom_revision() - stores a StarFive BOM revision into the local EEPROM copy
 *
 * Takes a pointer to a uppercase ASCII character representing the BOM
 * revision ("A" - "Z"), stores it in the bom_revision field of the
 * EEPROM local copy, and updates the CRC of the local copy.
 */
static void set_bom_revision(char *string)
{
	if (string[0] < 'A' || string[0] > 'Z') {
		printf("BOM revision must be an uppercase letter between A and Z\n");
		return;
	}

	pbuf.eeprom.atom4.data.bom_revision = string[0];

	update_crc();
}

/**
 * set_product_id() - stores a StarFive product ID into the local EEPROM copy
 *
 * Takes a pointer to a string representing the numeric product ID  in
 * string ("VF7100A1-2150-D008E000-00000001\0"), stores it in the product string
 * field of the EEPROM local copy, and updates the CRC of the local copy.
 */
static void set_product_id(char *string)
{
	u32 len;

	len = (strlen(string) > STARFIVE_EEPROM_ATOM1_PSTR_SIZE) ?
		STARFIVE_EEPROM_ATOM1_PSTR_SIZE : strlen(string);

	memcpy((void *)pbuf.eeprom.atom1.data.pstr, (void *)string, len);

	update_crc();
}

const char *get_product_id_from_eeprom(void)
{
	if (read_eeprom())
		return NULL;

	return pbuf.eeprom.atom1.data.pstr;
}

int do_mac(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	char *cmd;

	if (argc == 1) {
		show_eeprom();
		return 0;
	}

	if (argc > 3)
		return CMD_RET_USAGE;

	cmd = argv[1];

	/* Commands with no argument */
	if (!strcmp(cmd, "read_eeprom")) {
		has_been_read = 0;
		return read_eeprom();
	} else if (!strcmp(cmd, "initialize")) {
		init_local_copy();
		return 0;
	} else if (!strcmp(cmd, "write_eeprom")) {
		return prog_eeprom(STARFIVE_EEPROM_HATS_SIZE_MAX);
	} else if (!strcmp(cmd, "raw")) {
		dump_raw_eeprom();
		return 0;
	}

	if (argc != 3)
		return CMD_RET_USAGE;

	if (is_match_magic()) {
		printf("Please read the EEPROM ('read_eeprom') and/or initialize the EEPROM ('initialize') first.\n");
		return 0;
	}

	if (!strcmp(cmd, "mac0_address")) {
		set_mac_address(argv[2], 0);
		return 0;
	} else if (!strcmp(cmd, "mac1_address")) {
		set_mac_address(argv[2], 1);
		return 0;
	} else if (!strcmp(cmd, "pcb_revision")) {
		set_pcb_revision(argv[2]);
		return 0;
	} else if (!strcmp(cmd, "bom_revision")) {
		set_bom_revision(argv[2]);
		return 0;
	} else if (!strcmp(cmd, "product_id")) {
		set_product_id(argv[2]);
		return 0;
	}

	return CMD_RET_USAGE;
}

/**
 * mac_read_from_eeprom() - read the MAC address & the serial number in EEPROM
 *
 * This function reads the MAC address and the serial number from EEPROM and
 * sets the appropriate environment variables for each one read.
 *
 * The environment variables are only set if they haven't been set already.
 * This ensures that any user-saved variables are never overwritten.
 *
 * If CONFIG_ID_EEPROM is enabled, this function will be called in
 * "static init_fnc_t init_sequence_r[]" of u-boot/common/board_r.c.
 */
int mac_read_from_eeprom(void)
{
	/**
	 * try to fill the buff from EEPROM,
	 * always return SUCCESS, even some error happens.
	 */
	if (read_eeprom()) {
		dump_raw_eeprom();
		return 0;
	}

	// 1, setup ethaddr env
	eth_env_set_enetaddr("ethaddr", pbuf.eeprom.atom4.data.mac0_addr);
	eth_env_set_enetaddr("eth1addr", pbuf.eeprom.atom4.data.mac1_addr);

	/**
	 * 2, setup serial# env, reference to hifive-platform-i2c-eeprom.c,
	 * serial# can be a ASCII string, but not just a hex number, so we
	 * setup serial# in the 32Byte format:
	 * "VF7100A1-2201-D008E000-00000001;"
	 * "<product>-<date>-<DDR&eMMC>-<serial_number>"
	 * <date>: 4Byte, should be the output of `date +%y%W`
	 * <DDR&eMMC>: 8Byte, "D008" means 8GB, "D01T" means 1TB;
	 *     "E000" means no eMMC，"E032" means 32GB, "E01T" means 1TB.
	 * <serial_number>: 8Byte, the Unique Identifier of board in hex.
	 */
	if (!env_get("serial#"))
		env_set("serial#", pbuf.eeprom.atom1.data.pstr);

	printf("StarFive EEPROM format v%u\n", pbuf.eeprom.header.version);
	show_eeprom();
	return 0;
}

/**
 * get_pcb_revision_from_eeprom - get the PCB revision
 *
 * 1.2A return 'A'/'a', 1.3B return 'B'/'b',other values are illegal
 */
u8 get_pcb_revision_from_eeprom(void)
{
	u8 pv = 0xFF;

	if (read_eeprom())
		return pv;

	return pbuf.eeprom.atom1.data.pstr[6];
}

/**
 * get_ddr_size_from_eeprom - get the DDR size
 * pstr:  VF7110A1-2228-D008E000-00000001
 * VF7110A1/VF7110B1 : VisionFive JH7110A /VisionFive JH7110B
 * D008:　8GB LPDDR4
 * E000: No emmc device, ECxx: include emmc device, xx: Capacity size[GB]
 * return: the field of 'D008E000'
 */

u32 get_ddr_size_from_eeprom(void)
{
	u32 pv = 0xFFFFFFFF;

	if (read_eeprom())
		return pv;

	return hextoul(&pbuf.eeprom.atom1.data.pstr[14], NULL);
}

U_BOOT_LONGHELP(mac,
	"\n"
	"    - display EEPROM content\n"
	"mac read_eeprom\n"
	"    - read EEPROM content into memory data structure\n"
	"mac write_eeprom\n"
	"    - save memory data structure to the EEPROM\n"
	"mac initialize\n"
	"    - initialize the in-memory EEPROM copy with default data\n"
	"mac raw\n"
	"    - hexdump memory data structure\n"
	"mac mac0_address <xx:xx:xx:xx:xx:xx>\n"
	"    - stores a MAC0 address into the local EEPROM copy\n"
	"mac mac1_address <xx:xx:xx:xx:xx:xx>\n"
	"    - stores a MAC1 address into the local EEPROM copy\n"
	"mac pcb_revision <?>\n"
	"    - stores a StarFive PCB revision into the local EEPROM copy\n"
	"mac bom_revision <A>\n"
	"    - stores a StarFive BOM revision into the local EEPROM copy\n"
	"mac product_id <VF7110A1-2228-D008E000-xxxxxxxx>\n"
	"    - stores a StarFive product ID into the local EEPROM copy\n");

U_BOOT_CMD(
	mac, 3, 1,  do_mac,
	"display and program the board revision and MAC address in EEPROM",
	mac_help_text);
