#include <common.h>
#include <dm.h>
#include <miiphy.h>
#include <asm-generic/gpio.h>

#include "ihs_phys.h"
#include "dt_helpers.h"

enum {
	PORTTYPE_MAIN_CAT,
	PORTTYPE_TOP_CAT,
	PORTTYPE_16C_16F,
	PORTTYPE_UNKNOWN
};

static struct porttype {
	bool phy_invert_in_pol;
	bool phy_invert_out_pol;
} porttypes[] = {
	{ true, false },
	{ false, true },
	{ false, false },
};

static void ihs_phy_config(struct phy_device *phydev, bool qinpn, bool qoutpn)
{
	u16 reg;

	phy_config(phydev);

	/* enable QSGMII autonegotiation with flow control */
	phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0004);
	reg = phy_read(phydev, MDIO_DEVAD_NONE, 16);
	reg |= (3 << 6);
	phy_write(phydev, MDIO_DEVAD_NONE, 16, reg);

	/*
	 * invert QSGMII Q_INP/N and Q_OUTP/N if required
	 * and perform global reset
	 */
	reg = phy_read(phydev, MDIO_DEVAD_NONE, 26);
	if (qinpn)
		reg |= (1 << 13);
	if (qoutpn)
		reg |= (1 << 12);
	reg |= (1 << 15);
	phy_write(phydev, MDIO_DEVAD_NONE, 26, reg);

	/* advertise 1000BASE-T full-duplex only  */
	phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000);
	reg = phy_read(phydev, MDIO_DEVAD_NONE, 4);
	reg &= ~0x1e0;
	phy_write(phydev, MDIO_DEVAD_NONE, 4, reg);
	reg = phy_read(phydev, MDIO_DEVAD_NONE, 9);
	reg = (reg & ~0x300) | 0x200;
	phy_write(phydev, MDIO_DEVAD_NONE, 9, reg);

	/* copper power up */
	reg = phy_read(phydev, MDIO_DEVAD_NONE, 16);
	reg &= ~0x0004;
	phy_write(phydev, MDIO_DEVAD_NONE, 16, reg);
}

uint calculate_octo_phy_mask(void)
{
	uint k;
	uint octo_phy_mask = 0;
	struct gpio_desc gpio = {};
	char gpio_name[64];
	static const char * const dev_name[] = {"pca9698@23", "pca9698@21",
						"pca9698@24", "pca9698@25",
						"pca9698@26"};

	/* mark all octo phys that should be present */
	for (k = 0; k < 5; ++k) {
		snprintf(gpio_name, 64, "cat-gpio-%u", k);

		if (request_gpio_by_name(&gpio, dev_name[k], 0x20, gpio_name))
			continue;

		/* check CAT flag */
		if (dm_gpio_get_value(&gpio))
			octo_phy_mask |= (1 << (k * 2));
		else
			/* If CAT == 0, there's no second octo phy -> skip */
			continue;

		snprintf(gpio_name, 64, "second-octo-gpio-%u", k);

		if (request_gpio_by_name(&gpio, dev_name[k], 0x27, gpio_name)) {
			/* default: second octo phy is present */
			octo_phy_mask |= (1 << (k * 2 + 1));
			continue;
		}

		if (dm_gpio_get_value(&gpio) == 0)
			octo_phy_mask |= (1 << (k * 2 + 1));
	}

	return octo_phy_mask;
}

int register_miiphy_bus(uint k, struct mii_dev **bus)
{
	int retval;
	struct mii_dev *mdiodev = mdio_alloc();
	char *name = bb_miiphy_buses[k].name;

	if (!mdiodev)
		return -ENOMEM;
	strncpy(mdiodev->name,
		name,
		MDIO_NAME_LEN);
	mdiodev->read = bb_miiphy_read;
	mdiodev->write = bb_miiphy_write;

	retval = mdio_register(mdiodev);
	if (retval < 0)
		return retval;
	*bus = miiphy_get_dev_by_name(name);

	return 0;
}

