/* 2009-08-20: File added and changed by Sony Corporation */
/*
 * mp200_udc.h -- for MP200 High speed USB device controller.
 *  This driver doesn't support OTG.
 *
 *  Copyright (C) NEC Electronics Corporation 2007
 *
 */

/*-------------------------------------------------------------------------*/
#ifndef __MP200_UDC_H
#define __MP200_UDC_H

//*****************************************************************************
// board choice
//*****************************************************************************
//#define		USE_EM1DS_BOARD		// EM1DS board
#define		USE_EM1ES_BOARD		// EM1ES board



//-----------------------------------------------------------------------------
// usually-OFF
//#define		USB_TRANS_DIVISION		// divide forward
#ifdef USB_TRANS_DIVISION
	#define	USB_DIVISION_SIZE		(512)
#endif	// USB_TRANS_DIVISION


#ifndef bool
 #define bool int
#endif

#ifndef TRUE
 #define TRUE 1
#endif

#ifndef FALSE
 #define FALSE 0
#endif

/*-------------------------------------------------------------------------*/

#ifdef DEBUG
 #define DBG(stuff...)		printk(KERN_DEBUG "udc: " stuff)
#else
 #define DBG(stuff...)		do{}while(0)
#endif

#ifdef VERBOSE
 #define VDBG			DBG
#else
 #define VDBG(stuff...)		do{}while(0)
#endif

#define ERR(stuff...)		printk(KERN_ERR "udc: " stuff)
#define WARN(stuff...)		printk(KERN_WARNING "udc: " stuff)
#define INFO(stuff...)		printk(KERN_INFO "udc: " stuff)

/*-------------------------------------------------------------------------*/
/*  BITs */
#define BIT00		(0x00000001)
#define BIT01		(0x00000002)
#define BIT02		(0x00000004)
#define BIT03		(0x00000008)
#define BIT04		(0x00000010)
#define BIT05		(0x00000020)
#define BIT06		(0x00000040)
#define BIT07		(0x00000080)
#define BIT08		(0x00000100)
#define BIT09		(0x00000200)
#define BIT10		(0x00000400)
#define BIT11		(0x00000800)
#define BIT12		(0x00001000)
#define BIT13		(0x00002000)
#define BIT14		(0x00004000)
#define BIT15		(0x00008000)
#define BIT16		(0x00010000)
#define BIT17		(0x00020000)
#define BIT18		(0x00040000)
#define BIT19		(0x00080000)
#define BIT20		(0x00100000)
#define BIT21		(0x00200000)
#define BIT22		(0x00400000)
#define BIT23		(0x00800000)
#define BIT24		(0x01000000)
#define BIT25		(0x02000000)
#define BIT26		(0x04000000)
#define BIT27		(0x08000000)
#define BIT28		(0x10000000)
#define BIT29		(0x20000000)
#define BIT30		(0x40000000)
#define BIT31		(0x80000000)

#define BIT31_28	(0xF0000000)
#define BIT27_24	(0x0F000000)
#define BIT23_20	(0x00F00000)
#define BIT19_16	(0x000F0000)
#define BIT15_12	(0x0000F000)
#define BIT11_08	(0x00000F00)
#define BIT07_04	(0x000000F0)
#define BIT03_00	(0x0000000F)

#define BIT31_24	(0xFF000000)
#define BIT23_16	(0x00FF0000)
#define BIT15_08	(0x0000FF00)
#define BIT07_00	(0x000000FF)

#define BIT31_16	(0xFFFF0000)
#define BIT15_00	(0x0000FFFF)

#define BIT31_00	(0xFFFFFFFF)

#define BIT31_30	(BIT31|BIT30)
#define BIT30_29	(BIT30|BIT29)
#define BIT29_28	(BIT29|BIT28)
#define BIT28_27	(BIT28|BIT27)
#define BIT27_26	(BIT27|BIT26)
#define BIT19_18	(BIT19|BIT18)
#define BIT15_14	(BIT15|BIT14)
#define BIT12_11	(BIT12|BIT11)
#define BIT11_10	(BIT11|BIT10)
#define BIT03_02	(BIT03|BIT02)
#define BIT01_00	(BIT01|BIT00)

#define BIT31_25	(0xFE000000)
#define BIT31_17	(0xFFFE0000)
#define BIT31_12	(0xFFFFF000)
#define BIT31_11	(0xFFFFE000)
#define BIT31_05	(0xFFFFFFE0)
#define BIT30_24	(0x7F000000)
#define BIT30_16	(0x7FFF0000)
#define BIT26_24	(0x07000000)
#define BIT26_16	(0x07FF0000)
#define BIT23_17	(0x00FE0000)
#define BIT23_00	(0x00FFFFFF)
#define BIT21_16	(0x003F0000)
#define BIT15_01	(0x0000FFFE)
#define BIT13_08	(0x00003F00)
#define BIT13_00	(0x00003FFF)
#define BIT12_08	(0x00001F00)
#define BIT11_00	(0x00000FFF)
#define BIT10_00	(0x000007FF)
#define BIT07_01	(0x000000FE)
#define BIT05_00	(0x0000003F)
#define BIT05_01	(0x0000003E)
#define BIT04_00	(0x0000001F)
#define BIT03_01	(0x0000000E)

#define UDC_LE16_GET_L(wValue)		((u8)(((le16_to_cpu(wValue))&(BIT07_00))>>0))
#define UDC_LE16_GET_H(wValue)		((u8)(((le16_to_cpu(wValue))&(BIT15_08))>>8))

/*-------------------------------------------------------------------------*/
#define UDC_CHG_PINSEL_USB		CHG_PINSEL_USB
#define UDC_CHG_PINSEL_USB_HZ		0x00000000
#define UDC_CHG_PINSEL_USB_USB		0x00000001

#define	UDC_USB_INT				INT_USB
#ifdef CONFIG_MP200_PWC
#define	UDC_VBUS_INT			INT_PWC_DETUSBINT
#define UDC_USB_WAKEUP_INT		INT_PWC_USBWAKINT
#endif /* CONFIG_MP200_PWC */

#define UDC_PHY_CS				GPIO_USB_CSN

//-----------------------------------------------------------------------------
#ifdef CONFIG_MP200_PWC
#define PWC_PSW_VBUS				(BIT05)

#define PWC_CLRFACT3_VBUS			(BIT07)
#define PWC_BMASK3_VBUS				(BIT07)

#define PWC_CLRFACT3_WAKEUP			(BIT04)
#define PWC_BMASK3_WAKEUP			(BIT04)

#define PWC_VBUS_FALLING_EDGE		(BIT07)
#define PWC_VBUS_RISING_EDGE		(BIT06)
#define PWC_DETMOD3H_VBUS_MASK		(PWC_VBUS_FALLING_EDGE|PWC_VBUS_RISING_EDGE)

#define PWC_WAKEUP_FALLING_EDGE		(BIT01)
#define PWC_WAKEUP_RISING_EDGE		(BIT00)
#define PWC_DETMOD3H_WAKEUP_MASK	(PWC_WAKEUP_FALLING_EDGE|PWC_WAKEUP_RISING_EDGE)

#define PWC_MODESET1_VUSBPS			(BIT03)

#define PHY_POWER_BIT				(BIT03)

#define POWER_SAVE_MODE_WAIT_TIME	(150)	// usec
#endif /* CONFIG_MP200_PWC */

#define VBUS_CHATTERING_MDELAY			1		// ms
#define VBUS_CHATTERING_RETRY_MDELAY	20		// ms
#define VBUS_POWER_SAVE_MODE_UDELAY		150		// us

