zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/boot/common/src/uboot/drivers/usb_drv/Makefile b/boot/common/src/uboot/drivers/usb_drv/Makefile
new file mode 100644
index 0000000..f54ebee
--- /dev/null
+++ b/boot/common/src/uboot/drivers/usb_drv/Makefile
@@ -0,0 +1,48 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	:= $(obj)libusb_dwc.o
+
+# new USB gadget layer dependencies
+
+COBJS-y +=dwc_otg_cil.o dwc_otg_cil_intr.o dwc_otg_dev_test.o dwc_otg_pcd.o dwc_otg_pcd_intr.o global.o
+
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+
+all:	$(LIB)
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/boot/common/src/uboot/drivers/usb_drv/dwc_otg_cil.c b/boot/common/src/uboot/drivers/usb_drv/dwc_otg_cil.c
new file mode 100644
index 0000000..1243a53
--- /dev/null
+++ b/boot/common/src/uboot/drivers/usb_drv/dwc_otg_cil.c
@@ -0,0 +1,1191 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.c $
+ * $Revision: #191 $
+ * $Date: 2012/08/10 $
+ * $Change: 2047372 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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.
+ * ========================================================================== */
+
+/** @file
+ *
+ * The Core Interface Layer 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.
+ *
+ * The CIL manages the memory map for the core so that the HCD and PCD
+ * don't have to do this separately. It also handles basic tasks like
+ * reading/writing the registers and data FIFOs in the controller.
+ * Some of the data access functions provide encapsulation of several
+ * operations required to perform a task, such as writing multiple
+ * registers to start a transfer. Finally, the CIL performs basic
+ * services that are not specific to either the host or device modes
+ * of operation. These services include management of the OTG Host
+ * Negotiation Protocol (HNP) and Session Request Protocol (SRP). A
+ * Diagnostic API is also provided to allow testing of the controller
+ * hardware.
+ *
+ * The Core Interface Layer has the following requirements:
+ * - Provides basic controller operations.
+ * - Minimal use of OS services.
+ * - The OS services used will be abstracted by using inline functions
+ *	 or macros.
+ *
+ */
+#include <usb/global.h>
+#include <usb/dwc_otg_regs.h>
+#include <usb/dwc_otg_cil.h>
+#include <usb/dwc_otg_driver.h>
+
+
+
+static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if);
+
+void DWC_MODIFY_REG32(uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask)
+{
+    DWC_WRITE_REG32(reg,(DWC_READ_REG32(reg) & ~clear_mask) | set_mask);
+}
+
+dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr)
+{
+    dwc_otg_core_if_t *core_if = (&global.core_if_t);
+    dwc_otg_dev_if_t *dev_if = (&global.dev_if_t);
+    uint8_t *pt_core_if = ( uint8_t *)(&global.core_if_t);
+    uint8_t *pt_dev_if = ( uint8_t *)(&global.dev_if_t);
+    uint8_t *reg_base = (uint8_t *) reg_base_addr;
+    int i = 0;
+    for(i= 0;i<sizeof(global.core_if_t);i++)
+    {
+        pt_core_if[i] = 0;
+    }
+    core_if->core_global_regs = (dwc_otg_core_global_regs_t *) reg_base;
+
+    for(i= 0;i<sizeof(global.dev_if_t);i++)
+    {
+        pt_dev_if[i] = 0;
+    }
+
+    dev_if->dev_global_regs = (dwc_otg_device_global_regs_t *) (reg_base +DWC_DEV_GLOBAL_REG_OFFSET);
+
+    for (i = 0; i < MAX_EPS_CHANNELS; i++)
+    {
+        dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
+                                (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
+                                 (i * DWC_EP_REG_OFFSET));
+
+        dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
+                                 (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
+                                  (i * DWC_EP_REG_OFFSET));
+
+        core_if->data_fifo[i] =(uint32_t *) (reg_base + DWC_OTG_DATA_FIFO_OFFSET +(i * DWC_OTG_DATA_FIFO_SIZE));
+    }
+
+    dev_if->speed = 0;	
+
+    core_if->dev_if = dev_if;
+
+    core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET);
+
+    core_if->hwcfg1.d32 =DWC_READ_REG32(&core_if->core_global_regs->ghwcfg1);
+    core_if->hwcfg2.d32 =DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
+    core_if->hwcfg3.d32 =DWC_READ_REG32(&core_if->core_global_regs->ghwcfg3);
+    core_if->hwcfg4.d32 =DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4);
+
+    core_if->dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
+
+    dwc_otg_setup_params(core_if);
+
+
+    return core_if;
+}
+
+/**
+ * Initializes the DevSpd field of the DCFG register depending on the PHY type
+ * and the enumeration speed of the device.
+ */
+void init_devspd(dwc_otg_core_if_t * core_if,uint8_t speed)
+{
+    uint32_t val;
+    dcfg_data_t dcfg;
+
+    val = speed;
+    dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
+    dcfg.b.devspd = val;
+		if(global.g_enum == NEED_ENUM)
+	{
+    DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
+			}
+}
+
+/**
+ * This function initializes the DWC_otg controller registers and
+ * prepares the core for device mode or host mode operation.
+ *
+ * @param core_if Programming view of the DWC_otg controller
+ *
+ */
+void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
+	{
+		dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+		dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+		gahbcfg_data_t ahbcfg;
+		gotgctl_data_t gotgctl;
+	
+		gusbcfg_data_t usbcfg;
+		ahbcfg.d32 = 0;
+		usbcfg.d32 = 0;
+		gotgctl.d32 = 0;
+	
+	
+		usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+	if(global.g_enum == NEED_ENUM)
+	{
+	
+#if !USE_ASIC
+		usbcfg.b.ulpi_ext_vbus_drv =(core_if->core_params->phy_ulpi_ext_vbus == DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
+	
+		usbcfg.b.term_sel_dl_pulse = (core_if->core_params->ts_dline == 1) ? 1 : 0;
+	
+	
+		DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+#endif
+		dwc_otg_core_reset(core_if);
+		}
+	
+	
+		dev_if->num_in_eps =  2;//calc_num_in_eps(core_if);
+		dev_if->num_out_eps = 2;//calc_num_out_eps(core_if);
+	
+		core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
+		core_if->rx_fifo_size = DWC_READ_REG32(&global_regs->grxfsiz);
+		core_if->nperio_tx_fifo_size = DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16;
+		{
+			/* High speed PHY. */
+			if (!core_if->phy_init_done)
+			{
+				core_if->phy_init_done = 1;
+				/* HS PHY parameters.  These parameters are preserved
+				 * during soft reset so only program the first time.  Do
+				 * a soft reset immediately after setting phyif.  */
+         #if !USE_ASIC
+				if (core_if->core_params->phy_type == 2)
+				{
+					/* ULPI interface */
+					usbcfg.b.ulpi_utmi_sel = 1;
+					usbcfg.b.phyif = 0;
+					usbcfg.b.ddrsel = core_if->core_params->phy_ulpi_ddr;
+				}
+          #else
+				if (core_if->core_params->phy_type == 1)
+				{
+					/* UTMI+ interface */
+					usbcfg.b.ulpi_utmi_sel = 0;
+					if (core_if->core_params->phy_utmi_width == 16)
+					{
+						usbcfg.b.phyif = 1;
+	
+					}
+					else
+					{
+						usbcfg.b.phyif = 0;
+					}
+				}
+            #endif
+		if(global.g_enum == NEED_ENUM)
+		{
+				DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+				/* Reset after setting the PHY parameters */
+				dwc_otg_core_reset(core_if);
+		}
+			}
+		}
+		if(global.g_enum == NEED_ENUM)
+			{
+#if !USE_ASIC
+		if ((core_if->hwcfg2.b.hs_phy_type == 2) &&(core_if->hwcfg2.b.fs_phy_type == 1) &&(core_if->core_params->ulpi_fs_ls))
+		{
+			usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+			usbcfg.b.ulpi_fsls = 1;
+			usbcfg.b.ulpi_clk_sus_m = 1;
+			DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+		}
+		else
+		{
+			usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+			usbcfg.b.ulpi_fsls = 0;
+			usbcfg.b.ulpi_clk_sus_m = 0;
+			DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+		}
+#endif
+			}
+	
+	
+		ahbcfg.b.nptxfemplvl_txfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
+		ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
+	
+	
+		ahbcfg.b.dmaenable = 0;
+	//	ÅäÖÃÈ«¿ÕFIFO²úÉúÖжÏ
+		ahbcfg.b.nptxfemplvl_txfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_EMPTY ;
+		if(global.g_enum == NEED_ENUM)
+		{
+	
+			 DWC_WRITE_REG32(&global_regs->gahbcfg, ahbcfg.d32);
+		}
+	
+	
+		core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
+	
+		core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
+		core_if->multiproc_int_enable = dwc_param_mpi_enable_default;//core_if->core_params->mpi_enable;
+		/*
+		 * Program the GUSBCFG register.
+		 */
+		usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+		usbcfg.b.hnpcap = 0;
+		usbcfg.b.srpcap = 0;
+		
+		if(global.g_enum == NEED_ENUM)
+		{
+			DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+		}
+		{
+			gotgctl.b.otgver = core_if->core_params->otg_ver;
+		if(global.g_enum == NEED_ENUM)
+		  {
+				DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, 0, gotgctl.d32);
+		  }
+			/* Set OTG version supported */
+			core_if->otg_ver = core_if->core_params->otg_ver;
+		}
+		if(global.g_enum == NEED_ENUM)
+	   {
+		   dwc_otg_core_dev_init(core_if);
+	   }
+	
+	}
+
+
+/**
+ * This function enables the Device mode interrupts.
+ *
+ * @param core_if Programming view of DWC_otg controller
+ */
+void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * core_if)
+{
+    gintmsk_data_t intr_mask ;
+
+    dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+    intr_mask.d32 = 0;
+    /* Disable all interrupts. */
+    DWC_WRITE_REG32(&global_regs->gintmsk, 0);
+
+    /* Clear any pending interrupts */
+    DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
+
+    /* Enable the common interrupts */
+    intr_mask.b.rxstsqlvl = 1;
+    intr_mask.b.usbsuspend = 1;
+    DWC_WRITE_REG32(&global_regs->gintmsk, intr_mask.d32);
+    
+    intr_mask.d32 = 0x1e3400;
+    DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
+
+}
+
+/**
+ * This function initializes the DWC_otg controller registers for
+ * device mode.
+ *
+ * @param core_if Programming view of DWC_otg controller
+ *
+ */
+void dwc_otg_core_dev_init(dwc_otg_core_if_t * core_if)
+{
+    int i;
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    dcfg_data_t dcfg;
+    grstctl_t resetctl;
+    dctl_data_t dctl;
+    diepmsk_data_t msk;
+    dcfg.d32 = 0;
+    resetctl.d32 = 0;
+    dctl.d32 = 0;
+    msk.d32 = 0;
+    /* Restart the Phy Clock */
+    DWC_WRITE_REG32(core_if->pcgcctl, 0);
+
+    /* Device configuration register */
+    init_devspd(core_if,0);//ĬÈÏÅäÖóɸßËÙ
+    dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
+    dcfg.b.descdma = 0;
+    dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
+
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
+
+    /* Flush the FIFOs */
+    dwc_otg_flush_tx_fifo(core_if, 0x10);	/* all Tx FIFOs */
+    dwc_otg_flush_rx_fifo(core_if);
+
+    /* Flush the Learning Queue. */
+    resetctl.b.intknqflsh = 1;
+    DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
+    /* Clear all pending Device Interrupts */
+    /** @todo - if the condition needed to be checked
+     *  or in any case all pending interrutps should be cleared?
+     */
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, 0);
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, 0);
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk, 0);
+    
+    for (i = 0; i <= dev_if->num_in_eps; i++)
+    {
+        DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl,0);
+
+        DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
+        DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, 0);
+        DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
+
+        DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl,0);
+
+        DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
+        DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepdma, 0);
+        DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
+    }
+ //ÓÃÓÚhsic
+    if(1==global.g_USB_MODE)
+    {
+        DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, 0x40000000);
+    }
+    dwc_otg_enable_device_interrupts(core_if);
+    msk.b.txfifoundrn = 1;
+    DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk,msk.d32, msk.d32);
+    dctl.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dctl);
+    dctl.b.sftdiscon = 0;
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl, dctl.d32);
+
+}
+
+void dwc_otg_core_dev_disconnet(dwc_otg_core_if_t * core_if)
+{
+    dctl_data_t dctl;
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    dctl.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dctl);
+    dctl.b.sftdiscon = 1;
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl, dctl.d32);
+}
+/**
+ * This function reads a setup packet from the Rx FIFO into the destination
+ * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl)
+ * Interrupt routine when a SETUP packet has been received in Slave mode.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param dest Destination buffer for packet data.
+ */
+void dwc_otg_read_setup_packet(dwc_otg_core_if_t * core_if, uint32_t * dest)
+{
+    dest[0] = DWC_READ_REG32(core_if->data_fifo[0]);
+    dest[1] = DWC_READ_REG32(core_if->data_fifo[0]);
+
+}
+
+/**
+ * This function enables EP0 OUT to receive SETUP packets and configures EP0
+ * IN for transmitting packets. It is normally called when the
+ * "Enumeration Done" interrupt occurs.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP0 data.
+ */
+void dwc_otg_ep0_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    dsts_data_t dsts;
+    depctl_data_t diepctl;
+    dctl_data_t dctl;
+    ep->stp_rollover = 0;
+    dctl.d32 = 0;
+
+    /* Read the Device Status and Endpoint 0 Control registers */
+    dsts.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dsts);
+    diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
+
+    /* Set the MPS of the IN EP based on the enumeration speed */
+    switch (dsts.b.enumspd)
+    {
+    case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
+    case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
+    case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
+        diepctl.b.mps = DWC_DEP0CTL_MPS_64;
+        break;
+    }
+
+    DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
+    dctl.b.cgnpinnak = 1;
+
+    DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
+
+}
+
+/**
+ * This function activates an EP.  The Device EP control register for
+ * the EP is configured as defined in the ep structure. Note: This
+ * function is not used for EP0.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP to activate.
+ */
+void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    depctl_data_t depctl;
+    volatile uint32_t *addr;
+    daint_data_t daintmsk;
+
+    daintmsk.d32 = 0;
+    /* Read DEPCTLn register */
+    if (ep->is_in == 1)
+    {
+        addr = &dev_if->in_ep_regs[ep->num]->diepctl;
+        daintmsk.ep.in = 1 << ep->num;
+    }
+    else
+    {
+        addr = &dev_if->out_ep_regs[ep->num]->doepctl;
+        daintmsk.ep.out = 1 << ep->num;
+    }
+
+    /* If the EP is already active don't change the EP Control
+     * register. */
+    depctl.d32 = DWC_READ_REG32(addr);
+    if (!depctl.b.usbactep)
+    {
+        depctl.b.mps = ep->maxpacket;
+        depctl.b.eptype = ep->type;
+        depctl.b.txfnum = ep->tx_fifo_num;
+
+
+        depctl.b.setd0pid = 1;
+
+        depctl.b.usbactep = 1;
+
+        DWC_WRITE_REG32(addr, depctl.d32);
+    }
+    {
+
+        DWC_MODIFY_REG32(&dev_if->dev_global_regs->daintmsk,0, daintmsk.d32);
+    }
+
+    ep->stall_clear_flag = 0;
+
+    return;
+}
+/**
+ * This function does the setup for a data transfer for an EP and
+ * starts the transfer. For an IN transfer, the packets will be
+ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
+ * the packets are unloaded from the Rx FIFO in the ISR.  the ISR.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP to start the transfer on.
+ */
+
+void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+    //printf("#########start transfer#######\n");
+    depctl_data_t depctl;
+    deptsiz_data_t deptsiz;
+
+    if (ep->is_in == 1)
+    {   
+        //printf("#########ep->is_in == 1 INÐÍ´«Êä#######\n");
+        dwc_otg_dev_in_ep_regs_t *in_regs = core_if->dev_if->in_ep_regs[ep->num];
+
+        depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
+        deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
+
+        if (ep->maxpacket > (ep->maxxfer / MAX_PKT_CNT))
+        	{
+			//printf("#########ep->maxpacket > (ep->maxxfer / MAX_PKT_CNT)#######\n");
+            ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?\
+                            ep->maxxfer : (ep->total_len - ep->xfer_len);
+        	}
+        else
+        	{
+        	//printf("#########ep->maxpacket <= (ep->maxxfer / MAX_PKT_CNT)#######\n");
+            ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len - ep->xfer_len)) ?\
+                            MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
+        	}
+
+
+        /* Zero Length Packet? */
+        if ((ep->xfer_len - ep->xfer_count) == 0)
+        {
+            //printf("########(ep->xfer_len - ep->xfer_count) == 0########\n");
+            deptsiz.b.xfersize = 0;
+            deptsiz.b.pktcnt = 1;
+        }
+        else
+        {
+            //printf("########(ep->xfer_len - ep->xfer_count) != 0########\n");
+            deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
+            deptsiz.b.pktcnt = (ep->xfer_len - ep->xfer_count - 1 + ep->maxpacket) / ep->maxpacket;
+	#if 0/*unsigned the max value is 1023*/
+            if (deptsiz.b.pktcnt > MAX_PKT_CNT)
+            {
+               // printf("########deptsiz.b.pktcnt > MAX_PKT_CNT########\n");
+                deptsiz.b.pktcnt = MAX_PKT_CNT;
+                deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
+            }
+	#endif
+        }
+
+	if((ep->xfer_len - ep->xfer_count)% ep->maxpacket== 0)
+	{
+		printf("sent_zlp = 1\n");
+		ep->sent_zlp = 1;
+	}
+
+        DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
+
+        if (ep->xfer_len > 0)
+        {
+           // printf("########ep->xfer_len > 0########\n");
+            uint32_t fifoemptymsk = 0;
+            fifoemptymsk = 1 << ep->num;
+            DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,0, fifoemptymsk);
+
+        }
+    
+        /* EP enable, IN data in FIFO */
+        depctl.b.cnak = 1;
+        depctl.b.epena = 1;
+		//printf("EP enable, IN data in FIFO\n");
+        DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
+#if SIM_EN == EMULATION
+        REG32(ARM_PORTA)=0x82;
+#endif
+
+    }
+    else
+    {
+        /* OUT endpoint */
+		//printf("#########ep->is_in ==0 OUTÐÍ´«Êä#######\n");
+        dwc_otg_dev_out_ep_regs_t *out_regs = core_if->dev_if->out_ep_regs[ep->num];
+
+        depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
+        deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
+
+
+        if (ep->maxpacket > (ep->maxxfer / MAX_PKT_CNT))
+        	{
+        	//printf("#########ep->maxpacket > (ep->maxxfer / MAX_PKT_CNT)#######\n");
+            ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ? ep->maxxfer : (ep->total_len - ep->xfer_len);
+        	}
+        else
+        	{
+        	//printf("#########ep->maxpacket <= (ep->maxxfer / MAX_PKT_CNT)#######\n");
+            ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len - ep->xfer_len)) ? MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
+		    }
+
+
+        if ((ep->xfer_len - ep->xfer_count) == 0)
+        {
+            //printf("#########(ep->xfer_len - ep->xfer_count) == 0#######\n");
+            deptsiz.b.xfersize = ep->maxpacket;
+            deptsiz.b.pktcnt = 1;
+        }
+        else
+        {   
+            //printf("#########(ep->xfer_len - ep->xfer_count) != 0#######\n");
+            deptsiz.b.pktcnt = (ep->xfer_len - ep->xfer_count + (ep->maxpacket - 1)) / ep->maxpacket;
+			
+#if 0/*unsigned the max value is 1023*/
+            if (deptsiz.b.pktcnt > MAX_PKT_CNT)
+            {
+                //printf("usbusbdeptsiz.b.pktcnt > MAX_PKT_CNT#######\n");
+                deptsiz.b.pktcnt = MAX_PKT_CNT;
+            }
+#endif
+            ep->xfer_len = deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
+            deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
+        }
+
+        {
+
+            DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
+        }
+        /* EP enable */
+        depctl.b.cnak = 1;
+        depctl.b.epena = 1;
+        DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
+#if     SIM_EN == EMULATION
+       REG32(ARM_PORTA)=0x80;
+#endif
+
+    }
+}
+
+/**
+ * This function setup a zero length transfer in Buffer DMA and
+ * Slave modes for usb requests with zero field set
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP to start the transfer on.
+ *
+ */
+void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+
+    depctl_data_t depctl;
+    deptsiz_data_t deptsiz;
+
+    /* IN endpoint */
+    if (ep->is_in == 1)
+    {
+        dwc_otg_dev_in_ep_regs_t *in_regs = core_if->dev_if->in_ep_regs[ep->num];
+
+        depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
+        deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
+
+        deptsiz.b.xfersize = 0;
+        deptsiz.b.pktcnt = 1;
+        {
+            DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
+            {
+                /* Enable the Tx FIFO Empty Interrupt for this EP */
+                if (ep->xfer_len > 0)
+                {
+                    uint32_t fifoemptymsk = 0;
+                    fifoemptymsk = 1 << ep->num;
+                    DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,0, fifoemptymsk);
+                }
+            }
+        }
+
+        /* EP enable, IN data in FIFO */
+        depctl.b.cnak = 1;
+        depctl.b.epena = 1;
+        DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
+
+    }
+    else
+    {
+        /* OUT endpoint */
+        dwc_otg_dev_out_ep_regs_t *out_regs = core_if->dev_if->out_ep_regs[ep->num];
+
+        depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
+        deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
+
+        /* Zero Length Packet */
+        deptsiz.b.xfersize = ep->maxpacket;
+        deptsiz.b.pktcnt = 1;
+        {
+            DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
+        }
+
+        /* EP enable */
+        depctl.b.cnak = 1;
+        depctl.b.epena = 1;
+
+        DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
+
+    }
+}
+
+/**
+ * This function does the setup for a data transfer for EP0 and starts
+ * the transfer.  For an IN transfer, the packets will be loaded into
+ * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
+ * unloaded from the Rx FIFO in the ISR.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP0 data.
+ */
+void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+    depctl_data_t depctl;
+    deptsiz0_data_t deptsiz;
+    uint32_t fifoemptymsk;
+
+    ep->total_len = ep->xfer_len;
+
+    /* IN endpoint */
+    if (ep->is_in == 1)
+    {
+        //printf("ep0 tx data\n");
+       dwc_otg_dev_in_ep_regs_t *in_regs = core_if->dev_if->in_ep_regs[0];
+       depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
+       if (depctl.b.epena)
+           return;
+
+
+        /* If dedicated FIFO every time flush fifo before enable ep*/
+        dwc_otg_flush_tx_fifo(core_if, ep->tx_fifo_num);
+
+        depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
+        deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
+
+        /* Zero Length Packet? */
+        if (ep->xfer_len == 0)
+        {
+            deptsiz.b.xfersize = 0;
+            deptsiz.b.pktcnt = 1;
+        }
+        else
+        {
+            /* Program the transfer size and packet count
+             *      as follows: xfersize = N * maxpacket +
+             *      short_packet pktcnt = N + (short_packet
+             *      exist ? 1 : 0)
+             */
+            if (ep->xfer_len > ep->maxpacket)
+            {
+                ep->xfer_len = ep->maxpacket;
+                deptsiz.b.xfersize = ep->maxpacket;
+            }
+            else
+            {
+                deptsiz.b.xfersize = ep->xfer_len;
+            }
+            deptsiz.b.pktcnt = 1;
+
+        }
+
+
+        {
+            DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
+        }
+
+        /* EP enable, IN data in FIFO */
+        depctl.b.cnak = 1;
+        depctl.b.epena = 1;
+        DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
+
+        /**
+         * Enable the Non-Periodic Tx FIFO empty interrupt, the
+         * data will be written into the fifo by the ISR.
+         */
+
+      /* Enable the Tx FIFO Empty Interrupt for this EP */
+      if (ep->xfer_len > 0)
+      {
+          fifoemptymsk = 0;
+          fifoemptymsk |= 1 << ep->num;
+          DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,0, fifoemptymsk);
+      }
+
+    }
+    else
+    {
+        /* OUT endpoint */
+        dwc_otg_dev_out_ep_regs_t *out_regs = core_if->dev_if->out_ep_regs[0];
+
+        depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
+        deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
+
+        /* Program the transfer size and packet count as follows:
+         *      xfersize = N * (maxpacket + 4 - (maxpacket % 4))
+         *      pktcnt = N                                                                                      */
+        /* Zero Length Packet */
+        deptsiz.b.xfersize = ep->maxpacket;
+        deptsiz.b.pktcnt = 1;
+        deptsiz.b.supcnt = 3;
+        DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
+
+        /* EP enable */
+        depctl.b.cnak = 1;
+        depctl.b.epena = 1;
+        DWC_WRITE_REG32(&(out_regs->doepctl), depctl.d32);
+
+    }
+}
+
+/**
+ * This function continues control IN transfers started by
+ * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
+ * single packet.  NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
+ * bit for the packet count.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP0 data.
+ */
+void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+    depctl_data_t depctl;
+    deptsiz0_data_t deptsiz;
+
+    if (ep->is_in == 1)
+    {
+        dwc_otg_dev_in_ep_regs_t *in_regs = core_if->dev_if->in_ep_regs[0];
+
+        depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
+        deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
+
+        deptsiz.b.xfersize = (ep->total_len - ep->xfer_count) > ep->maxpacket ? ep->maxpacket : (ep->total_len - ep->xfer_count);
+        deptsiz.b.pktcnt = 1;
+
+        ep->xfer_len += deptsiz.b.xfersize;
+
+        DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
+
+
+        depctl.b.cnak = 1;
+        depctl.b.epena = 1;
+        DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
+
+        /**
+         * Enable the Non-Periodic Tx FIFO empty interrupt, the
+         * data will be written into the fifo by the ISR.
+         */
+
+        /* Enable the Tx FIFO Empty Interrupt for this EP */
+        if (ep->xfer_len > 0)
+        {
+            uint32_t fifoemptymsk = 0;
+            fifoemptymsk |= 1 << ep->num;
+            DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,0, fifoemptymsk);
+        }
+
+    }
+    else
+    {
+        dwc_otg_dev_out_ep_regs_t *out_regs = core_if->dev_if->out_ep_regs[0];
+
+        depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
+        deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
+
+        deptsiz.b.xfersize = ep->maxpacket;
+        deptsiz.b.pktcnt = 1;
+        DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
+        depctl.b.cnak = 1;
+        depctl.b.epena = 1;
+        DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
+
+    }
+}
+
+
+/**
+ * This function writes a packet into the Tx FIFO associated with the
+ * EP. For non-periodic EPs the non-periodic Tx FIFO is written.  For
+ * periodic EPs the periodic Tx FIFO associated with the EP is written
+ * with all packets for the next micro-frame.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP to write packet for.
+ * @param dma Indicates if DMA is being used.
+ */
+void dwc_otg_ep_write_packet(dwc_otg_core_if_t * core_if, dwc_ep_t * ep,
+                             int dma)
+{
+    uint32_t i;
+    uint32_t byte_count;
+    uint32_t dword_count;
+    uint32_t *fifo;
+    uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
+
+    if (ep->xfer_count >= ep->xfer_len)
+    {
+        return;
+    }
+
+    /* Find the byte length of the packet either short packet or MPS */
+    if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket)
+    {
+        byte_count = ep->xfer_len - ep->xfer_count;
+    }
+    else
+    {
+        byte_count = ep->maxpacket;
+    }
+
+    /* Find the DWORD length, padded by extra bytes as neccessary if MPS
+     * is not a multiple of DWORD */
+    dword_count = (byte_count + 3) / 4;
+
+    /**@todo NGS Where are the Periodic Tx FIFO addresses
+     * intialized?	What should this be? */
+    //printf("fifo = core_if->data_fifo[ep->num];\n");
+    fifo = core_if->data_fifo[ep->num];
+    for (i = 0; i < dword_count; i++, data_buff++)
+    {
+        DWC_WRITE_REG32(fifo, *data_buff);
+
+    }
+
+
+    ep->xfer_count += byte_count;
+    ep->xfer_buff += byte_count;
+}
+
+/**
+ * Set the EP STALL.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP to set the stall on.
+ */
+void dwc_otg_ep_set_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+    depctl_data_t depctl;
+    volatile uint32_t *depctl_addr;
+    if (ep->is_in == 1)
+    {
+        depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
+        depctl.d32 = DWC_READ_REG32(depctl_addr);
+
+        /* set the disable and stall bits */
+        if (depctl.b.epena)
+        {
+            depctl.b.epdis = 1;
+        }
+        depctl.b.stall = 1;
+        DWC_WRITE_REG32(depctl_addr, depctl.d32);
+    }
+    else
+    {
+        depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
+        depctl.d32 = DWC_READ_REG32(depctl_addr);
+
+        depctl.b.stall = 1;
+        DWC_WRITE_REG32(depctl_addr, depctl.d32);
+    }
+
+    return;
+}
+
+/**
+ * Clear the EP STALL.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP to clear stall from.
+ */
+void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+    depctl_data_t depctl;
+    volatile uint32_t *depctl_addr;
+
+    if (ep->is_in == 1)
+    {
+        depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
+    }
+    else
+    {
+        depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
+    }
+
+    depctl.d32 = DWC_READ_REG32(depctl_addr);
+
+    /* clear the stall bits */
+    depctl.b.stall = 0;
+
+    /*
+     * USB Spec 9.4.5: For endpoints using data toggle, regardless
+     * of whether an endpoint has the Halt feature set, a
+     * ClearFeature(ENDPOINT_HALT) request always results in the
+     * data toggle being reinitialized to DATA0.
+     */
+    if (ep->type == DWC_OTG_EP_TYPE_INTR ||
+            ep->type == DWC_OTG_EP_TYPE_BULK)
+    {
+        depctl.b.setd0pid = 1;	/* DATA0 */
+    }
+
+    DWC_WRITE_REG32(depctl_addr, depctl.d32);
+    return;
+}
+
+/**
+ * This function reads a packet from the Rx FIFO into the destination
+ * buffer. To read SETUP data use dwc_otg_read_setup_packet.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param dest	  Destination buffer for the packet.
+ * @param bytes  Number of bytes to copy to the destination.
+ */
+void dwc_otg_read_packet(dwc_otg_core_if_t * core_if,
+                         uint8_t * dest, uint16_t bytes)
+{
+    int i;
+    int word_count = (bytes + 3) / 4;
+
+    volatile uint32_t *fifo = core_if->data_fifo[0];
+    uint32_t *data_buff = (uint32_t *) dest;
+
+
+    for (i = 0; i < word_count; i++, data_buff++)
+    {
+        *data_buff = DWC_READ_REG32(fifo);
+    }
+
+    return;
+}
+
+/**
+ * Flush a Tx FIFO.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param num Tx FIFO to flush.
+ */
+void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num)
+{
+    dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+    volatile grstctl_t greset;
+    int count = 0;
+    greset.d32 = 0;
+
+    greset.b.txfflsh = 1;
+    greset.b.txfnum = num;
+if(global.g_enum == NEED_ENUM)
+{
+    DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
+
+    do
+    {
+        greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
+        if (++count > 10000)
+        {
+            break;
+        }
+        usdelay(10);
+    }
+    while (greset.b.txfflsh == 1);
+
+    /* Wait for 3 PHY Clocks */
+    usdelay(10);
+}
+
+}
+
+/**
+ * Flush Rx FIFO.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ */
+void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * core_if)
+{
+    dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+    volatile grstctl_t greset;
+    int count = 0;
+    greset.d32 = 0;
+    greset.b.rxfflsh = 1;
+if(global.g_enum == NEED_ENUM)
+{
+    DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
+
+    do
+    {
+        greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
+        if (++count > 10000)
+        {
+            break;
+        }
+        usdelay(10);   
+     }
+    while (greset.b.rxfflsh == 1);
+
+    /* Wait for 3 PHY Clocks */
+
+    usdelay(10);
+}
+}
+
+/**
+ * Do core a soft reset of the core.  Be careful with this because it
+ * resets all the internal state machines of the core.
+ */
+void dwc_otg_core_reset(dwc_otg_core_if_t * core_if)
+{
+    dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+    volatile grstctl_t greset;
+    int count = 0;
+    greset.d32 =0;
+    /* Wait for AHB master IDLE state. */
+    do
+    {
+        usdelay(10);
+        greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
+        if (++count > 100000)
+        {
+            return;
+        }
+    }
+    while (greset.b.ahbidle == 0);
+
+    /* Core Soft Reset */
+    count = 0;
+    greset.b.csftrst = 1;
+    DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
+    do
+    {
+        greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
+        if (++count > 10000)
+        {
+            break;
+        }
+        usdelay(10);
+    }
+    while (greset.b.csftrst == 1);
+/* Wait for 3 PHY Clocks */
+    usdelay(10);
+}
+
+static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if)
+{
+    int i;
+    core_if->core_params = &global.g_core_params;
+    core_if->core_params->otg_cap = DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE;
+    #if USB_PHY == ULPI   
+    core_if->core_params->phy_type = DWC_PHY_TYPE_PARAM_ULPI;
+    #elif USB_PHY == UTMI
+    core_if->core_params->phy_type = DWC_PHY_TYPE_PARAM_UTMI;
+    #endif
+
+    core_if->core_params->speed = DWC_SPEED_PARAM_HIGH;//DWC_SPEED_PARAM_FULL
+    core_if->core_params->phy_ulpi_ddr = dwc_param_phy_ulpi_ddr_default;
+    core_if->core_params->phy_ulpi_ext_vbus = dwc_param_phy_ulpi_ext_vbus_default;
+    //fpga use 30M,16bit width    asic use 60M,8bit width  add tj
+    core_if->core_params->phy_utmi_width = 8;
+
+    core_if->core_params->ts_dline = dwc_param_ts_dline_default;
+    core_if->core_params->ulpi_fs_ls = dwc_param_ulpi_fs_ls_default;
+    core_if->core_params->en_multiple_tx_fifo = dwc_param_en_multiple_tx_fifo_default;
+    for (i = 0; i < 15; i++)
+    {
+       core_if->core_params->dev_tx_fifo_size[i] = dwc_param_dev_tx_fifo_size_default;
+    }
+    core_if->core_params->otg_ver = 1;
+    return 0;
+}
+
+
+
+
+
+
+
diff --git a/boot/common/src/uboot/drivers/usb_drv/dwc_otg_cil_intr.c b/boot/common/src/uboot/drivers/usb_drv/dwc_otg_cil_intr.c
new file mode 100644
index 0000000..1e50cf1
--- /dev/null
+++ b/boot/common/src/uboot/drivers/usb_drv/dwc_otg_cil_intr.c
@@ -0,0 +1,69 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil_intr.c $
+ * $Revision: #32 $
+ * $Date: 2012/08/10 $
+ * $Change: 2047372 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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.
+ * ========================================================================== */
+
+/** @file
+ *
+ * The Core Interface Layer 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.
+ *
+ * This file contains the Common Interrupt handlers.
+ */
+
+#include <usb/dwc_otg_regs.h>
+#include <usb/dwc_otg_cil.h>
+#include <usb/dwc_otg_driver.h>
+#include <usb/dwc_otg_pcd.h>
+/**
+ * This interrupt indicates that SUSPEND state has been detected on
+ * the USB.
+ *
+ * For HNP the USB Suspend interrupt signals the change from
+ * "a_peripheral" to "a_host".
+ *
+ * When power management is enabled the core will be put in low power
+ * mode.
+ */
+int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t * core_if)
+{
+    gintsts_data_t gintsts;
+    printk("Suspend\n");
+  
+    /* Clear interrupt */
+    gintsts.d32 = 0;
+    gintsts.b.usbsuspend = 1;
+    DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
+
+    return 1;
+}
+
diff --git a/boot/common/src/uboot/drivers/usb_drv/dwc_otg_dev_test.c b/boot/common/src/uboot/drivers/usb_drv/dwc_otg_dev_test.c
new file mode 100755
index 0000000..b25466c
--- /dev/null
+++ b/boot/common/src/uboot/drivers/usb_drv/dwc_otg_dev_test.c
@@ -0,0 +1,732 @@
+/******************************************************************/

