zte's code,first commit
Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/boot/common/src/loader/drivers/Makefile b/boot/common/src/loader/drivers/Makefile
new file mode 100755
index 0000000..c07fefa
--- /dev/null
+++ b/boot/common/src/loader/drivers/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+# CFLAGS += -DET_DEBUG -DDEBUG
+
+LIB = libdrivers.a
+OBJS = ddr.o uart.o dwc_otg_cil.o dwc_otg_cil_intr.o dwc_otg_dev_test.o \
+ dwc_otg_pcd.o dwc_otg_pcd_intr.o global.o \
+ download.o drv_hash.o drv_rsa.o \
+ flash.o image.o efuse.o secure_verify.o
+
+ifeq ($(strip $(board)),$(filter $(board),mdl_mini mifi_mini mifi_mini_xr819 ufi_mini mifi_mini_64 mdl_mini_64))
+OBJS += nor.o
+else
+OBJS += bbt.o spifc.o
+endif
+
+
+all: $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+sinclude .depend
+
+#########################################################################
diff --git a/boot/common/src/loader/drivers/bbt.c b/boot/common/src/loader/drivers/bbt.c
new file mode 100755
index 0000000..7c34949
--- /dev/null
+++ b/boot/common/src/loader/drivers/bbt.c
@@ -0,0 +1,249 @@
+/*
+ * (C) Copyright 2016 ZXIC Inc.
+ */
+
+
+#include <common.h>
+#include <asm/io.h>
+#include <bbt.h>
+#include "config.h"
+#include "flash.h"
+
+
+static uint8_t block_bad_table[BBT_SIZE]={0};
+
+
+static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
+static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
+
+static struct nand_bbt_descr bbt_main_descr = {
+ .offs = 4,
+ .len = 4,
+ .veroffs = 20,
+ .maxblocks = 16,
+ .pattern = bbt_pattern,
+};
+
+static struct nand_bbt_descr bbt_mirror_descr = {
+ .offs = 4,
+ .len = 4,
+ .veroffs = 20,
+ .maxblocks = 16,
+ .pattern = mirror_pattern,
+};
+
+static int nand_check_pattern(uint8_t *buf,struct nand_bbt_descr *td)
+{
+ int i;
+ uint8_t *p = buf;
+ p += td->offs;
+
+ /* Compare the pattern */
+ for (i = 0; i < td->len; i++)
+ {
+ if (p[i] != td->pattern[i])
+ return -1;
+ }
+
+ return 0;
+}
+
+void nand_creat_ram_bbt( void )
+{
+ uint32_t i = 0;
+ uint32_t off = 0;
+ uint32_t oob_size = flash.oob_size;
+ uint32_t block_size = flash.block_size;
+ uint8_t oob[256]; /* ÕâÀﶨÒå×î´óµÄOOB SIZE */
+#ifdef CONFIG_ZX297520V3E_MDL_AB
+ uint32_t block_nums = 72;
+#else
+ uint32_t block_nums = 17;
+#endif
+
+ for( i=0; i<block_nums; i++ )
+ {
+ flash.read_oob(&oob[0], off, oob_size);
+ if(oob[0] != 0xff) /* bad block */
+ block_bad_table[i] = BAD_BLOCK;
+ else
+ block_bad_table[i] = 0x0;
+
+ off += block_size;
+ }
+}
+
+
+int nand_search_bbt(struct nand_bbt_descr *td)
+{
+
+ int startblock, block;
+ int blocktopage = flash.block_size_shift - flash.page_size_shift;
+
+ uint8_t oob_buffer[256]={0xFF};
+ uint32_t offs = 0;
+
+ /* Search direction down -> top */
+ startblock = flash.block_num -1;
+
+ td->page= -1;
+ /* Scan the maximum number of blocks */
+ for (block = 0; block < td->maxblocks; block++)
+ {
+
+ int actblock = startblock -block;
+ offs = actblock << flash.block_size_shift;
+
+ /* Read first page */
+ flash.read_oob(oob_buffer, offs, flash.oob_size);
+ if (!nand_check_pattern(oob_buffer,td))
+ {
+ td->page = actblock << blocktopage;
+ td->version= oob_buffer[td->veroffs];
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+static int nand_read_bbt(struct nand_bbt_descr *td,int num)
+{
+ int bits=2;
+
+ int res, i, j, act = 0;
+ int totlen;
+ int from;
+ uint8_t msk = (uint8_t) ((1 << bits) - 1);
+ totlen = (num * bits) >> 3;
+ from =(td->page)<<(flash.page_size_shift);
+ char* buf;
+
+
+ res = flash.read_page_raw(CFG_TEMP_ADDR, from);
+ if (res < 0)
+ {
+ return -1;
+ }
+
+ buf =(char*) CFG_TEMP_ADDR;
+
+
+ /* Analyse data */
+ for (i = 0; i < totlen; i++)
+ {
+ uint8_t dat = buf[i];
+ for (j = 0; j < 8; j += bits, act += 2)
+ {
+ uint8_t tmp = (dat >> j) & msk;
+ if (tmp == msk)
+ {
+ block_bad_table[(act >> 1)]= 0X0;
+ continue;
+ }
+ else
+ {
+ block_bad_table[(act >> 1)]= BAD_BLOCK;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+static void nand_init_bbt_descr(struct nand_bbt_descr *td,
+ struct nand_bbt_descr *md)
+{
+ switch(flash.manuf_id)
+ {
+ case NAND_MFR_PARAGON:
+ if(flash.device_id != NAND_DEVID_FDANWEI_1G)
+ {
+ td->offs = BBT_INFO_OOB_OFFSET_PARAGON;
+ md->offs = BBT_INFO_OOB_OFFSET_PARAGON;
+ td->veroffs = BBT_INFO_OOB_VER_OFFSET_PARAGON;
+ md->veroffs = BBT_INFO_OOB_VER_OFFSET_PARAGON;
+ }
+ break;
+ case NAND_MFR_HEYANGTEK:
+ td->offs = BBT_INFO_OOB_OFFSET_HEYANGTEK;
+ md->offs = BBT_INFO_OOB_OFFSET_HEYANGTEK;
+ td->veroffs = BBT_INFO_OOB_VER_OFFSET_HEYANGTEK;
+ md->veroffs =BBT_INFO_OOB_VER_OFFSET_HEYANGTEK;
+ break;
+ default:
+ break;
+ }
+}
+
+int nand_creat_bbt( void )
+{
+ struct nand_bbt_descr *td = &bbt_main_descr;
+ struct nand_bbt_descr *md = &bbt_mirror_descr;
+
+ nand_init_bbt_descr(td, md);
+
+ // 2.0 search main bbt
+ nand_search_bbt(td);
+ // 2.1 search mirror bbt
+ nand_search_bbt(md);
+
+ if(td->page==-1&&md->page ==-1)
+ {
+ /* if failed found bbt, we create a ram bbt */
+ nand_creat_ram_bbt();
+ return 0;
+ }
+
+ // 3.0 read and analyze bbt
+ if(td->page==-1)
+ {
+ nand_read_bbt(md,BBT_SIZE);
+ }
+ else
+ {
+ if(md->page == -1)
+ {
+ nand_read_bbt(td,BBT_SIZE);
+ }
+ else
+ {
+ if(td->version >= md->version)
+ {
+ nand_read_bbt(td,BBT_SIZE);
+ }
+ else
+ {
+ nand_read_bbt(md,BBT_SIZE);
+ }
+ }
+ }
+ printf("bbt ok.\n");
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+uint32_t nand_block_isbad(uint32_t offset)
+{
+ uint32_t block_offset = offset >> (flash.block_size_shift);
+ return block_bad_table[block_offset];
+}
+
+
+
diff --git a/boot/common/src/loader/drivers/config.h b/boot/common/src/loader/drivers/config.h
new file mode 100644
index 0000000..f40e927
--- /dev/null
+++ b/boot/common/src/loader/drivers/config.h
@@ -0,0 +1,96 @@
+/*******************************************************************************
+* °æÈ¨ËùÓÐ (C)2010, ÉîÛÚÊÐÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
+*
+* ÎļþÃû³Æ£º config.h
+* Îļþ±êʶ£º /include/config.h
+* ÄÚÈÝÕªÒª£º ÒýÈ뿪·¢°åµÄÅäÖÃÎļþ
+* ÆäËü˵Ã÷£º
+* µ±Ç°°æ±¾£º 1.0
+* ×÷¡¡¡¡Õߣº ÎÌÔÆ·å
+* Íê³ÉÈÕÆÚ£º 2010-9-30
+*
+*
+*******************************************************************************/
+#ifndef __INCLUDE_CONFIG_H_
+#define __INCLUDE_CONFIG_H_
+/*********************************************************************************
+1:open 0:close
+* ¹¦ÄÜ SIM_EN USE_ASIC SYNC_USB_CTRL SYNC_USB_HSIC SYNC_SETADDRESS
+* FPGA 1 0 0 0 0
+* usb_ctrlÑéÖ¤ 0 1 1 1 1
+* usb_hsicÑéÖ¤ 0 1 1 1 1
+* usbtimeoutÑéÖ¤0 1 1 1 1
+* asic 1 1 0 0 0
+**********************************************************************************/
+#define SIM_EN 1
+#define USE_ASIC 1
+#define SYNC_USB_CTRL 0
+#define SYNC_USB_HSIC 0
+#define SYNC_SETADDRESS 0
+
+#if !USE_ASIC ///0:fpga 1:asic
+// CPUʱÖÓÆµÂÊ
+#define SYS_CPU_FREQ 50000000 // ¶¨ÒåCPUʱÖÓ,ÓÃÓÚ¼ÆÊ±
+#define SYS_UART_CLK 25000000 // ʱÖÓÆµÂÊ
+#define SYS_UART_CLK_CONFIG_PLL 25000000 // ʱÖÓÆµÂÊ
+#else
+// CPUʱÖÓÆµÂÊ
+#define SYS_CPU_FREQ 208000000 // ¶¨ÒåCPUʱÖÓ,ÓÃÓÚ¼ÆÊ±
+#define SYS_UART_CLK (26000000/6) // ʱÖÓÆµÂÊ
+#define SYS_UART_CLK_CONFIG_PLL 104000000 // ʱÖÓÆµÂÊ
+#define ZX_TOP_CRM_BASE 0x0013B000
+#define ZX_SOC_SYS_BASE 0x00140000
+
+#endif
+// Æô¶¯Ä£Ê½Ñ¡Ôñ¼Ä´æÆ÷
+#define SYS_BOOTSEL_BASE 0x0013b004 // ¶¨ÒåBOOTSEL¼Ä´æÆ÷µØÖ·
+
+#define SOC_CRM_BASE (0x0010c000)
+#define BOOT_SEL (0x3c)
+#define NAND_CFG (0x34)
+#define SOC_MOD_CLKEN0 ZX_TOP_CRM_BASE+0x6c
+#define SOC_MOD_CLKEN1 ZX_TOP_CRM_BASE+0x6c
+#define SOC_MOD_RSTEN ZX_TOP_CRM_BASE + 0x80
+#define SOC_MOD_USBSTATECTRL ZX_TOP_CRM_BASE + 0x84
+#define SOC_MOD_RSTEN1 (0x0010c064)
+
+#define CFG_STACK_TOP 0x0008AFE0 // ¶¨ÒåÁËÕ»¶¥
+
+// UART ²ÎÊý
+#define SYS_UART_BASE 0x00102000 // »ùµØÖ·
+//#define SYS_UART_CLK 25000000 // ʱÖÓÆµÂÊ
+#define CFG_UART_BAUDRATE 115200 // ²¨ÌØÂÊ
+#define CFG_BUF_SIZE 64 // Êý¾Ý»º³åÇø´óС
+#if !USE_ASIC
+// USB ²ÎÊý
+#define SYS_USB_BASE 0x01500000 // »ùµØÖ·
+#define SYS_USB_HSIC_BASE 0x01600000 // »ùµØÖ·
+#else
+#define SYS_USB_BASE 0x01500000 // »ùµØÖ·
+#define SYS_USB_HSIC_BASE 0x01600000 // »ùµØÖ·
+#endif
+
+
+// NAND FLASH ²ÎÊý
+#define SYS_NAND_BASE 0x01207000 // ¼Ä´æÆ÷»ùµØÖ·
+#define SYS_NAND_DATA 0x01208000 // Êý¾Ý»ùµØÖ·
+
+// ͨÓòÎÊý
+#define CFG_LOAD_BASE 0x0008B000 // ¼ÓÔØ´úÂëµ½¸ÃµØÖ·,±ØÐë4K¶ÔÆë
+#define SYS_LOAD_LEN 0x1000 // ¼ÓÔØ³¤¶È
+#define CFG_PRINT_BUF_SIZE 256
+
+#define POWER_DOMAIN_ISO ZX_SOC_SYS_BASE+0x110
+#define POWER_DOMAIN_POWERON ZX_SOC_SYS_BASE+0x114
+#define POWER_DOMAIN_RST ZX_SOC_SYS_BASE+0x10C
+
+//ÑéÖ¤ÐèÒª
+#if SYNC_USB_CTRL
+#define ARM_PORTA (0x102040)
+#endif
+
+#if SYNC_USB_HSIC
+#define REG_GPIO_OUT 0x01400014
+#define REG_GPIO_IN 0x01409020
+#endif
+#endif
diff --git a/boot/common/src/loader/drivers/ddr.c b/boot/common/src/loader/drivers/ddr.c
new file mode 100644
index 0000000..0bcec12
--- /dev/null
+++ b/boot/common/src/loader/drivers/ddr.c
@@ -0,0 +1,811 @@
+/*
+ * ddr.c
+ *
+ * Copyright(c) 2016 ZXIC Inc. All rights reserved.
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <board.h>
+#include <ddr.h>
+#include <asm/arch/top_clock.h>
+
+#define _DDR_BYPASS_MODE 1 //1//1: 312m; 0:400m
+#if !_DDR_BYPASS_MODE
+#define _DDR_DS_48om
+#endif
+
+#define _DDR32M_BYPASS_MODE 0 //1//1: 312m; 0:400m
+#if !_DDR32M_BYPASS_MODE
+//#define _DDR32M_DS_48om //-40du 48ohm has problem,modify to 60ohm
+#endif
+/*****************************************
+ * Routine: nsdelay
+ * Description: Configure DDR
+ *****************************************/
+
+void nsdelay(volatile int count)
+{
+ volatile int cnt = 0;
+
+ while(cnt<count)
+ {
+ cnt++;
+ }
+ return;
+}
+
+
+/*****************************************
+ * Routine: ddr_init
+ * Description: Configure DDR
+ *****************************************/
+#ifdef DDR_FFC
+static UINT32 g_PhyReg[DDR_CLKEND][4]={0};//g_PhyReg[N][0]~PHY_PHYREGN[N][3]·Ö±ð´æ´¢PHYREGFB~FE
+
+void pow_DdrClkConfig(T_zDrvPow_DDRCLK clock_value)
+{
+ UINT32 rdata;
+
+ if(clock_value>=DDR_CLKEND)
+ return;
+
+ rdata = __REG(MOD_CLK_SEL)&0xfffffffc;
+ switch (clock_value)
+ {
+ //DDR top clock select, bit0-1, 0=156, 1=200, 2=104, 3=78
+ case DDR_156M:
+ {
+ __REG(MOD_CLK_SEL) = rdata|3;
+ break;
+ }
+ case DDR_208M:
+ {
+ __REG(MOD_CLK_SEL) = rdata|2;
+ break;
+ }
+ case DDR_312M:
+ {
+ __REG(MOD_CLK_SEL) = rdata|0;
+ break;
+ }
+ case DDR_400M:
+ {
+ __REG(MOD_CLK_SEL) = rdata|1;
+ break;
+ }
+ default:
+ break;
+ }
+
+}
+
+void pow_DdrFreqDivFactorConfig(T_zDrvPow_DDRCLK clock_value)
+{
+ if(clock_value>=DDR_CLKEND)
+ return;
+
+ //pow_DdrPllPowerdown();
+
+ __REG(DDR_PHY_BASE+0x3b0) =0;
+ __REG(DDR_PHY_BASE+0x3b4) &= ~0x1;//fbdiv[8]=0
+ __REG(DDR_PHY_BASE+0x3b8) =0;
+
+ /******************************************
+ Fclk4x = Fref ¡Á N ¡Â M ¡Â P
+ 0x013043b0:bit7~0--fbdiv[7:0]
+ 0x013043b4:bit4--PLL clock out enable,
+ bit1--PLL power down enable
+ bit0--fbdiv[8]
+ 0x013043b8:bit7~5--postdiv,
+ bit4~0--prediv
+ N=fbdiv[8:0]
+ M=prediv[4:0]
+ P=2^postdiv[2:0];
+
+ fref N M P
+ 10~20m 64 1 16
+ 21~50M 32 1 8
+ 51~100M 32 2 4
+ 101~200M 16 2 2
+ 201~400M 16 4 1
+ ******************************************/
+ switch (clock_value)
+ {
+ case DDR_156M://Fref=78m
+ {
+ __REG(DDR_PHY_BASE+0x3b0) =32 ;//N=fbdiv[7:0]=32
+ __REG(DDR_PHY_BASE+0x3b8) =(2<<5)|(2<<0) ;//postdiv=2; M=prediv=2
+ break;
+ }
+ case DDR_208M:////Fref=104m
+ {
+ __REG(DDR_PHY_BASE+0x3b0) =16 ;//N=fbdiv[7:0]=16
+ __REG(DDR_PHY_BASE+0x3b8) =(1<<5)|(2<<0) ;//postdiv=1; M=prediv=2
+ break;
+ }
+ case DDR_312M://Fref=156m
+ {
+ __REG(DDR_PHY_BASE+0x3b0) =16 ;//N=fbdiv[7:0]=16
+ __REG(DDR_PHY_BASE+0x3b8) =(1<<5)|(2<<0) ;//postdiv=1; M=prediv=2
+ break;
+ }
+ case DDR_400M://Fref=200m
+ {
+ __REG(DDR_PHY_BASE+0x3b0) =16 ;//N=fbdiv[7:0]=16
+ __REG(DDR_PHY_BASE+0x3b8) =(1<<5)|(2<<0) ;//postdiv=0; M=prediv=4
+ break;
+ }
+ default:
+ break;
+ }
+
+ //pow_DdrPllPoweron();
+
+}
+
+
+void pow_DdrPllDllLock(void)
+{
+
+ //ʹÄÜÁË0x00146000+0x4c*4µÄbit7£¬Ôò½øÈí¼þ×Ôˢкópll»ápowerdown£¬lockÐźÅûÓÐÁË
+ //Í˳ö×ÔˢкóÓ²¼þ»á×Ô¶¯´¥·¢pll lock£¬Èí¼þÖ»ÐèÒªµÈlockÐźÅ
+ //wait phy pll lock
+ while((__REG(DDR_PHY_BASE + 0x3e0)&0x1)!=0x1);
+ //start dll init ,ϽµÑØ´¥·¢
+ __REG(DDR_PHY_BASE + 0x17c) = 0x2a;
+ __REG(DDR_PHY_BASE + 0x17c) = 0xa;
+ nsdelay(2);
+ //wait phy dll lock,phy init done,
+ while((__REG(DDR_PHY_BASE + 0x3e0)&0x3)!=0x3);
+}
+
+void pow_DdrTraining(T_zDrvPow_DDRCLK clock_value)
+{
+ //phy DQS gate training start
+ __REG(DDR_PHY_BASE+0x02*4)=0x1;;
+ nsdelay(1);
+ //Ñ»·¼ì²âtraining over
+ while( (__REG(DDR_PHY_BASE+ 0xff*4)&0xf) != 0xf);
+
+ g_PhyReg[clock_value][0]=__REG(DDR_PHY_BASE+0xfb*4);
+ g_PhyReg[clock_value][1]=__REG(DDR_PHY_BASE+0xfc*4);
+ g_PhyReg[clock_value][2]=__REG(DDR_PHY_BASE+0xfd*4);
+ g_PhyReg[clock_value][3]=__REG(DDR_PHY_BASE+0xfe*4);
+
+ //phy DQS gate training stop
+ __REG(DDR_PHY_BASE+0x02*4)=0x0;
+}
+
+
+/*******************************************************************************
+* Function:pow_DdrChangeClk
+* Description:
+* Parameters:
+* Input:
+*
+* Output:
+*
+* Returns:
+*
+*
+* Others:
+********************************************************************************/
+void pow_DdrChangeClk(T_zDrvPow_DDRCLK clock_value)
+{
+
+ /* PWRCTL[5].selfref_sw=1, ʹ¿ØÖÆÆ÷½øÈëÈí¼þ×ÔË¢ÐÂģʽ*/
+ __REG(CRTL_PWRCTL) |= (1<<SELFREF_SW);
+
+ /*Ñ»·¼ì²âÖ±µ½STAT[2:0]==3'b011ÇÒSTAT[5:4]==2'b10£¬DDR´¦ÓÚÈí¼þ×ÔË¢ÐÂ״̬*/
+ while( (__REG(CTRL_STAT) & 0x37 ) !=0x23);
+
+ //ÅäÖÃϵͳCRM½øÐÐʱÖÓÇл»
+ pow_DdrClkConfig(clock_value);
+
+ //¸ù¾ÝƵÂÊÅäÖÃPHY PLLÄ¿±êƵµãµÄ·ÖƵϵÊý
+ pow_DdrFreqDivFactorConfig(clock_value);
+
+
+ //Ö»¹ØÊ±ÖÓ/ÇÐÆµ²»¶Ïµç£¬½øÈëÈí¼þ×ÔˢУ¬phy½øÉî˯Ãߣ¬pll»á¹Ø±Õ£¬
+ //Í˳öʱ»á×Ô¶¯´ò¿ªÆÚ¼ä²»ÓöÔpll½øÐпª¹Ø,ÒªµÈpll/dll lock,
+ pow_DdrPllDllLock();
+
+ //Éϵç³õʼ»¯½øÐÐÇÐÆµtrainingѵÁ·Ê±£¬
+ //ÔòÅäÖüĴæÆ÷PHYREG02[0]=1£¬â§·¢dqs gate training¡£
+ //È»ºóÑ»·¶ÁÈ¡PHYREGFF£¬Ö±µ½bit[3:0]Ϊ0xf£¬training¹ý³ÌÍê³É£¬
+ //¼Ç¼¼Ä´æÆ÷PHYREGFB~FEµÄÖµ
+
+ /* PWRCTL[5].selfref_sw=0, ʹ¿ØÖÆÆ÷Í˳öÈí¼þ×ÔË¢ÐÂģʽ*/
+ __REG(CRTL_PWRCTL) &= ~(1<<SELFREF_SW);
+
+ /* Ñ»·¼ì²âÖ±µ½STAT[2:0]==3'b001ÇÒSTAT[5:4]==2'b00£¬DDRÍ˳öÈí¼þ×ÔˢУ¬´¦ÓÚnormal״̬*/
+ while( (__REG(CTRL_STAT) & 0x37 ) !=0x1);
+ /*traning*/
+ pow_DdrTraining(clock_value);
+
+
+}
+
+
+void save_ddr_training(UINT32 count, T_zDrvPow_DDRCLK clock_value)
+{
+ __REG(DDR_FFC_ADDR_BASE+0x70*count+0x54) = g_PhyReg[clock_value][0];
+ __REG(DDR_FFC_ADDR_BASE+0x70*count+0x58) = g_PhyReg[clock_value][1];
+ __REG(DDR_FFC_ADDR_BASE+0x70*count+0x5c) = g_PhyReg[clock_value][2];
+ __REG(DDR_FFC_ADDR_BASE+0x70*count+0x60) = g_PhyReg[clock_value][3];
+
+}
+
+void ddr_ffc_init(void)
+{
+ UINT32 count;
+ __REG(STD_CRM_REG_BASE + 0x100) |= (0xf << 24); //release ddr ffc work and apb
+ for(count = 0; count <= 3; count++)
+ {
+ pow_DdrChangeClk(count);
+ save_ddr_training(count,count);
+ }
+ pow_DdrChangeClk(DDR_312M);
+}
+#endif
+
+#define ABSa_b(a,b) (((a) > (b)) ? (a-b) : (b-a))
+
+int ddr_clk_init(int flag)
+{
+ //DDR top clock select top clk 156M, bit0-1, 0=156, 1=200, 2=104, 3=78
+ // 0: top clk=156M, ddr use mission mode , dram io clk=312M
+ // 1: top clk=200M, ddr use mission mode , dram io clk=400M
+ // 2: top clk=104M, ddr use mission mode , dram io clk=208M
+ // 3: top clk=78M, ddr use mission mode , dram io clk=156M
+ if(flag == CHIP_DDR_IS_32M)
+ {
+ #if _DDR32M_BYPASS_MODE
+ __REG( 0x01306050 ) = 0x00000000 ; //·ÖƵÉèÖ㬶ÔÓ¦ÐèÒªÐÞ¸ÄÂð
+ #else
+ __REG( 0x01306050 ) = 0x00000001 ; //·ÖƵÉèÖ㬶ÔÓ¦ÐèÒªÐÞ¸ÄÂð
+ #endif
+ }
+ else
+ {
+ #if _DDR_BYPASS_MODE
+ __REG( 0x01306050 ) = 0x00000000 ; //·ÖƵÉèÖ㬶ÔÓ¦ÐèÒªÐÞ¸ÄÂð
+ #else
+ __REG( 0x01306050 ) = 0x00000001 ; //·ÖƵÉèÖ㬶ÔÓ¦ÐèÒªÐÞ¸ÄÂð
+ #endif
+ }
+
+ return 0;
+
+}
+
+int ddr_phy_init(int flag)
+{
+ if(flag == CHIP_DDR_IS_32M)
+ {
+ __REG( 0x00154000 ) = 0x0000003f ; //VALUE_PHYREG00 0x0000003f(16bit ddr) default: 0x000000ff(32bit ddr)
+ }
+
+ __REG( 0x00154004 ) = 0x00000007 ; //VALUE_PHYREG01 / Reserved:RW:2:6:=0x1, PHY_MODE:RW:0:2:=0x2(LPDDR2:0x3,LPDDR3:0x2)
+ __REG( 0x0015402c ) = 0x00000080 ; //VALUE_PHYREG0B / RL:RW:4:4:=0x8
+ __REG( 0x00154030 ) = 0x00000004 ; //VALUE_PHYREG0C / WL:RW:0:4:=0x4
+
+ __REG( 0x001543b0 ) = 0x00000010 ; //VALUE_PHYREGEC / fbdiv[7:0]=0x10
+ __REG( 0x001543b4 ) = 0x0000001a ; //VALUE_PHYREGED / PLLCLKOUTEN:RW:4:1:=0x1,Reserved:RW:2:2:=0x2, pllpd:RW:1:1:=0x1, fbdiv[8]:RW:0:1:=0x0
+ __REG( 0x001543b8 ) = 0x00000022 ; //VALUE_PHYREGEE / prediv[4:0]:RW:0:5:=0x2,postdiv[2:0]:RW:5:3:=0x1
+
+ if(flag == CHIP_DDR_IS_32M)
+ {
+ #ifndef _DDR32M_DS_48om //60ohm
+ __REG( 0x00154044 )= 0x00000008; //VALUE_PHYREG11 / CMD drive strength: cmd_nrcomp[4:0]:RW:0:5:=0xa
+ __REG(0x00154058 )= 0x00000008; //VALUE_PHYREG16 / CK drive strength: ck_nrcomp [4:0]:RW:0:5:=0xa
+ __REG(0x00154064 )= 0x00000008; //VALUE_PHYREG19 / CK pull_up drive strength(DS):RW:0:5:=0xa
+ __REG(0x00154068 )= 0x00000008; //VALUE_PHYREG1A / CMD pull_up drive strength(DS):RW:0:5:=0xa
+ __REG(0x00154080 )= 0x00000008; //VALUE_PHYREG20 / A_DQ0~A_DQ7 pull_down DS :RW:0:5:=0xa
+ __REG(0x00154084 )= 0x00000004; //VALUE_PHYREG21 / A_DQ0~A_DQ7 pull_down ODT:RW:0:5:=0xa
+ __REG(0x001540b8 )= 0x00000088; //VALUE_PHYREG2E / A_DQ0~A_DQ7 pull_up DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG(0x001540bc )= 0x00000084; //VALUE_PHYREG2F / A_DQ0~A_DQ7 pull_up ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+ __REG(0x001540c0 )= 0x00000088; //VALUE_PHYREG30 / A_DQ8~A_DQ15 pull_down DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG(0x001540c4 )= 0x00000084; //VALUE_PHYREG31 / A_DQ8~A_DQ15 pull_down ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+ __REG(0x001540f8 )= 0x00000008; //VALUE_PHYREG3E / A_DQ8~A_DQ15 pull_up DS :RW:0:5:=0xa
+ __REG(0x001540fc )= 0x00000004; //VALUE_PHYREG3F / A_DQ8~A_DQ15 pull_up ODT:RW:0:5:=0xa
+
+ __REG(0x00154100 )= 0x00000008; //VALUE_PHYREG40 / B_DQ0~B_DQ7 pull_down DS :RW:0:5:=0xa
+ __REG(0x00154104 )= 0x00000004; //VALUE_PHYREG41 / B_DQ0~B_DQ7 pull_down ODT:RW:0:5:=0xa
+ __REG(0x00154138 )= 0x00000088; //VALUE_PHYREG4E / B_DQ0~B_DQ7 pull_up DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG(0x0015413c )= 0x00000084; //VALUE_PHYREG4F / B_DQ0~B_DQ7 pull_up ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+
+ __REG(0x00154140 )= 0x00000088; //VALUE_PHYREG50 / B_DQ8~B_DQ15 pull_down DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG(0x00154144 )= 0x00000084; //VALUE_PHYREG51 / B_DQ8~B_DQ15 pull_down ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+ __REG(0x00154178 )= 0x00000008; //VALUE_PHYREG5E / B_DQ8~B_DQ15 pull_up DS :RW:0:5:=0xa
+ __REG(0x0015417c )= 0x00000024; //VALUE_PHYREG5F / B_DQ8~B_DQ15 pull_up ODT:RW:0:5:=0xa
+ #else //48om
+ //Drive strength(defualt) ODT µÈЧ48om
+ __REG( 0x00154044 ) = 0x0000000a ; //VALUE_PHYREG11 / CMD drive strength: cmd_prcomp[3:0]:RW:4:4:=0xa,cmd_nrcomp[3:0]:RW:0:4:=0xa
+ __REG( 0x00154058 ) = 0x0000000a ; //VALUE_PHYREG16 / CK drive strength: ck_prcomp [3:0]:RW:4:4:=0xa,ck_nrcomp [3:0]:RW:0:4:=0xa
+ __REG( 0x00154064 ) = 0x0000000a ; //VALUE_PHYREG19 / CK pull_up drive strength(DS):RW:0:5:=0xa
+ __REG( 0x00154068 ) = 0x0000000a ; //VALUE_PHYREG1A / CMD pull_up drive strength(DS):RW:0:5:=0xa
+ __REG( 0x00154080 ) = 0x0000000a ; //VALUE_PHYREG20 / A_DQ0~A_DQ7 pull_down DS :RW:0:5:=0xa
+ __REG( 0x00154084 ) = 0x00000005 ; //VALUE_PHYREG21 / A_DQ0~A_DQ7 pull_down ODT:RW:0:5:=0xa
+ __REG( 0x001540b8 ) = 0x0000008a ; //VALUE_PHYREG2E / A_DQ0~A_DQ7 pull_up DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG( 0x001540bc ) = 0x00000085 ; //VALUE_PHYREG2F / A_DQ0~A_DQ7 pull_up ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+ __REG( 0x001540c0 ) = 0x0000008a ; //VALUE_PHYREG30 / A_DQ8~A_DQ15 pull_down DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG( 0x001540c4 ) = 0x00000085 ; //VALUE_PHYREG31 / A_DQ8~A_DQ15 pull_down ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+ __REG( 0x001540f8 ) = 0x0000000a ; //VALUE_PHYREG3E / A_DQ8~A_DQ15 pull_up DS :RW:0:5:=0xa
+ __REG( 0x001540fc ) = 0x00000005 ; //VALUE_PHYREG3F / A_DQ8~A_DQ15 pull_up ODT:RW:0:5:=0xa
+
+ __REG( 0x00154100 ) = 0x0000000a ; //VALUE_PHYREG40 / B_DQ0~B_DQ7 pull_down DS :RW:0:5:=0xa
+ __REG( 0x00154104 ) = 0x00000005 ; //VALUE_PHYREG41 / B_DQ0~B_DQ7 pull_down ODT:RW:0:5:=0xa
+ __REG( 0x00154138 ) = 0x0000008a ; //VALUE_PHYREG4E / B_DQ0~B_DQ7 pull_up DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG( 0x0015413c ) = 0x00000085 ; //VALUE_PHYREG4F / B_DQ0~B_DQ7 pull_up ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+
+ __REG( 0x00154140 ) = 0x0000008a ; //VALUE_PHYREG50 / B_DQ8~B_DQ15 pull_down DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG( 0x00154144 ) = 0x00000085 ; //VALUE_PHYREG51 / B_DQ8~B_DQ15 pull_down ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+ __REG( 0x00154178 ) = 0x0000000a ; //VALUE_PHYREG5E / B_DQ8~B_DQ15 pull_up DS :RW:0:5:=0xa
+ __REG( 0x0015417c ) = 0x00000025 ; //VALUE_PHYREG5F / B_DQ8~B_DQ15 pull_up ODT:RW:0:5:=0xa
+ #endif
+
+ }
+ else
+ {
+ #ifndef _DDR_DS_48om //60ohm
+ __REG( 0x00154044 )= 0x00000008; //VALUE_PHYREG11 / CMD drive strength: cmd_nrcomp[4:0]:RW:0:5:=0xa
+ __REG(0x00154058 )= 0x00000008; //VALUE_PHYREG16 / CK drive strength: ck_nrcomp [4:0]:RW:0:5:=0xa
+ __REG(0x00154064 )= 0x00000008; //VALUE_PHYREG19 / CK pull_up drive strength(DS):RW:0:5:=0xa
+ __REG(0x00154068 )= 0x00000008; //VALUE_PHYREG1A / CMD pull_up drive strength(DS):RW:0:5:=0xa
+ __REG(0x00154080 )= 0x00000008; //VALUE_PHYREG20 / A_DQ0~A_DQ7 pull_down DS :RW:0:5:=0xa
+ __REG(0x00154084 )= 0x00000004; //VALUE_PHYREG21 / A_DQ0~A_DQ7 pull_down ODT:RW:0:5:=0xa
+ __REG(0x001540b8 )= 0x00000088; //VALUE_PHYREG2E / A_DQ0~A_DQ7 pull_up DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG(0x001540bc )= 0x00000084; //VALUE_PHYREG2F / A_DQ0~A_DQ7 pull_up ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+ __REG(0x001540c0 )= 0x00000088; //VALUE_PHYREG30 / A_DQ8~A_DQ15 pull_down DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG(0x001540c4 )= 0x00000084; //VALUE_PHYREG31 / A_DQ8~A_DQ15 pull_down ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+ __REG(0x001540f8 )= 0x00000008; //VALUE_PHYREG3E / A_DQ8~A_DQ15 pull_up DS :RW:0:5:=0xa
+ __REG(0x001540fc )= 0x00000004; //VALUE_PHYREG3F / A_DQ8~A_DQ15 pull_up ODT:RW:0:5:=0xa
+
+ __REG(0x00154100 )= 0x00000008; //VALUE_PHYREG40 / B_DQ0~B_DQ7 pull_down DS :RW:0:5:=0xa
+ __REG(0x00154104 )= 0x00000004; //VALUE_PHYREG41 / B_DQ0~B_DQ7 pull_down ODT:RW:0:5:=0xa
+ __REG(0x00154138 )= 0x00000088; //VALUE_PHYREG4E / B_DQ0~B_DQ7 pull_up DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG(0x0015413c )= 0x00000084; //VALUE_PHYREG4F / B_DQ0~B_DQ7 pull_up ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+
+ __REG(0x00154140 )= 0x00000088; //VALUE_PHYREG50 / B_DQ8~B_DQ15 pull_down DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG(0x00154144 )= 0x00000084; //VALUE_PHYREG51 / B_DQ8~B_DQ15 pull_down ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+ __REG(0x00154178 )= 0x00000008; //VALUE_PHYREG5E / B_DQ8~B_DQ15 pull_up DS :RW:0:5:=0xa
+ __REG(0x0015417c )= 0x00000024; //VALUE_PHYREG5F / B_DQ8~B_DQ15 pull_up ODT:RW:0:5:=0xa
+ #else //48om
+ //Drive strength(defualt) ODT µÈЧ48om
+ __REG( 0x00154044 ) = 0x0000000a ; //VALUE_PHYREG11 / CMD drive strength: cmd_prcomp[3:0]:RW:4:4:=0xa,cmd_nrcomp[3:0]:RW:0:4:=0xa
+ __REG( 0x00154058 ) = 0x0000000a ; //VALUE_PHYREG16 / CK drive strength: ck_prcomp [3:0]:RW:4:4:=0xa,ck_nrcomp [3:0]:RW:0:4:=0xa
+ __REG( 0x00154064 ) = 0x0000000a ; //VALUE_PHYREG19 / CK pull_up drive strength(DS):RW:0:5:=0xa
+ __REG( 0x00154068 ) = 0x0000000a ; //VALUE_PHYREG1A / CMD pull_up drive strength(DS):RW:0:5:=0xa
+ __REG( 0x00154080 ) = 0x0000000a ; //VALUE_PHYREG20 / A_DQ0~A_DQ7 pull_down DS :RW:0:5:=0xa
+ __REG( 0x00154084 ) = 0x00000005 ; //VALUE_PHYREG21 / A_DQ0~A_DQ7 pull_down ODT:RW:0:5:=0xa
+ __REG( 0x001540b8 ) = 0x0000008a ; //VALUE_PHYREG2E / A_DQ0~A_DQ7 pull_up DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG( 0x001540bc ) = 0x00000085 ; //VALUE_PHYREG2F / A_DQ0~A_DQ7 pull_up ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+ __REG( 0x001540c0 ) = 0x0000008a ; //VALUE_PHYREG30 / A_DQ8~A_DQ15 pull_down DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG( 0x001540c4 ) = 0x00000085 ; //VALUE_PHYREG31 / A_DQ8~A_DQ15 pull_down ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+ __REG( 0x001540f8 ) = 0x0000000a ; //VALUE_PHYREG3E / A_DQ8~A_DQ15 pull_up DS :RW:0:5:=0xa
+ __REG( 0x001540fc ) = 0x00000005 ; //VALUE_PHYREG3F / A_DQ8~A_DQ15 pull_up ODT:RW:0:5:=0xa
+
+ __REG( 0x00154100 ) = 0x0000000a ; //VALUE_PHYREG40 / B_DQ0~B_DQ7 pull_down DS :RW:0:5:=0xa
+ __REG( 0x00154104 ) = 0x00000005 ; //VALUE_PHYREG41 / B_DQ0~B_DQ7 pull_down ODT:RW:0:5:=0xa
+ __REG( 0x00154138 ) = 0x0000008a ; //VALUE_PHYREG4E / B_DQ0~B_DQ7 pull_up DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG( 0x0015413c ) = 0x00000085 ; //VALUE_PHYREG4F / B_DQ0~B_DQ7 pull_up ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+
+ __REG( 0x00154140 ) = 0x0000008a ; //VALUE_PHYREG50 / B_DQ8~B_DQ15 pull_down DS :RW:0:5:=0xa, falling edge slew rate:RW:5:3:=0x4
+ __REG( 0x00154144 ) = 0x00000085 ; //VALUE_PHYREG51 / B_DQ8~B_DQ15 pull_down ODT:RW:0:5:=0xa, rising edge slew rate:RW:5:3:=0x4
+ __REG( 0x00154178 ) = 0x0000000a ; //VALUE_PHYREG5E / B_DQ8~B_DQ15 pull_up DS :RW:0:5:=0xa
+ __REG( 0x0015417c ) = 0x00000025 ; //VALUE_PHYREG5F / B_DQ8~B_DQ15 pull_up ODT:RW:0:5:=0xa
+ #endif
+ }
+
+ return 0;
+
+}
+
+int ddr_ctrl_init(int flag)
+{
+
+ if(flag == CHIP_DDR_IS_32M)
+ {
+ __REG( 0x00150000 ) = 0x01041004; // 0x01041004(16bit) ; //VALUE_MSTR / device_config:RW:30:2:=0x0 frequency_mode:RW:29:1:=0x0 active_ranks:RW:24:4:=0x3 burst_rdwr:RW:16:4:=0x4 dll_off_mode:RW:15:1:=0x0 data_bus_width:RW:12:2:=0x0 geardown_mode:RW:11:1:=0x0 en_2t_timing_mode:RW:10:1:=0x0 burstchop:RW:9:1:=0x0 burst_mode:RW:8:1:=0x0 lpddr4:RW:5:1:=0x0 ddr4:RW:4:1:=0x0 lpddr3:RW:3:1:=0x0 lpddr2:RW:2:1:=0x1 mobile:RW:1:1:=0x0 ddr3:RW:0:1:=0x0
+ }
+ else
+ {
+ __REG( 0x00150000 ) = 0x01040004; // 0x01040004(32bit)
+ }
+
+ __REG( 0x00150010 ) = 0x00000030 ; //VALUE_MRCTRL0 / mr_wr:RW:31:1:=0x0 mr_addr:RW:12:4:=0x0 mr_rank:RW:4:4:=0x3 sw_init_int:RW:3:1:=0x0 pda_en:RW:2:1:=0x0 mpr_en:RW:1:1:=0x0 mr_type:RW:0:1:=0x0
+ __REG( 0x00150014 ) = 0x00000000 ; //VALUE_MRCTRL1 /mr_data:RW:0:16:=0x0
+ __REG( 0x00150020 ) = 0x00000000 ; //VALUE_DERATEEN /rc_derate_value:RW:8:2:=0x0 derate_byte:RW:4:4:=0x0 derate_value:RW:1:1:=0x0 derate_enable:RW:0:1:=0x0
+ __REG( 0x00150024 ) = 0x00800000 ; //VALUE_DERATEINT /mr4_read_interval:RW:0:32:=0x800000
+
+ __REG( 0x00150030 ) = 0x00000000 ; //VALUE_PWRCTL / stay_in_selfref:RW:6:1:=0x0 selfref_sw:RW:5:1:=0x0 mpsm_en:RW:4:1:=0x0 en_dfi_dram_clk_disable:RW:3:1:=0x0 deeppowerdown_en:RW:2:1:=0x0 powerdown_en:RW:1:1:=0x1 selfref_en:RW:0:1:=0x1
+ __REG( 0x00150034 ) = 0x00052002 ; //VALUE_PWRTMG / selfref_to_x32:RW:16:8:=0x5 deeppowerdown_to_x1024:RW:8:8:=0x20 powerdown_to_x32:RW:0:5:=0x2
+ __REG( 0x00150038 ) = 0x00040003 ; //VALUE_HWLPCTL / hw_lp_idle_x32:RW:16:12:=0x4 hw_lp_exit_idle_en:RW:1:1:=0x1 hw_lp_en:RW:0:1:=0x1
+ __REG( 0x00150050 ) = 0x00210000 ; //VALUE_RFSHCTL0 / refresh_margin:RW:20:4:=0x2 refresh_to_x32:RW:12:5:=0x10 refresh_burst:RW:4:5:=0x0 per_bank_refresh:RW:2:1:=0x0
+ __REG( 0x00150054 ) = 0x00000000 ; //VALUE_RFSHCTL1 / refresh_timer1_start_value_x32:RW:16:12:=0x0 refresh_timer0_start_value_x32:RW:0:12:=0x0
+ __REG( 0x00150058 ) = 0x00000000 ; //VALUE_RFSHCTL2 / refresh_timer3_start_value_x32:RW:16:12:=0x0 refresh_timer2_start_value_x32:RW:0:12:=0x0
+ __REG( 0x00150060 ) = 0x00000000 ; //VALUE_RFSHCTL3 / refresh_mode:RW:4:3:=0x0 refresh_update_level:RW:1:1:=0x0 dis_auto_refresh:RW:0:1:=0x0
+
+ if(flag == CHIP_DDR_IS_32M)
+ {
+ #if _DDR32M_BYPASS_MODE
+ __REG( 0x00150064 ) = 0x00260014 ; //VALUE_RFSHTMG / t_rfc_nom_x32(trefi):RW:16:12:=0x26 lpddr3_trefbw_en:RW:15:1:=0x0 t_rfc_min:RW:0:9:=0x14
+ __REG( 0x001500d0 ) = 0x001f0001 ; //VALUE_INIT0 / skip_dram_init:RW:31:2:=0x0 post_cke_x1024:RW:16:10:=0x1f pre_cke_x1024:RW:0:11:=0x1
+ __REG( 0x001500d4 ) = 0x00000000 ; //VALUE_INIT1 / dram_rstn_x1024:RW:16:8:=0x0 final_wait_x32:RW:8:7:=0x0 pre_ocd_x32:RW:0:4:=0x0
+ __REG( 0x001500d8 ) = 0x00000405 ; //VALUE_INIT2 / idle_after_reset_x32:RW:8:8:=0x4 min_stable_clock_x1:RW:0:4:=0x5
+ //MR2=RL/WL£¬1£ºRL3/WL1£¬2£ºRL4/WL2£¬3£ºRL:5/WL2£¬4£ºRL6/WL3:£¬5£ºRL7/WL4£¬6£ºRL8/WL4
+ __REG( 0x001500dc ) = 0x00630006 ; //VALUE_INIT3 / mr:RW:16:16:=0x63 emr:RW:0:16:=0x6
+ //bit16-31£¬LPDDR2 MR3 value£¬Æ÷¼þDSĬÈÏÊÇ40ohm£¬£¨1=34.3£¬2=40,3=48,4=60,6=80£©
+ #ifndef _DDR32M_DS_48om //60ohm
+ __REG( 0x001500e0 ) = 0x00040000 ; //VALUE_INIT4 / emr2:RW:16:16:=0x2 emr3:RW:0:16:=0x0
+ #else //48ohm
+ __REG( 0x001500e0 ) = 0x00030000 ; //VALUE_INIT4 / emr2:RW:16:16:=0x2 emr3:RW:0:16:=0x0
+ #endif
+ __REG( 0x001500e4 ) = 0x00050002 ; //VALUE_INIT5 / dev_zqinit_x32:RW:16:8:=0x5 max_auto_init_x1024:RW:0:10:=0x2
+ __REG( 0x001500f4 ) = 0x0000066f ; //VALUE_RANKCTL / diff_rank_wr_gap:RW:8:4:=0x6 diff_rank_rd_gap:RW:4:4:=0x6 max_rank_rd:RW:0:4:=0xf
+ __REG( 0x00150100 ) = 0x06080a07 ; //VALUE_DRAMTMG0 / wr2pre:RW:24:6:=0x6 t_faw:RW:16:6:=0x8 t_ras_max:RW:8:7:=0xa t_ras_min:RW:0:6:=0x7
+ __REG( 0x00150104 ) = 0x0002020a ; //VALUE_DRAMTMG1 / t_xp:RW:16:5:=0x2 rd2pre:RW:8:5:=0x2 t_rc:RW:0:6:=0x9
+ //RL=bit16-21£¬1£ºRL=2£¬2£ºRL=4£¬3£ºRL=6£¬4£ºR=8£¬WL=bit24-29£¬1£ºWL=2£¬2£ºWL=4
+ //ÕâÀïµ¼ÖÂMR2µÄÅäÖã¨0x012160dc£©²»ÄÜÑ¡Ôñº¬ÓÐÆæÊýµÄÖµ?
+ __REG( 0x00150108 ) = 0x02040606 ; //VALUE_DRAMTMG2 / write_latency:RW:24:6:=0x2 read_latency:RW:16:6:=0x4 rd2wr:RW:8:6:=0x6 wr2rd:RW:0:6:=0x6
+ __REG( 0x0015010c ) = 0x00501000 ; //VALUE_DRAMTMG3 / t_mrw:RW:20:10:=0x5 t_mrd:RW:12:6:=0x1 t_mod:RW:0:10:=0x0
+ __REG( 0x00150110 ) = 0x03010204 ; //VALUE_DRAMTMG4 / t_rcd:RW:24:5:=0x3 t_ccd:RW:16:4:=0x1 t_rrd:RW:8:4:=0x2 t_rp:RW:0:5:=0x4
+ __REG( 0x00150114 ) = 0x01010303 ; //VALUE_DRAMTMG5 / t_cksrx:RW:24:4:=0x1 t_cksre:RW:16:4:=0x1 t_ckesr:RW:8:6:=0x3 t_cke:RW:0:4:=0x3
+ __REG( 0x00150118 ) = 0x02020003 ; //VALUE_DRAMTMG6 / t_ckdpde:RW:24:4:=0x2 t_ckdpdx:RW:16:4:=0x2 t_ckcsx:RW:0:4:=0x3
+ __REG( 0x0015011c ) = 0x00000202 ; //VALUE_DRAMTMG7 / t_ckpde:RW:8:4:=0x2 t_ckpdx:RW:0:4:=0x2
+ __REG( 0x00150138 ) = 0x00000016 ; //VALUE_DRAMTMG14 / t_xsr:RW:0:12:=0x16
+ //bit30=1 Disable issuing of ZQCL/MPC(ZQ calibration) command at Self-Refresh/SR-Powerdown exit £¬7520×ʼÅäÖÃΪ0£¬µ¼ÖÂ×Ô¶¯×Ôˢй¦ÄÜÍ˳öʱÑÓʱºÜ´ó£¬sdio¶ÁÊý¾Ý³ö´í
+ __REG( 0x00150180 ) = 0x4039000f ; //VALUE_ZQCTL0 / dis_auto_zq:RW:31:1:=0x0 dis_srx_zqcl:RW:30:1:=0x1 zq_resistor_shared:RW:29:1:=0x0 dis_mpsmx_zqcl:RW:28:1:=0x0 t_zq_long_nop:RW:16:10:=0x39 t_zq_short_nop:RW:0:10:=0xf
+ __REG( 0x00150184 ) = 0x00800100 ; //VALUE_ZQCTL1 / t_zq_reset_nop:RW:20:10:=0x8 t_zq_short_interval_x1024:RW:0:20:=0x100
+
+ #else
+ __REG( 0x00150064 ) = 0x0030001a ; //VALUE_RFSHTMG / t_rfc_nom_x32(trefi):RW:16:12:=0x26 lpddr3_trefbw_en:RW:15:1:=0x0 t_rfc_min:RW:0:9:=0x14
+ __REG( 0x001500d0 ) = 0x00280001 ; //VALUE_INIT0 / skip_dram_init:RW:31:2:=0x0 post_cke_x1024:RW:16:10:=0x1f pre_cke_x1024:RW:0:11:=0x1
+ __REG( 0x001500d4 ) = 0x00000000 ; //VALUE_INIT1 / dram_rstn_x1024:RW:16:8:=0x0 final_wait_x32:RW:8:7:=0x0 pre_ocd_x32:RW:0:4:=0x0
+ __REG( 0x001500d8 ) = 0x00000605 ; //VALUE_INIT2 / idle_after_reset_x32:RW:8:8:=0x4 min_stable_clock_x1:RW:0:4:=0x5
+ //MR2=RL/WL£¬1£ºRL3/WL1£¬2£ºRL4/WL2£¬3£ºRL:5/WL2£¬4£ºRL6/WL3:£¬5£ºRL7/WL4£¬6£ºRL8/WL4
+ __REG( 0x001500dc ) = 0x00830006 ; //VALUE_INIT3 / mr:RW:16:16:=0x63 emr:RW:0:16:=0x6
+ //bit16-31£¬LPDDR2 MR3 value£¬Æ÷¼þDSĬÈÏÊÇ40ohm£¬£¨1=34.3£¬2=40,3=48,4=60,6=80£©
+ #ifndef _DDR32M_DS_48om //60ohm
+ __REG( 0x001500e0 ) = 0x00040000 ; //VALUE_INIT4 / emr2:RW:16:16:=0x2 emr3:RW:0:16:=0x0
+ #else //48ohm
+ __REG( 0x001500e0 ) = 0x00030000 ; //VALUE_INIT4 / emr2:RW:16:16:=0x2 emr3:RW:0:16:=0x0
+ #endif
+ __REG( 0x001500e4 ) = 0x00070002 ; //VALUE_INIT5 / dev_zqinit_x32:RW:16:8:=0x5 max_auto_init_x1024:RW:0:10:=0x2
+ __REG( 0x001500f4 ) = 0x0000066f ; //VALUE_RANKCTL / diff_rank_wr_gap:RW:8:4:=0x6 diff_rank_rd_gap:RW:4:4:=0x6 max_rank_rd:RW:0:4:=0xf
+ __REG( 0x00150100 ) = 0x070a0d08 ; //VALUE_DRAMTMG0 / wr2pre:RW:24:6:=0x6 t_faw:RW:16:6:=0x8 t_ras_max:RW:8:7:=0xa t_ras_min:RW:0:6:=0x7
+ __REG( 0x00150104 ) = 0x0002020d ; //VALUE_DRAMTMG1 / t_xp:RW:16:5:=0x2 rd2pre:RW:8:5:=0x2 t_rc:RW:0:6:=0x9
+ //RL=bit16-21£¬1£ºRL=2£¬2£ºRL=4£¬3£ºRL=6£¬4£ºR=8£¬WL=bit24-29£¬1£ºWL=2£¬2£ºWL=4
+ //ÕâÀïµ¼ÖÂMR2µÄÅäÖã¨0x012160dc£©²»ÄÜÑ¡Ôñº¬ÓÐÆæÊýµÄÖµ?
+ __REG( 0x00150108 ) = 0x02040607 ; //VALUE_DRAMTMG2 / write_latency:RW:24:6:=0x2 read_latency:RW:16:6:=0x4 rd2wr:RW:8:6:=0x6 wr2rd:RW:0:6:=0x6
+ __REG( 0x0015010c ) = 0x00501000 ; //VALUE_DRAMTMG3 / t_mrw:RW:20:10:=0x5 t_mrd:RW:12:6:=0x1 t_mod:RW:0:10:=0x0
+ __REG( 0x00150110 ) = 0x04010205 ; //VALUE_DRAMTMG4 / t_rcd:RW:24:5:=0x3 t_ccd:RW:16:4:=0x1 t_rrd:RW:8:4:=0x2 t_rp:RW:0:5:=0x4
+ __REG( 0x00150114 ) = 0x01010303 ; //VALUE_DRAMTMG5 / t_cksrx:RW:24:4:=0x1 t_cksre:RW:16:4:=0x1 t_ckesr:RW:8:6:=0x3 t_cke:RW:0:4:=0x3
+ __REG( 0x00150118 ) = 0x02020003 ; //VALUE_DRAMTMG6 / t_ckdpde:RW:24:4:=0x2 t_ckdpdx:RW:16:4:=0x2 t_ckcsx:RW:0:4:=0x3
+ __REG( 0x0015011c ) = 0x00000202 ; //VALUE_DRAMTMG7 / t_ckpde:RW:8:4:=0x2 t_ckpdx:RW:0:4:=0x2
+ __REG( 0x00150138 ) = 0x0000001c ; //VALUE_DRAMTMG14 / t_xsr:RW:0:12:=0x16
+ //bit30=1 Disable issuing of ZQCL/MPC(ZQ calibration) command at Self-Refresh/SR-Powerdown exit £¬7520×ʼÅäÖÃΪ0£¬µ¼ÖÂ×Ô¶¯×Ôˢй¦ÄÜÍ˳öʱÑÓʱºÜ´ó£¬sdio¶ÁÊý¾Ý³ö´í
+ __REG( 0x00150180 ) = 0x40480012 ; //VALUE_ZQCTL0 / dis_auto_zq:RW:31:1:=0x0 dis_srx_zqcl:RW:30:1:=0x1 zq_resistor_shared:RW:29:1:=0x0 dis_mpsmx_zqcl:RW:28:1:=0x0 t_zq_long_nop:RW:16:10:=0x39 t_zq_short_nop:RW:0:10:=0xf
+ __REG( 0x00150184 ) = 0x00a00100 ; //VALUE_ZQCTL1 / t_zq_reset_nop:RW:20:10:=0x8 t_zq_short_interval_x1024:RW:0:20:=0x100
+ #endif
+
+ }
+ else
+ {
+ #if _DDR_BYPASS_MODE
+ if(flag == CHIP_DDR_IS_256M)
+ __REG( 0x00150064 ) = 0x00130014 ; //VALUE_RFSHTMG / t_rfc_nom_x32(trefi):RW:16:12:=0x13 lpddr3_trefbw_en:RW:15:1:=0x0 t_rfc_min:RW:0:9:=0x0a
+ else
+ __REG( 0x00150064 ) = 0x00260014 ; //VALUE_RFSHTMG / t_rfc_nom_x32(trefi):RW:16:12:=0x26 lpddr3_trefbw_en:RW:15:1:=0x0 t_rfc_min:RW:0:9:=0x14
+ __REG( 0x001500d0 ) = 0x001f0001 ; //VALUE_INIT0 / skip_dram_init:RW:31:2:=0x0 post_cke_x1024:RW:16:10:=0x1f pre_cke_x1024:RW:0:11:=0x1
+ __REG( 0x001500d4 ) = 0x00000000 ; //VALUE_INIT1 / dram_rstn_x1024:RW:16:8:=0x0 final_wait_x32:RW:8:7:=0x0 pre_ocd_x32:RW:0:4:=0x0
+ __REG( 0x001500d8 ) = 0x00000405 ; //VALUE_INIT2 / idle_after_reset_x32:RW:8:8:=0x4 min_stable_clock_x1:RW:0:4:=0x5
+ //MR2=RL/WL£¬1£ºRL3/WL1£¬2£ºRL4/WL2£¬3£ºRL:5/WL2£¬4£ºRL6/WL3:£¬5£ºRL7/WL4£¬6£ºRL8/WL4
+ __REG( 0x001500dc ) = 0x00630006 ; //VALUE_INIT3 / mr:RW:16:16:=0x63 emr:RW:0:16:=0x6
+ //bit16-31£¬LPDDR2 MR3 value£¬Æ÷¼þDSĬÈÏÊÇ40ohm£¬£¨1=34.3£¬2=40,3=48,4=60,6=80£©
+ #ifndef _DDR_DS_48om //60ohm
+ __REG( 0x001500e0 ) = 0x00040000 ; //VALUE_INIT4 / emr2:RW:16:16:=0x2 emr3:RW:0:16:=0x0
+ #else //48ohm
+ __REG( 0x001500e0 ) = 0x00030000 ; //VALUE_INIT4 / emr2:RW:16:16:=0x2 emr3:RW:0:16:=0x0
+ #endif
+ __REG( 0x001500e4 ) = 0x00050002 ; //VALUE_INIT5 / dev_zqinit_x32:RW:16:8:=0x5 max_auto_init_x1024:RW:0:10:=0x2
+ __REG( 0x001500f4 ) = 0x0000066f ; //VALUE_RANKCTL / diff_rank_wr_gap:RW:8:4:=0x6 diff_rank_rd_gap:RW:4:4:=0x6 max_rank_rd:RW:0:4:=0xf
+ __REG( 0x00150100 ) = 0x06080a07 ; //VALUE_DRAMTMG0 / wr2pre:RW:24:6:=0x6 t_faw:RW:16:6:=0x8 t_ras_max:RW:8:7:=0xa t_ras_min:RW:0:6:=0x7
+ __REG( 0x00150104 ) = 0x0002020a ; //VALUE_DRAMTMG1 / t_xp:RW:16:5:=0x2 rd2pre:RW:8:5:=0x2 t_rc:RW:0:6:=0x9
+ //RL=bit16-21£¬1£ºRL=2£¬2£ºRL=4£¬3£ºRL=6£¬4£ºR=8£¬WL=bit24-29£¬1£ºWL=2£¬2£ºWL=4
+ //ÕâÀïµ¼ÖÂMR2µÄÅäÖã¨0x012160dc£©²»ÄÜÑ¡Ôñº¬ÓÐÆæÊýµÄÖµ?
+ __REG( 0x00150108 ) = 0x02040606 ; //VALUE_DRAMTMG2 / write_latency:RW:24:6:=0x2 read_latency:RW:16:6:=0x4 rd2wr:RW:8:6:=0x6 wr2rd:RW:0:6:=0x6
+ __REG( 0x0015010c ) = 0x00501000 ; //VALUE_DRAMTMG3 / t_mrw:RW:20:10:=0x5 t_mrd:RW:12:6:=0x1 t_mod:RW:0:10:=0x0
+ __REG( 0x00150110 ) = 0x03010204 ; //VALUE_DRAMTMG4 / t_rcd:RW:24:5:=0x3 t_ccd:RW:16:4:=0x1 t_rrd:RW:8:4:=0x2 t_rp:RW:0:5:=0x4
+ __REG( 0x00150114 ) = 0x01010303 ; //VALUE_DRAMTMG5 / t_cksrx:RW:24:4:=0x1 t_cksre:RW:16:4:=0x1 t_ckesr:RW:8:6:=0x3 t_cke:RW:0:4:=0x3
+ __REG( 0x00150118 ) = 0x02020003 ; //VALUE_DRAMTMG6 / t_ckdpde:RW:24:4:=0x2 t_ckdpdx:RW:16:4:=0x2 t_ckcsx:RW:0:4:=0x3
+ __REG( 0x0015011c ) = 0x00000202 ; //VALUE_DRAMTMG7 / t_ckpde:RW:8:4:=0x2 t_ckpdx:RW:0:4:=0x2
+ __REG( 0x00150138 ) = 0x00000016 ; //VALUE_DRAMTMG14 / t_xsr:RW:0:12:=0x16
+ //bit30=1 Disable issuing of ZQCL/MPC(ZQ calibration) command at Self-Refresh/SR-Powerdown exit £¬7520×ʼÅäÖÃΪ0£¬µ¼ÖÂ×Ô¶¯×Ôˢй¦ÄÜÍ˳öʱÑÓʱºÜ´ó£¬sdio¶ÁÊý¾Ý³ö´í
+ __REG( 0x00150180 ) = 0x4039000f ; //VALUE_ZQCTL0 / dis_auto_zq:RW:31:1:=0x0 dis_srx_zqcl:RW:30:1:=0x1 zq_resistor_shared:RW:29:1:=0x0 dis_mpsmx_zqcl:RW:28:1:=0x0 t_zq_long_nop:RW:16:10:=0x39 t_zq_short_nop:RW:0:10:=0xf
+ __REG( 0x00150184 ) = 0x00800100 ; //VALUE_ZQCTL1 / t_zq_reset_nop:RW:20:10:=0x8 t_zq_short_interval_x1024:RW:0:20:=0x100
+
+ #else
+ if(flag == CHIP_DDR_IS_256M)
+ __REG( 0x00150064 ) = 0x0018001a ; //VALUE_RFSHTMG / t_rfc_nom_x32(trefi):RW:16:12:=0x18 lpddr3_trefbw_en:RW:15:1:=0x0 t_rfc_min:RW:0:9:=0x0d
+ else
+ __REG( 0x00150064 ) = 0x0030001a ; //VALUE_RFSHTMG / t_rfc_nom_x32(trefi):RW:16:12:=0x26 lpddr3_trefbw_en:RW:15:1:=0x0 t_rfc_min:RW:0:9:=0x14
+ __REG( 0x001500d0 ) = 0x00280001 ; //VALUE_INIT0 / skip_dram_init:RW:31:2:=0x0 post_cke_x1024:RW:16:10:=0x1f pre_cke_x1024:RW:0:11:=0x1
+ __REG( 0x001500d4 ) = 0x00000000 ; //VALUE_INIT1 / dram_rstn_x1024:RW:16:8:=0x0 final_wait_x32:RW:8:7:=0x0 pre_ocd_x32:RW:0:4:=0x0
+ __REG( 0x001500d8 ) = 0x00000605 ; //VALUE_INIT2 / idle_after_reset_x32:RW:8:8:=0x4 min_stable_clock_x1:RW:0:4:=0x5
+ //MR2=RL/WL£¬1£ºRL3/WL1£¬2£ºRL4/WL2£¬3£ºRL:5/WL2£¬4£ºRL6/WL3:£¬5£ºRL7/WL4£¬6£ºRL8/WL4
+ __REG( 0x001500dc ) = 0x00830006 ; //VALUE_INIT3 / mr:RW:16:16:=0x63 emr:RW:0:16:=0x6
+ //bit16-31£¬LPDDR2 MR3 value£¬Æ÷¼þDSĬÈÏÊÇ40ohm£¬£¨1=34.3£¬2=40,3=48,4=60,6=80£©
+ #ifndef _DDR_DS_48om //60ohm
+ __REG( 0x001500e0 ) = 0x00040000 ; //VALUE_INIT4 / emr2:RW:16:16:=0x2 emr3:RW:0:16:=0x0
+ #else //48ohm
+ __REG( 0x001500e0 ) = 0x00030000 ; //VALUE_INIT4 / emr2:RW:16:16:=0x2 emr3:RW:0:16:=0x0
+ #endif
+ __REG( 0x001500e4 ) = 0x00070002 ; //VALUE_INIT5 / dev_zqinit_x32:RW:16:8:=0x5 max_auto_init_x1024:RW:0:10:=0x2
+ __REG( 0x001500f4 ) = 0x0000066f ; //VALUE_RANKCTL / diff_rank_wr_gap:RW:8:4:=0x6 diff_rank_rd_gap:RW:4:4:=0x6 max_rank_rd:RW:0:4:=0xf
+ __REG( 0x00150100 ) = 0x070a0d08 ; //VALUE_DRAMTMG0 / wr2pre:RW:24:6:=0x6 t_faw:RW:16:6:=0x8 t_ras_max:RW:8:7:=0xa t_ras_min:RW:0:6:=0x7
+ __REG( 0x00150104 ) = 0x0002020d ; //VALUE_DRAMTMG1 / t_xp:RW:16:5:=0x2 rd2pre:RW:8:5:=0x2 t_rc:RW:0:6:=0x9
+ //RL=bit16-21£¬1£ºRL=2£¬2£ºRL=4£¬3£ºRL=6£¬4£ºR=8£¬WL=bit24-29£¬1£ºWL=2£¬2£ºWL=4
+ //ÕâÀïµ¼ÖÂMR2µÄÅäÖã¨0x012160dc£©²»ÄÜÑ¡Ôñº¬ÓÐÆæÊýµÄÖµ?
+ __REG( 0x00150108 ) = 0x02040607 ; //VALUE_DRAMTMG2 / write_latency:RW:24:6:=0x2 read_latency:RW:16:6:=0x4 rd2wr:RW:8:6:=0x6 wr2rd:RW:0:6:=0x6
+ __REG( 0x0015010c ) = 0x00501000 ; //VALUE_DRAMTMG3 / t_mrw:RW:20:10:=0x5 t_mrd:RW:12:6:=0x1 t_mod:RW:0:10:=0x0
+ __REG( 0x00150110 ) = 0x04010205 ; //VALUE_DRAMTMG4 / t_rcd:RW:24:5:=0x3 t_ccd:RW:16:4:=0x1 t_rrd:RW:8:4:=0x2 t_rp:RW:0:5:=0x4
+ __REG( 0x00150114 ) = 0x01010303 ; //VALUE_DRAMTMG5 / t_cksrx:RW:24:4:=0x1 t_cksre:RW:16:4:=0x1 t_ckesr:RW:8:6:=0x3 t_cke:RW:0:4:=0x3
+ __REG( 0x00150118 ) = 0x02020003 ; //VALUE_DRAMTMG6 / t_ckdpde:RW:24:4:=0x2 t_ckdpdx:RW:16:4:=0x2 t_ckcsx:RW:0:4:=0x3
+ __REG( 0x0015011c ) = 0x00000202 ; //VALUE_DRAMTMG7 / t_ckpde:RW:8:4:=0x2 t_ckpdx:RW:0:4:=0x2
+ __REG( 0x00150138 ) = 0x0000001c ; //VALUE_DRAMTMG14 / t_xsr:RW:0:12:=0x16
+ //bit30=1 Disable issuing of ZQCL/MPC(ZQ calibration) command at Self-Refresh/SR-Powerdown exit £¬7520×ʼÅäÖÃΪ0£¬µ¼ÖÂ×Ô¶¯×Ôˢй¦ÄÜÍ˳öʱÑÓʱºÜ´ó£¬sdio¶ÁÊý¾Ý³ö´í
+ __REG( 0x00150180 ) = 0x40480012 ; //VALUE_ZQCTL0 / dis_auto_zq:RW:31:1:=0x0 dis_srx_zqcl:RW:30:1:=0x1 zq_resistor_shared:RW:29:1:=0x0 dis_mpsmx_zqcl:RW:28:1:=0x0 t_zq_long_nop:RW:16:10:=0x39 t_zq_short_nop:RW:0:10:=0xf
+ __REG( 0x00150184 ) = 0x00a00100 ; //VALUE_ZQCTL1 / t_zq_reset_nop:RW:20:10:=0x8 t_zq_short_interval_x1024:RW:0:20:=0x100
+ #endif
+ }
+
+ __REG( 0x00150188 ) = 0x00000000 ; //VALUE_ZQCTL2 / zq_reset:RW:0:1:=0x0
+ //dfi_t_rddata_en=3,֮ǰ7520ÉÏÉè³É2»áµ¼Ö¶Ámr¶Á´í
+ __REG( 0x00150190 ) = 0x04030001 ; //VALUE_DFITMG0 / dfi_t_ctrl_delay:RW:24:5:=0x4 dfi_rddata_use_sdr:RW:23:1:=0x0 dfi_t_rddata_en:RW:16:6:=0x3 dfi_wrdata_use_sdr:RW:15:1:=0x0 dfi_tphy_wrdata:RW:8:6:=0x0 dfi_tphy_wrlat:RW:0:6:=0x1
+ __REG( 0x00150194 ) = 0x00020404 ; //VALUE_DFITMG1 / dfi_t_cmd_lat:RW:28:4:=0x0 dfi_t_parin_lat:RW:24:2:=0x0 dfi_t_wrdata_delay:RW:16:5:=0x2 dfi_t_dram_clk_disable:RW:8:4:=0x4 dfi_t_dram_clk_enable:RW:0:4:=0x4
+ __REG( 0x00150198 ) = 0x09001111 ; //VALUE_DFILPCFG0 / dfi_tlp_resp:RW:24:4:=0x9 dfi_lp_wakeup_dpd:RW:20:4:=0x0 dfi_lp_en_dpd:RW:16:1:=0x0 dfi_lp_wakeup_sr:RW:12:4:=0x1 dfi_lp_en_sr:RW:8:1:=0x1 dfi_lp_wakeup_pd:RW:4:4:=0x1 dfi_lp_en_pd:RW:0:1:=0x1
+ __REG( 0x001501a0 ) = 0x80400003 ; //VALUE_DFIUPD0 / dis_auto_ctrlupd:RW:31:1:=0x1 dfi_t_ctrlup_max:RW:16:10:=0x40 dfi_t_ctrlup_min:RW:0:10:=0x3
+ __REG( 0x001501a4 ) = 0x00000000 ; //VALUE_DFIUPD1 / dfi_t_ctrlupd_interval_min_x1024:RW:16:8:=0x0 dfi_t_ctrlupd_interval_max_x1024:RW:0:8:=0x0
+ __REG( 0x001501a8 ) = 0x80100010 ; //VALUE_DFIUPD2 / dfi_phyupd_en:RW:31:1:=0x1 dfi_phyupd_type1:RW:16:12:=0x10 dfi_phyupd_type0:RW:0:12:=0x10
+ __REG( 0x001501b0 ) = 0x00000000 ; //VALUE_DFIMISC / dfi_data_cs_polarity:RW:2:1:=0x0 phy_dbi_mode:RW:1:1:=0x0 dfi_init_complete_en:RW:0:1:=0x0
+ __REG( 0x00150200 ) = 0x0000001f ; //VALUE_ADDRMAP0 / addrmap_dch_bit0:RW:16:5:=0x0 addrmap_cs_bit1:RW:8:5:=0x0 addrmap_cs_bit0:RW:0:5:=0x1f
+
+ if(flag == CHIP_DDR_IS_32M)
+ {
+ __REG( 0x00150204 ) = 0x001f0606 ; //VALUE_ADDRMAP1 / addrmap_bank_b2:RW:16:4:=0x7 addrmap_bank_b1:RW:8:4:=0x7 addrmap_bank_b0:RW:0:4:=0x7
+ __REG( 0x00150208 ) = 0x00000000 ; //VALUE_ADDRMAP2 / addrmap_col_b5:RW:24:4:=0x0 addrmap_col_b4:RW:16:4:=0x0 addrmap_col_b3:RW:8:4:=0x0 addrmap_col_b2:RW:0:4:=0x0
+ __REG( 0x0015020c ) = 0x0f0f0000 ; //VALUE_ADDRMAP3 / addrmap_col_b9:RW:24:4:=0xf addrmap_col_b8:RW:16:4:=0x0 addrmap_col_b7:RW:8:4:=0x0 addrmap_col_b6:RW:0:4:=0x0
+ __REG( 0x00150210 ) = 0x00000f0f ; //VALUE_ADDRMAP4 / addrmap_col_b11:RW:8:4:=0xf addrmap_col_b10:RW:0:4:=0xf
+
+ }
+ else if(flag == CHIP_DDR_IS_64M)
+ {
+ __REG( 0x00150204 ) = 0x001f0707 ; //VALUE_ADDRMAP1 / addrmap_bank_b2:RW:16:4:=0x7 addrmap_bank_b1:RW:8:4:=0x7 addrmap_bank_b0:RW:0:4:=0x7
+ __REG( 0x00150208 ) = 0x00000000 ; //VALUE_ADDRMAP2 / addrmap_col_b5:RW:24:4:=0x0 addrmap_col_b4:RW:16:4:=0x0 addrmap_col_b3:RW:8:4:=0x0 addrmap_col_b2:RW:0:4:=0x0
+ __REG( 0x0015020c ) = 0x0f000000 ; //VALUE_ADDRMAP3 / addrmap_col_b9:RW:24:4:=0xf addrmap_col_b8:RW:16:4:=0x0 addrmap_col_b7:RW:8:4:=0x0 addrmap_col_b6:RW:0:4:=0x0
+ __REG( 0x00150210 ) = 0x00000f0f ; //VALUE_ADDRMAP4 / addrmap_col_b11:RW:8:4:=0xf addrmap_col_b10:RW:0:4:=0xf
+
+ }
+ else
+ {
+ __REG( 0x00150204 ) = 0x00070707 ; //VALUE_ADDRMAP1 / addrmap_bank_b2:RW:16:4:=0x7 addrmap_bank_b1:RW:8:4:=0x7 addrmap_bank_b0:RW:0:4:=0x7
+ __REG( 0x00150208 ) = 0x00000000 ; //VALUE_ADDRMAP2 / addrmap_col_b5:RW:24:4:=0x0 addrmap_col_b4:RW:16:4:=0x0 addrmap_col_b3:RW:8:4:=0x0 addrmap_col_b2:RW:0:4:=0x0
+ __REG( 0x0015020c ) = 0x0f000000 ; //VALUE_ADDRMAP3 / addrmap_col_b9:RW:24:4:=0xf addrmap_col_b8:RW:16:4:=0x0 addrmap_col_b7:RW:8:4:=0x0 addrmap_col_b6:RW:0:4:=0x0
+ __REG( 0x00150210 ) = 0x00000f0f ; //VALUE_ADDRMAP4 / addrmap_col_b11:RW:8:4:=0xf addrmap_col_b10:RW:0:4:=0xf
+
+ }
+
+ if(flag == CHIP_DDR_IS_32M)
+ {
+ __REG( 0x00150214 ) = 0x04040404 ; //VALUE_ADDRMAP5 / addrmap_row_b11:RW:24:4:=0x6 addrmap_row_b2_10:RW:16:4:=0x6 addrmap_row_b1:RW:8:4:=0x6 addrmap_row_b0:RW:0:4:=0x6
+ __REG( 0x00150218 ) = 0x0f0f0f04 ; //VALUE_ADDRMAP6 / addrmap_row_b15:RW:24:4:=0xf addrmap_row_b14:RW:16:4:=0xf addrmap_row_b13:RW:8:4:=0xf addrmap_row_b12:RW:0:4:=0x6
+ }
+ else if(flag == CHIP_DDR_IS_64M)
+ {
+ __REG( 0x00150214 ) = 0x05050505 ; //VALUE_ADDRMAP5 / addrmap_row_b11:RW:24:4:=0x6 addrmap_row_b2_10:RW:16:4:=0x6 addrmap_row_b1:RW:8:4:=0x6 addrmap_row_b0:RW:0:4:=0x6
+ __REG( 0x00150218 ) = 0x0f0f0f05 ; //VALUE_ADDRMAP6 / addrmap_row_b15:RW:24:4:=0xf addrmap_row_b14:RW:16:4:=0xf addrmap_row_b13:RW:8:4:=0xf addrmap_row_b12:RW:0:4:=0x6
+ }
+
+ else if(flag == CHIP_DDR_IS_256M)
+ {
+ __REG( 0x00150214 ) = 0x06060606 ; //VALUE_ADDRMAP5 / addrmap_row_b11:RW:24:4:=0x6 addrmap_row_b2_10:RW:16:4:=0x6 addrmap_row_b1:RW:8:4:=0x6 addrmap_row_b0:RW:0:4:=0x6
+ __REG( 0x00150218 ) = 0x0f0f0606 ; //VALUE_ADDRMAP6 / addrmap_row_b15:RW:24:4:=0xf addrmap_row_b14:RW:16:4:=0xf addrmap_row_b13:RW:8:4:=0x6 addrmap_row_b12:RW:0:4:=0x6
+ }
+ else
+ {
+ __REG( 0x00150214 ) = 0x06060606 ; //VALUE_ADDRMAP5 / addrmap_row_b11:RW:24:4:=0x6 addrmap_row_b2_10:RW:16:4:=0x6 addrmap_row_b1:RW:8:4:=0x6 addrmap_row_b0:RW:0:4:=0x6
+ __REG( 0x00150218 ) = 0x0f0f0f06 ; //VALUE_ADDRMAP6 / addrmap_row_b15:RW:24:4:=0xf addrmap_row_b14:RW:16:4:=0xf addrmap_row_b13:RW:8:4:=0xf addrmap_row_b12:RW:0:4:=0x6
+ }
+ __REG( 0x00150240 ) = 0x04000400 ; //VALUE_ODTCFG / wr_odt_hold:RW:24:4:=0x4 wr_odt_delay:RW:16:4:=0x0 rd_odt_hold:RW:8:4:=0x4 rd_odt_delay:RW:2:4:=0x0
+ __REG( 0x00150244 ) = 0x00000000 ; //VALUE_ODTMAP / rank3_rd_odt:RW:28:4:=0x0 rank3_wr_odt:RW:24:4:=0x0 rank2_rd_odt:RW:20:4:=0x0 rank2_wr_odt:RW:16:4:=0x0 rank1_rd_odt:RW:12:4:=0x0 rank1_wr_odt:RW:8:4:=0x0 rank0_rd_odt:RW:4:4:=0x0 rank0_wr_odt:RW:0:4:=0x0
+ __REG( 0x00150250 ) = 0x00001805 ; //VALUE_SCHED / rdwr_idle_gap:RW:24:7:=0x0 go2critical_hysteresis:RW:16:8:=0x0 lpr_num_entries:RW:8:6:=0x18 pageclose:RW:2:1:=0x1 prefer_write:RW:1:1:=0x0 force_low_pri_n:RW:0:1:=0x1
+ __REG( 0x00150254 ) = 0x00000000 ; //VALUE_SCHED1 / pageclose_timer:RW:0:8:=0x0
+
+ __REG( 0x00150300 ) = 0x00000000 ; //VALUE_DBG0 / dis_collision_page_opt:RW:4:1:=0x0 dis_act_bypass:RW:2:1:=0x0 dis_rd_bypass:RW:1:1:=0x0 dis_wc:RW:0:1:=0x0
+ __REG( 0x00150304 ) = 0x00000000 ; //VALUE_DBG1 / dis_dq:RW:1:1:=0x0 dis_hig:RW:0:1:=0x0
+ __REG( 0x0015030c ) = 0x00000000 ; //VALUE_DBGCMD / ctrlupd:RWSC:5:1:=0x0 zq_calib_short:RWSC:4:1:=0x0 rank3_refresh:RWSC:3:1:=0x0 rank2_refresh:RWSC:2:1:=0x0 rank1_refresh:RWSC:1:1:=0x0 rank0_refresh:RWSC:0:1:=0x0
+
+ __REG( 0x00150400 ) = 0x00000000 ; //VALUE_PCCFG / bl_exp_mode:RW:8:1:=0x0 pagematch_limit:RW:1:1:=0x0 go2critical_en:RW:0:1:=0x0
+
+ return 0;
+
+}
+
+int ddr_prio_init(int flag)
+{
+ //port read static priority bit0-9, bit0-4 timeout, bit5-9 priority
+ __REG( 0x00150404 ) = 0x000013ff ; //VALUE_PCFGR_0 / rdwr_ordered_en:RW:16:1:=0x0 rd_port_pagematch_en:RW:14:1:=0x0 rd_port_urgent_en:RW:13:1:=0x0 rd_port_aging_en:RW:12:1:=0x1 read_reorder_bypass_en:RW:11:1:=0x0 rd_port_priority:RW:0:10:=0x3ff
+ __REG( 0x001504b4 ) = 0x00001020 ; //VALUE_PCFGR_1 / rdwr_ordered_en:RW:16:1:=0x0 rd_port_pagematch_en:RW:14:1:=0x0 rd_port_urgent_en:RW:13:1:=0x0 rd_port_aging_en:RW:12:1:=0x1 read_reorder_bypass_en:RW:11:1:=0x0 rd_port_priority:RW:0:10:=0x20
+ __REG( 0x00150564 ) = 0x00001000 ; //VALUE_PCFGR_2 / rdwr_ordered_en:RW:16:1:=0x0 rd_port_pagematch_en:RW:14:1:=0x0 rd_port_urgent_en:RW:13:1:=0x0 rd_port_aging_en:RW:12:1:=0x1 read_reorder_bypass_en:RW:11:1:=0x0 rd_port_priority:RW:0:10:=0x0
+ __REG( 0x00150614 ) = 0x00001004 ; //VALUE_PCFGR_3 / rdwr_ordered_en:RW:16:1:=0x0 rd_port_pagematch_en:RW:14:1:=0x0 rd_port_urgent_en:RW:13:1:=0x0 rd_port_aging_en:RW:12:1:=0x1 read_reorder_bypass_en:RW:11:1:=0x0 rd_port_priority:RW:0:10:=0x4
+ //port write static priority bit0-9
+ __REG( 0x00150408 ) = 0x000013ff ; //VALUE_PCFGW_0 / wr_port_pagematch_en:RW:14:1:=0x0 wr_port_urgent_en:RW:13:1:=0x0 wr_port_aging_en:RW:12:1:=0x1 wr_port_priority:RW:0:10:=0x3ff
+ __REG( 0x001504b8 ) = 0x000010ff ; //VALUE_PCFGW_1 / wr_port_pagematch_en:RW:14:1:=0x0 wr_port_urgent_en:RW:13:1:=0x0 wr_port_aging_en:RW:12:1:=0x1 wr_port_priority:RW:0:10:=0xff
+ __REG( 0x00150568 ) = 0x0000103f ; //VALUE_PCFGW_2 / wr_port_pagematch_en:RW:14:1:=0x0 wr_port_urgent_en:RW:13:1:=0x0 wr_port_aging_en:RW:12:1:=0x1 wr_port_priority:RW:0:10:=0x3f
+ __REG( 0x00150618 ) = 0x0000105f ; //VALUE_PCFGW_3 / wr_port_pagematch_en:RW:14:1:=0x0 wr_port_urgent_en:RW:13:1:=0x0 wr_port_aging_en:RW:12:1:=0x1 wr_port_priority:RW:0:10:=0x5f
+ //port read region set
+ __REG( 0x00150494 ) = 0x0020000e ; //VALUE_PCFGQOS0_0 / rqos_map_region2:RW:24:2:=0x0 rqos_map_region1:RW:20:2:=0x2 rqos_map_region0:RW:16:2:=0x0 rqos_map_level2:RW:8:4:=0x0 rqos_map_level1:RW:0:4:=0xe
+ __REG( 0x00150544 ) = 0x0020000e ; //VALUE_PCFGQOS0_1 / rqos_map_region2:RW:24:2:=0x0 rqos_map_region1:RW:20:2:=0x2 rqos_map_region0:RW:16:2:=0x0 rqos_map_level2:RW:8:4:=0x0 rqos_map_level1:RW:0:4:=0xe
+ __REG( 0x001505f4 ) = 0x0020000e ; //VALUE_PCFGQOS0_2 / rqos_map_region2:RW:24:2:=0x0 rqos_map_region1:RW:20:2:=0x2 rqos_map_region0:RW:16:2:=0x0 rqos_map_level2:RW:8:4:=0x0 rqos_map_level1:RW:0:4:=0xe
+ __REG( 0x001506a4 ) = 0x0020000e ; //VALUE_PCFGQOS0_3 / rqos_map_region2:RW:24:2:=0x0 rqos_map_region1:RW:20:2:=0x2 rqos_map_region0:RW:16:2:=0x0 rqos_map_level2:RW:8:4:=0x0 rqos_map_level1:RW:0:4:=0xe
+ //port write region set
+ __REG( 0x0015049c ) = 0x00000000 ; //VALUE_PCFGWQOS0_0 / wqos_map_region1:RW:20:2:=0x0 wqos_map_region0:RW:16:2:=0x0 wqos_map_level:RW:0:4:=0x0
+ __REG( 0x0015054c ) = 0x00000000 ; //VALUE_PCFGWQOS0_1 / wqos_map_region1:RW:20:2:=0x0 wqos_map_region0:RW:16:2:=0x0 wqos_map_level:RW:0:4:=0x0
+ __REG( 0x001505fc ) = 0x00000000 ; //VALUE_PCFGWQOS0_2 / wqos_map_region1:RW:20:2:=0x0 wqos_map_region0:RW:16:2:=0x0 wqos_map_level:RW:0:4:=0x0
+ __REG( 0x001506ac ) = 0x00000000 ; //VALUE_PCFGWQOS0_3 / wqos_map_region1:RW:20:2:=0x0 wqos_map_region0:RW:16:2:=0x0 wqos_map_level:RW:0:4:=0x0
+ //vpr timeout, region2 is red queue
+ __REG( 0x00150498 ) = 0x00000000 ; //VALUE_PCFGQOS1_0 / rqos_map_timeoutr:RW:16:11:=0x0 rqos_map_timeoutb:RW:0:11:=0x0
+ __REG( 0x00150548 ) = 0x00000000 ; //VALUE_PCFGQOS1_1 / rqos_map_timeoutr:RW:16:11:=0x0 rqos_map_timeoutb:RW:0:11:=0x0
+ __REG( 0x001505f8 ) = 0x00000000 ; //VALUE_PCFGQOS1_2 / rqos_map_timeoutr:RW:16:11:=0x0 rqos_map_timeoutb:RW:0:11:=0x0
+ __REG( 0x001506a8 ) = 0x00000000 ; //VALUE_PCFGQOS1_3 / rqos_map_timeoutr:RW:16:11:=0x0 rqos_map_timeoutb:RW:0:11:=0x0
+ //vpw timeout
+ __REG( 0x001504a0 ) = 0x00000000 ; //VALUE_PCFGWQOS1_0 / wqos_map_timeout:RW:0:11:=0x0
+ __REG( 0x00150550 ) = 0x00000000 ; //VALUE_PCFGWQOS1_1 / wqos_map_timeout:RW:0:11:=0x0
+ __REG( 0x00150600 ) = 0x00000000 ; //VALUE_PCFGWQOS1_2 / wqos_map_timeout:RW:0:11:=0x0
+ __REG( 0x001506b0 ) = 0x00000000 ; //VALUE_PCFGWQOS1_3 / wqos_map_timeout:RW:0:11:=0x0
+ //in CAM set
+ __REG( 0x0015025c ) = 0x0f000001 ; //VALUE_PERFHPR1 / hpr_xact_run_length:RW:24:8:=0xf hpr_max_starve:RW:0:16:=0x1
+ __REG( 0x00150264 ) = 0x0f00007f ; //VALUE_PERFLPR1 / lpr_xact_run_length:RW:24:8:=0xf lpr_max_starve:RW:0:16:=0x7f
+ __REG( 0x0015026c ) = 0x0f00007f ; //VALUE_PERFWR1 / w_xact_run_length:RW:24:8:=0xf w_max_starve:RW:0:16:=0x7f
+ __REG( 0x00150274 ) = 0x00000000 ; //VALUE_PERFVPR1 / vpr_timeout_range:RW:0:11:=0x0
+ __REG( 0x00150278 ) = 0x00000000 ; //VALUE_PERFVPW1 / vpw_timeout_range:RW:0:11:=0x0
+ //port extern static priority
+ //__REG( 0x0013d034 ) = 0xf0f00000 ; //port0,1 rqos=0(LPR); port2,3 rqos=F(HPR)
+
+ return 0;
+
+}
+
+int ddr_init(int flag)
+{
+ UINT32 g_PhyJZ[6]={0};
+
+ //__REG( 0x01306100 ) = 0xffffe000 ; //ddr all reset enable bit6-12=0
+ __REG( 0x01306100 ) = 0x0affe000 ; //ddr all reset enable bit6-12=0
+ nsdelay(200000);//0.01s
+ __REG( 0x01306100 ) = 0x0affe400 ; //release ddr apb(bit10)
+ nsdelay(200000);//0.01s
+
+ //ddr clk init
+ ddr_clk_init(flag);
+
+ //phy register init
+ ddr_phy_init(flag);
+
+ //controller register init
+ ddr_ctrl_init(flag);
+
+ //ddr_priority_config
+ ddr_prio_init(flag);
+
+ //wait all register configer done in hardware
+ nsdelay(200000);//0.01s
+
+
+ //***********************************************************
+ //ctroller and inno phy registers configer done
+ //***********************************************************
+ __REG( 0x01306100 ) = 0x0affffc0 ; //release ddr ctl(bit11) and axi_sn reset(bit6-9) and phy reset(bit12) ; //ÉèÖÃϵͳ¼Ä´æÆ÷Öµ
+ nsdelay(200000);//0.01s
+
+
+ //sw config done
+ __REG( 0x00150320 ) = 0x00000000 ; //SWCTL ; // sw_done:RW:0:1:=0x0
+ //check phy auto init done, wait 0x00150324 bit0 =0
+ nsdelay(200000);//0.01s
+
+
+ //power on PHY PLL
+ __REG( 0x001543b4 ) = 0x00000018 ; //PHYREGED,PLLCLKOUTEN:RW:4:1:=0x1,Reserved:RW:2:2:=0x2, pll_pd_en:RW:1:1:=0x0, fbdiv[8]:RW:0:1:=0x0
+ //wait PHY PLL lock,PHYREGF8[0]Pll lock indicate signal
+
+ nsdelay(200000);//0.01s
+
+
+ //PHY DLL init start, fall edge trigger
+ if(flag == CHIP_DDR_IS_32M)
+ {
+ #ifndef _DDR32M_DS_48om //60ohm
+ __REG( 0x0015417c ) = 0x00000004 ; //PHYREG5F, PHY init start:5:1:=0x1
+ #else //48ohm
+ __REG( 0x0015417c ) = 0x00000005 ; //PHYREG5F, PHY init start:5:1:=0x1
+ #endif
+ }
+ else
+ {
+ #ifndef _DDR_DS_48om //60ohm
+ __REG( 0x0015417c ) = 0x00000004 ; //PHYREG5F, PHY init start:5:1:=0x1
+ #else //48ohm
+ __REG( 0x0015417c ) = 0x00000005 ; //PHYREG5F, PHY init start:5:1:=0x1
+ #endif
+ }
+ //wait dll lock, phy init done, PHYREGF8[1]Phy init complete signal
+ nsdelay(200000);//0.01s
+
+
+ //enable controller dfi_init_complete_en to start sdram init, then will send dram init cmd
+ __REG( 0x001501b0 ) = 0x00000001 ; //DFIMISC ; // phy_dbi_mode:RW:1:1:=0x0 dfi_init_complete_en:RW:0:1:=0x1 ÊÇ·ñÈ¥µô£¬»òÕß¶ÔÓ¦ÐÞ¸Ä
+ //check controller status is sdram init done,wait 0x00150004 bit0-2 !=0
+ nsdelay(200000);//0.01s
+
+ __REG( 0x001501b0 ) = 0x00000000 ; //dfimisc[0] phy_dbi_mode:RW:1:1:=0x0 dfi_init_complete_en:RW:0:1:=0x0
+
+ if(flag == CHIP_DDR_IS_32M)
+ {
+ do
+ {
+ //phy DQS gate training start
+ __REG( 0x00154008 ) = 0x00000001 ; //PHYREG02,bit0:DQS gating calibration control=1, bit1:DQS gating bypass mode select=0
+ //wait training done
+ nsdelay(200000);//0.01s
+
+ //phy DQS gate training stop
+ __REG( 0x00154008 ) = 0x00000000 ; //PHYREG02,bit0:DQS gating calibration control=0, bit1:DQS gating bypass mode select=0
+
+ nsdelay(200000);//0.01s
+ g_PhyJZ[0]=ABSa_b(__REG(0x001543ec),__REG(0x001543f0));
+
+ }while((g_PhyJZ[0]>4)|(__REG(0x001543ec)&0x80));
+ }
+ else
+ {
+ do
+ {
+ //phy DQS gate training start
+ __REG( 0x00154008 ) = 0x00000001 ; //PHYREG02,bit0:DQS gating calibration control=1, bit1:DQS gating bypass mode select=0
+ //wait training done
+ nsdelay(200000);//0.01s
+
+ //phy DQS gate training stop
+ __REG( 0x00154008 ) = 0x00000000 ; //PHYREG02,bit0:DQS gating calibration control=0, bit1:DQS gating bypass mode select=0
+
+ nsdelay(200000);//0.01s
+ g_PhyJZ[0]=ABSa_b(__REG(0x001543ec),__REG(0x001543f0));
+ g_PhyJZ[1]=ABSa_b(__REG(0x001543ec),__REG(0x001543f4));
+ g_PhyJZ[2]=ABSa_b(__REG(0x001543ec),__REG(0x001543f8));
+
+ g_PhyJZ[3]=ABSa_b(__REG(0x001543f0),__REG(0x001543f4));
+ g_PhyJZ[4]=ABSa_b(__REG(0x001543f0),__REG(0x001543f8));
+
+ g_PhyJZ[5]=ABSa_b(__REG(0x001543f4),__REG(0x001543f8));
+ }while((g_PhyJZ[0]>4)|(g_PhyJZ[1]>4)|(g_PhyJZ[2]>4)|(g_PhyJZ[3]>4)|(g_PhyJZ[4]>4)|(g_PhyJZ[5]>4)|(__REG(0x001543ec)&0x80));
+ }
+
+ //enable port_n
+ __REG( 0x00150490 ) = 0x00000001 ; //VALUE_PCTRL_0 / port_en:RW:0:1:=0x1
+ __REG( 0x00150540 ) = 0x00000001 ; //VALUE_PCTRL_1 / port_en:RW:0:1:=0x1
+ __REG( 0x001505f0 ) = 0x00000001 ; //VALUE_PCTRL_2 / port_en:RW:0:1:=0x1
+ __REG( 0x001506a0 ) = 0x00000001 ; //VALUE_PCTRL_3 / port_en:RW:0:1:=0x1
+
+#ifdef DDR_FFC
+ ddr_ffc_init();
+#endif
+ return 0;
+
+}
+
+
diff --git a/boot/common/src/loader/drivers/debug.c b/boot/common/src/loader/drivers/debug.c
new file mode 100644
index 0000000..d295abc
--- /dev/null
+++ b/boot/common/src/loader/drivers/debug.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2016 ZXIC Inc.
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/gpio.h>
+#include <load_mode.h>
+#include <asm/arch/top_clock.h>
+#include <asm/arch/cpu.h>
+#include <board.h>
+#include <jtag.h>
+
+#if _ZLOADER_TRACE_DEBUG
+
+uint32_t patch = 0; /* ûÓÐÈκÎ×÷Óã¬ÓÃÀ´ÅäºÏBSS¶ÎÇåÁã */
+
+void debug_config(void)
+{
+ unsigned int tmp = 0;
+ int ret = 0;
+ patch = patch;
+
+/*¿½±´½Å±¾µÄʱÖÓ³õʼ»¯*/
+#ifdef CONFIG_BOARD_7520_UFI
+ /*
+ * Jtag0
+ * 0:M0Jtag, 1:function, 2:gpio, 3:psJtag, 4:phyJtag, 5:dspJtag, 6:ufiJtag, 7:gpio
+ */
+
+ #ifdef CONFIG_BOARD_7520_JTAG0_M0
+#define JTAG0_CONNECT 0
+ #endif
+
+ #ifdef CONFIG_BOARD_7520_JTAG0_PS
+#define JTAG0_CONNECT 3
+ #endif
+ tmp = __REG(0x00143030);
+ tmp &= 0xff0000f0;
+ tmp |= JTAG0_CONNECT|(JTAG0_CONNECT<<8)|(JTAG0_CONNECT<<12)|(JTAG0_CONNECT<<16)|(JTAG0_CONNECT<<20);
+ __REG(0x00143030) = tmp;
+
+ __REG(0x100000) = 0xeafffffe; /*ps release*/
+ writel(CPU_UFI_SW_RSTEN, CPU_R7_SUBSYS_CFG);
+#endif
+
+ /*
+ * D0/Jtag1
+ * 0:gpio, 1:sd0, 2:M0Jtag, 3:psJtag, 4:phyJtag, 5:dspJtag, 6:ufiJtag, 7:testpin
+ */
+#ifdef CONFIG_BOARD_7520_EVB
+#define JTAG1_CONNECT 3
+ tmp=__REG(0x00143028);
+ tmp=tmp&0xf0000ff0|0x03333003;
+ __REG(0x00143028) = tmp;
+
+ __REG(0x100000) = 0xeafffffe; /*ps release*/
+ writel(CPU_UFI_SW_RSTEN, CPU_R7_SUBSYS_CFG);
+#endif
+
+#if 0
+ /* ps */
+ __REG(SYS_IRAM2_BASE) = 0xEAFFFFFE; /* while(1) */
+ __REG(CPU_PS_SUBSYS_CFG) = CPU_PS_SW_RSTEN;
+
+ /* phy */
+ __REG(SYS_IRAM3_BASE) = 0xEAFFFFFE; /* while(1) */ /* while(1) */
+ __REG(CPU_PHY_SUBSYS_CFG) = CPU_PHY_SW_RSTEN;
+
+ /* A9 */
+ __REG(SYS_IRAM6_BASE) = 0xEAFFFFFE; /* while(1) */
+ __REG(CPU_UFI_SUBSYS_CFG) = CPU_UFI_SW_RSTEN;
+
+ /* release core reset */
+ __REG(0x0010c044) = 1; // phy
+ __REG(0x0010c048) = 1; // ps
+ __REG(0x0010c04c) = 1; // ufi
+ __REG(0x0010c050) = 1; // zsp
+
+ ret = nand_init();
+ if( ret != 0 )
+ while(1);
+
+ ddr_init();
+
+#ifdef CONFIG_BOARD_7520_EVB
+ /*light gpio9*/
+ tmp = __REG(0x10d440); /* ¹¦ÄÜÒý½Å */
+ tmp |= (0x1 << 24);
+ __REG(0x10d440) = tmp;
+
+
+ tmp = __REG(0x10dC04); /* config OUT */
+ tmp &= (~(0x1<<9));
+ __REG(0x10dC04) = tmp;
+
+ tmp = __REG(0x10dC08);
+ tmp |= (0x1<<9); /* OUT 1 */
+ __REG(0x10dC08) = tmp;
+#endif
+#endif
+ while(1);
+}
+
+#endif
diff --git a/boot/common/src/loader/drivers/denali.c b/boot/common/src/loader/drivers/denali.c
new file mode 100644
index 0000000..f4ddfd9
--- /dev/null
+++ b/boot/common/src/loader/drivers/denali.c
@@ -0,0 +1,496 @@
+/*
+ * (C) Copyright 2016 ZXIC Inc.
+ */
+
+
+#include <common.h>
+#include <asm/arch/denali.h>
+#include <asm/io.h>
+#include <bbt.h>
+
+#include "flash.h"
+
+
+static struct nand_flash_device_para *nand_info = NULL;
+/* nand flash parameter config */
+static const struct nand_flash_device_para nand_flash_para[] = {
+ /* MT29F4G08ABBDAH4 for 7520V5 evb 512MB X 8 */
+ {0x2C, 0xAC, 0x90, 0, 4, 2048,11, 64, 17, 4096, 0x20000},
+ /* MT29F2G08ABBEA for 7520 evb 256MB X 8 */
+ {0x2C, 0xAA, 0x90, 0, 4, 2048,11, 64, 17, 2048, 0x20000},
+
+ /* K9F2G08U0B for 7520 FPGA */
+ {0xEC, 0xDA, 0x10, 0, 4, 2048,11, 64, 17,2048, 0x20000},
+
+ /* JSFBA3YHABB for 7510 evb 256MB X 8 ---> DDR 128M*/
+ {0xAD, 0xAA, 0x90, 0, 8, 2048, 11, 128, 17,2048, 0x20000},
+
+ /* FM6BD2G1GA for 7510 evb 256MB X 8 ---> DDR 128M */
+ {0xC8, 0xAA, 0x90, 0, 4, 2048, 11, 64, 17, 2048, 0x20000},
+
+ /* H9TA4GG4GDMCPR for 7510 evb 512MB X 8 ---> DDR 512M */
+ {0xAD, 0xAC, 0x90, 0, 8, 2048, 11, 128, 17, 4096, 0x20000},
+
+ /* JSFCBX3Y7ABB for 7510 evb 512MB X 8 ---> DDR 256M */
+ {0x01, 0xAC, 0x90, 0, 8, 2048, 11, 128, 17, 4096, 0x20000},
+
+ /* FM6BD4G2GA for 7510 evb 512MB X 8 ---> DDR 256M*/
+ {0xC8, 0xAC, 0x90, 0, 4, 2048, 11, 64, 17, 4096, 0x20000},
+
+ /* NM1281KSLAXAJ for 7510 evb 256MB X 8 ---> DDR 128M*/
+ {0x98, 0xAA, 0x90, 0, 8, 2048, 11, 128, 17, 2048, 0x20000},
+
+ /* W71NW20GF3FW for 7520 evb 256MB X 8 */
+ {0xEF, 0xAA, 0x90, 0, 4, 2048,11, 64, 17, 2048, 0x20000},
+ {0}
+};
+
+
+
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ static uint32_t wait_for_ready(uint32_t status_type)
+{
+ uint32_t status = 0;
+ while (!(readl(INTR_STATUS(0)) & status_type));
+ status = readl(INTR_STATUS(0));
+ writew(0xffff, INTR_STATUS(0));
+ return status;
+}
+
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+static void index_addr(uint32_t address, uint32_t data)
+{
+ writel(address, NAND_DATA);
+ writel(data, NAND_DATA_10);
+}
+
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+static void index_addr_read_data(uint32_t address, uint32_t *pdata)
+{
+ writel(address, NAND_DATA);
+ *pdata = readl(NAND_DATA_10);
+}
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+void nand_read_oob(uint8_t *buf, uint32_t offset, uint32_t len)
+{
+ uint32_t cmd, i, status_type;
+ uint32_t *buf32 = NULL;
+ uint32_t addr = offset >> (nand_info->page_size_shift); //addr = bank0 | page
+
+ /* 0. disable ECC */
+ writel(ECC_DISABLE__FLAG, ECC_ENABLE);
+
+ writel(0xffff, INTR_STATUS(0));
+
+ writel(TRANSFER_SPARE_REG__FLAG, TRANSFER_SPARE_REG);
+
+ /* setup page read request for SPARE_ACCESS read */
+ cmd = MODE_10 | addr;
+ index_addr((uint32_t)cmd, SPARE_ACCESS);
+
+ cmd = MODE_10 | addr;
+ index_addr((uint32_t)cmd, 0x2001);
+
+ /* page 33 of the NAND controller spec indicates we should not
+ use the pipeline commands in Spare area only mode. So we
+ don't.
+ */
+ cmd = MODE_01 | addr;
+ writel(cmd, NAND_DATA);
+
+ status_type = wait_for_ready(INTR_STATUS__LOAD_COMP | INTR_STATUS__TIME_OUT);
+ if (status_type & INTR_STATUS__TIME_OUT)
+ printf("[OT]\n"); /* OOB TIMEOUT */
+
+ /* 0. read oob data */
+ buf32 = (uint32_t *)buf;
+ for (i = 0; i < len / 4; i++)
+ *buf32++ = readl(NAND_DATA_10);
+
+ /* We set the device back to MAIN_ACCESS here as I observed
+ * instability with the controller if you do a block erase
+ * and the last transaction was a SPARE_ACCESS. Block erase
+ * is reliable (according to the MTD test infrastructure)
+ * if you are in MAIN_ACCESS.
+ */
+ cmd = MODE_10 | addr;
+ index_addr((uint32_t)cmd, MAIN_ACCESS);
+
+}
+
+
+void clear_intr(void)
+{
+ while(readl(INTR_STATUS(0)))
+ {
+ writew(0xffff, INTR_STATUS(0));
+
+ }
+ writew(0xffff, INTR_STATUS(0));
+
+ nsdelay(400000);//0.02s
+}
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int32_t read_page(uint32_t buf, uint32_t offset)
+{
+ uint32_t status = 0;
+ int32_t ecc_status = 0;
+ uint32_t page = offset >> (nand_info->page_size_shift);
+ uint32_t mode = MODE_10; /* MODE_10 | BANK(denali->flash_bank) */
+
+ if((buf & 0x3) != 0) /* DMAµØÖ·ÒªÇó4×Ö½Ú¶ÔÆë */
+ {
+ printf("[AE]\n"); /* [read_page]:ADDR ERROR */
+ return -1;
+ }
+
+ ecc_status =readl(ECC_CORRECTION);
+
+ if(page < 64)
+ {
+ writel(0x8, ECC_CORRECTION);
+ }
+
+ /* clear status */
+ writew(0xffff, INTR_STATUS(0));
+
+ writel(TRANSFER_MAIN_REG__FLAG, TRANSFER_SPARE_REG);
+
+ /* enable DMA */
+ writel(DMA_ENABLE__FLAG, DMA_ENABLE);
+
+ /* setup transfer type and # of pages -FOR DMA */
+ index_addr(mode | page, 0x2001); //mode10(0x08000000) | bank0(0) | page,
+ // 0x2000 | DENALI_READ(0) | 1
+
+ /* set memory high address bits 23:8 -FOR DMA */
+ index_addr(mode | ((uint16_t)(buf >> 16) << 8), 0x2200);
+
+ /* set memory low address bits 23:8 -FOR DMA */
+ index_addr(mode | ((uint16_t)buf << 8), 0x2300);
+
+ /* interrupt when complete, burst len = 64 bytes -FOR DMA*/
+ index_addr( mode | 0x14000, 0x2400); //zhouqi not interrupt 0X40
+
+ /* wait_for_ready */
+ status = wait_for_ready (INTR_STATUS__DMA_CMD_COMP | INTR_STATUS__ECC_ERR);
+ if (status & INTR_STATUS__ECC_ERR )
+ {
+ printf("[EE]\n"); /* [read_page]: ECC ERROR */
+ /* 0. clear status */
+ clear_intr();
+ return -1;
+ }
+
+
+ if (status & INTR_STATUS__TIME_OUT)
+ {
+ printf("TO\n"); /* [read_page]: TIME OUT */
+ /* clear status */
+ clear_intr();
+ return -1;
+ }
+
+ writel(ecc_status, ECC_CORRECTION);
+
+ /* disable DMA */
+ writel(DMA_DISABLE__FLAG, DMA_ENABLE);
+
+ return 0;
+}
+
+
+/*******************************************************************************
+ * from: must page align
+ len: must page align
+ */
+ /*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int32_t nand_read(uint32_t from, uint32_t len, uint32_t to)
+{
+ uint32_t offset = from;
+ uint32_t left_to_read = len;
+ uint32_t p_to = to;
+ int32_t ret = 0;
+ int32_t page_size = (nand_info->page_size);
+
+ if((offset & (page_size - 1)) || (len & (page_size - 1)))
+ {
+ printf("param err.\n");
+ return -1;
+ }
+
+ while(left_to_read > 0)
+ {
+ ret = read_page(p_to, offset);
+ if(ret != 0)
+ {
+ return -1;
+ }
+
+ left_to_read -= page_size;
+ offset += page_size;
+ p_to += page_size;
+ }
+ return 0;
+}
+
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int32_t read_data(uint32_t from, uint32_t len, uint32_t to)
+{
+ uint32_t offset = from;
+ uint32_t left_to_read = len;
+ uint32_t p_to = to;
+ int32_t ret = 0;
+ int32_t block_size = (nand_info->block_size);
+
+ while( left_to_read > 0 )
+ {
+ uint32_t block_offset = offset & (block_size - 1);
+ uint32_t read_length;
+
+ if( nand_block_isbad(offset) )
+ {
+ offset += block_size;
+ continue;
+ }
+
+ if (left_to_read < (block_size - block_offset))
+ read_length = left_to_read;
+ else
+ read_length = block_size - block_offset;
+
+ ret = nand_read(offset, read_length, p_to);
+ if(ret != 0)
+ {
+ return -1;
+ }
+
+ left_to_read -= read_length;
+ offset += read_length;
+ p_to += read_length;
+ }
+
+ return 0;
+}
+
+
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ int32_t nand_read_id (void)
+{
+ uint32_t id[5];
+ uint32_t i = 0;
+ uint32_t addr = (uint32_t)MODE_11; /* | BANK(0) */
+ struct nand_flash_device_para *nand = &nand_flash_para[0];
+
+ index_addr(addr | 0, 0x90);
+ index_addr(addr | 1, 0);
+ for (i = 0; i < 5; i++)
+ {
+ index_addr_read_data(addr | 2, &id[i]);
+ }
+
+ i = 0;
+ while( nand->manuf_id != 0 )
+ {
+ if( ((uint8_t)id[0] == nand->manuf_id) &&
+ ((uint8_t)id[1] == nand->device_id) &&
+ ((uint8_t)id[2] == nand->res_id))
+ {
+ nand_info = nand;
+
+ writel(nand_info->bus_num, DEVICE_WIDTH);
+ writel(nand_info->page_size, DEVICE_MAIN_AREA_SIZE);
+ writel(nand_info->page_size, LOGICAL_PAGE_DATA_SIZE);
+ writel(nand_info->oob_size, DEVICE_SPARE_AREA_SIZE);
+ writel(nand_info->ecc_strength, ECC_CORRECTION);
+ return 0;
+ };
+ nand++;
+ i++;
+ }
+
+ return 1;
+}
+
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int32_t nand_init (void)
+{
+ int32_t ret = 0;
+ writel(ECC_DISABLE__FLAG, ECC_ENABLE); /* ecc_enable */
+ writel(2, SPARE_AREA_SKIP_BYTES);
+
+ ret = nand_read_id();
+ if( ret != 0 )
+ return -1;
+
+ flash.flash_type = NAND_BOOT;
+ flash.manuf_id = nand_info->manuf_id;
+ flash.device_id = nand_info->device_id;
+ flash.page_size = nand_info->page_size;
+ flash.page_size_shift = nand_info->page_size_shift;
+ flash.oob_size = nand_info->oob_size;
+ flash.block_size = nand_info->block_size;
+ flash.block_size_shift = nand_info->block_size_shift;
+ flash.block_num = nand_info->block_num;
+ flash.read = read_data;
+ flash.read_oob = nand_read_oob;
+
+ return 0;
+
+}
+
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+int board_flash_init(void)
+{
+ int ret = 0;
+ char boot_mode = 0;
+
+ boot_mode = get_boot_mode();
+ if(boot_mode != NAND_BOOT)
+ {
+ printf("not nand flash.\n");
+ return -1;
+ }
+
+ writel(CFG_START_MODE_NAND, CFG_BOOT_MODE_START_MODE_FOR_UBOOT);
+ ret = nand_init();
+ if(ret != 0)
+ {
+ printf("nand init err.\n");
+ return -1;
+ }
+ printf("nand init ok.\n");
+
+ nand_creat_bbt();
+
+ return 0;
+}
+
+
diff --git a/boot/common/src/loader/drivers/download.c b/boot/common/src/loader/drivers/download.c
new file mode 100644
index 0000000..9b47131
--- /dev/null
+++ b/boot/common/src/loader/drivers/download.c
@@ -0,0 +1,357 @@
+#include "global.h"
+#include <asm/arch/cpu.h>
+#include <asm/io.h>
+#include "common.h"
+
+#define ST_WAIT_SYNC_FLAG (0x0)
+#define ST_WAIT_REG_CONFIG (0x1)
+#define ST_REG_CONFIG (0x2)
+#define ST_WAIT_DOWNLOAD (0x3)
+#define ST_DOWNLOAD_HEAD (0x4)
+#define ST_DOWNLOAD_DATA (0x5)
+#define ST_DOWNLOAD_ADDR (0x6)
+
+#define SYNC_FLAG (0x5a) // "Z"
+#define REG_CONFIG_FLAG (0x6a) // ""
+#define DOWNLOAD_FLAG (0x7a) // "z"
+#define RUN_FLAG (0x8a) // ""
+#define GET_ID (0x9a) // new added
+
+extern void USB3Slave_boot(void);
+extern WORD32 usb_read(BYTE *pchBuf, WORD32 dwLen);
+extern WORD32 usb_write(BYTE *pchBuf, WORD32 dwLen);
+extern int UART_Read(char *pchBuf, int dwLen);
+extern int UART_Write(char *pchBuf, int dwLen);
+
+WORD32 Para_Section SyncACK=0xa5;
+__align(4) BYTE Para_Section CHIP_ID[8]={'Z','X','7','5','2','0','V','2'};
+WORD32 Para_Section UsbACK = 0;
+
+
+
+void Boot_Process(BYTE *pkt,int len)
+{
+ int i=0;
+ static int count=0;
+ static int addr;
+ static int value;
+ char cTmp=0;
+ //WORD32 SyncACK=0xa5;
+ int case_state;
+ if(0==len)
+ return ;
+ while(i<len)
+ {
+ cTmp=pkt[i++];
+
+ case_state = global.g_State;
+ if( ST_WAIT_SYNC_FLAG == case_state)
+ {
+ if(SYNC_FLAG==cTmp)
+ {
+ global.g_State=ST_WAIT_DOWNLOAD;
+#if CFG_USB
+ usb_write((BYTE *)&SyncACK,1);
+#else
+ UART_Write((BYTE *)&SyncACK,1);
+#endif
+ }
+ }
+ else if(ST_REG_CONFIG ==case_state)
+ {
+ if(count<4) // 4 bytes addr
+ {
+ addr<<=8;
+ addr|=cTmp;
+ }
+ else if(count<8) // 4 byte data
+ {
+ value<<=8;
+ value|=cTmp;
+ }
+
+ count++;
+
+ if(4==count)
+ {
+ if(0==addr)
+ {
+ global.g_State=ST_WAIT_DOWNLOAD;
+ UsbACK=0xA6;
+#if CFG_USB
+ usb_write(&UsbACK,1);
+#else
+ UART_Write(&UsbACK,1);
+#endif
+ }
+ }
+ else if(8==count)
+ {
+ REG32(addr)=value;
+ count=0;
+ }
+
+ }
+ else if (ST_WAIT_DOWNLOAD==case_state)
+ {
+ if(REG_CONFIG_FLAG==cTmp)
+ {
+ global.g_State=ST_REG_CONFIG;
+ count=0;
+ }
+ else if(DOWNLOAD_FLAG==cTmp)
+ {
+ global.g_State=ST_DOWNLOAD_HEAD;
+ count=0;
+ value=0;
+ }
+ else if(RUN_FLAG==cTmp) //Ö§³Ö¶à´ÎÏÂÔØ0818
+ {
+ global.g_State=ST_DOWNLOAD_ADDR;
+ count=0;
+ value=0;
+ }
+ }
+ else if( ST_DOWNLOAD_HEAD==case_state)
+ {
+ if(count<4) // 4 byte addr
+ {
+ addr<<=8;
+ addr|=cTmp;
+ }
+ else if(count<8) // 4 byte size
+ {
+ value<<=8;
+ value|=cTmp;
+ }
+
+ count++;
+
+ if(count==8)
+ {
+ count=0;
+ global.g_bootaddr=addr; //µØÖ·
+ global.g_bootsize=value;//³¤¶È
+ global.g_State=ST_DOWNLOAD_DATA;
+ UsbACK=0xA1;
+#if CFG_USB
+
+ usb_write(&UsbACK,1);
+#else
+ UART_Write(&UsbACK,1);
+#endif
+ }
+ }
+ else if( ST_DOWNLOAD_DATA==case_state)
+ {
+ if(global.g_bootsize==len)
+ {
+ if(global.g_bootaddr==(int)pkt)
+ {
+ global.g_State=ST_WAIT_DOWNLOAD;//Ö§³Ö¶à´ÎÏÂÔØ0818
+ UsbACK=0xA7;
+#if CFG_USB
+ usb_write(&UsbACK,1);
+#else
+ UART_Write(&UsbACK,1);
+#endif
+
+ return;
+ }
+ }
+ else
+ {
+ global.g_bootaddr+=len;
+ global.g_bootsize-=len;
+ return ;
+ }
+ }
+ else if( ST_DOWNLOAD_ADDR==case_state)
+ {
+ if(count<4) // 4 byte addr
+ {
+ addr<<=8;
+ addr|=cTmp;
+ }
+
+ count++;
+
+ if(count==4)
+ {
+ count=0;
+ global.g_bootaddr=addr;
+ global.g_bootfinish=1;
+ UsbACK=0xA8;
+#if CFG_USB
+ usb_write(&UsbACK,1);
+#else
+ UART_Write(&UsbACK,1);
+#endif
+ return ;
+ }
+ }
+ else
+ {
+
+ }
+
+ }
+
+}
+__align(4) BYTE Para_Section tmp[64]={0};
+
+void USB_Boot(void)
+{
+ WORD32 dwLen;
+ WORD32 dwMaxLen;
+ BYTE *pbyBuf;
+ printf("USB_Boot\n");
+ global.g_State = ST_WAIT_SYNC_FLAG;
+ pbyBuf = (BYTE*)tmp;
+
+ for(dwMaxLen = 0; dwMaxLen < 64; dwMaxLen++)
+ {
+ tmp[dwMaxLen] = 0;
+ }
+
+ dwMaxLen = 512; //¿ØÖÆÆ÷ÓÐÒªÇóbulk outʱ£¬½ÓÊÕ³¤¶È´óÓÚµÈÓÚ512
+/* µ±usb_mode =1ʱ£¬ÓÃÓÚHSIC,µ±usb_mode =0ʱ£¬ÓÃÓÚUSB */
+ if(global.g_USB_MODE == 0)
+ {
+ dwLen=USB_Check_Sync(pbyBuf,dwMaxLen);
+
+ if(0==dwLen)
+ {
+ return ;
+ }
+
+ Boot_Process(pbyBuf,dwLen);
+ }
+ while(0 == global.g_bootfinish)
+ {
+ dwLen=usb_read(pbyBuf,dwMaxLen);
+
+ Boot_Process(pbyBuf,dwLen);
+
+ if((ST_DOWNLOAD_DATA==global.g_State)&&(global.g_bootaddr!=0))
+ {
+ pbyBuf=(BYTE *)global.g_bootaddr;
+ dwMaxLen= 512;//global.g_bootsize;
+ }
+ else
+ {
+ pbyBuf=tmp;
+ dwMaxLen=512;//½ÓÊÕµØÖ·£¬³¤¶ÈÐÅÏ¢
+ }
+
+ }
+
+ if(1==global.g_bootfinish)
+ {
+#if 0 /*shield dma function*/
+ dwc_otg_core_dev_disconnet(global.g_dwc_otg_pcd_tp.core_if);
+ printf("disconnect usb controller\n");
+#endif
+ writel(0xE59ff000, SYS_IRAM1_BASE); /* Ìø×ªµ½r7Ö´ÐÐtboot */
+ writel(global.g_bootaddr, SYS_IRAM1_BASE + 8);
+ printf("Starting the tboot...\n");
+ writel(0xf, CPU_A9_SUBSYS_CFG);
+ }
+}
+
+void usb_boot(WORD32 USB_ADDR)
+{
+ global.g_USB_TIMEOUT = 0xff;
+
+ //USB3Slave_boot();
+ tsp_usb_init();
+
+ USB_Boot(); /*usb bootÏÂÔØÄ£Ê½*/
+}
+
+
+
+/*******************************************************************************
+ * Function: uart_boot
+ * Description: download from uart-bootrom
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+
+void UART_Boot(void)
+{
+ WORD32 dwLen;
+ WORD32 dwMaxLen;
+ BYTE *pbyBuf;
+ printf("UART_Boot\n");
+ global.g_State = ST_WAIT_SYNC_FLAG;
+ pbyBuf = (BYTE*)tmp;
+
+ for(dwMaxLen = 0; dwMaxLen < 64; dwMaxLen++)
+ {
+ tmp[dwMaxLen] = 0;
+ }
+
+ dwMaxLen = 512; //¿ØÖÆÆ÷ÓÐÒªÇóbulk outʱ£¬½ÓÊÕ³¤¶È´óÓÚµÈÓÚ512
+/* µ±usb_mode =1ʱ£¬ÓÃÓÚHSIC,µ±usb_mode =0ʱ£¬ÓÃÓÚUSB */
+ if(global.g_USB_MODE == 0)
+ {
+ dwLen=UART_Check_Sync(pbyBuf,dwMaxLen);
+
+ if(0==dwLen)
+ {
+ return ;
+ }
+
+ Boot_Process(pbyBuf,dwLen);
+ }
+ while(0 == global.g_bootfinish)
+ {
+
+ dwLen=UART_Read(pbyBuf,1); //0x7a uart
+ if(*pbyBuf == 0x7a)
+ {
+ dwLen=UART_Read(pbyBuf,4);
+ global.g_bootaddr = pbyBuf[3]|pbyBuf[2]<<8|pbyBuf[1]<<16|pbyBuf[0]<<24;
+
+ dwLen=UART_Read(pbyBuf,4);
+ global.g_bootsize = pbyBuf[3]|pbyBuf[2]<<8|pbyBuf[1]<<16|pbyBuf[0]<<24;
+ }
+
+ dwLen=UART_Read(global.g_bootaddr,global.g_bootsize);
+ dwLen=UART_Read(pbyBuf,1); //0x8a
+ if(*pbyBuf == 0x8a)
+ {
+ global.g_bootfinish = 1;
+ dwLen=UART_Read(pbyBuf,4);
+ global.g_bootaddr = pbyBuf[3]|pbyBuf[2]<<8|pbyBuf[1]<<16|pbyBuf[0]<<24;
+ }
+
+ }
+
+ if(1==global.g_bootfinish)
+ {
+
+ writel(0xE59ff000, SYS_IRAM1_BASE); /* Ìø×ªµ½r7Ö´ÐÐtboot */
+ writel(global.g_bootaddr, SYS_IRAM1_BASE + 8);
+ printf("Starting the tboot ...\n");
+ writel(0xf, CPU_A9_SUBSYS_CFG);
+ }
+}
+
+
+void uart_boot(void)
+{
+ global.g_USB_TIMEOUT = 0xff;
+
+ UART_Boot(); /*uart bootÏÂÔØÄ£Ê½*/
+}
+
+
diff --git a/boot/common/src/loader/drivers/drv_hash.c b/boot/common/src/loader/drivers/drv_hash.c
new file mode 100644
index 0000000..3d89edb
--- /dev/null
+++ b/boot/common/src/loader/drivers/drv_hash.c
@@ -0,0 +1,162 @@
+/* -------------------------------------------------------------------------------------------------------------------@udN
+ * °æÈ¨ËùÓÐ(C)2012, ÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾
+ *
+ * ÎÄ ¼þ Ãû: drv_hash.c
+ *
+------------------------------------------------------------------------------------------------------------*/
+
+#include "drv_hash.h"
+#include <sdio.h>
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ *Hash_set_len ¹¦ÄÜÏêÊö:
+ ½«ÏûÏ¢³¤¶ÈÒÔbitΪµ¥Î»ÅäÖõ½³¤¶È¼Ä´æÆ÷ÖÐ
+ --------------------------------------------------------------
+ ×¢Òâ:
+ ±¾º¯Êý¿¼Âǵ½¼ÆËãhashµÄÊý¾Ý³¤¶ÈÒ»°ã¶¼Êǰ´byte´«È룬ÇÒ×ÜÁ¿²»»á³¬¹ý4G byte£¬
+ Òò´Ë¼ò»¯Á˺¯Êý¹¦ÄÜ¡£
+ byte_Len ×ÜÊý²»Äܳ¬¹ý4G£¬·ñÔò¸Ãº¯ÊýÐèÒªÖØÐÂÐ޸ġ£
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void hash_SetLen(u32 byte_Len)
+{
+ REG32(HASH_LENGTH0) = byte_Len<<3;
+ REG32(HASH_LENGTH1) = byte_Len>>29;
+ REG32(HASH_LENGTH2) = 0;
+ REG32(HASH_LENGTH3) = 0;
+}
+
+#ifdef HASH_CODE_SUPPORT_ALL
+static void hash_SetHmacKey(u32* pHmacKey, u32* HmacKey_len)
+{
+ u32 udI;
+
+ for(udI=0;udI<32;udI++)
+ {
+ //¼Ä´æÆ÷¸ßµØÖ·´æ·ÅµÍλÊý¾Ý£¬Êý¾Ý´æ·ÅÊǵ͵ØÖ··Å¸ßλÊý¾Ý
+ if(udI<(32-HmacKey_len))
+ REG32(HASH_HMACKEY+udI*4) = 0;
+ else
+ REG32(HASH_HMACKEY+udI*4) = pHmacKey[udI-(32-HmacKey_len)];
+ }
+}
+#endif
+
+/* ·µ»Øhash ¼ÆËã½á¹ûºÍ½á¹ûµÄ³¤¶È£¬³¤¶Èµ¥Î»ÊÇword */
+static void hash_GetResult(u32 udMode, u32* HashResult, u32* ResultLen)
+{
+ u32 udI, udResultLen=0;
+
+#ifdef HASH_CODE_SUPPORT_ALL
+ switch(udMode)
+ {
+ case HASH_MODE_MD5:
+ case HASH_MODE_HMAC_MD5:
+ udResultLen = 4; /* 4*4bytes = 128bit*/
+ break;
+
+ case HASH_MODE_SHA1:
+ case HASH_MODE_HMAC_SHA1:
+ udResultLen = 5; /* 160 bit */
+ break;
+
+ case HASH_MODE_SHA224:
+ case HASH_MODE_HMAC_SHA224:
+ udResultLen = 7; /* 224 bit */
+ break;
+
+ case HASH_MODE_SHA256:
+ case HASH_MODE_HMAC_SHA256:
+ udResultLen = 8; /* 256 bit */
+ break;
+
+ case HASH_MODE_SHA384:
+ case HASH_MODE_HMAC_SHA384:
+ udResultLen = 12; /* 384 bit */
+ break;
+
+ case HASH_MODE_SHA512:
+ case HASH_MODE_HMAC_SHA512:
+ udResultLen = 16; /* 512 bit */
+ break;
+
+ default:
+ break;
+ }
+#else
+ udResultLen = 4;
+#endif
+
+ *ResultLen = udResultLen;
+
+ for(udI=0;udI<udResultLen;udI++) //hash¼ÆËãÖ§³Ö128bitÊý¾Ý
+ {
+ //¼Ä´æÆ÷µÍµØÖ·´æ·Åresult µÄ¸ßλ
+ HashResult[udI] = REG32(HASH_RESULT+(16-udResultLen+udI)*4);
+ }
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief HASHÄ£¿éÇý¶¯½Ó¿Ú
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - Hash_Computeº¯ÊýÊôÓÚ½Ó¿Úº¯Êý, Æä¹¦ÄÜÊÇ:
+ * - HASHÄ£¿éÇý¶¯½Ó¿Ú
+ *
+ * ²ÎÊý¸ÅÊö:
+ input:
+ udMode--------hashģʽ
+ udBigEndian----´óС¶Ë¸ñʽ
+ ploadAddr------¼ÆËãhashµÄÔ´Êý¾ÝÖ¸Õë
+ loadLen--------Ô´Êý¾Ý³¤¶È
+ pHmacKey------HMACģʽϵÄÃÜÔ¿
+ HmacKey_len---ÃÜÔ¿³¤¶È
+ output:
+ HashResult-----hash¼ÆËã½á¹û
+ ResultLen------hash½á¹ûµÄ³¤¶È
+ * ·µ »Ø Öµ: 0:³É¹¦ 1:ʧ°Ü
+
+ *--------------------------------------------------------------------------------------------------------------------*/
+u32 Hash_Calculate(u32 udMode, u32 udBigEndian, u32* ploadAddr, u32 loadLen, u32* pHmacKey, u32* HmacKey_len, u32* HashResult, u32* ResultLen)
+{
+ u32 udMessageLen_word;
+ u32 udI;
+
+ if((loadLen == 0) || (ploadAddr == NULL) || (HashResult == NULL) )
+ {
+ return 1;
+ }
+
+ //config hash mode and enable module
+ REG32(HASH_CONTROL) = (udMode<<4)|(udBigEndian<<12)|1;
+
+ hash_SetLen(loadLen);
+
+#ifdef HASH_CODE_SUPPORT_ALL
+ //write HMAC key
+ if(udMode&0x10)
+ {
+ hash_SetHmacKey(pHmacKey, HmacKey_len);
+ }
+#endif
+
+ REG32(HASH_START) = 1;//Hash_Start
+
+ //start write message data into fifo
+ udMessageLen_word = (loadLen+3)/4;
+ for(udI=0;udI<udMessageLen_word;udI++)
+ {
+ REG32(HASH_DATA) = ploadAddr[udI];
+ }
+
+ while(REG32(HASH_START) & 0x1); /* if cal busy, continue to wait*/
+
+ //read Result
+ hash_GetResult(udMode, HashResult, ResultLen);
+
+ REG32(HASH_CONTROL) = 0;//Hash_DisableModule;
+
+ return 0;
+}
+
+/** @} */
+
diff --git a/boot/common/src/loader/drivers/drv_hash.h b/boot/common/src/loader/drivers/drv_hash.h
new file mode 100644
index 0000000..86bd99a
--- /dev/null
+++ b/boot/common/src/loader/drivers/drv_hash.h
@@ -0,0 +1,67 @@
+/**---------------------------------------------------------------@n
+ * °æÈ¨ËùÓÐ(C)2011, ÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾
+ *
+ * ÎļþÃû³Æ: drv_hash.h
+ * ÄÚÈÝÕªÒª: HASHÉ豸linuxÇý¶¯³ÌÐòÍ·Îļþ
+ * ÆäËû˵Ã÷:
+ *
+ * --------------------------------------------------------------
+ * Ð޸ļǼ1: // ÐÞ¸ÄÀúÊ·¼Ç¼£¬°üÀ¨ÐÞ¸ÄÈÕÆÚ¡¢ÐÞ¸ÄÕß¼°ÐÞ¸ÄÄÚÈÝ
+ * ÐÞ¸ÄÈÕÆÚ:
+ * °æ ±¾ ºÅ:
+ * ÐÞ ¸Ä ÈË:
+ * ÐÞ¸ÄÄÚÈÝ:
+ *
+ * ---------------------------------------------------------*/
+
+#ifndef DRV_HASH_H
+#define DRV_HASH_H
+
+#include <common.h>
+
+#define SYS_HASH_BASE 0x0121d000
+
+
+#define HASH_CONTROL (SYS_HASH_BASE+0x04)
+#define HASH_START (SYS_HASH_BASE+0x08)
+#define HASH_DATA (SYS_HASH_BASE+0x10)
+#define HASH_INTSTATUS (SYS_HASH_BASE+0x1c)
+#define HASH_LENGTH0 (SYS_HASH_BASE+0x2c)
+#define HASH_LENGTH1 (SYS_HASH_BASE+0x28)
+#define HASH_LENGTH2 (SYS_HASH_BASE+0x24)
+#define HASH_LENGTH3 (SYS_HASH_BASE+0x20)
+#define HASH_RESULT (SYS_HASH_BASE+0x30)
+#define HASH_HMACKEY (SYS_HASH_BASE+0x70)
+
+//Çý¶¯ÊÇ·ñÖ§³ÖËùÓеÄģʽ£¬ÓÃÓÚ¼ò»¯´úÂëÁ¿
+//#define HASH_CODE_SUPPORT_ALL
+
+#define HASH_MODE_MD5 0x0
+#ifdef HASH_CODE_SUPPORT_ALL
+#define HASH_MODE_SHA1 0x1
+#define HASH_MODE_SHA224 0x2
+#define HASH_MODE_SHA256 0x3
+#define HASH_MODE_SHA384 0x4
+#define HASH_MODE_SHA512 0x5
+#define HASH_MODE_HMAC_MD5 (HASH_MODE_MD5|0x10)
+#define HASH_MODE_HMAC_SHA1 (HASH_MODE_SHA1|0x10)
+#define HASH_MODE_HMAC_SHA224 (HASH_MODE_SHA224|0x10)
+#define HASH_MODE_HMAC_SHA256 (HASH_MODE_SHA256|0x10)
+#define HASH_MODE_HMAC_SHA384 (HASH_MODE_SHA384|0x10)
+#define HASH_MODE_HMAC_SHA512 (HASH_MODE_SHA512|0x10)
+#endif
+
+#define HASH_SMALL_ENDIAN 0
+#define HASH_BIG_ENDIAN 1
+
+u32 Hash_Calculate(u32 udMode, u32 udBigEndian, u32* ploadAddr, u32 loadLen, u32* pHmacKey, u32* HmacKey_len, u32* HashResult, u32* ResultLen);
+
+#endif
+
+
+
+
+
+
+
+
diff --git a/boot/common/src/loader/drivers/drv_rsa.c b/boot/common/src/loader/drivers/drv_rsa.c
new file mode 100644
index 0000000..892fb83
--- /dev/null
+++ b/boot/common/src/loader/drivers/drv_rsa.c
@@ -0,0 +1,469 @@
+
+#include "drv_rsa.h"
+#include <sdio.h>
+
+/* º¯Êý¹¦ÄÜ: ʵÏÖ- N^-1 mod 2^32 µÄËã·¨*/
+static u32 get_N_inv(u32 N0)
+{
+ u32 N_inv=1;
+ u32 i,a,b;
+
+ for(i=1; i<32; i++)
+ {
+ a = 1<<i;
+ b = (N0*N_inv)&((2<<i)-1);
+ if(a<b)
+ {
+ N_inv = N_inv+ a;
+ }
+ }
+
+ return (0xffffffff-N_inv+1);
+}
+
+static void rsa_WriteDataToReg(u32* pudAddr, u32 udReg, u32 Len)
+{
+ u32 udI;
+ for(udI=0;udI<Len;udI++)
+ {
+ //Ä£¿éµÍµØÖ·¼Ä´æÆ÷´æ·ÅµÍµØÖ·Êý¾Ý£¬Êý¾Ý´æ·ÅÊǵ͵ØÖ··Å¸ßλÊý¾Ý
+ REG32(udReg + udI*4) = *(pudAddr+Len-1-udI);
+ }
+}
+
+static void rsa_ReadDataFromReg(u32* pudAddr, u32 udReg, u32 Len)
+{
+ u32 udI;
+ for(udI=0;udI<Len;udI++)
+ {
+ //Ä£¿éµÍµØÖ·¼Ä´æÆ÷´æ·ÅµÍµØÖ·Êý¾Ý£¬Êý¾Ý´æ·ÅÊǵ͵ØÖ··Å¸ßλÊý¾Ý
+ *(pudAddr+Len-1-udI) = REG32(udReg + udI*4);
+ }
+}
+
+#ifdef RSA_CODE_SUPPORT_ALL
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ´óÊý³Ë·¨¼ÆËã
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - Rsa_BigNumMultipleº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ¼ÆËãÁ½¸ö´óÊýÏà³Ë
+ *
+ * ²ÎÊý¸ÅÊö:
+ *
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 rsa_BigNumMultiple(u32 udNbitLen, u32* pudInputM, u32* pudInputE, u32* pudOutputP)
+{
+ u32 Nlen_word, Elen_word;
+ //input M, E, udNbitLen
+ if(udNbitLen>2048||udNbitLen==0\
+ ||pudInputM==NULL||pudInputE==NULL||pudOutputP==NULL)
+ {
+ return 1;
+ }
+
+ REG32(RSA_INT_MASK) = 0; /*unmask interrupt*/
+ REG32(RSA_INT_ENABLE) = 0; /*disable interrupt*/
+ REG32(RSA_CALC_MODE) = RSA_BIG_NUM_MULTIPLE; /* set computemode*/
+
+ //ÅäÖÃM,E µ½RAM¼Ä´æÆ÷ÖÐ
+ Nlen_word = (udNbitLen+31)/32;
+ rsa_WriteDataToReg(pudInputM, RSA_M_RAM, Nlen_word);
+ rsa_WriteDataToReg(pudInputE, RSA_E_RAM, Nlen_word);
+ //ÅäÖÃN µÄbit ³¤¶È
+ REG32(RSA_MODULAR_LENGTH) = udNbitLen-1;/*set modelength, µ¥Î»bit*/
+
+ //enable compute
+ REG32(RSA_MODULE_ENABLE) = 1;
+
+ /*check interrupt status, waiting for calculating finished*/
+ while(!(REG32(RSA_INT_STATUS)& 0x01));
+
+ /* clear the interrupt,input any */
+ REG32(RSA_INT_STATUS) = 1;
+
+ /* read the result */
+ rsa_ReadDataFromReg(pudOutputP, RSA_RESULT_RAM, Nlen_word);
+
+ /*close mode enable*/
+ REG32(RSA_MODULE_ENABLE) = 0;
+
+ return 0;
+
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ³õʼ»¯¼ÆËã
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - Rsa_InitComputeº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ³õʼ»¯¼ÆËã c= r*r mod N
+ *
+ * ²ÎÊý¸ÅÊö:
+ *
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 rsa_InitCompute(u32 udNbitLen, u32* pudInputN, u32* pudOutputP)
+{
+ u32 Nlen_word;
+ //input N, udNbitLen
+ if(udNbitLen>2048||udNbitLen==0\
+ ||pudInputN==NULL||pudOutputP==NULL)
+ {
+ return 1;
+ }
+
+ REG32(RSA_INT_MASK) = 0; /*unmask interrupt*/
+ REG32(RSA_INT_ENABLE) = 0; /*disable interrupt*/
+ REG32(RSA_CALC_MODE) = RSA_INIT_COMPUTE; /* set computemode*/
+
+ //ÅäÖÃN µ½RAM¼Ä´æÆ÷ÖÐ
+ Nlen_word = (udNbitLen+31)/32;
+ rsa_WriteDataToReg(pudInputN, RSA_N_RAM, Nlen_word);
+
+ //ÅäÖÃN µÄbit ³¤¶È
+ if((pudInputN[0]&0x80000000) == 0)
+ {
+ REG32(RSA_MODULAR_LENGTH) = udNbitLen-2;/*set modelength, µ¥Î»bit*/
+ }
+ else
+ {
+ REG32(RSA_MODULAR_LENGTH) = udNbitLen-1;/*set modelength, µ¥Î»bit*/
+ }
+
+ //enable compute
+ REG32(RSA_MODULE_ENABLE) = 1;
+
+ /*check interrupt status, waiting for calculating finished*/
+ while(!(REG32(RSA_INT_STATUS)& 0x01));
+
+ /* clear the interrupt,input any */
+ REG32(RSA_INT_STATUS) = 1;
+
+ /* read the result */
+ rsa_ReadDataFromReg(pudOutputP, RSA_INIT_CALC_RAM, Nlen_word);
+
+ /*close mode enable*/
+ REG32(RSA_MODULE_ENABLE) = 0;
+
+ return 0;
+
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ²»´ø³õʼ»¯¼ÆËãµÄÄ£³Ë
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - Rsa_ModMultipleNoInitº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ÔÚÄ£³ËÖУ¬²»½øÐгõʼ»¯¼ÆËã
+ *
+ * ²ÎÊý¸ÅÊö:
+ *
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void rsa_ModMultipleNoInit(u32 udNbitLen, u32 udEbitLen, u32* pudInputM, u32* pudInputE, u32* pudInputN, u32* pudInputC, u32* pudOutputP)
+{
+ u32 Nlen_word, Elen_word;
+ //input M, E, N, C, udNbitLen, udEbitLen
+ if(udNbitLen>2048||udNbitLen==0||udEbitLen>2048||udEbitLen==0\
+ ||pudInputM==NULL||pudInputE==NULL||pudInputN==NULL||pudInputC==NULL||pudOutputP==NULL)
+ {
+ return 1;
+ }
+
+ REG32(RSA_INT_MASK) = 0; /*unmask interrupt*/
+ REG32(RSA_INT_ENABLE) = 0; /*disable interrupt*/
+ REG32(RSA_CALC_MODE) = RSA_MOD_MULTIPLE_NO_INIT; /* set computemode*/
+
+ Nlen_word = (udNbitLen+31)/32;
+ Elen_word = (udEbitLen+31)/32;
+
+ //ÉèÖòÎÊýN0, µÈÓÚ²ÎÊýN µÄ×îµÍλ
+ REG32(RSA_NZORE) = pudInputN[Nlen_word-1];
+ // ÉèÖòÎÊýN0' , µÈÓÚ- N^-1 mod 2^32
+ REG32(RSA_NZORE_INV) = get_N_inv(pudInputN[Nlen_word-1]);
+
+ //ÅäÖÃM,E,N µ½RAM¼Ä´æÆ÷ÖÐ
+ rsa_WriteDataToReg(pudInputM, RSA_M_RAM, Nlen_word);
+ rsa_WriteDataToReg(pudInputE, RSA_E_RAM, Elen_word);
+ rsa_WriteDataToReg(pudInputN, RSA_N_RAM, Nlen_word);
+ rsa_WriteDataToReg(pudInputC, RSA_INIT_CALC_RAM, Nlen_word);
+
+ //ÅäÖÃN,E µÄbit ³¤¶È
+ if((pudInputN[0]&0x80000000) == 0)
+ {
+ REG32(RSA_MODULAR_LENGTH) = udNbitLen-2;/*set modelength, µ¥Î»bit*/
+ }
+ else
+ {
+ REG32(RSA_MODULAR_LENGTH) = udNbitLen-1;/*set modelength, µ¥Î»bit*/
+ }
+ REG32(RSA_EXP_LENGTH) = (Elen_word-1)<<5; /*set expolength, µ¥Î»word*/
+
+ //enable compute
+ REG32(RSA_MODULE_ENABLE) = 1;
+
+ /*check interrupt status, waiting for calculating finished*/
+ while(!(REG32(RSA_INT_STATUS)& 0x01));
+
+ /* clear the interrupt,input any */
+ REG32(RSA_INT_STATUS) = 1;
+
+ /* read the result */
+ rsa_ReadDataFromReg(pudOutputP, RSA_RESULT_RAM, Nlen_word);
+
+ /*close mode enable*/
+ REG32(RSA_MODULE_ENABLE) = 0;
+
+ return 0;
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ´ø³õʼ»¯¼ÆËãµÄÄ£³Ë
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - Rsa_ModMultipleWithInitº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ÔÚÄ£³ËÖУ¬½øÐгõʼ»¯¼ÆËã
+ *
+ * ²ÎÊý¸ÅÊö:
+ *
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 rsa_ModMultipleWithInit(u32 udNbitLen, u32 udEbitLen, u32* pudInputM, u32* pudInputE, u32* pudInputN, u32* pudOutputP)
+{
+ u32 Nlen_word, Elen_word;
+ //input M, E, N, udNbitLen, udEbitLen
+ if(udNbitLen>2048||udNbitLen==0||udEbitLen>2048||udEbitLen==0\
+ ||pudInputM==NULL||pudInputE==NULL||pudInputN==NULL||pudOutputP==NULL)
+ {
+ return 1;
+ }
+
+ REG32(RSA_INT_MASK) = 0; /*unmask interrupt*/
+ REG32(RSA_INT_ENABLE) = 0; /*disable interrupt*/
+ REG32(RSA_CALC_MODE) = RSA_MOD_MULTIPLE_WITH_INIT; /* set computemode*/
+
+ Nlen_word = (udNbitLen+31)/32;
+ Elen_word = (udEbitLen+31)/32;
+
+ //ÉèÖòÎÊýN0, µÈÓÚ²ÎÊýN µÄ×îµÍλ
+ REG32(RSA_NZORE) = pudInputN[Nlen_word-1];
+ // ÉèÖòÎÊýN0' , µÈÓÚ- N^-1 mod 2^32
+ REG32(RSA_NZORE_INV) = get_N_inv(pudInputN[Nlen_word-1]);
+
+ //ÅäÖÃM,E,N µ½RAM¼Ä´æÆ÷ÖÐ
+ rsa_WriteDataToReg(pudInputM, RSA_M_RAM, Nlen_word);
+ rsa_WriteDataToReg(pudInputE, RSA_E_RAM, Elen_word);
+ rsa_WriteDataToReg(pudInputN, RSA_N_RAM, Nlen_word);
+
+ //ÅäÖÃN,E µÄbit ³¤¶È
+ if((pudInputN[0]&0x80000000) == 0)
+ {
+ REG32(RSA_MODULAR_LENGTH) = udNbitLen-2;/*set modelength, µ¥Î»bit*/
+ }
+ else
+ {
+ REG32(RSA_MODULAR_LENGTH) = udNbitLen-1;/*set modelength, µ¥Î»bit*/
+ }
+ REG32(RSA_EXP_LENGTH) = (Elen_word-1)<<5; /*set expolength, µ¥Î»word*/
+
+ //enable compute
+ REG32(RSA_MODULE_ENABLE) = 1;
+
+ /*check interrupt status, waiting for calculating finished*/
+ while(!(REG32(RSA_INT_STATUS)& 0x01));
+
+ /* clear the interrupt,input any */
+ REG32(RSA_INT_STATUS) = 1;
+
+ /* read the result */
+ rsa_ReadDataFromReg(pudOutputP, RSA_RESULT_RAM, Nlen_word);
+
+ /*close mode enable*/
+ REG32(RSA_MODULE_ENABLE) = 0;
+
+ return 0;
+}
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ²»´ø³õʼ»¯¼ÆËãµÄÄ£ÃÝÔËËã
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - Rsa_ModExpoNoInitº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ÔÚÄ£ÃÝÔËËãÖУ¬²»½øÐгõʼ»¯¼ÆËã
+ *
+ * ²ÎÊý¸ÅÊö:
+ *
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 rsa_ModExpoNoInit(u32 udNbitLen, u32 udEbitLen, u32* pudInputM, u32* pudInputE, u32* pudInputN, u32* pudInputC, u32* pudOutputP)
+{
+ u32 Nlen_word, Elen_word;
+ //input M, E, N, C, udNbitLen, udEbitLen
+ if(udNbitLen>2048||udNbitLen==0||udEbitLen>2048||udEbitLen==0\
+ ||pudInputM==NULL||pudInputE==NULL||pudInputN==NULL||pudInputC==NULL||pudOutputP==NULL)
+ {
+ return 1;
+ }
+
+ REG32(RSA_INT_MASK) = 0; /*unmask interrupt*/
+ REG32(RSA_INT_ENABLE) = 0; /*disable interrupt*/
+ REG32(RSA_CALC_MODE) = RSA_MOD_EXPO_NO_INIT; /* set computemode*/
+
+ Nlen_word = (udNbitLen+31)/32;
+ Elen_word = (udEbitLen+31)/32;
+
+ //ÉèÖòÎÊýN0, µÈÓÚ²ÎÊýN µÄ×îµÍλ
+ REG32(RSA_NZORE) = pudInputN[Nlen_word-1];
+ // ÉèÖòÎÊýN0' , µÈÓÚ- N^-1 mod 2^32
+ REG32(RSA_NZORE_INV) = get_N_inv(pudInputN[Nlen_word-1]);
+
+ //ÅäÖÃM,E,N µ½RAM¼Ä´æÆ÷ÖÐ
+ rsa_WriteDataToReg(pudInputM, RSA_M_RAM, Nlen_word);
+ rsa_WriteDataToReg(pudInputE, RSA_E_RAM, Elen_word);
+ rsa_WriteDataToReg(pudInputN, RSA_N_RAM, Nlen_word);
+ rsa_WriteDataToReg(pudInputC, RSA_INIT_CALC_RAM, Nlen_word);
+
+ //ÅäÖÃN,E µÄbit ³¤¶È
+ if((pudInputN[0]&0x80000000) == 0)
+ {
+ REG32(RSA_MODULAR_LENGTH) = udNbitLen-2;/*set modelength, µ¥Î»bit*/
+ }
+ else
+ {
+ REG32(RSA_MODULAR_LENGTH) = udNbitLen-1;/*set modelength, µ¥Î»bit*/
+ }
+ REG32(RSA_EXP_LENGTH) = (Elen_word-1)<<5; /*set expolength, µ¥Î»word*/
+
+ //enable compute
+ REG32(RSA_MODULE_ENABLE) = 1;
+
+ /*check interrupt status, waiting for calculating finished*/
+ while(!(REG32(RSA_INT_STATUS)& 0x01));
+
+ /* clear the interrupt,input any */
+ REG32(RSA_INT_STATUS) = 1;
+
+ /* read the result */
+ rsa_ReadDataFromReg(pudOutputP, RSA_RESULT_RAM, Nlen_word);
+
+ /*close mode enable*/
+ REG32(RSA_MODULE_ENABLE) = 0;
+
+ return 0;
+}
+#endif
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ´ø³õʼ»¯¼ÆËãµÄÄ£ÃÝÔËËã
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - Rsa_ModExpoWithInitº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ÔÚÄ£ÃÝÔËËãÖУ¬½øÐгõʼ»¯¼ÆËã
+ *
+ * ²ÎÊý¸ÅÊö:
+ *
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 rsa_ModExpoWithInit(u32 udNbitLen, u32 udEbitLen, u32* pudInputM, u32* pudInputE, u32* pudInputN, u32* pudOutputP)
+{
+ u32 Nlen_word, Elen_word;
+ //input M, E, N, udNbitLen, udEbitLen
+ if(udNbitLen>2048||udNbitLen==0||udEbitLen>2048||udEbitLen==0\
+ ||pudInputM==NULL||pudInputE==NULL||pudInputN==NULL||pudOutputP==NULL)
+ {
+ return 1;
+ }
+
+ REG32(RSA_INT_MASK) = 0; /*unmask interrupt*/
+ REG32(RSA_INT_ENABLE) = 0; /*disable interrupt*/
+ REG32(RSA_CALC_MODE) = RSA_MOD_EXPO_WITH_INIT; /* set computemode*/
+
+ Nlen_word = (udNbitLen+31)/32;
+ Elen_word = (udEbitLen+31)/32;
+
+ //ÉèÖòÎÊýN0, µÈÓÚ²ÎÊýN µÄ×îµÍλ
+ REG32(RSA_NZORE) = pudInputN[Nlen_word-1];
+ // ÉèÖòÎÊýN0' , µÈÓÚ- N^-1 mod 2^32
+ REG32(RSA_NZORE_INV) = get_N_inv(pudInputN[Nlen_word-1]);
+
+ //ÅäÖÃM,E,N µ½RAM¼Ä´æÆ÷ÖÐ
+ rsa_WriteDataToReg(pudInputM, RSA_M_RAM, Nlen_word);
+ rsa_WriteDataToReg(pudInputE, RSA_E_RAM, Elen_word);
+ rsa_WriteDataToReg(pudInputN, RSA_N_RAM, Nlen_word);
+
+ //ÅäÖÃN,E µÄbit ³¤¶È
+ if((pudInputN[0]&0x80000000) == 0)
+ {
+ REG32(RSA_MODULAR_LENGTH) = udNbitLen - 2; /*set modelength, µ¥Î»bit*/
+ }
+ else
+ {
+ REG32(RSA_MODULAR_LENGTH) = udNbitLen -1; /*set modelength, µ¥Î»bit*/
+ }
+ REG32(RSA_EXP_LENGTH) = (Elen_word-1)<<5; /*set expolength, µ¥Î»word*/
+
+ //enable compute
+ REG32(RSA_MODULE_ENABLE) = 1;
+
+ /*check interrupt status, waiting for calculating finished*/
+ while(!(REG32(RSA_INT_STATUS)& 0x01));
+
+ /* clear the interrupt,input any */
+ REG32(RSA_INT_STATUS) = 1;
+
+ /* read the result */
+ rsa_ReadDataFromReg(pudOutputP, RSA_RESULT_RAM, Nlen_word);
+
+ /*close mode enable*/
+ REG32(RSA_MODULE_ENABLE) = 0;
+
+ return 0;
+}
+/*
+¹¦ÄÜÏêÊö:RSA ¸÷ÖÖ¼ÆËãµÄ½Ó¿Úº¯Êý
+¸÷²ÎÊý:
+ ptInput Ïê¼û½á¹¹Ìå˵Ã÷
+*/
+u32 Rsa_Calculate(T_Rsa_Paramter ptInput)
+{
+ switch(ptInput.udCalMode)
+ {
+#ifdef RSA_CODE_SUPPORT_ALL
+ case RSA_BIG_NUM_MULTIPLE: //input M, E, udNbitLen
+ return rsa_BigNumMultiple(ptInput.udNbitLen, ptInput.pudInputM, ptInput.pudInputE, ptInput.pudOutputP);
+
+ case RSA_INIT_COMPUTE: //input N, udNbitLen
+ return rsa_InitCompute(ptInput.udNbitLen, ptInput.pudInputN, ptInput.pudOutputP);
+
+ case RSA_MOD_MULTIPLE_NO_INIT: //input M, E, N, C, udNbitLen, udEbitLen
+ return rsa_ModMultipleNoInit(ptInput.udNbitLen, ptInput.udEbitLen, ptInput.pudInputM, ptInput.pudInputE, ptInput.pudInputN, ptInput.pudInputC, ptInput.pudOutputP);
+
+ case RSA_MOD_EXPO_NO_INIT: //input M, E, N, C, udNbitLen, udEbitLen
+ return rsa_ModExpoNoInit(ptInput.udNbitLen, ptInput.udEbitLen, ptInput.pudInputM, ptInput.pudInputE, ptInput.pudInputN, ptInput.pudInputC, ptInput.pudOutputP);
+
+ case RSA_MOD_MULTIPLE_WITH_INIT: //input M, E, N, udNbitLen, udEbitLen
+ return rsa_ModMultipleWithInit(ptInput.udNbitLen, ptInput.udEbitLen, ptInput.pudInputM, ptInput.pudInputE, ptInput.pudInputN, ptInput.pudOutputP);
+#endif
+ case RSA_MOD_EXPO_WITH_INIT: //input M, E, N, udNbitLen, udEbitLen
+ return rsa_ModExpoWithInit(ptInput.udNbitLen, ptInput.udEbitLen, ptInput.pudInputM, ptInput.pudInputE, ptInput.pudInputN, ptInput.pudOutputP);
+
+ default:
+ return 1;
+ }
+}
+
diff --git a/boot/common/src/loader/drivers/drv_rsa.h b/boot/common/src/loader/drivers/drv_rsa.h
new file mode 100644
index 0000000..379f155
--- /dev/null
+++ b/boot/common/src/loader/drivers/drv_rsa.h
@@ -0,0 +1,72 @@
+
+#ifndef RSA_DRV_H
+#define RSA_DRV_H
+
+#include <common.h>
+
+
+#define SYS_RSA_BASE 0x0121c000
+
+
+/**< offset:000 RW °æ±¾ÐÅÏ¢¼Ä´æÆ÷ */
+/**< offset:004 RW Ä£¿éʹÄܼĴæÆ÷ */
+/**< offset:008 RW Ä£³¤¼Ä´æÆ÷ */
+/**< offset:00C RW Ãݳ¤¼Ä´æÆ÷ */
+/**< offset:010 RW ÖжÏ״̬¼Ä´æÆ÷ */
+/**< offset:014 RW ÖжÏʹÄܼĴæÆ÷ */
+/**< offset:018 RW ÖÐ¶ÏÆÁ±Î¼Ä´æÆ÷ */
+/**< offset:01C RW N0¼Ä´æÆ÷ */
+/**< offset:020 RW N0¡¯¼Ä´æÆ÷ */
+/**< offset:024 RW ¼ÆËãģʽ */
+/**< offset:028 RW ռλ·û */
+/**< offset:100 RW M data RAM¼Ä´æÆ÷0x100~0x1FF */
+/**< offset:200 RW E data RAM¼Ä´æÆ÷0x200~0x2FF */
+/**< offset:300 RW N data RAM¼Ä´æÆ÷0x300~0x3FF */
+/**< offset:400 RW ³õʼ»¯¼ÆËãRAM¼Ä´æÆ÷0x400~0x4FF*/
+/**< offset:500 RW ½á¹ûRAM¼Ä´æÆ÷0x500~0x5FF */
+
+
+#define RSA_REV_INFO (SYS_RSA_BASE)
+#define RSA_MODULE_ENABLE (SYS_RSA_BASE+0x4)
+#define RSA_MODULAR_LENGTH (SYS_RSA_BASE+0x8)
+#define RSA_EXP_LENGTH (SYS_RSA_BASE+0xc)
+#define RSA_INT_STATUS (SYS_RSA_BASE+0x10)
+#define RSA_INT_ENABLE (SYS_RSA_BASE+0x14)
+#define RSA_INT_MASK (SYS_RSA_BASE+0x18)
+#define RSA_NZORE (SYS_RSA_BASE+0x1c)
+#define RSA_NZORE_INV (SYS_RSA_BASE+0x20)
+#define RSA_CALC_MODE (SYS_RSA_BASE+0x24)
+#define RSA_M_RAM (SYS_RSA_BASE+0x100)
+#define RSA_E_RAM (SYS_RSA_BASE+0x200)
+#define RSA_N_RAM (SYS_RSA_BASE+0x300)
+#define RSA_INIT_CALC_RAM (SYS_RSA_BASE+0x400)
+#define RSA_RESULT_RAM (SYS_RSA_BASE+0x500)
+
+//Çý¶¯ÊÇ·ñÖ§³ÖËùÓеÄģʽ£¬ÓÃÓÚ¼ò»¯´úÂëÁ¿
+//#define RSA_CODE_SUPPORT_ALL
+
+#ifdef RSA_CODE_SUPPORT_ALL
+#define RSA_BIG_NUM_MULTIPLE 9 //input M, E, udNbitLen
+#define RSA_INIT_COMPUTE 2 //input N, udNbitLen
+#define RSA_MOD_MULTIPLE_NO_INIT 8 //input M, E, N, C, udNbitLen, udEbitLen
+#define RSA_MOD_EXPO_NO_INIT 4 //input M, E, N, C, udNbitLen, udEbitLen
+#define RSA_MOD_MULTIPLE_WITH_INIT 10 //input M, E, N, udNbitLen, udEbitLen
+#endif
+#define RSA_MOD_EXPO_WITH_INIT 6 //input M, E, N, udNbitLen, udEbitLen
+
+/** RSAÇý¶¯¼ÆËã½Ó¿Ú´«Èë²ÎÊý*/
+typedef struct
+{
+ u32 udCalMode; /**< RSA¼ÆËãģʽ */
+ u32 udNbitLen; /**< Ä£ÊýN µÄλÊý»òÕßM µÄλÊý , ¿ÉÑ¡512, 1024, 1536, 2048 */
+ u32 udEbitLen; /**< ÃÝÊýE µÄλÊý, СÓÚ64 */
+ u32 *pudInputM; /**< ÊäÈëM»º´æÇø --ÏûÏ¢M */
+ u32 *pudInputE; /**< ÊäÈëE»º´æÇø --ÃÝÊýE */
+ u32 *pudInputN; /**< ÊäÈëÄ£»º´æÇø --Ä£ÊýN (Á½ËØÊýµÄ³Ë»ý) */
+ u32 *pudInputC; /**< ÊäÈëÔ¤¼ÆËãÖµ»º´æÇø,µÈÓÚr^2 mod N */
+ u32 *pudOutputP; /**< Êä³ö½á¹û»º´æÇø */
+}T_Rsa_Paramter;
+
+u32 Rsa_Calculate(T_Rsa_Paramter ptInput);
+#endif
+
diff --git a/boot/common/src/loader/drivers/drv_usb3slave.c b/boot/common/src/loader/drivers/drv_usb3slave.c
new file mode 100644
index 0000000..3b1df60
--- /dev/null
+++ b/boot/common/src/loader/drivers/drv_usb3slave.c
@@ -0,0 +1,2117 @@
+/*******************************************************************************
+* °æÈ¨ËùÓÐ (C)2010, ÉîÛÚÊÐÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
+*
+* ÎļþÃû³Æ£º drv_usb3slave.c
+* Îļþ±êʶ£º
+* ÄÚÈÝÕªÒª£º
+* ÆäËü˵Ã÷£º zx297520 project
+* µ±Ç°°æ±¾£º 1.0
+* ×÷¡¡¡¡Õߣº tangjian
+* Íê³ÉÈÕÆÚ£º
+*
+*
+*******************************************************************************/
+
+
+/*
+**==================================================================
+** Include files
+**==================================================================
+*/
+#include <commond.h>
+#include "drv_usb3slave.h"
+#include "config.h"
+#include <asm/string.h>
+
+/*zloader±àÒëÑ¡ÏîΪnostdlib,ÆÁ±ÎµôÏÂÃæµÄÍ·Îļþ*/
+//#include <stdlib.h>
+//#include <string.h>
+
+/*
+**==================================================================
+** Global Variables
+**==================================================================
+*/
+/* Èí¼þÓÃÀ´¼Ç¼ËùÓÐdeviceÏà¹ØµÄÐÅÏ¢µÄÈ«¾Ö½á¹¹Ìå*/
+
+extern __align(4) dwc_device_descriptor_t Para_Section device_desc ;
+extern __align(4) dwc_config_all_t Para_Section desc ;
+extern __align(4) dwc_string_descriptor_t Para_Section * pStrDescIdx[] ;
+extern __align(4) dwc_dev_qual_descriptor_t Para_Section dev_qual_desc ;
+__align(EVENT_BUFFERS_SIZE*4) T_USB3Slave_EventBuf Para_Section *gp_USB3Slave_EventBuf; //EventBufÒÔEVENT_BUFFERS_SIZE*4×Ö½Ú¶ÔÆë
+__align(16) T_USB3Slave_TRBToHW Para_Section USB3Slave_TRB ; //TRBÒÔ16×Ö½Ú¶ÔÆë
+__align(16) T_USB3Slave_TRBToHW Para_Section USB3Slave_TRB_EP[4] ; //TRBÒÔ16×Ö½Ú¶ÔÆë
+__align(16) T_USB3Slave_CtrlReq Para_Section pCtrlReq ; /**< ¿ØÖÆÇëÇó */
+T_USB3Slave_SlaveObj Para_Section g_USB3Slave={0};
+u8 g_needSetStall = 0;
+u32 g_debugFaultVal = 0;
+
+__align(EVENT_BUFFERS_SIZE*4) T_USB3Slave_EventBuf Para_Section USB3Slave_EventBuf; //EventBufÒÔEVENT_BUFFERS_SIZE*4×Ö½Ú¶ÔÆë
+
+extern void usb_timeout_usdelay(u32 us);
+#if 0
+static inline void delay(unsigned long loops)
+{
+ /*
+ __asm__ volatile ("1:\n" "subs %0, %1, #1\n"
+ "bne 1b":"=r" (loops):"0"(loops));
+ */
+}
+
+static inline void udelay(unsigned long us)
+{
+ delay(us * 200); /* approximate */
+}
+
+void usdelay(unsigned us)
+{
+ udelay(us);
+}
+#endif
+
+static T_USB3Slave_Ep *USB3Slave_GetEpObj(T_USB3Slave_SlaveObj *ptUsb3Slave, u16 uwIndex_le)
+{
+ T_USB3Slave_Ep *ptDep;
+ u32 udEpnum;
+
+ udEpnum = (uwIndex_le & USB_ENDPOINT_NUMBER_MASK) << 1;
+
+ if ( USB_DIR_IN == (uwIndex_le & USB_ENDPOINT_DIR_MASK))
+ udEpnum |= 1;
+
+ ptDep = &(ptUsb3Slave->tEps[udEpnum]);
+
+ /*if (ptDep->udFlags & EP_ENABLED)*/
+ return (T_USB3Slave_Ep*)ptDep;
+
+ //return (T_USB3Slave_Ep*)NULL;
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief Ïò¶ËµãдÃüÁîµÄͨÓú¯Êý
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_SendDevEpCmd º¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - Ïò¶ËµãдÃüÁîµÄͨÓú¯Êý
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: usb3 É豸½á¹¹Ìå
+ * - udEp: ¶ËµãºÅ
+ * - udCmd: ÃüÁî,ÊÇÓÉDEPCMD¼Ä´æÆ÷µÄCmdTypÓò·¢ÆðµÄ¡£
+ * -00h: Reserved
+ * -01h: Set Endpoint Configuration
+ * -02h: Set Endpoint Resource Configuration
+ * -03h: Get Endpoint State
+ * -04h: Set Stall
+ * -05h: Clear Stall
+ * -06h: Start Transfer
+ * -07h: Update Transfer
+ * -08h: End Transfer
+ * -09h: Start New Configuration
+ * - ptParams: ÃüÁî²ÎÊý
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:u32
+ * - ´íÎóÂë
+ *
+ * ÆäËû˵Ã÷:
+ * -
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+
+static u32 USB3Slave_SendDevEpCmd(T_USB3Slave_SlaveObj *ptUsb3Slave, u32 udEp,
+ u32 udCmd, T_USB3Slave_EpCmdPara *ptParams)
+{
+ volatile u32 udTimeout = 500;
+ u32 udRegValue;
+
+
+ REG32(ptUsb3Slave->udRegs_base + DEPCMDPAR0(udEp)) = ptParams->Parameter0;
+ REG32(ptUsb3Slave->udRegs_base + DEPCMDPAR1(udEp)) = ptParams->Parameter1;
+ REG32(ptUsb3Slave->udRegs_base + DEPCMDPAR2(udEp)) = ptParams->Parameter2;
+
+ REG32(ptUsb3Slave->udRegs_base + DEPCMD(udEp)) = udCmd | USB3Slave_DEPCMD_CMDACT_1;
+ // Ïòcmd¼Ä´æÆ÷µÚ10λд1ºó(command active)£¬¿ØÖÆÆ÷»á×Ô¶¯°Ñ¸ÃλÖÃ0
+
+ do
+ {
+ udRegValue = REG32(ptUsb3Slave->udRegs_base + DEPCMD(udEp));
+
+ if(!(udRegValue & USB3Slave_DEPCMD_CMDACT_1)) break;
+
+ udTimeout--;
+
+ if(!udTimeout)
+ {
+ return ERR_FAIL;
+ }
+ } while(1);
+
+ return SOK;
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief TRB½á¹¹ÌåλÓòÐÎʽת»»³ÉTRBÕûÌå½á¹¹ÌåÐÎʽ£¬±ãÓÚ¶ÔTRBÕûÌå²Ù×÷¡£
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_TrbToHWº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - TRB½á¹¹ÌåλÓòÐÎʽת»»³ÉTRB½á¹¹ÌåÕûÌåÐÎʽ£¬±ãÓÚ¶ÔTRBÕûÌå²Ù×÷¡£
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptTrbBit: TRBλÓòÐÎʽ½á¹¹Ìå
+ * - ptTrbRaw: TRB ÕûÌå½á¹¹ÌåÐÎʽ
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_TrbToHW(T_USB3Slave_TRB *ptTrbBit, T_USB3Slave_TRBToHW *ptTrbRaw)
+{
+ ptTrbRaw->udBpl = ptTrbBit->bplh & DATA_32BIT_MASK;
+ ptTrbRaw->udBph = 0;
+ ptTrbRaw->udSize = ptTrbBit->len_pcm.udVal;
+ /* HWO is written last */
+ ptTrbRaw->udCtrl = ptTrbBit->control.udVal;
+}
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ÔÚ¿ªÊ¼ÅäÖÃ֮ǰ£¬ÒªÏȸøep0дÃüÁî9:¿ªÊ¼ÐµÄÅäÖÃstart new configuration
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_StartCfg º¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ÔÚ¿ªÊ¼ÅäÖÃ֮ǰ£¬ÒªÏȸøep0дÃüÁî9£¬´ËÃüÁî²ÎÊýΪ0
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: usb 3.0É豸½á¹¹Ìå
+ * - ptDep: ¶ËµãÐÅÏ¢½á¹¹Ìå
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:u32
+ * - ´íÎóÂë
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 USB3Slave_StartCfg(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_Ep *ptDep)
+{
+ T_USB3Slave_EpCmdPara tParams = {0};
+ u32 udCmd;
+
+ /* ÏòDEPCMD дÃüÁî9 */ /*Ö´ÐÐCMD9£¬Ôڶ˵ã0ºÍ2µÄÇé¿ö£¬Ò»°ãÖ»Ôڶ˵ã0£¬¶Ëµã2ÓеãÑо¿*/
+ if (0 == ptDep->udEpNum)
+ {
+ udCmd = USB3Slave_DEPCMD_DEPSTARTCFG;
+ return USB3Slave_SendDevEpCmd(ptUsb3Slave, ptDep->udEpNum, udCmd, &tParams);
+ }
+ return SOK;
+}
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ¶Ô¶Ëµã½øÐÐÅäÖÃ
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_SetEpCfgCmdº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ¶Ô¶Ëµã½øÐÐÅäÖÃ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptDep: ¶ËµãÐÅÏ¢½á¹¹Ìå
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:u32
+ * - ´íÎóÂë
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 USB3Slave_SetEpCfgCmd(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_Ep *ptDep)
+{
+ T_USB3Slave_EpCmdPara tParams = {0};
+
+ if((0 == ptDep->udEpNum)||(1 == ptDep->udEpNum))
+ ptDep->ucType = USB_ENDPOINT_XFER_CONTROL; //¼Ç¼¶ËµãµÄ´«ÊäÀàÐÍ
+ else
+ ptDep->ucType = USB_ENDPOINT_XFER_BULK;
+
+
+ tParams.Parameter0 = DEPCFG_EP_TYPE(ptDep->ucType & USB_ENDPOINT_XFERTYPE_MASK) \
+ | DEPCFG_MAX_PACKET_SIZE(ptDep->udMaxPacket & 0xffff)
+ | DEPCFG_BURST_SIZE(ptDep->udMaxBurst);
+ /*
+ * We must use the lower 16 TX FIFOs even though
+ * HW might have more
+ */
+ if (ptDep->udDirection)
+ tParams.Parameter0 |= DEPCFG_FIFO_NUMBER(ptDep->udEpNum >> 1);
+
+ if((0 == ptDep->udEpNum)||(1 == ptDep->udEpNum))
+ tParams.Parameter1 = DEPCFG_XFER_COMPLETE_EN | DEPCFG_XFER_NOT_READY_EN;
+ else
+ tParams.Parameter1 = DEPCFG_XFER_COMPLETE_EN;
+
+ /*
+ * We are doing 1:1 mapping for endpoints, meaning
+ * Physical Endpoints 2 maps to Logical Endpoint 2 and
+ * so on. We consider the direction bit as part of the physical
+ * endpoint number. So USB endpoint 0x81 is 0x03.
+ */
+ tParams.Parameter1 |= DEPCFG_EP_NUMBER(ptDep->udEpNum);
+
+ return USB3Slave_SendDevEpCmd(ptUsb3Slave, ptDep->udEpNum,
+ USB3Slave_DEPCMD_SETEPCONFIG, &tParams);
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief Ϊÿ¸ö¶ËµãÉèÖô«Êä×ÊÔ´¸öÊý
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_SetXferResourceº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - Ϊÿ¸ö¶ËµãÉèÖô«Êä×ÊÔ´¸öÊý
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptDep: ¶ËµãÐÅÏ¢½á¹¹Ìå
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:u32
+ * - ´íÎóÂë
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 USB3Slave_SetXferResource(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_Ep *ptDep)
+{
+ T_USB3Slave_EpCmdPara tParams;
+
+ memset(&tParams, 0x00, sizeof(tParams));
+
+ tParams.Parameter0 = DEPXFERCFG_NUM_XFER_RES(1);
+ /* ÉèÖô«Êä×ÊÔ´*/
+ return USB3Slave_SendDevEpCmd(ptUsb3Slave, ptDep->udEpNum,
+ USB3Slave_DEPCMD_SETTRANSFRESOURCE, &tParams);
+}
+
+
+/**
+ * __dwc3_gadget_ep_enable - Initializes a HW endpoint
+ * @ptDep: endpoint to be initialized
+ * @ptDesc: USB Endpoint Descriptor
+ *
+ * Caller should take care of locking
+ */
+/**-------------------------------------------------------------------------------------------------------------------@n
+* @brief ³õʼ»¯Ò»¸öÓ²¼þ¶Ëµã£¬°üÀ¨¿ªÊ¼ÅäÖá¢Èý²ÎÅäÖᢴ«Êä×ÊÔ´ÅäÖã¬Èí¼þtrbÉèÖø³Öµµ½Ó²¼þÉ豸trbÖÐ
+*
+* ¹¦ÄÜÏêÊö:
+* - USB3Slave_CfgEpº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+* - ʹÄÜÒ»¸öÓ²¼þ¶Ëµã£¬°üÀ¨¿ªÊ¼ÅäÖá¢Èý²ÎÅäÖᢴ«Êä×ÊÔ´ÅäÖã¬Èí¼þtrbÉèÖø³Öµµ½Ó²¼þÉ豸trbÖÐ
+*
+* ²ÎÊý¸ÅÊö:
+* - ptDep: ³õʼ»¯¶Ëµã£¬¶ËµãÐÅÏ¢½á¹¹Ìå
+* - ptDesc: USB ¶ËµãÃèÊö·û
+* - ptComp_desc: ¶Ëµãcompanion ÃèÊö·û
+*
+* ·µ »Ø Öµ: ÀàÐÍ:u32
+* - ´íÎóÂë
+*
+*--------------------------------------------------------------------------------------------------------------------*/
+static u32 USB3Slave_CfgEp(T_USB3Slave_Ep *ptDep)
+{
+ T_USB3Slave_SlaveObj *pUSB3Slv = &g_USB3Slave;
+
+ if (!(ptDep->udFlags & EP_ENABLED))
+ {
+//step0:ep0¶ËµãÅäÖÿªÊ¼£¬Ö´ÐÐcmd=9£¬start new conguration
+ USB3Slave_StartCfg(pUSB3Slv, ptDep);
+ }
+
+//step1:Ö´ÐÐcmd1£¬SET EP CONFIG
+ USB3Slave_SetEpCfgCmd(pUSB3Slv, ptDep);
+
+//step2:Ö´ÐÐcmd2£¬Set Endpoint Transfer Resource Configuration £¬param0 = 1
+
+ if (!(ptDep->udFlags & EP_ENABLED))
+ {
+ USB3Slave_SetXferResource(pUSB3Slv, ptDep);
+
+ ptDep->udFlags |= EP_ENABLED;
+ if(global.need_enum ==1)
+ {
+
+//step3:active ep ,0xc720 £¬Ò»¸ö¶Ëµã¶ÔÓÚÒ»¸öbit
+ REG32(pUSB3Slv->udRegs_base + DWC3_DALEPENA)|= (1u<<ptDep->udEpNum);
+ }
+
+ }
+
+ return SOK;
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ep0·¢ËÍÊý¾Ý
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0StartXferº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ep0·¢ËÍÊý¾Ý
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÀàÐÅÏ¢µÄ½á¹¹Ìå
+ * - ucEpnum: ¶ËµãºÅ
+ * - udBufAddr: ÊäÈëµØÖ·
+ * - udLen: ³¤¶È
+ * - udType: TRB¿ØÖÆÀàÐÍ
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:u32
+ * - ÀàÐÍÂë
+ *
+ * ÆäËû˵Ã÷:
+ * -
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 USB3Slave_Ep0StartXfer(T_USB3Slave_SlaveObj *ptUsb3Slave, u8 ucEpnum, u32 udBufAddr,
+ u32 udLen, u32 udType)
+{
+ T_USB3Slave_EpCmdPara tParams;
+ T_USB3Slave_TRBToHW *ptTrbRaw;
+ T_USB3Slave_TRB tTrbBit;
+ T_USB3Slave_Ep *ptDep;
+
+ ptDep = &(ptUsb3Slave->tEps[ucEpnum]);
+
+ ptUsb3Slave->ptEp0TRB = ptDep->ptTRB;
+ ptTrbRaw = ptUsb3Slave->ptEp0TRB;
+
+ memset(&tTrbBit, 0, sizeof(tTrbBit));
+
+ tTrbBit.control.bit.TRBCTL = udType;
+ tTrbBit.bplh =udBufAddr ;
+ tTrbBit.len_pcm.bit.BUFSIZ = udLen;
+
+ tTrbBit.control.bit.HWO = 1;
+ tTrbBit.control.bit.LST = 1;
+ /*tTrbBit.control.bit.IOC = 1;
+ tTrbBit.control.bit.ISP_IMI = 1;*/
+
+ USB3Slave_TrbToHW(&tTrbBit, ptTrbRaw);
+
+ memset(&tParams, 0, sizeof(tParams));
+ tParams.Parameter0 = 0; /*tTrbBit¸ß32λµØÖ·£¬Ä¬ÈÏΪ0*/
+ tParams.Parameter1 = (u32)((u32)(ptUsb3Slave->ptEp0TRB)& (u32)0xFFFFFFFF);/* ys */
+
+ USB3Slave_SendDevEpCmd(ptUsb3Slave, ptDep->udEpNum,
+ USB3Slave_DEPCMD_STARTTRANSFER, &tParams);
+ ptDep->udFlags |= EP_BUSY;
+
+//»ñµÃ´«Êä×ÊÔ´Ë÷Òý
+ ptDep->ucResTransIdx = (REG32(ptUsb3Slave->udRegs_base + ((u32)DEPCMD(ptDep->udEpNum)>>16)));
+
+ ptUsb3Slave->eEp0NextEvent = EP0_COMPLETE;
+
+ return SOK;
+}
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ch 9.4.5,״̬½×¶Î·µ»ØµÄÊý¾Ý
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0HandleStatusº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ch 9.4.5,״̬½×¶Î·µ»ØµÄÊý¾Ý
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÀàÐÅÏ¢µÄ½á¹¹Ìå
+ * - ptCtrlReq: ±ê×¼ÇëÇóÃüÁî²ÎÊý
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:u32
+ * - ´íÎóÂë
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 USB3Slave_Ep0HandleStatus(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_CtrlReq *ptCtrlReq)
+{
+ T_USB3Slave_Ep *ptDep;
+ u32 udRetVal,udRecip;
+ u16 uwUsb_status = 0;
+ u16 *puwResponse_pkt;
+ u32 udDirection;
+
+ udRecip = ptCtrlReq->bmRequestType & USB_RECIP_MASK;
+ switch (udRecip)
+ {
+ case USB_RECIP_DEVICE:
+ {
+ /*
+ * We are self-powered. U1/U2/LTM will be set later
+ * once we handle this states. RemoteWakeup is 0 on SS
+ */
+ uwUsb_status |= ptUsb3Slave->udIsSelfPowered << USB_DEVICE_SELF_POWERED;
+ break;
+ }
+ case USB_RECIP_INTERFACE:
+ {
+ /*
+ * Function Remote Wake Capable D0
+ * Function Remote Wakeup D1
+ */
+ break;
+ }
+ case USB_RECIP_ENDPOINT:
+ {
+ ptDep = USB3Slave_GetEpObj(ptUsb3Slave, ptCtrlReq->wIndex);
+ if (!ptDep)
+ return ERR_INVPARAMS;
+ if (ptDep->udFlags & EP_STALL)
+ uwUsb_status = 1 << USB_ENDPOINT_HALT;
+ break;
+ }
+ default:
+ {
+ return ERR_INVPARAMS;
+ }
+ };
+
+ puwResponse_pkt = (u16 *) ptUsb3Slave->aucSetupBuf;
+ *puwResponse_pkt = uwUsb_status;
+
+ ptDep = &(ptUsb3Slave->tEps[0]);
+
+ udDirection = ptDep->udFlags & EP0_DIR_IN;
+
+ if (ptUsb3Slave->eEp0State != EP0_DATA_PHASE) //ÕâÀïµÈ´ýµÄ״̬¿ÉÄÜÓÐÎÊÌ⣬ÓдýÑо¿£¬pxp
+ {
+ return 0;
+ }
+
+ udRetVal = USB3Slave_Ep0StartXfer(ptUsb3Slave, udDirection,
+ (u32)ptUsb3Slave->aucSetupBuf, sizeof(*puwResponse_pkt),
+ TRBCTL_CONTROL_DATA);
+ ptDep->udFlags &= ~(EP_PENDING_REQUEST | EP0_DIR_IN);
+ return udRetVal;
+}
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ÉèÖÃhaltÌØÐÔ
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_EpSetHaltº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ÉèÖÃhaltÌØÐÔ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptDep: ¶ËµãÐÅÏ¢½á¹¹Ìå
+ * - udValue: 0ʱÇå³ýstallÌØÐÔ£¬1ʱÉèÖÃstallÌØÐÔ
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:u32
+ * - ´íÎóÂë
+ *
+ * ÆäËû˵Ã÷:
+ * -
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 USB3Slave_EpSetHalt(T_USB3Slave_Ep *ptDep, u32 udValue)
+{
+ T_USB3Slave_EpCmdPara tParams;
+ T_USB3Slave_SlaveObj *pUSB3Slv = &g_USB3Slave;
+ u32 udRetVal;
+
+ memset(&tParams, 0x00, sizeof(tParams));
+
+ if (udValue)
+ {
+ if (0 == ptDep->udEpNum || 1 == ptDep->udEpNum)
+ {
+ /*
+ * Whenever EP0 is stalled, we will restart
+ * the state machine, thus moving back to
+ * Setup Phase
+ */
+ pUSB3Slv->eEp0State = EP0_SETUP_PHASE;
+ }
+ printf("USB3Slave_EpSetHalt");
+// udRetVal = USB3Slave_SendDevEpCmd(pUSB3Slv, ptDep->udEpNum,
+ // USB3Slave_DEPCMD_CLEARSTALL, &tParams);
+ if(((global.need_enum ==0) || (1 == g_USB3Slave.udUSBSate))&&g_needSetStall!=1)
+ {
+ udRetVal = USB3Slave_SendDevEpCmd(pUSB3Slv, ptDep->udEpNum,
+ USB3Slave_DEPCMD_CLEARSTALL, &tParams);
+ }
+ else
+ {
+ g_needSetStall = 0;
+ pUSB3Slv->eEp0NextEvent = EP0_COMPLETE;
+ udRetVal = USB3Slave_SendDevEpCmd(pUSB3Slv, ptDep->udEpNum,
+ USB3Slave_DEPCMD_SETSTALL, &tParams);
+
+ USB3Slave_Ep0StartXfer(pUSB3Slv, 0, (u32)(pUSB3Slv->tCtrlReq), 8,
+ TRBCTL_CONTROL_SETUP);
+ }
+
+ }
+
+ return udRetVal;
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ÉèÖÃep0ÌØÐÔ
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0HandleFeatureº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ÉèÖÃep0ÌØÐÔ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢µÄ½á¹¹Ìå
+ * - ptCtrlReq: ±ê×¼ÇëÇóÃüÁî²ÎÊý
+ * - udSet: 1ʱÉèÖÃÌØÐÔ£¬0ʱÇå³ýÌØÐÔ
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:u32
+ * - ´íÎóÂë
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 USB3Slave_Ep0HandleFeature(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_CtrlReq *ptCtrlReq, u32 udSet)
+{
+ T_USB3Slave_Ep *ptDep;
+ u32 udRecip;
+ u32 udIndex;
+ u32 udRet;
+
+ udIndex = ptCtrlReq->wIndex;
+ udRecip = ptCtrlReq->bmRequestType & USB_RECIP_MASK;
+ switch (udRecip)
+ {
+ case USB_RECIP_ENDPOINT:
+ {
+
+ ptDep = USB3Slave_GetEpObj(ptUsb3Slave, udIndex);
+ if (!ptDep)
+ return ERR_INVPARAMS;
+ udRet = USB3Slave_EpSetHalt(ptDep, udSet);
+ if (udRet)
+ return ERR_INVPARAMS;
+ break;
+ }
+ default:
+ return ERR_INVPARAMS;
+ };
+
+ return SOK;
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ÉèÖÃep0µØÖ·
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0SetAddrº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ÉèÖÃep0µØÖ·
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptCtrlReq: ±ê×¼ÇëÇóÃüÁî²ÎÊý
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:u32
+ * - ´íÎóÂë
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 USB3Slave_Ep0SetAddr(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_CtrlReq *ptCtrlReq)
+{
+ u32 udAddr;
+ u32 udRegVal;
+
+ udAddr = ptCtrlReq->wValue;
+
+ udRegVal = REG32(ptUsb3Slave->udRegs_base + DWC3_DCFG);
+ udRegVal &= ~(DWC3_DCFG_DEVADDR_MASK);
+ udRegVal |= DWC3_DCFG_DEVADDR(udAddr);
+ REG32(ptUsb3Slave->udRegs_base + DWC3_DCFG) = udRegVal;
+
+ if (udAddr)
+ ptUsb3Slave->eDevState = ADDRESS_STATE;
+ else
+ ptUsb3Slave->eDevState = DEFAULT_STATE;
+
+ return SOK;
+}
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief »ñÈ¡É豸ÃèÊö·û£¬ÉèÖÃÃèÊö·ûÁôÓнӿڣ¬µ«Ôݲ»ÊµÏÖ
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0HandleDescº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - »ñÈ¡É豸ÃèÊö·û£¬ÉèÖÃÃèÊö·ûÁôÓнӿڣ¬µ«Ôݲ»ÊµÏÖ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptCtrlReq: ±ê×¼ÇëÇóÃüÁî²ÎÊý
+ * - udIsSet:
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:u32
+ * - ´íÎóÂë
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 USB3Slave_Ep0HandleDesc(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_CtrlReq *ptCtrlReq, u32 udIsSet)
+{
+
+ u32 udLen = 0;
+ u32 udDirection = 0;
+ u16 uwValue = ptCtrlReq->wValue;
+ u8 ucIdx =(u8)(ptCtrlReq->wValue &0xff);
+ u32 udRetVal = 0;
+ T_USB3Slave_Ep * ptDep = &ptUsb3Slave->tEps[1];
+ u16 temp = uwValue >> 8;
+
+ if( USB_DT_DEVICE == temp )
+ {
+ udDirection = 1;
+ udLen = MIN(sizeof(dwc_device_descriptor_t), ptCtrlReq->wLength);
+ udRetVal = USB3Slave_Ep0StartXfer(ptUsb3Slave, udDirection,
+ (u32)&device_desc, udLen,
+ TRBCTL_CONTROL_DATA);
+ ptUsb3Slave->eEp0State = EP0_DATA_PHASE;
+
+ }
+ else if( USB_DT_CONFIG == temp)
+ {
+ udDirection = 1;
+ udLen = MIN(sizeof(dwc_config_all_t), ptCtrlReq->wLength);
+ udRetVal = USB3Slave_Ep0StartXfer(ptUsb3Slave, udDirection,
+ (u32)&desc, udLen,
+ TRBCTL_CONTROL_DATA);
+ ptUsb3Slave->eEp0State=EP0_DATA_PHASE;
+
+ }
+ else if( USB_DT_STRING == temp)
+ {
+ udDirection = 1;
+ if(ucIdx > 5)
+ {
+ USB3Slave_EpSetHalt(ptDep,1);
+ }
+ else
+ {
+ udLen = MIN(((dwc_string_descriptor_t*)(pStrDescIdx[ucIdx]))->bLength, ptCtrlReq->wLength);
+ udRetVal = USB3Slave_Ep0StartXfer(ptUsb3Slave, udDirection,
+ (u32)pStrDescIdx[ucIdx], udLen,
+ TRBCTL_CONTROL_DATA);
+ ptUsb3Slave->eEp0State=EP0_DATA_PHASE;
+ }
+
+ }
+
+ else if( USB_DT_DEVICE_QUALIFIER == temp)
+ {
+ udDirection = 1;
+ udLen =MIN(sizeof(dwc_dev_qual_descriptor_t), ptCtrlReq->wLength);
+ udRetVal = USB3Slave_Ep0StartXfer(ptUsb3Slave, udDirection,
+ (u32)&dev_qual_desc, udLen,
+ TRBCTL_CONTROL_DATA);
+ ptUsb3Slave->eEp0State = EP0_DATA_PHASE;
+
+ }
+ else
+
+ {
+ USB3Slave_EpSetHalt(ptDep,1);
+
+ }
+
+ return udRetVal;
+
+}
+
+/*¸Ãº¯Êý¾ßÌåʵÏÖÓдýÌÖÂÛ£¬pxp */
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ÉèÖÃep0ÅäÖÃ
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0HandleCfgº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ÉèÖÃep0ÅäÖÃ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptCtrlReq: ±ê×¼ÇëÇóÃüÁî²ÎÊý
+ * - udIsSet:
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:u32
+ * - ´íÎóÂë
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 USB3Slave_Ep0HandleCfg(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_CtrlReq *ptCtrlReq, u32 udIsSet)
+{
+ u32 udCfg;
+ udCfg = ptCtrlReq->wValue;
+
+ if (udIsSet && udCfg)
+ {
+ ptUsb3Slave->eDevState = CONFIGURED_STATE;
+ REG32(ptUsb3Slave->udRegs_base + DWC3_DALEPENA) = 0x3f;
+
+#if SIM_EN == EMULATION
+ REG32(ARM_PORTA)=0x30;
+#endif
+
+ return SOK;
+ }
+ return SOK;
+}
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ep0±ê×¼ÇëÇóÀàÐÍ
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0Requestº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ep0±ê×¼ÇëÇóÀàÐÍ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptCtrlReq: ±ê×¼ÇëÇóÃüÁî²ÎÊý
+ * -bmRequestType: ¾ö¶¨Êý¾Ý´«Êä·½ÏòºÍ½ÓÊÕÕßÀàÐÍ¡£
+ * -bRequest : ¾ßÌåÇëÇóÀàÐÍ¡£
+ * -wValue : ×Ö³¤Óò,¸ù¾Ý²»Í¬µÄÇëÇóº¬Òå¸Ä±ä
+ * -wIndex : ×Ö³¤Óò,¸ù¾Ý²»Í¬µÄÇëÇóº¬Òå¸Ä±ä.µäÐÍÓÃÓÚ´«ËÍË÷Òý»òÆ«ÒÆ.
+ * -wLength : ÈçÓÐÊý¾Ý´«Ëͽ׶Î,´ËΪÊý¾Ý×Ö½ÚÊý.
+ * ·µ »Ø Öµ: ÀàÐÍ:u32
+ * - ´íÎóÂë
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static u32 USB3Slave_Ep0Request(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_CtrlReq *ptCtrlReq)
+{
+ u32 udRet = 0;
+ T_USB3Slave_Ep *ptDep0 = 0;
+ u8 temp = 0;
+ //tj Ôö¼ÓÅжÏbmRequestTypeÊÇ·ñΪ±ê×¼ÃüÁÈç¹û²»ÊÇ£¬Ö±½Ó»Østall
+ if(UT_GET_TYPE(ptCtrlReq->bmRequestType)!=UT_STANDARD)
+ {
+ ptDep0 = USB3Slave_GetEpObj(ptUsb3Slave,ptCtrlReq->wIndex);
+ USB3Slave_EpSetHalt(ptDep0, 1);
+ printf"command err.\n");
+ return 1;
+ }
+ temp = ptCtrlReq->bRequest;
+ if( USB_REQ_GET_STATUS == temp)
+
+ {
+ printf("USB_REQ_GET_STATUS\n");
+ udRet = USB3Slave_Ep0HandleStatus(ptUsb3Slave, ptCtrlReq);
+
+ }
+ else if(USB_REQ_CLEAR_FEATURE == temp)
+ {
+ printf("USB_REQ_CLEAR_FEATURE\n");
+// udRet = USB3Slave_Ep0HandleFeature(ptUsb3Slave, ptCtrlReq, 0);
+ udRet = USB3Slave_Ep0HandleFeature(ptUsb3Slave, ptCtrlReq, 1);
+
+ }
+ else if( USB_REQ_SET_ADDRESS == temp)
+ {
+
+ printf("USB_REQ_SET_ADDRESS\n");
+ udRet = USB3Slave_Ep0SetAddr(ptUsb3Slave, ptCtrlReq);
+
+ }
+ else if( USB_REQ_GET_DESCRIPTOR == temp)
+ {
+ printf("USB_REQ_GET_DESCRIPTOR\n");
+ udRet = USB3Slave_Ep0HandleDesc(ptUsb3Slave, ptCtrlReq,0);
+
+ }
+ else if( USB_REQ_SET_CONFIGURATION == temp)
+ {
+
+ printf("USB_REQ_SET_CONFIGURATION\n");
+ udRet = USB3Slave_Ep0HandleCfg(ptUsb3Slave, ptCtrlReq,1);
+
+ }
+ else
+ {
+
+ printf("USB3Slave_EpSetHalt\n");
+ USB3Slave_EpSetHalt(ptDep0, 1);
+ }
+
+
+ return udRet;
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ep0 setup ½×¶Î
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0InspectSetupº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ep0 setup ½×¶Î
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptEpEvt: ¶ËµãÀàÐÍʼþ
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_Ep0InspectSetup(T_USB3Slave_SlaveObj *ptUsb3Slave,
+ const T_USB3Slave_EpEvt *ptEpEvt)
+{
+ u32 udRetVal = 0;
+ u16 uwLen = 0;
+ T_USB3Slave_CtrlReq *ptCtrlReq = (ptUsb3Slave->tCtrlReq);
+
+ uwLen = ptCtrlReq->wLength;
+ /*Èç¹ûÊý¾Ý³¤¶ÈΪ0£¬±íʾûÓÐÊý¾Ý½×¶Î,Á½¸ö½×¶Î£¬Èç¹ûÓÐÊý¾Ý½×¶Î£¬Èý¸ö½×¶Î*/
+ if (!uwLen)
+ {
+ ptUsb3Slave->udThreeStageSetup = FALSE;
+ ptUsb3Slave->udEp0ExpectIn = FALSE;
+ ptUsb3Slave->eEp0NextEvent = EP0_NRDY_STATUS;
+ }
+ else
+ {
+ ptUsb3Slave->udThreeStageSetup = TRUE;
+ ptUsb3Slave->udEp0ExpectIn = !!(ptCtrlReq->bmRequestType & USB_DIR_IN);
+ ptUsb3Slave->eEp0NextEvent = EP0_NRDY_DATA;
+ }
+ printf("USB3Slave_Ep0Request\n");
+ udRetVal = USB3Slave_Ep0Request(ptUsb3Slave,ptCtrlReq);
+
+ if (udRetVal == USB_GADGET_DELAYED_STATUS)
+ ptUsb3Slave->udDelayedStatus = TRUE;
+ }
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ep0 data½×¶Î
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0CmpltDataº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ep0 data½×¶Î
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptEpEvt: ¶ËµãÀàÐÍʼþ
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_Ep0CmpltData(T_USB3Slave_SlaveObj *ptUsb3Slave,
+ const T_USB3Slave_EpEvt *ptEpEvt)
+{
+ /*bootÀïÃæÃ»ÓеȺò¶ÓÁУ¬ÕâÀïÔݲ»×öÈκδ¦Àí*/
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ep0 status ½×¶Î£¬½áÊø±¾´Î¿ØÖÆ´«Ê䣬״̬»Ø¹é
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0CmpltRequestº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ep0 status ½×¶Î£¬½áÊø±¾´Î¿ØÖÆ´«Ê䣬״̬»Ø¹é
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptEpEvt: ¶ËµãÀàÐÍʼþ
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_Ep0CmpltRequest(T_USB3Slave_SlaveObj *ptUsb3Slave,
+ const T_USB3Slave_EpEvt *ptEpEvt)
+{
+ if(ptUsb3Slave->eDevState == CONFIGURED_STATE)
+ {
+ ptUsb3Slave->udUSBSate = 1;
+#if SIM_EN == EMULATION
+ REG32(ARM_PORTA)=0x31;
+#endif
+
+ }
+ ptUsb3Slave->eEp0State = EP0_SETUP_PHASE;
+ USB3Slave_Ep0StartXfer(ptUsb3Slave, 0, (u32)(ptUsb3Slave->tCtrlReq), 8,
+ TRBCTL_CONTROL_SETUP);
+
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ´¦Àíxfercompleteʼþ
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0XferCmpltº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ´¦Àíxfercompleteʼþ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptEpEvt: ¶ËµãÀàÐÍʼþ
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+/*´¦Àíxfercompleteʼþ*/
+static void USB3Slave_Ep0XferCmplt(T_USB3Slave_SlaveObj *ptUsb3Slave,
+ const T_USB3Slave_EpEvt *ptEpEvt)
+{
+ T_USB3Slave_Ep *ptDep = &(ptUsb3Slave->tEps[ptEpEvt->udEndpoint_number]);
+
+ ptDep->udFlags &= ~EP_BUSY;
+ ptUsb3Slave->udSetupPacketPending = 0;
+ switch (ptUsb3Slave->eEp0State)
+ {
+ case EP0_SETUP_PHASE:
+ {
+ USB3Slave_Ep0InspectSetup(ptUsb3Slave, ptEpEvt);
+ break;
+ }
+ case EP0_DATA_PHASE:
+ {
+ USB3Slave_Ep0CmpltData(ptUsb3Slave, ptEpEvt);
+ break;
+ }
+ case EP0_STATUS_PHASE:
+ {
+ USB3Slave_Ep0CmpltRequest(ptUsb3Slave, ptEpEvt);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ¿ªÊ¼´«Ê䣬¿ØÖƽ¨Á¢½×¶Î
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0OutStartº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ¿ªÊ¼´«Ê䣬¿ØÖƽ¨Á¢½×¶ÎµÄͨÓýӿÚ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ * ÆäËû˵Ã÷:
+ * -
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_Ep0OutStart(T_USB3Slave_SlaveObj *ptUsb3Slave)
+{
+ USB3Slave_Ep0StartXfer(ptUsb3Slave, 0, (u32)(ptUsb3Slave->tCtrlReq), 8,
+ TRBCTL_CONTROL_SETUP);
+
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ¿ØÖƽ¨Á¢½×¶ÎͨÓýӿÚ
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0DoCtrlSetupº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ¿ØÖƽ¨Á¢½×¶ÎͨÓýӿÚ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptEpEvt: ¶ËµãÀàÐÍʼþ
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_Ep0DoCtrlSetup(T_USB3Slave_SlaveObj *ptUsb3Slave,
+ const T_USB3Slave_EpEvt *ptEpEvt)
+{
+ USB3Slave_Ep0OutStart(ptUsb3Slave);
+}
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ¿ØÖÆ×´Ì¬½×¶Î£¬¿ªÊ¼´«Ê䣬ÕÙ»½¶Ëµã½á¹¹Ìå½øÐд¦Àí
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0DoCtrlStatusº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ¿ØÖÆ×´Ì¬½×¶Î£¬¿ªÊ¼´«Ê䣬ÕÙ»½¶Ëµã½á¹¹Ìå½øÐд¦Àí
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - udEpnum: ¶ËµãºÅ
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_Ep0DoCtrlStatus(T_USB3Slave_SlaveObj *ptUsb3Slave, u32 udEpnum)
+{
+ u32 udType;
+ T_USB3Slave_Ep *ptDep = &(ptUsb3Slave->tEps[udEpnum]);
+ /* È·¶¨¿ØÖÆ´«ÊäµÄ״̬ÀàÐÍ */
+ udType = ptUsb3Slave->udThreeStageSetup ? TRBCTL_CONTROL_STATUS3
+ : TRBCTL_CONTROL_STATUS2;
+ /* ·¢Æð¿ªÊ¼´«ÊäÃüÁµÈ´ýÖжϲúÉú */
+ USB3Slave_Ep0StartXfer(ptUsb3Slave, ptDep->udEpNum,
+ (u32)(ptUsb3Slave->tCtrlReq), 0, udType);
+}
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ¿ØÖÆÊý¾Ý½×¶Î
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0DoCtrlDataº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ¿ØÖÆÊý¾Ý½×¶Î
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptEpEvt: ¶ËµãÀàÐÍʼþ
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_Ep0DoCtrlData(T_USB3Slave_SlaveObj *ptUsb3Slave,
+ const T_USB3Slave_EpEvt *ptEpEvt)
+{
+ if (ptEpEvt->udEndpoint_number)
+ ptUsb3Slave->tEps[ptEpEvt->udEndpoint_number].udFlags |= EP0_DIR_IN;
+
+ /* linuxÇý¶¯ÀﻹÊÇÈ¥ÅжÏÇëÇó¶ÓÁÐÊÇ·ñΪ¿Õ½øÐд¦Àí£¬ÂãÇýûÓÐÇëÇó¶ÓÁУ¬ÏÈ·Å×Å */
+
+}
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ´¦Àíxfernotreadyʼþ
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0XferNotReadyº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ´¦Àíxfernotreadyʼþ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptEpEvt: ¶ËµãÀàÐÍʼþ
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_Ep0XferNotReady(T_USB3Slave_SlaveObj *ptUsb3Slave,
+ const T_USB3Slave_EpEvt *ptEpEvt)
+{
+ u8 usb3Event = 0;
+ T_USB3Slave_Ep * ptDep = &ptUsb3Slave->tEps[0];
+ ptUsb3Slave->udSetupPacketPending = 1;
+ /*
+ * This part is very tricky: If we has just handled
+ * XferNotReady(Setup) and we're now expecting a
+ * XferComplete but, instead, we receive another
+ * XferNotReady(Setup), we should STALL and restart
+ * the state machine.
+ *
+ * In all other cases, we just continue waiting
+ * for the XferComplete event.
+ *
+ * We are a little bit unsafe here because we're
+ * not trying to ensure that last event was, indeed,
+ * XferNotReady(Setup).
+ *
+ * Still, we don't expect any condition where that
+ * should happen and, even if it does, it would be
+ * another error condition.
+ */
+ /*
+ if ((1 == ptUsb3Slave->udEventsequence) && (EP0_COMPLETE == ptUsb3Slave->eEp0NextEvent))
+ {
+ switch (ptEpEvt->EventStatus)
+ {
+ case DEPEVT_STATUS_CONTROL_SETUP:
+ {
+ IC_DBG(IC_DEBUG_INFO, "Unexpected XferNotReady(Setup)\n");
+ break;
+ }
+ case DEPEVT_STATUS_CONTROL_DATA:
+ {
+ IC_DBG(IC_DEBUG_INFO, "DEPEVT_STATUS_CONTROL_DATA: XferNotReady\n");
+ break;
+ }
+ case DEPEVT_STATUS_CONTROL_STATUS:
+ break;
+ default:
+ IC_DBG(IC_DEBUG_INFO, "Uwaiting for XferComplete\n");
+ }
+ return;
+ }
+ */
+ usb3Event = (u8)(ptEpEvt->EventStatus);
+ if (DEPEVT_STATUS_CONTROL_SETUP == usb3Event)
+ {
+ printf("USB3Slave event DEPEVT_STATUS_CONTROL_SETUP\n");
+ ptUsb3Slave->eEp0State = EP0_SETUP_PHASE;
+ USB3Slave_Ep0DoCtrlSetup(ptUsb3Slave, ptEpEvt);
+ }
+ else if (DEPEVT_STATUS_CONTROL_DATA == usb3Event)
+ {
+ printf("USB3Slave event DEPEVT_STATUS_CONTROL_DATA\n");
+ if ( ptUsb3Slave->eEp0NextEvent == EP0_COMPLETE)
+ {
+ return;
+ }
+ ptUsb3Slave->eEp0State = EP0_DATA_PHASE;
+ USB3Slave_Ep0DoCtrlData(ptUsb3Slave, ptEpEvt);
+ }
+ else if (DEPEVT_STATUS_CONTROL_STATUS == usb3Event)
+ {
+ printf("USB3Slave event DEPEVT_STATUS_CONTROL_STATUS\n");
+ ptUsb3Slave->eEp0State = EP0_STATUS_PHASE;
+ USB3Slave_Ep0DoCtrlStatus(ptUsb3Slave, ptEpEvt->udEndpoint_number);
+ }
+ else if (DEPEVT_STATUS_STATUS_SETUP == usb3Event)
+ {
+ printf("USB3Slave event DEPEVT_STATUS_STATUS_SETUP\n");
+ g_needSetStall = 1;
+ USB3Slave_EpSetHalt(ptDep,1);
+ }
+ else
+ {
+ g_debugFaultVal = ptEpEvt->EventStatus;
+ printf("USB3Slave event default\n");
+ }
+}
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ´¦Àíep0¿ØÖÆÖжÏ
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Ep0ISRº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ´¦Àí¿ØÖÆÖжÏ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptEpEvt: ¶ËµãÀàÐÍʼþ
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ * ÆäËû˵Ã÷:
+ * -
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_Ep0ISR(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_EpEvt *ptEpEvt)
+{
+ switch (ptEpEvt->udEndpoint_event)
+ {
+ case DEPEVT_XFERCOMPLETE:
+ {
+ USB3Slave_Ep0XferCmplt(ptUsb3Slave, ptEpEvt);
+ break;
+ }
+ case DEPEVT_XFERNOTREADY:
+ {
+ USB3Slave_Ep0XferNotReady(ptUsb3Slave, ptEpEvt);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ָʾ´«ÊäÍê³É
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_EpXferCmpltº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ָʾ´«ÊäÍê³É
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptDep: ¶ËµãÐÅÏ¢½á¹¹Ìå
+ * - ptEpEvt: ¶ËµãÀàÐÍʼþ
+ * - udStart_new:
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_EpXferCmplt(T_USB3Slave_SlaveObj *ptUsb3Slave,
+ T_USB3Slave_Ep *ptDep, const T_USB3Slave_EpEvt *ptEpEvt,u32 udStart_new)
+{
+
+ u32 udXfercount;
+ T_USB3Slave_TRB *tTrbBit;
+
+ tTrbBit = (T_USB3Slave_TRB *)ptDep->ptTRB ;
+ udXfercount = ptDep->udLen - tTrbBit->len_pcm.bit.BUFSIZ;
+
+ if((0x0 == ptDep->udDirection) && (0x2 == ptDep->ucType))
+ ptUsb3Slave->eDevState = BULKOUT_CMPL;
+ if((0x1 == ptDep->udDirection) && (0x2 == ptDep->ucType))
+ ptUsb3Slave->eDevState = BULKIN_CMPL;
+
+ ptDep->udFlags &= ~EP_BUSY;
+ ptDep->ucResTransIdx = 0;
+
+
+ if(ptDep->fnUsbCb)
+ ptDep->fnUsbCb((u32)(ptDep->pPara), 0, udXfercount, ptDep->udLen);
+}
+
+static void USB3Slave_Init_TRB(T_USB3Slave_Ep *ptDep)
+{
+ T_USB3Slave_TRBToHW *ptTrbRaw;
+ T_USB3Slave_TRB tTrbBit;
+
+ ptTrbRaw = ptDep->ptTRB;
+
+ memset(&tTrbBit, 0, sizeof(tTrbBit));
+
+ tTrbBit.control.bit.CHN = 0;
+ tTrbBit.control.bit.LST = 1;
+ tTrbBit.control.bit.TRBCTL = TRBCTL_NORMAL;
+ tTrbBit.control.bit.HWO = 1;
+
+ tTrbBit.len_pcm.bit.BUFSIZ = ptDep->udLen;
+
+ tTrbBit.bplh=(u64)(ptDep->pudAddrData);
+
+
+ USB3Slave_TrbToHW(&tTrbBit, ptTrbRaw);
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ÆÕͨ¶Ëµã½øÐÐÊý¾Ý´«Êä
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_EpStartXferº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ÆÕͨ¶Ëµã½øÐÐÊý¾Ý´«Êä
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptDep: ¶ËµãÐÅÏ¢½á¹¹Ìå
+ * - uwCmd_param: ÃüÁî²ÎÊý
+ * - udStart_new:
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:INT
+ * - ´íÎóÂë
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+/*ÆÕͨ¶Ëµã½øÐÐÊý¾Ý´«Êä*/
+static u32 USB3Slave_EpStartXfer(T_USB3Slave_Ep *ptDep, u16 uwCmd_param,
+ u32 udStart_new)
+{
+ T_USB3Slave_EpCmdPara tParams;
+ T_USB3Slave_SlaveObj *pUSB3Slv = &g_USB3Slave;
+ u32 udCmd;
+
+ USB3Slave_Init_TRB(ptDep); //ÅäÖÃTRB
+ memset(&tParams, 0, sizeof(tParams));
+
+ tParams.Parameter0 = 0; /*trb¸ß32λµØÖ·£¬Ä¬ÈÏΪ0*/
+ tParams.Parameter1 = (u32)((u32)(ptDep->ptTRB)& (u32)0xFFFFFFFF);/* ys */
+
+ if (udStart_new)
+ udCmd = USB3Slave_DEPCMD_STARTTRANSFER;
+ else
+ udCmd = USB3Slave_DEPCMD_UPDATETRANSFER;
+
+ udCmd |= USB2Slave_DEPCMD_PARAM(uwCmd_param); //0
+
+ USB3Slave_SendDevEpCmd(pUSB3Slv, ptDep->udEpNum, udCmd, &tParams);
+
+ return SOK;
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ¶ËµãÀàÐ͵ÄeventÖжϴ¦Àí³ÌÐò
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_EpISRº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ¶ËµãÀàÐ͵ÄeventÖжϴ¦Àí³ÌÐò
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptEpEvt: ¶ËµãÀàÐÍʼþ
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_EpISR(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_EpEvt *ptEpEvt)
+{
+ T_USB3Slave_Ep *ptDep;
+
+ u8 ucEpnum = ptEpEvt->udEndpoint_number;
+
+ ptDep = &(ptUsb3Slave->tEps[ucEpnum]);
+
+ if (0 == ucEpnum || 1 == ucEpnum)
+ {
+ USB3Slave_Ep0ISR(ptUsb3Slave, ptEpEvt);
+ return;
+ }
+
+ switch (ptEpEvt->udEndpoint_event)
+ {
+ case DEPEVT_XFERCOMPLETE:
+ {
+ USB3Slave_EpXferCmplt(ptUsb3Slave, ptDep, ptEpEvt, 1);
+ break;
+ }
+ default:
+ break;
+ }
+
+}
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief É豸¸´Î»Öжϴ¦Àí
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_ResetISRº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - É豸¸´Î»Öжϴ¦Àí
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_ResetISR(T_USB3Slave_SlaveObj *ptUsb3Slave)
+{
+ u32 udRegVal;
+
+ printf("R");
+//tangjian:±êÖ¾usbÁ¬½Ó
+ global.g_Connet = 1;
+
+/* Reset device address to zero */
+ udRegVal = REG32(ptUsb3Slave->udRegs_base + DWC3_DCFG);
+ udRegVal &= ~(0x7f<<3);
+ REG32(ptUsb3Slave->udRegs_base + DWC3_DCFG) = udRegVal;
+
+}
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief »ñÈ¡usb 3.0×ÜÏßʱÖÓ
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_UpdateRamClkSelº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - »ñÈ¡usb 3.0×ÜÏßʱÖÓ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ucSpeed: ָʾÁ¬½ÓËÙ¶È
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_UpdateRamClkSel(T_USB3Slave_SlaveObj *ptUsb3Slave, u32 ucSpeed)
+{
+ u32 udRegVal;
+ /*
+ * RAMClkSel is reset to 0 after USB reset, so it must be reprogrammed
+ * each time on Connect Done.
+ */
+
+ /* ÅäÖÃGCTL¼Ä´æÆ÷,sel bus = 0*/
+ udRegVal = REG32(ptUsb3Slave->udRegs_base + DWC3_GCTL);
+ udRegVal &= ~(0x3<<6);
+ REG32(ptUsb3Slave->udRegs_base + DWC3_GCTL) = udRegVal;
+}
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief É豸Á¬½ÓÖжϴ¦Àí
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_ConnectdoneISR º¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - É豸Á¬½ÓÖжϴ¦Àí
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÀàÐÅÏ¢½á¹¹Ìå
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_ConnectdoneISR(T_USB3Slave_SlaveObj *ptUsb3Slave)
+{
+ T_USB3Slave_Ep *ptDep;
+ u32 udRegVal;
+ u8 ucSpeed;
+
+ printf("D");
+
+
+ udRegVal = REG32(ptUsb3Slave->udRegs_base + DWC3_DSTS);
+ ucSpeed = udRegVal&0x7;
+
+ ptUsb3Slave->ucSpeed = ucSpeed;
+ USB3Slave_UpdateRamClkSel(ptUsb3Slave, ucSpeed);
+ if(USB3_HIGHSPEED == ucSpeed)
+ {
+
+ printf("2");
+ ptUsb3Slave->tEps[2].udMaxPacket = 512;
+ ptUsb3Slave->tEps[3].udMaxPacket = 512;
+ ptUsb3Slave->tEps[4].udMaxPacket = 512;
+ ptUsb3Slave->tEps[5].udMaxPacket = 512;
+ ptUsb3Slave->eDeviceSpeedType = USB30_SPEED_HIGH;
+ desc.atTxEP[0].wMaxPacketSize = USB_HIGHSPEED_BULK_MAXSIZE;
+ desc.atRxEP[0].wMaxPacketSize = USB_HIGHSPEED_BULK_MAXSIZE;
+ desc.atTxEP1[0].wMaxPacketSize = USB_HIGHSPEED_BULK_MAXSIZE;
+ desc.atRxEP1[0].wMaxPacketSize = USB_HIGHSPEED_BULK_MAXSIZE;
+ }
+ else if(USB3_FULLSPEED == ucSpeed)
+ {
+
+ printf("1");
+ ptUsb3Slave->tEps[2].udMaxPacket = 64;
+ ptUsb3Slave->tEps[3].udMaxPacket = 64;
+ ptUsb3Slave->tEps[4].udMaxPacket = 64;
+ ptUsb3Slave->tEps[5].udMaxPacket = 64;
+ ptUsb3Slave->eDeviceSpeedType = USB30_SPEED_FULL;
+ desc.atTxEP[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+ desc.atRxEP[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+ desc.atTxEP1[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+ desc.atRxEP1[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+ }
+//tangjian:ÉèÖÃep0µÄ¶ËµãÐÅÏ¢
+
+ ptDep = &(ptUsb3Slave->tEps[0]);
+ USB3Slave_SetEpCfgCmd(ptUsb3Slave, ptDep);
+ ptDep = &(ptUsb3Slave->tEps[1]);
+ USB3Slave_SetEpCfgCmd(ptUsb3Slave, ptDep);
+
+#if SIM_EN == EMULATION
+
+ REG32(REG_GPIO_OUT)=5;
+// while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+
+ REG32(REG_GPIO_OUT)=6;
+// while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+
+ REG32(REG_GPIO_OUT)=7;
+// while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+
+ REG32(REG_GPIO_OUT)=8;
+// while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+
+#endif
+
+
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief É豸Öжϴ¦Àí(¶Ï¿ª¡¢¸´Î»¡¢Á¬½Ó¡¢»½ÐÑ¡¢Á¬½Ó״̬¸Ä±ä¡¢EOPF¡¢ÃüÁîÍê³É¡¢Òç³ö¡¢´íÎó)
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_DevISRº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - É豸Öжϴ¦Àí(¶Ï¿ª¡¢¸´Î»¡¢Á¬½Ó¡¢»½ÐÑ¡¢Á¬½Ó״̬¸Ä±ä¡¢EOPF¡¢ÃüÁîÍê³É¡¢Òç³ö¡¢´íÎó)
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptDevEvt: É豸ÀàÐÍʼþ
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+
+static void USB3Slave_DevISR(T_USB3Slave_SlaveObj *ptUsb3Slave, const T_USB3Slave_DevEvt *ptDevEvt)
+{
+ switch (ptDevEvt->udType)
+ {
+ case DEVICE_EVENT_RESET:
+ {
+ USB3Slave_ResetISR(ptUsb3Slave);
+ break;
+ }
+ case DEVICE_EVENT_CONNECT_DONE:
+ {
+ USB3Slave_ConnectdoneISR(ptUsb3Slave);
+ break;
+ }
+ case DEVICE_EVENT_EOPF:
+ {
+ printf("S");
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ´¦Àí²»Í¬µÄÖжϺ¯ÊýÈë¿Ú
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_ProcessEvtEntryº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ´¦Àí²»Í¬µÄÖжϺ¯ÊýÈë¿Ú
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - ptEvt: ±íʾevent buffer ÄÚÈÝ
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_ProcessEvtEntry(T_USB3Slave_SlaveObj *ptUsb3Slave, T_USB3Slave_Event *ptEvt)
+{
+ /* Endpoint IRQ, handle it and return early */
+ /*0bit 0ÊÇÉ豸¶ËµãÖÐ¶Ï 1ÊÇÉ豸ÖжÏ*/
+ if (0 == ptEvt->tType.udIs_devspec)
+ USB3Slave_EpISR(ptUsb3Slave, &ptEvt->tEpEvt); /* tDepevt */
+ else
+ USB3Slave_DevISR(ptUsb3Slave, &ptEvt->tDevEvt);
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ´¦Àíevent buffer ÖеÄevent,·Ö·¢²»Í¬event bufferÖмǼµÄÖжϣ¬ÔÙµ÷ÓÃÕæÕýµÄÖжÏÈë¿Ú³ÌÐò
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_ProcessEvtBufº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ´¦Àíevent buffer ÖеÄevent,·Ö·¢²»Í¬event bufferÖмǼµÄÖжϣ¬ÔÙµ÷ÓÃÕæÕýµÄÖжÏÈë¿Ú³ÌÐò
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ * - udBufNum: ±íʾevent bufferÖÐij¸öevent
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_ProcessEvtBuf(T_USB3Slave_SlaveObj *ptUsb3Slave, u32 udBufNum)
+{
+ T_USB3Slave_EventBuf *ptevt;
+ T_USB3Slave_Event ptEvt;
+ u32 udLeft;
+ u32 udCount;
+
+//step0:ÔÚÖжϴ¦Àíº¯ÊýÖлñÈ¡event count£¬À´ÅжÏÓм¸¸öʼþ£¬²¢×÷ÏàÓ¦µÄ´¦Àí
+ udCount = REG32((ptUsb3Slave->udRegs_base + GEVNTCOUNT(udBufNum)));
+ if(!udCount)
+ return;
+ ptevt = ptUsb3Slave->ptEvtBuffs;
+ udLeft = udCount;
+ ptUsb3Slave->udEventsequence = 1;/* ys */
+//step1:´¦ÀíÏàÓ¦µÄʼþ
+ while (udLeft > 0)
+ {
+ ptEvt.udRaw = ptevt->EvtBuf[ptevt->udLpos];
+
+ USB3Slave_ProcessEvtEntry(ptUsb3Slave, &ptEvt);
+ /*
+ * XXX we wrap around correctly to the next entry as almost all
+ * entries are 4 bytes in size. There is one entry which has 12
+ * bytes which is a regular entry followed by 8 bytes data. ATM
+ * I don't know how things are organized if were get next to the
+ * a boundary so I worry about that once we try to handle that.
+ */
+ ptevt->udLpos = (ptevt->udLpos + 1) % EVENT_BUFFERS_SIZE;
+ udLeft -= 4;
+ ptUsb3Slave->udEventsequence++;
+ }
+
+ /*When read, returns the number of valid events in the Event Buffer (in bytes).
+ When written, hardware decrements the count by the value written.
+ The interrupt line remains high when count is not 0.*/
+ REG32(ptUsb3Slave->udRegs_base + GEVNTCOUNT(udBufNum)) = udCount;
+}
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ÖжÏÈë¿Úº¯Êý
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_ISRº¯ÊýÊôÓÚ½Ó¿Úº¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ÖжÏÈë¿Úº¯Êý
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - udIntNo: ÖжϺÅ
+ * - udPara: ÖжϲÎÊý
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ * ÆäËû˵Ã÷:
+ * -
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+void USB3Slave_ISR(u32 udIntNo,u32 udPara)
+{
+ T_USB3Slave_SlaveObj *pUSB3Slv = &g_USB3Slave;
+ u32 udIndex ;
+
+ for (udIndex = 0; udIndex < pUSB3Slv->udNumEvtBufs; udIndex++)
+ {
+ USB3Slave_ProcessEvtBuf(pUSB3Slv,udIndex);
+ }
+
+}
+
+/*³õʼ»¯ÓÃÓڼǼÉ豸ËùÓÐÐÅÏ¢µÄÈ«¾Ö½á¹¹Ìå*/
+/*Ò»´ÎÐÔд²»ÍêÕû£¬ ÔÚ´úÂë²¹³äµÄ¹ý³ÌÖÐÂýÂýÌí¼Ó*/
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ³õʼ»¯È«¾Ö½á¹¹ÌåptUsb3Slave
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Initº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ³õʼ»¯½á¹¹ÌåÄÚÈ«¾Ö±äÁ¿
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ * ÆäËû˵Ã÷:
+ * -
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_Init(T_USB3Slave_SlaveObj *ptUsb3Slave)
+{
+ T_USB3Slave_HWPARAMS *parms = &ptUsb3Slave->tHwParams;
+
+ gp_USB3Slave_EventBuf = &USB3Slave_EventBuf;
+ ptUsb3Slave->udRegs_base = SYS_USB_BASE;
+ ptUsb3Slave->eSpeedMode = USB3_HIGHSPEED;
+
+ parms->udHwparams0 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS0);
+ parms->udHwparams1 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS1);
+ parms->udHwparams2 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS2);
+ parms->udHwparams3 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS3);
+ parms->udHwparams4 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS4);
+ parms->udHwparams5 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS5);
+ parms->udHwparams6 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS6);
+ parms->udHwparams7 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS7);
+ parms->udHwparams8 = REG32(ptUsb3Slave->udRegs_base + GHWPARAMS8);
+
+ ptUsb3Slave->udNumEvtBufs = (parms->udHwparams1&(0x3f<<15))>>15; //»ñÈ¡event_int_num
+// if(global.need_enum ==0)
+ {
+ gp_USB3Slave_EventBuf->udLength = EVENT_BUFFERS_SIZE*4;
+ gp_USB3Slave_EventBuf->udLpos = 0;
+ }
+
+ ptUsb3Slave->ptEvtBuffs = gp_USB3Slave_EventBuf;
+
+ ptUsb3Slave->tCtrlReq = &pCtrlReq;
+}
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ¼Ç¼event bufferµØÖ·µ½¿ØÖÆÆ÷¼Ä´æÆ÷ÖÐ
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_EvtBufSetupº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ¼Ç¼event bufferµØÖ·µ½¿ØÖÆÆ÷¼Ä´æÆ÷ÖÐ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:INT
+ * - ´íÎóÂë
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_EvtBufSetup(T_USB3Slave_SlaveObj *ptUsb3Slave)
+{
+ T_USB3Slave_EventBuf *ptevt;
+ u32 udIndex = 0;
+ u32 udTemp_data;/*ÓÃÀ´±£´æµØÖ·µÄ*/
+
+ ptevt = ptUsb3Slave->ptEvtBuffs;
+ udTemp_data = (u32)&ptevt->EvtBuf;
+ REG32(ptUsb3Slave->udRegs_base + GEVNTADRLO(udIndex)) = udTemp_data;
+ REG32(ptUsb3Slave->udRegs_base + GEVNTADRHI(udIndex)) = 0;
+ REG32(ptUsb3Slave->udRegs_base + GEVNTSIZ(udIndex)) = ptevt->udLength & 0xffff;
+ REG32(ptUsb3Slave->udRegs_base + GEVNTCOUNT(udIndex)) = ptevt->udLpos;
+}
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ¼Ç¼event bufferµØÖ·µ½¿ØÖÆÆ÷¼Ä´æÆ÷ÖÐ
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_EvtBufSetupº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ¼Ç¼event bufferµØÖ·µ½¿ØÖÆÆ÷¼Ä´æÆ÷ÖÐ
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:INT
+ * - ´íÎóÂë
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+
+static void USB3Slave_EvtBufRestore(T_USB3Slave_SlaveObj *ptUsb3Slave)
+{
+ /*T_USB3Slave_EventBuf *ptevt;
+ u32 udIndex = 0;
+ u32 udTemp_data;
+ ptevt = ptUsb3Slave->ptEvtBuffs;
+ udTemp_data = (u32)&ptevt->EvtBuf;
+ REG32(ptUsb3Slave->udRegs_base + GEVNTADRLO(udIndex)) = udTemp_data;
+ REG32(ptUsb3Slave->udRegs_base + GEVNTADRHI(udIndex)) = 0;
+ REG32(ptUsb3Slave->udRegs_base + GEVNTSIZ(udIndex)) = ptevt->udLength & 0xffff;
+ REG32(ptUsb3Slave->udRegs_base + GEVNTCOUNT(udIndex)) = ptevt->udLpos;*/
+ u32 udRegVal;
+ u8 ucSpeed;
+
+ T_USB3Slave_EventBuf *ptevt;
+ u32 udIndex = 0;
+ ptevt = ptUsb3Slave->ptEvtBuffs;
+ ptUsb3Slave->ptEvtBuffs = (T_USB3Slave_EventBuf *)(REG32(ptUsb3Slave->udRegs_base + GEVNTADRLO(udIndex)));
+ ptevt->udLength =REG32(ptUsb3Slave->udRegs_base + GEVNTSIZ(udIndex));
+ // ptevt->udLpos = REG32(ptUsb3Slave->udRegs_base + GEVNTCOUNT(udIndex)) ;
+ ptUsb3Slave->tCtrlReq = (T_USB3Slave_CtrlReq *)(*(u32 *)(*(u32 *)(0x0200c804)));
+
+ udRegVal = REG32(ptUsb3Slave->udRegs_base + DWC3_DSTS);
+ ucSpeed = udRegVal&0x7;
+ ptUsb3Slave->ucSpeed = ucSpeed;
+}
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ÅäÖö˵ã0£¬¿ªÊ¼µÈ´ý½øÐпØÖÆ´«Êä
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_StartCtrlXferº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ÅäÖö˵ã0£¬¿ªÊ¼µÈ´ý½øÐпØÖÆ´«Êä
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ * ÆäËû˵Ã÷:
+ * -
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_StartCtrlXfer(T_USB3Slave_SlaveObj *ptUsb3Slave)
+{
+ T_USB3Slave_Ep *ptDep;
+ u32 udIndex;
+
+ for (udIndex=0; udIndex < 2; udIndex++) /*//MAX_EPS*2 2¶Ëµãbulk out£¬3¶Ëµãbulk in 4¶Ëµãintr out£¬5¶Ëµã intr in*/
+ {
+ ptDep = &(ptUsb3Slave->tEps[udIndex]);
+ ptDep->ptTRB= &USB3Slave_TRB; //tjÿ¸ö¶ËµãʹÓÃͬһ¸ötrb mem
+ ptDep->udEpNum = udIndex;
+ if(global.need_enum ==1)
+ {
+ USB3Slave_CfgEp(ptDep);
+ }
+ }
+ ptUsb3Slave->eEp0State = EP0_SETUP_PHASE;
+//Ö´ÐÐcmd6±íʾstart transfer¡£
+ USB3Slave_Ep0StartXfer(ptUsb3Slave, 0, (u32)(ptUsb3Slave->tCtrlReq), 8, TRBCTL_CONTROL_SETUP);
+}
+
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ³õʼ»¯¶Ëµã½á¹¹Ì壬ÒÔ¼°¶ÔÓ¦¼Ä´æÆ÷ÅäÖÃ(¶ËµãºÅ£¬¶Ëµã״̬£¬´«Êä·½Ïò£¬°ü´óС)
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_InitEpº¯ÊýÊôÓÚÄÚ²¿º¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ³õʼ»¯¶Ëµã½á¹¹Ì壬ÒÔ¼°¶ÔÓ¦¼Ä´æÆ÷ÅäÖÃ(¶ËµãºÅ£¬¶Ëµã״̬£¬´«Êä·½Ïò£¬°ü´óС)
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - ptUsb3Slave: É豸ÐÅÏ¢½á¹¹Ìå
+ *
+ * ·µ »Ø Öµ: ÎÞ
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+static void USB3Slave_InitEp(T_USB3Slave_SlaveObj *ptUsb3Slave)
+{
+ T_USB3Slave_Ep *ptDep;
+ u32 udIndex;
+ /* u32 udFifoNum = 0,udTxfram_space; */
+ for (udIndex = 0; udIndex < ENDPOINTS_NUM; udIndex++)
+ {
+ ptDep = &(ptUsb3Slave->tEps[udIndex]);
+ ptDep->udEpNum = udIndex;
+ ptDep->eEpState = EP_IDLE;
+ ptDep->udFlags = 0; //tj add ¶¨ÒåflagĬÈÏΪ0
+ ptDep->udMaxBurst = 0; //tj add ÓÃÓÚburst size 0-15 : 1-16
+ ptDep->udDirection = udIndex & 1;/*¶¨Òå´«Êä·½Ïò*/
+ if (0 == udIndex|| 1 == udIndex)
+ {
+ ptDep->udMaxPacket = EP0_PACKET_SIZE;/*ÐÒ鹿¶¨¿ØÖÆ´«Êä×î´ó°ü´óС512*/
+ }
+ else
+ {
+ ptDep->udMaxPacket = HS_MAX_PACKET_SIZE;
+ }
+ }
+}
+
+
+
+/**-------------------------------------------------------------------------------------------------------------------@n
+ * @brief ³õʼ»¯¼Ä´æÆ÷
+ *
+ * ¹¦ÄÜÏêÊö:
+ * - USB3Slave_Init º¯ÊýÊôÓÚ½Ó¿Úº¯Êý, Æä¹¦ÄÜÊÇ:
+ * - ³õʼ»¯¼Ä´æÆ÷
+ *
+ * ²ÎÊý¸ÅÊö:
+ * - eUSBSpeedType: USB É豸ËÙ¶ÈÀàÐÍ
+ *
+ * ·µ »Ø Öµ: ÀàÐÍ:u32
+ * - ´íÎóÂë
+ *
+ * ÆäËû˵Ã÷:
+ * -
+ *
+ *--------------------------------------------------------------------------------------------------------------------*/
+u32 USB3Slave_Ctrl_Init(void)
+{
+ u32 udRegValue, i = 0;
+
+ T_USB3Slave_SlaveObj *pUSB3Slv = &g_USB3Slave;
+//step0: ¶Ô½á¹¹Ìåg_USB3Slave½øÐи³Öµ
+ USB3Slave_Init(pUSB3Slv);
+
+//step1:DCTL£¬¶Ô¿ØÖÆÆ÷½øÐÐÈí¸´Î»
+ if(global.need_enum ==1)
+{
+
+ REG32(pUSB3Slv->udRegs_base + DWC3_DCTL) |= DWC3_DCTL_CSFTRST;
+ while(1)
+ {
+ i++;
+ usdelay(10);
+ udRegValue =REG32(pUSB3Slv->udRegs_base + DWC3_DCTL);
+ if ((!(udRegValue & DWC3_DCTL_CSFTRST))||(i>0x1000))/*¸´Î»Íê±Ïºó¸Ãλ×Ô¶¯ÇåÁã*/
+ break;
+ }
+}
+//step2:ÅäÖÃUSB2 PHY */ //0x0007a510
+ /*bit3: 0:8bit 1:16bit
+ bit4: 0:utmi 1:ulpi
+ bit[13:10] 5:16bit utmi 9:8bit utim/ulpi*/
+ if(global.need_enum ==1)
+{
+ #if(SIM_EN == FPGA)
+ #if (USB_PHY == ULPI)
+ udRegValue = 0x7a510|(1<<9); //0xf<<15+0x9<<10+0x1<<4+0x0<<3;
+ #elif (USB_PHY == UTMI)
+ udRegValue = 0x00001408|(1<<9);//0x0<<15|0x5<<10|0x0<<4+0x1<<3;
+ #endif
+ #elif ((SIM_EN == ASIC) || (SIM_EN == EMULATION))
+ udRegValue = 0x00002400|(1<<9);//0x0<<15|0x9<<10|0x0<<4+0x0<<3;
+ #endif
+
+
+ REG32(pUSB3Slv->udRegs_base + DWC3_GUSB2PHYCFG(0)) = udRegValue;
+
+//step3:DCTL£¬¶Ô¿ØÖÆÆ÷ÔٴνøÐÐÈí¸´Î»
+ REG32(pUSB3Slv->udRegs_base + DWC3_DCTL) |= DWC3_DCTL_CSFTRST;
+ while(1)
+ {
+ i++;
+ usdelay(10);
+ udRegValue =REG32(pUSB3Slv->udRegs_base + DWC3_DCTL);
+ if ((!(udRegValue & DWC3_DCTL_CSFTRST))||(i>0x1000))/*¸´Î»Íê±Ïºó¸Ãλ×Ô¶¯ÇåÁã*/
+ break;
+ }
+
+}
+//step4:´Óparams1ÖлñÈ¡eventnum£¬Ó²¼þĬÈÏΪ1,ÅäÖÃevent_buffer
+ if(global.need_enum ==1)
+{
+
+ USB3Slave_EvtBufSetup(pUSB3Slv);
+}
+ else
+{
+ USB3Slave_EvtBufRestore(pUSB3Slv);
+}
+
+//step5: ÅäÖüĴæÆ÷c110£¬°üº¬ÅäÖÃdev mode,ÅäÖÃc700,°üº¬high speed
+if(global.need_enum ==1)
+{
+
+ udRegValue = REG32(pUSB3Slv->udRegs_base + DWC3_GCTL);
+ udRegValue = (udRegValue & 0xffff0000) | 0x200c;//ÔÀ´ÊÇ0x2008 scaledown
+ udRegValue = udRegValue & (~(1<<17)); // In the real hardware, this bit must be set to 1'b0
+ udRegValue = udRegValue & (~(1<<16));//2012.11.9,never attempts three more times to connect at SS
+#if SIM_EN == EMULATION
+ udRegValue = (udRegValue & 0xffff0000) | 0x2008;
+ udRegValue = udRegValue|(0x3<<4); //lanxiang scaledown
+ udRegValue = udRegValue|(1<<16);
+#endif
+ REG32(pUSB3Slv->udRegs_base + DWC3_GCTL) = udRegValue;
+
+ udRegValue = REG32(pUSB3Slv->udRegs_base + DWC3_DCFG);
+ udRegValue &= ~(DWC3_DCFG_SPEED_MASK); //0Ϊhigh speed
+ udRegValue &= (~(0x1f<<17));
+ udRegValue |= pUSB3Slv->eSpeedMode | (1<<17) ; /*1×óÒÆ17ΪÀ´×ÔÑéÖ¤ÂãÇý£¬Óдý·ÖÎö£¬pxp*/
+ REG32(pUSB3Slv->udRegs_base + DWC3_DCFG)= udRegValue;
+}
+ pUSB3Slv->eDeviceSpeedType = USB30_SPEED_UNKNOWN;
+
+//step6:³õʼ»¯EP¶Ëµã£¬bootÖÐÖ»Óõ½0£¬1£¬2£¬3£¬4£¬5£¬ÆäËüµÄ¿ÉÒÔ¿¼ÂDz»Òª¡£
+
+ USB3Slave_InitEp(pUSB3Slv);
+
+//step7:ÅäÖÃÖжÏ(reset , connect done)ʹÄÜ£¬ÈíÁ¬½Ó£¬µÚ31bitÅäÖÃΪrun
+if(global.need_enum ==1)
+{
+ udRegValue = REG32(pUSB3Slv->udRegs_base + DWC3_DEVTEN);
+ udRegValue = udRegValue | (DWC3_DEVTEN_CONNECTDONEEN | DWC3_DEVTEN_USBRSTEN|DWC3_DEVTEN_USBSUSPENDEN);
+ //udRegValue = udRegValue & (~(1<<6)) & (~(1<<7));
+ REG32(pUSB3Slv->udRegs_base + DWC3_DEVTEN) = udRegValue;
+}
+//step8:start control tranfer
+ USB3Slave_StartCtrlXfer(pUSB3Slv);
+ if(global.need_enum ==1)
+{
+
+//step9:run softconnect
+ udRegValue = REG32(pUSB3Slv->udRegs_base + DWC3_DCTL);
+ udRegValue |= (1U<<31); //tj add 31bit for run or stop,correspond to softdisconnect
+ REG32(pUSB3Slv->udRegs_base + DWC3_DCTL) = udRegValue;
+
+
+#if SIM_EN == EMULATION
+ //for hsic
+ REG32(REG_GPIO_OUT)=2;
+// while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+#endif
+}
+
+ return SOK;
+}
+
+
+u32 USB3_RecvOutData(u32 dwEPNo, u8 *pchBuf, u32 dwLen, F_USB_CB fnUsbCb, void *pPara)
+{
+ T_USB3Slave_Ep *ptDep;
+ T_USB3Slave_SlaveObj *ptUsb3Slave = &g_USB3Slave;
+
+ ptDep = &(ptUsb3Slave->tEps[dwEPNo]);
+
+ ptDep->pudAddrData =(u32*)pchBuf;
+ ptDep->udLen = dwLen;
+ ptDep->fnUsbCb = fnUsbCb;
+ ptDep->pPara = pPara;
+
+ USB3Slave_EpStartXfer(ptDep, 0, 1);
+
+#if SIM_EN == EMULATION
+ REG32(ARM_PORTA)=0x80;
+#endif
+
+ return SOK;
+}
+
+
+
+u32 USB3_SendInData(u32 dwEPNo, u8 *pchBuf, u32 dwLen, F_USB_CB fnUsbCb, void *pPara)
+{
+
+ T_USB3Slave_Ep *ptDep;
+ T_USB3Slave_SlaveObj *ptUsb3Slave = &g_USB3Slave;
+
+ ptDep = &(ptUsb3Slave->tEps[dwEPNo]);
+
+ ptDep->pudAddrData = (u32*)pchBuf;
+ ptDep->udLen = dwLen;
+ ptDep->fnUsbCb = fnUsbCb;
+ ptDep->pPara = pPara;
+
+ USB3Slave_EpStartXfer(ptDep, 0, 1);
+
+#if SIM_EN == EMULATION
+ REG32(ARM_PORTA)=0x82;
+#endif
+
+ return SOK;
+}
+
+u32 USB3Slave_IsNeedZero(u32 dwLen)
+{
+ T_USB3Slave_Ep *ptDep;
+ T_USB3Slave_SlaveObj *ptUsb3Slave = &g_USB3Slave;
+ u32 udMaxPacket;
+
+ if (ptUsb3Slave->ucSpeed == USB3_HIGHSPEED)
+ {
+ udMaxPacket = HS_MAX_PACKET_SIZE;
+ }
+ else if (ptUsb3Slave->ucSpeed == USB3_FULLSPEED)
+ {
+ udMaxPacket = FS_MAX_PACKET_SIZE;
+ }
+ if (dwLen%udMaxPacket == 0)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+/*ö¾Ùº¯Êý*/
+u32 USB3Slave_CDC_Enum(void)
+{
+ T_USB3Slave_Ep *ptDep;
+ u32 dwCount=0;
+ u32 dwCount1=0;
+ u32 udIndex;
+
+
+ global.g_Connet = 0;
+ USB3Slave_Ctrl_Init();
+ if(global.need_enum ==0)
+ {
+ for (udIndex=2; udIndex < 6; udIndex++) /*//MAX_EPS*2 2¶Ëµãbulk out£¬3¶Ëµãbulk in 4¶Ëµãintr out£¬5¶Ëµã intr in*/
+ {
+ ptDep = &(g_USB3Slave.tEps[udIndex]);
+ ptDep->ptTRB= &USB3Slave_TRB_EP[udIndex-2]; //tjÿ¸ö¶ËµãʹÓÃͬһ¸ötrb mem
+ ptDep->udEpNum = udIndex;
+
+ //USB3Slave_CfgEp(ptDep);
+ }
+ }
+if(global.need_enum ==1)
+{
+ while(1)
+ {
+ USB3Slave_ISR(0,0);
+ if(0 == global.g_Connet)
+ {
+ dwCount++;
+ usb_timeout_usdelay(50000);
+ if(dwCount>(4000*global.g_USB_TIMEOUT))
+ return 1;
+
+ }
+ else if(1 == g_USB3Slave.udUSBSate)
+ {
+ for (udIndex=2; udIndex < 6; udIndex++) /*//MAX_EPS*2 2¶Ëµãbulk out£¬3¶Ëµãbulk in 4¶Ëµãintr out£¬5¶Ëµã intr in*/
+ {
+ ptDep = &(g_USB3Slave.tEps[udIndex]);
+ ptDep->ptTRB= &USB3Slave_TRB_EP[udIndex-2]; //tjÿ¸ö¶ËµãʹÓÃͬһ¸ötrb mem
+ ptDep->udEpNum = udIndex;
+ USB3Slave_CfgEp(ptDep);
+ }
+ break;
+ }
+ else
+ {
+ dwCount1++;
+ usb_timeout_usdelay(50000);
+ if(dwCount1>(200000*global.g_USB_TIMEOUT))
+ {
+ return 1;
+ }
+
+ }
+ }
+}
+ return 0;
+}
+
+extern void USB_Boot(void);
+extern void USB_Pll_Clk_Rst_InitEnv(void);
+
+void USB3Slave_boot(void)
+{
+ u32 dwConnect;
+ global.g_USB_MODE = 0;
+ global.need_enum = 0;
+// 1:config clock
+ if(global.need_enum ==1)
+ {
+ USB_Pll_Clk_Rst_InitEnv();
+ }
+// 2:USB30_CDC_Enum
+ dwConnect = USB3Slave_CDC_Enum();
+ if(1==dwConnect)
+ {
+ printf("NOLINK\n");
+ return ;
+ }
+
+#if 0//SIM_EN == EMULATION
+ REG32(ARM_PORTA)=0x32;
+#endif
+ printf("FAILED\n");
+}
+
+/** @} */
+
+
diff --git a/boot/common/src/loader/drivers/drv_usb3slave.h b/boot/common/src/loader/drivers/drv_usb3slave.h
new file mode 100644
index 0000000..a851b15
--- /dev/null
+++ b/boot/common/src/loader/drivers/drv_usb3slave.h
@@ -0,0 +1,643 @@
+/*******************************************************************************
+* °æÈ¨ËùÓÐ (C)2010, ÉîÛÚÊÐÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
+*
+* ÎļþÃû³Æ£º drv_usb3slave.h
+* Îļþ±êʶ£º
+* ÄÚÈÝÕªÒª£º
+* ÆäËü˵Ã÷£º zx297520 project
+* µ±Ç°°æ±¾£º 1.0
+* ×÷¡¡¡¡Õߣº tangjian
+* Íê³ÉÈÕÆÚ£º
+*
+*
+*******************************************************************************/
+
+#ifndef __USB3_SLAVE_DRV_H
+#define __USB3_SLAVE_DRV_H
+
+/* *INDENT-OFF* */
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* *INDENT-ON* */
+
+/*
+**==================================================================
+** Include files
+**==================================================================
+*/
+#include "usb.h"
+#include "global.h"
+#include "drv_usb3slave_reg.h"
+
+#include "dwc_otg_cil.h" //ÓÃÓÚ¶¨Ò廨µ÷º¯Êý
+
+/* DRV´íÎóÂë */
+#define SOK (0) /**< ÕýÈ· */
+#define ERR_FAIL (0x01) /**< Ò»°ã´íÎó */
+#define ERR_INUSE (0x02) /**< ÍâÉè×ÊÔ´ÕýÔÚʹÓà */
+#define ERR_XIO (0x03) /**< ¹²Ïí×ÊÔ´¾ºÕù */
+#define ERR_OVFL (0x04) /**< ¿ÉÓÃ×ÊÔ´ºÄ¾¡ */
+#define ERR_INVHANDLE (0x05) /**< ´«Èë¾ä±úÎÞЧ */
+#define ERR_INVPARAMS (0x06) /**< ²ÎÊýÎÞЧ */
+#define ERR_INVCMD (0x07) /**< ÃüÁîÎÞЧ */
+#define ERR_NOMEM (0x08) /**< ÄÚ´æºÄ¾¡ */
+#define ERR_UNSUPPORTED (0x09) /**< ÐÐΪ²»Ö§³Ö */
+#define ERR_INVHWVERSION (0x10) /**< Ó²¼þ°æ±¾²»Æ¥Åä */
+
+#define FALSE 0
+#define TRUE 1
+
+#define DWC3_DCFG_SPEED_MASK (7 << 0)
+
+#define DWC3_DCFG 0xc700
+#define DWC3_DCFG_DEVADDR(addr) ((addr) << 3)
+#define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f)
+#define DWC3_DCTL 0xc704
+#define DWC3_DCTL_CSFTRST (1 << 30)
+/*0x200-0x23c*/
+#define DWC3_GUSB2PHYCFG(n) (0xc200 + (n * 0x04))
+/*0x2C0-0x2fc*/
+#define DWC3_GUSB3PIPECTL(n) (0xc2c0 + (n * 0x04))
+
+/*0x300-0x37C*/
+#define DWC3_GTXFIFOSIZ(n) (0xc300 + (n * 0x04))
+
+/*0x380-0x3fc*/
+#define DWC3_GRXFIFOSIZ(n) (0xc380 + (n * 0x04))
+
+#define DWC3_GCTL 0xc110
+#define DWC3_DCTL_RUN_STOP (1 << 31)
+
+#define DWC3_DEVTEN_USBSUSPENDEN (1 << 6)
+#define DWC3_DEVTEN_WKUPEVTEN (1 << 4)
+#define DWC3_DEVTEN_ULSTCNGEN (1 << 3)
+#define DWC3_DEVTEN_CONNECTDONEEN (1 << 2)
+#define DWC3_DEVTEN_USBRSTEN (1 << 1)
+#define DWC3_DEVTEN_DISCONNEVTEN (1 << 0)
+
+#define DWC3_DEVTEN 0xc708
+#define DWC3_DSTS 0xc70c
+
+#define DWC3_DALEPENA 0xc720
+/** ¶¨ÒåÃèÊö·ûÀàÐÍ */
+#define USB_DT_DEVICE 0x01
+#define USB_DT_CONFIG 0x02
+#define USB_DT_STRING 0x03
+#define USB_DT_INTERFACE 0x04
+#define USB_DT_ENDPOINT 0x05
+#define USB_DT_DEVICE_QUALIFIER 0x06
+#define USB_DT_OTHER_SPEED_CONFIG 0x07
+#define USB_DT_INTERFACE_POWER 0x08
+/** these are from a minor usb 2.0 revision (ECN) */
+#define USB_DT_OTG 0x09
+#define USB_DT_DEBUG 0x0a
+#define USB_DT_INTERFACE_ASSOCIATION 0x0b
+/** these are from the Wireless USB spec */
+#define USB_DT_SECURITY 0x0c
+#define USB_DT_KEY 0x0d
+#define USB_DT_ENCRYPTION_TYPE 0x0e
+#define USB_DT_BOS 0x0f
+#define USB_DT_DEVICE_CAPABILITY 0x10
+#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
+#define USB_DT_WIRE_ADAPTER 0x21
+#define USB_DT_RPIPE 0x22
+#define USB_DT_CS_RADIO_CONTROL 0x23
+/** From the T10 UAS specification */
+#define USB_DT_PIPE_USAGE 0x24
+/** From the USB 3.0 spec */
+#define USB_DT_SS_ENDPOINT_COMP 0x30
+/** USB directions */
+#define USB_DIR_OUT 0 /* to device */
+#define USB_DIR_IN 0x80 /* to host */
+/** USB types, the second of three bmRequestType fields, ÐÒé9.3.1 */
+#define USB_TYPE_MASK (0x03 << 5)
+#define USB_TYPE_STANDARD (0x00 << 5)
+#define USB_TYPE_CLASS (0x01 << 5)
+#define USB_TYPE_VENDOR (0x02 << 5)
+#define USB_TYPE_RESERVED (0x03 << 5)
+/** USB recipients, the third of three bmRequestType fields */
+#define USB_RECIP_MASK 0x1f
+#define USB_RECIP_DEVICE 0x00
+#define USB_RECIP_INTERFACE 0x01
+#define USB_RECIP_ENDPOINT 0x02
+#define USB_RECIP_OTHER 0x03
+/** From Wireless USB 1.0 */
+#define USB_RECIP_PORT 0x04
+#define USB_RECIP_RPIPE 0x05
+/*
+* Standard requests, for the bRequest field of a SETUP packet.
+*
+* These are qualified by the bmRequestType field, so that for example
+* TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved
+* by a GET_STATUS request.
+*/
+#define USB_REQ_GET_STATUS 0x00
+#define USB_REQ_CLEAR_FEATURE 0x01
+#define USB_REQ_SET_FEATURE 0x03
+#define USB_REQ_SET_ADDRESS 0x05
+#define USB_REQ_GET_DESCRIPTOR 0x06
+#define USB_REQ_SET_DESCRIPTOR 0x07
+#define USB_REQ_GET_CONFIGURATION 0x08
+#define USB_REQ_SET_CONFIGURATION 0x09
+#define USB_REQ_GET_INTERFACE 0x0A
+#define USB_REQ_SET_INTERFACE 0x0B
+#define USB_REQ_SYNCH_FRAME 0x0C
+#define USB_REQ_GET_MAX_LUN 0xFE
+/*
+* USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and
+* are read as a bit array returned by USB_REQ_GET_STATUS. (So there
+* are at most sixteen features of each type.) Hubs may also support a
+* new USB_REQ_TEST_AND_SET_FEATURE to put ports into L1 suspend.
+*/
+#define USB_DEVICE_SELF_POWERED 0 /**< (read only) */
+#define USB_DEVICE_REMOTE_WAKEUP 1 /**< dev may initiate wakeup */
+#define USB_DEVICE_TEST_MODE 2 /**< (wired high speed only) */
+#define USB_DEVICE_BATTERY 2 /**< (wireless) */
+#define USB_DEVICE_B_HNP_ENABLE 3 /**< (otg) dev may initiate HNP */
+#define USB_DEVICE_WUSB_DEVICE 3 /**< (wireless)*/
+#define USB_DEVICE_A_HNP_SUPPORT 4 /**< (otg) RH port supports HNP */
+#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /**< (otg) other RH port does */
+#define USB_DEVICE_DEBUG_MODE 6 /**< (special devices only) */
+/*
+* New Feature Selectors as added by USB 3.0
+* See USB 3.0 spec Table 9-7
+* Suspend Options, Table 9-7 USB 3.0 spec
+*/
+#define USB_DEVICE_U1_ENABLE 48 /**< dev may initiate U1 transition */
+#define USB_DEVICE_U2_ENABLE 49 /**< dev may initiate U2 transition */
+#define USB_DEVICE_LTM_ENABLE 50 /**< dev may send LTM */
+
+#define USB_INTRF_FUNC_SUSPEND 0 /**< function suspend */
+#define USB_INTR_FUNC_SUSPEND_OPT_MASK 0xFF00
+#define USB_INTRF_FUNC_SUSPEND_LP (1 << (8 + 0))
+#define USB_INTRF_FUNC_SUSPEND_RW (1 << (8 + 1))
+
+#define USB_ENDPOINT_HALT 0 /**< IN/OUT will STALL */
+
+/** Bit array elements as returned by the USB_REQ_GET_STATUS request */
+#define USB_DEV_STAT_U1_ENABLED 2 /**< transition into U1 state */
+#define USB_DEV_STAT_U2_ENABLED 3 /**< transition into U2 state */
+#define USB_DEV_STAT_LTM_ENABLED 4 /**< Latency tolerance messages */
+/**
+* USB function drivers should return USB_GADGET_DELAYED_STATUS if they
+* wish to delay the data/status stages of the control transfer till they
+* are ready. The control transfer will then be kept from completing till
+* all the function drivers that requested for USB_GADGET_DELAYED_STAUS
+* invoke usb_composite_setup_continue().
+*/
+#define USB_GADGET_DELAYED_STATUS 0x7fff /**< Impossibly large value */
+//#define EP0_PACKET_SIZE 64
+//#define MAX_EPS (0x8)
+
+/**
+* struct usb_ctrlrequest - SETUP data for a USB device control request
+* Note that the driver for any interface can issue control requests.
+* For most devices, interfaces don't coordinate with each other, so
+* such requests may be made at any time.
+*/
+
+ typedef struct T_USB3Slave_CtrlReq
+{
+ u8 bmRequestType; /**< Æ¥Åäsetup°übmRequestTypeÓò */
+ u8 bRequest; /**< Æ¥Åäsetup°übRequestÓò */
+ u16 wValue; /**< Æ¥Åäsetup°üwValueÓò */
+ u16 wIndex; /**< Æ¥Åäsetup°üwIndexÓò */
+ u16 wLength; /**< Æ¥Åäsetup°üwLengthÓò */
+}__attribute__ ((__packed__)) T_USB3Slave_CtrlReq;
+
+/** ¶Ëµã´«ÊäÀàÐ͵Ⱥ궨Òå */
+#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
+#define USB_ENDPOINT_DIR_MASK 0x80
+
+#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
+#define USB_ENDPOINT_XFER_CONTROL 0
+#define USB_ENDPOINT_XFER_ISOC 1
+#define USB_ENDPOINT_XFER_BULK 2
+#define USB_ENDPOINT_XFER_INT 3
+#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
+
+/** ×î´ó°ü´óС£¬²ÎÕÕÐÒ飬¾ù¿ÉÉèÖÃΪ1024 */
+#define HS_MAX_PACKET_SIZE 512
+#define FS_MAX_PACKET_SIZE 64
+/** ¿ØÖÆ´«Êä×î´ó°ü´óС */
+/** ¶ËµãÊýÄ¿ */
+#define ENDPOINTS_NUM 6
+/** ÐÒé¶ËµãÃèÊö·û */
+
+/** TRB¿ØÖÆÖи÷¸öλ¶ÎµÄºê¶¨Òå*/
+#define TRBCTL_NORMAL 1
+#define TRBCTL_CONTROL_SETUP 2
+#define TRBCTL_CONTROL_STATUS2 3
+#define TRBCTL_CONTROL_STATUS3 4
+#define TRBCTL_CONTROL_DATA 5
+#define TRBCTL_ISOCHRONOUS_FIRST 6
+#define TRBCTL_ISOCHRONOUS 7
+#define TRBCTL_LINK_TRB 8
+/** struct T_USB3Slave_TRBToHW - transfer request block (hw format) */
+typedef struct T_USB3Slave_TRBToHW
+{
+ u32 udBpl; /**< Ö¸ÏòbufferµÄµÍ32λµØÖ· */
+ u32 udBph; /**< Ö¸ÏòbufferµÄ¸ß32λµØÖ· */
+ u32 udSize; /**< Êý¾Ý´«ÊäµÄ³¤¶È */
+ u32 udCtrl; /**< TRB¿ØÖÆ */
+}__attribute__ ((__packed__)) T_USB3Slave_TRBToHW;
+
+/** struct T_USB3Slave_TRB - transfer request block */
+ typedef struct T_USB3Slave_TRB
+{
+ u64 bplh; /**< Ö¸ÏòbufferµØÖ· */
+
+ union
+ {
+ struct
+ {
+ u32 BUFSIZ:24; /**< Êý¾Ý´«ÊäµÄ³¤¶È */
+ u32 PCM1:2; /**< Packet Count M1 */
+ u32 Reserved27_26:2;
+ u32 TRBSTS:4; /**< TRB״̬ */
+ }bit;
+ u32 udVal;
+ }len_pcm;
+
+ union
+ {
+ struct
+ {
+ u32 HWO:1; /**< ָʾӲ¼þÓµÓеÄTRB */
+ u32 LST:1; /**< ×îºóÒ»¸öTRB */
+ u32 CHN:1; /**< ´ËTRBÓëÏÂÒ»¸öTRBÏà¹ØÁª */
+ u32 CSP:1; /**< µ±½ÓÊÕµ½Ò»¸ö¶Ì°ücore½«»á¼ÌÐøµ½ÏÂÒ»¸öBuffer Descriptor */
+ u32 TRBCTL:6; /**< TRB ¿ØÖÆ */
+ u32 ISP_IMI:1; /**< Interrupt on Short Packet/Interrupt on Missed ISOC */
+ u32 IOC:1; /**< Èç¹û±»ÉèÖ㬱íʾ´«ÊäÍê³Éºó²úÉúÖÐ¶Ï */
+ u32 Reserved13_12:2;
+ u32 StreamID_SOFNum:16; /**< Stream ID/SOF Number */
+ u32 Reserved31_30:2;
+ }bit;
+ u32 udVal;
+ }control;
+}__attribute__ ((__packed__)) T_USB3Slave_TRB;
+
+/** EVENT buffer´óС */
+#define EVENT_BUFFERS_SIZE 256//256
+
+/**
+* struct T_USB3Slave_EventBuf - Software event buffer representation
+*/
+
+typedef struct
+{
+ u32 EvtBuf[EVENT_BUFFERS_SIZE]; /**< ·ÖÅäµÄEVENT Buffer */
+ u32 udLength; /**< ·ÖÅäEVENT Buffer ´óС */
+ u32 udLpos; /**< ÓÃÓÚָʾµ±Ç°EVENTµÄÆðʼλÖà */
+}T_USB3Slave_EventBuf;
+
+
+/** EVENTÀàÐÍ */
+#define EVENT_TYPE_MASK 0xfe
+#define EVENT_TYPE_DEV 0
+#define EVENT_TYPE_CARKIT 3
+#define EVENT_TYPE_I2C 4
+typedef struct T_USB3Slave_EventType
+{
+ u32 udIs_devspec:1; /**< ÓÃÓÚÅжÏÊǶ˵ãÀàÐÍEVENT»¹ÊÇÉ豸ÀàÐÍEVENT */
+ u32 udType:6; /**< EVENT ÀàÐÍ */
+ u32 udReserved8_31:25;
+}__attribute__ ((__packed__)) T_USB3Slave_EventType;
+
+/** ¶ËµãÀàÐÍEVENTÀàÐÍ */
+#define DEPEVT_XFERCOMPLETE 0x01
+#define DEPEVT_XFERINPROGRESS 0x02
+#define DEPEVT_XFERNOTREADY 0x03
+#define DEPEVT_RXTXFIFOEVT 0x04
+#define DEPEVT_STREAMEVT 0x06
+#define DEPEVT_EPCMDCMPLT 0x07
+
+#define DEPEVT_STATUS_BUSERR (1 << 0)
+#define DEPEVT_STATUS_SHORT (1 << 1)
+#define DEPEVT_STATUS_IOC (1 << 2)
+#define DEPEVT_STATUS_LST (1 << 3)
+/** Stream event only */
+#define DEPEVT_STREAMEVT_FOUND 1
+#define DEPEVT_STREAMEVT_NOTFOUND 2
+/** Control-only Status */
+#define DEPEVT_STATUS_CONTROL_SETUP 0
+#define DEPEVT_STATUS_CONTROL_DATA 1
+#define DEPEVT_STATUS_CONTROL_STATUS 2
+#define DEPEVT_STATUS_STATUS_SETUP 10
+
+/**
+* struct dwc3_event_depvt - Device Endpoint Events
+* @udOne_bit: indicates this is an endpoint event (not used)
+* @udEndpoint_number: number of the endpoint
+* @udEndpoint_event: The event we have:
+* 0x00 - Reserved
+* 0x01 - XferComplete
+* 0x02 - XferInProgress
+* 0x03 - XferNotReady
+* 0x04 - RxTxFifoEvt (IN->Underrun, OUT->Overrun)
+* 0x05 - Reserved
+* 0x06 - StreamEvt
+* 0x07 - EPCmdCmplt
+* @udReserved11_10: Reserved, don't use.
+* @EventStatus: Indicates the status of the event. Refer to databook for more information.
+* @EventParam: Parameters of the current event. Refer to databook for more information.
+*/
+/** ²Î¼ûÊÖ²á7.2.8.1ÃèÊö¶ËµãÀàÐÍEVENT */
+ typedef struct T_USB3Slave_EpEvt
+{
+ u32 udOne_bit:1; /**< 1bitÓÃÓÚÅжÏÊǶ˵ãÀàÐÍevent»¹ÊÇÉ豸ÀàÐÍevent */
+ u32 udEndpoint_number:5; /**< ָʾÎïÀí¶ËµãºÅ */
+ u32 udEndpoint_event:4; /**< ָʾ¶ËµãÀàÐÍevent */
+ u32 udReserved11_10:2;
+ u32 EventStatus:4; /**< ָʾevent״̬£¬Refer to databook for more information*/
+ u32 EventParam:16; /**< µ±Ç°event²ÎÊý. Refer to databook for more information */
+}__attribute__ ((__packed__)) T_USB3Slave_EpEvt;
+
+/**
+* struct T_USB3Slave_DevEvt - Device Events
+* @udOne_bit: indicates this is a non-endpoint event (not used)
+* @udDevice_event: indicates it's a device event. Should read as 0x00
+* @udType: indicates the type of device event.
+* 0 - DisconnEvt
+* 1 - USBRst
+* 2 - ConnectDone
+* 3 - ULStChng
+* 4 - WkUpEvt
+* 5 - Reserved
+* 6 - EOPF
+* 7 - SOF
+* 8 - Reserved
+* 9 - ErrticErr
+* 10 - CmdCmplt
+* 11 - EvntOverflow
+* 12 - VndrDevTstRcved
+* @udReserved15_12: Reserved, not used
+* @udEvtInfo: Information about this event
+* @udReserved31_24: Reserved, not used
+*/
+/** DEVICE EVENT ÀàÐÍ */
+#define DEVICE_EVENT_DISCONNECT 0
+#define DEVICE_EVENT_RESET 1
+#define DEVICE_EVENT_CONNECT_DONE 2
+#define DEVICE_EVENT_LINK_STATUS_CHANGE 3
+#define DEVICE_EVENT_WAKEUP 4
+#define DEVICE_EVENT_EOPF 6
+#define DEVICE_EVENT_SOF 7
+#define DEVICE_EVENT_ERRATIC_ERROR 9
+#define DEVICE_EVENT_CMD_CMPL 10
+#define DEVICE_EVENT_OVERFLOW 11
+
+typedef struct T_USB3Slave_DevEvt
+{
+ u32 udOne_bit:1; /**< 1bitÓÃÓÚÅжÏÊǶ˵ãÀàÐÍevent»¹ÊÇÉ豸ÀàÐÍevent */
+ u32 udDevice_event:7; /**< É豸ÀàÐÍevent */
+ u32 udType:4; /**< ָʾ·¢ÉúµÄ¸÷ÖÖevent */
+ u32 udReserved15_12:4;
+ u32 udEvtInfo:8; /**< event ÐÅÏ¢±ÈÌØ¡£ÓÃÓÚָʾÊÇ·ñÊÇSSºÍlink state */
+ u32 udReserved31_24:8;
+}__attribute__ ((__packed__)) T_USB3Slave_DevEvt;
+
+/**
+* struct T_USB3Slave_Event_GEvt - Other Core Events
+* @udOne_bit: indicates this is a non-endpoint event (not used)
+* @udDevice_event: indicates it's (0x03) Carkit or (0x04) I2C event.
+* @udPhy_port_number: self-explanatory
+* @udReserved31_12: Reserved, not used.
+*/
+
+ typedef struct T_USB3Slave_Event_GEvt
+{
+ u32 udOne_bit:1;
+ u32 udDevice_event:7;
+ u32 udPhy_port_number:4;
+ u32 udReserved31_12:20;
+}__attribute__ ((__packed__)) T_USB3Slave_Event_GEvt;
+
+/** union T_USB3Slave_Event - representation of Event Buffer contents */
+
+typedef union
+{
+ u32 udRaw; /**< ָʾµ±Ç°eventµÄÖµ */
+ T_USB3Slave_EventType tType; /**< ָʾevent ÀàÐÍ(00h±íʾdevice specific event) */
+ T_USB3Slave_EpEvt tEpEvt; /**< ¶ËµãÀàÐÍevent */
+ T_USB3Slave_DevEvt tDevEvt; /**< É豸ÀàÐÍevent */
+ T_USB3Slave_Event_GEvt tGetEvt; /**< Other Core Events */
+}T_USB3Slave_Event;
+
+/** ¶¨ÒåEPµÄ±ê¼Çºê */
+#define EP_ENABLED (1 << 0)
+#define EP_STALL (1 << 1)
+#define EP_WEDGE (1 << 2)
+#define EP_BUSY (1 << 4)
+#define EP_PENDING_REQUEST (1 << 5)
+/** This last one is specific to EP0 */
+#define EP0_DIR_IN ((u32)1 << 31)
+/** EP񈬀 */
+#define EP_FLAG_STALLED (1 << 0)
+#define EP_FLAG_WEDGED (1 << 1)
+/** EP·½Ïò */
+#define EP_DIRECTION_TX true
+#define EP_DIRECTION_RX false
+
+/** ¶ËµãµÄ״̬±ä»¯*/
+typedef enum
+{
+ EP_IDLE = 0, /**< EP¿ÕÏÐ */
+ EP_HALTED, /**< EP halt */
+ EP0_CTRLIN_SETUP, /**< EP0¿ØÖƽ¨Á¢IN½×¶Î */
+ EP0_CTRLOUT_SETUP, /**< EP0¿ØÖƽ¨Á¢OUT½×¶Î */
+ EP0_CTRLNULL_SETUP, /**< EP0¿ØÖƽ¨Á¢Îª¿Õ */
+ EP0_CTRL_INDATA, /**< EP0¿ØÖÆINÊý¾Ý½×¶Î */
+ EP0_CTRL_OUTDATA, /**< EP0¿ØÖÆOUTÊý¾Ý½×¶Î */
+ EP0_CTRL_INSTATUS, /**< EP0¿ØÖÆIN״̬½×¶Î */
+ EP0_CTRL_OUTSTATUS, /**< EP0¿ØÖÆOUT״̬½×¶Î */
+ EP_RX, /**< EP½ÓÊÕ״ָ̬ʾ */
+ EP_TX /**< EP·¢ËÍ״ָ̬ʾ */
+}E_USB3Slave_EpState;
+
+/** ָʾEp0ÏÂÒ»¸öEVENTÀàÐÍ */
+typedef enum
+{
+ EP0_UNKNOWN = 0,
+ EP0_COMPLETE, /**< EP0״ָ̬ʾΪÍê³É*/
+ EP0_NRDY_SETUP, /**< EP0״̬NRDYָʾΪ½¨Á¢½×¶Î*/
+ EP0_NRDY_DATA, /**< EP0״̬NRDYָʾΪÊý¾Ý½×¶Î*/
+ EP0_NRDY_STATUS, /**< EP0״̬NRDYָʾΪ״̬½×¶Î*/
+} E_USB3Slave_Ep0Next;
+/** ָʾEP0¿ØÖÆ´«ÊäµÄÈý¸ö½×¶Î */
+typedef enum
+{
+ EP0_UNCONNECTED = 0,
+ EP0_SETUP_PHASE, /**< EP0¿ØÖÆ´«ÊäµÄ½¨Á¢½×¶Î */
+ EP0_DATA_PHASE, /**< EP0¿ØÖÆ´«ÊäµÄÊý¾Ý½×¶Î */
+ EP0_STATUS_PHASE, /**< EP0¿ØÖÆ´«ÊäµÄ״̬½×¶Î */
+}E_USB3Slave_Ep0State;
+/** ³¬¸ßËÙģʽϵÄÁ¬½Ó״̬ */
+
+
+/** ¿ØÖÆ´«ÊäÖÐö¾ÙËù´¦µÄ״̬½×¶Î */
+typedef enum
+{
+ DEFAULT_STATE = 0, /**< ȱʡ״̬ */
+ ADDRESS_STATE, /**< µØÖ·×´Ì¬ */
+ CONFIGURED_STATE, /**< ÅäÖÃ״̬ */
+ SETINTERFACE_STATE, /**< ÉèÖýӿÚ״̬*/
+ GETMAXLUN_STATE, /**<GET MAX lUN*/
+ BULKIN_CMPL, /**< BULK IN´«ÊäÍê³É״̬ */
+ BULKOUT_CMPL, /**< BULK OUT´«ÊäÍê³É״̬ */
+ IntrIN_CMPL, /**< Interrupt IN´«ÊäÍê³É״̬ */
+ IntrOUT_CMPL, /**< Interrupt OUT´«ÊäÍê³É״̬ */
+}E_USB3Slave_ReqState;
+
+/** ¶¨ÒåUSB3.0µÄËÙ¶ÈÀàÐÍ£¬²ÎÕÕ¿ØÖÆÆ÷ÊÖ²áP513, DCFG¼Ä´æÆ÷0:2±ÈÌØ */
+typedef enum
+{
+ USB3_HIGHSPEED = 0, /**< 3'b000 USB2.0 PHY clock is 30 MHz or 60 MHz */
+ USB3_FULLSPEED = 1, /**< 3'b001 USB2.0 PHY clock is 30 MHz or 60 MHz */
+ USB3_SUPERSPEED = 4, /**< 3'b100 USB3.0 PHY clock is 30 MHz or 60 MH */
+}E_USB3Slave_SpeedMode;
+/** ָʾÁ¬½ÓµÄÉ豸µÄËÙ¶ÈÀàÐÍ */
+typedef enum
+{
+ USB30_SPEED_UNKNOWN = 0, /**< enumerating */
+ USB30_SPEED_LOW, USB30_SPEED_FULL, /**< usb 1.1 */
+ USB30_SPEED_HIGH, /**< usb 2.0 */
+ USB30_SPEED_WIRELESS, /**< wireless (usb 2.5) */
+ USB30_SPEED_SUPER, /**< usb 3.0 */
+}E_USB3Slave_Speed;
+
+/** T_USB3Slave_HWPARAMS - copy of HWPARAMS registers */
+
+typedef struct
+{
+ u32 udHwparams0; /**< ¶ÔÓ¦ÓÚGHWPARAMS0¼Ä´æÆ÷¶ÁÈ¡µÄÖµ */
+ u32 udHwparams1; /**< ¶ÔÓ¦ÓÚGHWPARAMS1¼Ä´æÆ÷¶ÁÈ¡µÄÖµ */
+ u32 udHwparams2; /**< ¶ÔÓ¦ÓÚGHWPARAMS2¼Ä´æÆ÷¶ÁÈ¡µÄÖµ */
+ u32 udHwparams3; /**< ¶ÔÓ¦ÓÚGHWPARAMS3¼Ä´æÆ÷¶ÁÈ¡µÄÖµ */
+ u32 udHwparams4; /**< ¶ÔÓ¦ÓÚGHWPARAMS4¼Ä´æÆ÷¶ÁÈ¡µÄÖµ */
+ u32 udHwparams5; /**< ¶ÔÓ¦ÓÚGHWPARAMS5¼Ä´æÆ÷¶ÁÈ¡µÄÖµ */
+ u32 udHwparams6; /**< ¶ÔÓ¦ÓÚGHWPARAMS6¼Ä´æÆ÷¶ÁÈ¡µÄÖµ */
+ u32 udHwparams7; /**< ¶ÔÓ¦ÓÚGHWPARAMS7¼Ä´æÆ÷¶ÁÈ¡µÄÖµ */
+ u32 udHwparams8; /**< ¶ÔÓ¦ÓÚGHWPARAMS8¼Ä´æÆ÷¶ÁÈ¡µÄÖµ */
+}T_USB3Slave_HWPARAMS;
+
+
+/** ÓÃÓڶ˵ãÃüÁîµÄÈý¸ö²ÎÊý */
+ typedef struct T_USB3Slave_EpCmdPara
+{
+ u32 Parameter2; /**< ָʾÉ豸ÎïÀí¶ËµãÃüÁî²ÎÊý2 */
+ u32 Parameter1; /**< ָʾÉ豸ÎïÀí¶ËµãÃüÁî²ÎÊý1 */
+ u32 Parameter0; /**< ָʾÉ豸ÎïÀí¶ËµãÃüÁî²ÎÊý0 */
+}__attribute__ ((__packed__)) T_USB3Slave_EpCmdPara;
+
+/** DEPCFG parameter 1 */
+#define DEPCFG_INT_NUM(n) ((n) << 0)
+#define DEPCFG_XFER_COMPLETE_EN (1 << 8)
+#define DEPCFG_XFER_IN_PROGRESS_EN (1 << 9)
+#define DEPCFG_XFER_NOT_READY_EN (1 << 10)
+#define DEPCFG_FIFO_ERROR_EN (1 << 11)
+#define DEPCFG_STREAM_EVENT_EN (1 << 13)
+#define DEPCFG_BINTERVAL_M1(n) ((n) << 16)
+#define DEPCFG_STREAM_CAPABLE (1 << 24)
+#define DEPCFG_EP_NUMBER(n) ((n) << 25)
+#define DEPCFG_BULK_BASED (1 << 30)
+#define DEPCFG_FIFO_BASED (1 << 31)
+
+/** DEPCFG parameter 0 */
+#define DEPCFG_EP_TYPE(n) ((n) << 1)
+#define DEPCFG_MAX_PACKET_SIZE(n) ((n) << 3)
+#define DEPCFG_FIFO_NUMBER(n) ((n) << 17)
+#define DEPCFG_BURST_SIZE(n) ((n) << 22)
+#define DEPCFG_DATA_SEQ_NUM(n) ((n) << 26)
+#define DEPCFG_IGN_SEQ_NUM (1 << 31)
+
+/** DEPXFERCFG parameter 0 */
+#define DEPXFERCFG_NUM_XFER_RES(n) ((n) & 0xffff)
+
+/** ¶ËµãÐÅÏ¢½á¹¹Ìå */
+#pragma pack (4) /*Ö¸¶¨°´4×Ö½Ú¶ÔÆë*/
+typedef struct
+{
+
+ u32 udEpNum; /**< µ±Ç°epºÅ */
+ u8 *pucBuf; /**< »º³åÇøÖ¸Õë */
+ u32 udPos; /**< »º³åÇø¶ÁдָÕë */
+ u32 udLen; /**< »º³åÇø×ܳ¤¶È */
+ u32 udMaxPacket; /**< ×î´ó°üµÄ´óС */
+ u32 udMaxStream; /**< Ö§³ÖµÄ×î´óÁ÷Êý */
+ u32 udMaxBurst; /**< ¸Ã¶ËµãÖ§³ÖµÄ×î´óburstÊý */
+ T_USB3Slave_TRBToHW *ptTRB; /**< ×¼±¸ÓÃÓÚtrbµÄ»º³åÇø */
+ u32 udDMAChannel; /**< ¶ËµãʹÓõÄdmaͨµÀ, ¸ß16Ϊģʽ£¬µÍ16ΪͨµÀºÅ */
+ u8 ucType; /**< Ö§³ÖµÄ´«ÊäÀàÐÍ */
+ void *pPara; /**< »Øµ÷º¯ÊýµÄ²ÎÊý */
+ E_USB3Slave_EpState eEpState; /**< ¶Ëµã״̬ */
+ u32 udDirection; /**< ¶Ëµã´«Êä·½Ïò * @direction: true for TX, false for RX */
+ void *DriverData; /**< Êý¾ÝÓÃÓÚ´«Êä,ºóÐøµ÷ÊÔ¿ÉÄÜ»áÓõ½*/
+ u32 udInterval; /**< ¶ËµãµÄInterval */
+ u32 udBusySlot; /**< ´¦ÓÚæ״̬TRB¸öÊý */
+ u32 udFreeSlot; /**< ´¦ÓÚ¿ÕÏÐ״̬TRB¸öÊý */
+ u32 *pudAddrData; /**< ĿǰÖ÷ÒªÊÇBULK´«ÊäÓÃÓÚ½ÓÊպͷ¢ËÍÊý¾ÝµÄµØÖ· */
+ u8 ucAddress; /**< µØÖ· */
+ u32 udFlags; /**< ¶Ëµã±ê¼Ç */
+ u32 udCurrentTrb; /**< µ±Ç°TRB */
+ u8 ucResTransIdx; /**< ´«Êä×ÊÔ´Ë÷Òý */
+ u32 udStreamCapable; /**< ÊÇ·ñ¾ßÓÐÁ÷ÄÜÁ¦ */
+ F_USB_CB fnUsbCb; //¶Ëµã²Ù×÷Íê³ÉºóµÄ»Øµ÷º¯Êý
+
+}T_USB3Slave_Ep;
+#pragma pack () /*È¡Ïû¶ÔÆë*/
+/** struct dwc3 - representation of our controller */
+/** È«¾ÖdeviceÐÅÏ¢½á¹¹Ì壬ÓÃÓÚÈí¼þ */
+#pragma pack (4) /*Ö¸¶¨°´4×Ö½Ú¶ÔÆë*/
+typedef struct
+{
+
+ u32 udRegs_base; /**< ¼Ç¼¼Ä´æÆ÷»ùÖ· */
+ E_USB3Slave_SpeedMode eSpeedMode; /**< µ±Ç°É豸µÄËÙ¶È */
+ E_USB3Slave_Speed eDeviceSpeedType; /**< ËÙ¶ÈÀàÐÍ£¬¼æÈÝlinuxÇý¶¯Ëù×÷£¬¾ßÌåʹÓôýÒé */
+ T_USB3Slave_HWPARAMS tHwParams; /**< ±£´æËùÓÐÓ²¼þ²ÎÊý */
+ u32 udMode; /**< ±£´æ¿ØÖÆÆ÷µ±Ç°Ëù´¦Ä£Ê½ */
+ T_USB3Slave_EventBuf *ptEvtBuffs; /**< ±£´æevent */
+ u32 udNumEvtBufs; /**< ¼Ç¼evnet¸öÊý£¬´ÓÓ²¼þ²ÎÊýÖлñµÃ*/
+ T_USB3Slave_Ep tEps[ENDPOINTS_NUM]; /**< ±£´æ¶ËµãÐÅÏ¢ */
+ u32 udIsSelfPowered; /**< ×Ô¹©µçture*/
+ u32 udThreeStageSetup; /**< Èý½×¶ÎÉèÖÃ*/
+ u32 udEp0Bounced; /**< bounce buffer for ep0 */
+ u32 udEp0ExpectIn; /**< true when we expect a DATA IN transfer */
+ u32 udSetupPacketPending; /**< true when there's a Setup Packet in FIFO. Workaround */
+ u32 udDelayedStatus; /**< ÑÓ³Ù״̬*/
+ u32 udEventsequence; /**< eventÐòºÅ */
+ E_USB3Slave_Ep0Next eEp0NextEvent; /**< ָʾ¶ËµãµÄÏÂÒ»¸öEVENT */
+ E_USB3Slave_Ep0State eEp0State; /**< ep0״̬*/
+ E_USB3Slave_ReqState eDevState; /**< É豸״̬ */
+ u32 udUSBSate; /**< ö¾Ù״̬ */
+/*ÒÔÏÂÊý¾Ý³ÉÔ±³¤¶ÈÉèÖòÎÕÕlinux 3.3.6ÖжÔusb3¿ØÖÆÆ÷µÄ³õʼº¯Êý*/
+ T_USB3Slave_CtrlReq *tCtrlReq; /**< ¿ØÖÆÇëÇó */
+ T_USB3Slave_TRBToHW *ptEp0TRB; /**< ep0 TRBÉèÖÃ*/
+ u8 aucSetupBuf[2]; /**< ½¨Á¢buffer δÓÃĿǰ */
+ u8 ucSpeed; /**< ËÙ¶È */
+ u32 *pudTxData; /**< Ö¸Ïò·¢Ë͵ÄÊý¾Ý´óС */
+}T_USB3Slave_SlaveObj;
+#pragma pack () /*È¡Ïû¶ÔÆë*/
+
+/** ¶¨ÒåSlaveObj ¶ÔÏóµÄÈ«¾Ö±äÁ¿*/
+
+/** DWC3 Features to be used as Driver Data ĿǰûÓÐÓõ½ÔÝʱ·ÅÔÚÕâÀï*/
+/*#define HAS_PERIPHERAL BIT(0)
+#define HAS_XHCI BIT(1)
+#define HAS_OTG BIT(3)*/
+#define DATA_32BIT_MASK 0xFFFFFFFF
+#define ADDRESS_MAX 127
+
+/* *INDENT-OFF* */
+#ifdef __cplusplus
+}
+#endif
+/* *INDENT-ON* */
+
+#endif /* __USB3_SLAVE_DRV_H */
+
+
+/** @} */
diff --git a/boot/common/src/loader/drivers/drv_usb3slave_reg.h b/boot/common/src/loader/drivers/drv_usb3slave_reg.h
new file mode 100644
index 0000000..3ec2de5
--- /dev/null
+++ b/boot/common/src/loader/drivers/drv_usb3slave_reg.h
@@ -0,0 +1,95 @@
+/*******************************************************************************
+* °æÈ¨ËùÓÐ (C)2010, ÉîÛÚÊÐÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
+*
+* ÎļþÃû³Æ£º drv_usb3slave_reg.h
+* Îļþ±êʶ£º
+* ÄÚÈÝÕªÒª£º
+* ÆäËü˵Ã÷£º zx297520 project
+* µ±Ç°°æ±¾£º 1.0
+* ×÷¡¡¡¡Õߣº tangjian
+* Íê³ÉÈÕÆÚ£º
+*
+*
+*******************************************************************************/
+
+
+#ifndef __DRV_USB3SLAVE_REG_H
+#define __DRV_USB3SLAVE_REG_H
+
+/* *INDENT-OFF* */
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* *INDENT-ON* */
+
+#include "common.h"
+
+
+/** ÏÂÃæµÄ¼¸¸ö¼Ä´æÆ÷µÄ¸ñʽÓÐÐ©ÌØ±ð£¬¼Ä´æÆ÷ÊDz»Á¬ÐøµÄ£¬¹Ê±£ÁôÁËlinuxÖмĴæÆ÷µÄ¸ñʽ*/
+
+ /*0x200-0x23c*/
+#define GUSB2PHYCFG(n) (0xc200 + (n * 0x04))
+
+ /*0x240-0x27c*/
+#define GUSB2I2CCTL(n) (0xc240 + (n * 0x04))
+
+ /*0x280-0x2bc*/
+#define GUSB2PHYACC(n) (0xc280 + (n * 0x04))
+
+ /*0x2C0-0x2fc*/
+#define GUSB3PIPECTL(n) (0xc2c0 + (n * 0x04))
+
+ /*0x300-0x37C*/
+#define GTXFIFOSIZ(n) (0xc300 + (n * 0x04))
+
+ /*0x380-0x3fc*/
+#define GRXFIFOSIZ(n) (0xc380 + (n * 0x04))
+
+#define GHWPARAMS0 0xc140
+#define GHWPARAMS1 0xc144
+#define GHWPARAMS2 0xc148
+#define GHWPARAMS3 0xc14c
+#define GHWPARAMS4 0xc150
+#define GHWPARAMS5 0xc154
+#define GHWPARAMS6 0xc158
+#define GHWPARAMS7 0xc15c
+#define GHWPARAMS8 0xc600
+
+#define GEVNTADRLO(n) (0xc400 + (n * 0x10))
+#define GEVNTADRHI(n) (0xc404 + (n * 0x10))
+#define GEVNTSIZ(n) (0xc408 + (n * 0x10))
+#define GEVNTCOUNT(n) (0xc40c + (n * 0x10))
+
+#define DEPCMDPAR2(n) (0xc800 + (n * 0x10))
+#define DEPCMDPAR1(n) (0xc804 + (n * 0x10))
+#define DEPCMDPAR0(n) (0xc808 + (n * 0x10))
+#define DEPCMD(n) (0xc80c + (n * 0x10))
+
+/** @} */
+/* RAMʱÖÓÑ¡Ôñλ */
+#define USB3Slave_GCTL_RAMCLKSEL_POS (6)
+#define USB3Slave_GCTL_CLK_BUS (0 << USB3Slave_GCTL_RAMCLKSEL_POS)
+
+#define USB3Slave_DEPCMD_COMMANDPARAM_POS (16)
+#define USB2Slave_DEPCMD_PARAM(x) (x << USB3Slave_DEPCMD_COMMANDPARAM_POS)
+/* ÃüÁ»îÉèÖÃλ */
+//#define USB3Slave_DEPCMD_CMDACT USB3Slave_DEPCMD_CMDACT
+#define USB3Slave_DEPCMD_CMDACT_POS (10)
+#define USB3Slave_DEPCMD_CMDACT_1 (1 << USB3Slave_DEPCMD_CMDACT_POS)
+/* ÃüÁîÀàÐÍ */
+//#define USB3Slave_DEPCMD_CMDTYP USB3Slave_DEPCMD_CMDTYP
+#define USB3Slave_DEPCMD_CMDTYP_POS (0)
+#define USB3Slave_DEPCMD_DEPSTARTCFG (0x09 << USB3Slave_DEPCMD_CMDTYP_POS)
+#define USB3Slave_DEPCMD_ENDTRANSFER (0x08 << USB3Slave_DEPCMD_CMDTYP_POS)
+#define USB3Slave_DEPCMD_UPDATETRANSFER (0x07 << USB3Slave_DEPCMD_CMDTYP_POS)
+#define USB3Slave_DEPCMD_STARTTRANSFER (0x06 << USB3Slave_DEPCMD_CMDTYP_POS)
+#define USB3Slave_DEPCMD_CLEARSTALL (0x05 << USB3Slave_DEPCMD_CMDTYP_POS)
+#define USB3Slave_DEPCMD_SETSTALL (0x04 << USB3Slave_DEPCMD_CMDTYP_POS)
+#define USB3Slave_DEPCMD_GETSEQNUMBER (0x03 << USB3Slave_DEPCMD_CMDTYP_POS)
+#define USB3Slave_DEPCMD_SETTRANSFRESOURCE (0x02 << USB3Slave_DEPCMD_CMDTYP_POS)
+#define USB3Slave_DEPCMD_SETEPCONFIG (0x01 << USB3Slave_DEPCMD_CMDTYP_POS)
+
+#endif /* __DRV_USB3SLAVE_REG_H */
+
+
+
diff --git a/boot/common/src/loader/drivers/dwc_otg_cil.c b/boot/common/src/loader/drivers/dwc_otg_cil.c
new file mode 100644
index 0000000..22fd410
--- /dev/null
+++ b/boot/common/src/loader/drivers/dwc_otg_cil.c
@@ -0,0 +1,1174 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.c $
+ * $Revision: #191 $
+ * $Date: 2012/08/10 $
+ * $Change: 2047372 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/** @file
+ *
+ * The Core Interface Layer provides basic services for accessing and
+ * managing the DWC_otg hardware. These services are used by both the
+ * Host Controller Driver and the Peripheral Controller Driver.
+ *
+ * The CIL manages the memory map for the core so that the HCD and PCD
+ * don't have to do this separately. It also handles basic tasks like
+ * reading/writing the registers and data FIFOs in the controller.
+ * Some of the data access functions provide encapsulation of several
+ * operations required to perform a task, such as writing multiple
+ * registers to start a transfer. Finally, the CIL performs basic
+ * services that are not specific to either the host or device modes
+ * of operation. These services include management of the OTG Host
+ * Negotiation Protocol (HNP) and Session Request Protocol (SRP). A
+ * Diagnostic API is also provided to allow testing of the controller
+ * hardware.
+ *
+ * The Core Interface Layer has the following requirements:
+ * - Provides basic controller operations.
+ * - Minimal use of OS services.
+ * - The OS services used will be abstracted by using inline functions
+ * or macros.
+ *
+ */
+
+#include <common.h>
+
+#include "global.h"
+#include "dwc_otg_regs.h"
+#include "dwc_otg_cil.h"
+#include "dwc_otg_driver.h"
+
+
+
+static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if);
+
+void DWC_MODIFY_REG32(uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask)
+{
+ DWC_WRITE_REG32(reg,(DWC_READ_REG32(reg) & ~clear_mask) | set_mask);
+}
+
+dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr)
+{
+ dwc_otg_core_if_t *core_if = (&global.core_if_t);
+ dwc_otg_dev_if_t *dev_if = (&global.dev_if_t);
+ uint8_t *pt_core_if = ( uint8_t *)(&global.core_if_t);
+ uint8_t *pt_dev_if = ( uint8_t *)(&global.dev_if_t);
+ uint8_t *reg_base = (uint8_t *) reg_base_addr;
+ int i = 0;
+ for(i= 0;i<sizeof(global.core_if_t);i++)
+ {
+ pt_core_if[i] = 0;
+ }
+ core_if->core_global_regs = (dwc_otg_core_global_regs_t *) reg_base;
+
+ for(i= 0;i<sizeof(global.dev_if_t);i++)
+ {
+ pt_dev_if[i] = 0;
+ }
+
+ dev_if->dev_global_regs = (dwc_otg_device_global_regs_t *) (reg_base +DWC_DEV_GLOBAL_REG_OFFSET);
+
+ for (i = 0; i < MAX_EPS_CHANNELS; i++)
+ {
+ dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
+ (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
+ (i * DWC_EP_REG_OFFSET));
+
+ dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
+ (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
+ (i * DWC_EP_REG_OFFSET));
+
+ core_if->data_fifo[i] =(uint32_t *) (reg_base + DWC_OTG_DATA_FIFO_OFFSET +(i * DWC_OTG_DATA_FIFO_SIZE));
+ }
+
+ dev_if->speed = 0;
+
+ core_if->dev_if = dev_if;
+
+ core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET);
+
+ core_if->hwcfg1.d32 =DWC_READ_REG32(&core_if->core_global_regs->ghwcfg1);
+ core_if->hwcfg2.d32 =DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
+ core_if->hwcfg3.d32 =DWC_READ_REG32(&core_if->core_global_regs->ghwcfg3);
+ core_if->hwcfg4.d32 =DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4);
+
+ core_if->dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
+
+ dwc_otg_setup_params(core_if);
+
+
+ return core_if;
+}
+
+/**
+ * Initializes the DevSpd field of the DCFG register depending on the PHY type
+ * and the enumeration speed of the device.
+ */
+void init_devspd(dwc_otg_core_if_t * core_if,uint8_t speed)
+{
+ uint32_t val;
+ dcfg_data_t dcfg;
+
+ val = speed;
+ dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
+ dcfg.b.devspd = val;
+ if(global.g_enum == NEED_ENUM)
+ {
+ DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
+ }
+}
+
+/**
+ * This function initializes the DWC_otg controller registers and
+ * prepares the core for device mode or host mode operation.
+ *
+ * @param core_if Programming view of the DWC_otg controller
+ *
+ */
+void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
+{
+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ gahbcfg_data_t ahbcfg;
+ gotgctl_data_t gotgctl;
+
+ gusbcfg_data_t usbcfg;
+ ahbcfg.d32 = 0;
+ usbcfg.d32 = 0;
+ gotgctl.d32 = 0;
+
+
+ usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+if(global.g_enum == NEED_ENUM)
+{
+
+#if !USE_ASIC
+ usbcfg.b.ulpi_ext_vbus_drv =(core_if->core_params->phy_ulpi_ext_vbus == DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
+
+ usbcfg.b.term_sel_dl_pulse = (core_if->core_params->ts_dline == 1) ? 1 : 0;
+
+
+ DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+#endif
+ dwc_otg_core_reset(core_if);
+ }
+
+
+ dev_if->num_in_eps = 2;//calc_num_in_eps(core_if);
+ dev_if->num_out_eps = 2;//calc_num_out_eps(core_if);
+
+ core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
+ core_if->rx_fifo_size = DWC_READ_REG32(&global_regs->grxfsiz);
+ core_if->nperio_tx_fifo_size = DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16;
+ {
+ /* High speed PHY. */
+ if (!core_if->phy_init_done)
+ {
+ core_if->phy_init_done = 1;
+ /* HS PHY parameters. These parameters are preserved
+ * during soft reset so only program the first time. Do
+ * a soft reset immediately after setting phyif. */
+ #if !USE_ASIC
+ if (core_if->core_params->phy_type == 2)
+ {
+ /* ULPI interface */
+ usbcfg.b.ulpi_utmi_sel = 1;
+ usbcfg.b.phyif = 0;
+ usbcfg.b.ddrsel = core_if->core_params->phy_ulpi_ddr;
+ }
+ #else
+ if (core_if->core_params->phy_type == 1)
+ {
+ /* UTMI+ interface */
+ usbcfg.b.ulpi_utmi_sel = 0;
+ if (core_if->core_params->phy_utmi_width == 16)
+ {
+ usbcfg.b.phyif = 1;
+
+ }
+ else
+ {
+ usbcfg.b.phyif = 0;
+ }
+ }
+ #endif
+ if(global.g_enum == NEED_ENUM)
+ {
+ DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+ /* Reset after setting the PHY parameters */
+ dwc_otg_core_reset(core_if);
+ }
+ }
+ }
+ if(global.g_enum == NEED_ENUM)
+ {
+#if !USE_ASIC
+ if ((core_if->hwcfg2.b.hs_phy_type == 2) &&(core_if->hwcfg2.b.fs_phy_type == 1) &&(core_if->core_params->ulpi_fs_ls))
+ {
+ usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+ usbcfg.b.ulpi_fsls = 1;
+ usbcfg.b.ulpi_clk_sus_m = 1;
+ DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+ }
+ else
+ {
+ usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+ usbcfg.b.ulpi_fsls = 0;
+ usbcfg.b.ulpi_clk_sus_m = 0;
+ DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+ }
+#endif
+ }
+
+
+ ahbcfg.b.nptxfemplvl_txfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
+ ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
+
+
+ ahbcfg.b.dmaenable = 0;
+// ÅäÖÃÈ«¿ÕFIFO²úÉúÖжÏ
+ ahbcfg.b.nptxfemplvl_txfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_EMPTY ;
+ if(global.g_enum == NEED_ENUM)
+ {
+
+ DWC_WRITE_REG32(&global_regs->gahbcfg, ahbcfg.d32);
+ }
+
+
+ core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
+
+ core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
+ core_if->multiproc_int_enable = dwc_param_mpi_enable_default;//core_if->core_params->mpi_enable;
+ /*
+ * Program the GUSBCFG register.
+ */
+ usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+ usbcfg.b.hnpcap = 0;
+ usbcfg.b.srpcap = 0;
+
+ if(global.g_enum == NEED_ENUM)
+ {
+ DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+ }
+ {
+ gotgctl.b.otgver = core_if->core_params->otg_ver;
+ if(global.g_enum == NEED_ENUM)
+ {
+ DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, 0, gotgctl.d32);
+ }
+ /* Set OTG version supported */
+ core_if->otg_ver = core_if->core_params->otg_ver;
+ }
+ if(global.g_enum == NEED_ENUM)
+ {
+ dwc_otg_core_dev_init(core_if);
+ }
+
+}
+
+/**
+ * This function enables the Device mode interrupts.
+ *
+ * @param core_if Programming view of DWC_otg controller
+ */
+void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * core_if)
+{
+ gintmsk_data_t intr_mask ;
+
+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+ intr_mask.d32 = 0;
+ /* Disable all interrupts. */
+ DWC_WRITE_REG32(&global_regs->gintmsk, 0);
+
+ /* Clear any pending interrupts */
+ DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
+
+ /* Enable the common interrupts */
+ intr_mask.b.rxstsqlvl = 1;
+ intr_mask.b.usbsuspend = 1;
+ DWC_WRITE_REG32(&global_regs->gintmsk, intr_mask.d32);
+
+ intr_mask.d32 = 0x1e3400;
+ DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
+
+}
+
+/**
+ * This function initializes the DWC_otg controller registers for
+ * device mode.
+ *
+ * @param core_if Programming view of DWC_otg controller
+ *
+ */
+void dwc_otg_core_dev_init(dwc_otg_core_if_t * core_if)
+{
+ int i;
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ dcfg_data_t dcfg;
+ grstctl_t resetctl;
+ dctl_data_t dctl;
+ diepmsk_data_t msk;
+ dcfg.d32 = 0;
+ resetctl.d32 = 0;
+ dctl.d32 = 0;
+ msk.d32 = 0;
+ /* Restart the Phy Clock */
+
+ DWC_WRITE_REG32(core_if->pcgcctl, 0);
+
+
+ /* Device configuration register */
+ init_devspd(core_if,0);//ĬÈÏÅäÖóɸßËÙ
+ dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
+ dcfg.b.descdma = 0;
+ dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
+
+ DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
+
+
+ /* Flush the FIFOs */
+ dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */
+ dwc_otg_flush_rx_fifo(core_if);
+
+ /* Flush the Learning Queue. */
+ resetctl.b.intknqflsh = 1;
+ DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
+
+ /* Clear all pending Device Interrupts */
+ /** @todo - if the condition needed to be checked
+ * or in any case all pending interrutps should be cleared?
+ */
+ DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, 0);
+ DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, 0);
+ DWC_WRITE_REG32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
+ DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk, 0);
+
+ for (i = 0; i <= dev_if->num_in_eps; i++)
+ {
+ DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl,0);
+
+ DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
+ DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, 0);
+ DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
+
+ DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl,0);
+
+ DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
+ DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepdma, 0);
+ DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
+ }
+
+ //ÓÃÓÚhsic
+ if(1==global.g_USB_MODE)
+ {
+ DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, 0x40000000);
+ }
+ dwc_otg_enable_device_interrupts(core_if);
+ msk.b.txfifoundrn = 1;
+ DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk,msk.d32, msk.d32);
+ dctl.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dctl);
+ dctl.b.sftdiscon = 0;
+ DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl, dctl.d32);
+
+}
+
+void dwc_otg_core_dev_disconnet(dwc_otg_core_if_t * core_if)
+{
+ dctl_data_t dctl;
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ dctl.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dctl);
+ dctl.b.sftdiscon = 1;
+ DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl, dctl.d32);
+}
+/**
+ * This function reads a setup packet from the Rx FIFO into the destination
+ * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl)
+ * Interrupt routine when a SETUP packet has been received in Slave mode.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param dest Destination buffer for packet data.
+ */
+void dwc_otg_read_setup_packet(dwc_otg_core_if_t * core_if, uint32_t * dest)
+{
+ dest[0] = DWC_READ_REG32(core_if->data_fifo[0]);
+ dest[1] = DWC_READ_REG32(core_if->data_fifo[0]);
+
+}
+
+/**
+ * This function enables EP0 OUT to receive SETUP packets and configures EP0
+ * IN for transmitting packets. It is normally called when the
+ * "Enumeration Done" interrupt occurs.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP0 data.
+ */
+void dwc_otg_ep0_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ dsts_data_t dsts;
+ depctl_data_t diepctl;
+ dctl_data_t dctl;
+ ep->stp_rollover = 0;
+ dctl.d32 = 0;
+
+ /* Read the Device Status and Endpoint 0 Control registers */
+ dsts.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dsts);
+ diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
+
+ /* Set the MPS of the IN EP based on the enumeration speed */
+ switch (dsts.b.enumspd)
+ {
+ case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
+ case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
+ case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
+ diepctl.b.mps = DWC_DEP0CTL_MPS_64;
+ break;
+ }
+
+ DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
+ dctl.b.cgnpinnak = 1;
+
+ DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
+
+}
+
+/**
+ * This function activates an EP. The Device EP control register for
+ * the EP is configured as defined in the ep structure. Note: This
+ * function is not used for EP0.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP to activate.
+ */
+void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ depctl_data_t depctl;
+ volatile uint32_t *addr;
+ daint_data_t daintmsk;
+
+ daintmsk.d32 = 0;
+ /* Read DEPCTLn register */
+ if (ep->is_in == 1)
+ {
+ addr = &dev_if->in_ep_regs[ep->num]->diepctl;
+ daintmsk.ep.in = 1 << ep->num;
+ }
+ else
+ {
+ addr = &dev_if->out_ep_regs[ep->num]->doepctl;
+ daintmsk.ep.out = 1 << ep->num;
+ }
+
+ /* If the EP is already active don't change the EP Control
+ * register. */
+ depctl.d32 = DWC_READ_REG32(addr);
+ if (!depctl.b.usbactep)
+ {
+ depctl.b.mps = ep->maxpacket;
+ depctl.b.eptype = ep->type;
+ depctl.b.txfnum = ep->tx_fifo_num;
+
+
+ depctl.b.setd0pid = 1;
+
+ depctl.b.usbactep = 1;
+
+ DWC_WRITE_REG32(addr, depctl.d32);
+ }
+ {
+
+ DWC_MODIFY_REG32(&dev_if->dev_global_regs->daintmsk,0, daintmsk.d32);
+ }
+
+ ep->stall_clear_flag = 0;
+
+ return;
+}
+/**
+ * This function does the setup for a data transfer for an EP and
+ * starts the transfer. For an IN transfer, the packets will be
+ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
+ * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP to start the transfer on.
+ */
+
+void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+ depctl_data_t depctl;
+ deptsiz_data_t deptsiz;
+
+ if (ep->is_in == 1)
+ {
+ dwc_otg_dev_in_ep_regs_t *in_regs = core_if->dev_if->in_ep_regs[ep->num];
+
+ depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
+ deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
+
+ if (ep->maxpacket > (ep->maxxfer / MAX_PKT_CNT))
+ ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?\
+ ep->maxxfer : (ep->total_len - ep->xfer_len);
+ else
+ ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len - ep->xfer_len)) ?\
+ MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
+
+
+ /* Zero Length Packet? */
+ if ((ep->xfer_len - ep->xfer_count) == 0)
+ {
+ deptsiz.b.xfersize = 0;
+ deptsiz.b.pktcnt = 1;
+ }
+ else
+ {
+ deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
+ deptsiz.b.pktcnt = (ep->xfer_len - ep->xfer_count - 1 + ep->maxpacket) / ep->maxpacket;
+ #if 0/*unsigned the max value is 1023*/
+ if (deptsiz.b.pktcnt > MAX_PKT_CNT)
+ {
+ deptsiz.b.pktcnt = MAX_PKT_CNT;
+ deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
+ }
+ #endif
+ }
+
+ if((ep->xfer_len - ep->xfer_count)% ep->maxpacket== 0)
+ {
+ printf("sent_zlp = 1\n");
+ ep->sent_zlp = 1;
+ }
+
+ DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
+
+ if (ep->xfer_len > 0)
+ {
+ uint32_t fifoemptymsk = 0;
+ fifoemptymsk = 1 << ep->num;
+ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,0, fifoemptymsk);
+
+ }
+
+ /* EP enable, IN data in FIFO */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
+#if SYNC_USB_CTRL
+ REG32(ARM_PORTA)=0x87;
+#endif
+
+ }
+ else
+ {
+ /* OUT endpoint */
+ dwc_otg_dev_out_ep_regs_t *out_regs = core_if->dev_if->out_ep_regs[ep->num];
+
+ depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
+ deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
+
+
+ if (ep->maxpacket > (ep->maxxfer / MAX_PKT_CNT))
+ ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ? ep->maxxfer : (ep->total_len - ep->xfer_len);
+ else
+ ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len - ep->xfer_len)) ? MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
+
+
+ if ((ep->xfer_len - ep->xfer_count) == 0)
+ {
+ deptsiz.b.xfersize = ep->maxpacket;
+ deptsiz.b.pktcnt = 1;
+ }
+ else
+ {
+ deptsiz.b.pktcnt = (ep->xfer_len - ep->xfer_count + (ep->maxpacket - 1)) / ep->maxpacket;
+ #if 0/*unsigned the max value is 1023*/
+ if (deptsiz.b.pktcnt > MAX_PKT_CNT)
+ {
+ deptsiz.b.pktcnt = MAX_PKT_CNT;
+ }
+ #endif
+ ep->xfer_len = deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
+ deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
+ }
+
+ {
+
+ DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
+ }
+ /* EP enable */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+
+ DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
+#if SYNC_USB_CTRL
+ REG32(ARM_PORTA)=0x76;
+#endif
+
+ }
+}
+
+/**
+ * This function setup a zero length transfer in Buffer DMA and
+ * Slave modes for usb requests with zero field set
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP to start the transfer on.
+ *
+ */
+void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+
+ depctl_data_t depctl;
+ deptsiz_data_t deptsiz;
+
+ /* IN endpoint */
+ if (ep->is_in == 1)
+ {
+ dwc_otg_dev_in_ep_regs_t *in_regs = core_if->dev_if->in_ep_regs[ep->num];
+
+ depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
+ deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
+
+ deptsiz.b.xfersize = 0;
+ deptsiz.b.pktcnt = 1;
+ {
+ DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
+ {
+ /* Enable the Tx FIFO Empty Interrupt for this EP */
+ if (ep->xfer_len > 0)
+ {
+ uint32_t fifoemptymsk = 0;
+ fifoemptymsk = 1 << ep->num;
+ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,0, fifoemptymsk);
+ }
+ }
+ }
+
+ /* EP enable, IN data in FIFO */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
+
+ }
+ else
+ {
+ /* OUT endpoint */
+ dwc_otg_dev_out_ep_regs_t *out_regs = core_if->dev_if->out_ep_regs[ep->num];
+
+ depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
+ deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
+
+ /* Zero Length Packet */
+ deptsiz.b.xfersize = ep->maxpacket;
+ deptsiz.b.pktcnt = 1;
+ {
+ DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
+ }
+
+ /* EP enable */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+
+ DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
+
+ }
+}
+
+/**
+ * This function does the setup for a data transfer for EP0 and starts
+ * the transfer. For an IN transfer, the packets will be loaded into
+ * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
+ * unloaded from the Rx FIFO in the ISR.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP0 data.
+ */
+void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+ depctl_data_t depctl;
+ deptsiz0_data_t deptsiz;
+ uint32_t fifoemptymsk;
+
+ ep->total_len = ep->xfer_len;
+
+ /* IN endpoint */
+ if (ep->is_in == 1)
+ {
+ printf("ep0 tx data\n");
+ dwc_otg_dev_in_ep_regs_t *in_regs = core_if->dev_if->in_ep_regs[0];
+ depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
+ if (depctl.b.epena)
+ return;
+
+
+ /* If dedicated FIFO every time flush fifo before enable ep*/
+ dwc_otg_flush_tx_fifo(core_if, ep->tx_fifo_num);
+
+ depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
+ deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
+
+ /* Zero Length Packet? */
+ if (ep->xfer_len == 0)
+ {
+ deptsiz.b.xfersize = 0;
+ deptsiz.b.pktcnt = 1;
+ }
+ else
+ {
+ /* Program the transfer size and packet count
+ * as follows: xfersize = N * maxpacket +
+ * short_packet pktcnt = N + (short_packet
+ * exist ? 1 : 0)
+ */
+ if (ep->xfer_len > ep->maxpacket)
+ {
+ ep->xfer_len = ep->maxpacket;
+ deptsiz.b.xfersize = ep->maxpacket;
+ }
+ else
+ {
+ deptsiz.b.xfersize = ep->xfer_len;
+ }
+ deptsiz.b.pktcnt = 1;
+
+ }
+
+
+ {
+ DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
+ }
+
+ /* EP enable, IN data in FIFO */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
+
+ /**
+ * Enable the Non-Periodic Tx FIFO empty interrupt, the
+ * data will be written into the fifo by the ISR.
+ */
+
+ /* Enable the Tx FIFO Empty Interrupt for this EP */
+ if (ep->xfer_len > 0)
+ {
+ fifoemptymsk = 0;
+ fifoemptymsk |= 1 << ep->num;
+ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,0, fifoemptymsk);
+ }
+
+ }
+ else
+ {
+
+ /* OUT endpoint */
+ dwc_otg_dev_out_ep_regs_t *out_regs = core_if->dev_if->out_ep_regs[0];
+
+ depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
+ deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
+
+ /* Program the transfer size and packet count as follows:
+ * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
+ * pktcnt = N */
+ /* Zero Length Packet */
+ deptsiz.b.xfersize = ep->maxpacket;
+ deptsiz.b.pktcnt = 1;
+ deptsiz.b.supcnt = 3;
+ DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
+
+ /* EP enable */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ DWC_WRITE_REG32(&(out_regs->doepctl), depctl.d32);
+
+ }
+}
+
+/**
+ * This function continues control IN transfers started by
+ * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
+ * single packet. NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
+ * bit for the packet count.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP0 data.
+ */
+void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+ depctl_data_t depctl;
+ deptsiz0_data_t deptsiz;
+
+ if (ep->is_in == 1)
+ {
+ dwc_otg_dev_in_ep_regs_t *in_regs = core_if->dev_if->in_ep_regs[0];
+
+ depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
+ deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
+
+ deptsiz.b.xfersize = (ep->total_len - ep->xfer_count) > ep->maxpacket ? ep->maxpacket : (ep->total_len - ep->xfer_count);
+ deptsiz.b.pktcnt = 1;
+
+ ep->xfer_len += deptsiz.b.xfersize;
+
+ DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
+
+
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
+
+ /**
+ * Enable the Non-Periodic Tx FIFO empty interrupt, the
+ * data will be written into the fifo by the ISR.
+ */
+
+ /* Enable the Tx FIFO Empty Interrupt for this EP */
+ if (ep->xfer_len > 0)
+ {
+ uint32_t fifoemptymsk = 0;
+ fifoemptymsk |= 1 << ep->num;
+ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,0, fifoemptymsk);
+ }
+
+ }
+ else
+ {
+ dwc_otg_dev_out_ep_regs_t *out_regs = core_if->dev_if->out_ep_regs[0];
+
+ depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
+ deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
+
+ deptsiz.b.xfersize = ep->maxpacket;
+ deptsiz.b.pktcnt = 1;
+ DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
+
+ }
+}
+
+
+/**
+ * This function writes a packet into the Tx FIFO associated with the
+ * EP. For non-periodic EPs the non-periodic Tx FIFO is written. For
+ * periodic EPs the periodic Tx FIFO associated with the EP is written
+ * with all packets for the next micro-frame.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP to write packet for.
+ * @param dma Indicates if DMA is being used.
+ */
+void dwc_otg_ep_write_packet(dwc_otg_core_if_t * core_if, dwc_ep_t * ep,
+ int dma)
+{
+ uint32_t i;
+ uint32_t byte_count;
+ uint32_t dword_count;
+ uint32_t *fifo;
+ uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
+
+ if (ep->xfer_count >= ep->xfer_len)
+ {
+ return;
+ }
+
+ /* Find the byte length of the packet either short packet or MPS */
+ if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket)
+ {
+ byte_count = ep->xfer_len - ep->xfer_count;
+ }
+ else
+ {
+ byte_count = ep->maxpacket;
+ }
+
+ /* Find the DWORD length, padded by extra bytes as neccessary if MPS
+ * is not a multiple of DWORD */
+ dword_count = (byte_count + 3) / 4;
+
+ /**@todo NGS Where are the Periodic Tx FIFO addresses
+ * intialized? What should this be? */
+
+ fifo = core_if->data_fifo[ep->num];
+ for (i = 0; i < dword_count; i++, data_buff++)
+ {
+ DWC_WRITE_REG32(fifo, *data_buff);
+
+ }
+
+
+ ep->xfer_count += byte_count;
+ ep->xfer_buff += byte_count;
+}
+
+/**
+ * Set the EP STALL.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP to set the stall on.
+ */
+void dwc_otg_ep_set_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+ depctl_data_t depctl;
+ volatile uint32_t *depctl_addr;
+ if (ep->is_in == 1)
+ {
+ depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
+ depctl.d32 = DWC_READ_REG32(depctl_addr);
+
+ /* set the disable and stall bits */
+ if (depctl.b.epena)
+ {
+ depctl.b.epdis = 1;
+ }
+ depctl.b.stall = 1;
+ DWC_WRITE_REG32(depctl_addr, depctl.d32);
+ }
+ else
+ {
+ depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
+ depctl.d32 = DWC_READ_REG32(depctl_addr);
+
+ depctl.b.stall = 1;
+ DWC_WRITE_REG32(depctl_addr, depctl.d32);
+ }
+
+ return;
+}
+
+/**
+ * Clear the EP STALL.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param ep The EP to clear stall from.
+ */
+void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
+{
+ depctl_data_t depctl;
+ volatile uint32_t *depctl_addr;
+
+ if (ep->is_in == 1)
+ {
+ depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
+ }
+ else
+ {
+ depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
+ }
+
+ depctl.d32 = DWC_READ_REG32(depctl_addr);
+
+ /* clear the stall bits */
+ depctl.b.stall = 0;
+
+ /*
+ * USB Spec 9.4.5: For endpoints using data toggle, regardless
+ * of whether an endpoint has the Halt feature set, a
+ * ClearFeature(ENDPOINT_HALT) request always results in the
+ * data toggle being reinitialized to DATA0.
+ */
+ if (ep->type == DWC_OTG_EP_TYPE_INTR ||
+ ep->type == DWC_OTG_EP_TYPE_BULK)
+ {
+ depctl.b.setd0pid = 1; /* DATA0 */
+ }
+
+ DWC_WRITE_REG32(depctl_addr, depctl.d32);
+ return;
+}
+
+/**
+ * This function reads a packet from the Rx FIFO into the destination
+ * buffer. To read SETUP data use dwc_otg_read_setup_packet.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param dest Destination buffer for the packet.
+ * @param bytes Number of bytes to copy to the destination.
+ */
+void dwc_otg_read_packet(dwc_otg_core_if_t * core_if,
+ uint8_t * dest, uint16_t bytes)
+{
+ int i;
+ int word_count = (bytes + 3) / 4;
+
+ volatile uint32_t *fifo = core_if->data_fifo[0];
+ uint32_t *data_buff = (uint32_t *) dest;
+
+
+ for (i = 0; i < word_count; i++, data_buff++)
+ {
+ *data_buff = DWC_READ_REG32(fifo);
+ }
+
+ return;
+}
+
+/**
+ * Flush a Tx FIFO.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param num Tx FIFO to flush.
+ */
+void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num)
+{
+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+ volatile grstctl_t greset;
+ int count = 0;
+ greset.d32 = 0;
+
+ greset.b.txfflsh = 1;
+ greset.b.txfnum = num;
+if(global.g_enum == NEED_ENUM)
+{
+ DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
+
+
+ do
+ {
+ greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
+ if (++count > 10000)
+ {
+ break;
+ }
+ usdelay(10);
+ }
+ while (greset.b.txfflsh == 1);
+
+ /* Wait for 3 PHY Clocks */
+ usdelay(10);
+}
+
+}
+
+/**
+ * Flush Rx FIFO.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ */
+void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * core_if)
+{
+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+ volatile grstctl_t greset;
+ int count = 0;
+ greset.d32 = 0;
+ greset.b.rxfflsh = 1;
+if(global.g_enum == NEED_ENUM)
+{
+ DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
+
+ do
+ {
+ greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
+ if (++count > 10000)
+ {
+ break;
+ }
+ usdelay(10);
+ }
+ while (greset.b.rxfflsh == 1);
+
+ /* Wait for 3 PHY Clocks */
+
+ usdelay(10);
+}
+}
+
+/**
+ * Do core a soft reset of the core. Be careful with this because it
+ * resets all the internal state machines of the core.
+ */
+void dwc_otg_core_reset(dwc_otg_core_if_t * core_if)
+{
+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+ volatile grstctl_t greset;
+ int count = 0;
+ greset.d32 =0;
+ /* Wait for AHB master IDLE state. */
+ do
+ {
+ usdelay(10);
+ greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
+ if (++count > 100000)
+ {
+ return;
+ }
+ }
+ while (greset.b.ahbidle == 0);
+
+ /* Core Soft Reset */
+ count = 0;
+ greset.b.csftrst = 1;
+ DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
+ do
+ {
+ greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
+ if (++count > 10000)
+ {
+ break;
+ }
+ usdelay(10);
+ }
+ while (greset.b.csftrst == 1);
+/* Wait for 3 PHY Clocks */
+ usdelay(10);
+}
+
+static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if)
+{
+ int i;
+ core_if->core_params = &global.g_core_params;
+ core_if->core_params->otg_cap = DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE;
+ #if !USE_ASIC
+ core_if->core_params->phy_type = DWC_PHY_TYPE_PARAM_ULPI;
+ #else
+ core_if->core_params->phy_type = DWC_PHY_TYPE_PARAM_UTMI;
+ #endif
+ core_if->core_params->speed = DWC_SPEED_PARAM_HIGH;//DWC_SPEED_PARAM_FULL
+ core_if->core_params->phy_ulpi_ddr = dwc_param_phy_ulpi_ddr_default;
+ core_if->core_params->phy_ulpi_ext_vbus = dwc_param_phy_ulpi_ext_vbus_default;
+ core_if->core_params->phy_utmi_width = 8;
+ core_if->core_params->ts_dline = dwc_param_ts_dline_default;
+ core_if->core_params->ulpi_fs_ls = dwc_param_ulpi_fs_ls_default;
+ core_if->core_params->en_multiple_tx_fifo = dwc_param_en_multiple_tx_fifo_default;
+ for (i = 0; i < 15; i++)
+ {
+ core_if->core_params->dev_tx_fifo_size[i] = dwc_param_dev_tx_fifo_size_default;
+ }
+ core_if->core_params->otg_ver = 1;
+ return 0;
+}
+
+
+
+
+
+
+
diff --git a/boot/common/src/loader/drivers/dwc_otg_cil.h b/boot/common/src/loader/drivers/dwc_otg_cil.h
new file mode 100644
index 0000000..1408175
--- /dev/null
+++ b/boot/common/src/loader/drivers/dwc_otg_cil.h
@@ -0,0 +1,404 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.h $
+ * $Revision: #123 $
+ * $Date: 2012/08/10 $
+ * $Change: 2047372 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+#if !defined(__DWC_CIL_H__)
+#define __DWC_CIL_H__
+
+#include "type.h"
+#include "dwc_otg_regs.h"
+
+#include "dwc_otg_core_if.h"
+
+//ÊÕ·¢»Øµ÷º¯ÊýµÄÔÐÍ
+typedef void (*F_USB_CB)(WORD32 dwPara, WORD32 dwResult, WORD32 dwLen, WORD32 dwWantLen);
+
+
+/** Macros defined for DWC OTG HW Release version */
+
+#define OTG_CORE_REV_2_60a 0x4F54260A
+#define OTG_CORE_REV_2_94a 0x4F54294A
+/**
+ * The <code>dwc_ep</code> structure represents the state of a single
+ * endpoint when acting in device mode. It contains the data items
+ * needed for an endpoint to be activated and transfer packets.
+ */
+#define DWC_OTG_EP_TYPE_ISOC 1
+#define DWC_OTG_EP_TYPE_BULK 2
+#define DWC_OTG_EP_TYPE_INTR 3
+
+typedef struct dwc_ep
+{
+ /** EP number used for register address lookup */
+ uint8_t num;
+ /** EP direction 0 = OUT */
+ unsigned is_in;//:1;
+ /** EP active. */
+ unsigned active;//:1;
+ /**
+ * Periodic Tx FIFO # for IN EPs For INTR EP set to 0 to use non-periodic
+ * Tx FIFO. If dedicated Tx FIFOs are enabled Tx FIFO # FOR IN EPs*/
+ unsigned tx_fifo_num;//:4;
+ /** EP type: 0 - Control, 1 - ISOC, 2 - BULK, 3 - INTR */
+ unsigned type;//:2;
+ /** DATA start PID for INTR and BULK EP */
+ unsigned data_pid_start;//:1;
+ /** Frame (even/odd) for ISOC EP */
+ unsigned even_odd_frame;//:1;
+ /** Max Packet bytes */
+ unsigned maxpacket;//:11;
+
+ /** Max Transfer size */
+ uint32_t maxxfer;
+
+ F_USB_CB fnUsbCb;
+
+ void *pPara;
+
+ uint8_t *start_xfer_buff;
+ /** pointer to the transfer buffer */
+ uint8_t *xfer_buff;
+ /** Number of bytes to transfer */
+ unsigned xfer_len;//:19;
+ /** Number of bytes transferred. */
+ unsigned xfer_count;//:19;
+ /** Sent ZLP */
+ unsigned sent_zlp;//:1;
+ /** Total len for control transfer */
+ unsigned total_len;//:19;
+
+ /** stall clear flag */
+ unsigned stall_clear_flag;//:1;
+
+ /** SETUP pkt cnt rollover flag for EP0 out*/
+ unsigned stp_rollover;
+
+} dwc_ep_t;
+
+/**
+ * The following parameters may be specified when starting the module. These
+ * parameters define how the DWC_otg controller should be configured.
+ */
+typedef struct dwc_otg_core_params
+{
+ /**
+ * Specifies the OTG capabilities. The driver will automatically
+ * detect the value for this parameter if none is specified.
+ * 0 - HNP and SRP capable (default)
+ * 1 - SRP Only capable
+ * 2 - No HNP/SRP capable
+ */
+ int32_t otg_cap;
+
+
+ /**
+ * Specifies the maximum speed of operation in host and device mode.
+ * The actual speed depends on the speed of the attached device and
+ * the value of phy_type. The actual speed depends on the speed of the
+ * attached device.
+ * 0 - High Speed (default)
+ * 1 - Full Speed
+ */
+ int32_t speed;
+
+ /**
+ * Specifies the type of PHY interface to use. By default, the driver
+ * will automatically detect the phy_type.
+ *
+ * 0 - Full Speed PHY
+ * 1 - UTMI+ (default)
+ * 2 - ULPI
+ */
+ int32_t phy_type;
+
+ /**
+ * Specifies the UTMI+ Data Width. This parameter is
+ * applicable for a PHY_TYPE of UTMI+ or ULPI. (For a ULPI
+ * PHY_TYPE, this parameter indicates the data width between
+ * the MAC and the ULPI Wrapper.) Also, this parameter is
+ * applicable only if the OTG_HSPHY_WIDTH cC parameter was set
+ * to "8 and 16 bits", meaning that the core has been
+ * configured to work at either data path width.
+ *
+ * 8 or 16 bits (default 16)
+ */
+ int32_t phy_utmi_width;
+
+ /**
+ * Specifies whether the ULPI operates at double or single
+ * data rate. This parameter is only applicable if PHY_TYPE is
+ * ULPI.
+ *
+ * 0 - single data rate ULPI interface with 8 bit wide data
+ * bus (default)
+ * 1 - double data rate ULPI interface with 4 bit wide data
+ * bus
+ */
+ int32_t phy_ulpi_ddr;
+
+ /**
+ * Specifies whether to use the internal or external supply to
+ * drive the vbus with a ULPI phy.
+ */
+ int32_t phy_ulpi_ext_vbus;
+
+ int32_t ulpi_fs_ls;
+
+ int32_t ts_dline;
+
+ /**
+ * Specifies whether dedicated transmit FIFOs are
+ * enabled for non periodic IN endpoints in device mode
+ * 0 - No
+ * 1 - Yes
+ */
+ int32_t en_multiple_tx_fifo;
+
+ /** Number of 4-byte words in each of the Tx FIFOs in device
+ * mode when dynamic FIFO sizing is enabled.
+ * 4 to 768 (default 256)
+ */
+ uint32_t dev_tx_fifo_size[MAX_TX_FIFOS];
+
+ /** Thresholding enable flag-
+ * bit 0 - enable non-ISO Tx thresholding
+ * bit 1 - enable ISO Tx thresholding
+ * bit 2 - enable Rx thresholding
+ */
+ //uint32_t thr_ctl;
+
+ /** Thresholding length for Tx
+ * FIFOs in 32 bit DWORDs
+ */
+ //uint32_t tx_thr_length;
+
+ /** Thresholding length for Rx
+ * FIFOs in 32 bit DWORDs
+ */
+ //uint32_t rx_thr_length;
+
+
+ /** Per Transfer Interrupt
+ * mode enable flag
+ * 1 - Enabled
+ * 0 - Disabled
+ */
+ int32_t pti_enable;
+
+
+ /** HFIR Reload Control
+ * 0 - The HFIR cannot be reloaded dynamically.
+ * 1 - Allow dynamic reloading of the HFIR register during runtime.
+ */
+ //int32_t reload_ctl;
+ /** DCFG: Enable device Out NAK
+ * 0 - The core does not set NAK after Bulk Out transfer complete.
+ * 1 - The core sets NAK after Bulk OUT transfer complete.
+ */
+ int32_t dev_out_nak;
+
+
+ /** OTG revision supported
+ * 0 - OTG 1.3 revision
+ * 1 - OTG 2.0 revision
+ */
+ int32_t otg_ver;
+
+} dwc_otg_core_params_t;
+/**
+ * The <code>dwc_otg_core_if</code> structure contains information needed to manage
+ * the DWC_otg controller acting in either host or device mode. It
+ * represents the programming view of the controller as a whole.
+ */
+#define DWC_OTG_PCGCCTL_OFFSET 0xE00
+#define DWC_OTG_DATA_FIFO_OFFSET 0x1000
+#define DWC_OTG_DATA_FIFO_SIZE 0x1000
+#define A_HOST (1)
+#define A_SUSPEND (2)
+#define A_PERIPHERAL (3)
+#define B_PERIPHERAL (4)
+#define B_HOST (5)
+
+struct dwc_otg_core_if
+{
+ dwc_otg_core_params_t *core_params;
+
+ dwc_otg_core_global_regs_t *core_global_regs;
+
+ dwc_otg_dev_if_t *dev_if;
+ uint8_t phy_init_done;
+
+
+ volatile uint32_t *pcgcctl;
+
+ uint32_t *data_fifo[MAX_EPS_CHANNELS];
+
+ uint16_t total_fifo_size;
+ uint16_t rx_fifo_size;
+ uint16_t nperio_tx_fifo_size;
+
+ uint8_t pti_enh_enable;
+
+ uint8_t multiproc_int_enable;
+
+ uint8_t en_multiple_tx_fifo;
+
+ hwcfg1_data_t hwcfg1;
+ hwcfg2_data_t hwcfg2;
+ hwcfg3_data_t hwcfg3;
+ hwcfg4_data_t hwcfg4;
+ fifosize_data_t hptxfsiz;
+ dcfg_data_t dcfg;
+
+ uint32_t otg_ver;
+
+};
+
+extern void dwc_otg_core_dev_init(dwc_otg_core_if_t * _core_if);
+
+extern void dwc_otg_read_setup_packet(dwc_otg_core_if_t * _core_if,
+ uint32_t * _dest);
+extern void dwc_otg_ep0_activate(dwc_otg_core_if_t * _core_if, dwc_ep_t * _ep);
+extern void dwc_otg_ep_activate(dwc_otg_core_if_t * _core_if, dwc_ep_t * _ep);
+extern void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * _core_if,
+ dwc_ep_t * _ep);
+extern void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * _core_if,
+ dwc_ep_t * _ep);
+extern void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * _core_if,
+ dwc_ep_t * _ep);
+extern void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * _core_if,
+ dwc_ep_t * _ep);
+extern void dwc_otg_ep_write_packet(dwc_otg_core_if_t * _core_if,
+ dwc_ep_t * _ep, int _dma);
+extern void dwc_otg_ep_set_stall(dwc_otg_core_if_t * _core_if, dwc_ep_t * _ep);
+extern void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * _core_if,
+ dwc_ep_t * _ep);
+extern void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * _core_if);
+
+void DWC_MODIFY_REG32(uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask);
+
+
+extern void dwc_otg_read_packet(dwc_otg_core_if_t * core_if,
+ uint8_t * dest, uint16_t bytes);
+
+extern void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * _core_if, const int _num);
+extern void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * _core_if);
+extern void dwc_otg_core_reset(dwc_otg_core_if_t * _core_if);
+
+/**
+ * This function returns the Core Interrupt register.
+ */
+static uint32_t dwc_otg_read_core_intr(dwc_otg_core_if_t * core_if)
+{
+ return (DWC_READ_REG32(&core_if->core_global_regs->gintsts) &
+ DWC_READ_REG32(&core_if->core_global_regs->gintmsk));
+}
+
+
+/**
+ * This function reads the Device All Endpoints Interrupt register and
+ * returns the IN endpoint interrupt bits.
+ */
+static uint32_t dwc_otg_read_dev_all_in_ep_intr(dwc_otg_core_if_t *
+ core_if)
+{
+
+ uint32_t v;
+ {
+ v = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daint) &
+ DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk);
+ }
+ return (v & 0xffff);
+}
+
+/**
+ * This function reads the Device All Endpoints Interrupt register and
+ * returns the OUT endpoint interrupt bits.
+ */
+static uint32_t dwc_otg_read_dev_all_out_ep_intr(dwc_otg_core_if_t *
+ core_if)
+{
+ uint32_t v;
+
+ {
+ v = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daint) &
+ DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk);
+ }
+
+ return ((v & 0xffff0000) >> 16);
+}
+
+/**
+ * This function returns the Device IN EP Interrupt register
+ */
+static uint32_t dwc_otg_read_dev_in_ep_intr(dwc_otg_core_if_t * core_if,
+ dwc_ep_t * ep)
+{
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ uint32_t v, msk, emp;
+
+ {
+ msk = DWC_READ_REG32(&dev_if->dev_global_regs->diepmsk);
+ emp = DWC_READ_REG32(&dev_if->dev_global_regs->dtknqr4_fifoemptymsk);
+ msk |= ((emp >> ep->num) & 0x1) << 7;
+ v = DWC_READ_REG32(&dev_if->in_ep_regs[ep->num]->diepint) & msk;
+ }
+
+ return v;
+}
+
+/**
+ * This function returns the Device OUT EP Interrupt register
+ */
+static uint32_t dwc_otg_read_dev_out_ep_intr(dwc_otg_core_if_t *_core_if, dwc_ep_t * _ep)
+{
+ dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
+ uint32_t v;
+ doepmsk_data_t msk;
+ msk.d32 = 0;
+ {
+ msk.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->doepmsk);
+ if (_core_if->pti_enh_enable)
+ {
+ msk.b.pktdrpsts = 1;
+ }
+ v = DWC_READ_REG32(&dev_if->out_ep_regs[_ep->num]->doepint) & msk.d32;
+ }
+ return v;
+}
+
+static uint32_t dwc_otg_mode(dwc_otg_core_if_t * _core_if)
+{
+ return (DWC_READ_REG32(&_core_if->core_global_regs->gintsts) & 0x1);
+}
+
+#endif
diff --git a/boot/common/src/loader/drivers/dwc_otg_cil_intr.c b/boot/common/src/loader/drivers/dwc_otg_cil_intr.c
new file mode 100644
index 0000000..b52b083
--- /dev/null
+++ b/boot/common/src/loader/drivers/dwc_otg_cil_intr.c
@@ -0,0 +1,69 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil_intr.c $
+ * $Revision: #32 $
+ * $Date: 2012/08/10 $
+ * $Change: 2047372 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/** @file
+ *
+ * The Core Interface Layer provides basic services for accessing and
+ * managing the DWC_otg hardware. These services are used by both the
+ * Host Controller Driver and the Peripheral Controller Driver.
+ *
+ * This file contains the Common Interrupt handlers.
+ */
+
+#include "dwc_otg_regs.h"
+#include "dwc_otg_cil.h"
+#include "dwc_otg_driver.h"
+#include "dwc_otg_pcd.h"
+/**
+ * This interrupt indicates that SUSPEND state has been detected on
+ * the USB.
+ *
+ * For HNP the USB Suspend interrupt signals the change from
+ * "a_peripheral" to "a_host".
+ *
+ * When power management is enabled the core will be put in low power
+ * mode.
+ */
+int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t * core_if)
+{
+ gintsts_data_t gintsts;
+ printf("S\n");
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.usbsuspend = 1;
+ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
+
+ return 1;
+}
+
diff --git a/boot/common/src/loader/drivers/dwc_otg_core_if.h b/boot/common/src/loader/drivers/dwc_otg_core_if.h
new file mode 100644
index 0000000..4a17de0
--- /dev/null
+++ b/boot/common/src/loader/drivers/dwc_otg_core_if.h
@@ -0,0 +1,109 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_core_if.h $
+ * $Revision: #13 $
+ * $Date: 2012/08/10 $
+ * $Change: 2047372 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+#if !defined(__DWC_CORE_IF_H__)
+#define __DWC_CORE_IF_H__
+#include <common.h>
+struct dwc_otg_core_if;
+typedef struct dwc_otg_core_if dwc_otg_core_if_t;
+
+#define DWC_E_NOT_SUPPORTED 1004
+#define DWC_E_INVALID 1001
+#define DWC_E_NO_MEMORY 1002
+#define DWC_E_NO_DEVICE 1003
+#define DWC_E_SHUTDOWN 1010
+
+/** Maximum number of Periodic FIFOs */
+#define MAX_TX_FIFOS 15
+
+/** Maximum number of Endpoints/HostChannels */
+#define MAX_EPS_CHANNELS 3
+
+extern dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * _reg_base_addr);
+extern void dwc_otg_core_init(dwc_otg_core_if_t * _core_if);
+
+#define DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE 0
+#define DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
+#define dwc_param_otg_cap_default DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE
+#define dwc_param_opt_default 1
+#define dwc_param_dma_enable_default 1
+#define dwc_param_dma_desc_enable_default 1
+#define dwc_param_dma_burst_size_default 32
+#define dwc_param_speed_default 0
+#define DWC_SPEED_PARAM_HIGH 0
+#define DWC_SPEED_PARAM_FULL 1
+#define dwc_param_host_support_fs_ls_low_power_default 0
+#define dwc_param_host_ls_low_power_phy_clk_default 0
+#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0
+#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1
+#define dwc_param_enable_dynamic_fifo_default 1
+#define dwc_param_data_fifo_size_default 8192
+#define dwc_param_dev_rx_fifo_size_default 1064
+#define dwc_param_dev_nperio_tx_fifo_size_default 1024
+#define dwc_param_dev_perio_tx_fifo_size_default 256
+#define dwc_param_host_rx_fifo_size_default 1024
+#define dwc_param_host_nperio_tx_fifo_size_default 1024
+#define dwc_param_host_perio_tx_fifo_size_default 1024
+#define dwc_param_max_transfer_size_default 65535
+#define dwc_param_max_packet_count_default 511
+#define dwc_param_host_channels_default 12
+#define dwc_param_dev_endpoints_default 6
+#define DWC_PHY_TYPE_PARAM_FS 0
+#define DWC_PHY_TYPE_PARAM_UTMI 1
+#define DWC_PHY_TYPE_PARAM_ULPI 2
+#define dwc_param_phy_type_default DWC_PHY_TYPE_PARAM_UTMI
+#define dwc_param_phy_utmi_width_default 16
+#define dwc_param_phy_ulpi_ddr_default 0
+#define DWC_PHY_ULPI_INTERNAL_VBUS 0
+#define DWC_PHY_ULPI_EXTERNAL_VBUS 1
+#define dwc_param_phy_ulpi_ext_vbus_default DWC_PHY_ULPI_INTERNAL_VBUS
+#define dwc_param_i2c_enable_default 0
+#define dwc_param_ulpi_fs_ls_default 0
+#define dwc_param_ts_dline_default 0
+#define dwc_param_en_multiple_tx_fifo_default 1
+#define dwc_param_dev_tx_fifo_size_default 768
+#define dwc_param_thr_ctl_default 0
+#define dwc_param_tx_thr_length_default 64
+#define dwc_param_rx_thr_length_default 64
+#define dwc_param_lpm_enable_default 1
+#define dwc_param_pti_enable_default 0
+#define dwc_param_mpi_enable_default 0
+#define dwc_param_adp_enable_default 0
+#define dwc_param_ic_usb_cap_default 0
+#define dwc_param_ahb_thr_ratio_default 0
+#define dwc_param_power_down_default 0
+#define dwc_param_reload_ctl_default 0
+#define dwc_param_dev_out_nak_default 0
+#define dwc_param_cont_on_bna_default 0
+#define dwc_param_ahb_single_default 0
+
+#endif /* __DWC_CORE_IF_H__ */
diff --git a/boot/common/src/loader/drivers/dwc_otg_dev_test.c b/boot/common/src/loader/drivers/dwc_otg_dev_test.c
new file mode 100644
index 0000000..a9d4968
--- /dev/null
+++ b/boot/common/src/loader/drivers/dwc_otg_dev_test.c
@@ -0,0 +1,521 @@
+/******************************************************************/
+#include "global.h"
+#include "dwc_otg_driver.h"
+#include "config.h"
+
+
+void USB_isr(WORD32 dwIntNo,WORD32 dwPara)
+{
+ dwc_otg_pcd_handle_intr(global.g_dwc_otg_dev_t.pcd);
+
+}
+void USB_TstDev_InitEnv(void)
+{
+#if USE_ASIC
+ WORD32 i;
+ if(0 == global.g_USB_MODE)
+ {
+
+ //ÊÍ·ÅUSB¸ôÀë8bit for usb ctrl
+ REG32(POWER_DOMAIN_ISO) |= (1<<8);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_RST) |= (1<<8);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_POWERON) &= ~(1<<8);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_POWERON) |= (1<<8);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_RST) &= ~(1<<8);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_ISO) &= ~(1<<8);
+ usdelay(10);
+
+ //usb ahb clock enable
+ REG32(SOC_MOD_CLKEN0)&=~(1<<4);
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN0)|=(1<<4);
+ //usb phy clock enable
+ REG32(SOC_MOD_CLKEN1)&=~(1<<3);
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN1)|=(1<<3);
+
+ // usb ahb reset ÏÈ×ÜÏߺó¹¤×÷
+ REG32(SOC_MOD_RSTEN)&=~(1<<5);
+ usdelay(100);
+ REG32(SOC_MOD_RSTEN)|=(1<<5);
+ usdelay(100);
+
+ // usb work reset
+ REG32(SOC_MOD_RSTEN)&=~(1<<4);
+ usdelay(100);
+ REG32(SOC_MOD_RSTEN)|=(1<<4);
+ usdelay(100);
+
+ //release usb phy reset
+ REG32(SOC_MOD_RSTEN)&=~(1<<3);
+ usdelay(100);
+ REG32(SOC_MOD_RSTEN) |= 1<<3;
+ usdelay(100);
+
+ i = 0;
+ while((REG32(SOC_MOD_USBSTATECTRL)&0x2) == 0)
+ {
+ i++;
+ usdelay(20);
+ if(i>50000) break;
+ }
+ }
+ else
+ {
+ //ÊÍ·ÅUSB_HSIC¸ôÀë9bit for hsic
+ REG32(POWER_DOMAIN_ISO) |= (1<<9);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_RST) |= (1<<9);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_POWERON) &= ~(1<<9);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_POWERON) |= (1<<9);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_RST) &= ~(1<<9);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_ISO) &= ~(1<<9);
+ usdelay(10);
+
+ //usb hsic ahb clock enable
+ REG32(SOC_MOD_CLKEN0)&=~(1<<2);
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN0)|=(1<<2);
+ //usb hsic phy clock enable
+ REG32(SOC_MOD_CLKEN0)&=~(1<<1);
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN0)|=(1<<1);
+
+ //usb hsic 480M clock enable
+ REG32(SOC_MOD_CLKEN0)&=~(1<<0);
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN0)|=(1<<0);
+
+ // usb hsic ahb reset
+ REG32(SOC_MOD_RSTEN)&=~(1<<2);
+ usdelay(20);
+ REG32(SOC_MOD_RSTEN)|=(1<<2);
+ usdelay(10);
+
+ // usb hsic work reset
+ REG32(SOC_MOD_RSTEN)&=~(1<<1);
+ usdelay(20);
+ REG32(SOC_MOD_RSTEN)|=(1<<1);
+ //release usb hsic phy reset
+ REG32(SOC_MOD_RSTEN)&=~(1<<0);
+ usdelay(20);
+ REG32(SOC_MOD_RSTEN)|=(1<<0);
+
+ usdelay(100);
+ i = 0;
+ while((REG32(SOC_MOD_USBSTATECTRL)&0x1) == 0)
+ {
+ i++;
+ usdelay(20);
+ if(i>50000) break;
+ }
+
+#if SYNC_USB_HSIC
+ usdelay(20);
+ REG32(REG_GPIO_OUT)=1;
+ while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+#endif
+ }
+#endif
+#if !USE_ASIC
+//usb power on
+ REG32(POWER_DOMAIN_POWERON) |= 0x22000;
+ usdelay(10);
+//usb disable reset
+ REG32(POWER_DOMAIN_RST) &= 0xfffddfff;
+ usdelay(10);
+//usb disable iso
+ REG32(POWER_DOMAIN_ISO) &= 0xfffddfff;
+ usdelay(10);
+
+//open usb0 and usb1
+ //usb ahb clock enable
+ REG32(SOC_MOD_CLKEN0)&=0xeffffffb;
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN0)|=0x10000004;
+ //usb phy clock enable
+ REG32(SOC_MOD_CLKEN1)&=~(3<<16);
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN1)|=(3<<16);
+
+
+ // usb ctr reset
+ REG32(SOC_MOD_RSTEN)&=0xeffffff7;
+ usdelay(20);
+ REG32(SOC_MOD_RSTEN)|=0x10000008;
+
+ // usb ahb reset
+ REG32(SOC_MOD_RSTEN)&=0xf7fffffb;
+ usdelay(20);
+ REG32(SOC_MOD_RSTEN)|=0x8000004;
+/*
+ usb ctr and ahb reset release ,delay 60us, check usb reset state,
+ if the reset state is 0, reset ,if 1,reset release.
+*/
+#endif
+}
+
+void USB_TstDev_Isr(void)
+{
+ USB_isr(0,0); //´¦ÀíÖжϷþÎñ
+}
+T_USB_ENUM USB_Need_Enum(WORD32 USB_ADDR)
+{
+ WORD32 temp = 0;
+ temp = DWC_READ_REG32(USB_ADDR+0x14);
+ if(((temp>>13)|1)==1)
+ {
+ return DONOT_NEED_ENUM;
+ }
+ return NEED_ENUM;
+}
+unsigned int g_testVal = 0;
+
+WORD32 USB_CDC_Enum(WORD32 USB_ADDR)
+{
+ WORD32 dwCount=0;
+ WORD32 dwCount1=0;
+ if(NEED_ENUM == global.g_enum)
+ {
+ global.g_Connet = 0;
+ }
+ else
+ {
+ global.g_Connet = 1;
+ }
+
+ global.g_USB_TIMEOUT = 10;
+
+ g_testVal = 20/5;
+ dwc_otg_driver_probe(USB_ADDR);
+ if(global.g_enum == NEED_ENUM)
+ {
+ while (1)
+ {
+ //poll mode or interrupt mode
+ USB_TstDev_Isr();
+#if SYNC_SETADDRESS
+ if (global.g_dwc_otg_dev_t.pcd->request_config == 2)
+ break;
+#else
+ //µÈ´ý½øÈëÅäÖÃ̬
+ if (global.g_dwc_otg_dev_t.pcd->request_config == 1)
+ break;
+#endif
+/* µ±usb_mode =1ʱ£¬ÓÃÓÚHSIC,µ±usb_mode =0ʱ£¬ÓÃÓÚUSB */
+ if(global.g_USB_MODE == 0)
+ {
+ if(0==global.g_Connet)
+ {
+ dwCount++;
+#if SIM_EN
+ //usdelay(5000);
+#else
+ usdelay(1);
+#endif
+ if(dwCount>(400*global.g_USB_TIMEOUT))
+ {
+ //return 1;
+ }
+ }
+#if SYNC_SETADDRESS
+ else if(global.g_dwc_otg_dev_t.pcd->request_config == 2)
+#else
+ else if(global.g_dwc_otg_dev_t.pcd->request_config == 1)
+#endif
+ {
+ break;
+ }
+ else
+ {
+ dwCount1++;
+#if SIM_EN
+ //usdelay(5000);
+#else
+ usdelay(1);
+#endif
+ if(dwCount1>(200*global.g_USB_TIMEOUT))
+ {
+ //return 1; huhuahong
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+void Out_callback( WORD32 dwPara, WORD32 dwCause, WORD32 dwDone, WORD32 dwLen)
+{
+ printf("Out_callback\n");
+ *((WORD32 *)dwPara) = dwDone;
+ global.dwRxQuit = 1;
+#if SYNC_USB_CTRL
+ REG32(ARM_PORTA)=0x77;
+#endif
+
+}
+
+void In_callback( WORD32 dwPara, WORD32 dwCause, WORD32 dwDone, WORD32 dwLen)
+{
+ *((WORD32 *)dwPara) = dwDone;
+ global.dwTxQuit = 1;
+#if SYNC_USB_CTRL
+ REG32(ARM_PORTA)=0x88;
+#endif
+}
+
+WORD32 USB_RecvOutData(WORD32 dwEPNo, BYTE *pchBuf, WORD32 dwLen, F_USB_CB fnUsbCb, void *pPara)
+{
+ dwc_otg_pcd_ep_t *ep = NULL;
+ ep = &(global.g_dwc_otg_dev_t.pcd->out_ep[dwEPNo-1]);
+ ep->dwc_ep.is_in = 0;
+ ep->dwc_ep.num = dwEPNo;
+ ep->dwc_ep.data_pid_start = 0;
+ ep->dwc_ep.tx_fifo_num = dwEPNo;
+ ep->dwc_ep.start_xfer_buff = pchBuf;
+ ep->dwc_ep.xfer_buff = pchBuf;
+ ep->dwc_ep.xfer_len = 0;
+ ep->dwc_ep.xfer_count = 0;
+ ep->dwc_ep.fnUsbCb = fnUsbCb;
+ ep->dwc_ep.pPara = pPara;
+ ep->dwc_ep.total_len = dwLen;
+ dwc_otg_ep_start_transfer(global.g_dwc_otg_dev_t.core_if,&ep->dwc_ep);
+ return 0;
+}
+
+WORD32 USB_SendInData(WORD32 dwEPNo, BYTE *pchBuf, WORD32 dwLen, F_USB_CB fnUsbCb, void *pPara)
+{
+ dwc_otg_pcd_ep_t *ep = NULL;
+ ep = &(global.g_dwc_otg_dev_t.pcd->in_ep[dwEPNo-1]);
+ ep->dwc_ep.is_in = 1;
+ ep->dwc_ep.num = dwEPNo;
+ ep->dwc_ep.data_pid_start = 0;
+ ep->dwc_ep.tx_fifo_num = dwEPNo;
+ ep->dwc_ep.start_xfer_buff = pchBuf;
+ ep->dwc_ep.xfer_buff = pchBuf;
+ ep->dwc_ep.fnUsbCb = fnUsbCb;
+ ep->dwc_ep.pPara = pPara;
+ ep->dwc_ep.xfer_len = 0;
+ ep->dwc_ep.xfer_count = 0;
+ ep->dwc_ep.total_len = dwLen;
+ dwc_otg_ep_start_transfer(global.g_dwc_otg_dev_t.core_if,&ep->dwc_ep);
+ return 0;
+}
+
+WORD32 usb_read(BYTE *pchBuf,WORD32 dwLen)
+{
+ WORD32 dwDone;
+
+ global.dwRxQuit=0;
+
+ USB_RecvOutData( 1,(BYTE *)pchBuf,dwLen,Out_callback,(void *)&dwDone);
+
+ while(!global.dwRxQuit)
+ {
+ USB_TstDev_Isr();
+ }
+
+ return dwDone;
+}
+
+WORD32 USB_Check_Sync(BYTE *pchBuf, WORD32 dwLen)
+{
+ WORD32 dwDone;
+ WORD32 dwCount = 0;
+
+ global.dwRxQuit=0;
+ USB_RecvOutData( 1,(BYTE *)pchBuf,dwLen,Out_callback,(void *)&dwDone);
+ dwCount=0;
+ while(1)
+ {
+ USB_TstDev_Isr();
+ if(0==global.dwRxQuit)
+ {
+ dwCount++;
+ if(dwCount>(200*global.g_USB_TIMEOUT))
+ {
+ //return 0;
+ }
+#if SIM_EN
+ //usdelay(5000);
+#else
+ usdelay(1);
+#endif
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if(0x5A!=*pchBuf)
+ {
+ return 0;
+ }
+
+ return dwDone;
+}
+WORD32 usb_write(BYTE *pchBuf,WORD32 dwLen)
+{
+ WORD32 dwDone;
+
+ global.dwTxQuit=0;
+
+ USB_SendInData(1,pchBuf, dwLen, In_callback,(void *)&dwDone);
+
+ while(!global.dwTxQuit)
+ {
+ USB_TstDev_Isr();
+ }
+
+ return dwDone;
+}
+
+int dwc_otg_driver_probe(WORD32 USB_ADDR)
+{
+ uint32_t udj = 0;
+ uint32_t *ptbase = (uint32_t *)USB_ADDR;
+ uint8_t* ptg_dwc_otg_dev_t = (uint8_t* )(&global.g_dwc_otg_dev_t);
+ for(udj= 0;udj<sizeof(global.g_dwc_otg_dev_t);udj++)
+ {
+ ptg_dwc_otg_dev_t[udj] = 0;
+ }
+
+ global.g_dwc_otg_dev_t.core_if = dwc_otg_cil_init(ptbase);
+
+ /*
+ * Initialize the DWC_otg core.
+ */
+ dwc_otg_core_init(global.g_dwc_otg_dev_t.core_if);
+
+#if SYNC_USB_CTRL
+ REG32(ARM_PORTA)=0x11;
+#endif
+ /*
+ * Initialize the PCD,½«pcd_initÕª³öÀ´
+ */
+ global.g_dwc_otg_dev_t.pcd = dwc_otg_pcd_init(global.g_dwc_otg_dev_t.core_if);
+
+#if SYNC_USB_CTRL
+ REG32(ARM_PORTA)=0x22;
+#endif
+#if SYNC_USB_HSIC
+ //for hsic
+ REG32(REG_GPIO_OUT)=2;
+ while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+#endif
+ global.g_dwc_otg_dev_t.pcd->otg_dev = (&global.g_dwc_otg_dev_t);
+ if(global.g_enum == NEED_ENUM)
+ {
+ DWC_MODIFY_REG32(&global.g_dwc_otg_dev_t.core_if->core_global_regs->gahbcfg, 0, 1);
+ }
+ return 0;
+}
+static inline void delay(unsigned long loops)
+{
+ /*
+ __asm__ volatile ("1:\n" "subs %0, %1, #1\n"
+ "bne 1b":"=r" (loops):"0"(loops));
+ */
+}
+static inline void udelay(unsigned long us)
+{
+ delay(us * 200); /* approximate */
+}
+
+#if 0
+void usdelay(unsigned us)
+{
+ udelay(us);
+}
+#endif
+extern void ep0_out_start(dwc_otg_core_if_t * core_if,dwc_otg_pcd_t * pcd);
+extern void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep);
+extern void active_allep(dwc_otg_pcd_t * pcd);
+typedef struct usb_record
+{
+ WORD32 address;
+ WORD32 value;
+
+}T_usb_record;
+T_usb_record usb_record[1000];
+WORD32 index = 0;
+
+void usb_printf (WORD32 *address)
+{
+ usb_record[index].address = (WORD32)address;
+ usb_record[index].value = *address;
+ index = (index+1)%1000;
+
+}
+
+static inline BYTE get_boot_mode(void)
+{
+ return (*(WORD32*)SYS_BOOTSEL_BASE &0x3);
+}
+
+int tsp_usb_init(void)
+{
+ WORD32 retVal = 0;
+ WORD32 usb_addr = 0;
+ BYTE boot_mode = get_boot_mode();
+ data_init();
+ /*add by sunyunchen*/
+ if(2 == boot_mode)
+ {
+ printf("hsic\n");
+ global.g_USB_MODE = 1;
+ usb_addr = SYS_USB_HSIC_BASE;
+ }
+ else
+ {
+ printf("usb\n");
+ global.g_USB_MODE = 0;
+ usb_addr = SYS_USB_BASE;
+ }
+ if((REG32(usb_addr+DWC_DEV_GLOBAL_REG_OFFSET)&0x7f0)!=0)//dcfg register
+ {
+ global.g_enum =DONOT_NEED_ENUM;
+ }
+ if(NEED_ENUM == global.g_enum)
+ {
+ USB_TstDev_InitEnv();
+ }
+ else
+ {
+ global.g_dwc_otg_pcd_tp.ep0state = EP0_IDLE;
+ global.dwRxQuit = 1;
+ global.dwTxQuit = 1;
+ global.g_dwc_otg_pcd_tp.request_config = 1;
+ }
+
+ retVal = USB_CDC_Enum(usb_addr);
+
+ return retVal;
+}
+
+
diff --git a/boot/common/src/loader/drivers/dwc_otg_driver.h b/boot/common/src/loader/drivers/dwc_otg_driver.h
new file mode 100644
index 0000000..c11e537
--- /dev/null
+++ b/boot/common/src/loader/drivers/dwc_otg_driver.h
@@ -0,0 +1,74 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_driver.h $
+ * $Revision: #19 $
+ * $Date: 2010/11/15 $
+ * $Change: 1627671 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+#ifndef __DWC_OTG_DRIVER_H__
+#define __DWC_OTG_DRIVER_H__
+
+
+
+
+#define DWC_DEVICE_ONLY
+#define DEV_FIRST
+/** @file
+ * This file contains the interface to the Linux driver.
+ */
+
+#include "usb.h"
+#include "dwc_otg_core_if.h"
+#include "dwc_otg_pcd.h"
+
+
+/* Type declarations */
+struct dwc_otg_pcd;
+/**
+ * This structure is a wrapper that encapsulates the driver components used to
+ * manage a single DWC_otg controller.
+ */
+typedef struct dwc_otg_device
+{
+
+ /** Pointer to the core interface structure. */
+ dwc_otg_core_if_t *core_if;
+
+ /** Pointer to the PCD structure. */
+ struct dwc_otg_pcd *pcd;
+
+} dwc_otg_device_t;
+
+
+
+
+int dwc_otg_driver_probe(WORD32 USB_ADDR);
+
+
+#endif
diff --git a/boot/common/src/loader/drivers/dwc_otg_pcd.c b/boot/common/src/loader/drivers/dwc_otg_pcd.c
new file mode 100644
index 0000000..74d6adb
--- /dev/null
+++ b/boot/common/src/loader/drivers/dwc_otg_pcd.c
@@ -0,0 +1,338 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd.c $
+ * $Revision: #101 $
+ * $Date: 2012/08/10 $
+ * $Change: 2047372 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+#ifndef DWC_HOST_ONLY
+
+/** @file
+ * This file implements PCD Core. All code in this file is portable and doesn't
+ * use any OS specific functions.
+ * PCD Core provides Interface, defined in <code><dwc_otg_pcd_if.h></code>
+ * header file, which can be used to implement OS specific PCD interface.
+ *
+ * An important function of the PCD is managing interrupts generated
+ * by the DWC_otg controller. The implementation of the DWC_otg device
+ * mode interrupt service routines is in dwc_otg_pcd_intr.c.
+ *
+ * @todo Add Device Mode test modes (Test J mode, Test K mode, etc).
+ * @todo Does it work when the request size is greater than DEPTSIZ
+ * transfer size
+ *
+ */
+#include "global.h"
+#include "dwc_otg_pcd.h"
+
+__align(4) const dwc_device_descriptor_t device_desc =
+{
+ sizeof(dwc_device_descriptor_t),
+ DEVICE_DESCRIPTOR,
+ 0x0200, // usb 2.0 //usb 1.1
+ 0x00,
+ 0x00,
+ 0x00,
+ CONTROL_64, // ×î´ó°ü8×Ö½Ú
+ USB_VENDOR_ID,
+ USB_PRODUCT_ID,
+ PRODUCT_RELEASE_NUMBER,
+ 0x01, // manufacturer descriptionË÷ÒýºÅ
+ 0x02, // product descriptionË÷ÒýºÅ
+ 0x03, // serial number descriptionË÷ÒýºÅ
+ 0x01 // ÅäÖÃÊý
+};
+
+__align(4) const dwc_dev_qual_descriptor_t dev_qual_desc =
+{
+ sizeof(dwc_dev_qual_descriptor_t),
+ 0x06,
+ 0x0200, // usb 2.0
+ VERDOR_SPECIFIC,
+ 0x00,
+ 0x00,
+ 64,
+ 0x01, // ÅäÖÃÊý
+ 0x0
+};
+
+
+
+__align(4) const dwc_langid_descriptor_t tLanguage=
+{
+ STRING_DESCRIPTOR_SIZE(1),
+ STRING_DESCRIPTOR,
+ LANGID_US_ENGLISH
+};
+
+__align(4) const dwc_string_descriptor_t tManufacture=
+{
+ STRING_DESCRIPTOR_SIZE(11),
+ STRING_DESCRIPTOR,
+ UNICODE('Z'), UNICODE('T'), UNICODE('E'), UNICODE(' '), UNICODE('C'),
+ UNICODE('o'), UNICODE(','), UNICODE('L'), UNICODE('t'), UNICODE('d'),
+ UNICODE('.'),
+};
+
+__align(4) const dwc_string_descriptor_t tProduct=
+{
+ STRING_DESCRIPTOR_SIZE(14),
+ STRING_DESCRIPTOR,
+ UNICODE('Z'), UNICODE('T'), UNICODE('E'), UNICODE(' '), UNICODE('B'),
+ UNICODE('o'), UNICODE('o'), UNICODE('t'), UNICODE('L'), UNICODE('o'),
+ UNICODE('a'), UNICODE('d'), UNICODE('e'), UNICODE('r')
+};
+
+__align(4) const dwc_string_descriptor_t tSN=
+{
+ STRING_DESCRIPTOR_SIZE(16),
+ STRING_DESCRIPTOR,
+ UNICODE('z'), UNICODE('t'), UNICODE('e'), UNICODE('&'), UNICODE('u'),
+ UNICODE('s'), UNICODE('b'), UNICODE('B'), UNICODE('o'), UNICODE('o'),
+ UNICODE('t'), UNICODE('l'), UNICODE('o'), UNICODE('d'), UNICODE('e'),
+ UNICODE('r')
+};
+
+__align(4) const dwc_string_descriptor_t tIfc0Name=
+ {
+ STRING_DESCRIPTOR_SIZE(9),
+ STRING_DESCRIPTOR,
+ UNICODE('B'), UNICODE('o'), UNICODE('o'), UNICODE('t'), UNICODE('l'),
+ UNICODE('o'), UNICODE('d'), UNICODE('e'), UNICODE('r')
+ };
+
+__align(4) const dwc_string_descriptor_t tIfc1Name=
+ {
+ STRING_DESCRIPTOR_SIZE(6),
+ STRING_DESCRIPTOR,
+ UNICODE('S'), UNICODE('e'), UNICODE('r'), UNICODE('i'), UNICODE('a'),
+ UNICODE('l')
+ };
+
+__align(4) const dwc_string_descriptor_t * const pStrDescIdx[]=
+{
+ (dwc_string_descriptor_t *)(&tLanguage),
+ (dwc_string_descriptor_t *)&tManufacture,
+ (dwc_string_descriptor_t *)&tProduct,
+ (dwc_string_descriptor_t *)&tSN,
+ (dwc_string_descriptor_t *)&tIfc0Name,
+ (dwc_string_descriptor_t *)&tIfc1Name,
+};
+
+
+static void do_get_descriptor(dwc_otg_pcd_t * pcd,uint32_t *buff,uint32_t len)
+{
+
+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+ pcd->ep0_pending = 1;
+ ep0->dwc_ep.start_xfer_buff =(uint8_t*) buff;
+ ep0->dwc_ep.xfer_buff =(uint8_t*)buff;
+ ep0->dwc_ep.xfer_len = len;
+ ep0->dwc_ep.xfer_count = 0;
+ ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
+ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
+
+}
+
+extern void ep0_do_stall(dwc_otg_pcd_t * pcd, const int err_val);
+
+int dwc_setup(dwc_otg_pcd_t * pcd, usb_device_request_t * ctrl)
+{
+ uint8_t byIdx;
+ uint32_t len = 0;
+ uint16_t value;
+ byIdx = (uint8_t)(ctrl->wValue &0xff);
+ value = ctrl->wValue>>8;
+
+ if( USB_DT_DEVICE ==value )
+ {
+ len = MIN( sizeof(dwc_device_descriptor_t), ctrl->wLength);
+ do_get_descriptor(pcd,(uint32_t*)&device_desc,len);
+ }
+ else if( USB_DT_CONFIG==value )
+ {
+ len = MIN( sizeof(dwc_config_all_t), ctrl->wLength);
+ do_get_descriptor(pcd,(uint32_t*)&g_config_desc,len);
+ }
+
+ else if( USB_DT_STRING ==value)
+ {
+ len = MIN(((dwc_string_descriptor_t*)(pStrDescIdx[byIdx]))->bLength, ctrl->wLength);
+ do_get_descriptor(pcd,(uint32_t*)pStrDescIdx[byIdx],len);
+ }
+
+ else if( USB_DT_INTERFACE == value)
+ {
+ len = MIN(((dwc_string_descriptor_t*)(pStrDescIdx[byIdx]))->bLength, ctrl->wLength);
+ do_get_descriptor(pcd,(uint32_t*)pStrDescIdx[byIdx],len);
+ }
+ else if( ENDPOINT_DESCRIPTOR == value)
+ {
+ len = MIN(((dwc_string_descriptor_t*)(pStrDescIdx[byIdx]))->bLength, ctrl->wLength);
+ do_get_descriptor(pcd,(uint32_t*)pStrDescIdx[byIdx],len);
+ }
+ else if( USB_DT_DEVICE_QUALIFIER ==value)
+ {
+ len = MIN(sizeof(dwc_dev_qual_descriptor_t),ctrl->wLength);
+ do_get_descriptor(pcd,(uint32_t*)&dev_qual_desc,len);
+ }
+ else
+ {
+ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
+ }
+
+ return 0;
+}
+
+
+static void dwc_otg_pcd_init_ep(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * pcd_ep,
+ uint32_t is_in, uint32_t ep_num)
+{
+ /* Init EP structure */
+ pcd_ep->desc = 0;
+ pcd_ep->pcd = pcd;
+ pcd_ep->stopped = 1;
+ pcd_ep->queue_sof = 0;
+
+ /* Init DWC ep structure */
+ pcd_ep->dwc_ep.is_in = is_in;
+ pcd_ep->dwc_ep.num = ep_num;
+ pcd_ep->dwc_ep.active = 0;
+ pcd_ep->dwc_ep.tx_fifo_num = 0;
+ /* Control until ep is actvated */
+ pcd_ep->dwc_ep.type = DWC_OTG_EP_TYPE_BULK;
+ pcd_ep->dwc_ep.maxpacket = 512;
+ pcd_ep->dwc_ep.maxxfer = 65536;
+
+ pcd_ep->dwc_ep.start_xfer_buff = 0;
+ pcd_ep->dwc_ep.xfer_buff = 0;
+ pcd_ep->dwc_ep.xfer_len = 0;
+ pcd_ep->dwc_ep.xfer_count = 0;
+ pcd_ep->dwc_ep.sent_zlp = 0;
+ pcd_ep->dwc_ep.total_len = 0;
+}
+
+/**
+ * Initialize ep's
+ */
+static void dwc_otg_pcd_reinit(dwc_otg_pcd_t * pcd)
+{
+ int i;
+ uint32_t hwcfg1;
+ dwc_otg_pcd_ep_t *ep;
+ int in_ep_cntr, out_ep_cntr;
+ uint32_t num_in_eps = (GET_CORE_IF(pcd))->dev_if->num_in_eps;
+ uint32_t num_out_eps = (GET_CORE_IF(pcd))->dev_if->num_out_eps;
+
+ /**
+ * Initialize the EP0 structure.
+ */
+ pcd->ep0.dwc_ep.pPara = (void*)(&global.g_in_pPara[1]);
+
+ ep = &pcd->ep0;
+ dwc_otg_pcd_init_ep(pcd, ep, 0, 0);
+
+ in_ep_cntr = 0;
+ hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 3;
+ for (i = 1; in_ep_cntr < num_in_eps; i++)
+ {
+ if ((hwcfg1 & 0x1) == 0)
+ {
+ pcd->in_ep[in_ep_cntr].dwc_ep.pPara = (void*)(&global.g_in_pPara[in_ep_cntr]);
+ ep = &pcd->in_ep[in_ep_cntr];
+ in_ep_cntr++;
+ /**
+ * @todo NGS: Add direction to EP, based on contents
+ * of HWCFG1. Need a copy of HWCFG1 in pcd structure?
+ * sprintf(";r
+ */
+ dwc_otg_pcd_init_ep(pcd, ep, 1 /* IN */ , i);
+ }
+ hwcfg1 >>= 2;
+ }
+
+ out_ep_cntr = 0;
+ hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 2;
+ for (i = 1; out_ep_cntr < num_out_eps; i++)
+ {
+ if ((hwcfg1 & 0x1) == 0)
+ {
+ pcd->out_ep[out_ep_cntr].dwc_ep.pPara = (void*)(&global.g_out_pPara[out_ep_cntr]);
+ ep = &pcd->out_ep[out_ep_cntr];
+ out_ep_cntr++;
+ /**
+ * @todo NGS: Add direction to EP, based on contents
+ * of HWCFG1. Need a copy of HWCFG1 in pcd structure?
+ * sprintf(";r
+ */
+ dwc_otg_pcd_init_ep(pcd, ep, 0 /* OUT */ , i);
+ }
+ hwcfg1 >>= 2;
+ }
+ if(NEED_ENUM == global.g_enum)
+ {
+ pcd->ep0state = EP0_DISCONNECT;
+ }
+ else
+ {
+ pcd->ep0state = EP0_IDLE;
+
+ }
+ pcd->ep0.dwc_ep.maxpacket = MAX_EP0_SIZE;
+ pcd->ep0.dwc_ep.type = 0;
+}
+
+/**
+ * This function initialized the PCD portion of the driver.
+ *
+ */
+dwc_otg_pcd_t *dwc_otg_pcd_init(dwc_otg_core_if_t * core_if)
+{
+ dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)&global.g_dwc_otg_pcd_tp;
+ int i;
+ uint8_t* pt_dwc_otg_pcd_t = (uint8_t*)&global.g_dwc_otg_pcd_tp;
+ for(i = 0;i<sizeof(dwc_otg_pcd_t);i++)
+ {
+ pt_dwc_otg_pcd_t[i] = 0;
+ }
+
+ pcd->core_if = core_if;
+
+ pcd->setup_pkt = global.g_u_setup_pkt;
+ pcd->status_buf = &global.g_status_buf;
+ dwc_otg_pcd_reinit(pcd);
+
+ return pcd;
+
+
+}
+
+
+/******************************************************************************/
+
+#endif /* DWC_HOST_ONLY */
diff --git a/boot/common/src/loader/drivers/dwc_otg_pcd.h b/boot/common/src/loader/drivers/dwc_otg_pcd.h
new file mode 100644
index 0000000..e96d8c7
--- /dev/null
+++ b/boot/common/src/loader/drivers/dwc_otg_pcd.h
@@ -0,0 +1,188 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd.h $
+ * $Revision: #48 $
+ * $Date: 2012/08/10 $
+ * $Change: 2047372 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+#ifndef DWC_HOST_ONLY
+#if !defined(__DWC_PCD_H__)
+#define __DWC_PCD_H__
+#include "usb.h"
+#include "dwc_otg_cil.h"
+#include "dwc_otg_pcd_if.h"
+/**
+ * @file
+ *
+ * This file contains the structures, constants, and interfaces for
+ * the Perpherial Contoller Driver (PCD).
+ *
+ * The Peripheral Controller Driver (PCD) for Linux will implement the
+ * Gadget API, so that the existing Gadget drivers can be used. For
+ * the Mass Storage Function driver the File-backed USB Storage Gadget
+ * (FBS) driver will be used. The FBS driver supports the
+ * Control-Bulk (CB), Control-Bulk-Interrupt (CBI), and Bulk-Only
+ * transports.
+ *
+ */
+
+/**
+ * Get the pointer to the core_if from the pcd pointer.
+ */
+#define GET_CORE_IF( _pcd ) (_pcd->core_if)
+
+/**
+ * States of EP0.
+ */
+typedef enum ep0_state
+{
+ EP0_DISCONNECT, /* no host */
+ EP0_IDLE,
+ EP0_IN_DATA_PHASE,
+ EP0_OUT_DATA_PHASE,
+ EP0_IN_STATUS_PHASE,
+ EP0_OUT_STATUS_PHASE,
+ EP0_STALL,
+} ep0state_e;
+
+/** Fordward declaration.*/
+struct dwc_otg_pcd;
+
+/** DWC_otg request structure.
+ * This structure is a list of requests.
+ */
+typedef struct dwc_otg_pcd_request
+{
+ void *priv;
+ void *buf;
+ uint32_t dma;
+ uint32_t length;
+ uint32_t actual;
+ unsigned sent_zlp:1;
+ /**
+ * Used instead of original buffer if
+ * it(physical address) is not dword-aligned.
+ **/
+ uint8_t *dw_align_buf;
+ uint32_t dw_align_buf_dma;
+} dwc_otg_pcd_request_t;
+
+/** PCD EP structure.
+ * This structure describes an EP, there is an array of EPs in the PCD
+ * structure.
+ */
+typedef struct dwc_otg_pcd_ep
+{
+ /** USB EP Descriptor */
+ usb_endpoint_descriptor_t *desc;
+
+ /** queue of dwc_otg_pcd_requests. */
+ unsigned stopped:1;
+ unsigned disabling:1;
+ unsigned dma:1;
+ unsigned queue_sof:1;
+ dwc_ep_t dwc_ep;
+
+ /** Pointer to PCD */
+ struct dwc_otg_pcd *pcd;
+
+ void *priv;
+} dwc_otg_pcd_ep_t;
+
+/** DWC_otg PCD Structure.
+ * This structure encapsulates the data for the dwc_otg PCD.
+ */
+
+typedef union
+{
+ usb_device_request_t req;
+ uint32_t d32[2];
+}u_setup_pkt;
+
+struct dwc_otg_pcd
+{
+ /** The DWC otg device pointer */
+ struct dwc_otg_device *otg_dev;
+ /** Core Interface */
+ dwc_otg_core_if_t *core_if;
+ /** State of EP0 */
+ ep0state_e ep0state;
+ /** EP0 Request is pending */
+ unsigned ep0_pending;
+ /** Indicates when SET CONFIGURATION Request is in process */
+ unsigned request_config;
+ unsigned request_pending;
+
+ /** SETUP packet for EP0
+ * This structure is allocated as a DMA buffer on PCD initialization
+ * with enough space for up to 3 setup packets.
+ */
+ u_setup_pkt *setup_pkt;
+
+ uint32_t setup_pkt_dma_handle;
+ /* Additional buffer and flag for CTRL_WR premature case */
+ uint8_t *backup_buf;
+ unsigned data_terminated;
+
+ /** 2-byte dma buffer used to return status from GET_STATUS */
+ uint16_t *status_buf;
+ uint32_t status_buf_dma_handle;
+ /** EP0 */
+ dwc_otg_pcd_ep_t ep0;
+
+ /** Array of IN EPs. */
+ dwc_otg_pcd_ep_t in_ep[MAX_EPS_CHANNELS - 1];
+ /** Array of OUT EPs. */
+ dwc_otg_pcd_ep_t out_ep[MAX_EPS_CHANNELS - 1];
+
+#ifdef DWC_UTE_CFI
+ cfiobject_t *cfi;
+#endif
+
+};
+
+#define CLEAR_OUT_EP_INTR(__core_if,__epnum,__intr) \
+do { \
+ doepint_data_t doepint ; \
+ doepint.d32 = 0;\
+ doepint.b.__intr = 1; \
+ DWC_WRITE_REG32(&__core_if->dev_if->out_ep_regs[__epnum]->doepint, \
+ doepint.d32); \
+} while (0)
+
+#define CLEAR_IN_EP_INTR(__core_if,__epnum,__intr) \
+do { \
+ diepint_data_t diepint; \
+ diepint.d32 = 0;\
+ diepint.b.__intr = 1; \
+ DWC_WRITE_REG32(&__core_if->dev_if->in_ep_regs[__epnum]->diepint, \
+ diepint.d32); \
+} while (0)
+
+#endif
+#endif /* DWC_HOST_ONLY */
diff --git a/boot/common/src/loader/drivers/dwc_otg_pcd_if.h b/boot/common/src/loader/drivers/dwc_otg_pcd_if.h
new file mode 100644
index 0000000..63d2ddc
--- /dev/null
+++ b/boot/common/src/loader/drivers/dwc_otg_pcd_if.h
@@ -0,0 +1,60 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_if.h $
+ * $Revision: #11 $
+ * $Date: 2011/10/26 $
+ * $Change: 1873028 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+#ifndef DWC_HOST_ONLY
+
+#if !defined(__DWC_PCD_IF_H__)
+#define __DWC_PCD_IF_H__
+#include "dwc_otg_core_if.h"
+#include "dwc_otg_pcd.h"
+
+/** @file
+ * This file defines DWC_OTG PCD Core API.
+ */
+
+typedef struct dwc_otg_pcd dwc_otg_pcd_t;
+
+/** Maxpacket size for EP0 */
+#define MAX_EP0_SIZE 64
+
+extern dwc_otg_pcd_t *dwc_otg_pcd_init(dwc_otg_core_if_t * core_if);
+
+extern void dwc_otg_pcd_start(dwc_otg_pcd_t * pcd);
+
+extern int dwc_otg_pcd_ep_enable(dwc_otg_pcd_t * pcd,
+ const uint8_t * ep_desc, void *usb_ep);
+
+extern int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t * pcd);
+
+#endif /* __DWC_PCD_IF_H__ */
+
+#endif /* DWC_HOST_ONLY */
diff --git a/boot/common/src/loader/drivers/dwc_otg_pcd_intr.c b/boot/common/src/loader/drivers/dwc_otg_pcd_intr.c
new file mode 100644
index 0000000..e364597
--- /dev/null
+++ b/boot/common/src/loader/drivers/dwc_otg_pcd_intr.c
@@ -0,0 +1,1453 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_intr.c $
+ * $Revision: #116 $
+ * $Date: 2012/08/10 $
+ * $Change: 2047372 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+#ifndef DWC_HOST_ONLY
+#include "dwc_otg_pcd.h"
+
+#ifdef DWC_UTE_CFI
+#include "dwc_otg_cfi.h"
+#endif
+
+#include "global.h"
+
+
+/**
+ * This function returns pointer to in ep struct with number ep_num
+ */
+static dwc_otg_pcd_ep_t *get_in_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
+{
+ int i;
+ int num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
+ if (ep_num == 0)
+ {
+ return &pcd->ep0;
+ }
+ else
+ {
+ for (i = 0; i < num_in_eps; ++i)
+ {
+ if (pcd->in_ep[i].dwc_ep.num == ep_num)
+ return &pcd->in_ep[i];
+ }
+ return 0;
+ }
+}
+
+/**
+ * This function returns pointer to out ep struct with number ep_num
+ */
+static dwc_otg_pcd_ep_t *get_out_ep(dwc_otg_pcd_t * pcd, uint32_t ep_num)
+{
+ int i;
+ int num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
+ if (ep_num == 0)
+ {
+ return &pcd->ep0;
+ }
+ else
+ {
+ for (i = 0; i < num_out_eps; ++i)
+ {
+ if (pcd->out_ep[i].dwc_ep.num == ep_num)
+ return &pcd->out_ep[i];
+ }
+ return 0;
+ }
+}
+
+/**
+ * This functions gets a pointer to an EP from the wIndex address
+ * value of the control request.
+ */
+dwc_otg_pcd_ep_t *get_ep_by_addr(dwc_otg_pcd_t * pcd, uint16_t wIndex)
+{
+ dwc_otg_pcd_ep_t *ep;
+ uint32_t ep_num = UE_GET_ADDR(wIndex);
+
+ if (ep_num >= MAX_EPS_CHANNELS)
+ return 0;
+
+ if (ep_num == 0)
+ {
+ ep = &pcd->ep0;
+ }
+ else if (UE_GET_DIR(wIndex) == UE_DIR_IN)
+ { /* in ep */
+ ep = &pcd->in_ep[ep_num - 1];
+ }
+ else
+ {
+ ep = &pcd->out_ep[ep_num - 1];
+ }
+
+ return ep;
+}
+/**
+ * This function handles the Rx Status Queue Level Interrupt, which
+ * indicates that there is a least one packet in the Rx FIFO. The
+ * packets are moved from the FIFO to memory, where they will be
+ * processed when the Endpoint Interrupt Register indicates Transfer
+ * Complete or SETUP Phase Done.
+ *
+ * Repeat the following until the Rx Status Queue is empty:
+ * -# Read the Receive Status Pop Register (GRXSTSP) to get Packet
+ * info
+ * -# If Receive FIFO is empty then skip to step Clear the interrupt
+ * and exit
+ * -# If SETUP Packet call dwc_otg_read_setup_packet to copy the
+ * SETUP data to the buffer
+ * -# If OUT Data Packet call dwc_otg_read_packet to copy the data
+ * to the destination buffer
+ */
+int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(dwc_otg_pcd_t * pcd)
+{
+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+ dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+ gintmsk_data_t gintmask;
+ device_grxsts_data_t status;
+ dwc_otg_pcd_ep_t *ep;
+ gintsts_data_t gintsts;
+ gintmask.d32 = 0;
+
+ /* Disable the Rx Status Queue Level interrupt */
+ gintmask.b.rxstsqlvl = 1;
+ DWC_MODIFY_REG32(&global_regs->gintmsk, gintmask.d32, 0);
+
+ /* Get the Status from the top of the FIFO */
+ status.d32 = DWC_READ_REG32(&global_regs->grxstsp);
+
+ /* Get pointer to EP structure */
+ ep = get_out_ep(pcd, status.b.epnum);
+ if(0==ep)
+ return -1;
+ switch (status.b.pktsts)
+ {
+ case DWC_DSTS_GOUT_NAK:
+ break;
+ case DWC_STS_DATA_UPDT:
+ if (status.b.bcnt && ep->dwc_ep.xfer_buff)
+ {
+ /** @todo NGS Check for buffer overflow? */
+ dwc_otg_read_packet(core_if, ep->dwc_ep.xfer_buff,status.b.bcnt);
+ ep->dwc_ep.xfer_count += status.b.bcnt;
+ ep->dwc_ep.xfer_buff += status.b.bcnt;
+ }
+ break;
+ case DWC_STS_XFER_COMP:
+ break;
+ case DWC_DSTS_SETUP_COMP:
+ break;
+ case DWC_DSTS_SETUP_UPDT:
+ printf("complete_ep11\n");
+ dwc_otg_read_setup_packet(core_if, pcd->setup_pkt->d32);
+ ep->dwc_ep.xfer_count += status.b.bcnt;
+
+ #if SYNC_USB_HSIC
+ if(pcd->setup_pkt->req.bRequest == 0x05)
+ {
+
+ REG32(REG_GPIO_OUT)=0x9;
+ while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+ }
+ #endif
+ #if 0
+ if(DONOT_NEED_ENUM == global.g_enum)
+ {
+ printf("unmask endpoint\n");
+ DWC_WRITE_REG32(&pcd->core_if->dev_if->dev_global_regs->daintmsk,0x3003);
+ }
+ #endif
+ break;
+ default:
+ break;
+ }
+
+ /* Enable the Rx Status Queue Level interrupt */
+ DWC_MODIFY_REG32(&global_regs->gintmsk, 0, gintmask.d32);
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.rxstsqlvl = 1;
+ DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
+
+ return 1;
+}
+
+/**
+ * This function examines the Device IN Token Learning Queue to
+ * determine the EP number of the last IN token received. This
+ * implementation is for the Mass Storage device where there are only
+ * 2 IN EPs (Control-IN and BULK-IN).
+ *
+ * The EP numbers for the first six IN Tokens are in DTKNQR1 and there
+ * are 8 EP Numbers in each of the other possible DTKNQ Registers.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ *
+ */
+/**
+ * This function is called when dedicated Tx FIFO Empty interrupt occurs.
+ * The active request is checked for the next packet to be loaded into
+ * apropriate Tx FIFO.
+ */
+static int32_t write_empty_tx_fifo(dwc_otg_pcd_t * pcd, uint32_t epnum)
+{
+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ dtxfsts_data_t txstatus;
+ dwc_otg_pcd_ep_t *ep = 0;
+ uint32_t len = 0;
+ int dwords;
+ txstatus.d32 = 0;
+
+ if(epnum >= MAX_EPS_CHANNELS)
+ return -1;
+
+ ep = get_in_ep(pcd, epnum);
+ if(0==ep)
+ return -1;
+ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
+
+ if (len > ep->dwc_ep.maxpacket)
+ {
+ len = ep->dwc_ep.maxpacket;
+ }
+
+ dwords = (len + 3) / 4;
+
+ /* While there is space in the queue and space in the FIFO and
+ * More data to tranfer, Write packets to the Tx FIFO */
+ txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
+ while (txstatus.b.txfspcavail > dwords &&
+ ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len &&
+ ep->dwc_ep.xfer_len != 0)
+ {
+ /* Write the FIFO */
+ dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
+
+ len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
+ if (len > ep->dwc_ep.maxpacket)
+ {
+ len = ep->dwc_ep.maxpacket;
+ }
+
+ dwords = (len + 3) / 4;
+ txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
+ }
+
+
+ return 1;
+}
+
+/**
+ * This function configures EPO to receive SETUP packets.
+ *
+ * @todo NGS: Update the comments from the HW FS.
+ *
+ * -# Program the following fields in the endpoint specific registers
+ * for Control OUT EP 0, in order to receive a setup packet
+ * - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
+ * setup packets)
+ * - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
+ * to back setup packets)
+ * - In DMA mode, DOEPDMA0 Register with a memory address to
+ * store any setup packets received
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ * @param pcd Programming view of the PCD.
+ */
+ void ep0_out_start(dwc_otg_core_if_t * core_if,
+ dwc_otg_pcd_t * pcd)
+{
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ deptsiz0_data_t doeptsize0;
+ depctl_data_t doepctl;
+ doepctl.d32 = 0;
+ doeptsize0.d32 =0;
+
+
+ doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl);
+ if (doepctl.b.epena)
+ {
+ return;
+ }
+
+ doeptsize0.b.supcnt = 3;
+ doeptsize0.b.pktcnt = 1;
+ doeptsize0.b.xfersize = 8 * 3;
+
+ /** put here as for Hermes mode deptisz register should not be written */
+ DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doeptsiz,doeptsize0.d32);
+
+ /** DOEPCTL0 Register write cnak will be set after setup interrupt */
+ doepctl.d32 = 0;
+ doepctl.b.epena = 1;
+
+ DWC_MODIFY_REG32(&dev_if->out_ep_regs[0]->doepctl, 0, doepctl.d32);
+
+}
+
+
+void USB_Recovercfg(dwc_otg_pcd_t *pcd)
+{
+ int i = 0;
+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ depctl_data_t doepctl;
+ depctl_data_t diepctl;
+ doepctl.d32 = 0;
+ diepctl.d32 = 0;
+
+ for (i = 0; i < dev_if->num_out_eps; i++)
+ {
+ doepctl.d32= DWC_READ_REG32(&dev_if->out_ep_regs[i+1]->doepctl);
+ doepctl.b.eptype = pcd->out_ep[i].dwc_ep.type;
+ doepctl.b.mps = pcd->out_ep[i].dwc_ep.maxpacket;
+ DWC_WRITE_REG32(&dev_if->out_ep_regs[i+1]->doepctl, doepctl.d32);
+
+ diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i+1]->diepctl);
+ diepctl.b.eptype = pcd->in_ep[i].dwc_ep.type;
+ diepctl.b.mps = pcd->in_ep[i].dwc_ep.maxpacket;
+ DWC_WRITE_REG32(&dev_if->in_ep_regs[i+1]->diepctl, diepctl.d32);
+ }
+
+}
+int32_t dwc_otg_pcd_handle_usb_reset_intr(dwc_otg_pcd_t * pcd)
+{
+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ depctl_data_t doepctl;
+ daint_data_t daintmsk;
+ doepmsk_data_t doepmsk;
+ diepmsk_data_t diepmsk ;
+ dcfg_data_t dcfg ;
+ grstctl_t resetctl;
+ dctl_data_t dctl;
+ int i = 0;
+ gintsts_data_t gintsts;
+ pcgcctl_data_t power;
+ doepctl.d32 = 0;
+ daintmsk.d32 = 0;
+ doepmsk.d32 = 0;
+ diepmsk.d32 = 0;
+ dcfg.d32 = 0;
+ resetctl.d32 = 0;
+ dctl.d32 = 0;
+ power.d32 = 0;
+
+ power.d32 = DWC_READ_REG32(core_if->pcgcctl);
+ if (power.b.stoppclk)
+ {
+ power.d32 = 0;
+ power.b.stoppclk = 1;
+ DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
+
+ power.b.pwrclmp = 1;
+ DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
+
+ power.b.rstpdwnmodule = 1;
+ DWC_MODIFY_REG32(core_if->pcgcctl, power.d32, 0);
+ }
+
+ printf("R\n");
+
+ /* Clear the Remote Wakeup Signalling */
+ dctl.b.rmtwkupsig = 1;
+ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
+
+ /* Set NAK for all OUT EPs */
+ doepctl.b.snak = 1;
+ for (i = 0; i <= dev_if->num_out_eps; i++)
+ {
+ DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, doepctl.d32);
+ }
+
+ /* Flush the NP Tx FIFO */
+ dwc_otg_flush_tx_fifo(core_if, 0x10);
+ /* Flush the Learning Queue */
+ resetctl.b.intknqflsh = 1;
+ DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
+ {
+ daintmsk.b.inep0 = 1;
+ daintmsk.b.outep0 = 1;
+ DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk,daintmsk.d32);
+
+ doepmsk.b.setup = 1;
+ doepmsk.b.xfercompl = 1;
+ doepmsk.b.ahberr = 1;
+ doepmsk.b.epdisabled = 1;
+ DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, doepmsk.d32);
+
+ diepmsk.b.xfercompl = 1;
+ diepmsk.b.timeout = 1;
+ diepmsk.b.epdisabled = 1;
+ diepmsk.b.ahberr = 1;
+
+ DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32);
+ }
+
+ /* Reset Device Address */
+ dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
+ dcfg.b.devaddr = 0;
+ DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.usbreset = 1;
+ DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
+
+ USB_Recovercfg(pcd);
+
+ return 1;
+}
+
+/**
+ * Get the device speed from the device status register and convert it
+ * to USB speed constant.
+ *
+ * @param core_if Programming view of DWC_otg controller.
+ */
+static int get_device_speed(dwc_otg_core_if_t * core_if)
+{
+ dsts_data_t dsts;
+ int speed = 0;
+ dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
+
+ switch (dsts.b.enumspd)
+ {
+ case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
+ speed = USB_SPEED_HIGH;
+ break;
+ case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
+ case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
+ speed = USB_SPEED_FULL;
+ break;
+
+ case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
+ speed = USB_SPEED_LOW;
+ break;
+ }
+
+ return speed;
+}
+
+/**
+ * Read the device status register and set the device speed in the
+ * data structure.
+ * Set up EP0 to receive SETUP packets by calling dwc_ep0_activate.
+ */
+extern void init_devspd(dwc_otg_core_if_t * core_if,uint8_t speed);
+
+
+int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t * pcd)
+{
+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+ gintsts_data_t gintsts;
+ gusbcfg_data_t gusbcfg;
+ dwc_otg_core_global_regs_t *global_regs = GET_CORE_IF(pcd)->core_global_regs;
+ uint8_t utmi16b, utmi8b;
+ int speed;
+ printf("D\n");
+
+ utmi16b = 6; //vahrama old value was 6; data bookÉÏÊÇ5£¬add by lx 2012.10.13
+ utmi8b = 9;
+ dwc_otg_ep0_activate(GET_CORE_IF(pcd), &ep0->dwc_ep);
+ ep0_out_start(GET_CORE_IF(pcd), pcd);
+#if SYNC_USB_HSIC
+
+ REG32(REG_GPIO_OUT)=5;
+ while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+
+ REG32(REG_GPIO_OUT)=6;
+ while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+
+ REG32(REG_GPIO_OUT)=7;
+ while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+
+ REG32(REG_GPIO_OUT)=8;
+ while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+
+#endif
+ if (pcd->ep0state == EP0_DISCONNECT)
+ {
+ pcd->ep0state = EP0_IDLE;
+ }
+ else if (pcd->ep0state == EP0_STALL)
+ {
+ pcd->ep0state = EP0_IDLE;
+ }
+
+ ep0->stopped = 0;
+
+ speed = get_device_speed(GET_CORE_IF(pcd));
+ /* Set USB turnaround time based on device speed and PHY interface. */
+ gusbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+ if (speed == USB_SPEED_HIGH)
+ {
+
+ if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI)
+ {
+ /* UTMI+ OR ULPI interface */
+ if (gusbcfg.b.ulpi_utmi_sel == 1)
+ {
+ /* ULPI interface */
+ gusbcfg.b.usbtrdtim = 9;
+ }
+ else
+ {
+ /* UTMI+ interface */
+ if (GET_CORE_IF(pcd)->core_params->phy_utmi_width == 16)
+ {
+ gusbcfg.b.usbtrdtim = utmi16b;
+ }
+ else
+ {
+ gusbcfg.b.usbtrdtim = utmi8b;
+ }
+ }
+ }
+
+ printf("2\n");
+
+ }
+ else
+ {
+ printf("1\n");
+ pcd->out_ep[0].dwc_ep.maxpacket = 64;
+ pcd->in_ep[0].dwc_ep.maxpacket = 64;
+ pcd->out_ep[1].dwc_ep.maxpacket = 64;
+ pcd->in_ep[1].dwc_ep.maxpacket = 64;
+ init_devspd(pcd->core_if,1);
+ g_config_desc.atTxEP[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+ g_config_desc.atRxEP[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+ g_config_desc.atTxEP1[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+ g_config_desc.atRxEP1[0].wMaxPacketSize = USB_FULLSPEED_BULK_MAXSIZE;
+ /* Full or low speed */
+ gusbcfg.b.usbtrdtim = 9;
+ }
+ DWC_WRITE_REG32(&global_regs->gusbcfg, gusbcfg.d32);
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.enumdone = 1;
+ DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,gintsts.d32);
+ return 1;
+}
+
+
+
+/**
+ * This funcion stalls EP0.
+ */
+void ep0_do_stall(dwc_otg_pcd_t * pcd, const int err_val)
+{
+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+
+ ep0->dwc_ep.is_in = 1;
+ dwc_otg_ep_set_stall(GET_CORE_IF(pcd), &ep0->dwc_ep);
+ pcd->ep0.stopped = 1;
+ pcd->ep0state = EP0_IDLE;
+ ep0_out_start(GET_CORE_IF(pcd), pcd);
+}
+
+static void do_setup_in_out_status_phase(dwc_otg_pcd_t * pcd,s8 udir)
+{
+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+ if (pcd->ep0state == EP0_STALL)
+ {
+ return;
+ }
+
+ if(udir)
+ {
+ pcd->ep0state = EP0_IN_STATUS_PHASE;
+ }
+ else
+ {
+ pcd->ep0state = EP0_OUT_STATUS_PHASE;
+ }
+
+ /* Prepare for more SETUP Packets */
+ ep0->dwc_ep.xfer_len = 0;
+ ep0->dwc_ep.xfer_count = 0;
+ ep0->dwc_ep.is_in = udir;
+ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
+}
+
+
+/**
+ * Clear the EP halt (STALL) and if pending requests start the
+ * transfer.
+ */
+static void pcd_clear_halt(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep)
+{
+ if (ep->dwc_ep.stall_clear_flag == 0)
+ dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
+
+ /* Reactive the EP */
+ dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
+ if (ep->stopped)
+ {
+ ep->stopped = 0;
+ /* If there is a request in the EP queue start it */
+
+ /** @todo FIXME: this causes an EP mismatch in DMA mode.
+ * epmismatch not yet implemented. */
+
+ /*
+ * Above fixme is solved by implmenting a tasklet to call the
+ * start_next_request(), outside of interrupt context at some
+ * time after the current time, after a clear-halt setup packet.
+ * Still need to implement ep mismatch in the future if a gadget
+ * ever uses more than one endpoint at once
+ */
+ ep->queue_sof = 1;
+ }
+ /* Start Control Status Phase */
+ do_setup_in_out_status_phase(pcd,1);
+}
+
+/**
+ * This function process the GET_STATUS Setup Commands.
+ */
+static void do_get_status(dwc_otg_pcd_t * pcd)
+{
+ usb_device_request_t ctrl = pcd->setup_pkt->req;
+ dwc_otg_pcd_ep_t *ep;
+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+ uint16_t *status = pcd->status_buf;
+
+ switch (UT_GET_RECIPIENT(ctrl.bmRequestType))
+ {
+ case UT_INTERFACE:
+ *status = 0;
+ break;
+
+ case UT_ENDPOINT:
+ ep = get_ep_by_addr(pcd, ctrl.wIndex);
+ if (ep == 0 || ctrl.wLength > 2)
+ {
+ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
+ return;
+ }
+ /** @todo check for EP stall */
+ *status = ep->stopped;
+ break;
+ }
+ pcd->ep0_pending = 1;
+ ep0->dwc_ep.start_xfer_buff = (uint8_t *) status;
+ ep0->dwc_ep.xfer_buff = (uint8_t *) status;
+ ep0->dwc_ep.xfer_len = 2;
+ ep0->dwc_ep.xfer_count = 0;
+ ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
+ dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
+}
+
+
+static void do_clear_feature(dwc_otg_pcd_t * pcd)
+{
+ usb_device_request_t ctrl = pcd->setup_pkt->req;
+ dwc_otg_pcd_ep_t *ep = 0;
+ switch (UT_GET_RECIPIENT(ctrl.bmRequestType))
+ {
+ case UT_ENDPOINT:
+ ep = get_ep_by_addr(pcd, ctrl.wIndex);
+ if (ep == 0)
+ {
+ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
+ return;
+ }
+
+ pcd_clear_halt(pcd, ep);
+
+ break;
+
+ }
+}
+
+/**
+ * This function process the SET_ADDRESS Setup Commands.
+ */
+static void do_set_address(dwc_otg_pcd_t * pcd)
+{
+ dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
+ usb_device_request_t ctrl = pcd->setup_pkt->req;
+ dcfg_data_t dcfg;
+ dcfg.d32 = 0;
+
+ if (ctrl.bmRequestType == UT_DEVICE)
+ {
+
+ dcfg.b.devaddr = ctrl.wValue;
+ DWC_MODIFY_REG32(&dev_if->dev_global_regs->dcfg, 0, dcfg.d32);
+#if SYNC_USB_HSIC
+ REG32(REG_GPIO_OUT)=0xa;
+ while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+
+ REG32(REG_GPIO_OUT)=0xb;
+ while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+
+#endif
+ do_setup_in_out_status_phase(pcd,1);
+#if SYNC_USB_HSIC
+ if(pcd->setup_pkt->req.bRequest == 0x05)
+ {
+ REG32(REG_GPIO_OUT)=0x9;
+ while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(10);
+ REG32(REG_GPIO_OUT)=0;
+ }
+#endif
+ }
+}
+
+/**
+ * This function processes SETUP commands. In Linux, the USB Command
+ * processing is done in two places - the first being the PCD and the
+ * second in the Gadget Driver (for example, the File-Backed Storage
+ * Gadget Driver).
+ *
+ * <table>
+ * <tr><td>Command </td><td>Driver </td><td>Description</td></tr>
+ *
+ * <tr><td>GET_STATUS </td><td>PCD </td><td>Command is processed as
+ * defined in chapter 9 of the USB 2.0 Specification chapter 9
+ * </td></tr>
+ *
+ * <tr><td>CLEAR_FEATURE </td><td>PCD </td><td>The Device and Endpoint
+ * requests are the ENDPOINT_HALT feature is procesed, all others the
+ * interface requests are ignored.</td></tr>
+ *
+ * <tr><td>SET_FEATURE </td><td>PCD </td><td>The Device and Endpoint
+ * requests are processed by the PCD. Interface requests are passed
+ * to the Gadget Driver.</td></tr>
+ *
+ * <tr><td>SET_ADDRESS </td><td>PCD </td><td>Program the DCFG reg,
+ * with device address received </td></tr>
+ *
+ * <tr><td>GET_DESCRIPTOR </td><td>Gadget Driver </td><td>Return the
+ * requested descriptor</td></tr>
+ *
+ * <tr><td>SET_DESCRIPTOR </td><td>Gadget Driver </td><td>Optional -
+ * not implemented by any of the existing Gadget Drivers.</td></tr>
+ *
+ * <tr><td>SET_CONFIGURATION </td><td>Gadget Driver </td><td>Disable
+ * all EPs and enable EPs for new configuration.</td></tr>
+ *
+ * <tr><td>GET_CONFIGURATION </td><td>Gadget Driver </td><td>Return
+ * the current configuration</td></tr>
+ *
+ * <tr><td>SET_INTERFACE </td><td>Gadget Driver </td><td>Disable all
+ * EPs and enable EPs for new configuration.</td></tr>
+ *
+ * <tr><td>GET_INTERFACE </td><td>Gadget Driver </td><td>Return the
+ * current interface.</td></tr>
+ *
+ * <tr><td>SYNC_FRAME </td><td>PCD </td><td>Display debug
+ * message.</td></tr>
+ * </table>
+ *
+ * When the SETUP Phase Done interrupt occurs, the PCD SETUP commands are
+ * processed by pcd_setup. Calling the Function Driver's setup function from
+ * pcd_setup processes the gadget SETUP commands.
+ */
+void active_allep(dwc_otg_pcd_t * pcd)
+{
+ int i = 0;
+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ for (i = 0; i <dev_if->num_out_eps; i++)
+ {
+ dwc_otg_ep_activate(pcd->core_if,&pcd->out_ep[i].dwc_ep);
+ dwc_otg_ep_activate(pcd->core_if,&pcd->in_ep[i].dwc_ep);
+ }
+
+}
+
+extern int dwc_setup(dwc_otg_pcd_t * pcd, usb_device_request_t * ctrl);
+
+static void pcd_setup(dwc_otg_pcd_t * pcd)
+{
+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+ usb_device_request_t ctrl = pcd->setup_pkt->req;
+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+
+ ep0->stopped = 0;
+
+ if (ctrl.bmRequestType & UE_DIR_IN)
+ {
+ ep0->dwc_ep.is_in = 1;
+ pcd->ep0state = EP0_IN_DATA_PHASE;
+ }
+ else
+ {
+ ep0->dwc_ep.is_in = 0;
+ pcd->ep0state = EP0_OUT_DATA_PHASE;
+ }
+
+ if (ctrl.wLength == 0)
+ {
+ printf("ctrl.wLength == 0\n");
+ ep0->dwc_ep.is_in = 1;
+ pcd->ep0state = EP0_IN_STATUS_PHASE;
+ }
+ if((ctrl.bmRequestType&0x60) == 0x40)
+ {
+ printf("vender request\n");
+ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
+ return;
+ }
+
+ if( UR_GET_STATUS == ctrl.bRequest)
+ {
+ do_get_status(pcd);
+ }
+
+ else if( UR_CLEAR_FEATURE == ctrl.bRequest)
+ {
+ do_clear_feature(pcd);
+ }
+
+ else if( UR_SET_FEATURE ==ctrl.bRequest)
+ {}
+
+ else if( UR_SET_ADDRESS == ctrl.bRequest)
+ {
+ #if SYNC_SETADDRESS
+ pcd->request_config = 2;
+ active_allep(pcd);
+ #endif
+ do_set_address(pcd);
+ }
+
+ else if( UR_GET_DESCRIPTOR== ctrl.bRequest)
+ {
+ dwc_setup(pcd, &ctrl);
+ }
+
+ else if( UR_SET_CONFIG== ctrl.bRequest)
+ {
+ pcd->request_config = 1;
+ active_allep(pcd);
+ do_setup_in_out_status_phase(pcd,1);
+ ep0_out_start(core_if, pcd);
+ }
+ else
+ {
+ ep0_do_stall(pcd, -DWC_E_NOT_SUPPORTED);
+ }
+
+}
+
+/**
+ * This function completes the ep0 control transfer.
+ */
+static int32_t ep0_complete_request(dwc_otg_pcd_ep_t * ep)
+{
+ dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ dwc_otg_dev_in_ep_regs_t *in_ep_regs =
+ dev_if->in_ep_regs[ep->dwc_ep.num];
+
+ deptsiz0_data_t deptsiz;
+ int is_last = 0;
+ dwc_otg_pcd_t *pcd = ep->pcd;
+
+ if (pcd->ep0_pending)
+ {
+ if (ep->dwc_ep.is_in)
+ {
+
+ do_setup_in_out_status_phase(pcd,0);
+ }
+ else
+ {
+ do_setup_in_out_status_phase(pcd,1);
+ }
+ pcd->ep0_pending = 0;
+ return 1;
+ }
+
+ if (pcd->ep0state == EP0_OUT_STATUS_PHASE
+ || pcd->ep0state == EP0_IN_STATUS_PHASE)
+ {
+ is_last = 1;
+ }
+ else if (ep->dwc_ep.is_in)
+ {
+ deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz);
+
+ if (deptsiz.b.xfersize == 0)
+ {
+ do_setup_in_out_status_phase(pcd,0);
+ }
+ }
+ else
+ {
+
+ ep0_out_start(core_if, pcd);
+
+ }
+
+ /* Complete the request */
+ if (is_last)
+ {
+ ep->dwc_ep.start_xfer_buff = 0;
+ ep->dwc_ep.xfer_buff = 0;
+ ep->dwc_ep.xfer_len = 0;
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * This function completes the request for the EP. If there are
+ * additional requests for the EP in the queue they will be started.
+ */
+static void complete_ep(dwc_otg_pcd_ep_t * ep)
+{
+ dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ dwc_otg_dev_in_ep_regs_t *in_ep_regs = dev_if->in_ep_regs[ep->dwc_ep.num];
+ deptsiz_data_t deptsiz;
+
+ if (ep->dwc_ep.is_in)
+ {
+ deptsiz.d32 = DWC_READ_REG32(&in_ep_regs->dieptsiz);
+ {
+ if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0)
+ {
+ /* Check if the whole transfer was completed,
+ * if no, setup transfer for next portion of data
+ */
+ if (ep->dwc_ep.xfer_len < ep->dwc_ep.total_len)
+ {
+ dwc_otg_ep_start_transfer(core_if,&ep->dwc_ep);
+ }
+ else if (ep->dwc_ep.sent_zlp)
+ {
+ /*
+ * This fragment of code should initiate 0
+ * length trasfer in case if it is queued
+ * a trasfer with size divisible to EPs max
+ * packet size and with usb_request zero field
+ * is set, which means that after data is transfered,
+ * it is also should be transfered
+ * a 0 length packet at the end. For Slave and
+ * Buffer DMA modes in this case SW has
+ * to initiate 2 transfers one with transfer size,
+ * and the second with 0 size. For Desriptor
+ * DMA mode SW is able to initiate a transfer,
+ * which will handle all the packets including
+ * the last 0 legth.
+ */
+ ep->dwc_ep.sent_zlp = 0;
+ dwc_otg_ep_start_zl_transfer(core_if,
+ &ep->dwc_ep);
+ }
+ else
+ {
+
+ if (ep->dwc_ep.fnUsbCb)
+ ep->dwc_ep.fnUsbCb( (WORD32)(ep->dwc_ep.pPara), 0, ep->dwc_ep.xfer_count, ep->dwc_ep.total_len);
+
+ }
+ }
+ }
+ }
+ // OUT EP
+ else
+ {
+
+ dwc_otg_dev_out_ep_regs_t *out_ep_regs = dev_if->out_ep_regs[ep->dwc_ep.num];
+ {
+ deptsiz.d32 = 0;
+ deptsiz.d32 = DWC_READ_REG32(&out_ep_regs->doeptsiz);
+ if (deptsiz.b.xfersize>0)
+ {
+
+ if (ep->dwc_ep.fnUsbCb)
+ ep->dwc_ep.fnUsbCb( (WORD32)(ep->dwc_ep.pPara), 0, ep->dwc_ep.xfer_count, ep->dwc_ep.total_len);
+
+ }
+ else
+ {
+ dwc_otg_ep_start_transfer(core_if,&ep->dwc_ep);
+ }
+ }
+
+
+ }
+
+}
+
+/**
+ * This function handles EP0 Control transfers.
+ *
+ * The state of the control transfers are tracked in
+ * <code>ep0state</code>.
+ */
+static void handle_ep0(dwc_otg_pcd_t * pcd)
+{
+ dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
+
+ if(EP0_DISCONNECT == pcd->ep0state )
+ {
+ return;
+ }
+ else if(EP0_IDLE == pcd->ep0state )
+ {
+ pcd->request_config = 0;
+
+ pcd_setup(pcd);
+ #if SYNC_USB_CTRL
+ REG32(ARM_PORTA)=0x55;
+ #endif
+ }
+ else if(EP0_IN_DATA_PHASE == pcd->ep0state)
+ {
+ if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len)
+ {
+ dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),&ep0->dwc_ep);
+ }
+ else if (ep0->dwc_ep.sent_zlp)
+ {
+ dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),&ep0->dwc_ep);
+ ep0->dwc_ep.sent_zlp = 0;
+ }
+ else
+ {
+ ep0_complete_request(ep0);
+ }
+ }
+ else if( EP0_OUT_DATA_PHASE == pcd->ep0state)
+ {
+ if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len)
+ {
+ dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd),
+ &ep0->dwc_ep);
+ }
+ else if (ep0->dwc_ep.sent_zlp)
+ {
+ dwc_otg_ep0_continue_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
+ ep0->dwc_ep.sent_zlp = 0;
+ }
+ else
+ {
+ ep0_complete_request(ep0);
+ }
+ }
+ else if(EP0_IN_STATUS_PHASE == pcd->ep0state ||EP0_OUT_STATUS_PHASE == pcd->ep0state )
+ {
+ ep0_complete_request(ep0);
+ pcd->ep0state = EP0_IDLE;
+ ep0->stopped = 1;
+ ep0->dwc_ep.is_in = 0; /* OUT for next SETUP */
+ }
+ else if(EP0_STALL == pcd->ep0state )
+ {
+
+ }
+ else
+ {}
+
+
+
+}
+
+/**
+ * Handler for the IN EP NAK interrupt.
+ */
+
+/**
+ * Handler for the OUT EP NAK interrupt.
+ */
+static int32_t handle_out_ep_nak_intr(dwc_otg_pcd_t * pcd,
+ const uint32_t epnum)
+{
+ /** @todo implement ISR */
+ dwc_otg_core_if_t *core_if;
+ doepmsk_data_t intr_mask;
+ intr_mask.d32 = 0;
+
+ core_if = GET_CORE_IF(pcd);
+ intr_mask.b.nak = 1;
+ {
+ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk,intr_mask.d32, 0);
+ }
+
+ return 1;
+}
+
+/**
+ * Handler for the OUT EP NYET interrupt.
+ */
+static int32_t handle_out_ep_nyet_intr(dwc_otg_pcd_t * pcd,
+ const uint32_t epnum)
+{
+ /** @todo implement ISR */
+ dwc_otg_core_if_t *core_if;
+ doepmsk_data_t intr_mask;
+ intr_mask.d32 = 0 ;
+
+ core_if = GET_CORE_IF(pcd);
+ intr_mask.b.nyet = 1;
+ {
+ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->doepmsk, intr_mask.d32, 0);
+ }
+
+ return 1;
+}
+
+/**
+ * This interrupt indicates that an IN EP has a pending Interrupt.
+ * The sequence for handling the IN EP interrupt is shown below:
+ * -# Read the Device All Endpoint Interrupt register
+ * -# Repeat the following for each IN EP interrupt bit set (from
+ * LSB to MSB).
+ * -# Read the Device Endpoint Interrupt (DIEPINTn) register
+ * -# If "Transfer Complete" call the request complete function
+ * -# If "Endpoint Disabled" complete the EP disable procedure.
+ * -# If "AHB Error Interrupt" log error
+ * -# If "Time-out Handshake" log error
+ * -# If "IN Token Received when TxFIFO Empty" write packet to Tx
+ * FIFO.
+ * -# If "IN Token EP Mismatch" (disable, this is handled by EP
+ * Mismatch Interrupt)
+ */
+static int32_t dwc_otg_pcd_handle_in_ep_intr(dwc_otg_pcd_t * pcd)
+{
+
+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+ dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+ diepint_data_t diepint;
+ depctl_data_t depctl;
+ uint32_t ep_intr;
+ uint32_t epnum = 0;
+ dwc_otg_pcd_ep_t *ep;
+ dwc_ep_t *dwc_ep;
+ diepmsk_data_t diepmsk;
+ uint32_t fifoemptymsk;
+ diepint.d32 = 0;
+ depctl.d32 = 0;
+ diepmsk.d32 = 0;
+
+ ep_intr = dwc_otg_read_dev_all_in_ep_intr(core_if);
+ /* Service the Device IN interrupts for each endpoint */
+ while ((ep_intr)&&(epnum<MAX_EPS_CHANNELS))
+ {
+ if (ep_intr & 0x1)
+ {
+
+ /* Get EP pointer */
+ ep = get_in_ep(pcd, epnum);
+ dwc_ep = &ep->dwc_ep;
+ depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->diepctl);
+ diepint.d32 = dwc_otg_read_dev_in_ep_intr(core_if, dwc_ep);
+ /* Transfer complete */
+ if (diepint.b.xfercompl)
+ {
+ {
+ /* Disable the Tx FIFO Empty Interrupt for this EP */
+ fifoemptymsk = 0x1 << dwc_ep->num;
+ DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,fifoemptymsk, 0);
+ }
+ /* Clear the bit in DIEPINTn for this interrupt */
+ CLEAR_IN_EP_INTR(core_if, epnum, xfercompl);
+
+ /* Complete the transfer */
+ if (epnum == 0)
+ {
+ handle_ep0(pcd);
+
+ }
+ else
+ {
+
+ complete_ep(ep);
+ if (diepint.b.nak)
+ CLEAR_IN_EP_INTR(core_if, epnum, nak);
+ }
+ }
+ /* Endpoint disable */
+ if (diepint.b.epdisabled)
+ {
+
+ CLEAR_IN_EP_INTR(core_if, epnum, epdisabled);
+ }
+
+ /* TimeOUT Handshake (non-ISOC IN EPs) */
+ if (diepint.b.timeout)
+ {
+ CLEAR_IN_EP_INTR(core_if, epnum, timeout);
+ }
+ /** IN Token received with TxF Empty */
+ if (diepint.b.intktxfemp)
+ {
+ if (!ep->stopped && epnum != 0)
+ {
+ diepmsk.b.intktxfemp = 1;
+ {
+ DWC_MODIFY_REG32
+ (&dev_if->dev_global_regs->diepmsk,
+ diepmsk.d32, 0);
+ }
+ }
+ CLEAR_IN_EP_INTR(core_if, epnum, intktxfemp);
+ }
+
+ /** IN Endpoint NAK Effective */
+ if (diepint.b.inepnakeff)
+ {
+ /* Periodic EP */
+ if (ep->disabling)
+ {
+ depctl.d32 = 0;
+ depctl.b.snak = 1;
+ depctl.b.epdis = 1;
+ DWC_MODIFY_REG32(&dev_if->in_ep_regs
+ [epnum]->diepctl,
+ depctl.d32,
+ depctl.d32);
+ }
+ CLEAR_IN_EP_INTR(core_if, epnum, inepnakeff);
+
+ }
+
+ /** IN EP Tx FIFO Empty Intr */
+ if (diepint.b.emptyintr)
+ {
+ printf("diepint.b.emptyintr\n");
+ write_empty_tx_fifo(pcd, epnum);
+
+ CLEAR_IN_EP_INTR(core_if, epnum, emptyintr);
+
+ }
+ /* NAK Interrutp */
+ if (diepint.b.nak)
+ {
+ CLEAR_IN_EP_INTR(core_if, epnum, nak);
+ }
+ }
+ epnum++;
+ ep_intr >>= 1;
+ }
+
+ return 1;
+#undef CLEAR_IN_EP_INTR
+}
+
+/**
+ * This interrupt indicates that an OUT EP has a pending Interrupt.
+ * The sequence for handling the OUT EP interrupt is shown below:
+ * -# Read the Device All Endpoint Interrupt register
+ * -# Repeat the following for each OUT EP interrupt bit set (from
+ * LSB to MSB).
+ * -# Read the Device Endpoint Interrupt (DOEPINTn) register
+ * -# If "Transfer Complete" call the request complete function
+ * -# If "Endpoint Disabled" complete the EP disable procedure.
+ * -# If "AHB Error Interrupt" log error
+ * -# If "Setup Phase Done" process Setup Packet (See Standard USB
+ * Command Processing)
+ */
+static int32_t dwc_otg_pcd_handle_out_ep_intr(dwc_otg_pcd_t * pcd)
+{
+
+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+ uint32_t ep_intr;
+ doepint_data_t doepint;
+ doepint_data_t doepint1;
+ uint32_t epnum = 0;
+ dwc_otg_pcd_ep_t *ep;
+ dwc_ep_t *dwc_ep;
+
+ doepint.d32 = 0;
+ doepint1.d32 = 0;
+
+ printf("dwc_otg_pcd_handle_out_ep_int\nr");
+ ep_intr = dwc_otg_read_dev_all_out_ep_intr(core_if);
+ while ((ep_intr)&&(epnum<MAX_EPS_CHANNELS))
+ {
+ if (ep_intr & 0x1)
+ {
+ /* Get EP pointer */
+ ep = get_out_ep(pcd, epnum);
+ dwc_ep = &ep->dwc_ep;
+ doepint.d32 = dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep);
+ /* Transfer complete */
+ if (doepint.b.xfercompl)
+ {
+ if (epnum == 0)
+ {
+ /* Clear the bit in DOEPINTn for this interrupt */
+ CLEAR_OUT_EP_INTR(core_if, epnum, xfercompl);
+ doepint1.d32 = DWC_READ_REG32(&core_if->dev_if->out_ep_regs[0]->doepint);
+ if (pcd->ep0state == EP0_IDLE && doepint1.b.sr)
+ {
+ CLEAR_OUT_EP_INTR(core_if, epnum, sr);
+ }
+ else if(pcd->ep0state != EP0_IDLE)
+ {
+ handle_ep0(pcd);
+ }
+ }
+ else
+ {
+ /* Clear the bit in DOEPINTn for this interrupt */
+ CLEAR_OUT_EP_INTR(core_if, epnum,xfercompl);
+ complete_ep(ep);
+ }
+
+ }
+
+ /* Endpoint disable */
+ if (doepint.b.epdisabled)
+ {
+ /* Clear the bit in DOEPINTn for this interrupt */
+ CLEAR_OUT_EP_INTR(core_if, epnum, epdisabled);
+ }
+ if (doepint.b.setup)
+ {
+ CLEAR_OUT_EP_INTR(core_if, epnum, setup);
+
+ handle_ep0(pcd);
+
+ }
+ if (doepint.b.outtknepdis)
+ {
+ CLEAR_OUT_EP_INTR(core_if, epnum, outtknepdis);
+ }
+
+ /* NAK Interrutp */
+ if (doepint.b.nak)
+ {
+ handle_out_ep_nak_intr(pcd, epnum);
+
+ CLEAR_OUT_EP_INTR(core_if, epnum, nak);
+ }
+
+ /* NYET Interrutp */
+ if (doepint.b.nyet)
+ {
+ handle_out_ep_nyet_intr(pcd, epnum);
+
+ CLEAR_OUT_EP_INTR(core_if, epnum, nyet);
+ }
+ }
+
+ epnum++;
+ ep_intr >>= 1;
+ }
+
+ return 1;
+
+#undef CLEAR_OUT_EP_INTR
+}
+
+/**
+ * PCD interrupt handler.
+ *
+ * The PCD handles the device interrupts. Many conditions can cause a
+ * device interrupt. When an interrupt occurs, the device interrupt
+ * service routine determines the cause of the interrupt and
+ * dispatches handling to the appropriate function. These interrupt
+ * handling functions are described below.
+ *
+ * All interrupt registers are processed from LSB to MSB.
+ *
+ */
+
+extern int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t * core_if);
+
+int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t * pcd)
+{
+ dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
+
+ gintsts_data_t gintr_status;
+ int32_t retval = 0;
+ gintr_status.d32 = dwc_otg_read_core_intr(core_if);
+
+ if (gintr_status.b.rxstsqlvl)
+ {
+ retval |=
+ dwc_otg_pcd_handle_rx_status_q_level_intr(pcd);
+ }
+ //½«Á½¸öÖжϺϳÉÒ»¸ö
+ if (gintr_status.b.usbsuspend)
+ {
+ retval |= dwc_otg_handle_usb_suspend_intr(pcd->core_if);
+ }
+ if (gintr_status.b.usbreset)
+ {
+ retval |= dwc_otg_pcd_handle_usb_reset_intr(pcd);
+ global.g_Connet =1;
+ }
+ if (gintr_status.b.enumdone)
+ {
+ retval |= dwc_otg_pcd_handle_enum_done_intr(pcd);
+#if SYNC_USB_CTRL
+ REG32(ARM_PORTA)=0x33;
+ usdelay(1);
+ REG32(ARM_PORTA)=0x66;
+#endif
+ }
+ if (gintr_status.b.inepint)
+ {
+ if (!core_if->multiproc_int_enable)
+ {
+ retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
+ }
+ }
+ if (gintr_status.b.outepintr)
+ {
+ if (!core_if->multiproc_int_enable)
+ {
+ retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
+ }
+ }
+ return retval;
+}
+
+#endif /* DWC_HOST_ONLY */
diff --git a/boot/common/src/loader/drivers/dwc_otg_regs.h b/boot/common/src/loader/drivers/dwc_otg_regs.h
new file mode 100644
index 0000000..5f1c0e5
--- /dev/null
+++ b/boot/common/src/loader/drivers/dwc_otg_regs.h
@@ -0,0 +1,1593 @@
+/* ==========================================================================
+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_regs.h $
+ * $Revision: #98 $
+ * $Date: 2012/08/10 $
+ * $Change: 2047372 $
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+#ifndef __DWC_OTG_REGS_H__
+#define __DWC_OTG_REGS_H__
+#include "dwc_otg_core_if.h"
+
+/**
+ * @file
+ *
+ * This file contains the data structures for accessing the DWC_otg core registers.
+ *
+ * The application interfaces with the HS OTG core by reading from and
+ * writing to the Control and Status Register (CSR) space through the
+ * AHB Slave interface. These registers are 32 bits wide, and the
+ * addresses are 32-bit-block aligned.
+ * CSRs are classified as follows:
+ * - Core Global Registers
+ * - Device Mode Registers
+ * - Device Global Registers
+ * - Device Endpoint Specific Registers
+ * - Host Mode Registers
+ * - Host Global Registers
+ * - Host Port CSRs
+ * - Host Channel Specific Registers
+ *
+ * Only the Core Global registers can be accessed in both Device and
+ * Host modes. When the HS OTG core is operating in one mode, either
+ * Device or Host, the application must not access registers from the
+ * other mode. When the core switches from one mode to another, the
+ * registers in the new mode of operation must be reprogrammed as they
+ * would be after a power-on reset.
+ */
+
+/****************************************************************************/
+/** DWC_otg Core registers .
+ * The dwc_otg_core_global_regs structure defines the size
+ * and relative field offsets for the Core Global registers.
+ */
+typedef struct dwc_otg_core_global_regs
+{
+ /** OTG Control and Status Register. <i>Offset: 000h</i> */
+ volatile uint32_t gotgctl;
+ /** OTG Interrupt Register. <i>Offset: 004h</i> */
+ volatile uint32_t gotgint;
+ /**Core AHB Configuration Register. <i>Offset: 008h</i> */
+ volatile uint32_t gahbcfg;
+ /**Core USB Configuration Register. <i>Offset: 00Ch</i> */
+ volatile uint32_t gusbcfg;
+ /**Core Reset Register. <i>Offset: 010h</i> */
+ volatile uint32_t grstctl;
+ /**Core Interrupt Register. <i>Offset: 014h</i> */
+ volatile uint32_t gintsts;
+ /**Core Interrupt Mask Register. <i>Offset: 018h</i> */
+ volatile uint32_t gintmsk;
+ /**Receive Status Queue Read Register (Read Only). <i>Offset: 01Ch</i> */
+ volatile uint32_t grxstsr;
+ /**Receive Status Queue Read & POP Register (Read Only). <i>Offset: 020h</i>*/
+ volatile uint32_t grxstsp;
+ /**Receive FIFO Size Register. <i>Offset: 024h</i> */
+ volatile uint32_t grxfsiz;
+ /**Non Periodic Transmit FIFO Size Register. <i>Offset: 028h</i> */
+ volatile uint32_t gnptxfsiz;
+ /**Non Periodic Transmit FIFO/Queue Status Register (Read
+ * Only). <i>Offset: 02Ch</i> */
+ volatile uint32_t gnptxsts;
+ /**I2C Access Register. <i>Offset: 030h</i> */
+ volatile uint32_t gi2cctl;
+ /**PHY Vendor Control Register. <i>Offset: 034h</i> */
+ volatile uint32_t gpvndctl;
+ /**General Purpose Input/Output Register. <i>Offset: 038h</i> */
+ volatile uint32_t ggpio;
+ /**User ID Register. <i>Offset: 03Ch</i> */
+ volatile uint32_t guid;
+ /**Synopsys ID Register (Read Only). <i>Offset: 040h</i> */
+ volatile uint32_t gsnpsid;
+ /**User HW Config1 Register (Read Only). <i>Offset: 044h</i> */
+ volatile uint32_t ghwcfg1;
+ /**User HW Config2 Register (Read Only). <i>Offset: 048h</i> */
+ volatile uint32_t ghwcfg2;
+ /**User HW Config3 Register (Read Only). <i>Offset: 04Ch</i> */
+ volatile uint32_t ghwcfg3;
+ /**User HW Config4 Register (Read Only). <i>Offset: 050h</i>*/
+ volatile uint32_t ghwcfg4;
+ /** Core LPM Configuration register <i>Offset: 054h</i>*/
+ volatile uint32_t glpmcfg;
+ /** Global PowerDn Register <i>Offset: 058h</i> */
+ volatile uint32_t gpwrdn;
+ /** Global DFIFO SW Config Register <i>Offset: 05Ch</i> */
+ volatile uint32_t gdfifocfg;
+ /** ADP Control Register <i>Offset: 060h</i> */
+ volatile uint32_t adpctl;
+} dwc_otg_core_global_regs_t;
+
+/**
+ * This union represents the bit fields of the Core OTG Control
+ * and Status Register (GOTGCTL). Set the bits using the bit
+ * fields then write the <i>d32</i> value to the register.
+ */
+typedef union gotgctl_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ unsigned sesreqscs:1;
+ unsigned sesreq:1;
+ unsigned vbvalidoven:1;
+ unsigned vbvalidovval:1;
+ unsigned avalidoven:1;
+ unsigned avalidovval:1;
+ unsigned bvalidoven:1;
+ unsigned bvalidovval:1;
+ unsigned hstnegscs:1;
+ unsigned hnpreq:1;
+ unsigned hstsethnpen:1;
+ unsigned devhnpen:1;
+ unsigned reserved12_15:4;
+ unsigned conidsts:1;
+ unsigned dbnctime:1;
+ unsigned asesvld:1;
+ unsigned bsesvld:1;
+ unsigned otgver:1;
+ unsigned reserved1:1;
+ unsigned multvalidbc:5;
+ unsigned chirpen:1;
+ unsigned reserved28_31:4;
+ } b;
+} gotgctl_data_t;
+/**
+ * This union represents the bit fields of the Core AHB Configuration
+ * Register (GAHBCFG). Set/clear the bits using the bit fields then
+ * write the <i>d32</i> value to the register.
+ */
+#define DWC_GAHBCFG_TXFEMPTYLVL_EMPTY 1
+#define DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
+typedef union gahbcfg_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ unsigned glblintrmsk:1;
+ unsigned hburstlen:4;
+ unsigned dmaenable:1;
+ unsigned reserved:1;
+ unsigned nptxfemplvl_txfemplvl:1;
+ unsigned ptxfemplvl:1;
+ unsigned reserved9_20:12;
+ unsigned remmemsupp:1;
+ unsigned notialldmawrit:1;
+ unsigned ahbsingle:1;
+ unsigned reserved24_31:8;
+ } b;
+} gahbcfg_data_t;
+
+/**
+ * This union represents the bit fields of the Core USB Configuration
+ * Register (GUSBCFG). Set the bits using the bit fields then write
+ * the <i>d32</i> value to the register.
+ */
+typedef union gusbcfg_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ unsigned toutcal:3;
+ unsigned phyif:1;
+ unsigned ulpi_utmi_sel:1;
+ unsigned fsintf:1;
+ unsigned physel:1;
+ unsigned ddrsel:1;
+ unsigned srpcap:1;
+ unsigned hnpcap:1;
+ unsigned usbtrdtim:4;
+ unsigned reserved1:1;
+ unsigned phylpwrclksel:1;
+ unsigned otgutmifssel:1;
+ unsigned ulpi_fsls:1;
+ unsigned ulpi_auto_res:1;
+ unsigned ulpi_clk_sus_m:1;
+ unsigned ulpi_ext_vbus_drv:1;
+ unsigned ulpi_int_vbus_indicator:1;
+ unsigned term_sel_dl_pulse:1;
+ unsigned indicator_complement:1;
+ unsigned indicator_pass_through:1;
+ unsigned ulpi_int_prot_dis:1;
+ unsigned ic_usb_cap:1;
+ unsigned ic_traffic_pull_remove:1;
+ unsigned tx_end_delay:1;
+ unsigned force_host_mode:1;
+ unsigned force_dev_mode:1;
+ unsigned reserved31:1;
+ } b;
+} gusbcfg_data_t;
+
+/**
+ * This union represents the bit fields of the Core Reset Register
+ * (GRSTCTL). Set/clear the bits using the bit fields then write the
+ * <i>d32</i> value to the register.
+ */
+typedef union grstctl_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** Core Soft Reset (CSftRst) (Device and Host)
+ *
+ * The application can flush the control logic in the
+ * entire core using this bit. This bit resets the
+ * pipelines in the AHB Clock domain as well as the
+ * PHY Clock domain.
+ *
+ * The state machines are reset to an IDLE state, the
+ * control bits in the CSRs are cleared, all the
+ * transmit FIFOs and the receive FIFO are flushed.
+ *
+ * The status mask bits that control the generation of
+ * the interrupt, are cleared, to clear the
+ * interrupt. The interrupt status bits are not
+ * cleared, so the application can get the status of
+ * any events that occurred in the core after it has
+ * set this bit.
+ *
+ * Any transactions on the AHB are terminated as soon
+ * as possible following the protocol. Any
+ * transactions on the USB are terminated immediately.
+ *
+ * The configuration settings in the CSRs are
+ * unchanged, so the software doesn't have to
+ * reprogram these registers (Device
+ * Configuration/Host Configuration/Core System
+ * Configuration/Core PHY Configuration).
+ *
+ * The application can write to this bit, any time it
+ * wants to reset the core. This is a self clearing
+ * bit and the core clears this bit after all the
+ * necessary logic is reset in the core, which may
+ * take several clocks, depending on the current state
+ * of the core.
+ */
+ unsigned csftrst:1;
+ /** Hclk Soft Reset
+ *
+ * The application uses this bit to reset the control logic in
+ * the AHB clock domain. Only AHB clock domain pipelines are
+ * reset.
+ */
+ unsigned hsftrst:1;
+ /** Host Frame Counter Reset (Host Only)<br>
+ *
+ * The application can reset the (micro)frame number
+ * counter inside the core, using this bit. When the
+ * (micro)frame counter is reset, the subsequent SOF
+ * sent out by the core, will have a (micro)frame
+ * number of 0.
+ */
+ unsigned hstfrm:1;
+ /** In Token Sequence Learning Queue Flush
+ * (INTknQFlsh) (Device Only)
+ */
+ unsigned intknqflsh:1;
+ /** RxFIFO Flush (RxFFlsh) (Device and Host)
+ *
+ * The application can flush the entire Receive FIFO
+ * using this bit. The application must first
+ * ensure that the core is not in the middle of a
+ * transaction. The application should write into
+ * this bit, only after making sure that neither the
+ * DMA engine is reading from the RxFIFO nor the MAC
+ * is writing the data in to the FIFO. The
+ * application should wait until the bit is cleared
+ * before performing any other operations. This bit
+ * will takes 8 clocks (slowest of PHY or AHB clock)
+ * to clear.
+ */
+ unsigned rxfflsh:1;
+ /** TxFIFO Flush (TxFFlsh) (Device and Host).
+ *
+ * This bit is used to selectively flush a single or
+ * all transmit FIFOs. The application must first
+ * ensure that the core is not in the middle of a
+ * transaction. The application should write into
+ * this bit, only after making sure that neither the
+ * DMA engine is writing into the TxFIFO nor the MAC
+ * is reading the data out of the FIFO. The
+ * application should wait until the core clears this
+ * bit, before performing any operations. This bit
+ * will takes 8 clocks (slowest of PHY or AHB clock)
+ * to clear.
+ */
+ unsigned txfflsh:1;
+
+ /** TxFIFO Number (TxFNum) (Device and Host).
+ *
+ * This is the FIFO number which needs to be flushed,
+ * using the TxFIFO Flush bit. This field should not
+ * be changed until the TxFIFO Flush bit is cleared by
+ * the core.
+ * - 0x0 : Non Periodic TxFIFO Flush
+ * - 0x1 : Periodic TxFIFO #1 Flush in device mode
+ * or Periodic TxFIFO in host mode
+ * - 0x2 : Periodic TxFIFO #2 Flush in device mode.
+ * - ...
+ * - 0xF : Periodic TxFIFO #15 Flush in device mode
+ * - 0x10: Flush all the Transmit NonPeriodic and
+ * Transmit Periodic FIFOs in the core
+ */
+ unsigned txfnum:5;
+ /** Reserved */
+ unsigned reserved11_29:19;
+ /** DMA Request Signal. Indicated DMA request is in
+ * probress. Used for debug purpose. */
+ unsigned dmareq:1;
+ /** AHB Master Idle. Indicates the AHB Master State
+ * Machine is in IDLE condition. */
+ unsigned ahbidle:1;
+ } b;
+} grstctl_t;
+
+/**
+ * This union represents the bit fields of the Core Interrupt Mask
+ * Register (GINTMSK). Set/clear the bits using the bit fields then
+ * write the <i>d32</i> value to the register.
+ */
+typedef union gintmsk_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ unsigned reserved0:1;
+ unsigned modemismatch:1;
+ unsigned otgintr:1;
+ unsigned sofintr:1;
+ unsigned rxstsqlvl:1;
+ unsigned nptxfempty:1;
+ unsigned ginnakeff:1;
+ unsigned goutnakeff:1;
+ unsigned ulpickint:1;
+ unsigned i2cintr:1;
+ unsigned erlysuspend:1;
+ unsigned usbsuspend:1;
+ unsigned usbreset:1;
+ unsigned enumdone:1;
+ unsigned isooutdrop:1;
+ unsigned eopframe:1;
+ unsigned restoredone:1;
+ unsigned epmismatch:1;
+ unsigned inepintr:1;
+ unsigned outepintr:1;
+ unsigned incomplisoin:1;
+ unsigned incomplisoout:1;
+ unsigned fetsusp:1;
+ unsigned resetdet:1;
+ unsigned portintr:1;
+ unsigned hcintr:1;
+ unsigned ptxfempty:1;
+ unsigned lpmtranrcvd:1;
+ unsigned conidstschng:1;
+ unsigned disconnect:1;
+ unsigned sessreqintr:1;
+ unsigned wkupintr:1;
+ } b;
+} gintmsk_data_t;
+/**
+ * This union represents the bit fields of the Core Interrupt Register
+ * (GINTSTS). Set/clear the bits using the bit fields then write the
+ * <i>d32</i> value to the register.
+ */
+#define DWC_SOF_INTR_MASK 0x0008
+#define DWC_HOST_MODE 1
+
+typedef union gintsts_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ unsigned curmode:1;
+ unsigned modemismatch:1;
+ unsigned otgintr:1;
+ unsigned sofintr:1;
+ unsigned rxstsqlvl:1;
+ unsigned nptxfempty:1;
+ unsigned ginnakeff:1;
+ unsigned goutnakeff:1;
+ unsigned ulpickint:1;
+ unsigned i2cintr:1;
+ unsigned erlysuspend:1;
+ unsigned usbsuspend:1;
+ unsigned usbreset:1;
+ unsigned enumdone:1;
+ unsigned isooutdrop:1;
+ unsigned eopframe:1;
+ unsigned restoredone:1;
+ unsigned epmismatch:1;
+ unsigned inepint:1;
+ unsigned outepintr:1;
+ unsigned incomplisoin:1;
+ unsigned incomplisoout:1;
+ unsigned fetsusp:1;
+ unsigned resetdet:1;
+ unsigned portintr:1;
+ unsigned hcintr:1;
+ unsigned ptxfempty:1;
+ unsigned lpmtranrcvd:1;
+ unsigned conidstschng:1;
+ unsigned disconnect:1;
+ unsigned sessreqintr:1;
+ unsigned wkupintr:1;
+ } b;
+} gintsts_data_t;
+
+/**
+ * This union represents the bit fields in the Device Receive Status Read and
+ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the <i>d32</i>
+ * element then read out the bits using the <i>b</i>it elements.
+ */
+
+#define DWC_STS_DATA_UPDT 0x2 // OUT Data Packet
+#define DWC_STS_XFER_COMP 0x3 // OUT Data Transfer Complete
+#define DWC_DSTS_GOUT_NAK 0x1 // Global OUT NAK
+#define DWC_DSTS_SETUP_COMP 0x4 // Setup Phase Complete
+#define DWC_DSTS_SETUP_UPDT 0x6 // SETUP Packet
+
+typedef union device_grxsts_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ unsigned epnum:4;
+ unsigned bcnt:11;
+ unsigned dpid:2;
+ unsigned pktsts:4;
+ unsigned fn:4;
+ unsigned reserved25_31:7;
+ } b;
+} device_grxsts_data_t;
+/**
+ * This union represents the bit fields in the FIFO Size Registers (HPTXFSIZ,
+ * GNPTXFSIZ, DPTXFSIZn, DIEPTXFn). Read the register into the <i>d32</i> element
+ * then read out the bits using the <i>b</i>it elements.
+ */
+typedef union fifosize_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ unsigned startaddr:16;
+ unsigned depth:16;
+ } b;
+} fifosize_data_t;
+
+/**
+ * This union represents the bit fields in the Non-Periodic Transmit
+ * FIFO/Queue Status Register (GNPTXSTS). Read the register into the
+ * <i>d32</i> element then read out the bits using the <i>b</i>it
+ * elements.
+ */
+typedef union gnptxsts_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ unsigned nptxfspcavail:16;
+ unsigned nptxqspcavail:8;
+ /** Top of the Non-Periodic Transmit Request Queue
+ * - bit 24 - Terminate (Last entry for the selected
+ * channel/EP)
+ * - bits 26:25 - Token Type
+ * - 2'b00 - IN/OUT
+ * - 2'b01 - Zero Length OUT
+ * - 2'b10 - PING/Complete Split
+ * - 2'b11 - Channel Halt
+ * - bits 30:27 - Channel/EP Number
+ */
+ unsigned nptxqtop_terminate:1;
+ unsigned nptxqtop_token:2;
+ unsigned nptxqtop_chnep:4;
+ unsigned reserved:1;
+ } b;
+} gnptxsts_data_t;
+
+/**
+ * This union represents the bit fields in the Transmit
+ * FIFO Status Register (DTXFSTS). Read the register into the
+ * <i>d32</i> element then read out the bits using the <i>b</i>it
+ * elements.
+ */
+typedef union dtxfsts_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ unsigned txfspcavail:16;
+ unsigned reserved:16;
+ } b;
+} dtxfsts_data_t;
+/**
+ * This union represents the bit fields in the User HW Config1
+ * Register. Read the register into the <i>d32</i> element then read
+ * out the bits using the <i>b</i>it elements.
+ */
+typedef union hwcfg1_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ unsigned ep_dir0:2;
+ unsigned ep_dir1:2;
+ unsigned ep_dir2:2;
+ unsigned ep_dir3:2;
+ unsigned ep_dir4:2;
+ unsigned ep_dir5:2;
+ unsigned ep_dir6:2;
+ unsigned ep_dir7:2;
+ unsigned ep_dir8:2;
+ unsigned ep_dir9:2;
+ unsigned ep_dir10:2;
+ unsigned ep_dir11:2;
+ unsigned ep_dir12:2;
+ unsigned ep_dir13:2;
+ unsigned ep_dir14:2;
+ unsigned ep_dir15:2;
+ } b;
+} hwcfg1_data_t;
+
+/**
+ * This union represents the bit fields in the User HW Config2
+ * Register. Read the register into the <i>d32</i> element then read
+ * out the bits using the <i>b</i>it elements.
+ */
+#define DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG 1
+#define DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG 2
+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3
+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4
+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST 5
+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6
+#define DWC_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0
+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI 1
+#define DWC_HWCFG2_HS_PHY_TYPE_ULPI 2
+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI 3
+
+typedef union hwcfg2_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /* GHWCFG2 */
+ unsigned op_mode:3;
+ unsigned architecture:2; //00 salve-only;01 external dma;10 internal dma;
+ unsigned point2point:1;
+ unsigned hs_phy_type:2;
+ unsigned fs_phy_type:2;
+ unsigned num_dev_ep:4;
+ unsigned num_host_chan:4;
+ unsigned perio_ep_supported:1;
+ unsigned dynamic_fifo:1;
+ unsigned multi_proc_int:1;
+ unsigned reserved21:1;
+ unsigned nonperio_tx_q_depth:2;
+ unsigned host_perio_tx_q_depth:2;
+ unsigned dev_token_q_depth:5;
+ unsigned otg_enable_ic_usb:1;
+ } b;
+} hwcfg2_data_t;
+
+/**
+ * This union represents the bit fields in the User HW Config3
+ * Register. Read the register into the <i>d32</i> element then read
+ * out the bits using the <i>b</i>it elements.
+ */
+typedef union hwcfg3_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /* GHWCFG3 */
+ unsigned xfer_size_cntr_width:4;
+ unsigned packet_size_cntr_width:3;
+ unsigned otg_func:1;
+ unsigned i2c:1;
+ unsigned vendor_ctrl_if:1;
+ unsigned optional_features:1;
+ unsigned synch_reset_type:1;
+ unsigned adp_supp:1;
+ unsigned otg_enable_hsic:1;
+ unsigned bc_support:1;
+ unsigned otg_lpm_en:1;
+ unsigned dfifo_depth:16;
+ } b;
+} hwcfg3_data_t;
+
+/**
+ * This union represents the bit fields in the User HW Config4
+ * Register. Read the register into the <i>d32</i> element then read
+ * out the bits using the <i>b</i>it elements.
+ */
+typedef union hwcfg4_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ unsigned num_dev_perio_in_ep:4;
+ unsigned power_optimiz:1;
+ unsigned min_ahb_freq:1;
+ unsigned hiber:1;
+ unsigned xhiber:1;
+ unsigned reserved:6;
+ unsigned utmi_phy_data_width:2;
+ unsigned num_dev_mode_ctrl_ep:4;
+ unsigned iddig_filt_en:1;
+ unsigned vbus_valid_filt_en:1;
+ unsigned a_valid_filt_en:1;
+ unsigned b_valid_filt_en:1;
+ unsigned session_end_filt_en:1;
+ unsigned ded_fifo_en:1;
+ unsigned num_in_eps:4;
+ unsigned desc_dma:1;
+ unsigned desc_dma_dyn:1;
+ } b;
+} hwcfg4_data_t;
+
+/**
+ * This union represents the bit fields of the Core LPM Configuration
+ * Register (GLPMCFG). Set the bits using bit fields then write
+ * the <i>d32</i> value to the register.
+ */
+typedef union glpmctl_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** LPM-Capable (LPMCap) (Device and Host)
+ * The application uses this bit to control
+ * the DWC_otg core LPM capabilities.
+ */
+ unsigned lpm_cap_en:1;
+ /** LPM response programmed by application (AppL1Res) (Device)
+ * Handshake response to LPM token pre-programmed
+ * by device application software.
+ */
+ unsigned appl_resp:1;
+ /** Host Initiated Resume Duration (HIRD) (Device and Host)
+ * In Host mode this field indicates the value of HIRD
+ * to be sent in an LPM transaction.
+ * In Device mode this field is updated with the
+ * Received LPM Token HIRD bmAttribute
+ * when an ACK/NYET/STALL response is sent
+ * to an LPM transaction.
+ */
+ unsigned hird:4;
+ /** RemoteWakeEnable (bRemoteWake) (Device and Host)
+ * In Host mode this bit indicates the value of remote
+ * wake up to be sent in wIndex field of LPM transaction.
+ * In Device mode this field is updated with the
+ * Received LPM Token bRemoteWake bmAttribute
+ * when an ACK/NYET/STALL response is sent
+ * to an LPM transaction.
+ */
+ unsigned rem_wkup_en:1;
+ /** Enable utmi_sleep_n (EnblSlpM) (Device and Host)
+ * The application uses this bit to control
+ * the utmi_sleep_n assertion to the PHY when in L1 state.
+ */
+ unsigned en_utmi_sleep:1;
+ /** HIRD Threshold (HIRD_Thres) (Device and Host)
+ */
+ unsigned hird_thres:5;
+ /** LPM Response (CoreL1Res) (Device and Host)
+ * In Host mode this bit contains handsake response to
+ * LPM transaction.
+ * In Device mode the response of the core to
+ * LPM transaction received is reflected in these two bits.
+ - 0x0 : ERROR (No handshake response)
+ - 0x1 : STALL
+ - 0x2 : NYET
+ - 0x3 : ACK
+ */
+ unsigned lpm_resp:2;
+ /** Port Sleep Status (SlpSts) (Device and Host)
+ * This bit is set as long as a Sleep condition
+ * is present on the USB bus.
+ */
+ unsigned prt_sleep_sts:1;
+ /** Sleep State Resume OK (L1ResumeOK) (Device and Host)
+ * Indicates that the application or host
+ * can start resume from Sleep state.
+ */
+ unsigned sleep_state_resumeok:1;
+ /** LPM channel Index (LPM_Chnl_Indx) (Host)
+ * The channel number on which the LPM transaction
+ * has to be applied while sending
+ * an LPM transaction to the local device.
+ */
+ unsigned lpm_chan_index:4;
+ /** LPM Retry Count (LPM_Retry_Cnt) (Host)
+ * Number host retries that would be performed
+ * if the device response was not valid response.
+ */
+ unsigned retry_count:3;
+ /** Send LPM Transaction (SndLPM) (Host)
+ * When set by application software,
+ * an LPM transaction containing two tokens
+ * is sent.
+ */
+ unsigned send_lpm:1;
+ /** LPM Retry status (LPM_RetryCnt_Sts) (Host)
+ * Number of LPM Host Retries still remaining
+ * to be transmitted for the current LPM sequence
+ */
+ unsigned retry_count_sts:3;
+ unsigned reserved28_29:2;
+ /** In host mode once this bit is set, the host
+ * configures to drive the HSIC Idle state on the bus.
+ * It then waits for the device to initiate the Connect sequence.
+ * In device mode once this bit is set, the device waits for
+ * the HSIC Idle line state on the bus. Upon receving the Idle
+ * line state, it initiates the HSIC Connect sequence.
+ */
+ unsigned hsic_connect:1;
+ /** This bit overrides and functionally inverts
+ * the if_select_hsic input port signal.
+ */
+ unsigned inv_sel_hsic:1;
+ } b;
+} glpmcfg_data_t;
+// Device Registers
+/**
+ * Device Global Registers. <i>Offsets 800h-BFFh</i>
+ *
+ * The following structures define the size and relative field offsets
+ * for the Device Mode Registers.
+ *
+ * <i>These registers are visible only in Device mode and must not be
+ * accessed in Host mode, as the results are unknown.</i>
+ */
+typedef struct dwc_otg_dev_global_regs
+{
+ /** Device Configuration Register. <i>Offset 800h</i> */
+ volatile uint32_t dcfg;
+ /** Device Control Register. <i>Offset: 804h</i> */
+ volatile uint32_t dctl;
+ /** Device Status Register (Read Only). <i>Offset: 808h</i> */
+ volatile uint32_t dsts;
+ /** Reserved. <i>Offset: 80Ch</i> */
+ uint32_t unused;
+ /** Device IN Endpoint Common Interrupt Mask
+ * Register. <i>Offset: 810h</i> */
+ volatile uint32_t diepmsk;
+ /** Device OUT Endpoint Common Interrupt Mask
+ * Register. <i>Offset: 814h</i> */
+ volatile uint32_t doepmsk;
+ /** Device All Endpoints Interrupt Register. <i>Offset: 818h</i> */
+ volatile uint32_t daint;
+ /** Device All Endpoints Interrupt Mask Register. <i>Offset:
+ * 81Ch</i> */
+ volatile uint32_t daintmsk;
+ /** Device IN Token Queue Read Register-1 (Read Only).
+ * <i>Offset: 820h</i> */
+ volatile uint32_t dtknqr1;
+ /** Device IN Token Queue Read Register-2 (Read Only).
+ * <i>Offset: 824h</i> */
+ volatile uint32_t dtknqr2;
+ /** Device VBUS discharge Register. <i>Offset: 828h</i> */
+ volatile uint32_t dvbusdis;
+ /** Device VBUS Pulse Register. <i>Offset: 82Ch</i> */
+ volatile uint32_t dvbuspulse;
+ /** Device IN Token Queue Read Register-3 (Read Only). /
+ * Device Thresholding control register (Read/Write)
+ * <i>Offset: 830h</i> */
+ volatile uint32_t dtknqr3_dthrctl;
+ /** Device IN Token Queue Read Register-4 (Read Only). /
+ * Device IN EPs empty Inr. Mask Register (Read/Write)
+ * <i>Offset: 834h</i> */
+ volatile uint32_t dtknqr4_fifoemptymsk;
+ /** Device Each Endpoint Interrupt Register (Read Only). /
+ * <i>Offset: 838h</i> */
+ volatile uint32_t deachint;
+ /** Device Each Endpoint Interrupt mask Register (Read/Write). /
+ * <i>Offset: 83Ch</i> */
+ volatile uint32_t deachintmsk;
+ /** Device Each In Endpoint Interrupt mask Register (Read/Write). /
+ * <i>Offset: 840h</i> */
+ volatile uint32_t diepeachintmsk[MAX_EPS_CHANNELS];
+ /** Device Each Out Endpoint Interrupt mask Register (Read/Write). /
+ * <i>Offset: 880h</i> */
+ volatile uint32_t doepeachintmsk[MAX_EPS_CHANNELS];
+} dwc_otg_device_global_regs_t;
+
+/**
+ * This union represents the bit fields in the Device Configuration
+ * Register. Read the register into the <i>d32</i> member then
+ * set/clear the bits using the <i>b</i>it elements. Write the
+ * <i>d32</i> member to the dcfg register.
+ */
+#define DWC_DCFG_SEND_STALL 1
+#define DWC_DCFG_FRAME_INTERVAL_80 0
+#define DWC_DCFG_FRAME_INTERVAL_85 1
+#define DWC_DCFG_FRAME_INTERVAL_90 2
+#define DWC_DCFG_FRAME_INTERVAL_95 3
+
+typedef union dcfg_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** Device Speed */
+ unsigned devspd:2;
+ /** Non Zero Length Status OUT Handshake */
+ unsigned nzstsouthshk:1;
+ unsigned ena32khzs:1;
+ /** Device Addresses */
+ unsigned devaddr:7;
+ /** Periodic Frame Interval */
+ unsigned perfrint:2;
+ /** Enable Device OUT NAK for bulk in DDMA mode */
+ unsigned endevoutnak:1;
+ unsigned reserved14_17:4;
+ /** In Endpoint Mis-match count */
+ unsigned epmscnt:5;
+ /** Enable Descriptor DMA in Device mode */
+ unsigned descdma:1;
+ unsigned perschintvl:2;
+ unsigned resvalid:6;
+ } b;
+} dcfg_data_t;
+
+/**
+ * This union represents the bit fields in the Device Control
+ * Register. Read the register into the <i>d32</i> member then
+ * set/clear the bits using the <i>b</i>it elements.
+ */
+typedef union dctl_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** Remote Wakeup */
+ unsigned rmtwkupsig:1;
+ /** Soft Disconnect */
+ unsigned sftdiscon:1;
+ /** Global Non-Periodic IN NAK Status */
+ unsigned gnpinnaksts:1;
+ /** Global OUT NAK Status */
+ unsigned goutnaksts:1;
+ /** Test Control */
+ unsigned tstctl:3;
+ /** Set Global Non-Periodic IN NAK */
+ unsigned sgnpinnak:1;
+ /** Clear Global Non-Periodic IN NAK */
+ unsigned cgnpinnak:1;
+ /** Set Global OUT NAK */
+ unsigned sgoutnak:1;
+ /** Clear Global OUT NAK */
+ unsigned cgoutnak:1;
+ /** Power-On Programming Done */
+ unsigned pwronprgdone:1;
+ /** Reserved */
+ unsigned reserved:1;
+ /** Global Multi Count */
+ unsigned gmc:2;
+ /** Ignore Frame Number for ISOC EPs */
+ unsigned ifrmnum:1;
+ /** NAK on Babble */
+ unsigned nakonbble:1;
+ /** Enable Continue on BNA */
+ unsigned encontonbna:1;
+
+ unsigned reserved18_31:14;
+ } b;
+} dctl_data_t;
+
+/**
+ * This union represents the bit fields in the Device Status
+ * Register. Read the register into the <i>d32</i> member then
+ * set/clear the bits using the <i>b</i>it elements.
+ */
+#define DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0
+#define DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1
+#define DWC_DSTS_ENUMSPD_LS_PHY_6MHZ 2
+#define DWC_DSTS_ENUMSPD_FS_PHY_48MHZ 3
+typedef union dsts_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** Suspend Status */
+ unsigned suspsts:1;
+ /** Enumerated Speed */
+ unsigned enumspd:2;
+ /** Erratic Error */
+ unsigned errticerr:1;
+ unsigned reserved4_7:4;
+ /** Frame or Microframe Number of the received SOF */
+ unsigned soffn:14;
+ unsigned reserved22_31:10;
+ } b;
+} dsts_data_t;
+
+/**
+ * This union represents the bit fields in the Device IN EP Interrupt
+ * Register and the Device IN EP Common Mask Register.
+ *
+ * - Read the register into the <i>d32</i> member then set/clear the
+ * bits using the <i>b</i>it elements.
+ */
+typedef union diepint_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** Transfer complete mask */
+ unsigned xfercompl:1;
+ /** Endpoint disable mask */
+ unsigned epdisabled:1;
+ /** AHB Error mask */
+ unsigned ahberr:1;
+ /** TimeOUT Handshake mask (non-ISOC EPs) */
+ unsigned timeout:1;
+ /** IN Token received with TxF Empty mask */
+ unsigned intktxfemp:1;
+ /** IN Token Received with EP mismatch mask */
+ unsigned intknepmis:1;
+ /** IN Endpoint NAK Effective mask */
+ unsigned inepnakeff:1;
+ /** Reserved */
+ unsigned emptyintr:1;
+
+ unsigned txfifoundrn:1;
+
+ /** BNA Interrupt mask */
+ unsigned bna:1;
+
+ unsigned reserved10_12:3;
+ /** BNA Interrupt mask */
+ unsigned nak:1;
+
+ unsigned reserved14_31:18;
+ } b;
+} diepint_data_t;
+
+/**
+ * This union represents the bit fields in the Device IN EP
+ * Common/Dedicated Interrupt Mask Register.
+ */
+typedef union diepint_data diepmsk_data_t;
+
+/**
+ * This union represents the bit fields in the Device OUT EP Interrupt
+ * Registerand Device OUT EP Common Interrupt Mask Register.
+ *
+ * - Read the register into the <i>d32</i> member then set/clear the
+ * bits using the <i>b</i>it elements.
+ */
+typedef union doepint_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** Transfer complete */
+ unsigned xfercompl:1;
+ /** Endpoint disable */
+ unsigned epdisabled:1;
+ /** AHB Error */
+ unsigned ahberr:1;
+ /** Setup Phase Done (contorl EPs) */
+ unsigned setup:1;
+ /** OUT Token Received when Endpoint Disabled */
+ unsigned outtknepdis:1;
+
+ unsigned stsphsercvd:1;
+ /** Back-to-Back SETUP Packets Received */
+ unsigned back2backsetup:1;
+
+ unsigned reserved7:1;
+ /** OUT packet Error */
+ unsigned outpkterr:1;
+ /** BNA Interrupt */
+ unsigned bna:1;
+
+ unsigned reserved10:1;
+ /** Packet Drop Status */
+ unsigned pktdrpsts:1;
+ /** Babble Interrupt */
+ unsigned babble:1;
+ /** NAK Interrupt */
+ unsigned nak:1;
+ /** NYET Interrupt */
+ unsigned nyet:1;
+ /** Bit indicating setup packet received */
+ unsigned sr:1;
+
+ unsigned reserved16_31:16;
+ } b;
+} doepint_data_t;
+
+/**
+ * This union represents the bit fields in the Device OUT EP
+ * Common/Dedicated Interrupt Mask Register.
+ */
+typedef union doepint_data doepmsk_data_t;
+
+/**
+ * This union represents the bit fields in the Device All EP Interrupt
+ * and Mask Registers.
+ * - Read the register into the <i>d32</i> member then set/clear the
+ * bits using the <i>b</i>it elements.
+ */
+typedef union daint_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** IN Endpoint bits */
+ unsigned in:16;
+ /** OUT Endpoint bits */
+ unsigned out:16;
+ } ep;
+ struct
+ {
+ /** IN Endpoint bits */
+ unsigned inep0:1;
+ unsigned inep1:1;
+ unsigned inep2:1;
+ unsigned inep3:1;
+ unsigned inep4:1;
+ unsigned inep5:1;
+ unsigned inep6:1;
+ unsigned inep7:1;
+ unsigned inep8:1;
+ unsigned inep9:1;
+ unsigned inep10:1;
+ unsigned inep11:1;
+ unsigned inep12:1;
+ unsigned inep13:1;
+ unsigned inep14:1;
+ unsigned inep15:1;
+ /** OUT Endpoint bits */
+ unsigned outep0:1;
+ unsigned outep1:1;
+ unsigned outep2:1;
+ unsigned outep3:1;
+ unsigned outep4:1;
+ unsigned outep5:1;
+ unsigned outep6:1;
+ unsigned outep7:1;
+ unsigned outep8:1;
+ unsigned outep9:1;
+ unsigned outep10:1;
+ unsigned outep11:1;
+ unsigned outep12:1;
+ unsigned outep13:1;
+ unsigned outep14:1;
+ unsigned outep15:1;
+ } b;
+} daint_data_t;
+
+/**
+ * This union represents the bit fields in the Device IN Token Queue
+ * Read Registers.
+ * - Read the register into the <i>d32</i> member.
+ * - READ-ONLY Register
+ */
+typedef union dtknq1_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** In Token Queue Write Pointer */
+ unsigned intknwptr:5;
+ /** Reserved */
+ unsigned reserved05_06:2;
+ /** write pointer has wrapped. */
+ unsigned wrap_bit:1;
+ /** EP Numbers of IN Tokens 0 ... 4 */
+ unsigned epnums0_5:24;
+ } b;
+} dtknq1_data_t;
+
+
+/**
+ * Device Logical IN Endpoint-Specific Registers. <i>Offsets
+ * 900h-AFCh</i>
+ *
+ * There will be one set of endpoint registers per logical endpoint
+ * implemented.
+ *
+ * <i>These registers are visible only in Device mode and must not be
+ * accessed in Host mode, as the results are unknown.</i>
+ */
+typedef struct dwc_otg_dev_in_ep_regs
+{
+ /** Device IN Endpoint Control Register. <i>Offset:900h +
+ * (ep_num * 20h) + 00h</i> */
+ volatile uint32_t diepctl;
+ /** Reserved. <i>Offset:900h + (ep_num * 20h) + 04h</i> */
+ uint32_t reserved04;
+ /** Device IN Endpoint Interrupt Register. <i>Offset:900h +
+ * (ep_num * 20h) + 08h</i> */
+ volatile uint32_t diepint;
+ /** Reserved. <i>Offset:900h + (ep_num * 20h) + 0Ch</i> */
+ uint32_t reserved0C;
+ /** Device IN Endpoint Transfer Size
+ * Register. <i>Offset:900h + (ep_num * 20h) + 10h</i> */
+ volatile uint32_t dieptsiz;
+ /** Device IN Endpoint DMA Address Register. <i>Offset:900h +
+ * (ep_num * 20h) + 14h</i> */
+ volatile uint32_t diepdma;
+ /** Device IN Endpoint Transmit FIFO Status Register. <i>Offset:900h +
+ * (ep_num * 20h) + 18h</i> */
+ volatile uint32_t dtxfsts;
+ /** Device IN Endpoint DMA Buffer Register. <i>Offset:900h +
+ * (ep_num * 20h) + 1Ch</i> */
+ volatile uint32_t diepdmab;
+} dwc_otg_dev_in_ep_regs_t;
+
+/**
+ * Device Logical OUT Endpoint-Specific Registers. <i>Offsets:
+ * B00h-CFCh</i>
+ *
+ * There will be one set of endpoint registers per logical endpoint
+ * implemented.
+ *
+ * <i>These registers are visible only in Device mode and must not be
+ * accessed in Host mode, as the results are unknown.</i>
+ */
+typedef struct dwc_otg_dev_out_ep_regs
+{
+ /** Device OUT Endpoint Control Register. <i>Offset:B00h +
+ * (ep_num * 20h) + 00h</i> */
+ volatile uint32_t doepctl;
+ /** Reserved. <i>Offset:B00h + (ep_num * 20h) + 04h</i> */
+ uint32_t reserved04;
+ /** Device OUT Endpoint Interrupt Register. <i>Offset:B00h +
+ * (ep_num * 20h) + 08h</i> */
+ volatile uint32_t doepint;
+ /** Reserved. <i>Offset:B00h + (ep_num * 20h) + 0Ch</i> */
+ uint32_t reserved0C;
+ /** Device OUT Endpoint Transfer Size Register. <i>Offset:
+ * B00h + (ep_num * 20h) + 10h</i> */
+ volatile uint32_t doeptsiz;
+ /** Device OUT Endpoint DMA Address Register. <i>Offset:B00h
+ * + (ep_num * 20h) + 14h</i> */
+ volatile uint32_t doepdma;
+ /** Reserved. <i>Offset:B00h + * (ep_num * 20h) + 18h</i> */
+ uint32_t unused;
+ /** Device OUT Endpoint DMA Buffer Register. <i>Offset:B00h
+ * + (ep_num * 20h) + 1Ch</i> */
+ uint32_t doepdmab;
+} dwc_otg_dev_out_ep_regs_t;
+
+/**
+ * This union represents the bit fields in the Device EP Control
+ * Register. Read the register into the <i>d32</i> member then
+ * set/clear the bits using the <i>b</i>it elements.
+ */
+#define DWC_DEP0CTL_MPS_64 0
+#define DWC_DEP0CTL_MPS_32 1
+#define DWC_DEP0CTL_MPS_16 2
+#define DWC_DEP0CTL_MPS_8 3
+
+typedef union depctl_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** Maximum Packet Size
+ * IN/OUT EPn
+ * IN/OUT EP0 - 2 bits
+ * 2'b00: 64 Bytes
+ * 2'b01: 32
+ * 2'b10: 16
+ * 2'b11: 8 */
+ unsigned mps:11;
+ /** Next Endpoint
+ * IN EPn/IN EP0
+ * OUT EPn/OUT EP0 - reserved */
+ unsigned nextep:4;
+
+ /** USB Active Endpoint */
+ unsigned usbactep:1;
+
+ /** Endpoint DPID (INTR/Bulk IN and OUT endpoints)
+ * This field contains the PID of the packet going to
+ * be received or transmitted on this endpoint. The
+ * application should program the PID of the first
+ * packet going to be received or transmitted on this
+ * endpoint , after the endpoint is
+ * activated. Application use the SetD1PID and
+ * SetD0PID fields of this register to program either
+ * D0 or D1 PID.
+ *
+ * The encoding for this field is
+ * - 0: D0
+ * - 1: D1
+ */
+ unsigned dpid:1;
+
+ /** NAK Status */
+ unsigned naksts:1;
+
+ /** Endpoint Type
+ * 2'b00: Control
+ * 2'b01: Isochronous
+ * 2'b10: Bulk
+ * 2'b11: Interrupt */
+ unsigned eptype:2;
+
+ /** Snoop Mode
+ * OUT EPn/OUT EP0
+ * IN EPn/IN EP0 - reserved */
+ unsigned snp:1;
+
+ /** Stall Handshake */
+ unsigned stall:1;
+
+ /** Tx Fifo Number
+ * IN EPn/IN EP0
+ * OUT EPn/OUT EP0 - reserved */
+ unsigned txfnum:4;
+
+ /** Clear NAK */
+ unsigned cnak:1;
+ /** Set NAK */
+ unsigned snak:1;
+ /** Set DATA0 PID (INTR/Bulk IN and OUT endpoints)
+ * Writing to this field sets the Endpoint DPID (DPID)
+ * field in this register to DATA0. Set Even
+ * (micro)frame (SetEvenFr) (ISO IN and OUT Endpoints)
+ * Writing to this field sets the Even/Odd
+ * (micro)frame (EO_FrNum) field to even (micro)
+ * frame.
+ */
+ unsigned setd0pid:1;
+ /** Set DATA1 PID (INTR/Bulk IN and OUT endpoints)
+ * Writing to this field sets the Endpoint DPID (DPID)
+ * field in this register to DATA1 Set Odd
+ * (micro)frame (SetOddFr) (ISO IN and OUT Endpoints)
+ * Writing to this field sets the Even/Odd
+ * (micro)frame (EO_FrNum) field to odd (micro) frame.
+ */
+ unsigned setd1pid:1;
+
+ /** Endpoint Disable */
+ unsigned epdis:1;
+ /** Endpoint Enable */
+ unsigned epena:1;
+ } b;
+} depctl_data_t;
+
+/**
+ * This union represents the bit fields in the Device EP Transfer
+ * Size Register. Read the register into the <i>d32</i> member then
+ * set/clear the bits using the <i>b</i>it elements.
+ */
+
+/** Max packet count for EP (pow(2,10)-1) */
+#define MAX_PKT_CNT 1023
+typedef union deptsiz_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** Transfer size */
+ unsigned xfersize:19;
+ /** Packet Count */
+ unsigned pktcnt:10;
+ /** Multi Count - Periodic IN endpoints */
+ unsigned mc:2;
+ unsigned reserved:1;
+ } b;
+} deptsiz_data_t;
+
+/**
+ * This union represents the bit fields in the Device EP 0 Transfer
+ * Size Register. Read the register into the <i>d32</i> member then
+ * set/clear the bits using the <i>b</i>it elements.
+ */
+typedef union deptsiz0_data
+{
+ /** raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** Transfer size */
+ unsigned xfersize:7;
+ /** Reserved */
+ unsigned reserved7_18:12;
+ /** Packet Count */
+ unsigned pktcnt:2;
+ /** Reserved */
+ unsigned reserved21_28:8;
+ /**Setup Packet Count (DOEPTSIZ0 Only) */
+ unsigned supcnt:2;
+ unsigned reserved31;
+ } b;
+} deptsiz0_data_t;
+
+/////////////////////////////////////////////////
+// DMA Descriptor Specific Structures
+//
+
+/** Buffer status definitions */
+
+#define BS_HOST_READY 0x0
+#define BS_DMA_BUSY 0x1
+#define BS_DMA_DONE 0x2
+#define BS_HOST_BUSY 0x3
+
+/** Receive/Transmit status definitions */
+
+#define RTS_SUCCESS 0x0
+#define RTS_BUFFLUSH 0x1
+#define RTS_RESERVED 0x2
+#define RTS_BUFERR 0x3
+
+
+/**
+ * The dwc_otg_dev_if structure contains information needed to manage
+ * the DWC_otg controller acting in device mode. It represents the
+ * programming view of the device-specific aspects of the controller.
+ */
+#define DWC_DEV_GLOBAL_REG_OFFSET 0x800
+#define DWC_DEV_IN_EP_REG_OFFSET 0x900
+#define DWC_EP_REG_OFFSET 0x20
+#define DWC_DEV_OUT_EP_REG_OFFSET 0xB00
+
+typedef struct dwc_otg_dev_if
+{
+ /** Pointer to device Global registers.
+ * Device Global Registers starting at offset 800h
+ */
+ dwc_otg_device_global_regs_t *dev_global_regs;
+ /**
+ * Device Logical IN Endpoint-Specific Registers 900h-AFCh
+ */
+ dwc_otg_dev_in_ep_regs_t *in_ep_regs[MAX_EPS_CHANNELS];
+
+ /** Device Logical OUT Endpoint-Specific Registers B00h-CFCh */
+ dwc_otg_dev_out_ep_regs_t *out_ep_regs[MAX_EPS_CHANNELS];
+ /* Device configuration information */
+ uint8_t speed; /**< Device Speed 0: Unknown, 1: LS, 2:FS, 3: HS */
+ uint8_t num_in_eps; /**< Number # of Tx EP range: 0-15 exept ep0 */
+ uint8_t num_out_eps; /**< Number # of Rx EP range: 0-15 exept ep 0*/
+
+ /** Thresholding enable flags and length varaiables **/
+ uint16_t rx_thr_en;
+ //uint16_t iso_tx_thr_en;
+ uint16_t non_iso_tx_thr_en;
+
+ uint16_t rx_thr_length;
+ uint16_t tx_thr_length;
+
+ /**
+ * Pointers to the DMA Descriptors for EP0 Control
+ * transfers (virtual and physical)
+ */
+
+ /** Setup Packet Detected - if set clear NAK when queueing */
+ uint32_t spd;
+
+} dwc_otg_dev_if_t;
+
+/////////////////////////////////////////////////
+// Host Mode Register Structures
+//
+
+/**
+ * This union represents the bit fields in the Host Configuration Register.
+ * Read the register into the <i>d32</i> member then set/clear the bits using
+ * the <i>b</i>it elements. Write the <i>d32</i> member to the hcfg register.
+ */
+#define DWC_HCFG_30_60_MHZ 0
+#define DWC_HCFG_48_MHZ 1
+#define DWC_HCFG_6_MHZ 2
+/**
+ * This union represents the bit fields in the Power and Clock Gating Control
+ * Register. Read the register into the <i>d32</i> member then set/clear the
+ * bits using the <i>b</i>it elements.
+ */
+typedef union pcgcctl_data
+{
+ /** raw register data */
+ uint32_t d32;
+
+ /** register bits */
+ struct
+ {
+ /** Stop Pclk */
+ unsigned stoppclk:1;
+ /** Gate Hclk */
+ unsigned gatehclk:1;
+ /** Power Clamp */
+ unsigned pwrclmp:1;
+ /** Reset Power Down Modules */
+ unsigned rstpdwnmodule:1;
+ /** Reserved */
+ unsigned reserved:1;
+ /** Enable Sleep Clock Gating (Enbl_L1Gating) */
+ unsigned enbl_sleep_gating:1;
+ /** PHY In Sleep (PhySleep) */
+ unsigned phy_in_sleep:1;
+ /** Deep Sleep*/
+ unsigned deep_sleep:1;
+ unsigned resetaftsusp:1;
+ unsigned restoremode:1;
+ unsigned enbl_extnd_hiber:1;
+ unsigned extnd_hiber_pwrclmp:1;
+ unsigned extnd_hiber_switch:1;
+ unsigned ess_reg_restored:1;
+ unsigned prt_clk_sel:2;
+ unsigned port_power:1;
+ unsigned max_xcvrselect:2;
+ unsigned max_termsel:1;
+ unsigned mac_dev_addr:7;
+ unsigned p2hd_dev_enum_spd:2;
+ unsigned p2hd_prt_spd:2;
+ unsigned if_dev_mode:1;
+ } b;
+} pcgcctl_data_t;
+
+/**
+ * This union represents the bit fields in the Global Data FIFO Software
+ * Configuration Register. Read the register into the <i>d32</i> member then
+ * set/clear the bits using the <i>b</i>it elements.
+ */
+typedef union gdfifocfg_data
+{
+ /* raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** OTG Data FIFO depth */
+ unsigned gdfifocfg:16;
+ /** Start address of EP info controller */
+ unsigned epinfobase:16;
+ } b;
+} gdfifocfg_data_t;
+
+/**
+ * This union represents the bit fields in the Global Power Down Register
+ * Register. Read the register into the <i>d32</i> member then set/clear the
+ * bits using the <i>b</i>it elements.
+ */
+#define disconn_det disconn_det
+
+#define lnstschng lnstschng
+
+#define rst_det rst_det
+
+#define srp_det srp_det
+
+#define sts_chngint sts_chngint
+
+typedef union gpwrdn_data
+{
+ /* raw register data */
+ uint32_t d32;
+ /** register bits */
+ struct
+ {
+ /** PMU Interrupt Select */
+ unsigned pmuintsel:1;
+ /** PMU Active */
+ unsigned pmuactv:1;
+ /** Restore */
+ unsigned restore:1;
+ /** Power Down Clamp */
+ unsigned pwrdnclmp:1;
+ /** Power Down Reset */
+ unsigned pwrdnrstn:1;
+ /** Power Down Switch */
+ unsigned pwrdnswtch:1;
+ /** Disable VBUS */
+ unsigned dis_vbus:1;
+ /** Line State Change */
+ unsigned lnstschng:1;
+ /** Line state change mask */
+ unsigned lnstchng_msk:1;
+ /** Reset Detected */
+ unsigned rst_det:1;
+ /** Reset Detect mask */
+ unsigned rst_det_msk:1;
+ /** Disconnect Detected */
+ unsigned disconn_det:1;
+ /** Disconnect Detect mask */
+ unsigned disconn_det_msk:1;
+ /** Connect Detected*/
+ unsigned connect_det:1;
+ /** Connect Detected Mask*/
+ unsigned connect_det_msk:1;
+ /** SRP Detected */
+ unsigned srp_det:1;
+ /** SRP Detect mask */
+ unsigned srp_det_msk:1;
+ /** Status Change Interrupt */
+ unsigned sts_chngint:1;
+ /** Status Change Interrupt Mask */
+ unsigned sts_chngint_msk:1;
+ /** Line State */
+ unsigned linestate:2;
+ /** Indicates current mode(status of IDDIG signal) */
+ unsigned idsts:1;
+ /** B Session Valid signal status*/
+ unsigned bsessvld:1;
+ /** ADP Event Detected */
+ unsigned adp_int:1;
+ /** Multi Valued ID pin */
+ unsigned mult_val_id_bc:5;
+ /** Reserved 24_31 */
+ unsigned reserved29_31:3;
+ } b;
+} gpwrdn_data_t;
+
+#endif
diff --git a/boot/common/src/loader/drivers/efuse.c b/boot/common/src/loader/drivers/efuse.c
new file mode 100644
index 0000000..0aa6bf8
--- /dev/null
+++ b/boot/common/src/loader/drivers/efuse.c
@@ -0,0 +1,100 @@
+/*
+ ***********************************************************
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <sdio.h>
+
+#include "efuse.h"
+
+
+
+void efuse_init(void)
+{
+ //start read efuse all 256bit
+ while((REG32(SYS_EFUSE_BASE + 0x4) & 1) == 1);// bit0=1 ctl is busy
+ REG32(SYS_EFUSE_BASE + 0x4) = 1;
+ while((REG32(SYS_EFUSE_BASE + 0x14) & 2) == 0);//bit1=0 read not over
+}
+
+int get_ddr_flag(void)
+{
+ efuse_struct *psEfuseInfo = NULL;
+ int ddr_flag = 0;
+
+
+ psEfuseInfo = (efuse_struct*)EFUSE_RAM_BASE;
+
+ /* get chip flag */
+ if(((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_GW_WINBD_256M_DDR)
+ ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_ZW_WINBD_256M_DDR)
+ ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_GW_UNILC_256M_DDR)
+ ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_ZW_UNILC_256M_DDR)
+ ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_GW_APM_256M_DDR)
+ ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_ZW_APM_256M_DDR))
+ {
+ ddr_flag = CHIP_DDR_32M;
+ }
+ else if(((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_GW_UNILC_512M_DDR)
+ ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_GW_APM_512M_DDR)
+ ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_GW_ESMT_512M_DDR)
+ ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_ZW_UNILC_512M_DDR)
+ ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_AZW_UNILC_512M_DDR)
+ ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_ZW_APM_512M_DDR)
+ ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_ZW_ESMT_512M_DDR))
+ {
+ ddr_flag = CHIP_DDR_64M;
+ }
+ else if((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOSC_GW_NYC_2G_DDR)
+ {
+ ddr_flag = CHIP_DDR_256M;
+ }
+ else
+ {
+ ddr_flag = CHIP_DDR_128M;
+ }
+
+ return ddr_flag;
+}
+
+int get_secure_verify_status(void)
+{
+ u32 uiLen;
+ efuse_struct *psEfuseInfo = NULL;
+
+ if((REG32(EFUSE_BYPASS) & 1) == 1) //Secure Verify. 1->Disable, 0->Enable.
+ {
+ return SECURE_VERIFY_DISABLE;
+ }
+
+ /*
+ * 0. Èç¹ûsecure flag²»µÈÓÚ0xFF£¬Í˳ö°²È«boot¡£
+ */
+ psEfuseInfo = (efuse_struct*)EFUSE_RAM_BASE;
+ if((psEfuseInfo->secure_flag & 0xFF) != 0xFF)
+ {
+ return SECURE_VERIFY_DISABLE;
+ }
+
+ /*
+ * 1.´ÓefuseÖжÁ³öpuk_hash[127:0], ÅжÏÈç¹ûÈ«²¿Îª0Í˳ö°²È«boot¡£
+ */
+ for(uiLen = 0; uiLen < 4; uiLen++)
+ {
+ if(psEfuseInfo->puk_hash[uiLen] != 0)
+ {
+ break;
+ }
+ if(uiLen == 3)
+ {
+ return SECURE_VERIFY_DISABLE;
+ }
+ }
+ printf("SecureVerify->enable.\n");
+
+ return SECURE_VERIFY_ENABLE;
+}
+
+
+
diff --git a/boot/common/src/loader/drivers/efuse.h b/boot/common/src/loader/drivers/efuse.h
new file mode 100644
index 0000000..7a891a1
--- /dev/null
+++ b/boot/common/src/loader/drivers/efuse.h
@@ -0,0 +1,72 @@
+/*
+ ***********************************************************
+ */
+
+#ifndef __EFUSE_H__
+#define __EFUSE_H__
+
+
+/* -------- efuse ¼Ä´æÆ÷-------------*/
+#define SYS_EFUSE_BASE 0x0121b000
+#define EFUSE_RAM_BASE (SYS_EFUSE_BASE+0x40)
+
+#define SYS_CTRL_BASE 0x00140000
+#define EFUSE_BYPASS (SYS_CTRL_BASE+0x140)
+
+
+#define CHIP_DDR_32M 0
+#define CHIP_DDR_64M 1
+#define CHIP_DDR_128M 2
+#define CHIP_DDR_256M 3
+
+
+#define SECURE_VERIFY_ENABLE 0
+#define SECURE_VERIFY_DISABLE 1
+
+#define ZX297520V3_GW_NYB_1G_DDR 0xF86302
+#define ZX297520V3_GW_NYC_1G_DDR 0xF86303
+#define ZX297520V3ECO_GW_UNILC_512M_DDR 0xF86304
+#define ZX297520V3ECO_GW_APM_512M_DDR 0xF86305
+#define ZX297520V3ECO_GW_NYB_1G_DDR 0xF86306
+#define ZX297520V3ECO_GW_NYC_1G_DDR 0xF86307
+#define ZX297520V3ECO_GW_WINBD_256M_DDR 0xF86308
+#define ZX297520V3ECO_GW_UNILC_256M_DDR 0xF86309
+#define ZX297520V3ECO_GW_APM_256M_DDR 0xF8630a
+#define ZX297520V3ECO_GW_ESMT_512M_DDR 0xF8630b
+#define ZX297520V3SC_GW_NYC_1G_DDR 0xF8630c
+#define ZX297520V3ECOSCC_GW_UNILC_1G_DDR 0xF8630d
+#define ZX297520V3ECOSCC_GW_NYC_1G_DDR 0xF8630e
+#define ZX297520V3ECOSC_GW_NYC_1G_DDR 0xF8630f
+#define ZX297520V3ECOSC_GW_UNILC_1G_DDR 0xF86310
+#define ZX297520V3ECOSC_GW_NYC_2G_DDR 0xF86311
+
+#define ZX297520V3_ZW_NYB_1G_DDR 0x1E871E
+#define ZX297520V3_ZW_NYC_1G_DDR 0x1E871F
+#define ZX297520V3ECO_ZW_UNILC_512M_DDR 0x1E8720
+#define ZX297520V3ECO_ZW_APM_512M_DDR 0x1E8721
+#define ZX297520V3ECO_ZW_NYB_1G_DDR 0x1E8722
+#define ZX297520V3ECO_ZW_NYC_1G_DDR 0x1E8723
+#define ZX297520V3ECO_ZW_WINBD_256M_DDR 0x1E8724
+#define ZX297520V3ECO_ZW_UNILC_256M_DDR 0x1E8725
+#define ZX297520V3ECO_ZW_APM_256M_DDR 0x1E8726
+#define ZX297520V3ECO_ZW_ESMT_512M_DDR 0x1E8727
+
+#define ZX297520V3ECO_AZW_UNILC_512M_DDR 0x1F9801
+
+
+/*ΪÁË¿´ÆðÀ´·½±ã, hashºÍkeyÔÚbufferµÄ´æ·Å˳ÐòΪµÍµØÖ··Å¸ßλÊý¾Ý*/
+// ¶¨Òå½á¹¹
+typedef volatile struct
+{
+ u32 secure_flag;
+ u32 puk_hash[4];
+} efuse_struct;
+
+
+
+void efuse_init(void);
+int get_ddr_flag(void);
+int get_secure_verify_status(void);
+
+
+#endif /* __EFUSE_H__ */
diff --git a/boot/common/src/loader/drivers/flash.c b/boot/common/src/loader/drivers/flash.c
new file mode 100755
index 0000000..75d5dd7
--- /dev/null
+++ b/boot/common/src/loader/drivers/flash.c
@@ -0,0 +1,50 @@
+/*
+ * (C) Copyright 2016 ZXIC Inc.
+ */
+#include <asm/io.h>
+#include <asm/arch/top_clock.h>
+
+#include "flash.h"
+
+struct flash_type flash;
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+char get_boot_mode(void)
+{
+ char boot_info = 0;
+
+ boot_info = readl(BOOTSEL_INFO);
+
+ if(((boot_info >> 4)&0x3) == 0x3)
+ {
+ return NOR_BOOT;
+ }
+ else
+ {
+ if(((boot_info & 0x7) == 0x0) || ((boot_info & 0x7) == 0x1))
+ {
+ return NAND_BOOT;
+ }
+ else if(((boot_info & 0x7) == 0x4) || ((boot_info & 0x7) == 0x5))
+ {
+ return SPI_NAND_BOOT;
+ }
+ else
+ {
+ return OTHER_BOOT;
+ }
+ }
+}
+
+
+
diff --git a/boot/common/src/loader/drivers/flash.h b/boot/common/src/loader/drivers/flash.h
new file mode 100755
index 0000000..2fe2ddb
--- /dev/null
+++ b/boot/common/src/loader/drivers/flash.h
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZXIC Corporation.
+ *
+ * File Name:
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: v1.0
+ * Author: zhouqi
+ * Date: 2013-8-21
+ * History 1:
+ * Date:
+ * Version:
+ * Author:
+ * Modification:
+ * History 2:
+ ********************************************************************************/
+
+#ifndef _FLASH_H_
+#define _FLASH_H_
+
+#include <linux/types.h>
+
+#define NOR_BOOT 0x0
+#define NAND_BOOT 0x1
+#define SPI_NAND_BOOT 0x2
+#define OTHER_BOOT 0xff
+
+struct flash_type{
+ uint8_t flash_type;
+ uint8_t manuf_id;
+ uint8_t device_id;
+ uint16_t page_size;
+ uint16_t page_size_shift;
+ uint16_t oob_size;
+ uint16_t block_size_shift;
+ uint16_t block_num;
+ uint32_t block_size;
+ int32_t (*read_page_raw)(uint32_t buf, uint32_t offset);
+ int32_t (*read)(uint32_t from, uint32_t len, uint32_t to);
+ void (*read_oob)(uint8_t *buf, uint32_t offset, uint32_t len);
+};
+
+
+extern struct flash_type flash;
+
+char get_boot_mode(void);
+int board_flash_init(void);
+
+
+#endif/*_FLASH_H_*/
+
+
diff --git a/boot/common/src/loader/drivers/global.c b/boot/common/src/loader/drivers/global.c
new file mode 100644
index 0000000..ab05703
--- /dev/null
+++ b/boot/common/src/loader/drivers/global.c
@@ -0,0 +1,96 @@
+#include "global.h"
+
+__align(4) const dwc_config_all_t desc =
+{
+//T_CONFIG_DESCRIPTOR
+{
+ sizeof(dwc_config_descriptor_t), //bLength
+ CONFIG_DESCRIPTOR, //bDescriptorType
+ sizeof(dwc_config_all_t),
+ 2, //bNumInterfaces
+ 1, //bConfigurationValue
+ 0, //iConfiguration×Ö·û´®ÃèÊöµÄË÷Òý
+ ATTR_D7 |ATTR_SELF_POWERED , //bmAttributes
+ POWER_MA(500), //
+},
+
+
+//T_INTERFACE_DESCRIPTOR
+{
+ sizeof(dwc_interface_descriptor_t), //bLength
+ INTERFACE_DESCRIPTOR, //bDescriptorType
+ 0, //bInterfaceNumber
+ 0, //bAlternateSetting
+ 0x02, //bNumEndpoints
+ VERDOR_SPECIFIC, //bInterfaceClass
+ 0xff, //bInterfaceSubClass
+ 0xff, //bInterfaceProtocol
+ 0x04, //iInterface×Ö·û´®ÃèÊöµÄË÷Òý
+},
+
+{
+ sizeof(dwc_ep_descriptor_t), //bLength
+ ENDPOINT_DESCRIPTOR, //bDescriptorType
+ EP_ADDRESS_DIRECTION_IN |0x1, //bEndpointAddress
+ EP_ATTR_TRANSFER_TYPE_BULK, //bmAttributes
+ USB_HIGHSPEED_BULK_MAXSIZE, //wMaxPacketSize
+ 0, //bInterval
+},
+{
+ sizeof(dwc_ep_descriptor_t), //bLength
+ ENDPOINT_DESCRIPTOR, //bDescriptorType
+ 0x1, //bEndpointAddress
+ EP_ATTR_TRANSFER_TYPE_BULK, //bmAttributes
+ USB_HIGHSPEED_BULK_MAXSIZE, //wMaxPacketSize
+ 0, //bInterval
+},
+//T_INTERFACE_DESCRIPTOR
+{
+ sizeof(dwc_interface_descriptor_t), //bLength
+ INTERFACE_DESCRIPTOR, //bDescriptorType
+ 1, //bInterfaceNumber
+ 0, //bAlternateSetting
+ 0x02, //bNumEndpoints
+ VERDOR_SPECIFIC, //bInterfaceClass
+ 0xff, //bInterfaceSubClass
+ 0xff, //bInterfaceProtocol
+ 0x05, //iInterface×Ö·û´®ÃèÊöµÄË÷Òý
+},
+
+{
+ sizeof(dwc_ep_descriptor_t), //bLength
+ ENDPOINT_DESCRIPTOR, //bDescriptorType
+ EP_ADDRESS_DIRECTION_IN |0x2, //bEndpointAddress
+ EP_ATTR_TRANSFER_TYPE_BULK, //bmAttributes
+ USB_HIGHSPEED_BULK_MAXSIZE, //wMaxPacketSize
+ 0, //bInterval
+},
+
+{
+ sizeof(dwc_ep_descriptor_t), //bLength
+ ENDPOINT_DESCRIPTOR, //bDescriptorType
+ 0x2, //bEndpointAddress
+ EP_ATTR_TRANSFER_TYPE_BULK, //bmAttributes
+ USB_HIGHSPEED_BULK_MAXSIZE, //wMaxPacketSize
+ 0, //bInterval
+},
+};
+
+
+struct g_data global;
+
+__align(4) dwc_config_all_t g_config_desc;
+
+void data_init(void)
+{
+ int i;
+ char *src = (char*)&desc;
+ char *dst = (char*)&g_config_desc;
+
+ for(i = 0; i < sizeof(dwc_config_all_t); i++)
+ {
+ *dst++ = *src++;
+ }
+}
+
+
diff --git a/boot/common/src/loader/drivers/global.h b/boot/common/src/loader/drivers/global.h
new file mode 100644
index 0000000..8d14d73
--- /dev/null
+++ b/boot/common/src/loader/drivers/global.h
@@ -0,0 +1,51 @@
+/*******************************************************************************
+* °æÈ¨ËùÓÐ (C)2010, ÉîÛÚÊÐÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
+*
+* ÎļþÃû³Æ£º global.c
+* Îļþ±êʶ£º
+* ÄÚÈÝÕªÒª£º È«¾Ö±äÁ¿¼°³õʼ»¯
+* ÆäËü˵Ã÷£º
+* µ±Ç°°æ±¾£º 1.0
+* ×÷¡¡¡¡Õߣº ÎÌÔÆ·å
+* Íê³ÉÈÕÆÚ£º
+*******************************************************************************/
+#ifndef __GLOBAL_H_
+#define __GLOBAL_H_
+#include "common.h"
+
+#include "dwc_otg_driver.h"
+
+
+struct g_data
+{
+ dwc_otg_device_t g_dwc_otg_dev_t;
+ u32 dwRxQuit;
+ u32 dwTxQuit;
+ u32 g_Connet;
+ u32 g_USB_MODE;
+ u32 g_USB_TIMEOUT;
+ u16 g_status_buf;
+ int g_State;
+ int g_bootfinish;
+ int g_bootaddr;
+ int g_bootsize;
+ int g_boot_save_size;
+ int g_boot_save_addr;
+
+ dwc_otg_core_if_t core_if_t;
+ dwc_otg_dev_if_t dev_if_t;
+ dwc_otg_core_params_t g_core_params;
+
+ u32 g_in_pPara[3];
+ u32 g_out_pPara[3];
+ u_setup_pkt g_u_setup_pkt[sizeof(u_setup_pkt)*5];
+ dwc_otg_pcd_t g_dwc_otg_pcd_tp;
+ u32 g_pll_cfg;
+ int g_enum;
+};
+
+extern struct g_data global;
+//extern dwc_config_all_t desc;
+extern dwc_config_all_t g_config_desc;
+#endif
+
diff --git a/boot/common/src/loader/drivers/image.c b/boot/common/src/loader/drivers/image.c
new file mode 100755
index 0000000..8b9c89e
--- /dev/null
+++ b/boot/common/src/loader/drivers/image.c
@@ -0,0 +1,350 @@
+/*
+ * (C) Copyright 2016 ZXIC Inc.
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/string.h>
+
+#include <image.h>
+#include <linux/byteorder/generic.h>
+#include <secure_verify.h>
+
+#include "flash.h"
+#include <bbt.h>
+
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+uint32_t page_align(uint32_t offset)
+{
+ uint32_t page_size = flash.page_size;
+ if(offset & (page_size - 1))
+ {
+ offset &= (~(page_size - 1));
+ offset += page_size;
+ }
+ return offset;
+}
+
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+uint32_t find_partition_para(partition_entry_t *entry,
+ uint32_t entrys,
+ uint8_t *name)
+{
+ partition_entry_t *p_entry = entry;
+ uint32_t entry_nums = entrys;
+ while(entry_nums--)
+ {
+ if(memcmp( p_entry->part_name, name, strlen(name)) == 0)
+ return p_entry->part_offset;
+ p_entry++;
+ }
+ return -1;
+}
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+int read_image_part_offset(uint8_t *name, uint32_t *offset)
+{
+ int ret = 0;
+ uint32_t part_size = 0;
+
+ if(flash.flash_type == NOR_BOOT)
+ {
+ part_size = 8*flash.page_size;
+ }
+ else
+ {
+ part_size = flash.page_size;
+ }
+
+ ret = flash.read(0x2000, part_size, CFG_TEMP_ADDR);
+ if(ret != 0)
+ {
+ return -1;
+ }
+
+ partition_table_t *part = (partition_table_t *)CFG_TEMP_ADDR;
+ partition_entry_t *entry = &part->table[0];
+ uint32_t entrys = part->entrys;
+
+ if(part->magic != CFG_PARTITION_MAGIC)
+ {
+ return -1;
+ }
+
+ *offset = find_partition_para(entry, entrys, name);
+ if(*offset == -1 )
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_ZX297520V3E_MDL_AB
+int read_flags_image(uint8_t *name)
+{
+ T_BOOT_FOTA_FLAG *fotaFlag;
+ uint32_t uiPageSize = 0;
+ uint32_t flags_offset = 0;
+ uint32_t off = 0;
+ uint32_t flags_size = 0x4E0000;/*flags·ÖÇø*/
+ uint32_t blockNum = 0;
+ int32_t flag_one = 0;
+ uint32_t work_area_offset = 0;
+ uint32_t backup_area_offset = 0;
+ int32_t ret = 0;
+ int32_t fota_size = sizeof(T_BOOT_FOTA_FLAG);
+ int32_t block_size = flash.block_size;
+
+ fota_size = page_align(fota_size);
+
+ ret = read_image_part_offset(name, &flags_offset);
+ if(ret != 0)
+ {
+ printf("flags partition offset fail.\n");
+ return -1;
+ }
+
+ /*È·¶¨¹¤×÷ÇøºÍ±¸·ÝÇøÆ«ÒÆµØÖ·*/
+ for (off = flags_offset; off < flags_offset+flags_size; off += flash.block_size)
+ {
+ if (!(nand_block_isbad(off)))
+ {
+ blockNum += 1;
+ }
+
+ if((blockNum == 1) && (flag_one == 0))
+ {
+ work_area_offset = off;
+ flag_one = 1;
+ }
+
+ else if(blockNum == 2)
+ {
+ backup_area_offset = off;
+ break;
+ }
+ }
+
+ if(blockNum < 2)
+ {
+ printf("flags partition have not enough space!\n");
+
+ return -1;
+ }
+
+ ret = flash.read(work_area_offset, fota_size, CFG_TEMP_ADDR);
+ if(ret != 0)
+ {
+ printf("read flags work partition err.\n");
+
+ return -1;
+ }
+
+ fotaFlag = (T_BOOT_FOTA_FLAG *)(CFG_TEMP_ADDR);
+
+ if(fotaFlag->magic != FLAGS_MAGIC)
+ {
+ ret = flash.read(backup_area_offset, fota_size, CFG_TEMP_ADDR);
+ if(ret != 0)
+ {
+ printf("read flags backup partition err.\n");
+
+ return -1;
+ }
+ fotaFlag = (T_BOOT_FOTA_FLAG *)(CFG_TEMP_ADDR);
+ if(fotaFlag->magic != FLAGS_MAGIC)
+ {
+ printf("flags magic err.\n");
+ return -1;
+ }
+ }
+
+ return 0;
+
+}
+#endif
+/*
+ ****************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *****************************************************************************
+ */
+int read_uboot_image(uint8_t *name, uint32_t *uboot_entry_point)
+{
+ /*
+ * +----------------------------------------------------------------+
+ * | sImageHeader | image_header_t | u-boot.bin |
+ * +----------------------------------------------------------------+
+ * | 384 Bytes | 64 Bytes | xxx Bytes |
+ *
+ */
+
+ image_header_t *psImgHdrOld = NULL;
+
+ uint32_t uiPageSize = 0;
+
+ uint32_t uiImgHdrSizeOld = sizeof(image_header_t);
+ uint32_t uiImgHdrSizeNew = sizeof(sImageHeader);
+
+ uint32_t uiUBootSize = 0;
+ uint32_t uiUBootLoadAddr = 0;
+ uint32_t uiUBootIsReadSize = 0;
+
+ int32_t ret = 0;
+ uint32_t uboot_offset = 0;
+
+
+
+ if(flash.flash_type == NOR_BOOT)
+ {
+ uiPageSize = 8*flash.page_size;
+ }
+ else
+ {
+ uiPageSize = flash.page_size;
+ }
+
+ ret = read_image_part_offset(name, &uboot_offset);
+ if(ret != 0)
+ {
+ printf("offset fail.\n");
+ return -1;
+ }
+
+ ret = flash.read(uboot_offset, uiPageSize, CFG_TEMP_ADDR);
+ if(ret != 0)
+ {
+ printf("image header err.\n");
+ return -1;
+ }
+
+ psImgHdrOld = (image_header_t *)(CFG_TEMP_ADDR + uiImgHdrSizeNew);
+ uiUBootSize = ___htonl(psImgHdrOld->ih_size);
+ uiUBootLoadAddr = ___htonl(psImgHdrOld->ih_load);
+ *uboot_entry_point = ___htonl(psImgHdrOld->ih_ep);
+
+ if(___htonl(psImgHdrOld->ih_magic) != IH_MAGIC)
+ {
+ printf("magic err.\n");
+ return -1;
+ }
+
+ uiUBootIsReadSize = uiPageSize - uiImgHdrSizeOld - uiImgHdrSizeNew;
+ uiUBootSize -= uiUBootIsReadSize;
+ uiUBootSize = page_align(uiUBootSize);
+
+ memcpy(uiUBootLoadAddr - uiImgHdrSizeOld,
+ CFG_TEMP_ADDR + uiImgHdrSizeNew,
+ uiUBootIsReadSize + uiImgHdrSizeOld);
+
+ ret = flash.read(uboot_offset + uiPageSize,
+ uiUBootSize,
+ uiUBootLoadAddr + uiUBootIsReadSize);
+ if(ret != 0)
+ {
+ printf("image err.\n");
+ return -1;
+ }
+
+ ret = SecureVerify(CFG_TEMP_ADDR);
+ if(ret != 0)
+ {
+ printf("Secure verify fail!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+ int nand_read_m0(uint32_t *m0_entry_point)
+{
+ int remap = 0;
+ image_header_t *header = NULL;
+ uint32_t image_header_size = sizeof(image_header_t);
+ uint32_t m0_size = 0;
+ uint32_t m0_load_addr = 0;
+ /*
+ * +---------------------------------------------------------+
+ * | image_header_t | m0 |
+ * +---------------------------------------------------------+
+ m0.bin
+ */
+
+ /*1¡¢µÈ´ýBOOT°áÔËM0°æ±¾µ½CONFIG_SYS_SDRAM_TEMP_BASEÖÐ*/
+ writel(0, M0_IMAGE_READY_FLAG_ADDR);
+ while(!readl(M0_IMAGE_READY_FLAG_ADDR));
+
+ /*2¡¢M0µÄ0µØÖ·ÖØÓ³Éä*/
+ remap = readl(0x140000);
+ remap |= 0x800000;
+ writel(remap,0x140000);
+
+ /*3¡¢½âÎöM0µÄ°æ±¾Í·£¬»ñÈ¡ÔËÐеØÖ·ÒÔ¼°´óС*/
+ header = (image_header_t *)CONFIG_SYS_SDRAM_TEMP_BASE;
+ m0_size = ___htonl(header->ih_size); /* m0.bin */
+ m0_load_addr = ___htonl(header->ih_load);
+ *m0_entry_point = ___htonl(header->ih_ep);
+
+ if(___htonl(header->ih_magic) != IH_MAGIC)
+ {
+ return -1;
+ }
+
+ /*4¡¢½«M0µÄ°æ±¾´ÓIRAM0¿½±´µ½load_addr*/
+ memcpy(m0_load_addr, CONFIG_SYS_SDRAM_TEMP_BASE + image_header_size, m0_size);
+
+ /*5¡¢ÐÞ¸ÄIRAM±ê¼Ç£¬Ê¹BOOT¼ÌÐøÍùÏÂÖ´ÐÐ*/
+ writel(0, M0_IMAGE_READY_FLAG_ADDR);
+
+ return 0;
+}
+
+
diff --git a/boot/common/src/loader/drivers/nor.c b/boot/common/src/loader/drivers/nor.c
new file mode 100755
index 0000000..afccaf9
--- /dev/null
+++ b/boot/common/src/loader/drivers/nor.c
@@ -0,0 +1,417 @@
+/*
+ * Freescale QuadSPI driver.
+ *
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <sdio.h>
+#include <common.h>
+#include <asm/io.h>
+#include "nor.h"
+#include <image.h>
+#include <linux/byteorder/generic.h>
+#include <secure_verify.h>
+#include "config.h"
+#include "flash.h"
+
+
+/* Used when the "_ext_id" is two bytes at most */
+#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
+ .id = { \
+ ((_jedec_id) >> 16) & 0xff, \
+ ((_jedec_id) >> 8) & 0xff, \
+ (_jedec_id) & 0xff, \
+ ((_ext_id) >> 8) & 0xff, \
+ (_ext_id) & 0xff, \
+ }, \
+ .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \
+ .sector_size = (_sector_size), \
+ .n_sectors = (_n_sectors), \
+ .page_size = 256, \
+ .flags = (_flags),
+
+
+spinor_cmd_t nor_cmd_table[]=
+{
+ {CMD_RDFT, TX_DMA_DIS, RX_DMA_DIS, ADDR_TX_EN, ADDR_WIDTH_24, DATA_TX_DIS, DATA_RX_EN, DUMY_TX_EN, 1, 0, ADDR_MULTI_LINE_DIS, DATA_MULTI_LINE_DIS, TRANS_MOD_SINGLE, "read fast"},
+ {CMD_RDID, TX_DMA_DIS, RX_DMA_DIS, ADDR_TX_DIS, ADDR_WIDTH_24, DATA_TX_DIS, DATA_RX_EN, DUMY_TX_DIS, 0, 0, ADDR_MULTI_LINE_DIS, DATA_MULTI_LINE_DIS, TRANS_MOD_SINGLE, "read identification"},
+ {NULL}
+};
+
+#ifdef CONFIG_ZX297520V3_UFI_MINI_32K_NOR
+static const struct nor_info spi_nor_ids[] = {
+ /* GigaDevice */
+ { "gd25q128", INFO(0xc86018, 0, 32 * 1024, 512, 0) },
+ /* winbond */
+ { "w25q128fw", INFO(0xef6018, 0, 32 * 1024, 512, 0) },
+ /* dosilicon */
+ { "fm25m4aa", INFO(0xf84218, 0, 32 * 1024, 512, 0) },
+ /* fudanwei */
+ { "fm25w128", INFO(0xA12818, 0, 32 * 1024, 512, 0) },
+ /* XMC */
+ { "XM25QU64C", INFO(0x204117, 0, 32 * 1024, 256, 0) },
+ { "XM25QU128", INFO(0x205018, 0, 32 * 1024, 512, 0) },
+ { "XM25QU128C", INFO(0x204118, 0, 32 * 1024, 512, 0) },
+ /* DQ25Q128AL */
+ { "DQ25Q128AL", INFO(0x546018, 0, 32 * 1024, 512, 0) },
+ /* dosilicon */
+ { "DS25M4AB", INFO(0xE54218, 0, 32 * 1024, 512, 0) },
+ /* esmt(eon) */
+ { "EN25SX128A", INFO(0x1C7818, 0, 32 * 1024, 512, 0) },
+ /* dosilicon */
+ { "FM25M4AA", INFO(0xF84218, 0, 32 * 1024, 512, 0) },
+ { },
+};
+#else
+static const struct nor_info spi_nor_ids[] = {
+ /* GigaDevice */
+ { "gd25q128", INFO(0xc86018, 0, 64 * 1024, 256, 0) },
+ /* winbond */
+ { "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, 0) },
+ /* dosilicon */
+ { "fm25m4aa", INFO(0xf84218, 0, 64 * 1024, 256, 0) },
+ /* fudanwei */
+ { "fm25w128", INFO(0xA12818, 0, 64 * 1024, 256, 0) },
+ /* xmc */
+ { "XM25QU128", INFO(0x205018, 0, 64 * 1024, 256, 0) },
+ { "XM25QU128C", INFO(0x204118, 0, 64 * 1024, 256, 0) },
+ /* DQ25Q128AL */
+ { "DQ25Q128AL", INFO(0x546018, 0, 64 * 1024, 256, 0) },
+ /* dosilicon */
+ { "DS25M4AB", INFO(0xE54218, 0, 64 * 1024, 256, 0) },
+ /* esmt(eon) */
+ { "EN25SX128A", INFO(0x1C7818, 0, 64 * 1024, 256, 0) },
+ /* dosilicon */
+ { "FM25M4AA", INFO(0xF84218, 0, 64 * 1024, 256, 0) },
+ { },
+};
+#endif
+
+
+struct nor_info *spi_nor_flash = NULL;
+
+
+ void spifc_enable(void)
+{
+ volatile struct spifc_nor_reg_t* spifc = (struct spifc_nor_reg_t*)SYS_SPI_NAND_BASE;
+
+ if(spifc->SFC_EN & FC_EN_BACK)
+ {
+ printf("spifc en err.\n");
+ return;
+ }
+ spifc->SFC_EN |= (1 << FC_EN);
+ spifc->SFC_CTRL0 |= (1 << FC_SCLK_PAUSE_EN);
+}
+
+ void spifc_disable(void)
+{
+ volatile struct spifc_nor_reg_t* spifc = (struct spifc_nor_reg_t*)SYS_SPI_NAND_BASE;
+
+ if(!(spifc->SFC_EN & FC_EN_BACK))
+ {
+ printf("spifc dis err.\n");
+ return;
+ }
+ spifc->SFC_EN &= (~(1 <<FC_EN));
+}
+
+ void spifc_setup_cmd(spinor_cmd_t *cmd, uint32_t addr, uint32_t len)
+{
+ volatile struct spifc_nor_reg_t* spifc = (struct spifc_nor_reg_t*)SYS_SPI_NAND_BASE;
+
+ /* clear dma config */
+ spifc->SFC_CTRL0 &= ~((1 << FC_RX_DMA_EN)|(1 << FC_TX_DMA_EN));
+ /* clear fifo */
+ spifc->SFC_CTRL0 |= (1 << FC_RXFIFO_CLR)|(1 << FC_TXFIFO_CLR);
+
+ /* clear interrupt register */
+ spifc->SFC_INT_SW_CLR = 0xFF;
+
+ /* dma + fifo config */
+ spifc->SFC_CTRL0 |= ((cmd->tx_dma_en << FC_TX_DMA_EN)
+ | (cmd->rx_dma_en << FC_RX_DMA_EN)
+ | (1 << FC_RXFIFO_THRES)
+ | (1 << FC_TXFIFO_THRES));
+
+ /* addr dumy data code config */
+ spifc->SFC_CTRL1 = 0;
+ spifc->SFC_CTRL1 = ((cmd->addr_tx_en << FC_ADDR_TX_EN)
+ | (cmd->dumy_tx_en << FC_DUMMY_TX_EN)
+ | (cmd->data_rx_en << FC_READ_DAT_EN)
+ | (cmd->data_tx_en << FC_WRITE_DAT_EN));
+
+ spifc->SFC_CTRL2 = 0;
+ spifc->SFC_CTRL2 = ((cmd->dumy_byte_num << FC_DUMMY_BYTE_NUM)
+ | (cmd->dumy_bit_num << FC_DUMMY_BIT_NUM)
+ | (cmd->addr_byte_num << FC_ADDR_BYTE_NUM)
+ | (cmd->addr_multi_line_en << FC_ADDR_MULTI_LINE_EN)
+ | (cmd->data_multi_line_en << FC_DAT_MULTI_LINE_EN)
+ | (cmd->trans_mod << FC_TRANS_MOD));
+
+ if(len)
+ spifc->SFC_BYTE_NUM = len - 1;
+ else
+ spifc->SFC_BYTE_NUM = 0;
+
+ spifc->SFC_ADDR = addr;
+ spifc->SFC_INS = cmd->cmd;
+}
+
+ int spifc_wait_cmd_end(void)
+{
+ volatile struct spifc_nor_reg_t* spifc = (struct spifc_nor_reg_t*)SYS_SPI_NAND_BASE;
+ uint32_t intr_status = 0;
+
+ while(!(spifc->SFC_INT_RAW & FC_INT_RAW_MASK));
+
+ intr_status = spifc->SFC_INT_RAW;
+ spifc->SFC_INT_SW_CLR = intr_status; /* ??? */
+
+ if(intr_status & FC_INT_RAW_CMD_END)
+ {
+ return 0;
+ }
+ else
+ {
+ printf("intr status err.\n");
+ return -1;
+ }
+}
+
+uint32_t spifc_read_fifo(uint8_t *buf, uint32_t len)
+{
+ volatile struct spifc_nor_reg_t* spifc = (struct spifc_nor_reg_t*)SYS_SPI_NAND_BASE;
+ uint32_t *p = (uint32_t *)buf;
+ uint32_t cnt = 0;
+
+ int remainder_cnt = len % 4;
+
+ if(remainder_cnt != 0)
+ {
+ len = len + (4 - remainder_cnt);
+ }
+ else
+ {
+ remainder_cnt = 4;
+ }
+
+ while(cnt < (len>>2))
+ {
+ if(spifc->SFC_SW & (FC_RX_FIFO_CNT_MASK<<FC_RX_FIFO_CNT))//rx fifo not empty
+ {
+ p[cnt++]= spifc->SFC_DATA;
+ }
+ }
+
+ return ((cnt<<2) - (4 - remainder_cnt));
+}
+
+ void spifc_start(void)
+{
+ volatile struct spifc_nor_reg_t* spifc = (struct spifc_nor_reg_t*)SYS_SPI_NAND_BASE;
+
+ spifc->SFC_START |= FC_START;
+}
+
+spinor_cmd_t *cmd_seek(u8 opcode)
+{
+ int i;
+
+ for(i = 0; (&nor_cmd_table[i]) != NULL; i++)
+ {
+ if(opcode == nor_cmd_table[i].cmd)
+ {
+ return (&nor_cmd_table[i]);
+ }
+ }
+
+ return NULL;
+}
+
+int nor_read_reg(u8 opcode, int len, u8 *buf)
+{
+ int ret = 0;
+ spinor_cmd_t *cmd = NULL;
+
+ cmd = cmd_seek(opcode);
+ if(cmd == NULL)
+ {
+ printf("cmd_seek unkown cmd error.\n");
+ return -1;
+ }
+
+ spifc_setup_cmd(cmd, 0x0, len);
+ spifc_start();
+ ret = spifc_wait_cmd_end();
+ if(ret != 0)
+ {
+ printf("spifc_wait_cmd_end error.\n");
+ return ret;
+ }
+
+ ret = spifc_read_fifo(buf, len);
+ if(ret < 0)
+ {
+ printf("spifc_read_fifo error.\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+int nor_read_id(void)
+{
+ int tmp;
+ u8 id[SPI_NOR_MAX_ID_LEN];
+ const struct nor_info *info;
+
+ tmp = nor_read_reg(CMD_RDID, SPI_NOR_MAX_ID_LEN, id);
+ if(tmp < 0)
+ {
+ printf("error reading JEDEC ID\n");
+ return tmp;
+ }
+
+ for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++)
+ {
+ info = &spi_nor_ids[tmp];
+ if(info->id_len)
+ {
+ if(!memcmp(info->id, id, info->id_len))
+ {
+ spi_nor_flash = info;
+ return 0;
+ }
+ }
+ }
+ printf("unrecognized JEDEC id\n");
+ return -1;
+
+}
+
+int spi_nor_read(uint32_t from, size_t len, u_char *buf)
+{
+ int ret;
+ spinor_cmd_t *cmd = NULL;
+
+ cmd = cmd_seek(CMD_RDFT);
+ if(cmd == NULL)
+ {
+ printf("cmd_seek unkown error.\n");
+ return -1;
+ }
+
+ spifc_setup_cmd(cmd, from, len);
+ spifc_start();
+ ret = spifc_read_fifo(buf, len);
+ if(ret < 0)
+ {
+ printf("spifc_read_fifo error.\n");
+ return ret;
+ }
+
+ ret = spifc_wait_cmd_end();
+ if(ret != 0)
+ {
+ printf("spifc_wait_cmd_end error.\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+int nor_read(uint32_t from, uint32_t len, uint32_t to)
+{
+ int ret;
+ u32 page_offset, page_size, i;
+ struct nor_info *info = spi_nor_flash;
+
+ page_offset = from & (info->page_size - 1);
+
+ /* do all the bytes fit onto one page? */
+ if (page_offset + len <= info->page_size) {
+ ret = spi_nor_read(from, len, (uint8_t *)to);
+ } else {
+ /* the size of data remaining on the first page */
+ page_size = info->page_size - page_offset;
+ ret = spi_nor_read(from, page_size, (uint8_t *)to);
+
+ /* read everything in nor->page_size chunks */
+ for (i = page_size; i < len; i += page_size) {
+ page_size = len - i;
+ if (page_size > info->page_size)
+ page_size = info->page_size;
+
+ ret = spi_nor_read(from + i, page_size, ((uint8_t *)to + i));
+ }
+ }
+
+ return ret;
+}
+
+
+
+int nor_init(void)
+{
+ int ret = 0;
+
+ spifc_disable(); //hsy ?
+
+ spifc_enable();
+
+ ret = nor_read_id();
+ if(ret != 0)
+ {
+ return -1;
+ }
+
+ flash.flash_type = NOR_BOOT;
+ flash.page_size = spi_nor_flash->page_size;
+ flash.read = nor_read;
+
+ return 0;
+}
+
+/*
+ **********************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ **********************************************************************
+ */
+int board_flash_init(void)
+{
+ int ret = 0;
+ char boot_mode = 0;
+
+ boot_mode = get_boot_mode();
+ if(boot_mode != NOR_BOOT)
+ {
+ printf("not nor flash.\n");
+ return -1;
+ }
+
+ writel(CFG_START_MODE_NOR, CFG_BOOT_MODE_START_MODE_FOR_UBOOT);
+ ret = nor_init();
+ if(ret != 0)
+ {
+ printf("nor init err.\n");
+ return -1;
+ }
+
+ printf("nor init ok.\n");
+
+ return 0;
+}
+
+
+
diff --git a/boot/common/src/loader/drivers/nor.h b/boot/common/src/loader/drivers/nor.h
new file mode 100644
index 0000000..c3e81db
--- /dev/null
+++ b/boot/common/src/loader/drivers/nor.h
@@ -0,0 +1,204 @@
+
+#ifndef _SPIFC_H_
+#define _SPIFC_H_
+
+#define SYS_SPI_NAND_BASE 0x01407000
+
+struct spifc_nor_reg_t
+{
+ uint32_t VER_REG; //0x00
+ uint32_t SFC_START; //0x04
+ uint32_t SFC_EN; //0x08
+ uint32_t SFC_CTRL0; //0x0c
+ uint32_t SFC_CTRL1; //0x10
+ uint32_t SFC_CTRL2; //0x14
+ uint32_t SFC_BYTE_NUM; //0x18
+ uint32_t SFC_ADDR; //0x1c
+ uint32_t SFC_INS; //0x20
+ uint32_t SFC_TIMING; //0x24
+ uint32_t SFC_INT_EN; //0x28
+ uint32_t SFC_INT_RAW; //0x2c
+ uint32_t SFC_INT_SW_CLR; //0x30
+ uint32_t SFC_SW; //0x34
+ uint32_t SFC_DATA; //0x38
+};
+
+/*spifc start 0x4*/
+#define FC_START (1<<0)
+#define FC_BUSY (1<<0)
+
+/*spifc enable 0x8*/
+#define FC_EN_BACK (1)
+#define FC_EN (0)
+
+/*spifc main ctr0 0xc*/
+#define FC_SCLK_PAUSE_CLR_ALLOW (17)
+#define FC_SCLK_PAUSE_EN (16)
+#define FC_TXFIFO_CLR (15)
+#define FC_RXFIFO_CLR (14)
+#define FC_TXFIFO_THRES (10)
+#define FC_RXFIFO_THRES (6)
+#define FC_TX_DMA_EN (5)
+#define FC_RX_DMA_EN (4)
+#define FC_WDOG_EN (3)
+#define FC_SPI_MODE (1)
+#define FC_WR_PROTECT (0)
+
+/*spifc ctrl1 0x10 in the condition : SFC_EN = 1 SFC_BUSY = 0*/
+#define FC_ADDR_TX_EN (4)
+#define FC_DUMMY_TX_EN (2)
+#define FC_READ_DAT_EN (1)
+#define FC_WRITE_DAT_EN (0)
+
+/*spifc ctrl2 0x14*/
+#define FC_DUMMY_BYTE_NUM (12) /* [12:15} */
+#define FC_DUMMY_BIT_NUM (8) /* [8:10] */
+#define FC_ADDR_BYTE_NUM (5) /* [5:6] */
+#define FC_ADDR_MULTI_LINE_EN (4)
+#define FC_DAT_MULTI_LINE_EN (2)
+#define FC_TRANS_MOD (0)
+
+#define FC_ADDR_BYTE_NUM_8 (0)
+#define FC_ADDR_BYTE_NUM_16 (1)
+#define FC_ADDR_BYTE_NUM_24 (2)
+#define FC_ADDR_BYTE_NUM_32 (3)
+
+
+/*spifc timing 0x24*/
+#define FC_READ_DELAY (1<<16) /* [17:16} */
+#define FC_T_CS_SETUP (1<<11) /* [11:13} */
+#define FC_T_CS_HOLD (1<<6) /* [8:6} */
+#define FC_T_CS_DESEL (1<<0) /* [0:3} */
+
+
+/*spifc int enable 0x28*/
+#define FC_INT_EN_TX_BYD_THES (1<<7)
+#define FC_INT_EN_RX_BYD_THES (1<<6)
+#define FC_INT_EN_TX_UNDERRUN (1<<5)
+#define FC_INT_EN_RX_OVERRUN (1<<4)
+#define FC_INT_EN_WDOG_OVERRUN (1<<2)
+#define FC_INT_EN_FMT_ERR (1<<1)
+#define FC_INT_EN_CMD_END (1<<0)
+
+/*spifc raw interrupt 0x2c*/
+#define FC_INT_RAW_TX_BYD_THES (1<<7)
+#define FC_INT_RAW_RX_BYD_THES (1<<6)
+#define FC_INT_RAW_TX_UNDERRUN (1<<5)
+#define FC_INT_RAW_RX_OVERRUN (1<<4)
+#define FC_INT_RAW_WDOG_OVERRUN (1<<2)
+#define FC_INT_RAW_FMT_ERR (1<<1)
+#define FC_INT_RAW_CMD_END (1<<0)
+#define FC_INT_RAW_MASK (FC_INT_RAW_TX_UNDERRUN| \
+ FC_INT_RAW_RX_OVERRUN| \
+ FC_INT_RAW_WDOG_OVERRUN| \
+ FC_INT_RAW_FMT_ERR| \
+ FC_INT_RAW_CMD_END)
+
+
+/*spifc int startus and clr 0x30*/
+#define FC_INT_CLR_TX_BYD_THES (1<<7)
+#define FC_INT_CLR_RX_BYD_THES (1<<6)
+#define FC_INT_CLR_TX_UNDERRUN (1<<5)
+#define FC_INT_CLR_RX_OVERRUN (1<<4)
+#define FC_INT_CLR_WDOG_OVERRUN (1<<2)
+#define FC_INT_CLR_FMT_ERR (1<<1)
+#define FC_INT_CLR_CMD_END (1<<0)
+
+/*spifc sw 0x34*/
+#define FC_TX_FIFO_CNT (16) /* [16:20} */
+#define FC_TX_FIFO_CNT_MASK (0x1F) /* [8:12} */
+#define FC_RX_FIFO_CNT (8) /* [8:12} */
+#define FC_RX_FIFO_CNT_MASK (0x1F) /* [8:12} */
+#define FC_TX_BYD_THRES (1<<5)
+#define FC_RX_BYD_THRES (1<<4)
+#define FC_SCLK_PAUSE_FLAG (1<<3)
+#define FC_WAIT_FLAG (1<<2)
+#define FC_FORMAT_ERR (1<<1)
+
+
+#define FC_DMA_NONE 0
+#define FC_DMA_TX 1
+#define FC_DMA_RX 2
+
+
+#define TX_DMA_EN 1
+#define TX_DMA_DIS 0
+#define RX_DMA_EN 1
+#define RX_DMA_DIS 0
+#define ADDR_TX_EN 1
+#define ADDR_TX_DIS 0
+#define DATA_TX_EN 1
+#define DATA_TX_DIS 0
+#define DATA_RX_EN 1
+#define DATA_RX_DIS 0
+#define DUMY_TX_EN 1
+#define DUMY_TX_DIS 0
+#define ADDR_MULTI_LINE_EN 1
+#define ADDR_MULTI_LINE_DIS 0
+#define DATA_MULTI_LINE_EN 1
+#define DATA_MULTI_LINE_DIS 0
+#define TRANS_MOD_QUAD 1
+#define TRANS_MOD_DUAL 0
+#define TRANS_MOD_SINGLE 2
+
+
+#define ADDR_WIDTH_8 0
+#define ADDR_WIDTH_16 1
+#define ADDR_WIDTH_24 2
+#define ADDR_WIDTH_32 3
+
+
+
+typedef struct spinor_cmd
+{
+ u8 cmd;
+ u8 tx_dma_en;
+ u8 rx_dma_en;
+ u8 addr_tx_en;
+ u8 addr_byte_num;
+ u8 data_tx_en;
+ u8 data_rx_en;
+ u8 dumy_tx_en;
+ u8 dumy_byte_num;
+ u8 dumy_bit_num;
+ u8 addr_multi_line_en;
+ u8 data_multi_line_en;
+ u8 trans_mod;
+ u8 reserved[3];
+ u8 *info;
+}spinor_cmd_t;
+
+#define CMD_RDFT 0x0B
+#define CMD_RDID 0x9F
+
+
+#define SPI_NOR_MAX_ID_LEN 8
+
+struct nor_info {
+ char *name;
+
+ u8 id[SPI_NOR_MAX_ID_LEN];
+ u8 id_len;
+
+ unsigned sector_size;
+ u16 n_sectors;
+
+ u16 page_size;
+ u16 addr_width;
+
+ u16 flags;
+#define SECT_4K 0x01
+#define SPI_NOR_NO_ERASE 0x02
+#define SST_WRITE 0x04
+#define SPI_NOR_NO_FR 0x08
+#define SECT_4K_PMC 0x10
+#define SPI_NOR_DUAL_READ 0x20
+#define SPI_NOR_QUAD_READ 0x40
+#define USE_FSR 0x80
+};
+
+extern struct nor_info *spi_nor_flash;
+
+
+#endif /* _SPIFC_H_ */
+
diff --git a/boot/common/src/loader/drivers/sdio.c b/boot/common/src/loader/drivers/sdio.c
new file mode 100644
index 0000000..03b4acc
--- /dev/null
+++ b/boot/common/src/loader/drivers/sdio.c
@@ -0,0 +1,544 @@
+/*******************************************************************************
+* °æÈ¨ËùÓÐ (C)2010, ÉîÛÚÊÐÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
+*
+* ÎļþÃû³Æ£º sdio.c
+* ÄÚÈÝÕªÒª£º
+* ÆäËü˵Ã÷£º
+* µ±Ç°°æ±¾£º 1.0
+* ×÷¡¡¡¡Õߣºcaidaofang
+* Íê³ÉÈÕÆÚ£º
+*
+*
+*******************************************************************************/
+#include <common.h>
+#include <linux/byteorder/generic.h>
+#include <asm/io.h>
+#include <sdio.h>
+#include <image.h>
+
+
+#define SYS_STD_CRM_BASE 0x1307000
+#define DMA_BUFFER_SIZE_16K (0x2<<1)
+
+#define DMA_BUFFER_SIZE_32K (0x3<<1)
+#define DMA_BUFFER_SIZE_64K (0x4<<1)
+
+#define DMA_BUFFER_SIZE_256K (0x6<<1)
+#define DMA_BUFFER_SIZE_512K (0x7<<1)
+#define SDIO_ERR -1
+#define SDIO_INPROGRESS -2
+
+uint32_t uboot_entry_point = 0;
+
+static void sdio_clk_reset(void)
+{
+// enable sdio clk 16,17 hclk
+ REG32(SYS_STD_CRM_BASE+0x44) |= (0x3<<16);
+ usdelay(80);
+// release reset sdio clk 16 ahb clk
+ REG32(SYS_STD_CRM_BASE+0x48) |= (0x1<<16);
+ usdelay(80);
+}
+
+/*²ÉÓÃCPU¶ÁÈ¡FIFO£¬½ûÖ¹ÖжÏ*/
+static void sdio_initial_setup(void)
+{
+ u32 val = 0;
+ REG32(SDIO_SLAVE_IOREADY) |= 0x3e;//ÅäÖÃ1-5bit
+
+ REG32(SDIO_SLAVE_INTSTATUS_EN) = 0; //mask sdio int
+ REG32(SDIO_SLAVE_INTSTATUS) = 0xffffffff;//clear int
+
+ REG32(SDIO_SLAVE_INTSTATUS_EN) = 0xffffffff; //enable status int
+
+ //REG32(SDIO_SLAVE_INTSTATUS_EN) = 0x33C0181B; //enable status int
+ REG32(SDIO_SLAVE_INTSIGNAL_EN) = 0; //maskedÖжÏÐźÅ1£¬²»Éϱ¨¸øÖжϿØÖÆÆ÷
+ REG32(SDIO_SLAVE_INT_SIGNAL_EN2) = 0; //maskedÖжÏÐźÅ2£¬²»Éϱ¨¸øÖжϿØÖÆÆ÷
+ val = REG32(SDIO_SLAVE_SDIO_CCCR_CTRL);
+ REG32(SDIO_SLAVE_SDIO_CCCR_CTRL) = val;//0x3FF3E343;
+
+ REG32(0x1307080)= 0x7ffe0;
+
+ memset((u8*)0x20000000,0,1024*180);
+
+ val = REG32(SDIO_SLAVE_CARD_OCR);
+
+ REG32(SDIO_SLAVE_CARD_OCR) = val|0x01000000;
+
+/*dma*/
+ /*dma1 address register config*/
+ // REG32(SDIO_SLAVE_DMA1ADDR) = CFG_SDIO_LOAD_BASE; //set dma address
+ /*adma/dma1 address register and buffer size is 0:not valid 1:valid,buffer size is 4K(default)*/
+ // REG32(SDIO_SLAVE_DMA1CTRL) |=0x1|DMA_BUFFER_SIZE_256K; //enable dma address
+ /*disable adma£¬enable dma ,sel one*/
+ REG32(SDIO_SLAVE_CTRL2) &=(~0x4);
+
+/*sdio slave config ready operate*/
+ REG32(SDIO_SLAVE_CTRL) |=0x4; //ÅäÖõÚ2bit£¬±íʾ׼±¸²Ù×÷
+
+
+
+}
+
+int Sdio_Slave_Read_4K(const u32 load_addr,u32 len)
+{
+ u32 status =0 ;
+ int ret = 0;
+
+ u32 dma_addr = (u32)CFG_SDIO_LOAD_BASE;
+
+ REG32(SDIO_SLAVE_DMA1ADDR) = CFG_SDIO_LOAD_BASE; //CFG_SDIO_LOAD_BASE;
+ REG32(SDIO_SLAVE_DMA1CTRL) |= 0x1; //|DMA_BUFFER_SIZE_512K; //256K
+
+ while(1)
+ {
+ status = REG32(SDIO_SLAVE_INTSTATUS);
+
+ if((status &SDIO_STS_DMA1)!=0)
+ {
+
+ dma_addr += 0x1000;
+ /*1,mask*/
+ REG32(SDIO_SLAVE_INTSTATUS_EN)&=(~SDIO_STS_DMA1);
+ /*2,clear*/
+
+ REG32(SDIO_SLAVE_INTSTATUS) |= SDIO_STS_DMA1;
+ /*3,enalbe*/
+ REG32(SDIO_SLAVE_INTSTATUS_EN) |= SDIO_STS_DMA1;
+
+ REG32(SDIO_SLAVE_DMA1ADDR) = dma_addr ;//CFG_SDIO_LOAD_BASE;
+ REG32(SDIO_SLAVE_DMA1CTRL) |= 0x1;
+
+ }
+
+
+ if((status &SDIO_STS_TC)!=0)
+ {
+ // printf("SDIO xfer OK!\n");
+ break;
+ }
+
+ if((status &SDIO_STS_F_CRC_E)!=0)
+ {
+ printf("SDIO CRC Error!\n");
+
+ /*1,mask*/
+ REG32(SDIO_SLAVE_INTSTATUS_EN)&=(~SDIO_STS_F_CRC_E);
+ /*2,clear*/
+ REG32(SDIO_SLAVE_INTSTATUS) |= SDIO_STS_F_CRC_E;
+ /*3,enalbe*/
+ REG32(SDIO_SLAVE_INTSTATUS_EN) |= SDIO_STS_F_CRC_E;
+
+ ret = SDIO_ERR;
+ }
+
+ if((status &SDIO_STS_F_A)!=0)
+ {
+
+ /*1,mask*/
+ REG32(SDIO_SLAVE_INTSTATUS_EN)&=(~SDIO_STS_F_A);
+ /*2,clear*/
+ //status = REG32(SDIO_SLAVE_INTSTATUS);
+ REG32(SDIO_SLAVE_INTSTATUS) |= SDIO_STS_F_A;
+ /*3,enalbe*/
+ REG32(SDIO_SLAVE_INTSTATUS_EN) |= SDIO_STS_F_A;
+
+
+ printf("SDIO ABORT Xfer!\n");
+
+ }
+
+
+ }
+/*thansfer complete,write program done*/
+ REG32(SDIO_SLAVE_CTRL) |= 0x1;
+/*clear int status*/
+ /*1,mask*/
+ // REG32(SDIO_SLAVE_INTSTATUS_EN)&=(~(SDIO_STS_TC|SDIO_STS_WS|SDIO_STS_DMA1|SDIO_STS_F_A|SDIO_STS_F_CRC_E));
+
+ REG32(SDIO_SLAVE_INTSTATUS_EN) = 0;
+ /*2,clear*/
+ status = REG32(SDIO_SLAVE_INTSTATUS);
+ REG32(SDIO_SLAVE_INTSTATUS) = status;
+ /*3,enalbe*/
+ REG32(SDIO_SLAVE_INTSTATUS_EN) = 0xffffffff;
+
+ /*thansfer complete,write program done*/
+ // REG32(SDIO_SLAVE_CTRL) |= 0x1;
+
+ // REG32(SDIO_SLAVE_INTSTATUS_EN) = 0x33C0181B; //enable status int;
+ memcpy(load_addr,(u32)CFG_SDIO_LOAD_BASE,len);
+
+
+ return ret;
+}
+
+
+int Sdio_Slave_Write_Ack(void)
+{
+
+
+ u32 status = 0;
+ int ret = 0;
+
+ //u32 ack[2] = {0x11223344,0xAABBCCDD};
+ char *ack = "rxok";
+
+ memcpy((u32)CFG_SDIO_LOAD_BASE,ack,4);
+
+ printf("SDIO write ack\n");
+
+ REG32(SDIO_SLAVE_DMA1ADDR) = CFG_SDIO_LOAD_BASE;
+ REG32(SDIO_SLAVE_DMA1CTRL) |= 0x1;
+
+ while(1)
+ {
+ status = REG32(SDIO_SLAVE_INTSTATUS);
+
+
+ if((status &SDIO_STS_TC)!=0)
+ {
+ // printf("SDIO xfer OK!\n");
+ break;
+ }
+
+ if((status &SDIO_STS_F_CRC_E)!=0)
+ {
+ printf("SDIO CRC Error!\n");
+
+ /*1,mask*/
+ REG32(SDIO_SLAVE_INTSTATUS_EN)&=(~SDIO_STS_F_CRC_E);
+ /*2,clear*/
+ REG32(SDIO_SLAVE_INTSTATUS) |= SDIO_STS_F_CRC_E;
+ /*3,enalbe*/
+ REG32(SDIO_SLAVE_INTSTATUS_EN) |= SDIO_STS_F_CRC_E;
+
+ ret = SDIO_ERR;
+ }
+
+ if((status &SDIO_STS_F_A)!=0)
+ {
+
+ /*1,mask*/
+ REG32(SDIO_SLAVE_INTSTATUS_EN)&=(~SDIO_STS_F_A);
+ /*2,clear*/
+ //status = REG32(SDIO_SLAVE_INTSTATUS);
+ REG32(SDIO_SLAVE_INTSTATUS) |= SDIO_STS_F_A;
+ /*3,enalbe*/
+ REG32(SDIO_SLAVE_INTSTATUS_EN) |= SDIO_STS_F_A;
+
+
+ printf("SDIO ABORT Xfer!\n");
+
+ }
+
+
+ }
+/*thansfer complete,write program done*/
+ // REG32(SDIO_SLAVE_CTRL) |= 0x1;
+/*clear int status*/
+ /*1,mask*/
+
+ REG32(SDIO_SLAVE_INTSTATUS_EN) = 0;
+ /*2,clear*/
+ status = REG32(SDIO_SLAVE_INTSTATUS);
+ REG32(SDIO_SLAVE_INTSTATUS) = status;
+ /*3,enalbe*/
+ REG32(SDIO_SLAVE_INTSTATUS_EN) = 0xffffffff;
+
+ return ret;
+
+}
+
+
+static int sdio_slave_init(void)
+{
+
+ // SDIOÉèÖÃCPRMÄ£¿éµÄ´úÂë
+ //sdio_clk_reset();
+
+ // Initialize controller
+ sdio_initial_setup();
+
+
+
+}
+
+static int slave_size = 0;
+
+/************** success :return boot size ***********/
+int sdio_slave_read(const u32 load_addr)
+{
+ u32 dwInt_status = 0;
+ u32 dwCurrent_Cmd = 0;
+ u32 cmdreg =0;
+ u32 argreg = 0;
+ u32 cmd = 0;
+ u32 blksize = 0;
+ u32 blkcnt = 0;
+ u32 boot_size = 0;
+
+ int ret = SDIO_INPROGRESS;
+
+ while(1)
+ {
+ // dwCurrent_CmdΪ53ʱ£¬½øÐÐÊý¾Ýдor¶Á²Ù×÷
+
+ dwCurrent_Cmd = ((REG32(SDIO_SLAVE_CMD)>>13) & 0x3F);
+
+ switch(dwCurrent_Cmd)
+ {
+ case SDIO_CMD53:
+ {
+
+ dwInt_status = REG32(SDIO_SLAVE_INTSTATUS);
+
+
+ if((dwInt_status & SDIO_STS_WS) == SDIO_STS_WS)
+ {
+ cmdreg = REG32(SDIO_SLAVE_CMD);
+ argreg = REG32(SDIO_SLAVE_ARGU);
+
+ blksize = (cmdreg >>1) &0xFFF;
+
+ blkcnt = argreg & 0x1FF;
+
+ if(!(argreg & 0x08000000))
+ {
+
+ boot_size =blksize;
+ }
+ else
+ {
+ boot_size =blkcnt * blksize;
+ }
+
+ slave_size = boot_size;
+
+
+ ret = Sdio_Slave_Read_4K(load_addr,boot_size);
+
+ if(!ret)
+ return boot_size;
+ else if(ret == SDIO_ERR)
+ return SDIO_ERR;
+
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ }
+
+ return boot_size;
+}
+
+int sdio_slave_write(void)
+{
+
+
+ u32 dwInt_status = 0;
+ u32 dwCurrent_Cmd = 0;
+ u32 cmdreg =0;
+ u32 argreg = 0;
+ u32 cmd = 0;
+ u32 blksize = 0;
+ u32 blkcnt = 0;
+ u32 boot_size = 0;
+
+ int ret = SDIO_INPROGRESS;
+
+ printf("SDIO slave write \n");
+
+ REG32(SDIO_SLAVE_FUN1CTRL) |= (0x4 & 0xFFFF);
+
+ while(1)
+ {
+ dwCurrent_Cmd = ((REG32(SDIO_SLAVE_CMD)>>13) & 0x3F);
+
+ switch(dwCurrent_Cmd)
+ {
+ case SDIO_CMD53:
+ {
+
+ dwInt_status = REG32(SDIO_SLAVE_INTSTATUS);
+
+
+ if((dwInt_status & SDIO_STS_RS) == SDIO_STS_RS)
+ {
+ cmdreg = REG32(SDIO_SLAVE_CMD);
+ argreg = REG32(SDIO_SLAVE_ARGU);
+
+ blksize = (cmdreg >>1) &0xFFF;
+
+ blkcnt = argreg & 0x1FF;
+
+ if(!(argreg & 0x08000000))
+ {
+
+ boot_size =blksize;
+ }
+ else
+ {
+ boot_size =blkcnt * blksize;
+ }
+
+
+ ret = Sdio_Slave_Write_Ack();
+
+ if(!ret)
+ return boot_size;
+ else if(ret == SDIO_ERR)
+ return SDIO_ERR;
+
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+
+
+ }
+
+ return boot_size;
+
+}
+
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int sdio_slave_read_bin()
+{
+ int32_t len = 0;
+ uint32_t i =0;
+
+ /*1.µÚÒ»´Î½ÓÊÕ */
+ len = sdio_slave_read((u32)CFG_TEMP_ADDR);
+ if( len < 0 )
+ {
+ printf("sdio_slave: read first error\n");
+ goto sdio_error1;
+ }
+
+ /*2.»ñÈ¡°æ±¾ÐÅÏ¢ */
+ image_header_t *header = NULL;
+ header = (image_header_t *)CFG_TEMP_ADDR;
+ uint32_t header_size = sizeof(image_header_t);
+ uint32_t size = ___htonl(header->ih_size);
+ uint32_t load_addr = ___htonl(header->ih_load);
+ uboot_entry_point = ___htonl(header->ih_ep);
+
+ /*3.¿½±´µÚÒ»´ÎÊý¾Ý */
+ memcpy(load_addr, CFG_TEMP_ADDR+sizeof(image_header_t), len);
+ load_addr = load_addr + len - header_size;
+
+ /*4.¼ÆËã´«Êä´ÎÊý */
+ /* Èç¹ûµÚÒ»´Î´«ÊäµÄ×Ö½Ú´óÓÚ»òµÈÓÚ°æ±¾µÄ´óС£¬Ôò´«ÊäÍê³ÉÖ±½Ó·µ»Ø */
+ if( (len > size) || (len == size) )
+ {
+ printf("sdio_slave: first finsh and return\n");
+ return 0;
+ }
+
+ uint32_t left_times = size/CFG_SDIO_SLAVE_PACKAGE_LEN;
+ uint32_t mod = size%CFG_SDIO_SLAVE_PACKAGE_LEN;
+ if( mod == 0 )
+ {
+ left_times--;
+ }
+
+
+ /* debug */
+ printf("sdio_slave: display the transfer times\n");
+ for( i=0; i<left_times+1; i++ )
+ printf(" + ");
+ printf("\n");
+
+ /*5.½ÓÊÕÆäÓàµÄÊý¾Ý */
+ for( i=0; i<left_times; i++ )
+ {
+ len = sdio_slave_read(load_addr);
+ if( len < 0 )
+ {
+ printf("sdio_slave: read others error\n");
+ goto sdio_error1;
+ }
+ load_addr += len;
+ }
+
+ return 0;
+ sdio_error1:
+ return -1;
+}
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+void sdio_slave_process(void)
+{
+ int ret = 0;
+
+ //sdio_slave_init();
+ printf("run into sdio_slave_process\n");
+/* 1. ½ÓÊÕuboot */
+ ret = sdio_slave_read_bin();
+ if( ret != 0 )
+ {
+ printf("sdio_slave: read uboot error\n");
+ goto wait_error;
+ }
+ printf("sdio_slave: read uboot OK\n");
+
+
+
+ ret = sdio_slave_write();
+ if(ret > 0)
+ {
+
+ printf("sdio_slave: write ack success\n");
+ }
+
+
+
+ /* r7 Ìø×ªÆô¶¯´úÂë */
+ writel(0xE59ff000, 0x100000);
+ writel(uboot_entry_point, 0x100000 + 8);
+
+ printf("Start the uboot....\n");
+
+
+ writel(0xf, 0x130702c);
+
+ while(1);
+
+wait_error:
+ printf("sdio_slave: error wait\n");
+ while(1);
+}
+
diff --git a/boot/common/src/loader/drivers/secure_verify.c b/boot/common/src/loader/drivers/secure_verify.c
new file mode 100644
index 0000000..98eea5c
--- /dev/null
+++ b/boot/common/src/loader/drivers/secure_verify.c
@@ -0,0 +1,189 @@
+/*
+ ***********************************************************
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/string.h>
+#include <sdio.h>
+#include <image.h>
+#include <key.h>
+
+
+#include "efuse.h"
+#include "drv_rsa.h"
+#include "drv_hash.h"
+
+
+#define E_N_LEN 256
+#define HASH_LEN 128
+
+
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+static u8 data_cmp_word(u32* src, u32* dst, u32 cnt)
+{
+ u32 i;
+ for(i = 0; i < cnt; i++)
+ {
+ if(src[i] != dst[i])
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+int SecureVerify(u32 puiSdrmStartAddr)
+{
+ u32 uiLen = 0;
+ u32 uiRet = -1;
+ image_header_t *puiLegacyImgAddr = NULL;
+ sImageHeader *psImageHeader = NULL;
+ efuse_struct *psEfuseInfo = NULL;
+
+ u32 *puiDataLoadAddr = NULL;
+ u32 *puiArrPubKeyEN = NULL;
+ u32 *puiArrHASH = NULL;
+ u32 uiHashResArr[4] = {0};
+ u32 uiHashResLen = 0;
+ u32 uiHashVerifySize = 0;
+ u32 uiRsaResArr[32] = {0};
+ int guiEfuseStatus = 1;
+
+ u32 sRamKey[5] = {SECURE_EN,SECURE_PUK_HASH0,SECURE_PUK_HASH1,
+ SECURE_PUK_HASH2,SECURE_PUK_HASH3};
+
+ T_Rsa_Paramter sRSAInput;
+ u32 *puiRsaResAddr = NULL;
+
+ if(0 == puiSdrmStartAddr)
+ {
+ return -1;
+ }
+
+ psImageHeader = (sImageHeader *)puiSdrmStartAddr;
+ puiLegacyImgAddr = (image_header_t *)(puiSdrmStartAddr + sizeof(sImageHeader));
+ uiHashVerifySize = ___htonl(puiLegacyImgAddr->ih_size) + sizeof(image_header_t);
+
+ guiEfuseStatus = get_secure_verify_status();
+ if(guiEfuseStatus == 0) //efuse secure verify.
+ psEfuseInfo = (efuse_struct*)EFUSE_RAM_BASE;
+ else
+ psEfuseInfo = (efuse_struct*)sRamKey;
+
+ /*
+ * 0. ¼ì²éPubKeyÊÇ·ñ±»´Û¸Ä¡£
+ * - ¶ÔPubKeyÃ÷ÎĽøÐÐHASH_MD5ÔËË㣬
+ * ²¢ÇÒÓëefuseÖб£´æµÄpuk_hash±È½Ï¡£
+ * - ±È½ÏÊý¾ÝÏàͬ£¬·µ»Ø0£»
+ * - ²»Í¬£¬·µ»Ø1¡£
+ */
+ uiLen = E_N_LEN; //¹«Ô¿EºÍN£¬¹²256byte³¤¶È¡£
+ puiArrPubKeyEN = psImageHeader->uiPubKeyRsaE;
+
+ uiRet = Hash_Calculate(HASH_MODE_MD5,
+ HASH_SMALL_ENDIAN,
+ puiArrPubKeyEN,
+ uiLen,
+ NULL,
+ 0,
+ uiHashResArr,
+ &uiHashResLen);
+ if(uiRet != 0)
+ {
+ return -1;
+ }
+
+ if(data_cmp_word((u32 *)psEfuseInfo->puk_hash,
+ uiHashResArr, uiHashResLen))
+ {
+ printf("Puk hash verify fail!\n");
+ return -1;
+ }
+
+ puiArrHASH = psImageHeader->uiHashY;
+ uiLen = HASH_LEN;
+
+ /*
+ * 1. ÀûÓù«Ô¿¶ÔuiHashY'½øÐнâÃÜ£¬µÃµ½1024bit½á¹û¡£
+ */
+ sRSAInput.udCalMode = RSA_MOD_EXPO_WITH_INIT;
+ sRSAInput.udNbitLen = 1024;
+ sRSAInput.udEbitLen = 1024;
+ sRSAInput.pudInputM = puiArrHASH;
+ sRSAInput.pudInputE = puiArrPubKeyEN;
+ sRSAInput.pudInputN = (puiArrPubKeyEN + 32);
+ sRSAInput.pudOutputP = uiRsaResArr;
+
+ uiRet = Rsa_Calculate(sRSAInput);
+ if(uiRet != 0)
+ {
+ printf("Rsa_Calculate fail!\n");
+ return -1;
+ }
+
+ //È¡×îºó4×Ö½Ú×÷ΪPubKey½âÃܺóµÄHASH_MD5Öµ¡£
+ puiRsaResAddr = sRSAInput.pudOutputP + (32 - uiHashResLen);
+
+ /*
+ * 2. ¼ÆËãÏÂÒ»¼¶¾µÏñµÄHASH_MD5Öµ¡£
+ * - ¶ÔLegacyImage(64 BytesµÄÍ·ÐÅÏ¢+°æ±¾Çø)½øÐÐhash¼ÆË㣬
+ * ²¢ÇÒÓëPubKeyÑéÇ©µÄ½á¹û½øÐбȽϡ£
+ */
+ uiLen = uiHashVerifySize;
+ puiDataLoadAddr = (u32 *)(___htonl(puiLegacyImgAddr->ih_load)
+ - sizeof(image_header_t));
+
+ /* Cleanup Output Buffer. */
+ uiHashResLen = 0;
+ memset(uiHashResArr, 0, 4*sizeof(uiHashResArr[0]));
+
+ uiRet = Hash_Calculate(HASH_MODE_MD5,
+ HASH_SMALL_ENDIAN,
+ puiDataLoadAddr,
+ uiLen,
+ NULL,
+ 0,
+ uiHashResArr,
+ &uiHashResLen);
+ if(uiRet != 0)
+ {
+ printf("Hash_Calculate Fail!\n");
+ return -1;
+ }
+
+ if(data_cmp_word(puiRsaResAddr, uiHashResArr, uiHashResLen))
+ {
+ printf("SignImage Verify Fail!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+
diff --git a/boot/common/src/loader/drivers/spifc.c b/boot/common/src/loader/drivers/spifc.c
new file mode 100755
index 0000000..7703efd
--- /dev/null
+++ b/boot/common/src/loader/drivers/spifc.c
@@ -0,0 +1,867 @@
+/*********************************************************************
+ Copyright 2016 by ZXIC Corporation.
+*
+* FileName:: spifc.c
+* File Mark:
+* Description:
+* Others:
+* Version:
+* Author:
+* Date:
+
+* History 1:
+* Date:
+* Version:
+* Author:
+* Modification:
+* History 2:
+**********************************************************************/
+#include <common.h>
+#include <asm/arch/spifc.h>
+#include <asm/io.h>
+#include <bbt.h>
+
+#include "flash.h"
+
+
+static const struct spi_flash_device_para *spi_flash_info = NULL;
+/* spi flash parameter config */
+static const struct spi_flash_device_para spi_flash_para[] = {
+ /* GIGADEVICE GD5F1GQ4R 128MB 1.8V SPI-NAND */
+ {0xC8, 0xC1, 0x77, 2048, 11, 128, 17, 1024, 0x20000, 1},
+ /* GIGADEVICE GD5F1GQ5RExxG 128MB 1.8V SPI-NAND */
+ {0xC8, 0x41, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* GIGADEVICE GD5F2GQ4R 256MB SPI-NAND */
+ {0xC8, 0xC2, 0x77, 2048, 11, 128, 17, 2048, 0x20000, 1},
+ /* GIGADEVICE GD5F4GQ4U 512MB SPI-NAND */
+ {0xC8, 0xC4, 0x77, 4096, 12, 256, 18, 2048, 0x40000, 1},
+
+ /* PARAGON PN26Q01AWSIUG 128MB SPI-NAND */
+ {0xA1, 0xC1, 0x77, 2048, 11, 128, 17, 1024, 0x20000, 1},
+ /* PN26Q02AWSIUG 1.8V 2G-BIT SPI NAND */
+ {0xA1, 0xC2, 0x77, 2048, 11, 128, 17, 2048, 0x20000, 1},
+
+ /* HYF1GQ4IAACAE SPI-NAND */
+ {0xC9, 0x51, 0x77, 2048, 11, 128, 17, 1024, 0x20000, 1},
+ /* HYF2GQ4IAACAE SPI-NAND */
+ {0xC9, 0x52, 0x77, 2048, 11, 128, 17, 2048, 0x20000, 1},
+ /*winbond W25N01G*/
+ {0xEF, 0xBA, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /*winbond W25N02G*/
+ {0xEF, 0xBB, 0x77, 2048, 11, 64, 17, 2048, 0x20000, 1},
+ /* TOSHIBA TC58CYG0S3HRAIG 128MB SPI-NAND*/
+ {0x98, 0xB2, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* TOSHIBA TC58CYG1S3HRAIG 256MB SPI-NAND*/
+ {0x98, 0xBB, 0x77, 2048, 11, 64, 17, 2048, 0x20000, 1},
+ /* ZETTA ZD35X1GAXXX 128MB SPI-NAND*/
+ {0xBA, 0x21, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* DOSILICON DS35X1GAXXX 128MB SPI-NAND*/
+ {0xE5, 0x21, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* DOSILICON DS35X12BXXX 64MB SPI-NAND*/
+ {0xE5, 0xA5, 0x77, 2048, 11, 128, 17, 512, 0x20000, 1},
+ /* FUDANWEI FM25LS01 128MB SPI-NAND*/
+ {0xA1, 0xA5, 0x77, 2048, 11, 128, 17, 1024, 0x20000, 1},
+ /* hosin HG-SPIXGb-1XAIA 128MB SPI-NAND*/
+ {0xD6, 0x21, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* EMST F50D1G41LB (2M) 128MB SPI-NAND */
+ {0xC8, 0x11, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* FORESEE F35UQA001G 128MB SPI-NAND */
+ {0xCD, 0x61, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
+ /* FORESEE F35UQA512M 64MB SPI-NAND */
+ {0xCD, 0x60, 0x77, 2048, 11, 64, 17, 512, 0x20000, 1},
+ /* micron-MT29F2G01ABAGDWB-ITG 256MB SPI-NAND */
+ {0x2C, 0x25, 0x77, 2048, 11, 128, 17, 2048, 0x20000, 2},
+ /* ESMT F50D44G41XB (2X) 512MB SPI-NAND*/
+ {0x2C, 0x35, 0x77, 4096, 12, 256, 18, 2048, 0x40000, 1},
+ {0}
+};
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_enable
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+static void spifc_enable(void)
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+
+ if( spi->SFC_EN & FC_EN_BACK )
+ return;
+
+ spi->SFC_EN |= FC_EN;
+ spi->SFC_CTRL0 |= FC_SCLK_PAUSE_EN;
+}
+
+/*
+ ******************************************************************************
+ * Function: spifc_clear_fifo
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+void spifc_clear_fifo( void )
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+
+ spi->SFC_CTRL0 |= (FC_RXFIFO_THRES | FC_TXFIFO_THRES |
+ FC_RXFIFO_CLR | FC_TXFIFO_CLR);
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_setup_cmd
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+static void spifc_setup_cmd( struct spiflash_cmd_t *cmd,
+ uint32_t addr, uint32_t len )
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+ uint32_t wrap = 0;
+ uint32_t tmp = 0;
+
+ /* ÃüÁîÂë */
+ spi->SFC_INS = cmd->cmd;
+
+ /* Êý¾Ý³¤¶È */
+ if( len )
+ spi->SFC_BYTE_NUM = len - 1;
+ else
+ spi->SFC_BYTE_NUM = 0;
+
+ switch( len )
+ {
+ case 2048:
+ wrap = WRAP_SIZE_MAIN;
+ break;
+ case 2112:
+ wrap = WRAP_SIZE_MAIN_OOB;;
+ break;
+ case 64:
+ wrap = WRAP_SIZE_OOB;;
+ break;
+ default:
+ wrap = 0;
+ break;
+ }
+
+ /* µØÖ·Âë */
+ switch( spi->SFC_INS )
+ {
+ case CMD_READ_FROM_CACHE:
+ // case CMD_READ_FROM_CACHE_X2:
+ case CMD_READ_FROM_CACHE_X4:
+ case CMD_READ_FROM_CACHE_QIO:
+ case CMD_PROGRAM_LOAD:
+ case CMD_PROGRAM_LOAD_X4:
+ // case CMD_PROGRAM_LOAD_RANDOM:
+ // case CMD_PROGRAM_LOAD_RANDOM_X4:
+ //case CMD_PROGRAM_LOAD_RANDOM_QIO:
+ addr |= wrap;
+ break;
+
+ default:
+ addr = addr;
+ break;
+ }
+ spi->SFC_ADDR = addr;
+
+ /* µØÖ·Âë¡¢¿ÕÖÜÆÚ¡¢¶Á/д ʹÄÜÉèÖà */
+ spi->SFC_CTRL1 = 0;
+ spi->SFC_CTRL1 = ((cmd->addr_tx_en << FC_ADDR_TX_EN) |
+ (cmd->dumy_tx_en << FC_DUMMY_TX_EN) |
+ (cmd->data_rx_en << FC_READ_DAT_EN) |
+ (cmd->data_tx_en << FC_WRITE_DAT_EN));
+
+
+ /* ¿ÕÖÜÆÚÊý¡¢µØÖ·¿í¶È(1£¬2£¬3£¬4×Ö½Ú)¡¢
+ * µØÖ·/Êý¾ÝÏß¶È¡¢´«Êäģʽ
+ */
+#if 0
+ tmp = spi->SFC_CTRL2;
+ tmp &= 0x1f;
+ tmp |= ((cmd->dumy_bytes << FC_DUMMY_BYTE_NUM) |
+ (cmd->dumy_bits << FC_DUMMY_BIT_NUM) |
+ (cmd->addr_width << FC_ADDR_BYTE_NUM));
+ spi->SFC_CTRL2 = tmp;
+#else
+ spi->SFC_CTRL2 = 0;
+ tmp |= ((cmd->dumy_bytes << FC_DUMMY_BYTE_NUM) |
+ (cmd->dumy_bits << FC_DUMMY_BIT_NUM) |
+ (cmd->addr_width << FC_ADDR_BYTE_NUM));
+ tmp &= ~0x700;
+ spi->SFC_CTRL2 = tmp;
+#endif
+
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_clear_int
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+ void spifc_clear_int( void )
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+
+ if(spi->SFC_INT_RAW & 0x2)
+ printf("\n");
+
+ spi->SFC_INT_SW_CLR = 0xFF; //clear int ?
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_wait_cmd_end
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+static int spifc_wait_cmd_end( void )
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+ uint32_t int_status = 0;
+
+ while(!(spi->SFC_INT_RAW & FC_INT_RAW_MASK));
+
+ int_status = spi->SFC_INT_RAW;
+ spi->SFC_INT_SW_CLR = int_status; /* clear intrrupt */
+
+ if(int_status & FC_INT_RAW_CMD_END)
+ {
+ return 0;
+ }
+ else
+ {
+ printf("intr err.\n");
+ return -1;
+ }
+
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_read_fifo_one_byte
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ *
+ * Others: only for:
+ [Instruction] |--addr width is 8 bit
+ [addr] |--get feature
+ [data_rx]
+ *******************************************************************************
+ */
+static int spifc_read_fifo_one_byte( uint8_t *value )
+{
+ uint32_t sw = 0;
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+
+ sw = spi->SFC_SW;
+
+ if( ((sw >> FC_RX_FIFO_CNT) & FC_RX_FIFO_CNT_MASK) != 1 )
+ {
+ return -1;
+ }
+
+ *value = (uint8_t)spi->SFC_DATA;
+
+ return 0;
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_read_fifo
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+static uint32_t spifc_read_fifo( uint32_t len, uint8_t *buf )
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+ uint32_t *p = (uint32_t *)buf;
+ uint32_t cnt = 0;
+
+ while(cnt < ((len+3)>>2))
+ {
+ if(spi->SFC_SW & (FC_RX_FIFO_CNT_MASK<<FC_RX_FIFO_CNT))//rx fifo not empty
+ {
+ p[cnt++]= spi->SFC_DATA;
+ }
+ }
+
+ return (cnt<<2);
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_start
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+static void spifc_start( void )
+{
+ volatile struct spi_t* spi = (struct spi_t*)SYS_SPI_NAND_BASE;
+
+ spi->SFC_START |= FC_START;
+}
+
+/*
+ ******************************************************************************
+ * Function: spifc_get_feature
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ *
+ * Others: [Instruction] |--addr width is 8 bit
+ [addr] |--get feature
+ [data_rx] |--read id
+
+ *******************************************************************************
+ */
+ static int spifc_get_feature( uint32_t reg_addr, uint8_t *value)
+ {
+ int ret = 0;
+
+ struct spiflash_cmd_t cmd = {CMD_GET_FEATURE,
+ 1,
+ FC_ADDR_BYTE_NUM_8,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0
+ };
+
+ spifc_clear_fifo();
+ spifc_clear_int();
+
+ spifc_setup_cmd(&cmd, reg_addr, 1);
+ spifc_start();
+ ret = spifc_wait_cmd_end();
+ if(ret != 0)
+ {
+ return ret;
+ }
+
+ ret = spifc_read_fifo_one_byte(value);
+ if(ret != 0)
+ {
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ ******************************************************************************
+ * Function: spifc_read_id
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ *
+ * Others: [Instruction] |--addr width is 8 bit
+ [addr] |--get feature
+ [data_rx] |--read id
+ *******************************************************************************
+ */
+static int spifc_read_id(uint32_t reg_addr, uint8_t *value, uint8_t len)
+{
+ int ret = 0;
+
+ struct spiflash_cmd_t cmd = { CMD_READ_ID,
+ 1,
+ FC_ADDR_BYTE_NUM_8,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0
+ };
+
+ spifc_clear_fifo();
+ spifc_clear_int();
+ spifc_setup_cmd(&cmd, reg_addr, len);
+ spifc_start();
+ ret = spifc_wait_cmd_end();
+ if(ret != 0)
+ {
+ return ret;
+ }
+
+ ret = spifc_read_fifo(len, value);
+ if(ret != 0)
+ {
+ return ret;
+ }
+
+ return 0;
+}
+
+
+/*
+ ******************************************************************************
+ * Function: spifc_read_page_to_cache
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others: [Instruction] |--addr width is 24 bit(page/block addr!!!!)
+ [addr] |--page read
+ |--block erase
+ |--program execute
+ *******************************************************************************
+ */
+static int spifc_read_page_to_cache(uint32_t page_addr)
+{
+ int ret = 0;
+ uint8_t status = 0;
+
+ struct spiflash_cmd_t cmd = { CMD_READ_PAGE_TO_CACHE,
+ 1,
+ FC_ADDR_BYTE_NUM_24,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ };
+
+ spifc_clear_fifo();
+ spifc_clear_int();
+ spifc_setup_cmd(&cmd, page_addr, 0);
+ spifc_start();
+ ret = spifc_wait_cmd_end();
+ if(ret != 0)
+ {
+ return ret;
+ }
+
+ do
+ {
+ spifc_get_feature(REG_STATUS, &status);
+ }while( status & OIP);
+
+ return 0;
+}
+
+/*
+ ******************************************************************************
+ * Function: spifc_read_from_cache
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others: [Instruction] |--addr width is 16 bit
+ [addr] |--dummy cycel 8/4/2
+ [dummy] |--read form cache(X1,X2,X4)
+ [data_rx] |--read form cache(dual,quad)IO
+ *******************************************************************************
+ */
+static int spifc_read_from_cache(uint32_t column_addr, uint32_t len, uint8_t *buf)
+{
+ int ret = 0;
+
+ uint32_t len_tmp = 0;
+ struct spiflash_cmd_t cmd;
+
+ cmd.cmd = CMD_READ_FROM_CACHE;
+ cmd.dumy_bytes = 1;
+ cmd.dumy_bits = 0;
+ cmd.addr_tx_en = 1;
+ cmd.addr_width = FC_ADDR_BYTE_NUM_16;
+ cmd.data_tx_en = 0;
+ cmd.data_rx_en = 1;
+ cmd.dumy_tx_en = 1;
+
+ spifc_clear_fifo();
+ spifc_clear_int();
+ spifc_setup_cmd(&cmd, column_addr, len);
+ spifc_start();
+
+ len_tmp = spifc_read_fifo(len, buf);
+ if( len_tmp != len )
+ {
+ ret = -2;
+ return ret;
+ }
+
+ ret = spifc_wait_cmd_end();
+ if( ret != 0 )
+ {
+ return ret;
+ }
+
+ return 0;
+}
+
+
+/*
+ ******************************************************************************
+ * Function: nand_read_oob
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+void spifc_read_oob(uint8_t *buf, uint32_t offset, uint32_t len)
+{
+ uint32_t column_offset = spi_flash_info->page_size;
+ uint32_t page = offset >> (spi_flash_info->page_size_shift);
+ uint32_t blocks = offset >> (spi_flash_info->block_size_shift);
+
+ spifc_read_page_to_cache(page);
+
+ if((spi_flash_info->planes == 2) && ((blocks%2) != 0))
+ {
+ column_offset |= (0x1 << 12);
+ }
+ spifc_read_from_cache(column_offset, spi_flash_info->oob_size, buf);
+}
+
+
+/*
+ ******************************************************************************
+ * Function: read_page
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+int32_t spifc_read_page(uint32_t buf, uint32_t offset)
+{
+ int ret = 0;
+ uint8_t feature = 0x0;
+
+ uint32_t page = offset >> (spi_flash_info->page_size_shift);
+ uint32_t blocks = offset >> (spi_flash_info->block_size_shift);
+ uint32_t column_offset = 0;
+
+ if( (buf & 0x3) != 0 ) /* DMAµØÖ·ÒªÇó4×Ö½Ú¶ÔÆë */
+ {
+ printf("addr err.\n");
+ return -1;
+ }
+
+ ret = spifc_read_page_to_cache(page);
+ if( ret != 0 )
+ return ret;
+
+ ret = spifc_get_feature(REG_STATUS, &feature);
+ if(ret != 0)
+ return ret;
+
+ if((feature>>ECC_ERR_BIT & 0x3) == 0x2)
+ {
+ printf("ecc err.\n");
+ return -1;
+ }
+ if((spi_flash_info->planes == 2) && ((blocks%2) != 0))
+ {
+ column_offset |= (0x1 << 12);
+ }
+ ret = spifc_read_from_cache(column_offset, spi_flash_info->page_size, (uint8_t *)buf);
+ if(ret != 0)
+ return ret;
+
+ return 0;
+}
+
+/*
+ ******************************************************************************
+ * Function: read_page
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+int32_t spifc_read_page_raw(uint32_t buf, uint32_t offset)
+{
+ int ret = 0;
+ uint8_t feature = 0x0;
+
+ uint32_t page = offset >> (spi_flash_info->page_size_shift);
+
+ if( (buf & 0x3) != 0 ) /* DMAµØÖ·ÒªÇó4×Ö½Ú¶ÔÆë */
+ {
+ printf("addr err.\n");
+ return -1;
+ }
+
+ ret = spifc_read_page_to_cache(page);
+ if( ret != 0 )
+ return ret;
+
+ ret = spifc_read_from_cache(0, spi_flash_info->page_size, (uint8_t *)buf);
+ if(ret != 0)
+ return ret;
+
+ return 0;
+}
+
+
+/*
+ ******************************************************************************
+ * Function: nand_read
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others: from: must page align len: must page align
+ *******************************************************************************
+ */
+int32_t spifc_read(uint32_t from, uint32_t len, uint32_t to)
+{
+ uint32_t offset = from;
+ uint32_t left_to_read = len;
+ uint32_t p_to = to;
+ int32_t ret = 0;
+ int32_t page_size = (spi_flash_info->page_size);
+
+ if((offset & (page_size - 1)) || (len & (page_size - 1)) )
+ {
+ return -1;
+ }
+
+ while( left_to_read > 0 )
+ {
+ ret = spifc_read_page(p_to, offset);
+ if(ret != 0)
+ {
+ return -1;
+ }
+
+ left_to_read -= page_size;
+ offset += page_size;
+ p_to += page_size;
+ }
+ return 0;
+}
+
+
+/*******************************************************************************
+ * Function: nand_read_id
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ int32_t read_id (void)
+{
+ uint8_t id[4];
+ const struct spi_flash_device_para *spi_flash = &spi_flash_para[0];
+
+ spifc_read_id(0x0, id, 2);
+
+ while( spi_flash->manuf_id != 0 )
+ {
+ if( ((uint8_t)id[0] == spi_flash->manuf_id) &&
+ ((uint8_t)id[1] == spi_flash->device_id) )
+ {
+ spi_flash_info = spi_flash;
+ return 0;
+ };
+ spi_flash++;
+ }
+
+ return -1;
+}
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int32_t read_data(uint32_t from, uint32_t len, uint32_t to)
+{
+ uint32_t offset = from;
+ uint32_t left_to_read = len;
+ uint32_t p_to = to;
+ int32_t ret = 0;
+ int32_t block_size = (spi_flash_info->block_size);
+
+ while(left_to_read > 0)
+ {
+ uint32_t block_offset = offset & (block_size - 1);
+ uint32_t read_length;
+
+ if( nand_block_isbad(offset) )
+ {
+ offset += block_size;
+ continue;
+ }
+
+ if (left_to_read < (block_size - block_offset))
+ read_length = left_to_read;
+ else
+ read_length = block_size - block_offset;
+
+ ret = spifc_read(offset, read_length, p_to);
+ if(ret != 0)
+ {
+ return -1;
+ }
+
+ left_to_read -= read_length;
+ offset += read_length;
+ p_to += read_length;
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Function: nand_init
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int32_t spifc_init (void)
+{
+ int32_t ret = 0;
+ spifc_enable();
+ ret = read_id();
+ if(ret != 0)
+ {
+ printf("id err!\n");
+ return -1;
+ }
+
+ flash.flash_type = SPI_NAND_BOOT;
+ flash.manuf_id = spi_flash_info->manuf_id;
+ flash.device_id = spi_flash_info->device_id;
+ flash.page_size = spi_flash_info->page_size;
+ flash.page_size_shift = spi_flash_info->page_size_shift;
+ flash.oob_size = spi_flash_info->oob_size;
+ flash.block_size = spi_flash_info->block_size;
+ flash.block_size_shift = spi_flash_info->block_size_shift;
+ flash.block_num = spi_flash_info->block_num;
+ flash.read_page_raw = spifc_read_page_raw;
+ flash.read_oob = spifc_read_oob;
+ flash.read = read_data;
+
+ return 0;
+
+}
+
+/*
+ ******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+int board_flash_init(void)
+{
+ int ret = 0;
+ char boot_mode = 0;
+
+ printf("spi-nand:");
+
+ boot_mode = get_boot_mode();
+ if(boot_mode != SPI_NAND_BOOT)
+ {
+ printf("mode err.\n");
+ return -1;
+ }
+
+ writel(CFG_START_MODE_SPI_NAND, CFG_BOOT_MODE_START_MODE_FOR_UBOOT);
+ ret = spifc_init();
+ if(ret != 0)
+ {
+ printf("init err.\n");
+ return -1;
+ }
+ printf("init ok.\n");
+
+// nand_creat_bbt();
+nand_creat_ram_bbt();
+
+ return 0;
+}
+
+
diff --git a/boot/common/src/loader/drivers/type.h b/boot/common/src/loader/drivers/type.h
new file mode 100755
index 0000000..13fbe4b
--- /dev/null
+++ b/boot/common/src/loader/drivers/type.h
@@ -0,0 +1,58 @@
+/*******************************************************************************
+* °æÈ¨ËùÓÐ (C)2010, ÉîÛÚÊÐÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
+*
+* ÎļþÃû³Æ£º types.h
+* ÄÚÈÝÕªÒª£º Êý¾ÝÀàÐͶ¨Òå
+* ÆäËü˵Ã÷£º
+* µ±Ç°°æ±¾£º 1.0
+* ×÷¡¡¡¡Õߣº 177792
+* Íê³ÉÈÕÆÚ£º 2010-9-30
+*
+*
+*******************************************************************************/
+
+#ifndef __INCLUDE_TYPES_H
+#define __INCLUDE_TYPES_H
+#include <linux/types.h>
+#if 0
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+#endif
+
+typedef u8 BYTE;
+typedef u32 WORD32;
+typedef u16 WORD16;
+
+#if 0
+typedef int int32_t;
+typedef u32 uint32_t;
+typedef u16 uint16_t;
+typedef u8 uint8_t;
+#endif
+
+
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#define REG(x) (*(volatile u32*)(x))
+#define REG8(x) (*(volatile u8*)(x))
+#define REG16(x) (*(volatile u16*)(x))
+#define REG32(x) (*(volatile u32*)(x))
+#define DWC_READ_REG32(a) (*(volatile u32 *)(a))
+#define DWC_WRITE_REG32(a,v) ((*(volatile u32 *)(a)) = v)
+
+// ÏÂÃæÊÇGCC±àÒëÑ¡ÏÒå
+#define __weak__ __attribute__((weak))
+#define __aligned(x) __attribute__((aligned(x)))
+#define __align(x) __attribute__((aligned(x)))
+
+
+#endif
+
diff --git a/boot/common/src/loader/drivers/uart.c b/boot/common/src/loader/drivers/uart.c
new file mode 100644
index 0000000..420b8e0
--- /dev/null
+++ b/boot/common/src/loader/drivers/uart.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2016 ZXIC Inc.
+ *
+ */
+
+#include <common.h>
+#include <asm/arch/uart.h>
+#include <asm/io.h>
+#include <asm/arch/top_clock.h>
+#include <asm/arch/gpio.h>
+
+#define CONFIG_BAUDRATE 921600
+
+/*******************************************************************************
+ * Function: serial_gpio_config
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+static void serial_gpio_config(void)
+{
+#ifdef CONFIG_ZX297520V3E_CPE
+ unsigned int tmp = 0;
+ /*uart0_cts----->uart1_txd*/
+ __REG(PAD_TOP_FUNC_BASE+0x20) |= (1<<2);
+ tmp = __REG(PAD_PD_FUNC_BASE+0x4);
+ tmp &= ~(0x3<<2);
+ __REG(PAD_PD_FUNC_BASE+0x4) = tmp | (0x1<<2);
+
+ /*uart0_rts----->uart1_rxd*/
+ __REG(PAD_TOP_FUNC_BASE+0x20) |= (1<<3);
+ tmp = __REG(PAD_PD_FUNC_BASE+0x4);
+ tmp &= ~(0x3<<4);
+ __REG(PAD_PD_FUNC_BASE+0x4) = tmp | (0x1<<4);
+
+#endif
+}
+
+/*******************************************************************************
+ * Function:
+ * Description: ÉèÖô®¿ÚµÄ²¨ÌØÂÊ
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+static void serial_setbrg(void)
+{
+ u32 uartClk = 26000000;
+ u32 ibrd = uartClk / (CONFIG_BAUDRATE << 4);
+ u32 fbrd = (((uartClk-((ibrd*CONFIG_BAUDRATE)<<4))<<6)+(CONFIG_BAUDRATE<<3))/(CONFIG_BAUDRATE<<4);
+ __REG(UART_IBRD) = ibrd;
+ __REG(UART_FBRD) = fbrd;
+ #if 0
+ if( __REG(PLL_624_208_CFG0_REG) & PLL_624_208_CFG0_LOCK )
+ {
+ __REG(UART_IBRD) = 0x38;
+ __REG(UART_FBRD) = 0x1b;
+ }
+ else
+ {
+ __REG(UART_IBRD) = 0x2; /* midify !!! */
+ __REG(UART_FBRD) = 0x16;
+ }
+ #endif
+}
+
+
+/*******************************************************************************
+ * Function:
+ * Description: ³õʼ»¯´®¿Ú²ÎÊý 115200
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+void uart_init(void)
+{
+ int count = 3000;
+
+ while(__REG(UART_FR) & UART_FR_TXBUSY){
+
+ if(--count == 0)
+ {
+ break;
+ }
+ }
+
+ /* Òý½Å¸´ÓÃÉèÖà */
+ serial_gpio_config();
+
+ /* ½ûÓÃUART */
+ __REG(UART_ICR) = 0xffff;
+ __REG(UART_CR) &= (~(UART_EN | UART_TXE));
+
+
+
+ /* ²¨ÌØÂÊÉèÖà */
+ serial_setbrg();
+
+ /* ÉèÖô«Êä¸ñʽΪ: ÎÞУÑé/1λֹͣλ/8λÊý¾Ýλ/ʹÄÜ FIFO £»¼Ä´æÆ÷³õʼ»¯Îª 0x0 */
+ __REG(UART_LCR_H) &= (~(UART_BREAK | UART_PEN | UART_STP2 ));
+ __REG(UART_LCR_H) |= (UART_WLEN_8 | UART_FEN );
+
+ /* ÆÁ±ÎËùÓеÄuartÄ£¿é·¢³öµÄÖÐ¶Ï */
+ __REG(UART_IMSC) &= (~UART_INT_MASK);
+
+ /* ʹÄÜUART */
+ __REG(UART_CR) |= (UART_TXE | UART_EN );
+
+}
+
+
+
+/*******************************************************************************
+ * Function: uart_putc
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ void uart_putc(const char c)
+{
+ /* µÈ´ý·¢ËÍ FIFO ²»Âú£¬¿ÉÒÔдÊý¾Ý */
+ while ((__REG(UART_FR) & UART_TXFF) != 0 );
+ __REG(UART_DR) = c;
+
+ /* If \n, also do \r */
+ if (c == '\n')
+ uart_putc('\r');
+}
+
+
+/*******************************************************************************
+ * Function: uart_puts
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+void uart_puts (const char *s)
+{
+ while (*s) {
+ uart_putc (*s++);
+ }
+}
+
+/*******************************************************************************
+ * Function: uart_getc
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+char uart_getc(void)
+{
+ while ((__REG(UART_FR) & UART_RXFE) != 0 );
+ return (__REG(UART_DR) & 0xff);
+}
+
+/*******************************************************************************
+ * Function: uart_tstc
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int uart_tstc(void)
+{
+ if( __REG(UART_FR) & UART_RXFE )
+ return 0; //µÈÓÚ1ʱ£¬½ÓÊÕFIFOΪ¿Õ£¬Ã»ÓÐÊý¾Ý
+ else
+ return 1; //µÈÓÚ0ʱ£¬½ÓÊÕFIFO²»Îª¿Õ£¬ÓÐÊý¾Ý;
+}
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+
+int UART_Read(char *pchBuf, int dwLen)
+{
+ int i = 0;
+ for(i=0;i<dwLen;i++)
+ {
+ pchBuf[i] = (char)uart_getc();
+ }
+
+ return dwLen;
+}
+
+/*******************************************************************************
+ * Function:
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+
+int UART_Write(char *pchBuf, int dwLen)
+
+{
+ int i = 0;
+ for(i=0;i<dwLen;i++)
+ {
+ uart_putc(pchBuf[i]);
+ }
+
+ return dwLen;
+}
+
+int UART_Check_Sync(char *pchBuf, int dwLen)
+{
+ int ret = 0;
+ ret = UART_Read(pchBuf,1);
+
+ if(0x5A!=*pchBuf)
+ {
+ return 0;
+ }
+
+ return ret;
+}
+
+
+
diff --git a/boot/common/src/loader/drivers/usb.h b/boot/common/src/loader/drivers/usb.h
new file mode 100644
index 0000000..6f46be4
--- /dev/null
+++ b/boot/common/src/loader/drivers/usb.h
@@ -0,0 +1,628 @@
+/*
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lennart@augustsson.net) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Modified by Synopsys, Inc, 12/12/2007 */
+
+
+#ifndef _USB_H_
+#define _USB_H_
+
+#include <common.h>
+#include "type.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// T_LANGID_DESCRIPTOR
+#define LANGID_US_ENGLISH 0x0409
+
+// T_STRING_DESCRIPTOR
+#define MAX_STRING_LENGTH (0x20)//(0x100)
+
+typedef enum
+{
+
+ NEED_ENUM = 0,
+ DONOT_NEED_ENUM
+
+}T_USB_ENUM;
+
+/*usb´«ÊäÀàÐÍ*/
+typedef enum
+{
+ TRA_CTRL = 0,
+ TRA_BULK,
+ TRA_INTR,
+ TRA_ISO
+}T_USB_TRAN;
+
+/* USB¿ØÖÆ´«ÊäÃüÁî*/
+typedef struct
+{
+ BYTE bmRequestType;
+ BYTE bRequest;
+ WORD16 wValue;
+ WORD16 wIndex;
+ WORD16 wLength;
+}T_CTRL_COMMAND;
+
+
+// ¶ËµãÊý¾Ý°ü´óС
+typedef enum
+{
+ CONTROL_8 =8,
+ CONTROL_16 =16,
+ CONTROL_32 =32,
+ CONTROL_64 =64,
+
+ BULK_8 =8,
+ BULK_16 =16,
+ BULK_32 =32,
+ BULKL_64 =64
+}T_EP_PKT_SIZE;
+
+
+// CLEAR_FEATURE, SET_FEATURE
+#define FEATURE_DEVICE_REMOTE_WAKEUP (0x1)
+#define FEATURE_ENDPOINT_HALT (0x0)
+#define FEATURE_TEST_MODE (0x2)
+
+// ¸ù¾Ýʵ¼ÊÇé¿öÐÞ¸Ä
+#define USB_VENDOR_ID (0x19D2) // 2×Ö½Ú
+#define USB_PRODUCT_ID (0x0256) // 2×Ö½Ú
+#define PRODUCT_RELEASE_NUMBER (0x7510) // 2×Ö½Ú
+
+#define VERDOR_SPECIFIC (0xff)
+
+#define EP0_PACKET_SIZE CONTROL_64
+#define EP1_PACKET_SIZE 64
+#define EPX_PACKET_SIZE 64
+
+#define EP_FOR_IN 2
+#define EP_FOR_OUT 3
+
+
+/*usbÉ豸µÄÆß¸ö״̬*/
+typedef enum
+{
+ eUSB_ATTACHED = 0,
+ eUSB_POWERED,
+ eUSB_DEFAULT,
+ eUSB_SUSPEND,
+ eUSB_RUSUME,
+ eUSB_ADDRESS,
+ eUSB_CONFIG
+}E_USB_STATE;
+
+
+// ±ê×¼ÇëÇóÃüÁî
+typedef enum
+{
+ GET_STATUS =0x0,
+ CLEAR_FEATURE =0x1,
+ SET_FEATURE =0x3,
+ SET_ADDRESS =0x5,
+ GET_DESCRIPTOR =0x6,
+ SET_DESCRIPTOR =0x7,
+ GET_CONFIGURATION =0x8,
+ SET_CONFIGURATION =0x9,
+ GET_INTERFACE =0xa,
+ SET_INTERFACE =0xb,
+ SYNCH_FRAME =0xc
+}T_STANDARD_REQUST;
+
+
+// ÃèÊö·ûÀàÐÍ
+typedef enum
+{
+ DEVICE_DESCRIPTOR = 0x01,
+ CONFIG_DESCRIPTOR = 0x02,
+ STRING_DESCRIPTOR = 0x03,
+ INTERFACE_DESCRIPTOR= 0x04,
+ ENDPOINT_DESCRIPTOR = 0x05
+} T_DESCRIPTORS_TYPE;
+
+// USBÖ§³ÖµÄÌØÕ÷¶¨Òå
+typedef enum
+{
+ DEVICE_REMOTE_WAKEUP =1, // Device
+ ENDPOINT_HALT =0, // Endpoint
+ TEST_MODE =2 //Device
+}T_FEATURE;
+
+
+// bmAttributes
+#define ATTR_D7 (0x01 <<7) // ±ØÐëΪ1
+#define ATTR_SELF_POWERED (0x01 <<6) // ×Ô¹©µç
+#define ATTR_SUPPORT_REMOTE_WAKEUP (0x01 <<5) // Ô¶³Ì»½ÐÑ
+
+// bMaxPower
+#define POWER_MA(power) (power>>1) // µ¥Î»: 2mA
+
+#define EP_ADDRESS_DIRECTION_MASK (0x01 <<7) //Direction, ignored for control endpoints
+#define EP_ADDRESS_DIRECTION_IN (0x01 <<7)
+#define EP_ADDRESS_DIRECTION_OUT (0x0 <<7)
+
+
+//bmAttributes
+#define EP_ATTR_TRANSFER_TYPE_MASK (0x03 <<0)
+#define EP_ATTR_TRANSFER_TYPE_CONTROL (0 <<0)
+#define EP_ATTR_TRANSFER_TYPE_ISO (1 <<0)
+#define EP_ATTR_TRANSFER_TYPE_BULK (2 <<0)
+#define EP_ATTR_TRANSFER_TYPE_INTERRUPT (3 <<0)
+
+//ͬ²½´«Êä¶Ëµã, ×î´ó1023×Ö½Ú, ÂÖѯ¼ä¸ô---2^(bInterval -1)Ö¡
+#define MAX_ISO_PKT (256) //×î´ó1023×Ö½Ú
+#define MAX_ISO_R_INTERVAL (1) //ÂÖѯ¼ä¸ô---2^(bInterval -1)Ö¡
+#define MAX_ISO_T_INTERVAL (1) //ÂÖѯ¼ä¸ô---2^(bInterval -1)Ö¡
+
+//T_STRING_DESCRIPTOR, ascii to unicode---*2, length,type--+2
+#define STRING_DESCRIPTOR_SIZE(size) ((size*2)+2)
+//ת»»ascii×Ö·ûΪunicode×Ö·û
+#define UNICODE(ascii) ascii,0x00
+
+/**************************************************************************/
+typedef uint8_t uByte;
+typedef uint8_t uWord[2];
+typedef uint8_t uDWord[4];
+
+
+#define UT_GET_TYPE(a) ((a) & 0x60)
+#define UT_STANDARD 0x00
+#define UT_CLASS 0x20
+#define UT_VENDOR 0x40
+
+#define UT_GET_RECIPIENT(a) ((a) & 0x1f)
+#define UT_DEVICE 0x00
+#define UT_INTERFACE 0x01
+#define UT_ENDPOINT 0x02
+#define UT_OTHER 0x03
+/* Requests */
+#define UR_GET_STATUS 0x00
+#define USTAT_STANDARD_STATUS 0x00
+#define UR_CLEAR_FEATURE 0x01
+#define UR_SET_FEATURE 0x03
+#define UR_SET_ADDRESS 0x05
+#define UR_GET_DESCRIPTOR 0x06
+#define UR_SET_CONFIG 0x09
+/* Feature numbers */
+#define UF_ENDPOINT_HALT 0
+
+
+
+
+
+#define UE_GET_DIR(a) ((a) & 0x80)
+#define UE_SET_DIR(a,d) ((a) | (((d)&1) << 7))
+#define UE_DIR_IN 0x80
+#define UE_DIR_OUT 0x00
+#define UE_ADDR 0x0f
+#define UE_GET_ADDR(a) ((a) & UE_ADDR)
+
+
+#define USB_MAX_STRING_LEN 128
+#define USB_LANGUAGE_TABLE 0 /* # of the string language id table */
+
+/* Hub specific request */
+#define UR_GET_BUS_STATE 0x02
+#define UR_CLEAR_TT_BUFFER 0x08
+#define UR_RESET_TT 0x09
+#define UR_GET_TT_STATE 0x0a
+#define UR_STOP_TT 0x0b
+
+/* Hub features */
+#define UHF_C_HUB_LOCAL_POWER 0
+#define UHF_C_HUB_OVER_CURRENT 1
+#define UHF_PORT_CONNECTION 0
+#define UHF_PORT_ENABLE 1
+#define UHF_PORT_SUSPEND 2
+#define UHF_PORT_OVER_CURRENT 3
+#define UHF_PORT_RESET 4
+#define UHF_PORT_L1 5
+#define UHF_PORT_POWER 8
+#define UHF_PORT_LOW_SPEED 9
+#define UHF_PORT_HIGH_SPEED 10
+#define UHF_C_PORT_CONNECTION 16
+#define UHF_C_PORT_ENABLE 17
+#define UHF_C_PORT_SUSPEND 18
+#define UHF_C_PORT_OVER_CURRENT 19
+#define UHF_C_PORT_RESET 20
+#define UHF_C_PORT_L1 23
+#define UHF_PORT_TEST 21
+#define UHF_PORT_INDICATOR 22
+
+#define UHD_PWR 0x0003
+#define UHD_PWR_GANGED 0x0000
+#define UHD_PWR_INDIVIDUAL 0x0001
+#define UHD_PWR_NO_SWITCH 0x0002
+#define UHD_COMPOUND 0x0004
+#define UHD_OC 0x0018
+#define UHD_OC_GLOBAL 0x0000
+#define UHD_OC_INDIVIDUAL 0x0008
+#define UHD_OC_NONE 0x0010
+#define UHD_TT_THINK 0x0060
+#define UHD_TT_THINK_8 0x0000
+#define UHD_TT_THINK_16 0x0020
+#define UHD_TT_THINK_24 0x0040
+#define UHD_TT_THINK_32 0x0060
+#define UHD_PORT_IND 0x0080
+#define UHD_PWRON_FACTOR 2
+#define UHD_NOT_REMOV(desc, i) (((desc)->DeviceRemovable[(i)/8] >> ((i) % 8)) & 1)
+
+#define USB_HUB_DESCRIPTOR_SIZE 9 /* includes deprecated PortPowerCtrlMask */
+
+
+/* OTG feature selectors */
+#define UOTG_B_HNP_ENABLE 3
+#define UOTG_A_HNP_SUPPORT 4
+#define UOTG_A_ALT_HNP_SUPPORT 5
+
+/* Device status flags */
+#define UDS_SELF_POWERED 0x0001
+#define UDS_REMOTE_WAKEUP 0x0002
+/* Endpoint status flags */
+#define UES_HALT 0x0001
+
+
+
+#define UHS_LOCAL_POWER 0x0001
+#define UHS_OVER_CURRENT 0x0002
+
+
+
+#define UPS_CURRENT_CONNECT_STATUS 0x0001
+#define UPS_PORT_ENABLED 0x0002
+#define UPS_SUSPEND 0x0004
+#define UPS_OVERCURRENT_INDICATOR 0x0008
+#define UPS_RESET 0x0010
+#define UPS_PORT_POWER 0x0100
+#define UPS_LOW_SPEED 0x0200
+#define UPS_HIGH_SPEED 0x0400
+#define UPS_PORT_TEST 0x0800
+#define UPS_PORT_INDICATOR 0x1000
+#define UPS_C_CONNECT_STATUS 0x0001
+#define UPS_C_PORT_ENABLED 0x0002
+#define UPS_C_SUSPEND 0x0004
+#define UPS_C_OVERCURRENT_INDICATOR 0x0008
+#define UPS_C_PORT_RESET 0x0010
+
+
+/* Device class codes */
+#define UDCLASS_IN_INTERFACE 0x00
+#define UDCLASS_COMM 0x02
+#define UDCLASS_HUB 0x09
+#define UDSUBCLASS_HUB 0x00
+#define UDPROTO_FSHUB 0x00
+#define UDPROTO_HSHUBSTT 0x01
+#define UDPROTO_HSHUBMTT 0x02
+#define UDCLASS_DIAGNOSTIC 0xdc
+#define UDCLASS_WIRELESS 0xe0
+#define UDSUBCLASS_RF 0x01
+#define UDPROTO_BLUETOOTH 0x01
+#define UDCLASS_VENDOR 0xff
+
+/* Interface class codes */
+#define UICLASS_UNSPEC 0x00
+
+#define UICLASS_AUDIO 0x01
+#define UISUBCLASS_AUDIOCONTROL 1
+#define UISUBCLASS_AUDIOSTREAM 2
+#define UISUBCLASS_MIDISTREAM 3
+
+#define UICLASS_CDC 0x02 /* communication */
+#define UISUBCLASS_DIRECT_LINE_CONTROL_MODEL 1
+#define UISUBCLASS_ABSTRACT_CONTROL_MODEL 2
+#define UISUBCLASS_TELEPHONE_CONTROL_MODEL 3
+#define UISUBCLASS_MULTICHANNEL_CONTROL_MODEL 4
+#define UISUBCLASS_CAPI_CONTROLMODEL 5
+#define UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6
+#define UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7
+#define UIPROTO_CDC_AT 1
+
+#define UICLASS_HID 0x03
+#define UISUBCLASS_BOOT 1
+#define UIPROTO_BOOT_KEYBOARD 1
+
+#define UICLASS_PHYSICAL 0x05
+
+#define UICLASS_IMAGE 0x06
+
+#define UICLASS_PRINTER 0x07
+#define UISUBCLASS_PRINTER 1
+#define UIPROTO_PRINTER_UNI 1
+#define UIPROTO_PRINTER_BI 2
+#define UIPROTO_PRINTER_1284 3
+
+#define UICLASS_MASS 0x08
+#define UISUBCLASS_RBC 1
+#define UISUBCLASS_SFF8020I 2
+#define UISUBCLASS_QIC157 3
+#define UISUBCLASS_UFI 4
+#define UISUBCLASS_SFF8070I 5
+#define UISUBCLASS_SCSI 6
+#define UIPROTO_MASS_CBI_I 0
+#define UIPROTO_MASS_CBI 1
+#define UIPROTO_MASS_BBB_OLD 2 /* Not in the spec anymore */
+#define UIPROTO_MASS_BBB 80 /* 'P' for the Iomega Zip drive */
+
+#define UICLASS_HUB 0x09
+#define UISUBCLASS_HUB 0
+#define UIPROTO_FSHUB 0
+#define UIPROTO_HSHUBSTT 0 /* Yes, same as previous */
+#define UIPROTO_HSHUBMTT 1
+
+#define UICLASS_CDC_DATA 0x0a
+#define UISUBCLASS_DATA 0
+#define UIPROTO_DATA_ISDNBRI 0x30 /* Physical iface */
+#define UIPROTO_DATA_HDLC 0x31 /* HDLC */
+#define UIPROTO_DATA_TRANSPARENT 0x32 /* Transparent */
+#define UIPROTO_DATA_Q921M 0x50 /* Management for Q921 */
+#define UIPROTO_DATA_Q921 0x51 /* Data for Q921 */
+#define UIPROTO_DATA_Q921TM 0x52 /* TEI multiplexer for Q921 */
+#define UIPROTO_DATA_V42BIS 0x90 /* Data compression */
+#define UIPROTO_DATA_Q931 0x91 /* Euro-ISDN */
+#define UIPROTO_DATA_V120 0x92 /* V.24 rate adaption */
+#define UIPROTO_DATA_CAPI 0x93 /* CAPI 2.0 commands */
+#define UIPROTO_DATA_HOST_BASED 0xfd /* Host based driver */
+#define UIPROTO_DATA_PUF 0xfe /* see Prot. Unit Func. Desc.*/
+#define UIPROTO_DATA_VENDOR 0xff /* Vendor specific */
+
+#define UICLASS_SMARTCARD 0x0b
+
+/*#define UICLASS_FIRM_UPD 0x0c*/
+
+#define UICLASS_SECURITY 0x0d
+
+#define UICLASS_DIAGNOSTIC 0xdc
+
+#define UICLASS_WIRELESS 0xe0
+#define UISUBCLASS_RF 0x01
+#define UIPROTO_BLUETOOTH 0x01
+
+#define UICLASS_APPL_SPEC 0xfe
+#define UISUBCLASS_FIRMWARE_DOWNLOAD 1
+#define UISUBCLASS_IRDA 2
+#define UIPROTO_IRDA 0
+
+#define UICLASS_VENDOR 0xff
+
+#define USB_HUB_MAX_DEPTH 5
+
+/*
+ * Minimum time a device needs to be powered down to go through
+ * a power cycle. XXX Are these time in the spec?
+ */
+#define USB_POWER_DOWN_TIME 200 /* ms */
+#define USB_PORT_POWER_DOWN_TIME 100 /* ms */
+
+
+/* Allow for marginal (i.e. non-conforming) devices. */
+#define USB_PORT_RESET_DELAY 50 /* ms */
+#define USB_PORT_ROOT_RESET_DELAY 250 /* ms */
+#define USB_PORT_RESET_RECOVERY 250 /* ms */
+#define USB_PORT_POWERUP_DELAY 300 /* ms */
+#define USB_SET_ADDRESS_SETTLE 10 /* ms */
+#define USB_RESUME_DELAY (50*5) /* ms */
+#define USB_RESUME_WAIT 50 /* ms */
+#define USB_RESUME_RECOVERY 50 /* ms */
+#define USB_EXTRA_POWER_UP_TIME 20 /* ms */
+
+
+#define USB_MIN_POWER 100 /* mA */
+#define USB_MAX_POWER 500 /* mA */
+
+#define USB_BUS_RESET_DELAY 100 /* ms XXX?*/
+
+#define USB_UNCONFIG_NO 0
+#define USB_UNCONFIG_INDEX (-1)
+
+typedef struct usb_device_request_t
+{
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} __attribute__ ((__packed__)) usb_device_request_t;
+
+/*** ioctl() related stuff ***/
+
+#define USBD_SHORT_XFER_OK 0x04 /* allow short reads */
+#define USB_CURRENT_CONFIG_INDEX (-1)
+#define USB_CURRENT_ALT_INDEX (-1)
+
+
+
+typedef struct usb_endpoint_descriptor_t
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bEndpointAddress;
+ uint8_t bmAttributes;
+ uint16_t wMaxPacketSize;
+ uint8_t bInterval;
+} __attribute__ ((__packed__)) usb_endpoint_descriptor_t;
+
+#define USB_MAX_DEVNAMES 4
+#define USB_MAX_DEVNAMELEN 16
+#define USB_SPEED_UNKNOWN 0
+#define USB_SPEED_LOW 1
+#define USB_SPEED_FULL 2
+#define USB_SPEED_HIGH 3
+/*
+ * USB directions
+ *
+ * This bit flag is used in endpoint descriptors' bEndpointAddress field.
+ * It's also one of three fields in control requests bRequestType.
+ */
+#define USB_DIR_OUT 0 /* to device */
+#define USB_DIR_IN 0x80 /* to host */
+
+#define USB_DT_DEVICE 0x01
+#define USB_DT_CONFIG 0x02
+#define USB_DT_STRING 0x03
+#define USB_DT_INTERFACE 0x04
+#define USB_DT_ENDPOINT 0x05
+#define USB_DT_DEVICE_QUALIFIER 0x06
+#define USB_DT_OTHER_SPEED_CONFIG 0x07
+#define USB_DT_INTERFACE_POWER 0x08
+
+/***************************************************/
+// ±ê×¼½Ó¿ÚÃèÊö·û
+typedef struct dwc_interface_descriptor_t
+{
+ BYTE bLength;
+ BYTE bDescriptorType;
+ BYTE bInterfaceNumber;
+ BYTE bAlternateSetting;
+ BYTE bNumEndpoints;
+ BYTE bInterfaceClass;
+ BYTE bInterfaceSubClass;
+ BYTE bInterfaceProtocol;
+ BYTE iInterface;
+}__attribute__ ((__packed__)) dwc_interface_descriptor_t;
+
+
+// ±ê×¼¶ËµãÃèÊö·û
+typedef struct dwc_ep_descriptor_t
+{
+ BYTE bLength;
+ BYTE bDescriptorType;
+ BYTE bEndpointAddress;
+ BYTE bmAttributes;
+ WORD16 wMaxPacketSize;
+ BYTE bInterval;
+}__attribute__ ((__packed__)) dwc_ep_descriptor_t;
+
+
+// ×Ö·û´®ÃèÊö·û
+typedef struct dwc_langid_descriptor_t
+{
+ BYTE bLength;
+ BYTE bDescriptorType;
+ WORD16 wLANGID0;
+
+}__attribute__ ((__packed__)) dwc_langid_descriptor_t;
+
+typedef struct dwc_string_descriptor_t
+{
+ BYTE bLength;
+ BYTE bDescriptorType;
+ BYTE bString[MAX_STRING_LENGTH];
+
+}__attribute__ ((__packed__)) dwc_string_descriptor_t;
+
+// É豸ÃèÊö·û
+typedef struct dwc_device_descriptor_t
+{
+ BYTE bLength;
+ BYTE bDescriptorType;
+ WORD16 bcdUSB;
+ BYTE bDeviceClass;
+ BYTE bDeviceSubClass;
+ BYTE bDeviceProtocol;
+ BYTE bMaxPacketSize0;
+ WORD16 idVendor;
+ WORD16 idProduct;
+ WORD16 bcdDevice;
+ BYTE iManufacturer;
+ BYTE iProduct;
+ BYTE iSerialNumber;
+ BYTE bNumConfigurations;
+}__attribute__ ((__packed__)) dwc_device_descriptor_t;
+
+//device qualifierÃèÊö·û
+typedef struct dwc_dev_qual_descriptor_t
+{
+ BYTE bLength;
+ BYTE bDescriptorType;
+ WORD16 bcdUSB;
+ BYTE bDeviceClass;
+ BYTE bDeviceSubClass;
+ BYTE bDeviceProtocol;
+ BYTE bMaxPacketSize0;
+ BYTE bNumConfigurations;
+ BYTE Reserved;
+}__attribute__ ((__packed__)) dwc_dev_qual_descriptor_t;
+
+
+// ±ê×¼ÅäÖÃÃèÊö·û
+typedef struct dwc_config_descriptor_t
+{
+ BYTE bLength;
+ BYTE bDescriptorType;
+ WORD16 wTotalLength;
+ BYTE bNumInterfaces;
+ BYTE bConfigurationValue;
+ BYTE iConfiguration;
+ BYTE bmAttributes;
+ BYTE bMaxPower;
+}__attribute__ ((__packed__)) dwc_config_descriptor_t;
+
+typedef struct dwc_product_descriptor_t
+{
+ BYTE bLength;
+ BYTE bDescriptorType;
+ char Prod_Desc[98];
+} __attribute__ ((__packed__)) dwc_product_descriptor_t;
+
+//#define MAX_EPS (0x8)
+#define MAX_EPS (0x2)
+typedef enum
+{
+ USB_MAX_PACKET_SIZE_NOT_SET = 0,
+ USB_FULLSPEED_BULK_MAXSIZE = 64,
+ USB_HIGHSPEED_BULK_MAXSIZE = 512,
+}T_USB_MAX_PACKET_SIZE;
+
+typedef struct dwc_config_all_t
+{
+ dwc_config_descriptor_t tConfig;
+ dwc_interface_descriptor_t tInterface;
+ dwc_ep_descriptor_t atTxEP[1]; //·¢ËͶ˵ã(²»°üÀ¨ep0)
+ dwc_ep_descriptor_t atRxEP[1]; //½ÓÊն˵ã(²»°üÀ¨ep0)
+ dwc_interface_descriptor_t tInterface1;
+ dwc_ep_descriptor_t atTxEP1[1]; //·¢ËͶ˵ã(²»°üÀ¨ep0)
+ dwc_ep_descriptor_t atRxEP1[1]; //½ÓÊն˵ã(²»°üÀ¨ep0)
+}__attribute__ ((__packed__)) dwc_config_all_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _USB_H_ */
diff --git a/boot/common/src/loader/drivers/zx_mmc.c b/boot/common/src/loader/drivers/zx_mmc.c
new file mode 100644
index 0000000..057b6e9
--- /dev/null
+++ b/boot/common/src/loader/drivers/zx_mmc.c
@@ -0,0 +1,256 @@
+/*
+ * (C) Copyright 2003
+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <common.h>
+#include "zx_mmc.h"
+#include "type.h"
+#include <asm/io.h>
+#include <image.h>
+#include <linux/byteorder/generic.h>
+
+
+u32 mmc_rca;
+static u32 ocr_avail = 0;
+static u32 block_addr = 0;
+
+#define MMC_BLOCK_SIZE 512
+
+static u32 emmc_cmd(u32 cmd, u32 arg,
+ void *resp, u32 flags)
+{
+ u32 *response = resp;
+ u32 i,response_words = 0;
+ u32 status,err_status = ZXMCI_STS_RE | ZXMCI_STS_RCRC | ZXMCI_STS_RTO;
+ u32 cmdreg;
+
+ /*Clear all raw interrupt status*/
+ REG32(SYS_EMMC_REGS_BASE+ZXMCI_RINTSTS) = 0xffffffff;
+
+ cmdreg = cmd & ZXMCI_CMD_INDEX_MASK;
+ cmdreg |= flags | ZXMCI_CMD_START;
+
+ cmdreg |= (0x1 << 29);
+
+ if(flags & ZXMCI_CMD_RSPLEN)
+ {
+ response_words = 4;
+ }
+ else if(flags & ZXMCI_CMD_RSPEXP)
+ {
+ response_words = 1;
+ }
+
+ REG32(SYS_EMMC_REGS_BASE+ZXMCI_CMDARG) = arg;
+ REG32(SYS_EMMC_REGS_BASE+ZXMCI_CMD) = cmdreg;
+
+/*check command done*/
+ do {
+ status = REG32(SYS_EMMC_REGS_BASE+ZXMCI_RINTSTS);
+
+ } while (!(status & ZXMCI_STS_CD));
+/*check error*/
+ if(status & err_status)
+ {
+ printf("send cmd error\n");
+ return 1;
+ }
+
+ for(i = 0;i < response_words;i++)
+ {
+ response[i] = REG32(SYS_EMMC_REGS_BASE+ZXMCI_RESP0 + i*4);
+ }
+
+ return 0;
+}
+
+s32 zx_mmc_read(u32 src, u8 * dst, u32 size)
+{
+ u32 ret, i = 0,j = 0;
+ u32 resp;
+ u32 data;
+ u32 wordcount;
+ u32 *p = (u32 *)dst;
+ u32 status;
+ u32 start_addr;
+ u32 fifo_cnt;
+
+ if (size == 0)
+ return -1;
+
+ while((REG32(SYS_EMMC_REGS_BASE+ZXMCI_STATUS) & ZXMCI_STA_DATBUSY) != 0)
+ {
+ i++;
+ mmcdelay((80));
+ if(i>200)
+ break;
+ }
+
+
+ start_addr = src;
+
+
+ data = REG32(SYS_EMMC_REGS_BASE+ZXMCI_CTRL);
+ data |=(1<<1) ;
+ REG32(SYS_EMMC_REGS_BASE+ZXMCI_CTRL) = data;
+
+ i = 0;
+ do
+ {
+ i++;
+ mmcdelay((80));
+ if(i>100)
+ {
+ printf("fifo reset failure");
+ break;
+ }
+ }while(REG32(SYS_EMMC_REGS_BASE+ZXMCI_CTRL) & 2);
+
+
+ REG32(SYS_EMMC_REGS_BASE+ZXMCI_BYTCNT) = size;
+ REG32(SYS_EMMC_REGS_BASE+ZXMCI_BLKSIZ) = MMC_DEFAULT_BLKLEN;
+
+ if (size > MMC_DEFAULT_BLKLEN)
+ {
+ ret = emmc_cmd(MMC_CMD_READ_MULTIPLE_BLOCK,start_addr, &resp,(R1 | CF_DATA));
+ if (ret)
+ {
+ return -MMC_CMD_READ_MULTIPLE_BLOCK;
+ }
+ }
+ else
+ {
+ ret = emmc_cmd(MMC_CMD_READ_SINGLE_BLOCK,start_addr, &resp,(R1 | CF_DATA));
+ if (ret)
+ {
+ return -MMC_CMD_READ_SINGLE_BLOCK;
+ }
+ }
+
+ wordcount = 0;
+ do {
+
+ status = REG32(SYS_EMMC_REGS_BASE+ZXMCI_STATUS);
+ fifo_cnt =(status >> 17) & 0x1fff;
+ for(j = 0;j < fifo_cnt;j++)
+ {
+ data = REG32(SYS_EMMC_REGS_BASE+ZXMCI_FIFO);
+ *p++ = data;
+ wordcount++;
+ }
+
+ } while(wordcount < (size/4));
+
+ return 0;
+
+}
+
+static u32 mmc_bread(u32 dev_num, u32 blknr, u32 blkcnt, void *dst)
+{
+ u32 src = 0;
+ s32 ret;
+
+ if (block_addr == 0)
+ {
+ src = blknr * MMC_BLOCK_SIZE;
+ }
+ else
+ {
+ src = blknr;
+ }
+
+ ret = zx_mmc_read(src, (u8 *) dst, blkcnt * MMC_BLOCK_SIZE);
+ if (ret < 0)
+ {
+ printf("mmc read error\n");
+ return 1;
+ }
+
+ return blkcnt;
+}
+
+
+ void mmcdelay(unsigned long us)
+ {
+ volatile int i = 0; /* approximate */
+ for(i=0;i<5000;i++)
+ {
+ ;
+ }
+ }
+
+int mmc_read( u32 src, u32 length, void *dst)
+{
+ u32 blkcnt = 0;
+ u32 start_blk = 0;
+ int ret = 0;
+
+ if(length%MMC_DEFAULT_BLKLEN)
+ blkcnt = (length/MMC_DEFAULT_BLKLEN)+1;
+ else
+ blkcnt = (length/MMC_DEFAULT_BLKLEN);
+
+ start_blk = src/MMC_DEFAULT_BLKLEN;
+ block_addr = 1;
+
+ printf("entry mmc_bread\n");
+ ret = mmc_bread(0, start_blk, blkcnt, (void *)dst);
+
+ if(ret == blkcnt )
+ return 0;
+ else
+ return -1;
+
+}
+
+uint32_t page_align(uint32_t offset)
+{
+ uint32_t page_size = 2048;
+ if( offset & (page_size - 1) )
+ {
+ offset &= (~(page_size - 1));
+ offset += page_size;
+ }
+ return offset;
+}
+
+/*******************************************************************************
+ * Function: nand_init
+ * Description: mmc init
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int32_t mmc_init (void)
+{
+ return 0;
+
+}
+
+
diff --git a/boot/common/src/loader/drivers/zx_mmc.h b/boot/common/src/loader/drivers/zx_mmc.h
new file mode 100644
index 0000000..bee530d
--- /dev/null
+++ b/boot/common/src/loader/drivers/zx_mmc.h
@@ -0,0 +1,307 @@
+/*
+ * linux/drivers/mmc/mmc_pxa.h
+ *
+ * Author: Vladimir Shebordaev, Igor Oblakov
+ * Copyright: MontaVista Software Inc.
+ *
+ * $Id: mmc_pxa.h,v 0.3.1.6 2002/09/25 19:25:48 ted Exp ted $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __MMC_ZX_P_H__
+#define __MMC_ZX_P_H__
+
+#define SD_VERSION_SD 0x20000
+#define SD_VERSION_2 (SD_VERSION_SD | 0x20)
+#define SD_VERSION_1_0 (SD_VERSION_SD | 0x10)
+#define SD_VERSION_1_10 (SD_VERSION_SD | 0x1a)
+#define MMC_VERSION_MMC 0x10000
+#define MMC_VERSION_UNKNOWN (MMC_VERSION_MMC)
+#define MMC_VERSION_1_2 (MMC_VERSION_MMC | 0x12)
+#define MMC_VERSION_1_4 (MMC_VERSION_MMC | 0x14)
+#define MMC_VERSION_2_2 (MMC_VERSION_MMC | 0x22)
+#define MMC_VERSION_3 (MMC_VERSION_MMC | 0x30)
+#define MMC_VERSION_4 (MMC_VERSION_MMC | 0x40)
+
+#define MMC_MODE_HS 0x001
+#define MMC_MODE_HS_52MHz 0x010
+#define MMC_MODE_4BIT 0x100
+#define MMC_MODE_8BIT 0x200
+
+#define SD_DATA_4BIT 0x00040000
+
+#define IS_SD(x) (x->version & SD_VERSION_SD)
+
+#define MMC_DATA_READ 1
+#define MMC_DATA_WRITE 2
+
+#define NO_CARD_ERR -16 /* No SD/MMC card inserted */
+#define UNUSABLE_ERR -17 /* Unusable Card */
+#define COMM_ERR -18 /* Communications Error */
+#define TIMEOUT -19
+
+#define MMC_CMD_GO_IDLE_STATE 0
+#define MMC_CMD_SEND_OP_COND 1
+#define MMC_CMD_ALL_SEND_CID 2
+#define MMC_CMD_SET_RELATIVE_ADDR 3
+#define MMC_CMD_SET_DSR 4
+#define MMC_CMD_SWITCH 6
+#define MMC_CMD_SELECT_CARD 7
+#define MMC_CMD_SEND_EXT_CSD 8
+#define MMC_CMD_SEND_CSD 9
+#define MMC_CMD_SEND_CID 10
+#define MMC_CMD_STOP_TRANSMISSION 12
+#define MMC_CMD_SEND_STATUS 13
+#define MMC_CMD_SET_BLOCKLEN 16
+#define MMC_CMD_READ_SINGLE_BLOCK 17
+#define MMC_CMD_READ_MULTIPLE_BLOCK 18
+#define MMC_CMD_WRITE_SINGLE_BLOCK 24
+#define MMC_CMD_WRITE_MULTIPLE_BLOCK 25
+
+#define MMC_CMD_ERASE_GROUP_START 35
+#define MMC_CMD_ERASE_GROUP_END 36
+#define MMC_CMD_ERASE 38
+
+#define MMC_CMD_APP_CMD 55
+
+#define SD_CMD_SEND_RELATIVE_ADDR 3
+#define SD_CMD_SWITCH_FUNC 6
+#define SD_CMD_SEND_IF_COND 8
+
+#define SD_CMD_APP_SET_BUS_WIDTH 6
+#define SD_CMD_APP_SEND_OP_COND 41
+#define SD_CMD_APP_SEND_SCR 51
+
+/* SCR definitions in different words */
+#define SD_HIGHSPEED_BUSY 0x00020000
+#define SD_HIGHSPEED_SUPPORTED 0x00020000
+
+#define MMC_HS_TIMING 0x00000100
+#define MMC_HS_52MHZ 0x2
+
+#define OCR_BUSY 0x80000000
+#define OCR_HCS 0x40000000
+
+#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
+#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
+#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */
+#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */
+#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */
+#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */
+#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */
+#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */
+#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */
+#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */
+#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */
+#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */
+#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */
+#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */
+#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */
+#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */
+#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */
+
+#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
+#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits in EXT_CSD byte
+ addressed by index which are
+ 1 in value field */
+#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits in EXT_CSD byte
+ addressed by index, which are
+ 1 in value field */
+#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target byte to value */
+
+#define SD_SWITCH_CHECK 0
+#define SD_SWITCH_SWITCH 1
+
+/*
+ * EXT_CSD fields
+ */
+
+#define EXT_CSD_BUS_WIDTH 183 /* R/W */
+#define EXT_CSD_HS_TIMING 185 /* R/W */
+#define EXT_CSD_CARD_TYPE 196 /* RO */
+#define EXT_CSD_REV 192 /* RO */
+#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
+
+/*
+ * EXT_CSD field definitions
+ */
+
+#define EXT_CSD_CMD_SET_NORMAL (1<<0)
+#define EXT_CSD_CMD_SET_SECURE (1<<1)
+#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
+
+#define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */
+#define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */
+
+#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
+#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
+#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
+
+#define R1_ILLEGAL_COMMAND (1 << 22)
+#define R1_APP_CMD (1 << 5)
+
+#define MMC_RSP_PRESENT (1 << 0)
+#define MMC_RSP_136 (1 << 1) /* 136 bit response */
+#define MMC_RSP_CRC (1 << 2) /* expect valid crc */
+#define MMC_RSP_BUSY (1 << 3) /* card may send busy */
+#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */
+
+#define MMC_RSP_NONE (0)
+#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R1b (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE| \
+ MMC_RSP_BUSY)
+#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
+#define MMC_RSP_R3 (MMC_RSP_PRESENT)
+#define MMC_RSP_R4 (MMC_RSP_PRESENT)
+#define MMC_RSP_R5 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+
+
+struct mmc_cid {
+ unsigned long psn;
+ unsigned short oid;
+ unsigned char mid;
+ unsigned char prv;
+ unsigned char mdt;
+ char pnm[7];
+};
+
+
+#define MMC_DEFAULT_BLKLEN 512
+#define MMC_DEFAULT_RCA 1
+
+/*¼Ä´æÆ÷Æ«ÒÆ*/
+#define ZXMCI_CTRL (0x00)
+#define ZXMCI_PWREN (0x04)
+#define ZXMCI_CLKDIV (0x08)
+#define ZXMCI_CLKSRC (0x0C)
+#define ZXMCI_CLKENA (0x10)
+#define ZXMCI_TMOUT (0x14)
+#define ZXMCI_CTYPE (0x18)
+#define ZXMCI_BLKSIZ (0x1C)
+#define ZXMCI_BYTCNT (0x20)
+#define ZXMCI_INTMSK (0x24)
+#define ZXMCI_CMDARG (0x28)
+#define ZXMCI_CMD (0x2C)
+#define ZXMCI_RESP0 (0x30)
+#define ZXMCI_RESP1 (0x34)
+#define ZXMCI_RESP2 (0x38)
+#define ZXMCI_RESP3 (0x3C)
+#define ZXMCI_MINTSTS (0x40)
+#define ZXMCI_RINTSTS (0x44)
+#define ZXMCI_STATUS (0x48)
+#define ZXMCI_FIFOTH (0x4C)
+
+#define ZXMCI_CDETECT (0x50)
+#define ZXMCI_CDETECT_MASK (0x3fffffff)
+
+#define ZXMCI_WRTPRT (0x54)
+#define ZXMCI_GPIO (0x58)
+#define ZXMCI_TCBCNT (0x5C)
+#define ZXMCI_TBBCNT (0x60)
+#define ZXMCI_DEBNCE (0x64)
+#define ZXMCI_USRID (0x68)
+#define ZXMCI_VERID (0x6C)
+#define ZXMCI_HCON (0x70)
+#define ZXMCI_BMOD (0x80)
+#define ZXMCI_PLDMND (0x84)
+#define ZXMCI_DBADDR (0x88)
+#define ZXMCI_IDSTS (0x8C)
+#define ZXMCI_IDINTEN (0x90)
+#define ZXMCI_DSCADDR (0x94)
+#define ZXMCI_BUFADDR (0x98)
+#define ZXMCI_CARDRDTHRCTRL (0x100)
+
+#define ZXMCI_FIFO (0x200)
+
+#define ZXMCI_FIFO_DEPTH 128
+
+/*CTRL Register BIT*/
+#define ZXMCI_CTRL_OD_PULLUP (1 << 24)
+
+
+/*rintstsÖжÏ״̬¼Ä´æÆ÷*/
+#define ZXMCI_STS_CRC (1<<15) //End-bit error (read)/write no CRC
+#define ZXMCI_STS_ACD (1<<14) //auto command done
+#define ZXMCI_STS_SBE (1<<13) //Start-bit error
+#define ZXMCI_STS_HLE (1<<12) //Hardware locked write error
+#define ZXMCI_STS_FRUN (1<<11) //FIFO underrun/overrun error
+#define ZXMCI_STS_HTO (1<<10) //Data starvation-by-host timeout
+#define ZXMCI_STS_DRTO (1<<9) //Data read timeout
+#define ZXMCI_STS_RTO (1<<8) //Response timeout
+#define ZXMCI_STS_DCRC (1<<7) //Data CRC error
+#define ZXMCI_STS_RCRC (1<<6) //Response CRC error
+#define ZXMCI_STS_RXDR (1<<5) //Receive FIFO data request
+#define ZXMCI_STS_TXDR (1<<4) //Transmit FIFO data request
+#define ZXMCI_STS_DTO (1<<3) //Data transfer over Êý¾Ý´«ÊäÍê±Ï
+#define ZXMCI_STS_CD (1<<2) //Command done
+#define ZXMCI_STS_RE (1<<1) //Response error
+#define ZXMCI_STS_CDT (1<<0) //Card detect
+
+/*ÃüÁî¼Ä´æÆ÷*/
+#define ZXMCI_CMD_START (1U<<31) //Start command,Once command is taken by CIU, bit is cleared
+#define ZXMCI_CMD_CCS (1<<23) // 1= Interrupts are enabled in CE-ATA device
+#define ZXMCI_CMD_RCEATA (1<<22) // 1= Host is performing read access (RW_REG or RW_BLK)towards CE-ATA
+#define ZXMCI_CMD_UCREG (1<<21) //0= Normal command sequencregisters_only,1= Do not send commands
+#define ZXMCI_CMD_CNUM (1<<16) //Card number in use
+#define ZXMCI_CMD_SINIT (1<<15) // 1= Send initialization sequence before sending this comman
+#define ZXMCI_CMD_STOP (1<<14) // 1= Stop or abort command intended to stop current data transferin progress.
+#define ZXMCI_CMD_WAITC (1<<13) // 1= Wait for previous data transfer completion before sending command
+#define ZXMCI_CMD_SSTOP (1<<12) // 1= Send stop command at end of data transfe
+#define ZXMCI_CMD_TMODE (1<<11) //0= Block data transfer command,1= Stream
+#define ZXMCI_CMD_WRITE (1<<10) //0= Read from card,1= Write
+#define ZXMCI_CMD_DEXP (1<<9) //0= No data transfer expected (read/write)
+#define ZXMCI_CMD_CRSP (1<<8) // 1= Check response CRC
+#define ZXMCI_CMD_RSPLEN (1<<7) // 1= Long response expected from car,0=Short
+#define ZXMCI_CMD_RSPEXP (1<<6) // 1= Response expected from car
+#define ZXMCI_CMD_INDEX (1<<0) //Command index
+#define ZXMCI_CMD_INDEX_MASK 0x3f
+
+/*״̬¼Ä´æÆ÷*/
+#define ZXMCI_STA_DMAREQ (1<<31) //DMA request signal state
+#define ZXMCI_STA_DMAACK (1<<30) //DMA acknowledge signal state
+#define ZXMCI_STA_FIFOCNT (1<<17) //FIFO count= Number of filled locations in FIFO
+#define ZXMCI_STA_PRERSP (1<<11) //Index of previous response, including any auto-stop sent by core
+#define ZXMCI_STA_TMTBUSY (1<<10) //Data transmit or receive state-machine is busy
+#define ZXMCI_STA_DATBUSY (1<<9) //Inverted version of raw selected card_data[0],1=BUSY
+#define ZXMCI_STA_D3STA (1<<8) //Raw selected card_data[3];1=card present
+#define ZXMCI_STA_FSMSTA (1<<4) //Command FSM states
+#define ZXMCI_STA_FIFOFULL (1<<3) //FIFO is full status
+#define ZXMCI_STA_FIFOEMPTY (1<<2) //FIFO is empty status
+#define ZXMCI_STA_TXWMARK (1<<1) //µ½´ï·§ÖµÁËFIFO reached Transmit watermark level; not qualified with data transfer
+#define ZXMCI_STA_RXWMARK (1<<0) //FIFO reached Receive watermark level
+
+#define ZXMCI_STA_FSM_MASK (0xF0)
+#define ZXMCI_STA_FSM_POS (0x04)
+#define ZXMCI_STA_FSM_IDLE (0x00)
+
+
+//#define R1 (ZXMCI_CMD_RSPEXP /*| ZXMCI_CMD_CRSP*/)
+#define R1 (ZXMCI_CMD_RSPEXP | ZXMCI_CMD_CRSP)
+#define R1B (ZXMCI_CMD_RSPEXP | ZXMCI_CMD_CRSP)
+//#define R2 (ZXMCI_CMD_RSPEXP | /*ZXMCI_CMD_CRSP |*/ZXMCI_CMD_RSPLEN)
+#define R2 (ZXMCI_CMD_RSPEXP | ZXMCI_CMD_CRSP |ZXMCI_CMD_RSPLEN)
+#define R3 (ZXMCI_CMD_RSPEXP)
+#define R4 (ZXMCI_CMD_RSPEXP)
+#define R5 (ZXMCI_CMD_RSPEXP | ZXMCI_CMD_CRSP)
+#define R6 (ZXMCI_CMD_RSPEXP | ZXMCI_CMD_CRSP)
+#define R7 (ZXMCI_CMD_RSPEXP | ZXMCI_CMD_CRSP)
+#define CF_DATA (ZXMCI_CMD_DEXP | ZXMCI_CMD_WAITC | ZXMCI_CMD_SSTOP)
+#define CF_WR ZXMCI_CMD_WRITE
+
+#define ERR_STS (ZXMCI_STS_CRC | ZXMCI_STS_DCRC | ZXMCI_STS_RCRC)
+
+/*SD/MMC ²ÎÊý*/
+#define SYS_EMMC_REGS_BASE 0x01210000 //SD0
+#define CFG_EMMC_CLK_REF 26000000
+#define CFG_EMMC_CLK_ENUM 400000
+#define CFG_EMMC_CLK_WORK 26000000
+
+#define SYS_STD_CRM_BASE 0x1307000
+
+
+
+#endif /* __MMC_PXA_P_H__ */