The branch main has been updated by bz:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=09cdf4878c621be4cd229fa88cdccdcdc8c101f7

commit 09cdf4878c621be4cd229fa88cdccdcdc8c101f7
Author:     Bjoern A. Zeeb <[email protected]>
AuthorDate: 2022-07-02 20:56:07 +0000
Commit:     Bjoern A. Zeeb <[email protected]>
CommitDate: 2022-07-03 22:17:35 +0000

    dwc3: add more quirks and checks
    
    Rather than just printing the Global SNPS ID Register store it as well
    so we can do a version check later.
    In addition, for debugging purposes, read the Global Hardware Parameters
    Registers and print them.
    
    Based on the snpsid disable an XHCI feature using a quirk prepared
    in 447c418da03454a2a00bc115a69c62055a6d5272.
    Add the "snps,dis_u3_susphy_quirk" quirk and handle Suspend USB3.0 SS PHY
    after power-on-reset/during core initialization (suggested to be cleared)
    based on the DWC3_GHWPARAMS0 register.
    
    MFC after:      2 weeks
    Obtained from:  an old debugging patch
    Reviewed by:    mw (earlier version), mmel
    Differential Revision: https://reviews.freebsd.org/D35699
---
 sys/dev/usb/controller/dwc3.c | 54 +++++++++++++++++++++++++++++++++++++++----
 sys/dev/usb/controller/dwc3.h |  3 +++
 2 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/sys/dev/usb/controller/dwc3.c b/sys/dev/usb/controller/dwc3.c
index ac94a1327bcf..4b5109291cc4 100644
--- a/sys/dev/usb/controller/dwc3.c
+++ b/sys/dev/usb/controller/dwc3.c
@@ -79,6 +79,7 @@ struct snps_dwc3_softc {
        phandle_t               node;
        phy_t                   usb2_phy;
        phy_t                   usb3_phy;
+       uint32_t                snpsid;
 };
 
 #define        DWC3_WRITE(_sc, _off, _val)             \
@@ -165,10 +166,30 @@ snsp_dwc3_dump_regs(struct snps_dwc3_softc *sc)
 }
 #endif
 
