// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
 *
 * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
 *	Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
 */

#include <clk.h>
#include <dm.h>
#include <dma.h>
#include <log.h>
#include <malloc.h>
#include <miiphy.h>
#include <net.h>
#include <reset.h>
#include <wait_bit.h>
#include <asm/io.h>
#include <dm/device_compat.h>
#include <linux/delay.h>
#include <linux/printk.h>

#define ETH_PORT_STR			"brcm,enetsw-port"

#define ETH_RX_DESC			PKTBUFSRX
#define ETH_ZLEN			60
#define ETH_TIMEOUT			100

#define ETH_MAX_PORT			8
#define ETH_RGMII_PORT0			4

/* Port traffic control */
#define ETH_PTCTRL_REG(x)		(0x0 + (x))
#define ETH_PTCTRL_RXDIS_SHIFT		0
#define ETH_PTCTRL_RXDIS_MASK		(1 << ETH_PTCTRL_RXDIS_SHIFT)
#define ETH_PTCTRL_TXDIS_SHIFT		1
#define ETH_PTCTRL_TXDIS_MASK		(1 << ETH_PTCTRL_TXDIS_SHIFT)

/* Switch mode register */
#define ETH_SWMODE_REG			0xb
#define ETH_SWMODE_FWD_EN_SHIFT		1
#define ETH_SWMODE_FWD_EN_MASK		(1 << ETH_SWMODE_FWD_EN_SHIFT)

/* IMP override Register */
#define ETH_IMPOV_REG			0xe
#define ETH_IMPOV_LINKUP_SHIFT		0
#define ETH_IMPOV_LINKUP_MASK		(1 << ETH_IMPOV_LINKUP_SHIFT)
#define ETH_IMPOV_FDX_SHIFT		1
#define ETH_IMPOV_FDX_MASK		(1 << ETH_IMPOV_FDX_SHIFT)
#define ETH_IMPOV_100_SHIFT		2
#define ETH_IMPOV_100_MASK		(1 << ETH_IMPOV_100_SHIFT)
#define ETH_IMPOV_1000_SHIFT		3
#define ETH_IMPOV_1000_MASK		(1 << ETH_IMPOV_1000_SHIFT)
#define ETH_IMPOV_RXFLOW_SHIFT		4
#define ETH_IMPOV_RXFLOW_MASK		(1 << ETH_IMPOV_RXFLOW_SHIFT)
#define ETH_IMPOV_TXFLOW_SHIFT		5
#define ETH_IMPOV_TXFLOW_MASK		(1 << ETH_IMPOV_TXFLOW_SHIFT)
#define ETH_IMPOV_FORCE_SHIFT		7
#define ETH_IMPOV_FORCE_MASK		(1 << ETH_IMPOV_FORCE_SHIFT)

/* Port override Register */
#define ETH_PORTOV_REG(x)		(0x58 + (x))
#define ETH_PORTOV_LINKUP_SHIFT		0
#define ETH_PORTOV_LINKUP_MASK		(1 << ETH_PORTOV_LINKUP_SHIFT)
#define ETH_PORTOV_FDX_SHIFT		1
#define ETH_PORTOV_FDX_MASK		(1 << ETH_PORTOV_FDX_SHIFT)
#define ETH_PORTOV_100_SHIFT		2
#define ETH_PORTOV_100_MASK		(1 << ETH_PORTOV_100_SHIFT)
#define ETH_PORTOV_1000_SHIFT		3
#define ETH_PORTOV_1000_MASK		(1 << ETH_PORTOV_1000_SHIFT)
#define ETH_PORTOV_RXFLOW_SHIFT		4
#define ETH_PORTOV_RXFLOW_MASK		(1 << ETH_PORTOV_RXFLOW_SHIFT)
#define ETH_PORTOV_TXFLOW_SHIFT		5
#define ETH_PORTOV_TXFLOW_MASK		(1 << ETH_PORTOV_TXFLOW_SHIFT)
#define ETH_PORTOV_ENABLE_SHIFT		6
#define ETH_PORTOV_ENABLE_MASK		(1 << ETH_PORTOV_ENABLE_SHIFT)

/* Port RGMII control register */
#define ETH_RGMII_CTRL_REG(x)		(0x60 + (x))
#define ETH_RGMII_CTRL_GMII_CLK_EN	(1 << 7)
#define ETH_RGMII_CTRL_MII_OVERRIDE_EN	(1 << 6)
#define ETH_RGMII_CTRL_MII_MODE_MASK	(3 << 4)
#define ETH_RGMII_CTRL_RGMII_MODE	(0 << 4)
#define ETH_RGMII_CTRL_MII_MODE		(1 << 4)
#define ETH_RGMII_CTRL_RVMII_MODE	(2 << 4)
#define ETH_RGMII_CTRL_TIMING_SEL_EN	(1 << 0)

