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 Import dwc2 2013-09-05
details: https://anonhg.NetBSD.org/src/rev/47ee108ee6b9
branches: trunk
changeset: 789727:47ee108ee6b9
user: skrll <skrll%NetBSD.org@localhost>
date: Thu Sep 05 07:53:10 2013 +0000
description:
Import dwc2 2013-09-05
diffstat:
sys/external/bsd/dwc2/dist/dwc2_core.c | 2731 ++++++++++++++++++++++++
sys/external/bsd/dwc2/dist/dwc2_core.h | 674 ++++++
sys/external/bsd/dwc2/dist/dwc2_coreintr.c | 500 ++++
sys/external/bsd/dwc2/dist/dwc2_hcd.c | 3063 ++++++++++++++++++++++++++++
sys/external/bsd/dwc2/dist/dwc2_hcd.h | 772 +++++++
sys/external/bsd/dwc2/dist/dwc2_hcdddma.c | 1212 +++++++++++
sys/external/bsd/dwc2/dist/dwc2_hcdintr.c | 2147 +++++++++++++++++++
sys/external/bsd/dwc2/dist/dwc2_hcdqueue.c | 875 +++++++
sys/external/bsd/dwc2/dist/dwc2_hw.h | 817 +++++++
9 files changed, 12791 insertions(+), 0 deletions(-)
diffs (truncated from 12827 to 300 lines):
diff -r 5f1db9320db2 -r 47ee108ee6b9 sys/external/bsd/dwc2/dist/dwc2_core.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/external/bsd/dwc2/dist/dwc2_core.c Thu Sep 05 07:53:10 2013 +0000
@@ -0,0 +1,2731 @@
+/* $NetBSD: dwc2_core.c,v 1.1.1.1 2013/09/05 07:53:10 skrll Exp $ */
+
+/*
+ * core.c - DesignWare HS OTG Controller common routines
+ *
+ * Copyright (C) 2004-2013 Synopsys, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * The Core code provides basic services for accessing and managing the
+ * DWC_otg hardware. These services are used by both the Host Controller
+ * Driver and the Peripheral Controller Driver.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+
+#include <linux/usb/hcd.h>
+#include <linux/usb/ch11.h>
+
+#include "core.h"
+#include "hcd.h"
+
+/**
+ * dwc2_enable_common_interrupts() - Initializes the commmon interrupts,
+ * used in both device and host modes
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ */
+static void dwc2_enable_common_interrupts(struct dwc2_hsotg *hsotg)
+{
+ u32 intmsk;
+
+ /* Clear any pending OTG Interrupts */
+ writel(0xffffffff, hsotg->regs + GOTGINT);
+
+ /* Clear any pending interrupts */
+ writel(0xffffffff, hsotg->regs + GINTSTS);
+
+ /* Enable the interrupts in the GINTMSK */
+ intmsk = GINTSTS_MODEMIS | GINTSTS_OTGINT;
+
+ if (hsotg->core_params->dma_enable <= 0)
+ intmsk |= GINTSTS_RXFLVL;
+
+ intmsk |= GINTSTS_CONIDSTSCHNG | GINTSTS_WKUPINT | GINTSTS_USBSUSP |
+ GINTSTS_SESSREQINT;
+
+ writel(intmsk, hsotg->regs + GINTMSK);
+}
+
+/*
+ * Initializes the FSLSPClkSel field of the HCFG register depending on the
+ * PHY type
+ */
+static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg)
+{
+ u32 hs_phy_type = hsotg->hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK;
+ u32 fs_phy_type = hsotg->hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK;
+ u32 hcfg, val;
+
+ if ((hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI &&
+ fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED &&
+ hsotg->core_params->ulpi_fs_ls > 0) ||
+ hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS) {
+ /* Full speed PHY */
+ val = HCFG_FSLSPCLKSEL_48_MHZ;
+ } else {
+ /* High speed PHY running at full speed or high speed */
+ val = HCFG_FSLSPCLKSEL_30_60_MHZ;
+ }
+
+ dev_dbg(hsotg->dev, "Initializing HCFG.FSLSPClkSel to %08x\n", val);
+ hcfg = readl(hsotg->regs + HCFG);
+ hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
+ hcfg |= val;
+ writel(hcfg, hsotg->regs + HCFG);
+}
+
+/*
+ * Do core a soft reset of the core. Be careful with this because it
+ * resets all the internal state machines of the core.
+ */
+static void dwc2_core_reset(struct dwc2_hsotg *hsotg)
+{
+ u32 greset;
+ int count = 0;
+
+ dev_vdbg(hsotg->dev, "%s()\n", __func__);
+
+ /* Wait for AHB master IDLE state */
+ do {
+ usleep_range(20000, 40000);
+ greset = readl(hsotg->regs + GRSTCTL);
+ if (++count > 50) {
+ dev_warn(hsotg->dev,
+ "%s() HANG! AHB Idle GRSTCTL=%0x\n",
+ __func__, greset);
+ return;
+ }
+ } while (!(greset & GRSTCTL_AHBIDLE));
+
+ /* Core Soft Reset */
+ count = 0;
+ greset |= GRSTCTL_CSFTRST;
+ writel(greset, hsotg->regs + GRSTCTL);
+ do {
+ usleep_range(20000, 40000);
+ greset = readl(hsotg->regs + GRSTCTL);
+ if (++count > 50) {
+ dev_warn(hsotg->dev,
+ "%s() HANG! Soft Reset GRSTCTL=%0x\n",
+ __func__, greset);
+ break;
+ }
+ } while (greset & GRSTCTL_CSFTRST);
+
+ /*
+ * 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);
+}
+
+static void dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
+{
+ u32 usbcfg, i2cctl;
+
+ /*
+ * core_init() is now called on every switch so only call the
+ * following for the first time through
+ */
+ if (select_phy) {
+ dev_dbg(hsotg->dev, "FS PHY selected\n");
+ usbcfg = readl(hsotg->regs + GUSBCFG);
+ usbcfg |= GUSBCFG_PHYSEL;
+ writel(usbcfg, hsotg->regs + GUSBCFG);
+
+ /* Reset after a PHY select */
+ dwc2_core_reset(hsotg);
+ }
+
+ /*
+ * Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also
+ * do this on HNP Dev/Host mode switches (done in dev_init and
+ * host_init).
+ */
+ if (dwc2_is_host_mode(hsotg))
+ dwc2_init_fs_ls_pclk_sel(hsotg);
+
+ if (hsotg->core_params->i2c_enable > 0) {
+ dev_dbg(hsotg->dev, "FS PHY enabling I2C\n");
+
+ /* Program GUSBCFG.OtgUtmiFsSel to I2C */
+ usbcfg = readl(hsotg->regs + GUSBCFG);
+ usbcfg |= GUSBCFG_OTG_UTMI_FS_SEL;
+ writel(usbcfg, hsotg->regs + GUSBCFG);
+
+ /* Program GI2CCTL.I2CEn */
+ i2cctl = readl(hsotg->regs + GI2CCTL);
+ i2cctl &= ~GI2CCTL_I2CDEVADDR_MASK;
+ i2cctl |= 1 << GI2CCTL_I2CDEVADDR_SHIFT;
+ i2cctl &= ~GI2CCTL_I2CEN;
+ writel(i2cctl, hsotg->regs + GI2CCTL);
+ i2cctl |= GI2CCTL_I2CEN;
+ writel(i2cctl, hsotg->regs + GI2CCTL);
+ }
+}
+
+static void dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
+{
+ u32 usbcfg;
+
+ if (!select_phy)
+ return;
+
+ usbcfg = readl(hsotg->regs + GUSBCFG);
+
+ /*
+ * HS PHY parameters. These parameters are preserved during soft reset
+ * so only program the first time. Do a soft reset immediately after
+ * setting phyif.
+ */
+ switch (hsotg->core_params->phy_type) {
+ case DWC2_PHY_TYPE_PARAM_ULPI:
+ /* ULPI interface */
+ dev_dbg(hsotg->dev, "HS ULPI PHY selected\n");
+ usbcfg |= GUSBCFG_ULPI_UTMI_SEL;
+ usbcfg &= ~(GUSBCFG_PHYIF16 | GUSBCFG_DDRSEL);
+ if (hsotg->core_params->phy_ulpi_ddr > 0)
+ usbcfg |= GUSBCFG_DDRSEL;
+ break;
+ case DWC2_PHY_TYPE_PARAM_UTMI:
+ /* UTMI+ interface */
+ dev_dbg(hsotg->dev, "HS UTMI+ PHY selected\n");
+ usbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16);
+ if (hsotg->core_params->phy_utmi_width == 16)
+ usbcfg |= GUSBCFG_PHYIF16;
+ break;
+ default:
+ dev_err(hsotg->dev, "FS PHY selected at HS!\n");
+ break;
+ }
+
+ writel(usbcfg, hsotg->regs + GUSBCFG);
+
+ /* Reset after setting the PHY parameters */
+ dwc2_core_reset(hsotg);
+}
+
+static void dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
+{
+ u32 usbcfg, hs_phy_type, fs_phy_type;
+
+ if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL &&
+ hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS) {
+ /* If FS mode with FS PHY */
+ dwc2_fs_phy_init(hsotg, select_phy);
+ } else {
+ /* High speed PHY */
+ dwc2_hs_phy_init(hsotg, select_phy);
+ }
+
+ hs_phy_type = hsotg->hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK;
+ fs_phy_type = hsotg->hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK;
+
+ if (hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI &&
+ fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED &&
+ hsotg->core_params->ulpi_fs_ls > 0) {
+ dev_dbg(hsotg->dev, "Setting ULPI FSLS\n");
+ usbcfg = readl(hsotg->regs + GUSBCFG);
+ usbcfg |= GUSBCFG_ULPI_FS_LS;
+ usbcfg |= GUSBCFG_ULPI_CLK_SUSP_M;
+ writel(usbcfg, hsotg->regs + GUSBCFG);
+ } else {
+ usbcfg = readl(hsotg->regs + GUSBCFG);
+ usbcfg &= ~GUSBCFG_ULPI_FS_LS;
+ usbcfg &= ~GUSBCFG_ULPI_CLK_SUSP_M;
+ writel(usbcfg, hsotg->regs + GUSBCFG);
+ }
+}
+
+static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg)
+{
+ u32 ahbcfg = readl(hsotg->regs + GAHBCFG);
+
+ switch (hsotg->hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) {
+ case GHWCFG2_EXT_DMA_ARCH:
+ dev_err(hsotg->dev, "External DMA Mode not supported\n");
+ return -EINVAL;
+
+ case GHWCFG2_INT_DMA_ARCH:
+ dev_dbg(hsotg->dev, "Internal DMA Mode\n");
+ if (hsotg->core_params->ahbcfg != -1) {
+ ahbcfg &= GAHBCFG_CTRL_MASK;
+ ahbcfg |= hsotg->core_params->ahbcfg &
+ ~GAHBCFG_CTRL_MASK;
+ }
+ break;
Home |
Main Index |
Thread Index |
Old Index