12cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang/* 22cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * Copyright (c) 2014-2015, Linaro Ltd and Contributors. All rights reserved. 32cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * Copyright (c) 2014-2015, Hisilicon Ltd and Contributors. All rights reserved. 42cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * 52cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * Redistribution and use in source and binary forms, with or without 62cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * modification, are permitted provided that the following conditions are met: 72cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * 82cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * Redistributions of source code must retain the above copyright notice, this 92cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * list of conditions and the following disclaimer. 102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * 112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * Redistributions in binary form must reproduce the above copyright notice, 122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * this list of conditions and the following disclaimer in the documentation 132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * and/or other materials provided with the distribution. 142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * 152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * Neither the name of ARM nor the names of its contributors may be used 162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * to endorse or promote products derived from this software without specific 172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * prior written permission. 182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * 192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * POSSIBILITY OF SUCH DAMAGE. 302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang */ 312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#include <assert.h> 332cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#include <ctype.h> 342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#include <debug.h> 3559fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang#include <gpio.h> 362cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#include <hi6220.h> 372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#include <mmio.h> 382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#include <partitions.h> 392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#include <platform_def.h> 402cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#include <sp804_timer.h> 412cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#include <string.h> 422cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#include <usb.h> 432cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#include "hikey_private.h" 44a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj#include <bl_common.h> 452cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 462cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#define NUM_ENDPOINTS 16 472cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 482cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#define USB_BLOCK_HIGH_SPEED_SIZE 512 492cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 50554b28ac1d6a6c75893fb5831107fee464ce581dVishal Bhoj#define VERSION_BOOTLOADER "0.4" 51554b28ac1d6a6c75893fb5831107fee464ce581dVishal Bhoj 522cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstruct ep_type { 532cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned char active; 542cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned char busy; 552cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned char done; 562cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int rc; 572cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int size; 582cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang}; 592cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 602cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstruct usb_endpoint { 612cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_endpoint *next; 622cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int maxpkt; 632cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_request *req; 642cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned char num; 652cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned char in; 662cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang}; 672cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 682cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstruct usb_config_bundle { 692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_config_descriptor config; 702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_interface_descriptor interface; 712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_endpoint_descriptor ep1; 722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_endpoint_descriptor ep2; 732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} __attribute__ ((packed)); 742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic setup_packet ctrl_req[NUM_ENDPOINTS] 762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang__attribute__ ((section("tzfw_coherent_mem"))); 772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic unsigned char ctrl_resp[2] 782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang__attribute__ ((section("tzfw_coherent_mem"))); 792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic struct ep_type endpoints[NUM_ENDPOINTS] 812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang__attribute__ ((section("tzfw_coherent_mem"))); 822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangdwc_otg_dev_dma_desc_t dma_desc 842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang__attribute__ ((section("tzfw_coherent_mem"))); 852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangdwc_otg_dev_dma_desc_t dma_desc_ep0 862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang__attribute__ ((section("tzfw_coherent_mem"))); 872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangdwc_otg_dev_dma_desc_t dma_desc_in 882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang__attribute__ ((section("tzfw_coherent_mem"))); 892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangdwc_otg_dev_dma_desc_t dma_desc_addr 902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang__attribute__ ((section("tzfw_coherent_mem"))); 912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic struct usb_config_bundle config_bundle 932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang__attribute__ ((section("tzfw_coherent_mem"))); 942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic struct usb_device_descriptor device_descriptor 952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang__attribute__ ((section("tzfw_coherent_mem"))); 962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic struct usb_request rx_req 982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang__attribute__ ((section("tzfw_coherent_mem"))); 992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic struct usb_request tx_req 1002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang__attribute__ ((section("tzfw_coherent_mem"))); 1012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 102b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuangstatic struct usb_string_descriptor serial_string 103b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang__attribute__ ((section("tzfw_coherent_mem"))); 104b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang 1052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic const struct usb_string_descriptor string_devicename = { 1062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 24, 1072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang USB_DT_STRING, 1082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang {'A', 'n', 'd', 'r', 'o', 'i', 'd', ' ', '2', '.', '0'} 1092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang}; 1102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic const struct usb_string_descriptor serial_string_descriptor = { 1122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 34, 1132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang USB_DT_STRING, 1142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'} 1152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang}; 1162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic const struct usb_string_descriptor lang_descriptor = { 1182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 4, 1192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang USB_DT_STRING, 1202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang {0x0409} /* en-US */ 1212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang}; 1222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void usb_rx_cmd_complete(unsigned actual, int stat); 1242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void usb_rx_data_complete(unsigned actual, int status); 1252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic unsigned int rx_desc_bytes = 0; 1272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic unsigned long rx_addr; 1282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic unsigned long rx_length; 1292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic unsigned int last_one = 0; 1302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic char *cmdbuf; 1312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic struct usb_endpoint ep1in, ep1out; 1322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic int g_usb_enum_flag = 0; 1332cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangint usb_need_reset = 0; 1352cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1362cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic int usb_drv_port_speed(void) 1372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 1382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* 2'b00 High speed (PHY clock is at 30MHz or 60MHz) */ 1392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return (mmio_read_32(DSTS) & 2) == 0 ? 1 : 0; 1402cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 1412cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1422cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void reset_endpoints(void) 1432cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 1442cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang int i; 1452cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int data; 1462cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1472cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang INFO("enter reset_endpoints.\n"); 1482cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang for (i = 0; i < NUM_ENDPOINTS; i++) { 1492cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[i].active = 0; 1502cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[i].busy = 0; 1512cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[i].rc = -1; 1522cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[i].done = 1; 1532cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 1542cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1552cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* EP0 IN ACTIVE NEXT=1 */ 1562cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPCTL0, 0x8800); 1572cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1582cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* EP0 OUT ACTIVE */ 1592cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPCTL0, 0x8000); 1602cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1612cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Clear any pending OTG Interrupts */ 1622cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GOTGINT, ~0); 1632cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1642cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Clear any pending interrupts */ 1652cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GINTSTS, ~0); 1662cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPINT0, ~0); 1672cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPINT0, ~0); 1682cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPINT1, ~0); 1692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPINT1, ~0); 1702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* IN EP interrupt mask */ 1722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPMSK, 0x0D); 1732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* OUT EP interrupt mask */ 1742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPMSK, 0x0D); 1752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Enable interrupts on Ep0 */ 1762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DAINTMSK, 0x00010001); 1772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 1782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* EP0 OUT Transfer Size:64 Bytes, 1 Packet, 3 Setup Packet, Read to receive setup packet*/ 1792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = DOEPTSIZ0_SUPCNT(3) | DOEPTSIZ0_PKTCNT | 1802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang (64 << DOEPTSIZ0_XFERSIZE_SHIFT); 1812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPTSIZ0, data); 1822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang //notes that:the compulsive conversion is expectable. 1832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.bs = 0x3; 1842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.mtrf = 0; 1852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.sr = 0; 1862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.l = 1; 1872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.ioc = 1; 1882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.sp = 0; 1892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.bytes = 64; 1902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.buf = (unsigned long)&ctrl_req; 1912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.sts = 0; 1922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.bs = 0x0; 1932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPDMA0, ((unsigned long)&(dma_desc_ep0))); 1942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("%s, &ctrl_req:%llx:%x, &dms_desc_ep0:%llx:%x\n", 1952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang __func__, (unsigned long)&ctrl_req, (unsigned long)&ctrl_req, 1962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang (unsigned long)&dma_desc_ep0, (unsigned long)&dma_desc_ep0); 1972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* EP0 OUT ENABLE CLEARNAK */ 1982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DOEPCTL0); 1992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPCTL0, (data | 0x84000000)); 2002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("exit reset_endpoints. \n"); 2022cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 2032cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2042cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic int usb_drv_request_endpoint(int type, int dir) 2052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 2062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang int ep = 1; /*FIXME*/ 2072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int newbits, data; 2082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang newbits = (type << 18) | 0x10000000; 2102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* 2122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * (type << 18):Endpoint Type (EPType) 2132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * 0x10000000:Endpoint Enable (EPEna) 2142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * 0x000C000:Endpoint Type (EPType);Hardcoded to 00 for control. 2152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * (ep<<22):TxFIFO Number (TxFNum) 2162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * 0x20000:NAK Status (NAKSts);The core is transmitting NAK handshakes on this endpoint. 2172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang */ 2182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (dir) { // IN: to host 2192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DIEPCTL(ep)); 2202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data &= ~0x000c0000; 2212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data |= newbits | (ep << 22) | 0x20000; 2222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPCTL(ep), data); 2232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { // OUT: to device 2242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DOEPCTL(ep)); 2252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data &= ~0x000c0000; 2262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data |= newbits; 2272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPCTL(ep), data); 2282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 2292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[ep].active = 1; // true 2302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return ep | dir; 2322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 2332cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangvoid usb_drv_release_endpoint(int ep) 2352cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 2362cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep = ep % NUM_ENDPOINTS; 2372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (ep < 1 || ep > NUM_ENDPOINTS) 2382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return; 2392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2402cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[ep].active = 0; 2412cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 2422cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2432cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangvoid usb_config(void) 2442cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 2452cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int data; 2462cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2472cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang INFO("enter usb_config\n"); 2482cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2492cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GDFIFOCFG, DATA_FIFO_CONFIG); 2502cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GRXFSIZ, RX_SIZE); 2512cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GNPTXFSIZ, ENDPOINT_TX_SIZE); 2522cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2532cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF1, DATA_IN_ENDPOINT_TX_FIFO1); 2542cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF2, DATA_IN_ENDPOINT_TX_FIFO2); 2552cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF3, DATA_IN_ENDPOINT_TX_FIFO3); 2562cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF4, DATA_IN_ENDPOINT_TX_FIFO4); 2572cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF5, DATA_IN_ENDPOINT_TX_FIFO5); 2582cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF6, DATA_IN_ENDPOINT_TX_FIFO6); 2592cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF7, DATA_IN_ENDPOINT_TX_FIFO7); 2602cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF8, DATA_IN_ENDPOINT_TX_FIFO8); 2612cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF9, DATA_IN_ENDPOINT_TX_FIFO9); 2622cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF10, DATA_IN_ENDPOINT_TX_FIFO10); 2632cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF11, DATA_IN_ENDPOINT_TX_FIFO11); 2642cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF12, DATA_IN_ENDPOINT_TX_FIFO12); 2652cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF13, DATA_IN_ENDPOINT_TX_FIFO13); 2662cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF14, DATA_IN_ENDPOINT_TX_FIFO14); 2672cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTXF15, DATA_IN_ENDPOINT_TX_FIFO15); 2682cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*Init global csr register.*/ 2702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* 2722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * set Periodic TxFIFO Empty Level, 2732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * Non-Periodic TxFIFO Empty Level, 2742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * Enable DMA, Unmask Global Intr 2752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang */ 2762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang INFO("USB: DMA mode.\n"); 2772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GAHBCFG, GAHBCFG_CTRL_MASK); 2782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*select 8bit UTMI+, ULPI Inerface*/ 2802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang INFO("USB ULPI PHY\n"); 2812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GUSBCFG, 0x2400); 2822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Detect usb work mode,host or device? */ 2842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang do { 2852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(GINTSTS); 2862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } while (data & GINTSTS_CURMODE_HOST); 2872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("Enter device mode\n"); 2882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang udelay(3); 2892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*Init global and device mode csr register.*/ 2912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*set Non-Zero-Length status out handshake */ 2922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = (0x20 << DCFG_EPMISCNT_SHIFT) | DCFG_NZ_STS_OUT_HSHK; 2932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DCFG, data); 2942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 2952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Interrupt unmask: IN event, OUT event, bus reset */ 2962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = GINTSTS_OEPINT | GINTSTS_IEPINT | GINTSTS_ENUMDONE | 2972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang GINTSTS_USBRST | GINTSTS_USBSUSP | GINTSTS_ERLYSUSP | 2982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang GINTSTS_GOUTNAKEFF; 2992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GINTMSK, data); 3002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang do { 3022cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(GINTSTS) & GINTSTS_ENUMDONE; 3032cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } while (data); 3042cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("USB Enum Done.\n"); 3052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Clear any pending OTG Interrupts */ 3072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GOTGINT, ~0); 3082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Clear any pending interrupts */ 3092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GINTSTS, ~0); 3102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GINTMSK, ~0); 3112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(GOTGINT); 3122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data &= ~0x3000; 3132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GOTGINT, data); 3142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*endpoint settings cfg*/ 3152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang reset_endpoints(); 3162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang udelay(1); 3182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*init finish. and ready to transfer data*/ 3202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Soft Disconnect */ 3222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DCTL, 0x802); 3232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang udelay(10000); 3242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Soft Reconnect */ 3262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DCTL, 0x800); 3272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("exit usb_config.\n"); 3282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 3292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangvoid usb_drv_set_address(int address) 3312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 3322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int cfg; 3332cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang cfg = mmio_read_32(DCFG); 3352cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang cfg &= ~0x7F0; 3362cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang cfg |= address << 4; 3372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DCFG, cfg); // 0x7F0: device address 3382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 3392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3402cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void ep_send(int ep, const void *ptr, int len) 3412cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 3422cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int data; 3432cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3442cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[ep].busy = 1; // true 3452cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[ep].size = len; 3462cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3472cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* EPx OUT ACTIVE */ 3482cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DIEPCTL(ep)) | DXEPCTL_USBACTEP; 3492cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPCTL(ep), data); 3502cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3512cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* set DMA Address */ 3522cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (!len) { 3532cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* send one empty packet */ 3542cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.buf = 0; 3552cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { 3562cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.buf = (unsigned long)ptr; 3572cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 3582cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.bs = 0x3; 3592cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.l = 1; 3602cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.ioc = 1; 3612cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.sp = 1; 3622cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.sts = 0; 3632cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.bs = 0x0; 3642cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.bytes = len; 3652cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPDMA(ep), (unsigned long)&dma_desc_in); 3662cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3672cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DIEPCTL(ep)); 3682cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data |= DXEPCTL_EPENA | DXEPCTL_CNAK | DXEPCTL_NEXTEP(ep + 1); 3692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPCTL(ep), data); 3702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 3712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangvoid usb_drv_stall(int endpoint, char stall, char in) 3732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 3742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int data; 3752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* 3772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * STALL Handshake (Stall) 3782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang */ 3792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DIEPCTL(endpoint)); 3812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (in) { 3822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (stall) 3832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPCTL(endpoint), data | 0x00200000); 3842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang else 3852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPCTL(endpoint), data & ~0x00200000); 3862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { 3872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (stall) 3882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPCTL(endpoint), data | 0x00200000); 3892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang else 3902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPCTL(endpoint), data & ~0x00200000); 3912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 3922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 3932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 3942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangint usb_drv_send_nonblocking(int endpoint, const void *ptr, int len) 3952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 3962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("%s, endpoint = %d, ptr = 0x%x, Len=%d.\n", 3972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang __func__, endpoint, ptr, len); 3982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep_send(endpoint % NUM_ENDPOINTS, ptr, len); 3992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return 0; 4002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 4012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 4022cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangvoid usb_drv_cancel_all_transfers(void) 4032cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 4042cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang reset_endpoints(); 4052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 4062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 4072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangint hiusb_epx_tx(unsigned ep, void *buf, unsigned len) 4082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 4092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang int blocksize,packets; 4102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int epints; 4112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int cycle = 0; 4122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int data; 4132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 4142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[ep].busy = 1; //true 4152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[ep].size = len; 4162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 4172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang while (mmio_read_32(GINTSTS) & 0x40) { 4182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DCTL); 4192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data |= 0x100; 4202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DCTL, data); 4212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 4222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 4232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DIEPCTL(ep)); 4242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data |= 0x08000000; 4252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPCTL(ep), data); 4262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 4272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* EPx OUT ACTIVE */ 4282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPCTL(ep), data | 0x8000); 4292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (!ep) { 4302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang blocksize = 64; 4312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { 4322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang blocksize = usb_drv_port_speed() ? USB_BLOCK_HIGH_SPEED_SIZE : 64; 4332cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 4342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang packets = (len + blocksize - 1) / blocksize; 4352cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 4362cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (!len) { 4372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* one empty packet */ 4382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTSIZ(ep), 1 << 19); 4392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* NULL */ 4402cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.bs = 0x3; 4412cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.l = 1; 4422cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.ioc = 1; 4432cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.sp = last_one; 4442cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.bytes = 0; 4452cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.buf = 0; 4462cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.sts = 0; 4472cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.bs = 0x0; 4482cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPDMA(ep), (unsigned long)&dma_desc_in); 4492cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { 4502cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPTSIZ(ep), len | (packets << 19)); 4512cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.bs = 0x3; 4522cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.l = 1; 4532cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.ioc = 1; 4542cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.sp = last_one; 4552cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.bytes = len; 4562cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.buf = (unsigned long)buf; 4572cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.sts = 0; 4582cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_in.status.b.bs = 0x0; 4592cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPDMA(ep), (unsigned long)&dma_desc_in); 4602cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 4612cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 4622cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang cycle = 0; 4632cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang while(1){ 4642cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DIEPINT(ep)); 4652cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if ((data & 0x2000) || (cycle > 10000)) { 4662cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (cycle > 10000) { 4672cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang NOTICE("Phase 2:ep(%d) status, DIEPCTL(%d) is [0x%x]," 4682cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang "DTXFSTS(%d) is [0x%x], DIEPINT(%d) is [0x%x]," 4692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang "DIEPTSIZ(%d) is [0x%x] GINTSTS is [0x%x]\n", 4702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep, ep, data, 4712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep, mmio_read_32(DTXFSTS(ep)), 4722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep, mmio_read_32(DIEPINT(ep)), 4732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep, mmio_read_32(DIEPTSIZ(ep)), 4742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_read_32(GINTSTS)); 4752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 4762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 4772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 4782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 4792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang cycle++; 4802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang udelay(10); 4812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 4822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("ep(%d) enable, DIEPCTL(%d) is [0x%x], DTXFSTS(%d) is [0x%x]," 4832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang "DIEPINT(%d) is [0x%x], DIEPTSIZ(%d) is [0x%x] \n", 4842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep, ep, mmio_read_32(DIEPCTL(ep)), 4852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep, mmio_read_32(DTXFSTS(ep)), 4862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep, mmio_read_32(DIEPINT(ep)), 4872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep, mmio_read_32(DIEPTSIZ(ep))); 4882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 4892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang __asm__ volatile("dsb sy\n" 4902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang "isb sy\n"); 4912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DIEPCTL(ep)); 4922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data |= 0x84000000; 4932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* epena & cnak*/ 4942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPCTL(ep), data); 4952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang __asm__ volatile("dsb sy\n" 4962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang "isb sy\n"); 4972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 4982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang cycle = 0; 4992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang while (1) { 5002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang epints = mmio_read_32(DIEPINT(ep)) & 1; 5012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if ((mmio_read_32(GINTSTS) & 0x40000) && epints) { 5022cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("Tx succ:ep(%d), DTXFSTS(%d) is [0x%x] \n", 5032cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep, ep, mmio_read_32(DTXFSTS(ep))); 5042cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPINT(ep), epints); 5052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (endpoints[ep].busy) { 5062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[ep].busy = 0;//false 5072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[ep].rc = 0; 5082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[ep].done = 1;//true 5092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 5102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 5112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 5122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang cycle++; 5132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang udelay(10); 5142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("loop for intr: ep(%d), DIEPCTL(%d) is [0x%x], ", 5152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang "DTXFSTS(%d) is [0x%x], DIEPINT(%d) is [0x%x] \n", 5162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep, ep, mmio_read_32(DIEPCTL(ep)), 5172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep, mmio_read_32(DTXFSTS(ep)), 5182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep, mmio_read_32(DIEPINT(ep))); 5192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 5202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (cycle > 1000000) { 5212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang WARN("Wait IOC intr over 10s! USB will reset\n"); 5222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_need_reset = 1; 5232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return 1; 5242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 5252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 5262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 5272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang cycle = 0; 5282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang while (1) { 5292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if ((mmio_read_32(DIEPINT(ep)) & 0x2000) || (cycle > 100000)) { 5302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (cycle > 100000){ 5312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang WARN("all wait cycle is [%d]\n",cycle); 5322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 5332cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 5342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 5352cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 5362cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang cycle++; 5372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang udelay(10); 5382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 5392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 5402cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return 0; 5412cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 5422cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 5432cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangint hiusb_epx_rx(unsigned ep, void *buf, unsigned len) 5442cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 5452cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int blocksize = 0, data; 5462cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang int packets; 5472cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 5482cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("ep%d rx, len = 0x%x, buf = 0x%x.\n", ep, len, buf); 5492cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 5502cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[ep].busy = 1;//true 5512cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* EPx UNSTALL */ 5522cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DOEPCTL(ep)) & ~0x00200000; 5532cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPCTL(ep), data); 5542cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* EPx OUT ACTIVE */ 5552cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DOEPCTL(ep)) | 0x8000; 5562cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPCTL(ep), data); 5572cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 5582cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang blocksize = usb_drv_port_speed() ? USB_BLOCK_HIGH_SPEED_SIZE : 64; 5592cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang packets = (len + blocksize - 1) / blocksize; 5602cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 5612cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#define MAX_RX_PACKET 0x3FF 5622cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 5632cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*Max recv packets is 1023*/ 5642cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (packets > MAX_RX_PACKET) { 5652cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[ep].size = MAX_RX_PACKET * blocksize; 5662cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang len = MAX_RX_PACKET * blocksize; 5672cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { 5682cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[ep].size = len; 5692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 5702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 5712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (!len) { 5722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* one empty packet */ 5732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPTSIZ(ep), 1 << 19); 5742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang //NULL /* dummy address */ 5752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.bs = 0x3; 5762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.mtrf = 0; 5772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.sr = 0; 5782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.l = 1; 5792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.ioc = 1; 5802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.sp = 0; 5812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.bytes = 0; 5822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.buf = 0; 5832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.sts = 0; 5842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.bs = 0x0; 5852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 5862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPDMA(ep), (unsigned long)&dma_desc); 5872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { 5882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (len >= blocksize * 64) { 5892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_desc_bytes = blocksize*64; 5902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { 5912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_desc_bytes = len; 5922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 5932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("rx len %d, rx_desc_bytes %d \n",len,rx_desc_bytes); 5942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.bs = 0x3; 5952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.mtrf = 0; 5962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.sr = 0; 5972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.l = 1; 5982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.ioc = 1; 5992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.sp = 0; 6002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.bytes = rx_desc_bytes; 6012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.buf = (unsigned long)buf; 6022cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.sts = 0; 6032cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc.status.b.bs = 0x0; 6042cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPDMA(ep), (unsigned long)&dma_desc); 6062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 6072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* EPx OUT ENABLE CLEARNAK */ 6082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DOEPCTL(ep)); 6092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data |= 0x84000000; 6102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPCTL(ep), data); 6112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return 0; 6122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 6132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangint usb_queue_req(struct usb_endpoint *ept, struct usb_request *req) 6152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 6162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (ept->in) 6172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang hiusb_epx_tx(ept->num, req->buf, req->length); 6182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang else 6192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang hiusb_epx_rx(ept->num, req->buf, req->length); 6202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return 0; 6222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 6232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void rx_cmd(void) 6252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 6262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_request *req = &rx_req; 6272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang req->buf = cmdbuf; 6282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang req->length = RX_REQ_LEN; 6292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang req->complete = usb_rx_cmd_complete; 6302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_queue_req(&ep1out, req); 6312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 6322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6332cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void rx_data(void) 6342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 6352cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_request *req = &rx_req; 6362cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang req->buf = (void *)((unsigned long) rx_addr); 6382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang req->length = rx_length; 6392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang req->complete = usb_rx_data_complete; 6402cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_queue_req(&ep1out, req); 6412cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 6422cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6432cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangvoid tx_status(const char *status) 6442cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 6452cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_request *req = &tx_req; 6462cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang int len = strlen(status); 6472cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6482cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memcpy(req->buf, status, (unsigned int)len); 6492cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang req->length = (unsigned int)len; 6502cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang req->complete = 0; 6512cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_queue_req(&ep1in, req); 6522cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 6532cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6542cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangvoid fastboot_tx_status(const char *status) 6552cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 6562cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang tx_status(status); 6572cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_cmd(); 6582cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 6592cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6602cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangvoid tx_dump_page(const char *ptr, int len) 6612cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 6622cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_request *req = &tx_req; 6632cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6642cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memcpy(req->buf, ptr, (unsigned int)len); 6652cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang req->length = (unsigned int)len; 6662cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang req->complete = 0; 6672cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_queue_req(&ep1in, req); 6682cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 6692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void usb_rx_data_complete(unsigned actual, int status) 6722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 6732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if(status != 0) 6752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return; 6762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if(actual > rx_length) { 6782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang actual = rx_length; 6792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 6802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_addr += actual; 6822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_length -= actual; 6832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if(rx_length > 0) { 6852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_data(); 6862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { 6872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang tx_status("OKAY"); 6882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_cmd(); 6892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 6902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 6912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 6922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void usb_status(unsigned online, unsigned highspeed) 6932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 6942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (online) { 6952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang INFO("usb: online (%s)\n", highspeed ? "highspeed" : "fullspeed"); 6962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_cmd(); 6972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 6982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 6992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 7002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangvoid usb_handle_control_request(setup_packet* req) 7012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 7022cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang const void* addr = NULL; 7032cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang int size = -1; 704b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang int i; 7052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang int maxpacket; 7062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int data; 707b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang char *serialno; 7082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_endpoint_descriptor epx; 7092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_config_bundle const_bundle = { 7102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .config = { 7112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bLength = sizeof(struct usb_config_descriptor), 7122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bDescriptorType = USB_DT_CONFIG, 7132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .wTotalLength = sizeof(struct usb_config_descriptor) + 7142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang sizeof(struct usb_interface_descriptor) + 7152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang sizeof(struct usb_endpoint_descriptor) * 7162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang USB_NUM_ENDPOINTS, 7172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bNumInterfaces = 1, 7182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bConfigurationValue = 1, 7192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .iConfiguration = 0, 7202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bmAttributes = USB_CONFIG_ATT_ONE, 7212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bMaxPower = 0x80 7222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang }, 7232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .interface = { 7242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bLength = sizeof(struct usb_interface_descriptor), 7252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bDescriptorType = USB_DT_INTERFACE, 7262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bInterfaceNumber = 0, 7272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bAlternateSetting = 0, 7282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bNumEndpoints = USB_NUM_ENDPOINTS, 7292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bInterfaceClass = USB_CLASS_VENDOR_SPEC, 7302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bInterfaceSubClass = 0x42, 7312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bInterfaceProtocol = 0x03, 7322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .iInterface = 0 7332cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 7342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang }; 7352cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 7362cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* avoid to hang on accessing unaligned memory */ 7372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_endpoint_descriptor const_ep1 = { 7382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bLength = sizeof(struct usb_endpoint_descriptor), 7392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bDescriptorType = USB_DT_ENDPOINT, 7402cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bEndpointAddress = 0x81, 7412cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bmAttributes = USB_ENDPOINT_XFER_BULK, 7422cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .wMaxPacketSize = 0, 7432cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bInterval = 0 7442cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang }; 7452cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 7462cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_endpoint_descriptor const_ep2 = { 7472cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bLength = sizeof(struct usb_endpoint_descriptor), 7482cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bDescriptorType = USB_DT_ENDPOINT, 7492cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bEndpointAddress = 0x01, 7502cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bmAttributes = USB_ENDPOINT_XFER_BULK, 7512cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .wMaxPacketSize = 0, 7522cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bInterval = 1 7532cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang }; 7542cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 7552cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct usb_device_descriptor const_device = { 7562cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bLength = sizeof(struct usb_device_descriptor), 7572cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bDescriptorType = USB_DT_DEVICE, 7582cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bcdUSB = 0x0200, 7592cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bDeviceClass = 0, 7602cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bDeviceClass = 0, 7612cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bDeviceProtocol = 0, 7622cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bMaxPacketSize0 = 0x40, 7632cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .idVendor = 0x18d1, 7642cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .idProduct = 0xd00d, 7652cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bcdDevice = 0x0100, 7662cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .iManufacturer = 1, 7672cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .iProduct = 2, 7682cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .iSerialNumber = 3, 7692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang .bNumConfigurations = 1 7702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang }; 7712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 7722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memcpy(&config_bundle, &const_bundle, sizeof(struct usb_config_bundle)); 7732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memcpy(&config_bundle.ep1, &const_ep1, sizeof(struct usb_endpoint_descriptor)); 7742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memcpy(&config_bundle.ep2, &const_ep2, sizeof(struct usb_endpoint_descriptor)); 7752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memcpy(&device_descriptor, &const_device, 7762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang sizeof(struct usb_device_descriptor)); 7772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 7782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang switch (req->request) { 7792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case USB_REQ_GET_STATUS: 7802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (req->type == USB_DIR_IN) 7812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ctrl_resp[0] = 1; 7822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang else 7832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ctrl_resp[0] = 0; 7842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ctrl_resp[1] = 0; 7852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang addr = ctrl_resp; 7862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang size = 2; 7872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 7882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 7892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case USB_REQ_CLEAR_FEATURE: 7902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if ((req->type == USB_RECIP_ENDPOINT) && 7912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang (req->value == USB_ENDPOINT_HALT)) 7922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_drv_stall(req->index & 0xf, 0, req->index >> 7); 7932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang size = 0; 7942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 7952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 7962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case USB_REQ_SET_FEATURE: 7972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang size = 0; 7982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 7992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 8002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case USB_REQ_SET_ADDRESS: 8012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang size = 0; 8022cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_drv_cancel_all_transfers(); // all endpoints reset 8032cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_drv_set_address(req->value); // set device address 8042cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 8052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 8062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case USB_REQ_GET_DESCRIPTOR: 8072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("USB_REQ_GET_DESCRIPTOR: 0x%x\n", req->value >> 8); 8082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang switch (req->value >> 8) { 8092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case USB_DT_DEVICE: 8102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang addr = &device_descriptor; 8112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang size = sizeof(device_descriptor); 8122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("Get device descriptor.\n"); 8132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 8142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 8152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case USB_DT_OTHER_SPEED_CONFIG: 8162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case USB_DT_CONFIG: 8172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if ((req->value >> 8) == USB_DT_CONFIG) { 8182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang maxpacket = usb_drv_port_speed() ? USB_BLOCK_HIGH_SPEED_SIZE : 64; 8192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang config_bundle.config.bDescriptorType = USB_DT_CONFIG; 8202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { 8212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang maxpacket = usb_drv_port_speed() ? 64 : USB_BLOCK_HIGH_SPEED_SIZE; 8222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang config_bundle.config.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG; 8232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 8242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* avoid hang when access unaligned structure */ 8252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memcpy(&epx, &config_bundle.ep1, sizeof(struct usb_endpoint_descriptor)); 8262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang epx.wMaxPacketSize = maxpacket; 8272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memcpy(&config_bundle.ep1, &epx, sizeof(struct usb_endpoint_descriptor)); 8282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memcpy(&epx, &config_bundle.ep2, sizeof(struct usb_endpoint_descriptor)); 8292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang epx.wMaxPacketSize = maxpacket; 8302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memcpy(&config_bundle.ep2, &epx, sizeof(struct usb_endpoint_descriptor)); 8312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang addr = &config_bundle; 8322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang size = sizeof(config_bundle); 8332cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("Get config descriptor.\n"); 8342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 8352cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 8362cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case USB_DT_STRING: 8372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang switch (req->value & 0xff) { 8382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case 0: 8392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang addr = &lang_descriptor; 8402cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang size = lang_descriptor.bLength; 8412cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 8422cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case 1: 8432cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang addr = &string_devicename; 8442cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang size = 14; 8452cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 8462cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case 2: 8472cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang addr = &string_devicename; 8482cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang size = string_devicename.bLength; 8492cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 8502cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case 3: 851b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang serialno = load_serialno(); 852b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang if (serialno == NULL) { 853b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang addr = &serial_string_descriptor; 854b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang size = serial_string_descriptor.bLength; 855b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang } else { 856b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang i = 0; 857b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang memcpy((void *)&serial_string, 858b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang (void *)&serial_string_descriptor, 859b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang sizeof(serial_string)); 860b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang while (1) { 861b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang serial_string.wString[i] = serialno[i]; 862b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang if (serialno[i] == '\0') 863b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang break; 864b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang i++; 865b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang } 866b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang addr = &serial_string; 867b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang size = serial_string.bLength; 868b90a668aabe56b07d93b27d9ef914a5d6cbbc41eHaojian Zhuang } 8692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 8702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang default: 8712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 8722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 8732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 8742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 8752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang default: 8762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 8772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 8782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 8792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 8802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case USB_REQ_GET_CONFIGURATION: 8812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ctrl_resp[0] = 1; 8822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang addr = ctrl_resp; 8832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang size = 1; 8842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 8852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 8862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang case USB_REQ_SET_CONFIGURATION: 8872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_drv_cancel_all_transfers(); // call reset_endpoints reset all EPs 8882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 8892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_drv_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_OUT); 8902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_drv_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_IN); 8912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* 8922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * 0x10088800: 8932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * 1:EP enable; 8:EP type:BULK; 8:USB Active Endpoint; 8:Next Endpoint 8942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang */ 8952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DIEPCTL1) | 0x10088800; 8962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPCTL1, data); 8972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DIEPCTL(1)) | 0x08000000; 8982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPCTL(1), data); 8992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 9002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Enable interrupts on all endpoints */ 9012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DAINTMSK, 0xffffffff); 9022cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 9032cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_status(req->value? 1 : 0, usb_drv_port_speed() ? 1 : 0); 9042cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang size = 0; 9052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("Set config descriptor.\n"); 9062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 9072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* USB ö�ٳɹ���,���ϱ�ʶ */ 9082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang g_usb_enum_flag = 1; 9092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 9102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 9112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang default: 9122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 9132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 9142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 9152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (!size) { 9162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_drv_send_nonblocking(0, 0, 0); // send an empty packet 9172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else if (size == -1) { // stall:Applies to non-control, non-isochronous IN and OUT endpoints only. 9182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_drv_stall(0, 1, 1); // IN 9192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_drv_stall(0, 1, 0); // OUT 9202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { // stall:Applies to control endpoints only. 9212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_drv_stall(0, 0, 1); // IN 9222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_drv_stall(0, 0, 0); // OUT 9232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 9242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_drv_send_nonblocking(0, addr, size > req->length ? req->length : size); 9252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 9262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 9272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 9282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang/* IRQ handler */ 9292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void usb_poll(void) 9302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 9312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang uint32_t ints; 9322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang uint32_t epints, data; 9332cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 9342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ints = mmio_read_32(GINTSTS); /* interrupt status */ 9352cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 9362cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 9372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if ((ints & 0xc3010) == 0) 9382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return; 9392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* 9402cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * bus reset 9412cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * The core sets this bit to indicate that a reset is detected on the USB. 9422cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang */ 9432cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (ints & GINTSTS_USBRST) { 9442cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("bus reset intr\n"); 9452cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*set Non-Zero-Length status out handshake */ 9462cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* 9472cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * DCFG:This register configures the core in Device mode after power-on 9482cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * or after certain control commands or enumeration. Do not make changes 9492cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * to this register after initial programming. 9502cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * Send a STALL handshake on a nonzero-length status OUT transaction and 9512cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * do not send the received OUT packet to the application. 9522cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang */ 9532cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DCFG, 0x800004); 9542cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang reset_endpoints(); 9552cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 9562cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* 9572cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * enumeration done, we now know the speed 9582cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * The core sets this bit to indicate that speed enumeration is complete. The 9592cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * application must read the Device Status (DSTS) register to obtain the 9602cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * enumerated speed. 9612cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang */ 9622cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (ints & GINTSTS_ENUMDONE) { 9632cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Set up the maximum packet sizes accordingly */ 9642cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang uint32_t maxpacket = usb_drv_port_speed() ? USB_BLOCK_HIGH_SPEED_SIZE : 64; // high speed maxpacket=512 9652cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("enum done intr. Maxpacket:%d\n", maxpacket); 9662cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang //Set Maximum In Packet Size (MPS) 9672cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DIEPCTL1) & ~0x000003ff; 9682cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPCTL1, data | maxpacket); 9692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang //Set Maximum Out Packet Size (MPS) 9702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DOEPCTL1) & ~0x000003ff; 9712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPCTL1, data | maxpacket); 9722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 9732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 9742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* 9752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * IN EP event 9762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * The core sets this bit to indicate that an interrupt is pending on one of the IN 9772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * endpoints of the core (in Device mode). The application must read the 9782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * Device All Endpoints Interrupt (DAINT) register to determine the exact 9792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * number of the IN endpoint on which the interrupt occurred, and then read 9802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * the corresponding Device IN Endpoint-n Interrupt (DIEPINTn) register to 9812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * determine the exact cause of the interrupt. The application must clear the 9822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * appropriate status bit in the corresponding DIEPINTn register to clear this bit. 9832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang */ 9842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (ints & GINTSTS_IEPINT) { 9852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang epints = mmio_read_32(DIEPINT0); 9862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPINT0, epints); 9872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 9882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang //VERBOSE("IN EP event,ints:0x%x, DIEPINT0:%x, DAINT:%x, DAINTMSK:%x.\n", 9892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang // ints, epints, mmio_read_32(DAINT), mmio_read_32(DAINTMSK)); 9902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (epints & 0x1) { /* Transfer Completed Interrupt (XferCompl) */ 9912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("TX completed.DIEPTSIZ(0) = 0x%x.\n", mmio_read_32(DIEPTSIZ0)); 9922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*FIXME,Maybe you can use bytes*/ 9932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*int bytes = endpoints[0].size - (DIEPTSIZ(0) & 0x3FFFF);*/ //actual transfer 9942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (endpoints[0].busy) { 9952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[0].busy = 0;//false 9962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[0].rc = 0; 9972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[0].done = 1;//true 9982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 9992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 10002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (epints & 0x4) { /* AHB error */ 10012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang WARN("AHB error on IN EP0.\n"); 10022cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 10032cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 10042cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (epints & 0x8) { /* Timeout */ 10052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang WARN("Timeout on IN EP0.\n"); 10062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (endpoints[0].busy) { 10072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[0].busy = 1;//false 10082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[0].rc = 1; 10092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[0].done = 1;//true 10102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 10112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 10122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 10132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 10142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* 10152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * OUT EP event 10162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * The core sets this bit to indicate that an interrupt is pending on one of the 10172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * OUT endpoints of the core (in Device mode). The application must read the 10182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * Device All Endpoints Interrupt (DAINT) register to determine the exact 10192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * number of the OUT endpoint on which the interrupt occurred, and then read 10202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * the corresponding Device OUT Endpoint-n Interrupt (DOEPINTn) register 10212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * to determine the exact cause of the interrupt. The application must clear the 10222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * appropriate status bit in the corresponding DOEPINTn register to clear this bit. 10232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang */ 10242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (ints & GINTSTS_OEPINT) { 10252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* indicates the status of an endpoint 10262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * with respect to USB- and AHB-related events. */ 10272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang epints = mmio_read_32(DOEPINT(0)); 10282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang //VERBOSE("OUT EP event,ints:0x%x, DOEPINT0:%x, DAINT:%x, DAINTMSK:%x.\n", 10292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang // ints, epints, mmio_read_32(DAINT), mmio_read_32(DAINTMSK)); 10302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (epints) { 10312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPINT(0), epints); 10322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Transfer completed */ 10332cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (epints & DXEPINT_XFERCOMPL) { 10342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*FIXME,need use bytes*/ 10352cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("EP0 RX completed. DOEPTSIZ(0) = 0x%x.\n", 10362cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_read_32(DOEPTSIZ(0))); 10372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (endpoints[0].busy) { 10382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[0].busy = 0; 10392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[0].rc = 0; 10402cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[0].done = 1; 10412cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 10422cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 10432cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (epints & DXEPINT_AHBERR) { /* AHB error */ 10442cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang WARN("AHB error on OUT EP0.\n"); 10452cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 10462cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 10472cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* 10482cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * IN Token Received When TxFIFO is Empty (INTknTXFEmp) 10492cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * Indicates that an IN token was received when the associated TxFIFO (periodic/nonperiodic) 10502cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * was empty. This interrupt is asserted on the endpoint for which the IN token 10512cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * was received. 10522cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang */ 10532cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (epints & DXEPINT_SETUP) { /* SETUP phase done */ 10542cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("Setup phase \n"); 10552cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DIEPCTL(0)) | DXEPCTL_SNAK; 10562cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPCTL(0), data); 10572cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(DOEPCTL(0)) | DXEPCTL_SNAK; 10582cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPCTL(0), data); 10592cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*clear IN EP intr*/ 10602cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DIEPINT(0), ~0); 10612cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_handle_control_request((setup_packet *)&ctrl_req); 10622cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 10632cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 10642cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Make sure EP0 OUT is set up to accept the next request */ 10652cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* memset(p_ctrlreq, 0, NUM_ENDPOINTS*8); */ 10662cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = DOEPTSIZ0_SUPCNT(3) | DOEPTSIZ0_PKTCNT | 10672cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang (64 << DOEPTSIZ0_XFERSIZE_SHIFT); 10682cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPTSIZ0, data); 10692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* 10702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * IN Token Received When TxFIFO is Empty (INTknTXFEmp) 10712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * Indicates that an IN token was received when the associated TxFIFO (periodic/nonperiodic) 10722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * was empty. This interrupt is asserted on the endpoint for which the IN token 10732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang * was received. 10742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang */ 10752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang // notes that:the compulsive conversion is expectable. 10762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang // Holds the start address of the external memory for storing or fetching endpoint data. 10772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.bs = 0x3; 10782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.mtrf = 0; 10792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.sr = 0; 10802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.l = 1; 10812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.ioc = 1; 10822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.sp = 0; 10832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.bytes = 64; 10842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.buf = (uintptr_t)&ctrl_req; 10852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.sts = 0; 10862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dma_desc_ep0.status.b.bs = 0x0; 10872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPDMA0, (uintptr_t)&dma_desc_ep0); 10882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang // endpoint enable; clear NAK 10892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPCTL0, 0x84000000); 10902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 10912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 10922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang epints = mmio_read_32(DOEPINT1); 10932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if(epints) { 10942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(DOEPINT1, epints); 10952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("OUT EP1: epints :0x%x,DOEPTSIZ1 :0x%x.\n",epints, mmio_read_32(DOEPTSIZ1)); 10962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* Transfer Completed Interrupt (XferCompl);Transfer completed */ 10972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (epints & DXEPINT_XFERCOMPL) { 10982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* ((readl(DOEPTSIZ(1))) & 0x7FFFF is Transfer Size (XferSize) */ 10992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*int bytes = (p_endpoints + 1)->size - ((readl(DOEPTSIZ(1))) & 0x7FFFF);*/ 11002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang int bytes = rx_desc_bytes - dma_desc.status.b.bytes; 11012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("OUT EP1: recv %d bytes \n",bytes); 11022cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (endpoints[1].busy) { 11032cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[1].busy = 0; 11042cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[1].rc = 0; 11052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang endpoints[1].done = 1; 11062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_req.complete(bytes, 0); 11072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 11082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 11092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (epints & DXEPINT_AHBERR) { /* AHB error */ 11112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang WARN("AHB error on OUT EP1.\n"); 11122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 11132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (epints & DXEPINT_SETUP) { /* SETUP phase done */ 11142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang WARN("SETUP phase done on OUT EP1.\n"); 11152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 11162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 11172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 11182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* write to clear interrupts */ 11192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GINTSTS, ints); 11202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 11212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#define EYE_PATTERN 0x70533483 11232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang/* 11252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang* pico phy exit siddq, nano phy enter siddq, 11262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang* and open the clock of pico phy and dvc, 11272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang*/ 11282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void dvc_and_picophy_init_chip(void) 11292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 11302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned int data; 11312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* enable USB clock */ 113319f72d7f8125d9c6283f8851f7ddc07ea2a7b213Leo Yan mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_USBOTG); 11342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang do { 11352cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); 113619f72d7f8125d9c6283f8851f7ddc07ea2a7b213Leo Yan } while ((data & PERI_CLK0_USBOTG) == 0); 11372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* out of reset */ 11402cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(PERI_SC_PERIPH_RSTDIS0, 114119f72d7f8125d9c6283f8851f7ddc07ea2a7b213Leo Yan PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY | 114219f72d7f8125d9c6283f8851f7ddc07ea2a7b213Leo Yan PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K); 11432cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang do { 11442cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); 114519f72d7f8125d9c6283f8851f7ddc07ea2a7b213Leo Yan data &= PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY | 114619f72d7f8125d9c6283f8851f7ddc07ea2a7b213Leo Yan PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K; 11472cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } while (data); 11482cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11492cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(PERI_SC_PERIPH_CTRL8, EYE_PATTERN); 11502cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11512cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* configure USB PHY */ 11522cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CTRL4); 11532cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* make PHY out of low power mode */ 115419f72d7f8125d9c6283f8851f7ddc07ea2a7b213Leo Yan data &= ~PERI_CTRL4_PICO_SIDDQ; 11552cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* detect VBUS by external circuit, switch D+ to 1.5KOhm pullup */ 115619f72d7f8125d9c6283f8851f7ddc07ea2a7b213Leo Yan data |= PERI_CTRL4_PICO_VBUSVLDEXTSEL | PERI_CTRL4_PICO_VBUSVLDEXT; 115719f72d7f8125d9c6283f8851f7ddc07ea2a7b213Leo Yan data &= ~PERI_CTRL4_FPGA_EXT_PHY_SEL; 11582cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* select PHY */ 115919f72d7f8125d9c6283f8851f7ddc07ea2a7b213Leo Yan data &= ~PERI_CTRL4_OTG_PHY_SEL; 11602cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(PERI_SC_PERIPH_CTRL4, data); 11612cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11622cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang udelay(1000); 11632cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11642cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CTRL5); 116519f72d7f8125d9c6283f8851f7ddc07ea2a7b213Leo Yan data &= ~PERI_CTRL5_PICOPHY_BC_MODE; 11662cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(PERI_SC_PERIPH_CTRL5, data); 1167a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj 11682cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang udelay(20000); 11692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 11702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangint init_usb(void) 11722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 11732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang static int init_flag = 0; 11742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang uint32_t data; 11752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (init_flag == 0) { 11772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memset(&ctrl_req, 0, sizeof(setup_packet)); 11782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memset(&ctrl_resp, 0, 2); 11792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memset(&endpoints, 0, sizeof(struct ep_type) * NUM_ENDPOINTS); 11802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memset(&dma_desc, 0, sizeof(struct dwc_otg_dev_dma_desc)); 11812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memset(&dma_desc_ep0, 0, sizeof(struct dwc_otg_dev_dma_desc)); 11822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang memset(&dma_desc_in, 0, sizeof(struct dwc_otg_dev_dma_desc)); 11832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 11842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("Pico PHY and DVC init start.\n"); 11862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang dvc_and_picophy_init_chip(); 11882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("Pico PHY and DVC init done.\n"); 11892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* wait for OTG AHB master idle */ 11912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang do { 11922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data = mmio_read_32(GRSTCTL) & GRSTCTL_AHBIDLE; 11932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } while (data == 0); 11942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("Reset usb controller\n"); 11952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* OTG: Assert software reset */ 11972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang mmio_write_32(GRSTCTL, GRSTCTL_CSFTRST); 11982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 11992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* wait for OTG to ack reset */ 12002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang while (mmio_read_32(GRSTCTL) & GRSTCTL_CSFTRST); 12012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 12022cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /* wait for OTG AHB master idle */ 12032cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang while ((mmio_read_32(GRSTCTL) & GRSTCTL_AHBIDLE) == 0); 12042cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 12052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("Reset usb controller done\n"); 12062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 12072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_config(); 12082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("exit usb_init()\n"); 12092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return 0; 12102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 12112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 12122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#define LOCK_STATE_LOCKED 0 12132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#define LOCK_STATE_UNLOCKED 1 12142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang#define LOCK_STATE_RELOCKED 2 12152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 12163da0f46f461e4927a67646685552cf096db7aa53Haojian Zhuang#define FB_MAX_FILE_SIZE (256 * 1024 * 1024) 12172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 12182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic struct ptentry *flash_ptn = NULL; 12192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 12202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void fb_getvar(char *cmdbuf) 12212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 12222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang char response[64]; 12232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang char part_name[32]; 12242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang int bytes; 12252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang struct ptentry *ptn = 0; 12262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 12272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (!strncmp(cmdbuf + 7, "max-download-size", 17)) { 12282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang bytes = sprintf(response, "OKAY0x%08x", 12292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang FB_MAX_FILE_SIZE); 12302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang response[bytes] = '\0'; 12312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang tx_status(response); 12322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_cmd(); 12332cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else if (!strncmp(cmdbuf + 7, "partition-type:", 15)) { 12342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang bytes = sprintf(part_name, "%s", cmdbuf + 22); 12352cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ptn = find_ptn(part_name); 12362cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (ptn == NULL) { 12372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang bytes = sprintf(response, "FAIL%s", 12382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang "invalid partition"); 12392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang response[bytes] = '\0'; 12402cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang flash_ptn = NULL; 12412cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { 12422cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang flash_ptn = ptn; 1243a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj if (!strncmp(cmdbuf +22, "system", 6) || !strncmp(cmdbuf +22, "userdata", 8) || 1244a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj !strncmp(cmdbuf +22, "cache", 5)) { 1245a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj bytes = sprintf(response, "OKAYext4"); 1246a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj response[bytes] = '\0'; 1247a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj } else { 1248a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj bytes = sprintf(response, "OKAYraw"); 1249a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj response[bytes] = '\0'; 1250a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj } 12512cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 12522cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang tx_status(response); 12532cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_cmd(); 1254a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj } else if (!strncmp(cmdbuf + 7, "partition-size:", 15)) { 1255a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj bytes = sprintf(part_name, "%s", cmdbuf + 22); 1256a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj ptn = find_ptn(part_name); 1257a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj if (ptn == NULL) { 1258a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj bytes = sprintf(response, "FAIL%s", 1259a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj "invalid partition"); 1260a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj response[bytes] = '\0'; 1261a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj flash_ptn = NULL; 1262a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj } else { 1263a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj bytes = sprintf(response, "OKAY%llx",ptn->length); 1264a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj response[bytes] = '\0'; 1265a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj flash_ptn = ptn; 1266a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj } 1267a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj tx_status(response); 1268a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj rx_cmd(); 1269b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang } else if (!strncmp(cmdbuf + 7, "serialno", 8)) { 1270b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang bytes = sprintf(response, "OKAY%s", 1271b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang load_serialno()); 1272b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang response[bytes] = '\0'; 1273b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang tx_status(response); 1274b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang rx_cmd(); 1275a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj } else if (!strncmp(cmdbuf + 7, "version-bootloader", 18)) { 1276554b28ac1d6a6c75893fb5831107fee464ce581dVishal Bhoj bytes = sprintf(response, "OKAY%s", VERSION_BOOTLOADER); 1277a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj response[bytes] = '\0'; 1278a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj tx_status(response); 1279a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj rx_cmd(); 1280a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj } else if (!strncmp(cmdbuf + 7, "version-baseband", 16)) { 1281a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj bytes = sprintf(response, "OKAYN/A"); 1282a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj response[bytes] = '\0'; 1283a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj tx_status(response); 1284a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj rx_cmd(); 1285a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj } else if (!strncmp(cmdbuf + 7, "product", 8)) { 12862111fbe1ea0a227c52069689221a95de913fc927Dmitry Shmidt bytes = sprintf(response, "OKAYhikey"); 1287a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj response[bytes] = '\0'; 1288a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj tx_status(response); 1289a1d0a7b097cefec3b4bedc8fa2212bdd9a5033f7Vishal Bhoj rx_cmd(); 12902190a7195ed2aed0d52958d92e3c405bc4245112John Stultz } else { 12912190a7195ed2aed0d52958d92e3c405bc4245112John Stultz bytes = sprintf(response, "FAIL%s", 12922190a7195ed2aed0d52958d92e3c405bc4245112John Stultz "unknown var"); 12932190a7195ed2aed0d52958d92e3c405bc4245112John Stultz response[bytes] = '\0'; 12942190a7195ed2aed0d52958d92e3c405bc4245112John Stultz tx_status(response); 12952190a7195ed2aed0d52958d92e3c405bc4245112John Stultz rx_cmd(); 12962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 12972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 12982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 12992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang/* FIXME: do not support endptr yet */ 13002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic unsigned long strtoul(const char *nptr, char **endptr, int base) 13012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 13022cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang unsigned long step, data; 13032cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang int i; 13042cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 13052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (base == 0) 13062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang step = 10; 13072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang else if ((base < 2) || (base > 36)) { 13082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("%s: invalid base %d\n", __func__, base); 13092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return 0; 13102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else 13112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang step = base; 13122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 13132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang for (i = 0, data = 0; ; i++) { 13142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (nptr[i] == '\0') 13152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang break; 13162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang else if (!isalpha(nptr[i]) && !isdigit(nptr[i])) { 13172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("%s: invalid string %s at %d [%x]\n", 13182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang __func__, nptr, i, nptr[i]); 13192cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return 0; 13202cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { 13212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data *= step; 13222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (isupper(nptr[i])) 13232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data += nptr[i] - 'A' + 10; 13242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang else if (islower(nptr[i])) 13252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data += nptr[i] - 'a' + 10; 13262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang else if (isdigit(nptr[i])) 13272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang data += nptr[i] - '0'; 13282cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 13292cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 13302cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return data; 13312cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 13322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 13338a372351b7c5794c05e4a69bf1fae35b8c110fcbHaojian Zhuangstatic void fb_serialno(char *cmdbuf) 13348a372351b7c5794c05e4a69bf1fae35b8c110fcbHaojian Zhuang{ 13358a372351b7c5794c05e4a69bf1fae35b8c110fcbHaojian Zhuang struct random_serial_num random; 13368a372351b7c5794c05e4a69bf1fae35b8c110fcbHaojian Zhuang 13378a372351b7c5794c05e4a69bf1fae35b8c110fcbHaojian Zhuang generate_serialno(&random); 13388a372351b7c5794c05e4a69bf1fae35b8c110fcbHaojian Zhuang flush_random_serialno((unsigned long)&random, sizeof(random)); 13398a372351b7c5794c05e4a69bf1fae35b8c110fcbHaojian Zhuang} 13408a372351b7c5794c05e4a69bf1fae35b8c110fcbHaojian Zhuang 1341b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuangstatic int fb_assigned_sn(char *cmdbuf) 1342b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang{ 1343b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang struct random_serial_num random; 1344b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang int ret; 1345b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang 1346b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang ret = assign_serialno(cmdbuf, &random); 1347b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang if (ret < 0) 1348b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang return ret; 1349b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang flush_random_serialno((unsigned long)&random, sizeof(random)); 1350b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang return 0; 1351b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang} 1352b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang 13533da0f46f461e4927a67646685552cf096db7aa53Haojian Zhuang#define FB_DOWNLOAD_BASE 0x20000000 13542cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 13552cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic unsigned long fb_download_base, fb_download_size; 13562cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 13572cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void fb_download(char *cmdbuf) 13582cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 13592cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang char response[64]; 13602cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang int bytes; 13612cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 13622cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (!flash_ptn) { 13632cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang bytes = sprintf(response, "FAIL%s", 13642cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang "invalid partition"); 13652cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang response[bytes] = '\0'; 13662cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang tx_status(response); 13672cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_cmd(); 13682cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { 13692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_addr = FB_DOWNLOAD_BASE; 13702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_length = strtoul(cmdbuf + 9, NULL, 16); 13712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang fb_download_base = rx_addr; 13722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang fb_download_size = rx_length; 13732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (rx_length > FB_MAX_FILE_SIZE) { 13742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang bytes = sprintf(response, "FAIL%s", 13752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang "file is too large"); 13762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang response[bytes] = '\0'; 13772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang tx_status(response); 13782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_cmd(); 13792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else { 13802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang bytes = sprintf(response, "DATA%08x", 13812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_length); 13822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("start:0x%x, length:0x%x, res:%s\n", 13832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_addr, rx_length, response); 13842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang response[bytes] = '\0'; 13852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang tx_status(response); 13862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_data(); 13872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 13882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 13892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 13902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 13912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void fb_flash(char *cmdbuf) 13922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 13932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang flush_user_images(cmdbuf + 6, fb_download_base, fb_download_size); 13942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang tx_status("OKAY"); 13952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_cmd(); 13962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 13972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 13987a0e1dd0f7ad4ba3137dcba1ca833502c535d7b8Haojian Zhuangstatic void fb_reboot(char *cmdbuf) 13997a0e1dd0f7ad4ba3137dcba1ca833502c535d7b8Haojian Zhuang{ 14007a0e1dd0f7ad4ba3137dcba1ca833502c535d7b8Haojian Zhuang /* Send the system reset request */ 14017a0e1dd0f7ad4ba3137dcba1ca833502c535d7b8Haojian Zhuang mmio_write_32(AO_SC_SYS_STAT0, 0x48698284); 14027a0e1dd0f7ad4ba3137dcba1ca833502c535d7b8Haojian Zhuang 14037a0e1dd0f7ad4ba3137dcba1ca833502c535d7b8Haojian Zhuang wfi(); 14047a0e1dd0f7ad4ba3137dcba1ca833502c535d7b8Haojian Zhuang panic(); 14057a0e1dd0f7ad4ba3137dcba1ca833502c535d7b8Haojian Zhuang} 14067a0e1dd0f7ad4ba3137dcba1ca833502c535d7b8Haojian Zhuang 14072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void usb_rx_cmd_complete(unsigned actual, int stat) 14082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 14092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if(stat != 0) return; 14102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 14112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if(actual > 4095) 14122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang actual = 4095; 14132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang cmdbuf[actual] = 0; 14142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 14152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang INFO("cmd :%s\n",cmdbuf); 14162cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 14172cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if(memcmp(cmdbuf, (void *)"reboot", 6) == 0) { 14182cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang tx_status("OKAY"); 14197a0e1dd0f7ad4ba3137dcba1ca833502c535d7b8Haojian Zhuang fb_reboot(cmdbuf); 14207a0e1dd0f7ad4ba3137dcba1ca833502c535d7b8Haojian Zhuang return; 14212cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else if (!memcmp(cmdbuf, (void *)"getvar:", 7)) { 14222cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang fb_getvar(cmdbuf); 14232cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return; 14242cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else if (!memcmp(cmdbuf, (void *)"download:", 9)) { 14252cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang fb_download(cmdbuf); 14262cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return; 14272cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else if(memcmp(cmdbuf, (void *)"erase:", 6) == 0) { 14287f58aa36c7b4215c289f4e7e1ff2175462dfb601Vishal Bhoj /* FIXME erase is not supported but we return success */ 14297f58aa36c7b4215c289f4e7e1ff2175462dfb601Vishal Bhoj tx_status("OKAY"); 14307f58aa36c7b4215c289f4e7e1ff2175462dfb601Vishal Bhoj rx_cmd(); 14317f58aa36c7b4215c289f4e7e1ff2175462dfb601Vishal Bhoj return; 14322cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else if(memcmp(cmdbuf, (void *)"flash:", 6) == 0) { 14332cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang INFO("recog updatefile\n"); 14342cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang fb_flash(cmdbuf); 14352cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return; 14362cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } else if(memcmp(cmdbuf, (void *)"boot", 4) == 0) { 14372cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang INFO(" - OKAY\n"); 14382cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 14392cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang return; 14408a372351b7c5794c05e4a69bf1fae35b8c110fcbHaojian Zhuang } else if (memcmp(cmdbuf, (void *)"oem serialno", 12) == 0) { 1441b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang if (*(cmdbuf + 12) == '\0') { 1442b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang fb_serialno(cmdbuf); 1443b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang tx_status("OKAY"); 1444b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang rx_cmd(); 1445b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang return; 1446b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang } else if (memcmp(cmdbuf + 12, (void *)" set", 4) == 0) { 1447b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang if (fb_assigned_sn(cmdbuf + 16) == 0) { 1448b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang tx_status("OKAY"); 1449b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang rx_cmd(); 1450b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang return; 1451b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang } 1452b85b3f3717ec3b0af0a2e992f01d533e31e90803Haojian Zhuang } 145359fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang } else if (memcmp(cmdbuf, (void *)"oem led", 7) == 0) { 145459fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang if ((*(cmdbuf + 7) >= '1') && (*(cmdbuf + 7) <= '4')) { 145559fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang int led; 145659fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang led = *(cmdbuf + 7) - '0'; 145759fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang if (memcmp(cmdbuf + 8, (void *)" on", 3) == 0) { 145859fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang gpio_set_value(31 + led, 1); 145959fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang tx_status("OKAY"); 146059fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang rx_cmd(); 146159fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang return; 146259fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang } else if (memcmp(cmdbuf + 8, (void *)" off", 4) == 0) { 146359fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang gpio_set_value(31 + led, 0); 146459fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang tx_status("OKAY"); 146559fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang rx_cmd(); 146659fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang return; 146759fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang } 146859fe132c49f99af8ef1969f13a94ba850e72b6a5Haojian Zhuang } 14692cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 14702cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 14712cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang tx_status("FAILinvalid command"); 14722cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang rx_cmd(); 14732cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 14742cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 14752cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangstatic void usbloader_init(void) 14762cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 14772cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("enter usbloader_init\n"); 14782cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 14792cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*usb sw and hw init*/ 14802cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang init_usb(); 14812cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 14822cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang /*alloc and init sth for transfer*/ 14832cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep1in.num = BULK_IN_EP; 14842cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep1in.in = 1; 14852cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep1in.req = NULL; 14862cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep1in.maxpkt = MAX_PACKET_LEN; 14872cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep1in.next = &ep1in; 14882cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep1out.num = BULK_OUT_EP; 14892cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep1out.in = 0; 14902cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep1out.req = NULL; 14912cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep1out.maxpkt = MAX_PACKET_LEN; 14922cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang ep1out.next = &ep1out; 14932cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang cmdbuf = (char *)(rx_req.buf); 14942cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 14952cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang VERBOSE("exit usbloader_init\n"); 14962cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 14972cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 14982cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangvoid usb_reinit() 14992cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 15002cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang if (usb_need_reset) 15012cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang { 15022cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_need_reset = 0; 15032cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang init_usb(); 15042cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 15052cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 15062cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang 15072cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuangvoid usb_download(void) 15082cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang{ 15092cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usbloader_init(); 15102cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang INFO("Enter downloading mode. Please run fastboot command on Host.\n"); 15112cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang for (;;) { 15122cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_poll(); 15132cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang usb_reinit(); 15142cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang } 15152cb2f7e3b5aa150d70afc5fcf574265c68491063Haojian Zhuang} 1516