// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2014-2015 Hisilicon Limited.
 */

#include <linux/acpi.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

#define MDIO_DRV_NAME "Hi-HNS_MDIO"
#define MDIO_BUS_NAME "Hisilicon MII Bus"

#define MDIO_TIMEOUT			1000000

struct hns_mdio_sc_reg {
	u16 mdio_clk_en;
	u16 mdio_clk_dis;
	u16 mdio_reset_req;
	u16 mdio_reset_dreq;
	u16 mdio_clk_st;
	u16 mdio_reset_st;
};

struct hns_mdio_device {
	u8 __iomem *vbase;		/* mdio reg base address */
	struct regmap *subctrl_vbase;
	struct hns_mdio_sc_reg sc_reg;
};

/* mdio reg */
#define MDIO_COMMAND_REG		0x0
#define MDIO_ADDR_REG			0x4
#define MDIO_WDATA_REG			0x8
#define MDIO_RDATA_REG			0xc
#define MDIO_STA_REG			0x10

/* cfg phy bit map */
#define MDIO_CMD_DEVAD_M	0x1f
#define MDIO_CMD_DEVAD_S	0
#define MDIO_CMD_PRTAD_M	0x1f
#define MDIO_CMD_PRTAD_S	5
#define MDIO_CMD_OP_S		10
#define MDIO_CMD_ST_S		12
#define MDIO_CMD_START_B	14

#define MDIO_ADDR_DATA_M	0xffff
#define MDIO_ADDR_DATA_S	0

#define MDIO_WDATA_DATA_M	0xffff
#define MDIO_WDATA_DATA_S	0

#define MDIO_RDATA_DATA_M	0xffff
#define MDIO_RDATA_DATA_S	0

#define MDIO_STATE_STA_B	0

enum mdio_st_clause {
	MDIO_ST_CLAUSE_45 = 0,
	MDIO_ST_CLAUSE_22
};

enum mdio_c22_op_seq {
	MDIO_C22_WRITE = 1,
	MDIO_C22_READ = 2
};

enum mdio_c45_op_seq {
	MDIO_C45_WRITE_ADDR = 0,
	MDIO_C45_WRITE_DATA,
	MDIO_C45_READ_INCREMENT,
	MDIO_C45_READ
};

/* peri subctrl reg */
#define MDIO_SC_CLK_EN		0x338
#define MDIO_SC_CLK_DIS		0x33C
#define MDIO_SC_RESET_REQ	0xA38
#define MDIO_SC_RESET_DREQ	0xA3C
#define MDIO_SC_CLK_ST		0x531C
#define MDIO_SC_RESET_ST	0x5A1C

static void mdio_write_reg(u8 __iomem *base, u32 reg, u32 value)
{
	writel_relaxed(value, base + reg);
}

#define MDIO_WRITE_REG(a, reg, value) \
	mdio_write_reg((a)->vbase, (reg), (value))

static u32 mdio_read_reg(u8 __iomem *base, u32 reg)
{
	return readl_relaxed(base + reg);
}

#define mdio_set_field(origin, mask, shift, val) \
	do { \
		(origin) &= (~((mask) << (shift))); \
		(origin) |= (((val) & (mask)) << (shift)); \
	} while (0)

#define mdio_get_field(origin, mask, shift) (((origin) >> (shift)) & (mask))

static void mdio_set_reg_field(u8 __iomem *base, u32 reg, u32 mask, u32 shift,
			       u32 val)
{
	u32 origin = mdio_read_reg(base, reg);

	mdio_set_field(origin, mask, shift, val);
	mdio_write_reg(base, reg, origin);
}

#define MDIO_SET_REG_FIELD(dev, reg, mask, shift, val) \
	mdio_set_reg_field((dev)->vbase, (reg), (mask), (shift), (val))

static u32 mdio_get_reg_field(u8 __iomem *base, u32 reg, u32 mask, u32 shift)
{
	u32 origin;

	origin = mdio_read_reg(base, reg);
	return mdio_get_field(origin, mask, shift);
}

