/*
 * Driver for the MDIO interface of Marvell network interfaces.
 *
 * Since the MDIO interface of Marvell network interfaces is shared
 * between all network interfaces, having a single driver allows to
 * handle concurrent accesses properly (you may have four Ethernet
 * ports, but they in fact share the same SMI interface to access
 * the MDIO bus). This driver is currently used by the mvneta and
 * mv643xx_eth drivers.
 *
 * Copyright (C) 2012 Marvell
 *
 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/acpi.h>
#include <linux/acpi_mdio.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_mdio.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/wait.h>

#define MVMDIO_SMI_DATA_SHIFT		0
#define MVMDIO_SMI_PHY_ADDR_SHIFT	16
#define MVMDIO_SMI_PHY_REG_SHIFT	21
#define MVMDIO_SMI_READ_OPERATION	BIT(26)
#define MVMDIO_SMI_WRITE_OPERATION	0
#define MVMDIO_SMI_READ_VALID		BIT(27)
#define MVMDIO_SMI_BUSY			BIT(28)
#define MVMDIO_ERR_INT_CAUSE		0x007C
#define  MVMDIO_ERR_INT_SMI_DONE	0x00000010
#define MVMDIO_ERR_INT_MASK		0x0080

#define MVMDIO_XSMI_MGNT_REG		0x0
#define  MVMDIO_XSMI_PHYADDR_SHIFT	16
#define  MVMDIO_XSMI_DEVADDR_SHIFT	21
#define  MVMDIO_XSMI_WRITE_OPERATION	(0x5 << 26)
#define  MVMDIO_XSMI_READ_OPERATION	(0x7 << 26)
#define  MVMDIO_XSMI_READ_VALID		BIT(29)
#define  MVMDIO_XSMI_BUSY		BIT(30)
#define MVMDIO_XSMI_ADDR_REG		0x8

#define MVMDIO_XSMI_CFG_REG		0xc
#define  MVMDIO_XSMI_CLKDIV_MASK	0x3
#define  MVMDIO_XSMI_CLKDIV_256		0x0
#define  MVMDIO_XSMI_CLKDIV_64		0x1
#define  MVMDIO_XSMI_CLKDIV_32		0x2
#define  MVMDIO_XSMI_CLKDIV_8		0x3

/*
 * SMI Timeout measurements:
 * - Kirkwood 88F6281 (Globalscale Dreamplug): 45us to 95us (Interrupt)
 * - Armada 370       (Globalscale Mirabox):   41us to 43us (Polled)
 */
#define MVMDIO_SMI_TIMEOUT		1000 /* 1000us = 1ms */

struct orion_mdio_dev {
	void __iomem *regs;
	struct clk *clk[4];
	/*
	 * If we have access to the error interrupt pin (which is
	 * somewhat misnamed as it not only reflects internal errors
	 * but also reflects SMI completion), use that to wait for
	 * SMI access completion instead of polling the SMI busy bit.
	 */
	int err_interrupt;
	wait_queue_head_t smi_busy_wait;
};

enum orion_mdio_bus_type {
	BUS_TYPE_SMI,
	BUS_TYPE_XSMI
};

struct orion_mdio_ops {
	int (*is_done)(struct orion_mdio_dev *);
};

/* Wait for the SMI unit to be ready for another operation
 */
static int orion_mdio_wait_ready(const struct orion_mdio_ops *ops,
				 struct mii_bus *bus)
{
	struct orion_mdio_dev *dev = bus->priv;
	unsigned long timeout;
	int done;

	if (dev->err_interrupt <= 0) {
		if (!read_poll_timeout_atomic(ops->is_done, done, done, 2,
					      MVMDIO_SMI_TIMEOUT, false, dev))
			return 0;
	} else {
		/* wait_event_timeout does not guarantee a delay of at
		 * least one whole jiffy, so timeout must be no less
		 * than two.
		 */
		timeout = max(usecs_to_jiffies(MVMDIO_SMI_TIMEOUT), 2);

		if (wait_event_timeout(dev->smi_busy_wait,
				       ops->is_done(dev), timeout))
			return 0;
	}

