【问题标题】:Linux Device Tree to Hardware MappingLinux 设备树到硬件映射
【发布时间】:2018-11-26 21:53:14
【问题描述】:

我想知道设备中的一些具体细节与硬件有什么关系,以及在哪里可以找到这些信息(如原理图、数据表等)。

下面给出了一个usb节点的例子:

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

【问题讨论】:

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


    【解决方案1】:

    现在我正在使用一个类似的平台 Allwinner A64,我正在尝试了解 DTS、时钟、重置的工作原理。幸运的是,您的问题出现在搜索引擎结果中。 Gaurav Pathak 的回答为我澄清了大部分问题,我想从他的观点延伸一点,以帮助那些试图填补桥接 DTS 和硬件空白的人。

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

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

    让我们仔细看看uart4node

    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 中。

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

        [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是一个管理时钟控制单元门控寄存器的宏。第 4 个参数,0x06c 指的是寄存器偏移量,第 5 个参数 BIT(20) 表示在 0x06c 的偏移量处的第 N 位(在本例中为 20)被调整为驱动 bus_uart4_clk .

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

    希望没有太多废话...如果我错了请纠正我。

    【讨论】:

      【解决方案2】:

      嗯,据我所知,在下面的结构中

      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 = &lt;&amp;ccu CLK_BUS_EHCI2&gt;, &lt;&amp;ccu CLK_BUS_OHCI2&gt;; 代表消费者时钟,即输入时钟,称为“phandle + 时钟说明符对”。正如您提到的 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 = &lt;1&gt;;代表多时钟输出,#clock-cells = &lt;0&gt;;是单时钟输出。
      ccu 结构只是一个例子。

      【讨论】:

        猜你喜欢
        • 2011-03-30
        • 2021-03-14
        • 1970-01-01
        • 1970-01-01
        • 2019-06-19
        • 1970-01-01
        • 1970-01-01
        • 2017-04-21
        • 1970-01-01
        相关资源
        最近更新 更多