#define UDC_PHY_CS_MDELAY				1		// ms
#ifdef CONFIG_MACH_PGPF
#define UDC_LINK_UNRESET_UDELAY			150		// us
#ifdef CONFIG_PGPF_USB_LOW_POWER_MODE_ENABLE
#define UDC_LOW_POWER_EXIT_MDELAY		5		// ms
#else /* CONFIG_PGPF_USB_LOW_POWER_MODE_ENABLE */
#define UDC_ULPI_ACCESS_MDELAY			5		// ms
#endif /* CONFIG_PGPF_USB_LOW_POWER_MODE_ENABLE */
#else /* CONFIG_MACH_PGPF */
#if 1	/* for SMSC */
#define UDC_LINK_UNRESET_MDELAY			4		// ms
#else
#define UDC_LINK_UNRESET_UDELAY			150		// us
#endif
#endif /* CONFIG_MACH_PGPF */


/*-------------------------------------------------------------------------*/
/* -------- (0x000) Identification Register */
/*  Read Only */
#define ID_REVISION			(BIT23_16)
#define ID_NID				(BIT13_08)
#define ID_ID				(BIT05_00)

/*  ------- (0x004) General Hardware Parameters */
/*  Read Only */
#define HWGENERAL_SM			(BIT09)
#define HWGENERAL_PHYM			(BIT08 | BIT07)
#define HWGENERAL_PHYW			(BIT06 | BIT05)
#define HWGENERAL_BWT			(BIT04 | BIT03)
#define HWGENERAL_CLKC			(BIT02 | BIT01)
#define HWGENERAL_RT			(BIT00)

/*  ------- (0x008) Host Hardware Parameters */
/*  Read Only */
#define HWHOST_TTPER			(BIT31_24)
#define HWHOST_TTASY			(BIT23_16)
#define HWHOST_NPORT			(BIT03_01)
#define HWHOST_HC			(BIT00)

/*  ------- (0x00C) Device Hardware Parameters */
/*  Read Only */
#define HWDEVICE_DEVEP			(BIT05_01)
#define HWDEVICE_DC			(BIT00)

/*  ------- (0x010) TX Buffer Hadware Parameters */
/*  Read Only */
#define HWTXBUF_TXLCR			(BIT31)
#define HWTXBUF_TXCHANADD		(BIT23_16)
#define HWTXBUF_TXADD			(BIT15_08)
#define HWTXBUF_TXBURST			(BIT07_00)

/*  ------- (0x014) RX Buffer Hadware Parameters */
/*  Read Only */
#define HWRXBUF_RXADD			(BIT15_08)
#define HWRXBUF_RXBURST			(BIT07_00)

/*  ------- (0x100) Capability Register Length & Host Interface Version Number */
/*  Read Only */
#define CH_CAPLENGTH			(BIT07_00)
#define CH_HCIVERSION			(BIT31_16)

/*  ------- (0x104) Host Control Structural Parameters */
/*  Read Only */
#define HCSPARAMS_N_TT			(BIT27_24)
#define HCSPARAMS_N_PTT			(BIT23_20)
#define HCSPARAMS_PI			(BIT16)
#define HCSPARAMS_N_CC			(BIT15_12)
#define HCSPARAMS_N_PCC			(BIT11_08)
#define HCSPARAMS_PPC			(BIT04)
#define HCSPARAMS_N_PORTS		(BIT03_00)

/*  ------- (0x108) Host Control Capability Parameters */
/*  Read Only */
#define HCCPARAMS_EECP			(BIT15_08)	/*  EHCI Extended Capabilities Pointer */
#define HCCPARAMS_IST			(BIT07_04)	/*  Isochronous Scheduling Threshold */
#define HCCPARAMS_ASP			(BIT02)		/*  Asynchronous Schedule Park Capability */
#define HCCPARAMS_PFL			(BIT01)		/*  Programmable Frame List Flag */
#define HCCPARAMS_ADC			(BIT00)		/*  64-bit Addressing Capability */

/*  ------- (0x080) General Purpose Timer 0 Load Register */
/*  Read/Write */
#define GPTIMER0LD_GPTLD		(BIT23_00)

/*  ------- (0x084) General Purpose Timer 0 Control Register */
/*  Read Only, Write Only, Read/Write */
#define GPTIMER0CTRL_GPTRUN		(BIT31)		/*  General Purpose Timer Run */
#define GPTIMER0CTRL_GPTRST		(BIT30)		/*  General Purpose Timer Reset */
#define GPTIMER0CTRL_GPTMODE		(BIT24)		/*  General Purpose Timer Mode */
#define GPTIMER0CTRL_GPTCNT		(BIT23_00)	/*  General Purpose Timer Counter */

/*  ------- (0x088) General Purpose Timer 1 Load Register */
/*  Read/Write */
#define GPTIMER1LD_GPTLD		(BIT23_00)

#define TIMER_COUNT_1_SEC	(1000*1000-1)
#define TIMER_COUNT_2_SEC	(1000*2000-1)

enum TIMER_MODE {
	TIMER_MODE_INIT=0,
	TIMER_MODE_SUSPEND,
	TIMER_MODE_RESUME,
	TIMER_MODE_END
};

/*  ------- (0x08C) General Purpose Timer 1 Control Register */
/*  Read Only, Write Only, Read/Write */
#define GPTIMER1CTRL_GPTRUN		(BIT31)			/*  General Purpose Timer Run */
#define GPTIMER1CTRL_GPTRST		(BIT30)			/*  General Purpose Timer Reset */
#define GPTIMER1CTRL_GPTMODE		(BIT24)			/*  General Purpose Timer Mode */
#define GPTIMER1CTRL_GPTCNT		(BIT23_00)		/*  General Purpose Timer Counter */

/*  ------- (0x120) Device Interface Version Number */
/*  Read Only */
#define DCIVERSION_DCIVERSION		(BIT15_00)

/*  ------- (0x124) Device Control Capability Parameters */
/*  Read Only */
#define DCCPARAMS_HC			(BIT08)			/*  Host Capable */
#define DCCPARAMS_DC			(BIT07)			/*  Device Capable */
#define DCCPARAMS_DEN			(BIT03_00)		/*  Device Endpoint Number */

/*  ------- (0x140) USB Command Register */
/*  Read Only, Write Only, Read/Write */
#define USBCMD_ITC			(BIT23_16)		/*  Inerrupt Threshold Control */
#define USBCMD_FS2			(BIT15)			/*  Frame List Size */
#define USBCMD_SUTW			(BIT13)			/*  Setup Trip Wire */
#define USBCMD_ATDTW			(BIT12)			/*  Add dTD TripWire */
#define USBCMD_ASPE			(BIT11)			/*  Asynchronous Schedule Park Mode Enable */
#define USBCMD_ASP			(BIT09_08)		/*  Asynchronous Schedule Park Mode Count */
#define USBCMD_LR			(BIT07)			/*  Light Host/Device Controller Reset */
#define USBCMD_IAA			(BIT06)			/*  Interrupt on Async Advanse Doorbell */
#define USBCMD_ASE			(BIT05)			/*  Asynchronous Schedule Enable */
#define USBCMD_PSE			(BIT04)			/*  Periodic Schedule Enable */
#define USBCMD_FS			(BIT03_02)		/*  Frame List Size */
#define USBCMD_RST			(BIT01)			/*  Controller Reset */
#define USBCMD_RS			(BIT00)			/*  Run/Stop */

#define USBCMD_ITC_01			(BIT16)

