mirror of
https://github.com/opnsense/src.git
synced 2026-04-22 23:02:02 -04:00
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 447c418da0.
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
This commit is contained in:
parent
cec0a5ec6b
commit
09cdf4878c
2 changed files with 53 additions and 4 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Reference in a new issue