/*
 * (C) Copyright 2010
 * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/*
 * Designware ethernet IP driver for u-boot
 */

#include <common.h>
#include <miiphy.h>
#include <malloc.h>
#include <linux/err.h>
#include <asm/io.h>
#include "designware.h"

static void tx_descs_init(struct eth_device *dev)
{
	struct dw_eth_dev *priv = dev->priv;
	struct eth_dma_regs *dma_p = priv->dma_regs_p;
	struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0];
	char *txbuffs = &priv->txbuffs[0];
	struct dmamacdescr *desc_p;
	u32 idx;

	for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) {
		desc_p = &desc_table_p[idx];
		desc_p->dmamac_addr = &txbuffs[idx * CONFIG_ETH_BUFSIZE];
		desc_p->dmamac_next = &desc_table_p[idx + 1];

#if defined(CONFIG_DW_ALTDESCRIPTOR)
		desc_p->txrx_status &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
				DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \
				DESC_TXSTS_TXCHECKINSCTRL | \
				DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);

		desc_p->txrx_status |= DESC_TXSTS_TXCHAIN;
		desc_p->dmamac_cntl = 0;
		desc_p->txrx_status &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
#else
		desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN;
		desc_p->txrx_status = 0;
#endif
	}

	/* Correcting the last pointer of the chain */
	desc_p->dmamac_next = &desc_table_p[0];

	writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
}

static void rx_descs_init(struct eth_device *dev)
{
	struct dw_eth_dev *priv = dev->priv;
	struct eth_dma_regs *dma_p = priv->dma_regs_p;
	struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0];
	char *rxbuffs = &priv->rxbuffs[0];
	struct dmamacdescr *desc_p;
	u32 idx;

	for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
		desc_p = &desc_table_p[idx];
		desc_p->dmamac_addr = &rxbuffs[idx * CONFIG_ETH_BUFSIZE];
		desc_p->dmamac_next = &desc_table_p[idx + 1];

		desc_p->dmamac_cntl =
			(MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) | \
				      DESC_RXCTRL_RXCHAIN;

		desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
	}

	/* Correcting the last pointer of the chain */
	desc_p->dmamac_next = &desc_table_p[0];

	writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr);
}

static void descs_init(struct eth_device *dev)
{
	tx_descs_init(dev);
	rx_descs_init(dev);
}

static int mac_reset(struct eth_device *dev)
{
	struct dw_eth_dev *priv = dev->priv;
	struct eth_mac_regs *mac_p = priv->mac_regs_p;
	struct eth_dma_regs *dma_p = priv->dma_regs_p;

	int timeout = CONFIG_MACRESET_TIMEOUT;

	writel(DMAMAC_SRST, &dma_p->busmode);
	writel(MII_PORTSELECT, &mac_p->conf);

	do {
		if (!(readl(&dma_p->busmode) & DMAMAC_SRST))
			return 0;
		udelay(1000);
	} while (timeout--);

	return -1;
}

static int dw_write_hwaddr(struct eth_device *dev)
{
	struct dw_eth_dev *priv = dev->priv;
	struct eth_mac_regs *mac_p = priv->mac_regs_p;
	u32 macid_lo, macid_hi;
	u8 *mac_id = &dev->enetaddr[0];

	macid_lo = mac_id[0] + (mac_id[1] << 8) + \
		   (mac_id[2] << 16) + (mac_id[3] << 24);
	macid_hi = mac_id[4] + (mac_id[5] << 8);

	writel(macid_hi, &mac_p->macaddr0hi);
	writel(macid_lo, &mac_p->macaddr0lo);

	return 0;
}

