/*
 * host.c - Cadence USB3 host controller driver
 *
 * Copyright 2017 NXP
 * Authors: Peter Chen <peter.chen@nxp.com>
 *
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/pm_runtime.h>
#include <linux/usb/of.h>

#include "../host/xhci.h"

#include "core.h"
#include "host-export.h"
#include "cdns3-nxp-reg-def.h"

static struct hc_driver __read_mostly xhci_cdns3_hc_driver;

static void xhci_cdns3_quirks(struct device *dev, struct xhci_hcd *xhci)
{
	/*
	 * As of now platform drivers don't provide MSI support so we ensure
	 * here that the generic code does not try to make a pci_dev from our
	 * dev struct in order to setup MSI
	 */
	xhci->quirks |= (XHCI_PLAT | XHCI_CDNS_HOST);
}

static int xhci_cdns3_setup(struct usb_hcd *hcd)
{
	int ret;
	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
	u32 command;

	ret = xhci_gen_setup(hcd, xhci_cdns3_quirks);
	if (ret)
		return ret;
	/* set usbcmd.EU3S */
	command = readl(&xhci->op_regs->command);
	command |= CMD_PM_INDEX;
	writel(command, &xhci->op_regs->command);

	return 0;
}

struct cdns3_host {
	struct device dev;
	struct usb_hcd *hcd;
	struct cdns3 *cdns;
};

static int xhci_cdns3_bus_suspend(struct usb_hcd *hcd)
{
	struct device *dev = hcd->self.controller;
	struct cdns3_host *host = container_of(dev, struct cdns3_host, dev);
	struct cdns3 *cdns = host->cdns;
	void __iomem *xhci_regs = cdns->xhci_regs;
	u32 value;
	int ret;

	ret = xhci_bus_suspend(hcd);
	if (ret)
		return ret;

	value = readl(xhci_regs + XECP_AUX_CTRL_REG1);
	value |= CFG_RXDET_P3_EN;
	writel(value, xhci_regs + XECP_AUX_CTRL_REG1);

	return 0;
}

static const struct xhci_driver_overrides xhci_cdns3_overrides __initconst = {
	.extra_priv_size = sizeof(struct xhci_hcd),
	.reset = xhci_cdns3_setup,
	.bus_suspend = xhci_cdns3_bus_suspend,
};

static irqreturn_t cdns3_host_irq(struct cdns3 *cdns)
{
	struct device *dev = cdns->host_dev;
	struct usb_hcd	*hcd;

	if (dev)
		hcd = dev_get_drvdata(dev);
	else
		return IRQ_NONE;

	if (hcd)
		return usb_hcd_irq(cdns->irq, hcd);
	else
		return IRQ_NONE;
}

static void cdns3_host_release(struct device *dev)
{
	struct cdns3_host *host = container_of(dev, struct cdns3_host, dev);

	dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
	kfree(host);
}

