/*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
* *
This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* *
This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* *
You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* *
Description:
*/

/* dwc controller pcd interrupt drivers  */
/*
 * (C) Copyright 2010 Amlogic, Inc
 *
 * Victor Wan, victor.wan@amlogic.com,
 * 2010-03-30 @ Shanghai
 *
 */
#include "platform.h"
#include "usb_ch9.h"
#include "dwc_pcd.h"
#include "dwc_pcd_irq.h"
//#define flush_cpu_cache()
extern void do_gadget_setup( pcd_struct_t *_pcd, struct usb_ctrlrequest * ctrl);
extern void do_vendor_request( pcd_struct_t *_pcd, struct usb_ctrlrequest * ctrl);
extern void do_vendor_out_complete( pcd_struct_t *_pcd, struct usb_ctrlrequest * ctrl);
extern void do_bulk_complete( pcd_struct_t *_pcd);
extern void do_modify_memory(u16 opcode,char * inbuff);

static void ep0_out_start(void);
static int32_t ep0_complete_request( pcd_struct_t * pcd);
/**
 * This function starts the Zero-Length Packet for the IN status phase
 * of a 2 stage control transfer.
 */
static void do_setup_in_status_phase( pcd_struct_t *_pcd)
{
        dwc_ep_t *ep0 = &g_dwc_eps[0];
        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 = 1;

        dwc_otg_ep_start_transfer( ep0 );

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

}
/**
 * This function starts the Zero-Length Packet for the OUT status phase
 * of a 2 stage control transfer.
 */
static void do_setup_out_status_phase( pcd_struct_t *_pcd)
{
        dwc_ep_t *ep0 = &g_dwc_eps[0];
        if (_pcd->ep0state == EP0_STALL) {
                return;
        }
        _pcd->ep0state = EP0_STATUS;

        /* Prepare for more SETUP Packets */
        //ep0_out_start( GET_CORE_IF(_pcd), _pcd );

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

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

}

static void pcd_out_completed(pcd_struct_t *_pcd)
{
    if (_pcd->cmdtype.out_complete && _pcd->cmdtype.in_complete)
    {
        _pcd->cmdtype.setup_complete = _pcd->cmdtype.out_complete = _pcd->cmdtype.in_complete = 0;
        do_vendor_out_complete(_pcd,(struct usb_ctrlrequest*)&_pcd->setup_pkt);
    }
}

static void pcd_in_completed(pcd_struct_t *_pcd)
{
	do_vendor_in_complete(_pcd,(struct usb_ctrlrequest*)&_pcd->setup_pkt);
}


