How to disable all HDMI used pins?

Hello there,
I am using Yocto to build the image for the BBB with the use of meta-ti layer. The generated image is a bit different from the generic one I am used to, i.e., it has no uEnv.txt and I figured I could load the custom device tree overlay via the extlinux/extlinux.conf file. Right now it looks like that:

root@beaglebone:~# cat /boot/extlinux/extlinux.conf
# Generic Distro Configuration file generated by OpenEmbedded
LABEL Poky (Yocto Project Reference Distro)
        KERNEL ../zImage
        FDTDIR ../
        FDTOVERLAYS ../beaglenode.dtbo
        APPEND root=PARTUUID=${uuid} rootwait rw console=${console},${baudrate}

And the boot dir:

root@beaglebone:/boot# ls -l
-rwxr-xr-x    1 root     root        110068 Apr  5  2011 MLO
-rwxr-xr-x    1 root     root         89315 Apr  5  2011 am335x-bone.dtb
-rwxr-xr-x    1 root     root         93883 Apr  5  2011 am335x-boneblack-wireless.dtb
-rwxr-xr-x    1 root     root         93434 Apr  5  2011 am335x-boneblack.dtb
-rwxr-xr-x    1 root     root         90586 Apr  5  2011 am335x-boneblue.dtb
-rwxr-xr-x    1 root     root         91607 Apr  5  2011 am335x-bonegreen-wireless.dtb
-rwxr-xr-x    1 root     root         89642 Apr  5  2011 am335x-bonegreen.dtb
-rwxr-xr-x    1 root     root           298 Mar 11 19:59 beaglenode.dtbo
drwxr-xr-x    2 root     root          4096 Apr  5  2011 extlinux
-rwxr-xr-x    1 root     root        898796 Apr  5  2011 u-boot.img
-rwxr-xr-x    1 root     root       5214720 Apr  5  2011 zImage

The /beaglenode.dtbo is my custom device tree overlay blob, which I for now manually compiled and placed there. It looks like this so far:

/dts-v1/;
/plugin/;

/ {
	compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";

	fragment@0 {
		target = <&lcdc>;
		__overlay__ {
			status = "disabled";
		};
	};
};

What I am trying to accomplish, is to disable all GPIO pins used for the lcd/ hdmi control. With the help of the above overlay, I was able to:

  1. Stop seeing the output on the connected via HDMI screen,
  2. Stop seeing the [ 3.056701] tilcdc 4830e000.lcdc: bound 0-0070 (ops tda998x_ops) ebtry during boot.

What I would still like to do is to manually make sure that the GPIOs (i.e., the whole nxp_hdmi_bonelt_pins) are unused/ uninitialized. My problem is that:

  1. I don’t know (during OS runtime) how to check in what mode which pin is,
  2. I don’t know how to deinitialize them in the overlay.

For the latter, I tried this in the overlay:

		target = <&nxp_hdmi_bonelt_pins>;
		__overlay__ {
			status = "disabled";
		};

With probably no effect. During runtime I am looking in the /sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single directory to check how different files look like, but it seems that no matter what I change in the overlay, these are fixed…

How to check each pin current mode?
How to deninitialize (high Z) all HDMI GPIOs?

I would appreciate all feedback!

So for reference, ignoring the pcb color and missing power jack… From the device-tree perspective, the ā€œGreenā€ is just a ā€œBlackā€ without HDMI… :wink:

 FDT ../am335x-bonegreen.dtb

Regards,

Hi Robert and thank you for the answer,
The proposed solution is actually quite ā€œspot onā€ and I will probably end up using it…

But with this question I wanted to actually learn how to properly ā€œreleaseā€ the hdmi pins via an overlay file, so I can adapt it in future for different purposes.

Also with your proposed solution for the modofication in the extlinux.conf file it made me wonder: since there is no similar entry about the beaglebone black dtb file entry, how does the uboot know to load it in the first place…?

Overlays can be tricky with this, as there is a ā€˜delete’ node, but this doesn’t actually work in most cases as all the references still exist. It works best to ā€˜overwrite’ everything with your own data. The problem with hdmi, you have lcdc, audio, pinmux, i2c bus, it’s easier to start with nothing and add hdmi in, then remove it. For BeagleBoard.org that’s what we do, we start with the ā€œgreenā€ (minus eMMC) and add each overlay depending on what users want…

