This is an old revision of the document!


Device tree for liteSOM/liteboard

<uml> title Example configuration flow\nvia device tree hide footbox box “i.MX6UL”

participant "Linux kernel" as linux
database "Device tree" as dtr
participant GPIO as gpio
participant I2C as i2c

end box participant “Audio codec” as audio →> linux : start activate linux linux → dtr : read activate dtr dtr –> linux : configuration deactivate dtr linux → linux : load GPIO driver linux → gpio : configure\nGPIO pins activate gpio linux → linux : load I2C driver linux → i2c : configure I2C activate i2c linux → linux : load driver\nfor audio codec linux → i2c : configure audio i2c → audio : configure audio activate audio linux → linux : continue booting … </uml>

Device tree is a structure used to describe hardware configuration. Each boot it is interpreted by the kernel and according to this configuration all:

  • CPU registers and peripherals,
  • Linux drivers,
  • external integrated circuits,

are configured.

In the past hardware configuration was hard coded in the source code (example), now it is a human readable file (example) compiled into a binary format FDT.

If you are interested how - in details - device tree works please read Device Tree Usage and Device Tree Reference articles created by eLinux team.

Generic information about device tree you can find in Booting the Linux without Open Firmware.

In case when you want to develop device tree for your own hardware device tree bindings documentation will guide you how to do it.

Below this section you can find few examples with configuration for litesom, liteboard and our evm.

Below you can find complete device tree for liteSOM.

Show complete device tree for liteSOM

#include "imx6ul.dtsi"

/ {
	model = "Grinn i.MX6UL liteSOM";
	compatible = "grinn,imx6ul-litesom", "fsl,imx6ul";

	memory {
		reg = <0x80000000 0x20000000>;
	};
};

&iomuxc {
	pinctrl_usdhc2: usdhc2grp {
		fsl,pins = <
			MX6UL_PAD_NAND_RE_B__USDHC2_CLK	    0x10069
			MX6UL_PAD_NAND_WE_B__USDHC2_CMD	    0x17059
			MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
			MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
			MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
			MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
			MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
			MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
			MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
			MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
			MX6UL_PAD_NAND_ALE__USDHC2_RESET_B  0x17059
		>;
	};
};

&usdhc2 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_usdhc2>;
	no-1-8-v;
	non-removable;
	keep-power-in-suspend;
	wakeup-source;
	bus-width = <8>;
	status = "okay";
};
#include "imx6ul.dtsi"

Since liteSOM is using i.MX6UL CPU kernel must know how to configure CPU, what peripherals are available etc. All (from CPU point of view) informations are available in imx6ul.dtsi file. This file is base for all \\device tree
files where i.MX6UL is used.

/ {
    model = "Grinn i.MX6UL liteSOM";
    compatible = "grinn,imx6ul-litesom", "fsl,imx6ul";

    memory {
        reg = <0x80000000 0x20000000>;
  };
};

Node model contains user defined device name. It can be - for example - used to identify your hardware version in the runtime.

Node compatible is used by the kernel to device how to start litesom. Value fsl,imx6ul informs kernel to initialize device as it is defined in mach-imx6ul.c file. Value grinn,imx6ul-litesom can be used to implement functionality required for the liteSOM platform. Currently it is not used and while liteSOM is fully compatible with i.MX6UL.

Node memory informs kernel about memory layout; it contains pair address & size configuration for liteSOM.

&iomuxc {
    pinctrl_usdhc2: usdhc2grp {
        fsl,pins = <
            MX6UL_PAD_NAND_RE_B__USDHC2_CLK      0x10069
            MX6UL_PAD_NAND_WE_B__USDHC2_CMD      0x17059
            MX6UL_PAD_NAND_DATA00__USDHC2_DATA0  0x17059
            MX6UL_PAD_NAND_DATA01__USDHC2_DATA1  0x17059
            MX6UL_PAD_NAND_DATA02__USDHC2_DATA2  0x17059
            MX6UL_PAD_NAND_DATA03__USDHC2_DATA3  0x17059
            MX6UL_PAD_NAND_DATA04__USDHC2_DATA4  0x17059
            MX6UL_PAD_NAND_DATA05__USDHC2_DATA5  0x17059
            MX6UL_PAD_NAND_DATA06__USDHC2_DATA6  0x17059
            MX6UL_PAD_NAND_DATA07__USDHC2_DATA7  0x17059
            MX6UL_PAD_NAND_ALE__USDHC2_RESET_B   0x17059
        >;
    };
};

