Colibri T30 - Custom DTB (5 UART)

Hi,

after editing, compiling and testing a custom DTB with all 5 UARTs activated for Colibri VF61, I’m trying to achieve the same for the Colibri T30. I could only recompile the kernel from the Tegra branch and flash it in the T30. However, I’ve found several discrepancies that led me to open a new post:

  • I’ve downloaded the sources from Colibri and Tegra branches. The Colibri one worked fine with the VF61 (as expected) both the kernel and a new DTB compilation, as expected. Is as simple as setting the configuration (colibri_vf_defconfig) and creating a new dts with the desired options, and copy it to the BSP (Colibri_VF_LinuxImageV2.5), overwritting the original zImage and the dtb.
  • However, the Tegra sources and BSP (Colibri_T30_LinuxImageV2.6) seem to be completely different from the structure followed by the Colibri branch: dts folder is almost empty and the BSP seems to have no dtb.
  • Even though, following your tutorials, I’ve tried to create a new Tegra dts within the Colibri dts folder since there are several dts related to Tegra in that folder (!).
  • Knowing this I tried to compile the kernel with the tegra config (colibri_t30_defconfig) within the Colibri branch but make reported an error that it couldn’t find the config file (kind of expected).
  • I tried copying the config file from the Tegra branch in arch/arm/configs to the Colibri branch first: Both the configuration and the compilation afterwards worked flawlessly! Also, the DTC generated the DTB without any issues.
  • I could not generate uImage, only zImage (in both branches).
  • Finally, I’ve tried copying both the dtb and the zImage to both BSP. The Tegra worked fine but no changes in the UARTs, and the Colibri didn’t load all of the kernel.

Any ideas?

Thanks, Álvaro.

However, the Tegra sources and BSP (Colibri_T30_LinuxImageV2.6) seem to be completely different from the structure followed by the Colibri branch: dts folder is almost empty and the BSP seems to have no dtb.

The tegra Linux kernel is based on NVidia’s L4T 3.1.10 version. This version of the kernel does not use device trees. Pin multiplexing settings and such are done using board files using platform data approach.

Even though, following your tutorials, I’ve tried to create a new Tegra dts within the Colibri dts folder since there are several dts related to Tegra in that folder (!).

Tegra kernel does not use device trees as mentioned above.

Knowing this I tried to compile the kernel with the tegra config (colibri_t30_defconfig) within the Colibri branch but make reported an error that it couldn’t find the config file (kind of expected).

And are you using the correct tegra kernel branch as described here?

I could not generate uImage, only zImage (in both branches).

Did you specify uImage while building the kernel?. See here.

Finally, I’ve tried copying both the dtb and the zImage to both BSP. The Tegra worked fine but no changes in the UARTs, and the Colibri didn’t load all of the kernel.

Device trees are not to be used for T20 and T30. T30 requires uImage and not zImage. See here.

For pin multiplexing on T30, see the T30 board file and T30 pinmux file.

What exactly do you mean by Colibri branch? I doubt this one built for Colibri VF61.

But there would even be a colibri_t30_defconfig in the Colibri branch.

However note that the Colibri branch is no longer maintained and has been superseded by the Tegra branch. Just adhere to the following article really like @sanchayan.tx pointed out.

Don’t know what you mean by ‘both BSP’ in your last tick above.

BTW: Alternatively all our modules are also mainline and depending on your requirements you may also use that. The mainline device tree would be here and the configuration is here.

Ok, thanks a lot :slight_smile: With this, I’ve been able to play a bit with the GPIOs in order to use the same pins I’m using in the Colibri VFXX (SODIMM45, 133 and 135).

Looking with cat /sys/kernel/debug/gpio I could check that those belong to the same CONFIG node: CONFIG_KEYBOARD_GPIO. However I found that

{TEGRA_GPIO_PK6,	GPIOF_IN,	"SODIMM pin 135"},

is commented when

{TEGRA_GPIO_PT5,	GPIOF_IN,	"SOD-133, Iris X16-14"},
{TEGRA_GPIO_PV1,	GPIOF_IN,	"SODI-45, Iris X16-20"},

are not. Is there any reason for that discrepancy?

Did you specify uImage while building the kernel?

Yes, I did but the error was: “mkimage” command not found - U-Boot images will not be built.
I could solve it with sudo apt-get install u-boot-tools. After that, kernel compilation went flawlessly.

I’ll add another comment with any progress with the UARTs. Checking at the board-colibri_t30.c, I don’t see any reference about the other 2 UARTs. Do I need to create a new device, add it to the uart_parent_clk array (can I reuse another clk?) and to the init routine?

Concerning the discrepancy I really don’t remember but on the Tegras one should really be able to use any pin as a GPIO from user space unless the Linux kernel already locked it. Have a look at the following article as well.

As for the five UARTs I don’t think we ever really tried that but once pin muxing, clocking and initialisation is taken care of like with the other ones it could work I guess.

I’ve been able to initialize and show /dev/ttyHS4 (UARTE) in T30 by adding a couple of lines to the board-colibri_t30.c file:

In static struct platform_device *colibri_t30_uart_devices[] __initdata

