/*
 * pic32_mdio.c: PIC32 MDIO/MII driver, part of pic32_eth.c.
 *
 * Copyright 2015 Microchip Inc.
 *	Purna Chandra Mandal <purna.mandal@microchip.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */
#include <common.h>
#include <phy.h>
#include <miiphy.h>
#include <errno.h>
#include <wait_bit.h>
#include <asm/io.h>
#include "pic32_eth.h"

static int pic32_mdio_write(struct mii_dev *bus,
			    int addr, int dev_addr,
			    int reg, u16 value)
{
	u32 v;
	struct pic32_mii_regs *mii_regs = bus->priv;

	/* Wait for the previous operation to finish */
	wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
		     false, CONFIG_SYS_HZ, true);

	/* Put phyaddr and regaddr into MIIMADD */
	v = (addr << MIIMADD_PHYADDR_SHIFT) | (reg & MIIMADD_REGADDR);
	writel(v, &mii_regs->madr.raw);

	/* Initiate a write command */
	writel(value, &mii_regs->mwtd.raw);

	/* Wait 30 clock cycles for busy flag to be set */
	udelay(12);

	/* Wait for write to complete */
	wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
		     false, CONFIG_SYS_HZ, true);

	return 0;
}

static int pic32_mdio_read(struct mii_dev *bus, int addr, int devaddr, int reg)
{
	u32 v;
	struct pic32_mii_regs *mii_regs = bus->priv;

	/* Wait for the previous operation to finish */
	wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
		     false, CONFIG_SYS_HZ, true);

	/* Put phyaddr and regaddr into MIIMADD */
	v = (addr << MIIMADD_PHYADDR_SHIFT) | (reg & MIIMADD_REGADDR);
	writel(v, &mii_regs->madr.raw);

	/* Initiate a read command */
	writel(MIIMCMD_READ, &mii_regs->mcmd.raw);

	/* Wait 30 clock cycles for busy flag to be set */
	udelay(12);

	/* Wait for read to complete */
	wait_for_bit(__func__, &mii_regs->mind.raw,
		     MIIMIND_NOTVALID | MIIMIND_BUSY,
		     false, CONFIG_SYS_HZ, false);

	/* Clear the command register */
	writel(0, &mii_regs->mcmd.raw);

	/* Grab the value read from the PHY */
	v = readl(&mii_regs->mrdd.raw);
	return v;
}

static int pic32_mdio_reset(struct mii_dev *bus)
{
	struct pic32_mii_regs *mii_regs = bus->priv;

	/* Reset MII (due to new addresses) */
	writel(MIIMCFG_RSTMGMT, &mii_regs->mcfg.raw);

	/* Wait for the operation to finish */
	wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
		     false, CONFIG_SYS_HZ, true);

	/* Clear reset bit */
	writel(0, &mii_regs->mcfg);

	/* Wait for the operation to finish */
	wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
		     false, CONFIG_SYS_HZ, true);

	/* Set the MII Management Clock (MDC) - no faster than 2.5 MHz */
	writel(MIIMCFG_CLKSEL_DIV40, &mii_regs->mcfg.raw);

	/* Wait for the operation to finish */
	wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
		     false, CONFIG_SYS_HZ, true);
	return 0;
}

int pic32_mdio_init(const char *name, ulong ioaddr)
{
	struct mii_dev *bus;

	bus = mdio_alloc();
	if (!bus) {
		printf("Failed to allocate PIC32-MDIO bus\n");
		return -ENOMEM;
	}

	bus->read = pic32_mdio_read;
	bus->write = pic32_mdio_write;
	bus->reset = pic32_mdio_reset;
	strncpy(bus->name, name, sizeof(bus->name));
	bus->priv = (void *)ioaddr;

	return mdio_register(bus);
}
