// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
 * Copyright (C) 2004-2013 Synopsys, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The names of the above-listed copyright holders may not be used
 *    to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * ALTERNATIVELY, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any
 * later version.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS 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.
 */
#include "diag_common.h"
#include "diag_misc.h"
#include "Galois_memmap.h"
#include "soc.h"
#include "diag_gic.h"
#include "diag_cpu.h"
#include "diag_misc.h"
#include "global.h"
#include "usb_memmap.h"
#include "hw.h"
#include "core.h"
#include "util.h"

#define MAX_RETRY 10

int g_msg_queue = 0;
const hcd_dwc2_ops_t *dwc2_msg;
struct dwc2_hsotg dwc2_drv;

unsigned long g_current_pipe = 0;
uint8_t *aligned_buffer_addr=(uint8_t *)USB_MASS_BULK_DATA_BASE;
uint8_t *status_buffer_addr=(uint8_t *)USB_MASS_BULK_CSW_BASE;
volatile struct dwc2_core_regs *g_regs = (struct dwc2_core_regs *)ACPU_MEMMAP_USBAHB_REG_BASE;
static int g_got_hc_int = 0;
int g_dwc2_chhltd_int_en = 1;
int g_dwc2_dma_mode=0;
int g_dwc2_host_channel = 0;
u8 *g_pid = 0;
u32 *g_hctsiz = 0;
unsigned int g_port_reset_delay = 100; // 100 x 10 ms , 1 second
unsigned int g_prtrst_duration_ms = 1000; // 1 second for port reset pulse duration, fix compatibility with some USB3.0 drive
static int dwc2_eptype[] = {
	DWC2_HCCHAR_EPTYPE_ISOC,
	DWC2_HCCHAR_EPTYPE_INTR,
	DWC2_HCCHAR_EPTYPE_CONTROL,
	DWC2_HCCHAR_EPTYPE_BULK,
};
int root_hub_devnum;

int _dwc2_clrbits_le32(volatile u32 *addr, unsigned long clear)
{
	unsigned long data;
	data = readl(addr);
	data &= ~clear;
	writel(data, addr);
	return 0;
}

int _dwc2_setbits_le32(volatile u32 *addr, unsigned long set)
{
	unsigned long data;
	data = readl(addr);
	data |= set;
	writel(data, addr);
	return 0;
}

int _dwc2_clrsetbits_le32(volatile u32 *addr, unsigned long clear, unsigned long set)
{
	_dwc2_clrbits_le32(addr, clear);
	_dwc2_setbits_le32(addr, set);
	return 0;
}

int _dwc2_wait_for_bit_le32(const u32 *reg, u32 mask, const bool set,const unsigned int timeout_ms, const bool breakable)
 {
	u32 val;
	int count_us=0;
	UNUSED(breakable);
	dbg_printf(PRN_INFO | PRN_BUFFERED,"_dwc2_wait_for_bit_le32: addr=0x%x mask=0x%x, set=%d, timeout_ms=%d..", reg, mask, set, timeout_ms);
	while (1) {
		val = readl(reg);
		if (!set)
			val = ~val;
		if ((val & mask) == mask){
			dbg_printf(PRN_INFO | PRN_BUFFERED,"done!\n");
			return 0;
		}
		if ((count_us/100) > (int)timeout_ms)
			break;
		udelay(1);
		count_us++;
	}
	dbg_printf(PRN_INFO | PRN_BUFFERED, "_dwc2_wait_for_bit_le32: Timeout (reg=%p mask=%08x wait_set=%i)\n", reg, mask, set);
	return -ETIMEDOUT;
}

/**
 * dwc2_hsotg_wait_bit_set - Waits for bit to be set.
 * @hsotg: Programming view of DWC_otg controller.
 * @offset: Register's offset where bit/bits must be set.
 * @mask: Mask of the bit/bits which must be set.
 * @timeout: Timeout to wait.
 *
 * Return: 0 if bit/bits are set or -ETIMEDOUT in case of timeout.
 */
int dwc2_hsotg_wait_bit_set(struct dwc2_hsotg *hsotg, u32 offset, u32 mask,
				u32 timeout)
{
	u32 i;

	for (i = 0; i < timeout; i++) {
		if (dwc2_readl(hsotg, offset) & mask)
			return 0;
		udelay(1);
	}

	return -ETIMEDOUT;
}

/**
 * dwc2_hsotg_wait_bit_clear - Waits for bit to be clear.
 * @hsotg: Programming view of DWC_otg controller.
 * @offset: Register's offset where bit/bits must be set.
 * @mask: Mask of the bit/bits which must be set.
 * @timeout: Timeout to wait.
 *
 * Return: 0 if bit/bits are set or -ETIMEDOUT in case of timeout.
 */
int dwc2_hsotg_wait_bit_clear(struct dwc2_hsotg *hsotg, u32 offset, u32 mask,
				  u32 timeout)
{
	u32 i;

	for (i = 0; i < timeout; i++) {
		if (!(dwc2_readl(hsotg, offset) & mask))
			return 0;
		udelay(1);
	}

	return -ETIMEDOUT;
}

/**
 * dwc2_flush_tx_fifo() - Flushes a Tx FIFO
 *
 * @hsotg: Programming view of DWC_otg controller
 * @num:   Tx FIFO to flush
 */
void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num)
{
	u32 greset;

	debug("Flush Tx FIFO %d\n", num);

	/* Wait for AHB master IDLE state */
	if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL, GRSTCTL_AHBIDLE, 10000))
		debug("%s:  HANG! AHB Idle GRSCTL\n",
			 __func__);

	greset = GRSTCTL_TXFFLSH;
	greset |= num << GRSTCTL_TXFNUM_SHIFT & GRSTCTL_TXFNUM_MASK;
	dwc2_writel(hsotg, greset, GRSTCTL);

	if (dwc2_hsotg_wait_bit_clear(hsotg, GRSTCTL, GRSTCTL_TXFFLSH, 10000))
		debug("%s:  HANG! timeout GRSTCTL GRSTCTL_TXFFLSH\n",
			 __func__);

	/* Wait for at least 3 PHY Clocks */
	udelay(1);
}

/**
 * dwc2_flush_rx_fifo() - Flushes the Rx FIFO
 *
 * @hsotg: Programming view of DWC_otg controller
 */
