switching pinmux configurations from SAI3 to GPIO pins

I am trying to enable GPIO_IO16 as GPIO pins and then tiggle it using Zephyr RTOS on M Core. However, these pins are listed as SAI3 pins under A55’s control. How can I move the ownership of SAI3 from A to M core and then configure them as GPIO pins in Zephyr’s application/dts and then toggle it using zephyr.elf?

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


GPIO3_IO16 Configuration for Cortex-M Core

Based on the available documentation, there are specific considerations when working with GPIO3_IO16 on Toradex modules with Cortex-M cores.

Known Issue with GPIO3_IO16

There is a documented issue with GPIO3_IO16 on Verdin iMX8M Plus when using it from the Cortex-M core (1). The pin may appear to always read “low” even when voltage is applied, which suggests configuration conflicts in the device tree.

Root Cause Analysis

The issue stems from pin configuration conflicts in the device tree files (1). Specifically:

  • GPIO3_IO16 (SODIMM_64) can be used for I2C3, USDHC3, or NAND functions
  • The pinctrl_flexspi0 node in imx8mp-verdin.dtsi configures this pin for peripheral functions
  • Even when I2C3 is disabled, the pinctrl configuration may still interfere with GPIO functionality

Device Tree Configuration

The current configuration in the device tree shows (1):

&iomuxc {
	pinctrl_flexspi0: flexspi0grp {
		fsl,pins =
			<MX8MP_IOMUXC_NAND_ALE__FLEXSPI_A_SCLK		0x1c2>,	/* SODIMM 52 */
			<MX8MP_IOMUXC_NAND_CE0_B__FLEXSPI_A_SS0_B	0x82>,	/* SODIMM 54 */
			<MX8MP_IOMUXC_NAND_DQS__FLEXSPI_A_DQS		0x82>,	/* SODIMM 66 */
			<MX8MP_IOMUXC_NAND_DATA00__FLEXSPI_A_DATA00	0x82>,	/* SODIMM 56 */
			<MX8MP_IOMUXC_NAND_DATA01__FLEXSPI_A_DATA01	0x82>,	/* SODIMM 58 */
			<MX8MP_IOMUXC_NAND_DATA02__FLEXSPI_A_DATA02	0x82>,	/* SODIMM 60 */
			<MX8MP_IOMUXC_NAND_DATA03__FLEXSPI_A_DATA03	0x82>,	/* SODIMM 62 */
			<MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16		0x82>;	/* SODIMM 64 */
	};
}

(1)

Workaround Solution

The documentation indicates that manual configuration within the Cortex-M program can work, but timing is critical (1):

  1. Early Configuration: If you configure GPIO3_IO16 at the very beginning of your Cortex-M program (started by u-boot), it works
  2. Late Configuration: If you configure it after Torizon OS has booted, the configuration is not overwritten

U-Boot Configuration Issue

There appears to be a mismatch between u-boot and Linux device tree configurations (1). The u-boot configuration may incorrectly set up the pin, which gets corrected later in the boot process.

Recommended Approach

For your Zephyr application on the M core:

  1. Configure the pin early in your Zephyr application initialization
  2. Ensure proper timing - configure after u-boot but before the full Linux boot process interferes
  3. Monitor the boot sequence to identify the optimal configuration window

Alternative Considerations

If GPIO3_IO16 continues to present issues, consider using other available GPIO pins that don’t have the same peripheral function conflicts documented in the device tree.

Note: The specific behavior may vary depending on your exact module version and software configuration. The timing-sensitive nature of this configuration suggests it’s related to the boot sequence and resource ownership between the A and M cores.

Best regards, Toradex AI Assistant.

I changed .cfg file on imx-system-manager: removed SAI3 from A55 Non secure and added it to M7’s resources, removed GPIO_IO16 from A55 and added under M7, and then rebuilt the image and flashed it. Then I configured the GPIO_IO16 in zephyr’s dts and wrote the application source code. running the west build command did not show any errors and successfully built and copied the zephyr.elf file to target. On running the elf file using remote proc, i can not observe the pin toggling.

Hello Deepshika Borundiya,

I think a good place to start would be to make sure not no use the pins on Linux, but configuring them on Zephyr.
You need to remove/disable in the Linux device tree and add to Zephyr device tree.
Let us know if this solves the issue of it persists.

Also, I think you are aware of this blog, but it may be relevant Loading Zephyr on iMX95 Cortex-M from Linux with OpenAMP

best regards

Maximiliano Zapata
Toradex

Hey Maximiliano.tx,

I disabled SAI3 pins on both Linux dts and zephyr dts. I also added the pinmux configuration for GPIO. Following is the overlay file created for zephyr:

/ {
aliases {
led0 = &user_led;
};

leds {
    compatible = "gpio-leds";

    /* USER LED on GPIO2 line 16 (GPIO_IO16) */
    user_led: led_gpio_io16 {
        gpios = <&gpio2 16 GPIO_ACTIVE_HIGH>;
        label = "USER_LED_IO16";
        /* NOTE: gpio-leds child nodes do NOT allow pinctrl-* properties */
    };
};

};

/\* Prevent GPIO1 (0x47400000) from probing on M7 \*/
&gpio1 {
status = “disabled”;
};

/\* Apply pin mux directly to the GPIO controller using the IOMUXC pin node \*/
&gpio2 {
status = “okay”;

/* This must point to the IOMUXC pin node (numeric pinmux array),
 * NOT to a pinctrl "group".
 */
pinmux = <&iomuxc_gpio_io16_gpio_io_bit_gpio2_io_bit16>;

};

/\* Optional: keep SAI3 out of the way \*/
&sai3 {
status = “disabled”;
/delete-property/ pinctrl-0;
/delete-property/ pinctrl-names;
};

However, while loading zephyr.elf and running it using remoteproc (opamp), M7 is not able to configure the gpio (gpio_pin_configure_dt returns ENOTSUP).

Hello Deepshika Borundiya,

The issue looks related to Zephyr. Our suggestion to discard Linux interference is to load the firmware from u-boot.
If the issue persist, it is a matter of a Zephyr configuration, for which is best to check on their community/support channel
Let me know how that goes

best regards

Maximiliano Zapata
Toradex

Hello Deepshika Borundiya,

just checking in, was this resolved?

thanks

Maximiliano Zapata
Toradex