diff options
Diffstat (limited to 'common/boards')
-rw-r--r-- | common/boards/Kconfig | 16 | ||||
-rw-r--r-- | common/boards/Makefile | 5 | ||||
-rw-r--r-- | common/boards/phytec/Makefile | 5 | ||||
-rw-r--r-- | common/boards/phytec/phytec-som-detection.c | 209 | ||||
-rw-r--r-- | common/boards/phytec/phytec-som-imx8m-detection.c | 151 | ||||
-rw-r--r-- | common/boards/qemu-virt/Makefile | 13 | ||||
-rw-r--r-- | common/boards/qemu-virt/board.c | 90 | ||||
-rw-r--r-- | common/boards/qemu-virt/fitimage-pubkey.dts | 7 | ||||
-rw-r--r-- | common/boards/qemu-virt/qemu-virt-flash.dtso | 99 | ||||
-rw-r--r-- | common/boards/qemu-virt/qemu-virt-flash.h | 22 | ||||
-rw-r--r-- | common/boards/tq/Makefile | 1 | ||||
-rw-r--r-- | common/boards/tq/tq_eeprom.c | 139 |
12 files changed, 757 insertions, 0 deletions
diff --git a/common/boards/Kconfig b/common/boards/Kconfig new file mode 100644 index 0000000000..f6d4a56f88 --- /dev/null +++ b/common/boards/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config BOARD_QEMU_VIRT + bool + select OF_OVERLAY + +config BOARD_PHYTEC_SOM_DETECTION + bool + +config BOARD_PHYTEC_SOM_IMX8M_DETECTION + bool + select BOARD_PHYTEC_SOM_DETECTION + +config BOARD_TQ + select CRC_ITU_T + bool diff --git a/common/boards/Makefile b/common/boards/Makefile new file mode 100644 index 0000000000..147c36643d --- /dev/null +++ b/common/boards/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_BOARD_QEMU_VIRT) += qemu-virt/ +obj-$(CONFIG_BOARD_PHYTEC_SOM_DETECTION) += phytec/ +obj-$(CONFIG_BOARD_TQ) += tq/ diff --git a/common/boards/phytec/Makefile b/common/boards/phytec/Makefile new file mode 100644 index 0000000000..fef6134a16 --- /dev/null +++ b/common/boards/phytec/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +lwl- += dummy.o +lwl-$(CONFIG_BOARD_PHYTEC_SOM_DETECTION) += phytec-som-detection.o +lwl-$(CONFIG_BOARD_PHYTEC_SOM_IMX8M_DETECTION) += phytec-som-imx8m-detection.o diff --git a/common/boards/phytec/phytec-som-detection.c b/common/boards/phytec/phytec-som-detection.c new file mode 100644 index 0000000000..e338639d03 --- /dev/null +++ b/common/boards/phytec/phytec-som-detection.c @@ -0,0 +1,209 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 PHYTEC Messtechnik GmbH + * Author: Teresa Remmet <t.remmet@phytec.de> + */ + +#include <boards/phytec/phytec-som-imx8m-detection.h> +#include <common.h> +#include <pbl/eeprom.h> + +struct phytec_eeprom_data eeprom_data; + +#define POLY (0x1070U << 3) + +static u8 _crc8(u16 data) +{ + int i; + + for (i = 0; i < 8; i++) { + if (data & 0x8000) + data = data ^ POLY; + data = data << 1; + } + + return data >> 8; +} + +static unsigned int crc8(unsigned int crc, const u8 *vptr, int len) +{ + int i; + + for (i = 0; i < len; i++) + crc = _crc8((crc ^ vptr[i]) << 8); + + return crc; +} + +const char *phytec_get_opt(const struct phytec_eeprom_data *data) +{ + const char *opt; + + if (!data) + data = &eeprom_data; + + switch (data->api_rev) { + case PHYTEC_API_REV0: + case PHYTEC_API_REV1: + opt = data->data.data_api0.opt; + break; + case PHYTEC_API_REV2: + opt = data->data.data_api2.opt; + break; + default: + opt = NULL; + break; + }; + + return opt; +} + +static int phytec_eeprom_data_init(struct pbl_i2c *i2c, + struct phytec_eeprom_data *data, + int addr, u8 phytec_som_type) +{ + unsigned int crc; + const char *opt; + int *ptr; + int ret = -1, i; + u8 som; + + if (!data) + data = &eeprom_data; + + eeprom_read(i2c, addr, I2C_ADDR_16_BIT, data, sizeof(struct phytec_eeprom_data)); + + if (data->api_rev == 0xff) { + pr_err("%s: EEPROM is not flashed. Prototype?\n", __func__); + return -EINVAL; + } + + for (i = 0, ptr = (int *)data; + i < sizeof(struct phytec_eeprom_data); + i += sizeof(ptr), ptr++) + if (*ptr != 0x0) + break; + + if (i == sizeof(struct phytec_eeprom_data)) { + pr_err("%s: EEPROM data is all zero. Erased?\n", __func__); + return -EINVAL; + } + + if (data->api_rev > PHYTEC_API_REV2) { + pr_err("%s: EEPROM API revision %u not supported\n", + __func__, data->api_rev); + return -EINVAL; + } + + /* We are done here for early revisions */ + if (data->api_rev <= PHYTEC_API_REV1) + return 0; + + crc = crc8(0, (const unsigned char *)data, + sizeof(struct phytec_eeprom_data)); + pr_debug("%s: crc: %x\n", __func__, crc); + + if (crc) { + pr_err("%s: CRC mismatch. EEPROM data is not usable\n", __func__); + return -EINVAL; + } + + som = data->data.data_api2.som_no; + pr_debug("%s: som id: %u\n", __func__, som); + opt = phytec_get_opt(data); + if (!opt) + return -EINVAL; + + if (IS_ENABLED(CONFIG_BOARD_PHYTEC_SOM_IMX8M_DETECTION)) + ret = phytec_imx8m_detect(som, opt, phytec_som_type); + + if (ret) { + pr_err("%s: SoM ID does not match. Wrong EEPROM data?\n", __func__); + return -EINVAL; + } + + return 0; +} + +void phytec_print_som_info(const struct phytec_eeprom_data *data) +{ + const struct phytec_api2_data *api2; + char pcb_sub_rev; + unsigned int ksp_no, sub_som_type1 = -1, sub_som_type2 = -1; + + if (!data) + data = &eeprom_data; + + if (data->api_rev < PHYTEC_API_REV2) + return; + + api2 = &data->data.data_api2; + + /* Calculate PCB subrevision */ + pcb_sub_rev = api2->pcb_sub_opt_rev & 0x0f; + pcb_sub_rev = pcb_sub_rev ? ((pcb_sub_rev - 1) + 'a') : ' '; + + /* print standard product string */ + if (api2->som_type <= 1) { + pr_info("SoM: %s-%03u-%s.%s PCB rev: %u%c\n", + phytec_som_type_str[api2->som_type], api2->som_no, + api2->opt, api2->bom_rev, api2->pcb_rev, pcb_sub_rev); + return; + } + /* print KSP/KSM string */ + if (api2->som_type <= 3) { + ksp_no = (api2->ksp_no << 8) | api2->som_no; + pr_info("SoM: %s-%u ", + phytec_som_type_str[api2->som_type], ksp_no); + /* print standard product based KSP/KSM strings */ + } else { + switch (api2->som_type) { + case 4: + sub_som_type1 = 0; + sub_som_type2 = 3; + break; + case 5: + sub_som_type1 = 0; + sub_som_type2 = 2; + break; + case 6: + sub_som_type1 = 1; + sub_som_type2 = 3; + break; + case 7: + sub_som_type1 = 1; + sub_som_type2 = 2; + break; + default: + break; + }; + + pr_info("SoM: %s-%03u-%s-%03u ", + phytec_som_type_str[sub_som_type1], + api2->som_no, phytec_som_type_str[sub_som_type2], + api2->ksp_no); + } + + printf("Option: %s BOM rev: %s PCB rev: %u%c\n", api2->opt, + api2->bom_rev, api2->pcb_rev, pcb_sub_rev); +} + +int phytec_eeprom_data_setup(struct pbl_i2c *i2c, struct phytec_eeprom_data *data, + int addr, int addr_fallback, u8 cpu_type) +{ + int ret; + + ret = phytec_eeprom_data_init(i2c, data, addr, cpu_type); + if (ret) { + pr_err("%s: init failed. Trying fall back address 0x%x\n", + __func__, addr_fallback); + ret = phytec_eeprom_data_init(i2c, data, addr_fallback, cpu_type); + } + + if (ret) + pr_err("%s: EEPROM data init failed\n", __func__); + else + pr_debug("%s: init successful\n", __func__); + + return ret; +} diff --git a/common/boards/phytec/phytec-som-imx8m-detection.c b/common/boards/phytec/phytec-som-imx8m-detection.c new file mode 100644 index 0000000000..495896f5b2 --- /dev/null +++ b/common/boards/phytec/phytec-som-imx8m-detection.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 PHYTEC Messtechnik GmbH + * Author: Teresa Remmet <t.remmet@phytec.de> + */ + +#include <boards/phytec/phytec-som-imx8m-detection.h> +#include <common.h> +#include <mach/imx/generic.h> + +extern struct phytec_eeprom_data eeprom_data; + +/* Check if the SoM is actually one of the following products: + * - i.MX8MM + * - i.MX8MN + * - i.MX8MP + * - i.MX8MQ + * + * Returns 0 in case it's a known SoM. Otherwise, returns -errno. + */ +int phytec_imx8m_detect(u8 som, const char *opt, u8 cpu_type) +{ + if (som == PHYTEC_IMX8MP_SOM && cpu_type == IMX_CPU_IMX8MP) + return 0; + + if (som == PHYTEC_IMX8MM_SOM) { + if (((opt[0] - '0') != 0) && + ((opt[1] - '0') == 0) && cpu_type == IMX_CPU_IMX8MM) + return 0; + else if (((opt[0] - '0') == 0) && + ((opt[1] - '0') != 0) && cpu_type == IMX_CPU_IMX8MN) + return 0; + return -EINVAL; + } + + if (som == PHYTEC_IMX8MQ_SOM && cpu_type == IMX_CPU_IMX8MQ) + return 0; + + return -EINVAL; +} + +/* + * So far all PHYTEC i.MX8M boards have RAM size definition at the + * same location. + */ +enum phytec_imx8m_ddr_size phytec_get_imx8m_ddr_size(const struct phytec_eeprom_data *data) +{ + const char *opt; + u8 ddr_id; + + if (!data) + data = &eeprom_data; + + opt = phytec_get_opt(data); + if (opt) + ddr_id = opt[2] - '0'; + else + ddr_id = PHYTEC_IMX8M_DDR_AUTODETECT; + + pr_debug("%s: ddr id: %u\n", __func__, ddr_id); + + return ddr_id; +} + +/* + * Filter SPI-NOR flash information. All i.MX8M boards have this at + * the same location. + * returns: 0x0 if no SPI is populated. Otherwise a board depended + * code for the size. PHYTEC_EEPROM_INVAL when the data is invalid. + */ +u8 phytec_get_imx8m_spi(const struct phytec_eeprom_data *data) +{ + const char *opt; + u8 spi; + + if (!data) + data = &eeprom_data; + + if (data->api_rev < PHYTEC_API_REV2) + return PHYTEC_EEPROM_INVAL; + + opt = phytec_get_opt(data); + if (opt) + spi = opt[4] - '0'; + else + spi = PHYTEC_EEPROM_INVAL; + + pr_debug("%s: spi: %u\n", __func__, spi); + + return spi; +} + +/* + * Filter ethernet phy information. All i.MX8M boards have this at + * the same location. + * returns: 0x0 if no ethernet phy is poulated. 0x1 if it is populated. + * PHYTEC_EEPROM_INVAL when the data is invalid. + */ +u8 phytec_get_imx8m_eth(const struct phytec_eeprom_data *data) +{ + const char *opt; + u8 eth; + + if (!data) + data = &eeprom_data; + + if (data->api_rev < PHYTEC_API_REV2) + return PHYTEC_EEPROM_INVAL; + + opt = phytec_get_opt(data); + if (opt) { + eth = opt[5] - '0'; + eth &= 0x1; + } else { + eth = PHYTEC_EEPROM_INVAL; + } + + pr_debug("%s: eth: %u\n", __func__, eth); + + return eth; +} + +/* + * Filter RTC information. + * returns: 0 if no RTC is poulated. 1 if it is populated. + * PHYTEC_EEPROM_INVAL when the data is invalid. + */ +u8 phytec_get_imx8mp_rtc(const struct phytec_eeprom_data *data) +{ + const char *opt; + u8 rtc; + + if (!data) + data = &eeprom_data; + + if (data->api_rev < PHYTEC_API_REV2) + return PHYTEC_EEPROM_INVAL; + + opt = phytec_get_opt(data); + if (opt) { + rtc = opt[5] - '0'; + rtc &= 0x4; + rtc = !(rtc >> 2); + } else { + rtc = PHYTEC_EEPROM_INVAL; + } + + pr_debug("%s: rtc: %u\n", __func__, rtc); + + return rtc; +} diff --git a/common/boards/qemu-virt/Makefile b/common/boards/qemu-virt/Makefile new file mode 100644 index 0000000000..30bf4f1955 --- /dev/null +++ b/common/boards/qemu-virt/Makefile @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-y += board.o +obj-y += qemu-virt-flash.dtbo.o fitimage-pubkey.dtb.o +ifeq ($(CONFIG_RISCV),y) +DTC_CPP_FLAGS_qemu-virt-flash.dtbo := -DCONFIG_RISCV +endif +ifeq ($(CONFIG_ARM),y) +DTC_CPP_FLAGS_qemu-virt-flash.dtbo := -DCONFIG_ARM +endif + +clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts *.dtb.z +clean-files += *.dtbo *.dtbo.S .*.dtso diff --git a/common/boards/qemu-virt/board.c b/common/boards/qemu-virt/board.c new file mode 100644 index 0000000000..4f2f7374c5 --- /dev/null +++ b/common/boards/qemu-virt/board.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 Pengutronix e.K. + * + */ +#include <common.h> +#include <init.h> +#include <of.h> +#include <deep-probe.h> +#include "qemu-virt-flash.h" + +#ifdef CONFIG_64BIT +#define MACHINE "virt64" +#else +#define MACHINE "virt" +#endif + +#ifdef CONFIG_ARM +#include <asm/system_info.h> + +static inline void arm_virt_init(void) +{ + const char *hostname = MACHINE; + + if (cpu_is_cortex_a7()) + hostname = "virt-a7"; + else if (cpu_is_cortex_a15()) + hostname = "virt-a15"; + + barebox_set_model("ARM QEMU " MACHINE); + barebox_set_hostname(hostname); +} + +#else +static inline void arm_virt_init(void) {} +#endif + +extern char __dtbo_qemu_virt_flash_start[]; +extern char __dtb_fitimage_pubkey_start[]; + +static const struct of_device_id virt_of_match[] = { + { .compatible = "linux,dummy-virt", .data = arm_virt_init }, + { .compatible = "riscv-virtio" }, + { /* Sentinel */}, +}; +BAREBOX_DEEP_PROBE_ENABLE(virt_of_match); + +/* + * We don't have a dedicated qemu-virt device tree and instead rely + * on what Qemu passes us. To be able to get fundamental changes + * in very early, we forego having a board driver here and do this + * directly in the initcall. + */ +static int virt_board_driver_init(void) +{ + struct device_node *root = of_get_root_node(); + struct device_node *flash, *overlay, *pubkey; + const struct of_device_id *id; + void (*init)(void); + + id = of_match_node(virt_of_match, root); + if (!id) + return 0; + + if (id->data) { + init = id->data; + init(); + } + + /* + * Catch both old Qemu versions that place /flash in /soc and + * configurations, where the first flash bank is secure-world only + */ + flash = of_find_node_by_path(PARTS_TARGET_PATH_STR); + if (flash && of_device_is_available(flash)) { + overlay = of_unflatten_dtb(__dtbo_qemu_virt_flash_start, INT_MAX); + of_overlay_apply_tree(root, overlay); + } + + pubkey = of_unflatten_dtb(__dtb_fitimage_pubkey_start, INT_MAX); + of_merge_nodes(root, pubkey); + + /* fragment may have added aliases to the DT */ + of_alias_scan(); + + /* of_probe() will happen later at of_populate_initcall */ + + return 0; +} +postcore_initcall(virt_board_driver_init); diff --git a/common/boards/qemu-virt/fitimage-pubkey.dts b/common/boards/qemu-virt/fitimage-pubkey.dts new file mode 100644 index 0000000000..497799fa4b --- /dev/null +++ b/common/boards/qemu-virt/fitimage-pubkey.dts @@ -0,0 +1,7 @@ +/dts-v1/; + +#ifdef CONFIG_BOOTM_FITIMAGE_PUBKEY +#include CONFIG_BOOTM_FITIMAGE_PUBKEY +#endif + +/{ }; diff --git a/common/boards/qemu-virt/qemu-virt-flash.dtso b/common/boards/qemu-virt/qemu-virt-flash.dtso new file mode 100644 index 0000000000..087568a26d --- /dev/null +++ b/common/boards/qemu-virt/qemu-virt-flash.dtso @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/dts-v1/; +/plugin/; + +#include "qemu-virt-flash.h" + +&{PARTS_TARGET_PATH} { +#ifdef CONFIG_ARM + virtual-reg = <0x1000>; +#endif + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "initramfs"; + reg = <0x0 0x3c00000>; + }; + + environment_flash: partition@3c00000 { + label = "barebox-environment"; + reg = <0x3c00000 0x200000>; + }; + + backend_state_flash: partition@3e00000 { + label = "barebox-state"; + reg = <0x3e00000 0x200000>; + }; + }; +}; + +&{/chosen} { + environment { + compatible = "barebox,environment"; + device-path = ENV_DEVICE_PATH_STR; + }; +}; + +&{/} { + aliases { + state = "/state"; + }; + + state { + #address-cells = <1>; + #size-cells = <1>; + compatible = "barebox,state"; + magic = <0x290cf8c6>; + backend-type = "raw"; + backend = < &backend_state_flash >; + backend-stridesize = <0x200>; + + bootstate { + #address-cells = <1>; + #size-cells = <1>; + + system0 { + #address-cells = <1>; + #size-cells = <1>; + + remaining_attempts@0 { + reg = <0x0 0x4>; + type = "uint32"; + default = <3>; + }; + + priority@4 { + reg = <0x4 0x4>; + type = "uint32"; + default = <20>; + }; + }; + + system1 { + #address-cells = <1>; + #size-cells = <1>; + + remaining_attempts@8 { + reg = <0x8 0x4>; + type = "uint32"; + default = <3>; + }; + + priority@c { + reg = <0xc 0x4>; + type = "uint32"; + default = <21>; + }; + }; + + last_chosen@10 { + reg = <0x10 0x4>; + type = "uint32"; + }; + }; + }; +}; diff --git a/common/boards/qemu-virt/qemu-virt-flash.h b/common/boards/qemu-virt/qemu-virt-flash.h new file mode 100644 index 0000000000..85f67ff030 --- /dev/null +++ b/common/boards/qemu-virt/qemu-virt-flash.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __QEMU_VIRT_FLASH_H__ +#define __QEMU_VIRT_FLASH_H__ + +#include <linux/stringify.h> + +#ifdef CONFIG_RISCV +#define PARTS_TARGET_PATH /flash@20000000 +#define ENV_DEVICE_PATH /flash@20000000/partitions/partition@3c00000 +#elif defined CONFIG_ARM +#define PARTS_TARGET_PATH /flash@0 +#define ENV_DEVICE_PATH /flash@0/partitions/partition@3c00000 +#else +#define PARTS_TARGET_PATH +#define ENV_DEVICE_PATH +#endif + +#define PARTS_TARGET_PATH_STR __stringify(PARTS_TARGET_PATH) +#define ENV_DEVICE_PATH_STR __stringify(ENV_DEVICE_PATH) + +#endif diff --git a/common/boards/tq/Makefile b/common/boards/tq/Makefile new file mode 100644 index 0000000000..9950cbdb00 --- /dev/null +++ b/common/boards/tq/Makefile @@ -0,0 +1 @@ +obj-pbl-y += tq_eeprom.o diff --git a/common/boards/tq/tq_eeprom.c b/common/boards/tq/tq_eeprom.c new file mode 100644 index 0000000000..fe776d6bab --- /dev/null +++ b/common/boards/tq/tq_eeprom.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2014-2023 TQ-Systems GmbH <u-boot@ew.tq-group.com>, + * D-82229 Seefeld, Germany. + * Author: Markus Niebel + */ + +#include <common.h> +#include <net.h> +#include <linux/ctype.h> +#include <crc.h> +#include <pbl/i2c.h> +#include <pbl/eeprom.h> +#include <boards/tq/tq_eeprom.h> + +/* + * static EEPROM layout + */ +#define TQ_EE_HRCW_BYTES 0x20 +#define TQ_EE_RSV1_BYTES 10 +#define TQ_EE_RSV2_BYTES 8 + +struct __packed tq_eeprom_data { + union { + struct tq_vard vard; + _Static_assert(sizeof(struct tq_vard) == TQ_EE_HRCW_BYTES, \ + "struct tq_vard has incorrect size"); + u8 hrcw_primary[TQ_EE_HRCW_BYTES]; + } tq_hw_data; + u8 mac[TQ_EE_MAC_BYTES]; /* 0x20 ... 0x25 */ + u8 rsv1[TQ_EE_RSV1_BYTES]; + u8 serial[TQ_EE_SERIAL_BYTES]; /* 0x30 ... 0x37 */ + u8 rsv2[TQ_EE_RSV2_BYTES]; + u8 id[TQ_EE_BDID_BYTES]; /* 0x40 ... 0x7f */ +}; + +static bool tq_vard_valid(const struct tq_vard *vard) +{ + const unsigned char *start = (const unsigned char *)(vard) + + sizeof(vard->crc); + u16 crc; + + crc = crc_itu_t(0, start, sizeof(*vard) - sizeof(vard->crc)); + + return vard->crc == crc; +} + +phys_size_t tq_vard_memsize(u8 val, unsigned int multiply, unsigned int tmask) +{ + phys_size_t result = 0; + + if (val != VARD_MEMSIZE_DEFAULT) { + result = 1 << (size_t)(val & VARD_MEMSIZE_MASK_EXP); + if (val & tmask) + result *= 3; + result *= multiply; + } + + return result; +} + +void tq_vard_show(const struct tq_vard *vard) +{ + /* display data anyway to support developer */ + printf("HW\tREV.%02uxx\n", (unsigned int)vard->hwrev); + printf("RAM\ttype %u, %lu MiB, %s\n", + (unsigned int)(vard->memtype & VARD_MEMTYPE_MASK_TYPE), + (unsigned long)(tq_vard_ramsize(vard) / (SZ_1M)), + (tq_vard_has_ramecc(vard) ? "ECC" : "no ECC")); + printf("RTC\t%c\nSPINOR\t%c\ne-MMC\t%c\nSE\t%c\nEEPROM\t%c\n", + (tq_vard_has_rtc(vard) ? 'y' : 'n'), + (tq_vard_has_spinor(vard) ? 'y' : 'n'), + (tq_vard_has_emmc(vard) ? 'y' : 'n'), + (tq_vard_has_secelem(vard) ? 'y' : 'n'), + (tq_vard_has_eeprom(vard) ? 'y' : 'n')); + + if (tq_vard_has_eeprom(vard)) + printf("EEPROM\ttype %u, %lu KiB, page %zu\n", + (unsigned int)(vard->eepromtype & VARD_EETYPE_MASK_MFR) >> 4, + (unsigned long)(tq_vard_eepromsize(vard) / (SZ_1K)), + tq_vard_eeprom_pgsize(vard)); + + printf("FORMFACTOR: "); + + switch (tq_vard_get_formfactor(vard)) { + case VARD_FORMFACTOR_TYPE_LGA: + printf("LGA\n"); + break; + case VARD_FORMFACTOR_TYPE_CONNECTOR: + printf("CONNECTOR\n"); + break; + case VARD_FORMFACTOR_TYPE_SMARC2: + printf("SMARC-2\n"); + break; + case VARD_FORMFACTOR_TYPE_NONE: + /* + * applies to boards with no variants or older boards + * where this field is not written + */ + printf("UNSPECIFIED\n"); + break; + default: + /* + * generic fall trough + * unhandled form factor or invalid data + */ + printf("UNKNOWN\n"); + break; + } +} + +static void tq_read_string(const char *src, char *dst, int len) +{ + int i; + + for (i = 0; i < len && isprint(src[i]) && isascii(src[i]); ++i) + dst[i] = src[i]; + dst[i] = '\0'; +} + +struct tq_eeprom *pbl_tq_read_eeprom(struct pbl_i2c *i2c, u8 addr, u32 eeprom_addr) +{ + struct tq_eeprom_data raw; + static struct tq_eeprom eeprom; + int ret; + + ret = eeprom_read(i2c, addr, eeprom_addr, &raw, sizeof(raw)); + if (ret) + return NULL; + + if (tq_vard_valid(&raw.tq_hw_data.vard)) + eeprom.vard = raw.tq_hw_data.vard; + + memcpy(eeprom.mac, raw.mac, TQ_EE_MAC_BYTES); + tq_read_string(raw.serial, eeprom.serial, TQ_EE_SERIAL_BYTES); + tq_read_string(raw.id, eeprom.id, TQ_EE_BDID_BYTES); + + return &eeprom; +} |