void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg)
{
	u32 greset;

	debug("%s()\n", __func__);

	/* Wait for AHB master IDLE state */
	if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL, GRSTCTL_AHBIDLE, 10000))
		debug("%s:  HANG! AHB Idle GRSCTL\n",
			 __func__);

	greset = GRSTCTL_RXFFLSH;
	dwc2_writel(hsotg, greset, GRSTCTL);

	/* Wait for RxFIFO flush done */
	if (dwc2_hsotg_wait_bit_clear(hsotg, GRSTCTL, GRSTCTL_RXFFLSH, 10000))
		debug("%s: HANG! timeout GRSTCTL GRSTCTL_RXFFLSH\n",
			 __func__);

	/* Wait for at least 3 PHY Clocks */
	udelay(1);
}

static void dwc2_set_dma_mode()
{
	 if ((g_dwc2_dma_mode)&&(!(g_regs->host_regs.hcfg & DWC2_HCFG_DESCDMA))){
		dbg_printf(PRN_INFO | PRN_BUFFERED,"HCFG: DESC mode\n");
		_dwc2_setbits_le32(&g_regs->host_regs.hcfg, DWC2_HCFG_DESCDMA);
	}
	else if ((!g_dwc2_dma_mode) && (g_regs->host_regs.hcfg & DWC2_HCFG_DESCDMA)){
		dbg_printf(PRN_INFO | PRN_BUFFERED,"HCFG: BUFFERED DMA mode\n");
		_dwc2_clrbits_le32(&g_regs->host_regs.hcfg, DWC2_HCFG_DESCDMA);
	}
}

/*
 * Do core a soft reset of the core.  Be careful with this because it
 * resets all the internal state machines of the core.
 */
int dwc2_core_reset(struct dwc2_hsotg *hsotg)
{
	u32 greset;
	//bool wait_for_host_mode = false;

	debug("%s()\n", __func__);

	/*
	 * If the current mode is host, either due to the force mode
	 * bit being set (which persists after core reset) or the
	 * connector id pin, a core soft reset will temporarily reset
	 * the mode to device. A delay from the IDDIG debounce filter
	 * will occur before going back to host mode.
	 *
	 * Determine whether we will go back into host mode after a
	 * reset and account for this delay after the reset.
	 */


	/* Core Soft Reset */
	greset = dwc2_readl(hsotg, GRSTCTL);
	greset |= GRSTCTL_CSFTRST;
	dwc2_writel(hsotg, greset, GRSTCTL);

	if (dwc2_hsotg_wait_bit_clear(hsotg, GRSTCTL, GRSTCTL_CSFTRST, 50)) {
		debug("%s: HANG! Soft Reset timeout GRSTCTL GRSTCTL_CSFTRST\n",
			 __func__);
		return -EBUSY;
	}

	/* Wait for AHB master IDLE state */
	if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL, GRSTCTL_AHBIDLE, 50)) {
		debug("%s: HANG! AHB Idle timeout GRSTCTL GRSTCTL_AHBIDLE\n",
			 __func__);
		return -EBUSY;
	}

	/*
	 * Wait for core to come out of reset.
	 * NOTE: This long sleep is _very_ important, otherwise the core will
	 *	   not stay in host mode after a connector ID change!
	 */
	mdelay(10/*100*/); // TIA TEMP : Reduce

	mdelay(100);

	return 0;
}

int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg)
{
	uint8_t brst_sz = CONFIG_DWC2_DMA_BURST_SIZE;
	uint32_t ahbcfg = 0;


	/* Program the GAHBCFG Register. */
	switch (dwc2_readl(hsotg, GHWCFG2) & DWC2_HWCFG2_ARCHITECTURE_MASK) {
	case DWC2_HWCFG2_ARCHITECTURE_SLAVE_ONLY:
		break;

	case DWC2_HWCFG2_ARCHITECTURE_EXT_DMA:
		while (brst_sz > 1) {
			ahbcfg |= ahbcfg + (1 << DWC2_GAHBCFG_HBURSTLEN_OFFSET);
			ahbcfg &= DWC2_GAHBCFG_HBURSTLEN_MASK;
			brst_sz >>= 1;
		}
		ahbcfg |= DWC2_GAHBCFG_DMAENABLE;
		break;

	case DWC2_HWCFG2_ARCHITECTURE_INT_DMA:
		ahbcfg |= DWC2_GAHBCFG_HBURSTLEN_INCR4;
		ahbcfg |= DWC2_GAHBCFG_DMAENABLE;
		break;
	}

	dwc2_writel(hsotg, ahbcfg, GAHBCFG);
	return 0;
}

static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg)
{
	u32 usbcfg;
	int retval = 0;

	usbcfg = dwc2_readl(hsotg, GUSBCFG);
	/* High speed PHY */
	usbcfg &= ~(DWC2_GUSBCFG_ULPI_UTMI_SEL | DWC2_GUSBCFG_PHYIF);
	usbcfg &=  DWC2_GUSBCFG_ULPI_UTMI_SEL_OFFSET; /* UTMI+ SELECTION */

	/* UTMI+ interface 0-8bits, 1-16bits*/
	//usbcfg |= DWC2_GUSBCFG_PHYIF;

	dwc2_writel(hsotg, usbcfg, GUSBCFG);

	/* Reset after setting the PHY parameters */
	retval = dwc2_core_reset(hsotg);
	if (retval) {
		debug("%s(): Reset failed, aborting\n",
			__func__);
		return retval;
	}

	usbcfg = dwc2_readl(hsotg, GUSBCFG);
	usbcfg &= ~(DWC2_GUSBCFG_ULPI_FSLS | DWC2_GUSBCFG_ULPI_CLK_SUS_M);

	if (hsotg->hnp_srp_disable){
		usbcfg |= DWC2_GUSBCFG_FORCEHOSTMODE;
		dbg_printf(PRN_INFO | PRN_BUFFERED,"Force HOST MODE\n");
	}

	dwc2_writel(hsotg, usbcfg, GUSBCFG);
	return retval;
}

/*
 * Initializes the FSLSPClkSel field of the HCFG register depending on the
 * PHY type
 */