+#include <usb/global.h>

+#include <usb/dwc_otg_driver.h>

+#include <usb/drv_usb3slave.h>

+#include <asm/arch/cpu.h>

+#include <asm/io.h>

+#include <config.h>

+

+

+#define SYS_SOC_MOD_CLKSEL         (SYS_SOC_CRM_BASE+0x54)

+#define SYS_SOC_MOD_RSTEN          (SYS_SOC_CRM_BASE+0x8c)          

+#define SYS_SOC_MOD_USBSTATECTRL   (SYS_SOC_CRM_BASE+0x90)

+

+#define ST_WAIT_SYNC_FLAG   (0x0)

+#define ST_WAIT_REG_CONFIG  (0x1)

+#define ST_REG_CONFIG       (0x2)

+#define ST_WAIT_DOWNLOAD    (0x3)

+#define ST_DOWNLOAD_HEAD    (0x4)

+#define ST_DOWNLOAD_DATA    (0x5)

+#define ST_DOWNLOAD_ADDR    (0x6)

+

+#define SYNC_FLAG           (0x5a) // "Z"

+#define REG_CONFIG_FLAG     (0x6a) // ""

+#define DOWNLOAD_FLAG       (0x7a) // "z"

+#define RUN_FLAG            (0x8a) // ""

