BBB+snappy: customizing dtb/hardware

Paolo Pisati paolo.pisati at canonical.com
Tue Feb 10 17:54:21 UTC 2015


On Mon, Feb 09, 2015 at 01:46:50PM -0500, Winston Smith wrote:
> 
>    I'm hoping to get out of the business of custom image/kernel builds!A  So
>    I'm really hoping to switch to a non-custom kernel (and a more recent
>    one).A  The device tree overlay stuff is pretty nice, but I don't need to
>    load arbitrary DTBs, as Alex says I just need to create a custom DTB once.

so, today i sat down and i tried to convert a couple of dts fragments from the
3.8robnelson kernel to our 3.16 kernel, and here is writedown/brain dump in a
step by step guide:

grab the source code of the kernel we use on the snappy bbb image:

$ git clone git://kernel.ubuntu.com/ubuntu/ubuntu-utopic.git

get the .config:

$ make ARCH=arm omap2plus_defconfig

compile the starting dts:

$ make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf- am335x-boneblack.dtb
...
DTC     arch/arm/boot/dts/am335x-boneblack.dtb

mount the fist partition of the snappy sd card (e.g. $MNTPOINT),
make a backup of the original dtb, and copy this one over it:

$ cp $MNTPOINT/a/dtbs/am335x-boneblack.dtb $MNTPOINT/a/dtbs/am335x-boneblack.dtb.orig
$ cp arch/arm/boot/dts/am335x-boneblack.dtb a/dtbs/

and boot the board - if it boots fine, then the starting dts is good and we can move to the
hacking session.

Now, let's say this is the fragment you want to incorporate into your device tree:

https://github.com/beagleboard/devicetree-source/blob/master/arch/arm/boot/dts/BB-UART1-00A0.dts

here is the important part:

--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------

	fragment at 0 {
		target = <&am33xx_pinmux>;
		__overlay__ {
			bb_uart1_pins: pinmux_bb_uart1_pins {
				pinctrl-single,pins = <
					0x184 0x20 /* P9.24 uart1_txd.uart1_txd  OUTPUT  */
					0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd  INPUT  */
				>;
			};
		};
	};

	fragment at 1 {
		target = <&uart2>;	/* really uart1 */
		__overlay__ {
			status = "okay";
			pinctrl-names = "default";
			pinctrl-0 = <&bb_uart1_pins>;
		};
	};

--------8<--------8<--------8<--------8<--------8<--------8<--------8<--------

create a copy of the original dts:

$ cp arch/arm/boot/dts/am335x-boneblack.dts arch/arm/boot/dts/am335x-boneblack-uart1.dts

append this at the end of the dts:

$ diff -du arch/arm/boot/dts/am335x-boneblack.dts arch/arm/boot/dts/am335x-boneblack-uart1.dts                                        
--- arch/arm/boot/dts/am335x-boneblack.dts      2015-02-09 22:29:52.689254123 +0100
+++ arch/arm/boot/dts/am335x-boneblack-uart1.dts        2015-02-10 11:05:30.139739184 +0100
@@ -75,3 +75,18 @@
                status = "okay";
        };
 };
+
+&am33xx_pinmux {
+       bb_uart1_pins: pinmux_bb_uart1_pins {
+                               pinctrl-single,pins = <
+                                       0x184 0x20 /* P9.24 uart1_txd.uart1_txd OUTPUT  */
+                                       0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd INPUT  */
+                               >;
+                       };
+};
+
+&uart2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&bb_uart1_pins>;
+};

and compile the dtb:

$ make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf- am335x-boneblack-uart1.dtb
  DTC     arch/arm/boot/dts/am335x-boneblack-uart1.dtb
$

time to try our new dtb - copy it over the sdcard ($MNTPOINT/a/dtbs/am335x-boneblack.dtb)
and boot it:

