/*
 * Copyright (C) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
 * Copyright (C) 2014 Marek Vasut <marex@denx.de>
 *
 * SPDX-License-Identifier:     GPL-2.0+
 */

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <usb.h>
#include <malloc.h>
#include <phys2bus.h>
#include <usbroothubdes.h>
#include <asm/io.h>

#include "dwc2.h"

/* Use only HC channel 0. */
#define DWC2_HC_CHANNEL			0

#define DWC2_STATUS_BUF_SIZE		64
#define DWC2_DATA_BUF_SIZE		(64 * 1024)

#define MAX_DEVICE			16
#define MAX_ENDPOINT			16

struct dwc2_priv {
#ifdef CONFIG_DM_USB
	uint8_t aligned_buffer[DWC2_DATA_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN);
	uint8_t status_buffer[DWC2_STATUS_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN);
#else
	uint8_t *aligned_buffer;
	uint8_t *status_buffer;
#endif
	int bulk_data_toggle[MAX_DEVICE][MAX_ENDPOINT];
	struct dwc2_core_regs *regs;
	int root_hub_devnum;
};

#ifndef CONFIG_DM_USB
/* We need cacheline-aligned buffers for DMA transfers and dcache support */
DEFINE_ALIGN_BUFFER(uint8_t, aligned_buffer_addr, DWC2_DATA_BUF_SIZE,
		ARCH_DMA_MINALIGN);
DEFINE_ALIGN_BUFFER(uint8_t, status_buffer_addr, DWC2_STATUS_BUF_SIZE,
		ARCH_DMA_MINALIGN);

static struct dwc2_priv local;
#endif

/*
 * DWC2 IP interface
 */
static int wait_for_bit(void *reg, const uint32_t mask, bool set)
{
	unsigned int timeout = 1000000;
	uint32_t val;

	while (--timeout) {
		val = readl(reg);
		if (!set)
			val = ~val;

		if ((val & mask) == mask)
			return 0;

		udelay(1);
	}

	debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n",
	      __func__, reg, mask, set);

	return -ETIMEDOUT;
}

/*
 * Initializes the FSLSPClkSel field of the HCFG register
 * depending on the PHY type.
 */
static void init_fslspclksel(struct dwc2_core_regs *regs)
{
	uint32_t phyclk;

#if (CONFIG_DWC2_PHY_TYPE == DWC2_PHY_TYPE_FS)
	phyclk = DWC2_HCFG_FSLSPCLKSEL_48_MHZ;	/* Full speed PHY */
#else
	/* High speed PHY running at full speed or high speed */
	phyclk = DWC2_HCFG_FSLSPCLKSEL_30_60_MHZ;
#endif

#ifdef CONFIG_DWC2_ULPI_FS_LS
	uint32_t hwcfg2 = readl(&regs->ghwcfg2);
	uint32_t hval = (ghwcfg2 & DWC2_HWCFG2_HS_PHY_TYPE_MASK) >>
			DWC2_HWCFG2_HS_PHY_TYPE_OFFSET;
	uint32_t fval = (ghwcfg2 & DWC2_HWCFG2_FS_PHY_TYPE_MASK) >>
			DWC2_HWCFG2_FS_PHY_TYPE_OFFSET;

	if (hval == 2 && fval == 1)
		phyclk = DWC2_HCFG_FSLSPCLKSEL_48_MHZ;	/* Full speed PHY */
#endif

	clrsetbits_le32(&regs->host_regs.hcfg,
			DWC2_HCFG_FSLSPCLKSEL_MASK,
			phyclk << DWC2_HCFG_FSLSPCLKSEL_OFFSET);
}

/*
 * Flush a Tx FIFO.
 *
 * @param regs Programming view of DWC_otg controller.
 * @param num Tx FIFO to flush.
 */
static void dwc_otg_flush_tx_fifo(struct dwc2_core_regs *regs, const int num)
{
	int ret;

	writel(DWC2_GRSTCTL_TXFFLSH | (num << DWC2_GRSTCTL_TXFNUM_OFFSET),
	       &regs->grstctl);
	ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_TXFFLSH, 0);
	if (ret)
		printf("%s: Timeout!\n", __func__);

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

/*
 * Flush Rx FIFO.
 *
 * @param regs Programming view of DWC_otg controller.
 */
static void dwc_otg_flush_rx_fifo(struct dwc2_core_regs *regs)
{
	int ret;

	writel(DWC2_GRSTCTL_RXFFLSH, &regs->grstctl);
	ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_RXFFLSH, 0);
	if (ret)
		printf("%s: Timeout!\n", __func__);

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

/*
 * Do core a soft reset of the core.  Be careful with this because it
 * resets all the internal state machines of the core.
 */