+#define GET_ID			    (0x9a) // new added

+

+WORD32 Para_Section SyncACK=0xa5;

+__align(4) BYTE Para_Section CHIP_ID[8]={'Z','X','7','5','2','0','V','2'};

+WORD32 Para_Section  UsbACK = 0;

+

+extern void udelay(unsigned long usec);

+void USB_isr(WORD32 dwIntNo,WORD32 dwPara);

+

+void Out_callback( WORD32 dwPara, WORD32 dwCause, WORD32 dwDone, WORD32 dwLen);

+

+

+void In_callback( WORD32 dwPara, WORD32 dwCause, WORD32 dwDone, WORD32 dwLen);

+

+

+

+void usdelay(unsigned us)

+{

+	udelay(us);

+}

+

+static inline void delay0(unsigned long loops)

+{

+    /*

+	__asm__ volatile ("1:\n" "subs %0, %1, #1\n"

+			  "bne 1b":"=r" (loops):"0"(loops));

+	*/

+}

+static inline void udelay0(unsigned long us)

+{

+	delay0(us * 200); /* approximate */

+}

+

+void usbdelay(unsigned us)

+{

+	udelay0(us);

+}

+

+void USB_TstDev_Isr(void)

+{

+    USB_isr(0,0);    //´¦ÀíÖжϷþÎñ

+}

+

+

+WORD32 USB_RecvOutData(WORD32 dwEPNo, BYTE *pchBuf, WORD32 dwLen, F_USB_CB fnUsbCb, void *pPara)

+{

+    dwc_otg_pcd_ep_t *ep = NULL;

+    ep = &(global.g_dwc_otg_dev_t.pcd->out_ep[dwEPNo-1]);

+    ep->dwc_ep.is_in = 0;

+    ep->dwc_ep.num = dwEPNo;

+    ep->dwc_ep.data_pid_start = 0;

+    ep->dwc_ep.tx_fifo_num = dwEPNo;

+    ep->dwc_ep.start_xfer_buff = pchBuf;

+    ep->dwc_ep.xfer_buff = pchBuf;

+    ep->dwc_ep.xfer_len = 0;

+    ep->dwc_ep.xfer_count = 0;

+    ep->dwc_ep.fnUsbCb = fnUsbCb;

+    ep->dwc_ep.pPara = pPara;

+    ep->dwc_ep.total_len = dwLen;

+    dwc_otg_ep_start_transfer(global.g_dwc_otg_dev_t.core_if,&ep->dwc_ep);

+    return 0;

+}

+

+WORD32 USB_SendInData(WORD32 dwEPNo, BYTE *pchBuf, WORD32 dwLen, F_USB_CB fnUsbCb, void *pPara)

+{

+    dwc_otg_pcd_ep_t *ep = NULL;

+    ep = &(global.g_dwc_otg_dev_t.pcd->in_ep[dwEPNo-1]);

+    ep->dwc_ep.is_in = 1;

+    ep->dwc_ep.num = dwEPNo;

+    ep->dwc_ep.data_pid_start = 0;

+    ep->dwc_ep.tx_fifo_num = dwEPNo;

+    ep->dwc_ep.start_xfer_buff = pchBuf;

+    ep->dwc_ep.xfer_buff = pchBuf;

+    ep->dwc_ep.fnUsbCb = fnUsbCb;

+    ep->dwc_ep.pPara = pPara;

+    ep->dwc_ep.xfer_len = 0;

+    ep->dwc_ep.xfer_count = 0;

+    ep->dwc_ep.total_len = dwLen;

+    dwc_otg_ep_start_transfer(global.g_dwc_otg_dev_t.core_if,&ep->dwc_ep);

+    return 0;

+}

+

+

+WORD32 usb_read(WORD32 dwLen, BYTE *pchBuf)

+{

+	WORD32 dwDone;

+

+	global.dwRxQuit=0;

+	USB_RecvOutData( 1,(BYTE *)pchBuf,dwLen,Out_callback,(void *)&dwDone);

+	while(!global.dwRxQuit)

+	{

+        USB_TstDev_Isr();

+	}

+	return dwDone;

+}

+

+

+WORD32 usb_write(WORD32 dwLen, BYTE *pchBuf)

+{

+	WORD32 dwDone;

+

+	global.dwTxQuit=0;

+	USB_SendInData(1,pchBuf, dwLen, In_callback,(void *)&dwDone);

+	while(!global.dwTxQuit)

+	{

+

+    		USB_TstDev_Isr();

+	}

+

+	return dwDone;

+}

+

+#if 0

+WORD32 USB_Check_Sync(BYTE *pchBuf, WORD32 dwLen)

+{

+	WORD32 dwDone;

+	WORD32 dwCount = 0;

+

+	global.dwRxQuit=0;

+	printf("########USB_RecvOutData start##########\n");

+	USB_RecvOutData( 1,(BYTE *)pchBuf,dwLen,Out_callback,(void *)&dwDone);

+	printf("########USB_RecvOutData end##########\n");

+	dwCount=0;

+	while(1)

+	{

+        USB_TstDev_Isr();

+		if(0==global.dwRxQuit)

+		{

+			dwCount++;

+			if(dwCount>(200*global.g_USB_TIMEOUT))

+			{

+				//return 0;

+			}

+#if SIM_EN

+        	//usbdelay(5000);

+#else

+            usbdelay(1);

+#endif

+		}

+		else

+		{

+		    printf("global.dwRxQuit == 1 \n");

+			break;

+		}

+	}

+    printf("########5a##########\n");

+	if(0x5A!=*pchBuf)

+	{

+	    printf("0x5A!=*pchBuf \n");

+		return 0;

+	}

+    printf("########end 5a##########\n");

+	return dwDone;

+}

+#endif

+

+#if 0

+char the_write_data;

+void Boot_Process(BYTE *pkt,int len)

+{

+    int i=0;

+    static int count=0;

+    static int addr;

+    static int value;

+    char cTmp=0;

+    //WORD32 SyncACK=0xa5;

+    int case_state;

+    if(0==len)

+        return ;

+    while(i<len)

+    {

+        cTmp=pkt[i++];

+		the_write_data=cTmp;

+        printf("usb_booting 0 \n");

+           case_state = global.g_State;

+           if( ST_WAIT_SYNC_FLAG == case_state)

+           	{

+           	  printf("usb_booting 1 \n");

+                if(SYNC_FLAG==cTmp)

+                {   

+                    printf("get 5A  \n");

+                    global.g_State=ST_WAIT_DOWNLOAD;

+#if CFG_USB

+                    printf("usb_write A5\n");

+                    usb_write(1,(BYTE *)&SyncACK);

+					 printf("usb_write A5 over\n");

+#else

+                    printf(" CFG_USB ==0  \n");

+                    UART_Write((BYTE *)&SyncACK,1);

+#endif

+                }

+           	}

+		   	else if(GET_ID==cTmp)//¶ÁȡоƬID

+	        {

+#if CFG_USB

+                    usb_write(8,(BYTE*)CHIP_ID);

+#else

+                    UART_Write((BYTE *)CHIP_ID,8);

+#endif	            

+	        }

+            else if(ST_REG_CONFIG ==case_state)

+            	{

+                if(count<4)    // 4 bytes addr

+                {

+                    addr<<=8;

+                    addr|=cTmp;

+                }

+                else if(count<8)    // 4 byte data

+                {

+                    value<<=8;

+                    value|=cTmp;

+                }

+

+                count++;

+

+                if(4==count)

+                {

+                    if(0==addr)

+                    {

+                       global.g_State=ST_WAIT_DOWNLOAD;

+					   UsbACK=0xA6;

+#if CFG_USB					  

+                       usb_write(1,&UsbACK);

+#else

+						UART_Write(&UsbACK,1);

+#endif

+                    }

+                }

+                else if(8==count)

+                {

+                    REG32(addr)=value;

+                    count=0;

+                }

+

+            	}

+            else if (ST_WAIT_DOWNLOAD==case_state)

+            	{

+                if(REG_CONFIG_FLAG==cTmp)

+                {

+                    global.g_State=ST_REG_CONFIG;

+                    count=0;

+                }

+                else if(DOWNLOAD_FLAG==cTmp)

+                {

+                    global.g_State=ST_DOWNLOAD_HEAD;

+                    count=0;

+                    value=0;

+                }

+                else if(RUN_FLAG==cTmp)    //Ö§³Ö¶à´ÎÏÂÔØ0818

+                {

+                    global.g_State=ST_DOWNLOAD_ADDR;

+                    count=0;

+                    value=0;

+                }

+            	}

+            else if( ST_DOWNLOAD_HEAD==case_state)

+            	{

+                if(count<4)    // 4 byte addr

+                {

+                    addr<<=8;

+                    addr|=cTmp;

+                }

+                else if(count<8) // 4 byte size

+                {

+                    value<<=8;

+                    value|=cTmp;

+                }

+

+                count++;

+

+                if(count==8)

+                {

+                    count=0;

+                    global.g_bootaddr=addr; //µØÖ·

+                    global.g_bootsize=value;//³¤¶È

+                    global.g_State=ST_DOWNLOAD_DATA;

+					UsbACK=0xA1;

+                    usb_write(1,&UsbACK);

+                }

+            	}

+            else if( ST_DOWNLOAD_DATA==case_state)

+            	{

+                if(global.g_bootsize==len)

+                {

+                    if(global.g_bootaddr==(int)pkt)

+                        {

+                        global.g_State=ST_WAIT_DOWNLOAD;//Ö§³Ö¶à´ÎÏÂÔØ0818

+                        UsbACK=0xA7;

+						usb_write(1,&UsbACK);

+                            return;

+                        }

+                    }

+                    else

+                    {

+                    global.g_bootaddr+=len;

+                    global.g_bootsize-=len;

+                        return ;

+                }

+            	}

+            else if( ST_DOWNLOAD_ADDR==case_state)

+            	{

+                if(count<4)    // 4 byte addr

+                {

+                    addr<<=8;

+                    addr|=cTmp;

+                }

+

+                count++;

+

+                if(count==4)

+                {

+                    count=0;

+                    global.g_bootaddr=addr;

+                    global.g_bootfinish=1;

+					UsbACK=0xA8;

+                    usb_write(1,&UsbACK);

+                    return ;

+                }

+            	}

+		else

+		{

+

+		}

+

+           }

+     

+}

