Verdin iMX8M Plus GPIO pull up configuration

From I brand new iMX8M Plus board I need to use 4 GPIO lines:

GPIO_1 - gpiochip0 pin 1
GPIO_2 - gpiochip0 pin 2
GPIO_3 - gpiochip0 pin 5
GPIO_4 - gpiochip0 pin 6

When booting up as default I’ve noticed thet GPIO_3 is pulled up (+1,8V), and the other inputs are not (0v).

I need all 4 lines to be pulled up and I found out I need to customize the device tree, as libgpiod cannot set the pull up configuration for input - can someone help and please confirm that - that would be much easier to do it on libgpiod?

Well, if really customizing the device tree is necessary, I’ve seen I need to build a DTS file, compile it a use torizoncode-builder to add to my image.

Where can I find the right configuration to set pull up on those 4 lines?

I tried to find the /arch/arm/boot/dts original files but the board does not have that directory.

How can I get an example/guide on how to change the DTS file to enable pull up on these lines, and how to compile and add it to the tcbuild.yml?

Hi, I’m the Toradex AI Assistant. The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


To configure the GPIO pull-up settings on your iMX8M Plus board, you indeed need to customize the device tree, as libgpiod cannot set pull-up configurations for inputs. Here’s a step-by-step guide based on the context provided:

  1. Create a Device Tree Source (DTS) File: You need to create or modify a DTS file to specify the pull-up configuration for the GPIO lines. The GPIO lines you are interested in are GPIO_1, GPIO_2, GPIO_3, and GPIO_4, which correspond to gpiochip0 pins 1, 2, 5, and 6 respectively.

  2. Example Configuration: You will need to define these GPIO pins in the DTS file and set the appropriate properties to enable pull-up resistors. The specific syntax for enabling pull-ups can typically be found in the documentation for the iMX8M Plus or similar boards. Unfortunately, the context does not provide the exact syntax, so you may need to refer to the official documentation or existing DTS files for examples.

  3. Compile the DTS File: Once you have your DTS file ready, compile it into a Device Tree Blob (DTB) file using the device tree compiler (DTC).

  4. Integrate with Torizon: Use torizoncode-builder to integrate the new DTB into your Torizon image. Modify the tcbuild.yml file to include the path to your new DTB file so that it is included in the final image used for your board.

  5. Finding Example DTS Files: If you cannot find the original DTS files in the /arch/arm/boot/dts directory, you might need to check the Torizon or Yocto Project repositories for example DTS files. These repositories often contain board-specific configurations that can serve as a reference.

  6. Resources: Utilize the official documentation for the iMX8M Plus board and community forums for additional guidance and examples from other users who have configured similar setups.

If you need further assistance with specific DTS file configurations or examples, you may need to reach out to community forums or support channels for more detailed guidance.

Please, also check if these links can help you solve your problem:

Device Tree Overlays on Torizon | Toradex Developer Center.

Here is what I’ve accomplished so far:

STEP 1: Built the device tree overlay to set pullup’s on desired lines:

Fiile gpio_pullup.dtsi

&iomuxc {
    pinctrl_gpio1: gpio1grp {
		fsl,pins = <
			MX8MP_IOMUXC_GPIO1_IO00__GPIO1_IO00		0x1c4	/* SODIMM 206 */
		>;
	};

	pinctrl_gpio2: gpio2grp {
		fsl,pins = <
			MX8MP_IOMUXC_GPIO1_IO01__GPIO1_IO01		0x1c4	/* SODIMM 208 */
		>;
	};

	pinctrl_gpio3: gpio3grp {
		fsl,pins = <
			MX8MP_IOMUXC_GPIO1_IO05__GPIO1_IO05		0x1c4	/* SODIMM 210 */
		>;
	};

	pinctrl_gpio4: gpio4grp {
		fsl,pins = <
			MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06		0x1c4	/* SODIMM 212 */
		>;
	};};

Questions:
A1) Should I need to include any base file on that? Like #include

A2) How to compile this dtsi file into dts (didd not find how torizoncore-builder can do it…)

STEP 2: Build a image with tcbuild.yml