/*  ------- (0x144) USB Status Register */
/*  Read Only, Read/Write, -Clear */
#define USBSTS_TI1			(BIT25)			/*  General Purpose Timer Interrupt 1 */
#define USBSTS_TI0			(BIT24)			/*  General Purpose Timer Interrupt 0 */
#define USBSTS_UPI			(BIT19)			/*  USB Host Periodic Interrupt */
#define USBSTS_UAI			(BIT18)			/*  USB Host Asynchronous Inetrrupt */
#define USBSTS_NAKI			(BIT16)			/*  NAK Interrupt */
#define USBSTS_AS			(BIT15)			/*  Asynchronous Schedule Status */
#define USBSTS_PS			(BIT14)			/*  Periodic Schedule Status */
#define USBSTS_RCL			(BIT13)			/*  Reclamation */
#define USBSTS_HCH			(BIT12)			/*  HCHaited */
#define USBSTS_ULPII			(BIT10)			/*  ULPI Interrupt */
#define USBSTS_SLI			(BIT08)			/*  DC Suspend */
#define USBSTS_SRI			(BIT07)			/*  SOF Received */
#define USBSTS_URI			(BIT06)			/*  USB Reset Received */
#define USBSTS_AAI			(BIT05)			/*  Interrupt on Async Advance */
#define USBSTS_SEI			(BIT04)			/*  System Error */
#define USBSTS_FRI			(BIT03)			/*  Frame List Rollover */
#define USBSTS_PCI			(BIT02)			/*  Port Change Detect */
#define USBSTS_UEI			(BIT01)			/*  USB Error Interrupt */
#define USBSTS_UI			(BIT00)			/*  USB Interrupt */

/*  ------- (0x148) USB Interrupt Enable Register */
/*  Read/Write */
#define USBINTR_TIE1			(BIT25)			/*  General Purpose Timer Interrupt Enable 1 */
#define USBINTR_TIE0			(BIT24)			/*  General Purpose Timer Interrupt Enable 0 */
#define USBINTR_UPIE			(BIT19)			/*  USB Host Periodic Interrupt Enable */
#define USBINTR_UAIE			(BIT18)			/*  USB Host Asynchronous Inetrrupt Enable */
#define USBINTR_NAKE			(BIT16)			/*  NAK Interrupt Enable */
#define USBINTR_ULPIE			(BIT10)			/*  ULPI Interrupt Enable */
#define USBINTR_SLE			(BIT08)			/*  DC Suspend Enable */
#define USBINTR_SRE			(BIT07)			/*  SOF Received Enable */
#define USBINTR_URE			(BIT06)			/*  USB Reset Received Enable */
#define USBINTR_AAE			(BIT05)			/*  Interrupt on Async Advance Enable */
#define USBINTR_SEE			(BIT04)			/*  System Error Enable */
#define USBINTR_FRE			(BIT03)			/*  Frame List Rollover Enable */
#define USBINTR_PCE			(BIT02)			/*  Port Change Detect Enable */
#define USBINTR_UEE			(BIT01)			/*  USB Error Interrupt Enable */
#define USBINTR_UE			(BIT00)			/*  USB Interrupt Enable */

#define USB_FC_INT_ENABLE			(USBINTR_TIE1|USBINTR_SLE|USBINTR_URE|USBINTR_PCE|USBINTR_UEE|USBINTR_UE)
#define USB_FC_INT_SUS_ENABLE		(USB_FC_INT_ENABLE|USBINTR_SRE)


/*  ------- (0x14C) USB Frame Index Register */
/*    Host:Read/Write */
/*  Device:Read Only */
#define FRINDEX_FRINDEX			(BIT13_00)		/*  Frame Index */

/*  ------- (0x154) Host Controller Frame List Base Address */
/*  ------- (0x154) Device Controller USB Device Address */
/*  Read/Write */
#define PERIODICLISTBASE_PERBASE	(BIT31_12)		/*  Base Address(Low) */

#define DEVICEADDR_USBADR		(BIT31_25)		/*  Device Address */
#define DEVICEADDR_USBADR_SHIFT		(25)			/*  Device Address_Position */
#define DEVICEADDR_USBADRA		(BIT24)			/*  Device Address Advance */

/*  ------- (0x158) Host Controller next Asynchronous Address */
/*  ------- (0x158) Device Controller Endpoint List Address */
/*  Read/Write */
#define ASYNCLISTADDR_ASYBASE		(BIT31_05)		/*  Link Pointer Low(LPL) */

#define ENDPOINTLISTADDR_EPBASE		(BIT31_11)		/*  Endpoint List Pointer(Low) */

/*  ------- (0x15C) Host Controller Embedded TT Asynchronous Buffer Control */
/*  Read/Write */
#define TTCTRL_TTHA			(BIT30_24)

/*  ------- (0x160) Host Controller Embedded TT Asynchronous Buffer Status */
/*  Read/Write */
#define BURSTSIZE_TXPBURST		(BIT15_08)		/*  Programmable TX Burst Length */
#define BURSTSIZE_RXPBURST		(BIT07_00)		/*  Programmable RX Burst Length */

/*  ------- (0x164) TX Full Tuning */
/*  Read/Write */
#define TXFILLTUNING_TXFIFOTHRES	(BIT21_16)
#define TXFILLTUNING_TXSCHHEALTH	(BIT12_08)
#define TXFILLTUNING_TXSCHOH		(BIT07_00)

/*  ------- (0x170) ULPI Viewport */
/*  Read/Write */
#define ULPIVIEWPORT_ULPIWU		(BIT31)			/*  ULPI Wakeup */
#define ULPIVIEWPORT_ULPIRUN		(BIT30)			/*  ULPI Read/Write Run */
#define ULPIVIEWPORT_ULPIRW		(BIT29)			/*  ULPI Read/Write Control */
#define ULPIVIEWPORT_ULPISS		(BIT27)			/*  ULPI Sync State */
#define ULPIVIEWPORT_ULPIPORT		(BIT26_24)		/*  ULPI Port Number */
#define ULPIVIEWPORT_ULPIADDR		(BIT23_16)		/*  ULPI Data Address */
#define ULPIVIEWPORT_ULPIDATRD		(BIT15_08)		/*  ULPI Data Read */
#define ULPIVIEWPORT_ULPIDATWR		(BIT07_00)		/*  ULPI Data Write */

/*  ------- (0x178) Endpoint NACK Received */
/*  Read/Write Clear */
#define ENDPTNAK_TXEPTN			(BIT31_16)		/*  TX Endpoint NAK */
#define ENDPTNAK_RXEPTN			(BIT15_00)		/*  RX Endpoint NAK */

/*  ------- (0x17C) Endpoint NACK Received Interrupt Enable */
/*  Read/Write Clear */
#define ENDPTNAKEN_TXEPTNE		(BIT31_16)		/*  TX Endpoint NAK */
#define ENDPTNAKEN_RXEPTNE		(BIT15_00)		/*  RX Endpoint NAK */

/*  ------- (0x180) Configuration Flag Register */

/*  ------- (0x184_1A0) Port Status */
/*  ------- (0x184_1A0) Port Status Control */
/*  Read Only, Read/Write, R/WC */
#define PORTSC_PTS			(BIT31_30)		/*  Parallel Transceiver Select */
#define PORTSC_STS			(BIT29)			/*  Serial Transceiver Select */
#define PORTSC_PTW			(BIT28)			/*  Parallel Transceiver Wide */
#define PORTSC_PSPD			(BIT27_26)		/*  Port Speed */
#define PORTSC_PFSC			(BIT24)			/*  Port Force Full Speed Connect */
#define PORTSC_PHCD			(BIT23)			/*  PHY Low Power Suspned - Clock Disable */
#define PORTSC_WKOC			(BIT22)			/*  Wake on Over Current Enable */
#define PORTSC_WKDC			(BIT21)			/*  Wake on Disconnect Enable */
#define PORTSC_WKCN			(BIT20)			/*  Wake on Connect Enable */
#define PORTSC_PTC			(BIT19_16)		/*  Port Test Control */
#define PORTSC_PIC			(BIT15_14)		/*  Port Indicator Control */
#define PORTSC_PO			(BIT13)			/*  Port Owner */
#define PORTSC_PP			(BIT12)			/*  Port Power */
#define PORTSC_LS			(BIT11_10)		/*  Line Status */
#define PORTSC_HSP			(BIT09)			/*  High-Speed Port */
#define PORTSC_PR			(BIT08)			/*  Port Reset */
#define PORTSC_SUSP			(BIT07)			/*  Suspned */
#define PORTSC_FPR			(BIT06)			/*  Force Port Resume */
#define PORTSC_OCC			(BIT05)			/*  Over Current Change */
#define PORTSC_OCA			(BIT04)			/*  Over Current Active */
#define PORTSC_PEC			(BIT03)			/*  Port Enable/Disable Change */
#define PORTSC_PE			(BIT02)			/*  Port Enabled/Disabled */
#define PORTSC_CSC			(BIT01)			/*  Connect Status Change */
#define PORTSC_CCS			(BIT00)			/*  Current Connect Status */