+#endif

+

+__align(4) BYTE Para_Section tmp[64]={0};

+

+

+#if 0   //loaderϵ÷Óã»

+void USB_Boot(void)

+{

+    WORD32			dwLen;

+    WORD32  		dwMaxLen;

+    BYTE 			*pbyBuf;

+    printf("######enter USB_Boot#####\n");

+    global.g_State	= ST_WAIT_SYNC_FLAG;

+    pbyBuf 			= (BYTE*)tmp;

+

+    for(dwMaxLen = 0; dwMaxLen < 64; dwMaxLen++)

+    {

+    	tmp[dwMaxLen] = 0;

+    }

+

+	dwMaxLen = 512;  //¿ØÖÆÆ÷ÓÐÒªÇóbulk outʱ£¬½ÓÊÕ³¤¶È´óÓÚµÈÓÚ512

+/* µ±usb_mode =1ʱ£¬ÓÃÓÚHSIC,µ±usb_mode =0ʱ£¬ÓÃÓÚUSB */

+    if(global.g_USB_MODE == 0)

+    {

+        printf("########USB_Check_Sync##########\n");

+		dwLen=USB_Check_Sync(pbyBuf,dwMaxLen);

+

+        if(0==dwLen)

+        {

+            return ;

+        }

+        printf("0!=dwLen,enter boot_process\n"); 

+

+        Boot_Process(pbyBuf,dwLen);

+    }

+	printf("########globalfinish##########\n");

+    while(0 == global.g_bootfinish)

+    {

+        //dwLen=usb_read(pbyBuf,dwMaxLen);

+        dwLen=usb_read(dwMaxLen,pbyBuf);

+

+        Boot_Process(pbyBuf,dwLen);

+

+        if((ST_DOWNLOAD_DATA==global.g_State)&&(global.g_bootaddr!=0))

+        {

+            pbyBuf=(BYTE *)global.g_bootaddr;

+            dwMaxLen=512;//global.g_bootsize;

+        }

+        else

+        {

+            pbyBuf=tmp;

+            dwMaxLen=512;//½ÓÊÕµØÖ·£¬³¤¶ÈÐÅÏ¢

+        }

+

+    }

+

+    if(1==global.g_bootfinish)

+    {

+       #if 0 /*shield dma function*/

+        dwc_otg_core_dev_disconnet(global.g_dwc_otg_pcd_tp.core_if);

+        printf("disconnect usb controller\n");

+	#endif

+    	writel(0xE59ff000, SYS_IRAM1_BASE);                 /* Ìø×ªµ½r7Ö´ÐÐtboot */

+        writel(global.g_bootaddr, SYS_IRAM1_BASE + 8); 

+	    printf("Starting the t-boot ...\n");

+        writel(0xf, CPU_A9_SUBSYS_CFG);

+    }

+}

+#endif

+

+void usb_boot(WORD32 USB_ADDR)

+{

+    global.g_USB_TIMEOUT = 0xff;

+

+    //printf( "#######tsp_usb_init...\n");

+    tsp_usb_init();  /*ÅäÖÃÍâΧ»·¾³£¬Ã¶¾ÙTLOADERµÄUSB¶Ë¿Ú*/

+	//printf("tsp_usb_init...end\n");

+	

+    //USB_Boot();    /*usb bootÏÂÔØÄ£Ê½*/

+}

+

+

+void USB_isr(WORD32 dwIntNo,WORD32 dwPara)

+{

+    dwc_otg_pcd_handle_intr(global.g_dwc_otg_dev_t.pcd);

+}

+

+#if 0

+void USB_Pll_Clk_Rst_InitEnv(void)

+{

+

+#if ((SIM_EN == ASIC)||(SIM_EN == EMULATION))

+

+    WORD32 i;

+    if(0 == global.g_pll_cfg)

+    {

+	//add pll config

+	    REG32(SYS_SOC_CRM_BASE+0x30)  = 0x1ffff;    //pll_MAIN lock need delay time

+	    REG32(SYS_SOC_CRM_BASE+0x34)  = 0x1ffff;    //pll_U lock need delay time for HSIC

+	//open pll_624_MainPll

+	    REG32(SYS_SOC_CRM_BASE+0x14) &= 0xffffffff;

+	    REG32(SYS_SOC_CRM_BASE+0x10) &= 0x7fffffff;

+    

+	    i = 0;

+	    do

+	    {

+	        i++;

+	        usdelay(PLL_8X(40));

+	        if(i>50000) 

+	        {

+	            printk("E1");

+	            break;

+	        }

+	    }while((REG32(SYS_SOC_CRM_BASE+0x10)&0x40000000) ==0);

+

+	 //HSIC need pll_480   

+	    if(1 == global.g_USB_MODE)

+	    {

+	        //open pll_480

+	        REG32(SYS_SOC_CRM_BASE+0x24) &= 0xffffffff;

+	        REG32(SYS_SOC_CRM_BASE+0x20) &= 0x7fffffff;

+

+	        i = 0;

+	        do

+	        {

+	            i++;

+	            usdelay(PLL_8X(40));

+	            if(i>50000) 

+	            {

+	                printk("E2");

+	                break;

+	            }

+	        }while((REG32(SYS_SOC_CRM_BASE+0x20)&0x40000000) ==0);

+	    }

+ 

+	// m0 and axi clk sel config ,M0 208M,axi 156M

+	    REG32(SYS_SOC_CRM_BASE+0x50) &= (~0x7);    //0:m0 sel pll_208   1:mclk

+	    REG32(SYS_STD_CRM_BASE+0x0) &= (~0x7);    //0:axi  sel 156m    1:mclk

+    

+#if SIM_EN == EMULATION

+		/* 1.pin mux*/

+		REG32(SYS_PAD_CTRL0_BASE+0x7c)&= 0x3ff00000;

+		REG32(SYS_PAD_CTRL0_BASE+0x80)&= (~0x3ff);

+		REG32(SYS_PAD_CTRL0_BASE+0x84)&= 0x3ff00000;

+		REG32(SYS_PAD_CTRL0_BASE+0x74)&= 0xc00ffc00; 	   

+		REG32(SYS_PAD_CTRL0_BASE+0x88)&= (~0xffc00);

+

+		/* 2.out or in enable*/

+		REG32(0x145000)&=0xff00;   //in

+		REG32(0x145000+0x40)|=0xff; //out		

+#endif

+    } 

+    if(0 == global.g_USB_MODE)

+    {

+

+        REG32(SYS_SOC_MOD_RSTEN)|=(0x3<<5);

+        usdelay(10);    

+        //select bus clk early

+        REG32(SYS_SOC_MOD_CLKSEL) &= ~0x3;

+        //release usb  phy reset 

+        usdelay(10);

+        REG32(SYS_SOC_MOD_RSTEN) |= 1<<4;     

+    }

+    else if(1 == global.g_USB_MODE)

+    {

+        REG32(SYS_SOC_MOD_RSTEN)|=(0x3<<1);

+        usdelay(10);

+        //select bus clk early

+        REG32(SYS_SOC_MOD_CLKSEL) &= ~0x3;  /*0:156M*/

+        usdelay(10);

+        //release usb hsic phy reset 

+        REG32(SYS_SOC_MOD_RSTEN) |= 0x1;

+        usdelay(100);

+        i = 0;

+        while((REG32(SYS_SOC_MOD_USBSTATECTRL)&0x1) == 0)

+        {

+            i++;

+            usdelay(20);

+            if(i>250000) 

+            {

+                printk("E4");

+                break;

+            }

+        }

+#if SIM_EN == EMULATION

+	   usdelay(20);

+	   REG32(REG_GPIO_OUT)=1;

+//		 while(REG32(REG_GPIO_IN)!=0xFF);

+	   usdelay(1);

+	   REG32(REG_GPIO_OUT)=0;

+#endif	   

+

+    }

+    else if(2 == global.g_USB_MODE)

+    {

+		REG32(SYS_LSP_CRM_BASE+0x28) &= (~(0x7<<4)); /*0:104M 1:26M,2:52M,4:156M*/

+        usdelay(10);

+        REG32(SYS_STD_CRM_BASE+0x4)&= ~0x3;  /*div 0:1 1:2 4:4*/

+        usdelay(10);

+    }

+

+#elif (SIM_EN == FPGA)

+    if(0 == global.g_USB_MODE)

+    {

+

+        REG32(SYS_SOC_MOD_RSTEN)|=(0x3<<5);

+        usdelay(10);    

+        //select bus clk early

+        REG32(SYS_SOC_MOD_CLKSEL) &= ~0x3;

+        //release usb  phy reset 

+        usdelay(10);

+        REG32(SYS_SOC_MOD_RSTEN) |= 1<<4;     

+    }

+

+#endif

+}

+#endif

+

+T_USB_ENUM USB_Need_Enum(WORD32 USB_ADDR)

+{

+	WORD32 temp = 0;

+	temp = DWC_READ_REG32(USB_ADDR+0x14);

+	if(((temp>>13)|1)==1)

+	{

+		return DONOT_NEED_ENUM;

+	}

+	return NEED_ENUM;

+}

+unsigned int g_testVal = 0;

+

+WORD32 USB_CDC_Enum(WORD32 USB_ADDR)

+{

+	WORD32 dwCount=0;

+	WORD32 dwCount1=0;

+	if(NEED_ENUM == global.g_enum)

+	{

+		global.g_Connet = 0;

+	}

+	else

+	{

+        	global.g_Connet = 1;

+	}

+

+	global.g_USB_TIMEOUT	= 10;

+

+	g_testVal = 20/5;

+	dwc_otg_driver_probe(USB_ADDR);

+	if(global.g_enum == NEED_ENUM)

+	{

+	 //printk("enuming\n");

+	while (1)

+	{

+	//poll mode or interrupt mode

+		USB_TstDev_Isr();

+#if SYNC_SETADDRESS

+	    if (global.g_dwc_otg_dev_t.pcd->request_config == 2)

+	    break;

+#else

+	    //µÈ´ý½øÈëÅäÖÃ̬

+		if (global.g_dwc_otg_dev_t.pcd->request_config == 1)

+			break;

+#endif

+/* µ±usb_mode =1ʱ£¬ÓÃÓÚHSIC,µ±usb_mode =0ʱ£¬ÓÃÓÚUSB */

+	    if(global.g_USB_MODE == 0)

+        {

+		    if(0==global.g_Connet)

+	        {

+			   dwCount++;

+#if SIM_EN

+			   usbdelay(5000);

+#else

+               usbdelay(1);

+#endif

+			   if(dwCount>(400*global.g_USB_TIMEOUT))

+			   {

+				   //return 1;

+			   }

+		    }

+#if SYNC_SETADDRESS            

+	        else if(global.g_dwc_otg_dev_t.pcd->request_config == 2)

+#else

+            else if(global.g_dwc_otg_dev_t.pcd->request_config == 1)

+#endif

+	        {

+	        	break;

+	        }

+		    else

+		    {

+			    dwCount1++;

+#if SIM_EN

+			    //usbdelay(5000);

+#else

+                usbdelay(1);

+#endif

+			    if(dwCount1>(200*global.g_USB_TIMEOUT))

+			    {

+				    //return 1;  huhuahong

+			    }

+	        }

+        }

+     }

+		}

+     return 0;

+}

+

+void Out_callback( WORD32 dwPara, WORD32 dwCause, WORD32 dwDone, WORD32 dwLen)

+{

+	*((WORD32 *)dwPara) = dwDone;

+	global.dwRxQuit	= 1;

+#if SIM_EN == EMULATION

+    REG32(ARM_PORTA)=0x81;

+#endif

+

+}

+

+void In_callback( WORD32 dwPara, WORD32 dwCause, WORD32 dwDone, WORD32 dwLen)

+{

+	*((WORD32 *)dwPara) = dwDone;

+	global.dwTxQuit	= 1;

+#if SIM_EN == EMULATION

+        REG32(ARM_PORTA)=0x83;

+#endif

+}

+

+

+//tangjian:µ÷ÓÃusb3.0µÄÊý¾Ý¶ÁºÍдº¯Êý

+extern WORD32 USB3_RecvOutData(WORD32 dwEPNo, BYTE *pchBuf, WORD32 dwLen, F_USB_CB fnUsbCb, void *pPara);

+extern WORD32 USB3_SendInData(WORD32 dwEPNo, BYTE *pchBuf, WORD32 dwLen, F_USB_CB fnUsbCb, void *pPara);

+extern void USB3Slave_ISR(u32 udIntNo,u32 udPara);

+extern u32 USB3Slave_IsNeedZero(u32 dwLen);

+

+

+

+

+

+

+

+

+

+int dwc_otg_driver_probe(WORD32 USB_ADDR)

+{
+    uint32_t udj = 0;

+    uint32_t *ptbase = (uint32_t *)USB_ADDR;

+    uint8_t* ptg_dwc_otg_dev_t = (uint8_t* )(&global.g_dwc_otg_dev_t);

+	

+    for(udj= 0;udj<sizeof(global.g_dwc_otg_dev_t);udj++)

+    {

+       ptg_dwc_otg_dev_t[udj] = 0;

+    }

+    global.g_dwc_otg_dev_t.core_if = dwc_otg_cil_init(ptbase);

+

+    /*
+    * Initialize the DWC_otg core.
+    */

+    dwc_otg_core_init(global.g_dwc_otg_dev_t.core_if);

+    /*
+     * Initialize the PCD,½«pcd_initÕª³öÀ´
+     */
+    global.g_dwc_otg_dev_t.pcd = dwc_otg_pcd_init(global.g_dwc_otg_dev_t.core_if);

+

+#if SYNC_USB_CTRL

+    REG32(ARM_PORTA)=0x22; 

+#endif

+

+#if SIM_EN == EMULATION

+	//for hsic

+	REG32(REG_GPIO_OUT)=2;

+	//while(REG32(REG_GPIO_IN)!=0xFF);

+	usdelay(1);

+	REG32(REG_GPIO_OUT)=0;

+#endif

+	global.g_dwc_otg_dev_t.pcd->otg_dev = (&global.g_dwc_otg_dev_t);

+	if(global.g_enum == NEED_ENUM)

+	{

+		DWC_MODIFY_REG32(&global.g_dwc_otg_dev_t.core_if->core_global_regs->gahbcfg, 0, 1);

+	} 

+	 return 0;

+}

+

+

