/*
 * Altera 10/100/1000 triple speed ethernet mac driver
 *
 * Copyright (C) 2008 Altera Corporation.
 * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <common.h>
#include <cpu_func.h>
#include <dm.h>
#include <errno.h>
#include <fdt_support.h>
#include <log.h>
#include <memalign.h>
#include <miiphy.h>
#include <net.h>
#include <asm/cache.h>
#include <asm/global_data.h>
#include <linux/dma-mapping.h>
#include <asm/io.h>
#include "altera_tse.h"

DECLARE_GLOBAL_DATA_PTR;

static inline void alt_sgdma_construct_descriptor(
	struct alt_sgdma_descriptor *desc,
	struct alt_sgdma_descriptor *next,
	void *read_addr,
	void *write_addr,
	u16 length_or_eop,
	int generate_eop,
	int read_fixed,
	int write_fixed_or_sop)
{
	u8 val;

	/*
	 * Mark the "next" descriptor as "not" owned by hardware. This prevents
	 * The SGDMA controller from continuing to process the chain.
	 */
	next->descriptor_control = next->descriptor_control &
		~ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK;

	memset(desc, 0, sizeof(struct alt_sgdma_descriptor));
	desc->source = virt_to_phys(read_addr);
	desc->destination = virt_to_phys(write_addr);
	desc->next = virt_to_phys(next);
	desc->bytes_to_transfer = length_or_eop;

	/*
	 * Set the descriptor control block as follows:
	 * - Set "owned by hardware" bit
	 * - Optionally set "generate EOP" bit
	 * - Optionally set the "read from fixed address" bit
	 * - Optionally set the "write to fixed address bit (which serves
	 *   serves as a "generate SOP" control bit in memory-to-stream mode).
	 * - Set the 4-bit atlantic channel, if specified
	 *
	 * Note this step is performed after all other descriptor information
	 * has been filled out so that, if the controller already happens to be
	 * pointing at this descriptor, it will not run (via the "owned by
	 * hardware" bit) until all other descriptor has been set up.
	 */
	val = ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK;
	if (generate_eop)
		val |= ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK;
	if (read_fixed)
		val |= ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK;
	if (write_fixed_or_sop)
		val |= ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK;
	desc->descriptor_control = val;
}

static int alt_sgdma_wait_transfer(struct alt_sgdma_registers *regs)
{
	int status;
	ulong ctime;

	/* Wait for the descriptor (chain) to complete */
	ctime = get_timer(0);
	while (1) {
		status = readl(&regs->status);
		if (!(status & ALT_SGDMA_STATUS_BUSY_MSK))
			break;
		if (get_timer(ctime) > ALT_TSE_SGDMA_BUSY_TIMEOUT) {
			status = -ETIMEDOUT;
			debug("sgdma timeout\n");
			break;
		}
	}

	/* Clear Run */
	writel(0, &regs->control);
	/* Clear status */
	writel(0xff, &regs->status);

	return status;
}

static int alt_sgdma_start_transfer(struct alt_sgdma_registers *regs,
				    struct alt_sgdma_descriptor *desc)
{
	u32 val;

	/* Point the controller at the descriptor */
	writel(virt_to_phys(desc), &regs->next_descriptor_pointer);

	/*
	 * Set up SGDMA controller to:
	 * - Disable interrupt generation
	 * - Run once a valid descriptor is written to controller
	 * - Stop on an error with any particular descriptor
	 */
	val = ALT_SGDMA_CONTROL_RUN_MSK | ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK;
	writel(val, &regs->control);

	return 0;
}

static void tse_adjust_link(struct altera_tse_priv *priv,
			    struct phy_device *phydev)
{
	struct alt_tse_mac *mac_dev = priv->mac_dev;
	u32 refvar;

	if (!phydev->link) {
		debug("%s: No link.\n", phydev->dev->name);
		return;
	}

	refvar = readl(&mac_dev->command_config);

	if (phydev->duplex)
		refvar |= ALTERA_TSE_CMD_HD_ENA_MSK;
	else
		refvar &= ~ALTERA_TSE_CMD_HD_ENA_MSK;

	switch (phydev->speed) {
	case 1000:
		refvar |= ALTERA_TSE_CMD_ETH_SPEED_MSK;
		refvar &= ~ALTERA_TSE_CMD_ENA_10_MSK;
		break;
	case 100:
		refvar &= ~ALTERA_TSE_CMD_ETH_SPEED_MSK;
		refvar &= ~ALTERA_TSE_CMD_ENA_10_MSK;
		break;
	case 10:
		refvar &= ~ALTERA_TSE_CMD_ETH_SPEED_MSK;
		refvar |= ALTERA_TSE_CMD_ENA_10_MSK;
		break;
	}
	writel(refvar, &mac_dev->command_config);
}