	dev_err(bus->parent, "Timeout: SMI busy for too long\n");
	return  -ETIMEDOUT;
}

static int orion_mdio_smi_is_done(struct orion_mdio_dev *dev)
{
	return !(readl(dev->regs) & MVMDIO_SMI_BUSY);
}

static const struct orion_mdio_ops orion_mdio_smi_ops = {
	.is_done = orion_mdio_smi_is_done,
};

static int orion_mdio_smi_read(struct mii_bus *bus, int mii_id,
			       int regnum)
{
	struct orion_mdio_dev *dev = bus->priv;
	u32 val;
	int ret;

	ret = orion_mdio_wait_ready(&orion_mdio_smi_ops, bus);
	if (ret < 0)
		return ret;

	writel(((mii_id << MVMDIO_SMI_PHY_ADDR_SHIFT) |
		(regnum << MVMDIO_SMI_PHY_REG_SHIFT)  |
		MVMDIO_SMI_READ_OPERATION),
	       dev->regs);

	ret = orion_mdio_wait_ready(&orion_mdio_smi_ops, bus);
	if (ret < 0)
		return ret;

	val = readl(dev->regs);
	if (!(val & MVMDIO_SMI_READ_VALID)) {
		dev_err(bus->parent, "SMI bus read not valid\n");
		return -ENODEV;
	}

	return val & GENMASK(15, 0);
}

static int orion_mdio_smi_write(struct mii_bus *bus, int mii_id,
				int regnum, u16 value)
{
	struct orion_mdio_dev *dev = bus->priv;
	int ret;

	ret = orion_mdio_wait_ready(&orion_mdio_smi_ops, bus);
	if (ret < 0)
		return ret;

	writel(((mii_id << MVMDIO_SMI_PHY_ADDR_SHIFT) |
		(regnum << MVMDIO_SMI_PHY_REG_SHIFT)  |
		MVMDIO_SMI_WRITE_OPERATION            |
		(value << MVMDIO_SMI_DATA_SHIFT)),
	       dev->regs);

	return 0;
}

static int orion_mdio_xsmi_is_done(struct orion_mdio_dev *dev)
{
	return !(readl(dev->regs + MVMDIO_XSMI_MGNT_REG) & MVMDIO_XSMI_BUSY);
}

static const struct orion_mdio_ops orion_mdio_xsmi_ops = {
	.is_done = orion_mdio_xsmi_is_done,
};

static int orion_mdio_xsmi_read_c45(struct mii_bus *bus, int mii_id,
				    int dev_addr, int regnum)
{
	struct orion_mdio_dev *dev = bus->priv;
	int ret;

	ret = orion_mdio_wait_ready(&orion_mdio_xsmi_ops, bus);
	if (ret < 0)
		return ret;

	writel(regnum, dev->regs + MVMDIO_XSMI_ADDR_REG);
	writel((mii_id << MVMDIO_XSMI_PHYADDR_SHIFT) |
	       (dev_addr << MVMDIO_XSMI_DEVADDR_SHIFT) |
	       MVMDIO_XSMI_READ_OPERATION,
	       dev->regs + MVMDIO_XSMI_MGNT_REG);

	ret = orion_mdio_wait_ready(&orion_mdio_xsmi_ops, bus);
	if (ret < 0)
		return ret;

	if (!(readl(dev->regs + MVMDIO_XSMI_MGNT_REG) &
	      MVMDIO_XSMI_READ_VALID)) {
		dev_err(bus->parent, "XSMI bus read not valid\n");
		return -ENODEV;
	}

	return readl(dev->regs + MVMDIO_XSMI_MGNT_REG) & GENMASK(15, 0);
}

static int orion_mdio_xsmi_write_c45(struct mii_bus *bus, int mii_id,
				     int dev_addr, int regnum, u16 value)
{
	struct orion_mdio_dev *dev = bus->priv;
	int ret;

	ret = orion_mdio_wait_ready(&orion_mdio_xsmi_ops, bus);
	if (ret < 0)
		return ret;

	writel(regnum, dev->regs + MVMDIO_XSMI_ADDR_REG);
	writel((mii_id << MVMDIO_XSMI_PHYADDR_SHIFT) |
	       (dev_addr << MVMDIO_XSMI_DEVADDR_SHIFT) |
	       MVMDIO_XSMI_WRITE_OPERATION | value,
	       dev->regs + MVMDIO_XSMI_MGNT_REG);

	return 0;
}

