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