&tegra_uarte_device,

static void __init colibri_t30_uart_init(void), right below the rest of the tegra_uartX_device…

tegra_uarte_device.dev.platform_data = &colibri_t30_uart_pdata; /ttyHS4

But when I use SODIMM pins 97 (UARTE_TX) and 79 (UARTE_RX) no data it received nor transmitted. It looks like the pin-mux is not done. And here is where I’m stuck.

In board-colibri_t30-pinmux.c and checking the definition of the other UART (A + 1-3), I’ve tried adding the following lines

DEFAULT_PINMUX(UART5_RXD, GMI, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(UART5_TXD, GMI, NORMAL, NORMAL, INPUT),  

and adding 2 new pingroups in pinmux-t3.h:

TEGRA_PINGROUP_UART5_TXD,
TEGRA_PINGROUP_UART5_RXD,

Also I tried commenting out

VI_PINMUX(VI_D4, VI, NORMAL, TRISTATE, INPUT, DISABLE, DISABLE), //SODIMM 79 (UART_E RX)
VI_PINMUX(VI_D5, VI, NORMAL, TRISTATE, INPUT, DISABLE, DISABLE), //SODIMM 97 (UART_E TX)

but without any change. Some last help with this issue? :’)

pinmux-t3.h file need not be touched. Taking a quick look, I believe below should be the required changes for enabling UART5/E.

diff --git a/arch/arm/mach-tegra/board-colibri_t30-pinmux.c b/arch/arm/mach-tegra/board-colibri_t30-pinmux.c
index 12dea99d0142..de3744200121 100644
--- a/arch/arm/mach-tegra/board-colibri_t30-pinmux.c
+++ b/arch/arm/mach-tegra/board-colibri_t30-pinmux.c
@@ -487,8 +487,8 @@ static __initdata struct tegra_pingroup_config colibri_t30_pinmux[] = {
        DEFAULT_PINMUX(SDMMC1_CMD, RSVD1, PULL_DOWN, NORMAL, INPUT),
        DEFAULT_PINMUX(SDMMC1_DAT0, RSVD1, PULL_DOWN, NORMAL, INPUT),
        DEFAULT_PINMUX(SDMMC1_DAT1, RSVD1, PULL_DOWN, NORMAL, INPUT),
-       DEFAULT_PINMUX(SDMMC1_DAT2, RSVD1, PULL_DOWN, NORMAL, INPUT),
-       DEFAULT_PINMUX(SDMMC1_DAT3, RSVD1, PULL_DOWN, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC1_DAT2, UARTE, PULL_DOWN, NORMAL, INPUT),
+       DEFAULT_PINMUX(SDMMC1_DAT3, UARTE, PULL_DOWN, NORMAL, INPUT),
 #endif
 
        DEFAULT_PINMUX(SDMMC3_CLK, PWM2, NORMAL, NORMAL, INPUT),
diff --git a/arch/arm/mach-tegra/board-colibri_t30.c b/arch/arm/mach-tegra/board-colibri_t30.c
index 83198a6375b8..745ca00a213c 100644
--- a/arch/arm/mach-tegra/board-colibri_t30.c
+++ b/arch/arm/mach-tegra/board-colibri_t30.c
@@ -1237,6 +1237,7 @@ static struct platform_device *colibri_t30_uart_devices[] __initdata = {
        &tegra_uarta_device, /* Colibri UART_A (formerly FFUART) */
        &tegra_uartd_device, /* Colibri UART_B (formerly BTUART) */
        &tegra_uartb_device, /* Colibri UART_C (formerly STDUART) */
+       &tegra_uarte_device,
 };
 
 static struct uart_clk_parent uart_parent_clk[] = {
@@ -1317,6 +1318,7 @@ static void __init colibri_t30_uart_init(void)
        tegra_uarta_device.dev.platform_data = &colibri_t30_uart_pdata;
        tegra_uartb_device.dev.platform_data = &colibri_t30_uart_pdata;
        tegra_uartd_device.dev.platform_data = &colibri_t30_uart_pdata;
+       tegra_uarte_device.dev.platform_data = &colibri_t30_uart_pdata;
 
        /* Register low speed only if it is selected */
        if (!is_tegra_debug_uartport_hs()) {

As can be seen from Sector 4.4 of Colibri T30 datasheet, UART5_TXD and UART5_RXD fall under SDMMC1_DAT3 and SDMMC1_DAT2 pingroups respectively. Looking at pingroup table and definition of DEFAULT_PINMUX, UARTE should be specified as second parameter as above. Note that I did not test this.

YES! I wouldn’t have guessed it in a thousand years. Just an appointment: the DEFAULT_PINMUX lines gave me an error while compiling. Changing it to UARTE (from UART5) did the trick!

PS: I’ve missed some documentation regarding these changes. While there is plenty for the VFXX and its dts editing, I have seen none of this board file editing, or any reference in the UART/GPIO documentation pages. Thankfully you were here, otherwise I would have been stuck ages.

Changing it to UARTE (from UART5) did the trick!

Yes, sorry for the typo. Glad to know it works now.