// SPDX-License-Identifier: GPL-2.0
/*
 * Amlogic G12A USB3 + PCIE Combo PHY driver
 *
 * Copyright (C) 2017 Amlogic, Inc. All rights reserved
 * Copyright (C) 2019 BayLibre, SAS
 * Author: Neil Armstrong <narmstrong@baylibre.com>
 */

#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/platform_device.h>
#include <dt-bindings/phy/phy.h>

#define PHY_R0							0x00
	#define PHY_R0_PCIE_POWER_STATE				GENMASK(4, 0)
	#define PHY_R0_PCIE_USB3_SWITCH				GENMASK(6, 5)

#define PHY_R1							0x04
	#define PHY_R1_PHY_TX1_TERM_OFFSET			GENMASK(4, 0)
	#define PHY_R1_PHY_TX0_TERM_OFFSET			GENMASK(9, 5)
	#define PHY_R1_PHY_RX1_EQ				GENMASK(12, 10)
	#define PHY_R1_PHY_RX0_EQ				GENMASK(15, 13)
	#define PHY_R1_PHY_LOS_LEVEL				GENMASK(20, 16)
	#define PHY_R1_PHY_LOS_BIAS				GENMASK(23, 21)
	#define PHY_R1_PHY_REF_CLKDIV2				BIT(24)
	#define PHY_R1_PHY_MPLL_MULTIPLIER			GENMASK(31, 25)

#define PHY_R2							0x08
	#define PHY_R2_PCS_TX_DEEMPH_GEN2_6DB			GENMASK(5, 0)
	#define PHY_R2_PCS_TX_DEEMPH_GEN2_3P5DB			GENMASK(11, 6)
	#define PHY_R2_PCS_TX_DEEMPH_GEN1			GENMASK(17, 12)
	#define PHY_R2_PHY_TX_VBOOST_LVL			GENMASK(20, 18)

#define PHY_R4							0x10
	#define PHY_R4_PHY_CR_WRITE				BIT(0)
	#define PHY_R4_PHY_CR_READ				BIT(1)
	#define PHY_R4_PHY_CR_DATA_IN				GENMASK(17, 2)
	#define PHY_R4_PHY_CR_CAP_DATA				BIT(18)
	#define PHY_R4_PHY_CR_CAP_ADDR				BIT(19)

#define PHY_R5							0x14
	#define PHY_R5_PHY_CR_DATA_OUT				GENMASK(15, 0)
	#define PHY_R5_PHY_CR_ACK				BIT(16)
	#define PHY_R5_PHY_BS_OUT				BIT(17)

#define PCIE_RESET_DELAY					500

struct phy_g12a_usb3_pcie_priv {
	struct regmap		*regmap;
	struct regmap		*regmap_cr;
	struct clk		*clk_ref;
	struct reset_control	*reset;
	struct phy		*phy;
	unsigned int		mode;
};

static const struct regmap_config phy_g12a_usb3_pcie_regmap_conf = {
	.reg_bits = 8,
	.val_bits = 32,
	.reg_stride = 4,
	.max_register = PHY_R5,
};

static int phy_g12a_usb3_pcie_cr_bus_addr(struct phy_g12a_usb3_pcie_priv *priv,
					  unsigned int addr)
{
	unsigned int val, reg;
	int ret;

	reg = FIELD_PREP(PHY_R4_PHY_CR_DATA_IN, addr);

	regmap_write(priv->regmap, PHY_R4, reg);
	regmap_write(priv->regmap, PHY_R4, reg);

	regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_CAP_ADDR);

	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
				       (val & PHY_R5_PHY_CR_ACK),
				       5, 1000);
	if (ret)
		return ret;

	regmap_write(priv->regmap, PHY_R4, reg);

	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
				       !(val & PHY_R5_PHY_CR_ACK),
				       5, 1000);
	if (ret)
		return ret;

	return 0;
}

static int phy_g12a_usb3_pcie_cr_bus_read(void *context, unsigned int addr,
					  unsigned int *data)
{
	struct phy_g12a_usb3_pcie_priv *priv = context;
	unsigned int val;
	int ret;

	ret = phy_g12a_usb3_pcie_cr_bus_addr(priv, addr);
	if (ret)
		return ret;

	regmap_write(priv->regmap, PHY_R4, 0);
	regmap_write(priv->regmap, PHY_R4, PHY_R4_PHY_CR_READ);

	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
				       (val & PHY_R5_PHY_CR_ACK),
				       5, 1000);
	if (ret)
		return ret;

	*data = FIELD_GET(PHY_R5_PHY_CR_DATA_OUT, val);

	regmap_write(priv->regmap, PHY_R4, 0);

	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
				       !(val & PHY_R5_PHY_CR_ACK),
				       5, 1000);
	if (ret)
		return ret;

	return 0;
}