/* Port RGMII timing register */
#define ENETSW_RGMII_TIMING_REG(x)	(0x68 + (x))

/* MDIO control register */
#define MII_SC_REG			0xb0
#define MII_SC_EXT_SHIFT		16
#define MII_SC_EXT_MASK			(1 << MII_SC_EXT_SHIFT)
#define MII_SC_REG_SHIFT		20
#define MII_SC_PHYID_SHIFT		25
#define MII_SC_RD_SHIFT			30
#define MII_SC_RD_MASK			(1 << MII_SC_RD_SHIFT)
#define MII_SC_WR_SHIFT			31
#define MII_SC_WR_MASK			(1 << MII_SC_WR_SHIFT)

/* MDIO data register */
#define MII_DAT_REG			0xb4

/* Global Management Configuration Register */
#define ETH_GMCR_REG			0x200
#define ETH_GMCR_RST_MIB_SHIFT		0
#define ETH_GMCR_RST_MIB_MASK		(1 << ETH_GMCR_RST_MIB_SHIFT)

/* Jumbo control register port mask register */
#define ETH_JMBCTL_PORT_REG		0x4004

/* Jumbo control mib good frame register */
#define ETH_JMBCTL_MAXSIZE_REG		0x4008

/* ETH port data */
struct bcm_enetsw_port {
	bool used;
	const char *name;
	/* Config */
	bool bypass_link;
	int force_speed;
	bool force_duplex_full;
	/* PHY */
	int phy_id;
};

/* ETH data */
struct bcm6368_eth_priv {
	void __iomem *base;
	/* DMA */
	struct dma rx_dma;
	struct dma tx_dma;
	/* Ports */
	uint8_t num_ports;
	struct bcm_enetsw_port used_ports[ETH_MAX_PORT];
	int sw_port_link[ETH_MAX_PORT];
	bool rgmii_override;
	bool rgmii_timing;
	/* PHY */
	int phy_id;
};

static inline bool bcm_enet_port_is_rgmii(int portid)
{
	return portid >= ETH_RGMII_PORT0;
}

static int bcm6368_mdio_read(struct bcm6368_eth_priv *priv, uint8_t ext,
			     int phy_id, int reg)
{
	uint32_t val;

	writel_be(0, priv->base + MII_SC_REG);

	val = MII_SC_RD_MASK |
	      (phy_id << MII_SC_PHYID_SHIFT) |
	      (reg << MII_SC_REG_SHIFT);

	if (ext)
		val |= MII_SC_EXT_MASK;

	writel_be(val, priv->base + MII_SC_REG);
	udelay(50);

	return readw_be(priv->base + MII_DAT_REG);
}

static int bcm6368_mdio_write(struct bcm6368_eth_priv *priv, uint8_t ext,
			      int phy_id, int reg, u16 data)
{
	uint32_t val;

	writel_be(0, priv->base + MII_SC_REG);

	val = MII_SC_WR_MASK |
	      (phy_id << MII_SC_PHYID_SHIFT) |
	      (reg << MII_SC_REG_SHIFT);

	if (ext)
		val |= MII_SC_EXT_MASK;

	val |= data;

	writel_be(val, priv->base + MII_SC_REG);
	udelay(50);

	return 0;
}

static int bcm6368_eth_free_pkt(struct udevice *dev, uchar *packet, int len)
{
	struct bcm6368_eth_priv *priv = dev_get_priv(dev);

	return dma_prepare_rcv_buf(&priv->rx_dma, packet, len);
}

static int bcm6368_eth_recv(struct udevice *dev, int flags, uchar **packetp)
{
	struct bcm6368_eth_priv *priv = dev_get_priv(dev);

	return dma_receive(&priv->rx_dma, (void**)packetp, NULL);
}

static int bcm6368_eth_send(struct udevice *dev, void *packet, int length)
{
	struct bcm6368_eth_priv *priv = dev_get_priv(dev);

	/* pad packets smaller than ETH_ZLEN */
	if (length < ETH_ZLEN) {
		memset(packet + length, 0, ETH_ZLEN - length);
		length = ETH_ZLEN;
	}

	return dma_send(&priv->tx_dma, packet, length, NULL);
}

