/*
 * EP93XX PATA controller driver.
 *
 * Copyright (c) 2012, Metasoft s.c.
 *	Rafal Prylowski <prylowski@metasoft.pl>
 *
 * Based on pata_scc.c, pata_icside.c and on earlier version of EP93XX
 * PATA driver by Lennert Buytenhek and Alessandro Zummo.
 * Read/Write timings, resource management and other improvements
 * from driver by Joao Ramos and Bartlomiej Zolnierkiewicz.
 * DMA engine support based on spi-ep93xx.c by Mika Westerberg.
 *
 * Original copyrights:
 *
 * Support for Cirrus Logic's EP93xx (EP9312, EP9315) CPUs
 * PATA host controller driver.
 *
 * Copyright (c) 2009, Bartlomiej Zolnierkiewicz
 *
 * Heavily based on the ep93xx-ide.c driver:
 *
 * Copyright (c) 2009, Joao Ramos <joao.ramos@inov.pt>
 *		      INESC Inovacao (INOV)
 *
 * EP93XX PATA controller driver.
 * Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
 *
 * An ATA driver for the Cirrus Logic EP93xx PATA controller.
 *
 * Based on an earlier version by Alessandro Zummo, which is:
 *   Copyright (C) 2006 Tower Technologies
 */

#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/blkdev.h>
#include <scsi/scsi_host.h>
#include <linux/ata.h>
#include <linux/libata.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/ktime.h>

#include <linux/platform_data/dma-ep93xx.h>
#include <mach/platform.h>

#define DRV_NAME	"ep93xx-ide"
#define DRV_VERSION	"1.0"

enum {
	/* IDE Control Register */
	IDECTRL				= 0x00,
	IDECTRL_CS0N			= (1 << 0),
	IDECTRL_CS1N			= (1 << 1),
	IDECTRL_DIORN			= (1 << 5),
	IDECTRL_DIOWN			= (1 << 6),
	IDECTRL_INTRQ			= (1 << 9),
	IDECTRL_IORDY			= (1 << 10),
	/*
	 * the device IDE register to be accessed is selected through
	 * IDECTRL register's specific bitfields 'DA', 'CS1N' and 'CS0N':
	 *   b4   b3   b2    b1     b0
	 *   A2   A1   A0   CS1N   CS0N
	 * the values filled in this structure allows the value to be directly
	 * ORed to the IDECTRL register, hence giving directly the A[2:0] and
	 * CS1N/CS0N values for each IDE register.
	 * The values correspond to the transformation:
	 *   ((real IDE address) << 2) | CS1N value << 1 | CS0N value
	 */
	IDECTRL_ADDR_CMD		= 0 + 2, /* CS1 */
	IDECTRL_ADDR_DATA		= (ATA_REG_DATA << 2) + 2,
	IDECTRL_ADDR_ERROR		= (ATA_REG_ERR << 2) + 2,
	IDECTRL_ADDR_FEATURE		= (ATA_REG_FEATURE << 2) + 2,
	IDECTRL_ADDR_NSECT		= (ATA_REG_NSECT << 2) + 2,
	IDECTRL_ADDR_LBAL		= (ATA_REG_LBAL << 2) + 2,
	IDECTRL_ADDR_LBAM		= (ATA_REG_LBAM << 2) + 2,
	IDECTRL_ADDR_LBAH		= (ATA_REG_LBAH << 2) + 2,
	IDECTRL_ADDR_DEVICE		= (ATA_REG_DEVICE << 2) + 2,
	IDECTRL_ADDR_STATUS		= (ATA_REG_STATUS << 2) + 2,
	IDECTRL_ADDR_COMMAND		= (ATA_REG_CMD << 2) + 2,
	IDECTRL_ADDR_ALTSTATUS		= (0x06 << 2) + 1, /* CS0 */
	IDECTRL_ADDR_CTL		= (0x06 << 2) + 1, /* CS0 */

	/* IDE Configuration Register */
	IDECFG				= 0x04,
	IDECFG_IDEEN			= (1 << 0),
	IDECFG_PIO			= (1 << 1),
	IDECFG_MDMA			= (1 << 2),
	IDECFG_UDMA			= (1 << 3),
	IDECFG_MODE_SHIFT		= 4,
	IDECFG_MODE_MASK		= (0xf << 4),
	IDECFG_WST_SHIFT		= 8,
	IDECFG_WST_MASK			= (0x3 << 8),

	/* MDMA Operation Register */
	IDEMDMAOP			= 0x08,

	/* UDMA Operation Register */
	IDEUDMAOP			= 0x0c,
	IDEUDMAOP_UEN			= (1 << 0),
	IDEUDMAOP_RWOP			= (1 << 1),

	/* PIO/MDMA/UDMA Data Registers */
	IDEDATAOUT			= 0x10,
	IDEDATAIN			= 0x14,
	IDEMDMADATAOUT			= 0x18,
	IDEMDMADATAIN			= 0x1c,
	IDEUDMADATAOUT			= 0x20,
	IDEUDMADATAIN			= 0x24,