static int dw_eth_init(struct eth_device *dev, bd_t *bis)
{
	struct dw_eth_dev *priv = dev->priv;
	struct eth_mac_regs *mac_p = priv->mac_regs_p;
	struct eth_dma_regs *dma_p = priv->dma_regs_p;
	u32 conf;

	/* Reset ethernet hardware */
	if (mac_reset(dev) < 0)
		return -1;

	writel(FIXEDBURST | PRIORXTX_41 | BURST_16,
			&dma_p->busmode);

	writel(FLUSHTXFIFO | readl(&dma_p->opmode), &dma_p->opmode);
	writel(STOREFORWARD | TXSECONDFRAME, &dma_p->opmode);

	conf = FRAMEBURSTENABLE | DISABLERXOWN;

	if (priv->speed != SPEED_1000M)
		conf |= MII_PORTSELECT;

	if (priv->duplex == FULL_DUPLEX)
		conf |= FULLDPLXMODE;

	writel(conf, &mac_p->conf);

	descs_init(dev);

	/*
	 * Start/Enable xfer at dma as well as mac level
	 */
	writel(readl(&dma_p->opmode) | RXSTART, &dma_p->opmode);
	writel(readl(&dma_p->opmode) | TXSTART, &dma_p->opmode);

	writel(readl(&mac_p->conf) | RXENABLE, &mac_p->conf);
	writel(readl(&mac_p->conf) | TXENABLE, &mac_p->conf);

	return 0;
}

static int dw_eth_send(struct eth_device *dev, volatile void *packet,
		int length)
{
	struct dw_eth_dev *priv = dev->priv;
	struct eth_dma_regs *dma_p = priv->dma_regs_p;
	u32 desc_num = priv->tx_currdescnum;
	struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];

	/* Check if the descriptor is owned by CPU */
	if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) {
		printf("CPU not owner of tx frame\n");
		return -1;
	}

	memcpy((void *)desc_p->dmamac_addr, (void *)packet, length);

#if defined(CONFIG_DW_ALTDESCRIPTOR)
	desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
	desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) & \
			       DESC_TXCTRL_SIZE1MASK;

	desc_p->txrx_status &= ~(DESC_TXSTS_MSK);
	desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA;
#else
	desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) & \
			       DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | \
			       DESC_TXCTRL_TXFIRST;

	desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
#endif

	/* Test the wrap-around condition. */
	if (++desc_num >= CONFIG_TX_DESCR_NUM)
		desc_num = 0;

	priv->tx_currdescnum = desc_num;

	/* Start the transmission */
	writel(POLL_DATA, &dma_p->txpolldemand);

	return 0;
}

static int dw_eth_recv(struct eth_device *dev)
{
	struct dw_eth_dev *priv = dev->priv;
	u32 desc_num = priv->rx_currdescnum;
	struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];

	u32 status = desc_p->txrx_status;
	int length = 0;

	/* Check  if the owner is the CPU */
	if (!(status & DESC_RXSTS_OWNBYDMA)) {

		length = (status & DESC_RXSTS_FRMLENMSK) >> \
			 DESC_RXSTS_FRMLENSHFT;

		NetReceive(desc_p->dmamac_addr, length);

		/*
		 * Make the current descriptor valid again and go to
		 * the next one
		 */
		desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;

		/* Test the wrap-around condition. */
		if (++desc_num >= CONFIG_RX_DESCR_NUM)
			desc_num = 0;
	}

	priv->rx_currdescnum = desc_num;

	return length;
}

static void dw_eth_halt(struct eth_device *dev)
{
	struct dw_eth_dev *priv = dev->priv;

	mac_reset(dev);
	priv->tx_currdescnum = priv->rx_currdescnum = 0;
}

static int eth_mdio_read(struct eth_device *dev, u8 addr, u8 reg, u16 *val)
{
	struct dw_eth_dev *priv = dev->priv;
	struct eth_mac_regs *mac_p = priv->mac_regs_p;
	u32 miiaddr;
	int timeout = CONFIG_MDIO_TIMEOUT;

	miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \
		  ((reg << MIIREGSHIFT) & MII_REGMSK);

	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);

	do {
		if (!(readl(&mac_p->miiaddr) & MII_BUSY)) {
			*val = readl(&mac_p->miidata);
			return 0;
		}
		udelay(1000);
	} while (timeout--);

	return -1;
}

