/*
 * drivers/net/ucc_geth_mii.c
 *
 * Gianfar Ethernet Driver -- MIIM bus implementation
 * Provides Bus interface for MIIM regs
 *
 * Author: Li Yang
 *
 * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 *
 */

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <asm/ocp.h>
#include <linux/crc32.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/fsl_devices.h>

#include <asm/of_platform.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/ucc.h>

#include "ucc_geth_mii.h"
#include "ucc_geth.h"

#define DEBUG
#ifdef DEBUG
#define vdbg(format, arg...) printk(KERN_DEBUG , format "\n" , ## arg)
#else
#define vdbg(format, arg...) do {} while(0)
#endif

#define DRV_DESC "QE UCC Ethernet Controller MII Bus"
#define DRV_NAME "fsl-uec_mdio"

/* Write value to the PHY for this device to the register at regnum, */
/* waiting until the write is done before it returns.  All PHY */
/* configuration has to be done through the master UEC MIIM regs */
int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
{
	struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;

	/* Setting up the MII Mangement Address Register */
	out_be32(&regs->miimadd,
		 (mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | regnum);

	/* Setting up the MII Mangement Control Register with the value */
	out_be32(&regs->miimcon, value);

	/* Wait till MII management write is complete */
	while ((in_be32(&regs->miimind)) & MIIMIND_BUSY)
		cpu_relax();

	return 0;
}

/* Reads from register regnum in the PHY for device dev, */
/* returning the value.  Clears miimcom first.  All PHY */
/* configuration has to be done through the TSEC1 MIIM regs */
int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
{
	struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
	u16 value;

	/* Setting up the MII Mangement Address Register */
	out_be32(&regs->miimadd,
		 (mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | regnum);

	/* Clear miimcom, perform an MII management read cycle */
	out_be32(&regs->miimcom, 0);
	out_be32(&regs->miimcom, MIIMCOM_READ_CYCLE);

	/* Wait till MII management write is complete */
	while ((in_be32(&regs->miimind)) & (MIIMIND_BUSY | MIIMIND_NOT_VALID))
		cpu_relax();

	/* Read MII management status  */
	value = in_be32(&regs->miimstat);

	return value;
}

/* Reset the MIIM registers, and wait for the bus to free */
int uec_mdio_reset(struct mii_bus *bus)
{
	struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
	unsigned int timeout = PHY_INIT_TIMEOUT;

	spin_lock_bh(&bus->mdio_lock);

	/* Reset the management interface */
	out_be32(&regs->miimcfg, MIIMCFG_RESET_MANAGEMENT);

	/* Setup the MII Mgmt clock speed */
	out_be32(&regs->miimcfg, MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112);

	/* Wait until the bus is free */
	while ((in_be32(&regs->miimind) & MIIMIND_BUSY) && timeout--)
		cpu_relax();

	spin_unlock_bh(&bus->mdio_lock);

	if (timeout <= 0) {
		printk(KERN_ERR "%s: The MII Bus is stuck!\n", bus->name);
		return -EBUSY;
	}

	return 0;
}

static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *match)
{
	struct device *device = &ofdev->dev;
	struct device_node *np = ofdev->node, *tempnp = NULL;
	struct device_node *child = NULL;
	struct ucc_mii_mng __iomem *regs;
	struct mii_bus *new_bus;
	struct resource res;
	int k, err = 0;

	new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);

	if (NULL == new_bus)
		return -ENOMEM;

	new_bus->name = "UCC Ethernet Controller MII Bus";
	new_bus->read = &uec_mdio_read;
	new_bus->write = &uec_mdio_write;
	new_bus->reset = &uec_mdio_reset;

	memset(&res, 0, sizeof(res));

	err = of_address_to_resource(np, 0, &res);
	if (err)
		goto reg_map_fail;

	new_bus->id = res.start;

	new_bus->irq = kmalloc(32 * sizeof(int), GFP_KERNEL);

	if (NULL == new_bus->irq) {
		err = -ENOMEM;
		goto reg_map_fail;
	}

	for (k = 0; k < 32; k++)
		new_bus->irq[k] = PHY_POLL;

	while ((child = of_get_next_child(np, child)) != NULL) {
		int irq = irq_of_parse_and_map(child, 0);
		if (irq != NO_IRQ) {
			const u32 *id = get_property(child, "reg", NULL);
			new_bus->irq[*id] = irq;
		}
	}

	/* Set the base address */
	regs = ioremap(res.start, sizeof(struct ucc_mii_mng));

	if (NULL == regs) {
		err = -ENOMEM;
		goto ioremap_fail;
	}

	new_bus->priv = (void __force *)regs;

	new_bus->dev = device;
	dev_set_drvdata(device, new_bus);

	/* Read MII management master from device tree */
	while ((tempnp = of_find_compatible_node(tempnp, "network", "ucc_geth"))
	       != NULL) {
		struct resource tempres;

		err = of_address_to_resource(tempnp, 0, &tempres);
		if (err)
			goto bus_register_fail;

		/* if our mdio regs fall within this UCC regs range */
		if ((res.start >= tempres.start) &&
		    (res.end <= tempres.end)) {
			/* set this UCC to be the MII master */
			const u32 *id = get_property(tempnp, "device-id", NULL);
			if (id == NULL)
				goto bus_register_fail;

			ucc_set_qe_mux_mii_mng(*id - 1);

			/* assign the TBI an address which won't
			 * conflict with the PHYs */
			out_be32(&regs->utbipar, UTBIPAR_INIT_TBIPA);
			break;
		}
	}

	err = mdiobus_register(new_bus);
	if (0 != err) {
		printk(KERN_ERR "%s: Cannot register as MDIO bus\n",
		       new_bus->name);
		goto bus_register_fail;
	}

	return 0;

bus_register_fail:
	iounmap(regs);
ioremap_fail:
	kfree(new_bus->irq);
reg_map_fail:
	kfree(new_bus);

	return err;
}

int uec_mdio_remove(struct of_device *ofdev)
{
	struct device *device = &ofdev->dev;
	struct mii_bus *bus = dev_get_drvdata(device);

	mdiobus_unregister(bus);

	dev_set_drvdata(device, NULL);

	iounmap((void __iomem *)bus->priv);
	bus->priv = NULL;
	kfree(bus);

	return 0;
}

static struct of_device_id uec_mdio_match[] = {
	{
		.type = "mdio",
		.compatible = "ucc_geth_phy",
	},
	{},
};

MODULE_DEVICE_TABLE(of, uec_mdio_match);

static struct of_platform_driver uec_mdio_driver = {
	.name	= DRV_NAME,
	.probe	= uec_mdio_probe,
	.remove	= uec_mdio_remove,
	.match_table	= uec_mdio_match,
};

int __init uec_mdio_init(void)
{
	return of_register_platform_driver(&uec_mdio_driver);
}

void __exit uec_mdio_exit(void)
{
	of_unregister_platform_driver(&uec_mdio_driver);
}
