恩智浦imx8qxp-mek的 device Tree 结构

Device Tree 的目录在
pwd 
~/imx-yocto-bsp/standalone/linux-imx/arch/arm64/boot/dts/freescale 
ls fsl-imx8* 
. 
├── fsl-imx8-ca35.dtsi 
├── fsl-imx8dx-17x17-val.dts 
├── fsl-imx8dx.dtsi 
├── fsl-imx8dx-lpddr4-arm2.dts 
├── fsl-imx8dxp.dtsi 
├── fsl-imx8dxp-lpddr4-arm2.dts 
├── fsl-imx8qxp-17x17-val.dts 
├── fsl-imx8qxp-ddr3l-val.dts 
├── fsl-imx8qxp.dtsi 
├── fsl-imx8qxp-enet2-tja1100.dtsi 
├── fsl-imx8qxp-lpddr4-arm2-a0.dts 
├── fsl-imx8qxp-lpddr4-arm2-dsi-rm67191.dts 
├── fsl-imx8qxp-lpddr4-arm2-dsp.dts 
├── fsl-imx8qxp-lpddr4-arm2.dts 
├── fsl-imx8qxp-lpddr4-arm2-enet2.dts 
├── fsl-imx8qxp-lpddr4-arm2-enet2-tja1100.dts 
├── fsl-imx8qxp-lpddr4-arm2-gpmi-nand.dts
├── fsl-imx8qxp-lpddr4-arm2-lpspi.dts 
├── fsl-imx8qxp-lpddr4-arm2-lpspi-slave.dts 
├── fsl-imx8qxp-lpddr4-arm2-mlb.dts 
├──fsl-imx8qxp-lpddr4-arm2-mqs.dts 
├── fsl-imx8qxp-lpddr4-arm2-spdif.dts 
├──fsl-imx8qxp-lpddr4-arm2-wm8962.dts 
├── fsl-imx8qxp-mek-a0.dts 
├──fsl-imx8qxp-mek-dom0.dts 
├── fsl-imx8qxp-mek-dsi-rm67191.dts 
├── fsl-imx8qxp-mek-dsp.dts 
├── fsl-imx8qxp-mek.dts 
├──fsl-imx8qxp-mek.dtsi 
├── fsl-imx8qxp-mek-enet2.dts 
├── fsl-imx8qxp-mek-enet2-tja1100.dts 
├── fsl-imx8qxp-mek-inmate.dts 
├── fsl-imx8qxp-mek-it6263-lvds0-dual-channel.dts 
├──fsl-imx8qxp-mek-it6263-lvds1-dual-channel.dts 
├──fsl-imx8qxp-mek-jdi-wuxga-lvds0-panel.dts 
├──fsl-imx8qxp-mek-jdi-wuxga-lvds1-panel.dts 
├──fsl-imx8qxp-mek-lcdif.dts 
├──fsl-imx8qxp-mek-lvds0-it6263.dtsi 
├──fsl-imx8qxp-mek-lvds1-it6263.dtsi 
├──fsl-imx8qxp-mek-ov5640.dts 
├──fsl-imx8qxp-mek-ov5640.dtsi 
├──fsl-imx8qxp-mek-ov5640-rpmsg.dts 
├──fsl-imx8qxp-mek-root.dts 
├──fsl-imx8qxp-mek-rpmsg.dts 
├──fsl-imx8qxp-mek-rpmsg.dtsi 
├──fsl-imx8qxp-xen.dtsi 
├── 
#include <dt-bindings/clock/imx8qxp-clock.h> 
#include <dt-bindings/interrupt-controller/arm-gic.h> 
/include/dt-bindings 
#include <dt-bindings/interrupt-controller/arm-gic.h> 
#include <dt-bindings/soc/imx_rsrc.h> 
#include <dt-bindings/soc/imx8_hsio.h>
#include <dt-bindings/soc/imx8_pd.h> 
#include <dt-bindings/clock/imx8qxp-clock.h> 
#include <dt-bindings/input/input.h> 
#include <dt-bindings/pinctrl/pads-imx8qxp.h> 
#include <dt-bindings/gpio/gpio.h> 
#include <dt-bindings/thermal/thermal.h> 
├── Makefile 
其中 imx8qxp-mek 板的 dts 由以下文件组成:
fsl-imx8-ca35.dtsi: SOC 的 A35 簇部分:包括 cpu,pmu 和 psci(Power State Coordination Interface). 
fsl-imx8dx.dtsi: SOC 中 i.MX8DX/DXP/QXP 共用部分。是 SOC 层的主要文件。
fsl-imx8dxp.dtsi: SOC 中 i.MX8/DXP/QXP 共用部分:包括 vpu_decoder 与 i.MX8DX 相比有
不同。
fsl-imx8qxp.dtsi: SOC 中 i.MX8QXP 独有部分:比 i.MX8DXP 相比多出两个 CPU 核。
fsl-imx8qxp-mek.dtsi:MEK 板级主要文件,包括所有外设驱动部分。
fsl-imx8qxp-mek.dts: MEK 板的 DTB 文件,直接包含 fsl-imx8qxp-mek.dtsi。
fsl-imx8qxp-mek-dsi-rm67191.dts: MEK 板支持两块直接连接的 rm67191 MiPi DSI 接口屏的
DTB 文件。
fsl-imx8qxp-mek-dsp.dts: MEK 板支持 HiFi DSP codec 的 DTB 文件。
fsl-imx8qxp-mek-enet2.dts/fsl-imx8qxp-enet2-tja1100.dtsi/fsl-imx8qxp-mek-enet2-tja1100.dts 
: MEK 板支持通过 enet2 连接到底板的 NXP tja1100 的 100Mhz 汽车级以太网 PHY。
fsl-imx8qxp-mek-it6263-lvds0/1-dual-channel.dts: MEK 板支持通过 LVDS0 或 LVDS1 接口的
dual channel 模式来连接 LVDS to HDMI 桥,来连接 HDMI 显示器(默认的 fsl-imx8qxp-mek.dts
是使用 single channel 模式来连接的。) 
fsl-imx8qxp-mek-jdi-wuxga-lvds0/1-panel.dts:MEK 板支持通过 LVDS0 或 LVDS1 接口的 dual 
channel 模式来连接 jdi_tx26d202vm0bwa dual channel LVDS 屏
fsl-imx8qxp-mek-lcdif.dts:MEK 板支持通过 LCDIF 接口连接 Seiko 43WVFIG adapter card。
fsl-imx8qxp-mek-ov5640.dtsi/dts:MEK 板支持通过 MiPi CSI 接口连接 OV5649 Camera sensor。
 编译 imx8qxp-mek 板 BSP 时,会合并相关的所有 dts/dtsi 文件,生成相应的 1~8 的 DTB 文