static int eth_mdio_write(struct eth_device *dev, u8 addr, u8 reg, u16 val)
{
	struct dw_eth_dev *priv = dev->priv;
	struct eth_mac_regs *mac_p = priv->mac_regs_p;
	u32 miiaddr;
	int ret = -1, timeout = CONFIG_MDIO_TIMEOUT;
	u16 value;

	writel(val, &mac_p->miidata);
	miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \
		  ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE;

	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);

	do {
		if (!(readl(&mac_p->miiaddr) & MII_BUSY))
			ret = 0;
		udelay(1000);
	} while (timeout--);

	/* Needed as a fix for ST-Phy */
	eth_mdio_read(dev, addr, reg, &value);

	return ret;
}

#if defined(CONFIG_DW_SEARCH_PHY)
static int find_phy(struct eth_device *dev)
{
	int phy_addr = 0;
	u16 ctrl, oldctrl;

	do {
		eth_mdio_read(dev, phy_addr, PHY_BMCR, &ctrl);
		oldctrl = ctrl & PHY_BMCR_AUTON;

		ctrl ^= PHY_BMCR_AUTON;
		eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);
		eth_mdio_read(dev, phy_addr, PHY_BMCR, &ctrl);
		ctrl &= PHY_BMCR_AUTON;

		if (ctrl == oldctrl) {
			phy_addr++;
		} else {
			ctrl ^= PHY_BMCR_AUTON;
			eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);

			return phy_addr;
		}
	} while (phy_addr < 32);

	return -1;
}
#endif

static int dw_reset_phy(struct eth_device *dev)
{
	struct dw_eth_dev *priv = dev->priv;
	u16 ctrl;
	int timeout = CONFIG_PHYRESET_TIMEOUT;
	u32 phy_addr = priv->address;

	eth_mdio_write(dev, phy_addr, PHY_BMCR, PHY_BMCR_RESET);
	do {
		eth_mdio_read(dev, phy_addr, PHY_BMCR, &ctrl);
		if (!(ctrl & PHY_BMCR_RESET))
			break;
		udelay(1000);
	} while (timeout--);

	if (timeout < 0)
		return -1;

#ifdef CONFIG_PHY_RESET_DELAY
	udelay(CONFIG_PHY_RESET_DELAY);
#endif
	return 0;
}

static int configure_phy(struct eth_device *dev)
{
	struct dw_eth_dev *priv = dev->priv;
	int phy_addr;
	u16 bmcr, ctrl;
#if defined(CONFIG_DW_AUTONEG)
	u16 bmsr;
	u32 timeout;
	u16 anlpar, btsr;
#endif

#if defined(CONFIG_DW_SEARCH_PHY)
	phy_addr = find_phy(dev);
	if (phy_addr > 0)
		priv->address = phy_addr;
	else
		return -1;
#endif
	if (dw_reset_phy(dev) < 0)
		return -1;

#if defined(CONFIG_DW_AUTONEG)
	bmcr = PHY_BMCR_AUTON | PHY_BMCR_RST_NEG | PHY_BMCR_100MB | \
	       PHY_BMCR_DPLX | PHY_BMCR_1000_MBPS;
#else
	bmcr = PHY_BMCR_100MB | PHY_BMCR_DPLX;

#if defined(CONFIG_DW_SPEED10M)
	bmcr &= ~PHY_BMCR_100MB;
#endif
#if defined(CONFIG_DW_DUPLEXHALF)
	bmcr &= ~PHY_BMCR_DPLX;
#endif
#endif
	if (eth_mdio_write(dev, phy_addr, PHY_BMCR, bmcr) < 0)
		return -1;

	/* Read the phy status register and populate priv structure */
#if defined(CONFIG_DW_AUTONEG)
	timeout = CONFIG_AUTONEG_TIMEOUT;
	do {
		eth_mdio_read(dev, phy_addr, PHY_BMSR, &bmsr);
		if (bmsr & PHY_BMSR_AUTN_COMP)
			break;
		udelay(1000);
	} while (timeout--);

	eth_mdio_read(dev, phy_addr, PHY_ANLPAR, &anlpar);
	eth_mdio_read(dev, phy_addr, PHY_1000BTSR, &btsr);

	if (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
		priv->speed = SPEED_1000M;
		if (btsr & PHY_1000BTSR_1000FD)
			priv->duplex = FULL_DUPLEX;
		else
			priv->duplex = HALF_DUPLEX;
	} else {
		if (anlpar & PHY_ANLPAR_100)
			priv->speed = SPEED_100M;
		else
			priv->speed = SPEED_10M;

		if (anlpar & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD))
			priv->duplex = FULL_DUPLEX;
		else
			priv->duplex = HALF_DUPLEX;
	}
