(1) 头文件
#include
#include
#include
#include
#include
#include
#include
#include
#include
头文件里面定义了dts文件中使用的宏,比如下面:
interrupts = ,
,
,
;
GIC_SPI和IRQ_TYPE_LEVEL_HIGH都是定义在头文件中的。
(2) 根节点
/ {
#address-cells = <2>;
#size-cells = <2>;
compatible = "rockchip,rk3288";
interrupt-parent = <&gic>;
........
}
#address-cells和#size-cells决定子节点的reg属性值为
< address1 length1 address2 length2>
compatible用来匹配machine_desc
interrupt-parent表示根节点所使用的中断控制器,如果子节点没有该属性,这和父节点共用。
(3) aliases(别名)
aliases {
ethernet0 = &gmac;
i2c0 = &i2c0;
i2c1 = &i2c1;
i2c2 = &i2c2;
i2c3 = &i2c3;
i2c4 = &i2c4;
i2c5 = &i2c5;
mshc0 = &emmc;
mshc1 = &sdmmc;
mshc2 = &sdio0;
mshc3 = &sdio1;
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
serial3 = &uart3;
serial4 = &uart4;
spi0 = &spi0;
spi1 = &spi1;
spi2 = &spi2;
};
定义节点别名
(4) arm-pmu(电源管理单元)
arm-pmu {
compatible = "arm,cortex-a12-pmu";
interrupts = ,
,
,
;
interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
};
这个节点的属性和属性值该如何定义?
"apm,potenza-pmu"
"arm,armv8-pmuv3"
"arm,cortex-a73-pmu"
"arm,cortex-a72-pmu"
"arm,cortex-a57-pmu"
"arm,cortex-a53-pmu"
"arm,cortex-a35-pmu"
"arm,cortex-a17-pmu"
"arm,cortex-a15-pmu"
"arm,cortex-a12-pmu"
"arm,cortex-a9-pmu"
"arm,cortex-a8-pmu"
"arm,cortex-a7-pmu"
"arm,cortex-a5-pmu"
"arm,arm11mpcore-pmu"
"arm,arm1176-pmu"
"arm,arm1136-pmu"
"brcm,vulcan-pmu"
"cavium,thunder-pmu"
"qcom,scorpion-pmu"
"qcom,scorpion-mp-pmu"
"qcom,krait-pmu"
然后根据cpu使用的arm核心版本来决定值,比如RK3288使用cortex-a12,所以选择"arm,cortex-a12-pmu"
为什么是三个值,每个值对应的含义是什么?
compatible = "arm,gic-400";
从上面的属性值可以找到中断控制器的类型为GIC (Generic Interrupt Controller),所以可以找到对应的说明文档kernel\Documentation\devicetree\bindings\interrupt-controller\arm,gic.txt
文档中说明GIC的**#interrupt-cells属性值应为3**,所以每个中断源对应三个值。
然后三个值对应的含义是什么,文档中也有解释。
1st cell:中断类型,0表示SPI中断,1表示PPI中断
2nd cell:该中断类型中的中断号,SPI中断的范围是[0-987], PPI中断范围是[0-15]
3rd cell : 标识, bit[3:0](1:上升沿触发 2:下降沿触发(SPI无效) 4:高电平触发 8:低电平触发(SPI无效) ) ; bit[15:8] (PPI中断掩码)
中断类型: SPI(GIC_SPI定义在arm-gic.h中),SPI表示该中断是所有cpu core共享的。
中断号: 151, RK3288 datasheet中给出的值是从0~159,该值具体如何定义还不清楚。
标识: 高电平,RK3288 datasheet中说“Input interrupt level is fixed , only high-level sensitive”(输入中断仅高电平有效)
interrupt-affinity属性用来关联中断和cpu core, 这个属性是和interrupts中的值一一对应的。即:
当超过一个SPI时interrupt-affinity属性必须出现。
(5) sdmmc(SDIO)
sdmmc: dwmmc@ff0c0000 {
compatible = "rockchip,rk3288-dw-mshc";
max-frequency = <150000000>;
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
<&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
fifo-depth = <0x100>;
interrupts = ;
reg = <0x0 0xff0c0000 0x0 0x4000>;
resets = <&cru SRST_MMC0>;
reset-names = "reset";
status = "disabled";
};
文档说明
kernel\Documentation\devicetree\bindings\mmc\rockchip-dw-mshc.txt
kernel\Documentation\devicetree\bindings\mmc\synopsy-dw-mshc.txt
kernel\Documentation\devicetree\bindings\mmc\mmc.txt
上面的文档对该节点中的属性都做了说明。
max-frequency: 最大时钟频率,查看datasheet
clocks: 指定时钟单元和时钟阀门,这个要和clock-name一一对应的。这里指定了4个属性值,对应到clock-name也是四个属性值。
biu: bus interface unit(总线接口单元)
ciu: card interface unit(卡接口单元)
cru: clock reset unit(时钟复位单元)
(6) spi
spi0: spi@ff110000 {
compatible = "rockchip,rk3288-spi", "rockchip,rk3066-spi";
clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
clock-names = "spiclk", "apb_pclk";
dmas = <&dmac_peri 11>, <&dmac_peri 12>;
dma-names = "tx", "rx";
interrupts = ;
pinctrl-names = "default";
pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
reg = <0x0 0xff110000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
总结:
(1) 上面的讲解主要是语法实践和如何来查找说明文档来进行配置。对于做二次开发的人来说主要是看芯片原厂给的文档和查看Documention\devicetree下的文档。当然也可以看datasheet, 只是没太大必要,而且很多芯片厂家不会提供完整的datasheet.
(2) 如果是芯片原厂工程师,主要是根据datasheet和Documention\devicetree下的文档来配置。有时候还要自定义属性。
(3) 属性值得配置一定要和驱动匹配。