// SPDX-License-Identifier: GPL-2.0
/*
 * phy-uniphier-pcie.c - PHY driver for UniPhier PCIe controller
 * Copyright 2018, Socionext Inc.
 * Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
 */

#include <linux/bitops.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/iopoll.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/resource.h>

/* PHY */
#define PCL_PHY_CLKCTRL		0x0000
#define PORT_SEL_MASK		GENMASK(11, 9)
#define PORT_SEL_1		FIELD_PREP(PORT_SEL_MASK, 1)

#define PCL_PHY_TEST_I		0x2000
#define PCL_PHY_TEST_O		0x2004
#define TESTI_DAT_MASK		GENMASK(13, 6)
#define TESTI_ADR_MASK		GENMASK(5, 1)
#define TESTI_WR_EN		BIT(0)

#define PCL_PHY_RESET		0x200c
#define PCL_PHY_RESET_N_MNMODE	BIT(8)	/* =1:manual */
#define PCL_PHY_RESET_N		BIT(0)	/* =1:deasssert */

/* SG */
#define SG_USBPCIESEL		0x590
#define SG_USBPCIESEL_PCIE	BIT(0)

#define PCL_PHY_R00		0
#define   RX_EQ_ADJ_EN		BIT(3)		/* enable for EQ adjustment */
#define PCL_PHY_R06		6
#define   RX_EQ_ADJ		GENMASK(5, 0)	/* EQ adjustment value */
#define   RX_EQ_ADJ_VAL		0
#define PCL_PHY_R26		26
#define   VCO_CTRL		GENMASK(7, 4)	/* Tx VCO adjustment value */
#define   VCO_CTRL_INIT_VAL	5

struct uniphier_pciephy_priv {
	void __iomem *base;
	struct device *dev;
	struct clk *clk, *clk_gio;
	struct reset_control *rst, *rst_gio;
	const struct uniphier_pciephy_soc_data *data;
};

struct uniphier_pciephy_soc_data {
	bool is_legacy;
	void (*set_phymode)(struct regmap *regmap);
};

static void uniphier_pciephy_testio_write(struct uniphier_pciephy_priv *priv,
					  u32 data)
{
	/* need to read TESTO twice after accessing TESTI */
	writel(data, priv->base + PCL_PHY_TEST_I);
	readl(priv->base + PCL_PHY_TEST_O);
	readl(priv->base + PCL_PHY_TEST_O);
}

static void uniphier_pciephy_set_param(struct uniphier_pciephy_priv *priv,
				       u32 reg, u32 mask, u32 param)
{
	u32 val;

	/* read previous data */
	val  = FIELD_PREP(TESTI_DAT_MASK, 1);
	val |= FIELD_PREP(TESTI_ADR_MASK, reg);
	uniphier_pciephy_testio_write(priv, val);
	val = readl(priv->base + PCL_PHY_TEST_O);

	/* update value */
	val &= ~FIELD_PREP(TESTI_DAT_MASK, mask);
	val  = FIELD_PREP(TESTI_DAT_MASK, mask & param);
	val |= FIELD_PREP(TESTI_ADR_MASK, reg);
	uniphier_pciephy_testio_write(priv, val);
	uniphier_pciephy_testio_write(priv, val | TESTI_WR_EN);
	uniphier_pciephy_testio_write(priv, val);

	/* read current data as dummy */
	val  = FIELD_PREP(TESTI_DAT_MASK, 1);
	val |= FIELD_PREP(TESTI_ADR_MASK, reg);
	uniphier_pciephy_testio_write(priv, val);
	readl(priv->base + PCL_PHY_TEST_O);
}

static void uniphier_pciephy_assert(struct uniphier_pciephy_priv *priv)
{
	u32 val;

	val = readl(priv->base + PCL_PHY_RESET);
	val &= ~PCL_PHY_RESET_N;
	val |= PCL_PHY_RESET_N_MNMODE;
	writel(val, priv->base + PCL_PHY_RESET);
}

static void uniphier_pciephy_deassert(struct uniphier_pciephy_priv *priv)
{
	u32 val;

	val = readl(priv->base + PCL_PHY_RESET);
	val |= PCL_PHY_RESET_N_MNMODE | PCL_PHY_RESET_N;
	writel(val, priv->base + PCL_PHY_RESET);
}

