// SPDX-License-Identifier: GPL-2.0
/*
 * Renesas R-Car Gen3 for USB3.0 PHY driver
 *
 * Copyright (C) 2017 Renesas Electronics Corporation
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>

#define USB30_CLKSET0		0x034
#define USB30_CLKSET1		0x036
#define USB30_SSC_SET		0x038
#define USB30_PHY_ENABLE	0x060
#define USB30_VBUS_EN		0x064

/* USB30_CLKSET0 */
#define CLKSET0_PRIVATE			0x05c0
#define CLKSET0_USB30_FSEL_USB_EXTAL	0x0002

/* USB30_CLKSET1 */
#define CLKSET1_USB30_PLL_MULTI_SHIFT		6
#define CLKSET1_USB30_PLL_MULTI_USB_EXTAL	(0x64 << \
						 CLKSET1_USB30_PLL_MULTI_SHIFT)
#define CLKSET1_PHYRESET	BIT(4)	/* 1: reset */
#define CLKSET1_REF_CLKDIV	BIT(3)	/* 1: USB_EXTAL */
#define CLKSET1_PRIVATE_2_1	BIT(1)	/* Write B'01 */
#define CLKSET1_REF_CLK_SEL	BIT(0)	/* 1: USB3S0_CLK_P */

/* USB30_SSC_SET */
#define SSC_SET_SSC_EN		BIT(12)
#define SSC_SET_RANGE_SHIFT	9
#define SSC_SET_RANGE_4980	(0x0 << SSC_SET_RANGE_SHIFT)
#define SSC_SET_RANGE_4492	(0x1 << SSC_SET_RANGE_SHIFT)
#define SSC_SET_RANGE_4003	(0x2 << SSC_SET_RANGE_SHIFT)

/* USB30_PHY_ENABLE */
#define PHY_ENABLE_RESET_EN	BIT(4)

/* USB30_VBUS_EN */
#define VBUS_EN_VBUS_EN		BIT(1)

struct rcar_gen3_usb3 {
	void __iomem *base;
	struct phy *phy;
	u32 ssc_range;
	bool usb3s_clk;
	bool usb_extal;
};

static void write_clkset1_for_usb_extal(struct rcar_gen3_usb3 *r, bool reset)
{
	u16 val = CLKSET1_USB30_PLL_MULTI_USB_EXTAL |
		  CLKSET1_REF_CLKDIV | CLKSET1_PRIVATE_2_1;

	if (reset)
		val |= CLKSET1_PHYRESET;

	writew(val, r->base + USB30_CLKSET1);
}

static void rcar_gen3_phy_usb3_enable_ssc(struct rcar_gen3_usb3 *r)
{
	u16 val = SSC_SET_SSC_EN;

	switch (r->ssc_range) {
	case 4980:
		val |= SSC_SET_RANGE_4980;
		break;
	case 4492:
		val |= SSC_SET_RANGE_4492;
		break;
	case 4003:
		val |= SSC_SET_RANGE_4003;
		break;
	default:
		dev_err(&r->phy->dev, "%s: unsupported range (%x)\n", __func__,
			r->ssc_range);
		return;
	}

	writew(val, r->base + USB30_SSC_SET);
}

static void rcar_gen3_phy_usb3_select_usb_extal(struct rcar_gen3_usb3 *r)
{
	write_clkset1_for_usb_extal(r, false);
	if (r->ssc_range)
		rcar_gen3_phy_usb3_enable_ssc(r);
	writew(CLKSET0_PRIVATE | CLKSET0_USB30_FSEL_USB_EXTAL,
	       r->base + USB30_CLKSET0);
	writew(PHY_ENABLE_RESET_EN, r->base + USB30_PHY_ENABLE);
	write_clkset1_for_usb_extal(r, true);
	usleep_range(10, 20);
	write_clkset1_for_usb_extal(r, false);
}

static int rcar_gen3_phy_usb3_init(struct phy *p)
{
	struct rcar_gen3_usb3 *r = phy_get_drvdata(p);

	dev_vdbg(&r->phy->dev, "%s: enter (%d, %d, %d)\n", __func__,
		 r->usb3s_clk, r->usb_extal, r->ssc_range);

	if (!r->usb3s_clk && r->usb_extal)
		rcar_gen3_phy_usb3_select_usb_extal(r);

	/* Enables VBUS detection anyway */
	writew(VBUS_EN_VBUS_EN, r->base + USB30_VBUS_EN);

	return 0;
}

static const struct phy_ops rcar_gen3_phy_usb3_ops = {
	.init		= rcar_gen3_phy_usb3_init,
	.owner		= THIS_MODULE,
};

static const struct of_device_id rcar_gen3_phy_usb3_match_table[] = {
	{ .compatible = "renesas,rcar-gen3-usb3-phy" },
	{ }
};
MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb3_match_table);

static int rcar_gen3_phy_usb3_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct rcar_gen3_usb3 *r;
	struct phy_provider *provider;
	int ret = 0;
	struct clk *clk;

	if (!dev->of_node) {
		dev_err(dev, "This driver needs device tree\n");
		return -EINVAL;
	}

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

	r->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(r->base))
		return PTR_ERR(r->base);

	clk = devm_clk_get(dev, "usb3s_clk");
	if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
		r->usb3s_clk = !!clk_get_rate(clk);
		clk_disable_unprepare(clk);
	}
	clk = devm_clk_get(dev, "usb_extal");
	if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
		r->usb_extal = !!clk_get_rate(clk);
		clk_disable_unprepare(clk);
	}

	if (!r->usb3s_clk && !r->usb_extal) {
		dev_err(dev, "This driver needs usb3s_clk and/or usb_extal\n");
		ret = -EINVAL;
		goto error;
	}

	/*
	 * devm_phy_create() will call pm_runtime_enable(&phy->dev);
	 * And then, phy-core will manage runtime pm for this device.
	 */
	pm_runtime_enable(dev);

	r->phy = devm_phy_create(dev, NULL, &rcar_gen3_phy_usb3_ops);
	if (IS_ERR(r->phy)) {
		dev_err(dev, "Failed to create USB3 PHY\n");
		ret = PTR_ERR(r->phy);
		goto error;
	}

	of_property_read_u32(dev->of_node, "renesas,ssc-range", &r->ssc_range);

	platform_set_drvdata(pdev, r);
	phy_set_drvdata(r->phy, r);

	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
	if (IS_ERR(provider)) {
		dev_err(dev, "Failed to register PHY provider\n");
		ret = PTR_ERR(provider);
		goto error;
	}

	return 0;

error:
	pm_runtime_disable(dev);

	return ret;
}

static int rcar_gen3_phy_usb3_remove(struct platform_device *pdev)
{
	pm_runtime_disable(&pdev->dev);

	return 0;
};

static struct platform_driver rcar_gen3_phy_usb3_driver = {
	.driver = {
		.name		= "phy_rcar_gen3_usb3",
		.of_match_table	= rcar_gen3_phy_usb3_match_table,
	},
	.probe	= rcar_gen3_phy_usb3_probe,
	.remove = rcar_gen3_phy_usb3_remove,
};
module_platform_driver(rcar_gen3_phy_usb3_driver);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Renesas R-Car Gen3 USB 3.0 PHY");
MODULE_AUTHOR("Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>");
