M4 outputs reset upon linux boot on A7

Hi there,

[Colibri iMX7D 512MB V1.1D]

At linux boot time, near the very end of it, we experienced a reset on the GPIOs we use.
Use case : M4 boots and sets 3 GPIOs as outputs and at high level, then does nothing. Once the linux boots, all those pins are reset to low level even if M4 is still in a wait state. Everything runs fine afterwards, there is no conflicts during execution, only at the very moment linux finishs booting.

Could this be related to our DTS, mixing GPIOs between M4 and A7 on same banks ?

alt text
We found this on Toradex website, does the driver also reset all GPIO output state ?
We do not have interrupts enabled on these pins, they are located on banks 1 and 5 (SODIMM 184, 186 and 188)

Best regards,


hi @nicolas.b

Could you provide the Version of the Software (Bsp) of your module?
Which carrier board are you using?

Are other pins on Bank 1 or Bank 5 configured/used in Linux (dts file)?

Best regards,

Hi @jaski.tx

I’m not the one in charge of the linux part but we use buildroot and use :

  • git clone -b 2016.11-toradex git://git.toradex.com/u-boot-toradex.git/
  • git clone -b toradex_4.9-1.0.x-imx git://git.toradex.com/linux-toradex.git
  • git clone -b colibri-imx7-m4-freertos-v8 git://git.toradex.com/freertos-toradex.git

Last update of these on our side was in september 2018.

We have a custom carrier board (but the pins we’re talking about are just connected to debug pads for tests).

Yes, some other pins are used in linux on these banks, however on bank 4 no other pins are used as GPIO by linux but we still have the problem on the bank4 GPIO on M4 side.

Does that mean we should dedicate a whole bank for the M4 with linux using absolutely none of them (even for something else than GPIO) ?

Best regards,


hi @nicolas.b

Thanks for the Information.

Yes, some other pins are used in linux on these banks, however on bank 4 no other pins are used as GPIO by linux but we still have the problem on the bank4 GPIO on M4 side.

Could you ensure that the pins are also not muxed as gpio? Please try to delete completely the Pin you want to use from devicetree files.

Additionally could you share the devicetree files?

hi @jaski.tx

I cannot communicate the whole DTS but I can paste the iomux part here :