	/* UDMA Status Register */
	IDEUDMASTS			= 0x28,
	IDEUDMASTS_DMAIDE		= (1 << 16),
	IDEUDMASTS_INTIDE		= (1 << 17),
	IDEUDMASTS_SBUSY		= (1 << 18),
	IDEUDMASTS_NDO			= (1 << 24),
	IDEUDMASTS_NDI			= (1 << 25),
	IDEUDMASTS_N4X			= (1 << 26),

	/* UDMA Debug Status Register */
	IDEUDMADEBUG			= 0x2c,
};

struct ep93xx_pata_data {
	const struct platform_device *pdev;
	void __iomem *ide_base;
	struct ata_timing t;
	bool iordy;

	unsigned long udma_in_phys;
	unsigned long udma_out_phys;

	struct dma_chan *dma_rx_channel;
	struct ep93xx_dma_data dma_rx_data;
	struct dma_chan *dma_tx_channel;
	struct ep93xx_dma_data dma_tx_data;
};

static void ep93xx_pata_clear_regs(void __iomem *base)
{
	writel(IDECTRL_CS0N | IDECTRL_CS1N | IDECTRL_DIORN |
		IDECTRL_DIOWN, base + IDECTRL);

	writel(0, base + IDECFG);
	writel(0, base + IDEMDMAOP);
	writel(0, base + IDEUDMAOP);
	writel(0, base + IDEDATAOUT);
	writel(0, base + IDEDATAIN);
	writel(0, base + IDEMDMADATAOUT);
	writel(0, base + IDEMDMADATAIN);
	writel(0, base + IDEUDMADATAOUT);
	writel(0, base + IDEUDMADATAIN);
	writel(0, base + IDEUDMADEBUG);
}

static bool ep93xx_pata_check_iordy(void __iomem *base)
{
	return !!(readl(base + IDECTRL) & IDECTRL_IORDY);
}

/*
 * According to EP93xx User's Guide, WST field of IDECFG specifies number
 * of HCLK cycles to hold the data bus after a PIO write operation.
 * It should be programmed to guarantee following delays:
 *
 * PIO Mode   [ns]
 * 0          30
 * 1          20
 * 2          15
 * 3          10
 * 4          5
 *
 * Maximum possible value for HCLK is 100MHz.
 */
static int ep93xx_pata_get_wst(int pio_mode)
{
	int val;

	if (pio_mode == 0)
		val = 3;
	else if (pio_mode < 3)
		val = 2;
	else
		val = 1;

	return val << IDECFG_WST_SHIFT;
}

static void ep93xx_pata_enable_pio(void __iomem *base, int pio_mode)
{
	writel(IDECFG_IDEEN | IDECFG_PIO |
		ep93xx_pata_get_wst(pio_mode) |
		(pio_mode << IDECFG_MODE_SHIFT), base + IDECFG);
}

/*
 * Based on delay loop found in mach-pxa/mp900.c.
 *
 * Single iteration should take 5 cpu cycles. This is 25ns assuming the
 * fastest ep93xx cpu speed (200MHz) and is better optimized for PIO4 timings
 * than eg. 20ns.
 */
static void ep93xx_pata_delay(unsigned long count)
{
	__asm__ volatile (
		"0:\n"
		"mov r0, r0\n"
		"subs %0, %1, #1\n"
		"bge 0b\n"
		: "=r" (count)
		: "0" (count)
	);
}

static unsigned long ep93xx_pata_wait_for_iordy(void __iomem *base,
						unsigned long t2)
{
	/*
	 * According to ATA specification, IORDY pin can be first sampled
	 * tA = 35ns after activation of DIOR-/DIOW-. Maximum IORDY pulse
	 * width is tB = 1250ns.
	 *
	 * We are already t2 delay loop iterations after activation of
	 * DIOR-/DIOW-, so we set timeout to (1250 + 35) / 25 - t2 additional
	 * delay loop iterations.
	 */
	unsigned long start = (1250 + 35) / 25 - t2;
	unsigned long counter = start;

	while (!ep93xx_pata_check_iordy(base) && counter--)
		ep93xx_pata_delay(1);
	return start - counter;
}

/* common part at start of ep93xx_pata_read/write() */
static void ep93xx_pata_rw_begin(void __iomem *base, unsigned long addr,
				 unsigned long t1)
{
	writel(IDECTRL_DIOWN | IDECTRL_DIORN | addr, base + IDECTRL);
	ep93xx_pata_delay(t1);
}

/* common part at end of ep93xx_pata_read/write() */
static void ep93xx_pata_rw_end(void __iomem *base, unsigned long addr,
			       bool iordy, unsigned long t0, unsigned long t2,
			       unsigned long t2i)
{
	ep93xx_pata_delay(t2);
	/* lengthen t2 if needed */
	if (iordy)
		t2 += ep93xx_pata_wait_for_iordy(base, t2);
	writel(IDECTRL_DIOWN | IDECTRL_DIORN | addr, base + IDECTRL);
	if (t0 > t2 && t0 - t2 > t2i)
		ep93xx_pata_delay(t0 - t2);
	else
		ep93xx_pata_delay(t2i);
}

