// SPDX-License-Identifier: GPL-2.0
/*
 * Amlogic AXG MIPI + PCIE analog PHY driver
 *
 * Copyright (C) 2019 Remi Pommarel <repk@triplefau.lt>
 */
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include <linux/delay.h>
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
#include <dt-bindings/phy/phy.h>

#define HHI_MIPI_CNTL0 0x00
#define		HHI_MIPI_CNTL0_COMMON_BLOCK	GENMASK(31, 28)
#define		HHI_MIPI_CNTL0_ENABLE		BIT(29)
#define		HHI_MIPI_CNTL0_BANDGAP		BIT(26)
#define		HHI_MIPI_CNTL0_DIF_REF_CTL1	GENMASK(25, 16)
#define		HHI_MIPI_CNTL0_DIF_REF_CTL0	GENMASK(15, 0)

#define HHI_MIPI_CNTL1 0x04
#define		HHI_MIPI_CNTL1_CH0_CML_PDR_EN	BIT(12)
#define		HHI_MIPI_CNTL1_LP_ABILITY	GENMASK(5, 4)
#define		HHI_MIPI_CNTL1_LP_RESISTER	BIT(3)
#define		HHI_MIPI_CNTL1_INPUT_SETTING	BIT(2)
#define		HHI_MIPI_CNTL1_INPUT_SEL	BIT(1)
#define		HHI_MIPI_CNTL1_PRBS7_EN		BIT(0)

#define HHI_MIPI_CNTL2 0x08
#define		HHI_MIPI_CNTL2_CH_PU		GENMASK(31, 25)
#define		HHI_MIPI_CNTL2_CH_CTL		GENMASK(24, 19)
#define		HHI_MIPI_CNTL2_CH0_DIGDR_EN	BIT(18)
#define		HHI_MIPI_CNTL2_CH_DIGDR_EN	BIT(17)
#define		HHI_MIPI_CNTL2_LPULPS_EN	BIT(16)
#define		HHI_MIPI_CNTL2_CH_EN		GENMASK(15, 11)
#define		HHI_MIPI_CNTL2_CH0_LP_CTL	GENMASK(10, 1)

#define DSI_LANE_0              BIT(4)
#define DSI_LANE_1              BIT(3)
#define DSI_LANE_CLK            BIT(2)
#define DSI_LANE_2              BIT(1)
#define DSI_LANE_3              BIT(0)

struct phy_axg_mipi_pcie_analog_priv {
	struct phy *phy;
	struct regmap *regmap;
	bool dsi_configured;
	bool dsi_enabled;
	bool powered;
	struct phy_configure_opts_mipi_dphy config;
};

static void phy_bandgap_enable(struct phy_axg_mipi_pcie_analog_priv *priv)
{
	regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
			HHI_MIPI_CNTL0_BANDGAP, HHI_MIPI_CNTL0_BANDGAP);

	regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
			HHI_MIPI_CNTL0_ENABLE, HHI_MIPI_CNTL0_ENABLE);
}

static void phy_bandgap_disable(struct phy_axg_mipi_pcie_analog_priv *priv)
{
	regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
			HHI_MIPI_CNTL0_BANDGAP, 0);
	regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
			HHI_MIPI_CNTL0_ENABLE, 0);
}

static void phy_dsi_analog_enable(struct phy_axg_mipi_pcie_analog_priv *priv)
{
	u32 reg;

	regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
			   HHI_MIPI_CNTL0_DIF_REF_CTL1,
			   FIELD_PREP(HHI_MIPI_CNTL0_DIF_REF_CTL1, 0x1b8));
	regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
			   BIT(31), BIT(31));
	regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
			   HHI_MIPI_CNTL0_DIF_REF_CTL0,
			   FIELD_PREP(HHI_MIPI_CNTL0_DIF_REF_CTL0, 0x8));

	regmap_write(priv->regmap, HHI_MIPI_CNTL1, 0x001e);

	regmap_write(priv->regmap, HHI_MIPI_CNTL2,
		     (0x26e0 << 16) | (0x459 << 0));

	reg = DSI_LANE_CLK;
	switch (priv->config.lanes) {
	case 4:
		reg |= DSI_LANE_3;
		fallthrough;
	case 3:
		reg |= DSI_LANE_2;
		fallthrough;
	case 2:
		reg |= DSI_LANE_1;
		fallthrough;
	case 1:
		reg |= DSI_LANE_0;
		break;
	default:
		reg = 0;
	}

	regmap_update_bits(priv->regmap, HHI_MIPI_CNTL2,
			   HHI_MIPI_CNTL2_CH_EN,
			   FIELD_PREP(HHI_MIPI_CNTL2_CH_EN, reg));

	priv->dsi_enabled = true;
}

