Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/external/bsd/dwc2/dist Merge conflicts



details:   https://anonhg.NetBSD.org/src/rev/70db4e717e6a
branches:  trunk
changeset: 813693:70db4e717e6a
user:      skrll <skrll%NetBSD.org@localhost>
date:      Sun Feb 14 10:53:30 2016 +0000

description:
Merge conflicts

diffstat:

 sys/external/bsd/dwc2/dist/dwc2_core.c     |  475 ++++++++++++++++++++++------
 sys/external/bsd/dwc2/dist/dwc2_core.h     |  147 ++++++--
 sys/external/bsd/dwc2/dist/dwc2_coreintr.c |   78 ++--
 sys/external/bsd/dwc2/dist/dwc2_hcd.c      |  165 ++++++++-
 sys/external/bsd/dwc2/dist/dwc2_hcd.h      |   35 +-
 sys/external/bsd/dwc2/dist/dwc2_hcdddma.c  |  195 ++++++++++-
 sys/external/bsd/dwc2/dist/dwc2_hcdintr.c  |  112 +++++-
 sys/external/bsd/dwc2/dist/dwc2_hcdqueue.c |   18 +-
 sys/external/bsd/dwc2/dist/dwc2_hw.h       |    7 +-
 9 files changed, 940 insertions(+), 292 deletions(-)

diffs (truncated from 2349 to 300 lines):

diff -r d9ee483681d6 -r 70db4e717e6a sys/external/bsd/dwc2/dist/dwc2_core.c
--- a/sys/external/bsd/dwc2/dist/dwc2_core.c    Sun Feb 14 10:34:09 2016 +0000
+++ b/sys/external/bsd/dwc2/dist/dwc2_core.c    Sun Feb 14 10:53:30 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dwc2_core.c,v 1.10 2015/09/01 14:03:00 skrll Exp $     */
+/*     $NetBSD: dwc2_core.c,v 1.11 2016/02/14 10:53:30 skrll Exp $     */
 
 /*
  * core.c - DesignWare HS OTG Controller common routines
@@ -43,7 +43,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dwc2_core.c,v 1.10 2015/09/01 14:03:00 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dwc2_core.c,v 1.11 2016/02/14 10:53:30 skrll Exp $");
 
 #include <sys/types.h>
 #include <sys/bus.h>
@@ -127,6 +127,7 @@
 
        DWC2_WRITE_4(hsotg, HPRT0, hr->hprt0);
        DWC2_WRITE_4(hsotg, HFIR, hr->hfir);
+       hsotg->frame_number = 0;
 
        return 0;
 }
@@ -408,6 +409,12 @@
                }
        }
 
+       /*
+        * Clear any pending interrupts since dwc2 will not be able to
+        * clear them after entering hibernation.
+        */
+       DWC2_WRITE_4(hsotg, GINTSTS, 0xffffffff);
+
        /* Put the controller in low power state */
        pcgcctl = DWC2_READ_4(hsotg, PCGCTL);
 
@@ -485,17 +492,32 @@
  * Do core a soft reset of the core.  Be careful with this because it
  * resets all the internal state machines of the core.
  */
