/*
 * Copyright (c) 2015 Amlogic, Inc. All rights reserved.
 *
 * This source code is subject to the terms and conditions defined in the
 * file 'LICENSE' which is part of this source code package.
 *
 * USB low level irq routines
 */

#include "usb_boot.h"
#include "usb_ch9.h"
#include "dwc_pcd.h"
#include "dwc_pcd_irq.h"
#include "platform.h"

static void ep0_out_start(void);
static int ep0_complete_request( pcd_struct_t * pcd);

void dwc_otg_flush_fifo(const int _num)
{
	grstctl_t greset = {0};
	u32 count = 0;

	DBG("dwc_otg_flush_tx_fifo: %d\n", _num);
	greset.b.txfflsh = 1;
	greset.b.txfnum = _num;
	dwc_write_reg32(DWC_REG_GRSTCTL, greset.d32);
	do {
		greset.d32 = dwc_read_reg32(DWC_REG_GRSTCTL);
		if (++count > 10000)
			break;
	} while (1 == greset.b.txfflsh);
	/* Wait for 3 PHY Clocks*/
	udelay(1);

	if (!_num)
		return;

	greset.d32 = 0;
	count = 0;

	greset.b.rxfflsh = 1;
	dwc_write_reg32(DWC_REG_GRSTCTL, greset.d32);
	do {
		greset.d32 = dwc_read_reg32(DWC_REG_GRSTCTL);
		if (++count > 10000)
			break;
	} while (1 == greset.b.rxfflsh);
    /* Wait for 3 PHY Clocks*/
	udelay(1);
}

static void dwc_otg_ep_start_transfer(dwc_ep_t *_ep)
{
	depctl_data_t depctl;
	deptsiz_data_t deptsiz;
	u32 epctl_reg, epctltsize_reg;
	u32 ep_num = _ep->num;
	u32 is_in = _ep->is_in;
	u32 ep_mps = _ep->maxpacket;

    _ep->total_len = _ep->xfer_len;

	if (is_in) {
		epctl_reg = DWC_REG_IN_EP_REG(ep_num);
		epctltsize_reg = DWC_REG_IN_EP_TSIZE(ep_num);
	} else {
		epctl_reg = DWC_REG_OUT_EP_REG(ep_num);
		epctltsize_reg = DWC_REG_OUT_EP_TSIZE(ep_num);
	}

	depctl.d32 = dwc_read_reg32(epctl_reg);
	deptsiz.d32 = dwc_read_reg32(epctltsize_reg);

	/* Zero Length Packet? */
	if (0 == _ep->xfer_len) {
		deptsiz.b.xfersize = is_in ? 0 : ep_mps;
		deptsiz.b.pktcnt = 1;
	} else {
		deptsiz.b.pktcnt =
		(_ep->xfer_len + (ep_mps - 1)) /ep_mps;
		if (is_in && _ep->xfer_len < ep_mps)
			deptsiz.b.xfersize = _ep->xfer_len;
		else
			deptsiz.b.xfersize = _ep->xfer_len - _ep->xfer_count;
	}

	/* Fill size and count */
	dwc_write_reg32(epctltsize_reg, deptsiz.d32);

	/* IN endpoint */
	if (is_in) {
		gintmsk_data_t intr_mask = {0};

		/* First clear it from GINTSTS */
		intr_mask.b.nptxfempty = 1;
		dwc_modify_reg32(DWC_REG_GINTSTS, intr_mask.d32, 0);
		dwc_modify_reg32(DWC_REG_GINTMSK, intr_mask.d32, intr_mask.d32);
	}

	/* EP enable */
	depctl.b.cnak = 1;
	depctl.b.epena = 1;
	dwc_write_reg32 (epctl_reg, depctl.d32);
}

void dwc_otg_bulk_ep_activate(dwc_ep_t *ep)
{
	depctl_data_t depctl = {0};
	daint_data_t daintmsk = {0};
	u32 epctl;
	u32 ep_num = ep->num;

	if (ep->is_in) {
		epctl = DWC_REG_IN_EP_REG(ep_num);
		daintmsk.b.inep1 = 1;
	} else {
		epctl = DWC_REG_OUT_EP_REG(ep_num);
		daintmsk.b.outep1 = 1;
	}

	depctl.d32 = dwc_read_reg32(epctl);
	if (!depctl.b.usbactep) {
		depctl.b.mps = BULK_EP_MPS;
		depctl.b.eptype = 2;
		depctl.b.setd0pid = 1;
		depctl.b.txfnum = 0;
		depctl.b.usbactep = 1;

		dwc_write_reg32(epctl, depctl.d32);
	}

	dwc_modify_reg32(DWC_REG_DAINTMSK, 0, daintmsk.d32);

	return;
}