#define PORTSC_PSPD_FS			(0)
#define PORTSC_PSPD_LS			(BIT26)
#define PORTSC_PSPD_HS			(BIT27)

/*  ------- (0x1A4) OTG Status Control Register */
/*  Read Only, Read/Write, R/WC */
#define OTGSC_DPIE			(BIT30)			/*  Data Pulse Interrupt Enable */
#define OTGSC_1msE			(BIT29)			/*  1 milisecond timer interrupt Enable */
#define OTGSC_BSEIE			(BIT28)			/*  B Session End Interrupt Enable */
#define OTGSC_BSVIE			(BIT27)			/*  B Session Valid Interrupt Enable */
#define OTGSC_ASVIE			(BIT26)			/*  A Session Valid Interrupt Enable */
#define OTGSC_AVVIE			(BIT25)			/*  A VBus Valid Interrupt Enable */
#define OTGSC_IDIE			(BIT24)			/*  USB ID Interrupt Enable */
#define OTGSC_DPIS			(BIT22)			/*  Data Pulse Interrupt Status */
#define OTGSC_1msS			(BIT21)			/*  1 milisecond timer interrupt Status */
#define OTGSC_BSEIS			(BIT20)			/*  B Session End Interrupt Status */
#define OTGSC_BSVIS			(BIT19)			/*  B Session Valid Interrupt Status */
#define OTGSC_ASVIS			(BIT18)			/*  A Session Valid Interrupt Status */
#define OTGSC_AVVIS			(BIT17)			/*  A VBus Valid Interrupt Status */
#define OTGSC_IDIS			(BIT16)			/*  USB ID Interrupt Status */
#define OTGSC_DPS			(BIT14)			/*  Data Bus Pulsing Status */
#define OTGSC_1msT			(BIT13)			/*  1 milisecond timer toggle */
#define OTGSC_BSE			(BIT12)			/*  B Session End */
#define OTGSC_BSV			(BIT11)			/*  B Session Valid */
#define OTGSC_ASV			(BIT10)			/*  A Session Valid */
#define OTGSC_AVV			(BIT09)			/*  A VBus Valid */
#define OTGSC_ID			(BIT08)			/*  USB ID */
#define OTGSC_HABA			(BIT07)			/*  Hardware Assist B-Disconnect to A-Connect */
#define OTGSC_HADP			(BIT06)			/*  Hardware Assist Data-Pulse-Write to Set */
#define OTGSC_IDPU			(BIT05)			/*  ID Pullup */
#define OTGSC_DP			(BIT04)			/*  Data Pulsing */
#define OTGSC_OT			(BIT03)			/*  OTG Termination */
#define OTGSC_HAAR			(BIT02)			/*  Hardware Assist Auto-Reset */
#define OTGSC_VC			(BIT01)			/*  VBUS Charge */
#define OTGSC_VD			(BIT00)			/*  VBUS Discharge */

#define OTG_INT_ENABLE			(OTGSC_BSEIE|OTGSC_BSVIE|OTGSC_ASVIE|OTGSC_AVVIE)
#define OTG_POWER_INT			(OTGSC_BSEIS|OTGSC_BSVIS|OTGSC_ASVIS|OTGSC_AVVIS)

/*  ------- (0x1A8) USB Deivce Mode Register */
/*  Read/Write, Read Only */
#define USBMODE_VBPS			(BIT05)			/*  VBus Power Select */
#define USBMODE_SDIS			(BIT04)			/*  Stream Disable Mode */
#define USBMODE_SLOM			(BIT03)			/*  Setup Lockout Mode */
#define USBMODE_ES			(BIT02)			/*  Endian Select */
#define USBMODE_CM			(BIT01_00)		/*  Controller Mode */

#define UDBMODE_CM_FC			(BIT01)			/*  Function Mode */
#define UDBMODE_CM_HC			(BIT01_00)		/*  Host Mode */

/*  ------- (0x1AC) Endpoint Setup Status Register */
/*  R/WC */
#define ENDPTSETUPSTAT_ENDPTSETUPSTAT	(BIT15_00)	/*  Setup Endpoint Status */
#define ENDPTSETUPSTAT_ENDPTSETUPSTAT_EP0	(BIT00)	/*  Setup Endpoint Status EP0 */

/*  ------- (0x1B0) Endpoint Initializetion Register */
/*  R/WS */
#define ENDPTPRIME_PETB			(BIT31_16)		/*  Prime Endpoint Transmit Buffer */
#define ENDPTPRIME_PERB			(BIT15_00)		/*  Prime Endpoint Receive Buffer */

/*  ------- (0x1B4) Endpoint De-Initialize Register */
/*  R/WS */
#define ENDPTFLUSH_FETB			(BIT31_16)		/*  Flush Endpoint Transmit Buffer */
#define ENDPTFLUSH_FERB			(BIT15_00)		/*  Flush Endpoint Receive Buffer */

/*  ------- (0x1B8) Endpoint Status Register */
/*  Read Only */
#define ENDPTSTATUS_ETBR		(BIT31_16)		/*  Endpoint Transmit Buffer Ready */
#define ENDPTSTATUS_ERBR		(BIT15_00)		/*  Endpoint Receive Buffer Ready */

/*  ------- (0x1BC) Endpoint Complete Register */
/*  R/WC */
#define ENDPTCOMPLETE_ETCE		(BIT31_16)		/*  Endpoint Transmit Complete Event(IN) */
#define ENDPTCOMPLETE_ERCE		(BIT15_00)		/*  Endpoint Receive Complete Event(OUT) */
#define ENDPTCOMPLETE_ETCE_SHIFT	(16)		/*  Endpoint Transmit Complete Event Position */
#define ENDPTCOMPLETE_ERCE_SHIFT	(0)			/*  Endpoint Receive Complete Event Position */

/* ENDPT_BIT_POS macro Introduction */
/*
static __inline__ u32
 ENDPT_BIT_POS(u8 bEndpointAddress)
{
	bit_pos = 1 << (bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);

	if((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN){
		bit_pos <<= ENDPTCOMPLETE_ETCE_SHIFT;
	}else{
		bit_pos <<= ENDPTCOMPLETE_ERCE_SHIFT;
	}
	return bit_pos;
}
*/