#define MDIO_GET_REG_FIELD(dev, reg, mask, shift) \
		mdio_get_reg_field((dev)->vbase, (reg), (mask), (shift))

#define MDIO_GET_REG_BIT(dev, reg, bit) \
		mdio_get_reg_field((dev)->vbase, (reg), 0x1ull, (bit))

#define MDIO_CHECK_SET_ST	1
#define MDIO_CHECK_CLR_ST	0

static int mdio_sc_cfg_reg_write(struct hns_mdio_device *mdio_dev,
				 u32 cfg_reg, u32 set_val,
				 u32 st_reg, u32 st_msk, u8 check_st)
{
	u32 time_cnt;
	u32 reg_value;
	int ret;

	regmap_write(mdio_dev->subctrl_vbase, cfg_reg, set_val);

	for (time_cnt = MDIO_TIMEOUT; time_cnt; time_cnt--) {
		ret = regmap_read(mdio_dev->subctrl_vbase, st_reg, &reg_value);
		if (ret)
			return ret;

		reg_value &= st_msk;
		if ((!!check_st) == (!!reg_value))
			break;
	}

	if ((!!check_st) != (!!reg_value))
		return -EBUSY;

	return 0;
}

static int hns_mdio_wait_ready(struct mii_bus *bus)
{
	struct hns_mdio_device *mdio_dev = bus->priv;
	u32 cmd_reg_value;
	int i;

	/* waitting for MDIO_COMMAND_REG 's mdio_start==0 */
	/* after that can do read or write*/
	for (i = 0; i < MDIO_TIMEOUT; i++) {
		cmd_reg_value = MDIO_GET_REG_BIT(mdio_dev,
						 MDIO_COMMAND_REG,
						 MDIO_CMD_START_B);
		if (!cmd_reg_value)
			break;
	}
	if ((i == MDIO_TIMEOUT) && cmd_reg_value)
		return -ETIMEDOUT;

	return 0;
}

static void hns_mdio_cmd_write(struct hns_mdio_device *mdio_dev,
			       u8 is_c45, u8 op, u8 phy_id, u16 cmd)
{
	u32 cmd_reg_value;
	u8 st = is_c45 ? MDIO_ST_CLAUSE_45 : MDIO_ST_CLAUSE_22;

	cmd_reg_value = st << MDIO_CMD_ST_S;
	cmd_reg_value |= op << MDIO_CMD_OP_S;
	cmd_reg_value |=
		(phy_id & MDIO_CMD_PRTAD_M) << MDIO_CMD_PRTAD_S;
	cmd_reg_value |= (cmd & MDIO_CMD_DEVAD_M) << MDIO_CMD_DEVAD_S;
	cmd_reg_value |= 1 << MDIO_CMD_START_B;

	MDIO_WRITE_REG(mdio_dev, MDIO_COMMAND_REG, cmd_reg_value);
}

/**
 * hns_mdio_write - access phy register
 * @bus: mdio bus
 * @phy_id: phy id
 * @regnum: register num
 * @data: register value
 *
 * Return 0 on success, negative on failure
 */
