/*
 * (C) Copyright 2009, 2011, 2016 Freescale Semiconductor, Inc.
 *
 * (C) Copyright 2008, Excito Elektronik i Sk=E5ne AB
 *
 * Author: Tor Krill tor@excito.com
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <pci.h>
#include <usb.h>
#include <asm/io.h>
#include <usb/ehci-ci.h>
#include <hwconfig.h>
#include <fsl_usb.h>
#include <fdt_support.h>
#include <dm.h>

#include "ehci.h"

DECLARE_GLOBAL_DATA_PTR;

#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
#endif

#ifdef CONFIG_DM_USB
struct ehci_fsl_priv {
	struct ehci_ctrl ehci;
	fdt_addr_t hcd_base;
	char *phy_type;
};
#endif

static void set_txfifothresh(struct usb_ehci *, u32);
#ifdef CONFIG_DM_USB
static int ehci_fsl_init(struct ehci_fsl_priv *priv, struct usb_ehci *ehci,
		  struct ehci_hccr *hccr, struct ehci_hcor *hcor);
#else
static int ehci_fsl_init(int index, struct usb_ehci *ehci,
			 struct ehci_hccr *hccr, struct ehci_hcor *hcor);
#endif

/* Check USB PHY clock valid */
static int usb_phy_clk_valid(struct usb_ehci *ehci)
{
	if (!((in_be32(&ehci->control) & PHY_CLK_VALID) ||
			in_be32(&ehci->prictrl))) {
		printf("USB PHY clock invalid!\n");
		return 0;
	} else {
		return 1;
	}
}

#ifdef CONFIG_DM_USB
static int ehci_fsl_ofdata_to_platdata(struct udevice *dev)
{
	struct ehci_fsl_priv *priv = dev_get_priv(dev);
	const void *prop;

	prop = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy_type",
			   NULL);
	if (prop) {
		priv->phy_type = (char *)prop;
		debug("phy_type %s\n", priv->phy_type);
	}

	return 0;
}

static int ehci_fsl_init_after_reset(struct ehci_ctrl *ctrl)
{
	struct usb_ehci *ehci = NULL;
	struct ehci_fsl_priv *priv = container_of(ctrl, struct ehci_fsl_priv,
						   ehci);

	ehci = (struct usb_ehci *)priv->hcd_base;
	if (ehci_fsl_init(priv, ehci, priv->ehci.hccr, priv->ehci.hcor) < 0)
		return -ENXIO;

	return 0;
}

static const struct ehci_ops fsl_ehci_ops = {
	.init_after_reset = ehci_fsl_init_after_reset,
};

static int ehci_fsl_probe(struct udevice *dev)
{
	struct ehci_fsl_priv *priv = dev_get_priv(dev);
	struct usb_ehci *ehci = NULL;
	struct ehci_hccr *hccr;
	struct ehci_hcor *hcor;

	/*
	 * Get the base address for EHCI controller from the device node
	 */
	priv->hcd_base = dev_get_addr(dev);
	if (priv->hcd_base == FDT_ADDR_T_NONE) {
		debug("Can't get the EHCI register base address\n");
		return -ENXIO;
	}
	ehci = (struct usb_ehci *)priv->hcd_base;
	hccr = (struct ehci_hccr *)(&ehci->caplength);
	hcor = (struct ehci_hcor *)
		((u32)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));

	if (ehci_fsl_init(priv, ehci, hccr, hcor) < 0)
		return -ENXIO;

	debug("ehci-fsl: init hccr %x and hcor %x hc_length %d\n",
	      (u32)hccr, (u32)hcor,
	      (u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));

	return ehci_register(dev, hccr, hcor, &fsl_ehci_ops, 0, USB_INIT_HOST);
}

static const struct udevice_id ehci_usb_ids[] = {
	{ .compatible = "fsl-usb2-mph", },
	{ .compatible = "fsl-usb2-dr", },
	{ }
};

U_BOOT_DRIVER(ehci_fsl) = {
	.name	= "ehci_fsl",
	.id	= UCLASS_USB,
	.of_match = ehci_usb_ids,
	.ofdata_to_platdata = ehci_fsl_ofdata_to_platdata,
	.probe = ehci_fsl_probe,
	.remove = ehci_deregister,
	.ops	= &ehci_usb_ops,
	.platdata_auto_alloc_size = sizeof(struct usb_platdata),
	.priv_auto_alloc_size = sizeof(struct ehci_fsl_priv),
	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
};
#else
/*
 * Create the appropriate control structures to manage
 * a new EHCI host controller.
 *
 * Excerpts from linux ehci fsl driver.
 */
int ehci_hcd_init(int index, enum usb_init_type init,
		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
	struct usb_ehci *ehci = NULL;

	switch (index) {
	case 0:
		ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB1_ADDR;
		break;
	case 1:
		ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB2_ADDR;
		break;
	default:
		printf("ERROR: wrong controller index!!\n");
		return -EINVAL;
	};

	*hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
	*hcor = (struct ehci_hcor *)((uint32_t) *hccr +
			HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));

	return ehci_fsl_init(index, ehci, *hccr, *hcor);
}