diff --git a/boot/common/src/uboot/drivers/usb_drv/dwc_otg_pcd.c b/boot/common/src/uboot/drivers/usb_drv/dwc_otg_pcd.c
new file mode 100644
index 0000000..bf93b71
--- /dev/null
+++ b/boot/common/src/uboot/drivers/usb_drv/dwc_otg_pcd.c
@@ -0,0 +1,327 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd.c $
+ * $Revision: #101 $
+ * $Date: 2012/08/10 $
+ * $Change: 2047372 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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.
+ * ========================================================================== */
+#ifndef DWC_HOST_ONLY
+
+/** @file
+ * This file implements PCD Core. All code in this file is portable and doesn't
+ * use any OS specific functions.
+ * PCD Core provides Interface, defined in <code><dwc_otg_pcd_if.h></code>
+ * header file, which can be used to implement OS specific PCD interface.
+ *
+ * An important function of the PCD is managing interrupts generated
+ * by the DWC_otg controller. The implementation of the DWC_otg device
+ * mode interrupt service routines is in dwc_otg_pcd_intr.c.
+ *
+ * @todo Add Device Mode test modes (Test J mode, Test K mode, etc).
+ * @todo Does it work when the request size is greater than DEPTSIZ
+ * transfer size
+ *
+ */
+#include <usb/global.h>
+#include <usb/dwc_otg_pcd.h>
+
+__align(4) dwc_device_descriptor_t  device_desc =
+{
+    sizeof(dwc_device_descriptor_t),
+    DEVICE_DESCRIPTOR,
+    0x0200, 			// usb 2.0   
+    0x00,
+    0x00,
+    0x00,
+    CONTROL_64,			// ×î´ó°ü8×Ö½Ú
+    USB_VENDOR_ID,
+    USB_PRODUCT_ID,
+    PRODUCT_RELEASE_NUMBER,
+    0x01,               // manufacturer descriptionË÷ÒýºÅ
+    0x02,               // product descriptionË÷ÒýºÅ
+    0x00,  //tj 0:host¸ù¾ÝusbÎïÀí¿ÚÀ´±£Ö¤USBÉ豸Ψһ 3:¸ù¾ÝϵÁкÅÀ´±£Ö¤USBÉ豸Ψһ
+                        // serial number descriptionË÷ÒýºÅ
+    0x01                // ÅäÖÃÊý
+};
+
+__align(4) dwc_dev_qual_descriptor_t  dev_qual_desc =
+{
+    sizeof(dwc_dev_qual_descriptor_t),
+    0x06,
+    0x0110,                      // usb 1.1
+    VERDOR_SPECIFIC,
+    0x00,
+    0x00,
+    64,
+    0x01,                      // ÅäÖÃÊý
+    0x0
+};
+
+
+
+__align(4) dwc_langid_descriptor_t    tLanguage=
+{
+    STRING_DESCRIPTOR_SIZE(1),
+    STRING_DESCRIPTOR,
+    LANGID_US_ENGLISH
+};
+
+__align(4) dwc_string_descriptor_t    tManufacture=
+{
+    STRING_DESCRIPTOR_SIZE(11),
+    STRING_DESCRIPTOR,
+    {UNICODE('Z'), UNICODE('T'), UNICODE('E'), UNICODE(' '), UNICODE('C'),
+    UNICODE('o'), UNICODE(','), UNICODE('L'), UNICODE('t'), UNICODE('d'),
+    UNICODE('.'),}
+};
+
+__align(4) dwc_string_descriptor_t    tProduct=
+{
+	STRING_DESCRIPTOR_SIZE(14),
+	STRING_DESCRIPTOR,
+	{UNICODE('Z'), UNICODE('T'), UNICODE('E'), UNICODE(' '), UNICODE('B'),
+	UNICODE('o'), UNICODE('o'), UNICODE('t'), UNICODE('L'), UNICODE('o'),
+	UNICODE('a'), UNICODE('d'), UNICODE('e'), UNICODE('r')}
+};
+
+__align(4) dwc_string_descriptor_t    tSN=
+{
+	STRING_DESCRIPTOR_SIZE(16),
+	STRING_DESCRIPTOR,
+	{UNICODE('z'), UNICODE('t'), UNICODE('e'), UNICODE('&'), UNICODE('u'),
+	UNICODE('s'), UNICODE('b'), UNICODE('B'), UNICODE('o'), UNICODE('o'),
+	UNICODE('t'), UNICODE('l'), UNICODE('o'), UNICODE('d'), UNICODE('e'),
+	UNICODE('r')}
+};
+
+__align(4) dwc_string_descriptor_t	tIfc0Name=
+{
+        STRING_DESCRIPTOR_SIZE(9),
+        STRING_DESCRIPTOR,
+        {UNICODE('B'), UNICODE('o'), UNICODE('o'), UNICODE('t'), UNICODE('l'),
+        UNICODE('o'), UNICODE('d'), UNICODE('e'), UNICODE('r')}
+};
+
+__align(4) dwc_string_descriptor_t	tIfc1Name=
+{
+        STRING_DESCRIPTOR_SIZE(6),
+        STRING_DESCRIPTOR,
+        {UNICODE('S'), UNICODE('e'), UNICODE('r'), UNICODE('i'), UNICODE('a'),
+        UNICODE('l')}
+};
+
+__align(4) dwc_string_descriptor_t * pStrDescIdx[]=
+{
+	(dwc_string_descriptor_t *)(&tLanguage),
+	(dwc_string_descriptor_t *)&tManufacture,
+	(dwc_string_descriptor_t *)&tProduct,
+	(dwc_string_descriptor_t *)&tSN,
+	(dwc_string_descriptor_t *)&tIfc0Name,
+	(dwc_string_descriptor_t *)&tIfc1Name,
+};
+
+
+static  void  do_get_descriptor(dwc_otg_pcd_t * pcd,uint32_t *buff,uint32_t len)
+{
+
+    dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+    pcd->ep0_pending = 1;
+    ep0->dwc_ep.start_xfer_buff =(uint8_t*) buff;
+    ep0->dwc_ep.xfer_buff =(uint8_t*)buff;
+    ep0->dwc_ep.xfer_len = len;
+    ep0->dwc_ep.xfer_count = 0;
+    ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
+    dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
+
+}
+
+extern void ep0_do_stall(dwc_otg_pcd_t * pcd, const int err_val);
+
+int  dwc_setup(dwc_otg_pcd_t * pcd,  usb_device_request_t * ctrl)
+{
+    uint8_t        byIdx;
+    uint32_t len = 0;
+	uint16_t temp = 0;
+    byIdx  = (uint8_t)(ctrl->wValue &0xff);
+    temp = ctrl->wValue>>8;
+	if(USB_DT_DEVICE == temp)
+    {
+        len = MIN( sizeof(dwc_device_descriptor_t), ctrl->wLength);
+        do_get_descriptor(pcd,(uint32_t*)&device_desc,len);
+	}
+	else if(USB_DT_CONFIG == temp)
+	{
+        len = MIN( sizeof(dwc_config_all_t), ctrl->wLength);
+	        do_get_descriptor(pcd,(uint32_t*)&g_config_desc,len);
+	}
+
+    else if( USB_DT_STRING== temp)
+    {
+        if(byIdx > 5)
+            byIdx = 5;
+        len = MIN(((dwc_string_descriptor_t*)(pStrDescIdx[byIdx]))->bLength, ctrl->wLength);
+        do_get_descriptor(pcd,(uint32_t*)pStrDescIdx[byIdx],len);
+
+  	}
+
+    else if( USB_DT_DEVICE_QUALIFIER == temp)
+    {
+        len = MIN(sizeof(dwc_dev_qual_descriptor_t),ctrl->wLength);
+        do_get_descriptor(pcd,(uint32_t*)&dev_qual_desc,len);
+    }
+	else
+      {
+        ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
+    }
+    return 0;
+}
+
+
+static void dwc_otg_pcd_init_ep(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * pcd_ep,
+                                uint32_t is_in, uint32_t ep_num)
+{
+    /* Init EP structure */
+    pcd_ep->desc = 0;
+    pcd_ep->pcd = pcd;
+    pcd_ep->stopped = 1;
+    pcd_ep->queue_sof = 0;
+
+    /* Init DWC ep structure */
+    pcd_ep->dwc_ep.is_in = is_in;
+    pcd_ep->dwc_ep.num = ep_num;
+    pcd_ep->dwc_ep.active = 0;
+    pcd_ep->dwc_ep.tx_fifo_num = 0;
+    /* Control until ep is actvated */
+    pcd_ep->dwc_ep.type = DWC_OTG_EP_TYPE_BULK;
+    pcd_ep->dwc_ep.maxpacket = 512;
+    pcd_ep->dwc_ep.maxxfer = 65536;
+
+    pcd_ep->dwc_ep.start_xfer_buff = 0;
+    pcd_ep->dwc_ep.xfer_buff = 0;
+    pcd_ep->dwc_ep.xfer_len = 0;
+    pcd_ep->dwc_ep.xfer_count = 0;
+    pcd_ep->dwc_ep.sent_zlp = 0;
+    pcd_ep->dwc_ep.total_len = 0;
+}
+
+/**
+ * Initialize ep's
+ */
+static void dwc_otg_pcd_reinit(dwc_otg_pcd_t * pcd)
+{
+    int i;
+    uint32_t hwcfg1;
+    dwc_otg_pcd_ep_t *ep;
+    int in_ep_cntr, out_ep_cntr;
+    uint32_t num_in_eps = (GET_CORE_IF(pcd))->dev_if->num_in_eps;
+    uint32_t num_out_eps = (GET_CORE_IF(pcd))->dev_if->num_out_eps;
+
+    /**
+     * Initialize the EP0 structure.
+     */
+    pcd->ep0.dwc_ep.pPara = (void*)(&global.g_in_pPara[1]);
+
+    ep = &pcd->ep0;
+    dwc_otg_pcd_init_ep(pcd, ep, 0, 0);
+
+    in_ep_cntr = 0;
+    hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 3;
+    for (i = 1; in_ep_cntr < num_in_eps; i++)
+    {
+        if ((hwcfg1 & 0x1) == 0)
+        {
+            pcd->in_ep[in_ep_cntr].dwc_ep.pPara = (void*)(&global.g_in_pPara[in_ep_cntr]);
+            ep = &pcd->in_ep[in_ep_cntr];
+            in_ep_cntr++;
+            /**
+             * @todo NGS: Add direction to EP, based on contents
+             * of HWCFG1.  Need a copy of HWCFG1 in pcd structure?
+             * sprintf(";r
+             */
+            dwc_otg_pcd_init_ep(pcd, ep, 1 /* IN */ , i);
+        }
+        hwcfg1 >>= 2;
+    }
+
+    out_ep_cntr = 0;
+    hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 2;
+    for (i = 1; out_ep_cntr < num_out_eps; i++)
+    {
+        if ((hwcfg1 & 0x1) == 0)
+        {
+            pcd->out_ep[out_ep_cntr].dwc_ep.pPara = (void*)(&global.g_out_pPara[out_ep_cntr]);
+            ep = &pcd->out_ep[out_ep_cntr];
+            out_ep_cntr++;
+            /**
+             * @todo NGS: Add direction to EP, based on contents
+             * of HWCFG1.  Need a copy of HWCFG1 in pcd structure?
+             * sprintf(";r
+             */
+            dwc_otg_pcd_init_ep(pcd, ep, 0 /* OUT */ , i);
+        }
+        hwcfg1 >>= 2;
+    }
+ if(NEED_ENUM == global.g_enum)
+ {
+    pcd->ep0state = EP0_DISCONNECT;
+ }
+ else
+ {
+	 pcd->ep0state = EP0_IDLE;
+ }
+    pcd->ep0.dwc_ep.maxpacket = MAX_EP0_SIZE;
+    pcd->ep0.dwc_ep.type = 0;
+}
+
+/**
+ * This function initialized the PCD portion of the driver.
+ *
+ */
+dwc_otg_pcd_t *dwc_otg_pcd_init(dwc_otg_core_if_t * core_if)
+{
+    dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)&global.g_dwc_otg_pcd_tp;
+    int i;
+    uint8_t* pt_dwc_otg_pcd_t = (uint8_t*)&global.g_dwc_otg_pcd_tp;
+    for(i = 0;i<sizeof(dwc_otg_pcd_t);i++)
+    {
+       pt_dwc_otg_pcd_t[i] = 0;
+    }
+
+    pcd->core_if = core_if;
+
+    pcd->setup_pkt = global.g_u_setup_pkt;
+    pcd->status_buf = &global.g_status_buf;
+    dwc_otg_pcd_reinit(pcd);
+
+    return pcd;
+}
+
+
+/******************************************************************************/
+
+#endif /* DWC_HOST_ONLY */
diff --git a/boot/common/src/uboot/drivers/usb_drv/dwc_otg_pcd_intr.c b/boot/common/src/uboot/drivers/usb_drv/dwc_otg_pcd_intr.c
new file mode 100644
index 0000000..29fd262
--- /dev/null
+++ b/boot/common/src/uboot/drivers/usb_drv/dwc_otg_pcd_intr.c
@@ -0,0 +1,1517 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_intr.c $
+ * $Revision: #116 $
+ * $Date: 2012/08/10 $
+ * $Change: 2047372 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 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.
+ * ========================================================================== */
+#ifndef DWC_HOST_ONLY
+#include <usb/dwc_otg_pcd.h>
+
+#ifdef DWC_UTE_CFI
+#include <usb/dwc_otg_cfi.h>
+#endif
+
+#include <usb/global.h>
+
+
+#if 1
+/**
+ * This function returns the Core Interrupt register.
+ */
+static uint32_t dwc_otg_read_core_intr(dwc_otg_core_if_t * core_if)
+{
+    return (DWC_READ_REG32(&core_if->core_global_regs->gintsts) &
+            DWC_READ_REG32(&core_if->core_global_regs->gintmsk));
+}
+
+
+/**
+ * This function reads the Device All Endpoints Interrupt register and
+ * returns the IN endpoint interrupt bits.
+ */
+static uint32_t dwc_otg_read_dev_all_in_ep_intr(dwc_otg_core_if_t *
+        core_if)
+{
+
+    uint32_t v;
+    {
+        v = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daint) &
+            DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk);
+    }
+    return (v & 0xffff);
+}
+
+/**
+ * This function reads the Device All Endpoints Interrupt register and
+ * returns the OUT endpoint interrupt bits.
+ */
+static uint32_t dwc_otg_read_dev_all_out_ep_intr(dwc_otg_core_if_t *
+        core_if)
+{
+    uint32_t v;
+
+    {
+        v = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daint) &
+            DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk);
+    }
+
+    return ((v & 0xffff0000) >> 16);
+}
+
+/**
+ * This function returns the Device IN EP Interrupt register
+ */
+static  uint32_t dwc_otg_read_dev_in_ep_intr(dwc_otg_core_if_t * core_if,
+        dwc_ep_t * ep)
+{
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    uint32_t v, msk, emp;
+
+    {
+        msk = DWC_READ_REG32(&dev_if->dev_global_regs->diepmsk);
+        emp = DWC_READ_REG32(&dev_if->dev_global_regs->dtknqr4_fifoemptymsk);
+        msk |= ((emp >> ep->num) & 0x1) << 7;
+        v = DWC_READ_REG32(&dev_if->in_ep_regs[ep->num]->diepint) & msk;
+    }
+
+    return v;
+}
+
+/**
+ * This function returns the Device OUT EP Interrupt register
+ */
+static uint32_t dwc_otg_read_dev_out_ep_intr(dwc_otg_core_if_t *_core_if, dwc_ep_t * _ep)
+{
+    dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
+    uint32_t v;
+    doepmsk_data_t msk;
+    msk.d32 = 0;
+    {
+        msk.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->doepmsk);
+        if (_core_if->pti_enh_enable)
+        {
+            msk.b.pktdrpsts = 1;
+        }
+        v = DWC_READ_REG32(&dev_if->out_ep_regs[_ep->num]->doepint) & msk.d32;
+    }
+    return v;
+}
+#endif
+
+/**
+ * This function returns pointer to in ep struct with number ep_num
+ */
+static  dwc_otg_pcd_ep_t *get_in_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
+{
+    int i;
+    int num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
+    if (ep_num == 0)
+    {
+        return &pcd->ep0;
+    }
+    else
+    {
+        for (i = 0; i < num_in_eps; ++i)
+        {
+            if (pcd->in_ep[i].dwc_ep.num == ep_num)
+                return &pcd->in_ep[i];
+        }
+        return 0;
+    }
+}
+
+/**
+ * This function returns pointer to out ep struct with number ep_num
+ */
+static  dwc_otg_pcd_ep_t *get_out_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
+{
+    int i;
+    int num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
+    if (ep_num == 0)
+    {
+        return &pcd->ep0;
+    }
+    else
+    {
+        for (i = 0; i < num_out_eps; ++i)
+        {
+            if (pcd->out_ep[i].dwc_ep.num == ep_num)
+                return &pcd->out_ep[i];
+        }
+        return 0;
+    }
+}
+
+/**
+ * This functions gets a pointer to an EP from the wIndex address
+ * value of the control request.
+ */
+dwc_otg_pcd_ep_t *get_ep_by_addr(dwc_otg_pcd_t * pcd, uint16_t wIndex)
+{
+    dwc_otg_pcd_ep_t *ep;
+    uint32_t ep_num = UE_GET_ADDR(wIndex);
+
+    if (ep_num == 0)
+    {
+        ep = &pcd->ep0;
+    }
+    else if (UE_GET_DIR(wIndex) == UE_DIR_IN)
+    {	/* in ep */
+        ep = &pcd->in_ep[ep_num - 1];
+    }
+    else
+    {
+        ep = &pcd->out_ep[ep_num - 1];
+    }
+
+    return ep;
+}
+/**
+ * This function handles the Rx Status Queue Level Interrupt, which
+ * indicates that there is a least one packet in the Rx FIFO.  The
+ * packets are moved from the FIFO to memory, where they will be
+ * processed when the Endpoint Interrupt Register indicates Transfer
+ * Complete or SETUP Phase Done.
+ *
+ * Repeat the following until the Rx Status Queue is empty:
+ *	 -# Read the Receive Status Pop Register (GRXSTSP) to get Packet
+ *		info
+ *	 -# If Receive FIFO is empty then skip to step Clear the interrupt
+ *		and exit
+ *	 -# If SETUP Packet call dwc_otg_read_setup_packet to copy the
+ *		SETUP data to the buffer
+ *	 -# If OUT Data Packet call dwc_otg_read_packet to copy the data
+ *		to the destination buffer
+ */
+int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(dwc_otg_pcd_t * pcd)
+{
+    dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+    dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+    gintmsk_data_t gintmask;
+    device_grxsts_data_t status;
+    dwc_otg_pcd_ep_t *ep;
+    gintsts_data_t gintsts;
+    gintmask.d32 = 0;
+
+    /* Disable the Rx Status Queue Level interrupt */
+    gintmask.b.rxstsqlvl = 1;
+    DWC_MODIFY_REG32(&global_regs->gintmsk, gintmask.d32, 0);
+
+    /* Get the Status from the top of the FIFO */
+    status.d32 = DWC_READ_REG32(&global_regs->grxstsp);
+
+    /* Get pointer to EP structure */
+    ep = get_out_ep(pcd, status.b.epnum);
+	if(0==ep)
+		return -1;
+
+    switch (status.b.pktsts)
+    {
+    case DWC_DSTS_GOUT_NAK:
+        break;
+    case DWC_STS_DATA_UPDT:
+        if (status.b.bcnt && ep->dwc_ep.xfer_buff)
+        {
+            /** @todo NGS Check for buffer overflow? */
+            dwc_otg_read_packet(core_if, ep->dwc_ep.xfer_buff,status.b.bcnt);
+            ep->dwc_ep.xfer_count += status.b.bcnt;
+            ep->dwc_ep.xfer_buff += status.b.bcnt;
+        }
+        break;
+    case DWC_STS_XFER_COMP:
+        break;
+    case DWC_DSTS_SETUP_COMP:
+        break;
+    case DWC_DSTS_SETUP_UPDT:
+        dwc_otg_read_setup_packet(core_if, pcd->setup_pkt->d32);
+        ep->dwc_ep.xfer_count += status.b.bcnt;
+
+        #if SIM_EN == EMULATION
+        if(pcd->setup_pkt->req.bRequest == 0x05)
+        {       
+			REG32(REG_GPIO_OUT)=0x9;
+//	        while(REG32(REG_GPIO_IN)!=0xFF);
+			usdelay(1);
+			REG32(REG_GPIO_OUT)=0;
+       }
+       #endif
+       
+        break;
+    default:
+        break;
+    }
+
+    /* Enable the Rx Status Queue Level interrupt */
+    DWC_MODIFY_REG32(&global_regs->gintmsk, 0, gintmask.d32);
+    /* Clear interrupt */
+    gintsts.d32 = 0;
+    gintsts.b.rxstsqlvl = 1;
+    DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
+
+    return 1;
+}
+
+/**
+ * This function examines the Device IN Token Learning Queue to
+ * determine the EP number of the last IN token received.  This
+ * implementation is for the Mass Storage device where there are only
+ * 2 IN EPs (Control-IN and BULK-IN).
+ *
+ * The EP numbers for the first six IN Tokens are in DTKNQR1 and there
+ * are 8 EP Numbers in each of the other possible DTKNQ Registers.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ *
+ */
+/**
+ * This function is called when dedicated Tx FIFO Empty interrupt occurs.
+ * The active request is checked for the next packet to be loaded into
+ * apropriate Tx FIFO.
+ */
+static int32_t write_empty_tx_fifo(dwc_otg_pcd_t * pcd, uint32_t epnum)
+{
+    dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    dtxfsts_data_t txstatus;
+    dwc_otg_pcd_ep_t *ep = 0;
+    uint32_t len = 0;
+    int dwords;
+    txstatus.d32 = 0;
+	
+	if(epnum >= MAX_EPS_CHANNELS)
+		return -1;
+	
+    ep = get_in_ep(pcd, epnum);
+	if(0==ep)
+		return -1;
+
+    len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
+
+    if (len > ep->dwc_ep.maxpacket)
+    {
+        len = ep->dwc_ep.maxpacket;
+    }
+
+    dwords = (len + 3) / 4;
+
+    /* While there is space in the queue and space in the FIFO and
+     * More data to tranfer, Write packets to the Tx FIFO */
+    txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
+    while (txstatus.b.txfspcavail > dwords &&
+            ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len &&
+            ep->dwc_ep.xfer_len != 0)
+    {
+        /* Write the FIFO */
+        dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
+
+        len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
+        if (len > ep->dwc_ep.maxpacket)
+        {
+            len = ep->dwc_ep.maxpacket;
+        }
+
+        dwords = (len + 3) / 4;
+        txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
+    }
+
+
+    return 1;
+}
+
+/**
+ * This function configures EPO to receive SETUP packets.
+ *
+ * @todo NGS: Update the comments from the HW FS.
+ *
+ *	-# Program the following fields in the endpoint specific registers
+ *	for Control OUT EP 0, in order to receive a setup packet
+ *	- DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
+ *	  setup packets)
+ *	- DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
+ *	  to back setup packets)
+ *		- In DMA mode, DOEPDMA0 Register with a memory address to
+ *		  store any setup packets received
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param pcd	  Programming view of the PCD.
+ */
+static  void ep0_out_start(dwc_otg_core_if_t * core_if,
+                           dwc_otg_pcd_t * pcd)
+{
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    deptsiz0_data_t doeptsize0;
+    depctl_data_t doepctl;
+    doepctl.d32 = 0;
+    doeptsize0.d32 =0;
+
+
+    doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl);
+    if (doepctl.b.epena)
+    {
+        return;
+    }
+
+    doeptsize0.b.supcnt = 3;
+    doeptsize0.b.pktcnt = 1;
+    doeptsize0.b.xfersize = 8 * 3;
+
+    /** put here as for Hermes mode deptisz register should not be written */
+    DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doeptsiz,doeptsize0.d32);
+
+    /** DOEPCTL0 Register write cnak will be set after setup interrupt */
+    doepctl.d32 = 0;
+    doepctl.b.epena = 1;
+
+    DWC_MODIFY_REG32(&dev_if->out_ep_regs[0]->doepctl, 0, doepctl.d32);
+
+}
+
+
+void USB_Recovercfg(dwc_otg_pcd_t *pcd)
+{
+    int i = 0;
+    dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    depctl_data_t doepctl;
+    depctl_data_t diepctl;
+    doepctl.d32 = 0;
+    diepctl.d32 = 0;
+
+    for (i = 0; i <= dev_if->num_out_eps; i++)
+    {
+        doepctl.d32= DWC_READ_REG32(&dev_if->out_ep_regs[i+1]->doepctl);
+        doepctl.b.eptype = pcd->out_ep[i].dwc_ep.type;
+        doepctl.b.mps = pcd->out_ep[i].dwc_ep.maxpacket;
+        DWC_WRITE_REG32(&dev_if->out_ep_regs[i+1]->doepctl, doepctl.d32);
+
+        diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i+1]->diepctl);
+        diepctl.b.eptype = pcd->in_ep[i].dwc_ep.type;
+        diepctl.b.mps = pcd->in_ep[i].dwc_ep.maxpacket;
+        DWC_WRITE_REG32(&dev_if->in_ep_regs[i+1]->diepctl, diepctl.d32);
+    }
+
+}
+int32_t dwc_otg_pcd_handle_usb_reset_intr(dwc_otg_pcd_t * pcd)
+{
+    dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    depctl_data_t doepctl;
+    daint_data_t daintmsk;
+    doepmsk_data_t doepmsk;
+    diepmsk_data_t diepmsk ;
+    dcfg_data_t dcfg ;
+    grstctl_t resetctl;
+    dctl_data_t dctl;
+    int i = 0;
+    gintsts_data_t gintsts;
+    pcgcctl_data_t power;
+    doepctl.d32 = 0;
+    daintmsk.d32 = 0;
+    doepmsk.d32 = 0;
+    diepmsk.d32 = 0;
+    dcfg.d32 = 0;
+    resetctl.d32 = 0;
+    dctl.d32 = 0;
+    power.d32 = 0;
+
+    power.d32 = DWC_READ_REG32(core_if->pcgcctl);
+    if (power.b.stoppclk)
+    {
+        power.d32 = 0;
+        power.b.stoppclk = 1;
+        DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
+
+        power.b.pwrclmp = 1;
+        DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
+
+        power.b.rstpdwnmodule = 1;
+        DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
+    }
+
+    printk("Reset\n");
+
+    /* Clear the Remote Wakeup Signalling */
+    dctl.b.rmtwkupsig = 1;
+    DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
+
+    /* Set NAK for all OUT EPs */
+    doepctl.b.snak = 1;
+    for (i = 0; i <= dev_if->num_out_eps; i++)
+    {
+        DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32);
+    }
+
+    /* Flush the NP Tx FIFO */
+    dwc_otg_flush_tx_fifo(core_if, 0x10);
+    /* Flush the Learning Queue */
+    resetctl.b.intknqflsh = 1;
+    DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
+    {
+        daintmsk.b.inep0 = 1;
+        daintmsk.b.outep0 = 1;
+        DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk,daintmsk.d32);
+
+        doepmsk.b.setup = 1;
+        doepmsk.b.xfercompl = 1;
+        doepmsk.b.ahberr = 1;
+        doepmsk.b.epdisabled = 1;
+        DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, doepmsk.d32);
+
+        diepmsk.b.xfercompl = 1;
+        diepmsk.b.timeout = 1;
+        diepmsk.b.epdisabled = 1;
+        diepmsk.b.ahberr = 1;
+
+        DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32);
+    }
+
+    /* Reset Device Address */
+    dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
+    dcfg.b.devaddr = 0;
+    DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
+
+    /* Clear interrupt */
+    gintsts.d32 = 0;
+    gintsts.b.usbreset = 1;
+    DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
+
+    USB_Recovercfg(pcd);
+
+    return 1;
+}
+
+/**
+ * Get the device speed from the device status register and convert it
+ * to USB speed constant.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ */
+static int get_device_speed(dwc_otg_core_if_t * core_if)
+{
+    dsts_data_t dsts;
+    int speed = 0;
+    dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
+
+    switch (dsts.b.enumspd)
+    {
+    case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
+        speed = USB_SPEED_HIGH;
+        break;
+    case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
+    case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
+        speed = USB_SPEED_FULL;
+        break;
+
+    case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
+        speed = USB_SPEED_LOW;
+        break;
+    }
+
+    return speed;
+}
+
+/**
+ * Read the device status register and set the device speed in the
+ * data structure.
+ * Set up EP0 to receive SETUP packets by calling dwc_ep0_activate.
+ */
+//extern void init_devspd(dwc_otg_core_if_t * core_if,uint8_t speed);
+
+
+int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t * pcd)
+{
+    dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+    gintsts_data_t gintsts;
+    gusbcfg_data_t gusbcfg;
+    dwc_otg_core_global_regs_t *global_regs = GET_CORE_IF(pcd)->core_global_regs;
+    uint8_t utmi16b, utmi8b;
+    int speed;
+    printk("D");
+    
+    utmi16b = 5;	//utmi phy use 5 add by tj
+    utmi8b = 9;
+    dwc_otg_ep0_activate(GET_CORE_IF(pcd), &ep0->dwc_ep);
+    ep0_out_start(GET_CORE_IF(pcd), pcd);
+#if SIM_EN == EMULATION
+
+	REG32(REG_GPIO_OUT)=5;
+//	while(REG32(REG_GPIO_IN)!=0xFF);
+	usdelay(1);
+	REG32(REG_GPIO_OUT)=0;
+
+	REG32(REG_GPIO_OUT)=6;
+//	while(REG32(REG_GPIO_IN)!=0xFF);
+	usdelay(1);
+	REG32(REG_GPIO_OUT)=0;
+
+	REG32(REG_GPIO_OUT)=7;
+//	while(REG32(REG_GPIO_IN)!=0xFF);
+	usdelay(1);
+	REG32(REG_GPIO_OUT)=0;
+
+	REG32(REG_GPIO_OUT)=8;
+//	while(REG32(REG_GPIO_IN)!=0xFF);
+	usdelay(1);
+	REG32(REG_GPIO_OUT)=0;
+
+#endif
+    if (pcd->ep0state == EP0_DISCONNECT)
+    {
+        pcd->ep0state = EP0_IDLE;
+    }
+    else if (pcd->ep0state == EP0_STALL)
+    {
+        pcd->ep0state = EP0_IDLE;
+    }
+
+    ep0->stopped = 0;
+
+    speed = get_device_speed(GET_CORE_IF(pcd));
+    /* Set USB turnaround time based on device speed and PHY interface. */
+    gusbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+    if (speed == USB_SPEED_HIGH)
+    {
+    
+        if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI)
+        {
+            /* UTMI+  OR  ULPI interface */
+            if (gusbcfg.b.ulpi_utmi_sel == 1)
+            {
+                /* ULPI interface */
+                gusbcfg.b.usbtrdtim = 9;
+            }
+            else
+            {
+                /* UTMI+ interface */
+                if (GET_CORE_IF(pcd)->core_params->phy_utmi_width == 16)
+                {
+                    gusbcfg.b.usbtrdtim = utmi16b;
+                }
+                else
+                {
+                    gusbcfg.b.usbtrdtim = utmi8b;
+                }
+            }
+        }
+
+        printk("2\n");
+        pcd->out_ep[0].dwc_ep.maxpacket = 512;
+        pcd->in_ep[0].dwc_ep.maxpacket  = 512;
+        pcd->out_ep[1].dwc_ep.maxpacket = 512;
+        pcd->in_ep[1].dwc_ep.maxpacket  = 512;   
+        g_config_desc.atTxEP[0].wMaxPacketSize  = USB_HIGHSPEED_BULK_MAXSIZE;
+        g_config_desc.atRxEP[0].wMaxPacketSize  = USB_HIGHSPEED_BULK_MAXSIZE;
+        g_config_desc.atTxEP1[0].wMaxPacketSize = USB_HIGHSPEED_BULK_MAXSIZE;
+        g_config_desc.atRxEP1[0].wMaxPacketSize = USB_HIGHSPEED_BULK_MAXSIZE;
+        
+    }
+    else
+    { 
+        printk("1\n");
+        pcd->out_ep[0].dwc_ep.maxpacket = 64;
+        pcd->in_ep[0].dwc_ep.maxpacket  = 64;
+        pcd->out_ep[1].dwc_ep.maxpacket = 64;
+        pcd->in_ep[1].dwc_ep.maxpacket  = 64;   
+      //  desc.atTxEP[0].wMaxPacketSize  = USB_FULLSPEED_BULK_MAXSIZE;
+      //  desc.atRxEP[0].wMaxPacketSize  = USB_FULLSPEED_BULK_MAXSIZE;
+     //   desc.atTxEP1[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+     //   desc.atRxEP1[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+        /* Full or low speed */
+	     g_config_desc.atTxEP[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+        g_config_desc.atRxEP[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+        g_config_desc.atTxEP1[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+        g_config_desc.atRxEP1[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+        gusbcfg.b.usbtrdtim = 9;
+    }
+    DWC_WRITE_REG32(&global_regs->gusbcfg, gusbcfg.d32);
+
+    /* Clear interrupt */
+    gintsts.d32 = 0;
+    gintsts.b.enumdone = 1;
+    DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,gintsts.d32);
+    return 1;
+}
+
+
+
+/**
+ * This funcion stalls EP0.
+ */
+void ep0_do_stall(dwc_otg_pcd_t * pcd, const int err_val)
+{
+    dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+
+    ep0->dwc_ep.is_in = 1;
+    dwc_otg_ep_set_stall(GET_CORE_IF(pcd), &ep0->dwc_ep);
+    pcd->ep0.stopped = 1;
+    pcd->ep0state = EP0_IDLE;
+    ep0_out_start(GET_CORE_IF(pcd), pcd);
+}
+
+static  void do_setup_in_out_status_phase(dwc_otg_pcd_t * pcd,s8 udir)
+{
+    dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+    if (pcd->ep0state == EP0_STALL)
+    {
+        return;
+    }
+
+    if(udir)
+    {
+     pcd->ep0state = EP0_IN_STATUS_PHASE;
+    }
+    else
+    {
+      pcd->ep0state = EP0_OUT_STATUS_PHASE;
+    }
+
+    /* Prepare for more SETUP Packets */
+    ep0->dwc_ep.xfer_len = 0;
+    ep0->dwc_ep.xfer_count = 0;
+    ep0->dwc_ep.is_in = udir;
+    dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
+}
+
+
+/**
+ * Clear the EP halt (STALL) and if pending requests start the
+ * transfer.
+ */
+static  void pcd_clear_halt(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep)
+{
+    if (ep->dwc_ep.stall_clear_flag == 0)
+        dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
+
+    /* Reactive the EP */
+    dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
+    if (ep->stopped)
+    {
+        ep->stopped = 0;
+        /* If there is a request in the EP queue start it */
+
+        /** @todo FIXME: this causes an EP mismatch in DMA mode.
+         * epmismatch not yet implemented. */
+
+        /*
+         * Above fixme is solved by implmenting a tasklet to call the
+         * start_next_request(), outside of interrupt context at some
+         * time after the current time, after a clear-halt setup packet.
+         * Still need to implement ep mismatch in the future if a gadget
+         * ever uses more than one endpoint at once
+         */
+        ep->queue_sof = 1;
+    }
+    /* Start Control Status Phase */
+    do_setup_in_out_status_phase(pcd,1);
+}
+
+/**
+ * This function process the GET_STATUS Setup Commands.
+ */
+static  void do_get_status(dwc_otg_pcd_t * pcd)
+{
+    usb_device_request_t ctrl = pcd->setup_pkt->req;
+    dwc_otg_pcd_ep_t *ep;
+    dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+    uint16_t *status = pcd->status_buf;
+
+    switch (UT_GET_RECIPIENT(ctrl.bmRequestType))
+    {
+    case UT_INTERFACE:
+        *status = 0;
+        break;
+
+    case UT_ENDPOINT:
+        ep = get_ep_by_addr(pcd, ctrl.wIndex);
+        if (ep == 0 || ctrl.wLength > 2)
+        {
+            ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
+            return;
+        }
+        /** @todo check for EP stall */
+        *status = ep->stopped;
+        break;
+    }
+    pcd->ep0_pending = 1;
+    ep0->dwc_ep.start_xfer_buff = (uint8_t *) status;
+    ep0->dwc_ep.xfer_buff = (uint8_t *) status;
+    ep0->dwc_ep.xfer_len = 2;
+    ep0->dwc_ep.xfer_count = 0;
+    ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
+    dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
+}
+
+
+static  void do_clear_feature(dwc_otg_pcd_t * pcd)
+{
+    usb_device_request_t ctrl = pcd->setup_pkt->req;
+    dwc_otg_pcd_ep_t *ep = 0;
+    switch (UT_GET_RECIPIENT(ctrl.bmRequestType))
+    {
+    case UT_ENDPOINT:
+        ep = get_ep_by_addr(pcd, ctrl.wIndex);
+        if (ep == 0)
+        {
+            ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
+            return;
+        }
+
+        pcd_clear_halt(pcd, ep);
+
+        break;
+
+    }
+}
+
+/**
+ * This function process the SET_ADDRESS Setup Commands.
+ */
+static  void do_set_address(dwc_otg_pcd_t * pcd)
+{
+    dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
+    usb_device_request_t ctrl = pcd->setup_pkt->req;
+    dcfg_data_t dcfg;
+    dcfg.d32 = 0;
+
+    if (ctrl.bmRequestType == UT_DEVICE)
+    {
+
+        dcfg.b.devaddr = ctrl.wValue;
+        DWC_MODIFY_REG32(&dev_if->dev_global_regs->dcfg, 0, dcfg.d32);
+#if SIM_EN == EMULATION
+		REG32(REG_GPIO_OUT)=0xa;
+//        while(REG32(REG_GPIO_IN)!=0xFF);
+		usdelay(1);
+		REG32(REG_GPIO_OUT)=0;
+
+		REG32(REG_GPIO_OUT)=0xb;
+//        while(REG32(REG_GPIO_IN)!=0xFF);
+		usdelay(1);
+		REG32(REG_GPIO_OUT)=0;
+		
+#endif
+        do_setup_in_out_status_phase(pcd,1);
+#if SIM_EN == EMULATION
+       if(pcd->setup_pkt->req.bRequest == 0x05)
+       {
+        	REG32(REG_GPIO_OUT)=0x9;
+//        	while(REG32(REG_GPIO_IN)!=0xFF);
+        	usdelay(10);
+        	REG32(REG_GPIO_OUT)=0;
+        }
+#endif
+    }
+}
+
+/**
+ *	This function processes SETUP commands. In Linux, the USB Command
+ *	processing is done in two places - the first being the PCD and the
+ *	second in the Gadget Driver (for example, the File-Backed Storage
+ *	Gadget Driver).
+ *
+ * <table>
+ * <tr><td>Command	</td><td>Driver </td><td>Description</td></tr>
+ *
+ * <tr><td>GET_STATUS </td><td>PCD </td><td>Command is processed as
+ * defined in chapter 9 of the USB 2.0 Specification chapter 9
+ * </td></tr>
+ *
+ * <tr><td>CLEAR_FEATURE </td><td>PCD </td><td>The Device and Endpoint
+ * requests are the ENDPOINT_HALT feature is procesed, all others the
+ * interface requests are ignored.</td></tr>
+ *
+ * <tr><td>SET_FEATURE </td><td>PCD </td><td>The Device and Endpoint
+ * requests are processed by the PCD.  Interface requests are passed
+ * to the Gadget Driver.</td></tr>
+ *
+ * <tr><td>SET_ADDRESS </td><td>PCD </td><td>Program the DCFG reg,
+ * with device address received </td></tr>
+ *
+ * <tr><td>GET_DESCRIPTOR </td><td>Gadget Driver </td><td>Return the
+ * requested descriptor</td></tr>
+ *
+ * <tr><td>SET_DESCRIPTOR </td><td>Gadget Driver </td><td>Optional -
+ * not implemented by any of the existing Gadget Drivers.</td></tr>
+ *
+ * <tr><td>SET_CONFIGURATION </td><td>Gadget Driver </td><td>Disable
+ * all EPs and enable EPs for new configuration.</td></tr>
+ *
+ * <tr><td>GET_CONFIGURATION </td><td>Gadget Driver </td><td>Return
+ * the current configuration</td></tr>
+ *
+ * <tr><td>SET_INTERFACE </td><td>Gadget Driver </td><td>Disable all
+ * EPs and enable EPs for new configuration.</td></tr>
+ *
+ * <tr><td>GET_INTERFACE </td><td>Gadget Driver </td><td>Return the
+ * current interface.</td></tr>
+ *
+ * <tr><td>SYNC_FRAME </td><td>PCD </td><td>Display debug
+ * message.</td></tr>
+ * </table>
+ *
+ * When the SETUP Phase Done interrupt occurs, the PCD SETUP commands are
+ * processed by pcd_setup. Calling the Function Driver's setup function from
+ * pcd_setup processes the gadget SETUP commands.
+ */
+void active_allep(dwc_otg_pcd_t * pcd)
+{
+    int i = 0;
+    dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    for (i = 0; i <dev_if->num_out_eps; i++)
+    {
+        dwc_otg_ep_activate(pcd->core_if,&pcd->out_ep[i].dwc_ep);
+        dwc_otg_ep_activate(pcd->core_if,&pcd->in_ep[i].dwc_ep);
+    }
+
+}
+
+extern int  dwc_setup(dwc_otg_pcd_t * pcd,  usb_device_request_t * ctrl);
+
+static  void pcd_setup(dwc_otg_pcd_t * pcd)
+{
+    dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+    usb_device_request_t ctrl = pcd->setup_pkt->req;
+    dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+
+    ep0->stopped = 0;
+
+    if (ctrl.bmRequestType & UE_DIR_IN)
+    {
+        ep0->dwc_ep.is_in = 1;
+        pcd->ep0state = EP0_IN_DATA_PHASE;
+    }
+    else
+    {
+        ep0->dwc_ep.is_in = 0;
+        pcd->ep0state = EP0_OUT_DATA_PHASE;
+    }
+
+    if (ctrl.wLength == 0)
+    {
+        ep0->dwc_ep.is_in = 1;
+        pcd->ep0state = EP0_IN_STATUS_PHASE;
+    }
+   /*tj Ôö¼Ó´¦Àí·Ç±ê×¼ÃüÁî*/ 
+    if(UT_GET_TYPE(ctrl.bmRequestType)!=UT_STANDARD)
+    {
+        ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
+        return;
+    }
+    
+    switch (ctrl.bRequest)
+    {
+    case UR_GET_STATUS:
+        do_get_status(pcd);
+        break;
+
+    case UR_CLEAR_FEATURE:
+        do_clear_feature(pcd);
+        break;
+
+    case UR_SET_FEATURE:
+        break;
+
+    case UR_SET_ADDRESS:
+        do_set_address(pcd); 
+        break;
+
+    case  UR_GET_DESCRIPTOR:
+        dwc_setup(pcd, &ctrl);
+        break;
+
+    case UR_SET_CONFIG:
+        pcd->request_config = 1;
+        active_allep(pcd);
+        do_setup_in_out_status_phase(pcd,1);
+        ep0_out_start(core_if, pcd);
+        break;
+    default:
+        ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
+        break;
+    }
+}
+
+/**
+ * This function completes the ep0 control transfer.
+ */
+static int32_t ep0_complete_request(dwc_otg_pcd_ep_t * ep)
+{
+    dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    dwc_otg_dev_in_ep_regs_t *in_ep_regs =
+    dev_if->in_ep_regs[ep->dwc_ep.num];
+    
+    deptsiz0_data_t deptsiz;
+    int is_last = 0;
+    dwc_otg_pcd_t *pcd = ep->pcd;
+
+    if (pcd->ep0_pending)
+    {
+        if (ep->dwc_ep.is_in)
+        {
+
+            do_setup_in_out_status_phase(pcd,0);
+        }
+        else
+        {
+            do_setup_in_out_status_phase(pcd,1);
+        }
+        pcd->ep0_pending = 0;
+        return 1;
+    }
+
+    if (pcd->ep0state == EP0_OUT_STATUS_PHASE
+            || pcd->ep0state == EP0_IN_STATUS_PHASE)
+    {
+        is_last = 1;
+    }
+    else if (ep->dwc_ep.is_in)
+    {
+        deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz);
+
+       if (deptsiz.b.xfersize == 0)
+        {
+            do_setup_in_out_status_phase(pcd,0);
+        }
+    }
+    else
+    {
+
+        ep0_out_start(core_if, pcd);
+
+    }
+
+    /* Complete the request */
+    if (is_last)
+    {
+        ep->dwc_ep.start_xfer_buff = 0;
+        ep->dwc_ep.xfer_buff = 0;
+        ep->dwc_ep.xfer_len = 0;
+        return 1;
+    }
+    return 0;
+}
+
+/**
+ * This function completes the request for the EP. If there are
+ * additional requests for the EP in the queue they will be started.
+ */
+static void complete_ep(dwc_otg_pcd_ep_t * ep)
+{
+    dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    dwc_otg_dev_in_ep_regs_t *in_ep_regs = dev_if->in_ep_regs[ep->dwc_ep.num];
+    deptsiz_data_t deptsiz;
+
+    if (ep->dwc_ep.is_in)
+    {
+        deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz);
+        {
+            if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0)
+            {
+                /*      Check if the whole transfer was completed,
+                 *      if no, setup transfer for next portion of data
+                 */
+                if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len)
+                {
+                    dwc_otg_ep_start_transfer(core_if,&ep->dwc_ep);
+                }
+                else if (ep->dwc_ep.sent_zlp)
+                {
+                    /*
+                     * This fragment of code should initiate 0
+                     * length trasfer in case if it is queued
+                     * a trasfer with size divisible to EPs max
+                     * packet size and with usb_request zero field
+                     * is set, which means that after data is transfered,
+                     * it is also should be transfered
+                     * a 0 length packet at the end. For Slave and
+                     * Buffer DMA modes in this case SW has
+                     * to initiate 2 transfers one with transfer size,
+                     * and the second with 0 size. For Desriptor
+                     * DMA mode SW is able to initiate a transfer,
+                     * which will handle all the packets including
+                     * the last  0 legth.
+                     */
+                    ep->dwc_ep.sent_zlp = 0;
+                    dwc_otg_ep_start_zl_transfer(core_if,
+                                                 &ep->dwc_ep);
+                }
+                else
+                {
+
+                    if (ep->dwc_ep.fnUsbCb)
+                        ep->dwc_ep.fnUsbCb( (WORD32)(ep->dwc_ep.pPara), 0, ep->dwc_ep.xfer_count, ep->dwc_ep.total_len);
+
+                }
+            }
+        }
+    }
+    // OUT EP
+    else
+    {
+        dwc_otg_dev_out_ep_regs_t *out_ep_regs = dev_if->out_ep_regs[ep->dwc_ep.num];
+        {
+            deptsiz.d32 = 0;
+            deptsiz.d32 = DWC_READ_REG32(&out_ep_regs->doeptsiz);
+            if (deptsiz.b.xfersize>0)
+            {
+
+                if (ep->dwc_ep.fnUsbCb)
+                    ep->dwc_ep.fnUsbCb( (WORD32)(ep->dwc_ep.pPara), 0, ep->dwc_ep.xfer_count, ep->dwc_ep.total_len);
+
+            }
+            else
+            {
+                dwc_otg_ep_start_transfer(core_if,&ep->dwc_ep);
+            }
+        }
+
+
+    }
+
+}
+
+/**
+ * This function handles EP0 Control transfers.
+ *
+ * The state of the control transfers are tracked in
+ * <code>ep0state</code>.
+ */
+static void handle_ep0(dwc_otg_pcd_t * pcd)
+{
+    dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+
+    switch (pcd->ep0state)
+    {
+    case EP0_DISCONNECT:
+        break;
+
+    case EP0_IDLE:
+        pcd->request_config = 0;
+
+        pcd_setup(pcd);
+
+        break;
+
+    case EP0_IN_DATA_PHASE:
+        if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len)
+        {
+            dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),&ep0->dwc_ep);
+        }
+        else if (ep0->dwc_ep.sent_zlp)
+        {
+            dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),&ep0->dwc_ep);
+            ep0->dwc_ep.sent_zlp = 0;
+        }
+        else
+        {
+            ep0_complete_request(ep0);
+        }
+        break;
+    case EP0_OUT_DATA_PHASE:
+        if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len)
+        {
+            dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
+                                          &ep0->dwc_ep);
+        }
+        else if (ep0->dwc_ep.sent_zlp)
+        {
+            dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
+            ep0->dwc_ep.sent_zlp = 0;
+        }
+        else
+        {
+            ep0_complete_request(ep0);
+        }
+        break;
+
+    case EP0_IN_STATUS_PHASE:
+    case EP0_OUT_STATUS_PHASE:
+        ep0_complete_request(ep0);
+        pcd->ep0state = EP0_IDLE;
+        ep0->stopped = 1;
+        ep0->dwc_ep.is_in = 0;	/* OUT for next SETUP */
+        break;
+
+    case EP0_STALL:
+        break;
+    }
+
+}
+
+/**
+ * Handler for the IN EP NAK interrupt.
+ */
+
+/**
+ * Handler for the OUT EP NAK interrupt.
+ */
+static  int32_t handle_out_ep_nak_intr(dwc_otg_pcd_t * pcd,
+                                       const uint32_t epnum)
+{
+    /** @todo implement ISR */
+    dwc_otg_core_if_t *core_if;
+    doepmsk_data_t intr_mask;
+    intr_mask.d32 = 0;
+
+    core_if = GET_CORE_IF(pcd);
+    intr_mask.b.nak = 1;
+    {
+        DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,intr_mask.d32, 0);
+    }
+
+    return 1;
+}
+
+/**
+ * Handler for the OUT EP NYET interrupt.
+ */
+static  int32_t handle_out_ep_nyet_intr(dwc_otg_pcd_t * pcd,
+                                        const uint32_t epnum)
+{
+    /** @todo implement ISR */
+    dwc_otg_core_if_t *core_if;
+    doepmsk_data_t intr_mask;
+    intr_mask.d32 = 0 ;
+
+    core_if = GET_CORE_IF(pcd);
+    intr_mask.b.nyet = 1;
+    {
+        DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk, intr_mask.d32, 0);
+    }
+
+    return 1;
+}
+
+/**
+ * This interrupt indicates that an IN EP has a pending Interrupt.
+ * The sequence for handling the IN EP interrupt is shown below:
+ * -#	Read the Device All Endpoint Interrupt register
+ * -#	Repeat the following for each IN EP interrupt bit set (from
+ *		LSB to MSB).
+ * -#	Read the Device Endpoint Interrupt (DIEPINTn) register
+ * -#	If "Transfer Complete" call the request complete function
+ * -#	If "Endpoint Disabled" complete the EP disable procedure.
+ * -#	If "AHB Error Interrupt" log error
+ * -#	If "Time-out Handshake" log error
+ * -#	If "IN Token Received when TxFIFO Empty" write packet to Tx
+ *		FIFO.
+ * -#	If "IN Token EP Mismatch" (disable, this is handled by EP
+ *		Mismatch Interrupt)
+ */
+static int32_t dwc_otg_pcd_handle_in_ep_intr(dwc_otg_pcd_t * pcd)
+{
+
+    dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+    dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+    diepint_data_t diepint;
+    depctl_data_t depctl;
+    uint32_t ep_intr;
+    uint32_t epnum = 0;
+    dwc_otg_pcd_ep_t *ep;
+    dwc_ep_t *dwc_ep;
+    diepmsk_data_t diepmsk;
+    uint32_t fifoemptymsk;
+    diepint.d32 = 0;
+    depctl.d32 = 0;
+    diepmsk.d32 = 0;
+
+    ep_intr = dwc_otg_read_dev_all_in_ep_intr(core_if);
+    /* Service the Device IN interrupts for each endpoint */
+    while (ep_intr&&(epnum<MAX_EPS_CHANNELS))
+    {
+        if (ep_intr & 0x1)
+        {
+
+            /* Get EP pointer */
+            ep = get_in_ep(pcd, epnum);
+            dwc_ep = &ep->dwc_ep;
+            depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl);
+            diepint.d32 = dwc_otg_read_dev_in_ep_intr(core_if, dwc_ep);
+            /* Transfer complete */
+            if (diepint.b.xfercompl)
+            {
+                {
+                   /* Disable the Tx FIFO Empty Interrupt for this EP */
+                    fifoemptymsk = 0x1 << dwc_ep->num;
+                    DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,fifoemptymsk, 0);
+                }
+                /* Clear the bit in DIEPINTn for this interrupt */
+                CLEAR_IN_EP_INTR(core_if, epnum, xfercompl);
+
+                /* Complete the transfer */
+                if (epnum == 0)
+                {
+                    handle_ep0(pcd);
+
+                }
+                else
+                {
+
+                    complete_ep(ep);
+                    if (diepint.b.nak)
+                        CLEAR_IN_EP_INTR(core_if, epnum, nak);
+                }
+            }
+            /* Endpoint disable      */
+            if (diepint.b.epdisabled)
+            {
+
+                CLEAR_IN_EP_INTR(core_if, epnum, epdisabled);
+            }
+
+            /* TimeOUT Handshake (non-ISOC IN EPs) */
+            if (diepint.b.timeout)
+            {
+                CLEAR_IN_EP_INTR(core_if, epnum, timeout);
+            }
+            /** IN Token received with TxF Empty */
+            if (diepint.b.intktxfemp)
+            {
+                if (!ep->stopped && epnum != 0)
+                {
+                    diepmsk.b.intktxfemp = 1;
+                    {
+                        DWC_MODIFY_REG32
+                        (&dev_if->dev_global_regs->diepmsk,
+                         diepmsk.d32, 0);
+                    }
+                }
+                CLEAR_IN_EP_INTR(core_if, epnum, intktxfemp);
+            }
+
+            /** IN Endpoint NAK Effective */
+            if (diepint.b.inepnakeff)
+            {
+                /* Periodic EP */
+                if (ep->disabling)
+                {
+                    depctl.d32 = 0;
+                    depctl.b.snak = 1;
+                    depctl.b.epdis = 1;
+                    DWC_MODIFY_REG32(&dev_if->in_ep_regs
+                                     [epnum]->diepctl,
+                                     depctl.d32,
+                                     depctl.d32);
+                }
+                CLEAR_IN_EP_INTR(core_if, epnum, inepnakeff);
+
+            }
+
+            /** IN EP Tx FIFO Empty Intr */
+            if (diepint.b.emptyintr)
+            {
+                write_empty_tx_fifo(pcd, epnum);
+                
+                CLEAR_IN_EP_INTR(core_if, epnum, emptyintr);
+ 
+            }
+            /* NAK Interrutp */
+            if (diepint.b.nak)
+            {
+                CLEAR_IN_EP_INTR(core_if, epnum, nak);
+            }
+        }
+        epnum++;
+        ep_intr >>= 1;
+    }
+
+    return 1;
+#undef CLEAR_IN_EP_INTR
+}
+
+/**
+ * This interrupt indicates that an OUT EP has a pending Interrupt.
+ * The sequence for handling the OUT EP interrupt is shown below:
+ * -#	Read the Device All Endpoint Interrupt register
+ * -#	Repeat the following for each OUT EP interrupt bit set (from
+ *		LSB to MSB).
+ * -#	Read the Device Endpoint Interrupt (DOEPINTn) register
+ * -#	If "Transfer Complete" call the request complete function
+ * -#	If "Endpoint Disabled" complete the EP disable procedure.
+ * -#	If "AHB Error Interrupt" log error
+ * -#	If "Setup Phase Done" process Setup Packet (See Standard USB
+ *		Command Processing)
+ */
+static int32_t dwc_otg_pcd_handle_out_ep_intr(dwc_otg_pcd_t * pcd)
+{
+
+    dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+    uint32_t ep_intr;
+    doepint_data_t doepint;
+    doepint_data_t doepint1;
+    uint32_t epnum = 0;
+    dwc_otg_pcd_ep_t *ep;
+    dwc_ep_t *dwc_ep;
+
+    doepint.d32 = 0;
+    doepint1.d32 = 0;
+
+
+    ep_intr = dwc_otg_read_dev_all_out_ep_intr(core_if);
+    while (ep_intr)
+    {
+        if (ep_intr & 0x1)
+        {
+            /* Get EP pointer */
+            ep = get_out_ep(pcd, epnum);
+            dwc_ep = &ep->dwc_ep;
+            doepint.d32 = dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep);
+            /* Transfer complete */
+            if (doepint.b.xfercompl)
+            {
+                if (epnum == 0)
+                {
+                    /* Clear the bit in DOEPINTn for this interrupt */
+                    CLEAR_OUT_EP_INTR(core_if, epnum, xfercompl);
+                    doepint1.d32 = DWC_READ_REG32(&core_if->dev_if->out_ep_regs[0]->doepint);
+                    if (pcd->ep0state == EP0_IDLE && doepint1.b.sr)
+                    {
+                        CLEAR_OUT_EP_INTR(core_if, epnum, sr);
+                    }
+                    else if(pcd->ep0state != EP0_IDLE)
+                    {
+                        handle_ep0(pcd);
+                    }
+                }
+                else
+                {
+                    /* Clear the bit in DOEPINTn for this interrupt */
+                    CLEAR_OUT_EP_INTR(core_if, epnum,xfercompl);
+                    complete_ep(ep);
+                }
+
+            }
+
+            /* Endpoint disable      */
+            if (doepint.b.epdisabled)
+            {
+                /* Clear the bit in DOEPINTn for this interrupt */
+                CLEAR_OUT_EP_INTR(core_if, epnum, epdisabled);
+            }
+            if (doepint.b.setup)
+            {
+                CLEAR_OUT_EP_INTR(core_if, epnum, setup);
+
+                handle_ep0(pcd);
+
+            }
+            if (doepint.b.outtknepdis)
+            {
+                CLEAR_OUT_EP_INTR(core_if, epnum, outtknepdis);
+            }
+
+            /* NAK Interrutp */
+            if (doepint.b.nak)
+            {
+                handle_out_ep_nak_intr(pcd, epnum);
+
+                CLEAR_OUT_EP_INTR(core_if, epnum, nak);
+            }
+
+            /* NYET Interrutp */
+            if (doepint.b.nyet)
+            {
+                handle_out_ep_nyet_intr(pcd, epnum);
+
+                CLEAR_OUT_EP_INTR(core_if, epnum, nyet);
+            }
+        }
+
+        epnum++;
+        ep_intr >>= 1;
+    }
+
+    return 1;
+
+#undef CLEAR_OUT_EP_INTR
+}
+
+/**
+ * PCD interrupt handler.
+ *
+ * The PCD handles the device interrupts.  Many conditions can cause a
+ * device interrupt. When an interrupt occurs, the device interrupt
+ * service routine determines the cause of the interrupt and
+ * dispatches handling to the appropriate function. These interrupt
+ * handling functions are described below.
+ *
+ * All interrupt registers are processed from LSB to MSB.
+ *
+ */
+
+extern int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t * core_if);
+
+int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t * pcd)
+{
+    dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+
+    gintsts_data_t gintr_status;
+    int32_t retval = 0;
+        gintr_status.d32 = dwc_otg_read_core_intr(core_if);
+
+        if (gintr_status.b.rxstsqlvl)
+        {
+            retval |=
+                dwc_otg_pcd_handle_rx_status_q_level_intr(pcd);
+        }
+      //½«Á½¸öÖжϺϳÉÒ»¸ö
+        if (gintr_status.b.usbsuspend)
+        {
+            retval |= dwc_otg_handle_usb_suspend_intr(pcd->core_if);
+        }
+        if (gintr_status.b.usbreset)
+        {
+            retval |= dwc_otg_pcd_handle_usb_reset_intr(pcd);
+	       global.g_Connet =1;
+        }
+        if (gintr_status.b.enumdone)
+        {
+            retval |= dwc_otg_pcd_handle_enum_done_intr(pcd);
+        }
+        if (gintr_status.b.inepint)
+        {
+            if (!core_if->multiproc_int_enable)
+            {
+                retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
+            }
+        }
+        if (gintr_status.b.outepintr)
+        {
+            if (!core_if->multiproc_int_enable)
+            {
+                retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
+            }
+        }
+    return retval;
+}
+
+#endif /* DWC_HOST_ONLY */
diff --git a/boot/common/src/uboot/drivers/usb_drv/global.c b/boot/common/src/uboot/drivers/usb_drv/global.c
new file mode 100644
index 0000000..4438c79
--- /dev/null
+++ b/boot/common/src/uboot/drivers/usb_drv/global.c
@@ -0,0 +1,101 @@
+#include <usb/global.h>