static void dwc_otg_core_reset(struct dwc2_core_regs *regs)
{
	int ret;

	/* Wait for AHB master IDLE state. */
	ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_AHBIDLE, 1);
	if (ret)
		printf("%s: Timeout!\n", __func__);

	/* Core Soft Reset */
	writel(DWC2_GRSTCTL_CSFTRST, &regs->grstctl);
	ret = wait_for_bit(&regs->grstctl, DWC2_GRSTCTL_CSFTRST, 0);
	if (ret)
		printf("%s: Timeout!\n", __func__);

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

/*
 * This function initializes the DWC_otg controller registers for
 * host mode.
 *
 * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
 * request queues. Host channels are reset to ensure that they are ready for
 * performing transfers.
 *
 * @param regs Programming view of DWC_otg controller
 *
 */
static void dwc_otg_core_host_init(struct dwc2_core_regs *regs)
{
	uint32_t nptxfifosize = 0;
	uint32_t ptxfifosize = 0;
	uint32_t hprt0 = 0;
	int i, ret, num_channels;

	/* Restart the Phy Clock */
	writel(0, &regs->pcgcctl);

	/* Initialize Host Configuration Register */
	init_fslspclksel(regs);
#ifdef CONFIG_DWC2_DFLT_SPEED_FULL
	setbits_le32(&regs->host_regs.hcfg, DWC2_HCFG_FSLSSUPP);
#endif

	/* Configure data FIFO sizes */
#ifdef CONFIG_DWC2_ENABLE_DYNAMIC_FIFO
	if (readl(&regs->ghwcfg2) & DWC2_HWCFG2_DYNAMIC_FIFO) {
		/* Rx FIFO */
		writel(CONFIG_DWC2_HOST_RX_FIFO_SIZE, &regs->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;
		writel(nptxfifosize, &regs->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;
		writel(ptxfifosize, &regs->hptxfsiz);
	}
#endif

	/* Clear Host Set HNP Enable in the OTG Control Register */
	clrbits_le32(&regs->gotgctl, DWC2_GOTGCTL_HSTSETHNPEN);

	/* Make sure the FIFOs are flushed. */
	dwc_otg_flush_tx_fifo(regs, 0x10);	/* All Tx FIFOs */
	dwc_otg_flush_rx_fifo(regs);

	/* Flush out any leftover queued requests. */
	num_channels = readl(&regs->ghwcfg2);
	num_channels &= DWC2_HWCFG2_NUM_HOST_CHAN_MASK;
	num_channels >>= DWC2_HWCFG2_NUM_HOST_CHAN_OFFSET;
	num_channels += 1;

	for (i = 0; i < num_channels; i++)
		clrsetbits_le32(&regs->hc_regs[i].hcchar,
				DWC2_HCCHAR_CHEN | DWC2_HCCHAR_EPDIR,
				DWC2_HCCHAR_CHDIS);

	/* Halt all channels to put them into a known state. */
	for (i = 0; i < num_channels; i++) {
		clrsetbits_le32(&regs->hc_regs[i].hcchar,
				DWC2_HCCHAR_EPDIR,
				DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS);
		ret = wait_for_bit(&regs->hc_regs[i].hcchar,
				   DWC2_HCCHAR_CHEN, 0);
		if (ret)
			printf("%s: Timeout!\n", __func__);
	}

	/* Turn on the vbus power. */
	if (readl(&regs->gintsts) & DWC2_GINTSTS_CURMODE_HOST) {
		hprt0 = readl(&regs->hprt0);
		hprt0 &= ~(DWC2_HPRT0_PRTENA | DWC2_HPRT0_PRTCONNDET);
		hprt0 &= ~(DWC2_HPRT0_PRTENCHNG | DWC2_HPRT0_PRTOVRCURRCHNG);
		if (!(hprt0 & DWC2_HPRT0_PRTPWR)) {
			hprt0 |= DWC2_HPRT0_PRTPWR;
			writel(hprt0, &regs->hprt0);
		}
	}
}

/*
 * This function initializes the DWC_otg controller registers and
 * prepares the core for device mode or host mode operation.
 *
 * @param regs Programming view of the DWC_otg controller
 */
static void dwc_otg_core_init(struct dwc2_core_regs *regs)
{
	uint32_t ahbcfg = 0;
	uint32_t usbcfg = 0;
	uint8_t brst_sz = CONFIG_DWC2_DMA_BURST_SIZE;

	/* Common Initialization */
	usbcfg = readl(&regs->gusbcfg);

	/* Program the ULPI External VBUS bit if needed */
#ifdef CONFIG_DWC2_PHY_ULPI_EXT_VBUS
	usbcfg |= DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV;
#else
	usbcfg &= ~DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV;
#endif

	/* Set external TS Dline pulsing */
#ifdef CONFIG_DWC2_TS_DLINE
	usbcfg |= DWC2_GUSBCFG_TERM_SEL_DL_PULSE;
#else
	usbcfg &= ~DWC2_GUSBCFG_TERM_SEL_DL_PULSE;
#endif
	writel(usbcfg, &regs->gusbcfg);

	/* Reset the Controller */
	dwc_otg_core_reset(regs);

	/*
	 * This programming sequence needs to happen in FS mode before
	 * any other programming occurs
	 */
#if defined(CONFIG_DWC2_DFLT_SPEED_FULL) && \
	(CONFIG_DWC2_PHY_TYPE == DWC2_PHY_TYPE_FS)
	/* If FS mode with FS PHY */
	setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_PHYSEL);

	/* Reset after a PHY select */
	dwc_otg_core_reset(regs);

	/*
	 * Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS.
	 * Also do this on HNP Dev/Host mode switches (done in dev_init
	 * and host_init).
	 */
	if (readl(&regs->gintsts) & DWC2_GINTSTS_CURMODE_HOST)
		init_fslspclksel(regs);

#ifdef CONFIG_DWC2_I2C_ENABLE
	/* Program GUSBCFG.OtgUtmifsSel to I2C */
	setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_OTGUTMIFSSEL);

	/* Program GI2CCTL.I2CEn */
	clrsetbits_le32(&regs->gi2cctl, DWC2_GI2CCTL_I2CEN |
			DWC2_GI2CCTL_I2CDEVADDR_MASK,
			1 << DWC2_GI2CCTL_I2CDEVADDR_OFFSET);
	setbits_le32(&regs->gi2cctl, DWC2_GI2CCTL_I2CEN);
#endif

#else
	/* High speed PHY. */

	/*
	 * HS PHY parameters. These parameters are preserved during
	 * soft reset so only program the first time. Do a soft reset
	 * immediately after setting phyif.
	 */
	usbcfg &= ~(DWC2_GUSBCFG_ULPI_UTMI_SEL | DWC2_GUSBCFG_PHYIF);
	usbcfg |= CONFIG_DWC2_PHY_TYPE << DWC2_GUSBCFG_ULPI_UTMI_SEL_OFFSET;

	if (usbcfg & DWC2_GUSBCFG_ULPI_UTMI_SEL) {	/* ULPI interface */
#ifdef CONFIG_DWC2_PHY_ULPI_DDR
		usbcfg |= DWC2_GUSBCFG_DDRSEL;
#else
		usbcfg &= ~DWC2_GUSBCFG_DDRSEL;
#endif
	} else {	/* UTMI+ interface */
#if (CONFIG_DWC2_UTMI_PHY_WIDTH == 16)
		usbcfg |= DWC2_GUSBCFG_PHYIF;
#endif
	}

	writel(usbcfg, &regs->gusbcfg);

	/* Reset after setting the PHY parameters */
	dwc_otg_core_reset(regs);
#endif

	usbcfg = readl(&regs->gusbcfg);
	usbcfg &= ~(DWC2_GUSBCFG_ULPI_FSLS | DWC2_GUSBCFG_ULPI_CLK_SUS_M);
#ifdef CONFIG_DWC2_ULPI_FS_LS
	uint32_t hwcfg2 = readl(&regs->ghwcfg2);
	uint32_t hval = (ghwcfg2 & DWC2_HWCFG2_HS_PHY_TYPE_MASK) >>
			DWC2_HWCFG2_HS_PHY_TYPE_OFFSET;
	uint32_t fval = (ghwcfg2 & DWC2_HWCFG2_FS_PHY_TYPE_MASK) >>
			DWC2_HWCFG2_FS_PHY_TYPE_OFFSET;
	if (hval == 2 && fval == 1) {
		usbcfg |= DWC2_GUSBCFG_ULPI_FSLS;
		usbcfg |= DWC2_GUSBCFG_ULPI_CLK_SUS_M;
	}
#endif
	writel(usbcfg, &regs->gusbcfg);

	/* Program the GAHBCFG Register. */
	switch (readl(&regs->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;
		}

#ifdef CONFIG_DWC2_DMA_ENABLE
		ahbcfg |= DWC2_GAHBCFG_DMAENABLE;
#endif
		break;

	case DWC2_HWCFG2_ARCHITECTURE_INT_DMA:
		ahbcfg |= DWC2_GAHBCFG_HBURSTLEN_INCR4;
#ifdef CONFIG_DWC2_DMA_ENABLE
		ahbcfg |= DWC2_GAHBCFG_DMAENABLE;
#endif
		break;
	}

	writel(ahbcfg, &regs->gahbcfg);

	/* Program the GUSBCFG register for HNP/SRP. */
	setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_HNPCAP | DWC2_GUSBCFG_SRPCAP);

