// SPDX-License-Identifier: GPL-2.0-only
/*
 * Samsung SATA SerDes(PHY) driver
 *
 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
 * Authors: Girish K S <ks.giri@samsung.com>
 *         Yuvaraj Kumar C D <yuvaraj.cd@samsung.com>
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/spinlock.h>
#include <linux/mfd/syscon.h>

#define SATAPHY_CONTROL_OFFSET		0x0724
#define EXYNOS5_SATAPHY_PMU_ENABLE	BIT(0)
#define EXYNOS5_SATA_RESET		0x4
#define RESET_GLOBAL_RST_N		BIT(0)
#define RESET_CMN_RST_N			BIT(1)
#define RESET_CMN_BLOCK_RST_N		BIT(2)
#define RESET_CMN_I2C_RST_N		BIT(3)
#define RESET_TX_RX_PIPE_RST_N		BIT(4)
#define RESET_TX_RX_BLOCK_RST_N		BIT(5)
#define RESET_TX_RX_I2C_RST_N		(BIT(6) | BIT(7))
#define LINK_RESET			0xf0000
#define EXYNOS5_SATA_MODE0		0x10
#define SATA_SPD_GEN3			BIT(1)
#define EXYNOS5_SATA_CTRL0		0x14
#define CTRL0_P0_PHY_CALIBRATED_SEL	BIT(9)
#define CTRL0_P0_PHY_CALIBRATED		BIT(8)
#define EXYNOS5_SATA_PHSATA_CTRLM	0xe0
#define PHCTRLM_REF_RATE		BIT(1)
#define PHCTRLM_HIGH_SPEED		BIT(0)
#define EXYNOS5_SATA_PHSATA_STATM	0xf0
#define PHSTATM_PLL_LOCKED		BIT(0)

#define PHY_PLL_TIMEOUT (usecs_to_jiffies(1000))

struct exynos_sata_phy {
	struct phy *phy;
	struct clk *phyclk;
	void __iomem *regs;
	struct regmap *pmureg;
	struct i2c_client *client;
};

static int wait_for_reg_status(void __iomem *base, u32 reg, u32 checkbit,
				u32 status)
{
	unsigned long timeout = jiffies + PHY_PLL_TIMEOUT;

	while (time_before(jiffies, timeout)) {
		if ((readl(base + reg) & checkbit) == status)
			return 0;
	}

	return -EFAULT;
}

static int exynos_sata_phy_power_on(struct phy *phy)
{
	struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy);

	return regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET,
			EXYNOS5_SATAPHY_PMU_ENABLE, true);

}

static int exynos_sata_phy_power_off(struct phy *phy)
{
	struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy);

	return regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET,
			EXYNOS5_SATAPHY_PMU_ENABLE, false);

}

static int exynos_sata_phy_init(struct phy *phy)
{
	u32 val = 0;
	int ret = 0;
	u8 buf[] = { 0x3a, 0x0b };
	struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy);

	ret = regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET,
			EXYNOS5_SATAPHY_PMU_ENABLE, true);
	if (ret != 0)
		dev_err(&sata_phy->phy->dev, "phy init failed\n");

	writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);

	val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
	val |= RESET_GLOBAL_RST_N | RESET_CMN_RST_N | RESET_CMN_BLOCK_RST_N
		| RESET_CMN_I2C_RST_N | RESET_TX_RX_PIPE_RST_N
		| RESET_TX_RX_BLOCK_RST_N | RESET_TX_RX_I2C_RST_N;
	writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);

	val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
	val |= LINK_RESET;
	writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);

	val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
	val |= RESET_CMN_RST_N;
	writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);

	val = readl(sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
	val &= ~PHCTRLM_REF_RATE;
	writel(val, sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);

	/* High speed enable for Gen3 */
	val = readl(sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
	val |= PHCTRLM_HIGH_SPEED;
	writel(val, sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);

	val = readl(sata_phy->regs + EXYNOS5_SATA_CTRL0);
	val |= CTRL0_P0_PHY_CALIBRATED_SEL | CTRL0_P0_PHY_CALIBRATED;
	writel(val, sata_phy->regs + EXYNOS5_SATA_CTRL0);

	val = readl(sata_phy->regs + EXYNOS5_SATA_MODE0);
	val |= SATA_SPD_GEN3;
	writel(val, sata_phy->regs + EXYNOS5_SATA_MODE0);

	ret = i2c_master_send(sata_phy->client, buf, sizeof(buf));
	if (ret < 0)
		return ret;

	/* release cmu reset */
	val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
	val &= ~RESET_CMN_RST_N;
	writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);

	val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
	val |= RESET_CMN_RST_N;
	writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);

	ret = wait_for_reg_status(sata_phy->regs,
				EXYNOS5_SATA_PHSATA_STATM,
				PHSTATM_PLL_LOCKED, 1);
	if (ret < 0)
		dev_err(&sata_phy->phy->dev,
			"PHY PLL locking failed\n");
	return ret;
}