&usdhc2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_usdhc2>;
    no-1-8-v;
    non-removable;
    keep-power-in-suspend;
    wakeup-source;
    bus-width = <8>;
    status = "okay";
};

i.MX6UL needs information how to use eMMC memory from liteSOM module. eMMC memory configuration is defined by usdhc2 node; required configuration for pinmux is defined by pinctrl_usdhc2 node.

More details about pinmux configuration you can find in pinmux configuration section.

Please take into account that usdhc2 doesn't contain complete configuration for MMC/SD/SDIO controller. Generic configuration is defined in imx6ul.dtsi file included in the 1st step.

usdhc2: usdhc@02194000 {
    compatible = "fsl,imx6ul-usdhc", "fsl,imx6sx-usdhc";
    reg = <0x02194000 0x4000>;
    interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&clks IMX6UL_CLK_USDHC2>,
    <&clks IMX6UL_CLK_USDHC2>,
    <&clks IMX6UL_CLK_USDHC2>;
    clock-names = "ipg", "ahb", "per";
    bus-width = <4>;
    status = "disabled";
};

i.MX6UL has very flexible IOMUX Controller which allows each pad to share several functional blocks. Each input and output signal can be configured via dedicated multiplexers.

IOMUX Cell Block Diagram

(from i.MX 6UltraLite Applications Processor Reference Manual, Rev. 1, 04/2016)

Each pad mus be configured via following registers:

  • IOMUXC_SW_MUX_CTRL_<PAD>,
  • IOMUXC_SW_PAD_CTRL_<PAD>,
  • <SOURCE>_SELECT_INPUT;

all of them are configured via device tree.

UART configuration for liteboard

On liteboard we are using UART1_RX pin as debug console input. Therefore in imx6ul-liteboard.dts file you can find following section.

/ {
    chosen {
        stdout-path = &uart1;
    };
};

&iomuxc {
    pinctrl_uart1: uart1grp {
        fsl,pins = <
            MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX  0x1b0b1
            MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX  0x1b0b1
        >;
    };
};

&uart1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart1>;
    status = "okay";
};
  • chosen/stdout-path - informs kernel specify device used as a boot console (see choosen.txt),
  • uart1/status - enables UART1 peripheral,
  • uart1/pinctrl-0 - informs kernel where to find pinmux configuration for UART1,
  • iomuxc/pinctrl_uart1 - contains configuration for I/O PADS.

imx6ul-pinfunc.h contains all allowed configurations for all i.MX6UL PADS. For UART1_RX pin you can find following items.

#define MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX		0x0088 0x0314 0x0624 0 3
#define MX6UL_PAD_UART1_RX_DATA__UART1_DTE_TX		0x0088 0x0314 0x0000 0 0
#define MX6UL_PAD_UART1_RX_DATA__ENET1_RDATA03		0x0088 0x0314 0x0000 1 0
#define MX6UL_PAD_UART1_RX_DATA__I2C3_SDA		0x0088 0x0314 0x05b8 2 0
#define MX6UL_PAD_UART1_RX_DATA__CSI_DATA03		0x0088 0x0314 0x04c8 3 1
#define MX6UL_PAD_UART1_RX_DATA__GPT1_CLK		0x0088 0x0314 0x0594 4 0
#define MX6UL_PAD_UART1_RX_DATA__GPIO1_IO17		0x0088 0x0314 0x0000 5 0
#define MX6UL_PAD_UART1_RX_DATA__SPDIF_IN		0x0088 0x0314 0x0618 8 1

In the liteboard device tree we are using it as

#define MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX		0x0088 0x0314 0x0624 0 3

As described in fsl,imx-pinctrl.txt documentation each value means:

  • 0x0088 - address of IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA register,
  • 0x0314 - address of IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA register,
  • 0x0624 - address of IOMUXC_UART1_RX_DATA_SELECT_INPUT register,
  • 0 - IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA register value,
  • 3 - IOMUXC_UART1_RX_DATA_SELECT_INPUT register value.

As you can see IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA register is not configured via MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX define. Value for this register is configured directly in device tree file.

&iomuxc {
    pinctrl_uart1: uart1grp {
        fsl,pins = <
            MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX  0x1b0b1
            MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX  0x1b0b1
        >;
    };
};

With this solution you can configure parameters like hysteresis, pull-up, pull-down, etc. directly in your device tree.

Instead of magic number 0x1b0b1 you can use defines from fsl,imx6ul-pinctrl.txt file.

