Skip to content

Conversation

@pdgendt
Copy link
Contributor

@pdgendt pdgendt commented Oct 23, 2025

This PR has the necessary bits to make the SYSCON API usable in NVMEM. Some of the parts

  • Add a syscon_get_reg_width API function to determine how many bytes are read
  • Add shell commands for easy testing
  • Implement i.MX OCOTP SYSCON driver

This work relates to #96598 as the OCOTP SYSCON driver will be used as an NVMEM backend. This allows to rework the following with NVMEM:

static inline void nxp_enet_fused_mac(uint8_t *mac_addr)
{
#ifdef CONFIG_SOC_FAMILY_NXP_IMXRT
uint32_t mac_addr_fuse[2] = {0};
#if defined(CONFIG_SOC_SERIES_IMXRT10XX)
OCOTP_Init((OCOTP_Type *)OCOTP_BASE, CLOCK_GetIpgFreq());
/* OTP bank 4, word 2: MAC0 */
OCOTP_ReadFuseShadowRegisterExt((OCOTP_Type *)OCOTP_BASE,
0x22, &mac_addr_fuse[0], 1);
/* OTP bank 4, word 3: MAC1*/
OCOTP_ReadFuseShadowRegisterExt((OCOTP_Type *)OCOTP_BASE,
0x23, &mac_addr_fuse[1], 1);
#elif defined(CONFIG_SOC_SERIES_IMXRT11XX)
OCOTP_Init((OCOTP_Type *)OCOTP_BASE, 0);
OCOTP_ReadFuseShadowRegisterExt((OCOTP_Type *)OCOTP_BASE,
0x28, &mac_addr_fuse[0], 2);
#endif
mac_addr[0] = mac_addr_fuse[0] & 0x000000FF;
mac_addr[1] = (mac_addr_fuse[0] & 0x0000FF00) >> 8;
mac_addr[2] = (mac_addr_fuse[0] & 0x00FF0000) >> 16;
mac_addr[3] = (mac_addr_fuse[0] & 0xFF000000) >> 24;
mac_addr[4] = (mac_addr_fuse[1] & 0x00FF);
mac_addr[5] = (mac_addr_fuse[1] & 0xFF00) >> 8;
#else
ARG_UNUSED(mac_addr);
#endif
}

Documenting return values with doxygen should use the @RetVal tags.

Signed-off-by: Pieter De Gendt <[email protected]>
Introduce a function to the syscon API that can be used to get the register
width of the device.

Signed-off-by: Pieter De Gendt <[email protected]>
Implement the get_reg_width API function for the generic syscon driver.

Signed-off-by: Pieter De Gendt <[email protected]>
Add shell commands to use the SYSCON driver API with SYSCON devices.

Signed-off-by: Pieter De Gendt <[email protected]>
Add OTP support for NXP i.MX OCOTP using the SYSCON API.

Signed-off-by: Pieter De Gendt <[email protected]>
Add device tree nodes for the OCOTP controller on i.MX RT10xx platforms.

Signed-off-by: Pieter De Gendt <[email protected]>
@sonarqubecloud
Copy link

@ZhaoxiangJin
Copy link
Contributor

Semantically speaking, OCOTP is not suitable for implementation based on the syscon device driver model. What we should introduce is the nvmem device driver model, with EEPROM and FUSE/OCOTP implemented based on this device driver model, just like in Linux.

@pdgendt
Copy link
Contributor Author

pdgendt commented Oct 23, 2025

Semantically speaking, OCOTP is not suitable for implementation based on the syscon device driver model. What we should introduce is the nvmem device driver model, with EEPROM and FUSE/OCOTP implemented based on this device driver model, just like in Linux.

@ZhaoxiangJin thanks for your feedback, currently the NVMEM subsystem expects a device driver in the backend, with only EEPROM implemented at the moment.

So the FUSE/OCOTP driver is missing, which is compatible with the syscon API, AFAICS? Do you have any references I can look into w.r.t. "just like in Linux"?

@ZhaoxiangJin
Copy link
Contributor

Semantically speaking, OCOTP is not suitable for implementation based on the syscon device driver model. What we should introduce is the nvmem device driver model, with EEPROM and FUSE/OCOTP implemented based on this device driver model, just like in Linux.

@ZhaoxiangJin thanks for your feedback, currently the NVMEM subsystem expects a device driver in the backend, with only EEPROM implemented at the moment.

So the FUSE/OCOTP driver is missing, which is compatible with the syscon API, AFAICS? Do you have any references I can look into w.r.t. "just like in Linux"?

@pdgendt, in Linux, FUSE, OTP, and EEPROM are abstracted into a device driver model called nvmem . In the current Zephyr, EEPROM has its own device driver model @henrikbrixandersen, but FUSE and OTP do not. Some people have implemented FUSE driver based on syscon, but this is a semantically wrong approach (just like using sensor to implement comparator before @bjarki-andreasen). In the long run, we need more than just being able to use it. The current EEPROM device driver moel in Zephyr is suitable for FUSE and OTP (This is why #89108 initially implemented the fuse driver based on eeprom), so we should now convert the current EEPROM device driver model in Zephyr into the NVMEM device driver model, and convert the existing EEPROM driver into the NVMEM driver (In fact, the implementation details may not be much different, just the name has changed). Based on this, let's think about what the nvmem subsys layer can bring us.

@pdgendt
Copy link
Contributor Author

pdgendt commented Oct 23, 2025

@ZhaoxiangJin The NVMEM subsystem has been introduced in #96379 already?

Looking at Linux it also uses syscon mechanisms to read/write OCOTP data, for example:
https://github.com/torvalds/linux/blob/43e9ad0c55a369ecc84a4788d06a8a6bfa634f1c/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml#L69-L87

So NVMEM needs a driver API to call into, and in this case for the OCOTP, I think the syscon API is the correct one to use.

@ZhaoxiangJin
Copy link
Contributor

ZhaoxiangJin commented Oct 23, 2025

@ZhaoxiangJin The NVMEM subsystem has been introduced in #96379 already?

Looking at Linux it also uses syscon mechanisms to read/write OCOTP data, for example: https://github.com/torvalds/linux/blob/43e9ad0c55a369ecc84a4788d06a8a6bfa634f1c/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml#L69-L87

So NVMEM needs a driver API to call into, and in this case for the OCOTP, I think the syscon API is the correct one to use.

@pdgendt, yes, I know this subsys was introduced recently, what I want to talk here is that we should abstract the nvmem device driver model for FUSE, OTP, and EEPROM. This design has already been validated in Linux.
Regarding your mention of using the syscon mechanism in Linux to read OTP/FUSE data, such cases do exist. However, after thoroughly reviewing Linux, this approach is quite uncommon compared to obtaining OCOTP data through the NVMEM device driver model via FUSE. It likely represents a minority scenario requiring direct register access—such as early code or specific IPs may need to read a specific offset.

Copy link
Member

@gmarull gmarull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to (ab)use syscon for peripherals that are not system controllers, but have a clear purpose like fuse controllers.

@pdgendt
Copy link
Contributor Author

pdgendt commented Nov 6, 2025

Closing due to incorrect API

Extracted #99015 and #99016 instead.

@pdgendt pdgendt closed this Nov 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants