Converting Device tree overlays to Kernel 3.12 on BeagleBone Black

device-tree-3.12
Most distributions for Beaglebone comes with the 3.8 version of the Linux Kernel, but since the BB is still quite young there is a lot of development going on and there are some advantages to upgrading to a newer kernel, for instance due to the SGX support. However, there has been a few changes to the device tree of the BB, so device tree overlays created for 3.8 kernel might not be compatible with the new kernel. Luckily it's not that much work updating the device tree overlays.

Looking at the diff of the am33xx.dtsi files going from 3.8 to 3.12 there seems to be lot of differences.

* The GPIO banks have changed index and now goes from 0-3 instead of 1-4. The bank number now match the BB SRM.

* The uart ports now goes from 0-6 matching the alias "serial"

* pruss is no longer a node in the 3.12 tree. (Needs to be enabled with patches)

The most prominent error that arises when trying to use a device tree overlay made for a 3.8 kernel on a 3.8 kernel is the error:

of_resolve: Could not find symbol 'ocp'

Funfact for the masochistic: OCP stands for On Chip Peripheral and indicates that the IP (Intellectual Property) core is a part of the SoC (System on Chip).

So to fix this error just attach the overlays to a different node by changing the symbol to something like "baseboard_beaglebone_black". If you want to use different symbol look in the dump from "fdtdump /boot/am335x-boneblack.dtb" to get an overview of the existing symbols.

The patches necessary for enabling PRUSS on 3.12 are here: https://github.com/eliasbakken/kernel/tree/3.12 and a pull request has been sent to the main Beagleboard/kernel repository.

Below is the device tree overlay for Replicape for kernel version 3.12.

/dts-v1/;
/plugin/;

/ {
    compatible = "ti,beaglebone", "ti,beaglebone-black";

    /* identification */
    part-number = "BB-BONE-REPLICAP";
    version = "0A4A";

    /* state the resources this cape uses */
    exclusive-use =
        /* the pin header P8 uses */
        "P8.8",  /* FAULT_EXT_2	*/
        "P8.9",  /* FAULT_Y 	*/
        "P8.10", /* FAULT_X 	*/
        "P8.11", /* STEP_EXT_2	*/
        "P8.12", /* STEP_Y      */
        "P8.13", /* STEP_Z      */
        "P8.14", /* DIR_Z       */
        "P8.15", /* DIR_EXT_1 	*/
        "P8.16", /* DIR_EXT_2 	*/
        "P8.17", /* STEP_X      */
        "P8.18", /* FAULT_EXT_1	*/
        "P8.19", /* DIR_Y       */
        "P8.26", /* DIR_X       */
        /* the pin header P9 uses */
        "P9.11", /* END_STOP_X2	*/
        "P9.12", /* STEP_EXT_1	*/
        "P9.13", /* END_STOP_Z1	*/
        "P9.16", /* END_STOP_Y2 */
        "P9.18", /* END_STOP_Z2	*/
        "P9.22", /* Dallas 1W   */
        "P9.23", /* END_STOP_Y1 */
        "P9.24", /* FAULT_Z     */
        "P9.25", /* END_STOP_X1	*/
        "P9.28", /* SPI1_CS0 	*/
        "P9.29", /* SPI1_MISO   */
        "P9.30", /* SPI1_MOSI	*/
        "P9.31", /* SPI1_SCLK	*/
        "P9.33", /* AIN4        */
        "P9.35", /* AIN6        */
        "P9.36", /* AIN5        */
        "P9.42"; /* SPI1_CS1	*/

    fragment@0 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            bone_replicape_spi1_pins: pinmux_replicape_spi1_pins {
                pinctrl-single,pins = <                     0x190 0x13	/* P9_31 = mcasp0_aclkx.spi1_sclk				 , OUTPUT_PULLUP | MODE3 */                     0x194 0x33	/* P9_29 = mcasp0_fsx.spi1_d0					 , INPUT_PULLUP  | MODE3 */                     0x198 0x13	/* P9_30 = mcasp0_axr0.spi1_d1					 , OUTPUT_PULLUP | MODE3 */                     0x19c 0x13	/* P9_28 = mcasp0_ahclkr.spi1_cs0				 , OUTPUT_PULLUP | MODE3 */					                     0x164 0x12  /* P9_42 = GPIO0_7 =  eCAP0_in_PWM0_out.gpio0[7] , OUTPUT_PULLUP | MODE2 */                 >;
            };					
            pruicss_stepper_pins: pinmux_pruicss_stepper_pins{
                pinctrl-single,pins = <                     0x038 0x07 // P8_16 (3)  = DIR_EXT_2	= GPIO1_14                     0x03C 0x07 // P8_15 (4)  = DIR_EXT_1	= GPIO1_15                     0x028 0x07 // P8_14 (5)  = DIR_Z   	 	= GPIO0_26                     0x02C 0x07 // P8_17 (6)  = STEP_X 	 	= GPIO0_27                  	0x034 0x07 // P8_11 (22) = step_ext_2 	= GPIO1_13	                     0x030 0x07 // P8_12 (23) = Step_y	 	= GPIO1_12                     0x024 0x07 // P8_13 (24) = Step_z	 	= GPIO0_23                     0x020 0x07 // P8_19 (25) = Dir_y 	 	= GPIO0_22                     0x07C 0x07 // P8_26 	 = Dir_x		= GPIO1_29                     0x078 0x07 // P9_12 	 = step ext 1 	= GPIO1_28                 >;
            };		

            stepper_fault_pins: pinmux_stepper_fault_pins{
                pinctrl-single,pins = <                     0x094 0x37 // P8_8  = Fault Ext 2 	= GPIO2_3    gpmc_oen_ren.gpio2[3]                       0x09C 0x37 // P8_9  = FAYLT Y		= GPIO2_5                     0x098 0x37 // P8_10 = FAULT X     	= GPIO2_4    gpmc_wen.gpio2[4]                           0x08C 0x37 // P8_18 = Fault_ext 1	= GPIO2_1                     0x184 0x37 // P9_24 = Fault Z		= GPIO0_15                 >;
            };

            end_stop_pins: pinmux_end_stop_pins{
                pinctrl-single,pins = <                     0x1AC 0x37 // P9_25 = End stop X1  = GPIO3_21                     0x070 0x37 // P9_11 = End stop X2  = GPIO0_30                     0x044 0x37 // P9_23 = End stop Y1  = GPIO1_17                     0x04C 0x37 // P9_16 = End stop Y2  = GPIO1_19                     0x074 0x37 // P9_13 = End stop Z1  = GPIO0_31                     0x158 0x37 // P9_18 = End stop Z2  = GPIO0_4                 >;
            };
            dallas_w1_pins: pinmux_dallas_w1_pins {
                pinctrl-single,pins = < 		            0x150 0x37	// Dallas 1W                 >;
            };
        };
    };

    fragment@1 {
        target = <&spi1>;
        __overlay__ {
            #address-cells 	= ;
            #size-cells 	= ;
            status			= "okay";
            pinctrl-names	= "default";
            pinctrl-0		= <&bone_replicape_spi1_pins>;	
            cs-gpios 		= <&gpio3 17 0>, <&gpio0 7 0>;

            stepper_control{
                #address-cells 	  = ;
                #size-cells 	  = ;
                compatible 		  = "spidev";
                reg 			  = ;
                spi-max-frequency = ;
                spi-cpha;		  // Stepper control has mode 1 (CPOL = 0, CPHA = 1)
            };

            stepper_current{
                #address-cells 	  = ;
                #size-cells 	  = ;
                compatible 		  = "spidev";
                reg 			  = ;
                spi-max-frequency = ;
                   				  // Stepper current has mode 0 (CPOL = 0, CPHA = 0)
            };
        };
    };

    fragment@2{
        target = <&pruss>;
        __overlay__{
            status = "okay";
            pinctrl-names = "default";
            pinctrl-0 	  = <&pruicss_stepper_pins>;

            stepper_x{
                pin-names 	= "Replic:pru-step_x", "Replic:pru-dir_x";		
                gpios 		= <&gpio0 27 0 		                 	   &gpio1 29 0>; 
            };			
            stepper_y{
                pin-names 	= "Replic:pru-step_y", "Replic:pru-dir_y";		
                gpios 		=<&gpio1 12 0 		                 	  &gpio0 22 0>; 
            };
            stepper_z{
                pin-names 	= "Replic:pru-step_z", "Replic:pru-dir_z";		
                gpios 		= <&gpio0 23 0 		                 	   &gpio0 26 0>; 
            };
            stepper_ext_1{
                pin-names 	= "Replic:pru-step_ext_1", "Replic:pru-dir_ext_1";		
                gpios 		= <&gpio1 28 0 		                 	   &gpio1 15 0>; 
            };
            stepper_ext_2{
                pin-names 	= "Replic:pru-step_ext_2", "Replic:pru-dir_ext_2";		
                gpios 		= <&gpio1 13 0 		                 	   &gpio1 14 0>; 
            };
        };
    };

    fragment@3 {
        target = <&baseboard_beaglebone_black>;
        __overlay__ {			
            #address-cells = ;
            #size-cells = ;							

            gpio_keys {
                compatible = "gpio-keys";
                pinctrl-names = "default";
                pinctrl-0 = <&end_stop_pins>;
                pinctrl-1 = <&stepper_fault_pins>;
                #address-cells = ;
                #size-cells = ;

                switch_x1 {
                    label               = "Replic:End-stop-X1";
                    debounce_interval   = ;
                    linux,code          = ;
                    gpios               = <&gpio3 21 0x5>;
                    gpio-key,wakeup;
                };				
                switch_x2 {
                    label               = "Replic:End-stop-X2";
                    debounce_interval   = ;
                    linux,code          = ;
                    gpios               = <&gpio0 30 0x5>;
                    gpio-key,wakeup;
                };
                switch_y1 {
                    label               = "Replic:End-stop-Y1";
                    debounce_interval   = ;
                    linux,code          = ;
                    gpios               = <&gpio1 17 0x5>;
                    gpio-key,wakeup;
                };				
                switch_y2 {
                    label               = "Replic:End-stop-Y2";
                    debounce_interval   = ;
                    linux,code          = ;
                    gpios               = <&gpio1 19 0x5>;
                    gpio-key,wakeup;
                };				
                switch_z1 {
                    label               = "Replic:End-stop-Z1";
                    debounce_interval   = ;
                    linux,code          = ;
                    gpios               = <&gpio0 31 0x5>;
                    gpio-key,wakeup;
                };				
                switch_z2 {
                    label               = "Replic:End-stop-Z2";
                    debounce_interval   = ;
                    linux,code          = ;
                    gpios               = <&gpio0 4 0x5>;
                    gpio-key,wakeup;
                };				
                fault_x {
                    label               = "Replic:Fault-X";
                    debounce_interval   = ;
                    linux,code          = ;
                    gpios               = <&gpio2 4 0x5>;
                    gpio-key,wakeup;	
                };
                fault_y {
                    label               = "Replic:Fault-Y";
                    debounce_interval   = ;
                    linux,code          = ;
                    gpios               = <&gpio2 5 0x5>;
                    gpio-key,wakeup;	
                };
                fault_z {
                    label               = "Replic:Fault-Z";
                    debounce_interval   = ;
                    linux,code          = ;
                    gpios               = <&gpio0 15 0x5>;
                    gpio-key,wakeup;	
                };
                fault_ext_1 {
                    label               = "Replic:Fault-Ext-1";
                    debounce_interval   = ;
                    linux,code          = ;
                    gpios               = <&gpio2 1 0x5>;
                    gpio-key,wakeup;	
                };
                fault_ext_2 {
                    label               = "Replic:Fault-Ext-2";
                    debounce_interval   = ;
                    linux,code          = ;
                    gpios               = <&gpio2 3 0x5>;
                    gpio-key,wakeup;	
                };
            };
            onewire {
               compatible      = "w1-gpio";
               pinctrl-names   = "default";
               pinctrl-0       = <&dallas_w1_pins>;
               status          = "okay";
               gpios           = <&gpio0 2 0>;
            };
        };
    };

    fragment@4 {
        target = <&tscadc>;
        __overlay__ {			
            status = "okay";
            adc {
                ti,adc-channels = ;
            };
        };
    };
};

This might serve as a starting point for anyone wanting to convert overlays for SPI, ADC, Dallas Onewire, PRU or GPIO keys which are the peripherals in use on Replicape.

If you want a precompiled version of the 3.12 kernel for BeagleBone (Black) have a look at the wiki page. Note: This is pretty experimental, so do it at your own risk.

If you want to compile your own version of the 3.12 kernel, have a look at the other wiki page.


Elias Bakken

5 COMMENTS
  • nomel
    Reply

    Man, I can't keep up with bleeding edge Linux.

  • zhalii
    Reply

    Works perfectly. Thanks a lot!

  • Cape manager reintroduced in kernel 4.1Thing-Printer.com
    Reply

    […] in porting old overlays A while back I ported the patches for the cape manager to a kernel 3.12 for use in an Angstrom based distro. If you want to port an old cape from the kernel 3.8 era, you […]

  • Imran Khan
    Reply

    Hi Ellias,
    I wonder you can shed some light on my problem.
    1/ I build a kernel 3.14.47 success fully for the Beaglebone Black
    2/ Build the Modules ie. libs
    3/ Stole tisdk-rootfs-image-am335x-evm.tar.gz for the rootfs file system
    4/ replaced boot/zImage with my new image and am335x-boneblack.dtb file
    6/ created a micro SD and booted the BBB from the SD card.
    7/ The BOOT process gone successfully and system has boot and prompted at beagbone~$
    8/ at promtp 'root' I managed to logged in
    9/ But when I ran lsmod command. I cannot see any driver been loaded in the kernel.
    10/ lsmod did not browse any kernel space loaded driver on to the screen
    11/ I wonder what I am doing wrong?

    I will be grateful if you can shed light on this problem.
    Thank you,
    ik

    1. Elias Bakken
      Reply

      depmod -a?

Leave a Reply

Your email address will not be published. Required fields are marked *