struct porttype *get_porttype(uint octo_phy_mask, uint k)
{
	uint octo_index = k * 4;

	if (!k) {
		if (octo_phy_mask & 0x01)
			return &porttypes[PORTTYPE_MAIN_CAT];
		else if (!(octo_phy_mask & 0x03))
			return &porttypes[PORTTYPE_16C_16F];
	} else {
		if (octo_phy_mask & (1 << octo_index))
			return &porttypes[PORTTYPE_TOP_CAT];
	}

	return NULL;
}

int init_single_phy(struct porttype *porttype, struct mii_dev *bus,
		    uint bus_idx, uint m, uint phy_idx)
{
	struct phy_device *phydev = phy_find_by_mask(
		bus, 1 << (m * 8 + phy_idx),
		PHY_INTERFACE_MODE_MII);

	printf(" %u", bus_idx * 32 + m * 8 + phy_idx);

	if (!phydev)
		puts("!");
	else
		ihs_phy_config(phydev, porttype->phy_invert_in_pol,
			       porttype->phy_invert_out_pol);

	return 0;
}

int init_octo_phys(uint octo_phy_mask)
{
	uint bus_idx;

	/* there are up to four octo-phys on each mdio bus */
	for (bus_idx = 0; bus_idx < bb_miiphy_buses_num; ++bus_idx) {
		uint m;
		uint octo_index = bus_idx * 4;
		struct mii_dev *bus = NULL;
		struct porttype *porttype = NULL;
		int ret;

		porttype = get_porttype(octo_phy_mask, bus_idx);

		if (!porttype)
			continue;

		for (m = 0; m < 4; ++m) {
			uint phy_idx;

			/**
			 * Register a bus device if there is at least one phy
			 * on the current bus
			 */
			if (!m && octo_phy_mask & (0xf << octo_index)) {
				ret = register_miiphy_bus(bus_idx, &bus);
				if (ret)
					return ret;
			}

			if (!(octo_phy_mask & BIT(octo_index + m)))
				continue;

			for (phy_idx = 0; phy_idx < 8; ++phy_idx)
				init_single_phy(porttype, bus, bus_idx, m,
						phy_idx);
		}
	}

	return 0;
}

/*
 * MII GPIO bitbang implementation
 * MDC MDIO bus
 * 13  14   PHY1-4
 * 25  45   PHY5-8
 * 46  24   PHY9-10
 */

struct gpio_mii {
	int index;
	struct gpio_desc mdc_gpio;
	struct gpio_desc mdio_gpio;
	int mdc_num;
	int mdio_num;
	int mdio_value;
} gpio_mii_set[] = {
	{ 0, {}, {}, 13, 14, 1 },
	{ 1, {}, {}, 25, 45, 1 },
	{ 2, {}, {}, 46, 24, 1 },
};

