// SPDX-License-Identifier: GPL-2.0+
#include <linux/bitfield.h>
#include <linux/firmware.h>
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/pinctrl/consumer.h>
#include <linux/phy.h>

#define MEDAITEK_2P5GE_PHY_DMB_FW "mediatek-2p5ge-phy-dmb.bin"
#define MEDIATEK_2P5GE_PHY_PMB_FW "mediatek-2p5ge-phy-pmb.bin"

#define MD32_EN_CFG	0x18
#define   MD32_EN	BIT(0)

#define BASE100T_STATUS_EXTEND		(0x10)
#define BASE1000T_STATUS_EXTEND		(0x11)
#define EXTEND_CTRL_AND_STATUS		(0x16)

#define PHY_AUX_CTRL_STATUS		(0x1d)
#define   PHY_AUX_DPX_MASK		GENMASK(5, 5)
#define   PHY_AUX_SPEED_MASK		GENMASK(4, 2)

/* Registers on MDIO_MMD_VEND2 */
#define MTK_PHY_LED0_ON_CTRL			(0x24)
#define   MTK_PHY_LED0_POLARITY			BIT(14)

enum {
	PHY_AUX_SPD_10 = 0,
	PHY_AUX_SPD_100,
	PHY_AUX_SPD_1000,
	PHY_AUX_SPD_2500,
};

static int mt798x_2p5ge_phy_probe(struct phy_device *phydev)
{
	struct pinctrl *pinctrl;

	phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
			 MTK_PHY_LED0_POLARITY);

	pinctrl = devm_pinctrl_get_select_default(&phydev->mdio.dev);
	if (IS_ERR(pinctrl)) {
		dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n");
		return PTR_ERR(pinctrl);
	}

	return 0;
}

static int mt798x_2p5ge_phy_config_init(struct phy_device *phydev)
{
	int ret;
	int i;
	const struct firmware *fw;
	struct device *dev = &phydev->mdio.dev;
	struct device_node *np;
	void __iomem *dmb_addr;
	void __iomem *pmb_addr;
	void __iomem *mcucsr_base;
	u16 reg;

	np = of_find_compatible_node(NULL, NULL, "mediatek,2p5gphy-fw");
	if (!np)
		return -ENOENT;

	dmb_addr = of_iomap(np, 0);
	if (!dmb_addr)
		return -ENOMEM;
	pmb_addr = of_iomap(np, 1);
	if (!pmb_addr)
		return -ENOMEM;
	mcucsr_base = of_iomap(np, 2);
	if (!mcucsr_base)
		return -ENOMEM;

	ret = request_firmware(&fw, MEDAITEK_2P5GE_PHY_DMB_FW, dev);
	if (ret) {
		dev_err(dev, "failed to load firmware: %s, ret: %d\n",
			MEDAITEK_2P5GE_PHY_DMB_FW, ret);
		return ret;
	}
	for (i = 0; i < fw->size - 1; i += 4)
		writel(*((uint32_t *)(fw->data + i)), dmb_addr + i);
	release_firmware(fw);

	ret = request_firmware(&fw, MEDIATEK_2P5GE_PHY_PMB_FW, dev);
	if (ret) {
		dev_err(dev, "failed to load firmware: %s, ret: %d\n",
			MEDIATEK_2P5GE_PHY_PMB_FW, ret);
		return ret;
	}
	for (i = 0; i < fw->size - 1; i += 4)
		writel(*((uint32_t *)(fw->data + i)), pmb_addr + i);
	release_firmware(fw);

	reg = readw(mcucsr_base + MD32_EN_CFG);
	writew(reg | MD32_EN, mcucsr_base + MD32_EN_CFG);
	dev_info(dev, "Firmware loading/trigger ok.\n");

	return 0;
}