int f_dwc_otg_ep_req_start(pcd_struct_t *pcd, u32 ep_num_1, u32 is_in,struct usb_request *req)
{
	dwc_ep_t *ep;
	int ep_num;
	struct usb_req_flag *req_flag = &gadget_wrapper.req_flag;

	if (ep_num_1 != 0)
		if (is_in)
			ep_num = ep_num_1;
		else {
			ep_num = ep_num_1+1;
		}
	else
		ep_num = ep_num_1;

	ep = &pcd->dwc_eps[ep_num].dwc_ep;

	ep->num = ep_num_1;
	ep->xfer_count = 0;
	ep->sent_zlp = 0;

	/* EP0 Transfer? */
	if (0 == ep_num) {
		switch (pcd->ep0state) {
		case EP0_IN_DATA_PHASE:
			break;
		case EP0_OUT_DATA_PHASE:
			if (req_flag->request_config | (0 == req->length)) {
				/* Work around for SetConfig cmd */
				/* Complete STATUS PHASE */
				ep->is_in = 1;
				pcd->ep0state = EP0_STATUS;
			}
			break;
		default:
			return -1;
		}

		ep->start_xfer_buff = (u8 *)req->buf;
		ep->xfer_buff = (u8 *)req->buf;
		ep->xfer_len = req->length;
		ep->total_len = ep->xfer_len;
		ep->maxpacket = 64;
	} else {
		/* Setup and start the Transfer for Bulk */
		ep->start_xfer_buff = (u8 *)req->buf;
		ep->xfer_buff = (u8 *)req->buf;
		ep->xfer_len = req->length;
		ep->total_len = ep->xfer_len;
		ep->maxpacket = BULK_EP_MPS;
		ep->is_in = (ep_num == BULK_IN_EP_NUM);
		dwc_otg_bulk_ep_activate(ep);
	}

	dwc_otg_ep_start_transfer(ep);

	return 0;
}

static void do_setup_status_phase(pcd_struct_t *_pcd, int is_in)
{
	dwc_ep_t *ep0 = &_pcd->dwc_eps[0].dwc_ep;

	if (_pcd->ep0state == EP0_STALL)
		return;

	_pcd->ep0state = EP0_STATUS;

	DBG( "EP0 IN ZLP\n");
	ep0->xfer_len = 0;
	ep0->xfer_count = 0;
	ep0->is_in = is_in;
	ep0->num = 0;

	dwc_otg_ep_start_transfer( ep0 );

	/* Prepare for more SETUP Packets */
	ep0_out_start();
}


static void pcd_setup(pcd_struct_t *_pcd)
{
	struct usb_ctrlrequest	ctrl = _pcd->setup_pkt.req;
	struct usb_request *req = &gadget_wrapper.req;
	struct usb_req_flag *req_flag = &gadget_wrapper.req_flag;
	struct usb_gadget_driver *driver = gadget_wrapper.driver;
	struct usb_gadget *gadget = &gadget_wrapper.gadget;
	dwc_ep_t	*ep0 = &_pcd->dwc_eps[0].dwc_ep;

	if (0 == req_flag->request_enable)
		return;

	_pcd->status = 0;
	req_flag->request_enable = 0;

	if (ctrl.bRequestType & USB_DIR_IN) {
		ep0->is_in = 1;
		_pcd->ep0state = EP0_IN_DATA_PHASE;
	} else {
		ep0->is_in = 0;
		_pcd->ep0state = EP0_OUT_DATA_PHASE;
	}

	if ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) {
		/* handle non-standard (class/vendor) requests in the gadget driver */
		printf("Vendor requset\n");
		f_dwc_otg_ep_req_start(_pcd, 0, 1, req);
		return;
	}

	/** @todo NGS: Handle bad setup packet? */
	switch (ctrl.bRequest) {
	case USB_REQ_GET_STATUS:
		_pcd->status = 0;
		req->buf = (char *)&_pcd->status;
		req->length = 2;
		f_dwc_otg_ep_req_start(_pcd, 0, 1, req);
		break;
	case USB_REQ_SET_ADDRESS:
		if (USB_RECIP_DEVICE == ctrl.bRequestType) {
			dcfg_data_t dcfg = {0};
			dcfg.b.devaddr = ctrl.wValue;
			dwc_modify_reg32(DWC_REG_DCFG, 0, dcfg.d32);
			do_setup_status_phase(_pcd, 1);
		}
		break;
	case USB_REQ_SET_INTERFACE:
	case USB_REQ_SET_CONFIGURATION:
		/* Configuration changed */
		req_flag->request_config = 1;
	default:
		DBG("Call the Gadget Driver's setup functions\n");
		/* Call the Gadget Driver's setup functions */
		driver->setup(gadget, &ctrl);
		if ((ctrl.bRequest == USB_REQ_CLEAR_FEATURE) &&
			((ctrl.bRequestType & USB_RECIP_MASK) == USB_RECIP_ENDPOINT)) {
			f_dwc_otg_ep_req_start(_pcd, 0, 1, req);
			break;
		}

		break;
	}

	return;
}