...
ubuntu at localhost:~$ dmesg | grep ttyO
[    8.045373] 44e09000.serial: ttyO0 at MMIO 0x44e09000 (irq = 88, base_baud = 3000000) is a OMAP UART0
[    8.868541] console [ttyO0] enabled
[    8.878788] 48024000.serial: ttyO2 at MMIO 0x48024000 (irq = 90, base_baud = 3000000) is a OMAP UART2
...

with respect to the original 3.8 kernel plus dtb fragment, this one seems to
activate the wrong serial (ttyO2 at 0x48024000 vs ttyO1 at 48022000), and indeed there
was a suspicous comment in fragment at 1:

...
target = <&uart2>;	/* really uart1 */
...

seems like the serial ports were renumbered at same point.

In these cases, looking around the original dts it usually helps:

$ grep uart2 arch/arm/boot/dts/am33*.dts
arch/arm/boot/dts/am335x-boneblack-uart1.dts:&uart2 {

nothing interesting here, let's try with the #included .dtsi. files:

$ grep uart2 arch/arm/boot/dts/am33*.dtsi
arch/arm/boot/dts/am33xx.dtsi:          serial1 = &uart2;
arch/arm/boot/dts/am33xx.dtsi:          uart2: serial at 48022000 {
arch/arm/boot/dts/am33xx.dtsi:                  ti,hwmods = "uart2";

$ less arch/arm/boot/dts/am33xx.dtsi
...
serial1 = &uart2
...
uart2: serial at 48022000 {
	compatible = "ti,omap3-uart";
	ti,hwmods = "uart2";
	clock-frequency = <48000000>;
	reg = <0x48022000 0x2000>;
	interrupts = <73>;
	status = "disabled";
};
...

here it is, and let's see the same uart2 in our kernel now:

$ less arch/arm/boot/dts/am33xx.dtsi
...
uart2: serial at 48024000 {
	compatible = "ti,omap3-uart";
	ti,hwmods = "uart3";
	clock-frequency = <48000000>;
	reg = <0x48024000 0x2000>;
	interrupts = <74>;
	status = "disabled";
};
...

while uart1:

...
uart1: serial at 48022000 {
	compatible = "ti,omap3-uart";
	ti,hwmods = "uart2";
	clock-frequency = <48000000>;
	reg = <0x48022000 0x2000>;
	interrupts = <73>;
	status = "disabled";
};
...

right, so the dt fragment we are applying to our kernel should patch uart1
instead of uart2, so:

$ diff -du arch/arm/boot/dts/am335x-boneblack-uart2.dts arch/arm/boot/dts/am335x-boneblack-uart1.dts
--- arch/arm/boot/dts/am335x-boneblack-uart2.dts        2015-02-10 17:22:14.275430817 +0100
+++ arch/arm/boot/dts/am335x-boneblack-uart1.dts        2015-02-10 17:22:22.807430700 +0100
@@ -85,7 +85,7 @@
                        };
 };
 