#ifdef CONFIG_DWC2_IC_USB_CAP
	setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_IC_USB_CAP);
#endif
}

/*
 * 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 dwc_otg_hc_init(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;

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

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

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

/*
 * DWC2 to USB API interface
 */
/* Direction: In ; Request: Status */
static int dwc_otg_submit_rh_msg_in_status(struct dwc2_core_regs *regs,
					   struct usb_device *dev, void *buffer,
					   int txlen, struct devrequest *cmd)
{
	uint32_t hprt0 = 0;
	uint32_t port_status = 0;
	uint32_t port_change = 0;
	int len = 0;
	int stat = 0;

	switch (cmd->requesttype & ~USB_DIR_IN) {
	case 0:
		*(uint16_t *)buffer = cpu_to_le16(1);
		len = 2;
		break;
	case USB_RECIP_INTERFACE:
	case USB_RECIP_ENDPOINT:
		*(uint16_t *)buffer = cpu_to_le16(0);
		len = 2;
		break;
	case USB_TYPE_CLASS:
		*(uint32_t *)buffer = cpu_to_le32(0);
		len = 4;
		break;
	case USB_RECIP_OTHER | USB_TYPE_CLASS:
		hprt0 = readl(&regs->hprt0);
		if (hprt0 & DWC2_HPRT0_PRTCONNSTS)
			port_status |= USB_PORT_STAT_CONNECTION;
		if (hprt0 & DWC2_HPRT0_PRTENA)
			port_status |= USB_PORT_STAT_ENABLE;
		if (hprt0 & DWC2_HPRT0_PRTSUSP)
			port_status |= USB_PORT_STAT_SUSPEND;
		if (hprt0 & DWC2_HPRT0_PRTOVRCURRACT)
			port_status |= USB_PORT_STAT_OVERCURRENT;
		if (hprt0 & DWC2_HPRT0_PRTRST)
			port_status |= USB_PORT_STAT_RESET;
		if (hprt0 & DWC2_HPRT0_PRTPWR)
			port_status |= USB_PORT_STAT_POWER;

		if ((hprt0 & DWC2_HPRT0_PRTSPD_MASK) == DWC2_HPRT0_PRTSPD_LOW)
			port_status |= USB_PORT_STAT_LOW_SPEED;
		else if ((hprt0 & DWC2_HPRT0_PRTSPD_MASK) ==
			 DWC2_HPRT0_PRTSPD_HIGH)
			port_status |= USB_PORT_STAT_HIGH_SPEED;

		if (hprt0 & DWC2_HPRT0_PRTENCHNG)
			port_change |= USB_PORT_STAT_C_ENABLE;
		if (hprt0 & DWC2_HPRT0_PRTCONNDET)
			port_change |= USB_PORT_STAT_C_CONNECTION;
		if (hprt0 & DWC2_HPRT0_PRTOVRCURRCHNG)
			port_change |= USB_PORT_STAT_C_OVERCURRENT;

		*(uint32_t *)buffer = cpu_to_le32(port_status |
					(port_change << 16));
		len = 4;
		break;
	default:
		puts("unsupported root hub command\n");
		stat = USB_ST_STALLED;
	}

	dev->act_len = min(len, txlen);
	dev->status = stat;

	return stat;
}