static void pcd_setup( pcd_struct_t *_pcd )
{

    struct usb_ctrlrequest	ctrl = _pcd->setup_pkt.req;
    dwc_ep_t	*ep0 = &g_dwc_eps[0];
    /*deptsiz0_data_t doeptsize0 = { 0};*/

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

    //	_pcd->setup_pkt.d32[0] = 0;
    //	_pcd->setup_pkt.d32[1] = 0;
    _pcd->status = 0;
    _pcd->request_enable = 0;

    /*doeptsize0.d32 = dwc_read_reg32( DWC_REG_OUT_EP_TSIZE(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 */
        //do_gadget_setup(_pcd, &ctrl );
        DBG("Vendor requset\n");
        do_vendor_request(_pcd, &ctrl );
        dwc_otg_ep_req_start(_pcd,0);
        return;
    }

    /** @todo NGS: Handle bad setup packet? */

    switch (ctrl.bRequest)
    {
        case USB_REQ_GET_STATUS:

            _pcd->status = 0;
            switch (ctrl.bRequestType & USB_RECIP_MASK) {

                case USB_RECIP_DEVICE:
                    _pcd->status = 0; /* Default Bus Powered, no Remote wakeup */
                    //_pcd->status |= 0x1; /* Self powered */
                    //_pcd->status |= 0x2;//_pcd->remote_wakeup_enable << 1;
                    break;

                case USB_RECIP_INTERFACE:
                    _pcd->status = 0;
                    break;
            }
            _pcd->buf = (char *)&_pcd->status;
            _pcd->length = 2;
            dwc_otg_ep_req_start(_pcd,0);
            break;
#if 0
        case USB_RECIP_INTERFACE:
            *status = 0;
            break;

        case USB_RECIP_ENDPOINT:
            ep = get_ep_by_addr(_pcd, ctrl.wIndex);
            if ( ep == 0 || ctrl.wLength > 2) {
                ep0_do_stall(_pcd, -EOPNOTSUPP);
                return;
            }
            /** @todo check for EP stall */
            *status = ep->stopped;
            break;
            _pcd->ep0_pending = 1;

            ep0->dwc_ep.start_xfer_buff = (uint8_t *)status;
            ep0->dwc_ep.xfer_buff = (uint8_t *)status;
            ep0->dwc_ep.dma_addr = _pcd->status_buf_dma_handle;
            ep0->dwc_ep.xfer_len = 2;
            ep0->dwc_ep.xfer_count = 0;
            ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
            dwc_otg_ep0_start_transfer( GET_CORE_IF(_pcd), &ep0->dwc_ep );
            break;

        case USB_REQ_CLEAR_FEATURE:
            do_clear_feature( _pcd );
            break;

        case USB_REQ_SET_FEATURE:
            do_set_feature( _pcd );
            break;
#endif
        case USB_REQ_SET_ADDRESS:
            if (ctrl.bRequestType == USB_RECIP_DEVICE)
            {
                dcfg_data_t dcfg = { 0 };

                printf("Set Addr %d\n",ctrl.wValue);
                dcfg.b.devaddr = ctrl.wValue;
                dwc_modify_reg32(DWC_REG_DCFG,0, dcfg.d32);
                do_setup_in_status_phase( _pcd );
                return;
            }
            break;

        case USB_REQ_SET_INTERFACE:
        case USB_REQ_SET_CONFIGURATION:
            _pcd->request_config = 1;   /* Configuration changed */
            do_gadget_setup(_pcd, &ctrl );
            dwc_otg_ep_req_start(_pcd,0);
            break;

        default:
            /* Call the Gadget Driver's setup functions */
            do_gadget_setup(_pcd, &ctrl );
            dwc_otg_ep_req_start(_pcd,0);
            break;
    }
}

/**
 * This function handles EP0 Control transfers.
 *
 * The state of the control tranfers are tracked in
 * <code>ep0state</code>.
 * is_in : 1 -- IN Trans
 * is_in : 0 -- OUT/SETUP Trans
 */
static void handle_ep0( int is_in )
{
	pcd_struct_t * _pcd = &this_pcd[0];//Oh, this_pcd
	dwc_ep_t * ep0 = &g_dwc_eps[0];

    switch (_pcd->ep0state)
    {
        case EP0_DISCONNECT:
            DBG("EP0 DISCONNECT\n");
            break;

        case EP0_IDLE:
            _pcd->request_config = 0;
            DBG("Enter PCD Setup()\n");
            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");
                //dwc_otg_ep0_continue_transfer ( GET_CORE_IF(_pcd), &ep0->dwc_ep );
            }
            else {
                ep0_complete_request( _pcd );
                pcd_in_completed(_pcd);/////////////
            }
            break;

        case EP0_OUT_DATA_PHASE:
            ep0_complete_request(_pcd );
            _pcd->cmdtype.in_complete = 1;
            pcd_out_completed(_pcd);
            break;


        case EP0_STATUS:

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

            break;

        case EP0_STALL:
            ERR("EP0 STALLed, should not get here pcd_setup()\n");
            break;
        }

    return ;
}

/**
 * This function completes the request for the 'BULK' EP.  If there are
 * additional requests for the EP in the queue they will be started.
 */
static void complete_ep( int ep_num,int is_in )
{
        deptsiz_data_t deptsiz;
        pcd_struct_t *pcd = &this_pcd[ep_num];
        dwc_ep_t *ep = &g_dwc_eps[ep_num];

	if (is_in)
    {
		pcd->xfer_len = ep->xfer_count;////////////////

		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;
		}
	}
	else
    {/* OUT Transfer */

		deptsiz.d32 = dwc_read_reg32(DWC_REG_OUT_EP_TSIZE(ep_num));

		pcd->xfer_len = ep->xfer_count;

		ep->start_xfer_buff = 0;
		ep->xfer_buff = 0;
		ep->xfer_len = 0;
	}

	do_bulk_complete(pcd);
}
/**
 * This function completes the ep0 control transfer.
 */