static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg)
{
	u32 hcfg, val;

	/* High speed PHY running at full speed or high speed */
	val = HCFG_FSLSPCLKSEL_30_60_MHZ;

	debug("Initializing HCFG.FSLSPClkSel to %08x\n", val);
	hcfg = dwc2_readl(hsotg, HCFG);
	hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
	hcfg |= val << HCFG_FSLSPCLKSEL_SHIFT;
	dwc2_writel(hsotg, hcfg, HCFG);
}

static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
{
	uint32_t nptxfifosize = 0;
	uint32_t ptxfifosize = 0;

	if (dwc2_readl(hsotg, GHWCFG2) & GHWCFG2_DYNAMIC_FIFO) {
		/* Rx FIFO */
		dwc2_writel(hsotg, CONFIG_DWC2_HOST_RX_FIFO_SIZE, GRXFSIZ);

		/* Non-periodic Tx FIFO */
		nptxfifosize |= CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE <<
				DWC2_FIFOSIZE_DEPTH_OFFSET;
		nptxfifosize |= CONFIG_DWC2_HOST_RX_FIFO_SIZE <<
				DWC2_FIFOSIZE_STARTADDR_OFFSET;
		dwc2_writel(hsotg, nptxfifosize, GNPTXFSIZ);

		/* Periodic Tx FIFO */
		ptxfifosize |= CONFIG_DWC2_HOST_PERIO_TX_FIFO_SIZE <<
				DWC2_FIFOSIZE_DEPTH_OFFSET;
		ptxfifosize |= (CONFIG_DWC2_HOST_RX_FIFO_SIZE +
				CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE) <<
				DWC2_FIFOSIZE_STARTADDR_OFFSET;
		dwc2_writel(hsotg, ptxfifosize, HPTXFSIZ);
	}
}

/*
 * Reads HPRT0 in preparation to modify. It keeps the WC bits 0 so that if they
 * are read as 1, they won't clear when written back.
 */
static u32 dwc2_read_hprt0(struct dwc2_hsotg *hsotg)
{
	u32 hprt0 = dwc2_readl(hsotg, HPRT0);

	hprt0 &= ~(HPRT0_ENA | HPRT0_CONNDET | HPRT0_ENACHG | HPRT0_OVRCURRCHG);
	return hprt0;
}

int dwc2_core_init(struct dwc2_hsotg *hsotg)
{
	u32 usbcfg;
	int retval;

	debug("%s(%p)\n", __func__, hsotg);

	usbcfg = dwc2_readl(hsotg, GUSBCFG);

	/* Set ULPI External VBUS bit if needed */
	usbcfg &= ~GUSBCFG_ULPI_EXT_VBUS_DRV;
	if (hsotg->phy_ulpi_ext_vbus)
		usbcfg |= GUSBCFG_ULPI_EXT_VBUS_DRV;

	/* Set external TS Dline pulsing bit if needed */
	usbcfg &= ~GUSBCFG_TERMSELDLPULSE;
	if (hsotg->ts_dline)
		usbcfg |= GUSBCFG_TERMSELDLPULSE;

	dwc2_writel(hsotg, usbcfg, GUSBCFG);

	/*
	 * Reset the Controller
	 *
	 * We only need to reset the controller if this is a re-init.
	 * For the first init we know for sure that earlier code reset us (it
	 * needed to in order to properly detect various parameters).
	 */
	retval = dwc2_core_reset(hsotg);
	if (retval) {
		debug("%s(): Reset failed, aborting\n",
			__func__);
		return retval;
	}



	/*
	 * This needs to happen in FS mode before any other programming occurs
	 */
	retval = dwc2_hs_phy_init(hsotg);
	if (retval)
		return retval;


	debug("Waiting for ginsts b0 set to 1 (acknowledge host mode), gusbcfg=0x%x\n", dwc2_readl(hsotg, GUSBCFG));
	while( !(dwc2_readl(hsotg, GINTSTS) & 0x1)){
		mdelay(10);
		dbg_printf(PRN_INFO | PRN_BUFFERED,".");
	}
	dbg_printf(PRN_INFO | PRN_BUFFERED,"HOST mode acknowledged!..continue\n");


	/* Program the GAHBCFG Register */
	retval = dwc2_gahbcfg_init(hsotg);
	if (retval)
		return retval;

	/* Program the GUSBCFG register */
	//dwc2_gusbcfg_init(hsotg);
	mdelay(1);

	/* Program the GOTGCTL register */
	//otgctl = dwc2_readl(hsotg, GOTGCTL);
	//otgctl &= ~GOTGCTL_OTGVER;
	//dwc2_writel(hsotg, otgctl, GOTGCTL);

	/* Clear the SRP success bit for FS-I2c */
	//hsotg->srp_success = 0;

	/* Enable common interrupts */
	//dwc2_enable_common_interrupts(hsotg);

	return 0;
}