# Documentation https://developer.toradex.com/torizon/os-customization/torizoncore-builder-workflow/#customizing-the-configuration-file
# Configuration file outline:
# ⚠️ Mouse hover to the properties to see documentation
# ⚠️ ctrl+space inside an object or property to get the autocompletion tips
input:
  easy-installer:
    toradex-feed:
      version: "6.7.0"
      release: quarterly
      machine: verdin-imx8mp
      distro: torizon
      variant: torizon-core-docker
      build-number: 18

customization:
  splash-screen: my_splash_screen.png
  device-tree:
    overlays:
      add:
        - gpio_pullup.dts

output:
  easy-installer:
    local: my-os
#    bundle: 
#      compose-file: docker-compose.yml
  ostree:
    branch: my-os
    commit-subject: my-os

I tried to run it without compiling the dtsi file, just copying the same file to .dts and naturally I got the following error:

$ torizoncore-builder build
Building image as per configuration file 'tcbuild.yaml'...

=>> Handling input section
Fetching URL 'https://artifacts.toradex.com/artifactory/torizoncore-oe-prod-frankfurt/kirkstone-6.x.y/release/18/verdin-imx8mp/torizon/torizon-core-docker/oedeploy/torizon-core-docker-verdin-imx8mp-Tezi_6.7.0+build.18.tar' into '/tmp/torizon-core-docker-verdin-imx8mp-Tezi_6.7.0+build.18.tar'
[========================================] 
Download Complete!
Downloaded file name: '/tmp/torizon-core-docker-verdin-imx8mp-Tezi_6.7.0+build.18.tar'
No integrity check performed because checksum was not specified.
Unpacking Toradex Easy Installer image.
Unpacking TorizonCore Toradex Easy Installer image.
Importing OSTree revision b2ae8a9faf113b989787bc2f86be4b31741853b47bace9f1eaf0f19ca06fd9ce from local repository...
1050 metadata, 9446 content objects imported; 583.3 MB content written          
0 metadata, 0 content objects imported; 0 bytes content written                 
Unpacked OSTree from Toradex Easy Installer image:
  Commit checksum: b2ae8a9faf113b989787bc2f86be4b31741853b47bace9f1eaf0f19ca06fd9ce
  TorizonCore Version: 6.7.0+build.18

=>> Handling customization section

=> Setting splash screen
splash screen merged to initramfs

=> Handling device-tree subsection
Not testing overlay because base image does not have a device-tree set!

=> Adding device-tree overlay 'gpio_pullup.dts'
Error: gpio_pullup.dts:27.4-5 syntax error
FATAL ERROR: Unable to parse input tree
error: cannot apply gpio_pullup.dts.

Questions:

B1) Is it the correct configuration for the tcbuild.yml - should I only add the overlay or do I need to configure the device tree overlay in the file - help appreeciated to fix that configuration file.

Thanks for supporting

Hi @renatom!

In order to set a pull-up in those 4 GPIOs you’ll need to write an overlay. You can follow this article to learn how to write a DTS.

About the configuration, if you check the Verdin iMX8MP device tree, you will find these GPIOs in 1129-1147 lines. On each pinctrl you’ll see a hexadecimal number along the pin name, this hexadecimal is used to set the pad control register of the SoC, which you can use to set a pull-up. You can use the Pad Mux Register table on page 27 of the Verdin iMX8MP datasheet to verify what number should be written (you must translate this hexadecimal to binary to use the table).

Following the table, your hexadecimal could be 0x1c4, which is 111000100 in binary.

To customize a pinctrl node, you can call it in your overlay using a &, for example:

&pinctrl_gpio1 {
             fsl,pins = <MX8MP_IOMUX_GPIO1_IO00__GPIO1_IO00         0x1c4>;
};

Then, you can compile it following the article Build Device Tree Overlays from Source Code and deploy it following this article for our BSPs or, for Torizon OS, you can add it in tcbuild.yaml following this section about Customizing the Configuration File

Best regards.
Lucas Azeituno

Hi @renatom!

I think my last message was delayed.

The .dtsi files are used as includes, if you are writing a device tree overlay it should be .dts.

I tested the following overlay and it worked. Could you test it, please?

/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include "imx8mp-pinfunc.h"

