Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/nick-nhusb]: src/sys/dev Add patch for intel chips quirk from ryoon@ in
details: https://anonhg.NetBSD.org/src/rev/89bbe30e8339
branches: nick-nhusb
changeset: 334213:89bbe30e8339
user: skrll <skrll%NetBSD.org@localhost>
date: Wed May 27 07:22:51 2015 +0000
description:
Add patch for intel chips quirk from ryoon@ in
https://mail-index.netbsd.org/netbsd-bugs/2014/08/31/msg038109.html
slightly modified to set quirks before calling xhci_init.
Set special IMOD value and route ports to xhci for intel chips.
>From Takahiro HAYASHI.
diffstat:
sys/dev/pci/xhci_pci.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++--
sys/dev/usb/xhci.c | 14 ++-----
2 files changed, 85 insertions(+), 14 deletions(-)
diffs (209 lines):
diff -r eb9915280ab1 -r 89bbe30e8339 sys/dev/pci/xhci_pci.c
--- a/sys/dev/pci/xhci_pci.c Wed May 27 07:08:16 2015 +0000
+++ b/sys/dev/pci/xhci_pci.c Wed May 27 07:22:51 2015 +0000
@@ -1,4 +1,5 @@
-/* $NetBSD: xhci_pci.c,v 1.4.2.2 2015/04/06 12:17:30 skrll Exp $ */
+/* $NetBSD: xhci_pci.c,v 1.4.2.3 2015/05/27 07:22:51 skrll Exp $ */
+/* OpenBSD: xhci_pci.c,v 1.4 2014/07/12 17:38:51 yuo Exp */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -31,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.4.2.2 2015/04/06 12:17:30 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.4.2.3 2015/05/27 07:22:51 skrll Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -43,6 +44,7 @@
#include <sys/bus.h>
#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -52,6 +54,17 @@
#include <dev/usb/xhcireg.h>
#include <dev/usb/xhcivar.h>
+struct xhci_pci_quirk {
+ pci_vendor_id_t vendor;
+ pci_product_id_t product;
+ int quirks;
+};
+
+static const struct xhci_pci_quirk xhci_pci_quirks[] = {
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_CORE4G_M_XHCI,
+ XHCI_QUIRK_FORCE_INTR },
+};
+
struct xhci_pci_softc {
struct xhci_softc sc_xhci;
pci_chipset_tag_t sc_pc;
@@ -59,6 +72,18 @@
};
static int
+xhci_pci_has_quirk(pci_vendor_id_t vendor, pci_product_id_t product)
+{
+ int i;
+
+ for (i = 0; i < __arraycount(xhci_pci_quirks); i++)
+ if (vendor == xhci_pci_quirks[i].vendor &&
+ product == xhci_pci_quirks[i].product)
+ return xhci_pci_quirks[i].quirks;
+ return 0;
+}
+
+static int
xhci_pci_match(device_t parent, cfdata_t match, void *aux)
{
struct pci_attach_args *pa = (struct pci_attach_args *) aux;
@@ -71,6 +96,42 @@
return 0;
}
+static int
+xhci_pci_port_route(struct xhci_pci_softc *psc)
+{
+ struct xhci_softc * const sc = &psc->sc_xhci;
+
+ 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);
+ aprint_debug_dev(sc->sc_dev,
+ "USB3PRM / USB3.0 configurable ports: 0x%08x\n", 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);
+ aprint_debug_dev(sc->sc_dev,
+ "USB3_PSSEN / Enabled USB3.0 ports under xHCI: 0x%08x\n", 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_USB2PRM);
+ aprint_debug_dev(sc->sc_dev,
+ "XUSB2PRM / USB2.0 ports can switch from EHCI to xHCI:"
+ "0x%08x\n", 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);
+ aprint_debug_dev(sc->sc_dev,
+ "XUSB2PR / USB2.0 ports under xHCI: 0x%08x\n", val);
+
+ return 0;
+}
+
static void
xhci_pci_attach(device_t parent, device_t self, void *aux)
{
@@ -92,6 +153,10 @@
pci_aprint_devinfo(pa, "USB Controller");
+ /* Check for quirks */
+ sc->sc_quirks = xhci_pci_has_quirk(PCI_VENDOR(pa->pa_id),
+ PCI_PRODUCT(pa->pa_id));
+
/* check if memory space access is enabled */
csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
#ifdef DEBUG
@@ -122,9 +187,9 @@
psc->sc_pc = pc;
psc->sc_tag = tag;
- hccparams = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 0x10);
+ hccparams = bus_space_read_4(sc->sc_iot, sc->sc_ioh, XHCI_HCCPARAMS);
- if (pci_dma64_available(pa) && ((hccparams&1)==1))
+ if (pci_dma64_available(pa) && (XHCI_HCC_AC64(hccparams) != 0))
sc->sc_bus.ub_dmatag = pa->pa_dmat64;
else
sc->sc_bus.ub_dmatag = pa->pa_dmat;
@@ -160,12 +225,24 @@
sc->sc_id_vendor);
#endif
+ /* Intel chipset requires SuperSpeed enable and USB2 port routing */
+ switch (PCI_VENDOR(pa->pa_id)) {
+ case PCI_VENDOR_INTEL:
+ sc->sc_quirks |= XHCI_QUIRK_INTEL;
+ break;
+ default:
+ break;
+ }
+
err = xhci_init(sc);
if (err) {
aprint_error_dev(self, "init failed, error=%d\n", err);
goto fail;
}
+ if ((sc->sc_quirks & XHCI_QUIRK_INTEL) != 0)
+ xhci_pci_port_route(psc);
+
if (!pmf_device_register1(self, xhci_suspend, xhci_resume,
xhci_shutdown))
aprint_error_dev(self, "couldn't establish power handler\n");
diff -r eb9915280ab1 -r 89bbe30e8339 sys/dev/usb/xhci.c
--- a/sys/dev/usb/xhci.c Wed May 27 07:08:16 2015 +0000
+++ b/sys/dev/usb/xhci.c Wed May 27 07:22:51 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: xhci.c,v 1.28.2.25 2015/05/27 07:08:16 skrll Exp $ */
+/* $NetBSD: xhci.c,v 1.28.2.26 2015/05/27 07:22:51 skrll Exp $ */
/*
* Copyright (c) 2013 Jonathan A. Kollasch
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.25 2015/05/27 07:08:16 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.26 2015/05/27 07:22:51 skrll Exp $");
#include "opt_usb.h"
@@ -910,13 +910,13 @@
#endif
xhci_rt_write_4(sc, XHCI_IMAN(0), XHCI_IMAN_INTR_ENA);
-#ifdef XHCI_QUIRK_INTEL
if ((sc->sc_quirks & XHCI_QUIRK_INTEL) != 0)
/* Intel xhci needs interrupt rate moderated. */
xhci_rt_write_4(sc, XHCI_IMOD(0), XHCI_IMOD_DEFAULT_LP);
else
-#endif /* XHCI_QUIRK_INTEL */
xhci_rt_write_4(sc, XHCI_IMOD(0), 0);
+ aprint_debug_dev(sc->sc_dev, "setting IMOD %u\n",
+ xhci_rt_read_4(sc, XHCI_IMOD(0)));
xhci_op_write_4(sc, XHCI_USBCMD, XHCI_CMD_INTE|XHCI_CMD_RS); /* Go! */
aprint_debug_dev(sc->sc_dev, "USBCMD %08"PRIx32"\n",
@@ -977,7 +977,6 @@
iman = xhci_rt_read_4(sc, XHCI_IMAN(0));
DPRINTFN(16, "IMAN0 %08x", iman, 0, 0, 0);
-#ifdef XHCI_QUIRK_FORCE_INTR
if (!(sc->sc_quirks & XHCI_QUIRK_FORCE_INTR)) {
if ((iman & XHCI_IMAN_INTR_PEND) == 0) {
@@ -985,11 +984,6 @@
}
}
-#else
- if ((iman & XHCI_IMAN_INTR_PEND) == 0) {
- return 0;
- }
-#endif /* XHCI_QUIRK_FORCE_INTR */
xhci_rt_write_4(sc, XHCI_IMAN(0), iman);
iman = xhci_rt_read_4(sc, XHCI_IMAN(0));
DPRINTFN(16, "IMAN0 %08x", iman, 0, 0, 0);
Home |
Main Index |
Thread Index |
Old Index