int dwc2_core_host_init(struct dwc2_hsotg *hsotg)
{
	u32 hcfg, otgctl, usbcfg;

	/* Set HS/FS Timeout Calibration to 7 (max available value).
	 * The number of PHY clocks that the application programs in
	 * this field is added to the high/full speed interpacket timeout
	 * duration in the core to account for any additional delays
	 * introduced by the PHY. This can be required, because the delay
	 * introduced by the PHY in generating the linestate condition
	 * can vary from one PHY to another.
	 */
	usbcfg = dwc2_readl(hsotg, GUSBCFG);
	usbcfg |= GUSBCFG_TOUTCAL(7);
	dwc2_writel(hsotg, usbcfg, GUSBCFG);

	/* Restart the Phy Clock */
	dwc2_writel(hsotg, 0, PCGCTL);


	/* Initialize Host Configuration Register */
	dwc2_init_fs_ls_pclk_sel(hsotg);
	if (hsotg->speed == DWC2_SPEED_PARAM_FULL ||
		hsotg->speed == DWC2_SPEED_PARAM_LOW) {
		hcfg = dwc2_readl(hsotg, HCFG);
		hcfg |= HCFG_FSLSSUPP;
		dwc2_writel(hsotg, hcfg, HCFG);
	}

	/* Configure data FIFO sizes */
	dwc2_config_fifos(hsotg);

	dwc2_set_dma_mode();

	/* TODO - check this */
	/* Clear Host Set HNP Enable in the OTG Control Register */
	otgctl = dwc2_readl(hsotg, GOTGCTL);
	otgctl &= ~GOTGCTL_HSTSETHNPEN;
	dwc2_writel(hsotg, otgctl, GOTGCTL);

	/* Make sure the FIFOs are flushed. */
	dwc2_flush_tx_fifo(hsotg, 0x10);	/* All Tx FIFOs */
	dwc2_flush_rx_fifo(hsotg);

	/* Clear Host Set HNP Enable in the OTG Control Register */
	otgctl = dwc2_readl(hsotg, GOTGCTL);
	otgctl &= ~GOTGCTL_HSTSETHNPEN;
	dwc2_writel(hsotg, otgctl, GOTGCTL);

	if (!hsotg->dma_desc_enable) {
		int num_channels, i;
		u32 hcchar;

		/* Flush out any leftover queued requests */
		num_channels = hsotg->host_channels;
		debug("Number of Host channels: %d\n", num_channels);

		for (i = 0; i < num_channels; i++) {
			hcchar = dwc2_readl(hsotg, HCCHAR(i));
			hcchar &= ~HCCHAR_CHENA;
			hcchar |= HCCHAR_CHDIS;
			hcchar &= ~HCCHAR_EPDIR;
			dwc2_writel(hsotg, hcchar, HCCHAR(i));
		}

		/* Halt all channels to put them into a known state */
		for (i = 0; i < num_channels; i++) {
			hcchar = dwc2_readl(hsotg, HCCHAR(i));
			hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS;
			hcchar &= ~HCCHAR_EPDIR;
			dwc2_writel(hsotg, hcchar, HCCHAR(i));
			debug("%s: Halt channel %d\n",
				__func__, i);

			if (dwc2_hsotg_wait_bit_clear(hsotg, HCCHAR(i),
							  HCCHAR_CHENA, 1000)) {
				debug("Unable to clear enable on channel %d\n",
					 i);
			}
		}
	}

	/* Enable ACG feature in host mode, if supported */
	//dwc2_enable_acg(hsotg);

	/* Turn on the vbus power */
	if (dwc2_readl(hsotg, GINTSTS) & GINTSTS_CURMODE_HOST) {
		u32 hprt0 = dwc2_read_hprt0(hsotg);

		debug("Init: Power Port (%d)\n",
			!!(hprt0 & HPRT0_PWR));
		if (!(hprt0 & HPRT0_PWR)) {
			hprt0 |= HPRT0_PWR;
			dwc2_writel(hsotg, hprt0, HPRT0);
		}
	}

	//dwc2_enable_host_interrupts(hsotg);
	//dwc2_enable_host_interrupt();


	return 0;
}

/*
 * Prepares a host channel for transferring packets to/from a specific
 * endpoint. The HCCHARn register is set up with the characteristics specified
 * in _hc. Host channel interrupts that may need to be serviced while this
 * transfer is in progress are enabled.
 *
 * @param regs Programming view of DWC_otg controller
 * @param hc Information needed to initialize the host channel
 */
static void dwc2_fill_chnl_chars(struct dwc2_core_regs *regs, uint8_t hc_num,
		struct usb_device *dev, uint8_t dev_addr, uint8_t ep_num,
		uint8_t ep_is_in, uint8_t ep_type, uint16_t max_packet)
{
	struct dwc2_hc_regs *hc_regs = &regs->hc_regs[hc_num];
	uint32_t hcchar = (dev_addr << DWC2_HCCHAR_DEVADDR_OFFSET) |
			  (ep_num << DWC2_HCCHAR_EPNUM_OFFSET) |
			  (ep_is_in << DWC2_HCCHAR_EPDIR_OFFSET) |
			  (ep_type << DWC2_HCCHAR_EPTYPE_OFFSET) |
			  (max_packet << DWC2_HCCHAR_MPS_OFFSET);

	if (dev->speed == USB_SPEED_LOW)
		hcchar |= DWC2_HCCHAR_LSPDDEV;

	/*
	 * Program the HCCHARn register with the endpoint characteristics
	 * for the current transfer.
	 */
	writel(hcchar, &hc_regs->hcchar);

	/* Program the HCSPLIT register, default to no SPLIT */
	writel(0, &hc_regs->hcsplt);
}

/*
 * DWC2 to USB API interface
 */
void dwc2_dump_interrupt_status()
{

	dbg_printf(PRN_INFO | PRN_BUFFERED,"gintsts=0x%x haint=%x hcint%d=%x\n",
				g_regs->gintsts,
				g_regs->host_regs.haint,
				DWC2_HC_CHANNEL,
				g_regs->hc_regs[DWC2_HC_CHANNEL].hcint);
	dbg_printf(PRN_INFO | PRN_BUFFERED,"gintmsk=0x%x haintmsk=%x hcint%dmsk=%x\n",
				g_regs->gintmsk,
				g_regs->host_regs.haintmsk,
				DWC2_HC_CHANNEL,
				g_regs->hc_regs[DWC2_HC_CHANNEL].hcintmsk);
}

void dwc2_clear_host_interrupt()
{
	g_regs->hc_regs[DWC2_HC_CHANNEL].hcint = g_regs->hc_regs[DWC2_HC_CHANNEL].hcint; // clear interrupts that were triggered.
}

static void _dwc2_set_data_toggle()
{
	if (g_pid && g_hctsiz){
		*g_pid = ((*g_hctsiz) & DWC2_HCTSIZ_PID_MASK) >> DWC2_HCTSIZ_PID_OFFSET;
	}
}

void dwc2_isr()
{
	dbg_printf(PRN_INFO | PRN_BUFFERED,"USB INTERRUPT: gintsts=0x%x haint=%x hcint%d=%x\n",
				g_regs->gintsts,
				g_regs->host_regs.haint,
				DWC2_HC_CHANNEL,
				g_regs->hc_regs[DWC2_HC_CHANNEL].hcint);

	g_got_hc_int = g_regs->hc_regs[DWC2_HC_CHANNEL].hcint;
	dwc2_clear_host_interrupt();

	if (g_got_hc_int & DWC2_HCINT_XFERCOMP){
		if (g_msg_queue){
			_dwc2_set_data_toggle();
			// Currently map callback based on PIPE type (BULK, INT, ISO)
			if (usb_pipebulk(g_current_pipe)){
				usb_mass_callback();
			}
			else if (usb_pipeint(g_current_pipe)){
				//usb_hid_callback();
			}
			else if (usb_pipeisoc(g_current_pipe)){

			}
		}
	}
	else{
		dbg_printf(PRN_RES,"INCOMPLETE USB TRANSFER (0x%x)\n", g_got_hc_int);
	}
}