/* Direction: In ; Request: Descriptor */
static int dwc_otg_submit_rh_msg_in_descriptor(struct usb_device *dev,
					       void *buffer, int txlen,
					       struct devrequest *cmd)
{
	unsigned char data[32];
	uint32_t dsc;
	int len = 0;
	int stat = 0;
	uint16_t wValue = cpu_to_le16(cmd->value);
	uint16_t wLength = cpu_to_le16(cmd->length);

	switch (cmd->requesttype & ~USB_DIR_IN) {
	case 0:
		switch (wValue & 0xff00) {
		case 0x0100:	/* device descriptor */
			len = min3(txlen, (int)sizeof(root_hub_dev_des), (int)wLength);
			memcpy(buffer, root_hub_dev_des, len);
			break;
		case 0x0200:	/* configuration descriptor */
			len = min3(txlen, (int)sizeof(root_hub_config_des), (int)wLength);
			memcpy(buffer, root_hub_config_des, len);
			break;
		case 0x0300:	/* string descriptors */
			switch (wValue & 0xff) {
			case 0x00:
				len = min3(txlen, (int)sizeof(root_hub_str_index0),
					   (int)wLength);
				memcpy(buffer, root_hub_str_index0, len);
				break;
			case 0x01:
				len = min3(txlen, (int)sizeof(root_hub_str_index1),
					   (int)wLength);
				memcpy(buffer, root_hub_str_index1, len);
				break;
			}
			break;
		default:
			stat = USB_ST_STALLED;
		}
		break;

	case USB_TYPE_CLASS:
		/* Root port config, set 1 port and nothing else. */
		dsc = 0x00000001;

		data[0] = 9;		/* min length; */
		data[1] = 0x29;
		data[2] = dsc & RH_A_NDP;
		data[3] = 0;
		if (dsc & RH_A_PSM)
			data[3] |= 0x1;
		if (dsc & RH_A_NOCP)
			data[3] |= 0x10;
		else if (dsc & RH_A_OCPM)
			data[3] |= 0x8;

		/* corresponds to data[4-7] */
		data[5] = (dsc & RH_A_POTPGT) >> 24;
		data[7] = dsc & RH_B_DR;
		if (data[2] < 7) {
			data[8] = 0xff;
		} else {
			data[0] += 2;
			data[8] = (dsc & RH_B_DR) >> 8;
			data[9] = 0xff;
			data[10] = data[9];
		}

		len = min3(txlen, (int)data[0], (int)wLength);
		memcpy(buffer, data, len);
		break;
	default:
		puts("unsupported root hub command\n");
		stat = USB_ST_STALLED;
	}

