diff mbox series

[1/2] warp7: usb: Introduce a get method for serial number

Message ID 1520942427-7366-2-git-send-email-bryan.odonoghue@linaro.org
State New
Headers show
Series NXP WaARP7 set serial# from OTP fuses for USB iSerial | expand

Commit Message

Bryan O'Donoghue March 13, 2018, noon UTC
We want to be able to set the USB device descriptor number iSerial number
or indeed a disk-label unique identifier based on a chip-specific piece of
data for the purposes of differentiating between WaRP7 boards via lsusb
when connected to a host machine.

In order to do this we want to have a serial number encoded in hardware,
which will persist across bootloader, filesystem and config file changes.

This patch utilises OCOTP_TESTER0 AND OCOTP_TESTER1 respectively for this
purpose. OCOTP_TESTER is a unique identifier for each chip representing

31:0 OCOTP_TESTER0 (most significant)
- FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID

OCOTP_TESTER1 (least significant)
31:24
- The X-coordinate of the die location on the wafer/SJC CHALLENGE/ Unique ID
23:16
- The Y-coordinate of the die location on the wafer/SJC CHALLENGE/ Unique ID
15:11
- The wafer number of the wafer on which the device was fabricated/SJC
  CHALLENGE/ Unique ID
10:0
- FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID

The 64 bits of data generate a unique serial number per-chip.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Reviewed-by: Rui Miguel Silva <rui.silva@linaro.org>
Reviewed-by: Ryan Harkin <ryan.harkin@linaro.org>
---
 board/warp7/warp7.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

Comments

Fabio Estevam March 13, 2018, 1:25 p.m. UTC | #1
Hi Bryan,

On Tue, Mar 13, 2018 at 9:00 AM, Bryan O'Donoghue
<bryan.odonoghue@linaro.org> wrote:

> +static int warp7_get_serialid(u64 *id)

Maybe you could turn place this function in a common location as it
may be useful for others.

> +{
> +       u32 val;
> +       int ret;
> +
> +       if (!id)
> +               return -EINVAL;
> +
> +       /* Read first word */
> +       ret = fuse_read(WARP7_USB_SERIALID_BANK, WARP7_USB_SERIALID_MSWORD, &val);
> +       if (ret)
> +               goto done;

Better just do 'return ret' instead of jumping to the 'done' label.
Bryan O'Donoghue March 13, 2018, 2:17 p.m. UTC | #2
On 13/03/18 13:25, Fabio Estevam wrote:
>> +static int warp7_get_serialid(u64 *id)
> Maybe you could turn place this function in a common location as it
> may be useful for others.
> 

Ah, looking for a place to stick this as shared code I've found 
something which already does what this patch does

arch/arm/mach-imx/mx7/soc.c::void get_board_serial(struct tag_serialnr 
*serialnr)

commit c5752f73a53a ("imx: imx7d: Add SoC system support")
diff mbox series

Patch

diff --git a/board/warp7/warp7.c b/board/warp7/warp7.c
index d422d63..2cec448 100644
--- a/board/warp7/warp7.c
+++ b/board/warp7/warp7.c
@@ -23,6 +23,7 @@ 
 #include <power/pmic.h>
 #include <power/pfuze3000_pmic.h>
 #include "../freescale/common/pfuze.h"
+#include <fuse.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -90,6 +91,58 @@  static struct fsl_esdhc_cfg usdhc_cfg[1] = {
 	{USDHC3_BASE_ADDR},
 };
 
+/*
+ * OCOTP_TESTER
+ * i.MX 7Solo Applications Processor Reference Manual, Rev. 0.1, 08/2016
+ * OCOTP_TESTER describes a unique ID based on silicon wafer
+ * and die X/Y position
+ *
+ * OCOTOP_TESTER offset 0x410
+ * 31:0 fuse 0
+ * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID
+ *
+ * OCOTP_TESTER1 offset 0x420
+ * 31:24 fuse 1
+ * The X-coordinate of the die location on the wafer/SJC CHALLENGE/ Unique ID
+ * 23:16 fuse 1
+ * The Y-coordinate of the die location on the wafer/SJC CHALLENGE/ Unique ID
+ * 15:11 fuse 1
+ * The wafer number of the wafer on which the device was fabricated/SJC
+ * CHALLENGE/ Unique ID
+ * 10:0 fuse 1
+ * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID
+ */
+#define WARP7_USB_SERIALID_BANK 0
+#define WARP7_USB_SERIALID_MSWORD 1
+#define WARP7_USB_SERIALID_LSWORD 2
+
+static int warp7_get_serialid(u64 *id)
+{
+	u32 val;
+	int ret;
+
+	if (!id)
+		return -EINVAL;
+
+	/* Read first word */
+	ret = fuse_read(WARP7_USB_SERIALID_BANK, WARP7_USB_SERIALID_MSWORD, &val);
+	if (ret)
+		goto done;
+
+	*id = val;
+	*id <<= 32;
+
+	/* Read second word */
+	ret = fuse_read(WARP7_USB_SERIALID_BANK, WARP7_USB_SERIALID_LSWORD, &val);
+	if (ret)
+		goto done;
+
+	*id |= val;
+
+done:
+	return ret;
+}
+
 int board_mmc_getcd(struct mmc *mmc)
 {
 		/* Assume uSDHC3 emmc is always present */