void dwc2_enable_host_interrupt()
{
	g_regs->gintmsk = 1<<25; // Enable channel interrupt
	g_regs->host_regs.haintmsk = 1<<DWC2_HC_CHANNEL; // host channel x interrupts enable
	g_regs->hc_regs[DWC2_HC_CHANNEL].hcintmsk = DWC2_HCINT_CHHLTD; // Channel halted interrupt
	g_regs->gahbcfg |= 1; // Enable INT on AHB to ARM core

	//register_isr(dwc2_isr, IRQ_usb0Intr);
	set_irq_enable(IRQ_usb0Intr);

	dbg_printf(PRN_INFO | PRN_BUFFERED,"ENABLE INT:");
	dwc2_dump_interrupt_status();
}

void dwc2_disable_host_interrupt()
{
	int cpuID;

	cpuID=getMPid();
	diag_GICSetInt(cpuID, MP_BERLIN_INTR_ID(IRQ_usb0Intr), 0);
	g_regs->gintmsk &= ~(1<<25); // Enable channel interrupt
	g_regs->host_regs.haintmsk &= ~(1<<DWC2_HC_CHANNEL); // host channel x interrupts disable
	g_regs->hc_regs[DWC2_HC_CHANNEL].hcintmsk &= ~DWC2_HCINT_CHHLTD; // Channel halted interrupt
	dbg_printf(PRN_INFO | PRN_BUFFERED,"DISABLE INT:");
	dwc2_dump_interrupt_status();
}

int dwc2_wait_for_interrupt(struct dwc2_hc_regs *hc_regs, uint32_t *sub, u8 *toggle)
{
	int ret;
	uint32_t hcint, hctsiz;

		dbg_printf(PRN_INFO | PRN_BUFFERED, "dwc2_wait_for_interrupt\n");

	if (!g_dwc2_chhltd_int_en){ // polling - NO INTERRUPT
		ret = _dwc2_wait_for_bit_le32(&hc_regs->hcint, DWC2_HCINT_CHHLTD, true,
				1000, false);
	}
	else{ // USE HW interrupt and ISR
		int to_loop_cnt = 10000;
		ret = 0;
		while(!g_got_hc_int){
			udelay(100); // wait for 1 seconds
			if (!to_loop_cnt--){
				dbg_printf(PRN_INFO | PRN_BUFFERED,"INTERRUPT NOT TRIGGER! HCINT=0x%08lx\n",hc_regs->hcint);
				ret = 1;
				break;
			}
		} // Wait for interrupt
	}

	if (ret)
		return ret;

	if (g_dwc2_chhltd_int_en){
		hcint = g_got_hc_int;
		g_got_hc_int = 0;
	}
	else
		hcint = readl(&hc_regs->hcint);
	hctsiz = readl(&hc_regs->hctsiz);
	*sub = (hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK) >>
		DWC2_HCTSIZ_XFERSIZE_OFFSET;
	*toggle = (hctsiz & DWC2_HCTSIZ_PID_MASK) >> DWC2_HCTSIZ_PID_OFFSET;

	dbg_printf( PRN_INFO | PRN_BUFFERED, "HCINT=%08x sub=%u toggle=%d\n",hcint, *sub,
		  *toggle);

	if (hcint & DWC2_HCINT_XFERCOMP){
		if (!(hcint & DWC2_HCINT_ACK)){
			dbg_printf(PRN_INFO | PRN_BUFFERED,"NOACK!!");
		}
		return 0;
	}

	if (hcint & (DWC2_HCINT_NAK | DWC2_HCINT_FRMOVRUN))
		return -EAGAIN;

	dbg_printf(PRN_INFO | PRN_BUFFERED,"Error (HCINT=%08x)\n",hcint);
	return -EINVAL;
}

static int packet_send(struct dwc2_hc_regs *hc_regs, void *aligned_buffer,
			  u8 *pid, int in, void *buffer, int num_packets,
			  int xfer_len, int *actual_len, int odd_frame)
{
	int ret = 0;
	uint32_t sub;
	int data;
	//struct dwc2_desc_dma *desctable = (struct dwc2_desc_dma *)USB_SCATGAT_DESC_QH;
	int desc_count=0; // number of descriptors
	unsigned int do_ping;

	UNUSED(aligned_buffer);
	dbg_printf(PRN_INFO | PRN_BUFFERED,"packet_send: pid=%d xfer_len=%u pkts=%u  buffer=0x%x\n",
		  *pid, xfer_len, num_packets, buffer);

	dwc2_set_dma_mode(); // Set DMA mode buffered or Scatter/Gather

	if (usb_pipebulk(g_current_pipe) && (!in) && (pdev_usb->speed == USB_SPEED_HIGH)){ /* perform ping protocol if BULK OUT . Necessary for compatibility with some USB 2.0 flash drive */
		do_ping = 1<<31;
	}
	else{
		do_ping = 0;
	}

	if (!g_dwc2_dma_mode){ // Buffered DMA mode
		dbg_printf(PRN_INFO | PRN_BUFFERED,"packet_send.buffered_dma\n");
		writel((unsigned long)buffer, &hc_regs->hcdma);
		BFM_HOST_Bus_Read32(&hc_regs->hcdma, &data);
		dbg_printf(PRN_INFO | PRN_BUFFERED,"before hcdma:%x\n", data);
		writel( do_ping |
			(xfer_len << DWC2_HCTSIZ_XFERSIZE_OFFSET) |
		   (num_packets << DWC2_HCTSIZ_PKTCNT_OFFSET) |
		   (*pid << DWC2_HCTSIZ_PID_OFFSET),
		   &hc_regs->hctsiz);
	}

	BFM_HOST_Bus_Read32(&hc_regs->hctsiz, &data);
	dbg_printf(PRN_INFO | PRN_BUFFERED,"PRE HCTSIZ mode(%d): 0x%x\n", g_dwc2_dma_mode, data);

	/* Clear old interrupt conditions for this host channel. */
	writel(0x3fff, &hc_regs->hcint);

	if (g_dwc2_chhltd_int_en){
		dwc2_enable_host_interrupt();
	}
	/* Set host channel enable after all other setup is complete. */
	_dwc2_clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
			DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS |
			DWC2_HCCHAR_ODDFRM,
			(1 << DWC2_HCCHAR_MULTICNT_OFFSET) |
			(odd_frame << DWC2_HCCHAR_ODDFRM_OFFSET) |
			DWC2_HCCHAR_CHEN);

	if (g_msg_queue){
		g_pid = pid;
		g_hctsiz = &hc_regs->hctsiz;
		return 0;
	}

	ret = dwc2_wait_for_interrupt(hc_regs, &sub, pid);

	if (g_dwc2_chhltd_int_en){
		dwc2_clear_host_interrupt();
		dwc2_disable_host_interrupt();
	}

	if (g_dwc2_dma_mode){
		dbg_printf(PRN_INFO | PRN_BUFFERED,"DESCDMA post [count=%d]:", desc_count);
		writel( (desc_count << 8) |
		   (*pid << DWC2_HCTSIZ_PID_OFFSET),
		   &hc_regs->hctsiz);
	}
	BFM_HOST_Bus_Read32(&hc_regs->hctsiz, &data);
	dbg_printf(PRN_INFO | PRN_BUFFERED,"POST HCTSIZ mode(%d): 0x%x\n",g_dwc2_dma_mode, data);

	BFM_HOST_Bus_Read32(&hc_regs->hcdma, &data);
	dbg_printf(PRN_INFO | PRN_BUFFERED,"after hcdma:%x\n", data);

	if (ret < 0)
		return ret;

	if (in) {
		if (!g_dwc2_dma_mode){
			xfer_len -= sub;
		}
	}
	*actual_len = xfer_len;

	return ret;
}

