starfive: add ID_EEPROM supoort for visionfive V1

This patch add ID_EEPROM (mac command) support for visionfive V1.

Signed-off-by: Wei Fu <wefu@redhat.com>
This commit is contained in:
Wei Fu 2021-12-28 16:44:18 +08:00 committed by Tekkaman Ninja
parent 8bd2d61d93
commit d434b5243d
5 changed files with 775 additions and 2 deletions

View file

@ -5,3 +5,5 @@
obj-y += jh7100.o
obj-y += jh_ptc.o
obj-$(CONFIG_ID_EEPROM) += jh7100-i2c-eeprom.o

View file

@ -0,0 +1,734 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
* Written by Wei Fu (wefu@redhat.com)
*/
#include <common.h>
#include <command.h>
#include <env.h>
#include <i2c.h>
#include <init.h>
#include <linux/ctype.h>
#include <linux/delay.h>
//#include <u-boot/crc.h>
/*
* MAGIC_NUMBER_BYTES: number of bytes used by the magic number
*/
#define MAGIC_NUMBER_BYTES 4
/*
* SERIAL_NUMBER_BYTES: number of bytes used by the board serial
* number
*/
//#define SERIAL_NUMBER_BYTES 16
/*
* MAC_ADDR_BYTES: number of bytes used by the Ethernet MAC address
*/
#define MAC_ADDR_BYTES 6
/*
* MAC_ADDR_STRLEN: length of mac address string
*/
#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_hats_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_hats_atom_header {
u16 type;
u16 count;
u32 dlen;
};
/**
* static eeprom: EEPROM layout for the StarFive platform I2C format
*/
struct starfive_eeprom_atom1_data {
u8 uuid[16];
u16 pid;
u16 pver;
u8 vslen;
u8 pslen;
uchar vstr[CONFIG_STARFIVE_EEPROM_ATOM1_VSTR_SIZE];
uchar pstr[CONFIG_STARFIVE_EEPROM_ATOM1_PSTR_SIZE]; /* product SN */
};
struct starfive_eeprom_atom1 {
struct eeprom_hats_atom_header header;
struct starfive_eeprom_atom1_data data;
u16 crc16;
};
struct starfive_eeprom_atom4_v1_data {
u16 version;
u8 pcb_revision; /* PCB version */
u8 bom_revision; /* BOM version */
u8 mac_addr[MAC_ADDR_BYTES]; /* Ethernet0 MAC */
};
struct starfive_eeprom_atom4_v1 {
struct eeprom_hats_atom_header header;
struct starfive_eeprom_atom4_v1_data data;
u16 crc16;
};
/* Set to 1 if we've read EEPROM into memory
* Set to -1 if EEPROM data is wrong
*/
static int has_been_read;
/**
* helper struct for getting info from the local EEPROM copy.
* most of the items are pointers to the eeprom_wp_buff.
* ONLY serialnum is the u32 from the last 8 Bytes of product string
*/
struct starfive_eeprom_info {
char *vstr; /* Vendor string in ATOM1 */
char *pstr; /* product string in ATOM1 */
u32 serialnum; /* serial number from in product string*/
u16 *version; /* custom data version in ATOM4 */
u8 *pcb_revision; /* PCB version in ATOM4 */
u8 *bom_revision; /* BOM version in ATOM4 */
u8 *mac_addr; /* Ethernet0 MAC in ATOM4 */
};
static struct starfive_eeprom_info einfo;
static uchar eeprom_wp_buff[CONFIG_STARFIVE_EEPROM_HATS_SIZE_MAX];
static struct eeprom_hats_header starfive_eeprom_hats_header_default = {
.signature = STARFIVE_EEPROM_HATS_SIG,
.version = FORMAT_VERSION,
.numatoms = 2,
.eeplen = sizeof(struct eeprom_hats_header) +
sizeof(struct starfive_eeprom_atom1) +
sizeof(struct starfive_eeprom_atom4_v1)
};
static struct starfive_eeprom_atom1 starfive_eeprom_atom1_default = {
.header = {
.type = HATS_ATOM_VENDOR,
.count = 1,
.dlen = sizeof(struct starfive_eeprom_atom1_data) + sizeof(u16)
},
.data = {
.uuid = {0},
.pid = 0,
.pver = 0,
.vslen = CONFIG_STARFIVE_EEPROM_ATOM1_VSTR_SIZE,
.pslen = CONFIG_STARFIVE_EEPROM_ATOM1_PSTR_SIZE,
.vstr = CONFIG_STARFIVE_EEPROM_ATOM1_VSTR,
.pstr = CONFIG_STARFIVE_EEPROM_ATOM1_PSTR
}
};
static struct starfive_eeprom_atom4_v1 starfive_eeprom_atom4_v1_default = {
.header = {
.type = HATS_ATOM_CUSTOM,
.count = 2,
.dlen = sizeof(struct starfive_eeprom_atom4_v1_data) + sizeof(u16)
},
.data = {
.version = FORMAT_VERSION,
.pcb_revision = PCB_VERSION,
.bom_revision = BOM_VERSION,
.mac_addr = STARFIVE_DEFAULT_MAC
}
};
//static u8 starfive_default_mac[MAC_ADDR_BYTES] = STARFIVE_DEFAULT_MAC;
/**
* is_match_magic() - Does the magic number match that of a StarFive EEPROM?
*
* @hats: the pointer of eeprom_hats_header
* Return: status code, 0: Yes, non-0: NO
*/
static inline int is_match_magic(char *hats)
{
return strncmp(hats, STARFIVE_EEPROM_HATS_SIG, MAGIC_NUMBER_BYTES);
}
/**
* calculate_crc16() - Calculate the current CRC for atom
* Porting from https://github.com/raspberrypi/hats, getcrc
* @data: the pointer of eeprom_hats_atom_header
* @size: total length in bytes of the entire atom
* (type, count, dlen, data)
* Return: result: crc16 code
*/
#define CRC16 0x8005
static u16 calculate_crc16(uchar* data, unsigned int size)
{
int i, j = 0x0001;
u16 out = 0, crc = 0;
int bits_read = 0, bit_flag;
/* Sanity check: */
if((data == NULL) || size == 0)
return 0;
while(size > 0) {
bit_flag = out >> 15;
/* Get next bit: */
out <<= 1;
// item a) work from the least significant bits
out |= (*data >> bits_read) & 1;
/* Increment bit counter: */
bits_read++;
if(bits_read > 7) {
bits_read = 0;
data++;
size--;
}
/* Cycle check: */
if(bit_flag)
out ^= CRC16;
}
// item b) "push out" the last 16 bits
for (i = 0; i < 16; ++i) {
bit_flag = out >> 15;
out <<= 1;
if(bit_flag)
out ^= CRC16;
}
// item c) reverse the bits
for (i = 0x8000; i != 0; i >>=1, j <<= 1) {
if (i & out)
crc |= j;
}
return crc;
}
/* This function should be called after each update to any EEPROM ATOM */
static inline void update_crc(struct eeprom_hats_atom_header *atom)
{
uint atom_crc_offset = sizeof(struct eeprom_hats_atom_header) +
atom->dlen - sizeof(u16);
u16 *atom_crc_p = (void *) atom + atom_crc_offset;
*atom_crc_p = calculate_crc16((uchar*) atom, atom_crc_offset);
}
/**
* dump_raw_eeprom - display the raw contents of the EEPROM
*/
static void dump_raw_eeprom(u8 *e, unsigned int size)
{
unsigned int i;
printf("EEPROM dump: (0x%x bytes)\n", size);
for (i = 0; i < size; i++) {
if (!(i % 0x10))
printf("%02X: ", i);
printf("%02X ", e[i]);
if (((i % 16) == 15) || (i == size - 1))
printf("\n");
}
return;
}
static int hats_atom_crc_check(struct eeprom_hats_atom_header *atom)
{
u16 atom_crc, data_crc;
uint atom_crc_offset = sizeof(struct eeprom_hats_atom_header) +
atom->dlen - sizeof(atom_crc);
u16 *atom_crc_p = (void *) atom + atom_crc_offset;
atom_crc = *atom_crc_p;
data_crc = calculate_crc16((uchar *) atom, atom_crc_offset);
if (atom_crc == data_crc)
return 0;
printf("EEPROM HATs: CRC ERROR in atom %x type %x, (%x!=%x)\n",
atom->count, atom->type, atom_crc, data_crc);
return -1;
}
static void *hats_get_atom(struct eeprom_hats_header *header, u16 type)
{
struct eeprom_hats_atom_header *atom;
void *hats_eeprom_max = (void *)header + header->eeplen;
void *temp = (void *)header + sizeof(struct eeprom_hats_header);
for (int numatoms = (int)header->numatoms; numatoms > 0; numatoms--) {
atom = (struct eeprom_hats_atom_header *)temp;
if (hats_atom_crc_check(atom))
return NULL;
if (atom->type == type)
return (void *)atom;
/* go to next atom */
temp = (void *)atom + sizeof(struct eeprom_hats_atom_header) +
atom->dlen;
if (temp > hats_eeprom_max) {
printf("EEPROM HATs: table overflow next@%p, max@%p\n",
temp, hats_eeprom_max);
break;
}
}
/* fail to get atom */
return NULL;
}
/**
* show_eeprom - display the contents of the EEPROM
*/
static void show_eeprom(struct starfive_eeprom_info *einfo)
{
printf("\n--------EEPROM INFO--------\n");
printf("Vendor : %s\n", einfo->vstr);
printf("Product full SN: %s\n", einfo->pstr);
printf("data version: 0x%x\n", *einfo->version);
if (1 == *einfo->version) {
printf("PCB revision: 0x%x\n", *einfo->pcb_revision);
printf("BOM revision: %c\n", *einfo->bom_revision);
printf("Ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
einfo->mac_addr[0], einfo->mac_addr[1],
einfo->mac_addr[2], einfo->mac_addr[3],
einfo->mac_addr[4], einfo->mac_addr[5]);
} else {
printf("Custom data v%d is not Supported\n", *einfo->version);
}
printf("--------EEPROM INFO--------\n\n");
}
/**
* parse_eeprom_info - parse the contents of the EEPROM
* If everthing gose right,
* 1, set has_been_read to 1
* 2, display info
*
* If anything goes wrong,
* 1, set has_been_read to -1
* 2, dump data by hex for debug
*
* @buf: the pointer of eeprom_hats_header in memory
* Return: status code, 0: Success, non-0: Fail
*
*/
static int parse_eeprom_info(struct eeprom_hats_header *buf)
{
struct eeprom_hats_atom_header *atom;
void *atom_data;
struct starfive_eeprom_atom1_data *atom1 = NULL;
struct starfive_eeprom_atom4_v1_data *atom4_v1 = NULL;
if (is_match_magic((char *)buf)) {
printf("Not a StarFive EEPROM data format - magic error\n");
goto error;
};
printf("StarFive EEPROM format v%u\n", buf->version);
// parse atom1(verdor)
atom = (struct eeprom_hats_atom_header *)
hats_get_atom(buf, HATS_ATOM_VENDOR);
if (atom) {
atom_data = (void *)atom +
sizeof(struct eeprom_hats_atom_header);
atom1 = (struct starfive_eeprom_atom1_data *)atom_data;
einfo.vstr = atom1->vstr;
einfo.pstr = atom1->pstr;
einfo.serialnum = (u32)hextoul((void *)atom1->pstr +
CONFIG_STARFIVE_EEPROM_ATOM1_SN_OFFSET,
NULL);
} else {
printf("fail to get vendor atom\n");
goto error;
};
// parse atom4(custom)
atom = (struct eeprom_hats_atom_header *)
hats_get_atom(buf, HATS_ATOM_CUSTOM);
if (atom) {
atom_data = (void *)atom +
sizeof(struct eeprom_hats_atom_header);
atom4_v1 = (struct starfive_eeprom_atom4_v1_data *)atom_data;
einfo.version = &atom4_v1->version;
if (*einfo.version == 1) {
einfo.pcb_revision = &atom4_v1->pcb_revision;
einfo.bom_revision = &atom4_v1->bom_revision;
einfo.mac_addr = atom4_v1->mac_addr;
}
} else {
printf("fail to get custom data atom\n");
goto error;
};
// everthing gose right
has_been_read = 1;
show_eeprom(&einfo);
return 0;
error:
has_been_read = -1;
dump_raw_eeprom(eeprom_wp_buff,
CONFIG_STARFIVE_EEPROM_HATS_SIZE_MAX);
return -1;
}
/**
* read_eeprom() - read the EEPROM into memory, if it hasn't been read yet
* @buf: the pointer of eeprom data buff
* Return: status code, 0: Success, non-0: Fail
* Note: depend on CONFIG_SYS_EEPROM_BUS_NUM
* CONFIG_SYS_I2C_EEPROM_ADDR
* CONFIG_STARFIVE_EEPROM_WP_OFFSET
* CONFIG_STARFIVE_EEPROM_HATS_SIZE_MAX
*/
static int read_eeprom(uint8_t *buf)
{
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,
CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
&dev);
if (!ret) {
ret = dm_i2c_read(dev, CONFIG_STARFIVE_EEPROM_WP_OFFSET,
buf, CONFIG_STARFIVE_EEPROM_HATS_SIZE_MAX);
}
if (ret) {
printf("fail to read EEPROM.\n");
return ret;
}
return parse_eeprom_info((struct eeprom_hats_header *)buf);
}
/**
* prog_eeprom() - write the EEPROM from memory
*/
static int prog_eeprom(uint8_t *buf, unsigned int size)
{
unsigned int i;
void *p;
uchar tmp_buff[CONFIG_STARFIVE_EEPROM_HATS_SIZE_MAX];
struct udevice *dev;
int ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM,
CONFIG_SYS_I2C_EEPROM_ADDR,
CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
&dev);
if (is_match_magic(buf)) {
printf("MAGIC ERROR, Please check the data@%p.\n", buf);
return -1;
}
for (i = 0, p = buf; i < size;
i += BYTES_PER_EEPROM_PAGE, p += BYTES_PER_EEPROM_PAGE) {
if (!ret)
ret = dm_i2c_write(dev,
i + CONFIG_STARFIVE_EEPROM_WP_OFFSET,
p, min((int)(size - i),
BYTES_PER_EEPROM_PAGE));
if (ret)
break;
udelay(EEPROM_WRITE_DELAY_MS);
}
if (!ret) {
/* Verify the write by reading back the EEPROM and comparing */
ret = dm_i2c_read(dev,
CONFIG_STARFIVE_EEPROM_WP_OFFSET,
tmp_buff,
CONFIG_STARFIVE_EEPROM_HATS_SIZE_MAX);
if (!ret && memcmp((void *)buf, (void *)tmp_buff,
CONFIG_STARFIVE_EEPROM_HATS_SIZE_MAX))
ret = -1;
}
if (ret) {
has_been_read = -1;
printf("Programming failed.Temp buff:\n");
dump_raw_eeprom(tmp_buff,
CONFIG_STARFIVE_EEPROM_HATS_SIZE_MAX);
return -1;
}
printf("Programming passed.\n");
return 0;
}
/**
* 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)
{
unsigned int i;
struct eeprom_hats_atom_header *atom4;
atom4 = (struct eeprom_hats_atom_header *)
hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff,
HATS_ATOM_CUSTOM);
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;
}
for (i = 0; *string && (i < MAC_ADDR_BYTES); i++) {
einfo.mac_addr[i] = hextoul(string, &string);
if (*string == ':')
string++;
}
update_crc(atom4);
}
/**
* 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)
{
u8 p;
uint base = 16;
struct eeprom_hats_atom_header *atom4;
atom4 = (struct eeprom_hats_atom_header *)
hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff,
HATS_ATOM_CUSTOM);
p = (u8)simple_strtoul(string, NULL, base);
if (p > U8_MAX) {
printf("%s must not be greater than %d\n", "PCB revision",
U8_MAX);
return;
}
*einfo.pcb_revision = p;
update_crc(atom4);
}
/**
* 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)
{
struct eeprom_hats_atom_header *atom4;
atom4 = (struct eeprom_hats_atom_header *)
hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff,
HATS_ATOM_CUSTOM);
if (string[0] < 'A' || string[0] > 'Z') {
printf("BOM revision must be an uppercase letter between A and Z\n");
return;
}
*einfo.bom_revision = string[0];
update_crc(atom4);
}
/**
* 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)
{
struct eeprom_hats_atom_header *atom1;
atom1 = (struct eeprom_hats_atom_header *)
hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff,
HATS_ATOM_VENDOR);
memcpy((void *)einfo.pstr, (void *)string,
CONFIG_STARFIVE_EEPROM_ATOM1_PSTR_SIZE);
update_crc(atom1);
}
/**
* 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(uchar *buff)
{
struct eeprom_hats_header *hats = (struct eeprom_hats_header *)buff;
struct eeprom_hats_atom_header *atom1 = (void *)hats +
sizeof(struct eeprom_hats_header);
struct eeprom_hats_atom_header *atom4_v1 = (void *)atom1 +
sizeof(struct starfive_eeprom_atom1);
memcpy((void *)hats, (void *)&starfive_eeprom_hats_header_default,
sizeof(struct eeprom_hats_header));
memcpy((void *)atom1, (void *)&starfive_eeprom_atom1_default,
sizeof(struct starfive_eeprom_atom1));
memcpy((void *)atom4_v1, (void *)&starfive_eeprom_atom4_v1_default,
sizeof(struct starfive_eeprom_atom4_v1));
update_crc(atom1);
update_crc(atom4_v1);
}
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 mac_address <xx:xx:xx:xx:xx:xx>\n"
" - stores a MAC 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 <VF7100A1-2150-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(&einfo);
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(eeprom_wp_buff);
} else if (!strcmp(cmd, "initialize")) {
init_local_copy(eeprom_wp_buff);
return 0;
} else if (!strcmp(cmd, "write_eeprom")) {
return prog_eeprom(eeprom_wp_buff,
CONFIG_STARFIVE_EEPROM_HATS_SIZE_MAX);
}
if (argc != 3)
return print_usage();
if (is_match_magic(eeprom_wp_buff)) {
printf("Please read the EEPROM ('read_eeprom') and/or initialize the EEPROM ('initialize') first.\n");
return 0;
}
if (!strcmp(cmd, "mac_address")) {
set_mac_address(argv[2]);
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(eeprom_wp_buff))
return 0;
// 1, setup ethaddr env
eth_env_set_enetaddr("ethaddr", einfo.mac_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#", einfo.pstr);
return 0;
}

View file

@ -40,6 +40,7 @@ CONFIG_LOG_ERROR_RETURN=y
CONFIG_DISPLAY_CPUINFO=y
CONFIG_DISPLAY_BOARDINFO=y
CONFIG_MISC_INIT_R=y
CONFIG_ID_EEPROM=y
CONFIG_SYS_PROMPT="VisionFive #"
CONFIG_CMD_CONFIG=y
CONFIG_CMD_LICENSE=y

View file

@ -77,8 +77,7 @@ config SIFIVE_OTP
config STARFIVE_OTP
bool "StarFive eMemory OTP driver"
depends on MISC && JH_STARLIGHT
default y if JH_STARLIGHT
depends on MISC && JH_STARLIGHT && !ID_EEPROM
help
Enable support for reading and writing the eMemory OTP on the
StarFive SoCs.

View file

@ -102,4 +102,41 @@
#define CONFIG_CQSPI_REF_CLK (250000000)
#endif
#ifdef CONFIG_ID_EEPROM /* EEPROM for SN and MAC */
#define CONFIG_SYS_EEPROM_BUS_NUM 0
#define FORMAT_VERSION 0x1
#define PCB_VERSION 0x1
#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_MAC {0x6C, 0xCF, 0x39, 0x08, 0x08, 0x08}
/* Magic number at the first four bytes of EEPROM HATs */
#define STARFIVE_EEPROM_HATS_SIG "SFVF" /* StarFive VisionFive */
#define CONFIG_STARFIVE_EEPROM_HATS_SIZE_MAX 128 /* Header + Atom1&4(v1) */
#define CONFIG_STARFIVE_EEPROM_WP_OFFSET 256 /* Read only field */
#define CONFIG_STARFIVE_EEPROM_ATOM1_PSTR "VF7100A1-2201-D008E000-00000001\0"
#define CONFIG_STARFIVE_EEPROM_ATOM1_PSTR_SIZE 32
#define CONFIG_STARFIVE_EEPROM_ATOM1_SN_OFFSET 23
#define CONFIG_STARFIVE_EEPROM_ATOM1_VSTR "StarFive Technology Co., Ltd.\0\0\0"
#define CONFIG_STARFIVE_EEPROM_ATOM1_VSTR_SIZE 32
#endif
#endif /* __CONFIG_H */