	dev->act_len = min(len, txlen);
	dev->status = stat;

	return stat;
}

/* Direction: In ; Request: Configuration */
static int dwc_otg_submit_rh_msg_in_configuration(struct usb_device *dev,
						  void *buffer, int txlen,
						  struct devrequest *cmd)
{
	int len = 0;
	int stat = 0;

	switch (cmd->requesttype & ~USB_DIR_IN) {
	case 0:
		*(uint8_t *)buffer = 0x01;
		len = 1;
		break;
	default:
		puts("unsupported root hub command\n");
		stat = USB_ST_STALLED;
	}

	dev->act_len = min(len, txlen);
	dev->status = stat;

	return stat;
}

/* Direction: In */
static int dwc_otg_submit_rh_msg_in(struct dwc2_priv *priv,
				    struct usb_device *dev, void *buffer,
				    int txlen, struct devrequest *cmd)
{
	switch (cmd->request) {
	case USB_REQ_GET_STATUS:
		return dwc_otg_submit_rh_msg_in_status(priv->regs, dev, buffer,
						       txlen, cmd);
	case USB_REQ_GET_DESCRIPTOR:
		return dwc_otg_submit_rh_msg_in_descriptor(dev, buffer,
							   txlen, cmd);
	case USB_REQ_GET_CONFIGURATION:
		return dwc_otg_submit_rh_msg_in_configuration(dev, buffer,
							      txlen, cmd);
	default:
		puts("unsupported root hub command\n");
		return USB_ST_STALLED;
	}
}

/* Direction: Out */
static int dwc_otg_submit_rh_msg_out(struct dwc2_priv *priv,
				     struct usb_device *dev,
				     void *buffer, int txlen,
				     struct devrequest *cmd)
{
	struct dwc2_core_regs *regs = priv->regs;
	int len = 0;
	int stat = 0;
	uint16_t bmrtype_breq = cmd->requesttype | (cmd->request << 8);
	uint16_t wValue = cpu_to_le16(cmd->value);

	switch (bmrtype_breq & ~USB_DIR_IN) {
	case (USB_REQ_CLEAR_FEATURE << 8) | USB_RECIP_ENDPOINT:
	case (USB_REQ_CLEAR_FEATURE << 8) | USB_TYPE_CLASS:
		break;

	case (USB_REQ_CLEAR_FEATURE << 8) | USB_RECIP_OTHER | USB_TYPE_CLASS:
		switch (wValue) {
		case USB_PORT_FEAT_C_CONNECTION:
			setbits_le32(&regs->hprt0, DWC2_HPRT0_PRTCONNDET);
			break;
		}
		break;

	case (USB_REQ_SET_FEATURE << 8) | USB_RECIP_OTHER | USB_TYPE_CLASS:
		switch (wValue) {
		case USB_PORT_FEAT_SUSPEND:
			break;

		case USB_PORT_FEAT_RESET:
			clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
					DWC2_HPRT0_PRTCONNDET |
					DWC2_HPRT0_PRTENCHNG |
					DWC2_HPRT0_PRTOVRCURRCHNG,
					DWC2_HPRT0_PRTRST);
			mdelay(50);
			clrbits_le32(&regs->hprt0, DWC2_HPRT0_PRTRST);
			break;

		case USB_PORT_FEAT_POWER:
			clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
					DWC2_HPRT0_PRTCONNDET |
					DWC2_HPRT0_PRTENCHNG |
					DWC2_HPRT0_PRTOVRCURRCHNG,
					DWC2_HPRT0_PRTRST);
			break;

