/*
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/phy/phy.h>

struct qcom_ipq806x_sata_phy {
	void __iomem *mmio;
	struct clk *cfg_clk;
	struct device *dev;
};

#define __set(v, a, b)	(((v) << (b)) & GENMASK(a, b))

#define SATA_PHY_P0_PARAM0		0x200
#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(x)	__set(x, 17, 12)
#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK	GENMASK(17, 12)
#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2(x)	__set(x, 11, 6)
#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK	GENMASK(11, 6)
#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1(x)	__set(x, 5, 0)
#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK	GENMASK(5, 0)

#define SATA_PHY_P0_PARAM1		0x204
#define SATA_PHY_P0_PARAM1_RESERVED_BITS31_21(x)	__set(x, 31, 21)
#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(x)	__set(x, 20, 14)
#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK	GENMASK(20, 14)
#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(x)	__set(x, 13, 7)
#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK	GENMASK(13, 7)
#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(x)	__set(x, 6, 0)
#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK	GENMASK(6, 0)

#define SATA_PHY_P0_PARAM2		0x208
#define SATA_PHY_P0_PARAM2_RX_EQ(x)	__set(x, 20, 18)
#define SATA_PHY_P0_PARAM2_RX_EQ_MASK	GENMASK(20, 18)

#define SATA_PHY_P0_PARAM3		0x20C
#define SATA_PHY_SSC_EN			0x8
#define SATA_PHY_P0_PARAM4		0x210
#define SATA_PHY_REF_SSP_EN		0x2
#define SATA_PHY_RESET			0x1

static int qcom_ipq806x_sata_phy_init(struct phy *generic_phy)
{
	struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy);
	u32 reg;

	/* Setting SSC_EN to 1 */
	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM3);
	reg = reg | SATA_PHY_SSC_EN;
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM3);

	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM0) &
			~(SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK |
			  SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK |
			  SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK);
	reg |= SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(0xf);
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM0);

	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM1) &
			~(SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK |
			  SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK |
			  SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK);
	reg |= SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(0x55) |
		SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(0x55) |
		SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(0x55);
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM1);

	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM2) &
		~SATA_PHY_P0_PARAM2_RX_EQ_MASK;
	reg |= SATA_PHY_P0_PARAM2_RX_EQ(0x3);
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM2);

	/* Setting PHY_RESET to 1 */
	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
	reg = reg | SATA_PHY_RESET;
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);

	/* Setting REF_SSP_EN to 1 */
	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
	reg = reg | SATA_PHY_REF_SSP_EN | SATA_PHY_RESET;
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);

	/* make sure all changes complete before we let the PHY out of reset */
	mb();

	/* sleep for max. 50us more to combine processor wakeups */
	usleep_range(20, 20 + 50);

	/* Clearing PHY_RESET to 0 */
	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
	reg = reg & ~SATA_PHY_RESET;
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);

	return 0;
}

static int qcom_ipq806x_sata_phy_exit(struct phy *generic_phy)
{
	struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy);
	u32 reg;

	/* Setting PHY_RESET to 1 */
	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
	reg = reg | SATA_PHY_RESET;
	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);

	return 0;
}

static const struct phy_ops qcom_ipq806x_sata_phy_ops = {
	.init		= qcom_ipq806x_sata_phy_init,
	.exit		= qcom_ipq806x_sata_phy_exit,
	.owner		= THIS_MODULE,
};

static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev)
{
	struct qcom_ipq806x_sata_phy *phy;
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct phy_provider *phy_provider;
	struct phy *generic_phy;
	int ret;

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

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	phy->mmio = devm_ioremap_resource(dev, res);
	if (IS_ERR(phy->mmio))
		return PTR_ERR(phy->mmio);

	generic_phy = devm_phy_create(dev, NULL, &qcom_ipq806x_sata_phy_ops);
	if (IS_ERR(generic_phy)) {
		dev_err(dev, "%s: failed to create phy\n", __func__);
		return PTR_ERR(generic_phy);
	}

	phy->dev = dev;
	phy_set_drvdata(generic_phy, phy);
	platform_set_drvdata(pdev, phy);

	phy->cfg_clk = devm_clk_get(dev, "cfg");
	if (IS_ERR(phy->cfg_clk)) {
		dev_err(dev, "Failed to get sata cfg clock\n");
		return PTR_ERR(phy->cfg_clk);
	}

	ret = clk_prepare_enable(phy->cfg_clk);
	if (ret)
		return ret;

	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
	if (IS_ERR(phy_provider)) {
		clk_disable_unprepare(phy->cfg_clk);
		dev_err(dev, "%s: failed to register phy\n", __func__);
		return PTR_ERR(phy_provider);
	}

	return 0;
}

static int qcom_ipq806x_sata_phy_remove(struct platform_device *pdev)
{
	struct qcom_ipq806x_sata_phy *phy = platform_get_drvdata(pdev);

	clk_disable_unprepare(phy->cfg_clk);

	return 0;
}

static const struct of_device_id qcom_ipq806x_sata_phy_of_match[] = {
	{ .compatible = "qcom,ipq806x-sata-phy" },
	{ },
};
MODULE_DEVICE_TABLE(of, qcom_ipq806x_sata_phy_of_match);

static struct platform_driver qcom_ipq806x_sata_phy_driver = {
	.probe	= qcom_ipq806x_sata_phy_probe,
	.remove	= qcom_ipq806x_sata_phy_remove,
	.driver = {
		.name	= "qcom-ipq806x-sata-phy",
		.of_match_table	= qcom_ipq806x_sata_phy_of_match,
	}
};
module_platform_driver(qcom_ipq806x_sata_phy_driver);

MODULE_DESCRIPTION("QCOM IPQ806x SATA PHY driver");
MODULE_LICENSE("GPL v2");
