// SPDX-License-Identifier: GPL-2.0+
/*
 * ENETC ethernet controller driver
 * Copyright 2019 NXP
 */

#include <dm.h>
#include <errno.h>
#include <pci.h>
#include <miiphy.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <miiphy.h>

#include "fsl_enetc.h"

static void enetc_mdio_wait_bsy(struct enetc_mdio_priv *priv)
{
	int to = 10000;

	while ((enetc_read(priv, ENETC_MDIO_CFG) & ENETC_EMDIO_CFG_BSY) &&
	       --to)
		cpu_relax();
	if (!to)
		printf("T");
}

int enetc_mdio_read_priv(struct enetc_mdio_priv *priv, int addr, int devad,
			 int reg)
{
	if (devad == MDIO_DEVAD_NONE)
		enetc_write(priv, ENETC_MDIO_CFG, ENETC_EMDIO_CFG_C22);
	else
		enetc_write(priv, ENETC_MDIO_CFG, ENETC_EMDIO_CFG_C45);
	enetc_mdio_wait_bsy(priv);

	if (devad == MDIO_DEVAD_NONE) {
		enetc_write(priv, ENETC_MDIO_CTL, ENETC_MDIO_CTL_READ |
			    (addr << 5) | reg);
	} else {
		enetc_write(priv, ENETC_MDIO_CTL, (addr << 5) + devad);
		enetc_mdio_wait_bsy(priv);

		enetc_write(priv, ENETC_MDIO_STAT, reg);
		enetc_mdio_wait_bsy(priv);

		enetc_write(priv, ENETC_MDIO_CTL, ENETC_MDIO_CTL_READ |
			    (addr << 5) | devad);
	}

	enetc_mdio_wait_bsy(priv);
	if (enetc_read(priv, ENETC_MDIO_CFG) & ENETC_EMDIO_CFG_RD_ER)
		return ENETC_MDIO_READ_ERR;

	return enetc_read(priv, ENETC_MDIO_DATA);
}

int enetc_mdio_write_priv(struct enetc_mdio_priv *priv, int addr, int devad,
			  int reg, u16 val)
{
	if (devad == MDIO_DEVAD_NONE)
		enetc_write(priv, ENETC_MDIO_CFG, ENETC_EMDIO_CFG_C22);
	else
		enetc_write(priv, ENETC_MDIO_CFG, ENETC_EMDIO_CFG_C45);
	enetc_mdio_wait_bsy(priv);

	if (devad != MDIO_DEVAD_NONE) {
		enetc_write(priv, ENETC_MDIO_CTL, (addr << 5) + devad);
		enetc_write(priv, ENETC_MDIO_STAT, reg);
	} else {
		enetc_write(priv, ENETC_MDIO_CTL, (addr << 5) + reg);
	}
	enetc_mdio_wait_bsy(priv);

	enetc_write(priv, ENETC_MDIO_DATA, val);
	enetc_mdio_wait_bsy(priv);

	return 0;
}

/* DM wrappers */
static int dm_enetc_mdio_read(struct udevice *dev, int addr, int devad, int reg)
{
	struct enetc_mdio_priv *priv = dev_get_priv(dev);

	return enetc_mdio_read_priv(priv, addr, devad, reg);
}

static int dm_enetc_mdio_write(struct udevice *dev, int addr, int devad,
			       int reg, u16 val)
{
	struct enetc_mdio_priv *priv = dev_get_priv(dev);

	return enetc_mdio_write_priv(priv, addr, devad, reg, val);
}

static const struct mdio_ops enetc_mdio_ops = {
	.read = dm_enetc_mdio_read,
	.write = dm_enetc_mdio_write,
};

static int enetc_mdio_bind(struct udevice *dev)
{
	char name[16];
	static int eth_num_devices;

	/*
	 * prefer using PCI function numbers to number interfaces, but these
	 * are only available if dts nodes are present.  For PCI they are
	 * optional, handle that case too.  Just in case some nodes are present
	 * and some are not, use different naming scheme - enetc-N based on
	 * PCI function # and enetc#N based on interface count
	 */
	if (ofnode_valid(dev_ofnode(dev)))
		sprintf(name, "emdio-%u", PCI_FUNC(pci_get_devfn(dev)));
	else
		sprintf(name, "emdio#%u", eth_num_devices++);
	device_set_name(dev, name);

	return 0;
}

static int enetc_mdio_probe(struct udevice *dev)
{
	struct enetc_mdio_priv *priv = dev_get_priv(dev);

	priv->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_TYPE, 0);
	if (!priv->regs_base) {
		enetc_dbg(dev, "failed to map BAR0\n");
		return -EINVAL;
	}

	priv->regs_base += ENETC_MDIO_BASE;

	dm_pci_clrset_config16(dev, PCI_COMMAND, 0, PCI_COMMAND_MEMORY);

	return 0;
}

U_BOOT_DRIVER(enetc_mdio) = {
	.name	= "enetc_mdio",
	.id	= UCLASS_MDIO,
	.bind	= enetc_mdio_bind,
	.probe	= enetc_mdio_probe,
	.ops	= &enetc_mdio_ops,
	.priv_auto	= sizeof(struct enetc_mdio_priv),
};

static struct pci_device_id enetc_mdio_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_ENETC_MDIO) },
	{ }
};

U_BOOT_PCI_DEVICE(enetc_mdio, enetc_mdio_ids);
