/*
 * Amlogic Meson8b and GXBB DWMAC glue layer
 *
 * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/ethtool.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/of_net.h>
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
#include <linux/stmmac.h>

#include "stmmac_platform.h"

#define PRG_ETH0			0x0

#define PRG_ETH0_RGMII_MODE		BIT(0)

/* mux to choose between fclk_div2 (bit unset) and mpll2 (bit set) */
#define PRG_ETH0_CLK_M250_SEL_SHIFT	4
#define PRG_ETH0_CLK_M250_SEL_MASK	GENMASK(4, 4)

#define PRG_ETH0_TXDLY_SHIFT		5
#define PRG_ETH0_TXDLY_MASK		GENMASK(6, 5)

/* divider for the result of m250_sel */
#define PRG_ETH0_CLK_M250_DIV_SHIFT	7
#define PRG_ETH0_CLK_M250_DIV_WIDTH	3

#define PRG_ETH0_RGMII_TX_CLK_EN	10

#define PRG_ETH0_INVERTED_RMII_CLK	BIT(11)
#define PRG_ETH0_TX_AND_PHY_REF_CLK	BIT(12)

#define MUX_CLK_NUM_PARENTS		2

struct meson8b_dwmac {
	struct platform_device	*pdev;

	void __iomem		*regs;

	phy_interface_t		phy_mode;

	struct clk_mux		m250_mux;
	struct clk		*m250_mux_clk;
	struct clk		*m250_mux_parent[MUX_CLK_NUM_PARENTS];

	struct clk_divider	m250_div;
	struct clk		*m250_div_clk;

	struct clk_fixed_factor	fixed_div2;
	struct clk		*fixed_div2_clk;

	struct clk_gate		rgmii_tx_en;
	struct clk		*rgmii_tx_en_clk;

	u32			tx_delay_ns;
};

static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg,
				    u32 mask, u32 value)
{
	u32 data;

	data = readl(dwmac->regs + reg);
	data &= ~mask;
	data |= (value & mask);

	writel(data, dwmac->regs + reg);
}