static u16 ep93xx_pata_read(struct ep93xx_pata_data *drv_data,
			    unsigned long addr,
			    bool reg)
{
	void __iomem *base = drv_data->ide_base;
	const struct ata_timing *t = &drv_data->t;
	unsigned long t0 = reg ? t->cyc8b : t->cycle;
	unsigned long t2 = reg ? t->act8b : t->active;
	unsigned long t2i = reg ? t->rec8b : t->recover;

	ep93xx_pata_rw_begin(base, addr, t->setup);
	writel(IDECTRL_DIOWN | addr, base + IDECTRL);
	/*
	 * The IDEDATAIN register is loaded from the DD pins at the positive
	 * edge of the DIORN signal. (EP93xx UG p27-14)
	 */
	ep93xx_pata_rw_end(base, addr, drv_data->iordy, t0, t2, t2i);
	return readl(base + IDEDATAIN);
}

/* IDE register read */
static u16 ep93xx_pata_read_reg(struct ep93xx_pata_data *drv_data,
				unsigned long addr)
{
	return ep93xx_pata_read(drv_data, addr, true);
}

/* PIO data read */
static u16 ep93xx_pata_read_data(struct ep93xx_pata_data *drv_data,
				 unsigned long addr)
{
	return ep93xx_pata_read(drv_data, addr, false);
}

static void ep93xx_pata_write(struct ep93xx_pata_data *drv_data,
			      u16 value, unsigned long addr,
			      bool reg)
{
	void __iomem *base = drv_data->ide_base;
	const struct ata_timing *t = &drv_data->t;
	unsigned long t0 = reg ? t->cyc8b : t->cycle;
	unsigned long t2 = reg ? t->act8b : t->active;
	unsigned long t2i = reg ? t->rec8b : t->recover;

	ep93xx_pata_rw_begin(base, addr, t->setup);
	/*
	 * Value from IDEDATAOUT register is driven onto the DD pins when
	 * DIOWN is low. (EP93xx UG p27-13)
	 */
	writel(value, base + IDEDATAOUT);
	writel(IDECTRL_DIORN | addr, base + IDECTRL);
	ep93xx_pata_rw_end(base, addr, drv_data->iordy, t0, t2, t2i);
}

/* IDE register write */
static void ep93xx_pata_write_reg(struct ep93xx_pata_data *drv_data,
				  u16 value, unsigned long addr)
{
	ep93xx_pata_write(drv_data, value, addr, true);
}

/* PIO data write */
static void ep93xx_pata_write_data(struct ep93xx_pata_data *drv_data,
				   u16 value, unsigned long addr)
{
	ep93xx_pata_write(drv_data, value, addr, false);
}

static void ep93xx_pata_set_piomode(struct ata_port *ap,
				    struct ata_device *adev)
{
	struct ep93xx_pata_data *drv_data = ap->host->private_data;
	struct ata_device *pair = ata_dev_pair(adev);
	/*
	 * Calculate timings for the delay loop, assuming ep93xx cpu speed
	 * is 200MHz (maximum possible for ep93xx). If actual cpu speed is
	 * slower, we will wait a bit longer in each delay.
	 * Additional division of cpu speed by 5, because single iteration
	 * of our delay loop takes 5 cpu cycles (25ns).
	 */
	unsigned long T = 1000000 / (200 / 5);

	ata_timing_compute(adev, adev->pio_mode, &drv_data->t, T, 0);
	if (pair && pair->pio_mode) {
		struct ata_timing t;
		ata_timing_compute(pair, pair->pio_mode, &t, T, 0);
		ata_timing_merge(&t, &drv_data->t, &drv_data->t,
			ATA_TIMING_SETUP | ATA_TIMING_8BIT);
	}
	drv_data->iordy = ata_pio_need_iordy(adev);

	ep93xx_pata_enable_pio(drv_data->ide_base,
			       adev->pio_mode - XFER_PIO_0);
}

/* Note: original code is ata_sff_check_status */
static u8 ep93xx_pata_check_status(struct ata_port *ap)
{
	struct ep93xx_pata_data *drv_data = ap->host->private_data;

	return ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_STATUS);
}

static u8 ep93xx_pata_check_altstatus(struct ata_port *ap)
{
	struct ep93xx_pata_data *drv_data = ap->host->private_data;

	return ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_ALTSTATUS);
}