static int32_t ep0_complete_request( pcd_struct_t * pcd)
{

    deptsiz0_data_t deptsiz;
    int is_last = 0;
    dwc_ep_t* ep = &g_dwc_eps[0];

    DBG("ep0_complete_request()\n");
    if (pcd->ep0state == EP0_STATUS)
    {
        is_last = 1;
    }
    else if (ep->xfer_len == 0)
    {
        ep->xfer_len = 0;
        ep->xfer_count = 0;
        ep->sent_zlp = 1;
        dwc_otg_ep_start_transfer( ep );
        return 1;
    }
    else if (ep->is_in)
    {
        deptsiz.d32 = dwc_read_reg32(DWC_REG_IN_EP_TSIZE(0) );
        if (deptsiz.b.xfersize == 0) {
            /* Is a Zero Len Packet needed? */
            do_setup_out_status_phase(pcd);
        }
    }
    else {
        /* ep0-OUT */
        do_setup_in_status_phase(pcd);
    }

    /* Complete the request */
    if (is_last) {
        ep->start_xfer_buff = 0;
        ep->xfer_buff = 0;
        ep->xfer_len = 0;
        return 1;
    }
    return 0;
}

/**
 * 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(uint8_t *_dest, uint16_t _bytes)	//Elvis Fool, add 'static'
{
	int i;
    /*const char* str =   (char*)_dest;*/
    uint32_t* pu32  = (uint32_t*)_dest;
    const unsigned lenIn32  = (_bytes>>2);
    const unsigned rest     = (_bytes & 3);

	/**
	 * @todo Account for the case where _dest is not dword aligned. This
	 * requires reading data from the FIFO into a uint32_t temp buffer,
	 * then moving it into the data buffer.
	 */
	//DBG("dwc_otg_read_packet() dest: %p, len: %d\n",_dest,_bytes);
    for (i = 0; i < lenIn32; ++i)
    {
        *pu32++ = dwc_read_reg32(DWC_REG_DATA_FIFO_START);
    }
    if (rest)
    {
        const unsigned fifoVal  = dwc_read_reg32(DWC_REG_DATA_FIFO_START);
        uint8_t*            pBufDst8    = (uint8_t*)pu32;
        const uint8_t*      pBufSrc8    = (const uint8_t*)&fifoVal;
        for (i = 0; i < rest; ++i)
        {
            *pBufDst8++ = *pBufSrc8++;
        }
    }

    /*
     *if(!strcmp("power", str))
     *    printf("%d>", _bytes),printf(str),printf("\n");
     */

	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.
 */
void dwc_otg_ep_write_packet( dwc_ep_t *_ep)
{
	/**
	 * The buffer is padded to DWORD on a per packet basis in
	 * slave/dma mode if the MPS is not DWORD aligned.  The last
	 * packet, if short, is also padded to a multiple of DWORD.
	 *
	 * ep->xfer_buff always starts DWORD aligned in memory and is a
	 * multiple of DWORD in length
	 *
	 * ep->xfer_len can be any number of bytes
	 *
	 * ep->xfer_count is a multiple of ep->maxpacket until the last
	 *  packet
	 *
	 * FIFO access is DWORD */

	uint32_t i;
	uint32_t byte_count;
	uint32_t dword_count;
	uint32_t fifo;
    uint8_t *data_buff = _ep->xfer_buff;
    uint32_t temp_data ;

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

        /* Find the byte length of the packet either short packet or MPS */
        byte_count = _ep->xfer_len - _ep->xfer_count;
        if (byte_count > _ep->maxpacket) byte_count = _ep->maxpacket;

	/* Find the DWORD length, padded by extra bytes as neccessary if MPS
	 * is not a multiple of DWORD */
	dword_count =  (byte_count + 3) / 4;


       //fifo = _core_if->data_fifo[_ep->num];
     fifo = DWC_REG_DATA_FIFO(_ep->num);


	for (i=0; i<dword_count; i++) {
		temp_data =get_unaligned(data_buff);
		dwc_write_reg32( fifo, temp_data );
		data_buff += 4;
	}


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

	flush_cpu_cache();

}
/**
 * This function reads a setup packet from the Rx FIFO into the destination
 * buffer.  This function is called from the Rx Status Queue Level (RxStsQLvl)
 * Interrupt routine when a SETUP packet has been received in Slave mode.
 *
 * @param _core_if Programming view of DWC_otg controller.
 * @param _dest Destination buffer for packet data.
 */
