// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2021 BayLibre, SAS
 */

#include <asm/io.h>
#include <dm.h>
#include <phy.h>
#include "designware.h"
#include <dm/device_compat.h>
#include <linux/err.h>

#define ETH_REG_0		0x0
#define ETH_REG_1		0x4
#define ETH_REG_2		0x18
#define ETH_REG_3		0x1c

#define GX_ETH_REG_0_PHY_INTF		BIT(0)
#define GX_ETH_REG_0_TX_PHASE(x)	(((x) & 3) << 5)
#define GX_ETH_REG_0_TX_RATIO(x)	(((x) & 7) << 7)
#define GX_ETH_REG_0_PHY_CLK_EN	BIT(10)
#define GX_ETH_REG_0_INVERT_RMII_CLK	BIT(11)
#define GX_ETH_REG_0_CLK_EN		BIT(12)

#define AXG_ETH_REG_0_PHY_INTF_RGMII	BIT(0)
#define AXG_ETH_REG_0_PHY_INTF_RMII	BIT(2)
#define AXG_ETH_REG_0_TX_PHASE(x)	(((x) & 3) << 5)
#define AXG_ETH_REG_0_TX_RATIO(x)	(((x) & 7) << 7)
#define AXG_ETH_REG_0_PHY_CLK_EN	BIT(10)
#define AXG_ETH_REG_0_INVERT_RMII_CLK	BIT(11)
#define AXG_ETH_REG_0_CLK_EN		BIT(12)

struct dwmac_meson8b_plat {
	struct dw_eth_pdata dw_eth_pdata;
	int (*dwmac_setup)(struct udevice *dev, struct eth_pdata *edata);
	void *regs;
};

static int dwmac_meson8b_of_to_plat(struct udevice *dev)
{
	struct dwmac_meson8b_plat *pdata = dev_get_plat(dev);

	pdata->regs = dev_read_addr_index_ptr(dev, 1);
	if (!pdata->regs)
		return -EINVAL;

	pdata->dwmac_setup = (void *)dev_get_driver_data(dev);
	if (!pdata->dwmac_setup)
		return -EINVAL;

	return designware_eth_of_to_plat(dev);
}

static int dwmac_setup_axg(struct udevice *dev, struct eth_pdata *edata)
{
	struct dwmac_meson8b_plat *plat = dev_get_plat(dev);

	switch (edata->phy_interface) {
	case PHY_INTERFACE_MODE_RGMII:
	case PHY_INTERFACE_MODE_RGMII_ID:
		/* Set RGMII mode */
		setbits_le32(plat->regs + ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RGMII |
						     AXG_ETH_REG_0_TX_PHASE(1) |
						     AXG_ETH_REG_0_TX_RATIO(4) |
						     AXG_ETH_REG_0_PHY_CLK_EN |
						     AXG_ETH_REG_0_CLK_EN);
		break;

	case PHY_INTERFACE_MODE_RGMII_RXID:
	case PHY_INTERFACE_MODE_RGMII_TXID:
		/* TOFIX: handle amlogic,tx-delay-ns & rx-internal-delay-ps from DT */
		setbits_le32(plat->regs + ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RGMII |
						     AXG_ETH_REG_0_TX_RATIO(4) |
						     AXG_ETH_REG_0_PHY_CLK_EN |
						     AXG_ETH_REG_0_CLK_EN);
		break;

	case PHY_INTERFACE_MODE_RMII:
		/* Set RMII mode */
		out_le32(plat->regs + ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RMII |
						 AXG_ETH_REG_0_INVERT_RMII_CLK |
						 AXG_ETH_REG_0_CLK_EN);
		break;
	default:
		dev_err(dev, "Unsupported PHY mode\n");
		return -EINVAL;
	}

	return 0;
}

static int dwmac_setup_gx(struct udevice *dev, struct eth_pdata *edata)
{
	struct dwmac_meson8b_plat *plat = dev_get_plat(dev);

	switch (edata->phy_interface) {
	case PHY_INTERFACE_MODE_RGMII:
	case PHY_INTERFACE_MODE_RGMII_ID:
		/* Set RGMII mode */
		setbits_le32(plat->regs + ETH_REG_0, GX_ETH_REG_0_PHY_INTF |
						     GX_ETH_REG_0_TX_PHASE(1) |
						     GX_ETH_REG_0_TX_RATIO(4) |
						     GX_ETH_REG_0_PHY_CLK_EN |
						     GX_ETH_REG_0_CLK_EN);

		break;

	case PHY_INTERFACE_MODE_RGMII_RXID:
	case PHY_INTERFACE_MODE_RGMII_TXID:
		/* TOFIX: handle amlogic,tx-delay-ns & rx-internal-delay-ps from DT */
		setbits_le32(plat->regs + ETH_REG_0, GX_ETH_REG_0_PHY_INTF |
						     GX_ETH_REG_0_TX_RATIO(4) |
						     GX_ETH_REG_0_PHY_CLK_EN |
						     GX_ETH_REG_0_CLK_EN);

		break;

	case PHY_INTERFACE_MODE_RMII:
		/* Set RMII mode */
		out_le32(plat->regs + ETH_REG_0, GX_ETH_REG_0_INVERT_RMII_CLK |
						 GX_ETH_REG_0_CLK_EN);

		if (!IS_ENABLED(CONFIG_MESON_GXBB))
			writel(0x10110181, plat->regs + ETH_REG_2);

		break;
	default:
		dev_err(dev, "Unsupported PHY mode\n");
		return -EINVAL;
	}

	return 0;
}

static int dwmac_meson8b_probe(struct udevice *dev)
{
	struct dwmac_meson8b_plat *pdata = dev_get_plat(dev);
	struct eth_pdata *edata = &pdata->dw_eth_pdata.eth_pdata;
	int ret;

	ret = pdata->dwmac_setup(dev, edata);
	if (ret)
		return ret;

	return designware_eth_probe(dev);
}

static const struct udevice_id dwmac_meson8b_ids[] = {
	{ .compatible = "amlogic,meson-gxbb-dwmac", .data = (ulong)dwmac_setup_gx },
	{ .compatible = "amlogic,meson-g12a-dwmac", .data = (ulong)dwmac_setup_axg },
	{ .compatible = "amlogic,meson-axg-dwmac", .data = (ulong)dwmac_setup_axg },
	{ }
};

U_BOOT_DRIVER(dwmac_meson8b) = {
	.name		= "dwmac_meson8b",
	.id		= UCLASS_ETH,
	.of_match	= dwmac_meson8b_ids,
	.of_to_plat = dwmac_meson8b_of_to_plat,
	.probe		= dwmac_meson8b_probe,
	.ops		= &designware_eth_ops,
	.priv_auto	= sizeof(struct dw_eth_dev),
	.plat_auto	= sizeof(struct dwmac_meson8b_plat),
	.flags		= DM_FLAG_ALLOC_PRIV_DMA,
};