static int altera_tse_send_sgdma(struct udevice *dev, void *packet, int length)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);
	struct alt_sgdma_descriptor *tx_desc = priv->tx_desc;

	alt_sgdma_construct_descriptor(
		tx_desc,
		tx_desc + 1,
		packet,	/* read addr */
		NULL,	/* write addr */
		length,	/* length or EOP ,will change for each tx */
		1,	/* gen eop */
		0,	/* read fixed */
		1	/* write fixed or sop */
		);

	/* send the packet */
	alt_sgdma_start_transfer(priv->sgdma_tx, tx_desc);
	alt_sgdma_wait_transfer(priv->sgdma_tx);
	debug("sent %d bytes\n", tx_desc->actual_bytes_transferred);

	return tx_desc->actual_bytes_transferred;
}

static int altera_tse_recv_sgdma(struct udevice *dev, int flags,
				 uchar **packetp)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);
	struct alt_sgdma_descriptor *rx_desc = priv->rx_desc;
	int packet_length;

	if (rx_desc->descriptor_status &
	    ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) {
		alt_sgdma_wait_transfer(priv->sgdma_rx);
		packet_length = rx_desc->actual_bytes_transferred;
		debug("recv %d bytes\n", packet_length);
		*packetp = priv->rx_buf;

		return packet_length;
	}

	return -EAGAIN;
}

static int altera_tse_free_pkt_sgdma(struct udevice *dev, uchar *packet,
				     int length)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);
	struct alt_sgdma_descriptor *rx_desc = priv->rx_desc;

	alt_sgdma_construct_descriptor(
		rx_desc,
		rx_desc + 1,
		NULL,	/* read addr */
		priv->rx_buf, /* write addr */
		0,	/* length or EOP */
		0,	/* gen eop */
		0,	/* read fixed */
		0	/* write fixed or sop */
		);

	/* setup the sgdma */
	alt_sgdma_start_transfer(priv->sgdma_rx, rx_desc);
	debug("recv setup\n");

	return 0;
}

static void altera_tse_stop_mac(struct altera_tse_priv *priv)
{
	struct alt_tse_mac *mac_dev = priv->mac_dev;
	u32 status;
	ulong ctime;

	/* reset the mac */
	writel(ALTERA_TSE_CMD_SW_RESET_MSK, &mac_dev->command_config);
	ctime = get_timer(0);
	while (1) {
		status = readl(&mac_dev->command_config);
		if (!(status & ALTERA_TSE_CMD_SW_RESET_MSK))
			break;
		if (get_timer(ctime) > ALT_TSE_SW_RESET_TIMEOUT) {
			debug("Reset mac timeout\n");
			break;
		}
	}
}

static void altera_tse_stop_sgdma(struct udevice *dev)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);
	struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx;
	struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx;
	struct alt_sgdma_descriptor *rx_desc = priv->rx_desc;
	int ret;

	/* clear rx desc & wait for sgdma to complete */
	rx_desc->descriptor_control = 0;
	writel(0, &rx_sgdma->control);
	ret = alt_sgdma_wait_transfer(rx_sgdma);
	if (ret == -ETIMEDOUT)
		writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK,
		       &rx_sgdma->control);

	writel(0, &tx_sgdma->control);
	ret = alt_sgdma_wait_transfer(tx_sgdma);
	if (ret == -ETIMEDOUT)
		writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK,
		       &tx_sgdma->control);
}

static void msgdma_reset(struct msgdma_csr *csr)
{
	u32 status;
	ulong ctime;

	/* Reset mSGDMA */
	writel(MSGDMA_CSR_STAT_MASK, &csr->status);
	writel(MSGDMA_CSR_CTL_RESET, &csr->control);
	ctime = get_timer(0);
	while (1) {
		status = readl(&csr->status);
		if (!(status & MSGDMA_CSR_STAT_RESETTING))
			break;
		if (get_timer(ctime) > ALT_TSE_SW_RESET_TIMEOUT) {
			debug("Reset msgdma timeout\n");
			break;
		}
	}
	/* Clear status */
	writel(MSGDMA_CSR_STAT_MASK, &csr->status);
}