#else
	if (eth_mdio_read(dev, phy_addr, PHY_BMCR, &ctrl) < 0)
		return -1;

	if (ctrl & PHY_BMCR_DPLX)
		priv->duplex = FULL_DUPLEX;
	else
		priv->duplex = HALF_DUPLEX;

	if (ctrl & PHY_BMCR_1000_MBPS)
		priv->speed = SPEED_1000M;
	else if (ctrl & PHY_BMCR_100_MBPS)
		priv->speed = SPEED_100M;
	else
		priv->speed = SPEED_10M;
#endif
	return 0;
}

#if defined(CONFIG_MII)
static int dw_mii_read(const char *devname, u8 addr, u8 reg, u16 *val)
{
	struct eth_device *dev;

	dev = eth_get_dev_by_name(devname);
	if (dev)
		eth_mdio_read(dev, addr, reg, val);

	return 0;
}

static int dw_mii_write(const char *devname, u8 addr, u8 reg, u16 val)
{
	struct eth_device *dev;

	dev = eth_get_dev_by_name(devname);
	if (dev)
		eth_mdio_write(dev, addr, reg, val);

	return 0;
}
#endif

int designware_initialize(u32 id, ulong base_addr, u32 phy_addr)
{
	struct eth_device *dev;
	struct dw_eth_dev *priv;

	dev = (struct eth_device *) malloc(sizeof(struct eth_device));
	if (!dev)
		return -ENOMEM;

	/*
	 * Since the priv structure contains the descriptors which need a strict
	 * buswidth alignment, memalign is used to allocate memory
	 */
	priv = (struct dw_eth_dev *) memalign(16, sizeof(struct dw_eth_dev));
	if (!priv) {
		free(dev);
		return -ENOMEM;
	}

	memset(dev, 0, sizeof(struct eth_device));
	memset(priv, 0, sizeof(struct dw_eth_dev));

	sprintf(dev->name, "mii%d", id);
	dev->iobase = (int)base_addr;
	dev->priv = priv;

	eth_getenv_enetaddr_by_index(id, &dev->enetaddr[0]);

	priv->dev = dev;
	priv->mac_regs_p = (struct eth_mac_regs *)base_addr;
	priv->dma_regs_p = (struct eth_dma_regs *)(base_addr +
			DW_DMA_BASE_OFFSET);
	priv->address = phy_addr;

	if (mac_reset(dev) < 0)
		return -1;

	if (configure_phy(dev) < 0) {
		printf("Phy could not be configured\n");
		return -1;
	}

	dev->init = dw_eth_init;
	dev->send = dw_eth_send;
	dev->recv = dw_eth_recv;
	dev->halt = dw_eth_halt;
	dev->write_hwaddr = dw_write_hwaddr;

	eth_register(dev);

#if defined(CONFIG_MII)
	miiphy_register(dev->name, dw_mii_read, dw_mii_write);
#endif
	return 1;
}