static int phy_g12a_usb3_pcie_cr_bus_write(void *context, unsigned int addr,
					   unsigned int data)
{
	struct phy_g12a_usb3_pcie_priv *priv = context;
	unsigned int val, reg;
	int ret;

	ret = phy_g12a_usb3_pcie_cr_bus_addr(priv, addr);
	if (ret)
		return ret;

	reg = FIELD_PREP(PHY_R4_PHY_CR_DATA_IN, data);

	regmap_write(priv->regmap, PHY_R4, reg);
	regmap_write(priv->regmap, PHY_R4, reg);

	regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_CAP_DATA);

	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
				       (val & PHY_R5_PHY_CR_ACK),
				       5, 1000);
	if (ret)
		return ret;

	regmap_write(priv->regmap, PHY_R4, reg);

	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
				       (val & PHY_R5_PHY_CR_ACK) == 0,
				       5, 1000);
	if (ret)
		return ret;

	regmap_write(priv->regmap, PHY_R4, reg);

	regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_WRITE);

	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
				       (val & PHY_R5_PHY_CR_ACK),
				       5, 1000);
	if (ret)
		return ret;

	regmap_write(priv->regmap, PHY_R4, reg);

	ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val,
				       (val & PHY_R5_PHY_CR_ACK) == 0,
				       5, 1000);
	if (ret)
		return ret;

	return 0;
}

static const struct regmap_config phy_g12a_usb3_pcie_cr_regmap_conf = {
	.reg_bits = 16,
	.val_bits = 16,
	.reg_read = phy_g12a_usb3_pcie_cr_bus_read,
	.reg_write = phy_g12a_usb3_pcie_cr_bus_write,
	.max_register = 0xffff,
	.disable_locking = true,
};

static int phy_g12a_usb3_init(struct phy *phy)
{
	struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy);
	int data, ret;

	ret = reset_control_reset(priv->reset);
	if (ret)
		return ret;

	/* Switch PHY to USB3 */
	/* TODO figure out how to handle when PCIe was set in the bootloader */
	regmap_update_bits(priv->regmap, PHY_R0,
			   PHY_R0_PCIE_USB3_SWITCH,
			   PHY_R0_PCIE_USB3_SWITCH);

	/*
	 * WORKAROUND: There is SSPHY suspend bug due to
	 * which USB enumerates
	 * in HS mode instead of SS mode. Workaround it by asserting
	 * LANE0.TX_ALT_BLOCK.EN_ALT_BUS to enable TX to use alt bus
	 * mode
	 */
	ret = regmap_update_bits(priv->regmap_cr, 0x102d, BIT(7), BIT(7));
	if (ret)
		return ret;

	ret = regmap_update_bits(priv->regmap_cr, 0x1010, 0xff0, 20);
	if (ret)
		return ret;

	/*
	 * Fix RX Equalization setting as follows
	 * LANE0.RX_OVRD_IN_HI. RX_EQ_EN set to 0
	 * LANE0.RX_OVRD_IN_HI.RX_EQ_EN_OVRD set to 1
	 * LANE0.RX_OVRD_IN_HI.RX_EQ set to 3
	 * LANE0.RX_OVRD_IN_HI.RX_EQ_OVRD set to 1
	 */
	ret = regmap_read(priv->regmap_cr, 0x1006, &data);
	if (ret)
		return ret;

	data &= ~BIT(6);
	data |= BIT(7);
	data &= ~(0x7 << 8);
	data |= (0x3 << 8);
	data |= (1 << 11);
	ret = regmap_write(priv->regmap_cr, 0x1006, data);
	if (ret)
		return ret;

	/*
	 * Set EQ and TX launch amplitudes as follows
	 * LANE0.TX_OVRD_DRV_LO.PREEMPH set to 22
	 * LANE0.TX_OVRD_DRV_LO.AMPLITUDE set to 127
	 * LANE0.TX_OVRD_DRV_LO.EN set to 1.
	 */
	ret = regmap_read(priv->regmap_cr, 0x1002, &data);
	if (ret)
		return ret;

	data &= ~0x3f80;
	data |= (0x16 << 7);
	data &= ~0x7f;
	data |= (0x7f | BIT(14));
	ret = regmap_write(priv->regmap_cr, 0x1002, data);
	if (ret)
		return ret;

	/* MPLL_LOOP_CTL.PROP_CNTRL = 8 */
	ret = regmap_update_bits(priv->regmap_cr, 0x30, 0xf << 4, 8 << 4);
	if (ret)
		return ret;

	regmap_update_bits(priv->regmap, PHY_R2,
			PHY_R2_PHY_TX_VBOOST_LVL,
			FIELD_PREP(PHY_R2_PHY_TX_VBOOST_LVL, 0x4));

	regmap_update_bits(priv->regmap, PHY_R1,
			PHY_R1_PHY_LOS_BIAS | PHY_R1_PHY_LOS_LEVEL,
			FIELD_PREP(PHY_R1_PHY_LOS_BIAS, 4) |
			FIELD_PREP(PHY_R1_PHY_LOS_LEVEL, 9));

	return 0;
}