/* Note: original code is ata_sff_tf_load */
static void ep93xx_pata_tf_load(struct ata_port *ap,
				const struct ata_taskfile *tf)
{
	struct ep93xx_pata_data *drv_data = ap->host->private_data;
	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;

	if (tf->ctl != ap->last_ctl) {
		ep93xx_pata_write_reg(drv_data, tf->ctl, IDECTRL_ADDR_CTL);
		ap->last_ctl = tf->ctl;
		ata_wait_idle(ap);
	}

	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
		ep93xx_pata_write_reg(drv_data, tf->hob_feature,
			IDECTRL_ADDR_FEATURE);
		ep93xx_pata_write_reg(drv_data, tf->hob_nsect,
			IDECTRL_ADDR_NSECT);
		ep93xx_pata_write_reg(drv_data, tf->hob_lbal,
			IDECTRL_ADDR_LBAL);
		ep93xx_pata_write_reg(drv_data, tf->hob_lbam,
			IDECTRL_ADDR_LBAM);
		ep93xx_pata_write_reg(drv_data, tf->hob_lbah,
			IDECTRL_ADDR_LBAH);
	}

	if (is_addr) {
		ep93xx_pata_write_reg(drv_data, tf->feature,
			IDECTRL_ADDR_FEATURE);
		ep93xx_pata_write_reg(drv_data, tf->nsect, IDECTRL_ADDR_NSECT);
		ep93xx_pata_write_reg(drv_data, tf->lbal, IDECTRL_ADDR_LBAL);
		ep93xx_pata_write_reg(drv_data, tf->lbam, IDECTRL_ADDR_LBAM);
		ep93xx_pata_write_reg(drv_data, tf->lbah, IDECTRL_ADDR_LBAH);
	}

	if (tf->flags & ATA_TFLAG_DEVICE)
		ep93xx_pata_write_reg(drv_data, tf->device,
			IDECTRL_ADDR_DEVICE);

	ata_wait_idle(ap);
}

/* Note: original code is ata_sff_tf_read */
static void ep93xx_pata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
	struct ep93xx_pata_data *drv_data = ap->host->private_data;

	tf->command = ep93xx_pata_check_status(ap);
	tf->feature = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_FEATURE);
	tf->nsect = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_NSECT);
	tf->lbal = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_LBAL);
	tf->lbam = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_LBAM);
	tf->lbah = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_LBAH);
	tf->device = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_DEVICE);

	if (tf->flags & ATA_TFLAG_LBA48) {
		ep93xx_pata_write_reg(drv_data, tf->ctl | ATA_HOB,
			IDECTRL_ADDR_CTL);
		tf->hob_feature = ep93xx_pata_read_reg(drv_data,
			IDECTRL_ADDR_FEATURE);
		tf->hob_nsect = ep93xx_pata_read_reg(drv_data,
			IDECTRL_ADDR_NSECT);
		tf->hob_lbal = ep93xx_pata_read_reg(drv_data,
			IDECTRL_ADDR_LBAL);
		tf->hob_lbam = ep93xx_pata_read_reg(drv_data,
			IDECTRL_ADDR_LBAM);
		tf->hob_lbah = ep93xx_pata_read_reg(drv_data,
			IDECTRL_ADDR_LBAH);
		ep93xx_pata_write_reg(drv_data, tf->ctl, IDECTRL_ADDR_CTL);
		ap->last_ctl = tf->ctl;
	}
}

/* Note: original code is ata_sff_exec_command */
static void ep93xx_pata_exec_command(struct ata_port *ap,
				     const struct ata_taskfile *tf)
{
	struct ep93xx_pata_data *drv_data = ap->host->private_data;

	ep93xx_pata_write_reg(drv_data, tf->command,
			  IDECTRL_ADDR_COMMAND);
	ata_sff_pause(ap);
}

/* Note: original code is ata_sff_dev_select */
static void ep93xx_pata_dev_select(struct ata_port *ap, unsigned int device)
{
	struct ep93xx_pata_data *drv_data = ap->host->private_data;
	u8 tmp = ATA_DEVICE_OBS;

	if (device != 0)
		tmp |= ATA_DEV1;

	ep93xx_pata_write_reg(drv_data, tmp, IDECTRL_ADDR_DEVICE);
	ata_sff_pause(ap);	/* needed; also flushes, for mmio */
}

/* Note: original code is ata_sff_set_devctl */
static void ep93xx_pata_set_devctl(struct ata_port *ap, u8 ctl)
{
	struct ep93xx_pata_data *drv_data = ap->host->private_data;

	ep93xx_pata_write_reg(drv_data, ctl, IDECTRL_ADDR_CTL);
}