static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
{
	struct clk_init_data init;
	int i, ret;
	struct device *dev = &dwmac->pdev->dev;
	char clk_name[32];
	const char *clk_div_parents[1];
	const char *mux_parent_names[MUX_CLK_NUM_PARENTS];

	/* get the mux parents from DT */
	for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
		char name[16];

		snprintf(name, sizeof(name), "clkin%d", i);
		dwmac->m250_mux_parent[i] = devm_clk_get(dev, name);
		if (IS_ERR(dwmac->m250_mux_parent[i])) {
			ret = PTR_ERR(dwmac->m250_mux_parent[i]);
			if (ret != -EPROBE_DEFER)
				dev_err(dev, "Missing clock %s\n", name);
			return ret;
		}

		mux_parent_names[i] =
			__clk_get_name(dwmac->m250_mux_parent[i]);
	}

	/* create the m250_mux */
	snprintf(clk_name, sizeof(clk_name), "%s#m250_sel", dev_name(dev));
	init.name = clk_name;
	init.ops = &clk_mux_ops;
	init.flags = CLK_SET_RATE_PARENT;
	init.parent_names = mux_parent_names;
	init.num_parents = MUX_CLK_NUM_PARENTS;

	dwmac->m250_mux.reg = dwmac->regs + PRG_ETH0;
	dwmac->m250_mux.shift = PRG_ETH0_CLK_M250_SEL_SHIFT;
	dwmac->m250_mux.mask = PRG_ETH0_CLK_M250_SEL_MASK;
	dwmac->m250_mux.flags = 0;
	dwmac->m250_mux.table = NULL;
	dwmac->m250_mux.hw.init = &init;

	dwmac->m250_mux_clk = devm_clk_register(dev, &dwmac->m250_mux.hw);
	if (WARN_ON(IS_ERR(dwmac->m250_mux_clk)))
		return PTR_ERR(dwmac->m250_mux_clk);

	/* create the m250_div */
	snprintf(clk_name, sizeof(clk_name), "%s#m250_div", dev_name(dev));
	init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL);
	init.ops = &clk_divider_ops;
	init.flags = CLK_SET_RATE_PARENT;
	clk_div_parents[0] = __clk_get_name(dwmac->m250_mux_clk);
	init.parent_names = clk_div_parents;
	init.num_parents = ARRAY_SIZE(clk_div_parents);

	dwmac->m250_div.reg = dwmac->regs + PRG_ETH0;
	dwmac->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT;
	dwmac->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH;
	dwmac->m250_div.hw.init = &init;
	dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED |
				CLK_DIVIDER_ALLOW_ZERO |
				CLK_DIVIDER_ROUND_CLOSEST;

	dwmac->m250_div_clk = devm_clk_register(dev, &dwmac->m250_div.hw);
	if (WARN_ON(IS_ERR(dwmac->m250_div_clk)))
		return PTR_ERR(dwmac->m250_div_clk);

	/* create the fixed_div2 */
	snprintf(clk_name, sizeof(clk_name), "%s#fixed_div2", dev_name(dev));
	init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL);
	init.ops = &clk_fixed_factor_ops;
	init.flags = CLK_SET_RATE_PARENT;
	clk_div_parents[0] = __clk_get_name(dwmac->m250_div_clk);
	init.parent_names = clk_div_parents;
	init.num_parents = ARRAY_SIZE(clk_div_parents);

	dwmac->fixed_div2.mult = 1;
	dwmac->fixed_div2.div = 2;
	dwmac->fixed_div2.hw.init = &init;

	dwmac->fixed_div2_clk = devm_clk_register(dev, &dwmac->fixed_div2.hw);
	if (WARN_ON(IS_ERR(dwmac->fixed_div2_clk)))
		return PTR_ERR(dwmac->fixed_div2_clk);

	/* create the rgmii_tx_en */
	init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#rgmii_tx_en",
				   dev_name(dev));
	init.ops = &clk_gate_ops;
	init.flags = CLK_SET_RATE_PARENT;
	clk_div_parents[0] = __clk_get_name(dwmac->fixed_div2_clk);
	init.parent_names = clk_div_parents;
	init.num_parents = ARRAY_SIZE(clk_div_parents);

	dwmac->rgmii_tx_en.reg = dwmac->regs + PRG_ETH0;
	dwmac->rgmii_tx_en.bit_idx = PRG_ETH0_RGMII_TX_CLK_EN;
	dwmac->rgmii_tx_en.hw.init = &init;

	dwmac->rgmii_tx_en_clk = devm_clk_register(dev,
						   &dwmac->rgmii_tx_en.hw);
	if (WARN_ON(IS_ERR(dwmac->rgmii_tx_en_clk)))
		return PTR_ERR(dwmac->rgmii_tx_en_clk);

	return 0;
}

static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
{
	int ret;
	u8 tx_dly_val = 0;

	switch (dwmac->phy_mode) {
	case PHY_INTERFACE_MODE_RGMII:
	case PHY_INTERFACE_MODE_RGMII_RXID:
		/* TX clock delay in ns = "8ns / 4 * tx_dly_val" (where
		 * 8ns are exactly one cycle of the 125MHz RGMII TX clock):
		 * 0ns = 0x0, 2ns = 0x1, 4ns = 0x2, 6ns = 0x3
		 */
		tx_dly_val = dwmac->tx_delay_ns >> 1;
		/* fall through */

	case PHY_INTERFACE_MODE_RGMII_ID:
	case PHY_INTERFACE_MODE_RGMII_TXID:
		/* enable RGMII mode */
		meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
					PRG_ETH0_RGMII_MODE);

		/* only relevant for RMII mode -> disable in RGMII mode */
		meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
					PRG_ETH0_INVERTED_RMII_CLK, 0);

		meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
					tx_dly_val << PRG_ETH0_TXDLY_SHIFT);

		/* Configure the 125MHz RGMII TX clock, the IP block changes
		 * the output automatically (= without us having to configure
		 * a register) based on the line-speed (125MHz for Gbit speeds,
		 * 25MHz for 100Mbit/s and 2.5MHz for 10Mbit/s).
		 */
		ret = clk_set_rate(dwmac->rgmii_tx_en_clk, 125 * 1000 * 1000);
		if (ret) {
			dev_err(&dwmac->pdev->dev,
				"failed to set RGMII TX clock\n");
			return ret;
		}

		ret = clk_prepare_enable(dwmac->rgmii_tx_en_clk);
		if (ret) {
			dev_err(&dwmac->pdev->dev,
				"failed to enable the RGMII TX clock\n");
			return ret;
		}
		break;

	case PHY_INTERFACE_MODE_RMII:
		/* disable RGMII mode -> enables RMII mode */
		meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
					0);

		/* invert internal clk_rmii_i to generate 25/2.5 tx_rx_clk */
		meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
					PRG_ETH0_INVERTED_RMII_CLK,
					PRG_ETH0_INVERTED_RMII_CLK);

		/* TX clock delay cannot be configured in RMII mode */
		meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
					0);

		break;

	default:
		dev_err(&dwmac->pdev->dev, "unsupported phy-mode %s\n",
			phy_modes(dwmac->phy_mode));
		return -EINVAL;
	}

	/* enable TX_CLK and PHY_REF_CLK generator */
	meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TX_AND_PHY_REF_CLK,
				PRG_ETH0_TX_AND_PHY_REF_CLK);

	return 0;
}

