/*
 * Qualcomm Atheros IPQ806x GMAC glue layer
 *
 * Copyright (C) 2015 The Linux Foundation
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/phy.h>
#include <linux/regmap.h>
#include <linux/clk.h>
#include <linux/reset.h>
#include <linux/of_net.h>
#include <linux/mfd/syscon.h>
#include <linux/stmmac.h>
#include <linux/of_mdio.h>
#include <linux/module.h>
#include <linux/sys_soc.h>
#include <linux/bitfield.h>

#include "stmmac_platform.h"

#define NSS_COMMON_CLK_GATE			0x8
#define NSS_COMMON_CLK_GATE_PTP_EN(x)		BIT(0x10 + x)
#define NSS_COMMON_CLK_GATE_RGMII_RX_EN(x)	BIT(0x9 + (x * 2))
#define NSS_COMMON_CLK_GATE_RGMII_TX_EN(x)	BIT(0x8 + (x * 2))
#define NSS_COMMON_CLK_GATE_GMII_RX_EN(x)	BIT(0x4 + x)
#define NSS_COMMON_CLK_GATE_GMII_TX_EN(x)	BIT(0x0 + x)

#define NSS_COMMON_CLK_DIV0			0xC
#define NSS_COMMON_CLK_DIV_OFFSET(x)		(x * 8)
#define NSS_COMMON_CLK_DIV_MASK			0x7f

#define NSS_COMMON_CLK_SRC_CTRL			0x14
#define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x)	(x)
/* Mode is coded on 1 bit but is different depending on the MAC ID:
 * MAC0: QSGMII=0 RGMII=1
 * MAC1: QSGMII=0 SGMII=0 RGMII=1
 * MAC2 & MAC3: QSGMII=0 SGMII=1
 */
#define NSS_COMMON_CLK_SRC_CTRL_RGMII(x)	1
#define NSS_COMMON_CLK_SRC_CTRL_SGMII(x)	((x >= 2) ? 1 : 0)

#define NSS_COMMON_GMAC_CTL(x)			(0x30 + (x * 4))
#define NSS_COMMON_GMAC_CTL_CSYS_REQ		BIT(19)
#define NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL	BIT(16)
#define NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET	8
#define NSS_COMMON_GMAC_CTL_IFG_OFFSET		0

#define NSS_COMMON_CLK_DIV_RGMII_1000		1
#define NSS_COMMON_CLK_DIV_RGMII_100		9
#define NSS_COMMON_CLK_DIV_RGMII_10		99
#define NSS_COMMON_CLK_DIV_SGMII_1000		0
#define NSS_COMMON_CLK_DIV_SGMII_100		4
#define NSS_COMMON_CLK_DIV_SGMII_10		49

#define QSGMII_PCS_ALL_CH_CTL			0x80
#define QSGMII_PCS_CH_SPEED_FORCE		BIT(1)
#define QSGMII_PCS_CH_SPEED_10			0x0
#define QSGMII_PCS_CH_SPEED_100			BIT(2)
#define QSGMII_PCS_CH_SPEED_1000		BIT(3)
#define QSGMII_PCS_CH_SPEED_MASK		(QSGMII_PCS_CH_SPEED_FORCE | \
						 QSGMII_PCS_CH_SPEED_10 | \
						 QSGMII_PCS_CH_SPEED_100 | \
						 QSGMII_PCS_CH_SPEED_1000)
#define QSGMII_PCS_CH_SPEED_SHIFT(x)		((x) * 4)

#define QSGMII_PCS_CAL_LCKDT_CTL		0x120
#define QSGMII_PCS_CAL_LCKDT_CTL_RST		BIT(19)

/* Only GMAC1/2/3 support SGMII and their CTL register are not contiguous */
#define QSGMII_PHY_SGMII_CTL(x)			((x == 1) ? 0x134 : \
						 (0x13c + (4 * (x - 2))))