<uml> object “imx6ul.dtsi” as imx6ul object “imx6ul-litesom.dtsi” as litesom object “imx6ul-liteboard.dtsi” as liteboard object “liteSOM base project” as custom1 object “liteboard base project” as custom2 imx6ul <|– litesom litesom <|– custom1 litesom <|– liteboard liteboard <|– custom2 </uml>

Mainline Linux contains two files:

If you need more device tree customizations you can include one of the mentioned file and extend it to fit into your project configuration.

On the following pages you can find more examples about device tree fir liteSOM and liteboard:

end


FIXME change TX to RX

Each define name is build with the following syntax <PAD NAME>_<MUX_MODE>. Each ALTX function for UART1_TX PAD can be configured as presented below.

ALT function Define name
ALT0 mux port: UART1_TX MX6UL_PAD_UART1_TX_DATAUART1_DCE_TX | | | MX6UL_PAD_UART1_TX_DATAUART1_DTE_RX
ALT1 mux port: ENET1_RDATA02 MX6UL_PAD_UART1_TX_DATAENET1_RDATA02 | | ALT2 mux port: I2C3_SCL | MX6UL_PAD_UART1_TX_DATAI2C3_SCL
ALT3 mux port: CSI_DATA02 MX6UL_PAD_UART1_TX_DATACSI_DATA02 | | ALT4 mux port: GPT1_COMPARE1 | MX6UL_PAD_UART1_TX_DATAGPT1_COMPARE1
ALT5 mux port: GPIO1_IO16 MX6UL_PAD_UART1_TX_DATAGPIO1_IO16 | | ALT8 mux port: SPDIF_OUT | MX6UL_PAD_UART1_TX_DATASPDIF_OUT

Based on all defines from imx6ul-pinfunc.h file you can build configuration for IOMUX Controller.


To configure IOMUX Controller for each pad following registers must

allows to configure one pad to share up to eight functional blocks.

IOMUX Controller allows to share one pad to several (up to eight) functional blocks.

IOMUX Controller allows to share several (up to eight) functional signals on single I/O pad. For example UART1_TX_DATA pin can be configured via SW_MUX_CTL_PAD_UART1_TX_DATA SW MUX register to provide following signals:

  • ALT0 — Select mux mode: ALT0 mux port: UART1_TX of instance: uart1,
  • ALT1 — Select mux mode: ALT1 mux port: ENET1_RDATA02 of instance: enet1,
  • ALT2 — Select mux mode: ALT2 mux port: I2C3_SCL of instance: i2c3,
  • ALT3 — Select mux mode: ALT3 mux port: CSI_DATA02 of instance: csi,
  • ALT4 — Select mux mode: ALT4 mux port: GPT1_COMPARE1 of instance: gpt1,
  • ALT5 — Select mux mode: ALT5 mux port: GPIO1_IO16 of instance: gpio1,
  • ALT8 — Select mux mode: ALT8 mux port: SPDIF_OUT of instance: spdif.

On liteboard we are using this pin as UART1_TX - it is our debug console output. Therefore in imx6ul-liteboard.dts file you can find following configuration.

/ {
    chosen {
        stdout-path = &uart1;
    };
};

&iomuxc {
    pinctrl_uart1: uart1grp {
        fsl,pins = <
            MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX  0x1b0b1
            MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX  0x1b0b1
        >;
    };
}

&uart1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart1>;
    status = "okay";
};
  • chosen/stdout-path - informs kernel specify device used as a boot console (see choosen.txt),
  • uart1/status - enables UART1 peripheral,
  • uart1/pinctrl-0 - informs kernel where to find pinmux configuration for UART1,
  • iomuxc/pinctrl_uart1 - contains configuration for I/O PADS.

imx6ul-pinfunc.h contains all allowed PAD configurations for i.MX6UL. In our case for each mentioned above alternate function you can find items as presented below.

#define MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX		0x0084 0x0310 0x0000 0 0
#define MX6UL_PAD_UART1_TX_DATA__UART1_DTE_RX		0x0084 0x0310 0x0624 0 2
#define MX6UL_PAD_UART1_TX_DATA__ENET1_RDATA02		0x0084 0x0310 0x0000 1 0
#define MX6UL_PAD_UART1_TX_DATA__I2C3_SCL		0x0084 0x0310 0x05b4 2 0
#define MX6UL_PAD_UART1_TX_DATA__CSI_DATA02		0x0084 0x0310 0x04c4 3 1
#define MX6UL_PAD_UART1_TX_DATA__GPT1_COMPARE1		0x0084 0x0310 0x0000 4 0
#define MX6UL_PAD_UART1_TX_DATA__GPIO1_IO16		0x0084 0x0310 0x0000 5 0
#define MX6UL_PAD_UART1_TX_DATA__SPDIF_OUT		0x0084 0x0310 0x0000 8 0
  • 0x0084 - address of SW_MUX_CTL_PAD_UART1_TX_DATA SW MUX Control Register
  • 0x0310 - address of SW_PAD_CTL_PAD_UART1_TX_DATA SW PAD Control Register
  • 0x0000 - address of UART1_RX_DATA_SELECT_INPUT DAISY Register
  • 0
  • 0

