Message ID | 20210204202948.1609959-1-sean.anderson@seco.com |
---|---|
State | Changes Requested |
Delegated to: | Stefano Babic |
Headers | show |
Series | ARM: mx6: Add function to read UNIQUE_ID | expand |
On Thu, Feb 04, 2021 at 03:29:48PM -0500, Sean Anderson wrote: > This is almost identical to the imx7 version, except that the register > names are different. > > Signed-off-by: Sean Anderson <sean.anderson@seco.com> > --- > > arch/arm/mach-imx/mx6/soc.c | 33 +++++++++++++++++++++++++++++++++ > 1 file changed, 33 insertions(+) > > diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c > index bf6dddfdc9..cb729be46f 100644 > --- a/arch/arm/mach-imx/mx6/soc.c > +++ b/arch/arm/mach-imx/mx6/soc.c > @@ -11,6 +11,7 @@ > #include <linux/delay.h> > #include <linux/errno.h> > #include <asm/io.h> > +#include <asm/setup.h> > #include <asm/arch/imx-regs.h> > #include <asm/arch/clock.h> > #include <asm/arch/sys_proto.h> > @@ -705,6 +706,38 @@ int arch_misc_init(void) > } > #endif > > +#ifdef CONFIG_SERIAL_TAG > +/* > + * UNIQUE_ID describes a unique ID based on silicon wafer > + * and die X/Y position > + * > + * UNIQUE_ID offset 0x410 > + * 31:0 fuse 0 > + * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID > + * > + * UNIQUE_ID 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 > + */ > +void get_board_serial(struct tag_serialnr *serialnr) > +{ > + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; > + struct fuse_bank *bank = &ocotp->bank[0]; > + struct fuse_bank0_regs *fuse = > + (struct fuse_bank0_regs *)bank->fuse_regs; > + > + serialnr->low = fuse->uid_low; > + serialnr->high = fuse->uid_high; > +} > +#endif > + > /* > * gpr_init() function is common for boards using MX6S, MX6DL, MX6D, > * MX6Q and MX6QP processors NAK. This needs to use the normal mechanism to populate "serial#" directly and not abuse the old ATAG infrastructure.
On 2/4/21 3:41 PM, Tom Rini wrote: > On Thu, Feb 04, 2021 at 03:29:48PM -0500, Sean Anderson wrote: > >> This is almost identical to the imx7 version, except that the register >> names are different. >> >> Signed-off-by: Sean Anderson <sean.anderson@seco.com> >> --- >> >> arch/arm/mach-imx/mx6/soc.c | 33 +++++++++++++++++++++++++++++++++ >> 1 file changed, 33 insertions(+) >> >> diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c >> index bf6dddfdc9..cb729be46f 100644 >> --- a/arch/arm/mach-imx/mx6/soc.c >> +++ b/arch/arm/mach-imx/mx6/soc.c >> @@ -11,6 +11,7 @@ >> #include <linux/delay.h> >> #include <linux/errno.h> >> #include <asm/io.h> >> +#include <asm/setup.h> >> #include <asm/arch/imx-regs.h> >> #include <asm/arch/clock.h> >> #include <asm/arch/sys_proto.h> >> @@ -705,6 +706,38 @@ int arch_misc_init(void) >> } >> #endif >> >> +#ifdef CONFIG_SERIAL_TAG >> +/* >> + * UNIQUE_ID describes a unique ID based on silicon wafer >> + * and die X/Y position >> + * >> + * UNIQUE_ID offset 0x410 >> + * 31:0 fuse 0 >> + * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID >> + * >> + * UNIQUE_ID 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 >> + */ >> +void get_board_serial(struct tag_serialnr *serialnr) >> +{ >> + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; >> + struct fuse_bank *bank = &ocotp->bank[0]; >> + struct fuse_bank0_regs *fuse = >> + (struct fuse_bank0_regs *)bank->fuse_regs; >> + >> + serialnr->low = fuse->uid_low; >> + serialnr->high = fuse->uid_high; >> +} >> +#endif >> + >> /* >> * gpr_init() function is common for boards using MX6S, MX6DL, MX6D, >> * MX6Q and MX6QP processors > > NAK. This needs to use the normal mechanism to populate "serial#" > directly and not abuse the old ATAG infrastructure. What is the "normal" mechanism? Define something like omap_die_id_serial which sets serial# directly? From what I can tell, get_board_serial is the "generic" function for separating the getting of the serial from the setting of serial#. --Sean
On 2/4/21 9:29 PM, Sean Anderson wrote: > This is almost identical to the imx7 version, except that the register > names are different. > > Signed-off-by: Sean Anderson <sean.anderson@seco.com> Hello Sean, I tried to understand where this serial number is ending up. It seems to be used by the bootm command. But shouldn't we use it to define environment variable #serial instead? Best regards Heinrich > --- > > arch/arm/mach-imx/mx6/soc.c | 33 +++++++++++++++++++++++++++++++++ > 1 file changed, 33 insertions(+) > > diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c > index bf6dddfdc9..cb729be46f 100644 > --- a/arch/arm/mach-imx/mx6/soc.c > +++ b/arch/arm/mach-imx/mx6/soc.c > @@ -11,6 +11,7 @@ > #include <linux/delay.h> > #include <linux/errno.h> > #include <asm/io.h> > +#include <asm/setup.h> > #include <asm/arch/imx-regs.h> > #include <asm/arch/clock.h> > #include <asm/arch/sys_proto.h> > @@ -705,6 +706,38 @@ int arch_misc_init(void) > } > #endif > > +#ifdef CONFIG_SERIAL_TAG > +/* > + * UNIQUE_ID describes a unique ID based on silicon wafer > + * and die X/Y position > + * > + * UNIQUE_ID offset 0x410 > + * 31:0 fuse 0 > + * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID > + * > + * UNIQUE_ID 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 > + */ > +void get_board_serial(struct tag_serialnr *serialnr) > +{ > + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; > + struct fuse_bank *bank = &ocotp->bank[0]; > + struct fuse_bank0_regs *fuse = > + (struct fuse_bank0_regs *)bank->fuse_regs; > + > + serialnr->low = fuse->uid_low; > + serialnr->high = fuse->uid_high; > +} > +#endif > + > /* > * gpr_init() function is common for boards using MX6S, MX6DL, MX6D, > * MX6Q and MX6QP processors >
On 2/4/21 3:52 PM, Heinrich Schuchardt wrote: > On 2/4/21 9:29 PM, Sean Anderson wrote: >> This is almost identical to the imx7 version, except that the register >> names are different. >> >> Signed-off-by: Sean Anderson <sean.anderson@seco.com> > > Hello Sean, > > I tried to understand where this serial number is ending up. > > It seems to be used by the bootm command. But shouldn't we use it to > define environment variable #serial instead? Yes. Typically boards will use get_board_serial to set serial#. For example, the warp7 board does int board_late_init(void) { /* ... snip ... */ #ifdef CONFIG_SERIAL_TAG /* Set serial# standard environment variable based on OTP settings */ get_board_serial(&serialnr); snprintf(serial_string, sizeof(serial_string), "WaRP7-0x%08x%08x", serialnr.low, serialnr.high); env_set("serial#", serial_string); #endif return 0; } I would like to do the same on an i.MX6-based board. --Sean > > Best regards > > Heinrich > >> --- >> >> arch/arm/mach-imx/mx6/soc.c | 33 +++++++++++++++++++++++++++++++++ >> 1 file changed, 33 insertions(+) >> >> diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c >> index bf6dddfdc9..cb729be46f 100644 >> --- a/arch/arm/mach-imx/mx6/soc.c >> +++ b/arch/arm/mach-imx/mx6/soc.c >> @@ -11,6 +11,7 @@ >> #include <linux/delay.h> >> #include <linux/errno.h> >> #include <asm/io.h> >> +#include <asm/setup.h> >> #include <asm/arch/imx-regs.h> >> #include <asm/arch/clock.h> >> #include <asm/arch/sys_proto.h> >> @@ -705,6 +706,38 @@ int arch_misc_init(void) >> } >> #endif >> >> +#ifdef CONFIG_SERIAL_TAG >> +/* >> + * UNIQUE_ID describes a unique ID based on silicon wafer >> + * and die X/Y position >> + * >> + * UNIQUE_ID offset 0x410 >> + * 31:0 fuse 0 >> + * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID >> + * >> + * UNIQUE_ID 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 >> + */ >> +void get_board_serial(struct tag_serialnr *serialnr) >> +{ >> + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; >> + struct fuse_bank *bank = &ocotp->bank[0]; >> + struct fuse_bank0_regs *fuse = >> + (struct fuse_bank0_regs *)bank->fuse_regs; >> + >> + serialnr->low = fuse->uid_low; >> + serialnr->high = fuse->uid_high; >> +} >> +#endif >> + >> /* >> * gpr_init() function is common for boards using MX6S, MX6DL, MX6D, >> * MX6Q and MX6QP processors >> >
On Thu, Feb 04, 2021 at 03:52:51PM -0500, Sean Anderson wrote: > > > On 2/4/21 3:41 PM, Tom Rini wrote: > > On Thu, Feb 04, 2021 at 03:29:48PM -0500, Sean Anderson wrote: > > > >> This is almost identical to the imx7 version, except that the register > >> names are different. > >> > >> Signed-off-by: Sean Anderson <sean.anderson@seco.com> > >> --- > >> > >> arch/arm/mach-imx/mx6/soc.c | 33 +++++++++++++++++++++++++++++++++ > >> 1 file changed, 33 insertions(+) > >> > >> diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c > >> index bf6dddfdc9..cb729be46f 100644 > >> --- a/arch/arm/mach-imx/mx6/soc.c > >> +++ b/arch/arm/mach-imx/mx6/soc.c > >> @@ -11,6 +11,7 @@ > >> #include <linux/delay.h> > >> #include <linux/errno.h> > >> #include <asm/io.h> > >> +#include <asm/setup.h> > >> #include <asm/arch/imx-regs.h> > >> #include <asm/arch/clock.h> > >> #include <asm/arch/sys_proto.h> > >> @@ -705,6 +706,38 @@ int arch_misc_init(void) > >> } > >> #endif > >> > >> +#ifdef CONFIG_SERIAL_TAG > >> +/* > >> + * UNIQUE_ID describes a unique ID based on silicon wafer > >> + * and die X/Y position > >> + * > >> + * UNIQUE_ID offset 0x410 > >> + * 31:0 fuse 0 > >> + * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID > >> + * > >> + * UNIQUE_ID 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 > >> + */ > >> +void get_board_serial(struct tag_serialnr *serialnr) > >> +{ > >> + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; > >> + struct fuse_bank *bank = &ocotp->bank[0]; > >> + struct fuse_bank0_regs *fuse = > >> + (struct fuse_bank0_regs *)bank->fuse_regs; > >> + > >> + serialnr->low = fuse->uid_low; > >> + serialnr->high = fuse->uid_high; > >> +} > >> +#endif > >> + > >> /* > >> * gpr_init() function is common for boards using MX6S, MX6DL, MX6D, > >> * MX6Q and MX6QP processors > > > > NAK. This needs to use the normal mechanism to populate "serial#" > > directly and not abuse the old ATAG infrastructure. > > What is the "normal" mechanism? Define something like > omap_die_id_serial which sets serial# directly? From what I can tell, > get_board_serial is the "generic" function for separating the getting of > the serial from the setting of serial#. The normal method is more like stm32 (arch/arm/mach-stm32mp/cpu.c) or rockchip (arch/arm/mach-rockchip/misc.c) where there's no ATAGs legacy design (which is where omap_die_id_serial is).
On Thu, Feb 04, 2021 at 03:56:23PM -0500, Sean Anderson wrote: > > > On 2/4/21 3:52 PM, Heinrich Schuchardt wrote: > > On 2/4/21 9:29 PM, Sean Anderson wrote: > >> This is almost identical to the imx7 version, except that the register > >> names are different. > >> > >> Signed-off-by: Sean Anderson <sean.anderson@seco.com> > > > > Hello Sean, > > > > I tried to understand where this serial number is ending up. See common/fdt_support.c and fdt_root(). That's the common use and way it's populated and passed on. > > It seems to be used by the bootm command. But shouldn't we use it to > > define environment variable #serial instead? > > Yes. Typically boards will use get_board_serial to set serial#. For > example, the warp7 board does > > int board_late_init(void) > { > /* ... snip ... */ > > #ifdef CONFIG_SERIAL_TAG > /* Set serial# standard environment variable based on OTP settings */ > get_board_serial(&serialnr); > snprintf(serial_string, sizeof(serial_string), "WaRP7-0x%08x%08x", > serialnr.low, serialnr.high); > env_set("serial#", serial_string); > #endif > > return 0; > } > > I would like to do the same on an i.MX6-based board. Please note that the WaRP7 case of mixing the serial# with some other string is not the common / best practices case. It's typically just the die-ID or similar value without other text around it, which makes for an easy generic function. The WaRP7 case makes it harder for imx7 to have a generic everyone gets it populated function like imx6 could have with your patch and a few changes, and like I want to go adjust the currently unused imx8 code to do.
On 2/4/21 9:52 PM, Sean Anderson wrote: > > > On 2/4/21 3:41 PM, Tom Rini wrote: > > On Thu, Feb 04, 2021 at 03:29:48PM -0500, Sean Anderson wrote: > > > >> This is almost identical to the imx7 version, except that the register > >> names are different. > >> > >> Signed-off-by: Sean Anderson <sean.anderson@seco.com> > >> --- > >> > >> arch/arm/mach-imx/mx6/soc.c | 33 +++++++++++++++++++++++++++++++++ > >> 1 file changed, 33 insertions(+) > >> > >> diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c > >> index bf6dddfdc9..cb729be46f 100644 > >> --- a/arch/arm/mach-imx/mx6/soc.c > >> +++ b/arch/arm/mach-imx/mx6/soc.c > >> @@ -11,6 +11,7 @@ > >> #include <linux/delay.h> > >> #include <linux/errno.h> > >> #include <asm/io.h> > >> +#include <asm/setup.h> > >> #include <asm/arch/imx-regs.h> > >> #include <asm/arch/clock.h> > >> #include <asm/arch/sys_proto.h> > >> @@ -705,6 +706,38 @@ int arch_misc_init(void) > >> } > >> #endif > >> > >> +#ifdef CONFIG_SERIAL_TAG > >> +/* > >> + * UNIQUE_ID describes a unique ID based on silicon wafer > >> + * and die X/Y position > >> + * > >> + * UNIQUE_ID offset 0x410 > >> + * 31:0 fuse 0 > >> + * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID > >> + * > >> + * UNIQUE_ID 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 > >> + */ > >> +void get_board_serial(struct tag_serialnr *serialnr) > >> +{ > >> + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; > >> + struct fuse_bank *bank = &ocotp->bank[0]; > >> + struct fuse_bank0_regs *fuse = > >> + (struct fuse_bank0_regs *)bank->fuse_regs; > >> + > >> + serialnr->low = fuse->uid_low; > >> + serialnr->high = fuse->uid_high; > >> +} > >> +#endif > >> + > >> /* > >> * gpr_init() function is common for boards using MX6S, MX6DL, MX6D, > >> * MX6Q and MX6QP processors > > > > NAK. This needs to use the normal mechanism to populate "serial#" > > directly and not abuse the old ATAG infrastructure. > > What is the "normal" mechanism? Define something like > omap_die_id_serial which sets serial# directly? From what I can tell, > get_board_serial is the "generic" function for separating the getting of > the serial from the setting of serial#. > > --Sean get_board_serial() is defined as empty function in bootm.h if CONFIG_SERIAL_TAG=n. But CONFIG_SERIAL_TAG is not documented anywhere. board/gateworks/gw_ventana/gw_ventana.c has this comment: #ifdef CONFIG_SERIAL_TAG /* * called when setting up ATAGS before booting kernel * populate serialnum from the following (in order of priority): * serial# env var * eeprom */ void get_board_serial(struct tag_serialnr *serialnr) serial# seems to be set generally in misc_init_r(). But doing this on a per board level seems to be an inadequate design for i.mx6. The best place for i.mx6 seems to be arch_misc_init(). @Tom: Linux Kconfig has: CONFIG_ATAGS: This is the traditional way of passing data to the kernel at boot time. If you are solely relying on the flattened device tree (or the ARM_ATAG_DTB_COMPAT option) then you may unselect this option to remove ATAGS support from your kernel binary. If unsure, leave this to y. CONFIG_DEPRECATED_PARAM_STRUCT depends on ATAGS This was deprecated in 2001 and announced to live on for 5 years. Some old boot loaders still use this way. As this has been deprecated 20 years ago, why don't we remove it from U-Boot? Best regards Heinrich
On 2/4/21 10:09 PM, Tom Rini wrote: > On Thu, Feb 04, 2021 at 03:56:23PM -0500, Sean Anderson wrote: >> >> >> On 2/4/21 3:52 PM, Heinrich Schuchardt wrote: >>> On 2/4/21 9:29 PM, Sean Anderson wrote: >>>> This is almost identical to the imx7 version, except that the register >>>> names are different. >>>> >>>> Signed-off-by: Sean Anderson <sean.anderson@seco.com> >>> >>> Hello Sean, >>> >>> I tried to understand where this serial number is ending up. > > See common/fdt_support.c and fdt_root(). That's the common use and way > it's populated and passed on. This is where the environment variable serial# ends up. But get_board_serial() which Sean is implementing does not populate serial#. That is why I asked. Best regards Heinrich
On 2/4/21 4:04 PM, Tom Rini wrote: > On Thu, Feb 04, 2021 at 03:52:51PM -0500, Sean Anderson wrote: >> >> >> On 2/4/21 3:41 PM, Tom Rini wrote: >>> On Thu, Feb 04, 2021 at 03:29:48PM -0500, Sean Anderson wrote: >>> >>>> This is almost identical to the imx7 version, except that the register >>>> names are different. >>>> >>>> Signed-off-by: Sean Anderson <sean.anderson@seco.com> >>>> --- >>>> >>>> arch/arm/mach-imx/mx6/soc.c | 33 +++++++++++++++++++++++++++++++++ >>>> 1 file changed, 33 insertions(+) >>>> >>>> diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c >>>> index bf6dddfdc9..cb729be46f 100644 >>>> --- a/arch/arm/mach-imx/mx6/soc.c >>>> +++ b/arch/arm/mach-imx/mx6/soc.c >>>> @@ -11,6 +11,7 @@ >>>> #include <linux/delay.h> >>>> #include <linux/errno.h> >>>> #include <asm/io.h> >>>> +#include <asm/setup.h> >>>> #include <asm/arch/imx-regs.h> >>>> #include <asm/arch/clock.h> >>>> #include <asm/arch/sys_proto.h> >>>> @@ -705,6 +706,38 @@ int arch_misc_init(void) >>>> } >>>> #endif >>>> >>>> +#ifdef CONFIG_SERIAL_TAG >>>> +/* >>>> + * UNIQUE_ID describes a unique ID based on silicon wafer >>>> + * and die X/Y position >>>> + * >>>> + * UNIQUE_ID offset 0x410 >>>> + * 31:0 fuse 0 >>>> + * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID >>>> + * >>>> + * UNIQUE_ID 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 >>>> + */ >>>> +void get_board_serial(struct tag_serialnr *serialnr) >>>> +{ >>>> + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; >>>> + struct fuse_bank *bank = &ocotp->bank[0]; >>>> + struct fuse_bank0_regs *fuse = >>>> + (struct fuse_bank0_regs *)bank->fuse_regs; >>>> + >>>> + serialnr->low = fuse->uid_low; >>>> + serialnr->high = fuse->uid_high; >>>> +} >>>> +#endif >>>> + >>>> /* >>>> * gpr_init() function is common for boards using MX6S, MX6DL, MX6D, >>>> * MX6Q and MX6QP processors >>> >>> NAK. This needs to use the normal mechanism to populate "serial#" >>> directly and not abuse the old ATAG infrastructure. >> >> What is the "normal" mechanism? Define something like >> omap_die_id_serial which sets serial# directly? From what I can tell, >> get_board_serial is the "generic" function for separating the getting of >> the serial from the setting of serial#. > > The normal method is more like stm32 (arch/arm/mach-stm32mp/cpu.c) or > rockchip (arch/arm/mach-rockchip/misc.c) where there's no ATAGs legacy > design (which is where omap_die_id_serial is). > Thanks for the reference. It's often difficult to figure out what the "best practice" is with so many boards added at different times. --Sean
On Thu, Feb 04, 2021 at 10:41:20PM +0100, Heinrich Schuchardt wrote: > On 2/4/21 9:52 PM, Sean Anderson wrote: > > > > > > On 2/4/21 3:41 PM, Tom Rini wrote: > > > On Thu, Feb 04, 2021 at 03:29:48PM -0500, Sean Anderson wrote: > > > > > >> This is almost identical to the imx7 version, except that the register > > >> names are different. > > >> > > >> Signed-off-by: Sean Anderson <sean.anderson@seco.com> > > >> --- > > >> > > >> arch/arm/mach-imx/mx6/soc.c | 33 +++++++++++++++++++++++++++++++++ > > >> 1 file changed, 33 insertions(+) > > >> > > >> diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c > > >> index bf6dddfdc9..cb729be46f 100644 > > >> --- a/arch/arm/mach-imx/mx6/soc.c > > >> +++ b/arch/arm/mach-imx/mx6/soc.c > > >> @@ -11,6 +11,7 @@ > > >> #include <linux/delay.h> > > >> #include <linux/errno.h> > > >> #include <asm/io.h> > > >> +#include <asm/setup.h> > > >> #include <asm/arch/imx-regs.h> > > >> #include <asm/arch/clock.h> > > >> #include <asm/arch/sys_proto.h> > > >> @@ -705,6 +706,38 @@ int arch_misc_init(void) > > >> } > > >> #endif > > >> > > >> +#ifdef CONFIG_SERIAL_TAG > > >> +/* > > >> + * UNIQUE_ID describes a unique ID based on silicon wafer > > >> + * and die X/Y position > > >> + * > > >> + * UNIQUE_ID offset 0x410 > > >> + * 31:0 fuse 0 > > >> + * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID > > >> + * > > >> + * UNIQUE_ID 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 > > >> + */ > > >> +void get_board_serial(struct tag_serialnr *serialnr) > > >> +{ > > >> + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; > > >> + struct fuse_bank *bank = &ocotp->bank[0]; > > >> + struct fuse_bank0_regs *fuse = > > >> + (struct fuse_bank0_regs *)bank->fuse_regs; > > >> + > > >> + serialnr->low = fuse->uid_low; > > >> + serialnr->high = fuse->uid_high; > > >> +} > > >> +#endif > > >> + > > >> /* > > >> * gpr_init() function is common for boards using MX6S, MX6DL, MX6D, > > >> * MX6Q and MX6QP processors > > > > > > NAK. This needs to use the normal mechanism to populate "serial#" > > > directly and not abuse the old ATAG infrastructure. > > > > What is the "normal" mechanism? Define something like > > omap_die_id_serial which sets serial# directly? From what I can tell, > > get_board_serial is the "generic" function for separating the getting of > > the serial from the setting of serial#. > > > > --Sean > > get_board_serial() is defined as empty function in bootm.h if > CONFIG_SERIAL_TAG=n. But CONFIG_SERIAL_TAG is not documented anywhere. Correct, it's ATAGs related stuff, so quite old and at best may have been documented in the README at some point. > board/gateworks/gw_ventana/gw_ventana.c has this comment: > > #ifdef CONFIG_SERIAL_TAG > /* > * called when setting up ATAGS before booting kernel > * populate serialnum from the following (in order of priority): > * serial# env var > * eeprom > */ > void get_board_serial(struct tag_serialnr *serialnr) Right. > serial# seems to be set generally in misc_init_r(). > But doing this on a per board level seems to be an inadequate design for > i.mx6. The best place for i.mx6 seems to be arch_misc_init(). Yes, there's a number of reasonable examples of where to populate serial# from, and a few examples from when we had to support the kernel with it. > @Tom: > Linux Kconfig has: > > CONFIG_ATAGS: > This is the traditional way of passing data to the kernel at boot time. > If you are solely relying on the flattened device tree (or > the ARM_ATAG_DTB_COMPAT option) then you may unselect this option > to remove ATAGS support from your kernel binary. If unsure, leave this > to y. > > CONFIG_DEPRECATED_PARAM_STRUCT > depends on ATAGS > This was deprecated in 2001 and announced to live on for 5 years. > Some old boot loaders still use this way. > > As this has been deprecated 20 years ago, why don't we remove it from > U-Boot? The history is a lot more complex than that. The earliest starting date for "ATAGs is dead, use DT" would be 2010 or so when Linaro started real work on migrating ARM to DT. I also _think_ that deprecated param struct note is about what predated ATAGs actually. But, we can't universally drop ATAGs support from U-Boot as we support hardware that runs on pre-device tree kernels only (Nokia N900) or older VxWorks that also used ATAGs I _think__. But we certainly have some cases that should be cleaned up and disabled, hence my series yesterday.
diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c index bf6dddfdc9..cb729be46f 100644 --- a/arch/arm/mach-imx/mx6/soc.c +++ b/arch/arm/mach-imx/mx6/soc.c @@ -11,6 +11,7 @@ #include <linux/delay.h> #include <linux/errno.h> #include <asm/io.h> +#include <asm/setup.h> #include <asm/arch/imx-regs.h> #include <asm/arch/clock.h> #include <asm/arch/sys_proto.h> @@ -705,6 +706,38 @@ int arch_misc_init(void) } #endif +#ifdef CONFIG_SERIAL_TAG +/* + * UNIQUE_ID describes a unique ID based on silicon wafer + * and die X/Y position + * + * UNIQUE_ID offset 0x410 + * 31:0 fuse 0 + * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID + * + * UNIQUE_ID 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 + */ +void get_board_serial(struct tag_serialnr *serialnr) +{ + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[0]; + struct fuse_bank0_regs *fuse = + (struct fuse_bank0_regs *)bank->fuse_regs; + + serialnr->low = fuse->uid_low; + serialnr->high = fuse->uid_high; +} +#endif + /* * gpr_init() function is common for boards using MX6S, MX6DL, MX6D, * MX6Q and MX6QP processors
This is almost identical to the imx7 version, except that the register names are different. Signed-off-by: Sean Anderson <sean.anderson@seco.com> --- arch/arm/mach-imx/mx6/soc.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)