static int uniphier_pciephy_init(struct phy *phy)
{
	struct uniphier_pciephy_priv *priv = phy_get_drvdata(phy);
	u32 val;
	int ret;

	ret = clk_prepare_enable(priv->clk);
	if (ret)
		return ret;

	ret = clk_prepare_enable(priv->clk_gio);
	if (ret)
		goto out_clk_disable;

	ret = reset_control_deassert(priv->rst);
	if (ret)
		goto out_clk_gio_disable;

	ret = reset_control_deassert(priv->rst_gio);
	if (ret)
		goto out_rst_assert;

	/* support only 1 port */
	val = readl(priv->base + PCL_PHY_CLKCTRL);
	val &= ~PORT_SEL_MASK;
	val |= PORT_SEL_1;
	writel(val, priv->base + PCL_PHY_CLKCTRL);

	/* legacy controller doesn't have phy_reset and parameters */
	if (priv->data->is_legacy)
		return 0;

	uniphier_pciephy_set_param(priv, PCL_PHY_R00,
				   RX_EQ_ADJ_EN, RX_EQ_ADJ_EN);
	uniphier_pciephy_set_param(priv, PCL_PHY_R06, RX_EQ_ADJ,
				   FIELD_PREP(RX_EQ_ADJ, RX_EQ_ADJ_VAL));
	uniphier_pciephy_set_param(priv, PCL_PHY_R26, VCO_CTRL,
				   FIELD_PREP(VCO_CTRL, VCO_CTRL_INIT_VAL));
	usleep_range(1, 10);

	uniphier_pciephy_deassert(priv);
	usleep_range(1, 10);

	return 0;

out_rst_assert:
	reset_control_assert(priv->rst);
out_clk_gio_disable:
	clk_disable_unprepare(priv->clk_gio);
out_clk_disable:
	clk_disable_unprepare(priv->clk);

	return ret;
}

static int uniphier_pciephy_exit(struct phy *phy)
{
	struct uniphier_pciephy_priv *priv = phy_get_drvdata(phy);

	if (!priv->data->is_legacy)
		uniphier_pciephy_assert(priv);
	reset_control_assert(priv->rst_gio);
	reset_control_assert(priv->rst);
	clk_disable_unprepare(priv->clk_gio);
	clk_disable_unprepare(priv->clk);

	return 0;
}

static const struct phy_ops uniphier_pciephy_ops = {
	.init  = uniphier_pciephy_init,
	.exit  = uniphier_pciephy_exit,
	.owner = THIS_MODULE,
};

static int uniphier_pciephy_probe(struct platform_device *pdev)
{
	struct uniphier_pciephy_priv *priv;
	struct phy_provider *phy_provider;
	struct device *dev = &pdev->dev;
	struct regmap *regmap;
	struct phy *phy;

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

	priv->data = of_device_get_match_data(dev);
	if (WARN_ON(!priv->data))
		return -EINVAL;

	priv->dev = dev;

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

	if (priv->data->is_legacy) {
		priv->clk_gio = devm_clk_get(dev, "gio");
		if (IS_ERR(priv->clk_gio))
			return PTR_ERR(priv->clk_gio);

		priv->rst_gio =
			devm_reset_control_get_shared(dev, "gio");
		if (IS_ERR(priv->rst_gio))
			return PTR_ERR(priv->rst_gio);

		priv->clk = devm_clk_get(dev, "link");
		if (IS_ERR(priv->clk))
			return PTR_ERR(priv->clk);

		priv->rst = devm_reset_control_get_shared(dev, "link");
		if (IS_ERR(priv->rst))
			return PTR_ERR(priv->rst);
	} else {
		priv->clk = devm_clk_get(dev, NULL);
		if (IS_ERR(priv->clk))
			return PTR_ERR(priv->clk);

		priv->rst = devm_reset_control_get_shared(dev, NULL);
		if (IS_ERR(priv->rst))
			return PTR_ERR(priv->rst);
	}

	phy = devm_phy_create(dev, dev->of_node, &uniphier_pciephy_ops);
	if (IS_ERR(phy))
		return PTR_ERR(phy);

	regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
						 "socionext,syscon");
	if (!IS_ERR(regmap) && priv->data->set_phymode)
		priv->data->set_phymode(regmap);

	phy_set_drvdata(phy, priv);
	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);

	return PTR_ERR_OR_ZERO(phy_provider);
}

static void uniphier_pciephy_ld20_setmode(struct regmap *regmap)
{
	regmap_update_bits(regmap, SG_USBPCIESEL,
			   SG_USBPCIESEL_PCIE, SG_USBPCIESEL_PCIE);
}

static const struct uniphier_pciephy_soc_data uniphier_pro5_data = {
	.is_legacy = true,
};

static const struct uniphier_pciephy_soc_data uniphier_ld20_data = {
	.is_legacy = false,
	.set_phymode = uniphier_pciephy_ld20_setmode,
};

static const struct uniphier_pciephy_soc_data uniphier_pxs3_data = {
	.is_legacy = false,
};

static const struct of_device_id uniphier_pciephy_match[] = {
	{
		.compatible = "socionext,uniphier-pro5-pcie-phy",
		.data = &uniphier_pro5_data,
	},
	{
		.compatible = "socionext,uniphier-ld20-pcie-phy",
		.data = &uniphier_ld20_data,
	},
	{
		.compatible = "socionext,uniphier-pxs3-pcie-phy",
		.data = &uniphier_pxs3_data,
	},
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, uniphier_pciephy_match);

static struct platform_driver uniphier_pciephy_driver = {
	.probe = uniphier_pciephy_probe,
	.driver = {
		.name = "uniphier-pcie-phy",
		.of_match_table = uniphier_pciephy_match,
	},
};
module_platform_driver(uniphier_pciephy_driver);

MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
MODULE_DESCRIPTION("UniPhier PHY driver for PCIe controller");
MODULE_LICENSE("GPL v2");