-static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
+int dwc2_core_reset(struct dwc2_hsotg *hsotg)
 {
        u32 greset;
        int count = 0;
-       u32 gusbcfg;
 
        dev_vdbg(hsotg->dev, "%s()\n", __func__);
 
-       /* Wait for AHB master IDLE state */
+       /* Core Soft Reset */
+       greset = DWC2_READ_4(hsotg, GRSTCTL);
+       greset |= GRSTCTL_CSFTRST;
+       DWC2_WRITE_4(hsotg, GRSTCTL, greset);
        do {
-               usleep_range(20000, 40000);
+               udelay(1);
+               greset = DWC2_READ_4(hsotg, GRSTCTL);
+               if (++count > 50) {
+                       dev_warn(hsotg->dev,
+                                "%s() HANG! Soft Reset GRSTCTL=%0x\n",
+                                __func__, greset);
+                       return -EBUSY;
+               }
+       } while (greset & GRSTCTL_CSFTRST);
+
+       /* Wait for AHB master IDLE state */
+       count = 0;
+       do {
+               udelay(1);
                greset = DWC2_READ_4(hsotg, GRSTCTL);
                if (++count > 50) {
                        dev_warn(hsotg->dev,
@@ -505,44 +527,131 @@
                }
        } while (!(greset & GRSTCTL_AHBIDLE));
 
-       /* Core Soft Reset */
-       count = 0;
-       greset |= GRSTCTL_CSFTRST;
-       DWC2_WRITE_4(hsotg, GRSTCTL, greset);
-       do {
-               usleep_range(20000, 40000);
-               greset = DWC2_READ_4(hsotg, GRSTCTL);
-               if (++count > 50) {
-                       dev_warn(hsotg->dev,
-                                "%s() HANG! Soft Reset GRSTCTL=%0x\n",
-                                __func__, greset);
-                       return -EBUSY;
-               }
-       } while (greset & GRSTCTL_CSFTRST);
-
-       if (hsotg->dr_mode == USB_DR_MODE_HOST) {
-               gusbcfg = DWC2_READ_4(hsotg, GUSBCFG);
-               gusbcfg &= ~GUSBCFG_FORCEDEVMODE;
-               gusbcfg |= GUSBCFG_FORCEHOSTMODE;
-               DWC2_WRITE_4(hsotg, GUSBCFG, gusbcfg);
-       } else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) {
-               gusbcfg = DWC2_READ_4(hsotg, GUSBCFG);
-               gusbcfg &= ~GUSBCFG_FORCEHOSTMODE;
-               gusbcfg |= GUSBCFG_FORCEDEVMODE;
-               DWC2_WRITE_4(hsotg, GUSBCFG, gusbcfg);
-       } else if (hsotg->dr_mode == USB_DR_MODE_OTG) {
-               gusbcfg = DWC2_READ_4(hsotg, GUSBCFG);
-               gusbcfg &= ~GUSBCFG_FORCEHOSTMODE;
-               gusbcfg &= ~GUSBCFG_FORCEDEVMODE;
-               DWC2_WRITE_4(hsotg, GUSBCFG, gusbcfg);
+       return 0;
+}
+
+/*
+ * Force the mode of the controller.
+ *
+ * Forcing the mode is needed for two cases:
+ *
+ * 1) If the dr_mode is set to either HOST or PERIPHERAL we force the
+ * controller to stay in a particular mode regardless of ID pin
+ * changes. We do this usually after a core reset.
+ *
+ * 2) During probe we want to read reset values of the hw
+ * configuration registers that are only available in either host or
+ * device mode. We may need to force the mode if the current mode does
+ * not allow us to access the register in the mode that we want.
+ *
+ * In either case it only makes sense to force the mode if the
+ * controller hardware is OTG capable.
+ *
+ * Checks are done in this function to determine whether doing a force
+ * would be valid or not.
+ *
+ * If a force is done, it requires a 25ms delay to take effect.
+ *
+ * Returns true if the mode was forced.
+ */
+static bool dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host)
+{
+       u32 gusbcfg;
+       u32 set;
+       u32 clear;
+
+       dev_dbg(hsotg->dev, "Forcing mode to %s\n", host ? "host" : "device");
+
+       /*
+        * Force mode has no effect if the hardware is not OTG.
+        */
+       if (!dwc2_hw_is_otg(hsotg))
+               return false;
+
+       /*
+        * If dr_mode is either peripheral or host only, there is no
+        * need to ever force the mode to the opposite mode.
+        */
+       if (host && hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) {
+               WARN_ON(1);
+               return false;
        }
 
+       if (!host && hsotg->dr_mode == USB_DR_MODE_HOST) {
+               WARN_ON(1);
+               return false;
+       }
+
+       gusbcfg = DWC2_READ_4(hsotg, GUSBCFG);
+
+       set = host ? GUSBCFG_FORCEHOSTMODE : GUSBCFG_FORCEDEVMODE;
+       clear = host ? GUSBCFG_FORCEDEVMODE : GUSBCFG_FORCEHOSTMODE;
+
+       gusbcfg &= ~clear;
+       gusbcfg |= set;
+       DWC2_WRITE_4(hsotg, GUSBCFG, gusbcfg);
+
+       msleep(25);
+       return true;
+}
+
+/*
+ * Clears the force mode bits.
+ */
+static void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg)
+{
+       u32 gusbcfg;
+
+       gusbcfg = DWC2_READ_4(hsotg, GUSBCFG);
+       gusbcfg &= ~GUSBCFG_FORCEHOSTMODE;
+       gusbcfg &= ~GUSBCFG_FORCEDEVMODE;
+       DWC2_WRITE_4(hsotg, GUSBCFG, gusbcfg);
+
        /*
         * NOTE: This long sleep is _very_ important, otherwise the core will
         * not stay in host mode after a connector ID change!
         */
-       usleep_range(150000, 200000);
-
+       msleep(25);
+}
+
+/*
+ * Sets or clears force mode based on the dr_mode parameter.
+ */
+void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg)
+{
+       switch (hsotg->dr_mode) {
+       case USB_DR_MODE_HOST:
+               dwc2_force_mode(hsotg, true);
+               break;
+       case USB_DR_MODE_PERIPHERAL:
+               dwc2_force_mode(hsotg, false);
+               break;
+       case USB_DR_MODE_OTG:
+               dwc2_clear_force_mode(hsotg);
+               break;
+       default:
+               dev_warn(hsotg->dev, "%s() Invalid dr_mode=%d\n",
+                        __func__, hsotg->dr_mode);
+               break;
+       }
+}
+
+/*
+ * Do core a soft reset of the core.  Be careful with this because it
+ * resets all the internal state machines of the core.
+ *
+ * Additionally this will apply force mode as per the hsotg->dr_mode
+ * parameter.
+ */
+int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg)
+{
+       int retval;
+
+       retval = dwc2_core_reset(hsotg);
+       if (retval)
+               return retval;
+
+       dwc2_force_dr_mode(hsotg);
        return 0;
 }
 