static void handle_ep0(void)
{
	pcd_struct_t * _pcd = &gadget_wrapper.pcd;
	dwc_ep_t * ep0 = &_pcd->dwc_eps[0].dwc_ep;
	struct usb_req_flag *req_flag = &gadget_wrapper.req_flag;

	switch (_pcd->ep0state) {
	case EP0_IDLE:
		req_flag->request_config = 0;
		pcd_setup(_pcd);
		break;

	case EP0_IN_DATA_PHASE:
		if (ep0->xfer_count < ep0->total_len)
			DBG("FIX ME!! dwc_otg_ep0_continue_transfer!\n");
		else
			ep0_complete_request(_pcd);

		break;

	case EP0_OUT_DATA_PHASE:
		ep0_complete_request(_pcd);
		break;

	case EP0_STATUS:
		ep0_complete_request(_pcd);
		/* OUT for next SETUP */
		_pcd->ep0state = EP0_IDLE;
		ep0->stopped = 1;
		ep0->is_in = 0;
		break;

	case EP0_STALL:
	case EP0_DISCONNECT:
	default:
		printf("EP0 state is %d, should not get here pcd_setup()\n", _pcd->ep0state);
		break;
    }

	return;
}

/**
 * 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(u32 ep_num, int is_in)
{
	deptsiz_data_t deptsiz;
	pcd_struct_t *pcd = &gadget_wrapper.pcd;
	dwc_ep_t * ep;
	u32 epnum = ep_num;

	if (ep_num) {
		if (!is_in)
			epnum = ep_num + 1;
	}

	ep = &pcd->dwc_eps[epnum].dwc_ep;

	if (is_in) {
		pcd->dwc_eps[epnum].req->actual = ep->xfer_len;
		deptsiz.d32 = dwc_read_reg32(DWC_REG_IN_EP_TSIZE(ep_num));
		if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0 &&
                    ep->xfer_count == ep->xfer_len) {
			ep->start_xfer_buff = 0;
			ep->xfer_buff = 0;
			ep->xfer_len = 0;
		}
		pcd->dwc_eps[epnum].req->status = 0;
	} else {
		deptsiz.d32 = dwc_read_reg32(DWC_REG_OUT_EP_TSIZE(ep_num));
		pcd->dwc_eps[epnum].req->actual = ep->xfer_count;
		ep->start_xfer_buff = 0;
		ep->xfer_buff = 0;
		ep->xfer_len = 0;
		pcd->dwc_eps[epnum].req->status = 0;
	}

	if (pcd->dwc_eps[epnum].req->complete) {
		pcd->dwc_eps[epnum].req->complete((struct usb_ep *)(pcd->dwc_eps[epnum].priv), pcd->dwc_eps[epnum].req);
	}
}
/**
 * This function completes the ep0 control transfer.
 */
static int ep0_complete_request(pcd_struct_t * pcd)
{
	deptsiz0_data_t deptsiz;
	dwc_ep_t* ep = &pcd->dwc_eps[0].dwc_ep;
	int ret = 0;

	if (EP0_STATUS == pcd->ep0state) {
		ep->start_xfer_buff = 0;
		ep->xfer_buff = 0;
		ep->xfer_len = 0;
		ep->num = 0;
		ret = 1;
	} else if (0 == ep->xfer_len) {
		ep->xfer_len = 0;
		ep->xfer_count = 0;
		ep->sent_zlp = 1;
		ep->num = 0;
		dwc_otg_ep_start_transfer(ep);
		ret = 1;
	} else if (ep->is_in) {
		deptsiz.d32 = dwc_read_reg32(DWC_REG_IN_EP_TSIZE(0));
		if (0 == deptsiz.b.xfersize) {
			/* Is a Zero Len Packet needed? */
			do_setup_status_phase(pcd, 0);
		}
	} else {
		/* ep0-OUT */
		do_setup_status_phase(pcd, 1);
	}

	return ret;
}
/**
 * This function reads a packet from the Rx FIFO into the destination
 * buffer.  To read SETUP data use dwc_otg_read_setup_packet.
 *
 * @param _dest   Destination buffer for the packet.
 * @param _bytes  Number of bytes to copy to the destination.
 */