static int cdns3_host_start(struct cdns3 *cdns)
{
	struct cdns3_host *host;
	struct device *dev;
	struct device *sysdev;
	struct xhci_hcd	*xhci;
	int ret;

	host = kzalloc(sizeof(*host), GFP_KERNEL);
	if (!host)
		return -ENOMEM;

	dev = &host->dev;
	dev->release = cdns3_host_release;
	dev->parent = cdns->dev;
	dev_set_name(dev, "xhci-cdns3");
	cdns->host_dev = dev;
	host->cdns = cdns;
	ret = device_register(dev);
	if (ret)
		goto err1;

	sysdev = cdns->dev;
	/* Try to set 64-bit DMA first */
	if (WARN_ON(!sysdev->dma_mask))
		/* Platform did not initialize dma_mask */
		ret = dma_coerce_mask_and_coherent(sysdev,
						   DMA_BIT_MASK(64));
	else
		ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(64));

	/* If setting 64-bit DMA mask fails, fall back to 32-bit DMA mask */
	if (ret) {
		ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(32));
		if (ret)
			return ret;
	}
	pm_runtime_set_active(dev);
	pm_runtime_no_callbacks(dev);
	pm_runtime_enable(dev);

	host->hcd = __usb_create_hcd(&xhci_cdns3_hc_driver, sysdev, dev,
			       dev_name(dev), NULL);
	if (!host->hcd) {
		ret = -ENOMEM;
		goto err2;
	}

	host->hcd->regs = cdns->xhci_regs;
	host->hcd->rsrc_start = cdns->xhci_res->start;
	host->hcd->rsrc_len = resource_size(cdns->xhci_res);

	device_wakeup_enable(host->hcd->self.controller);

	xhci = hcd_to_xhci(host->hcd);

	xhci->quirks = XHCI_SKIP_ACCESS_RESERVED_REG;
	xhci->main_hcd = host->hcd;
	xhci->shared_hcd = __usb_create_hcd(&xhci_cdns3_hc_driver, sysdev, dev,
			dev_name(dev), host->hcd);
	if (!xhci->shared_hcd) {
		ret = -ENOMEM;
		goto err3;
	}
	host->hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node);
	xhci->shared_hcd->tpl_support = host->hcd->tpl_support;

	ret = usb_add_hcd(host->hcd, 0, IRQF_SHARED);
	if (ret)
		goto err4;

	ret = usb_add_hcd(xhci->shared_hcd, 0, IRQF_SHARED);
	if (ret)
		goto err5;

	device_set_wakeup_capable(dev, true);
	dev_dbg(dev, "%s ends\n", __func__);

	return 0;

err5:
	usb_remove_hcd(host->hcd);
err4:
	usb_put_hcd(xhci->shared_hcd);
err3:
	usb_put_hcd(host->hcd);
err2:
	device_del(dev);
err1:
	put_device(dev);
	cdns->host_dev = NULL;
	return ret;
}

static void cdns3_host_stop(struct cdns3 *cdns)
{
	struct device *dev = cdns->host_dev;
	struct usb_hcd	*hcd, *shared_hcd;
	struct xhci_hcd	*xhci;

	if (dev) {
		hcd = dev_get_drvdata(dev);
		xhci = hcd_to_xhci(hcd);
		shared_hcd = xhci->shared_hcd;
		xhci->xhc_state |= XHCI_STATE_REMOVING;
		usb_remove_hcd(shared_hcd);
		xhci->shared_hcd = NULL;
		usb_remove_hcd(hcd);
		synchronize_irq(cdns->irq);
		usb_put_hcd(shared_hcd);
		usb_put_hcd(hcd);
		cdns->host_dev = NULL;
		pm_runtime_set_suspended(dev);
		pm_runtime_disable(dev);
		device_del(dev);
		put_device(dev);
	}
}

static int cdns3_host_suspend(struct cdns3 *cdns, bool do_wakeup)
{
	struct device *dev = cdns->host_dev;
	struct xhci_hcd	*xhci;

	if (!dev)
		return 0;

	xhci = hcd_to_xhci(dev_get_drvdata(dev));
	return xhci_suspend(xhci, do_wakeup);
}

static int cdns3_host_resume(struct cdns3 *cdns, bool hibernated)
{
	struct device *dev = cdns->host_dev;
	struct xhci_hcd	*xhci;

	if (!dev)
		return 0;

	xhci = hcd_to_xhci(dev_get_drvdata(dev));
	return xhci_resume(xhci, hibernated);
}

int cdns3_host_init(struct cdns3 *cdns)
{
	struct cdns3_role_driver *rdrv;

	rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL);
	if (!rdrv)
		return -ENOMEM;

	rdrv->start	= cdns3_host_start;
	rdrv->stop	= cdns3_host_stop;
	rdrv->irq	= cdns3_host_irq;
	rdrv->suspend	= cdns3_host_suspend;
	rdrv->resume	= cdns3_host_resume;
	rdrv->name	= "host";
	cdns->roles[CDNS3_ROLE_HOST] = rdrv;

	return 0;
}

void cdns3_host_remove(struct cdns3 *cdns)
{
	cdns3_host_stop(cdns);
}

void __init cdns3_host_driver_init(void)
{
	xhci_init_driver(&xhci_cdns3_hc_driver, &xhci_cdns3_overrides);
}
