// SPDX-License-Identifier: GPL-2.0
/*
 * dwc3-imx8mp.c - NXP imx8mp Specific Glue layer
 *
 * Copyright (c) 2020 NXP.
 */

#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>

#include "core.h"

/* USB wakeup registers */
#define USB_WAKEUP_CTRL			0x00

/* Global wakeup interrupt enable, also used to clear interrupt */
#define USB_WAKEUP_EN			BIT(31)
/* Wakeup from connect or disconnect, only for superspeed */
#define USB_WAKEUP_SS_CONN		BIT(5)
/* 0 select vbus_valid, 1 select sessvld */
#define USB_WAKEUP_VBUS_SRC_SESS_VAL	BIT(4)
/* Enable signal for wake up from u3 state */
#define USB_WAKEUP_U3_EN		BIT(3)
/* Enable signal for wake up from id change */
#define USB_WAKEUP_ID_EN		BIT(2)
/* Enable signal for wake up from vbus change */
#define	USB_WAKEUP_VBUS_EN		BIT(1)
/* Enable signal for wake up from dp/dm change */
#define USB_WAKEUP_DPDM_EN		BIT(0)

#define USB_WAKEUP_EN_MASK		GENMASK(5, 0)

/* USB glue registers */
#define USB_CTRL0		0x00
#define USB_CTRL1		0x04

#define USB_CTRL0_PORTPWR_EN	BIT(12) /* 1 - PPC enabled (default) */
#define USB_CTRL0_USB3_FIXED	BIT(22) /* 1 - USB3 permanent attached */
#define USB_CTRL0_USB2_FIXED	BIT(23) /* 1 - USB2 permanent attached */

#define USB_CTRL1_OC_POLARITY	BIT(16) /* 0 - HIGH / 1 - LOW */
#define USB_CTRL1_PWR_POLARITY	BIT(17) /* 0 - HIGH / 1 - LOW */

struct dwc3_imx8mp {
	struct device			*dev;
	struct platform_device		*dwc3;
	void __iomem			*hsio_blk_base;
	void __iomem			*glue_base;
	struct clk			*hsio_clk;
	struct clk			*suspend_clk;
	int				irq;
	bool				pm_suspended;
	bool				wakeup_pending;
};

static void imx8mp_configure_glue(struct dwc3_imx8mp *dwc3_imx)
{
	struct device *dev = dwc3_imx->dev;
	u32 value;

	if (!dwc3_imx->glue_base)
		return;

	value = readl(dwc3_imx->glue_base + USB_CTRL0);

	if (device_property_read_bool(dev, "fsl,permanently-attached"))
		value |= (USB_CTRL0_USB2_FIXED | USB_CTRL0_USB3_FIXED);
	else
		value &= ~(USB_CTRL0_USB2_FIXED | USB_CTRL0_USB3_FIXED);

	if (device_property_read_bool(dev, "fsl,disable-port-power-control"))
		value &= ~(USB_CTRL0_PORTPWR_EN);
	else
		value |= USB_CTRL0_PORTPWR_EN;

	writel(value, dwc3_imx->glue_base + USB_CTRL0);

	value = readl(dwc3_imx->glue_base + USB_CTRL1);
	if (device_property_read_bool(dev, "fsl,over-current-active-low"))
		value |= USB_CTRL1_OC_POLARITY;
	else
		value &= ~USB_CTRL1_OC_POLARITY;

	if (device_property_read_bool(dev, "fsl,power-active-low"))
		value |= USB_CTRL1_PWR_POLARITY;
	else
		value &= ~USB_CTRL1_PWR_POLARITY;

	writel(value, dwc3_imx->glue_base + USB_CTRL1);
}

static void dwc3_imx8mp_wakeup_enable(struct dwc3_imx8mp *dwc3_imx)
{
	struct dwc3	*dwc3 = platform_get_drvdata(dwc3_imx->dwc3);
	u32		val;

	if (!dwc3)
		return;

	val = readl(dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);

	if ((dwc3->current_dr_role == DWC3_GCTL_PRTCAP_HOST) && dwc3->xhci)
		val |= USB_WAKEUP_EN | USB_WAKEUP_SS_CONN |
		       USB_WAKEUP_U3_EN | USB_WAKEUP_DPDM_EN;
	else if (dwc3->current_dr_role == DWC3_GCTL_PRTCAP_DEVICE)
		val |= USB_WAKEUP_EN | USB_WAKEUP_VBUS_EN |
		       USB_WAKEUP_VBUS_SRC_SESS_VAL;

	writel(val, dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);
}

static void dwc3_imx8mp_wakeup_disable(struct dwc3_imx8mp *dwc3_imx)
{
	u32 val;

	val = readl(dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);
	val &= ~(USB_WAKEUP_EN | USB_WAKEUP_EN_MASK);
	writel(val, dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);
}

