// SPDX-License-Identifier: GPL-2.0
/*
 * Nuvoton NPCM7xx driver for EHCI HCD
 *
 * Copyright (C) 2018 Nuvoton Technologies,
 * Avi Fishman <avi.fishman@nuvoton.com> <avifishman70@gmail.com>
 * Tomer Maimon <tomer.maimon@nuvoton.com> <tmaimon77@gmail.com>
 *
 * Based on various ehci-spear.c driver
 */


#include <linux/dma-mapping.h>

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>

#include "ehci.h"

#include <linux/regmap.h>
#include <linux/mfd/syscon.h>

#define DRIVER_DESC "EHCI npcm7xx driver"

static const char hcd_name[] = "npcm7xx-ehci";

#define  USB2PHYCTL_OFFSET 0x144

#define  IPSRST2_OFFSET 0x24
#define  IPSRST3_OFFSET 0x34


static struct hc_driver __read_mostly ehci_npcm7xx_hc_driver;

static int __maybe_unused ehci_npcm7xx_drv_suspend(struct device *dev)
{
	struct usb_hcd *hcd = dev_get_drvdata(dev);
	bool do_wakeup = device_may_wakeup(dev);

	return ehci_suspend(hcd, do_wakeup);
}

static int __maybe_unused ehci_npcm7xx_drv_resume(struct device *dev)
{
	struct usb_hcd *hcd = dev_get_drvdata(dev);

	ehci_resume(hcd, false);
	return 0;
}

static SIMPLE_DEV_PM_OPS(ehci_npcm7xx_pm_ops, ehci_npcm7xx_drv_suspend,
		ehci_npcm7xx_drv_resume);

static int npcm7xx_ehci_hcd_drv_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct resource *res;
	struct regmap *gcr_regmap;
	struct regmap *rst_regmap;
	const struct hc_driver *driver = &ehci_npcm7xx_hc_driver;
	int irq;
	int retval;

	dev_dbg(&pdev->dev,	"initializing npcm7xx ehci USB Controller\n");

	gcr_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
	if (IS_ERR(gcr_regmap)) {
		dev_err(&pdev->dev, "%s: failed to find nuvoton,npcm750-gcr\n",
			__func__);
		return PTR_ERR(gcr_regmap);
	}

	rst_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-rst");
	if (IS_ERR(rst_regmap)) {
		dev_err(&pdev->dev, "%s: failed to find nuvoton,npcm750-rst\n",
			__func__);
		return PTR_ERR(rst_regmap);
	}

	/********* phy init  ******/
	// reset usb host
	regmap_update_bits(rst_regmap, IPSRST2_OFFSET,
			(0x1 << 26), (0x1 << 26));
	regmap_update_bits(rst_regmap, IPSRST3_OFFSET,
			(0x1 << 25), (0x1 << 25));
	regmap_update_bits(gcr_regmap, USB2PHYCTL_OFFSET,
			(0x1 << 28), 0);

	udelay(1);

	// enable phy
	regmap_update_bits(rst_regmap, IPSRST3_OFFSET,
			(0x1 << 25), 0);

	udelay(50); // enable phy

	regmap_update_bits(gcr_regmap, USB2PHYCTL_OFFSET,
			(0x1 << 28), (0x1 << 28));

	// enable host
	regmap_update_bits(rst_regmap, IPSRST2_OFFSET,
			(0x1 << 26), 0);

	if (usb_disabled())
		return -ENODEV;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		retval = irq;
		goto fail;
	}

	/*
	 * Right now device-tree probed devices don't get dma_mask set.
	 * Since shared usb code relies on it, set it here for now.
	 * Once we have dma capability bindings this can go away.
	 */
	retval = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
	if (retval)
		goto fail;

	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
	if (!hcd) {
		retval = -ENOMEM;
		goto fail;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	hcd->regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(hcd->regs)) {
		retval = PTR_ERR(hcd->regs);
		goto err_put_hcd;
	}
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);

	/* registers start at offset 0x0 */
	hcd_to_ehci(hcd)->caps = hcd->regs;

	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (retval)
		goto err_put_hcd;

	device_wakeup_enable(hcd->self.controller);
	return retval;

err_put_hcd:
	usb_put_hcd(hcd);
fail:
	dev_err(&pdev->dev, "init fail, %d\n", retval);

	return retval;
}

static int npcm7xx_ehci_hcd_drv_remove(struct platform_device *pdev)
{
	struct usb_hcd *hcd = platform_get_drvdata(pdev);

	usb_remove_hcd(hcd);

	usb_put_hcd(hcd);

	return 0;
}

static const struct of_device_id npcm7xx_ehci_id_table[] = {
	{ .compatible = "nuvoton,npcm750-ehci" },
	{ },
};
MODULE_DEVICE_TABLE(of, npcm7xx_ehci_id_table);

static struct platform_driver npcm7xx_ehci_hcd_driver = {
	.probe		= npcm7xx_ehci_hcd_drv_probe,
	.remove		= npcm7xx_ehci_hcd_drv_remove,
	.shutdown	= usb_hcd_platform_shutdown,
	.driver		= {
		.name = "npcm7xx-ehci",
		.bus = &platform_bus_type,
		.pm = pm_ptr(&ehci_npcm7xx_pm_ops),
		.of_match_table = npcm7xx_ehci_id_table,
	}
};

static int __init ehci_npcm7xx_init(void)
{
	if (usb_disabled())
		return -ENODEV;

	pr_info("%s: " DRIVER_DESC "\n", hcd_name);

	ehci_init_driver(&ehci_npcm7xx_hc_driver, NULL);
	return platform_driver_register(&npcm7xx_ehci_hcd_driver);
}
module_init(ehci_npcm7xx_init);

static void __exit ehci_npcm7xx_cleanup(void)
{
	platform_driver_unregister(&npcm7xx_ehci_hcd_driver);
}
module_exit(ehci_npcm7xx_cleanup);

MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_ALIAS("platform:npcm7xx-ehci");
MODULE_AUTHOR("Avi Fishman");
MODULE_LICENSE("GPL v2");
