// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Adaptrum Anarion DWMAC glue layer
 *
 * Copyright (C) 2017, Adaptrum, Inc.
 * (Written by Alexandru Gagniuc <alex.g at adaptrum.com> for Adaptrum, Inc.)
 */

#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_net.h>
#include <linux/stmmac.h>

#include "stmmac.h"
#include "stmmac_platform.h"

#define GMAC_RESET_CONTROL_REG		0
#define GMAC_SW_CONFIG_REG		4
#define  GMAC_CONFIG_INTF_SEL_MASK	(0x7 << 0)
#define  GMAC_CONFIG_INTF_RGMII		(0x1 << 0)

struct anarion_gmac {
	uintptr_t ctl_block;
	uint32_t phy_intf_sel;
};

static uint32_t gmac_read_reg(struct anarion_gmac *gmac, uint8_t reg)
{
	return readl((void *)(gmac->ctl_block + reg));
};

static void gmac_write_reg(struct anarion_gmac *gmac, uint8_t reg, uint32_t val)
{
	writel(val, (void *)(gmac->ctl_block + reg));
}

static int anarion_gmac_init(struct platform_device *pdev, void *priv)
{
	uint32_t sw_config;
	struct anarion_gmac *gmac = priv;

	/* Reset logic, configure interface mode, then release reset. SIMPLE! */
	gmac_write_reg(gmac, GMAC_RESET_CONTROL_REG, 1);

	sw_config = gmac_read_reg(gmac, GMAC_SW_CONFIG_REG);
	sw_config &= ~GMAC_CONFIG_INTF_SEL_MASK;
	sw_config |= (gmac->phy_intf_sel & GMAC_CONFIG_INTF_SEL_MASK);
	gmac_write_reg(gmac, GMAC_SW_CONFIG_REG, sw_config);

	gmac_write_reg(gmac, GMAC_RESET_CONTROL_REG, 0);

	return 0;
}

static void anarion_gmac_exit(struct platform_device *pdev, void *priv)
{
	struct anarion_gmac *gmac = priv;

	gmac_write_reg(gmac, GMAC_RESET_CONTROL_REG, 1);
}

static struct anarion_gmac *anarion_config_dt(struct platform_device *pdev)
{
	struct anarion_gmac *gmac;
	phy_interface_t phy_mode;
	void __iomem *ctl_block;
	int err;

	ctl_block = devm_platform_ioremap_resource(pdev, 1);
	if (IS_ERR(ctl_block)) {
		dev_err(&pdev->dev, "Cannot get reset region (%ld)!\n",
			PTR_ERR(ctl_block));
		return ctl_block;
	}

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

	gmac->ctl_block = (uintptr_t)ctl_block;

	err = of_get_phy_mode(pdev->dev.of_node, &phy_mode);
	if (err)
		return ERR_PTR(err);

	switch (phy_mode) {
	case PHY_INTERFACE_MODE_RGMII:		/* Fall through */
	case PHY_INTERFACE_MODE_RGMII_ID	/* Fall through */:
	case PHY_INTERFACE_MODE_RGMII_RXID:	/* Fall through */
	case PHY_INTERFACE_MODE_RGMII_TXID:
		gmac->phy_intf_sel = GMAC_CONFIG_INTF_RGMII;
		break;
	default:
		dev_err(&pdev->dev, "Unsupported phy-mode (%d)\n",
			phy_mode);
		return ERR_PTR(-ENOTSUPP);
	}

	return gmac;
}

static int anarion_dwmac_probe(struct platform_device *pdev)
{
	int ret;
	struct anarion_gmac *gmac;
	struct plat_stmmacenet_data *plat_dat;
	struct stmmac_resources stmmac_res;

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

	gmac = anarion_config_dt(pdev);
	if (IS_ERR(gmac))
		return PTR_ERR(gmac);

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

	plat_dat->init = anarion_gmac_init;
	plat_dat->exit = anarion_gmac_exit;
	anarion_gmac_init(pdev, gmac);
	plat_dat->bsp_priv = gmac;

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

	return 0;
}

static const struct of_device_id anarion_dwmac_match[] = {
	{ .compatible = "adaptrum,anarion-gmac" },
	{ }
};
MODULE_DEVICE_TABLE(of, anarion_dwmac_match);

static struct platform_driver anarion_dwmac_driver = {
	.probe  = anarion_dwmac_probe,
	.remove = stmmac_pltfr_remove,
	.driver = {
		.name           = "anarion-dwmac",
		.pm		= &stmmac_pltfr_pm_ops,
		.of_match_table = anarion_dwmac_match,
	},
};
module_platform_driver(anarion_dwmac_driver);

MODULE_DESCRIPTION("Adaptrum Anarion DWMAC specific glue layer");
MODULE_AUTHOR("Alexandru Gagniuc <mr.nuke.me@gmail.com>");
MODULE_LICENSE("GPL v2");
