/*
 * 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);
		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);
				}
			}

			// If there are interrupt bits set other than transfer complete and set up,
			// log it.
			if (doepint.d32 & ~0x9) {
				printf("epnum = %d, OUT EP has additional interrupt: %x\n",
				       epnum, doepint.d32);
			}

			/* 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);
				}
			}

			// If there are interrupt bits set other than transfer complete.
			if (diepint.d32 & ~0x1) {
				printf("epnum = %d, IN EP has additional interrupt: %x\n",
				       epnum, diepint.d32);
			}

			/* 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);
}

#ifdef CONFIG_DEV_BUILD
void fastboot_usb_status_poll(void);
#endif

int f_dwc_pcd_irq(void)
{
#ifdef CONFIG_DEV_BUILD
	fastboot_usb_status_poll();
#endif

	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 (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;
}