/* Note: original code is ata_sff_data_xfer */
static unsigned int ep93xx_pata_data_xfer(struct ata_device *adev,
					  unsigned char *buf,
					  unsigned int buflen, int rw)
{
	struct ata_port *ap = adev->link->ap;
	struct ep93xx_pata_data *drv_data = ap->host->private_data;
	u16 *data = (u16 *)buf;
	unsigned int words = buflen >> 1;

	/* Transfer multiple of 2 bytes */
	while (words--)
		if (rw == READ)
			*data++ = cpu_to_le16(
				ep93xx_pata_read_data(
					drv_data, IDECTRL_ADDR_DATA));
		else
			ep93xx_pata_write_data(drv_data, le16_to_cpu(*data++),
				IDECTRL_ADDR_DATA);

	/* Transfer trailing 1 byte, if any. */
	if (unlikely(buflen & 0x01)) {
		unsigned char pad[2] = { };

		buf += buflen - 1;

		if (rw == READ) {
			*pad = cpu_to_le16(
				ep93xx_pata_read_data(
					drv_data, IDECTRL_ADDR_DATA));
			*buf = pad[0];
		} else {
			pad[0] = *buf;
			ep93xx_pata_write_data(drv_data, le16_to_cpu(*pad),
					  IDECTRL_ADDR_DATA);
		}
		words++;
	}

	return words << 1;
}

/* Note: original code is ata_devchk */
static bool ep93xx_pata_device_is_present(struct ata_port *ap,
					  unsigned int device)
{
	struct ep93xx_pata_data *drv_data = ap->host->private_data;
	u8 nsect, lbal;

	ap->ops->sff_dev_select(ap, device);

	ep93xx_pata_write_reg(drv_data, 0x55, IDECTRL_ADDR_NSECT);
	ep93xx_pata_write_reg(drv_data, 0xaa, IDECTRL_ADDR_LBAL);

	ep93xx_pata_write_reg(drv_data, 0xaa, IDECTRL_ADDR_NSECT);
	ep93xx_pata_write_reg(drv_data, 0x55, IDECTRL_ADDR_LBAL);

	ep93xx_pata_write_reg(drv_data, 0x55, IDECTRL_ADDR_NSECT);
	ep93xx_pata_write_reg(drv_data, 0xaa, IDECTRL_ADDR_LBAL);

	nsect = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_NSECT);
	lbal = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_LBAL);

	if ((nsect == 0x55) && (lbal == 0xaa))
		return true;

	return false;
}

/* Note: original code is ata_sff_wait_after_reset */
static int ep93xx_pata_wait_after_reset(struct ata_link *link,
					unsigned int devmask,
					unsigned long deadline)
{
	struct ata_port *ap = link->ap;
	struct ep93xx_pata_data *drv_data = ap->host->private_data;
	unsigned int dev0 = devmask & (1 << 0);
	unsigned int dev1 = devmask & (1 << 1);
	int rc, ret = 0;

	ata_msleep(ap, ATA_WAIT_AFTER_RESET);

	/* always check readiness of the master device */
	rc = ata_sff_wait_ready(link, deadline);
	/*
	 * -ENODEV means the odd clown forgot the D7 pulldown resistor
	 * and TF status is 0xff, bail out on it too.
	 */
	if (rc)
		return rc;

	/*
	 * if device 1 was found in ata_devchk, wait for register
	 * access briefly, then wait for BSY to clear.
	 */
	if (dev1) {
		int i;

		ap->ops->sff_dev_select(ap, 1);

		/*
		 * Wait for register access.  Some ATAPI devices fail
		 * to set nsect/lbal after reset, so don't waste too
		 * much time on it.  We're gonna wait for !BSY anyway.
		 */
		for (i = 0; i < 2; i++) {
			u8 nsect, lbal;

			nsect = ep93xx_pata_read_reg(drv_data,
				IDECTRL_ADDR_NSECT);
			lbal = ep93xx_pata_read_reg(drv_data,
				IDECTRL_ADDR_LBAL);
			if (nsect == 1 && lbal == 1)
				break;
			msleep(50);	/* give drive a breather */
		}

		rc = ata_sff_wait_ready(link, deadline);
		if (rc) {
			if (rc != -ENODEV)
				return rc;
			ret = rc;
		}
	}
	/* is all this really necessary? */
	ap->ops->sff_dev_select(ap, 0);
	if (dev1)
		ap->ops->sff_dev_select(ap, 1);
	if (dev0)
		ap->ops->sff_dev_select(ap, 0);

	return ret;
}

/* Note: original code is ata_bus_softreset */
static int ep93xx_pata_bus_softreset(struct ata_port *ap, unsigned int devmask,
				     unsigned long deadline)
{
	struct ep93xx_pata_data *drv_data = ap->host->private_data;

	ep93xx_pata_write_reg(drv_data, ap->ctl, IDECTRL_ADDR_CTL);
	udelay(20);		/* FIXME: flush */
	ep93xx_pata_write_reg(drv_data, ap->ctl | ATA_SRST, IDECTRL_ADDR_CTL);
	udelay(20);		/* FIXME: flush */
	ep93xx_pata_write_reg(drv_data, ap->ctl, IDECTRL_ADDR_CTL);
	ap->last_ctl = ap->ctl;

	return ep93xx_pata_wait_after_reset(&ap->link, devmask, deadline);
}

static void ep93xx_pata_release_dma(struct ep93xx_pata_data *drv_data)
{
	if (drv_data->dma_rx_channel) {
		dma_release_channel(drv_data->dma_rx_channel);
		drv_data->dma_rx_channel = NULL;
	}
	if (drv_data->dma_tx_channel) {
		dma_release_channel(drv_data->dma_tx_channel);
		drv_data->dma_tx_channel = NULL;
	}
}

