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

#include <common.h>
#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);
	}
	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();
}

static int print_usage(void)
{
	printf("display and program the system ID and MAC addresses in EEPROM\n"
	"[read_eeprom|initialize|write_eeprom|mac_address|pcb_revision|bom_revision|product_id]\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 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");
	return 0;
}

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 print_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);
	}

	if (argc != 3)
		return print_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 print_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);
}
