RFC: Add mode setting to bone-pinmux-helper

Request For Comment

Request For Comment

In order to make the cape-universal approach to modifying the BeagleBone
I/O setup at runtime via user-land (ie: no kernel driver and no
device-tree overlays or changesets), the bone-pinmux-helper driver needs
to be in control of the pinmux register for each I/O pin. It is not
currently possible, however, to (easily) set the default pinmux mode for
the bone-pinmux-helper.

Therefore, I have modified the bone-pinmux-helper code to support a
"mode" parameter in the device tree:

bone-pinmux-helper: Add support for "mode" device-tree parameter · cdsteinkuehler/linux@e0e0f1d · GitHub

I did a quick read through that made sense, though I don't know the
specific functions.

...which allows a device tree fragment to specify the startup default
mode of the pinmux from one of the available choices:

bone-pinmux-helper: Example usage of the mode= device tree parameter · cdsteinkuehler/dtb-rebuilder@b78226f · GitHub

...and a tweaked the config-pin utility supporting the new options:

Add support for modifying I2C bus pins P9.19 & P9.20 · cdsteinkuehler/beaglebone-universal-io@e742ff1 · GitHub

Approach looks good to me. I know the dropping of the pin assignment
in the i2c device tree itself will cause some heartache for some.

I don't see where you removed the definition of the i2c pin settings
themselves. Will not removing those entries cause headaches by someone
assuming they are used or is it comfortable for them to simply be
there by reference? I suspect it would only be an issue if a bug was
found in the setting and someone missed that the real mode was coming
from the helper.

This will allow any initial hardware pinmux configuration to be
overridden by user-space code at run-time, making it possible to switch
(for instance) the i2c2 cape EEPROM bus to standard GPIO pins as shown
in this example.

Woohoo! Hold on to your hats!

"Takeover" of the i2c2 bus is intended mainly as a proof-of-concept, the
real power of this approach is the ability to do things like enable SPI
or a UART in the boot-time device tree and have the pin muxing correct,
but be able to override the pinmux settings once the system is booted
(perhaps turning an unused RxD line into a useful PWM or similar). This
also makes it possible to modify the pinmux hardware configuration as
soon as sysfs is available (ie: very early in the system boot stage).
Who wants to write the user-mode version of cape-manager?!?

It seems to me that the existing kernel module should be extended.
Extending config-pin to read cape EEPROMs and have a database of pin
settings is fine and I can understanding you wanting to find an owner
for that task, but if looking for a real replacement of cape-manager
(by that name) then real overlays still need to be
understood/supported as you still can't quite do all the
experimenting/fpga-ing you'd desire without being able to reconfigure
the rest of the device tree at runtime.

Jason Kridner <jkridner-hcmAuCOw+vXj4SYmN/TMmA@public.gmane.org> writes:

Add support for modifying I2C bus pins P9.19 & P9.20 · cdsteinkuehler/beaglebone-universal-io@e742ff1 · GitHub

Approach looks good to me. I know the dropping of the pin assignment
in the i2c device tree itself will cause some heartache for some.

I don't see where you removed the definition of the i2c pin settings
themselves. Will not removing those entries cause headaches by someone
assuming they are used or is it comfortable for them to simply be
there by reference? I suspect it would only be an issue if a bug was
found in the setting and someone missed that the real mode was coming
from the helper.

I've been trying to follow along with these changes and I admit, I
haven't been able to keep up.

Some questions:

1. My Cape DTS does not explicitly call out for i2c2 [1], with this
change does that, and all capes using i2c2, need to be fixed?

2. Is the default mode of pins P_19/20, once user space is reached, GPIO
or i2c2?

Josh

[1] linux-stable-rcn-ee/arch/arm/boot/dts/am335x-bone-crypto-00a0.dtsi at 29723a20cdfe75e81e964739284643ab32a38231 · RobertCNelson/linux-stable-rcn-ee · GitHub

Approach looks good to me. I know the dropping of the pin assignment
in the i2c device tree itself will cause some heartache for some.

