Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Jul 2022 09:50:12 GMT
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: a7717dc610eb - stable/13 - dwc3: add more quirks and checks
Message-ID:  <202207180950.26I9oCKZ034987@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by bz:

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

commit a7717dc610ebe5ce9d1fa21ce84a8e6766b5e60b
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2022-07-02 20:56:07 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2022-07-18 01:00:21 +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.
    
    Obtained from:  an old debugging patch
    Reviewed by:    mw (earlier version), mmel
    Differential Revision: https://reviews.freebsd.org/D35699
    
    (cherry picked from commit 09cdf4878c621be4cd229fa88cdccdcdc8c101f7)
    (cherry picked from commit ec32fc2af52530e49d8a522ae29bf20b2e57603b)
---
 sys/dev/usb/controller/dwc3.c | 55 +++++++++++++++++++++++++++++++++++++++----
 sys/dev/usb/controller/dwc3.h |  3 +++
 2 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/sys/dev/usb/controller/dwc3.c b/sys/dev/usb/controller/dwc3.c
index b4156903874b..596fcb19ce1a 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,26 +166,54 @@ 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);
 	if (sc->usb3_phy)
 		phy_enable(sc->usb3_phy);
 
+	ghwp0 = DWC3_READ(sc, DWC3_GHWPARAMS0);
+
 	gctl = DWC3_READ(sc, DWC3_GCTL);
 	gctl |= DWC3_GCTL_CORESOFTRESET;
 	DWC3_WRITE(sc, DWC3_GCTL, gctl);
 
 	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 +278,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 +289,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 +308,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 +369,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))



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202207180950.26I9oCKZ034987>