Hello,

Allwinner V3s shares one USB port with MUSB OTG module and EHCI/OHCI.
The default route of USB-PHY is to OTG module so we have to add workaround
to sys/dev/fdt/ehci_fdt.c that the port connects to host controller.

(reference: sun4i_usb_phy0_reroute() at drivers/phy/allwinner/phy-sun4i-usb.c,
Linux-5.0-RC6 code)

Index: ehci_fdt.c
===================================================================
RCS file: /cvs/src/sys/dev/fdt/ehci_fdt.c,v
retrieving revision 1.4
diff -u -p -u -r1.4 ehci_fdt.c
--- ehci_fdt.c  6 Aug 2018 10:52:30 -0000       1.4
+++ ehci_fdt.c  20 Feb 2019 10:42:49 -0000
@@ -254,6 +254,57 @@ ehci_init_phys(struct ehci_fdt_softc *sc
 #define  SUNXI_AHB_INCR8       (1 << 10)
 #define  SUNXI_AHB_INCR16      (1 << 11)
 
+#define SUNXI_OTG_CTL          0x020
+#define  SUNXI_ROUTE_MUSB      (1 << 0)
+
+/*
+ * Allwinner V3s shares one USB port with MUSB OTG module and OHCI/EHCI.
+ * Different from other Allwinner SoCs, V3s has no dedicated port connected
+ * to host controller. And default port routing is to MUSB OTG.
+ * So this workaround is needed.
+ */
+void
+sun4i_port_routing(struct ehci_fdt_softc *sc, uint32_t *cells)
+{
+       bus_space_tag_t iot;
+       bus_space_handle_t ioh;
+       int     idx, len, node;
+       uint32_t *reg;
+       uint32_t val;
+
+       node = OF_getnodebyphandle(cells[0]);
+       if (node == 0)
+               return;
+
+       if (!OF_is_compatible(node, "allwinner,sun8i-v3s-usb-phy"))
+               return;
+
+       idx = OF_getindex(node, "phy_ctrl", "reg-names");
+       if (idx < 0)
+               return;
+
+       len = OF_getproplen(node, "reg");
+       if (len <= 0)
+               return;
+
+       reg = malloc(len, M_TEMP, M_WAITOK);
+       OF_getpropintarray(node, "reg", reg, len);
+
+       iot = sc->sc.iot;
+       if (bus_space_map(iot, reg[idx], reg[idx + 1], 0, &ioh)) {
+               free(reg, M_TEMP, len);
+               return;
+       }
+
+       /* assign USB port to OHCI/EHCI */
+       val = bus_space_read_4(iot, ioh, SUNXI_OTG_CTL);
+       val &= ~SUNXI_ROUTE_MUSB;
+       bus_space_write_4(iot, ioh, SUNXI_OTG_CTL, val);
+
+       bus_space_unmap(iot, ioh, reg[idx + 1]);
+       free(reg, M_TEMP, len);
+}
+
 void
 sun4i_phy_init(struct ehci_fdt_softc *sc, uint32_t *cells)
 {
@@ -278,6 +329,7 @@ sun4i_phy_init(struct ehci_fdt_softc *sc
         */
        if (OF_is_compatible(node, "allwinner,sun8i-h3-usb-phy") ||
            OF_is_compatible(node, "allwinner,sun8i-r40-usb-phy") ||
+           OF_is_compatible(node, "allwinner,sun8i-v3s-usb-phy") ||
            OF_is_compatible(node, "allwinner,sun50i-a64-usb-phy")) {
                val = bus_space_read_4(sc->sc.iot, sc->sc.ioh, 0x810);
                val &= ~(1 << 1);
@@ -306,6 +358,8 @@ sun4i_phy_init(struct ehci_fdt_softc *sc
        vbus_supply = OF_getpropint(node, name, 0);
        if (vbus_supply)
                regulator_enable(vbus_supply);
+
+       sun4i_port_routing(sc, cells);
 }
 
 void


--------
To support OHCI/EHCI on LicheePi Zero, we have to modify devicetree
like this diff. ehci (and maybe ohci) node needs phys and phy-names
property.

--- sun8i-v3s.dtsi.orig Thu Feb 14 21:59:49 2019
+++ sun8i-v3s.dtsi      Wed Feb 20 12:59:19 2019
@@ -180,6 +180,29 @@
                        #phy-cells = <1>;
                };
 
+               ehci0: usb@01c1a000 {
+                       compatible = "allwinner,sun8i-v3s-ehci", "generic-ehci";
+                       reg = <0x01c1a000 0x100>;
+                       interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>;
+                       resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
+                       phys = <&usbphy 0>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               ohci0: usb@01c1a400 {
+                       compatible = "allwinner,sun8i-v3s-ohci", "generic-ohci";
+                       reg = <0x01c1a400 0x100>;
+                       interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>,
+                                <&ccu CLK_USB_OHCI0>;
+                       resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
+                       phys = <&usbphy 0>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
                ccu: clock@01c20000 {
                        compatible = "allwinner,sun8i-v3s-ccu";
                        reg = <0x01c20000 0x400>;
--- sun8i-v3s-licheepi-zero.dts.orig    Thu Feb 14 21:59:49 2019
+++ sun8i-v3s-licheepi-zero.dts Thu Feb 14 22:46:31 2019
@@ -57,6 +57,10 @@
        };
 };
 
+&ehci0 {
+       status = "okay";
+};
+
 &mmc0 {
        pinctrl-0 = <&mmc0_pins_a>;
        pinctrl-names = "default";
@@ -64,6 +68,10 @@
        bus-width = <4>;
        vmmc-supply = <&reg_vcc3v3>;
        status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
 };
 
 &uart0 {


Regards,
-- 
SASANO Takayoshi (JG1UAA) <u...@mx5.nisiq.net>

Reply via email to