Yes, but there's no other way to do this, AFAIK. I would suggest
migrating the mode= settings and the device stanza into it's own include
file. I tried more to make the minimal possible changes vs.
restructuring the whole device-tree layout (ie: I didn't want to try and
factor out the i2c2 device into it's own dtsi file).

I don't see where you removed the definition of the i2c pin settings
themselves. Will not removing those entries cause headaches by someone
assuming they are used or is it comfortable for them to simply be
there by reference? I suspect it would only be an issue if a bug was
found in the setting and someone missed that the real mode was coming
from the helper.

I didn't remove them, and they might still be useful. It possible to
switch between the "old style" of pinmux control for devices and the
pinmux helper version, possibly even by using different dtsi include
files. At this point I am not trying to advocate any particular device
tree layout (in terms of what goes into which include files), I'm simply
making the feature available.

If the modified pinmux helper is a sensible approach, we can start
talking about exactly what the device tree files should look like.

I've been trying to follow along with these changes and I admit, I
haven't been able to keep up.

Some questions:

1. My Cape DTS does not explicitly call out for i2c2 [1], with this
change does that, and all capes using i2c2, need to be fixed?

The i2c2 is typically defined by the base BeagleBone device tree (or
more specifically, am335x-bone-common-pinmux.dtsi in Robert's latest
device trees for 3.14). The cape dtsi files (or overly files for 3.8)
generally only include things that need to be changed to support the
cape, so unless you were intentionally trying to modify the i2c2
hardware, you wouldn't reference it in you cape file.

Your cape file simply adds some target entries for the i2c2 bus, which
would work as expected and need no changes regardless of whether the
i2c2 pinmux is handled directly or by using the bone-pinmux-helper (the
device tree compiler will merge the main i2c2 definitions with your
additions). By way of similar example, you're also not specifying the
base address of the i2c2 hardware, the interrupt(s) it uses, etc, but
that all works since it's pulled in from common dts files before your
cape file is included.

2. Is the default mode of pins P_19/20, once user space is reached, GPIO
or i2c2?

The purpose of this change is to allow the pinmux-helper to be in
control of the pin, but have it come up in the desired mode (i2c in this
case) instead of the default gpio mode, which is what would have
happened previously.

I've been trying to follow along with these changes and I admit, I
haven't been able to keep up.

Some questions:

1. My Cape DTS does not explicitly call out for i2c2 [1], with this
change does that, and all capes using i2c2, need to be fixed?

The i2c2 is typically defined by the base BeagleBone device tree (or
more specifically, am335x-bone-common-pinmux.dtsi in Robert's latest
device trees for 3.14). The cape dtsi files (or overly files for 3.8)
generally only include things that need to be changed to support the
cape, so unless you were intentionally trying to modify the i2c2
hardware, you wouldn't reference it in you cape file.

Your cape file simply adds some target entries for the i2c2 bus, which
would work as expected and need no changes regardless of whether the
i2c2 pinmux is handled directly or by using the bone-pinmux-helper (the
device tree compiler will merge the main i2c2 definitions with your
additions). By way of similar example, you're also not specifying the
base address of the i2c2 hardware, the interrupt(s) it uses, etc, but
that all works since it's pulled in from common dts files before your
cape file is included.

2. Is the default mode of pins P_19/20, once user space is reached, GPIO
or i2c2?

The purpose of this change is to allow the pinmux-helper to be in
control of the pin, but have it come up in the desired mode (i2c in this
case) instead of the default gpio mode, which is what would have
happened previously.

Just going along to state the obvious...

eMMC and HDMI will be equally interesting tests and more practically
useful for more capes.

It will only be a matter of time before someone damages a board by:
A) setting an HDMI pin to a output without disabling the HDMI
B) driving an eMMC pin into conflict without putting the eMMC in reset

I don't think there is a simple way for the current pinmux helper to
check for these conditions, but it wouldn't hurt if any config-pin
sort of utility would check the state of those hardware control bits
before helping someone screw things up. :slight_smile:

Any way you can imagine a way to keep the current uEnv.txt lines to
disable both of those working without breaking compatibility?

Maybe somewhat off topic, however I cannot help but to ask this;

“How can we disable HDMI in kernel version >= 3.14?” where we do not
have capemgr?

Load a different device tree. There's probably an easier way (there are
several available device trees already installed), but I would:

cd /opt/source/dtb-3.14-ti
vi src/arm/am335x-boneblack.dts

<comment line 62, which loads "am335x-boneblack-nxp-hdmi-audio.dtsi">

make
sudo make install
sudo reboot

Just going along to state the obvious...

eMMC and HDMI will be equally interesting tests and more practically
useful for more capes.

I'll try and work up a patch set for HDMI, but it won't be until tomorrow.

It will only be a matter of time before someone damages a board by:
A) setting an HDMI pin to a output without disabling the HDMI

The worst that can happen with HDMI is a bus fight (driving an HDMI pin
without first configuring the BBB side as an input). The HDMI framer
does not drive any signals back to the AM335x (other than I2C), so it
won't cause problems. If you start playing with pinmux values you could
easily see wonky video, but that's not a "break the hardware" kind of
problem.

B) driving an eMMC pin into conflict without putting the eMMC in reset

This is much more likely, and while it might not be easy to destroy the
hardware, it is probably pretty easy to corrupt the eMMC. It might be
worth requiring loading an alternate device-tree to disable the eMMC,
which can make sure it stays in reset.

I don't think there is a simple way for the current pinmux helper to
check for these conditions, but it wouldn't hurt if any config-pin
sort of utility would check the state of those hardware control bits
before helping someone screw things up. :slight_smile:

Agreed!

Any way you can imagine a way to keep the current uEnv.txt lines to
disable both of those working without breaking compatibility?

Maybe, there's some groundwork to do first. For instance I still don't
know what happens if you leave the HDMI enabled, but take all the pins
out from under it via the pinmux. I'll keep this in mind and see what I
can come up with...

Thank you. I’ve just changed state of hdmi in /boot/dtbs/am335x-boneblack.dtb as disabled, however,
which might not be a correct way of disabling HDMI, so I asked.

Just going along to state the obvious...

eMMC and HDMI will be equally interesting tests and more practically
useful for more capes.