static int mt798x_2p5ge_phy_config_aneg(struct phy_device *phydev)
{
	bool changed = false;
	u32 adv;
	int ret;

	if (phydev->autoneg == AUTONEG_DISABLE) {
		/* Configure half duplex with genphy_setup_forced,
		 * because genphy_c45_pma_setup_forced does not support.
		 */
		return phydev->duplex != DUPLEX_FULL
			? genphy_setup_forced(phydev)
			: genphy_c45_pma_setup_forced(phydev);
	}

	ret = genphy_c45_an_config_aneg(phydev);
	if (ret < 0)
		return ret;
	if (ret > 0)
		changed = true;

	adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
	ret = phy_modify_changed(phydev, MII_CTRL1000,
				 ADVERTISE_1000FULL | ADVERTISE_1000HALF,
				 adv);
	if (ret < 0)
		return ret;
	if (ret > 0)
		changed = true;

	return genphy_c45_check_and_restart_aneg(phydev, changed);
}

static int mt798x_2p5ge_phy_get_features(struct phy_device *phydev)
{
	int ret;

	ret = genphy_read_abilities(phydev);
	if (ret)
		return ret;

	/* We don't support HDX at MAC layer on mt798x.
	 * So mask phy's HDX capabilities, too.
	 */
	linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
			 phydev->supported);
	linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
			 phydev->supported);
	linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
			 phydev->supported);
	linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
			 phydev->supported);
	linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);

	return 0;
}

static int mt798x_2p5ge_phy_read_status(struct phy_device *phydev)
{
	int ret;

	ret = genphy_update_link(phydev);
	if (ret)
		return ret;

	phydev->speed = SPEED_UNKNOWN;
	phydev->duplex = DUPLEX_UNKNOWN;
	phydev->pause = 0;
	phydev->asym_pause = 0;

	if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
		ret = genphy_c45_read_lpa(phydev);
		if (ret < 0)
			return ret;

		/* Read the link partner's 1G advertisement */
		ret = phy_read(phydev, MII_STAT1000);
		if (ret < 0)
			return ret;
		mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret);
	} else if (phydev->autoneg == AUTONEG_DISABLE) {
		linkmode_zero(phydev->lp_advertising);
	}

	ret = phy_read(phydev, PHY_AUX_CTRL_STATUS);
	if (ret < 0)
		return ret;

	/* Actually this phy supports only FDX */
	phydev->duplex = (ret & PHY_AUX_DPX_MASK) ? DUPLEX_FULL : DUPLEX_HALF;
	switch (FIELD_GET(PHY_AUX_SPEED_MASK, ret)) {
	case PHY_AUX_SPD_10:
		phydev->speed = SPEED_10;
		break;
	case PHY_AUX_SPD_100:
		phydev->speed = SPEED_100;
		break;
	case PHY_AUX_SPD_1000:
		phydev->speed = SPEED_1000;
		break;
	case PHY_AUX_SPD_2500:
		phydev->speed = SPEED_2500;
		phydev->duplex = DUPLEX_FULL; /* 2.5G must be FDX */
		break;
	}

	return 0;
}

static struct phy_driver mtk_gephy_driver[] = {
	{
		PHY_ID_MATCH_EXACT(0x00339c11),
		.name		= "MediaTek MT798x 2.5GbE PHY",
		.probe		= mt798x_2p5ge_phy_probe,
		.config_init	= mt798x_2p5ge_phy_config_init,
		.config_aneg    = mt798x_2p5ge_phy_config_aneg,
		.get_features	= mt798x_2p5ge_phy_get_features,
		.read_status	= mt798x_2p5ge_phy_read_status,
		//.config_intr	= genphy_no_config_intr,
		//.handle_interrupt = genphy_no_ack_interrupt,
		//.suspend	= genphy_suspend,
		//.resume		= genphy_resume,
	},
};

module_phy_driver(mtk_gephy_driver);

static struct mdio_device_id __maybe_unused mtk_2p5ge_phy_tbl[] = {
	{ PHY_ID_MATCH_VENDOR(0x00339c00) },
	{ }
};

MODULE_DESCRIPTION("MediaTek 2.5Gb Ethernet PHY driver");
MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
MODULE_LICENSE("GPL");

MODULE_DEVICE_TABLE(mdio, mtk_2p5ge_phy_tbl);
