/* ==========================================================================
 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd.c $
 * $Revision: #99 $
 * $Date: 2011/10/24 $
 * $Change: 1871160 $
 *
 * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
 * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
 * otherwise expressly agreed to in writing between Synopsys and you.
 *
 * The Software IS NOT an item of Licensed Software or Licensed Product under
 * any End User Software License Agreement or Agreement for Licensed Product
 * with Synopsys or any supplement thereto. You are permitted to use and
 * redistribute this Software in source and binary forms, with or without
 * modification, provided that redistributions of source code must retain this
 * notice. You may not view, use, disclose, copy or distribute this file or
 * any information contained herein except pursuant to this license grant from
 * Synopsys. If you do not agree with this notice, including the disclaimer
 * below, then you are not authorized to use the Software.
 *
 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * ========================================================================== */
#ifndef DWC_HOST_ONLY

/** @file
 * This file implements PCD Core. All code in this file is portable and doesn't
 * use any OS specific functions.
 * PCD Core provides Interface, defined in <code><dwc_otg_pcd_if.h></code>
 * header file, which can be used to implement OS specific PCD interface.
 *
 * An important function of the PCD is managing interrupts generated
 * by the DWC_otg controller. The implementation of the DWC_otg device
 * mode interrupt service routines is in dwc_otg_pcd_intr.c.
 *
 * @todo Add Device Mode test modes (Test J mode, Test K mode, etc).
 * @todo Does it work when the request size is greater than DEPTSIZ
 * transfer size
 *
 */

#include "dwc_otg_pcd.h"

#ifdef DWC_UTE_CFI
#include "dwc_otg_cfi.h"

extern int init_cfi(cfiobject_t * cfiobj);
#endif

/**
 * Choose endpoint from ep arrays using usb_ep structure.
 */
static dwc_otg_pcd_ep_t *get_ep_from_handle(dwc_otg_pcd_t * pcd, void *handle)
{
	int i;
	if (pcd->ep0.priv == handle) {
		return &pcd->ep0;
	}
	for (i = 0; i < MAX_EPS_CHANNELS - 1; i++) {
		if (pcd->in_ep[i].priv == handle)
			return &pcd->in_ep[i];
		if (pcd->out_ep[i].priv == handle)
			return &pcd->out_ep[i];
	}

	return NULL;
}

/**
 * This function completes a request.  It call's the request call back.
 */
void dwc_otg_request_done(dwc_otg_pcd_ep_t * ep, dwc_otg_pcd_request_t * req,
			  int32_t status)
{
	unsigned stopped = ep->stopped;
	
	DWC_DEBUGPL(DBG_PCDV, "%s(ep %p req %p)\n", __func__, ep, req);
	DWC_CIRCLEQ_REMOVE_INIT(&ep->queue, req, queue_entry);

	/* don't modify queue heads during completion callback */
	ep->stopped = 1;
	/* spin_unlock/spin_lock now done in fops->complete() */
	ep->pcd->fops->complete(ep->pcd, ep->priv, req->priv, status,
				req->actual);

	if (ep->pcd->request_pending > 0) {
		--ep->pcd->request_pending;
	}

	ep->stopped = stopped;
	DWC_FREE(req);
}

/**
 * This function terminates all the requsts in the EP request queue.
 */
void dwc_otg_request_nuke(dwc_otg_pcd_ep_t * ep)
{
	dwc_otg_pcd_request_t *req;

	ep->stopped = 1;

	/* called with irqs blocked?? */
	while (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
		req = DWC_CIRCLEQ_FIRST(&ep->queue);
		dwc_otg_request_done(ep, req, -DWC_E_SHUTDOWN);
	}
}

void dwc_otg_pcd_start(dwc_otg_pcd_t * pcd,
		       const struct dwc_otg_pcd_function_ops *fops)
{
	pcd->fops = fops;
}

/**
 * PCD Callback function for initializing the PCD when switching to
 * device mode.
 *
 * @param p void pointer to the <code>dwc_otg_pcd_t</code>
 */
static int32_t dwc_otg_pcd_start_cb(void *p)
{
	dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) p;
	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);

	/*
	 * Initialized the Core for Device mode.
	 */
	if (dwc_otg_is_device_mode(core_if)) {
		dwc_otg_core_dev_init(core_if);
		/* Set core_if's lock pointer to the pcd->lock */
		core_if->lock = pcd->lock;
	}
	return 1;
}

/** CFI-specific buffer allocation function for EP */
#ifdef DWC_UTE_CFI
uint8_t *cfiw_ep_alloc_buffer(dwc_otg_pcd_t * pcd, void *pep, dwc_dma_t * addr,
			      size_t buflen, int flags)
{
	dwc_otg_pcd_ep_t *ep;
	ep = get_ep_from_handle(pcd, pep);
	if (!ep) {
		DWC_WARN("bad ep\n");
		return -DWC_E_INVALID;
	}

	return pcd->cfi->ops.ep_alloc_buf(pcd->cfi, pcd, ep, addr, buflen,
					  flags);
}
#else
uint8_t *cfiw_ep_alloc_buffer(dwc_otg_pcd_t * pcd, void *pep, dwc_dma_t * addr,
			      size_t buflen, int flags);
#endif

/**
 * PCD Callback function for notifying the PCD when resuming from
 * suspend.
 *
 * @param p void pointer to the <code>dwc_otg_pcd_t</code>
 */
static int32_t dwc_otg_pcd_resume_cb(void *p)
{
	dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) p;

	if (pcd->fops->resume) {
		pcd->fops->resume(pcd);
	}

	/* Stop the SRP timeout timer. */
	if ((GET_CORE_IF(pcd)->core_params->phy_type != DWC_PHY_TYPE_PARAM_FS)
	    || (!GET_CORE_IF(pcd)->core_params->i2c_enable)) {
		if (GET_CORE_IF(pcd)->srp_timer_started) {
			GET_CORE_IF(pcd)->srp_timer_started = 0;
			DWC_TIMER_CANCEL(GET_CORE_IF(pcd)->srp_timer);
		}
	}
	return 1;
}

/**
 * PCD Callback function for notifying the PCD device is suspended.
 *
 * @param p void pointer to the <code>dwc_otg_pcd_t</code>
 */
static int32_t dwc_otg_pcd_suspend_cb(void *p)
{
	dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) p;

	if (pcd->fops->suspend) {
		DWC_SPINUNLOCK(pcd->lock);
		pcd->fops->suspend(pcd);
		DWC_SPINLOCK(pcd->lock);
	}

	return 1;
}

/**
 * PCD Callback function for stopping the PCD when switching to Host
 * mode.
 *
 * @param p void pointer to the <code>dwc_otg_pcd_t</code>
 */
static int32_t dwc_otg_pcd_stop_cb(void *p)
{
	dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) p;
	extern void dwc_otg_pcd_stop(dwc_otg_pcd_t * _pcd);

	dwc_otg_pcd_stop(pcd);
	return 1;
}

/**
 * PCD Callback structure for handling mode switching.
 */
static dwc_otg_cil_callbacks_t pcd_callbacks = {
	.start = dwc_otg_pcd_start_cb,
	.stop = dwc_otg_pcd_stop_cb,
	.suspend = dwc_otg_pcd_suspend_cb,
	.resume_wakeup = dwc_otg_pcd_resume_cb,
	.p = 0,			/* Set at registration */
};

/**
 * This function allocates a DMA Descriptor chain for the Endpoint
 * buffer to be used for a transfer to/from the specified endpoint.
 */
dwc_otg_dev_dma_desc_t *dwc_otg_ep_alloc_desc_chain(dwc_dma_t * dma_desc_addr,
						    uint32_t count)
{
	return DWC_DMA_ALLOC_ATOMIC(count * sizeof(dwc_otg_dev_dma_desc_t), 
							dma_desc_addr);
}

/**
 * This function frees a DMA Descriptor chain that was allocated by ep_alloc_desc.
 */
void dwc_otg_ep_free_desc_chain(dwc_otg_dev_dma_desc_t * desc_addr,
				uint32_t dma_desc_addr, uint32_t count)
{
	DWC_DMA_FREE(count * sizeof(dwc_otg_dev_dma_desc_t), desc_addr,
		     dma_desc_addr);
}

#ifdef DWC_EN_ISOC

/**
 * This function initializes a descriptor chain for Isochronous transfer
 *
 * @param core_if Programming view of DWC_otg controller.
 * @param dwc_ep The EP to start the transfer on.
 *
 */