+

+__align(4) dwc_config_all_t  desc =

+{
+//T_CONFIG_DESCRIPTOR
+{
+	sizeof(dwc_config_descriptor_t),				//bLength
+	CONFIG_DESCRIPTOR,							//bDescriptorType
+	sizeof(dwc_config_all_t),
+	2,											//bNumInterfaces
+	1,											//bConfigurationValue
+	0,											//iConfiguration×Ö·û´®ÃèÊöµÄË÷Òý
+	ATTR_D7 |ATTR_SELF_POWERED ,	//bmAttributes
+	POWER_MA(500),											//
+},
+
+
+//T_INTERFACE_DESCRIPTOR
+{
+	sizeof(dwc_interface_descriptor_t),		//bLength
+	INTERFACE_DESCRIPTOR,				//bDescriptorType
+	0,									//bInterfaceNumber
+	0,									//bAlternateSetting
+	0x02,						//bNumEndpoints
+	VERDOR_SPECIFIC,					//bInterfaceClass
+	0xff,								//bInterfaceSubClass
+	0xff,								//bInterfaceProtocol
+	0x04,									//iInterface×Ö·û´®ÃèÊöµÄË÷Òý
+},
+{

+    {

+        sizeof(dwc_ep_descriptor_t), 		//bLength

+        ENDPOINT_DESCRIPTOR, 			//bDescriptorType

+        EP_ADDRESS_DIRECTION_IN	|0x1, 	//bEndpointAddress

+        EP_ATTR_TRANSFER_TYPE_BULK, 	//bmAttributes

+        USB_HIGHSPEED_BULK_MAXSIZE, 		   //wMaxPacketSize

+        0,								//bInterval

+    }

+},

+{

+    {

+    	sizeof(dwc_ep_descriptor_t), 		//bLength

+    	ENDPOINT_DESCRIPTOR, 			//bDescriptorType

+    	0x1, 							//bEndpointAddress

+    	EP_ATTR_TRANSFER_TYPE_BULK, 	//bmAttributes

+    	USB_HIGHSPEED_BULK_MAXSIZE, 		 //wMaxPacketSize

+    	0,							//bInterval

+    }

+},

+//T_INTERFACE_DESCRIPTOR
+{
+    sizeof(dwc_interface_descriptor_t),		//bLength
+    INTERFACE_DESCRIPTOR,				//bDescriptorType
+    1,									//bInterfaceNumber
+    0,									//bAlternateSetting
+    0x02,						//bNumEndpoints
+    VERDOR_SPECIFIC,					//bInterfaceClass
+    0xff,								//bInterfaceSubClass
+    0xff,								//bInterfaceProtocol
+    0x05,									//iInterface×Ö·û´®ÃèÊöµÄË÷Òý
+},

+{

+    {

+    	sizeof(dwc_ep_descriptor_t), 		//bLength

+    	ENDPOINT_DESCRIPTOR, 			//bDescriptorType

+    	EP_ADDRESS_DIRECTION_IN	|0x2, 	//bEndpointAddress

+    	EP_ATTR_TRANSFER_TYPE_BULK, 	//bmAttributes

+    	USB_HIGHSPEED_BULK_MAXSIZE, 	      //wMaxPacketSize

+    	0,								//bInterval

+    }

+},

+{

+    {

+    	sizeof(dwc_ep_descriptor_t), 		//bLength

+    	ENDPOINT_DESCRIPTOR, 			//bDescriptorType

+    	0x2, 							//bEndpointAddress

+    	EP_ATTR_TRANSFER_TYPE_BULK, 	//bmAttributes

+    	USB_HIGHSPEED_BULK_MAXSIZE, 	     //wMaxPacketSize

+    	0,							//bInterval

+    }

+},

+};

+

+struct g_data	  					global;

+

+__align(4) dwc_config_all_t	g_config_desc ;

+

+void data_init(void)

+{

+	int i;

+	char *src 	= (char*)&desc;

+	char *dst	= (char*)&g_config_desc;

+

+	for(i = 0; i < sizeof(dwc_config_all_t); i++)

+	{

+		*dst++	= *src++;

+	}

+}

+

+

+