FIXME change TX to RX

Each define name is build with the following syntax <PAD NAME>_<MUX_MODE>. Each ALTX function for UART1_TX PAD can be configured as presented below.

ALT function Define name
ALT0 mux port: UART1_TX MX6UL_PAD_UART1_TX_DATAUART1_DCE_TX | | | MX6UL_PAD_UART1_TX_DATAUART1_DTE_RX
ALT1 mux port: ENET1_RDATA02 MX6UL_PAD_UART1_TX_DATAENET1_RDATA02 | | ALT2 mux port: I2C3_SCL | MX6UL_PAD_UART1_TX_DATAI2C3_SCL
ALT3 mux port: CSI_DATA02 MX6UL_PAD_UART1_TX_DATACSI_DATA02 | | ALT4 mux port: GPT1_COMPARE1 | MX6UL_PAD_UART1_TX_DATAGPT1_COMPARE1
ALT5 mux port: GPIO1_IO16 MX6UL_PAD_UART1_TX_DATAGPIO1_IO16 | | ALT8 mux port: SPDIF_OUT | MX6UL_PAD_UART1_TX_DATASPDIF_OUT

Based on all defines from imx6ul-pinfunc.h file you can build configuration for IOMUX Controller.

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt

imx6ul-litesom.dtsi file includes imx6ul.dtsi file and appends all items required to configure litesom.

For liteboard based project you can use imx6ul-liteboard.dts device tree with configuration for all peripherals from liteboard.

<uml> object “imx6ul.dtsi” as imx6ul object “imx6ul-litesom.dtsi” as litesom object “imx6ul-liteboard.dtsi” as liteboard object “liteSOM base project” as custom1 object “liteboard base project” as custom2 imx6ul <|– litesom litesom <|– custom1 litesom <|– liteboard liteboard <|– custom2 </uml>

Of course you can include imx6ul-litesom.dtsi or imx6ul-liteboard.dts in your project device tree and extend existing configuration according to your hardware configuration like presented below.

liteSOM based project

<uml> package foo «Node» { object “imx6ul.dtsi” as imx6ul object “imx6ul-litesom.dtsi” as litesom }

object “custom-project.dts” as custom imx6ul <|– litesom litesom <|– custom </uml>

liteboard based project

<uml> object “imx6ul.dtsi” as imx6ul object “imx6ul-litesom.dtsi” as litesom object “imx6ul-liteboard.dtsi” as liteboard object “custom-project.dts” as custom

imx6ul <|– litesom litesom <|– liteboard liteboard <|– custom </uml>


<uml> object “imx6ul.dtsi” as imx6ul object “imx6ul-litesom.dtsi” as litesom object “custom-project.dts” as project imx6ul <|– litesom litesom <|– project </uml>

<uml> object “imx6ul.dtsi” as imx6ul object “imx6ul-litesom.dtsi” as litesom object “imx6ul-liteboard.dtsi” as liteboard object “custom-project.dts” as project

imx6ul <|– litesom litesom <|– liteboard liteboard <|– project </uml>

imx6ul.dtsi

file is included by [https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/imx6ul-litesom.dtsi imx6ul-litesom.dtsi] where you can find minimal configuration for liteSOM module. This file can be included in all liteSOM based projects.

In our case we are including

imx6ul-litesom.dtsi

file in [https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/imx6ul-liteboard.dts imx6ul-liteboard.dts] which is a complete configuration for our liteSOM based liteboard.

Based on [https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/imx6ul-litesom.dtsi imx6ul-litesom.dtsi] and [https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/imx6ul-liteboard.dts imx6ul-liteboard.dts] files you can customize any liteSOM/liteboard based project to fit into your project requirements.

For example you can check out [https://github.com/grinn-pub/examples/blob/master/board/grinn/liteboard-lcd-res/imx6ul-liteboard-lcd-res.dts imx6ul-liteboard-lcd-res.dts] example where liteboard is configured to support 800×480 LCD panel with resistive touchscreen.

  • litesom/devicetree.1486845873.txt.gz
  • Last modified: 2017/02/11 20:44
  • by filug