static const struct phy_ops exynos_sata_phy_ops = {
	.init		= exynos_sata_phy_init,
	.power_on	= exynos_sata_phy_power_on,
	.power_off	= exynos_sata_phy_power_off,
	.owner		= THIS_MODULE,
};

static int exynos_sata_phy_probe(struct platform_device *pdev)
{
	struct exynos_sata_phy *sata_phy;
	struct device *dev = &pdev->dev;
	struct phy_provider *phy_provider;
	struct device_node *node;
	int ret = 0;

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

	sata_phy->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(sata_phy->regs))
		return PTR_ERR(sata_phy->regs);

	sata_phy->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
					"samsung,syscon-phandle");
	if (IS_ERR(sata_phy->pmureg)) {
		dev_err(dev, "syscon regmap lookup failed.\n");
		return PTR_ERR(sata_phy->pmureg);
	}

	node = of_parse_phandle(dev->of_node,
			"samsung,exynos-sataphy-i2c-phandle", 0);
	if (!node)
		return -EINVAL;

	sata_phy->client = of_find_i2c_device_by_node(node);
	if (!sata_phy->client)
		return -EPROBE_DEFER;

	dev_set_drvdata(dev, sata_phy);

	sata_phy->phyclk = devm_clk_get(dev, "sata_phyctrl");
	if (IS_ERR(sata_phy->phyclk)) {
		dev_err(dev, "failed to get clk for PHY\n");
		return PTR_ERR(sata_phy->phyclk);
	}

	ret = clk_prepare_enable(sata_phy->phyclk);
	if (ret < 0) {
		dev_err(dev, "failed to enable source clk\n");
		return ret;
	}

	sata_phy->phy = devm_phy_create(dev, NULL, &exynos_sata_phy_ops);
	if (IS_ERR(sata_phy->phy)) {
		clk_disable_unprepare(sata_phy->phyclk);
		dev_err(dev, "failed to create PHY\n");
		return PTR_ERR(sata_phy->phy);
	}

	phy_set_drvdata(sata_phy->phy, sata_phy);

	phy_provider = devm_of_phy_provider_register(dev,
					of_phy_simple_xlate);
	if (IS_ERR(phy_provider)) {
		clk_disable_unprepare(sata_phy->phyclk);
		return PTR_ERR(phy_provider);
	}

	return 0;
}

static const struct of_device_id exynos_sata_phy_of_match[] = {
	{ .compatible = "samsung,exynos5250-sata-phy" },
	{ },
};
MODULE_DEVICE_TABLE(of, exynos_sata_phy_of_match);

static struct platform_driver exynos_sata_phy_driver = {
	.probe	= exynos_sata_phy_probe,
	.driver = {
		.of_match_table	= exynos_sata_phy_of_match,
		.name  = "samsung,sata-phy",
		.suppress_bind_attrs = true,
	}
};
module_platform_driver(exynos_sata_phy_driver);

MODULE_DESCRIPTION("Samsung SerDes PHY driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Girish K S <ks.giri@samsung.com>");
MODULE_AUTHOR("Yuvaraj C D <yuvaraj.cd@samsung.com>");