void dwc_otg_read_setup_packet(uint32_t *_dest)
{
	/* Get the 8 bytes of a setup transaction data */

	DBG("dwc_otg_read_setup_packet()\n");
	/* 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);
}



/**
 * handle the IN EP disable interrupt.
 */
static void handle_in_ep_disable_intr(uint32_t _epnum)
{
#if 0
        deptsiz_data_t dieptsiz = { 0 };
        dctl_data_t dctl = { 0 };
        depctl_data_t diepctl = { 0 };
        dwc_ep_t *ep = &g_dwc_eps[_epnum];

        if (ep->stopped) {
                /* Flush the Tx FIFO */
                /** @todo NGS: This is not the correct FIFO */
                dwc_otg_flush_tx_fifo( core_if, 0 );
                /* Clear the Global IN NP NAK */
                dctl.d32 = 0;
                dctl.b.cgnpinnak = 1;
                dwc_modify_reg32(&dev_if->in_ep_regs[_epnum]->diepctl,
                                 diepctl.d32, diepctl.d32);
                /* Restart the transaction */
                if (dieptsiz.b.pktcnt != 0 ||
                    dieptsiz.b.xfersize != 0) {
                        restart_transfer( _pcd, _epnum );
                }
        }
#endif
}

/**
 * Handler for the IN EP timeout handshake interrupt.
 */
static void handle_in_ep_timeout_intr(uint32_t _epnum)
{

        dctl_data_t dctl = { 0 };
        dwc_ep_t *ep = &g_dwc_eps[_epnum];

        gintmsk_data_t intr_mask = {0};


        /* Disable the NP Tx Fifo Empty Interrrupt */

	intr_mask.b.nptxfempty = 1;
	dwc_modify_reg32( DWC_REG_GINTMSK, intr_mask.d32, 0);
        /** @todo NGS Check EP type.
         * Implement for Periodic EPs */
        /*
         * Non-periodic EP
         */
        /* 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
 */
int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(void)
{
    gintmsk_data_t gintmask = { 0 };
    device_grxsts_data_t status;
    gintsts_data_t gintsts;
    dwc_ep_t *ep;


    DBG("dwc_otg_pcd_handle_rx_status_q_level_intr()\n");
    /* 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);

    //DBG("rx status: ep%d, pktsts: %d\n",status.b.epnum,status.b.pktsts);

    /* Get pointer to EP structure */
    ep = &g_dwc_eps[status.b.epnum];

    switch (status.b.pktsts)
    {
        case DWC_DSTS_GOUT_NAK:
            DBG( "Global OUT NAK\n");
            break;

        case DWC_STS_DATA_UPDT:
            DBG( "OUT Data Packet\n");
            {
                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;

                    if (!status.b.epnum)
                    {
                        /*const char* p = ep->xfer_buff - status.b.bcnt;*/
                        this_pcd[0].cmdtype.out_complete = 1;
                        /*
                         *if(!strcmp("power", p) || !strcmp("low_power", p)){
                         *    printf("%s, bcnt %d, cnt %d, %d\n", p, status.b.bcnt, ep->xfer_count, this_pcd.cmdtype.in_complete);
                         *}
                         */
                    }
                }
            }
            break;

        case DWC_STS_XFER_COMP:
            DBG("OUT Complete\n");
            break;

        case DWC_DSTS_SETUP_COMP:
            DBG("SETUP Complete\n");
            break;

        case DWC_DSTS_SETUP_UPDT:
            DBG("SETUP update\n");
            {
                static int _is_first_setup_out_in_cmd = 1;

                dwc_otg_read_setup_packet( this_pcd[0].setup_pkt.d32);
                this_pcd[0].request_enable = 1;
                ep->xfer_count += status.b.bcnt;

                DBG("set %d, %d\n", status.b.bcnt, ep->xfer_count);
                if (_is_first_setup_out_in_cmd) //first tplcmd/bulkcmd that in sequence 'setup + out + in'
                {
                    struct usb_ctrlrequest request = this_pcd[0].setup_pkt.req;
                    if ( USB_TYPE_VENDOR == (request.bRequestType & USB_TYPE_MASK) )
                    {
                        unsigned bRequest = request.bRequest;

                        if ((AM_REQ_WR_LARGE_MEM == bRequest) || (AM_REQ_RD_LARGE_MEM == bRequest)
                                ||(AM_REQ_TPL_CMD == bRequest) || (AM_REQ_TPL_STAT == bRequest)
                                || (AM_REQ_DOWNLOAD == bRequest) || (AM_REQ_BULKCMD == bRequest))
                        {
                            __udelay(20);//delay for first command that consisted of consecutive 'ep0 out', i.e. 'setup + out + in'
                            _is_first_setup_out_in_cmd = 0;
                        }
                    }
                }
            }
        break;

        default:
            //DBG( "Invalid Packet Status (0x%0x)\n", status.b.pktsts);
            break;

    }

    /* Enable the Rx Status Queue Level interrupt */
    dwc_modify_reg32( DWC_REG_GINTMSK, 0, gintmask.d32);
    /* Clear interrupt */
    gintsts.d32 = 0;
    gintsts.b.rxstsqlvl = 1;
    dwc_write_reg32 ( DWC_REG_GINTSTS, gintsts.d32);

    return 1;
}


/**
 * 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.
 */
int32_t dwc_otg_pcd_handle_np_tx_fifo_empty_intr(void)
{
        gnptxsts_data_t txstatus = {0};
        gintsts_data_t gintsts;

        int epnum = 0;
        dwc_ep_t *ep = 0;
        uint32_t len = 0;
        int dwords;
	 depctl_data_t depctl;

	DBG("dwc_otg_pcd_handle_np_tx_fifo_empty_intr()\n");
        /* Get the epnum from the IN Token Learning Queue. */
	for (epnum=0; epnum < NUM_EP; epnum++)
	{

		ep = &g_dwc_eps[epnum];


		/* IN endpoint ? */
		if (epnum && !ep->is_in ) {
			continue;
	        }
		depctl.d32 = dwc_read_reg32(DWC_REG_IN_EP_REG(epnum));
	       if (depctl.b.epena != 1)
			continue;

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

		 flush_cpu_cache();

	        len = ep->xfer_len - ep->xfer_count;
	        if (len > ep->maxpacket) {
	                len = ep->maxpacket;
	        }
	        dwords = (len + 3)/4;

		 //DBG("nptx: write data to fifo, ep%d , size %d\n",epnum,len);
	        /* 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) {

			   flush_cpu_cache();

			   /* Write the FIFO */
	                dwc_otg_ep_write_packet( ep );

	                len = ep->xfer_len - ep->xfer_count;
	                if (len > ep->maxpacket) {
	                        len = ep->maxpacket;
	                }
	                dwords = (len + 3)/4;
			   flush_cpu_cache();
			   //txstatus.d32 = dwc_read_reg32(DWC_REG_GNPTXSTS);
#if 1
			   /*
				  TODO:  Remove these code.
				  Because, if code break from "while"(Line427), an incomplete-in-trans will occour.
				  Then the tansfer will break.
			   */
			   int retry = 50000;	//retry times
			   while (retry--)
			   {
			       txstatus.d32 = dwc_read_reg32(DWC_REG_GNPTXSTS);
				if(txstatus.b.nptxqspcavail > 0  || //txstatus.b.nptxfspcavail <= dwords ||
					ep->xfer_count >= ep->xfer_len)
					break;
				else
				{
					flush_cpu_cache();
				}

			   }
			   if (retry <= 0)
			   {
				//DWC_ERROR("TxFIFO FULL: Can't trans data to HOST !\n");
			   }

			   /* END todo */
#endif
	        }

	}

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

        return 1;
}
/**
 * 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.
 */