/*
 * Destroy the appropriate control structures corresponding
 * the the EHCI host controller.
 */
int ehci_hcd_stop(int index)
{
	return 0;
}
#endif

#ifdef CONFIG_DM_USB
static int ehci_fsl_init(struct ehci_fsl_priv *priv, struct usb_ehci *ehci,
		  struct ehci_hccr *hccr, struct ehci_hcor *hcor)
#else
static int ehci_fsl_init(int index, struct usb_ehci *ehci,
			 struct ehci_hccr *hccr, struct ehci_hcor *hcor)
#endif
{
	const char *phy_type = NULL;
#ifndef CONFIG_DM_USB
	size_t len;
	char current_usb_controller[5];
#endif
#ifdef CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
	char usb_phy[5];

	usb_phy[0] = '\0';
#endif
	if (has_erratum_a007075()) {
		/*
		 * A 5ms delay is needed after applying soft-reset to the
		 * controller to let external ULPI phy come out of reset.
		 * This delay needs to be added before re-initializing
		 * the controller after soft-resetting completes
		 */
		mdelay(5);
	}

	/* Set to Host mode */
	setbits_le32(&ehci->usbmode, CM_HOST);

	out_be32(&ehci->snoop1, SNOOP_SIZE_2GB);
	out_be32(&ehci->snoop2, 0x80000000 | SNOOP_SIZE_2GB);

	/* Init phy */
#ifdef CONFIG_DM_USB
	if (priv->phy_type)
		phy_type = priv->phy_type;
#else
	memset(current_usb_controller, '\0', 5);
	snprintf(current_usb_controller, sizeof(current_usb_controller),
		 "usb%d", index+1);

	if (hwconfig_sub(current_usb_controller, "phy_type"))
		phy_type = hwconfig_subarg(current_usb_controller,
				"phy_type", &len);
#endif
	else
		phy_type = getenv("usb_phy_type");

	if (!phy_type) {
#ifdef CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
		/* if none specified assume internal UTMI */
		strcpy(usb_phy, "utmi");
		phy_type = usb_phy;
#else
		printf("WARNING: USB phy type not defined !!\n");
		return -1;
#endif
	}

	if (!strncmp(phy_type, "utmi", 4)) {
#if defined(CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY)
		clrsetbits_be32(&ehci->control, CONTROL_REGISTER_W1C_MASK,
				PHY_CLK_SEL_UTMI);
		clrsetbits_be32(&ehci->control, CONTROL_REGISTER_W1C_MASK,
				UTMI_PHY_EN);
		udelay(1000); /* delay required for PHY Clk to appear */
#endif
		out_le32(&(hcor)->or_portsc[0], PORT_PTS_UTMI);
		clrsetbits_be32(&ehci->control, CONTROL_REGISTER_W1C_MASK,
				USB_EN);
	} else {
		clrsetbits_be32(&ehci->control, CONTROL_REGISTER_W1C_MASK,
				PHY_CLK_SEL_ULPI);
		clrsetbits_be32(&ehci->control, UTMI_PHY_EN |
				CONTROL_REGISTER_W1C_MASK, USB_EN);
		udelay(1000); /* delay required for PHY Clk to appear */
		if (!usb_phy_clk_valid(ehci))
			return -EINVAL;
		out_le32(&(hcor)->or_portsc[0], PORT_PTS_ULPI);
	}

	out_be32(&ehci->prictrl, 0x0000000c);
	out_be32(&ehci->age_cnt_limit, 0x00000040);
	out_be32(&ehci->sictrl, 0x00000001);

	in_le32(&ehci->usbmode);

	if (has_erratum_a007798())
		set_txfifothresh(ehci, TXFIFOTHRESH);

	if (has_erratum_a004477()) {
		/*
		 * When reset is issued while any ULPI transaction is ongoing
		 * then it may result to corruption of ULPI Function Control
		 * Register which eventually causes phy clock to enter low
		 * power mode which stops the clock. Thus delay is required
		 * before reset to let ongoing ULPI transaction complete.
		 */
		udelay(1);
	}
	return 0;
}

/*
 * Setting the value of TXFIFO_THRESH field in TXFILLTUNING register
 * to counter DDR latencies in writing data into Tx buffer.
 * This prevents Tx buffer from getting underrun
 */
static void set_txfifothresh(struct usb_ehci *ehci, u32 txfifo_thresh)
{
	u32 cmd;
	cmd = ehci_readl(&ehci->txfilltuning);
	cmd &= ~TXFIFO_THRESH_MASK;
	cmd |= TXFIFO_THRESH(txfifo_thresh);
	ehci_writel(&ehci->txfilltuning, cmd);
}