+#ifdef DWC3_DEBUG
+static void
+snps_dwc3_dump_ctrlparams(struct snps_dwc3_softc *sc)
+{
+       const bus_size_t offs[] = {
+           DWC3_GHWPARAMS0, DWC3_GHWPARAMS1, DWC3_GHWPARAMS2, DWC3_GHWPARAMS3,
+           DWC3_GHWPARAMS4, DWC3_GHWPARAMS5, DWC3_GHWPARAMS6, DWC3_GHWPARAMS7,
+           DWC3_GHWPARAMS8,
+       };
+       uint32_t reg;
+       int i;
+
+       for (i = 0; i < nitems(offs); i++) {
+               reg = DWC3_READ(sc, offs[i]);
+               if (bootverbose)
+                       device_printf(sc->dev, "hwparams[%d]: %#012x\n", i, 
reg);
+       }
+}
+#endif
+
 static void
 snps_dwc3_reset(struct snps_dwc3_softc *sc)
 {
-       uint32_t gctl, phy2, phy3;
+       uint32_t gctl, ghwp0, phy2, phy3;
 
        if (sc->usb2_phy)
                phy_enable(sc->usb2_phy);
@@ -179,12 +200,19 @@ snps_dwc3_reset(struct snps_dwc3_softc *sc)
        gctl |= DWC3_GCTL_CORESOFTRESET;
        DWC3_WRITE(sc, DWC3_GCTL, gctl);
 
+       ghwp0 = DWC3_READ(sc, DWC3_GHWPARAMS0);
        phy2 = DWC3_READ(sc, DWC3_GUSB2PHYCFG0);
        phy2 |= DWC3_GUSB2PHYCFG0_PHYSOFTRST;
+       if ((ghwp0 & DWC3_GHWPARAMS0_MODE_MASK) ==
+           DWC3_GHWPARAMS0_MODE_DUALROLEDEVICE)
+               phy2 &= ~DWC3_GUSB2PHYCFG0_SUSPENDUSB20;
        DWC3_WRITE(sc, DWC3_GUSB2PHYCFG0, phy2);
 
        phy3 = DWC3_READ(sc, DWC3_GUSB3PIPECTL0);
        phy3 |= DWC3_GUSB3PIPECTL0_PHYSOFTRST;
+       if ((ghwp0 & DWC3_GHWPARAMS0_MODE_MASK) ==
+           DWC3_GHWPARAMS0_MODE_DUALROLEDEVICE)
+               phy3 &= ~DWC3_GUSB3PIPECTL0_SUSPENDUSB3;
        DWC3_WRITE(sc, DWC3_GUSB3PIPECTL0, phy3);
 
        DELAY(1000);
@@ -249,8 +277,10 @@ snps_dwc3_configure_phy(struct snps_dwc3_softc *sc)
 static void
 snps_dwc3_do_quirks(struct snps_dwc3_softc *sc)
 {
-       uint32_t reg;
+       struct xhci_softc *xsc;
+       uint32_t ghwp0, reg;
 
+       ghwp0 = DWC3_READ(sc, DWC3_GHWPARAMS0);
        reg = DWC3_READ(sc, DWC3_GUSB2PHYCFG0);
        if (device_has_property(sc->dev, "snps,dis-u2-freeclk-exists-quirk"))
                reg &= ~DWC3_GUSB2PHYCFG0_U2_FREECLK_EXISTS;
@@ -258,7 +288,8 @@ snps_dwc3_do_quirks(struct snps_dwc3_softc *sc)
                reg |= DWC3_GUSB2PHYCFG0_U2_FREECLK_EXISTS;
        if (device_has_property(sc->dev, "snps,dis_u2_susphy_quirk"))
                reg &= ~DWC3_GUSB2PHYCFG0_SUSPENDUSB20;
-       else
+       else if ((ghwp0 & DWC3_GHWPARAMS0_MODE_MASK) ==
+           DWC3_GHWPARAMS0_MODE_DUALROLEDEVICE)
                reg |= DWC3_GUSB2PHYCFG0_SUSPENDUSB20;
        if (device_has_property(sc->dev, "snps,dis_enblslpm_quirk"))
                reg &= ~DWC3_GUSB2PHYCFG0_ENBLSLPM;
@@ -276,7 +307,18 @@ snps_dwc3_do_quirks(struct snps_dwc3_softc *sc)
                reg &= ~DWC3_GUSB3PIPECTL0_DELAYP1TRANS;
        if (device_has_property(sc->dev, "snps,dis_rxdet_inp3_quirk"))
                reg |= DWC3_GUSB3PIPECTL0_DISRXDETINP3;
+       if (device_has_property(sc->dev, "snps,dis_u3_susphy_quirk"))
+               reg &= ~DWC3_GUSB3PIPECTL0_SUSPENDUSB3;
+       else if ((ghwp0 & DWC3_GHWPARAMS0_MODE_MASK) ==
+           DWC3_GHWPARAMS0_MODE_DUALROLEDEVICE)
+               reg |= DWC3_GUSB3PIPECTL0_SUSPENDUSB3;
        DWC3_WRITE(sc, DWC3_GUSB3PIPECTL0, reg);
+
+       /* Port Disable does not work on <= 3.00a. Disable PORT_PED. */
+       if ((sc->snpsid & 0xffff) <= 0x300a) {
+               xsc = &sc->sc;
+               xsc->sc_quirks |= XHCI_QUIRK_DISABLE_PORT_PED;
+       }
 }
 
 static int
@@ -326,8 +368,12 @@ snps_dwc3_attach(device_t dev)
        sc->bst = rman_get_bustag(sc->mem_res);
        sc->bsh = rman_get_bushandle(sc->mem_res);
 
+       sc->snpsid = DWC3_READ(sc, DWC3_GSNPSID);
        if (bootverbose)
-               device_printf(dev, "snps id: %x\n", DWC3_READ(sc, 
DWC3_GSNPSID));
+               device_printf(sc->dev, "snps id: %#012x\n", sc->snpsid);
+#ifdef DWC3_DEBUG
+       snps_dwc3_dump_ctrlparams(sc);
+#endif
 
        /* Get the phys */
        sc->node = ofw_bus_get_node(dev);
diff --git a/sys/dev/usb/controller/dwc3.h b/sys/dev/usb/controller/dwc3.h
index 862e17b1bcd9..83951d327c8c 100644
--- a/sys/dev/usb/controller/dwc3.h
+++ b/sys/dev/usb/controller/dwc3.h
@@ -59,6 +59,8 @@
 #define        DWC3_GBUSERRADDRHI      0xc134
 #define        DWC3_GPRTBIMAPLO        0xc138
 #define        DWC3_GHWPARAMS0         0xc140
+#define        DWC3_GHWPARAMS0_MODE_DUALROLEDEVICE     0x2
+#define        DWC3_GHWPARAMS0_MODE_MASK               0x3
 #define        DWC3_GHWPARAMS1         0xc144
 #define        DWC3_GHWPARAMS2         0xc148
 #define        DWC3_GHWPARAMS3         0xc14C
@@ -93,6 +95,7 @@
 #define         DWC3_GUSB3PIPECTL0_PHYSOFTRST          (1 << 31)
 #define         DWC3_GUSB3PIPECTL0_DISRXDETINP3        (1 << 28)
 #define         DWC3_GUSB3PIPECTL0_DELAYP1TRANS        (1 << 18)
+#define         DWC3_GUSB3PIPECTL0_SUSPENDUSB3         (1 << 17)
 
 #define        DWC3_GTXFIFOSIZ(x)      (0xc300 + 0x4 * (x))
 #define        DWC3_GRXFIFOSIZ(x)      (0xc380 + 0x4 * (x))

Reply via email to