static int hns_mdio_write(struct mii_bus *bus,
			  int phy_id, int regnum, u16 data)
{
	int ret;
	struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;
	u8 devad = ((regnum >> 16) & 0x1f);
	u8 is_c45 = !!(regnum & MII_ADDR_C45);
	u16 reg = (u16)(regnum & 0xffff);
	u8 op;
	u16 cmd_reg_cfg;

	dev_dbg(&bus->dev, "mdio write %s,base is %p\n",
		bus->id, mdio_dev->vbase);
	dev_dbg(&bus->dev, "phy id=%d, is_c45=%d, devad=%d, reg=%#x, write data=%d\n",
		phy_id, is_c45, devad, reg, data);

	/* wait for ready */
	ret = hns_mdio_wait_ready(bus);
	if (ret) {
		dev_err(&bus->dev, "MDIO bus is busy\n");
		return ret;
	}

	if (!is_c45) {
		cmd_reg_cfg = reg;
		op = MDIO_C22_WRITE;
	} else {
		/* config the cmd-reg to write addr*/
		MDIO_SET_REG_FIELD(mdio_dev, MDIO_ADDR_REG, MDIO_ADDR_DATA_M,
				   MDIO_ADDR_DATA_S, reg);

		hns_mdio_cmd_write(mdio_dev, is_c45,
				   MDIO_C45_WRITE_ADDR, phy_id, devad);

		/* check for read or write opt is finished */
		ret = hns_mdio_wait_ready(bus);
		if (ret) {
			dev_err(&bus->dev, "MDIO bus is busy\n");
			return ret;
		}

		/* config the data needed writing */
		cmd_reg_cfg = devad;
		op = MDIO_C45_WRITE_DATA;
	}

	MDIO_SET_REG_FIELD(mdio_dev, MDIO_WDATA_REG, MDIO_WDATA_DATA_M,
			   MDIO_WDATA_DATA_S, data);

	hns_mdio_cmd_write(mdio_dev, is_c45, op, phy_id, cmd_reg_cfg);

	return 0;
}

/**
 * hns_mdio_read - access phy register
 * @bus: mdio bus
 * @phy_id: phy id
 * @regnum: register num
 *
 * Return phy register value
 */
static int hns_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
{
	int ret;
	u16 reg_val;
	u8 devad = ((regnum >> 16) & 0x1f);
	u8 is_c45 = !!(regnum & MII_ADDR_C45);
	u16 reg = (u16)(regnum & 0xffff);
	struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;

	dev_dbg(&bus->dev, "mdio read %s,base is %p\n",
		bus->id, mdio_dev->vbase);
	dev_dbg(&bus->dev, "phy id=%d, is_c45=%d, devad=%d, reg=%#x!\n",
		phy_id, is_c45, devad, reg);

	/* Step 1: wait for ready */
	ret = hns_mdio_wait_ready(bus);
	if (ret) {
		dev_err(&bus->dev, "MDIO bus is busy\n");
		return ret;
	}

	if (!is_c45) {
		hns_mdio_cmd_write(mdio_dev, is_c45,
				   MDIO_C22_READ, phy_id, reg);
	} else {
		MDIO_SET_REG_FIELD(mdio_dev, MDIO_ADDR_REG, MDIO_ADDR_DATA_M,
				   MDIO_ADDR_DATA_S, reg);

		/* Step 2; config the cmd-reg to write addr*/
		hns_mdio_cmd_write(mdio_dev, is_c45,
				   MDIO_C45_WRITE_ADDR, phy_id, devad);

		/* Step 3: check for read or write opt is finished */
		ret = hns_mdio_wait_ready(bus);
		if (ret) {
			dev_err(&bus->dev, "MDIO bus is busy\n");
			return ret;
		}

		hns_mdio_cmd_write(mdio_dev, is_c45,
				   MDIO_C45_READ, phy_id, devad);
	}

	/* Step 5: waitting for MDIO_COMMAND_REG 's mdio_start==0,*/
	/* check for read or write opt is finished */
	ret = hns_mdio_wait_ready(bus);
	if (ret) {
		dev_err(&bus->dev, "MDIO bus is busy\n");
		return ret;
	}

	reg_val = MDIO_GET_REG_BIT(mdio_dev, MDIO_STA_REG, MDIO_STATE_STA_B);
	if (reg_val) {
		dev_err(&bus->dev, " ERROR! MDIO Read failed!\n");
		return -EBUSY;
	}

	/* Step 6; get out data*/
	reg_val = (u16)MDIO_GET_REG_FIELD(mdio_dev, MDIO_RDATA_REG,
					  MDIO_RDATA_DATA_M, MDIO_RDATA_DATA_S);

	return reg_val;
}

/**
 * hns_mdio_reset - reset mdio bus
 * @bus: mdio bus
 *
 * Return 0 on success, negative on failure
 */