static int bcm6368_eth_adjust_link(struct udevice *dev)
{
	struct bcm6368_eth_priv *priv = dev_get_priv(dev);
	unsigned int i;

	for (i = 0; i < priv->num_ports; i++) {
		struct bcm_enetsw_port *port;
		int val, j, up, adv, lpa, speed, duplex, media;
		int external_phy = bcm_enet_port_is_rgmii(i);
		u8 override;

		port = &priv->used_ports[i];
		if (!port->used)
			continue;

		if (port->bypass_link)
			continue;

		/* dummy read to clear */
		for (j = 0; j < 2; j++)
			val = bcm6368_mdio_read(priv, external_phy,
						port->phy_id, MII_BMSR);

		if (val == 0xffff)
			continue;

		up = (val & BMSR_LSTATUS) ? 1 : 0;
		if (!(up ^ priv->sw_port_link[i]))
			continue;

		priv->sw_port_link[i] = up;

		/* link changed */
		if (!up) {
			dev_info(dev, "link DOWN on %s\n", port->name);
			writeb_be(ETH_PORTOV_ENABLE_MASK,
				  priv->base + ETH_PORTOV_REG(i));
			writeb_be(ETH_PTCTRL_RXDIS_MASK |
				  ETH_PTCTRL_TXDIS_MASK,
				  priv->base + ETH_PTCTRL_REG(i));
			continue;
		}

		adv = bcm6368_mdio_read(priv, external_phy,
					port->phy_id, MII_ADVERTISE);

		lpa = bcm6368_mdio_read(priv, external_phy, port->phy_id,
					MII_LPA);

		/* figure out media and duplex from advertise and LPA values */
		media = mii_nway_result(lpa & adv);
		duplex = (media & ADVERTISE_FULL) ? 1 : 0;

		if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF))
			speed = 100;
		else
			speed = 10;

		if (val & BMSR_ESTATEN) {
			adv = bcm6368_mdio_read(priv, external_phy,
						port->phy_id, MII_CTRL1000);

			lpa = bcm6368_mdio_read(priv, external_phy,
						port->phy_id, MII_STAT1000);

			if ((adv & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
			    (lpa & (LPA_1000FULL | LPA_1000HALF))) {
				speed = 1000;
				duplex = (lpa & LPA_1000FULL);
			}
		}

		pr_alert("link UP on %s, %dMbps, %s-duplex\n",
			 port->name, speed, duplex ? "full" : "half");

		override = ETH_PORTOV_ENABLE_MASK |
			   ETH_PORTOV_LINKUP_MASK;

		if (speed == 1000)
			override |= ETH_PORTOV_1000_MASK;
		else if (speed == 100)
			override |= ETH_PORTOV_100_MASK;
		if (duplex)
			override |= ETH_PORTOV_FDX_MASK;

		writeb_be(override, priv->base + ETH_PORTOV_REG(i));
		writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
	}

	return 0;
}

static int bcm6368_eth_start(struct udevice *dev)
{
	struct bcm6368_eth_priv *priv = dev_get_priv(dev);
	uint8_t i;

	/* disable all ports */
	for (i = 0; i < priv->num_ports; i++) {
		setbits_8(priv->base + ETH_PORTOV_REG(i),
			  ETH_PORTOV_ENABLE_MASK);
		setbits_8(priv->base + ETH_PTCTRL_REG(i),
			  ETH_PTCTRL_RXDIS_MASK | ETH_PTCTRL_TXDIS_MASK);
		priv->sw_port_link[i] = 0;
	}

	/* enable external ports */
	for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) {
		u8 rgmii_ctrl = ETH_RGMII_CTRL_GMII_CLK_EN;

		if (!priv->used_ports[i].used)
			continue;

		if (priv->rgmii_override)
			rgmii_ctrl |= ETH_RGMII_CTRL_MII_OVERRIDE_EN;
		if (priv->rgmii_timing)
			rgmii_ctrl |= ETH_RGMII_CTRL_TIMING_SEL_EN;

		setbits_8(priv->base + ETH_RGMII_CTRL_REG(i), rgmii_ctrl);
	}

	/* reset mib */
	setbits_8(priv->base + ETH_GMCR_REG, ETH_GMCR_RST_MIB_MASK);
	mdelay(1);
	clrbits_8(priv->base + ETH_GMCR_REG, ETH_GMCR_RST_MIB_MASK);
	mdelay(1);

	/* force CPU port state */
	setbits_8(priv->base + ETH_IMPOV_REG,
		  ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK);

	/* enable switch forward engine */
	setbits_8(priv->base + ETH_SWMODE_REG, ETH_SWMODE_FWD_EN_MASK);

	/* prepare rx dma buffers */
	for (i = 0; i < ETH_RX_DESC; i++) {
		int ret = dma_prepare_rcv_buf(&priv->rx_dma, net_rx_packets[i],
					      PKTSIZE_ALIGN);
		if (ret < 0)
			break;
	}

	/* enable dma rx channel */
	dma_enable(&priv->rx_dma);

	/* enable dma tx channel */
	dma_enable(&priv->tx_dma);

	/* apply override config for bypass_link ports here. */
	for (i = 0; i < priv->num_ports; i++) {
		struct bcm_enetsw_port *port;
		u8 override;

		port = &priv->used_ports[i];
		if (!port->used)
			continue;

		if (!port->bypass_link)
			continue;

		override = ETH_PORTOV_ENABLE_MASK |
			   ETH_PORTOV_LINKUP_MASK;

		switch (port->force_speed) {
		case 1000:
			override |= ETH_PORTOV_1000_MASK;
			break;
		case 100:
			override |= ETH_PORTOV_100_MASK;
			break;
		case 10:
			break;
		default:
			pr_warn("%s: invalid forced speed on port %s\n",
				__func__, port->name);
			break;
		}

		if (port->force_duplex_full)
			override |= ETH_PORTOV_FDX_MASK;

		writeb_be(override, priv->base + ETH_PORTOV_REG(i));
		writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
	}

	bcm6368_eth_adjust_link(dev);

	return 0;
}

