]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
imx: kontron: Add common function to get HW UIDs from OTPs
authorFrieder Schrempf <frieder.schrempf@kontron.de>
Tue, 4 Nov 2025 12:54:26 +0000 (13:54 +0100)
committerFabio Estevam <festevam@nabladev.com>
Tue, 4 Nov 2025 15:46:10 +0000 (12:46 -0300)
The factory provides a CPU UID in the OTPs and the SoM module
and the carrier board might provide additional UIDs in the GP
registers of the OTPs.

Provide a common function to load UIDs from arbitrary OTP
registers and generate a serial number string that is saved
in the "serial#" env variable.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
board/kontron/common/Kconfig [new file with mode: 0644]
board/kontron/common/Makefile [new file with mode: 0644]
board/kontron/common/hw-uid.c [new file with mode: 0644]
board/kontron/common/hw-uid.h [new file with mode: 0644]

diff --git a/board/kontron/common/Kconfig b/board/kontron/common/Kconfig
new file mode 100644 (file)
index 0000000..d581006
--- /dev/null
@@ -0,0 +1,14 @@
+menuconfig KONTRON_HW_UID
+       bool "Enable reading Kontron HW UID from OTP fuses"
+       help
+         Enable support for reading Kontron hardware UIDs from OTP fuse registers.
+         The UIDs are factory-programmed for SoMs and boards and are printed to the
+         console and used as serial numbers if this option is enabled.
+
+menuconfig KONTRON_HW_UID_USE_SOC_FALLBACK
+       bool "Use the unique ID of the SoC as fallback serial number"
+       depends on KONTRON_HW_UID
+       default n
+       help
+         Enable the fallback to the UID of the SoC programmed by the SoC
+         manufacturer if no Kontron UID is found in the OTP fuses.
diff --git a/board/kontron/common/Makefile b/board/kontron/common/Makefile
new file mode 100644 (file)
index 0000000..634744d
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_KONTRON_HW_UID) += hw-uid.o
diff --git a/board/kontron/common/hw-uid.c b/board/kontron/common/hw-uid.c
new file mode 100644 (file)
index 0000000..5358b1d
--- /dev/null
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Kontron Electronics GmbH
+ */
+
+#include <linux/errno.h>
+#include <compiler.h>
+#include <asm/io.h>
+#include <env.h>
+#include <string.h>
+#include <vsprintf.h>
+
+#include "hw-uid.h"
+
+int get_serial_str_from_otp(struct uid_otp_loc loc, char *str, size_t str_len)
+{
+       u64 uid;
+       int ret;
+
+       if (loc.len < 1 || loc.len > 2) {
+               printf("Invalid number of UID OTP registers set!\n");
+               return -EINVAL;
+       }
+
+       uid = readl(loc.addr);
+
+       if (loc.len == 2)
+               uid |= (u64)readl(loc.addr + 0x4) << 32;
+
+       if (!uid)
+               return -ENOENT;
+
+       if (uid) {
+               switch (loc.format) {
+               case UID_OTP_FORMAT_DEC:
+                       ret = snprintf(str, str_len, "%010llu", uid);
+                       break;
+               case UID_OTP_FORMAT_HEX:
+                       ret = snprintf(str, str_len, "%016llX", uid);
+                       break;
+               }
+               if (ret < 0 || ret >= str_len) {
+                       printf("Failed to convert UID!\n");
+                       return -EFAULT;
+               }
+       }
+
+       return 0;
+}
+
+void get_serial_number(struct uid_otp_loc *locs, unsigned int num)
+{
+       char serial_string[17];
+       unsigned int i;
+       int ret;
+
+       for (i = 0; i < num; i++) {
+               ret  = get_serial_str_from_otp(locs[i], serial_string, sizeof(serial_string));
+               if (ret == 0)
+                       break;
+       }
+
+       /* No valid UID in the OTP fuses, skip. */
+       if (ret) {
+               printf("Serial Number: None\n");
+               return;
+       }
+
+       printf("Serial Number: %s (%s)\n", serial_string, locs[i].desc);
+
+       if (!env_get("serial#"))
+               env_set("serial#", serial_string);
+       else if (strcmp(env_get("serial#"), serial_string))
+               printf("Warning: mismatch of UIDs in env and OTPs!\n");
+}
diff --git a/board/kontron/common/hw-uid.h b/board/kontron/common/hw-uid.h
new file mode 100644 (file)
index 0000000..7eaf2cc
--- /dev/null
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2024 Kontron Electronics GmbH
+ */
+
+#ifndef _KONTRON_HW_UID_H
+#define _KONTRON_HW_UID_H
+
+#include <compiler.h>
+#include <stddef.h>
+
+enum {
+       UID_OTP_FORMAT_DEC = 0,
+       UID_OTP_FORMAT_HEX,
+};
+
+struct uid_otp_loc {
+       u32 *addr;
+       size_t len;
+       unsigned int format;
+       char *desc;
+};
+
+void get_serial_number(struct uid_otp_loc *locs, unsigned int num);
+
+#endif /* _KONTRON_HW_UID_H */