void dwc_otg_iso_ep_start_ddma_transfer(dwc_otg_core_if_t * core_if,
					dwc_ep_t * dwc_ep)
{

	dsts_data_t dsts = {.d32 = 0 };
	depctl_data_t depctl = {.d32 = 0 };
	volatile uint32_t *addr;
	int i, j;
	uint32_t len;

	if (dwc_ep->is_in)
		dwc_ep->desc_cnt = dwc_ep->buf_proc_intrvl / dwc_ep->bInterval;
	else
		dwc_ep->desc_cnt =
		    dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm /
		    dwc_ep->bInterval;

	/** Allocate descriptors for double buffering */
	dwc_ep->iso_desc_addr =
	    dwc_otg_ep_alloc_desc_chain(&dwc_ep->iso_dma_desc_addr,
					dwc_ep->desc_cnt * 2);
	if (dwc_ep->desc_addr) {
		DWC_WARN("%s, can't allocate DMA descriptor chain\n", __func__);
		return;
	}

	dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);

	/** ISO OUT EP */
	if (dwc_ep->is_in == 0) {
		dev_dma_desc_sts_t sts = {.d32 = 0 };
		dwc_otg_dev_dma_desc_t *dma_desc = dwc_ep->iso_desc_addr;
		dma_addr_t dma_ad;
		uint32_t data_per_desc;
		dwc_otg_dev_out_ep_regs_t *out_regs =
		    core_if->dev_if->out_ep_regs[dwc_ep->num];
		int offset;

		addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
		dma_ad = (dma_addr_t) DWC_READ_REG32(&(out_regs->doepdma));

		/** Buffer 0 descriptors setup */
		dma_ad = dwc_ep->dma_addr0;

		sts.b_iso_out.bs = BS_HOST_READY;
		sts.b_iso_out.rxsts = 0;
		sts.b_iso_out.l = 0;
		sts.b_iso_out.sp = 0;
		sts.b_iso_out.ioc = 0;
		sts.b_iso_out.pid = 0;
		sts.b_iso_out.framenum = 0;

		offset = 0;
		for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
		     i += dwc_ep->pkt_per_frm) {

			for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
				uint32_t len = (j + 1) * dwc_ep->maxpacket;
				if (len > dwc_ep->data_per_frame)
					data_per_desc =
					    dwc_ep->data_per_frame -
					    j * dwc_ep->maxpacket;
				else
					data_per_desc = dwc_ep->maxpacket;
				len = data_per_desc % 4;
				if (len)
					data_per_desc += 4 - len;

				sts.b_iso_out.rxbytes = data_per_desc;
				dma_desc->buf = dma_ad;
				dma_desc->status.d32 = sts.d32;

				offset += data_per_desc;
				dma_desc++;
				dma_ad += data_per_desc;
			}
		}

		for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
			uint32_t len = (j + 1) * dwc_ep->maxpacket;
			if (len > dwc_ep->data_per_frame)
				data_per_desc =
				    dwc_ep->data_per_frame -
				    j * dwc_ep->maxpacket;
			else
				data_per_desc = dwc_ep->maxpacket;
			len = data_per_desc % 4;
			if (len)
				data_per_desc += 4 - len;
			sts.b_iso_out.rxbytes = data_per_desc;
			dma_desc->buf = dma_ad;
			dma_desc->status.d32 = sts.d32;

			offset += data_per_desc;
			dma_desc++;
			dma_ad += data_per_desc;
		}

		sts.b_iso_out.ioc = 1;
		len = (j + 1) * dwc_ep->maxpacket;
		if (len > dwc_ep->data_per_frame)
			data_per_desc =
			    dwc_ep->data_per_frame - j * dwc_ep->maxpacket;
		else
			data_per_desc = dwc_ep->maxpacket;
		len = data_per_desc % 4;
		if (len)
			data_per_desc += 4 - len;
		sts.b_iso_out.rxbytes = data_per_desc;

		dma_desc->buf = dma_ad;
		dma_desc->status.d32 = sts.d32;
		dma_desc++;

		/** Buffer 1 descriptors setup */
		sts.b_iso_out.ioc = 0;
		dma_ad = dwc_ep->dma_addr1;

		offset = 0;
		for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
		     i += dwc_ep->pkt_per_frm) {
			for (j = 0; j < dwc_ep->pkt_per_frm; ++j) {
				uint32_t len = (j + 1) * dwc_ep->maxpacket;
				if (len > dwc_ep->data_per_frame)
					data_per_desc =
					    dwc_ep->data_per_frame -
					    j * dwc_ep->maxpacket;
				else
					data_per_desc = dwc_ep->maxpacket;
				len = data_per_desc % 4;
				if (len)
					data_per_desc += 4 - len;

				data_per_desc =
				    sts.b_iso_out.rxbytes = data_per_desc;
				dma_desc->buf = dma_ad;
				dma_desc->status.d32 = sts.d32;

				offset += data_per_desc;
				dma_desc++;
				dma_ad += data_per_desc;
			}
		}
		for (j = 0; j < dwc_ep->pkt_per_frm - 1; ++j) {
			data_per_desc =
			    ((j + 1) * dwc_ep->maxpacket >
			     dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
			    j * dwc_ep->maxpacket : dwc_ep->maxpacket;
			data_per_desc +=
			    (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
			sts.b_iso_out.rxbytes = data_per_desc;
			dma_desc->buf = dma_ad;
			dma_desc->status.d32 = sts.d32;

			offset += data_per_desc;
			dma_desc++;
			dma_ad += data_per_desc;
		}

		sts.b_iso_out.ioc = 1;
		sts.b_iso_out.l = 1;
		data_per_desc =
		    ((j + 1) * dwc_ep->maxpacket >
		     dwc_ep->data_per_frame) ? dwc_ep->data_per_frame -
		    j * dwc_ep->maxpacket : dwc_ep->maxpacket;
		data_per_desc +=
		    (data_per_desc % 4) ? (4 - data_per_desc % 4) : 0;
		sts.b_iso_out.rxbytes = data_per_desc;

		dma_desc->buf = dma_ad;
		dma_desc->status.d32 = sts.d32;

		dwc_ep->next_frame = 0;

		/** Write dma_ad into DOEPDMA register */
		DWC_WRITE_REG32(&(out_regs->doepdma),
				(uint32_t) dwc_ep->iso_dma_desc_addr);

	}
	/** ISO IN EP */
	else {
		dev_dma_desc_sts_t sts = {.d32 = 0 };
		dwc_otg_dev_dma_desc_t *dma_desc = dwc_ep->iso_desc_addr;
		dma_addr_t dma_ad;
		dwc_otg_dev_in_ep_regs_t *in_regs =
		    core_if->dev_if->in_ep_regs[dwc_ep->num];
		unsigned int frmnumber;
		fifosize_data_t txfifosize, rxfifosize;

		txfifosize.d32 =
		    DWC_READ_REG32(&core_if->dev_if->
				   in_ep_regs[dwc_ep->num]->dtxfsts);
		rxfifosize.d32 =
		    DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);

		addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;

		dma_ad = dwc_ep->dma_addr0;

		dsts.d32 =
		    DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);

		sts.b_iso_in.bs = BS_HOST_READY;
		sts.b_iso_in.txsts = 0;
		sts.b_iso_in.sp =
		    (dwc_ep->data_per_frame % dwc_ep->maxpacket) ? 1 : 0;
		sts.b_iso_in.ioc = 0;
		sts.b_iso_in.pid = dwc_ep->pkt_per_frm;

		frmnumber = dwc_ep->next_frame;

		sts.b_iso_in.framenum = frmnumber;
		sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
		sts.b_iso_in.l = 0;

		/** Buffer 0 descriptors setup */
		for (i = 0; i < dwc_ep->desc_cnt - 1; i++) {
			dma_desc->buf = dma_ad;
			dma_desc->status.d32 = sts.d32;
			dma_desc++;

			dma_ad += dwc_ep->data_per_frame;
			sts.b_iso_in.framenum += dwc_ep->bInterval;
		}

		sts.b_iso_in.ioc = 1;
		dma_desc->buf = dma_ad;
		dma_desc->status.d32 = sts.d32;
		++dma_desc;

		/** Buffer 1 descriptors setup */
		sts.b_iso_in.ioc = 0;
		dma_ad = dwc_ep->dma_addr1;

		for (i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm;
		     i += dwc_ep->pkt_per_frm) {
			dma_desc->buf = dma_ad;
			dma_desc->status.d32 = sts.d32;
			dma_desc++;

			dma_ad += dwc_ep->data_per_frame;
			sts.b_iso_in.framenum += dwc_ep->bInterval;

			sts.b_iso_in.ioc = 0;
		}
		sts.b_iso_in.ioc = 1;
		sts.b_iso_in.l = 1;

		dma_desc->buf = dma_ad;
		dma_desc->status.d32 = sts.d32;

		dwc_ep->next_frame = sts.b_iso_in.framenum + dwc_ep->bInterval;

		/** Write dma_ad into diepdma register */
		DWC_WRITE_REG32(&(in_regs->diepdma),
				(uint32_t) dwc_ep->iso_dma_desc_addr);
	}
	/** Enable endpoint, clear nak  */
	depctl.d32 = 0;
	depctl.b.epena = 1;
	depctl.b.usbactep = 1;
	depctl.b.cnak = 1;

	DWC_MODIFY_REG32(addr, depctl.d32, depctl.d32);
	depctl.d32 = DWC_READ_REG32(addr);
}

/**
 * This function initializes a descriptor chain for Isochronous transfer
 *
 * @param core_if Programming view of DWC_otg controller.
 * @param ep The EP to start the transfer on.
 *
 */
