Skip to content

Device Tree on ARCH_BCM2708

notro edited this page Jul 30, 2014 · 3 revisions

This page details the work getting Device Tree support on ARCH_BCM2708 (used in the official RPi kernel).
The work is done in parallel with the Upstreaming (ARCH_BCM2835) effort.
Moving to ARCH_BCM2835 can take some time, so this aims at giving Device Tree support sooner.

Status

Core Device Tree support is added.
Devices that can be added: Platform, SPI and I2C

Drivers

These drivers are needed to give full Device Tree support for the end user

ARCH_BCM2708 ARCH_BCM2835 Status
bcm2708_gpio pinctrl-bcm2835 pinctrl-bcm2708 is added
spi-bcm2708 spi-bcm2835 OK
i2c-bcm2708 i2c-bcm2835 OK

Other drivers

ARCH_BCM2708 ARCH_BCM2835 Status
bcm2708_wdog bcm2835_wdt
bcm2708-rng bcm2835-rng
bcm2708-i2s bcm2835-i2s

Install and use a Device Tree enabled kernel

Install kernel

sudo REPO_URI=https://github.com/notro/rpi-firmware BRANCH=dt rpi-update
[...]
 *** Running post-install script
     /lib/firmware
     Backup /boot/config.txt -> /boot/config.txt.2014-07-30--15-43-04
     Adding Device Tree options to /boot/config.txt

     Remember to restore/edit /boot/config.txt when installing a non-DT kernel

[...]

Device Tree Compiler

Build dtc from source to get the ability to add properties to the dtb

sudo apt-get install flex bison
git clone http://git.jdl.com/software/dtc.git
cd dtc
make

# make install, puts the files in ~/, instead we do:
sudo cp -v libfdt/libfdt*.so /usr/lib/
sudo cp -v dtc fdtdump fdtget fdtput /usr/bin/

dtc -v
Version: DTC 1.4.0

Note: The debian pakage is too old:

sudo apt-get install device-tree-compiler
Setting up device-tree-compiler (1.3.0-4) ...

sudo fdtput -t s /boot/bcm2708-rpi-b.dtb /display status "disabled"
Error at 'status': FDT_ERR_NOSPACE

'status' property

The status property determines whether the device is enabled or not.
Absent property, "okay" or "ok" value, means the device is enabled. Any other value means disabled.
Ref: http://lxr.free-electrons.com/ident?a=arm;i=__of_device_is_available

dtb source files

These files are used to build the bcm2708-rpi-b.dtb file

SPI

Enable SPI (also remove module blacklisting if on Raspian)

$ fdtget /boot/bcm2708-rpi-b.dtb /soc/spi@7e204000 status
disabled
$ sudo fdtput --type s /boot/bcm2708-rpi-b.dtb /soc/spi@7e204000 status "okay"
$ sudo reboot

Use the spi-bcm2835 driver

$ fdtget /boot/bcm2708-rpi-b.dtb /soc/spi@7e204000 compatible
brcm,bcm2708-spi
$ sudo fdtput --type s /boot/bcm2708-rpi-b.dtb /soc/spi@7e204000 compatible "brcm,bcm2835-spi"
$ fdtget /boot/bcm2708-rpi-b.dtb /soc/spi@7e204000 compatible
brcm,bcm2835-spi
$ sudo reboot

Example adding a ADS7846 touch controller device

Note: This kernel doesn't have the ads7846 module. I have previously used this for testing in another kernel.

Get a device tree source representation

dtc -I dtb /boot/bcm2708-rpi-b.dtb > bcm2708-rpi-b.dts

Edit bcm2708-rpi-b.dts (also remove or disable spidev@1)

Add a label to the gpio node, so we can reference it

		gpio: gpio {

Add node

		spi@7e204000 {

			tsc2046@1 {
				compatible = "ti,tsc2046";
				reg = <1>;	/* CE1 */
				interrupts = <3 17>;	/* bank 3 is GPIO interrupts */
				spi-max-frequency = <2000000>;
				pendown-gpio = <&gpio 17 0>;
		
				ti,x-min = /bits/ 16 <230>;
				ti,x-max = /bits/ 16 <3850>;
				ti,y-min = /bits/ 16 <190>;
				ti,y-max = /bits/ 16 <3850>;
				ti,x-plate-ohms = /bits/ 16 <60>;
				ti,pressure-max = /bits/ 16 <255>;
		
				linux,wakeup;
				status = "okay";
			};

		};

Compile dts

dtc -I dts -O dtb -o bcm2708-rpi-b.dtb bcm2708-rpi-b.dts

Use it

sudo cp /boot/bcm2708-rpi-b.dtb /boot/bcm2708-rpi-b.dtb.backup
sudo cp bcm2708-rpi-b.dtb /boot/bcm2708-rpi-b.dtb
sudo reboot

Verify that the device is present

$ ls -l /proc/device-tree/soc/spi@7e204000/tsc2046@1/
total 0
-r--r--r-- 1 root root 11 Jul 30 16:20 compatible
-r--r--r-- 1 root root  8 Jul 30 16:20 interrupts
-r--r--r-- 1 root root  0 Jul 30 16:20 linux,wakeup
-r--r--r-- 1 root root  8 Jul 30 16:20 name
-r--r--r-- 1 root root 12 Jul 30 16:20 pendown-gpio
-r--r--r-- 1 root root  4 Jul 30 16:20 reg
-r--r--r-- 1 root root  4 Jul 30 16:20 spi-max-frequency
-r--r--r-- 1 root root  5 Jul 30 16:20 status
-r--r--r-- 1 root root  2 Jul 30 16:20 ti,pressure-max
-r--r--r-- 1 root root  2 Jul 30 16:20 ti,x-max
-r--r--r-- 1 root root  2 Jul 30 16:20 ti,x-min
-r--r--r-- 1 root root  2 Jul 30 16:20 ti,x-plate-ohms
-r--r--r-- 1 root root  2 Jul 30 16:20 ti,y-max
-r--r--r-- 1 root root  2 Jul 30 16:20 ti,y-min

$ cat /sys/devices/soc.0/20204000.spi/spi_master/spi0/spi0.1/modalias
spi:tsc2046

I2C

Enable i2c-1 (also remove module blacklisting if on Raspian)

$ fdtget /boot/bcm2708-rpi-b.dtb /soc/i2c@7e804000 status
disabled
$ sudo fdtput --type s /boot/bcm2708-rpi-b.dtb /soc/i2c@7e804000 status "okay"
$ sudo reboot
$ dmesg
[    6.613730] bcm2708_i2c_init_pinmode(1,2)
[    6.811634] bcm2708_i2c_init_pinmode(1,3)
[    6.964823] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
[    8.090310] pcm512x 1-004c: Failed to reset device: -5
[    8.107153] pcm512x: probe of 1-004c failed with error -5

Use the i2c-bcm2835 driver

$ fdtget /boot/bcm2708-rpi-b.dtb /soc/i2c@7e804000 compatible
brcm,bcm2708-i2c
$ sudo fdtput --type s /boot/bcm2708-rpi-b.dtb /soc/i2c@7e804000 compatible "brcm,bcm2835-i2c"
$ fdtget /boot/bcm2708-rpi-b.dtb /soc/i2c@7e804000 compatible
brcm,bcm2835-i2c
$ sudo reboot
$ dmesg
[    8.020037] i2c-bcm2835 20804000.i2c: i2c transfer failed: 100
[    8.028457] pcm512x 1-004c: Failed to reset device: -121
[    8.036192] pcm512x: probe of 1-004c failed with error -121
$ ls -l /dev/i2c*
crw-rw---T 1 root i2c 89, 1 Jul 28 20:47 /dev/i2c-1

The transfer error is related to the failed pcm512x probing.

DS1307 RTC chip

Add to dts

		i2c@7e804000 {

			rtc@68 {
				compatible = "dallas,ds1307";
				reg = <0x68>;
			};

		};

Verify

$ dmesg
[    6.895287] rtc-ds1307 1-0068: rtc core: registered ds1307 as rtc0
[    6.903734] rtc-ds1307 1-0068: 56 bytes nvram
[    7.242081] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
$ sudo hwclock -r
Mon 28 Jul 2014 20:26:15 UTC  -0.905546 seconds

Dynamic debug

This kernel has DYNAMIC_DEBUG enabled.

https://www.kernel.org/doc/Documentation/dynamic-debug-howto.txt

sudo mount -t debugfs none /sys/kernel/debug/
sudo chmod 777 /sys/kernel/debug/

grep pinctrl /sys/kernel/debug/dynamic_debug/control
...

Adding this to /boot/cmdline.txt, gives some Device Tree related debug output:

debug dyndbg="module pinctrl_bcm2708 +p; file drivers/gpio/gpiolib.c +p; file drivers/of/platform.c +p; file kernel/irq/irqdomain.c +p; file kernel/irq/manage.c +p; file kernel/resource.c +p;" 

Build a Device Tree enabled kernel

How to build: http://elinux.org/RPi_Kernel_Compilation

Kernel config

Enable Device Tree

ARCH=arm make bcmrpi_defconfig
ARCH=arm make menuconfig
# System Type  --->  Broadcom BCM2708 Implementations  --->  [*]   BCM2708 Device Tree support

The quick way including debug option

ARCH=arm make bcmrpi_defconfig
scripts/config --enable BCM2708_DT
# Device Tree contents in /proc/device-tree/
scripts/config --enable PROC_DEVICETREE
yes "" | ARCH=arm make oldconfig

Bootloader setup

Add to /boot/config.txt

device_tree=bcm2708-rpi-b.dtb
device_tree_address=0x100
kernel_address=0x8000
disable_commandline_tags=2

Pull Request history

Abbreviations

  • DT - Device Tree
  • FDT - Flattended Device Tree: a DT representation used in the dtb blob.
  • .dtb - Device Tree Binary
  • .dts - Device Tree Source
  • .dtsi - Device Tree Source Include
  • dtc - Device Tree Compiler