-&uart2 {
+&uart1 {
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&bb_uart1_pins>;

compile again and copy on the sd card:

$ make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf- am335x-boneblack-uart1.dtb
  DTC     arch/arm/boot/dts/am335x-boneblack-uart1.dtb
$ cp arch/arm/boot/dts/am335x-boneblack-uart1.dtb $MNTPOINT/a/dtbs/am335x-boneblack.dtb

and boot the board:

[    8.046198] 44e09000.serial: ttyO0 at MMIO 0x44e09000 (irq = 88, base_baud = 3000000) is a OMAP UART0
[    8.869391] console [ttyO0] enabled
[    8.879648] 48022000.serial: ttyO1 at MMIO 0x48022000 (irq = 89, base_baud = 3000000) is a OMAP UART1

here we are, this time it looks good.

Here is another example with the rtc cape - in this case the pps part attaches,
while the rtc not - i'll leave it as an exercise for anyone with the rtc cape
who want to try it out, or i might pick it again when i have time:

https://github.com/jadonk/cape-firmware/blob/master/arch/arm/boot/dts/BB-BONE-RTC-00A0.dts

here is the important part of the dt fragment:

--------8<--------8<--------8<--------8<--------8<--------8<--------

fragment at 0 {
		target = <&am33xx_pinmux>;
		__overlay__ {
			pps_pins: pinmux_pps_pins {
				pinctrl-single,pins = <
					0x040	0x27	/* gpmc_a0.gpio1_16, INPUT | PULLDIS | MODE7 */
				>;
			};
		};
	};


	fragment at 1 {
		target = <&i2c2>;

		__overlay__ {
			/* shut up DTC warnings */
			#address-cells = <1>;
			#size-cells = <0>;

			/* DS1307 RTC module */
			rtc at 68 {
				compatible = "dallas,ds1307";
				reg = <0x68>;
			};
		};
	};

	fragment at 2 {
		target = <&ocp>;
		__overlay__ {
			pps {
				compatible = "pps-gpio";
				status = "okay";
				pinctrl-names = "default";
				pinctrl-0 = <&pps_pins>;

				gpios = <&gpio2 16 0>;
				assert-falling-edge;
			};
		};
	};

--------8<--------8<--------8<--------8<--------8<--------8<--------

create a copy of the original dts:

$ cp arch/arm/boot/dts/am335x-boneblack.dts arch/arm/boot/dts/am335x-boneblack-rtc.dts

and append this to the end of the dts:

diff -du arch/arm/boot/dts/am335x-boneblack.dts arch/arm/boot/dts/am335x-boneblack-rtc.dts
--- arch/arm/boot/dts/am335x-boneblack.dts      2015-02-09 22:29:52.689254123 +0100
+++ arch/arm/boot/dts/am335x-boneblack-rtc.dts  2015-02-10 09:35:49.419812588 +0100
@@ -75,3 +75,31 @@
                status = "okay";
        };
 };
+
+&am33xx_pinmux {
+       pps_pins: pinmux_pps_pins {
+                               pinctrl-single,pins = <
+                                       0x040   0x27    /* gpmc_a0.gpio1_16, INPUT | PULLDIS | MODE7 */
+                               >;
+                       };
+};
+
+&i2c2 {
+
+       /* DS1307 RTC module */
+       rtc at 68 {
+               compatible = "dallas,ds1307";
+               reg = <0x68>;
+       };
+};
+
+&ocp {
+       pps {
+               compatible = "pps-gpio";
+               status = "okay";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pps_pins>;
+               gpios = <&gpio2 16 0>;
+               assert-falling-edge;
+       };
+};

if you try to build the new dtb now, you will get an error:

$ make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf- am335x-boneblack-rtc.dtb
  DTC     arch/arm/boot/dts/am335x-boneblack-rtc.dtb
Error: arch/arm/boot/dts/am335x-boneblack-rtc.dts:108.2-3 label or path, 'ocp', not found

that's because in our modification we were referring to an 'ocp' label that wasn't declared yet,
so starting from am335x-boneblack-rtc.dts walk back the chain of included dts files and
look for an ocp node:

$ grep ocp arch/arm/boot/dts/am335x-boneblack.dts
$ grep "#include" arch/arm/boot/dts/am335x-boneblack.dts
#include "am33xx.dtsi"
#include "am335x-bone-common.dtsi" 
$ grep ocp arch/arm/boot/dts/am33xx.dtsi
        ocp {
$

ok, we found it, now let's add the label:

diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 4a4e02d..32d24c6 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -99,7 +99,7 @@
         * for the moment, just use a fake OCP bus entry to represent
         * the whole bus hierarchy.
         */
-       ocp {
+       ocp: ocp {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;

and recompile:

$ make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf- am335x-boneblack-rtc.dtb                                                  
  DTC     arch/arm/boot/dts/am335x-boneblack-rtc.dtb
$

That's it, i hope this writedown can help anyone who want to try and build a
custom dtb for the upstream/vanilla kernel.
-- 
bye,
p.



More information about the snappy-devel mailing list