static void dwc_otg_hc_init_split(struct dwc2_hc_regs *hc_regs,
				  uint8_t hub_devnum, uint8_t hub_port)
{
	uint32_t hcsplt = 0;

	hcsplt = DWC2_HCSPLT_SPLTENA;
	hcsplt |= hub_devnum << DWC2_HCSPLT_HUBADDR_OFFSET;
	hcsplt |= hub_port << DWC2_HCSPLT_PRTADDR_OFFSET;

	/* Program the HCSPLIT register for SPLITs */
	writel(hcsplt, &hc_regs->hcsplt);
}

int packet_message(struct dwc2_hsotg *hsotg, struct usb_device *dev,
		  unsigned long pipe, u8 *pid, int in, void *buffer, int len)
{
	struct dwc2_core_regs *regs = hsotg->regs;
	struct dwc2_hc_regs *hc_regs = &regs->hc_regs[DWC2_HC_CHANNEL];
	struct dwc2_host_regs *host_regs = &regs->host_regs;
	int devnum = usb_pipedevice(pipe);
	int ep = usb_pipeendpoint(pipe);
	int max = usb_maxpacket(dev, pipe);
	int eptype = dwc2_eptype[usb_pipetype(pipe)];
	int done = 0;
	int ret = 0;
	int do_split = 0;
	int complete_split = 0;
	uint32_t xfer_len;
	uint32_t num_packets;
	int stop_transfer = 0;
	uint32_t max_xfer_len;
	int ssplit_frame_num = 0;

	g_current_pipe = pipe;

	dbg_printf(PRN_INFO | PRN_BUFFERED,"packet_message: pipe=%x pid=%d in=%d len=%d buffer=0x%x ep=%d maxpktsz=%d eptype=%d \n",
				pipe, *pid, in, len, buffer, ep, max,eptype);

	max_xfer_len = CONFIG_DWC2_MAX_PACKET_COUNT * max;
	if (max_xfer_len > CONFIG_DWC2_MAX_TRANSFER_SIZE)
		max_xfer_len = CONFIG_DWC2_MAX_TRANSFER_SIZE;
	if (max_xfer_len > DWC2_DATA_BUF_SIZE)
		max_xfer_len = DWC2_DATA_BUF_SIZE;

	/* Make sure that max_xfer_len is a multiple of max packet size. */
	num_packets = max_xfer_len / max;
	max_xfer_len = num_packets * max;

	/* Initialize channel */
	dwc2_fill_chnl_chars(regs, DWC2_HC_CHANNEL, dev, devnum, ep, in,
			eptype, max);

	dbg_printf(PRN_INFO | PRN_BUFFERED,"after dwc2_fill_chnl_chars\n");


	/* Check if the target is a FS/LS device behind a HS hub */
	if (dev->speed != USB_SPEED_HIGH) {
		uint8_t hub_addr;
		uint8_t hub_port;
		uint32_t hprt0 = readl(&regs->hprt0);

		dbg_printf(PRN_INFO | PRN_BUFFERED," Checking Hub\n");

		if ((hprt0 & DWC2_HPRT0_PRTSPD_MASK) ==
			 DWC2_HPRT0_PRTSPD_HIGH) {
			usb_find_usb2_hub_address_port(dev, &hub_addr,
							   &hub_port);
			dwc_otg_hc_init_split(hc_regs, hub_addr, hub_port);

			do_split = 1;
			num_packets = 1;
			max_xfer_len = max;
		}
	}

	do {
		int actual_len = 0;
		uint32_t hcint;
		int odd_frame = 0;
		xfer_len = len - done;

		if (xfer_len > max_xfer_len)
			xfer_len = max_xfer_len;
		else if (xfer_len > (unsigned long) max)
			num_packets = (xfer_len + max - 1) / max;
		else
			num_packets = 1;

		if (complete_split)
			_dwc2_setbits_le32(&hc_regs->hcsplt, DWC2_HCSPLT_COMPSPLT);
		else if (do_split)
			_dwc2_clrbits_le32(&hc_regs->hcsplt, DWC2_HCSPLT_COMPSPLT);

		if (eptype == DWC2_HCCHAR_EPTYPE_INTR) {
			int uframe_num = readl(&host_regs->hfnum);
			if (!(uframe_num & 0x1))
				odd_frame = 1;
		}

		ret = dwc2_msg->packet_snd(hc_regs, /*hsotg->aligned_buffer*/ /*aligned_buffer_addr*/ NULL, pid,
					 in, (char *)buffer + done, num_packets,
					 xfer_len, &actual_len, odd_frame);

		if (g_msg_queue){
			return ret;
		}

		hcint = readl(&hc_regs->hcint);
		if (complete_split) {
			stop_transfer = 0;
			if (hcint & DWC2_HCINT_NYET) {
				ret = 0;
				int frame_num = DWC2_HFNUM_MAX_FRNUM &
						readl(&host_regs->hfnum);
				if (((frame_num - ssplit_frame_num) &
					DWC2_HFNUM_MAX_FRNUM) > 4)
					ret = -EAGAIN;
			} else
				complete_split = 0;
		} else if (do_split) {
			if (hcint & DWC2_HCINT_ACK) {
				ssplit_frame_num = DWC2_HFNUM_MAX_FRNUM &
						   readl(&host_regs->hfnum);
				ret = 0;
				complete_split = 1;
			}
		}

		if (ret)
			break;

		if ((unsigned long)actual_len < xfer_len){
			dbg_printf(PRN_INFO | PRN_BUFFERED,"USB ABORT Transfer (actual=%d < requested=%d)\n", actual_len, xfer_len);
			stop_transfer = 1;
		}

		done += actual_len;

	/* Transactions are done when when either all data is transferred or
	 * there is a short transfer. In case of a SPLIT make sure the CSPLIT
	 * is executed.
	 */
	} while (((done < len) && !stop_transfer) || complete_split);

	writel(0, &hc_regs->hcintmsk);
	writel(0xFFFFFFFF, &hc_regs->hcint);

	dev->status = 0;
	dev->transfer_len = done;

	return ret;
}