static void dwc_otg_read_packet(u8 *_dest, u16 _bytes)
{
	int i;
	u8* pbyte = _dest;
	u32 buffer = 0;
	u64 t_64 = (u64)_dest;

	if (0 == (t_64 & 0x3))
		for (i = 0; i < _bytes; i += 4) {
			*(u32*)t_64 = dwc_read_reg32(DWC_REG_DATA_FIFO_START);
			t_64 += 4;
		}
	else
		for (i = 0; i < _bytes; i++) {
			if (0 == (i % 4))
				buffer = dwc_read_reg32(DWC_REG_DATA_FIFO_START);
			*(u8*)pbyte ++ = buffer;
		}

	return;
}

/**
 * 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.
 */
static void dwc_otg_ep_write_packet(dwc_ep_t *_ep, u32 byte_count, u32 dword_count)
{
	u32 i;
	u32 fifo;
	u32 temp_data;
	u8 *data_buff = _ep->xfer_buff;
	u64 t_64 = (u64)_ep->xfer_buff;

	if (_ep->xfer_count >= _ep->xfer_len) {
		ERR("%s() No data for EP%d!!!\n", "dwc_otg_ep_write_packet", _ep->num);
		return;
	}

	fifo = DWC_REG_DATA_FIFO(_ep->num);

	if (t_64 & 0x3) {
		for (i = 0; i < dword_count; i++) {
			temp_data = get_unaligned(data_buff);
			dwc_write_reg32(fifo, temp_data);
			data_buff += 4;
		}
	} else {
		for (i = 0; i < dword_count; i++) {
			temp_data = *(u32*)t_64;
			dwc_write_reg32(fifo, temp_data);
			t_64 += 4;
		}
	}

	_ep->xfer_count += byte_count;
    _ep->xfer_buff += byte_count;

	flush_cpu_cache();

	return;
}
/**
 * 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.
 */
static void dwc_otg_read_setup_packet(u32 *_dest)
{
	/* Get the 8 bytes of a setup transaction data */
	/* Pop 2 DWORDS off the receive data FIFO into memory */
	_dest[0] = dwc_read_reg32(DWC_REG_DATA_FIFO_START);
	_dest[1] = dwc_read_reg32(DWC_REG_DATA_FIFO_START);
}

/**
 * Handler for the IN EP timeout handshake interrupt.
 */
static void handle_in_ep_timeout_intr(u32 _epnum)
{
	dctl_data_t dctl = {0};
	gintmsk_data_t intr_mask = {0};
	pcd_struct_t *pcd = &gadget_wrapper.pcd;
	dwc_ep_t * ep = &pcd->dwc_eps[_epnum].dwc_ep;

	/* Disable the NP Tx Fifo Empty Interrrupt */
	intr_mask.b.nptxfempty = 1;
	dwc_modify_reg32(DWC_REG_GINTMSK, intr_mask.d32, 0);

	/* Enable the Global IN NAK Effective Interrupt */
	intr_mask.b.ginnakeff = 1;
	dwc_modify_reg32(DWC_REG_GINTMSK, 0, intr_mask.d32);

	/* Set Global IN NAK */
	dctl.b.sgnpinnak = 1;
	dwc_modify_reg32(DWC_REG_DCTL,dctl.d32, dctl.d32);

	ep->stopped = 1;
}

/**
 * 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
 */

static void dwc_otg_pcd_handle_rx_status_q_level_intr(void)
{
	gintmsk_data_t gintmask = {0};
	gintsts_data_t gintsts = {0};
	dwc_ep_t *ep;
	pcd_struct_t *pcd = &gadget_wrapper.pcd;
	struct usb_req_flag *req_flag = &gadget_wrapper.req_flag;
	device_grxsts_data_t status;

	/* Disable the Rx Status Queue Level interrupt */
	gintmask.b.rxstsqlvl = 1;
	dwc_modify_reg32(DWC_REG_GINTMSK, gintmask.d32, 0);

	/* Get the Status from the top of the FIFO */
	status.d32 = dwc_read_reg32(DWC_REG_GRXSTSP);
	if (status.b.epnum != 0)
		status.b.epnum = 2;
	/* Get pointer to EP structure */
	ep = &pcd->dwc_eps[status.b.epnum].dwc_ep;

	switch (status.b.pktsts) {
	case DWC_STS_DATA_UPDT:
		if (status.b.bcnt && ep->xfer_buff) {
			/** @todo NGS Check for buffer overflow? */
			dwc_otg_read_packet(ep->xfer_buff, status.b.bcnt);
			ep->xfer_count += status.b.bcnt;
			ep->xfer_buff += status.b.bcnt;
		}

		break;

	case DWC_DSTS_SETUP_UPDT:
		dwc_otg_read_setup_packet(gadget_wrapper.pcd.setup_pkt.d32);
		req_flag->request_enable = 1;
		ep->xfer_count += status.b.bcnt;
		break;

	case DWC_DSTS_GOUT_NAK:
	case DWC_STS_XFER_COMP:
	case DWC_DSTS_SETUP_COMP:
	default:
		break;
	}


	/* Enable the Rx Status Queue Level interrupt */
	dwc_modify_reg32(DWC_REG_GINTMSK, 0, gintmask.d32);

	/* Clear interrupt */
	gintsts.b.rxstsqlvl = 1;
	dwc_write_reg32 (DWC_REG_GINTSTS, gintsts.d32);
}


