diff options
author | mmel <mmel@FreeBSD.org> | 2016-01-28 14:11:59 +0000 |
---|---|---|
committer | mmel <mmel@FreeBSD.org> | 2016-01-28 14:11:59 +0000 |
commit | a0d10caff7d70d415567d9fa0d26a1edb67ddb90 (patch) | |
tree | ef843ecdfe61e0893df4ac898bda28e2355d0fd5 /sys/mips | |
parent | fd752ed774f32a9029b1719067ee8463f9d53859 (diff) | |
download | FreeBSD-src-a0d10caff7d70d415567d9fa0d26a1edb67ddb90.zip FreeBSD-src-a0d10caff7d70d415567d9fa0d26a1edb67ddb90.tar.gz |
EHCI: Make core reset and port speed reading more generic.
Use driver settable callbacks for handling of:
- core post reset
- reading actual port speed
Typically, OTG enabled EHCI cores wants setting of USBMODE register,
but this register is not defined in EHCI specification and different
cores can have it on different offset.
Also, for cores with TT extension, actual port speed must be determinable.
But again, EHCI specification not covers this so this patch provides
function for two most common variant of speed bits layout.
Reviewed by: hselasky
Differential Revision: https://reviews.freebsd.org/D5088
Diffstat (limited to 'sys/mips')
-rw-r--r-- | sys/mips/atheros/ar71xx_ehci.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/sys/mips/atheros/ar71xx_ehci.c b/sys/mips/atheros/ar71xx_ehci.c index 5b7b3e2..07e06b9 100644 --- a/sys/mips/atheros/ar71xx_ehci.c +++ b/sys/mips/atheros/ar71xx_ehci.c @@ -61,6 +61,10 @@ __FBSDID("$FreeBSD$"); #define EHCI_HC_DEVSTR "AR71XX Integrated USB 2.0 controller" +#define EHCI_USBMODE 0x68 /* USB Device mode register */ +#define EHCI_UM_CM 0x00000003 /* R/WO Controller Mode */ +#define EHCI_UM_CM_HOST 0x3 /* Host Controller */ + struct ar71xx_ehci_softc { ehci_softc_t base; /* storage for EHCI code */ }; @@ -71,6 +75,18 @@ static device_detach_t ar71xx_ehci_detach; bs_r_1_proto(reversed); bs_w_1_proto(reversed); +static void +ar71xx_ehci_post_reset(struct ehci_softc *ehci_softc) +{ + uint32_t usbmode; + + /* Force HOST mode */ + usbmode = EOREAD4(ehci_softc, EHCI_USBMODE_NOLPM); + usbmode &= ~EHCI_UM_CM; + usbmode |= EHCI_UM_CM_HOST; + EOWRITE4(ehci_softc, EHCI_USBMODE_NOLPM, usbmode); +} + static int ar71xx_ehci_probe(device_t self) { @@ -161,7 +177,8 @@ ar71xx_ehci_attach(device_t self) * which means port speed must be read from the Port Status * register following a port enable. */ - sc->sc_flags = EHCI_SCFLG_SETMODE; + sc->sc_flags = 0; + sc->sc_vendor_post_reset = ar71xx_ehci_post_reset; switch (ar71xx_soc) { case AR71XX_SOC_AR7241: @@ -178,6 +195,8 @@ ar71xx_ehci_attach(device_t self) case AR71XX_SOC_QCA9556: case AR71XX_SOC_QCA9558: sc->sc_flags |= EHCI_SCFLG_TT | EHCI_SCFLG_NORESTERM; + sc->sc_vendor_get_port_speed = + ehci_get_port_speed_portsc; break; default: /* fallthrough */ |