		case USB_PORT_FEAT_ENABLE:
			break;
		}
		break;
	case (USB_REQ_SET_ADDRESS << 8):
		priv->root_hub_devnum = wValue;
		break;
	case (USB_REQ_SET_CONFIGURATION << 8):
		break;
	default:
		puts("unsupported root hub command\n");
		stat = USB_ST_STALLED;
	}

	len = min(len, txlen);

	dev->act_len = len;
	dev->status = stat;

	return stat;
}

static int dwc_otg_submit_rh_msg(struct dwc2_priv *priv, struct usb_device *dev,
				 unsigned long pipe, void *buffer, int txlen,
				 struct devrequest *cmd)
{
	int stat = 0;

	if (usb_pipeint(pipe)) {
		puts("Root-Hub submit IRQ: NOT implemented\n");
		return 0;
	}

	if (cmd->requesttype & USB_DIR_IN)
		stat = dwc_otg_submit_rh_msg_in(priv, dev, buffer, txlen, cmd);
	else
		stat = dwc_otg_submit_rh_msg_out(priv, dev, buffer, txlen, cmd);

	mdelay(1);

	return stat;
}

int wait_for_chhltd(struct dwc2_core_regs *regs, uint32_t *sub, int *toggle,
		    bool ignore_ack)
{
	uint32_t hcint_comp_hlt_ack = DWC2_HCINT_XFERCOMP | DWC2_HCINT_CHHLTD;
	struct dwc2_hc_regs *hc_regs = &regs->hc_regs[DWC2_HC_CHANNEL];
	int ret;
	uint32_t hcint, hctsiz;

	ret = wait_for_bit(&hc_regs->hcint, DWC2_HCINT_CHHLTD, true);
	if (ret)
		return ret;

	hcint = readl(&hc_regs->hcint);
	if (hcint & (DWC2_HCINT_NAK | DWC2_HCINT_FRMOVRUN))
		return -EAGAIN;
	if (ignore_ack)
		hcint &= ~DWC2_HCINT_ACK;
	else
		hcint_comp_hlt_ack |= DWC2_HCINT_ACK;
	if (hcint != hcint_comp_hlt_ack) {
		debug("%s: Error (HCINT=%08x)\n", __func__, hcint);
		return -EINVAL;
	}

	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;

	debug("%s: sub=%u toggle=%d\n", __func__, *sub, *toggle);

	return 0;
}

static int dwc2_eptype[] = {
	DWC2_HCCHAR_EPTYPE_ISOC,
	DWC2_HCCHAR_EPTYPE_INTR,
	DWC2_HCCHAR_EPTYPE_CONTROL,
	DWC2_HCCHAR_EPTYPE_BULK,
};

int chunk_msg(struct dwc2_priv *priv, struct usb_device *dev,
	      unsigned long pipe, int *pid, int in, void *buffer, int len,
	      bool ignore_ack)
{
	struct dwc2_core_regs *regs = priv->regs;
	struct dwc2_hc_regs *hc_regs = &regs->hc_regs[DWC2_HC_CHANNEL];
	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;
	uint32_t sub;
	uint32_t xfer_len;
	uint32_t num_packets;
	int stop_transfer = 0;

	debug("%s: msg: pipe %lx pid %d in %d len %d\n", __func__, pipe, *pid,
	      in, len);

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

		xfer_len = len - done;
		if (xfer_len > CONFIG_DWC2_MAX_TRANSFER_SIZE)
			xfer_len = CONFIG_DWC2_MAX_TRANSFER_SIZE - max + 1;
		if (xfer_len > DWC2_DATA_BUF_SIZE)
			xfer_len = DWC2_DATA_BUF_SIZE - max + 1;

		/* Make sure that xfer_len is a multiple of max packet size. */
		if (xfer_len > 0) {
			num_packets = (xfer_len + max - 1) / max;
			if (num_packets > CONFIG_DWC2_MAX_PACKET_COUNT) {
				num_packets = CONFIG_DWC2_MAX_PACKET_COUNT;
				xfer_len = num_packets * max;
			}
		} else {
			num_packets = 1;
		}

		if (in)
			xfer_len = num_packets * max;

		debug("%s: chunk: pid %d xfer_len %u pkts %u\n", __func__,
		      *pid, xfer_len, num_packets);

		writel((xfer_len << DWC2_HCTSIZ_XFERSIZE_OFFSET) |
		       (num_packets << DWC2_HCTSIZ_PKTCNT_OFFSET) |
		       (*pid << DWC2_HCTSIZ_PID_OFFSET),
		       &hc_regs->hctsiz);

		if (!in) {
			memcpy(priv->aligned_buffer, (char *)buffer + done, len);

			flush_dcache_range((unsigned long)priv->aligned_buffer,
				(unsigned long)((void *)priv->aligned_buffer +
				roundup(len, ARCH_DMA_MINALIGN)));
		}

		writel(phys_to_bus((unsigned long)priv->aligned_buffer),
		       &hc_regs->hcdma);

		/* Set host channel enable after all other setup is complete. */
		clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
				DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS,
				(1 << DWC2_HCCHAR_MULTICNT_OFFSET) |
				DWC2_HCCHAR_CHEN);

		ret = wait_for_chhltd(regs, &sub, pid, ignore_ack);
		if (ret)
			break;

		if (in) {
			xfer_len -= sub;

			invalidate_dcache_range((unsigned long)priv->aligned_buffer,
				(unsigned long)((void *)priv->aligned_buffer +
				roundup(xfer_len, ARCH_DMA_MINALIGN)));

			memcpy(buffer + done, priv->aligned_buffer, xfer_len);
			if (sub)
				stop_transfer = 1;
		}

		done += xfer_len;

	} while ((done < len) && !stop_transfer);

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

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

	return ret;
}