#define QSGMII_PHY_CDR_EN			BIT(0)
#define QSGMII_PHY_RX_FRONT_EN			BIT(1)
#define QSGMII_PHY_RX_SIGNAL_DETECT_EN		BIT(2)
#define QSGMII_PHY_TX_DRIVER_EN			BIT(3)
#define QSGMII_PHY_QSGMII_EN			BIT(7)
#define QSGMII_PHY_DEEMPHASIS_LVL_MASK		GENMASK(11, 10)
#define QSGMII_PHY_DEEMPHASIS_LVL(x)		FIELD_PREP(QSGMII_PHY_DEEMPHASIS_LVL_MASK, (x))
#define QSGMII_PHY_PHASE_LOOP_GAIN_MASK		GENMASK(14, 12)
#define QSGMII_PHY_PHASE_LOOP_GAIN(x)		FIELD_PREP(QSGMII_PHY_PHASE_LOOP_GAIN_MASK, (x))
#define QSGMII_PHY_RX_DC_BIAS_MASK		GENMASK(19, 18)
#define QSGMII_PHY_RX_DC_BIAS(x)		FIELD_PREP(QSGMII_PHY_RX_DC_BIAS_MASK, (x))
#define QSGMII_PHY_RX_INPUT_EQU_MASK		GENMASK(21, 20)
#define QSGMII_PHY_RX_INPUT_EQU(x)		FIELD_PREP(QSGMII_PHY_RX_INPUT_EQU_MASK, (x))
#define QSGMII_PHY_CDR_PI_SLEW_MASK		GENMASK(23, 22)
#define QSGMII_PHY_CDR_PI_SLEW(x)		FIELD_PREP(QSGMII_PHY_CDR_PI_SLEW_MASK, (x))
#define QSGMII_PHY_TX_SLEW_MASK			GENMASK(27, 26)
#define QSGMII_PHY_TX_SLEW(x)			FIELD_PREP(QSGMII_PHY_TX_SLEW_MASK, (x))
#define QSGMII_PHY_TX_DRV_AMP_MASK		GENMASK(31, 28)
#define QSGMII_PHY_TX_DRV_AMP(x)		FIELD_PREP(QSGMII_PHY_TX_DRV_AMP_MASK, (x))

struct ipq806x_gmac {
	struct platform_device *pdev;
	struct regmap *nss_common;
	struct regmap *qsgmii_csr;
	uint32_t id;
	struct clk *core_clk;
	phy_interface_t phy_mode;
};

static int get_clk_div_sgmii(struct ipq806x_gmac *gmac, unsigned int speed)
{
	struct device *dev = &gmac->pdev->dev;
	int div;

	switch (speed) {
	case SPEED_1000:
		div = NSS_COMMON_CLK_DIV_SGMII_1000;
		break;

	case SPEED_100:
		div = NSS_COMMON_CLK_DIV_SGMII_100;
		break;

	case SPEED_10:
		div = NSS_COMMON_CLK_DIV_SGMII_10;
		break;

	default:
		dev_err(dev, "Speed %dMbps not supported in SGMII\n", speed);
		return -EINVAL;
	}

	return div;
}

static int get_clk_div_rgmii(struct ipq806x_gmac *gmac, unsigned int speed)
{
	struct device *dev = &gmac->pdev->dev;
	int div;

	switch (speed) {
	case SPEED_1000:
		div = NSS_COMMON_CLK_DIV_RGMII_1000;
		break;

	case SPEED_100:
		div = NSS_COMMON_CLK_DIV_RGMII_100;
		break;

	case SPEED_10:
		div = NSS_COMMON_CLK_DIV_RGMII_10;
		break;

	default:
		dev_err(dev, "Speed %dMbps not supported in RGMII\n", speed);
		return -EINVAL;
	}

	return div;
}

static int ipq806x_gmac_set_speed(struct ipq806x_gmac *gmac, unsigned int speed)
{
	uint32_t clk_bits, val;
	int div;

	switch (gmac->phy_mode) {
	case PHY_INTERFACE_MODE_RGMII:
		div = get_clk_div_rgmii(gmac, speed);
		clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
			   NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
		break;

	case PHY_INTERFACE_MODE_SGMII:
		div = get_clk_div_sgmii(gmac, speed);
		clk_bits = NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
			   NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
		break;

	default:
		dev_err(&gmac->pdev->dev, "Unsupported PHY mode: \"%s\"\n",
			phy_modes(gmac->phy_mode));
		return -EINVAL;
	}

	/* Disable the clocks */
	regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
	val &= ~clk_bits;
	regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);

	/* Set the divider */
	regmap_read(gmac->nss_common, NSS_COMMON_CLK_DIV0, &val);
	val &= ~(NSS_COMMON_CLK_DIV_MASK
		 << NSS_COMMON_CLK_DIV_OFFSET(gmac->id));
	val |= div << NSS_COMMON_CLK_DIV_OFFSET(gmac->id);
	regmap_write(gmac->nss_common, NSS_COMMON_CLK_DIV0, val);

	/* Enable the clock back */
	regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
	val |= clk_bits;
	regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);

	return 0;
}