void dwc_otg_iso_ep_start_buf_transfer(dwc_otg_core_if_t * core_if,
				       dwc_ep_t * ep)
{
	depctl_data_t depctl = {.d32 = 0 };
	volatile uint32_t *addr;

	if (ep->is_in) {
		addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
	} else {
		addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
	}

	if (core_if->dma_enable == 0 || core_if->dma_desc_enable != 0) {
		return;
	} else {
		deptsiz_data_t deptsiz = {.d32 = 0 };

		ep->xfer_len =
		    ep->data_per_frame * ep->buf_proc_intrvl / ep->bInterval;
		ep->pkt_cnt =
		    (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
		ep->xfer_count = 0;
		ep->xfer_buff =
		    (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
		ep->dma_addr =
		    (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;

		if (ep->is_in) {
			/* Program the transfer size and packet count
			 *      as follows: xfersize = N * maxpacket +
			 *      short_packet pktcnt = N + (short_packet
			 *      exist ? 1 : 0) 
			 */
			deptsiz.b.mc = ep->pkt_per_frm;
			deptsiz.b.xfersize = ep->xfer_len;
			deptsiz.b.pktcnt =
			    (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
			DWC_WRITE_REG32(&core_if->dev_if->
					in_ep_regs[ep->num]->dieptsiz,
					deptsiz.d32);

			/* Write the DMA register */
			DWC_WRITE_REG32(&
					(core_if->dev_if->
					 in_ep_regs[ep->num]->diepdma),
					(uint32_t) ep->dma_addr);

		} else {
			deptsiz.b.pktcnt =
			    (ep->xfer_len + (ep->maxpacket - 1)) /
			    ep->maxpacket;
			deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;

			DWC_WRITE_REG32(&core_if->dev_if->
					out_ep_regs[ep->num]->doeptsiz,
					deptsiz.d32);

			/* Write the DMA register */
			DWC_WRITE_REG32(&
					(core_if->dev_if->
					 out_ep_regs[ep->num]->doepdma),
					(uint32_t) ep->dma_addr);

		}
		/** Enable endpoint, clear nak  */
		depctl.d32 = 0;
		depctl.b.epena = 1;
		depctl.b.cnak = 1;

		DWC_MODIFY_REG32(addr, depctl.d32, depctl.d32);
	}
}

/**
 * This function does the setup for a data transfer for an EP and
 * starts the transfer. For an IN transfer, the packets will be
 * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
 * the packets are unloaded from the Rx FIFO in the ISR.
 *
 * @param core_if Programming view of DWC_otg controller.
 * @param ep The EP to start the transfer on.
 */

static void dwc_otg_iso_ep_start_transfer(dwc_otg_core_if_t * core_if,
					  dwc_ep_t * ep)
{
	if (core_if->dma_enable) {
		if (core_if->dma_desc_enable) {
			if (ep->is_in) {
				ep->desc_cnt = ep->pkt_cnt / ep->pkt_per_frm;
			} else {
				ep->desc_cnt = ep->pkt_cnt;
			}
			dwc_otg_iso_ep_start_ddma_transfer(core_if, ep);
		} else {
			if (core_if->pti_enh_enable) {
				dwc_otg_iso_ep_start_buf_transfer(core_if, ep);
			} else {
				ep->cur_pkt_addr =
				    (ep->proc_buf_num) ? ep->
				    xfer_buff1 : ep->xfer_buff0;
				ep->cur_pkt_dma_addr =
				    (ep->proc_buf_num) ? ep->
				    dma_addr1 : ep->dma_addr0;
				dwc_otg_iso_ep_start_frm_transfer(core_if, ep);
			}
		}
	} else {
		ep->cur_pkt_addr =
		    (ep->proc_buf_num) ? ep->xfer_buff1 : ep->xfer_buff0;
		ep->cur_pkt_dma_addr =
		    (ep->proc_buf_num) ? ep->dma_addr1 : ep->dma_addr0;
		dwc_otg_iso_ep_start_frm_transfer(core_if, ep);
	}
}

/**
 * This function stops transfer for an EP and
 * resets the ep's variables. 
 *
 * @param core_if Programming view of DWC_otg controller.
 * @param ep The EP to start the transfer on.
 */

void dwc_otg_iso_ep_stop_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
{
	depctl_data_t depctl = {.d32 = 0 };
	volatile uint32_t *addr;

	if (ep->is_in == 1) {
		addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
	} else {
		addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
	}

	/* disable the ep */
	depctl.d32 = DWC_READ_REG32(addr);

	depctl.b.epdis = 1;
	depctl.b.snak = 1;

	DWC_WRITE_REG32(addr, depctl.d32);

	if (core_if->dma_desc_enable &&
	    ep->iso_desc_addr && ep->iso_dma_desc_addr) {
		dwc_otg_ep_free_desc_chain(ep->iso_desc_addr,
					   ep->iso_dma_desc_addr,
					   ep->desc_cnt * 2);
	}

	/* reset varibales */
	ep->dma_addr0 = 0;
	ep->dma_addr1 = 0;
	ep->xfer_buff0 = 0;
	ep->xfer_buff1 = 0;
	ep->data_per_frame = 0;
	ep->data_pattern_frame = 0;
	ep->sync_frame = 0;
	ep->buf_proc_intrvl = 0;
	ep->bInterval = 0;
	ep->proc_buf_num = 0;
	ep->pkt_per_frm = 0;
	ep->pkt_per_frm = 0;
	ep->desc_cnt = 0;
	ep->iso_desc_addr = 0;
	ep->iso_dma_desc_addr = 0;
}

int dwc_otg_pcd_iso_ep_start(dwc_otg_pcd_t * pcd, void *ep_handle,
			     uint8_t * buf0, uint8_t * buf1, dwc_dma_t dma0,
			     dwc_dma_t dma1, int sync_frame, int dp_frame,
			     int data_per_frame, int start_frame,
			     int buf_proc_intrvl, void *req_handle,
			     int atomic_alloc)
{
	dwc_otg_pcd_ep_t *ep;
	dwc_irqflags_t flags = 0;
	dwc_ep_t *dwc_ep;
	int32_t frm_data;
	dsts_data_t dsts;
	dwc_otg_core_if_t *core_if;

	ep = get_ep_from_handle(pcd, ep_handle);

	if (!ep || !ep->desc || ep->dwc_ep.num == 0) {
		DWC_WARN("bad ep\n");
		return -DWC_E_INVALID;
	}

	DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags);
	core_if = GET_CORE_IF(pcd);
	dwc_ep = &ep->dwc_ep;

	if (ep->iso_req_handle) {
		DWC_WARN("ISO request in progress\n");
	}

	dwc_ep->dma_addr0 = dma0;
	dwc_ep->dma_addr1 = dma1;

	dwc_ep->xfer_buff0 = buf0;
	dwc_ep->xfer_buff1 = buf1;

	dwc_ep->data_per_frame = data_per_frame;

	/** @todo - pattern data support is to be implemented in the future */
	dwc_ep->data_pattern_frame = dp_frame;
	dwc_ep->sync_frame = sync_frame;

	dwc_ep->buf_proc_intrvl = buf_proc_intrvl;

	dwc_ep->bInterval = 1 << (ep->desc->bInterval - 1);

	dwc_ep->proc_buf_num = 0;

	dwc_ep->pkt_per_frm = 0;
	frm_data = ep->dwc_ep.data_per_frame;
	while (frm_data > 0) {
		dwc_ep->pkt_per_frm++;
		frm_data -= ep->dwc_ep.maxpacket;
	}

	dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);

	if (start_frame == -1) {
		dwc_ep->next_frame = dsts.b.soffn + 1;
		if (dwc_ep->bInterval != 1) {
			dwc_ep->next_frame =
			    dwc_ep->next_frame + (dwc_ep->bInterval - 1 -
						  dwc_ep->next_frame %
						  dwc_ep->bInterval);
		}
	} else {
		dwc_ep->next_frame = start_frame;
	}

	if (!core_if->pti_enh_enable) {
		dwc_ep->pkt_cnt =
		    dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm /
		    dwc_ep->bInterval;
	} else {
		dwc_ep->pkt_cnt =
		    (dwc_ep->data_per_frame *
		     (dwc_ep->buf_proc_intrvl / dwc_ep->bInterval)
		     - 1 + dwc_ep->maxpacket) / dwc_ep->maxpacket;
	}

	if (core_if->dma_desc_enable) {
		dwc_ep->desc_cnt =
		    dwc_ep->buf_proc_intrvl * dwc_ep->pkt_per_frm /
		    dwc_ep->bInterval;
	}

	if (atomic_alloc) {
		dwc_ep->pkt_info =
		    DWC_ALLOC_ATOMIC(sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt);
	} else {
		dwc_ep->pkt_info =
		    DWC_ALLOC(sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt);
	}
	if (!dwc_ep->pkt_info) {
		DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
		return -DWC_E_NO_MEMORY;
	}
	if (core_if->pti_enh_enable) {
		dwc_memset(dwc_ep->pkt_info, 0,
			   sizeof(iso_pkt_info_t) * dwc_ep->pkt_cnt);
	}

	dwc_ep->cur_pkt = 0;
	ep->iso_req_handle = req_handle;

	DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
	dwc_otg_iso_ep_start_transfer(core_if, dwc_ep);
	return 0;
}

int dwc_otg_pcd_iso_ep_stop(dwc_otg_pcd_t * pcd, void *ep_handle,
			    void *req_handle)
{
	dwc_irqflags_t flags = 0;
	dwc_otg_pcd_ep_t *ep;
	dwc_ep_t *dwc_ep;

	ep = get_ep_from_handle(pcd, ep_handle);
	if (!ep || !ep->desc || ep->dwc_ep.num == 0) {
		DWC_WARN("bad ep\n");
		return -DWC_E_INVALID;
	}
	dwc_ep = &ep->dwc_ep;

	dwc_otg_iso_ep_stop_transfer(GET_CORE_IF(pcd), dwc_ep);

	DWC_FREE(dwc_ep->pkt_info);
	DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags);
	if (ep->iso_req_handle != req_handle) {
		DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
		return -DWC_E_INVALID;
	}

	DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);

	ep->iso_req_handle = 0;
	return 0;
}

/**
 * This function is used for perodical data exchnage between PCD and gadget drivers.
 * for Isochronous EPs
 *
 *	- Every time a sync period completes this function is called to
 *	  perform data exchange between PCD and gadget
 */
void dwc_otg_iso_buffer_done(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep,
			     void *req_handle)
{
	int i;
	dwc_ep_t *dwc_ep;

	dwc_ep = &ep->dwc_ep;

	DWC_SPINUNLOCK(ep->pcd->lock);
	pcd->fops->isoc_complete(pcd, ep->priv, ep->iso_req_handle,
				 dwc_ep->proc_buf_num ^ 0x1);
	DWC_SPINLOCK(ep->pcd->lock);

	for (i = 0; i < dwc_ep->pkt_cnt; ++i) {
		dwc_ep->pkt_info[i].status = 0;
		dwc_ep->pkt_info[i].offset = 0;
		dwc_ep->pkt_info[i].length = 0;
	}
}

int dwc_otg_pcd_get_iso_packet_count(dwc_otg_pcd_t * pcd, void *ep_handle,
				     void *iso_req_handle)
{
	dwc_otg_pcd_ep_t *ep;
	dwc_ep_t *dwc_ep;

	ep = get_ep_from_handle(pcd, ep_handle);
	if (!ep->desc || ep->dwc_ep.num == 0) {
		DWC_WARN("bad ep\n");
		return -DWC_E_INVALID;
	}
	dwc_ep = &ep->dwc_ep;

	return dwc_ep->pkt_cnt;
}

void dwc_otg_pcd_get_iso_packet_params(dwc_otg_pcd_t * pcd, void *ep_handle,
				       void *iso_req_handle, int packet,
				       int *status, int *actual, int *offset)
{
	dwc_otg_pcd_ep_t *ep;
	dwc_ep_t *dwc_ep;

	ep = get_ep_from_handle(pcd, ep_handle);
	if (!ep)
		DWC_WARN("bad ep\n");

	dwc_ep = &ep->dwc_ep;

	*status = dwc_ep->pkt_info[packet].status;
	*actual = dwc_ep->pkt_info[packet].length;
	*offset = dwc_ep->pkt_info[packet].offset;
}

#endif /* DWC_EN_ISOC */

static void dwc_otg_pcd_init_ep(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * pcd_ep,
				uint32_t is_in, uint32_t ep_num)
{
	/* Init EP structure */
	pcd_ep->desc = 0;
	pcd_ep->pcd = pcd;
	pcd_ep->stopped = 1;
	pcd_ep->queue_sof = 0;

	/* Init DWC ep structure */
	pcd_ep->dwc_ep.is_in = is_in;
	pcd_ep->dwc_ep.num = ep_num;
	pcd_ep->dwc_ep.active = 0;
	pcd_ep->dwc_ep.tx_fifo_num = 0;
	/* Control until ep is actvated */
	pcd_ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
	pcd_ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
	pcd_ep->dwc_ep.dma_addr = 0;
	pcd_ep->dwc_ep.start_xfer_buff = 0;
	pcd_ep->dwc_ep.xfer_buff = 0;
	pcd_ep->dwc_ep.xfer_len = 0;
	pcd_ep->dwc_ep.xfer_count = 0;
	pcd_ep->dwc_ep.sent_zlp = 0;
	pcd_ep->dwc_ep.total_len = 0;
	pcd_ep->dwc_ep.desc_addr = 0;
	pcd_ep->dwc_ep.dma_desc_addr = 0;
	DWC_CIRCLEQ_INIT(&pcd_ep->queue);
}

/**
 * Initialize ep's
 */
static void dwc_otg_pcd_reinit(dwc_otg_pcd_t * pcd)
{
	int i;
	uint32_t hwcfg1;
	dwc_otg_pcd_ep_t *ep;
	int in_ep_cntr, out_ep_cntr;
	uint32_t num_in_eps = (GET_CORE_IF(pcd))->dev_if->num_in_eps;
	uint32_t num_out_eps = (GET_CORE_IF(pcd))->dev_if->num_out_eps;

	/**
	 * Initialize the EP0 structure.
	 */
	ep = &pcd->ep0;
	dwc_otg_pcd_init_ep(pcd, ep, 0, 0);

	in_ep_cntr = 0;
	hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 3;
	for (i = 1; in_ep_cntr < num_in_eps; i++) {
		if ((hwcfg1 & 0x1) == 0) {
			dwc_otg_pcd_ep_t *ep = &pcd->in_ep[in_ep_cntr];
			in_ep_cntr++;
			/**
			 * @todo NGS: Add direction to EP, based on contents
			 * of HWCFG1.  Need a copy of HWCFG1 in pcd structure?
			 * sprintf(";r
			 */
			dwc_otg_pcd_init_ep(pcd, ep, 1 /* IN */ , i);

			DWC_CIRCLEQ_INIT(&ep->queue);
		}
		hwcfg1 >>= 2;
	}

	out_ep_cntr = 0;
	hwcfg1 = (GET_CORE_IF(pcd))->hwcfg1.d32 >> 2;
	for (i = 1; out_ep_cntr < num_out_eps; i++) {
		if ((hwcfg1 & 0x1) == 0) {
			dwc_otg_pcd_ep_t *ep = &pcd->out_ep[out_ep_cntr];
			out_ep_cntr++;
			/**
			 * @todo NGS: Add direction to EP, based on contents
			 * of HWCFG1.  Need a copy of HWCFG1 in pcd structure?
			 * sprintf(";r
			 */
			dwc_otg_pcd_init_ep(pcd, ep, 0 /* OUT */ , i);
			DWC_CIRCLEQ_INIT(&ep->queue);
		}
		hwcfg1 >>= 2;
	}

	pcd->ep0state = EP0_DISCONNECT;
	pcd->ep0.dwc_ep.maxpacket = MAX_EP0_SIZE;
	pcd->ep0.dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
}

/**
 * This function is called when the SRP timer expires. The SRP should
 * complete within 6 seconds.
 */
