Device Tree - dma

Device Tree是一種描述硬件的數據結構,它起源於 OpenFirmware (OF)。在Linux 2.6中,ARM架構的板極硬件細節過多地被硬編碼在arch/arm/plat-xxx和arch/arm/mach-xxx,採用Device Tree後,許多硬件的細節可以直接透過它傳遞給Linux,而不再需要在kernel中進行大量的冗餘編碼。Device Tree由一系列被命名的結點(node)和屬性(property)組成,而結點本身可包含子結點。所謂屬性,其實就是成對出現的name和value。
如果要使用Device Tree,首先用戶要了解自己的硬件配置和系統運行參數,並把這些信息組織成Device Tree source file。
Device Tree將會被通過DTC(Device Tree Compiler)編譯成適合機器處理的DTB(device tree blob)文件。
Device Tree不是必須要描述系統中的所有硬件信息,可以動態探測到的設備是不需要描述的,但是無法動態識別的,需要在device tree中描述。例如,USB device不需要描述,usb host controller不能被探測,需要描述。
下面給出一個Device Tree的模版:
/  
  name = "device-tree" 
  model = "MyBoardName" 
  compatible = "MyBoardFamilyName" 
  #address-cells = <2> 
  #size-cells = <2> 
  linux,phandle = <0>  
  chosen {
   name = "chosen" 
   bootargs = "root=/dev/sda2" 
   linux,phandle = <4>
   }
  cpus {
    #address-cells = <1>;
    #size-cells = <0>;
    cpu0:cpu@0x000 {
        device_type = "cpu";
        compatible = "arm,cortex-a7";
        reg = <0x000>;
        clock-latency = <40000>;
        clocks = <&cru ARMCLK>;
        resets = <&cru SRST_CORE0>;
    };
    memory {
    device_type = "memory";
    reg = <0x60000000 0x40000000>;
};
分析上面給出的例子,總結一下幾點:
1、device tree的基本單元是node。這些node被組織成樹狀結構,root node的node name是確定的,必須是“/”。除了root node,每個node都只有一個parent。一個device tree文件中只能有一個root node。
2、每個node中包含了若干的property/value來描述該node的一些特性。
2-1、每個node用節點名字(node name)標識,節點名字的格式是node-name@unit-address。
2-2、如果該node沒有reg屬性(後面會描述這個property),那麼該節點名字中必須不能包括@和unit-address。
2-3、對於cpu,其unit-address就是從0開始編址,以此加一。而具體的設備,其unit-address就是寄存器地址。
3、在一個樹狀結構的device tree中,要想唯一指定一個node必須使用full path。在上面的例子中,cpu node我們可以通過/cpus/cpu@0x000訪問。
4、屬性:
4-1、可能是空,也就是沒有值的定義。
4-2、屬性值是32bit unsigned integers可能是一個u32、u64的數值(值得一提的是cell這個術語,在Device Tree表示32bit的信息單位)。例如#address-cells = <1> 。如果一個device node中包含了有尋址需求(要定義reg property),那麼就必須要定義#address-cells和#size-cells這兩個屬性
4-3、屬性值是text string或者string list,可能是一個字符串。例如device_type = "cpu";

一個node被定義成如下:
[label:] node-name[@unit-address] { 
   [properties definitions] 
   [child nodes] 
}
“[]”表示option,label方便在dts文件中引用,一個dts文件可以嵌套多個node,並且可以通過include xxx.dtsi來包含其他的node(如果包含,dti中的內容將把dtsi覆蓋)
其中的相關的規則如下:
1、aliases 節點定義了一些別名。(當要引用一個node的時候要指明相對於root node的full path,如果多次引用,每次都要寫這麼複雜的字符串多少是有些麻煩,因此可以在aliases 節點定義一些設備節點full path的縮寫。)
2、memory device node是所有設備樹文件的必備節點,它定義了系統物理內存的layout。reg定義了該memory的起始地址和長度。其device_type必須等於memory。
3、device_type屬性定義了該node的設備類型,例如cpu、serial等。
4、reg屬性定義了訪問該device node的地址信息,該屬性的值被解析成任意長度的(address,size)數組,具體用多長的數據來表示address和size是在其parent node中定義(#address-cells和#size-cells)。reg描述了memory-mapped IO register的offset和length。
5、model屬性指明瞭該設備屬於哪個設備生產商的哪一個model。
6、compatible屬性,該屬性的值是string list,定義了一系列的modle(每個string是一個model)。這些字符串列表被操作系統用來選擇用哪一個driver來驅動該設備。compatible的作用就是,在uboot中的代碼能通過compatible屬性match到dts相同的driver。uboot代碼內容如下:
static const struct udevice_id rockchip_gpio_ids[] = {
{ .compatible = "rockchip,gpio-bank" },
{ }
};
U_BOOT_DRIVER(gpio_rockchip) = {
.name   = "gpio_rockchip",
.id = UCLASS_GPIO,
.of_match = rockchip_gpio_ids,
.ops    = &gpio_rockchip_ops,
.priv_auto_alloc_size = sizeof(struct rockchip_gpio_priv),
.probe  = rockchip_gpio_probe,
};
Device Tree顯示的內容如下:
  gpio0: gpio0@2007c000 {
        compatible = "rockchip,gpio-bank";
        reg = <0x2007c000 0x100>;
    interrupts = <GIC_SPI 36  IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&cru PCLK_GPIO0>;
        gpio-controller;
        #gpio-cells = <2>;
        interrupt-controller;
        #interrupt-cells = <2>;
    };
7、在dts文件中是用interrupt-parent這個屬性來標識,使interrupt source物理連接到interruptcontroller。因爲能夠產生中斷的device node沒有定義interrupt-parent的話,其interrupt-parent屬性就是跟隨parent node。因此,與其在所有的下游設備中定義interrupt-parent,不如統一在root node中定義了。
8、interrupts屬性有三個
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
第一個member表示該 interrupt 是 SPI 還是 PPI。
第二個member就是具體的中斷號了。查閱SoC的手冊就可以得到。(36 = number - 32)
第三個member指的是中斷的觸發方式,每個SoC是不同的,查閱SoC的手冊就可以知道了。
9、dmas = <&pdma 2>, <&pdma 3>;dma地址和dma通道選擇
--------------------- 
作者:Orangehaswing 
來源:CSDN 
原文:https://blog.csdn.net/gxlzyt123456/article/details/60141297 
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章