@@ -557,16 +666,20 @@
         */
        if (select_phy) {
                dev_dbg(hsotg->dev, "FS PHY selected\n");
+
                usbcfg = DWC2_READ_4(hsotg, GUSBCFG);
-               usbcfg |= GUSBCFG_PHYSEL;
-               DWC2_WRITE_4(hsotg, GUSBCFG, usbcfg);
-
-               /* Reset after a PHY select */
-               retval = dwc2_core_reset(hsotg);
-               if (retval) {
-                       dev_err(hsotg->dev, "%s() Reset failed, aborting",
-                                       __func__);
-                       return retval;
+               if (!(usbcfg & GUSBCFG_PHYSEL)) {
+                       usbcfg |= GUSBCFG_PHYSEL;
+                       DWC2_WRITE_4(hsotg, GUSBCFG, usbcfg);
+
+                       /* Reset after a PHY select */
+                       retval = dwc2_core_reset_and_force_dr_mode(hsotg);
+
+                       if (retval) {
+                               dev_err(hsotg->dev,
+                                       "%s: Reset failed, aborting", __func__);
+                               return retval;
+                       }
                }
        }
 
@@ -601,13 +714,13 @@
 
 static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 {
-       u32 usbcfg;
+       u32 usbcfg, usbcfg_old;
        int retval = 0;
 
        if (!select_phy)
                return 0;
 
-       usbcfg = DWC2_READ_4(hsotg, GUSBCFG);
+       usbcfg = usbcfg_old = DWC2_READ_4(hsotg, GUSBCFG);
 
        /*
         * HS PHY parameters. These parameters are preserved during soft reset
@@ -635,14 +748,16 @@
                break;
        }
 
-       DWC2_WRITE_4(hsotg, GUSBCFG, usbcfg);
-
-       /* Reset after setting the PHY parameters */
-       retval = dwc2_core_reset(hsotg);
-       if (retval) {
-               dev_err(hsotg->dev, "%s() Reset failed, aborting",
-                               __func__);
-               return retval;
+       if (usbcfg != usbcfg_old) {
+               DWC2_WRITE_4(hsotg, GUSBCFG, usbcfg);



Home | Main Index | Thread Index | Old Index