static u32 msgdma_wait(struct msgdma_csr *csr)
{
	u32 status;
	ulong ctime;

	/* Wait for the descriptor to complete */
	ctime = get_timer(0);
	while (1) {
		status = readl(&csr->status);
		if (!(status & MSGDMA_CSR_STAT_BUSY))
			break;
		if (get_timer(ctime) > ALT_TSE_SGDMA_BUSY_TIMEOUT) {
			debug("sgdma timeout\n");
			break;
		}
	}
	/* Clear status */
	writel(MSGDMA_CSR_STAT_MASK, &csr->status);

	return status;
}

static int altera_tse_send_msgdma(struct udevice *dev, void *packet,
				  int length)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);
	struct msgdma_extended_desc *desc = priv->tx_desc;
	u32 tx_buf = virt_to_phys(packet);
	u32 status;

	writel(tx_buf, &desc->read_addr_lo);
	writel(0, &desc->read_addr_hi);
	writel(0, &desc->write_addr_lo);
	writel(0, &desc->write_addr_hi);
	writel(length, &desc->len);
	writel(0, &desc->burst_seq_num);
	writel(MSGDMA_DESC_TX_STRIDE, &desc->stride);
	writel(MSGDMA_DESC_CTL_TX_SINGLE, &desc->control);
	status = msgdma_wait(priv->sgdma_tx);
	debug("sent %d bytes, status %08x\n", length, status);

	return 0;
}

static int altera_tse_recv_msgdma(struct udevice *dev, int flags,
				  uchar **packetp)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);
	struct msgdma_csr *csr = priv->sgdma_rx;
	struct msgdma_response *resp = priv->rx_resp;
	u32 level, length, status;

	level = readl(&csr->resp_fill_level);
	if (level & 0xffff) {
		length = readl(&resp->bytes_transferred);
		status = readl(&resp->status);
		debug("recv %d bytes, status %08x\n", length, status);
		*packetp = priv->rx_buf;

		return length;
	}

	return -EAGAIN;
}

static int altera_tse_free_pkt_msgdma(struct udevice *dev, uchar *packet,
				      int length)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);
	struct msgdma_extended_desc *desc = priv->rx_desc;
	u32 rx_buf = virt_to_phys(priv->rx_buf);

	writel(0, &desc->read_addr_lo);
	writel(0, &desc->read_addr_hi);
	writel(rx_buf, &desc->write_addr_lo);
	writel(0, &desc->write_addr_hi);
	writel(PKTSIZE_ALIGN, &desc->len);
	writel(0, &desc->burst_seq_num);
	writel(MSGDMA_DESC_RX_STRIDE, &desc->stride);
	writel(MSGDMA_DESC_CTL_RX_SINGLE, &desc->control);
	debug("recv setup\n");

	return 0;
}

static void altera_tse_stop_msgdma(struct udevice *dev)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);

	msgdma_reset(priv->sgdma_rx);
	msgdma_reset(priv->sgdma_tx);
}

static int tse_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
{
	struct altera_tse_priv *priv = bus->priv;
	struct alt_tse_mac *mac_dev = priv->mac_dev;
	u32 value;

	/* set mdio address */
	writel(addr, &mac_dev->mdio_phy1_addr);
	/* get the data */
	value = readl(&mac_dev->mdio_phy1[reg]);

	return value & 0xffff;
}

static int tse_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
			  u16 val)
{
	struct altera_tse_priv *priv = bus->priv;
	struct alt_tse_mac *mac_dev = priv->mac_dev;

	/* set mdio address */
	writel(addr, &mac_dev->mdio_phy1_addr);
	/* set the data */
	writel(val, &mac_dev->mdio_phy1[reg]);

	return 0;
}

static int tse_mdio_init(const char *name, struct altera_tse_priv *priv)
{
	struct mii_dev *bus = mdio_alloc();

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

	bus->read = tse_mdio_read;
	bus->write = tse_mdio_write;
	snprintf(bus->name, sizeof(bus->name), "%s", name);

	bus->priv = (void *)priv;

	return mdio_register(bus);
}

static int tse_phy_init(struct altera_tse_priv *priv, void *dev)
{
	struct phy_device *phydev;

	phydev = phy_connect(priv->bus, -1, dev, priv->interface);
	if (!phydev)
		return -ENODEV;

	phydev->supported &= PHY_GBIT_FEATURES;
	phydev->advertising = phydev->supported;

	priv->phydev = phydev;
	phy_config(phydev);

	return 0;
}