/ {
	compatible = "toradex,verdin-imx8mp-nonwifi-dahlia",
	 	     "toradex,verdin-imx8mp-nonwifi",
		     "toradex,verdin-imx8mp",
		     "fsl,imx8mp";
};

&pinctrl_gpio1 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO00__GPIO1_IO00		0x1c4>;
};

&pinctrl_gpio3 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO05__GPIO1_IO05 	0x1c4>;
};

&pinctrl_gpio4 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06	 	0x1c4>;
};

Best regards.
Lucas Azeituno

Thanks Lucas for the response. I’ve already gone through all the reading and have build the code above.

So:
The .dtsi files are used as includes, if you are writing a device tree overlay it should be .dts.*

You mean I don’t need to compile the DTS file, or, in other words, use it as typed in the tcbuild.yml?

Indeed I’ve tried that - renamed my dtsi to dts and configured the tcbuild.yml as shown but I got the logged error. So, how to correctly setup the tcbuild.yml to use my dts?

Check the below log for a full session log of what’s going on:


renato@devlinux:~/workspace/testprj/my-os$ cat gpio_pullup.dts
/*
GPIO control bits: PE  HYS  PUE  ODE  FSEL  X  DSE1  DSE0  X
-----------------
Pull Select Field       : PE_0_PULL_DISABLE / PE_1_PULL_ENABLE
Input Select Field      : HYS_0_CMOS / HYS_1_SCHMITT
Pull Up / Down Config.  : PUE_0_WEAK_PULL_DOWN / PUE_1_WEAK_PULL_UP
Open Drain Field        : ODE_0_OPEN_DRAIN_DISABLE / ODE_1_OPEN_DRAIN_ENABLE
Slew Rate Field         : FSEL_0_SLOW_SLEW_RATE / FSEL_1_FAST_SLEW_RATE
Drive Strength Field    : DSE_X1 / DSE_X2 / DSE_X4 /DSE_X6
-----------------

1C4 hexadecimal = 0b111000100 binary (PE_1_PULL_ENABLE | HYS+1+SCHMITT | PUE_1_WEAK_PULL_UP | ODE_0_OPEN_DRAIN_DISABLE | FSEL_0_SLOW_SLEW_RATE | DSE_X2 )

*/

/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include "imx8mp-pinfunc.h"

/ {
	compatible = "toradex,verdin-imx8mp-nonwifi-dahlia",
	 	     "toradex,verdin-imx8mp-nonwifi",
		     "toradex,verdin-imx8mp",
		     "fsl,imx8mp";
};

&pinctrl_gpio1 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO00__GPIO1_IO00		0x1c4>;
};

&pinctrl_gpio3 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO05__GPIO1_IO05 	0x1c4>;
};

&pinctrl_gpio4 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06	 	0x1c4>;
};

renato@devlinux:~/workspace/testprj/my-os$ cat tcbuild.yaml
# Documentation https://developer.toradex.com/torizon/os-customization/torizoncore-builder-workflow/#customizing-the-configuration-file
# Configuration file outline:
# ⚠️ Mouse hover to the properties to see documentation
# ⚠️ ctrl+space inside an object or property to get the autocompletion tips
input:
  easy-installer:
    toradex-feed:
      version: "6.7.0"
      release: quarterly
      machine: verdin-imx8mp
      distro: torizon
      variant: torizon-core-docker
      build-number: 18

customization:
  splash-screen: my_splash_screen.png
  device-tree:
    overlays:
      add:
        - gpio_pullup.dts

output:
  easy-installer:
    local: my-os
#    bundle: 
#      compose-file: docker-compose.yml
  ostree:
    branch: my-os
    commit-subject: my-os
renato@devlinux:~/workspace/testprj/my-os$ 



renato@devlinux:~/workspace/testprj/my-os$ torizoncore-builder build
Building image as per configuration file 'tcbuild.yaml'...