static void srp_timeout(void *ptr)
{
	gotgctl_data_t gotgctl;
	dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *) ptr;
	volatile uint32_t *addr = &core_if->core_global_regs->gotgctl;

	gotgctl.d32 = DWC_READ_REG32(addr);

	core_if->srp_timer_started = 0;
	
	if (core_if->adp_enable) {
		if (gotgctl.b.bsesvld == 0) {
			gpwrdn_data_t gpwrdn = {.d32 = 0 };
			DWC_PRINTF("SRP Timeout BSESSVLD = 0\n");
			/* Power off the core */
			if (core_if->power_down == 2) {
				gpwrdn.b.pwrdnswtch = 1;
				DWC_MODIFY_REG32(&core_if->core_global_regs->
					gpwrdn, gpwrdn.d32, 0);
			}

			gpwrdn.d32 = 0;
			gpwrdn.b.pmuintsel = 1;
			gpwrdn.b.pmuactv = 1;
			DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
			dwc_otg_adp_probe_start(core_if);
		} else {
			DWC_PRINTF("SRP Timeout BSESSVLD = 1\n");
			core_if->op_state = B_PERIPHERAL;
			dwc_otg_core_init(core_if);
			dwc_otg_enable_global_interrupts(core_if);
			cil_pcd_start(core_if);
		}
	}

	if ((core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) &&
	    (core_if->core_params->i2c_enable)) {
		DWC_PRINTF("SRP Timeout\n");

		if ((core_if->srp_success) && (gotgctl.b.bsesvld)) {
			if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) {
				core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
			}

			/* Clear Session Request */
			gotgctl.d32 = 0;
			gotgctl.b.sesreq = 1;
			DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl,
					 gotgctl.d32, 0);

			core_if->srp_success = 0;
		} else {
			__DWC_ERROR("Device not connected/responding\n");
			gotgctl.b.sesreq = 0;
			DWC_WRITE_REG32(addr, gotgctl.d32);
		}
	} else if (gotgctl.b.sesreq) {
		DWC_PRINTF("SRP Timeout\n");

		__DWC_ERROR("Device not connected/responding\n");
		gotgctl.b.sesreq = 0;
		DWC_WRITE_REG32(addr, gotgctl.d32);
	} else {
		DWC_PRINTF(" SRP GOTGCTL=%0x\n", gotgctl.d32);
	}
}

/**
 * Tasklet
 *
 */
extern void start_next_request(dwc_otg_pcd_ep_t * ep);

static void start_xfer_tasklet_func(void *data)
{
	dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *) data;
	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);

	int i;
	depctl_data_t diepctl;

	DWC_DEBUGPL(DBG_PCDV, "Start xfer tasklet\n");

	diepctl.d32 = DWC_READ_REG32(&core_if->dev_if->in_ep_regs[0]->diepctl);

	if (pcd->ep0.queue_sof) {
		pcd->ep0.queue_sof = 0;
		start_next_request(&pcd->ep0);
		// break;
	}

	for (i = 0; i < core_if->dev_if->num_in_eps; i++) {
		depctl_data_t diepctl;
		diepctl.d32 =
		    DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl);

		if (pcd->in_ep[i].queue_sof) {
			pcd->in_ep[i].queue_sof = 0;
			start_next_request(&pcd->in_ep[i]);
			// break;
		}
	}

	return;
}

/**
 * This function initialized the PCD portion of the driver.
 *
 */
dwc_otg_pcd_t *dwc_otg_pcd_init(dwc_otg_core_if_t * core_if)
{
	dwc_otg_pcd_t *pcd = NULL;
	dwc_otg_dev_if_t *dev_if;
	int i;

	/*
	 * Allocate PCD structure
	 */
	pcd = DWC_ALLOC(sizeof(dwc_otg_pcd_t));

	if (pcd == NULL) {
		return NULL;
	}

	pcd->lock = DWC_SPINLOCK_ALLOC();
	if (!pcd->lock) {
		DWC_ERROR("Could not allocate lock for pcd");
		DWC_FREE(pcd);
		return NULL;
	}
	/* Set core_if's lock pointer to hcd->lock */
	core_if->lock = pcd->lock;
	pcd->core_if = core_if;

	dev_if = core_if->dev_if;
	dev_if->isoc_ep = NULL;

	if (core_if->hwcfg4.b.ded_fifo_en) {
		DWC_PRINTF("Dedicated Tx FIFOs mode\n");
	} else {
		DWC_PRINTF("Shared Tx FIFO mode\n");
	}

	/*
	 * Initialized the Core for Device mode here if there is nod ADP support. 
	 * Otherwise it will be done later in dwc_otg_adp_start routine.
	 */																				 
	if (dwc_otg_is_device_mode(core_if) /*&& !core_if->adp_enable*/) {
		dwc_otg_core_dev_init(core_if);
	}

	/*
	 * Register the PCD Callbacks.
	 */
	dwc_otg_cil_register_pcd_callbacks(core_if, &pcd_callbacks, pcd);

	/*
	 * Initialize the DMA buffer for SETUP packets
	 */
	if (GET_CORE_IF(pcd)->dma_enable) {
		pcd->setup_pkt =
		    DWC_DMA_ALLOC(sizeof(*pcd->setup_pkt) * 5,
				  &pcd->setup_pkt_dma_handle);
		if (pcd->setup_pkt == NULL) {
			DWC_FREE(pcd);
			return NULL;
		}

		pcd->status_buf =
		    DWC_DMA_ALLOC(sizeof(uint16_t),
				  &pcd->status_buf_dma_handle);
		if (pcd->status_buf == NULL) {
			DWC_DMA_FREE(sizeof(*pcd->setup_pkt) * 5,
				     pcd->setup_pkt, pcd->setup_pkt_dma_handle);
			DWC_FREE(pcd);
			return NULL;
		}

		if (GET_CORE_IF(pcd)->dma_desc_enable) {
			dev_if->setup_desc_addr[0] =
			    dwc_otg_ep_alloc_desc_chain(&dev_if->
							dma_setup_desc_addr[0],
							1);
			dev_if->setup_desc_addr[1] =
			    dwc_otg_ep_alloc_desc_chain(&dev_if->
							dma_setup_desc_addr[1],
							1);
			dev_if->in_desc_addr =
			    dwc_otg_ep_alloc_desc_chain(&dev_if->
							dma_in_desc_addr, 1);
			dev_if->out_desc_addr =
			    dwc_otg_ep_alloc_desc_chain(&dev_if->
							dma_out_desc_addr, 1);

			if (dev_if->setup_desc_addr[0] == 0
			    || dev_if->setup_desc_addr[1] == 0
			    || dev_if->in_desc_addr == 0
			    || dev_if->out_desc_addr == 0) {

				if (dev_if->out_desc_addr)
					dwc_otg_ep_free_desc_chain(dev_if->
								   out_desc_addr,
								   dev_if->
								   dma_out_desc_addr,
								   1);
				if (dev_if->in_desc_addr)
					dwc_otg_ep_free_desc_chain(dev_if->
								   in_desc_addr,
								   dev_if->
								   dma_in_desc_addr,
								   1);
				if (dev_if->setup_desc_addr[1])
					dwc_otg_ep_free_desc_chain(dev_if->
								   setup_desc_addr
								   [1],
								   dev_if->
								   dma_setup_desc_addr
								   [1], 1);
				if (dev_if->setup_desc_addr[0])
					dwc_otg_ep_free_desc_chain(dev_if->
								   setup_desc_addr
								   [0],
								   dev_if->
								   dma_setup_desc_addr
								   [0], 1);

				DWC_DMA_FREE(sizeof(*pcd->setup_pkt) * 5,
					     pcd->setup_pkt,
					     pcd->setup_pkt_dma_handle);
				DWC_DMA_FREE(sizeof(*pcd->status_buf),
					     pcd->status_buf,
					     pcd->status_buf_dma_handle);

				DWC_FREE(pcd);

				return NULL;
			}
		}
	} else {
		pcd->setup_pkt = DWC_ALLOC(sizeof(*pcd->setup_pkt) * 5);
		if (pcd->setup_pkt == NULL) {
			DWC_FREE(pcd);
			return NULL;
		}

		pcd->status_buf = DWC_ALLOC(sizeof(uint16_t));
		if (pcd->status_buf == NULL) {
			DWC_FREE(pcd->setup_pkt);
			DWC_FREE(pcd);
			return NULL;
		}
	}

	dwc_otg_pcd_reinit(pcd);

	/* Allocate the cfi object for the PCD */
#ifdef DWC_UTE_CFI
	pcd->cfi = DWC_ALLOC(sizeof(cfiobject_t));
	if (NULL == pcd->cfi)
		goto fail;
	if (init_cfi(pcd->cfi)) {
		CFI_INFO("%s: Failed to init the CFI object\n", __func__);
		goto fail;
	}
#endif

	/* Initialize tasklets */
	pcd->start_xfer_tasklet = DWC_TASK_ALLOC("xfer_tasklet",
						 start_xfer_tasklet_func, pcd);
	pcd->test_mode_tasklet = DWC_TASK_ALLOC("test_mode_tasklet",
						do_test_mode, pcd);

	/* Initialize SRP timer */
	core_if->srp_timer = DWC_TIMER_ALLOC("SRP TIMER", srp_timeout, core_if);
	
	if (core_if->core_params->dev_out_nak) {
		/** 
		* Initialize xfer timeout timer. Implemented for
		* 2.93a feature "Device DDMA OUT NAK Enhancement"
		*/
		for(i = 0; i < MAX_EPS_CHANNELS; i++) {
			pcd->core_if->ep_xfer_timer[i] =
				DWC_TIMER_ALLOC("ep timer", ep_xfer_timeout,
				&pcd->core_if->ep_xfer_info[i]);
		}
	}
	
	return pcd;
#ifdef DWC_UTE_CFI
fail:
#endif
	if (pcd->setup_pkt)
		DWC_FREE(pcd->setup_pkt);
	if (pcd->status_buf)
		DWC_FREE(pcd->status_buf);
#ifdef DWC_UTE_CFI
	if (pcd->cfi)
		DWC_FREE(pcd->cfi);
#endif
	if (pcd)
		DWC_FREE(pcd);
	return NULL;

}

/**
 * Remove PCD specific data
 */
void dwc_otg_pcd_remove(dwc_otg_pcd_t * pcd)
{
	dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
	int i;
	if (pcd->core_if->core_params->dev_out_nak) {
		for (i = 0; i < MAX_EPS_CHANNELS; i++) {
			DWC_TIMER_CANCEL(pcd->core_if->ep_xfer_timer[i]);
			pcd->core_if->ep_xfer_info[i].state = 0;
		}
	}

	if (GET_CORE_IF(pcd)->dma_enable) {
		DWC_DMA_FREE(sizeof(*pcd->setup_pkt) * 5, pcd->setup_pkt,
			     pcd->setup_pkt_dma_handle);
		DWC_DMA_FREE(sizeof(uint16_t), pcd->status_buf,
			     pcd->status_buf_dma_handle);
		if (GET_CORE_IF(pcd)->dma_desc_enable) {
			dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[0],
						   dev_if->dma_setup_desc_addr
						   [0], 1);
			dwc_otg_ep_free_desc_chain(dev_if->setup_desc_addr[1],
						   dev_if->dma_setup_desc_addr
						   [1], 1);
			dwc_otg_ep_free_desc_chain(dev_if->in_desc_addr,
						   dev_if->dma_in_desc_addr, 1);
			dwc_otg_ep_free_desc_chain(dev_if->out_desc_addr,
						   dev_if->dma_out_desc_addr,
						   1);
		}
	} else {
		DWC_FREE(pcd->setup_pkt);
		DWC_FREE(pcd->status_buf);
	}
	DWC_SPINLOCK_FREE(pcd->lock);
	/* Set core_if's lock pointer to NULL */
	pcd->core_if->lock = NULL;

	DWC_TASK_FREE(pcd->start_xfer_tasklet);
	DWC_TASK_FREE(pcd->test_mode_tasklet);
	if (pcd->core_if->core_params->dev_out_nak) {
		for (i = 0; i < MAX_EPS_CHANNELS; i++) {
			if (pcd->core_if->ep_xfer_timer[i]) {
					DWC_TIMER_FREE(pcd->core_if->ep_xfer_timer[i]);
			}
		}
	}