static int ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac)
{
	struct device *dev = &gmac->pdev->dev;
	int ret;

	ret = of_get_phy_mode(dev->of_node, &gmac->phy_mode);
	if (ret) {
		dev_err(dev, "missing phy mode property\n");
		return -EINVAL;
	}

	if (of_property_read_u32(dev->of_node, "qcom,id", &gmac->id) < 0) {
		dev_err(dev, "missing qcom id property\n");
		return -EINVAL;
	}

	/* The GMACs are called 1 to 4 in the documentation, but to simplify the
	 * code and keep it consistent with the Linux convention, we'll number
	 * them from 0 to 3 here.
	 */
	if (gmac->id > 3) {
		dev_err(dev, "invalid gmac id\n");
		return -EINVAL;
	}

	gmac->core_clk = devm_clk_get(dev, "stmmaceth");
	if (IS_ERR(gmac->core_clk)) {
		dev_err(dev, "missing stmmaceth clk property\n");
		return PTR_ERR(gmac->core_clk);
	}
	clk_set_rate(gmac->core_clk, 266000000);

	/* Setup the register map for the nss common registers */
	gmac->nss_common = syscon_regmap_lookup_by_phandle(dev->of_node,
							   "qcom,nss-common");
	if (IS_ERR(gmac->nss_common)) {
		dev_err(dev, "missing nss-common node\n");
		return PTR_ERR(gmac->nss_common);
	}

	/* Setup the register map for the qsgmii csr registers */
	gmac->qsgmii_csr = syscon_regmap_lookup_by_phandle(dev->of_node,
							   "qcom,qsgmii-csr");
	if (IS_ERR(gmac->qsgmii_csr))
		dev_err(dev, "missing qsgmii-csr node\n");

	return PTR_ERR_OR_ZERO(gmac->qsgmii_csr);
}

static void ipq806x_gmac_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
{
	struct ipq806x_gmac *gmac = priv;

	ipq806x_gmac_set_speed(gmac, speed);
}

static int
ipq806x_gmac_configure_qsgmii_pcs_speed(struct ipq806x_gmac *gmac)
{
	struct platform_device *pdev = gmac->pdev;
	struct device *dev = &pdev->dev;
	struct device_node *dn;
	int link_speed;
	int val = 0;
	int ret;

	/* Some bootloader may apply wrong configuration and cause
	 * not functioning port. If fixed link is not set,
	 * reset the force speed bit.
	 */
	if (!of_phy_is_fixed_link(pdev->dev.of_node))
		goto write;

	dn = of_get_child_by_name(pdev->dev.of_node, "fixed-link");
	ret = of_property_read_u32(dn, "speed", &link_speed);
	of_node_put(dn);
	if (ret) {
		dev_err(dev, "found fixed-link node with no speed");
		return ret;
	}

	val = QSGMII_PCS_CH_SPEED_FORCE;

	switch (link_speed) {
	case SPEED_1000:
		val |= QSGMII_PCS_CH_SPEED_1000;
		break;
	case SPEED_100:
		val |= QSGMII_PCS_CH_SPEED_100;
		break;
	case SPEED_10:
		val |= QSGMII_PCS_CH_SPEED_10;
		break;
	}

write:
	regmap_update_bits(gmac->qsgmii_csr, QSGMII_PCS_ALL_CH_CTL,
			   QSGMII_PCS_CH_SPEED_MASK <<
			   QSGMII_PCS_CH_SPEED_SHIFT(gmac->id),
			   val <<
			   QSGMII_PCS_CH_SPEED_SHIFT(gmac->id));

	return 0;
}

static const struct soc_device_attribute ipq806x_gmac_soc_v1[] = {
	{
		.revision = "1.*",
	},
	{
		/* sentinel */
	}
};

static int
ipq806x_gmac_configure_qsgmii_params(struct ipq806x_gmac *gmac)
{
	struct platform_device *pdev = gmac->pdev;
	const struct soc_device_attribute *soc;
	struct device *dev = &pdev->dev;
	u32 qsgmii_param;

	switch (gmac->id) {
	case 1:
		soc = soc_device_match(ipq806x_gmac_soc_v1);

		if (soc)
			qsgmii_param = QSGMII_PHY_TX_DRV_AMP(0xc) |
				       QSGMII_PHY_TX_SLEW(0x2) |
				       QSGMII_PHY_DEEMPHASIS_LVL(0x2);
		else
			qsgmii_param = QSGMII_PHY_TX_DRV_AMP(0xd) |
				       QSGMII_PHY_TX_SLEW(0x0) |
				       QSGMII_PHY_DEEMPHASIS_LVL(0x0);

		qsgmii_param |= QSGMII_PHY_RX_DC_BIAS(0x2);
		break;
	case 2:
	case 3:
		qsgmii_param = QSGMII_PHY_RX_DC_BIAS(0x3) |
			       QSGMII_PHY_TX_DRV_AMP(0xc);
		break;
	default: /* gmac 0 can't be set in SGMII mode */
		dev_err(dev, "gmac id %d can't be in SGMII mode", gmac->id);
		return -EINVAL;
	}

	/* Common params across all gmac id */
	qsgmii_param |= QSGMII_PHY_CDR_EN |
			QSGMII_PHY_RX_FRONT_EN |
			QSGMII_PHY_RX_SIGNAL_DETECT_EN |
			QSGMII_PHY_TX_DRIVER_EN |
			QSGMII_PHY_QSGMII_EN |
			QSGMII_PHY_PHASE_LOOP_GAIN(0x4) |
			QSGMII_PHY_RX_INPUT_EQU(0x1) |
			QSGMII_PHY_CDR_PI_SLEW(0x2);

	regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id),
		     qsgmii_param);

	return 0;
}