=>> Handling input section
Fetching URL 'https://artifacts.toradex.com/artifactory/torizoncore-oe-prod-frankfurt/kirkstone-6.x.y/release/18/verdin-imx8mp/torizon/torizon-core-docker/oedeploy/torizon-core-docker-verdin-imx8mp-Tezi_6.7.0+build.18.tar' into '/tmp/torizon-core-docker-verdin-imx8mp-Tezi_6.7.0+build.18.tar'
[========================================] 
Download Complete!
Downloaded file name: '/tmp/torizon-core-docker-verdin-imx8mp-Tezi_6.7.0+build.18.tar'
No integrity check performed because checksum was not specified.
Unpacking Toradex Easy Installer image.
Unpacking TorizonCore Toradex Easy Installer image.
Importing OSTree revision b2ae8a9faf113b989787bc2f86be4b31741853b47bace9f1eaf0f19ca06fd9ce from local repository...
1050 metadata, 9446 content objects imported; 583.3 MB content written          
0 metadata, 0 content objects imported; 0 bytes content written                 
Unpacked OSTree from Toradex Easy Installer image:
  Commit checksum: b2ae8a9faf113b989787bc2f86be4b31741853b47bace9f1eaf0f19ca06fd9ce
  TorizonCore Version: 6.7.0+build.18

=>> Handling customization section

=> Setting splash screen
splash screen merged to initramfs

=> Handling device-tree subsection
Not testing overlay because base image does not have a device-tree set!

=> Adding device-tree overlay 'gpio_pullup.dts'
gpio_pullup.dts:25:35: error: no include path in which to search for dt-bindings/gpio/gpio.h
   25 | #include <dt-bindings/gpio/gpio.h>
      |                                   ^
gpio_pullup.dts:26:10: fatal error: imx8mp-pinfunc.h: No such file or directory
   26 | #include "imx8mp-pinfunc.h"
      |          ^~~~~~~~~~~~~~~~~~
compilation terminated.
Error: gpio_pullup.dts:23.9-10 syntax error
FATAL ERROR: Unable to parse input tree
error: cannot apply gpio_pullup.dts.

Hi @renatom!

You must add the include directory, please refer to this section of the article about TorizonCore Builder Tool - Customizing Torizon OS Images.

To do this, you’ll need to clone our kernel and device tree repository, and add the path linux/include within include-dirs section.

This should solve the problem, since the error is caused by the TCB not finding the included files in the overlay.

Best regards.
Lucas Azeituno

In that case what should be used in the device-tree, custom field of the tcbuild.yaml? What dts should I base on?

BTW: I can now make tcbuild.yaml (without custom section) work and generate the image, but when sent to device the pullups are not yet enabled…

# Documentation https://developer.toradex.com/torizon/os-customization/torizoncore-builder-workflow/#customizing-the-configuration-file

# Configuration file outline:
# ⚠️ Mouse hover to the properties to see documentation
# ⚠️ ctrl+space inside an object or property to get the autocompletion tips
input:
  easy-installer:
    toradex-feed:
      version: "6.7.0"
      release: quarterly
      machine: verdin-imx8mp
      distro: torizon
      variant: torizon-core-docker
      build-number: 18

customization:
  splash-screen: my_splash_screen.png
  device-tree:
    include-dirs:
      - linux/include
      - linux/arch/arm64/boot/dts/freescale/
    overlays:
      add:
      - overlays/gpio_pullup.dts

output:
  easy-installer:
    local: my-os
#    bundle: 
#      compose-file: docker-compose.yml
  ostree:
    branch: my-os
    commit-subject: my-os

/*
GPIO control bits: PE  HYS  PUE  ODE  FSEL  X  DSE1  DSE0  X
-----------------
Pull Select Field       : PE_0_PULL_DISABLE / PE_1_PULL_ENABLE
Input Select Field      : HYS_0_CMOS / HYS_1_SCHMITT
Pull Up / Down Config.  : PUE_0_WEAK_PULL_DOWN / PUE_1_WEAK_PULL_UP
Open Drain Field        : ODE_0_OPEN_DRAIN_DISABLE / ODE_1_OPEN_DRAIN_ENABLE
Slew Rate Field         : FSEL_0_SLOW_SLEW_RATE / FSEL_1_FAST_SLEW_RATE
Drive Strength Field    : DSE_X1 / DSE_X2 / DSE_X4 /DSE_X6
-----------------
1C4 hexadecimal = 0b111000100 binary (PE_1_PULL_ENABLE | HYS+1+SCHMITT | PUE_1_WEAK_PULL_UP | ODE_0_OPEN_DRAIN_DISABLE | FSEL_0_SLOW_SLEW_RATE | DSE_X2 )
*/

