January 30, 2022

Orange Pi 4 (Rockchip 3399) USB and linux sources

I have gotten the itch to look at source code for the RK3399 usb devices. The TRM documents registers and the bits within them, but says nothing about data structures in memory that are specific to the hardware.

The trick with linux is that there are dozens of different USB drivers and it is all but impossible to figure out what driver to look at. I often resort to U-Boot sources for such things because they are both simpler and there are fewer of them. But it is by no means clear that U-Boot will include a usb driver, particularly for the RK3399.

Xulong linux sources

Since I am working with an Orange Pi board, this is not an unreasonable place to start looking. Years ago I downloaded their linux source tree, and still have it on my machine. Some searching led me to this file:
/u1/Projects/OrangePi/Xulong/linux-orangepi/arch/arm64/boot/dts/rockchip/rk3399.dtsi
This has entries for the four USB devices in the chip. Two of them for the USB-2.0 interfaces and two for the USB-3.0-OTG. For the latter, we see for the first of them:
usbdrd3_0: usb@fe800000 {
                compatible = "rockchip,rk3399-dwc3";
                #address-cells = <2>;
                #size-cells = <2>;
                ranges;
                clocks = <&cru SCLK_USB3OTG0_REF>, <&cru SCLK_USB3OTG0_SUSPEND>,
                         <&cru ACLK_USB3OTG0>, <&cru ACLK_USB3_RKSOC_AXI_PERF>,
                         <&cru ACLK_USB3>, <&cru ACLK_USB3_GRF>;
                clock-names = "ref_clk", "suspend_clk",
                              "bus_clk", "aclk_usb3_rksoc_axi_perf",
                              "aclk_usb3", "grf_clk";
                resets = <&cru SRST_A_USB3_OTG0>;
                reset-names = "usb3-otg";
                status = "disabled";

                usbdrd_dwc3_0: usb@fe800000 {
                        compatible = "snps,dwc3";
                        reg = <0x0 0xfe800000 0x0 0x100000>;
                        interrupts = ;
                        clocks = <&cru SCLK_USB3OTG0_REF>, <&cru ACLK_USB3OTG0>,
                                 <&cru SCLK_USB3OTG0_SUSPEND>;
                        clock-names = "ref", "bus_early", "suspend";
                        dr_mode = "otg";
                        phys = <&u2phy0_otg>, <&tcphy0_usb3>;
                        phy-names = "usb2-phy", "usb3-phy";
                        phy_type = "utmi_wide";
                        snps,dis_enblslpm_quirk;
                        snps,dis-u2-freeclk-exists-quirk;
                        snps,dis_u2_susphy_quirk;
                        snps,dis-del-phy-power-chg-quirk;
                        snps,dis-tx-ipgap-linecheck-quirk;
                        power-domains = <&power RK3399_PD_USB3>;
                        status = "disabled";
                };
        };
What particularly catches my eye is "rk3399-dwc3". Doing a search on that string leads me to the following, but it is a very small (203 line) file. A string inside labels it as "DesignWare USB3".
drivers/usb/dwc3/dwc3-of-simple.c
drivers/usb/dwc3/core.h
The core.h file has this for an event buffer entry:
union dwc3_event {
        u32                             raw;
        struct dwc3_event_type          type;
        struct dwc3_event_depevt        depevt;
        struct dwc3_event_devt          devt;
        struct dwc3_event_gevt          gevt;
};
This is promising, because I know that events are 32 bit objects.
struct dwc3_event_type {
        u32     is_devspec:1;
        u32     type:7;
        u32     reserved8_31:24;
} __packed;

Have any comments? Questions? Drop me a line!

Tom's electronics pages / [email protected]