件,默认 uboot 使用的 fdt_file=fsl-imx8qxp-mek.dtb。
device Tree 的基础与语法(no updates)
在描述 Device Tree 的结构之前,我们先问一个基础问题:是否 Device Tree 要描述系统中的所
有硬件信息?答案是否定的。基本上,那些可以动态探测到的设备是不需要描述的,例如 USB 
device。不过对于 SOC 上的 usb host controller,它是无法动态识别的,需要在 device tree 中描述。
同样的道理,在 computer system 中,PCI device 可以被动态探测到,不需要在 device tree 中描述,
但是 PCI bridge 如果不能被探测,那么就需要描述之。 需要描述的内容一般包括
• CPUs 
• Memory 
• Buses 
• Peripheral connections 
• Interrupt Controllers 
• GPIO controllers 
• Clock controllers 
…… 
DTS 是一个由节点及其属性构成的一个简单的树,其优点主要有
内核在解析 device tree 是动态创建平台设备
平台设备的配置及数据可能通过 device tree 来描述
允许内核和板级专用的配置数据脱勾
Device tree 主要包括以下部分
DTS: Device Tree Source: 文本描述文件,在 arch/arm/boot/dts 下  DTB:Device Treee Blob:由 DTS 通过特定的编译器编译出来的二进制文件,也在
arch/arm/boot/dts 下,内核在启动时会解析它
DTC:Device Tree Compiler:位于 script/dtc/dtc,编译命令为
make ARCH=arm imx6q-sabresd.dtb 
为了了解 Device Tree 的结构,我们首先给出一个 Device Tree 的示例:
/ { //root node “/”
 node1 { //child nodes “node1”,” node2”
 a-string-property = "A string"; //字符串型属性,由””定义
 a-string-list-property = "first string", "second string"; //字符串列表型属性,由””定义, “,“分开。
 a-byte-data-property = [0x01 0x23 0x34 0x56]; //BYTE 数据型属性,由[]定义。
 child-node1 { // children nodes of node1: "child-node1" and "child-node2" 
 first-child-property; 
 second-child-property = <1>; 
 a-string-property = "Hello, world"; 
 }; 
 child-node2 { 
 }; 
 }; 
 node2 { 
 an-empty-property; 
 a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */ //u32 数据型属性,由<>定义
 child-node1 { 
 }; 
 }; 
}; 
节点 node 
从上图中可以看出,device tree 的基本单元是 node。系统中的每个设备用一个 node 来描述,
这些 node 被组织成树状结构,除了 root node,每个 node 都只有一个 parent。一个 device tree 文件中只能有一个 root node。每个 node 中包含了若干的 property/value 来描述该 node 的一些特性。每个 node 用节点名字(node name)标识,节点名字的格式是
[label:]node-name[@unit-address]。如果该 node 没有 reg 属性(后面会描述这个 property),那
么该节点名字中必须不能包括@和 unit-address。unit-address 的具体格式是和设备挂在那个 bus 上
相关。例如对于 cpu,其 unit-address 就是从 0 开始编址,以此加一。而具体的设备,例如以太网
控制器,其 unit-address 就是寄存器地址。root node 的 node name 是确定的,必须是“/”。  node-name 说明了何种设备,必须使用字符开头,
unit-address:访问此设备的主地址,必须唯一,必须和此节点的 reg 属性的开始地址一致
根节点 root node 
只能有一个 root node,它用来描述从 CPU 端看到的地址空间,至少需要用 cpu 和 memory 节点
组成,如下: 
/ { 
 model = "NXP i.MX6 Quad SABRE Smart Device Board"; 
 compatible = "fsl,imx6q-sabresd", "fsl,imx6q"; 
cpus { 
 #address-cells = <1>; 
 #size-cells = <0>; 
 cpu0: cpu@0 { 
… 
 }; 
 cpu@1 { 
… 
 }; 
 cpu@2 { 
… 
 }; 
 cpu@3 {
… 
 }; 
 }; 
 soc { 
… 
 } 
 memory { 
 reg = <0x10000000 0x40000000>; 
 }; 
} 
别名节点
aliases 节点定义了一些别名。为何要定义这个 node 呢?因为 Device tree 是树状结构,当要引
用一个 node 的时候要指明相对于 root node 的 full path,例如/ node1 / child-node1。如果多次引用,每
次都要写这么复杂的字符串多少是有些麻烦,因此可以在 aliases 节点定义一些设备节点 full path
的缩写。 
 *Given the alias mxcfb0, it will lookup aliases nodes for the full device path 