#include "imx7d.dtsi"

    &iomuxc {
    	pinctrl-names = "default";
    	pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4
    		     &pinctrl_gpio5 &pinctrl_gpio6 &pinctrl_gpio7>;
    	pinctrl_gpio1: gpio1-grp {
    		fsl,pins = <
                /* HARDWARE REVISION PINS */
    			/* SODIMM 45 -> M4 */
    			/* SODIMM 47 -> M4 */
    			/* SODIMM 49 -> M4 */
    			/* SODIMM 51 -> M4 */
    			/* SODIMM 53 -> M4 */
    			MX7D_PAD_SAI1_RX_SYNC__GPIO6_IO16	0x14 /* SODIMM 77 */
    			MX7D_PAD_EPDC_DATA09__GPIO2_IO9		0x14 /* SODIMM 89 */
    			MX7D_PAD_EPDC_DATA08__GPIO2_IO8		0x74 /* SODIMM 91 */
    			MX7D_PAD_LCD_RESET__GPIO3_IO4		0x14 /* SODIMM 93 */
    			MX7D_PAD_EPDC_DATA13__GPIO2_IO13	0x14 /* SODIMM 95 */
    			MX7D_PAD_ENET1_RGMII_TXC__GPIO7_IO11	0x14 /* SODIMM 99 */
    			MX7D_PAD_EPDC_DATA10__GPIO2_IO10	0x74 /* SODIMM 105 */
    			MX7D_PAD_EPDC_DATA00__GPIO2_IO0		0x14 /* SODIMM 111 */
    			MX7D_PAD_EPDC_DATA01__GPIO2_IO1		0x14 /* SODIMM 113 */
    			MX7D_PAD_EPDC_DATA02__GPIO2_IO2		0x14 /* SODIMM 115 */
    			MX7D_PAD_EPDC_DATA03__GPIO2_IO3		0x14 /* SODIMM 117 */
    			MX7D_PAD_EPDC_DATA04__GPIO2_IO4		0x14 /* SODIMM 119 */
    			MX7D_PAD_EPDC_DATA05__GPIO2_IO5		0x14 /* SODIMM 121 */
    			MX7D_PAD_EPDC_DATA06__GPIO2_IO6		0x14 /* SODIMM 123 -- PIN enable to activate
    			                                          USB_OTG on USB1 (aka USB_OTG_ENABLE).
    			                                          Is available on system via /dev/usb_otg_enable */
    			MX7D_PAD_EPDC_DATA07__GPIO2_IO7		0x14 /* SODIMM 125 -- PIN to see USB1
    			                                           Over Current value.
    			                                          Is available on system via /dev/usb_otg_oc */
    			MX7D_PAD_EPDC_SDCE2__GPIO2_IO22		0x14 /* SODIMM 127 */
    			MX7D_PAD_UART3_RTS_B__GPIO4_IO6		0x14 /* SODIMM 131 -- PIN to see USB2
    			                                           Over Current value (aka NFC_READER_USB_OC).
    			                                          Is available on system via /dev/usb_host_oc */
    			MX7D_PAD_EPDC_GDRL__GPIO2_IO26		0x14 /* SODIMM 133 */
    			MX7D_PAD_SAI1_RX_DATA__GPIO6_IO12	0x14 /* SODIMM 169 */
    			MX7D_PAD_SAI1_RX_BCLK__GPIO6_IO17	0x14 /* SODIMM 24 */
                /* ROTARY ENCODER */
    			//MX7D_PAD_SD2_DATA2__GPIO5_IO16		0x74 /* SODIMM 100  1 -> M4 */
    			//MX7D_PAD_SD2_DATA3__GPIO5_IO17		0x74 /* SODIMM 102  2 -> M4 */
    			//MX7D_PAD_EPDC_GDSP__GPIO2_IO27		0x74 /* SODIMM 104  4 -> M4 */
    			//MX7D_PAD_EPDC_BDR0__GPIO2_IO28		0x74 /* SODIMM 106  8 -> M4 */
    			MX7D_PAD_EPDC_DATA15__GPIO2_IO15	0x74 /* SODIMM 107 */
    			MX7D_PAD_EPDC_BDR1__GPIO2_IO29		0x14 /* SODIMM 110 */
    			MX7D_PAD_EPDC_PWR_COM__GPIO2_IO30	0x14 /* SODIMM 112 */
    			MX7D_PAD_EPDC_SDCLK__GPIO2_IO16		0x14 /* SODIMM 114 */
    			MX7D_PAD_EPDC_SDLE__GPIO2_IO17		0x14 /* SODIMM 116 */
    			MX7D_PAD_EPDC_SDOE__GPIO2_IO18		0x14 /* SODIMM 118 */
    			MX7D_PAD_EPDC_SDSHR__GPIO2_IO19		0x14 /* SODIMM 120 */
    			MX7D_PAD_EPDC_SDCE0__GPIO2_IO20		0x14 /* SODIMM 122 */
    			MX7D_PAD_EPDC_SDCE1__GPIO2_IO21		0x14 /* SODIMM 124 */
    			MX7D_PAD_EPDC_DATA14__GPIO2_IO14	0x14 /* SODIMM 126 */
    			MX7D_PAD_EPDC_PWR_STAT__GPIO2_IO31	0x14 /* SODIMM 128 */
    			MX7D_PAD_EPDC_SDCE3__GPIO2_IO23		0x14 /* SODIMM 130 */
    			MX7D_PAD_EPDC_GDCLK__GPIO2_IO24		0x14 /* SODIMM 132 */
    			MX7D_PAD_EPDC_GDOE__GPIO2_IO25		0x14 /* SODIMM 134 */
    			MX7D_PAD_EPDC_DATA12__GPIO2_IO12	0x14 /* SODIMM 150 */
    			MX7D_PAD_EPDC_DATA11__GPIO2_IO11	0x14 /* SODIMM 152 */
                /* TEST PADS */
    			//MX7D_PAD_SD2_CLK__GPIO5_IO12		0x74 /* SODIMM 184 TP4 -> M4 */
    			//MX7D_PAD_SD2_CMD__GPIO5_IO13		0x74 /* SODIMM 186 TP5 -> M4 */
    			//MX7D_PAD_GPIO1_IO14__GPIO1_IO14	0x74 /* SODIMM 188 TP6 -> M4 */
    	pinctrl_gpio2: gpio2-grp { /* On X22 Camera interface */
    		fsl,pins = <
    			MX7D_PAD_SD1_CD_B__GPIO5_IO0		0x74 /* SODIMM 69 */
    			MX7D_PAD_I2C4_SDA__GPIO4_IO15		0x14 /* SODIMM 75 */
    			MX7D_PAD_ECSPI1_MISO__GPIO4_IO18	0x14 /* SODIMM 79 */
    			MX7D_PAD_I2C3_SCL__GPIO4_IO12		0x14 /* SODIMM 81 */
    			MX7D_PAD_ECSPI2_MISO__GPIO4_IO22	0x14 /* SODIMM 85 */
    			MX7D_PAD_ECSPI1_SS0__GPIO4_IO19		0x14 /* SODIMM 97 */
    			MX7D_PAD_ECSPI1_SCLK__GPIO4_IO16	0x14 /* SODIMM 101 */
    			MX7D_PAD_ECSPI1_MOSI__GPIO4_IO17	0x14 /* SODIMM 103 */
                /* RESET VAULT */
    			//MX7D_PAD_I2C3_SDA__GPIO4_IO13		0x14 /* SODIMM 94 -> M4 */
    			MX7D_PAD_I2C4_SCL__GPIO4_IO14		0x14 /* SODIMM 96 */
    			MX7D_PAD_SD2_RESET_B__GPIO5_IO11	0x14 /* SODIMM 98 */
    	pinctrl_gpio3: gpio3-grp { /* LCD 18-23 */
    		fsl,pins = <
    			MX7D_PAD_LCD_DATA18__GPIO3_IO23		0x14 /* SODIMM 136 */
    			MX7D_PAD_LCD_DATA19__GPIO3_IO24		0x14 /* SODIMM 138 */
    			MX7D_PAD_LCD_DATA20__GPIO3_IO25		0x14 /* SODIMM 140 */
    			MX7D_PAD_LCD_DATA21__GPIO3_IO26		0x14 /* SODIMM 142 */
    			MX7D_PAD_LCD_DATA22__GPIO3_IO27		0x74 /* SODIMM 144 */
    			MX7D_PAD_LCD_DATA23__GPIO3_IO28		0x74 /* SODIMM 146 */
                /* USB OTG and USB HOST control and monitoring */
    			                                            to detect if VBUS (5V tension from outisde) is present*/
    			// FOR NFC USB
    			//MX7D_PAD_UART3_RTS__GPIO4_IO6		0x14 /* SODIMM 131 USB_HOST_OC */
    			//MX7D_PAD_UART3_CTS__GPIO4_IO7	  0x14 /* SODIMM 129 USB_HOST_ENABLE */
    	pinctrl_gpio4: gpio4-grp { /* Alternatively CAN2 */
    		fsl,pins = <
    			MX7D_PAD_GPIO1_IO15__GPIO1_IO15		0x14 /* SODIMM 178 */
    	pinctrl_gpio5: spigpios {
    		fsl,pins = <
    			/* CS1 */
    			MX7D_PAD_ECSPI2_SS0__GPIO4_IO23		0x74 /* SODIMM 65 */
                /* TouchScreen RESET*/
                MX7D_PAD_SD1_CMD__GPIO5_IO4         0x74 /* SODIMM 190 */
                /* TouchScreen INT */
                MX7D_PAD_SD1_DATA0__GPIO5_IO5       0x74 /* SODIMM 192 */
                /* NFC_READER_IO1 */
                MX7D_PAD_SD2_DATA1__GPIO5_IO15		0x74 /* SODIMM 31*/
    	pinctrl_gpio6: gpio6-grp {
    		fsl,pins = <
                /* Accelerometer INT1 */
                MX7D_PAD_SAI2_TX_BCLK__GPIO6_IO20   0x74 /* SODIMM 27 */
                /* Accelerometer INT2 */
                MX7D_PAD_SAI2_TX_SYNC__GPIO6_IO19   0x74 /* SODIMM 25 */
    	pinctrl_gpio7: gpio7-grp { /* Alternatively CAN1 */
    		fsl,pins = <
    			MX7D_PAD_ENET1_RGMII_RD3__GPIO7_IO3	0x14 /* SODIMM 55 */
    			MX7D_PAD_ENET1_RGMII_RD2__GPIO7_IO2	0x14 /* SODIMM 63 */

The commented pins are used by M4.
We’ve seen the reset problem on both SODIMM184, 186, 188 and 94.

Could you provide the dmesg log in a file?
What is the output of cat /sys/kernel/debug/gpio?

Hi @jaski.tx

Please find the log attached :
link text

Also, our /sys/kernel/debug/ folder is empty.

Also, our /sys/kernel/debug/ folder is empty.

This is strange. Could you provide your kernelconfig (.config) and devicetree .dtb file?

link text

Please find attached our DTS, kernel config and DTB.

Also, we didn’t activate the debug so it’s normal not to have anything in the /sys/kernel/debug/ folder.

Hello @nicolas.b

I talked with @andy.tx about your problem. He is our expert for the M4. From what I read on your description we thought that this problem is linux related. So I’m trying my luck answering your question.
But first let me get to your questions:

Could this be related to our DTS, mixing GPIOs between M4 and A7 on same banks ?

I think that this is possible. But I believe that linux won’t touch anything that it is not supposed to. With interrupts linux has to clear those and it’s usually done on the whole bank so for interrupts this is not that easy. I believe with GPIO’s this should work like you set it up

We found this on Toradex website, does the driver also reset all GPIO output state ?

I went through linux source code but couldn’t find any hint that any pin that gets registered is reset or anything. I could be very well wrong here.

To narrow down what’s going wrong at your side I did a simple test:

  1. I installed our 2.8b5 linux on a Colibri iMX7D 1GB V1.1A module
  2. On the standard BSP devicetree ‘imx7d-colibri-emmc-eval-v3.dtb’ I commented the pinmuxing stuff for the three pins you are using (SODIMM 184,186,188).
  3. I hooked those gpio’s up to three LED’s on our eval-board
  4. I light the gpios in u-boot with gpio set 140 && gpio set 141 && gpio set 14
  5. I boot linux

After boot the gpios are still on and the LED’s lighting up, that shows that on our bare BSP it is indeed working. So the error has to be buried somewhere else…

Are you sure, you do not set those pins in a script in linux to gpio input for example?

Hi @philippe.tx

Thank you for investigating and for the help.

We’re pretty sure that no script on linux side is using all these pins.

Small modifications you could do on your test are :

1 - We have a 512MB V1.1D module, can this change anything ?

2 - Maybe you could try with our DTS to see if it brings the problem

4 - Having UBoot setting the GPIO is different from using the M4 to set them, maybe the M4 loses handle over the pins at linux startup ?

If none of these modifications change anything, then we could try to either :

  • Flash our board with the 2.8b5 linux

  • Test with the standard DTS (but you have it on your side, you’d have seen anything weird in it)

  • Use the Iris carrier board (to see if the problem is hardware related)

and see if it make the problem disappear.

This problem isn’t blocking our developpements so far unlike the RPMSG one so we cannot afford to spent too much time on solving it.

For the moment a viable workaround is to have the M4 wait until linux is up (linux will then put a byte in DDR that M4 reads to check if it can start).

Hi @philippe.tx
We did a little more testing to add information here :

In UBoot we call

gpio set 14 

and verified on oscilloscope that the pin was set.

We then launched LINUX ONLY with

run setup; setenv bootargs ${defargs} ${ubiargs} ${setupargs} ${vidargs}; echo Booting from NAND...; nand read ${kernel_addr_r} kernel && nand read ${fdt_addr_r} dtb && bootz ${kernel_addr_r} - ${fdt_addr_r}


setup = setup=setenv setupargs console=tty1 console=${console},${baudrate}n8 ${memargs} consoleblank=0

And we can see the GPIO being reset when linux is completely started.
This completely excludes the M4 from the problem’s scope.

1 - We have a 512MB V1.1D module, can this change anything ?

You’re right. This could change stuff so I used the exact same module with the exact same RAM size. Still, the gpio does not get reset on linux-boot.

2 - Maybe you could try with our DTS to see if it brings the problem

I booted with your devicetree then. Still, the gpio does not get reset on linux-boot.

4 - Having UBoot setting the GPIO is different from using the M4 to set them, maybe the M4 loses handle over the pins at linux startup ?

I think this question is answered with your second post.

That’s very good if we can exclude the M4!

Unfortunately I was not able to reproduce your issue. I didn’t boot with the nand command in uboot I rather used ubi read as we have it on our bsp.

Two questions from my side.

  1. You are including imx7d.dtsi instead of the SoM level imx7-colibri.dtsi in your devicetree. May I ask the reason for that?

  2. Could you try reproducing the issue with gpio set in Uboot on our BSP (Uboot, kernel, devicetree from us as far as possible) so you could narrow it further down to eliminate or confirm your hardware being the issue.

I assume you are using a custom carrier board as the SODIMM pins 184, 186 and 188 are not connected on iris?

Best regards,

Hi @philippe.tx,

This story finally comes to an end !

It was, and I’m sorry about it, related to one of our scripts indeed. I checked extensively with our linux guy what it did :

  • Upon linux startup we wanted to expose the pin in linux anyway (in case we needed to debug with the M4 not launched) so the script does the following :

    GENERAL PURPOSE TEST PADS (here, defined as output)

                  GPIO_LABEL="test_pad_TP4"; GPIO_OFFSET="140"; create_output_link
                  GPIO_LABEL="test_pad_TP5"; GPIO_OFFSET="141"; create_output_link
                  GPIO_LABEL="test_pad_TP6"; GPIO_OFFSET="14"; create_output_link

with create_output_link function doing :

create_output_link() {
    echo ${GPIO_OFFSET} > ${GPIO_PATH}/export
    echo "out" > ${GPIO_PATH}/gpio${GPIO_OFFSET}/direction
    /bin/ln -s ${GPIO_PATH}/gpio${GPIO_OFFSET}/value /dev/${GPIO_LABEL}

We tested setting gpio 14 in uboot and launching linux WITH and WITHOUT those 3 script lines and noted that the problem disapears if the script is commented out.

Then we tried to enter manually each individual command to see which one was reseting our pin.

In the end, it turns out

echo "out" > ${GPIO_PATH}/gpio${GPIO_OFFSET}/direction

is reseting the GPIO even if it is already set as an output…
So yeah, setting the direction of a pin to “out” in linux clears the gpio value.

Our workaround will be to add a simple check in the function : if the GPIO’s direction is already in the wanted state, do not set it.

Thank you again for the ideas you gave us with your test scenario, and again sorry the problem was on our side since the beginning !

Best Regards,


Hi Nicolas

You’re very welcome. I’m glad I could help at least with the idea.


Hi @philippe.tx
One last question though, do you experiment the same behaviour in your test conditions ? Was it expected to behave this way ?

Should I accept my own answer ?

Hello Nicolas,

Yes I observe the same thing. If a gpio is high from u-boot and I write “out” into the respective gpio it gets cleared. I think that’s normal but if you check it first with cat gpio14 then this should be a good solution.

Yes, please accept your own answer since this answers your original question from this topic.

Best Regards,