summaryrefslogtreecommitdiffstats
path: root/sys/mips
diff options
context:
space:
mode:
authormmel <mmel@FreeBSD.org>2016-01-28 14:11:59 +0000
committermmel <mmel@FreeBSD.org>2016-01-28 14:11:59 +0000
commita0d10caff7d70d415567d9fa0d26a1edb67ddb90 (patch)
treeef843ecdfe61e0893df4ac898bda28e2355d0fd5 /sys/mips
parentfd752ed774f32a9029b1719067ee8463f9d53859 (diff)
downloadFreeBSD-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.c21
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 */
OpenPOWER on IntegriCloud