static void phy_dsi_analog_disable(struct phy_axg_mipi_pcie_analog_priv *priv)
{
	regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
			HHI_MIPI_CNTL0_DIF_REF_CTL1,
			FIELD_PREP(HHI_MIPI_CNTL0_DIF_REF_CTL1, 0));
	regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0, BIT(31), 0);
	regmap_update_bits(priv->regmap, HHI_MIPI_CNTL0,
			HHI_MIPI_CNTL0_DIF_REF_CTL1, 0);

	regmap_write(priv->regmap, HHI_MIPI_CNTL1, 0x6);

	regmap_write(priv->regmap, HHI_MIPI_CNTL2, 0x00200000);

	priv->dsi_enabled = false;
}

static int phy_axg_mipi_pcie_analog_configure(struct phy *phy,
					      union phy_configure_opts *opts)
{
	struct phy_axg_mipi_pcie_analog_priv *priv = phy_get_drvdata(phy);
	int ret;

	ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy);
	if (ret)
		return ret;

	memcpy(&priv->config, opts, sizeof(priv->config));

	priv->dsi_configured = true;

	/* If PHY was already powered on, setup the DSI analog part */
	if (priv->powered) {
		/* If reconfiguring, disable & reconfigure */
		if (priv->dsi_enabled)
			phy_dsi_analog_disable(priv);

		usleep_range(100, 200);

		phy_dsi_analog_enable(priv);
	}

	return 0;
}

static int phy_axg_mipi_pcie_analog_power_on(struct phy *phy)
{
	struct phy_axg_mipi_pcie_analog_priv *priv = phy_get_drvdata(phy);

	phy_bandgap_enable(priv);

	if (priv->dsi_configured)
		phy_dsi_analog_enable(priv);

	priv->powered = true;

	return 0;
}

static int phy_axg_mipi_pcie_analog_power_off(struct phy *phy)
{
	struct phy_axg_mipi_pcie_analog_priv *priv = phy_get_drvdata(phy);

	phy_bandgap_disable(priv);

	if (priv->dsi_enabled)
		phy_dsi_analog_disable(priv);

	priv->powered = false;

	return 0;
}

static const struct phy_ops phy_axg_mipi_pcie_analog_ops = {
	.configure = phy_axg_mipi_pcie_analog_configure,
	.power_on = phy_axg_mipi_pcie_analog_power_on,
	.power_off = phy_axg_mipi_pcie_analog_power_off,
	.owner = THIS_MODULE,
};

static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev)
{
	struct phy_provider *phy;
	struct device *dev = &pdev->dev;
	struct phy_axg_mipi_pcie_analog_priv *priv;
	struct device_node *np = dev->of_node, *parent_np;
	struct regmap *map;
	int ret;

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

	/* Get the hhi system controller node */
	parent_np = of_get_parent(dev->of_node);
	map = syscon_node_to_regmap(parent_np);
	of_node_put(parent_np);
	if (IS_ERR(map)) {
		dev_err(dev,
			"failed to get HHI regmap\n");
		return PTR_ERR(map);
	}

	priv->regmap = map;

	priv->phy = devm_phy_create(dev, np, &phy_axg_mipi_pcie_analog_ops);
	if (IS_ERR(priv->phy)) {
		ret = PTR_ERR(priv->phy);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "failed to create PHY\n");
		return ret;
	}

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

	phy = devm_of_phy_provider_register(dev, of_phy_simple_xlate);

	return PTR_ERR_OR_ZERO(phy);
}

static const struct of_device_id phy_axg_mipi_pcie_analog_of_match[] = {
	{
		.compatible = "amlogic,axg-mipi-pcie-analog-phy",
	},
	{ },
};
MODULE_DEVICE_TABLE(of, phy_axg_mipi_pcie_analog_of_match);

static struct platform_driver phy_axg_mipi_pcie_analog_driver = {
	.probe = phy_axg_mipi_pcie_analog_probe,
	.driver = {
		.name = "phy-axg-mipi-pcie-analog",
		.of_match_table = phy_axg_mipi_pcie_analog_of_match,
	},
};
module_platform_driver(phy_axg_mipi_pcie_analog_driver);

MODULE_AUTHOR("Remi Pommarel <repk@triplefau.lt>");
MODULE_DESCRIPTION("Amlogic AXG MIPI + PCIE analog PHY driver");
MODULE_LICENSE("GPL v2");