int _snd_blk_msg(struct dwc2_hsotg *hsotg, struct usb_device *dev,
			 unsigned long pipe, void *buffer, int len)
{
	int devnum = usb_pipedevice(pipe);
	int ep = usb_pipeendpoint(pipe);
	u8* pid;

	if ((devnum >= MAX_DEVICE) || (devnum == hsotg->root_hub_devnum)) {
		dev->status = 0;
		return -EINVAL;
	}
	if (usb_pipein(pipe))
		pid = &hsotg->in_data_toggle[devnum][ep];
	else
		pid = &hsotg->out_data_toggle[devnum][ep];

	return dwc2_msg->packet_msg(hsotg, dev, pipe, pid, usb_pipein(pipe), buffer, len);
}

static int _snd_ctl_msg(struct dwc2_hsotg *hsotg, struct usb_device *dev,
				   unsigned long pipe, void *buffer, int len,
				   struct devrequest *setup)
{
	int devnum = usb_pipedevice(pipe);
	int ret, transfer_len;
	u8 pid;
	/* For CONTROL endpoint pid should start with DATA1 */
	int status_direction;

	dbg_printf(PRN_INFO | PRN_BUFFERED,"_snd_ctl_msg: devnum=%d pipe=0x%x buffer=%x len=%d setup=0x%x\n",
			devnum, pipe, buffer, len, setup);

	/* SETUP stage */
	pid = DWC2_HC_PID_SETUP;
	do {
		dbg_printf(PRN_INFO | PRN_BUFFERED,"Control Setup:");
		dbg_dump_buffer( (unsigned char *) setup, 8);
		ret = dwc2_msg->packet_msg(hsotg, dev, pipe, &pid, 0, setup, 8);
	} while (ret == -EAGAIN);
	if (ret)
		return ret;

	/* DATA stage */
	transfer_len = 0;
	if (buffer) {
		pid = DWC2_HC_PID_DATA1;
		do {
			ret = dwc2_msg->packet_msg(hsotg, dev, pipe, &pid, usb_pipein(pipe),
					buffer, len);
			transfer_len += dev->transfer_len;
			{
				unsigned char *b = (unsigned char *)buffer;

				b += dev->transfer_len;
				buffer = (void *)b;
			}
			len -= dev->transfer_len;
		} while (ret == -EAGAIN);
		if (ret)
			return ret;
		status_direction = usb_pipeout(pipe);
	} else {
		/* No-data CONTROL always ends with an IN transaction */
		status_direction = 1;
	}

	/* STATUS stage */
	pid = DWC2_HC_PID_DATA1;
	do {
		ret = dwc2_msg->packet_msg(hsotg, dev, pipe, &pid, status_direction,
				hsotg->status_buffer, 0);
	} while (ret == -EAGAIN);
	if (ret)
		return ret;

	dev->transfer_len = transfer_len;

	return 0;
}

int dwc2_wait_device_detection()
{
	struct dwc2_core_regs *regs;
	unsigned long data;
	const char spd[4][12]={"HIGH","FULL","LOW","RESERVED"};
	int timeout=g_port_reset_delay;

	regs = (struct dwc2_core_regs *) ACPU_MEMMAP_USBAHB_REG_BASE;

	dbg_printf(PRN_RES,"Wait PortChange..");

	while(1){
		BFM_HOST_Bus_Read32(&regs->hprt0, &data);
		dbg_printf(PRN_INFO,"hprt=0x%x\n",data);

		if (data&8){ // Check PrtEnchng bit
			int speed  = (data>>17)&3;
			int enable = data&4;
			int attached = data&1;
			int detected = data&2;

			dbg_printf(PRN_RES,"done!\n");
			dbg_printf(PRN_RES,"Device Present: Speed:%s Port:%s Dev: %s,%s \n",
			spd[speed],
			enable?"ENABLE":"DISABLE",
			detected?"DETECTED":"NO_DETECT",
			attached?"ATTACHED":"DETACHED");
			switch(speed){
				case 0:
				pdev_usb->speed = USB_SPEED_HIGH;
				if (enable && attached)
					return 1;
				break;
				case 1:
				pdev_usb->speed = USB_SPEED_FULL;
				if (enable && attached)
					return 1;
				break;
				case 2:
				pdev_usb->speed = USB_SPEED_LOW;
				if (enable && attached)
					return 1;
				break;
				default:
				dbg_printf(PRN_RES,"ERROR: INVALID SPEED. WIll force HS from now\n");
				pdev_usb->speed = USB_SPEED_HIGH;
				return 0;
				break;
			}
		}
		mdelay(10);

		if (!timeout--){
			dbg_printf(PRN_RES,"Connection TimeOut!\n");
			return 0; // time out
		}
	}
	return 0;
}