static irqreturn_t dwc3_imx8mp_interrupt(int irq, void *_dwc3_imx)
{
	struct dwc3_imx8mp	*dwc3_imx = _dwc3_imx;
	struct dwc3		*dwc = platform_get_drvdata(dwc3_imx->dwc3);

	if (!dwc3_imx->pm_suspended)
		return IRQ_HANDLED;

	disable_irq_nosync(dwc3_imx->irq);
	dwc3_imx->wakeup_pending = true;

	if ((dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) && dwc->xhci)
		pm_runtime_resume(&dwc->xhci->dev);
	else if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_DEVICE)
		pm_runtime_get(dwc->dev);

	return IRQ_HANDLED;
}

static int dwc3_imx8mp_probe(struct platform_device *pdev)
{
	struct device		*dev = &pdev->dev;
	struct device_node	*dwc3_np, *node = dev->of_node;
	struct dwc3_imx8mp	*dwc3_imx;
	struct resource		*res;
	int			err, irq;

	if (!node) {
		dev_err(dev, "device node not found\n");
		return -EINVAL;
	}

	dwc3_imx = devm_kzalloc(dev, sizeof(*dwc3_imx), GFP_KERNEL);
	if (!dwc3_imx)
		return -ENOMEM;

	platform_set_drvdata(pdev, dwc3_imx);

	dwc3_imx->dev = dev;

	dwc3_imx->hsio_blk_base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(dwc3_imx->hsio_blk_base))
		return PTR_ERR(dwc3_imx->hsio_blk_base);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!res) {
		dev_warn(dev, "Base address for glue layer missing. Continuing without, some features are missing though.");
	} else {
		dwc3_imx->glue_base = devm_ioremap_resource(dev, res);
		if (IS_ERR(dwc3_imx->glue_base))
			return PTR_ERR(dwc3_imx->glue_base);
	}

	dwc3_imx->hsio_clk = devm_clk_get(dev, "hsio");
	if (IS_ERR(dwc3_imx->hsio_clk)) {
		err = PTR_ERR(dwc3_imx->hsio_clk);
		dev_err(dev, "Failed to get hsio clk, err=%d\n", err);
		return err;
	}

	err = clk_prepare_enable(dwc3_imx->hsio_clk);
	if (err) {
		dev_err(dev, "Failed to enable hsio clk, err=%d\n", err);
		return err;
	}

	dwc3_imx->suspend_clk = devm_clk_get(dev, "suspend");
	if (IS_ERR(dwc3_imx->suspend_clk)) {
		err = PTR_ERR(dwc3_imx->suspend_clk);
		dev_err(dev, "Failed to get suspend clk, err=%d\n", err);
		goto disable_hsio_clk;
	}

	err = clk_prepare_enable(dwc3_imx->suspend_clk);
	if (err) {
		dev_err(dev, "Failed to enable suspend clk, err=%d\n", err);
		goto disable_hsio_clk;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		err = irq;
		goto disable_clks;
	}
	dwc3_imx->irq = irq;

	imx8mp_configure_glue(dwc3_imx);

	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);
	err = pm_runtime_get_sync(dev);
	if (err < 0)
		goto disable_rpm;

	dwc3_np = of_get_compatible_child(node, "snps,dwc3");
	if (!dwc3_np) {
		err = -ENODEV;
		dev_err(dev, "failed to find dwc3 core child\n");
		goto disable_rpm;
	}

	err = of_platform_populate(node, NULL, NULL, dev);
	if (err) {
		dev_err(&pdev->dev, "failed to create dwc3 core\n");
		goto err_node_put;
	}

	dwc3_imx->dwc3 = of_find_device_by_node(dwc3_np);
	if (!dwc3_imx->dwc3) {
		dev_err(dev, "failed to get dwc3 platform device\n");
		err = -ENODEV;
		goto depopulate;
	}
	of_node_put(dwc3_np);

	err = devm_request_threaded_irq(dev, irq, NULL, dwc3_imx8mp_interrupt,
					IRQF_ONESHOT, dev_name(dev), dwc3_imx);
	if (err) {
		dev_err(dev, "failed to request IRQ #%d --> %d\n", irq, err);
		goto depopulate;
	}

	device_set_wakeup_capable(dev, true);
	pm_runtime_put(dev);

	return 0;

depopulate:
	of_platform_depopulate(dev);
err_node_put:
	of_node_put(dwc3_np);
disable_rpm:
	pm_runtime_disable(dev);
	pm_runtime_put_noidle(dev);
disable_clks:
	clk_disable_unprepare(dwc3_imx->suspend_clk);
disable_hsio_clk:
	clk_disable_unprepare(dwc3_imx->hsio_clk);

	return err;
}

static void dwc3_imx8mp_remove(struct platform_device *pdev)
{
	struct dwc3_imx8mp *dwc3_imx = platform_get_drvdata(pdev);
	struct device *dev = &pdev->dev;

	pm_runtime_get_sync(dev);
	of_platform_depopulate(dev);

	clk_disable_unprepare(dwc3_imx->suspend_clk);
	clk_disable_unprepare(dwc3_imx->hsio_clk);

	pm_runtime_disable(dev);
	pm_runtime_put_noidle(dev);
	platform_set_drvdata(pdev, NULL);
}

