Linux设备树到硬件的映射

时间:2018-11-26 21:53:14

标签: linux-device-driver embedded-linux device-driver

我想知道设备中的一些特定细节与硬件有关,以及在何处找到此信息(例如原理图,数据表等)。

下面是一个usb节点的示例: enter image description here

在上图中,我想知道如何在硬件上找到CLK_BUS_OHCI2RST_BUS_EHCI2。如果转到包含文件,则会得到一个值(CLK_BUS_OHCI2 = 39),但是我不确定这与实际硬件有何关系。像是哪个寄存器或哪个引脚等等。

2 个答案:

答案 0 :(得分:3)

如今,我正在使用类似的平台Allwinner A64,并且我试图了解DTS,时钟和重置的工作方式。幸运的是,您的问题出现在搜索引擎结果中。 Gaurav Pathak的回答为我澄清了大部分事情,我想从他的观点出发进一步扩展一点,以帮助那些试图填补桥接DTS和硬件空白的人。

我将参考Linux kernel 5.7Allwinner A64 User Manual (v1.1)

uart4ehci2之间,在节点定义方面有相似之处;例如,我们在两个属性中都具有clocksresets的属性。但是ccu的时钟输出用法实现了不同。

让我们仔细看看uart4 node

uart4: serial@1c29000 {
        compatible = "snps,dw-apb-uart";
        reg = <0x01c29000 0x400>;
        interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
        reg-shift = <2>;
        reg-io-width = <4>;
        clocks = <&ccu CLK_BUS_UART4>;
        resets = <&ccu RST_BUS_UART4>;
        status = "disabled";
    };

现在我们已经知道CLK_BUS_UART4中包含了include/dt-bindings/clock/sun50i-a64-ccu.h

<&ccu CLK_BUS_UART4>

进一步搜索CLK_BUS_UART4,发现include/dt-bindings/clock/sun50i-a64-ccu.h也间接(通过drivers/clk/sunxi-ng/ccu-sun50i-a64.h)包含在drivers/clk/sunxi-ng/ccu-sun50i-a64.c中。

然后可以像下面(L807 @ ccu-sun50i-a64.c)一样引用CLK_BUS_UART4

    [CLK_BUS_UART4] = &bus_uart4_clk.common.hw

但是bus_uart4_clk是什么?让我们看看。

它在L381 @ ccu-sun50i-a64.c中定义。看起来是这样:

    static SUNXI_CCU_GATE(bus_uart4_clk,    "bus-uart4",    "apb2",
              0x06c, BIT(20), 0);

SUNXI_CCU_GATE是一个宏,用于管理时钟控制单元的选通寄存器。第四个参数0x06c指向寄存器偏移量,第五个参数BIT(20)表示偏移量0x06c的第 N 位(在这种情况下为20)为调整后可以驱动bus_uart4_clk

Allwinner A64 UART4 CCU Gating Register Description

resets属性同样适用。举一个具体的例子;只需在Linux内核源代码中搜索RST_BUS_UART40x2d8,然后查看《 A64用户手册》第142页的底部。

我希望不要胡说八道...如果我错了,请纠正我。

答案 1 :(得分:1)

据我在以下结构中所知

ehci2: usb@01c1c000 {
            compatible = "allwinner,sun8i-h3-ehci", "generic-ehci";
            reg = <0x01c1c000 0x100>;
            interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
            clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>;
            resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>;
            phys = <&usbphy 2>;
            phy-names = "usb";
            status = "disabled";
        };

clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>;代表使用者时钟,即输入时钟,称为“虚拟机+时钟说明符对”。正如您提到的CLK_BUS_OHCI2的值为39,这意味着USB控制器将从ccu时钟源的输出39中获取输入时钟。

在您发布上述屏幕快照的dtsi文件中,应该有一个定义ccu的结构,如下所示:

ccu: clk@01c20060 {
            #clock-cells = <1>;
            compatible = "allwinner,sun7i-a20-ahb-gates-clk";
            reg = <0x01c20060 0x8>;
            clocks = <&ahb>;
            clock-output-names = "ahb_usb0", "ahb_ehci0",
                "ahb_ohci0", "ahb_ehci1", "ahb_ohci1",
                "ahb_ss", "ahb_dma", "ahb_bist", "ahb_mmc0",
                "ahb_mmc1", "ahb_mmc2", "ahb_mmc3", "ahb_ms",
                "ahb_nand", "ahb_sdram", "ahb_ace",
                "ahb_emac", "ahb_ts", "ahb_spi0", "ahb_spi1",
                "ahb_spi2", "ahb_spi3", "ahb_sata",
                "ahb_hstimer", "ahb_ve", "ahb_tvd", "ahb_tve0",
                "ahb_tve1", "ahb_lcd0", "ahb_lcd1", "ahb_csi0",
                "ahb_csi1", "ahb_hdmi1", "ahb_hdmi0",
                "ahb_de_be0", "ahb_de_be1", "ahb_de_fe0",
                "ahb_de_fe1", "ahb_gmac", "ahb_ehci2",
                "ahb_mali";
        };

在上述结构中,有多个时钟源输出,因此上述USB控制器应使用时钟源39进行时钟输入,请注意,#clock-cells = <1>;代表多个时钟输出,#clock-cells = <0>;代表单时钟输出。
ccu结构只是一个例子。