#define ENDPT_BIT_POS(bEndpointAddress)\
	((1 << ((bEndpointAddress) & USB_ENDPOINT_NUMBER_MASK)) \
		<< ( (((bEndpointAddress) & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) \
			? ENDPTCOMPLETE_ETCE_SHIFT : ENDPTCOMPLETE_ERCE_SHIFT))

/*  ------- (0x1C0) Endpoint Control Register */
/*  R/WC */
#define ENDPTCTRL_TXE			(BIT23)			/*  TX Endpoint Enable */
#define ENDPTCTRL_TXR			(BIT22)			/*  TX Data Toggle Reset */
#define ENDPTCTRL_TXI			(BIT21)			/*  TX Data Toggle inhibit */
#define ENDPTCTRL_TXT			(BIT19_18)		/*  TX Endpoint Type */
#define ENDPTCTRL_TXD			(BIT17)			/*  TX Endpoint Data Source */
#define ENDPTCTRL_TXS			(BIT16)			/*  TX Endpoint Stall */
#define ENDPTCTRL_RXE			(BIT07)			/*  RX Endpoint Enable */
#define ENDPTCTRL_RXR			(BIT06)			/*  RX Data Toggle Reset */
#define ENDPTCTRL_RXI			(BIT05)			/*  RX Data Toggle inhibit */
#define ENDPTCTRL_RXT			(BIT03_02)		/*  RX Endpoint Type */
#define ENDPTCTRL_RXD			(BIT01)			/*  RX Endpoint Data Sink */
#define ENDPTCTRL_RXS			(BIT00)			/*  RX Endpoint Stall */

#define ENDPTCTRL_TXT_SHIFT		(18)
#define ENDPTCTRL_RXT_SHIFT		(2)

/*  OTG Control Registers */
typedef struct _T_OTG_REGS {			/*  ----- offset */
	u32 ID;					/*  (0x000) Identification Register */
	u32 HWGENERAL;				/*  (0x004) General Hardware Parameters */
	u32 HWHOST;				/*  (0x008) Host Hardware Parameters */
	u32 HWDEVICE;				/*  (0x00C) Device Hardware Parameters */
	u32 HWTXBUF;				/*  (0x010) TX Buffer Hadware Parameters */
	u32 HWRXBUF;				/*  (0x014) RX Buffer Hadware Parameters */
	u32 HWTTTXBUF;				/*  (0x018) TT TX Buffer Hadware Parameters */
	u32 HWTTRXBUF;				/*  (0x01C) TT RX Buffer Hadware Parameters */
	u32 Reserved020[24];
	u32 GPTIMER0LD;				/*  (0x080) General Purpose Timer 0 Load Register */
	u32 GPTIMER0CTRL;			/*  (0x084) General Purpose Timer 0 Control Register */
	u32 GPTIMER1LD;				/*  (0x088) General Purpose Timer 1 Load Register */
	u32 GPTIMER1CTRL;			/*  (0x08C) General Purpose Timer 1 Control Register */
	u32 Reserved090[28];

	u32 CAPLENGTH_HCIVERSION;		/*  (0x100) Capability Register Length & Host Interface Version Number */
	u32 HCSPARAMS;				/*  (0x104) Host Control Structural Parameters */
	u32 HCCPARAMS;				/*  (0x108) Host Control Capability Parameters */
	u32 Reserved10C[5];
	u32 DCIVERSION;				/*  (0x120) Device Interface Version Number */
	u32 DCCPARAMS;				/*  (0x124) Device Control Capability Parameters */
	u32 Reserved128[6];

	u32 USBCMD;				/*  (0x140) USB Command Register */
	u32 USBSTS;				/*  (0x144) USB Status Register */
	u32 USBINTR;				/*  (0x148) USB Interrupt Enable Register */
	u32 FRINDEX;				/*  (0x14C) USB Frame Index Register */
	u32 Reserved150;
	u32 PERIODICLISTBASE_DEVICEADDR;	/*  (0x154) Host Controller Frame List Base Address */
						/*  (0x154) Device Controller USB Device Address */
	u32 ASYNCLISTADDR_ENDPOINTLISTADDR;	/*  (0x158) Host Controller next Asynchronous Address */
						/*  (0x158) Device Controller Endpoint List Address */
	u32 TTCTRL;				/*  (0x15C) Host Controller Embedded TT Asynchronous Buffer Control */
	u32 BURSTSIZE;				/*  (0x160) Host Controller Embedded TT Asynchronous Buffer Status */
	u32 TXFILLTUNING;			/*  (0x164) TX Full Tuning */
	u32 TXTTFILLTUNING;			/*  (0x168) TT TX Full Tuning */
	u32 Reserved16C;
	u32 ULPIVIEWPORT;			/*  (0x170) ULPI Viewport */
	u32 Reserved174;
	u32 ENDPTNAK;				/*  (0x178) Endpoint NACK Received */
	u32 ENDPTNAKEN;				/*  (0x17C) Endpoint NACK Received Interrupt Enable */
	u32 CONFIGFLAG;				/*  (0x180) Configuration Flag Register */
	u32 PORTSC[8];				/*  (0x184_1A0) Port Status */
	u32 OTGSC;				/*  (0x1A4) OTG Status Control Register */
	u32 USBMODE;				/*  (0x1A8) USB Deivce Mode Register */
	u32 ENDPTSETUPSTAT;			/*  (0x1AC) Endpoint Setup Status Register */
	u32 ENDPTPRIME;				/*  (0x1B0) Endpoint Initializetion Register */
	u32 ENDPTFLUSH;				/*  (0x1B4) Endpoint De-Initialize Register */
	u32 ENDPTSTATUS;			/*  (0x1B8) Endpoint Status Register */
	u32 ENDPTCOMPLETE;			/*  (0x1BC) Endpoint Complete Register */
	u32 ENDPTCTRL[16];			/*  (0x1C0) Endpoint Control Register */
} __attribute__ ((aligned(32))) T_OTG_REGS, *PT_OTG_REGS;


/*-------------------------------------------------------------------------*/
/*  Function Registers */
typedef struct _T_FC_REGS {
	u32 USBCMD;				/*  (0x140) USB Command Register */
	u32 USBSTS;				/*  (0x144) USB Status Register */
	u32 USBINTR;				/*  (0x148) USB Interrupt Enable Register */
	u32 FRINDEX;				/*  (0x14C) USB Frame Index Register */
	u32 Reserved150;
	u32 DEVICEADDR;				/*  (0x154) Device Controller USB Device Address */
	u32 ENDPOINTLISTADDR;			/*  (0x158) Device Controller Endpoint List Address */
	u32 TTCTRL;				/*  (0x15C) Host Controller Embedded TT Asynchronous Buffer Control */
	u32 BURSTSIZE;				/*  (0x160) Host Controller Embedded TT Asynchronous Buffer Status */
	u32 TXFILLTUNING;			/*  (0x164) TX Full Tuning */
	u32 TXTTFILLTUNING;			/*  (0x168) TT TX Full Tuning */
	u32 Reserved16C;
	u32 ULPIVIEWPORT;			/*  (0x170) ULPI Viewport */
	u32 Reserved174;
	u32 ENDPTNAK;				/*  (0x178) Endpoint NACK Received */
	u32 ENDPTNAKEN;				/*  (0x17C) Endpoint NACK Received Interrupt Enable */
	u32 CONFIGFLAG;				/*  (0x180) Configuration Flag Register */
	u32 PORTSC[8];				/*  (0x184_1A0) Port Status */
	u32 OTGSC;				/*  (0x1A4) OTG Status Control Register */
	u32 USBMODE;				/*  (0x1A8) USB Deivce Mode Register */
	u32 ENDPTSETUPSTAT;			/*  (0x1AC) Endpoint Setup Status Register */
	u32 ENDPTPRIME;				/*  (0x1B0) Endpoint Initializetion Register */
	u32 ENDPTFLUSH;				/*  (0x1B4) Endpoint De-Initialize Register */
	u32 ENDPTSTATUS;			/*  (0x1B8) Endpoint Status Register */
	u32 ENDPTCOMPLETE;			/*  (0x1BC) Endpoint Complete Register */
	u32 ENDPTCTRL[16];			/*  (0x1C0) Endpoint Control Register */
} __attribute__ ((aligned(32))) T_FC_REGS, *PT_FC_REGS;

/*-------------------------------------------------------------------------*/
/*  Host Registers */
typedef struct _T_HC_REGS {
	u32 USBCMD;				/*  (0x140) USB Command Register */
	u32 USBSTS;				/*  (0x144) USB Status Register */
	u32 USBINTR;				/*  (0x148) USB Interrupt Enable Register */
	u32 FRINDEX;				/*  (0x14C) USB Frame Index Register */
	u32 Reserved150;
	u32 PERIODICLISTBASE;			/*  (0x154) Host Controller Frame List Base Address */
	u32 ASYNCLISTADDR;			/*  (0x158) Host Controller next Asynchronous Address */
	u32 TTCTRL;				/*  (0x15C) Host Controller Embedded TT Asynchronous Buffer Control */
	u32 BURSTSIZE;				/*  (0x160) Host Controller Embedded TT Asynchronous Buffer Status */
	u32 TXFILLTUNING;			/*  (0x164) TX Full Tuning */
	u32 TXTTFILLTUNING;			/*  (0x168) TT TX Full Tuning */
	u32 Reserved16C;
	u32 ULPIVIEWPORT;			/*  (0x170) ULPI Viewport */
	u32 Reserved174;
	u32 ENDPTNAK;				/*  (0x178) Endpoint NACK Received */
	u32 ENDPTNAKEN;				/*  (0x17C) Endpoint NACK Received Interrupt Enable */
	u32 CONFIGFLAG;				/*  (0x180) Configuration Flag Register */
	u32 PORTSC[8];				/*  (0x184_1A0) Port Status */
	u32 OTGSC;				/*  (0x1A4) OTG Status Control Register */
	u32 USBMODE;				/*  (0x1A8) USB Deivce Mode Register */
	u32 ENDPTSETUPSTAT;			/*  (0x1AC) Endpoint Setup Status Register */
	u32 ENDPTPRIME;				/*  (0x1B0) Endpoint Initializetion Register */
	u32 ENDPTFLUSH;				/*  (0x1B4) Endpoint De-Initialize Register */
	u32 ENDPTSTATUS;			/*  (0x1B8) Endpoint Status Register */
	u32 ENDPTCOMPLETE;			/*  (0x1BC) Endpoint Complete Register */
	u32 ENDPTCTRL[16];			/*  (0x1C0) Endpoint Control Register */
} __attribute__ ((aligned(32))) T_HC_REGS, *PT_HC_REGS;

/*-------------------------------------------------------------------------*/
/*  Endpoint Qurere Head (dQH) */
#define EQH_MULTI			(BIT31_30)		/*  Multi */
#define EQH_ZLT				(BIT29)			/*  Zero Length Termination Select */
#define EQH_MAXPL			(BIT26_16)		/*  Maximum Packet Length */
#define EQH_SETUP_INT			(BIT15)			/*  Interrupt On Setup */

#define EQH_MPLENGTH_BIT_POS		(16)			/*  Isochronous Multi Pos */
#define EQH_MPS_ISO_MULTI_NONE		(BIT30)			/*  Isochronous Multi None */
#define EQH_MPS_ISO_MULTI_1ADD		(BIT31)			/*  Isochronous Multi 2 */
#define EQH_MPS_ISO_MULTI_2ADD		(BIT31_30)		/*  Isochronous Multi 3 */

#define EQH_CURR_DTD_PTR		(BIT31_05)		/*  Current dTD pointer */

#define EQH_NEXT_DTD_PTR		(BIT31_05)		/*  Next dTD pointer */
#define EQH_T				(BIT00)			/*  Terminate */

#define EQH_TOTAL_BYTES			(BIT30_16)		/*  Total Bytes */
#define EQH_COMPLETE_INT		(BIT15)			/*  Interrupt On Complete */
#define EQH_MULTI_OVER			(BIT11_10)		/*  Multiplier Override */
#define EQH_STATUS			(BIT07_00)		/*  Status */

#define EQH_BUF_PTR			(BIT31_12)		/*  Buffer Pointer */
#define EQH_CURR_OFFSET			(BIT11_00)		/*  Cuurent Offset */


typedef struct _T_ENDPOINT_QUEUE_HEAD {
	u32		max_length;		/*  Bits 16..26 Bit 15 is Interrupt */
						/*  On Setup */
	u32		curr_ptr;		/*  Current dTD Pointer */
	u32		next_ptr;		/*  Next dTD Pointer */
	u32		total_bytes;		/*  Total bytes (16..30), IOC (15) */
						/*  INT (8), STS (0-7) */
	u32		buf_ptr[5];		/*  Buffer pointer Page 0-4 */
	u32		RESERVED1;
	u32		setup_buf[2];		/*  8 bytes of setup data that follows the Setup PID */
	u32		RESERVED2[4];
} __attribute__ ((aligned(32))) T_ENDPOINT_QUEUE_HEAD, *PT_ENDPOINT_QUEUE_HEAD;


/*-------------------------------------------------------------------------*/
/*  Endpoint Transfer Descriptor (dTD) */
#define DTD_NEXT_LINK_PTR			(BIT31_05)		/*  Next Link Pointer */
#define DTD_T					(BIT00)			/*  Terminate */

#define DTD_TOTAL_BYTES				(BIT30_16)		/*  Total Bytes */
#define DTD_COMPLETE_INT			(BIT15)			/*  Interrupt On Complete */
#define DTD_MULTI_OVER				(BIT11_10)		/*  Multiplier Override */
#define DTD_STATUS				(BIT07_00)		/*  Status */

#define DTD_BUFFER_PTR				(BIT31_12)		/*  Buffer Pointer */
#define DTD_CURR_OFFSET				(BIT11_00)		/*  Cuurent Offset */
#define DTD_FRAME_NUMBER			(BIT10_00)		/*  Frame Number */

#define  DTD_NEXT_TERMINATE			(0x00000001)
#define  DTD_IOC				(0x00008000)
#define  DTD_STATUS_ACTIVE			(0x00000080)
#define  DTD_STATUS_HALTED			(0x00000040)
#define  DTD_RESERVED_FIELDS			(0x00007F00)
#define  DTD_ERROR_MASK				(0x68)
#define  DTD_ADDR_MASK				(0xFFFFFFE0)
#define  DTD_LENGTH_BIT_POS			(16)
#define  DTD_STATUS_DATA_BUFFER_ERR		(BIT05)
#define  DTD_STATUS_TRANSACION_ERR		(BIT03)

typedef struct _T_EP_TRANS_DESC {
	u32		next_ptr;			/*  Next Link Pointer */
							/*  Terminate */
	u32		total_bytes;			/*  Total Bytes, ioc, MultiO, Status */
	u32		buf_ptr[6];			/*  Buffer pointer Page 0-4 */
} __attribute__ ((aligned(32))) T_EP_TRANS_DESC, *PT_EP_TRANS_DESC;

/*-------------------------------------------------------------------------*/
#define	UDC_EP0_MAXPACKETSIZE		64
#define	UDC_EP0_BUFSIZE			PAGE_SIZE
#define	UDC_EP_AUTO_BUFSIZE		(64*1024)

#define USB_ENDPOINT_MPS_SIZE_MASK	(BIT10_00)
#define USB_ENDPOINT_MPS_MULTI_MASK	(BIT12_11)
#define USB_ENDPOINT_MPS_MULTI_NONE	(0)
#define USB_ENDPOINT_MPS_MULTI_1ADD	(BIT11)
#define USB_ENDPOINT_MPS_MULTI_2ADD	(BIT12)

#ifdef CONFIG_MP200_PWC
#define UDC_TRANS_STATE1		PWC_STATE1
#define UDC_TRANS_FACTOR1		PWC_FACTOR1
#define UDC_TRANS_CLRFACT1		PWC_CLRFACT1
#define UDC_TRANS_1_USBINT		(1<<7)
#define UDC_TRANS_USBSEL		PWC_USBSEL
#define UDC_TRANS_USBSEL_USBSEL		(1<<7)
#define UDC_TRANS_USBSEL_SUSFIX		(1<<4)
#define UDC_TRANS_USBSEL_USBPLLON	(1<<3)
#define UDC_TRANS_USBSEL_ULPINI		(1<<2)
#define UDC_TRANS_USBSEL_REFSEL		(1<<1)
#define UDC_TRANS_USBSEL_MODESEL	(1<<0)
#define UDC_TRANS_USBSEL_DEFAULT	(0)
#endif /* CONFIG_MP200_PWC */

#define	NUM_ENDPOINTS			(16)
#define	NUM_DIRECTIONS			(2)
#define	UDC_DIRECTION_SHIFT		(7)
#define DQH_MEMORY_SIZE			(2048)			/*  2K */
#define DQH_ALLOC_MEMORY_SIZE		(DQH_MEMORY_SIZE*2)	/*  2K * 2 */

#define SUPPORT_DTD_NUM			(8)

#define DTD_STRUCT_SIZE			(0x20)
#define DTD_MEMORY_SIZE			(DTD_STRUCT_SIZE * NUM_DIRECTIONS * NUM_ENDPOINTS * SUPPORT_DTD_NUM)
#define DTD_ALLOC_MEMORY_SIZE		(DTD_MEMORY_SIZE + DTD_STRUCT_SIZE)

#define DTD_MAX_TRANSFER_SIZE		(0x1000 * 4)

#define DTD_MANAGEMENT_FREE		(0)
#define DTD_MANAGEMENT_RESERVE		(1)
#define DTD_MANAGEMENT_USE		(2)
#define DTD_MANAGEMENT_COMPLETE		(3)

struct mp200_req {
	struct usb_request		req;
	struct list_head		queue;

	u32				division_len;
	u32				act_len;

	unsigned			mapped:1;
};

typedef struct _T_MEMORY_VP_INFO {
	dma_addr_t			padrs;			/*  phy */
	u32				*p_vadrs;		/*  virtual */
} T_MEMORY_VP_INFO, *PT_MEMORY_VP_INFO;

struct mp200_ep {
	struct usb_ep				ep;
	struct list_head			queue;
	const struct usb_endpoint_descriptor	*pdesc;
	char					name[14];
	struct mp200_udc			*pudc;
	T_MEMORY_VP_INFO			mem;
#ifdef DEBUG_COUNT
	int					start_count;
	int					normal_start_count;
	int					dummy_start_count;
	int					done_count;
	int					done_callback_count;
	int					done_callback_ok_count;
	int					done_callback_reset_count;
	int					done_callback_fail_count;
#endif /* DEBUG_COUNT */
};

typedef struct _T_DTD_MANAGEMENT {
	T_MEMORY_VP_INFO		mem_info;
	u32				use_flag;
	void				*p_context;
} T_DTD_MANAGEMENT, *PT_DTD_MANAGEMENT;

struct mp200_udc {
	struct usb_gadget		gadget;
	struct usb_gadget_driver	*pdriver;
	spinlock_t			lock;
	struct mp200_ep			ep[(NUM_ENDPOINTS)*(NUM_DIRECTIONS) -1];
	unsigned			softconnect:1;
	unsigned			vbus_active:1;
	unsigned			linux_suspended:1;
	unsigned			linux_resume:1;
	unsigned			usb_suspended:1;
	unsigned			self_powered:1;
	unsigned			remote_wakeup:1;
	unsigned			mA;
	enum usb_device_state 		devstate;

	struct usb_ctrlrequest		ctrl;
	struct mp200_req		ep0_req;
	struct mp200_req		null_packet_req;
	T_MEMORY_VP_INFO		ep0_mem;

	struct completion		*pdone;
	int				usbint_intno;
	int				usb_wakeup_intno;
	struct platform_device		*pdev;
	PT_OTG_REGS			potg_reg;
	PT_FC_REGS			pfc_reg;

	T_MEMORY_VP_INFO		dQH_align_mem;		/*  2K */
	T_MEMORY_VP_INFO		dQH;			/*  dQH */

	T_MEMORY_VP_INFO		dTD_align_mem;		/*  32 byte */
	T_MEMORY_VP_INFO		dTD;			/*  dTD */

	T_DTD_MANAGEMENT		dTD_Manage[NUM_DIRECTIONS][NUM_ENDPOINTS][SUPPORT_DTD_NUM];

	u32		clk_reg;
	u32		timer_mode[2];

#ifdef DUMMY_PRIME
	u32		dummy_prime_waiting;
	u32		dummy_prime_transferring;
#endif	// DUMMY_PRIME

#ifdef DEBUG_LOG
	int				dbg_log_count;
	u8				dbg_log[50000];
#endif /* DEBUG_LOG */
#ifdef MEMORY_LOG
	int				mem_log_count;
	u8				mem_log[50000];
#endif /* MEMORY_LOG */

#ifdef CONFIG_SNSC_MP200_PLATFORM
	struct mp200_udc_platform_data *config;
#endif /* CONFIG_SNSC_MP200_PLATFORM */

};

#ifdef DEBUG_LOG
/*-------------------------------------------------------------------------*/
 #define DBG_LOG(pudc,stuff...)	do{\
	u8 tmp[257];\
	\
	if((pudc)->dbg_log_count > (sizeof((pudc)->dbg_log) - sizeof(tmp))){\
		break;\
	}\
	\
	sprintf(tmp, stuff );\
	(pudc)->dbg_log_count += strlen(tmp);\
	strcat((pudc)->dbg_log,tmp);\
	\
\
 }while(0)