int dwc2_hw_init(struct dwc2_hsotg *hsotg)
{
	struct dwc2_core_regs *regs = hsotg->regs;
	uint32_t snpsid;
	int i, j;
	//int data;
	int res=0;
	debug("%s,%d\n",__func__,__LINE__);

	//g_regs = (struct dwc2_core_regs *)ACPU_MEMMAP_USBAHB_REG_BASE;

	snpsid = readl(&regs->gsnpsid);
	dbg_printf(PRN_RES,"Core Release: %x.%03x\n", snpsid >> 12 & 0xf, snpsid & 0xfff);

	if ((snpsid & GSNPSID_ID_MASK) != DWC2_OTG_ID &&
		(snpsid & GSNPSID_ID_MASK) != DWC2_FS_IOT_ID &&
		(snpsid & GSNPSID_ID_MASK) != DWC2_HS_IOT_ID) {
		debug("Bad value for GSNPSID: 0x%08x\n",
			snpsid);
		return -ENODEV;
	}

	debug("Core Release: %1x.%1x%1x%1x (snpsid=%x)\n",
		snpsid >> 12 & 0xf, snpsid >> 8 & 0xf,
		snpsid >> 4 & 0xf, snpsid & 0xf, snpsid);

	dwc2_core_init(hsotg);
	dwc2_core_host_init(hsotg);
	dbg_printf(PRN_RES,"Wait PortConnectInterrupt..");
	j=g_port_reset_delay;
	while(j){
		mdelay(10);
		if (dwc2_readl(hsotg, HPRT0) & HPRT0_CONNDET){
			dbg_printf(PRN_RES,"done!\n");
			break;
		}
		dbg_printf(PRN_RES,".");
		if (g_port_reset_delay) // wait forever if g_port_reset_delay  0
			j--;
	}

	for(i=0;i<MAX_RETRY;i++){ //Try 10 times because port detection is not stable on VELOCE.
		/*
		 * Reset the port. During a HNP mode switch the reset
		 * needs to occur within 1ms and have a duration of at
		 * least 50ms.
		 */
		u32 hprt0 = dwc2_read_hprt0(hsotg);
		hprt0 |= HPRT0_RST;
		dwc2_writel(hsotg, hprt0, HPRT0);
		dbg_printf(PRN_RES,"Port RESET started..");

		mdelay(g_prtrst_duration_ms); // wait 50 msec per user guide, or more
		dbg_printf(PRN_RES,"done!\n");

		hprt0 = dwc2_read_hprt0(hsotg);
		hprt0 &= ~HPRT0_RST;
		dwc2_writel(hsotg, hprt0, HPRT0);

		if (dwc2_wait_device_detection()){
			break;
		}
		else{
			dbg_printf(PRN_RES,"Retry INIT...\n");
			dwc2_core_init(hsotg);
			dwc2_core_host_init(hsotg);
		}
	}
	if (i == MAX_RETRY)
		return 1;

	for (i = 0; i < MAX_DEVICE; i++) {
		for (j = 0; j < MAX_EPS_CHANNELS; j++) {
			hsotg->in_data_toggle[i][j] = DWC2_HC_PID_DATA0;
			hsotg->out_data_toggle[i][j] = DWC2_HC_PID_DATA0;
		}
	}

	mdelay(3000);  // Add  delay for problematic flash drive

	return res;
}

void dwc2_host_reset(struct dwc2_core_regs *regs)
{
	/* Put everything in reset. */
	_dwc2_clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
			DWC2_HPRT0_PRTCONNDET | DWC2_HPRT0_PRTENCHNG |
			DWC2_HPRT0_PRTOVRCURRCHNG,
			DWC2_HPRT0_PRTRST);
}

int que_blk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int len)
{
	g_msg_queue = 1;
	return dwc2_msg->blk(&dwc2_drv, dev, pipe, buffer, len);
}

int snd_ctl_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
			   int len, struct devrequest *setup)
{
	g_msg_queue = 0;
	return dwc2_msg->ctl(&dwc2_drv, dev, pipe, buffer, len, setup);
}

int snd_blk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
			int len)
{
	g_msg_queue = 0;

	return dwc2_msg->blk(&dwc2_drv, dev, pipe, buffer, len);
}

static const hcd_dwc2_ops_t hcd_hcd_dwc2_ops = {
	.packet_msg = packet_message,
	.packet_snd = packet_send,
	.ctl = _snd_ctl_msg,
	.blk = _snd_blk_msg,
};

void dwc2_hcd_setup_ops(const hcd_dwc2_ops_t **dwc2_ops)
{
	*dwc2_ops = &hcd_hcd_dwc2_ops;
}

void dwc2_init(struct dwc2_hsotg *hsotg)
{
	hsotg->root_hub_devnum = 0;
	hsotg->regs = (struct dwc2_core_regs *) ACPU_MEMMAP_USBAHB_REG_BASE;
	hsotg->reg_base = ACPU_MEMMAP_USBAHB_REG_BASE;
	hsotg->aligned_buffer = aligned_buffer_addr;
	hsotg->status_buffer = status_buffer_addr;
	hsotg->phy_ulpi_ext_vbus = true;	//use external vbus
	hsotg->hnp_srp_disable = true; // will force host mode
	hsotg->ts_dline = false;
	hsotg->phy_ulpi_ddr = false;
	hsotg->ulpi_fs_ls = false;
	hsotg->speed = DWC2_SPEED_PARAM_HIGH;
	hsotg->dma_desc_enable = false;
	hsotg->host_channels = 1 + ((dwc2_readl(hsotg, GHWCFG2) & GHWCFG2_NUM_HOST_CHAN_MASK) >>
		GHWCFG2_NUM_HOST_CHAN_SHIFT);
	dwc2_hcd_setup_ops(&dwc2_msg);
	if (g_dwc2_chhltd_int_en == 1) {
		register_isr(dwc2_isr, IRQ_usb0Intr);
	}

}