static bool ep93xx_pata_dma_filter(struct dma_chan *chan, void *filter_param)
{
	if (ep93xx_dma_chan_is_m2p(chan))
		return false;

	chan->private = filter_param;
	return true;
}

static void ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data)
{
	const struct platform_device *pdev = drv_data->pdev;
	dma_cap_mask_t mask;
	struct dma_slave_config conf;

	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);

	/*
	 * Request two channels for IDE. Another possibility would be
	 * to request only one channel, and reprogram it's direction at
	 * start of new transfer.
	 */
	drv_data->dma_rx_data.port = EP93XX_DMA_IDE;
	drv_data->dma_rx_data.direction = DMA_FROM_DEVICE;
	drv_data->dma_rx_data.name = "ep93xx-pata-rx";
	drv_data->dma_rx_channel = dma_request_channel(mask,
		ep93xx_pata_dma_filter, &drv_data->dma_rx_data);
	if (!drv_data->dma_rx_channel)
		return;

	drv_data->dma_tx_data.port = EP93XX_DMA_IDE;
	drv_data->dma_tx_data.direction = DMA_TO_DEVICE;
	drv_data->dma_tx_data.name = "ep93xx-pata-tx";
	drv_data->dma_tx_channel = dma_request_channel(mask,
		ep93xx_pata_dma_filter, &drv_data->dma_tx_data);
	if (!drv_data->dma_tx_channel) {
		dma_release_channel(drv_data->dma_rx_channel);
		return;
	}

	/* Configure receive channel direction and source address */
	memset(&conf, 0, sizeof(conf));
	conf.direction = DMA_FROM_DEVICE;
	conf.src_addr = drv_data->udma_in_phys;
	conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	if (dmaengine_slave_config(drv_data->dma_rx_channel, &conf)) {
		dev_err(&pdev->dev, "failed to configure rx dma channel\n");
		ep93xx_pata_release_dma(drv_data);
		return;
	}

	/* Configure transmit channel direction and destination address */
	memset(&conf, 0, sizeof(conf));
	conf.direction = DMA_TO_DEVICE;
	conf.dst_addr = drv_data->udma_out_phys;
	conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	if (dmaengine_slave_config(drv_data->dma_tx_channel, &conf)) {
		dev_err(&pdev->dev, "failed to configure tx dma channel\n");
		ep93xx_pata_release_dma(drv_data);
	}
}

static void ep93xx_pata_dma_start(struct ata_queued_cmd *qc)
{
	struct dma_async_tx_descriptor *txd;
	struct ep93xx_pata_data *drv_data = qc->ap->host->private_data;
	void __iomem *base = drv_data->ide_base;
	struct ata_device *adev = qc->dev;
	u32 v = qc->dma_dir == DMA_TO_DEVICE ? IDEUDMAOP_RWOP : 0;
	struct dma_chan *channel = qc->dma_dir == DMA_TO_DEVICE
		? drv_data->dma_tx_channel : drv_data->dma_rx_channel;

	txd = dmaengine_prep_slave_sg(channel, qc->sg, qc->n_elem, qc->dma_dir,
		DMA_CTRL_ACK);
	if (!txd) {
		dev_err(qc->ap->dev, "failed to prepare slave for sg dma\n");
		return;
	}
	txd->callback = NULL;
	txd->callback_param = NULL;

	if (dmaengine_submit(txd) < 0) {
		dev_err(qc->ap->dev, "failed to submit dma transfer\n");
		return;
	}
	dma_async_issue_pending(channel);

	/*
	 * When enabling UDMA operation, IDEUDMAOP register needs to be
	 * programmed in three step sequence:
	 * 1) set or clear the RWOP bit,
	 * 2) perform dummy read of the register,
	 * 3) set the UEN bit.
	 */
	writel(v, base + IDEUDMAOP);
	readl(base + IDEUDMAOP);
	writel(v | IDEUDMAOP_UEN, base + IDEUDMAOP);

	writel(IDECFG_IDEEN | IDECFG_UDMA |
		((adev->xfer_mode - XFER_UDMA_0) << IDECFG_MODE_SHIFT),
		base + IDECFG);
}

static void ep93xx_pata_dma_stop(struct ata_queued_cmd *qc)
{
	struct ep93xx_pata_data *drv_data = qc->ap->host->private_data;
	void __iomem *base = drv_data->ide_base;

	/* terminate all dma transfers, if not yet finished */
	dmaengine_terminate_all(drv_data->dma_rx_channel);
	dmaengine_terminate_all(drv_data->dma_tx_channel);

	/*
	 * To properly stop IDE-DMA, IDEUDMAOP register must to be cleared
	 * and IDECTRL register must be set to default value.
	 */
	writel(0, base + IDEUDMAOP);
	writel(readl(base + IDECTRL) | IDECTRL_DIOWN | IDECTRL_DIORN |
		IDECTRL_CS0N | IDECTRL_CS1N, base + IDECTRL);

	ep93xx_pata_enable_pio(drv_data->ide_base,
		qc->dev->pio_mode - XFER_PIO_0);

	ata_sff_dma_pause(qc->ap);
}