static int phy_g12a_usb3_pcie_power_on(struct phy *phy)
{
	struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy);

	if (priv->mode == PHY_TYPE_USB3)
		return 0;

	regmap_update_bits(priv->regmap, PHY_R0,
			   PHY_R0_PCIE_POWER_STATE,
			   FIELD_PREP(PHY_R0_PCIE_POWER_STATE, 0x1c));

	return 0;
}

static int phy_g12a_usb3_pcie_power_off(struct phy *phy)
{
	struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy);

	if (priv->mode == PHY_TYPE_USB3)
		return 0;

	regmap_update_bits(priv->regmap, PHY_R0,
			   PHY_R0_PCIE_POWER_STATE,
			   FIELD_PREP(PHY_R0_PCIE_POWER_STATE, 0x1d));

	return 0;
}

static int phy_g12a_usb3_pcie_reset(struct phy *phy)
{
	struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy);
	int ret;

	if (priv->mode == PHY_TYPE_USB3)
		return 0;

	ret = reset_control_assert(priv->reset);
	if (ret)
		return ret;

	udelay(PCIE_RESET_DELAY);

	ret = reset_control_deassert(priv->reset);
	if (ret)
		return ret;

	udelay(PCIE_RESET_DELAY);

	return 0;
}

static int phy_g12a_usb3_pcie_init(struct phy *phy)
{
	struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy);

	if (priv->mode == PHY_TYPE_USB3)
		return phy_g12a_usb3_init(phy);

	return 0;
}

static int phy_g12a_usb3_pcie_exit(struct phy *phy)
{
	struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy);

	if (priv->mode == PHY_TYPE_USB3)
		return reset_control_reset(priv->reset);

	return 0;
}

static struct phy *phy_g12a_usb3_pcie_xlate(struct device *dev,
					    struct of_phandle_args *args)
{
	struct phy_g12a_usb3_pcie_priv *priv = dev_get_drvdata(dev);
	unsigned int mode;

	if (args->args_count < 1) {
		dev_err(dev, "invalid number of arguments\n");
		return ERR_PTR(-EINVAL);
	}

	mode = args->args[0];

	if (mode != PHY_TYPE_USB3 && mode != PHY_TYPE_PCIE) {
		dev_err(dev, "invalid phy mode select argument\n");
		return ERR_PTR(-EINVAL);
	}

	priv->mode = mode;

	return priv->phy;
}

static const struct phy_ops phy_g12a_usb3_pcie_ops = {
	.init		= phy_g12a_usb3_pcie_init,
	.exit		= phy_g12a_usb3_pcie_exit,
	.power_on	= phy_g12a_usb3_pcie_power_on,
	.power_off	= phy_g12a_usb3_pcie_power_off,
	.reset		= phy_g12a_usb3_pcie_reset,
	.owner		= THIS_MODULE,
};

static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct phy_g12a_usb3_pcie_priv *priv;
	struct phy_provider *phy_provider;
	void __iomem *base;

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

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

	priv->regmap = devm_regmap_init_mmio(dev, base,
					     &phy_g12a_usb3_pcie_regmap_conf);
	if (IS_ERR(priv->regmap))
		return PTR_ERR(priv->regmap);

	priv->regmap_cr = devm_regmap_init(dev, NULL, priv,
					   &phy_g12a_usb3_pcie_cr_regmap_conf);
	if (IS_ERR(priv->regmap_cr))
		return PTR_ERR(priv->regmap_cr);

	priv->clk_ref = devm_clk_get_enabled(dev, "ref_clk");
	if (IS_ERR(priv->clk_ref))
		return PTR_ERR(priv->clk_ref);

	priv->reset = devm_reset_control_array_get_exclusive(dev);
	if (IS_ERR(priv->reset))
		return PTR_ERR(priv->reset);

	priv->phy = devm_phy_create(dev, np, &phy_g12a_usb3_pcie_ops);
	if (IS_ERR(priv->phy))
		return dev_err_probe(dev, PTR_ERR(priv->phy), "failed to create PHY\n");

	phy_set_drvdata(priv->phy, priv);
	dev_set_drvdata(dev, priv);

	phy_provider = devm_of_phy_provider_register(dev,
						     phy_g12a_usb3_pcie_xlate);
	return PTR_ERR_OR_ZERO(phy_provider);
}

static const struct of_device_id phy_g12a_usb3_pcie_of_match[] = {
	{ .compatible = "amlogic,g12a-usb3-pcie-phy", },
	{ },
};
MODULE_DEVICE_TABLE(of, phy_g12a_usb3_pcie_of_match);

static struct platform_driver phy_g12a_usb3_pcie_driver = {
	.probe	= phy_g12a_usb3_pcie_probe,
	.driver	= {
		.name		= "phy-g12a-usb3-pcie",
		.of_match_table	= phy_g12a_usb3_pcie_of_match,
	},
};
module_platform_driver(phy_g12a_usb3_pcie_driver);

MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
MODULE_DESCRIPTION("Amlogic G12A USB3 + PCIE Combo PHY driver");
MODULE_LICENSE("GPL v2");