static void orion_mdio_xsmi_set_mdc_freq(struct mii_bus *bus)
{
	struct orion_mdio_dev *dev = bus->priv;
	struct clk *mg_core;
	u32 div, freq, cfg;

	if (device_property_read_u32(bus->parent, "clock-frequency", &freq))
		return;

	mg_core = of_clk_get_by_name(bus->parent->of_node, "mg_core_clk");
	if (IS_ERR(mg_core)) {
		dev_err(bus->parent,
			"MG core clock unknown, not changing MDC frequency");
		return;
	}

	div = clk_get_rate(mg_core) / (freq + 1) + 1;
	clk_put(mg_core);

	if (div <= 8)
		div = MVMDIO_XSMI_CLKDIV_8;
	else if (div <= 32)
		div = MVMDIO_XSMI_CLKDIV_32;
	else if (div <= 64)
		div = MVMDIO_XSMI_CLKDIV_64;
	else
		div = MVMDIO_XSMI_CLKDIV_256;

	cfg = readl(dev->regs + MVMDIO_XSMI_CFG_REG);
	cfg &= ~MVMDIO_XSMI_CLKDIV_MASK;
	cfg |= div;
	writel(cfg, dev->regs + MVMDIO_XSMI_CFG_REG);
}

static irqreturn_t orion_mdio_err_irq(int irq, void *dev_id)
{
	struct orion_mdio_dev *dev = dev_id;

	if (readl(dev->regs + MVMDIO_ERR_INT_CAUSE) &
			MVMDIO_ERR_INT_SMI_DONE) {
		writel(~MVMDIO_ERR_INT_SMI_DONE,
				dev->regs + MVMDIO_ERR_INT_CAUSE);
		wake_up(&dev->smi_busy_wait);
		return IRQ_HANDLED;
	}

	return IRQ_NONE;
}