int32_t dwc_otg_pcd_handle_enum_done_intr(void)
{
	gintsts_data_t gintsts;
	gusbcfg_data_t gusbcfg;
	/*dsts_data_t dsts;*/
	depctl_data_t diepctl;
	depctl_data_t doepctl;
	dctl_data_t dctl ={0};
#if (defined CONFIG_USB_DEVICE_V2)
	depctl_data_t depctl;
#endif

	DBG("SPEED ENUM\n");

#ifdef CONFIG_USB_DEVICE_V2
	set_usb_phy21_tuning_update();
#endif

	/* Read the Device Status and Endpoint 0 Control registers */
	/*dsts.d32 = dwc_read_reg32(DWC_REG_DSTS);*/
	diepctl.d32 = dwc_read_reg32(DWC_REG_IN_EP_REG(0) );
	doepctl.d32 = dwc_read_reg32(DWC_REG_OUT_EP_REG(0));

	/* Set the MPS of the IN EP based on the enumeration speed */
	diepctl.b.mps = DWC_DEP0CTL_MPS_64;
	dwc_write_reg32(DWC_REG_IN_EP_REG(0) , diepctl.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

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

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

        if (this_pcd[0].ep0state == EP0_DISCONNECT) {
				this_pcd[0].ep0state = EP0_IDLE;
		} else if (this_pcd[0].ep0state == EP0_STALL) {
				this_pcd[0].ep0state = EP0_IDLE;
        }

    this_pcd[0].ep0state = EP0_IDLE;


	/* Set USB turnaround time based on device speed and PHY interface. */
	gusbcfg.d32 = dwc_read_reg32(DWC_REG_GUSBCFG);
#if 0
	if (_pcd->gadget.speed == USB_SPEED_HIGH) {
		if (GET_CORE_IF(_pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_ULPI) {
			/* ULPI interface */
			gusbcfg.b.usbtrdtim = 9;
		}
		if (GET_CORE_IF(_pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_UTMI) {
			/* UTMI+ interface */
			if (GET_CORE_IF(_pcd)->core_params->phy_utmi_width == 16) {
				gusbcfg.b.usbtrdtim = 5;
			} else {
				gusbcfg.b.usbtrdtim = 9;
			}
		}
		if (GET_CORE_IF(_pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI) {
			/* UTMI+  OR  ULPI interface */
			if (gusbcfg.b.ulpi_utmi_sel == 1) {
				/* ULPI interface */
				gusbcfg.b.usbtrdtim = 9;
			} else {
				/* UTMI+ interface */
				if (GET_CORE_IF(_pcd)->core_params->phy_utmi_width == 16) {
					gusbcfg.b.usbtrdtim = 5;
				} else {
					gusbcfg.b.usbtrdtim = 9;
				}
			}
		}
	} else {
		/* Full or low speed */
		gusbcfg.b.usbtrdtim = 9;
	}
#else
	/* Full or low speed */
#if (defined CONFIG_USB_DEVICE_V2)
	gusbcfg.b.usbtrdtim = 9;
#else
	gusbcfg.b.usbtrdtim = 5;
#endif
#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 );
	return 1;
}
///////////////////////////////////////////////////////////////////
/**
 * This interrupt indicates that an OUT EP has a pending Interrupt.
 * The sequence for handling the OUT EP interrupt is shown below:
 * -#	Read the Device All Endpoint Interrupt register
 * -#	Repeat the following for each OUT EP interrupt bit set (from
 *   	LSB to MSB).
 * -#	Read the Device Endpoint Interrupt (DOEPINTn) register
 * -#	If "Transfer Complete" call the request complete function
 * -#	If "Endpoint Disabled" complete the EP disable procedure.
 * -#	If "AHB Error Interrupt" log error
 * -#	If "Setup Phase Done" process Setup Packet (See Standard USB
 *   	Command Processing)
 */
static int32_t dwc_otg_pcd_handle_out_ep_intr(void)
{
#define CLEAR_OUT_EP_INTR(__epnum,__intr) \
do { \
        doepint_data_t doepint = { 0 }; \
	doepint.b.__intr = 1; \
	dwc_write_reg32(DWC_REG_OUT_EP_INTR(__epnum), \
			doepint.d32); \
} while (0)

        uint32_t ep_intr;
        doepint_data_t doepint = { 0 };
        uint32_t epnum = 0;
//	 uint32_t epnum_trans = 0;
        gintsts_data_t gintsts;

        DBG( "dwc_otg_pcd_handle_out_ep_intr()\n" );

	/* 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.d32 = 0;
	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 ) {
				DBG("EP%d OUT Xfer Complete\n", epnum);

				/* Clear the bit in DOEPINTn for this interrupt */
				CLEAR_OUT_EP_INTR(epnum,xfercompl);

				if (epnum == 0) {
					handle_ep0( 0 );
				} else {
					complete_ep( epnum,0 );
				}
                    }
                    /* Endpoint disable  */
                    if ( doepint.b.epdisabled ) {
                            DBG("EP%d OUT disabled\n", epnum);
				/* Clear the bit in DOEPINTn for this interrupt */
				CLEAR_OUT_EP_INTR(epnum,epdisabled);
                    }
                    /* AHB Error */
                    if ( doepint.b.ahberr ) {
                            DBG("EP%d OUT AHB Error\n", epnum);
				CLEAR_OUT_EP_INTR(epnum,ahberr);
                    }
                    /* Setup Phase Done (contorl EPs) */
                    if ( doepint.b.setup ) {
                            handle_ep0( 0 );
				CLEAR_OUT_EP_INTR(epnum,setup);
                    }
            }
		epnum++;
		ep_intr >>=1;
        }

        return 1;

#undef CLEAR_OUT_EP_INTR
}
/**
 * This interrupt indicates that an IN EP has a pending Interrupt.
 * The sequence for handling the IN EP interrupt is shown below:
 * -#	Read the Device All Endpoint Interrupt register
 * -#	Repeat the following for each IN EP interrupt bit set (from
 *   	LSB to MSB).
 * -#	Read the Device Endpoint Interrupt (DIEPINTn) register
 * -#	If "Transfer Complete" call the request complete function
 * -#	If "Endpoint Disabled" complete the EP disable procedure.
 * -#	If "AHB Error Interrupt" log error
 * -#	If "Time-out Handshake" log error
 * -#	If "IN Token Received when TxFIFO Empty" write packet to Tx
 *   	FIFO.
 * -#	If "IN Token EP Mismatch" (disable, this is handled by EP
 *   	Mismatch Interrupt)
 */
static int32_t dwc_otg_pcd_handle_in_ep_intr(void)
{
#define CLEAR_IN_EP_INTR(__epnum,__intr) \
do { \
        diepint_data_t diepint = { 0 }; \
	diepint.b.__intr = 1; \
	dwc_write_reg32(DWC_REG_IN_EP_INTR(__epnum), \
			diepint.d32); \
} while (0)

        diepint_data_t diepint = { 0 };
//        depctl_data_t diepctl = { 0 };
        uint32_t ep_intr;
        uint32_t epnum = 0;
        gintmsk_data_t intr_mask = {0};
        gintsts_data_t gintsts;

	 DBG( "dwc_otg_pcd_handle_in_ep_intr()\n" );

	/* Read in the device interrupt bits */
        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.d32 = 0;
	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 (epnum == 0) {
						handle_ep0( 0 );
					} else {
						complete_ep( epnum,1 );
					}
                        }
                        /* Endpoint disable  */
                        if ( diepint.b.epdisabled ) {
                                handle_in_ep_disable_intr( epnum );

                                /* 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) {
                                DWN_MSG("diepint.b.intktxfemp\n");
#if 0
                                if (!ep->stopped && epnum != 0) {
                                        diepmsk_data_t diepmsk = { 0};
                                        diepmsk.b.intktxfemp = 1;
                                        dwc_modify_reg32( &dev_if->dev_global_regs->diepmsk, diepmsk.d32, 0 );
                                        start_next_request(ep);
                                }
#endif
				CLEAR_IN_EP_INTR(epnum,intktxfemp);
                        }
                        /** IN Token Received with EP mismatch */
                        if (diepint.b.intknepmis) {
                                DWN_MSG("intknepmis ep%d\n", epnum);
                                CLEAR_IN_EP_INTR(epnum,intknepmis);
                        }
                        /** IN Endpoint NAK Effective */
                        if (diepint.b.inepnakeff) {
				CLEAR_IN_EP_INTR(epnum,inepnakeff);
                        }
                }
                epnum++;
                ep_intr >>=1;
        }

        return 1;