static void ep93xx_pata_dma_setup(struct ata_queued_cmd *qc)
{
	qc->ap->ops->sff_exec_command(qc->ap, &qc->tf);
}

static u8 ep93xx_pata_dma_status(struct ata_port *ap)
{
	struct ep93xx_pata_data *drv_data = ap->host->private_data;
	u32 val = readl(drv_data->ide_base + IDEUDMASTS);

	/*
	 * UDMA Status Register bits:
	 *
	 * DMAIDE - DMA request signal from UDMA state machine,
	 * INTIDE - INT line generated by UDMA because of errors in the
	 *          state machine,
	 * SBUSY - UDMA state machine busy, not in idle state,
	 * NDO   - error for data-out not completed,
	 * NDI   - error for data-in not completed,
	 * N4X   - error for data transferred not multiplies of four
	 *         32-bit words.
	 * (EP93xx UG p27-17)
	 */
	if (val & IDEUDMASTS_NDO || val & IDEUDMASTS_NDI ||
	    val & IDEUDMASTS_N4X || val & IDEUDMASTS_INTIDE)
		return ATA_DMA_ERR;

	/* read INTRQ (INT[3]) pin input state */
	if (readl(drv_data->ide_base + IDECTRL) & IDECTRL_INTRQ)
		return ATA_DMA_INTR;

	if (val & IDEUDMASTS_SBUSY || val & IDEUDMASTS_DMAIDE)
		return ATA_DMA_ACTIVE;

	return 0;
}

/* Note: original code is ata_sff_softreset */
static int ep93xx_pata_softreset(struct ata_link *al, unsigned int *classes,
				 unsigned long deadline)
{
	struct ata_port *ap = al->ap;
	unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
	unsigned int devmask = 0;
	int rc;
	u8 err;

	/* determine if device 0/1 are present */
	if (ep93xx_pata_device_is_present(ap, 0))
		devmask |= (1 << 0);
	if (slave_possible && ep93xx_pata_device_is_present(ap, 1))
		devmask |= (1 << 1);

	/* select device 0 again */
	ap->ops->sff_dev_select(al->ap, 0);

	/* issue bus reset */
	rc = ep93xx_pata_bus_softreset(ap, devmask, deadline);
	/* if link is ocuppied, -ENODEV too is an error */
	if (rc && (rc != -ENODEV || sata_scr_valid(al))) {
		ata_link_err(al, "SRST failed (errno=%d)\n", rc);
		return rc;
	}

	/* determine by signature whether we have ATA or ATAPI devices */
	classes[0] = ata_sff_dev_classify(&al->device[0], devmask & (1 << 0),
					  &err);
	if (slave_possible && err != 0x81)
		classes[1] = ata_sff_dev_classify(&al->device[1],
						  devmask & (1 << 1), &err);

	return 0;
}

/* Note: original code is ata_sff_drain_fifo */
static void ep93xx_pata_drain_fifo(struct ata_queued_cmd *qc)
{
	int count;
	struct ata_port *ap;
	struct ep93xx_pata_data *drv_data;

	/* We only need to flush incoming data when a command was running */
	if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
		return;

	ap = qc->ap;
	drv_data = ap->host->private_data;
	/* Drain up to 64K of data before we give up this recovery method */
	for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
		     && count < 65536; count += 2)
		ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_DATA);

	/* Can become DEBUG later */
	if (count)
		ata_port_dbg(ap, "drained %d bytes to clear DRQ.\n", count);

}

static int ep93xx_pata_port_start(struct ata_port *ap)
{
	struct ep93xx_pata_data *drv_data = ap->host->private_data;

	/*
	 * Set timings to safe values at startup (= number of ns from ATA
	 * specification), we'll switch to properly calculated values later.
	 */
	drv_data->t = *ata_timing_find_mode(XFER_PIO_0);
	return 0;
}

static struct scsi_host_template ep93xx_pata_sht = {
	ATA_BASE_SHT(DRV_NAME),
	/* ep93xx dma implementation limit */
	.sg_tablesize		= 32,
	/* ep93xx dma can't transfer 65536 bytes at once */
	.dma_boundary		= 0x7fff,
};

static struct ata_port_operations ep93xx_pata_port_ops = {
	.inherits		= &ata_bmdma_port_ops,

	.qc_prep		= ata_noop_qc_prep,

	.softreset		= ep93xx_pata_softreset,
	.hardreset		= ATA_OP_NULL,