We get the board id from the eeprom and then set a default device tree, the ā€˜database’ is here: image-builder/readme.md at master Ā· beagleboard/image-builder Ā· GitHub

Regards,

For BeagleBoard.org that’s what we do, we start with the ā€œgreenā€ (minus eMMC) and add each overlay depending on what users want…

What do you mean exactly (also with the eMMC)? When I compare the am335x-boneblack.dts and am335x-bonegreen.dts in this build directory I get from Yocto and meta-ti ./tmp/work/beaglebone-poky-linux-gnueabi/u-boot-ti-staging/1_2021.01+gitAUTOINC+3a5205e980-r33/git/arch/arm/dts/, I see that the differences are that green lacks the lcdc, hdmi and hdmi related pinmux config, but gets the uart2 config (the groove connector I guess). What I mean is- what is the exact difference in the approach?

am335x-boneblack.dts (3.4 KB)
am335x-bonegreen.dts (1.2 KB)

For Beaglebone green, a similar approach is made with uart2_pins as for the nxp_hdmi_bonelt_pins and nxp_hdmi_bonelt_off_pins for BBB- again here I can easily disable the uart2 node in the overlay, but still there are the pins that needs to be deconfigured- how would I do that in the overlay, so then I do not see these pins when reading /sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single files (asking because I need the uart2 pins used as something else too)?

The relevant part in am335x-bonegreen.dts:

&am33xx_pinmux {
	uart2_pins: uart2_pins {
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE1)	/* spi0_sclk.uart2_rxd */
			AM33XX_IOPAD(0x954, PIN_OUTPUT | MUX_MODE1)	/* spi0_d0.uart2_txd */
		>;
	};
};

&uart2 {
	pinctrl-names = "default";
	pinctrl-0 = <&uart2_pins>;
	status = "okay";
};

We get the board id from the eeprom and then set a default device tree, the ā€˜database’ is here: image-builder/readme.md at master Ā· beagleboard/image-builder Ā· GitHub

Understood, so by adding the FDT ../am335x-bonegreen.dtb entry, I simply overwrite the default setting (for black) read from the eeprom?

I would appreciate your further feedback, thank you!

Oh this might work, not compiled or tested…

/dts-v1/;
/plugin/;

&uart2 {
	pinctrl-names = "default";
	pinctrl-0 = <>;
	status = "disabled";
};

This overlay does 2 things, disables the peripheral, and overwrites the &uart2_pins pinmux value with null/nothing… So those pins should be in a default state now…

Regards,

Hi again Robert,
I think it worked:

  • I stopped seeing the /dev/ttyO2 -> ttyS2,
  • I dont see the group: pinmux_uart2_pins in /sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single/pingroups.

Thank you a lot!

If now I wanted to register a new group with custom GPIOs in the overlay file, would I need to create a new ā€œdeviceā€, like the uart2, or would setting the pinmux gpios be enough? For example (this won’t compile though):

        fragment@0 {
                target = <&uart2>;
                __overlay__ {
                        pinctrl-names = "default";
                        pinctrl-0 = <>;
                        status = "disabled";
                };
        };

        &am33xx_pinmux {
        my_pins: my_pins {
                pinctrl-single,pins = <
                        AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE1)      /* spi0_sclk.uart2_rxd */
                        AM33XX_IOPAD(0x954, PIN_OUTPUT | MUX_MODE1)     /* spi0_d0.uart2_txd */
                >;
        };
};

Above, my pins are the same TX and RX gpios as in uart2, but eventually I would like to create a new group in which I add multiple gpios configured as plain digital push-pull outputs or PRU controlled inputs (or pins in general, mode6 or 5). The thing is, would I then get all of the pins under the /sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single/pingroups? I cannot figure out which ā€œentityā€ is the one doing the registration there…

I would appreciate your further feedback!

So adding nodes to am33xx_pinmux only defines them in the struct. For them to be initialized and used, some node has to call them with pinctrl-0 etc…

Now that the pru is mainline, we have some good examples:

For the PocketBeagle, here’s the pinchange: ARM: dts: am335x-pocketbeagle: enable pru - kernel/git/torvalds/linux.git - Linux kernel source tree