/* Release the CFI object's dynamic memory */
#ifdef DWC_UTE_CFI
	if (pcd->cfi->ops.release) {
		pcd->cfi->ops.release(pcd->cfi);
	}
#endif

	DWC_FREE(pcd);
}

/**
 * Returns whether registered pcd is dual speed or not
 */
uint32_t dwc_otg_pcd_is_dualspeed(dwc_otg_pcd_t * pcd)
{
	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);

	if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) ||
	    ((core_if->hwcfg2.b.hs_phy_type == 2) &&
	     (core_if->hwcfg2.b.fs_phy_type == 1) &&
	     (core_if->core_params->ulpi_fs_ls))) {
		return 0;
	}

	return 1;
}

/**
 * Returns whether registered pcd is OTG capable or not
 */
uint32_t dwc_otg_pcd_is_otg(dwc_otg_pcd_t * pcd)
{
	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
	gusbcfg_data_t usbcfg = {.d32 = 0 };

	usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
	if (!usbcfg.b.srpcap || !usbcfg.b.hnpcap) {
		return 0;
	}

	return 1;
}

/**
 * This function assigns periodic Tx FIFO to an periodic EP
 * in shared Tx FIFO mode
 */
static uint32_t assign_tx_fifo(dwc_otg_core_if_t * core_if)
{
	uint32_t TxMsk = 1;
	int i;

	for (i = 0; i < core_if->hwcfg4.b.num_in_eps; ++i) {
		if ((TxMsk & core_if->tx_msk) == 0) {
			core_if->tx_msk |= TxMsk;
			return i + 1;
		}
		TxMsk <<= 1;
	}
	return 0;
}

/**
 * This function assigns periodic Tx FIFO to an periodic EP
 * in shared Tx FIFO mode
 */
static uint32_t assign_perio_tx_fifo(dwc_otg_core_if_t * core_if)
{
	uint32_t PerTxMsk = 1;
	int i;
	for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; ++i) {
		if ((PerTxMsk & core_if->p_tx_msk) == 0) {
			core_if->p_tx_msk |= PerTxMsk;
			return i + 1;
		}
		PerTxMsk <<= 1;
	}
	return 0;
}

/**
 * This function releases periodic Tx FIFO
 * in shared Tx FIFO mode
 */
static void release_perio_tx_fifo(dwc_otg_core_if_t * core_if,
				  uint32_t fifo_num)
{
	core_if->p_tx_msk =
	    (core_if->p_tx_msk & (1 << (fifo_num - 1))) ^ core_if->p_tx_msk;
}

/**
 * This function releases periodic Tx FIFO
 * in shared Tx FIFO mode
 */
static void release_tx_fifo(dwc_otg_core_if_t * core_if, uint32_t fifo_num)
{
	core_if->tx_msk =
	    (core_if->tx_msk & (1 << (fifo_num - 1))) ^ core_if->tx_msk;
}

/**
 * This function is being called from gadget 
 * to enable PCD endpoint.
 */
int dwc_otg_pcd_ep_enable(dwc_otg_pcd_t * pcd,
			  const uint8_t * ep_desc, void *usb_ep)
{
	int num, dir;
	dwc_otg_pcd_ep_t *ep = NULL;
	const usb_endpoint_descriptor_t *desc;
	dwc_irqflags_t flags;
	fifosize_data_t dptxfsiz = {.d32 = 0 };
	gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
	gdfifocfg_data_t gdfifocfgbase = {.d32 = 0 };
	int retval = 0;
	int i, epcount;

	desc = (const usb_endpoint_descriptor_t *)ep_desc;

	if (!desc) {
		pcd->ep0.priv = usb_ep;
		ep = &pcd->ep0;
		retval = -DWC_E_INVALID;
		goto out;
	}

	num = UE_GET_ADDR(desc->bEndpointAddress);
	dir = UE_GET_DIR(desc->bEndpointAddress);

	if (!desc->wMaxPacketSize) {
		DWC_WARN("bad maxpacketsize\n");
		retval = -DWC_E_INVALID;
		goto out;
	}

	if (dir == UE_DIR_IN) {
		epcount = pcd->core_if->dev_if->num_in_eps;
		for (i = 0; i < epcount; i++) {
			if (num == pcd->in_ep[i].dwc_ep.num) {
				ep = &pcd->in_ep[i];
				break;
			}
		}
	} else {
		epcount = pcd->core_if->dev_if->num_out_eps;
		for (i = 0; i < epcount; i++) {
			if (num == pcd->out_ep[i].dwc_ep.num) {
				ep = &pcd->out_ep[i];
				break;
			}
		}
	}

	if (!ep) {
		DWC_WARN("bad address\n");
		retval = -DWC_E_INVALID;
		goto out;
	}

	DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags);

	ep->desc = desc;
	ep->priv = usb_ep;

	/*
	 * Activate the EP
	 */
	ep->stopped = 0;

	ep->dwc_ep.is_in = (dir == UE_DIR_IN);
	ep->dwc_ep.maxpacket = UGETW(desc->wMaxPacketSize);

	ep->dwc_ep.type = desc->bmAttributes & UE_XFERTYPE;

	if (ep->dwc_ep.is_in) {
		if (!GET_CORE_IF(pcd)->en_multiple_tx_fifo) {
			ep->dwc_ep.tx_fifo_num = 0;

			if (ep->dwc_ep.type == UE_ISOCHRONOUS) {
				/*
				 * if ISOC EP then assign a Periodic Tx FIFO.
				 */
				ep->dwc_ep.tx_fifo_num =
				    assign_perio_tx_fifo(GET_CORE_IF(pcd));
			}
		} else {
			/*
			 * if Dedicated FIFOs mode is on then assign a Tx FIFO.
			 */
			ep->dwc_ep.tx_fifo_num =
			    assign_tx_fifo(GET_CORE_IF(pcd));
		}

		/* Calculating EP info controller base address */
		if (ep->dwc_ep.tx_fifo_num && GET_CORE_IF(pcd)->en_multiple_tx_fifo) {
			gdfifocfg.d32 =
			    DWC_READ_REG32(&GET_CORE_IF(pcd)->core_global_regs->
					   gdfifocfg);
			gdfifocfgbase.d32 = gdfifocfg.d32 >> 16;
			dptxfsiz.d32 =
			    (DWC_READ_REG32
			     (&GET_CORE_IF(pcd)->
			      core_global_regs->dtxfsiz[ep->dwc_ep.
							tx_fifo_num-1]) >> 16);
			gdfifocfg.b.epinfobase =
			    gdfifocfgbase.d32 + dptxfsiz.d32;
			DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->
					gdfifocfg, gdfifocfg.d32);
		}
	}
	/* Set initial data PID. */
	if (ep->dwc_ep.type == UE_BULK) {
		ep->dwc_ep.data_pid_start = 0;
	}

	/* Alloc DMA Descriptors */
	if (GET_CORE_IF(pcd)->dma_desc_enable) {
#ifndef DWC_UTE_PER_IO
		if (ep->dwc_ep.type != UE_ISOCHRONOUS) {
#endif
			ep->dwc_ep.desc_addr =
			    dwc_otg_ep_alloc_desc_chain(&ep->
							dwc_ep.dma_desc_addr,
							MAX_DMA_DESC_CNT);
			if (!ep->dwc_ep.desc_addr) {
				DWC_WARN("%s, can't allocate DMA descriptor\n",
					 __func__);
				retval = -DWC_E_SHUTDOWN;
				DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
				goto out;
			}
#ifndef DWC_UTE_PER_IO
		}
#endif
	}

	DWC_DEBUGPL(DBG_PCD, "Activate %s: type=%d, mps=%d desc=%p\n",
		    (ep->dwc_ep.is_in ? "IN" : "OUT"),
		    ep->dwc_ep.type, ep->dwc_ep.maxpacket, ep->desc);
#ifdef DWC_UTE_PER_IO
	ep->dwc_ep.xiso_bInterval = 1 << (ep->desc->bInterval - 1);
#endif
	if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
		ep->dwc_ep.bInterval = 1 << (ep->desc->bInterval - 1);
		ep->dwc_ep.frame_num = 0xFFFFFFFF;
	}	 	

	dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);

#ifdef DWC_UTE_CFI
	if (pcd->cfi->ops.ep_enable) {
		pcd->cfi->ops.ep_enable(pcd->cfi, pcd, ep);
	}
#endif

	DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);

out:
	return retval;
}

/**
 * This function is being called from gadget 
 * to disable PCD endpoint.
 */
int dwc_otg_pcd_ep_disable(dwc_otg_pcd_t * pcd, void *ep_handle)
{
	dwc_otg_pcd_ep_t *ep;
	dwc_irqflags_t flags;
	dwc_otg_dev_dma_desc_t *desc_addr;
	dwc_dma_t dma_desc_addr;
	gdfifocfg_data_t gdfifocfgbase = {.d32 = 0 };
	gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
	fifosize_data_t dptxfsiz = {.d32 = 0 };

	ep = get_ep_from_handle(pcd, ep_handle);

	if (!ep || !ep->desc) {
		DWC_DEBUGPL(DBG_PCD, "bad ep address\n");
		return -DWC_E_INVALID;
	}

	DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags);

	dwc_otg_request_nuke(ep);

	dwc_otg_ep_deactivate(GET_CORE_IF(pcd), &ep->dwc_ep);
	if (pcd->core_if->core_params->dev_out_nak)
	{
		DWC_TIMER_CANCEL(pcd->core_if->ep_xfer_timer[ep->dwc_ep.num]);
		pcd->core_if->ep_xfer_info[ep->dwc_ep.num].state = 0;
	}
	ep->desc = NULL;
	ep->stopped = 1;

	gdfifocfg.d32 =
	    DWC_READ_REG32(&GET_CORE_IF(pcd)->core_global_regs->gdfifocfg);
	gdfifocfgbase.d32 = gdfifocfg.d32 >> 16;

	if (ep->dwc_ep.is_in) {
		if (GET_CORE_IF(pcd)->en_multiple_tx_fifo) {
			/* Flush the Tx FIFO */
			dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd), ep->dwc_ep.tx_fifo_num);
		}
		release_perio_tx_fifo(GET_CORE_IF(pcd), ep->dwc_ep.tx_fifo_num);
		release_tx_fifo(GET_CORE_IF(pcd), ep->dwc_ep.tx_fifo_num);
		if (GET_CORE_IF(pcd)->en_multiple_tx_fifo) {
			/* Decreasing EPinfo Base Addr */
			dptxfsiz.d32 =
			    (DWC_READ_REG32
			     (&GET_CORE_IF(pcd)->
		      		core_global_regs->dtxfsiz[ep->dwc_ep.tx_fifo_num-1]) >> 16);
			gdfifocfg.b.epinfobase = gdfifocfgbase.d32 - dptxfsiz.d32;
			DWC_WRITE_REG32(&GET_CORE_IF(pcd)->core_global_regs->gdfifocfg,
					gdfifocfg.d32);
		}
	}

	/* Free DMA Descriptors */
	if (GET_CORE_IF(pcd)->dma_desc_enable) {
		if (ep->dwc_ep.type != UE_ISOCHRONOUS) {
			desc_addr = ep->dwc_ep.desc_addr;
			dma_desc_addr = ep->dwc_ep.dma_desc_addr;

			/* Cannot call dma_free_coherent() with IRQs disabled */
			DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
			dwc_otg_ep_free_desc_chain(desc_addr, dma_desc_addr,
						   MAX_DMA_DESC_CNT);

			goto out_unlocked;
		}
	}
	DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);