Example 
aliases { 
serial0 = "/simple-bus@fe000000/serial@llc500"; 
ethernet0 = "/simple-bus@fe000000/ethernet@31c000"; 
} 
CPU 节点
Describes CPUs or cores in the system 
Standard properties include: reg, clock-frequency, reservation-granule-size, etc 
TLB, L1 cache, as well as multi level and shared caches can be described 
cpus {
 #address-cells = <1>; 
 #size-cells = <0>; 
 cpu0: cpu@0 { 
 compatible = "arm,cortex-a9"; 
 device_type = "cpu"; 
 reg = <0>; 
 next-level-cache = <&L2>; 
 operating-points = < 
 /* kHz uV */ 
 1200000 1275000 
 996000 1250000 
 852000 1250000 
 792000 1175000 
 396000 975000 
 >; 
 fsl,soc-operating-points = < 
 /* ARM kHz SOC-PU uV */ 
 1200000 1275000 
 996000 1250000 
 852000 1250000 
 792000 1175000 
 396000 1175000 
 >; 
 clock-latency = <61036>; /* two CLK32 periods */ 
 clocks = <&clks IMX6QDL_CLK_ARM>, 
 <&clks IMX6QDL_CLK_PLL2_PFD2_396M>, 
 <&clks IMX6QDL_CLK_STEP>, 
 <&clks IMX6QDL_CLK_PLL1_SW>, 
 <&clks IMX6QDL_CLK_PLL1_SYS>, 
 <&clks IMX6QDL_PLL1_BYPASS>, 
 <&clks IMX6QDL_CLK_PLL1>, 
 <&clks IMX6QDL_PLL1_BYPASS_SRC> ; 
 clock-names = "arm", "pll2_pfd2_396m", "step", 
 "pll1_sw", "pll1_sys", "pll1_bypass", "pll1", "pll1_bypass_src"; 
 arm-supply = <&reg_arm>; 
 pu-supply = <&reg_pu>;
 soc-supply = <&reg_soc>; 
 }; 
 cpu@1 { 
 compatible = "arm,cortex-a9"; 
 device_type = "cpu"; 
 reg = <1>; 
 next-level-cache = <&L2>; 
 }; 
 cpu@2 { 
 compatible = "arm,cortex-a9"; 
 device_type = "cpu"; 
 reg = <2>; 
 next-level-cache = <&L2>; 
 }; 
 cpu@3 { 
 compatible = "arm,cortex-a9"; 
 device_type = "cpu"; 
 reg = <3>; 
 next-level-cache = <&L2>; 
 }; 
Memory 节点
memory device node 是所有设备树文件的必备节点,它定义了系统物理内存的 layout。
device_type 属性定义了该 node 的设备类型,例如 cpu、serial 等。对于 memory node,其 device_type
必须等于 memory。reg 属性定义了访问该 device node 的地址信息,该属性的值被解析成任意长度
的(address,size)数组,具体用多长的数据来表示 address 和 size 是在其 parent node 中定义
(#address-cells 和#size-cells)。对于 device node,reg 描述了 memory-mapped IO register 的 offset
和 length。对于 memory node,定义了该 memory 的起始地址和长度。
一个 32bit 的内存分布示例:
RAM: starting address 0x0, length 0x40000000 (1GB) 
 #address-cells = 1 and a #size-cells = 1: 
memory { 
 device_type = "memory"; 
 reg = <0x10000000 0x40000000>; 
 }; 
一个 64bit 的内存分布示例:(64bit 由两个 32bit 来描述)
RAM: starting address 0x0, length 0x80000000 (2GB) 
RAM: starting address 0x100000000, length 0x100000000 (4GB) 
方法 1: 
memory@0 { 
 device_type = "memory"; 
 reg = <0x000000000 0x00000000 0x00000000 0x80000000 
 0x000000001 0x00000000 0x00000001 0x00000000>; 
}; 
方法 2: 
memory@0 { 
 device_type = "memory"; 
 reg = <0x000000000 0x00000000 0x00000000 0x80000000>; 
}; 
memory@100000000 { 
 device_type = "memory"; 
 reg = <0x000000001 0x00000000 0x00000001 0x00000000>; 
}; 
可选节点
chosen node 主要用来描述由系统 firmware 指定的 runtime parameter。如果存在 chosen 这个
node,其 parent node 必须是名字是“/”的根节点。原来通过 tag list 传递的一些 linux kernel 的运行
时参数可以通过 Device Tree 传递。例如 command line 可以通过 bootargs 这个 property 这个属性传
递;initrd 的开始地址也可以通过 linux,initrd-start 这个 property 这个属性传递。在实际中,建议增
加一个 bootargs 的属性,例如: 
chosen { bootargs = "console=ttymxc0,115200"; }; 
 我们知道,device tree 用于 HW platform 识别,runtime parameter 传递以及硬件设备描述。
chosen 节点并没有描述任何硬件设备节点的信息,它只是传递了 runtime parameter。
属性
了解了基本的 device tree 的结构后,我们总要把这些结构体现在 device tree source code 上来。
在 linux kernel 中,扩展名是 dts 的文件就是描述硬件信息的 device tree source file,在 dts 文件中,
一个 node 被定义成: 
[label:] node-name[@unit-address] { 
 [properties definitions] 
 [child nodes] 
} 
“[]”表示 option,因此可以定义一个只有node name的空节点。label方便在 dts文件中引用,具
体后面会描述。child node的格式和node是完全一样的,因此,一个dts文件中就是若干嵌套组成
的 node,property 以及 child note、child note property 描述。 
 各家 ARM vendor 也会共用一些硬件定义信息,这个文件就是 skeleton.dtsi。我们自下而上(类
似 C++中的从基类到顶层的派生类)逐个进行分析。 
1、skeleton.dtsi。位于 linux-3.14\arch\arm\boot\dts 目录下,具体该文件的内容如下: 
/ { 
 #address-cells = <1>; 
 #size-cells = <1>; 
 chosen { }; 
 aliases { }; 
 memory { device_type = "memory"; reg = <0 0>; }; 
}; 
device tree 顾名思义是一个树状的结构,既然是树,必然有根。“/”是根节点的 node name。“{”和
“}”之间的内容是该节点的具体的定义,其内容包括各种属性的定义以及 child node 的定义。
chosen、aliases 和 memory 都是 sub node,sub node 的结构和 root node 是完全一样的,因此,sub 
node 也有自己的属性和它自己的 sub node,最终形成了一个树状的 device tree。属性的定义采用

property = value 的形式。例如#address-cells 和#size-cells 就是 property,而<1>就是 value。value
有以下几种情况: 
1)属性值是空<empty> Value is empty—used for conveying true-false information. 
2)属性值是 32bit unsigned integers,用尖括号表示。例如#size-cells = <1> , <u32> A 32-bit integer 
in big-endian format. Example: the 32-bit value 0x11223344 would be represented in memory as: 
 address 0x11 
 address+1 0x22 
 address+2 0x33 
 address+3 0x44 