static int hns_mdio_reset(struct mii_bus *bus)
{
	struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;
	const struct hns_mdio_sc_reg *sc_reg;
	int ret;

	if (dev_of_node(bus->parent)) {
		if (!mdio_dev->subctrl_vbase) {
			dev_err(&bus->dev, "mdio sys ctl reg has not mapped\n");
			return -ENODEV;
		}

		sc_reg = &mdio_dev->sc_reg;
		/* 1. reset req, and read reset st check */
		ret = mdio_sc_cfg_reg_write(mdio_dev, sc_reg->mdio_reset_req,
					    0x1, sc_reg->mdio_reset_st, 0x1,
					    MDIO_CHECK_SET_ST);
		if (ret) {
			dev_err(&bus->dev, "MDIO reset fail\n");
			return ret;
		}

		/* 2. dis clk, and read clk st check */
		ret = mdio_sc_cfg_reg_write(mdio_dev, sc_reg->mdio_clk_dis,
					    0x1, sc_reg->mdio_clk_st, 0x1,
					    MDIO_CHECK_CLR_ST);
		if (ret) {
			dev_err(&bus->dev, "MDIO dis clk fail\n");
			return ret;
		}

		/* 3. reset dreq, and read reset st check */
		ret = mdio_sc_cfg_reg_write(mdio_dev, sc_reg->mdio_reset_dreq,
					    0x1, sc_reg->mdio_reset_st, 0x1,
					    MDIO_CHECK_CLR_ST);
		if (ret) {
			dev_err(&bus->dev, "MDIO dis clk fail\n");
			return ret;
		}

		/* 4. en clk, and read clk st check */
		ret = mdio_sc_cfg_reg_write(mdio_dev, sc_reg->mdio_clk_en,
					    0x1, sc_reg->mdio_clk_st, 0x1,
					    MDIO_CHECK_SET_ST);
		if (ret)
			dev_err(&bus->dev, "MDIO en clk fail\n");
	} else if (is_acpi_node(bus->parent->fwnode)) {
		acpi_status s;

		s = acpi_evaluate_object(ACPI_HANDLE(bus->parent),
					 "_RST", NULL, NULL);
		if (ACPI_FAILURE(s)) {
			dev_err(&bus->dev, "Reset failed, return:%#x\n", s);
			ret = -EBUSY;
		} else {
			ret = 0;
		}
	} else {
		dev_err(&bus->dev, "Can not get cfg data from DT or ACPI\n");
		ret = -ENXIO;
	}
	return ret;
}

/**
 * hns_mdio_probe - probe mdio device
 * @pdev: mdio platform device
 *
 * Return 0 on success, negative on failure
 */