#else

 #define DBG_LOG(pudc,stuff...)	do{\
 }while(0)

#endif /* DEBUG_LOG */
#ifdef MEMORY_LOG
/*-------------------------------------------------------------------------*/
 #define MEM_LOG(pudc,stuff...)	do{\
	u8 tmp[257];\
	\
	if((pudc)->mem_log_count > (sizeof((pudc)->mem_log) - sizeof(tmp))){\
		break;\
	}\
	\
	sprintf(tmp, stuff );\
	(pudc)->mem_log_count += strlen(tmp);\
	strcat((pudc)->mem_log,tmp);\
	\
\
 }while(0)
#else

 #define MEM_LOG(pudc,stuff...)	do{\
 }while(0)

#endif /* MEMORY_LOG */

#ifdef CONFIG_MP200_PWC
#define TRANS_REPEATED_COUNT		3
/*-------------------------------------------------------------------------*/
static __inline__ int mp200st_udc_trans_read(u8 addr, u8* pdata)
{
	int	status;
	int	repeated_count = TRANS_REPEATED_COUNT;
	unsigned int	tmp_data;

	do{
		status = pwc_read(addr, &tmp_data);
		repeated_count--;
	}while((status < 0) && (repeated_count > 0));

	if(status >= 0){
		*pdata = (u8)tmp_data;
	}

	return status;
}