out_unlocked:
	DWC_DEBUGPL(DBG_PCD, "%d %s disabled\n", ep->dwc_ep.num,
		    ep->dwc_ep.is_in ? "IN" : "OUT");
	return 0;

}

/******************************************************************************/
#ifdef DWC_UTE_PER_IO

/**
 * Free the request and its extended parts
 *
 */
void dwc_pcd_xiso_ereq_free(dwc_otg_pcd_ep_t * ep, dwc_otg_pcd_request_t * req)
{
	DWC_FREE(req->ext_req.per_io_frame_descs);
	DWC_FREE(req);
}

/**
 * Start the next request in the endpoint's queue.
 *
 */
int dwc_otg_pcd_xiso_start_next_request(dwc_otg_pcd_t * pcd,
					dwc_otg_pcd_ep_t * ep)
{
	int i;
	dwc_otg_pcd_request_t *req = NULL;
	dwc_ep_t *dwcep = NULL;
	struct dwc_iso_xreq_port *ereq = NULL;
	struct dwc_iso_pkt_desc_port *ddesc_iso;
	uint16_t nat;
	depctl_data_t diepctl;

	dwcep = &ep->dwc_ep;

	if (dwcep->xiso_active_xfers > 0) {
#if 0	//Disable this to decrease s/w overhead that is crucial for Isoc transfers
		DWC_WARN("There are currently active transfers for EP%d \
				(active=%d; queued=%d)", dwcep->num, dwcep->xiso_active_xfers, 
				dwcep->xiso_queued_xfers);
#endif
		return 0;
	}

	nat = UGETW(ep->desc->wMaxPacketSize);
	nat = (nat >> 11) & 0x03;

	if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
		req = DWC_CIRCLEQ_FIRST(&ep->queue);
		ereq = &req->ext_req;
		ep->stopped = 0;

		/* Get the frame number */
		dwcep->xiso_frame_num =
		    dwc_otg_get_frame_number(GET_CORE_IF(pcd));
		DWC_DEBUG("FRM_NUM=%d", dwcep->xiso_frame_num);

		ddesc_iso = ereq->per_io_frame_descs;

		if (dwcep->is_in) {
			/* Setup DMA Descriptor chain for IN Isoc request */
			for (i = 0; i < ereq->pio_pkt_count; i++) {
				//if ((i % (nat + 1)) == 0)
				if ( i > 0 )
					dwcep->xiso_frame_num = (dwcep->xiso_bInterval +
										dwcep->xiso_frame_num) & 0x3FFF;
				dwcep->desc_addr[i].buf =
				    req->dma + ddesc_iso[i].offset;
				dwcep->desc_addr[i].status.b_iso_in.txbytes =
				    ddesc_iso[i].length;
				dwcep->desc_addr[i].status.b_iso_in.framenum =
				    dwcep->xiso_frame_num;
				dwcep->desc_addr[i].status.b_iso_in.bs =
				    BS_HOST_READY;
				dwcep->desc_addr[i].status.b_iso_in.txsts = 0;
				dwcep->desc_addr[i].status.b_iso_in.sp =
				    (ddesc_iso[i].length %
				     dwcep->maxpacket) ? 1 : 0;
				dwcep->desc_addr[i].status.b_iso_in.ioc = 0;
				dwcep->desc_addr[i].status.b_iso_in.pid = nat + 1;
				dwcep->desc_addr[i].status.b_iso_in.l = 0;

				/* Process the last descriptor */
				if (i == ereq->pio_pkt_count - 1) {
					dwcep->desc_addr[i].status.b_iso_in.ioc = 1;
					dwcep->desc_addr[i].status.b_iso_in.l = 1;
				}
			}

			/* Setup and start the transfer for this endpoint */
			dwcep->xiso_active_xfers++;
			DWC_WRITE_REG32(&GET_CORE_IF(pcd)->dev_if->
					in_ep_regs[dwcep->num]->diepdma,
					dwcep->dma_desc_addr);
			diepctl.d32 = 0;
			diepctl.b.epena = 1;
			diepctl.b.cnak = 1;
			DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->dev_if->
					 in_ep_regs[dwcep->num]->diepctl, 0,
					 diepctl.d32);
		} else {
			/* Setup DMA Descriptor chain for OUT Isoc request */
			for (i = 0; i < ereq->pio_pkt_count; i++) {
				//if ((i % (nat + 1)) == 0)
				dwcep->xiso_frame_num = (dwcep->xiso_bInterval + 
										dwcep->xiso_frame_num) & 0x3FFF;
				dwcep->desc_addr[i].buf =
				    req->dma + ddesc_iso[i].offset;
				dwcep->desc_addr[i].status.b_iso_out.rxbytes =
				    ddesc_iso[i].length;
				dwcep->desc_addr[i].status.b_iso_out.framenum =
				    dwcep->xiso_frame_num;
				dwcep->desc_addr[i].status.b_iso_out.bs =
				    BS_HOST_READY;
				dwcep->desc_addr[i].status.b_iso_out.rxsts = 0;
				dwcep->desc_addr[i].status.b_iso_out.sp =
				    (ddesc_iso[i].length %
				     dwcep->maxpacket) ? 1 : 0;
				dwcep->desc_addr[i].status.b_iso_out.ioc = 0;
				dwcep->desc_addr[i].status.b_iso_out.pid = nat + 1;
				dwcep->desc_addr[i].status.b_iso_out.l = 0;
				
				/* Process the last descriptor */
				if (i == ereq->pio_pkt_count - 1) {
					dwcep->desc_addr[i].status.b_iso_out.ioc = 1;
					dwcep->desc_addr[i].status.b_iso_out.l = 1;
				}			
			}
			
			/* Setup and start the transfer for this endpoint */
			dwcep->xiso_active_xfers++;
			DWC_WRITE_REG32(&GET_CORE_IF(pcd)->dev_if->
					out_ep_regs[dwcep->num]->doepdma,
					dwcep->dma_desc_addr);
			diepctl.d32 = 0;
			diepctl.b.epena = 1;
			diepctl.b.cnak = 1;
			DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->dev_if->
					 out_ep_regs[dwcep->num]->doepctl, 0,
					 diepctl.d32);
		}

	} else {
		ep->stopped = 1;
	}

	return 0;
}

/**
 *	- Remove the request from the queue
 */
void complete_xiso_ep(dwc_otg_pcd_ep_t * ep)
{
	dwc_otg_pcd_request_t *req = NULL;
	struct dwc_iso_xreq_port *ereq = NULL;
	struct dwc_iso_pkt_desc_port *ddesc_iso = NULL;
	dwc_ep_t *dwcep = NULL;
	int i;

	//DWC_DEBUG();
	dwcep = &ep->dwc_ep;

	/* Get the first pending request from the queue */
	if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
		req = DWC_CIRCLEQ_FIRST(&ep->queue);
		if (!req) {
			DWC_PRINTF("complete_ep 0x%p, req = NULL!\n", ep);
			return;
		}
		dwcep->xiso_active_xfers--;
		dwcep->xiso_queued_xfers--;
		/* Remove this request from the queue */
		DWC_CIRCLEQ_REMOVE_INIT(&ep->queue, req, queue_entry);
	} else {
		DWC_PRINTF("complete_ep 0x%p, ep->queue empty!\n", ep);
		return;
	}

	ep->stopped = 1;
	ereq = &req->ext_req;
	ddesc_iso = ereq->per_io_frame_descs;

	if (dwcep->xiso_active_xfers < 0) {
		DWC_WARN("EP#%d (xiso_active_xfers=%d)", dwcep->num,
			 dwcep->xiso_active_xfers);
	}

	/* Fill the Isoc descs of portable extended req from dma descriptors */
	for (i = 0; i < ereq->pio_pkt_count; i++) {
		if (dwcep->is_in) {	/* IN endpoints */
			ddesc_iso[i].actual_length = ddesc_iso[i].length -
			    dwcep->desc_addr[i].status.b_iso_in.txbytes;
			ddesc_iso[i].status =
			    dwcep->desc_addr[i].status.b_iso_in.txsts;
		} else {	/* OUT endpoints */
			ddesc_iso[i].actual_length = ddesc_iso[i].length -
			    dwcep->desc_addr[i].status.b_iso_out.rxbytes;
			ddesc_iso[i].status =
			    dwcep->desc_addr[i].status.b_iso_out.rxsts;
		}
	}

	DWC_SPINUNLOCK(ep->pcd->lock);

	/* Call the completion function in the non-portable logic */
	ep->pcd->fops->xisoc_complete(ep->pcd, ep->priv, req->priv, 0,
				      &req->ext_req);

	DWC_SPINLOCK(ep->pcd->lock);

	/* Free the request - specific freeing needed for extended request object */
	dwc_pcd_xiso_ereq_free(ep, req);

	/* Start the next request */
	dwc_otg_pcd_xiso_start_next_request(ep->pcd, ep);

	return;
}

/**
 * Create and initialize the Isoc pkt descriptors of the extended request.
 *
 */
static int dwc_otg_pcd_xiso_create_pkt_descs(dwc_otg_pcd_request_t * req,
					     void *ereq_nonport,
					     int atomic_alloc)
{
	struct dwc_iso_xreq_port *ereq = NULL;
	struct dwc_iso_xreq_port *req_mapped = NULL;
	struct dwc_iso_pkt_desc_port *ipds = NULL;	/* To be created in this function */
	uint32_t pkt_count;
	int i;

	ereq = &req->ext_req;
	req_mapped = (struct dwc_iso_xreq_port *)ereq_nonport;
	pkt_count = req_mapped->pio_pkt_count;

	/* Create the isoc descs */
	if (atomic_alloc) {
		ipds = DWC_ALLOC_ATOMIC(sizeof(*ipds) * pkt_count);
	} else {
		ipds = DWC_ALLOC(sizeof(*ipds) * pkt_count);
	}

	if (!ipds) {
		DWC_ERROR("Failed to allocate isoc descriptors");
		return -DWC_E_NO_MEMORY;
	}

	/* Initialize the extended request fields */
	ereq->per_io_frame_descs = ipds;
	ereq->error_count = 0;
	ereq->pio_alloc_pkt_count = pkt_count;
	ereq->pio_pkt_count = pkt_count;
	ereq->tr_sub_flags = req_mapped->tr_sub_flags;

	/* Init the Isoc descriptors */
	for (i = 0; i < pkt_count; i++) {
		ipds[i].length = req_mapped->per_io_frame_descs[i].length;
		ipds[i].offset = req_mapped->per_io_frame_descs[i].offset;
		ipds[i].status = req_mapped->per_io_frame_descs[i].status;	/* 0 */
		ipds[i].actual_length =
		    req_mapped->per_io_frame_descs[i].actual_length;
	}

	return 0;
}