static int hns_mdio_probe(struct platform_device *pdev)
{
	struct hns_mdio_device *mdio_dev;
	struct mii_bus *new_bus;
	int ret;

	if (!pdev) {
		dev_err(NULL, "pdev is NULL!\r\n");
		return -ENODEV;
	}

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

	new_bus = devm_mdiobus_alloc(&pdev->dev);
	if (!new_bus) {
		dev_err(&pdev->dev, "mdiobus_alloc fail!\n");
		return -ENOMEM;
	}

	new_bus->name = MDIO_BUS_NAME;
	new_bus->read = hns_mdio_read;
	new_bus->write = hns_mdio_write;
	new_bus->reset = hns_mdio_reset;
	new_bus->priv = mdio_dev;
	new_bus->parent = &pdev->dev;

	mdio_dev->vbase = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(mdio_dev->vbase)) {
		ret = PTR_ERR(mdio_dev->vbase);
		return ret;
	}

	platform_set_drvdata(pdev, new_bus);
	snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%s", "Mii",
		 dev_name(&pdev->dev));
	if (dev_of_node(&pdev->dev)) {
		struct of_phandle_args reg_args;

		ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
						       "subctrl-vbase",
						       4,
						       0,
						       &reg_args);
		if (!ret) {
			mdio_dev->subctrl_vbase =
				syscon_node_to_regmap(reg_args.np);
			if (IS_ERR(mdio_dev->subctrl_vbase)) {
				dev_warn(&pdev->dev, "syscon_node_to_regmap error\n");
				mdio_dev->subctrl_vbase = NULL;
			} else {
				if (reg_args.args_count == 4) {
					mdio_dev->sc_reg.mdio_clk_en =
						(u16)reg_args.args[0];
					mdio_dev->sc_reg.mdio_clk_dis =
						(u16)reg_args.args[0] + 4;
					mdio_dev->sc_reg.mdio_reset_req =
						(u16)reg_args.args[1];
					mdio_dev->sc_reg.mdio_reset_dreq =
						(u16)reg_args.args[1] + 4;
					mdio_dev->sc_reg.mdio_clk_st =
						(u16)reg_args.args[2];
					mdio_dev->sc_reg.mdio_reset_st =
						(u16)reg_args.args[3];
				} else {
					/* for compatible */
					mdio_dev->sc_reg.mdio_clk_en =
						MDIO_SC_CLK_EN;
					mdio_dev->sc_reg.mdio_clk_dis =
						MDIO_SC_CLK_DIS;
					mdio_dev->sc_reg.mdio_reset_req =
						MDIO_SC_RESET_REQ;
					mdio_dev->sc_reg.mdio_reset_dreq =
						MDIO_SC_RESET_DREQ;
					mdio_dev->sc_reg.mdio_clk_st =
						MDIO_SC_CLK_ST;
					mdio_dev->sc_reg.mdio_reset_st =
						MDIO_SC_RESET_ST;
				}
			}
		} else {
			dev_warn(&pdev->dev, "find syscon ret = %#x\n", ret);
			mdio_dev->subctrl_vbase = NULL;
		}

		ret = of_mdiobus_register(new_bus, pdev->dev.of_node);
	} else if (is_acpi_node(pdev->dev.fwnode)) {
		/* Clear all the IRQ properties */
		memset(new_bus->irq, PHY_POLL, 4 * PHY_MAX_ADDR);

		/* Mask out all PHYs from auto probing. */
		new_bus->phy_mask = ~0;

		/* Register the MDIO bus */
		ret = mdiobus_register(new_bus);
	} else {
		dev_err(&pdev->dev, "Can not get cfg data from DT or ACPI\n");
		ret = -ENXIO;
	}

	if (ret) {
		dev_err(&pdev->dev, "Cannot register as MDIO bus!\n");
		platform_set_drvdata(pdev, NULL);
		return ret;
	}

	return 0;
}

/**
 * hns_mdio_remove - remove mdio device
 * @pdev: mdio platform device
 *
 * Return 0 on success, negative on failure
 */
static int hns_mdio_remove(struct platform_device *pdev)
{
	struct mii_bus *bus;

	bus = platform_get_drvdata(pdev);

	mdiobus_unregister(bus);
	platform_set_drvdata(pdev, NULL);
	return 0;
}

static const struct of_device_id hns_mdio_match[] = {
	{.compatible = "hisilicon,mdio"},
	{.compatible = "hisilicon,hns-mdio"},
	{}
};
MODULE_DEVICE_TABLE(of, hns_mdio_match);

static const struct acpi_device_id hns_mdio_acpi_match[] = {
	{ "HISI0141", 0 },
	{ },
};
MODULE_DEVICE_TABLE(acpi, hns_mdio_acpi_match);

static struct platform_driver hns_mdio_driver = {
	.probe = hns_mdio_probe,
	.remove = hns_mdio_remove,
	.driver = {
		   .name = MDIO_DRV_NAME,
		   .of_match_table = hns_mdio_match,
		   .acpi_match_table = ACPI_PTR(hns_mdio_acpi_match),
		   },
};

module_platform_driver(hns_mdio_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
MODULE_DESCRIPTION("Hisilicon HNS MDIO driver");
MODULE_ALIAS("platform:" MDIO_DRV_NAME);
