// SPDX-License-Identifier: GPL-2.0+
/*
 * StarFive DWMAC platform driver
 *
 * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
 * Copyright (C) 2022 StarFive Technology Co., Ltd.
 *
 */

#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>

#include "stmmac_platform.h"

#define STARFIVE_DWMAC_PHY_INFT_RGMII		0x1
#define STARFIVE_DWMAC_PHY_INFT_RMII		0x4
#define STARFIVE_DWMAC_PHY_INFT_FIELD		0x7U

#define JH7100_SYSMAIN_REGISTER49_DLYCHAIN	0xc8

struct starfive_dwmac_data {
	unsigned int gtxclk_dlychain;
};

struct starfive_dwmac {
	struct device *dev;
	struct clk *clk_tx;
	const struct starfive_dwmac_data *data;
};

static void starfive_dwmac_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
{
	struct starfive_dwmac *dwmac = priv;
	unsigned long rate;
	int err;

	rate = clk_get_rate(dwmac->clk_tx);

	switch (speed) {
	case SPEED_1000:
		rate = 125000000;
		break;
	case SPEED_100:
		rate = 25000000;
		break;
	case SPEED_10:
		rate = 2500000;
		break;
	default:
		dev_err(dwmac->dev, "invalid speed %u\n", speed);
		break;
	}

	err = clk_set_rate(dwmac->clk_tx, rate);
	if (err)
		dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
}

static int starfive_dwmac_set_mode(struct plat_stmmacenet_data *plat_dat)
{
	struct starfive_dwmac *dwmac = plat_dat->bsp_priv;
	struct regmap *regmap;
	unsigned int args[2];
	unsigned int mode;
	int err;

	switch (plat_dat->mac_interface) {
	case PHY_INTERFACE_MODE_RMII:
		mode = STARFIVE_DWMAC_PHY_INFT_RMII;
		break;

	case PHY_INTERFACE_MODE_RGMII:
	case PHY_INTERFACE_MODE_RGMII_ID:
	case PHY_INTERFACE_MODE_RGMII_RXID:
	case PHY_INTERFACE_MODE_RGMII_TXID:
		mode = STARFIVE_DWMAC_PHY_INFT_RGMII;
		break;

	default:
		dev_err(dwmac->dev, "unsupported interface %d\n",
			plat_dat->mac_interface);
		return -EINVAL;
	}

	regmap = syscon_regmap_lookup_by_phandle_args(dwmac->dev->of_node,
						      "starfive,syscon",
						      2, args);
	if (IS_ERR(regmap))
		return dev_err_probe(dwmac->dev, PTR_ERR(regmap), "getting the regmap failed\n");

	/* args[0]:offset  args[1]: shift */
	err = regmap_update_bits(regmap, args[0],
				 STARFIVE_DWMAC_PHY_INFT_FIELD << args[1],
				 mode << args[1]);
	if (err)
		return dev_err_probe(dwmac->dev, err, "error setting phy mode\n");

	if (dwmac->data) {
		err = regmap_write(regmap, JH7100_SYSMAIN_REGISTER49_DLYCHAIN,
				   dwmac->data->gtxclk_dlychain);
		if (err)
			return dev_err_probe(dwmac->dev, err,
					     "error selecting gtxclk delay chain\n");
	}

	return 0;
}

static int starfive_dwmac_probe(struct platform_device *pdev)
{
	struct plat_stmmacenet_data *plat_dat;
	struct stmmac_resources stmmac_res;
	struct starfive_dwmac *dwmac;
	struct clk *clk_gtx;
	int err;

	err = stmmac_get_platform_resources(pdev, &stmmac_res);
	if (err)
		return dev_err_probe(&pdev->dev, err,
				     "failed to get resources\n");

	plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
	if (IS_ERR(plat_dat))
		return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
				     "dt configuration failed\n");

	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
	if (!dwmac)
		return -ENOMEM;

	dwmac->data = device_get_match_data(&pdev->dev);

	dwmac->clk_tx = devm_clk_get_enabled(&pdev->dev, "tx");
	if (IS_ERR(dwmac->clk_tx))
		return dev_err_probe(&pdev->dev, PTR_ERR(dwmac->clk_tx),
				     "error getting tx clock\n");

	clk_gtx = devm_clk_get_enabled(&pdev->dev, "gtx");
	if (IS_ERR(clk_gtx))
		return dev_err_probe(&pdev->dev, PTR_ERR(clk_gtx),
				     "error getting gtx clock\n");

	/* Generally, the rgmii_tx clock is provided by the internal clock,
	 * which needs to match the corresponding clock frequency according
	 * to different speeds. If the rgmii_tx clock is provided by the
	 * external rgmii_rxin, there is no need to configure the clock
	 * internally, because rgmii_rxin will be adaptively adjusted.
	 */
	if (!device_property_read_bool(&pdev->dev, "starfive,tx-use-rgmii-clk"))
		plat_dat->fix_mac_speed = starfive_dwmac_fix_mac_speed;

	dwmac->dev = &pdev->dev;
	plat_dat->bsp_priv = dwmac;
	plat_dat->dma_cfg->dche = true;

	err = starfive_dwmac_set_mode(plat_dat);
	if (err)
		return err;

	err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
	if (err) {
		stmmac_remove_config_dt(pdev, plat_dat);
		return err;
	}

	return 0;
}

static const struct starfive_dwmac_data jh7100_data = {
	.gtxclk_dlychain = 4,
};

static const struct of_device_id starfive_dwmac_match[] = {
	{ .compatible = "starfive,jh7100-dwmac", .data = &jh7100_data },
	{ .compatible = "starfive,jh7110-dwmac" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, starfive_dwmac_match);

static struct platform_driver starfive_dwmac_driver = {
	.probe  = starfive_dwmac_probe,
	.remove_new = stmmac_pltfr_remove,
	.driver = {
		.name = "starfive-dwmac",
		.pm = &stmmac_pltfr_pm_ops,
		.of_match_table = starfive_dwmac_match,
	},
};
module_platform_driver(starfive_dwmac_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("StarFive DWMAC platform driver");
MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");