/*-------------------------------------------------------------------------*/
static __inline__ int mp200st_udc_trans_read_modification_write(u8 addr, u8 mask, u8 data)
{
	int	status;
	int	repeated_count = TRANS_REPEATED_COUNT;

	do{
		status = pwc_write(addr, data, mask);
		repeated_count--;
	}while((status < 0) && (repeated_count > 0));

	return status;
}

/*-------------------------------------------------------------------------*/
static __inline__ int mp200st_udc_trans_write(u8 addr, u8 data)
{
	return mp200st_udc_trans_read_modification_write(addr, 0xFF, data);
}
#endif /* CONFIG_MP200_PWC */

/*-------------------------------------------------------------------------*/
/*  read(DWORD) */
static __inline__ u32 mp200st_udc_readl(u32 *adrs)
{
	return ioread32(adrs);
}

/*-------------------------------------------------------------------------*/
/*  write(DWORD) */
static __inline__ void mp200st_udc_writel(u32 *adrs, u32 data)
{
	iowrite32((data), (adrs));
}

/*-------------------------------------------------------------------------*/
/*  maskget */
static __inline__ u32 mp200st_udc_mask_get_bit(u32 *adrs, u32 mask)
{
	return mp200st_udc_readl(adrs) & mask;
}

/*-------------------------------------------------------------------------*/
/*  maskset */
static __inline__ void mp200st_udc_mask_set_bit(u32 *adrs, u32 mask, u32 data)
{
	u32	tmp;
	tmp = (mp200st_udc_readl(adrs) & ~mask) | data;
	mp200st_udc_writel(adrs, tmp);
}