static void prn_ext_request(struct dwc_iso_xreq_port *ereq)
{
	struct dwc_iso_pkt_desc_port *xfd = NULL;
	int i;

	DWC_DEBUG("per_io_frame_descs=%p", ereq->per_io_frame_descs);
	DWC_DEBUG("tr_sub_flags=%d", ereq->tr_sub_flags);
	DWC_DEBUG("error_count=%d", ereq->error_count);
	DWC_DEBUG("pio_alloc_pkt_count=%d", ereq->pio_alloc_pkt_count);
	DWC_DEBUG("pio_pkt_count=%d", ereq->pio_pkt_count);
	DWC_DEBUG("res=%d", ereq->res);

	for (i = 0; i < ereq->pio_pkt_count; i++) {
		xfd = &ereq->per_io_frame_descs[0];
		DWC_DEBUG("FD #%d", i);

		DWC_DEBUG("xfd->actual_length=%d", xfd->actual_length);
		DWC_DEBUG("xfd->length=%d", xfd->length);
		DWC_DEBUG("xfd->offset=%d", xfd->offset);
		DWC_DEBUG("xfd->status=%d", xfd->status);
	}
}

/**
 *
 */
int dwc_otg_pcd_xiso_ep_queue(dwc_otg_pcd_t * pcd, void *ep_handle,
			      uint8_t * buf, dwc_dma_t dma_buf, uint32_t buflen,
			      int zero, void *req_handle, int atomic_alloc,
			      void *ereq_nonport)
{
	dwc_otg_pcd_request_t *req = NULL;
	dwc_otg_pcd_ep_t *ep;
	dwc_irqflags_t flags;
	int res;

	ep = get_ep_from_handle(pcd, ep_handle);
	if (!ep) {
		DWC_WARN("bad ep\n");
		return -DWC_E_INVALID;
	}

	/* We support this extension only for DDMA mode */
	if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC)
		if (!GET_CORE_IF(pcd)->dma_desc_enable)
			return -DWC_E_INVALID;

	/* Create a dwc_otg_pcd_request_t object */
	if (atomic_alloc) {
		req = DWC_ALLOC_ATOMIC(sizeof(*req));
	} else {
		req = DWC_ALLOC(sizeof(*req));
	}

	if (!req) {
		return -DWC_E_NO_MEMORY;
	}

	/* Create the Isoc descs for this request which shall be the exact match
	 * of the structure sent to us from the non-portable logic */
	res =
	    dwc_otg_pcd_xiso_create_pkt_descs(req, ereq_nonport, atomic_alloc);
	if (res) {
		DWC_WARN("Failed to init the Isoc descriptors");
		DWC_FREE(req);
		return res;
	}

	DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags);

	DWC_CIRCLEQ_INIT_ENTRY(req, queue_entry);
	req->buf = buf;
	req->dma = dma_buf;
	req->length = buflen;
	req->sent_zlp = zero;
	req->priv = req_handle;

	//DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags);
	ep->dwc_ep.dma_addr = dma_buf;
	ep->dwc_ep.start_xfer_buff = buf;
	ep->dwc_ep.xfer_buff = buf;
	ep->dwc_ep.xfer_len = 0;
	ep->dwc_ep.xfer_count = 0;
	ep->dwc_ep.sent_zlp = 0;
	ep->dwc_ep.total_len = buflen;

	/* Add this request to the tail */
	DWC_CIRCLEQ_INSERT_TAIL(&ep->queue, req, queue_entry);
	ep->dwc_ep.xiso_queued_xfers++;

//DWC_DEBUG("CP_0");
//DWC_DEBUG("req->ext_req.tr_sub_flags=%d", req->ext_req.tr_sub_flags);
//prn_ext_request((struct dwc_iso_xreq_port *) ereq_nonport);
//prn_ext_request(&req->ext_req);

	//DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);

	/* If the req->status == ASAP  then check if there is any active transfer
	 * for this endpoint. If no active transfers, then get the first entry
	 * from the queue and start that transfer
	 */
	if (req->ext_req.tr_sub_flags == DWC_EREQ_TF_ASAP) {
		res = dwc_otg_pcd_xiso_start_next_request(pcd, ep);
		if (res) {
			DWC_WARN("Failed to start the next Isoc transfer");
			DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
			DWC_FREE(req);
			return res;
		}
	}

	DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
	return 0;
}

#endif
/* END ifdef DWC_UTE_PER_IO ***************************************************/
int dwc_otg_pcd_ep_queue(dwc_otg_pcd_t * pcd, void *ep_handle,
			 uint8_t * buf, dwc_dma_t dma_buf, uint32_t buflen,
			 int zero, void *req_handle, int atomic_alloc)
{
	dwc_irqflags_t flags;
	dwc_otg_pcd_request_t *req;
	dwc_otg_pcd_ep_t *ep;
	uint32_t max_transfer;

	ep = get_ep_from_handle(pcd, ep_handle);
	if (!ep || (!ep->desc && ep->dwc_ep.num != 0)) {
		DWC_WARN("bad ep\n");
		return -DWC_E_INVALID;
	}

	if (atomic_alloc) {
		req = DWC_ALLOC_ATOMIC(sizeof(*req));
	} else {
		req = DWC_ALLOC(sizeof(*req));
	}

	if (!req) {
		return -DWC_E_NO_MEMORY;
	}
	DWC_CIRCLEQ_INIT_ENTRY(req, queue_entry);
	if (!GET_CORE_IF(pcd)->core_params->opt) {
		if (ep->dwc_ep.num != 0) {
			DWC_ERROR("queue req %p, len %d buf %p\n",
				  req_handle, buflen, buf);
		}
	}

	req->buf = buf;
	req->dma = dma_buf;
	req->length = buflen;
	req->sent_zlp = zero;
	req->priv = req_handle;
	req->dw_align_buf = NULL;
	if ((dma_buf & 0x3) && GET_CORE_IF(pcd)->dma_enable
			&& !GET_CORE_IF(pcd)->dma_desc_enable)
		req->dw_align_buf = DWC_DMA_ALLOC(buflen,
				 &req->dw_align_buf_dma);
	DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags);

	/*
	 * After adding request to the queue for IN ISOC wait for In Token Received
	 * when TX FIFO is empty interrupt and for OUT ISOC wait for OUT Token 
	 * Received when EP is disabled interrupt to obtain starting microframe
	 * (odd/even) start transfer
	 */
	if (ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC)
	{
		if (req != 0) {
			depctl_data_t depctl = {.d32 = DWC_READ_REG32(&pcd->core_if->dev_if->in_ep_regs[ep->dwc_ep.num]->diepctl)};
			++pcd->request_pending;

			DWC_CIRCLEQ_INSERT_TAIL(&ep->queue, req, queue_entry);
			if (ep->dwc_ep.is_in)
			{
				depctl.b.cnak = 1;
				DWC_WRITE_REG32(&pcd->core_if->dev_if->in_ep_regs[ep->dwc_ep.num]->diepctl, depctl.d32);
			}
			
			DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
		}
		return 0;
	}

	/*
	 * For EP0 IN without premature status, zlp is required?
	 */
	if (ep->dwc_ep.num == 0 && ep->dwc_ep.is_in) {
		DWC_DEBUGPL(DBG_PCDV, "%d-OUT ZLP\n", ep->dwc_ep.num);
		//_req->zero = 1;
	}

	/* Start the transfer */
	if (DWC_CIRCLEQ_EMPTY(&ep->queue) && !ep->stopped) {
		/* EP0 Transfer? */
		if (ep->dwc_ep.num == 0) {
			switch (pcd->ep0state) {
			case EP0_IN_DATA_PHASE:
				DWC_DEBUGPL(DBG_PCD,
					    "%s ep0: EP0_IN_DATA_PHASE\n",
					    __func__);
				break;

			case EP0_OUT_DATA_PHASE:
				DWC_DEBUGPL(DBG_PCD,
					    "%s ep0: EP0_OUT_DATA_PHASE\n",
					    __func__);
				if (pcd->request_config) {
					/* Complete STATUS PHASE */
					ep->dwc_ep.is_in = 1;
					pcd->ep0state = EP0_IN_STATUS_PHASE;
				}
				break;

			case EP0_IN_STATUS_PHASE:
				DWC_DEBUGPL(DBG_PCD,
					    "%s ep0: EP0_IN_STATUS_PHASE\n",
					    __func__);
				break;

			default:
				DWC_DEBUGPL(DBG_ANY, "ep0: odd state %d\n",
					    pcd->ep0state);
				DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
				return -DWC_E_SHUTDOWN;
			}

			ep->dwc_ep.dma_addr = dma_buf;
			ep->dwc_ep.start_xfer_buff = buf;
			ep->dwc_ep.xfer_buff = buf;
			ep->dwc_ep.xfer_len = buflen;
			ep->dwc_ep.xfer_count = 0;
			ep->dwc_ep.sent_zlp = 0;
			ep->dwc_ep.total_len = ep->dwc_ep.xfer_len;

			if (zero) {
				if ((ep->dwc_ep.xfer_len %
				     ep->dwc_ep.maxpacket == 0)
				    && (ep->dwc_ep.xfer_len != 0)) {
					ep->dwc_ep.sent_zlp = 1;
				}

			}

			dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd),
						   &ep->dwc_ep);
		}		// non-ep0 endpoints
		else {
#ifdef DWC_UTE_CFI
			if (ep->dwc_ep.buff_mode != BM_STANDARD) {
				/* store the request length */
				ep->dwc_ep.cfi_req_len = buflen;
				pcd->cfi->ops.build_descriptors(pcd->cfi, pcd,
								ep, req);
			} else {
#endif
				max_transfer =
				    GET_CORE_IF(ep->pcd)->
				    core_params->max_transfer_size;

				/* Setup and start the Transfer */
				if (req->dw_align_buf){
					if (ep->dwc_ep.is_in)
						dwc_memcpy(req->dw_align_buf, buf, buflen);
					ep->dwc_ep.dma_addr = req->dw_align_buf_dma;
					ep->dwc_ep.start_xfer_buff = req->dw_align_buf;
                                        ep->dwc_ep.xfer_buff = req->dw_align_buf;
				} else {
					ep->dwc_ep.dma_addr = dma_buf;
					ep->dwc_ep.start_xfer_buff = buf;
                                        ep->dwc_ep.xfer_buff = buf;	
				}
				ep->dwc_ep.xfer_len = 0;
				ep->dwc_ep.xfer_count = 0;
				ep->dwc_ep.sent_zlp = 0;
				ep->dwc_ep.total_len = buflen;

				ep->dwc_ep.maxxfer = max_transfer;
				if (GET_CORE_IF(pcd)->dma_desc_enable) {
					uint32_t out_max_xfer =
					    DDMA_MAX_TRANSFER_SIZE -
					    (DDMA_MAX_TRANSFER_SIZE % 4);
					if (ep->dwc_ep.is_in) {
						if (ep->dwc_ep.maxxfer >
						    DDMA_MAX_TRANSFER_SIZE) {
							ep->dwc_ep.maxxfer =
							    DDMA_MAX_TRANSFER_SIZE;
						}
					} else {
						if (ep->dwc_ep.maxxfer >
						    out_max_xfer) {
							ep->dwc_ep.maxxfer =
							    out_max_xfer;
						}
					}
				}
				if (ep->dwc_ep.maxxfer < ep->dwc_ep.total_len) {
					ep->dwc_ep.maxxfer -=
					    (ep->dwc_ep.maxxfer %
					     ep->dwc_ep.maxpacket);
				}

				if (zero) {
					if ((ep->dwc_ep.total_len %
					     ep->dwc_ep.maxpacket == 0)
					    && (ep->dwc_ep.total_len != 0)) {
						ep->dwc_ep.sent_zlp = 1;
					}
				}
#ifdef DWC_UTE_CFI
			}
#endif
			dwc_otg_ep_start_transfer(GET_CORE_IF(pcd),
						  &ep->dwc_ep);
		}
	}

	if (req != 0) {
		++pcd->request_pending;
		DWC_CIRCLEQ_INSERT_TAIL(&ep->queue, req, queue_entry);
		if (ep->dwc_ep.is_in && ep->stopped
		    && !(GET_CORE_IF(pcd)->dma_enable)) {
			/** @todo NGS Create a function for this. */
			diepmsk_data_t diepmsk = {.d32 = 0 };
			diepmsk.b.intktxfemp = 1;
			if (GET_CORE_IF(pcd)->multiproc_int_enable) {
				DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->dev_if->
						 dev_global_regs->
						 diepeachintmsk[ep->dwc_ep.num],
						 0, diepmsk.d32);
			} else {
				DWC_MODIFY_REG32(&GET_CORE_IF(pcd)->dev_if->
						 dev_global_regs->diepmsk, 0,
						 diepmsk.d32);
			}

		}
	}
	DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);

	return 0;
}