/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include "imx8mp-pinfunc.h"

/ {
	compatible = "toradex,verdin-imx8mp-nonwifi-dahlia",
	 	     "toradex,verdin-imx8mp-nonwifi",
		     "toradex,verdin-imx8mp",
		     "fsl,imx8mp";
};

&pinctrl_gpio1 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO00__GPIO1_IO00		0x1c4>;
};

&pinctrl_gpio2 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO01__GPIO1_IO01		0x1c4>;
};

&pinctrl_gpio3 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO05__GPIO1_IO05 	0x1c4>;
};

&pinctrl_gpio4 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06	 	0x1c4>;
};

Got it working. Final configuration:

tcbuild.yaml


# Documentation https://developer.toradex.com/torizon/os-customization/torizoncore-builder-workflow/#customizing-the-configuration-file
# Configuration file outline:
# ⚠️ Mouse hover to the properties to see documentation
# ⚠️ ctrl+space inside an object or property to get the autocompletion tips
input:
  easy-installer:
    toradex-feed:
      version: "6.7.0"
      release: quarterly
      machine: verdin-imx8mp
      distro: torizon
      variant: torizon-core-docker
      build-number: 18

customization:
  splash-screen: my_splash_screen.png
  device-tree:
    include-dirs:
      - linux/include
      - linux/arch/arm64/boot/dts/freescale/
    custom: linux/arch/arm64/boot/dts/freescale/imx8mp-verdin-wifi-mallow.dts
    overlays:
      add:
      - device-trees/overlays/verdin-imx8mp_hdmi_overlay.dts
      - overlays/gpio_pullup.dts

output:
  easy-installer:
    local: my-os
#    bundle: 
#      compose-file: docker-compose.yml
  ostree:
    branch: my-os
    commit-subject: my-os

And gpio_pullup.dts:


/*
GPIO control bits: PE  HYS  PUE  ODE  FSEL  X  DSE1  DSE0  X
-----------------
Pull Select Field       : PE_0_PULL_DISABLE / PE_1_PULL_ENABLE
Input Select Field      : HYS_0_CMOS / HYS_1_SCHMITT
Pull Up / Down Config.  : PUE_0_WEAK_PULL_DOWN / PUE_1_WEAK_PULL_UP
Open Drain Field        : ODE_0_OPEN_DRAIN_DISABLE / ODE_1_OPEN_DRAIN_ENABLE
Slew Rate Field         : FSEL_0_SLOW_SLEW_RATE / FSEL_1_FAST_SLEW_RATE
Drive Strength Field    : DSE_X1 / DSE_X2 / DSE_X4 /DSE_X6
-----------------

1C4 hexadecimal = 0b111000100 binary (PE_1_PULL_ENABLE | HYS+1+SCHMITT | PUE_1_WEAK_PULL_UP | ODE_0_OPEN_DRAIN_DISABLE | FSEL_0_SLOW_SLEW_RATE | DSE_X2 )
*/

/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include "imx8mp-pinfunc.h"

/ {
	compatible = "toradex,verdin-imx8mp-nonwifi-dahlia",
	 	     "toradex,verdin-imx8mp-nonwifi",
		     "toradex,verdin-imx8mp",
		     "fsl,imx8mp";
};

&pinctrl_gpio1 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO00__GPIO1_IO00		0x1c4>;
};

&pinctrl_gpio2 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO01__GPIO1_IO01		0x1c4>;
};

&pinctrl_gpio3 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO05__GPIO1_IO05 	0x1c4>;
};

&pinctrl_gpio4 {
	fsl,pins = <MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06	 	0x1c4>;
};

A final comment:

The parameter: clear: false on tcbuild.yaml device-tree session seens not to be working. So it clears all overlays from custom dts on any condition. I had to add HDMI overlay again in order to have my HDMI display working again. I suggest a check/fix on this to engineering.

Anyway thanks for supporting.