/* U-Boot USB transmission interface */
int _submit_bulk_msg(struct dwc2_priv *priv, struct usb_device *dev,
		     unsigned long pipe, void *buffer, int len)
{
	int devnum = usb_pipedevice(pipe);
	int ep = usb_pipeendpoint(pipe);

	if (devnum == priv->root_hub_devnum) {
		dev->status = 0;
		return -EINVAL;
	}

	return chunk_msg(priv, dev, pipe, &priv->bulk_data_toggle[devnum][ep],
			 usb_pipein(pipe), buffer, len, true);
}

static int _submit_control_msg(struct dwc2_priv *priv, struct usb_device *dev,
			       unsigned long pipe, void *buffer, int len,
			       struct devrequest *setup)
{
	int devnum = usb_pipedevice(pipe);
	int pid, ret, act_len;
	/* For CONTROL endpoint pid should start with DATA1 */
	int status_direction;

	if (devnum == priv->root_hub_devnum) {
		dev->status = 0;
		dev->speed = USB_SPEED_HIGH;
		return dwc_otg_submit_rh_msg(priv, dev, pipe, buffer, len,
					     setup);
	}

	pid = DWC2_HC_PID_SETUP;
	ret = chunk_msg(priv, dev, pipe, &pid, 0, setup, 8, true);
	if (ret)
		return ret;

	if (buffer) {
		pid = DWC2_HC_PID_DATA1;
		ret = chunk_msg(priv, dev, pipe, &pid, usb_pipein(pipe), buffer,
				len, false);
		if (ret)
			return ret;
		act_len = dev->act_len;
	} /* End of DATA stage */
	else
		act_len = 0;

	/* STATUS stage */
	if ((len == 0) || usb_pipeout(pipe))
		status_direction = 1;
	else
		status_direction = 0;

	pid = DWC2_HC_PID_DATA1;
	ret = chunk_msg(priv, dev, pipe, &pid, status_direction,
			priv->status_buffer, 0, false);
	if (ret)
		return ret;

	dev->act_len = act_len;

	return 0;
}

int _submit_int_msg(struct dwc2_priv *priv, struct usb_device *dev,
		    unsigned long pipe, void *buffer, int len, int interval)
{
	unsigned long timeout;
	int ret;

	/* FIXME: what is interval? */

	timeout = get_timer(0) + USB_TIMEOUT_MS(pipe);
	for (;;) {
		if (get_timer(0) > timeout) {
			printf("Timeout poll on interrupt endpoint\n");
			return -ETIMEDOUT;
		}
		ret = _submit_bulk_msg(priv, dev, pipe, buffer, len);
		if (ret != -EAGAIN)
			return ret;
	}
}