#undef CLEAR_IN_EP_INTR
}
/**
 * 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;

	DBG("ep0_out_start()\n");
	dwc_write_reg32( DWC_REG_OUT_EP_TSIZE(0),doeptsize0.d32 );


	// EP enable
	doepctl.d32 = dwc_read_reg32(DWC_REG_OUT_EP_REG(0));
	doepctl.b.epena = 1;

	doepctl.d32 = 0x80008000;
	dwc_write_reg32(DWC_REG_OUT_EP_REG(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.
 */
int32_t 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 };
        int i = 0;
        gintsts_data_t gintsts;


        DBG("\nUSB RESET\n");


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

        /* Disable all active IN EPs */
        diepctl.b.epdis = 1;
        diepctl.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) {
                        dwc_write_reg32(DWC_REG_IN_EP_REG(i),diepctl.d32 );
                }
        }

        /* Set NAK for all OUT EPs */
        doepctl.b.snak = 1;
        for (i=0; i < NUM_EP; i++) {
                dwc_write_reg32(DWC_REG_OUT_EP_REG(i), doepctl.d32 );
        }

        /* Flush the NP Tx FIFO */
        dwc_otg_flush_tx_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.d32 = 0;
	gintsts.b.usbreset = 1;
	dwc_write_reg32 ( DWC_REG_GINTSTS, gintsts.d32);

	flush_cpu_cache();
        return 1;
}