static void bcm6368_eth_stop(struct udevice *dev)
{
	struct bcm6368_eth_priv *priv = dev_get_priv(dev);
	uint8_t i;

	/* disable all ports */
	for (i = 0; i < priv->num_ports; i++) {
		setbits_8(priv->base + ETH_PORTOV_REG(i),
			  ETH_PORTOV_ENABLE_MASK);
		setbits_8(priv->base + ETH_PTCTRL_REG(i),
			  ETH_PTCTRL_RXDIS_MASK | ETH_PTCTRL_TXDIS_MASK);
	}

	/* disable external ports */
	for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) {
		if (!priv->used_ports[i].used)
			continue;

		clrbits_8(priv->base + ETH_RGMII_CTRL_REG(i),
			  ETH_RGMII_CTRL_GMII_CLK_EN);
	}

	/* disable CPU port */
	clrbits_8(priv->base + ETH_IMPOV_REG,
		  ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK);

	/* disable switch forward engine */
	clrbits_8(priv->base + ETH_SWMODE_REG, ETH_SWMODE_FWD_EN_MASK);

	/* disable dma rx channel */
	dma_disable(&priv->rx_dma);

	/* disable dma tx channel */
	dma_disable(&priv->tx_dma);
}

static const struct eth_ops bcm6368_eth_ops = {
	.free_pkt = bcm6368_eth_free_pkt,
	.recv = bcm6368_eth_recv,
	.send = bcm6368_eth_send,
	.start = bcm6368_eth_start,
	.stop = bcm6368_eth_stop,
};

static const struct udevice_id bcm6368_eth_ids[] = {
	{ .compatible = "brcm,bcm6368-enet", },
	{ /* sentinel */ }
};

static bool bcm6368_phy_is_external(struct bcm6368_eth_priv *priv, int phy_id)
{
	uint8_t i;

	for (i = 0; i < priv->num_ports; ++i) {
		if (!priv->used_ports[i].used)
			continue;
		if (priv->used_ports[i].phy_id == phy_id)
			return bcm_enet_port_is_rgmii(i);
	}

	return true;
}

static int bcm6368_mii_mdio_read(struct mii_dev *bus, int addr, int devaddr,
				 int reg)
{
	struct bcm6368_eth_priv *priv = bus->priv;
	bool ext = bcm6368_phy_is_external(priv, addr);

	return bcm6368_mdio_read(priv, ext, addr, reg);
}

static int bcm6368_mii_mdio_write(struct mii_dev *bus, int addr, int devaddr,
				  int reg, u16 data)
{
	struct bcm6368_eth_priv *priv = bus->priv;
	bool ext = bcm6368_phy_is_external(priv, addr);

	return bcm6368_mdio_write(priv, ext, addr, reg, data);
}

