// SPDX-License-Identifier: GPL-2.0-only
/*
 * Oxford Semiconductor OXNAS DWMAC glue layer
 *
 * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
 * Copyright (C) 2014 Daniel Golle <daniel@makrotopia.org>
 * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com>
 * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
 */

#include <linux/device.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include <linux/stmmac.h>

#include "stmmac_platform.h"

/* System Control regmap offsets */
#define OXNAS_DWMAC_CTRL_REGOFFSET	0x78
#define OXNAS_DWMAC_DELAY_REGOFFSET	0x100

/* Control Register */
#define DWMAC_CKEN_RX_IN        14
#define DWMAC_CKEN_RXN_OUT      13
#define DWMAC_CKEN_RX_OUT       12
#define DWMAC_CKEN_TX_IN        10
#define DWMAC_CKEN_TXN_OUT      9
#define DWMAC_CKEN_TX_OUT       8
#define DWMAC_RX_SOURCE         7
#define DWMAC_TX_SOURCE         6
#define DWMAC_LOW_TX_SOURCE     4
#define DWMAC_AUTO_TX_SOURCE    3
#define DWMAC_RGMII             2
#define DWMAC_SIMPLE_MUX        1
#define DWMAC_CKEN_GTX          0

/* Delay register */
#define DWMAC_TX_VARDELAY_SHIFT		0
#define DWMAC_TXN_VARDELAY_SHIFT	8
#define DWMAC_RX_VARDELAY_SHIFT		16
#define DWMAC_RXN_VARDELAY_SHIFT	24
#define DWMAC_TX_VARDELAY(d)		((d) << DWMAC_TX_VARDELAY_SHIFT)
#define DWMAC_TXN_VARDELAY(d)		((d) << DWMAC_TXN_VARDELAY_SHIFT)
#define DWMAC_RX_VARDELAY(d)		((d) << DWMAC_RX_VARDELAY_SHIFT)
#define DWMAC_RXN_VARDELAY(d)		((d) << DWMAC_RXN_VARDELAY_SHIFT)

struct oxnas_dwmac {
	struct device	*dev;
	struct clk	*clk;
	struct regmap	*regmap;
};

static int oxnas_dwmac_init(struct platform_device *pdev, void *priv)
{
	struct oxnas_dwmac *dwmac = priv;
	unsigned int value;
	int ret;

	/* Reset HW here before changing the glue configuration */
	ret = device_reset(dwmac->dev);
	if (ret)
		return ret;

	ret = clk_prepare_enable(dwmac->clk);
	if (ret)
		return ret;

	ret = regmap_read(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, &value);
	if (ret < 0) {
		clk_disable_unprepare(dwmac->clk);
		return ret;
	}

	/* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
	value |= BIT(DWMAC_CKEN_GTX)		|
		 /* Use simple mux for 25/125 Mhz clock switching */
		 BIT(DWMAC_SIMPLE_MUX)		|
		 /* set auto switch tx clock source */
		 BIT(DWMAC_AUTO_TX_SOURCE)	|
		 /* enable tx & rx vardelay */
		 BIT(DWMAC_CKEN_TX_OUT)		|
		 BIT(DWMAC_CKEN_TXN_OUT)	|
		 BIT(DWMAC_CKEN_TX_IN)		|
		 BIT(DWMAC_CKEN_RX_OUT)		|
		 BIT(DWMAC_CKEN_RXN_OUT)	|
		 BIT(DWMAC_CKEN_RX_IN);
	regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value);

	/* set tx & rx vardelay */
	value = DWMAC_TX_VARDELAY(4)	|
		DWMAC_TXN_VARDELAY(2)	|
		DWMAC_RX_VARDELAY(10)	|
		DWMAC_RXN_VARDELAY(8);
	regmap_write(dwmac->regmap, OXNAS_DWMAC_DELAY_REGOFFSET, value);

	return 0;
}

static void oxnas_dwmac_exit(struct platform_device *pdev, void *priv)
{
	struct oxnas_dwmac *dwmac = priv;

	clk_disable_unprepare(dwmac->clk);
}

static int oxnas_dwmac_probe(struct platform_device *pdev)
{
	struct plat_stmmacenet_data *plat_dat;
	struct stmmac_resources stmmac_res;
	struct oxnas_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;
	}

	dwmac->dev = &pdev->dev;
	plat_dat->bsp_priv = dwmac;
	plat_dat->init = oxnas_dwmac_init;
	plat_dat->exit = oxnas_dwmac_exit;

	dwmac->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
							"oxsemi,sys-ctrl");
	if (IS_ERR(dwmac->regmap)) {
		dev_err(&pdev->dev, "failed to have sysctrl regmap\n");
		ret = PTR_ERR(dwmac->regmap);
		goto err_remove_config_dt;
	}

	dwmac->clk = devm_clk_get(&pdev->dev, "gmac");
	if (IS_ERR(dwmac->clk)) {
		ret = PTR_ERR(dwmac->clk);
		goto err_remove_config_dt;
	}

	ret = oxnas_dwmac_init(pdev, plat_dat->bsp_priv);
	if (ret)
		goto err_remove_config_dt;

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


	return 0;

err_dwmac_exit:
	oxnas_dwmac_exit(pdev, plat_dat->bsp_priv);
err_remove_config_dt:
	stmmac_remove_config_dt(pdev, plat_dat);

	return ret;
}

static const struct of_device_id oxnas_dwmac_match[] = {
	{ .compatible = "oxsemi,ox820-dwmac" },
	{ }
};
MODULE_DEVICE_TABLE(of, oxnas_dwmac_match);

static struct platform_driver oxnas_dwmac_driver = {
	.probe  = oxnas_dwmac_probe,
	.remove = stmmac_pltfr_remove,
	.driver = {
		.name           = "oxnas-dwmac",
		.pm		= &stmmac_pltfr_pm_ops,
		.of_match_table = oxnas_dwmac_match,
	},
};
module_platform_driver(oxnas_dwmac_driver);

MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
MODULE_DESCRIPTION("Oxford Semiconductor OXNAS DWMAC glue layer");
MODULE_LICENSE("GPL v2");