static int altera_tse_write_hwaddr(struct udevice *dev)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);
	struct alt_tse_mac *mac_dev = priv->mac_dev;
	struct eth_pdata *pdata = dev_get_plat(dev);
	u8 *hwaddr = pdata->enetaddr;
	u32 mac_lo, mac_hi;

	mac_lo = (hwaddr[3] << 24) | (hwaddr[2] << 16) |
		(hwaddr[1] << 8) | hwaddr[0];
	mac_hi = (hwaddr[5] << 8) | hwaddr[4];
	debug("Set MAC address to 0x%04x%08x\n", mac_hi, mac_lo);

	writel(mac_lo, &mac_dev->mac_addr_0);
	writel(mac_hi, &mac_dev->mac_addr_1);
	writel(mac_lo, &mac_dev->supp_mac_addr_0_0);
	writel(mac_hi, &mac_dev->supp_mac_addr_0_1);
	writel(mac_lo, &mac_dev->supp_mac_addr_1_0);
	writel(mac_hi, &mac_dev->supp_mac_addr_1_1);
	writel(mac_lo, &mac_dev->supp_mac_addr_2_0);
	writel(mac_hi, &mac_dev->supp_mac_addr_2_1);
	writel(mac_lo, &mac_dev->supp_mac_addr_3_0);
	writel(mac_hi, &mac_dev->supp_mac_addr_3_1);

	return 0;
}

static int altera_tse_send(struct udevice *dev, void *packet, int length)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);
	unsigned long tx_buf = (unsigned long)packet;

	flush_dcache_range(tx_buf, tx_buf + length);

	return priv->ops->send(dev, packet, length);
}

static int altera_tse_recv(struct udevice *dev, int flags, uchar **packetp)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);

	return priv->ops->recv(dev, flags, packetp);
}

static int altera_tse_free_pkt(struct udevice *dev, uchar *packet,
			       int length)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);
	unsigned long rx_buf = (unsigned long)priv->rx_buf;

	invalidate_dcache_range(rx_buf, rx_buf + PKTSIZE_ALIGN);

	return priv->ops->free_pkt(dev, packet, length);
}

static void altera_tse_stop(struct udevice *dev)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);

	priv->ops->stop(dev);
	altera_tse_stop_mac(priv);
}

static int altera_tse_start(struct udevice *dev)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);
	struct alt_tse_mac *mac_dev = priv->mac_dev;
	u32 val;
	int ret;

	/* need to create sgdma */
	debug("Configuring rx desc\n");
	altera_tse_free_pkt(dev, priv->rx_buf, PKTSIZE_ALIGN);
	/* start TSE */
	debug("Configuring TSE Mac\n");
	/* Initialize MAC registers */
	writel(PKTSIZE_ALIGN, &mac_dev->max_frame_length);
	writel(priv->rx_fifo_depth - 16, &mac_dev->rx_sel_empty_threshold);
	writel(0, &mac_dev->rx_sel_full_threshold);
	writel(priv->tx_fifo_depth - 16, &mac_dev->tx_sel_empty_threshold);
	writel(0, &mac_dev->tx_sel_full_threshold);
	writel(8, &mac_dev->rx_almost_empty_threshold);
	writel(8, &mac_dev->rx_almost_full_threshold);
	writel(8, &mac_dev->tx_almost_empty_threshold);
	writel(3, &mac_dev->tx_almost_full_threshold);

	/* NO Shift */
	writel(0, &mac_dev->rx_cmd_stat);
	writel(0, &mac_dev->tx_cmd_stat);

	/* enable MAC */
	val = ALTERA_TSE_CMD_TX_ENA_MSK | ALTERA_TSE_CMD_RX_ENA_MSK;
	writel(val, &mac_dev->command_config);

	/* Start up the PHY */
	ret = phy_startup(priv->phydev);
	if (ret) {
		debug("Could not initialize PHY %s\n",
		      priv->phydev->dev->name);
		return ret;
	}

	tse_adjust_link(priv, priv->phydev);

	if (!priv->phydev->link)
		return -EIO;

	return 0;
}

static const struct tse_ops tse_sgdma_ops = {
	.send		= altera_tse_send_sgdma,
	.recv		= altera_tse_recv_sgdma,
	.free_pkt	= altera_tse_free_pkt_sgdma,
	.stop		= altera_tse_stop_sgdma,
};

static const struct tse_ops tse_msgdma_ops = {
	.send		= altera_tse_send_msgdma,
	.recv		= altera_tse_recv_msgdma,
	.free_pkt	= altera_tse_free_pkt_msgdma,
	.stop		= altera_tse_stop_msgdma,
};

