zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/boot/common/src/loader/drivers/dwc_otg_pcd.c b/boot/common/src/loader/drivers/dwc_otg_pcd.c
new file mode 100644
index 0000000..74d6adb
--- /dev/null
+++ b/boot/common/src/loader/drivers/dwc_otg_pcd.c
@@ -0,0 +1,338 @@
+/* ==========================================================================
+ * $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 "global.h"
+#include "dwc_otg_pcd.h"
+
+__align(4) const dwc_device_descriptor_t  device_desc =
+{
+    sizeof(dwc_device_descriptor_t),
+    DEVICE_DESCRIPTOR,
+    0x0200, 			// usb 2.0   //usb 1.1
+    0x00,
+    0x00,
+    0x00,
+    CONTROL_64,			// ×î´ó°ü8×Ö½Ú
+    USB_VENDOR_ID,
+    USB_PRODUCT_ID,
+    PRODUCT_RELEASE_NUMBER,
+    0x01,               // manufacturer descriptionË÷ÒýºÅ
+    0x02,               // product descriptionË÷ÒýºÅ
+    0x03,               // serial number descriptionË÷ÒýºÅ
+    0x01                // ÅäÖÃÊý
+};
+
+__align(4) const dwc_dev_qual_descriptor_t  dev_qual_desc =
+{
+    sizeof(dwc_dev_qual_descriptor_t),
+    0x06,
+    0x0200,                      // usb 2.0
+    VERDOR_SPECIFIC,
+    0x00,
+    0x00,
+    64,
+    0x01,                      // ÅäÖÃÊý
+    0x0
+};
+
+
+
+__align(4) const dwc_langid_descriptor_t    tLanguage=
+{
+    STRING_DESCRIPTOR_SIZE(1),
+    STRING_DESCRIPTOR,
+    LANGID_US_ENGLISH
+};
+
+__align(4) const 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) const 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) const 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) const 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) const 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) const dwc_string_descriptor_t * const 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 value;
+    byIdx  = (uint8_t)(ctrl->wValue &0xff);
+    value = ctrl->wValue>>8;
+
+    if( USB_DT_DEVICE ==value )
+    	{
+	    len = MIN( sizeof(dwc_device_descriptor_t), ctrl->wLength);
+	    do_get_descriptor(pcd,(uint32_t*)&device_desc,len);
+    	}
+    else if( USB_DT_CONFIG==value )
+    	{
+	        len = MIN( sizeof(dwc_config_all_t), ctrl->wLength);
+	        do_get_descriptor(pcd,(uint32_t*)&g_config_desc,len);
+    	}
+
+    else if( USB_DT_STRING ==value)
+    	{
+	        len = MIN(((dwc_string_descriptor_t*)(pStrDescIdx[byIdx]))->bLength, ctrl->wLength);
+	        do_get_descriptor(pcd,(uint32_t*)pStrDescIdx[byIdx],len);
+	 }
+  
+     else if(  USB_DT_INTERFACE == value)
+     	{
+	        len = MIN(((dwc_string_descriptor_t*)(pStrDescIdx[byIdx]))->bLength, ctrl->wLength);
+	        do_get_descriptor(pcd,(uint32_t*)pStrDescIdx[byIdx],len);
+     	}
+     else if(   ENDPOINT_DESCRIPTOR == value)
+     	{
+	        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 ==value)
+    	{
+	        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 */