	.sff_dev_select		= ep93xx_pata_dev_select,
	.sff_set_devctl		= ep93xx_pata_set_devctl,
	.sff_check_status	= ep93xx_pata_check_status,
	.sff_check_altstatus	= ep93xx_pata_check_altstatus,
	.sff_tf_load		= ep93xx_pata_tf_load,
	.sff_tf_read		= ep93xx_pata_tf_read,
	.sff_exec_command	= ep93xx_pata_exec_command,
	.sff_data_xfer		= ep93xx_pata_data_xfer,
	.sff_drain_fifo		= ep93xx_pata_drain_fifo,
	.sff_irq_clear		= ATA_OP_NULL,

	.set_piomode		= ep93xx_pata_set_piomode,

	.bmdma_setup		= ep93xx_pata_dma_setup,
	.bmdma_start		= ep93xx_pata_dma_start,
	.bmdma_stop		= ep93xx_pata_dma_stop,
	.bmdma_status		= ep93xx_pata_dma_status,

	.cable_detect		= ata_cable_unknown,
	.port_start		= ep93xx_pata_port_start,
};

static int ep93xx_pata_probe(struct platform_device *pdev)
{
	struct ep93xx_pata_data *drv_data;
	struct ata_host *host;
	struct ata_port *ap;
	int irq;
	struct resource *mem_res;
	void __iomem *ide_base;
	int err;

	err = ep93xx_ide_acquire_gpio(pdev);
	if (err)
		return err;

	/* INT[3] (IRQ_EP93XX_EXT3) line connected as pull down */
	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		err = -ENXIO;
		goto err_rel_gpio;
	}

	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	ide_base = devm_ioremap_resource(&pdev->dev, mem_res);
	if (IS_ERR(ide_base)) {
		err = PTR_ERR(ide_base);
		goto err_rel_gpio;
	}

	drv_data = devm_kzalloc(&pdev->dev, sizeof(*drv_data), GFP_KERNEL);
	if (!drv_data) {
		err = -ENXIO;
		goto err_rel_gpio;
	}

	platform_set_drvdata(pdev, drv_data);
	drv_data->pdev = pdev;
	drv_data->ide_base = ide_base;
	drv_data->udma_in_phys = mem_res->start + IDEUDMADATAIN;
	drv_data->udma_out_phys = mem_res->start + IDEUDMADATAOUT;
	ep93xx_pata_dma_init(drv_data);

	/* allocate host */
	host = ata_host_alloc(&pdev->dev, 1);
	if (!host) {
		err = -ENXIO;
		goto err_rel_dma;
	}

	ep93xx_pata_clear_regs(ide_base);

	host->private_data = drv_data;

	ap = host->ports[0];
	ap->dev = &pdev->dev;
	ap->ops = &ep93xx_pata_port_ops;
	ap->flags |= ATA_FLAG_SLAVE_POSS;
	ap->pio_mask = ATA_PIO4;

	/*
	 * Maximum UDMA modes:
	 * EP931x rev.E0 - UDMA2
	 * EP931x rev.E1 - UDMA3
	 * EP931x rev.E2 - UDMA4
	 *
	 * MWDMA support was removed from EP931x rev.E2,
	 * so this driver supports only UDMA modes.
	 */
	if (drv_data->dma_rx_channel && drv_data->dma_tx_channel) {
		int chip_rev = ep93xx_chip_revision();

		if (chip_rev == EP93XX_CHIP_REV_E1)
			ap->udma_mask = ATA_UDMA3;
		else if (chip_rev == EP93XX_CHIP_REV_E2)
			ap->udma_mask = ATA_UDMA4;
		else
			ap->udma_mask = ATA_UDMA2;
	}

	/* defaults, pio 0 */
	ep93xx_pata_enable_pio(ide_base, 0);

	dev_info(&pdev->dev, "version " DRV_VERSION "\n");

	/* activate host */
	err = ata_host_activate(host, irq, ata_bmdma_interrupt, 0,
		&ep93xx_pata_sht);
	if (err == 0)
		return 0;

err_rel_dma:
	ep93xx_pata_release_dma(drv_data);
err_rel_gpio:
	ep93xx_ide_release_gpio(pdev);
	return err;
}

static int ep93xx_pata_remove(struct platform_device *pdev)
{
	struct ata_host *host = platform_get_drvdata(pdev);
	struct ep93xx_pata_data *drv_data = host->private_data;

	ata_host_detach(host);
	ep93xx_pata_release_dma(drv_data);
	ep93xx_pata_clear_regs(drv_data->ide_base);
	ep93xx_ide_release_gpio(pdev);
	return 0;
}

static struct platform_driver ep93xx_pata_platform_driver = {
	.driver = {
		.name = DRV_NAME,
	},
	.probe = ep93xx_pata_probe,
	.remove = ep93xx_pata_remove,
};

module_platform_driver(ep93xx_pata_platform_driver);

MODULE_AUTHOR("Alessandro Zummo, Lennert Buytenhek, Joao Ramos, "
		"Bartlomiej Zolnierkiewicz, Rafal Prylowski");
MODULE_DESCRIPTION("low-level driver for cirrus ep93xx IDE controller");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("platform:pata_ep93xx");
