From 1009312d5ba1e26b927a6b5631e9b791a12767be Mon Sep 17 00:00:00 2001 From: Yojiro Uo Date: Sat, 12 Jul 2014 17:38:52 +0000 Subject: To enable Intel XHCI host controller, re-route all of usb port to xhci instead of connected to ehci. ok mpi@ --- sys/dev/pci/xhci_pci.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- sys/dev/usb/xhcireg.h | 7 +++++-- 2 files changed, 52 insertions(+), 3 deletions(-) (limited to 'sys') diff --git a/sys/dev/pci/xhci_pci.c b/sys/dev/pci/xhci_pci.c index a908f61954f..9f175edafe9 100644 --- a/sys/dev/pci/xhci_pci.c +++ b/sys/dev/pci/xhci_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xhci_pci.c,v 1.3 2014/04/07 23:32:41 brad Exp $ */ +/* $OpenBSD: xhci_pci.c,v 1.4 2014/07/12 17:38:51 yuo Exp $ */ /* * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. @@ -87,6 +87,41 @@ xhci_pci_match(struct device *parent, void *match, void *aux) return (0); } +static int +xhci_pci_port_route(struct xhci_pci_softc *psc) +{ + pcireg_t val; + + /* + * Check USB3 Port Routing Mask register that indicates the ports + * can be changed from OS, and turn on by USB3 Port SS Enable register. + */ + val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB3PRM); + DPRINTF(("%s: USB3PRM / USB3.0 configurable ports: 0x%08x\n", + psc->sc.sc_bus.bdev.dv_xname, val)); + + pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB3_PSSEN, val); + val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB3_PSSEN); + DPRINTF(("%s: USB3_PSSEN / Enabled USB3.0 ports under xHCI: 0x%08x\n", + psc->sc.sc_bus.bdev.dv_xname, val)); + + /* + * Check USB2 Port Routing Mask register that indicates the USB2.0 + * ports to be controlled by xHCI HC, and switch them to xHCI HC. + */ + val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_XUSB2PRM); + DPRINTF(("%s: XUSB2PRM / USB2.0 ports can switch from EHCI to xHCI:" + "0x%08x\n", psc->sc.sc_bus.bdev.dv_xname, val)); + + pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_XUSB2PR, val); + val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_XUSB2PR); + DPRINTF(("%s: XUSB2PR / USB2.0 ports under xHCI: 0x%08x\n", + psc->sc.sc_bus.bdev.dv_xname, val)); + + return (0); +} + + void xhci_pci_attach(struct device *parent, struct device *self, void *aux) { @@ -154,6 +189,17 @@ xhci_pci_attach(struct device *parent, struct device *self, void *aux) goto disestablish_ret; } + switch (PCI_VENDOR(pa->pa_id)) { + case PCI_VENDOR_INTEL: + switch (PCI_PRODUCT(pa->pa_id)) { + case PCI_PRODUCT_INTEL_8SERIES_XHCI: + case PCI_PRODUCT_INTEL_8SERIES_LP_XHCI: + case PCI_PRODUCT_INTEL_7SERIES_XHCI: + xhci_pci_port_route(psc); + break; + } + } + /* Attach usb device. */ config_found(self, &psc->sc.sc_bus, usbctlprint); diff --git a/sys/dev/usb/xhcireg.h b/sys/dev/usb/xhcireg.h index e8ac28cee51..6ea860468a0 100644 --- a/sys/dev/usb/xhcireg.h +++ b/sys/dev/usb/xhcireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: xhcireg.h,v 1.1 2014/03/08 14:34:11 mpi Exp $ */ +/* $OpenBSD: xhcireg.h,v 1.2 2014/07/12 17:38:51 yuo Exp $ */ /*- * Copyright (c) 2014 Martin Pieuchot. All rights reserved. @@ -44,7 +44,9 @@ #define PCI_XHCI_FLADJ 0x61 /* RW frame length adjust */ #define PCI_XHCI_INTEL_XUSB2PR 0xd0 /* Intel USB2 Port Routing */ +#define PCI_XHCI_INTEL_XUSB2PRM 0xd4 /* Intel USB2 Port Routing Mask */ #define PCI_XHCI_INTEL_USB3_PSSEN 0xd8 /* Intel USB3 Port SuperSpeed Enable */ +#define PCI_XHCI_INTEL_USB3PRM 0xdc /* Intel USB3 Port Routing Mask */ /* XHCI capability registers */ #define XHCI_CAPLENGTH 0x00 /* RO Capability reg. length field */ @@ -194,7 +196,8 @@ #define XHCI_IMOD_IVAL_SET(x) (((x) & 0xffff) << 0) /* 250ns unit */ #define XHCI_IMOD_ICNT_GET(x) (((x) >> 16) & 0xffff) /* 250ns unit */ #define XHCI_IMOD_ICNT_SET(x) (((x) & 0xffff) << 16) /* 250ns unit */ -#define XHCI_IMOD_DEFAULT 0x000003E8U /* 8000 IRQ/second */ +#define XHCI_IMOD_DEFAULT 0x000001F4U /* 8000 IRQ/second */ +#define XHCI_IMOD_DEFAULT_LP 0x000003E8U /* 4000 IRQ/second */ /* XHCI event ring segment table size */ #define XHCI_ERSTSZ(n) (0x0028 + (0x20 * (n))) -- cgit v1.2.3