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