IMX95 : Linux and Zephyr sharing GPIO3 ressource

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IMX95 : Linux and Zephyr sharing GPIO3 ressource

1,348 Views
anicolle
Contributor II

Hello,

I am working on the i.MX95 (9596) using an evaluation board from NXP. For timing measurements in an application implementing the RPMSG protocol between Zephyr (running on M7) and Linux (on the A55 cores), I need to use GPIOs. However, there are no free GPIOs available on the board, so I decided to repurpose the ones from USDHC2.

The goal is to use USDHC2's DATA0 and DATA1 as GPIOs controlled by Zephyr, and DATA2 and DATA3 as GPIOs controlled by Linux.

I configured the System Manager (SM) to grant access to M7, M33, and A55 for GPIO3, which controls the USDHC2 DATA0–DATA3 lines. I verified that all of them have access to this memory region by successfully reading and writing to it.

On the Linux side, I disabled USDHC2 in the device tree and remuxed the required pins to GPIO mode. I then configured them in my driver application, and I can confirm via oscilloscope that they change state as expected.

On the Zephyr side, I did the same: I updated the device tree to configure the pins as GPIOs. However, since CONFIG_GPIO is not implemented for i.MX95 in Zephyr, I interact with the GPIOs by directly writing to the memory-mapped registers.

The problem is: When Linux is not booted, Zephyr and M33 can control the GPIOs correctly. But once Linux boots, Zephyr can no longer control the GPIOs—only the pins configured under Linux work.

Therefore, I suspect that Linux is doing something (perhaps reinitializing or remuxing the pins) that overrides Zephyr’s configuration, making GPIO writes from Zephyr ineffective.

Is anyone familiar with what might be causing this behavior and how I could modify the setup to allow shared GPIO control between Zephyr and Linux when both are running?

Thank you for your help.

0 Kudos
Reply
6 Replies

1,286 Views
AshutoshNama
Contributor III

Hey Anicolle,

You're digging into a really interesting (and pretty advanced!) setup — great work getting this far! 
From what you’re describing, you’re absolutely right: Linux is most likely reinitializing or reconfiguring the pins during its boot process, and that’s why Zephyr loses control over those GPIOs once Linux is up.

Here’s what’s likely happening:
Even though you disabled USDHC2 and remuxed the pins in Linux, the pinctrl system in Linux might still be reapplying default or unintended configurations at boot (or when a driver probes).
Linux likes to “own” any resources it thinks it’s responsible for, especially pins, and it will happily reset or overwrite settings even if you did something earlier from another core.

How you can fix or work around it:
Explicitly reserve or configure the GPIOs properly in Linux’s device tree so Linux knows not to touch them unless your app tells it to.
You might want to add a simple GPIO stub node in Linux’s device tree with status = "okay"; and a very basic config — this stops the pin from being grabbed by other parts of Linux (like drivers or default init scripts).
Alternatively, mark those GPIOs as “reserved” or even better, create a coordination mechanism between Zephyr and Linux (through RPMsg or similar) to share control properly — but that’s a bit heavier.
Double-check any pinctrl default settings in Linux. Even if you disabled USDHC2, some default groups might still remux things during early kernel stages.

Quick tip:
You can boot Linux with earlycon debug enabled and watch when the pins are being reconfigured — it gives clues where/when it happens.

If need further help feel free to text, Anicolle

Best Regards,
Ashutosh



0 Kudos
Reply

1,224 Views
anicolle
Contributor II

Hello again,

Thank you for your response.

I checked the IOMUX registers on the M33 side and in U-Boot. The GPIOs are correctly configured for "GPIO use" and not in SD mode, so pin muxing does not appear to be the issue.

I also added a stub node in the Linux device tree, but it had no effect. In my case, I’m avoiding RPMsg coordination, as I am measuring RPMsg timing. Although SEMA42 could be used, coordination should not be necessary since GPIO accesses are temporally separated across OSes. I double-checked all pinctrl settings, and everything is correctly configured. As mentioned, the IOMUX registers always remain in GPIO mode. I also modified the U-Boot device tree to ensure it doesn’t override the pinmux.

Another observation: when Linux or U-Boot is running, reading GPIO3 registers (e.g., direction, set, clear, output) from M33 or Linux returns only 0x0. However, in U-Boot, I can read and modify the registers correctly and observe the changes made by Zephyr before U-Boot starts. Do you know why these registers would return 0 when accessed from M33 or Zephyr after Linux has booted?

I also tried using separate GPIO banks—GPIO3 for Zephyr and GPIO2 for Linux. However, when I removed GPIO3 access from the M33 config file, M33 reset continuously  the A55 cores and I get this error from M33:
Reset LM 2, reason=fccu, errId=19
This corresponds to Watchdog 3 monitoring the Linux domain, as described in the M33 config. Even after disabling the watchdog fault, U-Boot still  does not boot. I removed all references to GPIO3 from the Linux and U-Boot device trees, but the problem persists. It seems U-Boot may still attempt to access GPIO3, at least that's my guess. Do you have any idea what could be causing this behavior?

Have a nice day.

 

0 Kudos
Reply

1,204 Views
AshutoshNama
Contributor III
Dear Anicolle,

I noticed there may be a few issues causing trouble. I'd like to recreate the problem on my end, analyze it, and then share a solution with you.

Would you be available for a quick call to discuss this further and see how we can work through it together?

Looking forward to your response.



Best Regards, 
Ashutosh Nama.
0 Kudos
Reply

1,192 Views
anicolle
Contributor II
Hello,

Thank you for your proposal. Could you please let me know how I can contact you privately?

Regards,
Audrey Nicolle

385 Views
Sadatan123
Contributor II
  • Can I controll all the available peripherals and GPIOs through A55? I mean 
  • Will I be able to control all the peripherals like UART, I2C, SPI, SDIO, GPIOs, USB, LVDS, PCIe etc. directly using A55, without having M33 and M7 in picture i.e., can I map these Peripherals and GPIOs to A55 cores.
0 Kudos
Reply

1,184 Views
AshutoshNama
Contributor III
I'm running out of DMs limit here, meanwhile,
You can connect me via my mail- ashutoshnama26@gmail.com
0 Kudos
Reply