int dwc_otg_pcd_ep_dequeue(dwc_otg_pcd_t * pcd, void *ep_handle,
			   void *req_handle)
{
	dwc_irqflags_t flags;
	dwc_otg_pcd_request_t *req;
	dwc_otg_pcd_ep_t *ep;

	ep = get_ep_from_handle(pcd, ep_handle);
	if (!ep || (!ep->desc && ep->dwc_ep.num != 0)) {
		DWC_WARN("bad argument\n");
		return -DWC_E_INVALID;
	}

	DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags);

	/* make sure it's actually queued on this endpoint */
	DWC_CIRCLEQ_FOREACH(req, &ep->queue, queue_entry) {
		if (req->priv == (void *)req_handle) {
			break;
		}
	}

	if (req->priv != (void *)req_handle) {
		DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
		return -DWC_E_INVALID;
	}

	if (!DWC_CIRCLEQ_EMPTY_ENTRY(req, queue_entry)) {
		dwc_otg_request_done(ep, req, -DWC_E_RESTART);
	} else {
		req = NULL;
	}

	DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);

	return req ? 0 : -DWC_E_SHUTDOWN;

}

int dwc_otg_pcd_ep_halt(dwc_otg_pcd_t * pcd, void *ep_handle, int value)
{
	dwc_otg_pcd_ep_t *ep;
	dwc_irqflags_t flags;
	int retval = 0;

	ep = get_ep_from_handle(pcd, ep_handle);

	if (!ep || (!ep->desc && ep != &pcd->ep0) ||
	    (ep->desc && (ep->desc->bmAttributes == UE_ISOCHRONOUS))) {
		DWC_WARN("%s, bad ep\n", __func__);
		return -DWC_E_INVALID;
	}

	DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags);
	if (!DWC_CIRCLEQ_EMPTY(&ep->queue)) {
		DWC_WARN("%d %s XFer In process\n", ep->dwc_ep.num,
			 ep->dwc_ep.is_in ? "IN" : "OUT");
		retval = -DWC_E_AGAIN;
	} else if (value == 0) {
		dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
	} else if (value == 1) {
		if (ep->dwc_ep.is_in == 1 && GET_CORE_IF(pcd)->dma_desc_enable) {
			dtxfsts_data_t txstatus;
			fifosize_data_t txfifosize;

			txfifosize.d32 =
			    DWC_READ_REG32(&GET_CORE_IF(pcd)->core_global_regs->
					   dtxfsiz[ep->dwc_ep.tx_fifo_num]);
			txstatus.d32 =
			    DWC_READ_REG32(&GET_CORE_IF(pcd)->dev_if->
					   in_ep_regs[ep->dwc_ep.num]->dtxfsts);

			if (txstatus.b.txfspcavail < txfifosize.b.depth) {
				DWC_WARN("%s() Data In Tx Fifo\n", __func__);
				retval = -DWC_E_AGAIN;
			} else {
				if (ep->dwc_ep.num == 0) {
					pcd->ep0state = EP0_STALL;
				}

				ep->stopped = 1;
				dwc_otg_ep_set_stall(GET_CORE_IF(pcd),
						     &ep->dwc_ep);
			}
		} else {
			if (ep->dwc_ep.num == 0) {
				pcd->ep0state = EP0_STALL;
			}

			ep->stopped = 1;
			dwc_otg_ep_set_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
		}
	} else if (value == 2) {
		ep->dwc_ep.stall_clear_flag = 0;
	} else if (value == 3) {
		ep->dwc_ep.stall_clear_flag = 1;
	}

	DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);

	return retval;
}

/**
 * This function initiates remote wakeup of the host from suspend state.
 */
void dwc_otg_pcd_rem_wkup_from_suspend(dwc_otg_pcd_t * pcd, int set)
{
	dctl_data_t dctl = { 0 };
	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
	dsts_data_t dsts;

	dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
	if (!dsts.b.suspsts) {
		DWC_WARN("Remote wakeup while is not in suspend state\n");
	}
	/* Check if DEVICE_REMOTE_WAKEUP feature enabled */
	if (pcd->remote_wakeup_enable) {
		if (set) {

			if (core_if->adp_enable) {
				gpwrdn_data_t gpwrdn;

				dwc_otg_adp_probe_stop(core_if);

				/* Mask SRP detected interrupt from Power Down Logic */
				gpwrdn.d32 = 0;
				gpwrdn.b.srp_det_msk = 1;
				DWC_MODIFY_REG32(&core_if->core_global_regs->
						 gpwrdn, gpwrdn.d32, 0);

				/* Disable Power Down Logic */
				gpwrdn.d32 = 0;
				gpwrdn.b.pmuactv = 1;
				DWC_MODIFY_REG32(&core_if->core_global_regs->
						 gpwrdn, gpwrdn.d32, 0);

				/*
				 * Initialize the Core for Device mode.
				 */
				core_if->op_state = B_PERIPHERAL;
				dwc_otg_core_init(core_if);
				dwc_otg_enable_global_interrupts(core_if);
				cil_pcd_start(core_if);

				dwc_otg_initiate_srp(core_if);
			}

			dctl.b.rmtwkupsig = 1;
			DWC_MODIFY_REG32(&core_if->dev_if->
					 dev_global_regs->dctl, 0, dctl.d32);
			DWC_DEBUGPL(DBG_PCD, "Set Remote Wakeup\n");

			dwc_mdelay(2);
			DWC_MODIFY_REG32(&core_if->dev_if->
					 dev_global_regs->dctl, dctl.d32, 0);
			DWC_DEBUGPL(DBG_PCD, "Clear Remote Wakeup\n");
		}
	} else {
		DWC_DEBUGPL(DBG_PCD, "Remote Wakeup is disabled\n");
	}
}

#ifdef CONFIG_USB_DWC_OTG_LPM
/**
 * This function initiates remote wakeup of the host from L1 sleep state.
 */
void dwc_otg_pcd_rem_wkup_from_sleep(dwc_otg_pcd_t * pcd, int set)
{
	glpmcfg_data_t lpmcfg;
	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);

	lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);

	/* Check if we are in L1 state */
	if (!lpmcfg.b.prt_sleep_sts) {
		DWC_DEBUGPL(DBG_PCD, "Device is not in sleep state\n");
		return;
	}

	/* Check if host allows remote wakeup */
	if (!lpmcfg.b.rem_wkup_en) {
		DWC_DEBUGPL(DBG_PCD, "Host does not allow remote wakeup\n");
		return;
	}

	/* Check if Resume OK */
	if (!lpmcfg.b.sleep_state_resumeok) {
		DWC_DEBUGPL(DBG_PCD, "Sleep state resume is not OK\n");
		return;
	}

	lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
	lpmcfg.b.en_utmi_sleep = 0;
	lpmcfg.b.hird_thres &= (~(1 << 4));
	DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);

	if (set) {
		dctl_data_t dctl = {.d32 = 0 };
		dctl.b.rmtwkupsig = 1;
		/* Set RmtWkUpSig bit to start remote wakup signaling.
		 * Hardware will automatically clear this bit.
		 */
		DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl,
				 0, dctl.d32);
		DWC_DEBUGPL(DBG_PCD, "Set Remote Wakeup\n");
	}

}
#endif

/**
 * Performs remote wakeup.
 */
void dwc_otg_pcd_remote_wakeup(dwc_otg_pcd_t * pcd, int set)
{
	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
	dwc_irqflags_t flags;
	if (dwc_otg_is_device_mode(core_if)) {
		DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags);
#ifdef CONFIG_USB_DWC_OTG_LPM
		if (core_if->lx_state == DWC_OTG_L1) {
			dwc_otg_pcd_rem_wkup_from_sleep(pcd, set);
		} else {
#endif
			dwc_otg_pcd_rem_wkup_from_suspend(pcd, set);
#ifdef CONFIG_USB_DWC_OTG_LPM
		}
#endif
		DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
	}
	return;
}

void dwc_otg_pcd_disconnect_us(dwc_otg_pcd_t * pcd, int no_of_usecs)
{
	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
	dctl_data_t dctl = { 0 };

	if (dwc_otg_is_device_mode(core_if)) {
		dctl.b.sftdiscon = 1;
		DWC_PRINTF("Soft disconnect for %d useconds\n",no_of_usecs);
		DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
		dwc_udelay(no_of_usecs);
		DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32,0);
		
	} else{
		DWC_PRINTF("NOT SUPPORTED IN HOST MODE\n");
	}
	return;

}

int dwc_otg_pcd_wakeup(dwc_otg_pcd_t * pcd)
{
	dsts_data_t dsts;
	gotgctl_data_t gotgctl;

	/*
	 * This function starts the Protocol if no session is in progress. If
	 * a session is already in progress, but the device is suspended,
	 * remote wakeup signaling is started.
	 */

	/* Check if valid session */
	gotgctl.d32 =
	    DWC_READ_REG32(&(GET_CORE_IF(pcd)->core_global_regs->gotgctl));
	if (gotgctl.b.bsesvld) {
		/* Check if suspend state */
		dsts.d32 =
		    DWC_READ_REG32(&
				   (GET_CORE_IF(pcd)->dev_if->
				    dev_global_regs->dsts));
		if (dsts.b.suspsts) {
			dwc_otg_pcd_remote_wakeup(pcd, 1);
		}
	} else {
		dwc_otg_pcd_initiate_srp(pcd);
	}

	return 0;

}

/**
 * Start the SRP timer to detect when the SRP does not complete within
 * 6 seconds.
 *
 * @param pcd the pcd structure.
 */
void dwc_otg_pcd_initiate_srp(dwc_otg_pcd_t * pcd)
{
	dwc_irqflags_t flags;
	DWC_SPINLOCK_IRQSAVE(pcd->lock, &flags);
	dwc_otg_initiate_srp(GET_CORE_IF(pcd));
	DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
}

int dwc_otg_pcd_get_frame_number(dwc_otg_pcd_t * pcd)
{
	return dwc_otg_get_frame_number(GET_CORE_IF(pcd));
}

int dwc_otg_pcd_is_lpm_enabled(dwc_otg_pcd_t * pcd)
{
	return GET_CORE_IF(pcd)->core_params->lpm_enable;
}

uint32_t get_b_hnp_enable(dwc_otg_pcd_t * pcd)
{
	return pcd->b_hnp_enable;
}

uint32_t get_a_hnp_support(dwc_otg_pcd_t * pcd)
{
	return pcd->a_hnp_support;
}

uint32_t get_a_alt_hnp_support(dwc_otg_pcd_t * pcd)
{
	return pcd->a_alt_hnp_support;
}

int dwc_otg_pcd_get_rmwkup_enable(dwc_otg_pcd_t * pcd)
{
	return pcd->remote_wakeup_enable;
}

#endif /* DWC_HOST_ONLY */