static int altera_tse_probe(struct udevice *dev)
{
	struct eth_pdata *pdata = dev_get_plat(dev);
	struct altera_tse_priv *priv = dev_get_priv(dev);
	void *blob = (void *)gd->fdt_blob;
	int node = dev_of_offset(dev);
	const char *list, *end;
	const fdt32_t *cell;
	void *base, *desc_mem = NULL;
	unsigned long addr, size;
	int parent, addrc, sizec;
	int len, idx;
	int ret;

	priv->dma_type = dev_get_driver_data(dev);
	if (priv->dma_type == ALT_SGDMA)
		priv->ops = &tse_sgdma_ops;
	else
		priv->ops = &tse_msgdma_ops;
	/*
	 * decode regs. there are multiple reg tuples, and they need to
	 * match with reg-names.
	 */
	parent = fdt_parent_offset(blob, node);
	fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
	list = fdt_getprop(blob, node, "reg-names", &len);
	if (!list)
		return -ENOENT;
	end = list + len;
	cell = fdt_getprop(blob, node, "reg", &len);
	if (!cell)
		return -ENOENT;
	idx = 0;
	while (list < end) {
		addr = fdt_translate_address((void *)blob,
					     node, cell + idx);
		size = fdt_addr_to_cpu(cell[idx + addrc]);
		base = map_physmem(addr, size, MAP_NOCACHE);
		len = strlen(list);
		if (strcmp(list, "control_port") == 0)
			priv->mac_dev = base;
		else if (strcmp(list, "rx_csr") == 0)
			priv->sgdma_rx = base;
		else if (strcmp(list, "rx_desc") == 0)
			priv->rx_desc = base;
		else if (strcmp(list, "rx_resp") == 0)
			priv->rx_resp = base;
		else if (strcmp(list, "tx_csr") == 0)
			priv->sgdma_tx = base;
		else if (strcmp(list, "tx_desc") == 0)
			priv->tx_desc = base;
		else if (strcmp(list, "s1") == 0)
			desc_mem = base;
		idx += addrc + sizec;
		list += (len + 1);
	}
	/* decode fifo depth */
	priv->rx_fifo_depth = fdtdec_get_int(blob, node,
		"rx-fifo-depth", 0);
	priv->tx_fifo_depth = fdtdec_get_int(blob, node,
		"tx-fifo-depth", 0);
	/* decode phy */
	addr = fdtdec_get_int(blob, node,
			      "phy-handle", 0);
	addr = fdt_node_offset_by_phandle(blob, addr);
	priv->phyaddr = fdtdec_get_int(blob, addr,
		"reg", 0);
	/* init desc */
	if (priv->dma_type == ALT_SGDMA) {
		len = sizeof(struct alt_sgdma_descriptor) * 4;
		if (!desc_mem) {
			desc_mem = dma_alloc_coherent(len, &addr);
			if (!desc_mem)
				return -ENOMEM;
		}
		memset(desc_mem, 0, len);
		priv->tx_desc = desc_mem;
		priv->rx_desc = priv->tx_desc +
			2 * sizeof(struct alt_sgdma_descriptor);
	}
	/* allocate recv packet buffer */
	priv->rx_buf = malloc_cache_aligned(PKTSIZE_ALIGN);
	if (!priv->rx_buf)
		return -ENOMEM;

	/* stop controller */
	debug("Reset TSE & SGDMAs\n");
	altera_tse_stop(dev);

	/* start the phy */
	priv->interface = pdata->phy_interface;
	tse_mdio_init(dev->name, priv);
	priv->bus = miiphy_get_dev_by_name(dev->name);

	ret = tse_phy_init(priv, dev);

	return ret;
}

static int altera_tse_of_to_plat(struct udevice *dev)
{
	struct eth_pdata *pdata = dev_get_plat(dev);

	pdata->phy_interface = dev_read_phy_mode(dev);
	if (pdata->phy_interface == PHY_INTERFACE_MODE_NA)
		return -EINVAL;

	return 0;
}

static const struct eth_ops altera_tse_ops = {
	.start		= altera_tse_start,
	.send		= altera_tse_send,
	.recv		= altera_tse_recv,
	.free_pkt	= altera_tse_free_pkt,
	.stop		= altera_tse_stop,
	.write_hwaddr	= altera_tse_write_hwaddr,
};

static const struct udevice_id altera_tse_ids[] = {
	{ .compatible = "altr,tse-msgdma-1.0", .data = ALT_MSGDMA },
	{ .compatible = "altr,tse-1.0", .data = ALT_SGDMA },
	{}
};

U_BOOT_DRIVER(altera_tse) = {
	.name	= "altera_tse",
	.id	= UCLASS_ETH,
	.of_match = altera_tse_ids,
	.ops	= &altera_tse_ops,
	.of_to_plat = altera_tse_of_to_plat,
	.plat_auto	= sizeof(struct eth_pdata),
	.priv_auto	= sizeof(struct altera_tse_priv),
	.probe	= altera_tse_probe,
};