I'll try and work up a patch set for HDMI, but it won't be until tomorrow.

It will only be a matter of time before someone damages a board by:
A) setting an HDMI pin to a output without disabling the HDMI

The worst that can happen with HDMI is a bus fight (driving an HDMI pin
without first configuring the BBB side as an input). The HDMI framer
does not drive any signals back to the AM335x (other than I2C), so it
won't cause problems. If you start playing with pinmux values you could
easily see wonky video, but that's not a "break the hardware" kind of
problem.

Yeah, brainfart. Agreed, no potential damaging hardware issues.
Anything like an LCD add-on board would just have inputs on those
signals as well.

B) driving an eMMC pin into conflict without putting the eMMC in reset

This is much more likely, and while it might not be easy to destroy the
hardware, it is probably pretty easy to corrupt the eMMC. It might be
worth requiring loading an alternate device-tree to disable the eMMC,
which can make sure it stays in reset.

Getting all of those HDMI pins back for GPIO when not using HDMI w/o
needing to do anything special on boot should make a lot of people
happy, even if the eMMC pins aren't available.

Nice work, i like this! I'll cherry-pick it tomorrow and also start
the conversion ttOx/i2c/spi..

Regards,

Hi Josh,

I'm going to make sure we do it both ways. The default
"am335x-boneblack.dtb" (<device.dtb>) will have every peripheral
enabled and it'll be up to Charles's userspace tool (and a cape
database file that we need to write, (it'll probably be bone-script))
to correctly setup the pinmux's for your cape.

But i'll also have a backup: <device>-<cape>.dtb, that'll just be the
minimal needed for your cape. Which the end user could enable "other"
stuff just like in this base dts:

https://github.com/RobertCNelson/dtb-rebuilder/blob/3.14-ti/src/arm/am335x-bone-crypto-00a0.dts

One of the big unknowns i have... How will the "fat"
am335x-boneblack.dtb compare with a <device>-<cape>.dtb power wise.
Switching i2c/spi/usart/gpio worked well with the 3.8 cape-universal.
The big one is getting the hdmi/drm stack to seamlessly work with this
setup.

Regards,

Is there any chance working HDMI support can be compiled as a loadable
module? When I was experimenting with trying to get sgx support
working, it seemed like there were circular dependencies that prevented
this.

Sure, we can move those to modules:

I'll set them up exactly like ti has them by default in 3.14. :wink:

CONFIG_BACKLIGHT_PWM=m
CONFIG_DRM=m
CONFIG_DRM_KMS_HELPER=m
CONFIG_DRM_KMS_FB_HELPER=y
CONFIG_DRM_GEM_CMA_HELPER=y
CONFIG_DRM_KMS_CMA_HELPER=y
CONFIG_DRM_I2C_NXP_TDA998X=m
CONFIG_DRM_TILCDC=m

Regards,

Great!

That should fix any potential issues with disabling HDMI at runtime
(assuming the module can actually be unloaded). As for getting the HDMI
display running at power-on, there will likely be a delay (even if
loaded via an initial ramdisk), but I don't think total time to "usable
GUI" should be affected (famous last words!).

this is cool :wink: (but i forgot my capes, so i'll tag and push out..)

[ 2.600874] bone-pinmux-helper P9_11_pinmux.18: Set initial pinmux
mode to uart
[ 2.601710] bone-pinmux-helper P9_13_pinmux.20: Set initial pinmux
mode to uart
[ 2.605222] bone-pinmux-helper P9_21_pinmux.26: Set initial pinmux
mode to uart
[ 2.606014] bone-pinmux-helper P9_22_pinmux.27: Set initial pinmux
mode to uart
[ 2.607362] bone-pinmux-helper P9_24_pinmux.29: Set initial pinmux
mode to uart
[ 2.608211] bone-pinmux-helper P9_26_pinmux.30: Set initial pinmux
mode to uart
debian@beaglebone:~$ dmesg | grep serial
[ 2.555652] omap_uart 44e09000.serial: no wakeirq for uart0
[ 2.556486] 44e09000.serial: ttyO0 at MMIO 0x44e09000 (irq = 88,
base_baud = 3000000) is a OMAP UART0
[ 2.558932] omap_uart 48022000.serial: no wakeirq for uart0
[ 2.559252] 48022000.serial: ttyO1 at MMIO 0x48022000 (irq = 89,
base_baud = 3000000) is a OMAP UART1
[ 2.560216] omap_uart 48024000.serial: no wakeirq for uart0
[ 2.560482] 48024000.serial: ttyO2 at MMIO 0x48024000 (irq = 90,
base_baud = 3000000) is a OMAP UART2
[ 2.561469] omap_uart 481a8000.serial: no wakeirq for uart0
[ 2.561729] 481a8000.serial: ttyO4 at MMIO 0x481a8000 (irq = 61,
base_baud = 3000000) is a OMAP UART4
[ 2.562640] omap_uart 481aa000.serial: no wakeirq for uart0
[ 2.562890] 481aa000.serial: ttyO5 at MMIO 0x481aa000 (irq = 62,
base_baud = 3000000) is a OMAP UART5

Regards,