static int bcm6368_mdio_init(const char *name, struct bcm6368_eth_priv *priv)
{
	struct mii_dev *bus;

	bus = mdio_alloc();
	if (!bus) {
		pr_err("%s: failed to allocate MDIO bus\n", __func__);
		return -ENOMEM;
	}

	bus->read = bcm6368_mii_mdio_read;
	bus->write = bcm6368_mii_mdio_write;
	bus->priv = priv;
	snprintf(bus->name, sizeof(bus->name), "%s", name);

	return mdio_register(bus);
}

static int bcm6368_eth_probe(struct udevice *dev)
{
	struct eth_pdata *pdata = dev_get_plat(dev);
	struct bcm6368_eth_priv *priv = dev_get_priv(dev);
	int num_ports, ret, i;
	ofnode node;

	/* get base address */
	priv->base = dev_remap_addr(dev);
	if (!priv->base)
		return -EINVAL;
	pdata->iobase = (phys_addr_t) priv->base;

	/* get number of ports */
	num_ports = dev_read_u32_default(dev, "brcm,num-ports", ETH_MAX_PORT);
	if (!num_ports || num_ports > ETH_MAX_PORT)
		return -EINVAL;

	/* get dma channels */
	ret = dma_get_by_name(dev, "tx", &priv->tx_dma);
	if (ret)
		return -EINVAL;

	ret = dma_get_by_name(dev, "rx", &priv->rx_dma);
	if (ret)
		return -EINVAL;

	/* try to enable clocks */
	for (i = 0; ; i++) {
		struct clk clk;
		int ret;

		ret = clk_get_by_index(dev, i, &clk);
		if (ret < 0)
			break;

		ret = clk_enable(&clk);
		if (ret < 0) {
			pr_err("%s: error enabling clock %d\n", __func__, i);
			return ret;
		}
	}

	/* try to perform resets */
	for (i = 0; ; i++) {
		struct reset_ctl reset;
		int ret;

		ret = reset_get_by_index(dev, i, &reset);
		if (ret < 0)
			break;

		ret = reset_deassert(&reset);
		if (ret < 0) {
			pr_err("%s: error deasserting reset %d\n", __func__, i);
			return ret;
		}

		ret = reset_free(&reset);
		if (ret < 0) {
			pr_err("%s: error freeing reset %d\n", __func__, i);
			return ret;
		}
	}

	/* set priv data */
	priv->num_ports = num_ports;
	if (dev_read_bool(dev, "brcm,rgmii-override"))
		priv->rgmii_override = true;
	if (dev_read_bool(dev, "brcm,rgmii-timing"))
		priv->rgmii_timing = true;

	/* get ports */
	dev_for_each_subnode(node, dev) {
		const char *comp;
		const char *label;
		unsigned int p;
		int phy_id;
		int speed;

		comp = ofnode_read_string(node, "compatible");
		if (!comp || memcmp(comp, ETH_PORT_STR, sizeof(ETH_PORT_STR)))
			continue;

		p = ofnode_read_u32_default(node, "reg", ETH_MAX_PORT);
		if (p >= num_ports)
			return -EINVAL;

		label = ofnode_read_string(node, "label");
		if (!label) {
			debug("%s: node %s has no label\n", __func__,
			      ofnode_get_name(node));
			return -EINVAL;
		}

		phy_id = ofnode_read_u32_default(node, "brcm,phy-id", -1);

		priv->used_ports[p].used = true;
		priv->used_ports[p].name = label;
		priv->used_ports[p].phy_id = phy_id;

		if (ofnode_read_bool(node, "full-duplex"))
			priv->used_ports[p].force_duplex_full = true;
		if (ofnode_read_bool(node, "bypass-link"))
			priv->used_ports[p].bypass_link = true;
		speed = ofnode_read_u32_default(node, "speed", 0);
		if (speed)
			priv->used_ports[p].force_speed = speed;
	}

	/* init mii bus */
	ret = bcm6368_mdio_init(dev->name, priv);
	if (ret)
		return ret;

	/* enable jumbo on all ports */
	writel_be(0x1ff, priv->base + ETH_JMBCTL_PORT_REG);
	writew_be(9728, priv->base + ETH_JMBCTL_MAXSIZE_REG);

	return 0;
}

U_BOOT_DRIVER(bcm6368_eth) = {
	.name = "bcm6368_eth",
	.id = UCLASS_ETH,
	.of_match = bcm6368_eth_ids,
	.ops = &bcm6368_eth_ops,
	.plat_auto	= sizeof(struct eth_pdata),
	.priv_auto	= sizeof(struct bcm6368_eth_priv),
	.probe = bcm6368_eth_probe,
};