static int __maybe_unused dwc3_imx8mp_suspend(struct dwc3_imx8mp *dwc3_imx,
					      pm_message_t msg)
{
	if (dwc3_imx->pm_suspended)
		return 0;

	/* Wakeup enable */
	if (PMSG_IS_AUTO(msg) || device_may_wakeup(dwc3_imx->dev))
		dwc3_imx8mp_wakeup_enable(dwc3_imx);

	dwc3_imx->pm_suspended = true;

	return 0;
}

static int __maybe_unused dwc3_imx8mp_resume(struct dwc3_imx8mp *dwc3_imx,
					     pm_message_t msg)
{
	struct dwc3	*dwc = platform_get_drvdata(dwc3_imx->dwc3);
	int ret = 0;

	if (!dwc3_imx->pm_suspended)
		return 0;

	/* Wakeup disable */
	dwc3_imx8mp_wakeup_disable(dwc3_imx);
	dwc3_imx->pm_suspended = false;

	/* Upon power loss any previous configuration is lost, restore it */
	imx8mp_configure_glue(dwc3_imx);

	if (dwc3_imx->wakeup_pending) {
		dwc3_imx->wakeup_pending = false;
		if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_DEVICE) {
			pm_runtime_mark_last_busy(dwc->dev);
			pm_runtime_put_autosuspend(dwc->dev);
		} else {
			/*
			 * Add wait for xhci switch from suspend
			 * clock to normal clock to detect connection.
			 */
			usleep_range(9000, 10000);
		}
		enable_irq(dwc3_imx->irq);
	}

	return ret;
}

static int __maybe_unused dwc3_imx8mp_pm_suspend(struct device *dev)
{
	struct dwc3_imx8mp *dwc3_imx = dev_get_drvdata(dev);
	int ret;

	ret = dwc3_imx8mp_suspend(dwc3_imx, PMSG_SUSPEND);

	if (device_may_wakeup(dwc3_imx->dev))
		enable_irq_wake(dwc3_imx->irq);
	else
		clk_disable_unprepare(dwc3_imx->suspend_clk);

	clk_disable_unprepare(dwc3_imx->hsio_clk);
	dev_dbg(dev, "dwc3 imx8mp pm suspend.\n");

	return ret;
}

static int __maybe_unused dwc3_imx8mp_pm_resume(struct device *dev)
{
	struct dwc3_imx8mp *dwc3_imx = dev_get_drvdata(dev);
	int ret;

	if (device_may_wakeup(dwc3_imx->dev)) {
		disable_irq_wake(dwc3_imx->irq);
	} else {
		ret = clk_prepare_enable(dwc3_imx->suspend_clk);
		if (ret)
			return ret;
	}

	ret = clk_prepare_enable(dwc3_imx->hsio_clk);
	if (ret)
		return ret;

	ret = dwc3_imx8mp_resume(dwc3_imx, PMSG_RESUME);

	pm_runtime_disable(dev);
	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);

	dev_dbg(dev, "dwc3 imx8mp pm resume.\n");

	return ret;
}

static int __maybe_unused dwc3_imx8mp_runtime_suspend(struct device *dev)
{
	struct dwc3_imx8mp *dwc3_imx = dev_get_drvdata(dev);

	dev_dbg(dev, "dwc3 imx8mp runtime suspend.\n");

	return dwc3_imx8mp_suspend(dwc3_imx, PMSG_AUTO_SUSPEND);
}

static int __maybe_unused dwc3_imx8mp_runtime_resume(struct device *dev)
{
	struct dwc3_imx8mp *dwc3_imx = dev_get_drvdata(dev);

	dev_dbg(dev, "dwc3 imx8mp runtime resume.\n");

	return dwc3_imx8mp_resume(dwc3_imx, PMSG_AUTO_RESUME);
}

static const struct dev_pm_ops dwc3_imx8mp_dev_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(dwc3_imx8mp_pm_suspend, dwc3_imx8mp_pm_resume)
	SET_RUNTIME_PM_OPS(dwc3_imx8mp_runtime_suspend,
			   dwc3_imx8mp_runtime_resume, NULL)
};

static const struct of_device_id dwc3_imx8mp_of_match[] = {
	{ .compatible = "fsl,imx8mp-dwc3", },
	{},
};
MODULE_DEVICE_TABLE(of, dwc3_imx8mp_of_match);

static struct platform_driver dwc3_imx8mp_driver = {
	.probe		= dwc3_imx8mp_probe,
	.remove_new	= dwc3_imx8mp_remove,
	.driver		= {
		.name	= "imx8mp-dwc3",
		.pm	= &dwc3_imx8mp_dev_pm_ops,
		.of_match_table	= dwc3_imx8mp_of_match,
	},
};

module_platform_driver(dwc3_imx8mp_driver);

MODULE_ALIAS("platform:imx8mp-dwc3");
MODULE_AUTHOR("jun.li@nxp.com");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("DesignWare USB3 imx8mp Glue Layer");
