PetaLinux學習筆記 2

現在遇到這樣一個問題,沒有USB,甚至於USB都沒有電壓輸出,檢查電路,USB供電是由一個TPS2051BDBV來控制的,這個芯片又是USB3320C來控制的,說明這個芯片沒有工作。經過一天的排查,最後終於找到原因了。是因爲沒有設置設備樹。設備樹這方面我並不是很懂,所以整理一下。
首先,先找到編譯出來的設備樹。文件是images/linux/system.dtb
在這篇文章 《設備樹(device tree)學習筆記》 找到了反向編譯工具fdtdump,使用fdtdump工具將其反向編譯。
結果就是這樣的:

$ fdtdump image/linux/system.dtb 
/dts-v1/;
// magic:		0xd00dfeed
// totalsize:		0x3681 (13953)
// off_dt_struct:	0xb8
// off_dt_strings:	0x22ec
// off_mem_rsvmap:	0x28
// version:		17
// last_comp_version:	16
// boot_cpuid_phys:	0x0
// size_dt_strings:	0x395
// size_dt_struct:	0x2234

/ {										// 根節點
    #address-cells = <0x00000001>;			// 這部分可以在官方手冊UG585/4.1 Address Map 章得到證實,尋址最大不超過FFFF_FFFF,所以是32位。而設備樹中cell規定爲32位,所以是1
    #size-cells = <0x00000001>;				// TODO: 這裏我是不是可以這麼理解,尋址只有32位,大小也超不過32位呢?這裏標記一下,等之後研究過MPU後再來處理這個。
    compatible = "xlnx,zynq-7000";			// 機器的標識,xlnx爲廠家名稱,後面的是板子的名字
    cpus {
        #address-cells = <0x00000001>;		// CPU 在32位總線上尋址
        #size-cells = <0x00000000>;			// 不在整個總線上佔有地址空間,所以是0?
        cpu@0 {
            compatible = "arm,cortex-a9";		// CPU的型號,這個就是和驅動用來配對的字符串。
            device_type = "cpu";				// 設備類型
            reg = <0x00000000>;					// 不懂,說是標識號
            clocks = <0x00000001 0x0000003d>;	// 這裏要參考build/tmp/work-shared/plnx-zynq7/kernel-source/arch/arm/boot/dts/zynq-7000.dtsi 這個文件的內容,文件中這個位置的數據是:clocks = <&clkc 3>;而這個clk也是有跡可循的。
            clock-latency = <0x000003e8>;		// 延遲?
            cpu0-supply = <0x00000002>;			// ??
            operating-points = <0x000a2c2a 0x00000002 0x00000003 0x636f7274>;	// ??
        };
        cpu@1 {
            compatible = "arm,cortex-a9";		// CPU的型號
            device_type = "cpu";				// 設備類型
            reg = <0x00000001>;					// 不懂,說是標識號
            clocks = <0x00000001 0x00000001>;	// 不懂
        };
    };
    fpga-full {
        compatible = "fpga-region";				// 應該是PL部分的接口
        fpga-mgr = <0x00000003>;
        #address-cells = <0x00000001>;
        #size-cells = <0x00000001>;
        ranges;
    };
    pmu@f8891000 {								// Performance Monitor Unit
        compatible = "arm,cortex-a9-pmu";
        interrupts = <0x00000000 0x00000006 0x00000083 0x00000032 0x00001000 0x64726567>;
        interrupt-parent = <0x00000004>;
        reg = <0xf8891000 0x00000002 0x756c6174 0x0000001b>;
    };
    fixedregulator {
        compatible = "regulator-fixed";
        regulator-name = "VCCPINT";
        regulator-min-microvolt = <0x000f4240>;
        regulator-max-microvolt = <0x000f4240>;
        regulator-boot-on;
        regulator-always-on;
        linux,phandle = <0x00000002>;
        phandle = <0x00000002>;
    };
    											// 先進微控制器總線體系結構(就是ARM的總線)
    amba {										// Advanced Microcontroller Bus Architecture
        u-boot,dm-pre-reloc;
        compatible = "simple-bus";
        #address-cells = <0x00000001>;
        #size-cells = <0x00000001>;
        interrupt-parent = <0x00000004>;
        ranges;
        adc@f8007100 {
            compatible = "xlnx,zynq-xadc-1.00.a";
            reg = <0xf8007100 0x00000078>;
            interrupts = <0x00000000 0x00000004 0x00000008>;
            interrupt-parent = <0x00000004>;
            clocks = <0x00000001 0x63616e40>;
        };
        can@e0008000 {
            compatible = "xlnx,zynq-can-1.0";
            status = "disabled";
            clocks = <0x00000001 0x00000003 0x636c6b00 0x00000008>;
            clock-names = "can_clk", "pclk";
            reg = <0xe0008000 0x00000078>;
            interrupts = <0x00000000 0x00000004 0x00000004>;
            interrupt-parent = <0x00000004>;
            tx-fifo-depth = <0x00000040>;
            rx-fifo-depth = <0x00000040>;
        };
        can@e0009000 {
            compatible = "xlnx,zynq-can-1.0";
            status = "disabled";
            clocks = <0x00000001 0x00000003 0x636c6b00 0x00000008>;
            clock-names = "can_clk", "pclk";
            reg = <0xe0009000 0x00000078>;
            interrupts = <0x00000000 0x00000004 0x00000004>;
            interrupt-parent = <0x00000004>;
            tx-fifo-depth = <0x00000040>;
            rx-fifo-depth = <0x00000040>;
        };
        gpio@e000a000 {
            compatible = "xlnx,zynq-gpio-1.0";
            #gpio-cells = <0x00000002>;
            clocks = <0x00000001 0x00000156>;
            gpio-controller;
            interrupt-controller;
            #interrupt-cells = <0x00000002>;
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000008 0x00000003>;
            reg = <0xe000a000 0x0000018c>;
            emio-gpio-width = <0x00000040>;
            gpio-mask-high = <0x00000000>;
            gpio-mask-low = <0x00005600>;
            linux,phandle = <0x00000005>;
            phandle = <0x00000005>;
        };
        i2c@e0004000 {
            compatible = "cdns,i2c-r1p10";
            status = "disabled";
            clocks = <0x00000001 0x00000083>;
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000008 0x00000003>;
            reg = <0xe0004000 0x00000000>;
            #address-cells = <0x00000001>;
            #size-cells = <0x00000000>;
        };
        i2c@e0005000 {
            compatible = "cdns,i2c-r1p10";
            status = "disabled";
            clocks = <0x00000001 0x00000083>;
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000008 0x00000003>;
            reg = <0xe0005000 0x00000000>;
            #address-cells = <0x00000001>;
            #size-cells = <0x00000000>;
        };
        interrupt-controller@f8f01000 {
            compatible = "arm,cortex-a9-gic";
            #interrupt-cells = <0x00000003>;
            interrupt-controller;
            reg = <0xf8f01000 0x00000003 0x00000003 0x00000003>;
            num_cpus = <0x00000002>;
            num_interrupts = <0x00000060>;
            linux,phandle = <0x00000004>;
            phandle = <0x00000004>;
        };
        cache-controller@f8f02000 {
            compatible = "arm,pl310-cache";
            reg = <0xf8f02000 0x00000078>;
            interrupts = <0x00000000 0x0000000c 0x00000002>;
            arm,data-latency = <0x00000003 0x0000000c 0x00000002>;
            arm,tag-latency = <0x00000002 0x00000000 0x00000200>;
            cache-unified;
            cache-level = <0x00000002>;
        };
        memory-controller@f8006000 {
            compatible = "xlnx,zynq-ddrc-a05";
            reg = <0xf8006000 0x6f636d63>;
        };
        ocmc@f800c000 {
            compatible = "xlnx,zynq-ocmc-1.0";
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000008 0x00000002>;
            reg = <0xf800c000 0x73657269>;
        };
        serial@e0000000 {
            compatible = "xlnx,xuartps", "cdns,uart-r1p8";
            status = "disabled";
            clocks = <0x00000001 0x00000003 0x5f636c6b 0x00000008>;
            clock-names = "uart_clk", "pclk";
            reg = <0xe0000000 0x00000078>;
            interrupts = <0x00000000 0x00000001 0x30303000>;
        };
        serial@e0001000 {
            compatible = "xlnx,xuartps", "cdns,uart-r1p8";
            status = "okay";
            clocks = <0x00000001 0x00000003 0x5f636c6b 0x00000008>;
            clock-names = "uart_clk", "pclk";
            reg = <0xe0001000 0x00000078>;
            interrupts = <0x00000000 0x00000007 0x00000003>;
            device_type = "serial";
            port-number = <0x00000000>;
        };
        spi@e0006000 {
            compatible = "xlnx,zynq-spi-r1p6";
            reg = <0xe0006000 0x0000011b>;
            status = "disabled";
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000010 0x00000001>;
            clocks = <0x00000001 0x00000003 0x636c6b00 0x00000004>;
            clock-names = "ref_clk", "pclk";
            #address-cells = <0x00000001>;
            #size-cells = <0x00000000>;
        };
        spi@e0007000 {
            compatible = "xlnx,zynq-spi-r1p6";
            reg = <0xe0007000 0x0000011b>;
            status = "disabled";
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000010 0x00000001>;
            clocks = <0x00000001 0x00000003 0x636c6b00 0x00000004>;
            clock-names = "ref_clk", "pclk";
            #address-cells = <0x00000001>;
            #size-cells = <0x00000000>;
        };
        spi@e000d000 {
            clock-names = "ref_clk", "pclk";
            clocks = <0x00000001 0x00000003 0x2c7a796e 0x00000003>;
            compatible = "xlnx,zynq-qspi-1.0";
            status = "okay";
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000008 0x00000003>;
            reg = <0xe000d000 0x00000000>;
            #address-cells = <0x00000001>;
            #size-cells = <0x00000000>;
            is-dual = <0x00000000>;
            num-cs = <0x00000001>;
            spi-rx-bus-width = <0x00000004>;
            spi-tx-bus-width = <0x00000004>;
            flash@0 {
                compatible = "n25q512a", "micron,m25p80";
                reg = <0x00000000>;
                #address-cells = <0x00000001>;
                #size-cells = <0x00000001>;
                spi-max-frequency = <0x02faf080>;
                partition@0x00000000 {
                    label = "boot";
                    reg = <0x00000000 0x70617274>;
                };
                partition@0x00040000 {
                    label = "bootenv";
                    reg = <0x00040000 0x70617274>;
                };
                partition@0x00060000 {
                    label = "kernel";
                    reg = <0x00060000 0x00000002>;
                };
            };
        };
        memory-controller@e000e000 {
            #address-cells = <0x00000001>;
            #size-cells = <0x00000001>;
            status = "disabled";
            clock-names = "memclk", "aclk";
            clocks = <0x00000001 0x00000003 0x706c3335 0x00000003>;
            compatible = "arm,pl353-smc-r2p1";
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000000 0x00000032>;
            ranges;
            reg = <0xe000e000 0x68406531>;
            flash@e1000000 {
                status = "disabled";
                compatible = "arm,pl353-nand-r2p1";
                reg = <0xe1000000 0x00000000>;
                #address-cells = <0x00000001>;
                #size-cells = <0x00000001>;
            };
            flash@e2000000 {
                status = "disabled";
                compatible = "cfi-flash";
                reg = <0xe2000000 0x00000000>;
                #address-cells = <0x00000001>;
                #size-cells = <0x00000001>;
            };
        };
        ethernet@e000b000 {
            compatible = "cdns,zynq-gem", "cdns,gem";
            reg = <0xe000b000 0x0000011b>;
            status = "okay";
            interrupts = <0x00000000 0x00000018 0x00000001>;
            clocks = <0x00000001 0x00000001 0x00000122 0x5f636c6b 0x00000000 0x0000000f>;
            clock-names = "pclk", "hclk", "tx_clk";
            #address-cells = <0x00000001>;
            #size-cells = <0x00000000>;
            enet-reset = <0x00000005 0x00000009 0x00000000>;
            phy-mode = "rgmii-id";
            xlnx,ptp-enet-clock = <0x069f6bcb>;
            local-mac-address = [00 0a 35 00 22 01];
        };
        ethernet@e000c000 {
            compatible = "cdns,zynq-gem", "cdns,gem";
            reg = <0xe000c000 0x0000011b>;
            status = "disabled";
            interrupts = <0x00000000 0x00000018 0x00000001>;
            clocks = <0x00000001 0x00000001 0x00000122 0x5f636c6b 0x00000000 0x0000000f>;
            clock-names = "pclk", "hclk", "tx_clk";
            #address-cells = <0x00000001>;
            #size-cells = <0x00000000>;
        };
        mmc@e0100000 {
            compatible = "arasan,sdhci-8.9a";
            status = "okay";
            clock-names = "clk_xin", "clk_ahb";
            clocks = <0x00000001 0x00000003 0x00000003 0x00000018>;
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000008 0x00000003>;
            reg = <0xe0100000 0x0000029b>;
            xlnx,has-cd = <0x00000001>;
            xlnx,has-power = <0x00000000>;
            xlnx,has-wp = <0x00000000>;
        };
        mmc@e0101000 {
            compatible = "arasan,sdhci-8.9a";
            status = "okay";
            clock-names = "clk_xin", "clk_ahb";
            clocks = <0x00000001 0x00000003 0x00000003 0x0000002f>;
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000008 0x00000003>;
            reg = <0xe0101000 0x0000029b>;
            xlnx,has-cd = <0x00000000>;
            xlnx,has-power = <0x00000000>;
            xlnx,has-wp = <0x00000000>;
        };
		slcr@f8000000 {
            u-boot,dm-pre-reloc;
            #address-cells = <0x00000001>;
            #size-cells = <0x00000001>;
            compatible = "xlnx,zynq-slcr", "syscon", "simple-mfd";
            reg = <0xf8000000 0x00000071>;
            ranges;
            linux,phandle = <0x00000006>;
            phandle = <0x00000006>;
            clkc@100 {
                u-boot,dm-pre-reloc;
                #clock-cells = <0x00000001>;
                compatible = "xlnx,ps7-clkc";
                fclk-enable = <0x00000000>;
                clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci", "lqspi", "smc", "pcap", "gem0", "gem1", "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper", "swdt", "dbg_trc", "dbg_apb";
                reg = <0x00000100 0x000002ee>;
                ps-clk-frequency = <0x01fca055>;
                linux,phandle = <0x00000001>;
                phandle = <0x00000001>;
            };
            rstc@200 {
                compatible = "xlnx,zynq-reset";
                reg = <0x00000200 0x000002ff>;
                #reset-cells = <0x00000001>;
                syscon = <0x00000006>;
            };
            pinctrl@700 {
                compatible = "xlnx,pinctrl-zynq";
                reg = <0x00000700 0x0000030c>;
                syscon = <0x00000006>;
            };
        };
        dmac@f8003000 {
            compatible = "arm,pl330", "arm,primecell";
            reg = <0xf8003000 0x00000083>;
            interrupt-parent = <0x00000004>;
            interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3", "dma4", "dma5", "dma6", "dma7";
            interrupts = <0x00000000 0x0000000e 0x00000004 0x00000000 0x00000028 0x00000004 0x00000000 0x00000004 0x00000004 0x00000004 0x00000008 0x00000003 0x70636c6b 0x64657663 0x00000003 0x2c7a796e 0x00000000 0x00000004 0x00000000 0x00000008 0x00000003 0x0000000c 0x00000010 0x00000012 0x7265665f 0x6c6b3100 0x00000003>;
            #dma-cells = <0x00000001>;
            #dma-channels = <0x00000008>;
            #dma-requests = <0x00000004>;
            clocks = <0x00000001 0x00000122>;
            clock-names = "apb_pclk";
        };
        devcfg@f8007000 {
            compatible = "xlnx,zynq-devcfg-1.0";
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000008 0x00000003>;
            reg = <0xf8007000 0x00000036>;
            clocks = <0x00000001 0x00000001 0x00000001 0x00000122 0x30006663 0x6c6b3300 0x00000006 0x00000003 0x00000003 0x65406638>;
            clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
            syscon = <0x00000006>;
            linux,phandle = <0x00000003>;
            phandle = <0x00000003>;
        };
        efuse@f800d000 {
            compatible = "xlnx,zynq-efuse";
            reg = <0xf800d000 0x74696d65>;
        };
        timer@f8f00200 {
            compatible = "arm,cortex-a9-global-timer";
            reg = <0xf8f00200 0x00000078>;
            interrupts = <0x00000001 0x00000004 0x00000008>;
            interrupt-parent = <0x00000004>;
            clocks = <0x00000001 0x74696d65>;
        };
        timer@f8001000 {
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x0000000b 0x00000004 0x63646e73 0x00000008 0x00000003 0x00001000 0x72406638 0x00000004>;
            compatible = "cdns,ttc";
            clocks = <0x00000001 0x00000032>;
            reg = <0xf8001000 0x74696d65>;
        };
        timer@f8002000 {
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000026 0x00000004 0x63646e73 0x00000008 0x00000003 0x00001000 0x72406638 0x00000004>;
            compatible = "cdns,ttc";
            clocks = <0x00000001 0x00000032>;
            reg = <0xf8002000 0x74696d65>;
        };
        timer@f8f00600 {
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000001 0x00000018 0x65782d61>;
            compatible = "arm,cortex-a9-twd-timer";
            reg = <0xf8f00600 0x00000036>;
            clocks = <0x00000001 0x75736240>;
        };
        usb@e0002000 {
            compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
            status = "okay";
            clocks = <0x00000001 0x00000083>;
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000008 0x00000003>;
            reg = <0xe0002000 0x0000034a>;
            phy_type = "ulpi";
            usb-reset = <0x00000005 0x00000001 0x00000000>;
        };
        usb@e0003000 {
            compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
            status = "disabled";
            clocks = <0x00000001 0x00000083>;
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000008 0x00000003>;
            reg = <0xe0003000 0x0000034a>;
            phy_type = "ulpi";
        };
        watchdog@f8005000 {
            clocks = <0x00000001 0x0000001b>;
            compatible = "cdns,wdt-r1p2";
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000008 0x00000003>;
            reg = <0xf8005000 0x0000035d>;
            timeout-sec = <0x0000000a>;
        };
    };
    chosen {
        bootargs = "console=ttyPS0,115200 earlyprintk";
        stdout-path = "serial0:115200n8";
    };
    aliases {
        ethernet0 = "/amba/ethernet@e000b000";
        serial0 = "/amba/serial@e0001000";
        spi0 = "/amba/spi@e000d000";
    };
    memory {
        device_type = "memory";
        reg = <0x00000000 0x00000009>;
    };
};