static int orion_mdio_probe(struct platform_device *pdev)
{
	enum orion_mdio_bus_type type;
	struct resource *r;
	struct mii_bus *bus;
	struct orion_mdio_dev *dev;
	int i, ret;

	type = (uintptr_t)device_get_match_data(&pdev->dev);

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		dev_err(&pdev->dev, "No SMI register address given\n");
		return -ENODEV;
	}

	bus = devm_mdiobus_alloc_size(&pdev->dev,
				      sizeof(struct orion_mdio_dev));
	if (!bus)
		return -ENOMEM;

	switch (type) {
	case BUS_TYPE_SMI:
		bus->read = orion_mdio_smi_read;
		bus->write = orion_mdio_smi_write;
		break;
	case BUS_TYPE_XSMI:
		bus->read_c45 = orion_mdio_xsmi_read_c45;
		bus->write_c45 = orion_mdio_xsmi_write_c45;
		break;
	}

	bus->name = "orion_mdio_bus";
	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii",
		 dev_name(&pdev->dev));
	bus->parent = &pdev->dev;

	dev = bus->priv;
	dev->regs = devm_ioremap(&pdev->dev, r->start, resource_size(r));
	if (!dev->regs) {
		dev_err(&pdev->dev, "Unable to remap SMI register\n");
		return -ENODEV;
	}

	init_waitqueue_head(&dev->smi_busy_wait);

	if (pdev->dev.of_node) {
		for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
			dev->clk[i] = of_clk_get(pdev->dev.of_node, i);
			if (PTR_ERR(dev->clk[i]) == -EPROBE_DEFER) {
				ret = -EPROBE_DEFER;
				goto out_clk;
			}
			if (IS_ERR(dev->clk[i]))
				break;
			clk_prepare_enable(dev->clk[i]);
		}

		if (!IS_ERR(of_clk_get(pdev->dev.of_node,
				       ARRAY_SIZE(dev->clk))))
			dev_warn(&pdev->dev,
				 "unsupported number of clocks, limiting to the first "
				 __stringify(ARRAY_SIZE(dev->clk)) "\n");

		if (type == BUS_TYPE_XSMI)
			orion_mdio_xsmi_set_mdc_freq(bus);
	} else {
		dev->clk[0] = clk_get(&pdev->dev, NULL);
		if (PTR_ERR(dev->clk[0]) == -EPROBE_DEFER) {
			ret = -EPROBE_DEFER;
			goto out_clk;
		}
		if (!IS_ERR(dev->clk[0]))
			clk_prepare_enable(dev->clk[0]);
	}


	dev->err_interrupt = platform_get_irq_optional(pdev, 0);
	if (dev->err_interrupt > 0 &&
	    resource_size(r) < MVMDIO_ERR_INT_MASK + 4) {
		dev_err(&pdev->dev,
			"disabling interrupt, resource size is too small\n");
		dev->err_interrupt = 0;
	}
	if (dev->err_interrupt > 0) {
		ret = devm_request_irq(&pdev->dev, dev->err_interrupt,
					orion_mdio_err_irq,
					IRQF_SHARED, pdev->name, dev);
		if (ret)
			goto out_mdio;

		writel(MVMDIO_ERR_INT_SMI_DONE,
			dev->regs + MVMDIO_ERR_INT_MASK);

	} else if (dev->err_interrupt == -EPROBE_DEFER) {
		ret = -EPROBE_DEFER;
		goto out_mdio;
	}

	/* For the platforms not supporting DT/ACPI fall-back
	 * to mdiobus_register via of_mdiobus_register.
	 */
	if (is_acpi_node(pdev->dev.fwnode))
		ret = acpi_mdiobus_register(bus, pdev->dev.fwnode);
	else
		ret = of_mdiobus_register(bus, pdev->dev.of_node);
	if (ret < 0) {
		dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);
		goto out_mdio;
	}

	platform_set_drvdata(pdev, bus);

	return 0;

out_mdio:
	if (dev->err_interrupt > 0)
		writel(0, dev->regs + MVMDIO_ERR_INT_MASK);

out_clk:
	for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
		if (IS_ERR(dev->clk[i]))
			break;
		clk_disable_unprepare(dev->clk[i]);
		clk_put(dev->clk[i]);
	}

	return ret;
}

static void orion_mdio_remove(struct platform_device *pdev)
{
	struct mii_bus *bus = platform_get_drvdata(pdev);
	struct orion_mdio_dev *dev = bus->priv;
	int i;

	if (dev->err_interrupt > 0)
		writel(0, dev->regs + MVMDIO_ERR_INT_MASK);
	mdiobus_unregister(bus);

	for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
		if (IS_ERR(dev->clk[i]))
			break;
		clk_disable_unprepare(dev->clk[i]);
		clk_put(dev->clk[i]);
	}
}

static const struct of_device_id orion_mdio_match[] = {
	{ .compatible = "marvell,orion-mdio", .data = (void *)BUS_TYPE_SMI },
	{ .compatible = "marvell,xmdio", .data = (void *)BUS_TYPE_XSMI },
	{ }
};
MODULE_DEVICE_TABLE(of, orion_mdio_match);

#ifdef CONFIG_ACPI
static const struct acpi_device_id orion_mdio_acpi_match[] = {
	{ "MRVL0100", BUS_TYPE_SMI },
	{ "MRVL0101", BUS_TYPE_XSMI },
	{ },
};
MODULE_DEVICE_TABLE(acpi, orion_mdio_acpi_match);
#endif

static struct platform_driver orion_mdio_driver = {
	.probe = orion_mdio_probe,
	.remove_new = orion_mdio_remove,
	.driver = {
		.name = "orion-mdio",
		.of_match_table = orion_mdio_match,
		.acpi_match_table = ACPI_PTR(orion_mdio_acpi_match),
	},
};

module_platform_driver(orion_mdio_driver);

MODULE_DESCRIPTION("Marvell MDIO interface driver");
MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:orion-mdio");