static int mii_mdio_init(struct bb_miiphy_bus *bus)
{
	struct gpio_mii *gpio_mii = bus->priv;
	char name[32] = {};
	struct udevice *gpio_dev1 = NULL;
	struct udevice *gpio_dev2 = NULL;

	if (uclass_get_device_by_name(UCLASS_GPIO, "gpio@18100", &gpio_dev1) ||
	    uclass_get_device_by_name(UCLASS_GPIO, "gpio@18140", &gpio_dev2)) {
		printf("Could not get GPIO device.\n");
		return 1;
	}

	if (gpio_mii->mdc_num > 31) {
		gpio_mii->mdc_gpio.dev = gpio_dev2;
		gpio_mii->mdc_gpio.offset = gpio_mii->mdc_num - 32;
	} else {
		gpio_mii->mdc_gpio.dev = gpio_dev1;
		gpio_mii->mdc_gpio.offset = gpio_mii->mdc_num;
	}
	gpio_mii->mdc_gpio.flags = 0;
	snprintf(name, 32, "bb_miiphy_bus-%d-mdc", gpio_mii->index);
	dm_gpio_request(&gpio_mii->mdc_gpio, name);

	if (gpio_mii->mdio_num > 31) {
		gpio_mii->mdio_gpio.dev = gpio_dev2;
		gpio_mii->mdio_gpio.offset = gpio_mii->mdio_num - 32;
	} else {
		gpio_mii->mdio_gpio.dev = gpio_dev1;
		gpio_mii->mdio_gpio.offset = gpio_mii->mdio_num;
	}
	gpio_mii->mdio_gpio.flags = 0;
	snprintf(name, 32, "bb_miiphy_bus-%d-mdio", gpio_mii->index);
	dm_gpio_request(&gpio_mii->mdio_gpio, name);

	dm_gpio_set_dir_flags(&gpio_mii->mdc_gpio, GPIOD_IS_OUT);
	dm_gpio_set_value(&gpio_mii->mdc_gpio, 1);

	return 0;
}

static int mii_mdio_active(struct bb_miiphy_bus *bus)
{
	struct gpio_mii *gpio_mii = bus->priv;

	dm_gpio_set_value(&gpio_mii->mdc_gpio, gpio_mii->mdio_value);

	return 0;
}

static int mii_mdio_tristate(struct bb_miiphy_bus *bus)
{
	struct gpio_mii *gpio_mii = bus->priv;

	dm_gpio_set_dir_flags(&gpio_mii->mdio_gpio, GPIOD_IS_IN);

	return 0;
}

static int mii_set_mdio(struct bb_miiphy_bus *bus, int v)
{
	struct gpio_mii *gpio_mii = bus->priv;

	dm_gpio_set_dir_flags(&gpio_mii->mdio_gpio, GPIOD_IS_OUT);
	dm_gpio_set_value(&gpio_mii->mdio_gpio, v);
	gpio_mii->mdio_value = v;

	return 0;
}

static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v)
{
	struct gpio_mii *gpio_mii = bus->priv;

	dm_gpio_set_dir_flags(&gpio_mii->mdio_gpio, GPIOD_IS_IN);
	*v = (dm_gpio_get_value(&gpio_mii->mdio_gpio));

	return 0;
}

static int mii_set_mdc(struct bb_miiphy_bus *bus, int v)
{
	struct gpio_mii *gpio_mii = bus->priv;

	dm_gpio_set_value(&gpio_mii->mdc_gpio, v);

	return 0;
}

static int mii_delay(struct bb_miiphy_bus *bus)
{
	udelay(1);

	return 0;
}

struct bb_miiphy_bus bb_miiphy_buses[] = {
	{
		.name = "ihs0",
		.init = mii_mdio_init,
		.mdio_active = mii_mdio_active,
		.mdio_tristate = mii_mdio_tristate,
		.set_mdio = mii_set_mdio,
		.get_mdio = mii_get_mdio,
		.set_mdc = mii_set_mdc,
		.delay = mii_delay,
		.priv = &gpio_mii_set[0],
	},
	{
		.name = "ihs1",
		.init = mii_mdio_init,
		.mdio_active = mii_mdio_active,
		.mdio_tristate = mii_mdio_tristate,
		.set_mdio = mii_set_mdio,
		.get_mdio = mii_get_mdio,
		.set_mdc = mii_set_mdc,
		.delay = mii_delay,
		.priv = &gpio_mii_set[1],
	},
	{
		.name = "ihs2",
		.init = mii_mdio_init,
		.mdio_active = mii_mdio_active,
		.mdio_tristate = mii_mdio_tristate,
		.set_mdio = mii_set_mdio,
		.get_mdio = mii_get_mdio,
		.set_mdc = mii_set_mdc,
		.delay = mii_delay,
		.priv = &gpio_mii_set[2],
	},
};

int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