static int meson8b_dwmac_probe(struct platform_device *pdev)
{
	struct plat_stmmacenet_data *plat_dat;
	struct stmmac_resources stmmac_res;
	struct resource *res;
	struct meson8b_dwmac *dwmac;
	int ret;

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

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

	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
	if (!dwmac) {
		ret = -ENOMEM;
		goto err_remove_config_dt;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	dwmac->regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(dwmac->regs)) {
		ret = PTR_ERR(dwmac->regs);
		goto err_remove_config_dt;
	}

	dwmac->pdev = pdev;
	dwmac->phy_mode = of_get_phy_mode(pdev->dev.of_node);
	if (dwmac->phy_mode < 0) {
		dev_err(&pdev->dev, "missing phy-mode property\n");
		ret = -EINVAL;
		goto err_remove_config_dt;
	}

	/* use 2ns as fallback since this value was previously hardcoded */
	if (of_property_read_u32(pdev->dev.of_node, "amlogic,tx-delay-ns",
				 &dwmac->tx_delay_ns))
		dwmac->tx_delay_ns = 2;

	ret = meson8b_init_rgmii_tx_clk(dwmac);
	if (ret)
		goto err_remove_config_dt;

	ret = meson8b_init_prg_eth(dwmac);
	if (ret)
		goto err_remove_config_dt;

	plat_dat->bsp_priv = dwmac;

	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
	if (ret)
		goto err_clk_disable;

	return 0;

err_clk_disable:
	if (phy_interface_mode_is_rgmii(dwmac->phy_mode))
		clk_disable_unprepare(dwmac->rgmii_tx_en_clk);
err_remove_config_dt:
	stmmac_remove_config_dt(pdev, plat_dat);

	return ret;
}

static int meson8b_dwmac_remove(struct platform_device *pdev)
{
	struct meson8b_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev);

	if (phy_interface_mode_is_rgmii(dwmac->phy_mode))
		clk_disable_unprepare(dwmac->rgmii_tx_en_clk);

	return stmmac_pltfr_remove(pdev);
}

static const struct of_device_id meson8b_dwmac_match[] = {
	{ .compatible = "amlogic,meson8b-dwmac" },
	{ .compatible = "amlogic,meson-gxbb-dwmac" },
	{ }
};
MODULE_DEVICE_TABLE(of, meson8b_dwmac_match);

static struct platform_driver meson8b_dwmac_driver = {
	.probe  = meson8b_dwmac_probe,
	.remove = meson8b_dwmac_remove,
	.driver = {
		.name           = "meson8b-dwmac",
		.pm		= &stmmac_pltfr_pm_ops,
		.of_match_table = meson8b_dwmac_match,
	},
};
module_platform_driver(meson8b_dwmac_driver);

MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
MODULE_DESCRIPTION("Amlogic Meson8b and GXBB DWMAC glue layer");
MODULE_LICENSE("GPL v2");