interrupts = <17 0xc>; 
3)属性值是 64bit unsigned integers,用尖括号表示。<u64> -- A 64-bit integer in big-endian format, 
would be represented as two <u32> cells 
clock-frequency = <0x00000001 0x00000000>; 
4)<phandle> -- specifies a numerical identifier for a node that is unique within the device tree 
5)属性值是 binary data,用方括号表示。例如 binary-property = [0x01 0x23 0x45 0x67] <bytestring> 
-- each byte represented by two hexadecimal digits 
local-mac-address = [00 00 12 34 56 78]; 
or equivalently: 
local-mac-address = [000012345678]; 
6)属性值是 text string, 用双引号表示。例如 device_type = "memory" <string> -- Strings are printable 
and NULL-terminated 
7)属性值是 string list,用双引号表示。<stringlist> -- A list of <string> values concatenated together 
Compatible 属性和 model 属性在描述 compatible 属性之前要先描述 model 属性。model 属性指明了该设备属于哪个设备生产商的哪一个 model。一般而言,我们会给 model 赋值“manufacturer,model”。例如 model = "fsl,imx6q-sabresd"。fsl 是生产商,imx6q-sabresd 是 model 类型,指明了具体的是哪一个系列的SOC。OK,现在我们回到 compatible 属性,该属性的值是 string list,定义了一系列的 modle(每个 string 是一个 model)。这些字符串列表被操作系统用来选择用哪一个 driver 来驱动该设备。假设定义该属性:compatible = “aaaaaa”, “bbbbb"。那么操作操作系统可能首先使用 aaaaaa 来匹配适合的 driver,如果没有匹配到,那么使用字符串 bbbbb 来继续寻找适合的 driver,对于本例,
compatible = "fsl,imx6q-sabresd", "fsl,imx6q";,这里只定义了一个 list。对于 root node,compatible属性是用来匹配 machine type 的(在 device tree 代码分析文章中会给出更细致的描述)。对于普
通的 HW block 的节点,例如 interrupt-controller,compatible 属性是用来匹配适合的 driver 的。 
Phandle 属性
A <u32> value specifies a numerical identifier for a node that is unique within the device tree. 
Used by other nodes that need to refer to the node associated with the property. 
Example 
pic@10000000 { 
phandle = <1>; 
interrupt-controller; 
}; 
*A phandle value of 1 is defined. Another device node could reference the pic node with a 
phandle value of 1: 
interrupt-parent = <1>; 
The DTC tool automatically inserts the phandle properties when the DTS is 
compiled into the binary DTB format when no explicit phandle properties. 
属性标签
Defines a human readable string describing a device 
[label:] node-name[@unit-address] 
[label:] property-name = value; 
[label:] property-name; 
Labels may also appear before or after any component of a property value, or between cells of 
a cell array, or between bytes of a bytestring. 
reg = reglabel: <0 sizelabel: 0x1000000>; 
prop = [ab cd ef byte4: 00 ff fe]; 
str = start: "string value" end: ; 
寻址属性
如果一个 device node 中包含了有寻址需求(要定义 reg property)的 sub node(后文也许会用
child node,和 sub node 是一样的意思),那么就必须要定义这两个属性。“#”是 number 的意思,
#address-cells 这个属性是用来描述 sub node 中的 reg 属性的地址域特性的,也就是说需要用多少
个 u32 的 cell 来描述该地址域。同理可以推断#size-cells 的含义,下面对 reg 的描述中会给出更详
细的信息。 
#address-cells : 
defines the number of <u32> cells used to encode the address field in a child node’s reg 
property 
#size-cells 
property defines the number of <u32> cells used to encode the size field in a child node’s 
reg property. 
reg: 
A list of tuples in the form 
reg = <address1 length1 [address2 length2] [address3 length3] ... > 
The reg property is interpreted by its parent node’s #address-cells and #size-cells.
地址区域
− The root-direct children describe the CPU's view of the address space (memory mapped 
address). 
− Root-indirect children use the parent domain defined by their parent. 
− Parent nodes are free to define whatever addressing scheme makes sense for the bus. 
− Root-indirect children need be translated to a root address domain.
地址范围
− Ranges is a list of address translations.
− Each entry in the ranges table is a tuple in the form of (child-bus-address, 
parent-bus-address, length). 
− The size of each field is determined by taking the child's #address-cells value, the parent's 
#address-cells value, and the child's #size-cells value.
• Ranges is empty 
If it’s defined with an <empty> value, it specifies that the parent and child address space is 
identical, and no address translation is required.
中断
• interrupt-controller - An empty property declaring a node as a device that receives interrupt 
signals 
• #interrupt-cells - a property of the interrupt controller node. It states how many cells are in an 
interrupt specifier for this interrupt controller (Similar to #address-cells and #size-cells).
• interrupt-parent - specify a phandle to the interrupt controller that it is attached to. 
*Nodes that do not have an interrupt-parent property can also inherit the property from their parent 
node. 
• interrupts - A property of a device node containing a list of interrupt specifiers, one for each 
interrupt output signal on the device.
节点状态
• Property: status 
• Value type: <string> 
• Description: -- indicates the operational status of a device
可以使用 okay 和 disabled 来打开和注掉某一个驱动的设备注册。
Bindings
• A binding documents what a particular compatible value means, what properties it should have, 
what child nodes it might have, and what device it represents 
− Located in Documentation/devicetree/bindings/ 
− Each binding page specifies the properties and child nodes that are expected and/or 
allowed for the binding 
− grouped into categories to make them easy to find an understand 
− Please read the binding doc for each module under Documentation/devicetree/bindings/ 
before you create the DTS file for the first time
Documentation/devicetree/binding/pinctrl/fsl,imx8qxp-pinctrl.txt 
* NXP IMX8QXP IOMUX Controller
如何基于 device tree 来开发驱动
设备驱动需要与.dts 中下定义设备一致,从而使用相应的 probe 函数被调用,所以平台驱动中
需要定义一下.of_match_table,如 drivers\pinctrol\pinctrol-imx6q.c 
static struct of_device_id imx6q_pinctrl_of_match[] = { 
 { .compatible = "fsl,imx6q-iomuxc", }, 
 { /* sentinel */ } 
}; 
static int imx6q_pinctrl_probe(struct platform_device *pdev) 
{ 
 return imx_pinctrl_probe(pdev, &imx6q_pinctrl_info); 
} 
static struct platform_driver imx6q_pinctrl_driver = { 
 .driver = { 
 .name = "imx6q-pinctrl", 
 .owner = THIS_MODULE,
 .of_match_table = imx6q_pinctrl_of_match, 
 }, 
 .probe = imx6q_pinctrl_probe, 
 .remove = imx_pinctrl_remove, 
}; 
相应的.dts 定义为: 
 iomuxc: iomuxc@020e0000 { 
 compatible = "fsl,imx6dl-iomuxc", "fsl,imx6q-iomuxc"; 
 reg = <0x020e0000 0x4000>; 
 };
memory and IRQ resources 
Memory and IRQ resources work in the same way with non-DT probe. ,IORESOURCE_DMA does 
not work with DT. 
see sound/soc/fsl/imx-ssi.c vs. sound/soc/fsl/fsl_ssi.c

platform_data is retrieved from DT 
 For non-DT, platform_data is used pass hardware configuration between board file and device 
driver. 
struct esdhc_platform_data { 
 unsigned int wp_gpio; 
 unsigned int cd_gpio; 
 enum wp_types wp_type; 
 enum cd_types cd_type; 
}; 
For DT probe, all these data should be retrieved from 
    DT 
        Bindings 
            • Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
• Documentation/devicetree/bindings/gpio/gpio.txt
Helper functions 
• of_get_property(), of_get_named_gpio(), of_property_read_u32() etc. 
• include/linux/of.h
platform_data is retrieved from DT 示例 i2c
Imx6qdl.dtsi

 

Run “cat cat /proc/iomem | grep i2c”

of_match_table defined for i2c_imx_driver

platform_driver_probe

i2c_imx_probe: apply resources, irq, add i2c adapt

imx6qdl-sabresd.dtsi

of_i2c_register_devices() parse i2c child nodes, get addr, irq etc. 
for_each_available_child_of_node{} loop 
-> request_module: load device driver 
-> i2c_new_device: generate device. 
-> driver probe 
From now on, it’s same as non-DT 
Child node wm8962 of i2c1 
imx6qdl-sabresd.dtsi

wm8962_set_pdata_from_of parse and get conf.

i2c adapt log

i2c device - wm8962 log

DTS 示例 gpio 
• gpio-cells: how many cells to specify a gpio 
• gpio-controller: specify its identity. 
• gpio-phandle : phandle to gpio controller node 
• single-gpio ::= <gpio-phandle> <gpio-specifier> 
• gpio-list ::= <single-gpio> [gpio-list] 
• gpio-specifier : Array of #gpio-cells specifying specific gpio, it’s “25 0” in this example.

Node using GPIOs: gpio-keys/volume-up uses the gpio pin “4 0” of controller &gpio1 
(imx6qdl-sabresd.dtsi)

 

• Pin allocation is managed by pinctrl system 
• Gpio is maintained by gpio drivers 
• different pin ranges managed by different gpio drivers. 
• let gpio drivers announce their pin ranges to the pinctrl subsystem and call 
'pinctrl_request_gpio' in order to request the corresponding pin before any 
gpio usage. 
• gpio controller can use a pinctrl phandle and pins to announce the pinrange 
to the pin ctrl subsystem 
qe_pio_e: gpio-controller@1460 { 
 #gpio-cells = <2>; 
 compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; 
 reg = <0x1460 0x18>; 
 gpio-controller; 
 gpio-ranges = <&pinctrl1 0 20 10>, <&pinctrl2 10 50 20>; 
 }
*<&pinctrl1 0 20 10>: from base pin 20 to pin 29 under pinctrl1 with gpio offset 0 is handled by 
this gpio controller

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: imx8qxp是一款高性能的嵌入式系统芯片,但在使用过程中出现系统卡顿的问题。导致系统卡顿的原因可能有很多,下面我将列举一些常见的可能原因以及解决方法。 首先,硬件配置不足可能导致系统卡顿。imx8qxp需要配备足够的内存和处理器资源来运行各种应用程序。如果内存不足,系统将无法处理大量数据,从而导致卡顿。解决方法是增加内存或者升级处理器。 其次,过多的后台运行程序也可能导致系统卡顿。如果有过多的应用程序在后台运行,会占用大量的系统资源,导致系统变得缓慢。解决方法是关闭不常用的后台应用程序或者通过任务管理器来管理后台运行的程序。 另外,软件问题也可能导致系统卡顿。可能是由于应用程序的bug或者操作系统的问题导致系统卡顿。解决方法是更新软件版本或者寻找替代性的软件应用。 最后,硬件故障也可能导致系统卡顿。如果有硬件组件损坏或者连接问题,系统可能无法正常运行,导致卡顿。解决方法是检查硬件连接,更换损坏的硬件组件。 综上所述,imx8qxp系统卡顿可能是由硬件配置不足、后台程序过多、软件问题或者硬件故障所致。通过增加内存、关闭不常用的后台应用程序、更新软件版本或者检查硬件连接,可以有效解决系统卡顿问题。 ### 回答2: imx8qxp系统卡顿可能是由以下几个原因引起的。 首先,系统卡顿可能是由于资源占用过高导致的。imx8qxp系统是一种高性能的处理器,但如果同时运行多个高性能应用程序或者进行大量的多任务处理,系统资源可能会被耗尽,导致系统卡顿。解决这个问题的方法是关闭一些不必要的应用程序或者进行资源管理,确保系统有足够的资源来运行。 其次,系统卡顿可能是由于系统计算能力不足引起的。imx8qxp是一种较新的处理器,但如果运行的应用程序或者任务过于复杂,处理器的计算能力可能不足以处理这些任务,从而导致系统响应迟缓。解决这个问题的方法是优化应用程序或者任务的代码,减少计算量,或者升级到更高性能的处理器。 最后,系统卡顿可能是由于软件冲突或者系统错误引起的。imx8qxp系统的稳定性可能受到安装的软件版本或者硬件驱动程序的影响。如果出现软件冲突或者系统错误,可能会导致系统卡顿或者崩溃。解决这个问题的方法是更新软件版本,检查并修复可能存在的软件冲突或者驱动程序错误。 综上所述,imx8qxp系统卡顿可能是由于资源占用过高、系统计算能力不足或者软件冲突引起的。解决这个问题的方法包括进行资源管理、优化任务代码、升级处理器、更新软件版本等。 ### 回答3: imx8qxp系统卡顿可能由以下几个原因引起: 1. 资源占用过高:imx8qxp系统资源有限,如果同时运行多个大型应用程序或者后台进程过多,会导致系统卡顿。解决方法可以是关闭不必要的应用程序或者优化应用程序的资源占用。 2. 内存不足:imx8qxp系统内存不足也会导致系统卡顿。可以通过清理内存、关闭不必要的后台进程或者增加系统内存解决。 3. 外部设备冲突:如果imx8qxp系统连接了大量外部设备,如USB设备、摄像头等,可能会出现冲突导致系统卡顿。可以尝试断开一些不必要的设备或者更换高质量的设备。 4. 软件问题:imx8qxp系统的操作系统或应用程序可能存在软件问题,例如程序错误、不兼容等。可以尝试更新系统或者应用程序来解决。 总之,当imx8qxp系统出现卡顿问题时,我们可以先检查资源占用情况,然后处理内存不足的问题,同时确保外部设备没有冲突,并且更新软件来解决潜在的问题。如果问题依然存在,可能需要联系厂商或专业人士进行进一步的故障排查和修复。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值