///////////////////////////////////////////////////////////////////
int dwc_common_irq(void)
{
	int ret = 0;
	gotgint_data_t gotgint;

	gotgint.d32 = dwc_read_reg32(DWC_REG_GOTGINT);
	if (gotgint.d32 == 0)
		return 0;
	if (gotgint.b.sesreqsucstschng) {
		ERR("Session Request Success Status Change\n");
	}
	if (gotgint.b.sesenddet) {
		ERR("Session End Detected, Line Disconected\n");
                cb_4_dis_connect_intr();
	}

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

	return ret;
}

int dwc_pcd_irq(void)
{
	gintsts_data_t  gintr_status;
	gintsts_data_t  gintr_msk;

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

	if ((gintr_status.d32 & gintr_msk.d32)== 0)
		return 0;

	DBG("irq gintmsk:  0x%08x\n",gintr_msk.d32);
	DBG("irq gintrsts: 0x%08x\n",gintr_status.d32);

	gintr_status.d32 = gintr_status.d32 & gintr_msk.d32;
	DBG("irq gintmsk & gintrsts = 0x%08x\n",gintr_status.d32);

    if (gintr_status.b.sofintr)
	{
#if (defined CONFIG_USB_DEVICE_V2)
		curTime_sof = get_timer(0);
		_sofintr = 1;
#endif
        if (_sofintr_not_occur) {
			DWN_MSG("sof\n");
			_sofintr_not_occur = 0;
		}
	}

	if (gintr_status.b.rxstsqlvl) {
		dwc_otg_pcd_handle_rx_status_q_level_intr();
		pcd_out_completed(&this_pcd[0]);
	}
	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.enumdone) {
	    dwc_otg_pcd_handle_enum_done_intr();
	}
	if (gintr_status.b.epmismatch) {
	    //dwc_otg_pcd_handle_ep_mismatch_intr( core_if );
	}
	if (gintr_status.b.inepint) {
	    dwc_otg_pcd_handle_in_ep_intr();
	}
	if (gintr_status.b.outepintr) {
	    dwc_otg_pcd_handle_out_ep_intr( );
	}

#if 0
    if (gintr_status.b.otgintr)
    {
        gotgint_data_t gotgint;

        gotgint.d32 = dwc_read_reg32(DWC_REG_GOTGINT);
        if (gotgint.b.sesenddet)
        {
            printf("dis-connect-intr\n");
            cb_4_dis_connect_intr();
        }
    }
#endif//#if 0

    dwc_write_reg32(DWC_REG_GINTSTS,gintr_status.d32);
    flush_cpu_cache();
	return 0;
}