/**
 * This interrupt occurs when the non-periodic Tx FIFO is half-empty.
 * The active request is checked for the next packet to be loaded into
 * the non-periodic Tx FIFO.
 */
static void dwc_otg_pcd_handle_np_tx_fifo_empty_intr(void)
{
	gnptxsts_data_t txstatus = {0};
	gintsts_data_t gintsts = {0};
	dwc_ep_t *ep = 0;
	depctl_data_t depctl;
	u32 len = 0;
	u32 dwords;
	u32 epnum = 0;
	pcd_struct_t *pcd = &gadget_wrapper.pcd;

    /* Get the epnum from the IN Token Learning Queue. */
	for (epnum = 0; epnum < NUM_EP; epnum++) {
		ep = &pcd->dwc_eps[epnum].dwc_ep;

		/* IN endpoint ? */
		if (epnum && !ep->is_in)
			continue;

		if (ep->type == DWC_OTG_EP_TYPE_INTR && ep->xfer_len == 0)
			continue;

		depctl.d32 = dwc_read_reg32(DWC_REG_IN_EP_REG(epnum));
		if (depctl.b.epena != 1)
			continue;

		flush_cpu_cache();

		/* 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(DWC_REG_GNPTXSTS);
		while  (/*txstatus.b.nptxqspcavail > 0 &&
			txstatus.b.nptxfspcavail > dwords &&*/
			ep->xfer_count < ep->xfer_len) {
				u32 retry = 1000000;

				len = ep->xfer_len - ep->xfer_count;
				if (len > ep->maxpacket)
					len = ep->maxpacket;

				dwords = (len + 3) >> 2;

				while (retry--) {
					txstatus.d32 = dwc_read_reg32(DWC_REG_GNPTXSTS);
					if (txstatus.b.nptxqspcavail > 0 && txstatus.b.nptxfspcavail > dwords)
						break;
					else
						flush_cpu_cache();
				}
				if (0 == retry) {
					printf("TxFIFO FULL: Can't trans data to HOST !\n");
					break;
				}
				/* Write the FIFO */
				dwc_otg_ep_write_packet(ep, len, dwords);

				flush_cpu_cache();
			}

	}

	/* Clear interrupt */
	gintsts.b.nptxfempty = 1;
	dwc_write_reg32 (DWC_REG_GINTSTS, gintsts.d32);
}
/**
 * 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.
 */
static void dwc_otg_pcd_handle_enum_done_intr(void)
{
	gintsts_data_t gintsts = {0};
	gusbcfg_data_t gusbcfg;
	depctl_data_t diepctl;
	depctl_data_t doepctl;
	dctl_data_t dctl = {0};
#if (defined CONFIG_USB_DEVICE_V2)
		depctl_data_t depctl;
#endif

	printf("SPEED ENUM\n");
#ifdef CONFIG_USB_DEVICE_V2
	set_usb_phy21_tuning_fb();
#endif

	gadget_wrapper.pcd.ep0state = EP0_IDLE;

	/* Set the MPS of the IN EP based on the enumeration speed */
	diepctl.d32 = dwc_read_reg32(DWC_REG_IN_EP_REG(0));
	diepctl.b.mps = DWC_DEP0CTL_MPS_64;
	dwc_write_reg32(DWC_REG_IN_EP_REG(0), diepctl.d32);

	/* Enable OUT EP for receive */
	doepctl.d32 = dwc_read_reg32(DWC_REG_OUT_EP_REG(0));
	doepctl.b.epena = 1;
	dwc_write_reg32(DWC_REG_OUT_EP_REG(0), doepctl.d32);

#if (defined CONFIG_USB_DEVICE_V2)
	depctl.d32 = dwc_read_reg32(DWC_REG_IN_EP_REG(1));
	if (!depctl.b.usbactep) {
		depctl.b.mps = BULK_EP_MPS;
		depctl.b.eptype = 2;//BULK_STYLE
		depctl.b.setd0pid = 1;
		depctl.b.txfnum = 0;   //Non-Periodic TxFIFO
		depctl.b.usbactep = 1;
		dwc_write_reg32(DWC_REG_IN_EP_REG(1), depctl.d32);
	}

	depctl.d32 = dwc_read_reg32(DWC_REG_OUT_EP_REG(2));
	if (!depctl.b.usbactep) {
		depctl.b.mps = BULK_EP_MPS;
		depctl.b.eptype = 2;//BULK_STYLE
		depctl.b.setd0pid = 1;
		depctl.b.txfnum = 0;   //Non-Periodic TxFIFO
		depctl.b.usbactep = 1;
		dwc_write_reg32(DWC_REG_OUT_EP_REG(2), depctl.d32);
	}
#endif


	dctl.b.cgnpinnak = 1;
	dwc_modify_reg32(DWC_REG_DCTL, dctl.d32, dctl.d32);

	/* high speed */
	gusbcfg.d32 = dwc_read_reg32(DWC_REG_GUSBCFG);
#if (defined CONFIG_USB_DEVICE_V2)
	gusbcfg.b.usbtrdtim = 9;
#else
	gusbcfg.b.usbtrdtim = 5;
#endif
	dwc_write_reg32(DWC_REG_GUSBCFG, gusbcfg.d32);

	/* Clear interrupt */
	gintsts.d32 = 0;
	gintsts.b.enumdone = 1;
	dwc_write_reg32(DWC_REG_GINTSTS, gintsts.d32);
}