static int ipq806x_gmac_probe(struct platform_device *pdev)
{
	struct plat_stmmacenet_data *plat_dat;
	struct stmmac_resources stmmac_res;
	struct device *dev = &pdev->dev;
	struct ipq806x_gmac *gmac;
	int val;
	int err;

	val = stmmac_get_platform_resources(pdev, &stmmac_res);
	if (val)
		return val;

	plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
	if (IS_ERR(plat_dat))
		return PTR_ERR(plat_dat);

	gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
	if (!gmac) {
		err = -ENOMEM;
		goto err_remove_config_dt;
	}

	gmac->pdev = pdev;

	err = ipq806x_gmac_of_parse(gmac);
	if (err) {
		dev_err(dev, "device tree parsing error\n");
		goto err_remove_config_dt;
	}

	regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
		     QSGMII_PCS_CAL_LCKDT_CTL_RST);

	/* Inter frame gap is set to 12 */
	val = 12 << NSS_COMMON_GMAC_CTL_IFG_OFFSET |
	      12 << NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET;
	/* We also initiate an AXI low power exit request */
	val |= NSS_COMMON_GMAC_CTL_CSYS_REQ;
	switch (gmac->phy_mode) {
	case PHY_INTERFACE_MODE_RGMII:
		val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
		break;
	case PHY_INTERFACE_MODE_SGMII:
		val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
		break;
	default:
		goto err_unsupported_phy;
	}
	regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);

	/* Configure the clock src according to the mode */
	regmap_read(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, &val);
	val &= ~(1 << NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id));
	switch (gmac->phy_mode) {
	case PHY_INTERFACE_MODE_RGMII:
		val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
			NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
		break;
	case PHY_INTERFACE_MODE_SGMII:
		val |= NSS_COMMON_CLK_SRC_CTRL_SGMII(gmac->id) <<
			NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
		break;
	default:
		goto err_unsupported_phy;
	}
	regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);

	/* Enable PTP clock */
	regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
	val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
	switch (gmac->phy_mode) {
	case PHY_INTERFACE_MODE_RGMII:
		val |= NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
			NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
		break;
	case PHY_INTERFACE_MODE_SGMII:
		val |= NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
				NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
		break;
	default:
		goto err_unsupported_phy;
	}
	regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);

	if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {
		err = ipq806x_gmac_configure_qsgmii_params(gmac);
		if (err)
			goto err_remove_config_dt;

		err = ipq806x_gmac_configure_qsgmii_pcs_speed(gmac);
		if (err)
			goto err_remove_config_dt;
	}

	plat_dat->has_gmac = true;
	plat_dat->bsp_priv = gmac;
	plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
	plat_dat->multicast_filter_bins = 0;
	plat_dat->tx_fifo_size = 8192;
	plat_dat->rx_fifo_size = 8192;

	err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
	if (err)
		goto err_remove_config_dt;

	return 0;

err_unsupported_phy:
	dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
		phy_modes(gmac->phy_mode));
	err = -EINVAL;

err_remove_config_dt:
	stmmac_remove_config_dt(pdev, plat_dat);

	return err;
}

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

static struct platform_driver ipq806x_gmac_dwmac_driver = {
	.probe = ipq806x_gmac_probe,
	.remove_new = stmmac_pltfr_remove,
	.driver = {
		.name		= "ipq806x-gmac-dwmac",
		.pm		= &stmmac_pltfr_pm_ops,
		.of_match_table	= ipq806x_gmac_dwmac_match,
	},
};
module_platform_driver(ipq806x_gmac_dwmac_driver);

MODULE_AUTHOR("Mathieu Olivari <mathieu@codeaurora.org>");
MODULE_DESCRIPTION("Qualcomm Atheros IPQ806x DWMAC specific glue layer");
MODULE_LICENSE("Dual BSD/GPL");