static int dwc2_init_common(struct dwc2_priv *priv)
{
	struct dwc2_core_regs *regs = priv->regs;
	uint32_t snpsid;
	int i, j;

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

	if ((snpsid & DWC2_SNPSID_DEVID_MASK) != DWC2_SNPSID_DEVID_VER_2xx &&
	    (snpsid & DWC2_SNPSID_DEVID_MASK) != DWC2_SNPSID_DEVID_VER_3xx) {
		printf("SNPSID invalid (not DWC2 OTG device): %08x\n", snpsid);
		return -ENODEV;
	}

	dwc_otg_core_init(regs);
	dwc_otg_core_host_init(regs);

	clrsetbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA |
			DWC2_HPRT0_PRTCONNDET | DWC2_HPRT0_PRTENCHNG |
			DWC2_HPRT0_PRTOVRCURRCHNG,
			DWC2_HPRT0_PRTRST);
	mdelay(50);
	clrbits_le32(&regs->hprt0, DWC2_HPRT0_PRTENA | DWC2_HPRT0_PRTCONNDET |
		     DWC2_HPRT0_PRTENCHNG | DWC2_HPRT0_PRTOVRCURRCHNG |
		     DWC2_HPRT0_PRTRST);

	for (i = 0; i < MAX_DEVICE; i++) {
		for (j = 0; j < MAX_ENDPOINT; j++)
			priv->bulk_data_toggle[i][j] = DWC2_HC_PID_DATA0;
	}

	return 0;
}

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

#ifndef CONFIG_DM_USB
int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
		       int len, struct devrequest *setup)
{
	return _submit_control_msg(&local, dev, pipe, buffer, len, setup);
}

int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
		    int len)
{
	return _submit_bulk_msg(&local, dev, pipe, buffer, len);
}

int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
		   int len, int interval)
{
	return _submit_int_msg(&local, dev, pipe, buffer, len, interval);
}

/* U-Boot USB control interface */
int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
{
	struct dwc2_priv *priv = &local;

	memset(priv, '\0', sizeof(*priv));
	priv->root_hub_devnum = 0;
	priv->regs = (struct dwc2_core_regs *)CONFIG_USB_DWC2_REG_ADDR;
	priv->aligned_buffer = aligned_buffer_addr;
	priv->status_buffer = status_buffer_addr;

	/* board-dependant init */
	if (board_usb_init(index, USB_INIT_HOST))
		return -1;

	return dwc2_init_common(priv);
}

int usb_lowlevel_stop(int index)
{
	dwc2_uninit_common(local.regs);

	return 0;
}
#endif

#ifdef CONFIG_DM_USB
static int dwc2_submit_control_msg(struct udevice *dev, struct usb_device *udev,
				   unsigned long pipe, void *buffer, int length,
				   struct devrequest *setup)
{
	struct dwc2_priv *priv = dev_get_priv(dev);

	debug("%s: dev='%s', udev=%p, udev->dev='%s', portnr=%d\n", __func__,
	      dev->name, udev, udev->dev->name, udev->portnr);

	return _submit_control_msg(priv, udev, pipe, buffer, length, setup);
}

static int dwc2_submit_bulk_msg(struct udevice *dev, struct usb_device *udev,
				unsigned long pipe, void *buffer, int length)
{
	struct dwc2_priv *priv = dev_get_priv(dev);

	debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);

	return _submit_bulk_msg(priv, udev, pipe, buffer, length);
}

static int dwc2_submit_int_msg(struct udevice *dev, struct usb_device *udev,
			       unsigned long pipe, void *buffer, int length,
			       int interval)
{
	struct dwc2_priv *priv = dev_get_priv(dev);

	debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);

	return _submit_int_msg(priv, udev, pipe, buffer, length, interval);
}

static int dwc2_usb_ofdata_to_platdata(struct udevice *dev)
{
	struct dwc2_priv *priv = dev_get_priv(dev);
	fdt_addr_t addr;

	addr = dev_get_addr(dev);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;
	priv->regs = (struct dwc2_core_regs *)addr;

	return 0;
}

static int dwc2_usb_probe(struct udevice *dev)
{
	struct dwc2_priv *priv = dev_get_priv(dev);

	return dwc2_init_common(priv);
}

static int dwc2_usb_remove(struct udevice *dev)
{
	struct dwc2_priv *priv = dev_get_priv(dev);

	dwc2_uninit_common(priv->regs);

	return 0;
}

struct dm_usb_ops dwc2_usb_ops = {
	.control = dwc2_submit_control_msg,
	.bulk = dwc2_submit_bulk_msg,
	.interrupt = dwc2_submit_int_msg,
};

static const struct udevice_id dwc2_usb_ids[] = {
	{ .compatible = "brcm,bcm2835-usb" },
	{ }
};

U_BOOT_DRIVER(usb_dwc2) = {
	.name	= "dwc2_exynos",
	.id	= UCLASS_USB,
	.of_match = dwc2_usb_ids,
	.ofdata_to_platdata = dwc2_usb_ofdata_to_platdata,
	.probe	= dwc2_usb_probe,
	.remove = dwc2_usb_remove,
	.ops	= &dwc2_usb_ops,
	.priv_auto_alloc_size = sizeof(struct dwc2_priv),
	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
};
#endif
