From 2030b0714313508cc128152111cf2c4bf5ea8a72 Mon Sep 17 00:00:00 2001 From: Alvin Xie Date: Tue, 25 Jun 2024 10:43:28 +0800 Subject: [PATCH 1/5] drivers: misc: add radxa eeprom support Read eeprom data in Radxa specified format and set mac address read from eeprom. Signed-off-by: Alvin Xie --- arch/arm/mach-rockchip/misc.c | 7 + drivers/misc/Kconfig | 9 +- drivers/misc/Makefile | 1 + drivers/misc/radxa-i2c-eeprom.c | 519 ++++++++++++++++++++++++++++++++ include/radxa-i2c-eeprom.h | 56 ++++ 5 files changed, 591 insertions(+), 1 deletion(-) create mode 100644 drivers/misc/radxa-i2c-eeprom.c create mode 100644 include/radxa-i2c-eeprom.h diff --git a/arch/arm/mach-rockchip/misc.c b/arch/arm/mach-rockchip/misc.c index 349155bdf68..9415701f987 100644 --- a/arch/arm/mach-rockchip/misc.c +++ b/arch/arm/mach-rockchip/misc.c @@ -17,11 +17,18 @@ #include #include #include +#include #include int rockchip_setup_macaddr(void) { + +#ifdef CONFIG_RADXA_ID_EEPROM + if(!radxa_mac_read_from_eeprom()) + return 0; +#endif + #if CONFIG_IS_ENABLED(HASH) && CONFIG_IS_ENABLED(SHA256) int ret; const char *cpuid = env_get("cpuid#"); diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index fe288ad6bd3..87a86279a2a 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -59,7 +59,7 @@ config ATSHA204A board. config ROCKCHIP_EFUSE - bool "Rockchip e-fuse support" + bool "Rockchip e-fuse support" depends on MISC help Enable (read-only) access for the e-fuse block found in Rockchip @@ -266,6 +266,13 @@ config I2C_EEPROM help Enable a generic driver for EEPROMs attached via I2C. +config RADXA_ID_EEPROM + bool "Enable Radxa ID EEPROM driver" + depends on MISC + help + Enable support for Radxa ID EEPROM. + This EEPROM is used to store persistent platform data, such as MAC address. + if I2C_EEPROM config SYS_I2C_EEPROM_ADDR diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 1e50f4b5622..f7b566eca3c 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o obj-$(CONFIG_QFW) += qfw.o obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o obj-$(CONFIG_ROCKCHIP_OTP) += rockchip-otp.o +obj-$(CONFIG_RADXA_ID_EEPROM) += radxa-i2c-eeprom.o ifeq ($(CONFIG_$(SPL_TPL_)ROCKCHIP_SECURE_OTP),y) obj-$(CONFIG_ROCKCHIP_RK3308) += rk3308-secure-otp.o diff --git a/drivers/misc/radxa-i2c-eeprom.c b/drivers/misc/radxa-i2c-eeprom.c new file mode 100644 index 00000000000..d4305d5ebd4 --- /dev/null +++ b/drivers/misc/radxa-i2c-eeprom.c @@ -0,0 +1,519 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. + * Copyright (C) 2024 Radxa Technology Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include + + +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 ROCK platform I2C format + */ + +struct eeprom_atom1_data { + u8 uuid[16]; + u16 pid; + u16 pver; + u8 vslen; + u8 pslen; + + char vstr[CONFIG_EEPROM_ATOM1_VSTR_SIZE]; + char pstr[CONFIG_EEPROM_ATOM1_PSTR_SIZE]; /* product SN */ + +}; + +struct eeprom_atom1 { + struct eeprom_hats_atom_header header; + struct eeprom_atom1_data data; + u16 crc16; +}; + +struct eeprom_atom4_v1_data { + u16 version; + u8 bom_revision[BOM_ATOM4_BYTES];/* BOM version */ +}; + +struct eeprom_atom4_v1 { + struct eeprom_hats_atom_header header; + struct eeprom_atom4_v1_data data; + u16 crc16; +}; + +struct eeprom_atom5_data { + u16 version; + u8 sn_revision[SN_BYTES]; /* PCB version */ + u8 mac_addr[MAC_ADDR_BYTES]; /* Ethernet MAC */ +}; + +struct eeprom_atom5 { + struct eeprom_hats_atom_header header; + struct eeprom_atom5_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_page1_buff. + * ONLY serialnum is the u32 from the last 8 Bytes of product string + */ +struct eeprom_info_page1 { + 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 *bom_revision; /* BOM version in ATOM4 */ +}; +static struct eeprom_info_page1 einfo_page1; + +struct eeprom_info_page2 { + u16 *version; /* custom data version in ATOM5 */ + u8 *sn_revision; /* serial number from in product string*/ + u8 *mac_addr; /* MAC in ATOM5 */ +}; +static struct eeprom_info_page2 einfo_page2; + + +static uchar eeprom_buff[CONFIG_EEPROM_HATS_SIZE_MAX]; + +/** + * is_match_magic() - Does the magic number match that of a ROCK 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, 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 + */ + +ulong hextoul(const char *cp, char **endp) +{ + return simple_strtoul(cp, endp, 16); +} + +#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(void) +{ + printf("\n--------EEPROM INFO--------\n"); + printf("Vendor: %s\n", einfo_page1.vstr); + printf("Product full SN: %s\n", einfo_page1.pstr); + printf("Data version: 0x%x\n", *einfo_page1.version); + + if (*einfo_page1.version == 1) { + printf("BOM revision: %s\n", einfo_page1.bom_revision); + + for (int i = 0; i < 10; i++) { + int idx = i * 6; + printf("Ethernet%d MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", i, + einfo_page2.mac_addr[idx], einfo_page2.mac_addr[idx + 1], + einfo_page2.mac_addr[idx + 2], einfo_page2.mac_addr[idx + 3], + einfo_page2.mac_addr[idx + 4], einfo_page2.mac_addr[idx + 5]); + } + } else { + printf("Custom data v%d is not supported\n", *einfo_page1.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 eeprom_atom1_data *atom1 = NULL; + struct eeprom_atom4_v1_data *atom4_v1 = NULL; + struct eeprom_atom5_data *atom5 = NULL; + + if (is_match_magic((char *)buf)) { + printf("Not a ROCK EEPROM data format - magic error\n"); + goto error; + }; + + printf("ROCK 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 eeprom_atom1_data *)atom_data; + einfo_page1.vstr = atom1->vstr; + einfo_page1.pstr = atom1->pstr; + einfo_page1.serialnum = (u32)hextoul((void *)atom1->pstr + + CONFIG_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 eeprom_atom4_v1_data *)atom_data; + einfo_page1.version = &atom4_v1->version; + if (*einfo_page1.version == 1) { + einfo_page1.bom_revision = atom4_v1->bom_revision; + } + } else { + printf("fail to get custom data atom\n"); + goto error; + }; + + // parse atom5 + atom = (struct eeprom_hats_atom_header *) + hats_get_atom(buf, HATS_ATOM5_CUSTOM); + if (atom) { + atom_data = (void *)atom + sizeof(struct eeprom_hats_atom_header); + atom5 = (struct eeprom_atom5_data *)atom_data; + einfo_page2.version = &atom5->version; + + if (*einfo_page2.version == 1) + { + einfo_page2.sn_revision = atom5->sn_revision ; + einfo_page2.mac_addr = atom5->mac_addr; + } + } + else { + printf("fail to get page2 data atom\n"); + goto error; + }; + // everthing gose right + has_been_read = 1; + show_eeprom(); + return 0; +error: + + has_been_read = -1; + dump_raw_eeprom(eeprom_buff, CONFIG_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_EEPROM_WP_OFFSET + * CONFIG_EEPROM_HATS_SIZE_MAX + */ + +#include +#include +#include +#include +#include + + +#define COMPATIBLE_STR "i2c-eeprom" + + +int find_i2c_bus_by_compatible(const char *compatible, struct udevice **bus) +{ + struct udevice *dev; + + // 遍历所有 I2C 总线设备 + for (uclass_first_device(UCLASS_I2C, &dev); + dev; + uclass_next_device(&dev)) { + + printf("Checking device: %s\n", dev_read_name(dev)); + // 检查设备的 compatible 字段 + if (device_is_compatible(dev, compatible)) { + printf("Found compatible device: %s\n", dev_read_name(dev)); + *bus = dev; + return dev->seq; + } + } + printf("fail to get i2c device.\n"); + // 没有找到匹配的设备 + return -ENODEV; +} + + +static int read_eeprom(uint8_t *buf) +{ + int ret; + int i2c_bus_num; + struct udevice *dev; + + if (has_been_read == 1) + return 0; + + i2c_bus_num = find_i2c_bus_by_compatible("i2c-eeprom",&dev); + + printf("!!!! i2c_bus_num: %d\n", i2c_bus_num); + ret = i2c_get_chip_for_busnum(i2c_bus_num, + CONFIG_SYS_I2C_EEPROM_ADDR, + CONFIG_SYS_I2C_EEPROM_ADDR_LEN, + &dev); + + printf("!!!! i2c_get_chip_for_busnum device: %s\n", dev_read_name(dev)); + + if (!ret) { + ret = dm_i2c_read(dev, CONFIG_EEPROM_WP_OFFSET, + buf, CONFIG_EEPROM_HATS_SIZE_MAX); + } + + if (ret) { + printf("fail to read EEPROM.\n"); + return ret; + } + + return parse_eeprom_info((struct eeprom_hats_header *)buf); + +} + +static int set_mac_address_env(u8 *mac_addr) +{ + + char env_name[32]; // Buffer to hold the environment variable name + u8 mac_str[6]; // Buffer to hold the MAC address string + int indx = 0 ; + int mac_env_num = 1; + if (mac_addr == NULL) { + printf("Invalid MAC address pointer.\n"); + return -1; + } + +//set mac address to env + for(int i=0; i<10; i++) + { + for(int tmp = 0; tmp<6; tmp++) + { + mac_str[tmp] = mac_addr[indx++]; + } + + if(!(mac_str[0]|mac_str[1]|mac_str[2]|mac_str[3]|mac_str[4]|mac_str[5])) + continue; + + printf("Set Ethernet%d MAC address: %02X:%02X:%02X:%02X:%02X:%02X \n",mac_env_num, + mac_str[0],mac_str[1],mac_str[2],mac_str[3],mac_str[4],mac_str[5]); + + if(i==0) { + sprintf(env_name, "ethaddr"); + eth_env_set_enetaddr(env_name, mac_str); + } + else { + sprintf(env_name, "eth%daddr", mac_env_num++); + eth_env_set_enetaddr(env_name, mac_str); + } + } + return 0; +} + + + + +/** + * radxa_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_RADXA_ID_EEPROM is enabled, this function will be called in + * "int rockchip_setup_macaddr(void)" of u-boot/arch/arm/mach-rockchip/misc.c. + */ + +// Function to set MAC address environment variable +int radxa_mac_read_from_eeprom(void) +{ + /** + * try to fill the buff from EEPROM, + * always return SUCCESS, even some error happens. + */ + // setup ethaddr env + + if(read_eeprom(eeprom_buff)) + return -1; + if (!set_mac_address_env(einfo_page2.mac_addr)) + return -1; + + return 0; +} + +// int do_mac(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +// { +// printf("This device does not support user programmable EEPROM.\n"); +// return -1; +// } diff --git a/include/radxa-i2c-eeprom.h b/include/radxa-i2c-eeprom.h new file mode 100644 index 00000000000..1cafde8cfba --- /dev/null +++ b/include/radxa-i2c-eeprom.h @@ -0,0 +1,56 @@ +#define CONFIG_SYS_EEPROM_BUS_NUM 0 + +/* Magic number at the first four bytes of EEPROM HATs */ + +#define EEPROM_HATS_SIG "RADX" /* Radxa ROCK */ + +/* + * MAGIC_NUMBER_BYTES: number of bytes used by the magic number + */ +#define MAGIC_NUMBER_BYTES 4 + +/* + * MAC_ADDR_BYTES: number of bytes used by the Ethernet MAC address + */ +#define MAC_ADDR_BYTES 60 + +/* + * SN_BYTES: length of sn string +*/ +#define SN_BYTES 20 + +/* + * 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_ATOM5_CUSTOM 0x0005 +#define HATS_ATOM_INVALID_END 0xffff + +#define BOM_ATOM4_BYTES 8 + +#define CONFIG_EEPROM_HATS_SIZE_MAX 256 /* Header + Atom1&4&5(v1) */ + +#define CONFIG_EEPROM_WP_OFFSET 256 /* Read only field */ + +#define CONFIG_EEPROM_ATOM1_PSTR_SIZE 32 + +#define CONFIG_EEPROM_ATOM1_SN_OFFSET 23 + +#define CONFIG_EEPROM_ATOM1_VSTR_SIZE 32 + +#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 + +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 + +int radxa_mac_read_from_eeprom(void); From 6ba9a0ee39955af84bd99aa7915aa75e5406d8bf Mon Sep 17 00:00:00 2001 From: Alvin Xie Date: Tue, 25 Jun 2024 10:52:45 +0800 Subject: [PATCH 2/5] arm: dts: rock-2a: enable i2c1 for eeprom Signed-off-by: Alvin Xie --- arch/arm/dts/rk3528-rock-2a.dts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/arm/dts/rk3528-rock-2a.dts b/arch/arm/dts/rk3528-rock-2a.dts index 0115e0735f3..3b87d23b52d 100644 --- a/arch/arm/dts/rk3528-rock-2a.dts +++ b/arch/arm/dts/rk3528-rock-2a.dts @@ -68,3 +68,26 @@ vref-supply = <&vdd_1v8_s3>; status = "okay"; }; + +&i2c1 { + status = "okay"; + u-boot,dm-pre-reloc; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1m0_xfer>; + compatible = "rockchip,rk3528-i2c", "rockchip,rk3399-i2c", "i2c-eeprom"; +}; + +&pinctrl { + i2c1 { + u-boot,dm-spl; + }; +}; + +&i2c1m0_xfer { + u-boot,dm-spl; + rockchip,pins = + /* i2c1_scl_m0 */ + <4 RK_PA3 2 &pcfg_pull_up>, + /* i2c1_sda_m0 */ + <4 RK_PA2 2 &pcfg_pull_up>; +}; From 2c55dace61931cbd1ef0139e347296eb1fd46424 Mon Sep 17 00:00:00 2001 From: lisongjun Date: Mon, 9 Dec 2024 11:14:46 +0800 Subject: [PATCH 3/5] defconfig: rock 2: enable CONFIG_RADXA_ID_EEPROM Reference link: https://github.com/Radxa-Alvin/u-boot/commit/8c2c05fa7020a2069fcf5a9c55aee7e7f16ea727 Signed-off-by: SongJun Li --- configs/rock-2-rk3528_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/rock-2-rk3528_defconfig b/configs/rock-2-rk3528_defconfig index 76715fd8908..bb3e2fefd90 100644 --- a/configs/rock-2-rk3528_defconfig +++ b/configs/rock-2-rk3528_defconfig @@ -109,6 +109,7 @@ CONFIG_MISC=y CONFIG_SPL_MISC=y CONFIG_ROCKCHIP_OTP=y CONFIG_SPL_ROCKCHIP_SECURE_OTP=y +CONFIG_RADXA_ID_EEPROM=y CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y From c9c159bb286f6bfc73e40e66bbf8d2463143b5f5 Mon Sep 17 00:00:00 2001 From: lisongjun Date: Mon, 9 Dec 2024 15:17:59 +0800 Subject: [PATCH 4/5] drivers: misc: Kconfig: Fix indentation problem Signed-off-by: SongJun Li --- drivers/misc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 87a86279a2a..ebbfea31170 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -59,7 +59,7 @@ config ATSHA204A board. config ROCKCHIP_EFUSE - bool "Rockchip e-fuse support" + bool "Rockchip e-fuse support" depends on MISC help Enable (read-only) access for the e-fuse block found in Rockchip From 8326b6bcca403c2a10d16f6381f0d51bd61f8d72 Mon Sep 17 00:00:00 2001 From: lisongjun Date: Mon, 9 Dec 2024 16:27:56 +0800 Subject: [PATCH 5/5] drivers: misc: Fix the forma of files related to radxa eeprom Signed-off-by: SongJun Li --- drivers/misc/radxa-i2c-eeprom.c | 95 ++++++++++++++------------------- include/radxa-i2c-eeprom.h | 28 +++++----- 2 files changed, 54 insertions(+), 69 deletions(-) diff --git a/drivers/misc/radxa-i2c-eeprom.c b/drivers/misc/radxa-i2c-eeprom.c index d4305d5ebd4..12a1ff5c2b1 100644 --- a/drivers/misc/radxa-i2c-eeprom.c +++ b/drivers/misc/radxa-i2c-eeprom.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. - * Copyright (C) 2024 Radxa Technology Co., Ltd. + * Copyright (C) 2024 Radxa Computer (Shenzhen) Co., Ltd. */ #include @@ -11,7 +11,11 @@ #include #include #include - +#include +#include +#include +#include +#include struct eeprom_hats_header { char signature[MAGIC_NUMBER_BYTES]; /* ASCII table signature */ @@ -42,7 +46,6 @@ struct eeprom_atom1_data { char vstr[CONFIG_EEPROM_ATOM1_VSTR_SIZE]; char pstr[CONFIG_EEPROM_ATOM1_PSTR_SIZE]; /* product SN */ - }; struct eeprom_atom1 { @@ -74,7 +77,6 @@ struct eeprom_atom5 { u16 crc16; }; - /* Set to 1 if we've read EEPROM into memory * Set to -1 if EEPROM data is wrong */ @@ -101,7 +103,6 @@ struct eeprom_info_page2 { }; static struct eeprom_info_page2 einfo_page2; - static uchar eeprom_buff[CONFIG_EEPROM_HATS_SIZE_MAX]; /** @@ -125,7 +126,7 @@ static inline int is_match_magic(char *hats) ulong hextoul(const char *cp, char **endp) { - return simple_strtoul(cp, endp, 16); + return simple_strtoul(cp, endp, 16); } #define CRC16 0x8005 @@ -218,7 +219,6 @@ static int hats_atom_crc_check(struct eeprom_hats_atom_header *atom) atom->count, atom->type, atom_crc, data_crc); return -1; - } static void *hats_get_atom(struct eeprom_hats_header *header, u16 type) @@ -253,26 +253,26 @@ static void *hats_get_atom(struct eeprom_hats_header *header, u16 type) */ static void show_eeprom(void) { - printf("\n--------EEPROM INFO--------\n"); - printf("Vendor: %s\n", einfo_page1.vstr); - printf("Product full SN: %s\n", einfo_page1.pstr); - printf("Data version: 0x%x\n", *einfo_page1.version); - - if (*einfo_page1.version == 1) { - printf("BOM revision: %s\n", einfo_page1.bom_revision); - - for (int i = 0; i < 10; i++) { - int idx = i * 6; - printf("Ethernet%d MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", i, - einfo_page2.mac_addr[idx], einfo_page2.mac_addr[idx + 1], - einfo_page2.mac_addr[idx + 2], einfo_page2.mac_addr[idx + 3], - einfo_page2.mac_addr[idx + 4], einfo_page2.mac_addr[idx + 5]); - } - } else { - printf("Custom data v%d is not supported\n", *einfo_page1.version); - } + printf("\n--------EEPROM INFO--------\n"); + printf("Vendor: %s\n", einfo_page1.vstr); + printf("Product full SN: %s\n", einfo_page1.pstr); + printf("Data version: 0x%x\n", *einfo_page1.version); + + if (*einfo_page1.version == 1) { + printf("BOM revision: %s\n", einfo_page1.bom_revision); + + for (int i = 0; i < 10; i++) { + int idx = i * 6; + printf("Ethernet%d MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", i, + einfo_page2.mac_addr[idx], einfo_page2.mac_addr[idx + 1], + einfo_page2.mac_addr[idx + 2], einfo_page2.mac_addr[idx + 3], + einfo_page2.mac_addr[idx + 4], einfo_page2.mac_addr[idx + 5]); + } + } else { + printf("Custom data v%d is not supported\n", *einfo_page1.version); + } - printf("--------EEPROM INFO--------\n\n"); + printf("--------EEPROM INFO--------\n\n"); } /** @@ -375,36 +375,25 @@ static int parse_eeprom_info(struct eeprom_hats_header *buf) * CONFIG_EEPROM_HATS_SIZE_MAX */ -#include -#include -#include -#include -#include - - #define COMPATIBLE_STR "i2c-eeprom" - int find_i2c_bus_by_compatible(const char *compatible, struct udevice **bus) { - struct udevice *dev; + struct udevice *dev; - // 遍历所有 I2C 总线设备 - for (uclass_first_device(UCLASS_I2C, &dev); - dev; - uclass_next_device(&dev)) { + for (uclass_first_device(UCLASS_I2C, &dev); + dev; + uclass_next_device(&dev)) { - printf("Checking device: %s\n", dev_read_name(dev)); - // 检查设备的 compatible 字段 - if (device_is_compatible(dev, compatible)) { + printf("Checking device: %s\n", dev_read_name(dev)); + if (device_is_compatible(dev, compatible)) { printf("Found compatible device: %s\n", dev_read_name(dev)); - *bus = dev; - return dev->seq; - } - } + *bus = dev; + return dev->seq; + } + } printf("fail to get i2c device.\n"); - // 没有找到匹配的设备 - return -ENODEV; + return -ENODEV; } @@ -421,9 +410,9 @@ static int read_eeprom(uint8_t *buf) printf("!!!! i2c_bus_num: %d\n", i2c_bus_num); ret = i2c_get_chip_for_busnum(i2c_bus_num, - CONFIG_SYS_I2C_EEPROM_ADDR, - CONFIG_SYS_I2C_EEPROM_ADDR_LEN, - &dev); + CONFIG_SYS_I2C_EEPROM_ADDR, + CONFIG_SYS_I2C_EEPROM_ADDR_LEN, + &dev); printf("!!!! i2c_get_chip_for_busnum device: %s\n", dev_read_name(dev)); @@ -438,7 +427,6 @@ static int read_eeprom(uint8_t *buf) } return parse_eeprom_info((struct eeprom_hats_header *)buf); - } static int set_mac_address_env(u8 *mac_addr) @@ -479,9 +467,6 @@ static int set_mac_address_env(u8 *mac_addr) return 0; } - - - /** * radxa_mac_read_from_eeprom() - read the MAC address & the serial number in EEPROM * diff --git a/include/radxa-i2c-eeprom.h b/include/radxa-i2c-eeprom.h index 1cafde8cfba..49790da84d9 100644 --- a/include/radxa-i2c-eeprom.h +++ b/include/radxa-i2c-eeprom.h @@ -29,28 +29,28 @@ * 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_ATOM5_CUSTOM 0x0005 -#define HATS_ATOM_INVALID_END 0xffff +#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_ATOM5_CUSTOM 0x0005 +#define HATS_ATOM_INVALID_END 0xffff #define BOM_ATOM4_BYTES 8 -#define CONFIG_EEPROM_HATS_SIZE_MAX 256 /* Header + Atom1&4&5(v1) */ +#define CONFIG_EEPROM_HATS_SIZE_MAX 256 /* Header + Atom1&4&5(v1) */ -#define CONFIG_EEPROM_WP_OFFSET 256 /* Read only field */ +#define CONFIG_EEPROM_WP_OFFSET 256 /* Read only field */ -#define CONFIG_EEPROM_ATOM1_PSTR_SIZE 32 +#define CONFIG_EEPROM_ATOM1_PSTR_SIZE 32 -#define CONFIG_EEPROM_ATOM1_SN_OFFSET 23 +#define CONFIG_EEPROM_ATOM1_SN_OFFSET 23 -#define CONFIG_EEPROM_ATOM1_VSTR_SIZE 32 +#define CONFIG_EEPROM_ATOM1_VSTR_SIZE 32 -#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 +#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 -#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 int radxa_mac_read_from_eeprom(void);