Regards,

Thank you for the link,
I think these PRU configs are done in the main dts, while I am trying to make it in a dts that will become a dtbo. I tried this for the purposes of testing:

/dts-v1/;
/plugin/;

/ {
        compatible = "ti,am335x-bone-green", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";

        fragment@0 {
                target = <&uart2>;
                __overlay__ {
                        pinctrl-names = "default";
                        pinctrl-0 = <>;
                        status = "disabled";
                };
        };

        fragment@1 {
                target = <&am33xx_pinmux>;
                __overlay__ {

                        my_pins: my_pins {
                                pinctrl-single,pins = <
                                0xa0 0x08       /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                0xa4 0x08       /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                >;
                        };

                };
        };
};

But the /sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single/pingroups file did not list ā€œgroup: my_pinsā€ or similar… I must be still missing some sort of registration mechanism. Any ideas?

you don’t need that, that was only for 3.8.x

                        my_pins: my_pins {
                                pinctrl-single,pins = <
                                0xa0 0x08       /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                0xa4 0x08       /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                >;
                        };

You need a node with this in it to make the pins show up:

                        pinctrl-names = "default";
                        pinctrl-0 = <&my_pins>;

Ok, so my overlay file looks like this right now:

/dts-v1/;
/plugin/;

/ {
        fragment@0 {
                target = <&uart2>;
                __overlay__ {
                        pinctrl-names = "default";
                        pinctrl-0 = <>;
                        status = "disabled";
                };
        };

        fragment@1 {
                target = <&am33xx_pinmux>;
                __overlay__ {

                        my_pins: my_pins {
                                pinctrl-single,pins = <
                                0xa0 0x08       /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                0xa4 0x08       /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                >;
                        };

                };
        };
};

/ {
        my {
                pinctrl-names = "default";
                pinctrl-0 = <&my_pins>;
                status = "okay";
        };
};

It compiles, but the pins do not show up…

is there a device driver looking for my…

just overwrite the am33x_pinmux: clkout2_pin option am335x-bone-common.dtsi Ā« omap Ā« ti Ā« dts Ā« boot Ā« arm Ā« arch - kernel/git/torvalds/linux.git - Linux kernel source tree

Original:

&am33xx_pinmux {
	pinctrl-names = "default";
	pinctrl-0 = <&clkout2_pin>;

Overlay:

        fragment@1 {
                target = <&am33xx_pinmux>;
                __overlay__ {
                        pinctrl-names = "default";
                        pinctrl-0 = <&my_pins>;

                        my_pins: my_pins {
                                pinctrl-single,pins = <
                                0xa0 0x08       /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                0xa4 0x08       /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                >;
                        };

                };
        };

clkout2_pin is legacy signal for jtag(and maybe hdmi cec), but no one solders the jtag in place

Regards,

No, not yet.

just overwrite the am33x_pinmux: clkout2_pin option am335x-bone-common.dtsi Ā« omap Ā« ti Ā« dts Ā« boot Ā« arm Ā« arch - kernel/git/torvalds/linux.git - Linux kernel source tree

Ok, a bit hacky I guess, but works (sort of):

root@beaglebone:~# cat /sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single/pingroups
registered pin groups:
group: my_pins
pin 40 (PIN40)

group: pinmux_uart0_pins
pin 92 (PIN92)
pin 93 (PIN93)

group: cpsw_default
pin 68 (PIN68)
pin 69 (PIN69)
.
.
.

There is just 1 pin: 40, aka P8_45. The second one (41, P8_46) is missing. Since there was just 1 pin for the clkout2_pin, is there a constraint here?

hum… double checking…

your defines are good…

#define AM335X_PIN_LCD_DATA0			0x8a0
#define AM335X_PIN_LCD_DATA1			0x8a4

is pinctrl complaining?

debian@26-am335x-bbg:~$ dmesg | grep pinctrl
[    0.107643] pinctrl core: initialized pinctrl subsystem
[    2.729718] pinctrl-single 44e10800.pinmux: 142 pins, size 568

Regards,

I have the same output as you:

root@beaglebone:~# dmesg | grep pinctrl
[    0.104554] pinctrl core: initialized pinctrl subsystem
[    1.624006] pinctrl-single 44e10800.pinmux: 142 pins, size 568

Pasting my overlay file for confirmation:

/dts-v1/;
/plugin/;

/ {
        fragment@0 {
                target = <&uart2>;
                __overlay__ {
                        pinctrl-names = "default";
                        pinctrl-0 = <>;
                        status = "disabled";
                };
        };

        fragment@1 {
                target = <&am33xx_pinmux>;
                __overlay__ {
                        pinctrl-names = "default";
                        pinctrl-0 = <&my_pins>;

                        my_pins: my_pins {
                                pinctrl-single,pins = <
                                        0xa0 0x08       /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                        0xa4 0x08       /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                >;
                        };

                };
        };
};

Hello again @RobertCNelson ,
It feels like the issue is somewhat related to specific addresses of the pins. For example when the DTS was changes to this (copied over more pins):

/dts-v1/;
/plugin/;

/ {
        fragment@0 {
                target = <&uart2>;
                __overlay__ {
                        pinctrl-names = "default";
                        pinctrl-0 = <>;
                        status = "disabled";
                };
        };

        fragment@1 {
                target = <&am33xx_pinmux>;
                __overlay__ {
                        pinctrl-names = "default";
                        pinctrl-0 = <&my_pins>;

                        my_pins: my_pins {
                                pinctrl-single,pins = <
                                        0xa0 0x08       /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                        0xa4 0x08       /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                        0xa8 0x08       /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                        0xac 0x08       /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                        0xb0 0x08       /* lcd_data4.lcd_data4, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                        0xb4 0x08       /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                        0xb8 0x08       /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                        0xbc 0x08       /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                        0xc0 0x08       /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                        0xc4 0x08       /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
                                >;
                        };

                };
        };
};

The output is:

root@beaglebone:~# cat /sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single/pingroups
registered pin groups:
group: my_pins
pin 40 (PIN40)
pin 2 (PIN2)
pin 43 (PIN43)
pin 2 (PIN2)
pin 46 (PIN46)
pin 2 (PIN2)
  • Why would PIN2 be multiplied?
  • Based on the addresses, there should be no PIN2.

When looking at the table, PIN2 is address 8:

And the values here are set to 0x08. So it seems as if there was an offset or some kind of intermix of the addresses and the assignments… what do you think?

Hi @RobertCNelson ,
Any further feedback on this one?

I started to think whether it would not be better to replace the am335x-bonegreen.dts with my custom ā€œbaseā€ dts with all the required definitions, but its not so easy to compile it with dtc, since there are dtsi includes.

I would appreciate your further feedback!

Why not use the appropriate dts, i.e. BBB, and just add your own dt include file that disables the lcd and enables and sets up any additional nodes you want?

Seems like a pretty simple .dtsi file compiled into your build via a very basic kernel recipe would do it.

/ {
ocp {
P8_38_pinmux { status = ā€œdisabledā€; }; /* P8_38: lcd_data9.uart2_rtsn */
P8_37_pinmux { status = ā€œdisabledā€; }; /* P8_37: lcd_data8.uart2_ctsn */
…
…
};
};

Hello and thank ypu for answer,
I began with the device tree overlay way, since I thought this is the preferred, ā€œcleanā€ approach. I then thought of replacing the base dts file, as I have suggested above. But then you have provided a 3rd approach- I would not thought of this one, as it would require me to modify an existing dts (i.e., am335x-bonegreen.dts or am335x-bonegreen.dts). Unless you had something different in mind that I have not grasped?

Seems like a pretty simple .dtsi file compiled into your build via a very basic kernel recipe would do it.

Yes so the thing is, I am still bad at Yocto, and I dont know how to do that yet. If you had any specific steps in mind and willing to show/ share them I would really appreciate that.

Eventually, I would like to add poky as a git submodule to my repo that would build the complete image for my custom device based on bbb or bbg. Right now I am a bit stuck on the device trees :expressionless: . This is the HW I am doing this for:

Can we clarify a couple things first?

  • Are you using Yocto to build your OS image? …if so, which version (i.e. Dunfell , Kirkstone, other)?
  • In the device tree, what are you wanting to dissable
  • In the device tree, what are you wanting to enable and configure (that isnt already in the BBB dt)?