summaryrefslogtreecommitdiff
path: root/board/toradex/common/tdx-eeprom.c
diff options
context:
space:
mode:
authorIgor Opaniuk <igor.opaniuk@toradex.com>2020-04-06 22:22:16 +0300
committerIgor Opaniuk <igor.opaniuk@toradex.com>2020-05-04 21:42:21 +0300
commit4554a0918af7e74c934a3ad707aba10ef31e111a (patch)
tree5b595365e64bad1a7d7d5f1225fd92d39c619ac5 /board/toradex/common/tdx-eeprom.c
parentc4731c7ad61e1d4f022bfae14345956b07af47bd (diff)
toradex: tdx-cfg-block: add support for EEPROM
This introduces support for EEPROM as a storage for the main Toradex config block and additional config blocks on extra EEPROM chips (on carrier board or video adapters). To enable EEPROM as a storage for the main config block: TDX_HAVE_EEPROM=y. For additional EEPROMs please enable this Kconfig symbol: TDX_CFG_BLOCK_EXTRA=y. Information about existing EEPROM chips is provide via Device Tree using aliases. You can also write configuration for the carrier board using create_carrier subcommand for cfgblock. Example: Verdin iMX8MM # cfgblock create_carrier Supported carrier boards: UNKNOWN CARRIER = [0] Verdin Carrier Board = [1] Choose your carrier board (provide ID): 1 Enter carrier board version (e.g. V1.1B): V1.0A Enter carrier board serial number: 10622780 Also with barcode: cVerdin iMX8MM # cfgblock create carrier -y 0156100010622780 Relates-to: ELB-1402 Signed-off-by: Igor Opaniuk <igor.opaniuk@toradex.com>
Diffstat (limited to 'board/toradex/common/tdx-eeprom.c')
-rw-r--r--board/toradex/common/tdx-eeprom.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/board/toradex/common/tdx-eeprom.c b/board/toradex/common/tdx-eeprom.c
new file mode 100644
index 0000000000..176302248d
--- /dev/null
+++ b/board/toradex/common/tdx-eeprom.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020 Toradex
+ */
+
+#include <dm.h>
+#include <i2c_eeprom.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int get_tdx_eeprom(u32 eeprom_id, struct udevice **devp)
+{
+ int ret = 0;
+ int node;
+ ofnode eeprom;
+ char eeprom_str[16];
+ const char *path;
+
+ if (gd->fdt_blob == NULL) {
+ printf("%s: don't have a valid gd->fdt_blob!\n", __func__);
+ return -EFAULT;
+ }
+
+ node = fdt_path_offset(gd->fdt_blob, "/aliases");
+ if (node < 0)
+ return -ENODEV;
+
+ sprintf(eeprom_str, "eeprom%d", eeprom_id);
+
+ path = fdt_getprop(gd->fdt_blob, node, eeprom_str, NULL);
+ if (!path) {
+ printf("%s: no alias for %s\n", __func__, eeprom_str);
+ return -ENODEV;
+ }
+
+ eeprom = ofnode_path(path);
+ if (!ofnode_valid(eeprom)) {
+ printf("%s: invalid hardware path to EEPROM\n", __func__);
+ return -ENODEV;
+ }
+
+ ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, eeprom, devp);
+ if (ret) {
+ printf("%s: cannot find EEPROM by node\n", __func__);
+ return ret;
+ }
+
+ return ret;
+}
+
+#ifdef DEBUG
+static void print_tdx_hex(u8 *buf, int size)
+{
+ unsigned char *p = (unsigned char *)buf;
+
+ printf("Toradex config block: \n");
+ for (int i = 0; i < size; ++i) {
+ if (! (i % 16) && i)
+ printf("\n");
+
+ printf("0x%02x ", p[i]);
+ }
+ printf("\n\n");
+}
+#endif
+
+int read_tdx_eeprom_data(u32 eeprom_id, int offset, u8 *buf,
+ int size)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = get_tdx_eeprom(eeprom_id, &dev);
+ if (ret)
+ return ret;
+
+ ret = i2c_eeprom_read(dev, 0x0, buf, size);
+ if (ret) {
+ printf("%s: error reading data from EEPROM id: %d!, ret = %d\n",
+ __func__, eeprom_id, ret);
+ return ret;
+ }
+#ifdef DEBUG
+ print_tdx_hex(buf, size);
+#endif
+ return ret;
+}
+
+int write_tdx_eeprom_data(u32 eeprom_id, int offset, u8 *buf,
+ int size)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = get_tdx_eeprom(eeprom_id, &dev);
+ if (ret)
+ return ret;
+
+#ifdef DEBUG
+ print_tdx_hex(buf, size);
+#endif
+ ret = i2c_eeprom_write(dev, 0x0, buf, size);
+ if (ret) {
+ printf("%s: error writing data to EEPROM id: %d, ret = %d\n",
+ __func__, eeprom_id, ret);
+ return ret;
+ }
+
+ return ret;
+}