/**
 * 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 void dwc_otg_pcd_handle_out_ep_intr(void)
{
	u32 ep_intr;
	u32 epnum = 0;
	doepint_data_t doepint = {0};
	gintsts_data_t gintsts = {0};

	/* Read in the device interrupt bits */
	ep_intr = (dwc_read_reg32(DWC_REG_DAINT) &
			dwc_read_reg32(DWC_REG_DAINTMSK));
	ep_intr = ((ep_intr & 0xffff0000) >> 16);

	/* Clear the OUTEPINT in GINTSTS */
	gintsts.b.outepintr = 1;
	dwc_write_reg32(DWC_REG_GINTSTS, gintsts.d32);
	dwc_write_reg32(DWC_REG_DAINT, 0xFFFF0000);

	while (ep_intr) {
		if (ep_intr & 0x1) {
			doepint.d32 = (dwc_read_reg32(DWC_REG_OUT_EP_INTR(epnum)) &
				dwc_read_reg32(DWC_REG_DOEPMSK));

			/* Transfer complete */
			if (doepint.b.xfercompl) {
				/* Clear the bit in DOEPINTn for this interrupt */
				CLEAR_OUT_EP_INTR(epnum, xfercompl);
				if (0 == epnum) {
#if (defined CONFIG_USB_DEVICE_V2)
					if (doepint.b.setup) {
						CLEAR_OUT_EP_INTR(epnum,setup);
						doepint.b.setup = 0;
					}
#else
					CLEAR_OUT_EP_INTR(epnum, setup);
					doepint.b.setup = 0;
#endif
					handle_ep0();
				} else {
					complete_ep(epnum, 0);
				}
			}
			/* Endpoint disable  */
			if (doepint.b.epdisabled) {
				/* Clear the bit in DOEPINTn for this interrupt */
				CLEAR_OUT_EP_INTR(epnum, epdisabled);
			}
			/* AHB Error */
			if (doepint.b.ahberr) {
				CLEAR_OUT_EP_INTR(epnum, ahberr);
			}
			/* Setup Phase Done (contorl EPs) */
			if (doepint.b.setup) {
#if (defined CONFIG_USB_DEVICE_V2)
				handle_ep0();
#endif
				CLEAR_OUT_EP_INTR(epnum, setup);
			}
		}
		epnum++;
		ep_intr >>= 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 void dwc_otg_pcd_handle_in_ep_intr(void)
{
	diepint_data_t diepint = {0};
	gintmsk_data_t intr_mask = {0};
	gintsts_data_t gintsts = {0};
	u32 ep_intr;
	u32 epnum = 0;

	/* Read in the device interrupt bits */
	ep_intr = dwc_read_reg32(DWC_REG_DAINT);

	ep_intr = (dwc_read_reg32(DWC_REG_DAINT) &
		dwc_read_reg32(DWC_REG_DAINTMSK));
	ep_intr =(ep_intr & 0xffff);

	/* Clear the INEPINT in GINTSTS */
	/* Clear all the interrupt bits for all IN endpoints in DAINT */
	gintsts.b.inepint = 1;
	dwc_write_reg32(DWC_REG_GINTSTS, gintsts.d32);
	dwc_write_reg32(DWC_REG_DAINT, 0xFFFF);
	flush_cpu_cache();

	/* Service the Device IN interrupts for each endpoint */
	while (ep_intr) {
		if (ep_intr & 0x1) {
			diepint.d32 = (dwc_read_reg32(DWC_REG_IN_EP_INTR(epnum)) &
				dwc_read_reg32(DWC_REG_DAINTMSK));

			/* Transfer complete */
			if (diepint.b.xfercompl) {
				/* Disable the NP Tx FIFO Empty Interrrupt  */
				intr_mask.b.nptxfempty = 1;
				dwc_modify_reg32(DWC_REG_GINTMSK, intr_mask.d32, 0);
				/* Clear the bit in DIEPINTn for this interrupt */
				CLEAR_IN_EP_INTR(epnum, xfercompl);
				/* Complete the transfer */
				if (0 == epnum) {
					handle_ep0();
				} else {
					complete_ep(epnum, 1);
					if (diepint.b.nak)
						CLEAR_IN_EP_INTR(epnum, nak);
				}
			}
			/* Endpoint disable  */
			if (diepint.b.epdisabled) {
				/* Clear the bit in DIEPINTn for this interrupt */
				CLEAR_IN_EP_INTR(epnum, epdisabled);
			}
			/* AHB Error */
			if (diepint.b.ahberr) {
				/* Clear the bit in DIEPINTn for this interrupt */
				CLEAR_IN_EP_INTR(epnum, ahberr);
			}
			/* TimeOUT Handshake (non-ISOC IN EPs) */
			if (diepint.b.timeout) {
				handle_in_ep_timeout_intr(epnum);
				CLEAR_IN_EP_INTR(epnum, timeout);
			}
			/** IN Token received with TxF Empty */
			if (diepint.b.intktxfemp) {
				CLEAR_IN_EP_INTR(epnum, intktxfemp);
			}
			/** IN Token Received with EP mismatch */
			if (diepint.b.intknepmis) {
				CLEAR_IN_EP_INTR(epnum, intknepmis);
			}
			/** IN Endpoint NAK Effective */
			if (diepint.b.inepnakeff) {
				CLEAR_IN_EP_INTR(epnum, inepnakeff);
			}
		}
		epnum++;
		ep_intr >>= 1;
	}
}
/**
 * This function configures EP0 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
 *
 */
static void ep0_out_start(void)
{
	deptsiz0_data_t doeptsize0 = {0};
	depctl_data_t doepctl = {0};

	doeptsize0.b.supcnt = 3;
	doeptsize0.b.pktcnt = 1;
	doeptsize0.b.xfersize = 8*3;

	dwc_write_reg32(DWC_REG_OUT_EP_TSIZE(0), doeptsize0.d32);

	/*EP enable*/
	doepctl.d32 = 0;
	doepctl.b.epena = 1;
	dwc_modify_reg32(DWC_REG_OUT_EP_REG(0), 0, doepctl.d32);

	flush_cpu_cache();
}
/**
 * This interrupt occurs when a USB Reset is detected.  When the USB
 * Reset Interrupt occurs the device state is set to DEFAULT and the
 * EP0 state is set to IDLE.
 *  -#	Set the NAK bit for all OUT endpoints (DOEPCTLn.SNAK = 1)
 *  -#	Unmask the following interrupt bits
 *  	- DAINTMSK.INEP0 = 1 (Control 0 IN endpoint)
 * 	- DAINTMSK.OUTEP0 = 1 (Control 0 OUT endpoint)
 * 	- DOEPMSK.SETUP = 1
 * 	- DOEPMSK.XferCompl = 1
 * 	- DIEPMSK.XferCompl = 1
 *	- DIEPMSK.TimeOut = 1
 *  -# 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
 * At this point, all the required initialization, except for enabling
 * the control 0 OUT endpoint is done, for receiving SETUP packets.
 */
static void dwc_otg_pcd_handle_usb_reset_intr(void)
{
	depctl_data_t doepctl = {0};
	daint_data_t daintmsk = {0};
	doepmsk_data_t doepmsk = {0};
	diepmsk_data_t diepmsk = {0};
	dcfg_data_t dcfg = {0};
	depctl_data_t diepctl = {0};
	depctl_data_t diepctl_rd = {0};
	grstctl_t resetctl = {0};
	dctl_data_t dctl = {0};
	gintsts_data_t gintsts = {0};
	int i = 0;

	printf("\nUSB RESET\n");

	/* Clear the Remote Wakeup Signalling */
	dctl.b.rmtwkupsig = 1;
	dwc_modify_reg32( DWC_REG_DCTL,dctl.d32, 0 );

	diepctl.b.epdis = 1;
	diepctl.b.snak = 1;
	doepctl.b.snak = 1;

	for (i = 0; i < NUM_EP; i++) {
		diepctl_rd.d32 = dwc_read_reg32(DWC_REG_IN_EP_REG(i));
		if (diepctl_rd.b.epena) {
			/* Disable all active IN EPs */
			dwc_write_reg32(DWC_REG_IN_EP_REG(i), diepctl.d32);
		}

		/* Set NAK for all OUT EPs */
		dwc_write_reg32(DWC_REG_OUT_EP_REG(i), doepctl.d32);
	}

	/* Flush the NP Tx FIFO */
	dwc_otg_flush_fifo(0);
	/* Flush the Learning Queue */
	resetctl.b.intknqflsh = 1;
	dwc_write_reg32(DWC_REG_GRSTCTL, resetctl.d32);

	daintmsk.b.inep0 = 1;
	daintmsk.b.outep0 = 1;
	dwc_write_reg32(DWC_REG_DAINTMSK, daintmsk.d32);

	doepmsk.b.setup = 1;
	doepmsk.b.xfercompl = 1;
	doepmsk.b.ahberr = 1;
	doepmsk.b.epdisabled = 1;
	dwc_write_reg32(DWC_REG_DOEPMSK, doepmsk.d32);

	diepmsk.b.xfercompl = 1;
	diepmsk.b.timeout = 1;
	diepmsk.b.epdisabled = 1;
	diepmsk.b.ahberr = 1;
	dwc_write_reg32(DWC_REG_DIEPMSK, diepmsk.d32);
	/* Reset Device Address */
	dcfg.d32 = dwc_read_reg32(DWC_REG_DCFG);
	dcfg.b.devaddr = 0;
	dwc_write_reg32(DWC_REG_DCFG, dcfg.d32);

	/* setup EP0 to receive SETUP packets */
	ep0_out_start();

	/* Clear interrupt */
	gintsts.b.usbreset = 1;
	dwc_write_reg32 (DWC_REG_GINTSTS, gintsts.d32);

	flush_cpu_cache();
}
/**
 * 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.
 */
static void dwc_otg_handle_usb_suspend_intr(void)
{
	gintsts_data_t gintsts = {0};

	DBG("USB Suspend\n");

	/* Clear interrupt */
	gintsts.b.usbsuspend = 1;
	dwc_write_reg32 (DWC_REG_GINTSTS, gintsts.d32);
}

#if (defined CONFIG_USB_DEVICE_V2)
extern unsigned int fb_sofintr;
extern unsigned fb_curTime_sof;
#endif

int f_dwc_pcd_irq(void)
{
	gintsts_data_t  gintr_status;
	gintsts_data_t  gintr_msk;
	gotgint_data_t  gotgint;
	int ret = 0;

	gintr_msk.d32 = dwc_read_reg32(DWC_REG_GINTMSK);
	gintr_status.d32 = dwc_read_reg32(DWC_REG_GINTSTS);

	gintr_status.d32 = gintr_status.d32 & gintr_msk.d32;

	if (gintr_status.d32 == 0)
		return ret;

	gotgint.d32 = dwc_read_reg32(DWC_REG_GOTGINT);

	if (gotgint.b.sesreqsucstschng)
		ERR("Session Request Success Status Change\n");
	else if (gotgint.b.sesenddet) {
		/*break to romboot*/
		ERR("Session End Detected\n");
		ret = 11;
	}

	/* clear intr */
	dwc_write_reg32(DWC_REG_GOTGINT, gotgint.d32);

#if (defined CONFIG_USB_DEVICE_V2)
	if (gintr_status.b.sofintr) {
		fb_curTime_sof = get_timer(0);
		fb_sofintr = 1;
	}
#endif

	if (gintr_status.b.rxstsqlvl) {
	    dwc_otg_pcd_handle_rx_status_q_level_intr();
	}

	if (gintr_status.b.nptxfempty)
	    dwc_otg_pcd_handle_np_tx_fifo_empty_intr();

	if (gintr_status.b.usbreset)
		dwc_otg_pcd_handle_usb_reset_intr();

	if (gintr_status.b.usbsuspend)
		dwc_otg_handle_usb_suspend_intr();

	if (gintr_status.b.enumdone)
	    dwc_otg_pcd_handle_enum_done_intr();

	if (gintr_status.b.inepint)
	    dwc_otg_pcd_handle_in_ep_intr();

	if (gintr_status.b.outepintr)
	    dwc_otg_pcd_handle_out_ep_intr();

	dwc_write_reg32(DWC_REG_GINTSTS, gintr_status.d32);
	flush_cpu_cache();

	return ret;
}