/*-------------------------------------------------------------------------*/
/*  bitclear */
static __inline__ void mp200st_udc_clear_bit(u32 *adrs, u32 data)
{
	u32	tmp;
	tmp = mp200st_udc_readl(adrs) & ~data;
	mp200st_udc_writel(adrs, tmp);
}

/*-------------------------------------------------------------------------*/
/*  bitset */
static __inline__ void mp200st_udc_set_bit(u32 *adrs, u32 data)
{
	u32	tmp;
	tmp = mp200st_udc_readl(adrs) | data;
	mp200st_udc_writel(adrs, tmp);
}

/*-------------------------------------------------------------------------*/
/*  ULPI CLK (VBUS) Check write(DWORD) */
#ifdef CONFIG_SNSC_MP200_PLATFORM
static __inline__ int mp200st_udc_ulc_chk_writel(struct mp200_udc *pudc, u32 *adrs, u32 data)
{
	u32	reg_data = 0;
	int	status = 0;

	if(pudc->vbus_active){
		status = MP200_UDC_ULPI_ACTIVE;
		if (pudc->config && pudc->config->udc_is_ulpi_active)
			status = pudc->config->udc_is_ulpi_active(pudc);
		if (status != MP200_UDC_ULPI_ACTIVE)
			goto err;

		reg_data = mp200st_udc_readl(&pudc->pfc_reg->PORTSC[0]);
		if ((reg_data & PORTSC_SUSP) != 0)
			goto err;

		/* write */
		mp200st_udc_writel(adrs, data);

		if (pudc->config && pudc->config->udc_is_ulpi_active)
			status = pudc->config->udc_is_ulpi_active(pudc);
		if (status != MP200_UDC_ULPI_ACTIVE)
			goto err;

		reg_data = mp200st_udc_readl(&pudc->pfc_reg->PORTSC[0]);
		if ((reg_data & PORTSC_SUSP) != 0)
			goto err;

		return 0;
	}
	else{
		return -EIO;
	}

err:
	WARN("ULPI=%d PORTSC=%08x\n", status, reg_data);
	WARN("ulpi off writel %08x = %08x\n",(int)adrs,(int)data);
	return -EIO;
}
#else /* CONFIG_SNSC_MP200_PLATFORM */
static __inline__ int mp200st_udc_ulc_chk_writel(struct mp200_udc *pudc, u32 *adrs, u32 data)
{
	int	status;
	u8	pwc_state=0;
	u32	reg_data;

	if(pudc->vbus_active){
		status = mp200st_udc_trans_read(PWC_PSW_STATE, &pwc_state);
		if(status < 0){
			ERR("**** mp200st_udc_trans_read(1) err ***\n");
			return status;
		}

		reg_data = mp200st_udc_readl(&pudc->pfc_reg->PORTSC[0]);
		if((((pwc_state & PWC_PSW_VBUS) == 0) || (reg_data & PORTSC_SUSP) != 0)){
			WARN("before VBUS=%d PORTSC=%08x\n",((pwc_state & PWC_PSW_VBUS) == PWC_PSW_VBUS), reg_data);
			WARN("ulpi off writel %08x = %08x\n",(int)adrs,(int)data);
			return -EIO;
		}

		mp200st_udc_writel(adrs, data);

		status = mp200st_udc_trans_read(PWC_PSW_STATE, &pwc_state);
		if(status < 0){
			ERR("**** mp200st_udc_trans_read(2) err ***\n");
			return status;
		}

		reg_data = mp200st_udc_readl(&pudc->pfc_reg->PORTSC[0]);
		if((((pwc_state & PWC_PSW_VBUS) == 0) || (reg_data & PORTSC_SUSP) != 0)){
			WARN("before VBUS=%d PORTSC=%08x\n",((pwc_state & PWC_PSW_VBUS) == PWC_PSW_VBUS), reg_data);
			WARN("ulpi off writel %08x = %08x\n",(int)adrs,(int)data);
			return -EIO;
		}

		return 0;
	}
	else{
		return -EIO;
	}
}
#endif /* CONFIG_SNSC_MP200_PLATFORM */

/*-------------------------------------------------------------------------*/
/*  ULPI CLK (VBUS) Check maskset */
static __inline__ int mp200st_udc_ulc_chk_mask_set_bit(struct mp200_udc *pudc, u32 *adrs, u32 mask, u32 data)
{
	u32	tmp;
	tmp = (mp200st_udc_readl(adrs) & ~mask) | data;
	return mp200st_udc_ulc_chk_writel(pudc, adrs, tmp);
}

/*-------------------------------------------------------------------------*/
/*  ULPI CLK (VBUS) Check bitclear */
static __inline__ int mp200st_udc_ulc_chk_clear_bit(struct mp200_udc *pudc, u32 *adrs, u32 data)
{
	u32	tmp;
	tmp = mp200st_udc_readl(adrs) & ~data;
	return mp200st_udc_ulc_chk_writel(pudc, adrs, tmp);
}

/*-------------------------------------------------------------------------*/
/*  ULPI CLK (VBUS) Check bitset */
static __inline__ int mp200st_udc_ulc_chk_set_bit(struct mp200_udc *pudc, u32 *adrs, u32 data)
{
	u32	tmp;
	tmp = mp200st_udc_readl(adrs) | data;
	return mp200st_udc_ulc_chk_writel(pudc, adrs, tmp);
}

#define ULPI_REPEATED_COUNT	100

/*-------------------------------------------------------------------------*/
/*  ULPI Read */
static int __inline__ mp200st_udc_ulpi_read(struct mp200_udc *pudc, u8 adrs)
{
	int		i, status = -EIO;
	u32		tmp_viewport;

	tmp_viewport = ULPIVIEWPORT_ULPIRUN | (adrs <<16);
	mp200st_udc_ulc_chk_writel(pudc, &pudc->pfc_reg->ULPIVIEWPORT, tmp_viewport);

	for(i=0; i<ULPI_REPEATED_COUNT; i++){
		tmp_viewport = mp200st_udc_readl(&pudc->pfc_reg->ULPIVIEWPORT);
		if(tmp_viewport & ULPIVIEWPORT_ULPIRUN) continue;
		else{
			status = (((tmp_viewport & ULPIVIEWPORT_ULPIDATRD) >> 8) & 0xFF);
			break;
		}
	}

	return status;
}

/*-------------------------------------------------------------------------*/
/*  ULPI Write */
static int __inline__ mp200st_udc_ulpi_write(struct mp200_udc *pudc, u8 adrs, u8 data)
{
	int		i, status = -EIO;
	u32		tmp_viewport;

	tmp_viewport = ULPIVIEWPORT_ULPIRUN | ULPIVIEWPORT_ULPIRW | (adrs <<16) | data;
	mp200st_udc_ulc_chk_writel(pudc, &pudc->pfc_reg->ULPIVIEWPORT, tmp_viewport);

	for(i=0; i<ULPI_REPEATED_COUNT; i++){
		tmp_viewport = mp200st_udc_readl(&pudc->pfc_reg->ULPIVIEWPORT);
		if((tmp_viewport & ULPIVIEWPORT_ULPIRUN) == 0){
			status = 0;
			break;
		}
	}

	return status;
}

#endif /* __MP200_UDC_H */