通過閱讀《5. 設備樹的規範 - DTS格式》,可以對設備樹比較好的瞭解一番。感謝Jalyn_Fang的文章,講的非常詳細。但是根節點的#address-cells, #size-cells看的我已一倆矇蔽,找到這個例子:由《設備樹中#address-cells和#size-cells作用》文中舉出例子。這樣很好理解

相對的我也在內核的代碼裏找到了一官方的板子的設備樹文件:

		usb@e0002000 {
            compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
            status = "okay";
            clocks = <0x00000001 0x00000083>;
            interrupt-parent = <0x00000004>;
            interrupts = <0x00000000 0x00000008 0x00000003>;
            reg = <0xe0002000 0x0000034a>;
            phy_type = "ulpi";
            usb-reset = <0x00000005 0x00000001 0x00000000>;
        };

可以看到status是OK,說明這個部分已經啓用了。
全局搜索xlnx,zynq-usb-2.20a

Searching 61690 files for "xlnx,zynq-usb-2.20a"

/home/godenfreemans/FTP_Folder/project_1/project_1.petalinux/build/tmp/work-shared/plnx-zynq7/kernel-source/arch/arm/boot/dts/zynq-7000.dtsi:
  393  
  394  		usb0: usb@e0002000 {
  395: 			compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
  396  			status = "disabled";
  397  			clocks = <&clkc 28>;
  ...
  403  
  404  		usb1: usb@e0003000 {
  405: 			compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
  406  			status = "disabled";
  407  			clocks = <&clkc 29>;

/home/godenfreemans/FTP_Folder/project_1/project_1.petalinux/build/tmp/work-shared/plnx-zynq7/kernel-source/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt:
   14  	"qcom,ci-hdrc"
   15  	"chipidea,usb2"
   16: 	"xlnx,zynq-usb-2.20a"
   17  - reg: base address and length of the registers
   18  - interrupts: interrupt for the USB controller

/home/godenfreemans/FTP_Folder/project_1/project_1.petalinux/build/tmp/work-shared/plnx-zynq7/kernel-source/drivers/usb/chipidea/ci_hdrc_usb2.c:
   39  static const struct of_device_id ci_hdrc_usb2_of_match[] = {
   40  	{ .compatible = "chipidea,usb2"},
   41: 	{ .compatible = "xlnx,zynq-usb-2.20a", .data = &ci_zynq_pdata},
   42  	{ }
   43  };

4 matches across 3 files

跳轉到文檔 /home/godenfreemans/FTP_Folder/project_1/project_1.petalinux/build/tmp/work-shared/plnx-zynq7/kernel-source/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
裏面有說明:

Recommended properies:
- phy_type: the type of the phy connected to the core. Should be one
  of "utmi", "utmi_wide", "ulpi", "serial" or "hsic". Without this
  property the PORTSC register won't be touched.
- dr_mode: One of "host", "peripheral" or "otg". Defaults to "otg"

不供電可能是因爲默認爲OTG模式。

Optional properties:
- clocks: reference to the USB clock
- phys: reference to the USB PHY
- phy-names: should be "usb-phy"
- vbus-supply: reference to the VBUS regulator
- maximum-speed: limit the maximum connection speed to "full-speed".
- tpl-support: TPL (Targeted Peripheral List) feature for targeted hosts
- itc-setting: interrupt threshold control register control, the setting
  should be aligned with ITC bits at register USBCMD.
- ahb-burst-config: it is vendor dependent, the required value should be
  aligned with AHBBRST at SBUSCFG, the range is from 0x0 to 0x7. This
  property is used to change AHB burst configuration, check the chipidea
  spec for meaning of each value. If this property is not existed, it
  will use the reset value.
- tx-burst-size-dword: it is vendor dependent, the tx burst size in dword
  (4 bytes), This register represents the maximum length of a the burst
  in 32-bit words while moving data from system memory to the USB
  bus, the value of this property will only take effect if property
  "ahb-burst-config" is set to 0, if this property is missing the reset
  default of the hardware implementation will be used.
- rx-burst-size-dword: it is vendor dependent, the rx burst size in dword
  (4 bytes), This register represents the maximum length of a the burst
  in 32-bit words while moving data from the USB bus to system memory,
  the value of this property will only take effect if property
  "ahb-burst-config" is set to 0, if this property is missing the reset
  default of the hardware implementation will be used.
- extcon: phandles to external connector devices. First phandle should point to
  external connector, which provide "USB" cable events, the second should point
  to external connector device, which provide "USB-HOST" cable events. If one
  of the external connector devices is not required, empty <0> phandle should
  be specified.
- phy-clkgate-delay-us: the delay time (us) between putting the PHY into
  low power mode and gating the PHY clock.
- non-zero-ttctrl-ttha: after setting this property, the value of register
  ttctrl.ttha will be 0x7f; if not, the value will be 0x0, this is the default
  value. It needs to be very carefully for setting this property, it is
  recommended that consult with your IC engineer before setting this value.
  On the most of chipidea platforms, the "usage_tt" flag at RTL is 0, so this
  property only affects siTD.
  If this property is not set, the max packet size is 1023 bytes, and if
  the total of packet size for pervious transactions are more than 256 bytes,
  it can't accept any transactions within this frame. The use case is single
  transaction, but higher frame rate.
  If this property is set, the max packet size is 188 bytes, it can handle
  more transactions than above case, it can accept transactions until it
  considers the left room size within frame is less than 188 bytes, software
  needs to make sure it does not send more than 90%
  maximum_periodic_data_per_frame. The use case is multiple transactions, but
  less frame rate.

i.mx specific properties
- fsl,usbmisc: phandler of non-core register device, with one
  argument that indicate usb controller index
- disable-over-current: disable over current detect
- over-current-active-high: over current signal polarity is high active,
  typically over current signal polarity is low active.
- external-vbus-divider: enables off-chip resistor divider for Vbus

剛剛發現可以掛代理了,在Google上搜到了這個:《Zynq Linux USB Device Driver》
有給出要設置爲主機模式需要的設備樹如何寫。

    usb_0: usb@e0002000 {
         compatible = "xlnx,zynq-usb-2.20.a", "chipidea,usb2";
         clocks = <&clkc 28>;
         dr_mode = "host";
         interrupt-parent = <&intc>;
         interrupts = <0 21 4>;
         reg = <0xe0002000 0x1000>;
         usb-phy = <&usb_phy0>;
     };
 
 usb_phy0: phy0 {
    compatible = "ulpi-phy";
    #phy-cells = <0>;
    reg = <0xe0002000 0x1000>;
    view-port = <0x170>;
    drv-vbus;
}

其中就出現了dr_mode,比起目前的文件多了

dr_mode = "host";
view-port = <0x170>;
drv-vbus;

有比較明顯不同的:

compatible = "ulpi-phy";

dr_mode,USB模式,view-port 可以在UG585中找到,寄存器的地址是0xE0002170。搜索這個參數:

/home/godenfreemans/FTP_Folder/project_1/project_1.petalinux/build/tmp/work-shared/plnx-zynq7/kernel-source/drivers/usb/phy/phy-ulpi.c:
  334  		return PTR_ERR(uphy->regs);
  335  
  336: 	ret = of_property_read_u32(np, "view-port", &uphy->vp_offset);
  337  	if (IS_ERR(uphy->regs)) {
  338: 		dev_err(&pdev->dev, "view-port register not specified\n");
  339  		return PTR_ERR(uphy->regs);
  340  	}

可以看出,這個是一個偏移量,所以view-port = <0x170>;就說得通了。這個文件名字是phy-ulpi所以compatible = "ulpi-phy";這個也說的通把。最後就是`drv-vbus:

/home/godenfreemans/FTP_Folder/project_1/project_1.petalinux/build/tmp/work-shared/plnx-zynq7/kernel-source/drivers/usb/phy/phy-ulpi.c:
  340  	}
  341  
  342: 	flag = of_property_read_bool(np, "drv-vbus");
  343  	if (flag)
  344  		uphy->flags |= ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT;

這個是一個bool型的參數:

static inline bool of_property_read_bool(const struct device_node *np,
					 const char *propname)
{
	struct property *prop = of_find_property(np, propname, NULL);

	return prop ? true : false;
}

這個參數只要寫在設備樹中,就是1。之後設置了兩個標誌位:ULPI_OTG_DRVVBUSULPI_OTG_DRVVBUS_EXT,而這兩個參數,在USB3320中也可以找到,不如說這個是ulpi的一部分,在這裏插入圖片描述
這兩個信號貌似是一樣的,用來外部啓動5V供電的。這樣5V就可以供電了。說起來OTG也是向外部供電,所以dr_mode不設置應該也是可以的。

再翻一下這個文件,發現一開始有枚舉:

static struct ulpi_info ulpi_ids[] = {
	ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"),
	ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"),
	ULPI_INFO(ULPI_ID(0x0424, 0x0007), "SMSC USB3320"),
	ULPI_INFO(ULPI_ID(0x0424, 0x0009), "SMSC USB334x"),
	ULPI_INFO(ULPI_ID(0x0451, 0x1507), "TI TUSB1210"),
};

開發板上的就是這個芯片。而在函數ulpi_init中也有遍歷

	for (i = 0; i < ARRAY_SIZE(ulpi_ids); i++) {
		if (ulpi_ids[i].id == ULPI_ID(vid, pid)) {
			pr_info("Found %s ULPI transceiver.\n",
				ulpi_ids[i].name);
			break;
		}
	}

這樣就說的通了,難怪之前在USB文件夾中沒有找到這個以這個芯片命名的文件。而。compatible = "ulpi-phy"自然就是必須的了。
加上這三個去編譯不通過,對照了一下,發現忽略了一個東西:

usb-phy = <&usb_phy0>

找一下

/home/godenfreemans/FTP_Folder/project_1/project_1.petalinux/build/tmp/work-shared/plnx-zynq7/kernel-source/drivers/usb/chipidea/core.c:
  939  		ci->usb_phy = ci->platdata->usb_phy;
  940  	} else {
  941: 		ci->phy = devm_phy_get(dev->parent, "usb-phy");
  942  		ci->usb_phy = devm_usb_get_phy(dev->parent, USB_PHY_TYPE_USB2);

這些東西不能直接添加在usb中,我想是因爲ulpi的寄存器不能映射在USB這個外設上,但是它可以被USB間接的存取。所以是一個子節點。直接添加Xilinx給的東西是不能通過編譯的。需要稍微修改一下,

/include/ "system-conf.dtsi"

/{
	aliases {
		usb0 = &usb0;
	};
	usb_phy0: usb_phy@0 {
		compatible = "ulpi-phy";
		#phy-cells = <0>;
		reg = <0xe0002000 0x1000>;
		view-port = <0x0170>;
		drv-vbus;
	};
};

&usb0 {
	compatible = "xlnx,zynq-usb-2.20.a", "chipidea,usb2";
	clocks = <&clkc 28>;
	dr_mode = "host";
	interrupt-parent = <&intc>;
	interrupts = <0 21 4>;
	reg = <0xe0002000 0x1000>;
	usb-phy = <&usb_phy0>;
};

但是還是不工作,我尋思着有啥問題呢,找來找去都沒發現問題。
吃完飯後重新看了一遍生成的system.dtb。偶然發現這個東西有點奇怪啊。xlnx,zynq-usb-2.20.a這個.是哪裏冒出來的,我還去官網確認了一下有,但是全局搜索這個沒有找到對應的文件。這裏有問題,把這裏改一下。

/include/ "system-conf.dtsi"

/{
	aliases {
		usb0 = &usb0;
	};
	usb_phy0: usb_phy@0 {
		compatible = "ulpi-phy";
		#phy-cells = <0>;
		reg = <0xe0002000 0x1000>;
		view-port = <0x0170>;
		drv-vbus;
	};
};

&usb0 {
	compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
	clocks = <&clkc 28>;
	dr_mode = "host";
	interrupt-parent = <&intc>;
	interrupts = <0 21 4>;
	reg = <0xe0002000 0x1000>;
	usb-phy = <&usb_phy0>;
};

現在USB可以正常工作了。官方文檔挖坑了?

root@project_1:/proc/bus/pci# dmesg | grep USB
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
Found SMSC USB3320 ULPI transceiver.
ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1
ci_hdrc ci_hdrc.0: USB 2.0 started, EHCI 1.00
hub 1-0:1.0: USB hub found
usbhid: USB HID core driver
usb 1-1: new high-speed USB device number 2 using ci_hdrc
hub 1-1:1.0: USB hub found
usb 1-1.1: new high-speed USB device number 3 using ci_hdrc
usb-storage 1-1.1:1.0: USB Mass Storage device detected

插在上面的U盤已經被識別出來了。USB部分就是OK的了。
說起來我的SPI好像也沒工作,SPI的設備樹配置的是:

			flash@0 {
                compatible = "n25q512a", "micron,m25p80";
                reg = <0x00000000>;
                #address-cells = <0x00000001>;
                #size-cells = <0x00000001>;
                spi-max-frequency = <0x02faf080>;
                partition@0x00000000 {
                    label = "boot";
                    reg = <0x00000000 0x70617274>;
                };
                partition@0x00040000 {
                    label = "bootenv";
                    reg = <0x00040000 0x70617274>;
                };
                partition@0x00060000 {
                    label = "kernel";
                    reg = <0x00060000 0x00000002>;
                };
            };

這個n25q512amicron,m25p80肯定不對,下一篇再來修復它。

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