/*
 * Driver for Blackfin on-chip ATAPI controller.
 *
 * Enter bugs at http://blackfin.uclinux.org/
 *
 * Copyright (c) 2008 Analog Devices Inc.
 *
 * Licensed under the GPL-2 or later.
 */

#include <common.h>
#include <command.h>
#include <config.h>
#include <asm/byteorder.h>
#include <asm/clock.h>
#include <asm/io.h>
#include <linux/errno.h>
#include <asm/portmux.h>
#include <asm/mach-common/bits/pata.h>
#include <ata.h>
#include <sata.h>
#include <libata.h>
#include "pata_bfin.h"

static struct ata_port port[CONFIG_SYS_SATA_MAX_DEVICE];

/**
 * PIO Mode - Frequency compatibility
 */
/* mode: 0         1         2         3         4 */
static const u32 pio_fsclk[] =
{ 33333333, 33333333, 33333333, 33333333, 33333333 };

/**
 * MDMA Mode - Frequency compatibility
 */
/*               mode:      0         1         2        */
static const u32 mdma_fsclk[] = { 33333333, 33333333, 33333333 };

/**
 * UDMA Mode - Frequency compatibility
 *
 * UDMA5 - 100 MB/s   - SCLK  = 133 MHz
 * UDMA4 - 66 MB/s    - SCLK >=  80 MHz
 * UDMA3 - 44.4 MB/s  - SCLK >=  50 MHz
 * UDMA2 - 33 MB/s    - SCLK >=  40 MHz
 */
/* mode: 0         1         2         3         4          5 */
static const u32 udma_fsclk[] =
{ 33333333, 33333333, 40000000, 50000000, 80000000, 133333333 };

/**
 * Register transfer timing table
 */
/*               mode:       0    1    2    3    4    */
/* Cycle Time                     */
static const u32 reg_t0min[]   = { 600, 383, 330, 180, 120 };
/* DIOR/DIOW to end cycle         */
static const u32 reg_t2min[]   = { 290, 290, 290, 70,  25  };
/* DIOR/DIOW asserted pulse width */
static const u32 reg_teocmin[] = { 290, 290, 290, 80,  70  };

/**
 * PIO timing table
 */
/*               mode:       0    1    2    3    4    */
/* Cycle Time                     */
static const u32 pio_t0min[]   = { 600, 383, 240, 180, 120 };
/* Address valid to DIOR/DIORW    */
static const u32 pio_t1min[]   = { 70,  50,  30,  30,  25  };
/* DIOR/DIOW to end cycle         */
static const u32 pio_t2min[]   = { 165, 125, 100, 80,  70  };
/* DIOR/DIOW asserted pulse width */
static const u32 pio_teocmin[] = { 165, 125, 100, 70,  25  };
/* DIOW data hold                 */
static const u32 pio_t4min[]   = { 30,  20,  15,  10,  10  };

/* ******************************************************************
 * Multiword DMA timing table
 * ******************************************************************
 */
/*               mode:       0   1    2        */
/* Cycle Time                     */
static const u32 mdma_t0min[]  = { 480, 150, 120 };
/* DIOR/DIOW asserted pulse width */
static const u32 mdma_tdmin[]  = { 215, 80,  70  };
/* DMACK to read data released    */
static const u32 mdma_thmin[]  = { 20,  15,  10  };
/* DIOR/DIOW to DMACK hold        */
static const u32 mdma_tjmin[]  = { 20,  5,   5   };
/* DIOR negated pulse width       */
static const u32 mdma_tkrmin[] = { 50,  50,  25  };
/* DIOR negated pulse width       */
static const u32 mdma_tkwmin[] = { 215, 50,  25  };
/* CS[1:0] valid to DIOR/DIOW     */
static const u32 mdma_tmmin[]  = { 50,  30,  25  };
/* DMACK to read data released    */
static const u32 mdma_tzmax[]  = { 20,  25,  25  };

/**
 * Ultra DMA timing table
 */
/*               mode:         0    1    2    3    4    5       */
static const u32 udma_tcycmin[]  = { 112, 73,  54,  39,  25,  17 };
static const u32 udma_tdvsmin[]  = { 70,  48,  31,  20,  7,   5  };
static const u32 udma_tenvmax[]  = { 70,  70,  70,  55,  55,  50 };
static const u32 udma_trpmin[]   = { 160, 125, 100, 100, 100, 85 };
static const u32 udma_tmin[]     = { 5,   5,   5,   5,   3,   3  };


static const u32 udma_tmlimin = 20;
static const u32 udma_tzahmin = 20;
static const u32 udma_tenvmin = 20;
static const u32 udma_tackmin = 20;
static const u32 udma_tssmin = 50;

static void msleep(int count)
{
	int i;

	for (i = 0; i < count; i++)
		udelay(1000);
}

/**
 *
 *	Function:       num_clocks_min
 *
 *	Description:
 *	calculate number of SCLK cycles to meet minimum timing
 */
static unsigned short num_clocks_min(unsigned long tmin,
				unsigned long fsclk)
{
	unsigned long tmp ;
	unsigned short result;

	tmp = tmin * (fsclk/1000/1000) / 1000;
	result = (unsigned short)tmp;
	if ((tmp*1000*1000) < (tmin*(fsclk/1000)))
		result++;

	return result;
}

/**
 *	bfin_set_piomode - Initialize host controller PATA PIO timings
 *	@ap: Port whose timings we are configuring
 *	@pio_mode: mode
 *
 *	Set PIO mode for device.
 *
 *	LOCKING:
 *	None (inherited from caller).
 */

static void bfin_set_piomode(struct ata_port *ap, int pio_mode)
{
	int mode = pio_mode - XFER_PIO_0;
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	unsigned int fsclk = get_sclk();
	unsigned short teoc_reg, t2_reg, teoc_pio;
	unsigned short t4_reg, t2_pio, t1_reg;
	unsigned short n0, n6, t6min = 5;

	/* the most restrictive timing value is t6 and tc, the DIOW - data hold
	* If one SCLK pulse is longer than this minimum value then register
	* transfers cannot be supported at this frequency.
	*/
	n6 = num_clocks_min(t6min, fsclk);
	if (mode >= 0 && mode <= 4 && n6 >= 1) {
		debug("set piomode: mode=%d, fsclk=%ud\n", mode, fsclk);
		/* calculate the timing values for register transfers. */
		while (mode > 0 && pio_fsclk[mode] > fsclk)
			mode--;

		/* DIOR/DIOW to end cycle time */
		t2_reg = num_clocks_min(reg_t2min[mode], fsclk);
		/* DIOR/DIOW asserted pulse width */
		teoc_reg = num_clocks_min(reg_teocmin[mode], fsclk);
		/* Cycle Time */
		n0  = num_clocks_min(reg_t0min[mode], fsclk);

		/* increase t2 until we meed the minimum cycle length */
		if (t2_reg + teoc_reg < n0)
			t2_reg = n0 - teoc_reg;

		/* calculate the timing values for pio transfers. */

		/* DIOR/DIOW to end cycle time */
		t2_pio = num_clocks_min(pio_t2min[mode], fsclk);
		/* DIOR/DIOW asserted pulse width */
		teoc_pio = num_clocks_min(pio_teocmin[mode], fsclk);
		/* Cycle Time */
		n0  = num_clocks_min(pio_t0min[mode], fsclk);

		/* increase t2 until we meed the minimum cycle length */
		if (t2_pio + teoc_pio < n0)
			t2_pio = n0 - teoc_pio;

		/* Address valid to DIOR/DIORW */
		t1_reg = num_clocks_min(pio_t1min[mode], fsclk);

		/* DIOW data hold */
		t4_reg = num_clocks_min(pio_t4min[mode], fsclk);

		ATAPI_SET_REG_TIM_0(base, (teoc_reg<<8 | t2_reg));
		ATAPI_SET_PIO_TIM_0(base, (t4_reg<<12 | t2_pio<<4 | t1_reg));
		ATAPI_SET_PIO_TIM_1(base, teoc_pio);
		if (mode > 2) {
			ATAPI_SET_CONTROL(base,
				ATAPI_GET_CONTROL(base) | IORDY_EN);
		} else {
			ATAPI_SET_CONTROL(base,
				ATAPI_GET_CONTROL(base) & ~IORDY_EN);
		}

		/* Disable host ATAPI PIO interrupts */
		ATAPI_SET_INT_MASK(base, ATAPI_GET_INT_MASK(base)
			& ~(PIO_DONE_MASK | HOST_TERM_XFER_MASK));
		SSYNC();
	}
}

/**
 *
 *    Function:       wait_complete
 *
 *    Description:    Waits the interrupt from device
 *
 */
static inline void wait_complete(void __iomem *base, unsigned short mask)
{
	unsigned short status;
	unsigned int i = 0;

	for (i = 0; i < PATA_BFIN_WAIT_TIMEOUT; i++) {
		status = ATAPI_GET_INT_STATUS(base) & mask;
		if (status)
			break;
	}

	ATAPI_SET_INT_STATUS(base, mask);
}

/**
 *
 *    Function:       write_atapi_register
 *
 *    Description:    Writes to ATA Device Resgister
 *
 */

static void write_atapi_register(void __iomem *base,
		unsigned long ata_reg, unsigned short value)
{
	/* Program the ATA_DEV_TXBUF register with write data (to be
	 * written into the device).
	 */
	ATAPI_SET_DEV_TXBUF(base, value);

	/* Program the ATA_DEV_ADDR register with address of the
	 * device register (0x01 to 0x0F).
	 */
	ATAPI_SET_DEV_ADDR(base, ata_reg);

	/* Program the ATA_CTRL register with dir set to write (1)
	 */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | XFER_DIR));

	/* ensure PIO DMA is not set */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA));

	/* and start the transfer */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START));

	/* Wait for the interrupt to indicate the end of the transfer.
	 * (We need to wait on and clear rhe ATA_DEV_INT interrupt status)
	 */
	wait_complete(base, PIO_DONE_INT);
}

/**
 *
 *	Function:       read_atapi_register
 *
 *Description:    Reads from ATA Device Resgister
 *
 */

static unsigned short read_atapi_register(void __iomem *base,
		unsigned long ata_reg)
{
	/* Program the ATA_DEV_ADDR register with address of the
	 * device register (0x01 to 0x0F).
	 */
	ATAPI_SET_DEV_ADDR(base, ata_reg);

	/* Program the ATA_CTRL register with dir set to read (0) and
	 */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~XFER_DIR));

	/* ensure PIO DMA is not set */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA));

	/* and start the transfer */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START));

	/* Wait for the interrupt to indicate the end of the transfer.
	 * (PIO_DONE interrupt is set and it doesn't seem to matter
	 * that we don't clear it)
	 */
	wait_complete(base, PIO_DONE_INT);

	/* Read the ATA_DEV_RXBUF register with write data (to be
	 * written into the device).
	 */
	return ATAPI_GET_DEV_RXBUF(base);
}

/**
 *
 *    Function:       write_atapi_register_data
 *
 *    Description:    Writes to ATA Device Resgister
 *
 */

static void write_atapi_data(void __iomem *base,
		int len, unsigned short *buf)
{
	int i;

	/* Set transfer length to 1 */
	ATAPI_SET_XFER_LEN(base, 1);

	/* Program the ATA_DEV_ADDR register with address of the
	 * ATA_REG_DATA
	 */
	ATAPI_SET_DEV_ADDR(base, ATA_REG_DATA);

	/* Program the ATA_CTRL register with dir set to write (1)
	 */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | XFER_DIR));

	/* ensure PIO DMA is not set */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA));

	for (i = 0; i < len; i++) {
		/* Program the ATA_DEV_TXBUF register with write data (to be
		 * written into the device).
		 */
		ATAPI_SET_DEV_TXBUF(base, buf[i]);

		/* and start the transfer */
		ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START));

		/* Wait for the interrupt to indicate the end of the transfer.
		 * (We need to wait on and clear rhe ATA_DEV_INT
		 * interrupt status)
		 */
		wait_complete(base, PIO_DONE_INT);
	}
}

/**
 *
 *	Function:       read_atapi_register_data
 *
 *	Description:    Reads from ATA Device Resgister
 *
 */

static void read_atapi_data(void __iomem *base,
		int len, unsigned short *buf)
{
	int i;

	/* Set transfer length to 1 */
	ATAPI_SET_XFER_LEN(base, 1);

	/* Program the ATA_DEV_ADDR register with address of the
	 * ATA_REG_DATA
	 */
	ATAPI_SET_DEV_ADDR(base, ATA_REG_DATA);

	/* Program the ATA_CTRL register with dir set to read (0) and
	 */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~XFER_DIR));

	/* ensure PIO DMA is not set */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA));

	for (i = 0; i < len; i++) {
		/* and start the transfer */
		ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START));

		/* Wait for the interrupt to indicate the end of the transfer.
		 * (PIO_DONE interrupt is set and it doesn't seem to matter
		 * that we don't clear it)
		 */
		wait_complete(base, PIO_DONE_INT);

		/* Read the ATA_DEV_RXBUF register with write data (to be
		 * written into the device).
		 */
		buf[i] = ATAPI_GET_DEV_RXBUF(base);
	}
}

/**
 *	bfin_check_status - Read device status reg & clear interrupt
 *	@ap: port where the device is
 *
 *	Note: Original code is ata_check_status().
 */

static u8 bfin_check_status(struct ata_port *ap)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	return read_atapi_register(base, ATA_REG_STATUS);
}

/**
 *	bfin_check_altstatus - Read device alternate status reg
 *	@ap: port where the device is
 */

static u8 bfin_check_altstatus(struct ata_port *ap)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	return read_atapi_register(base, ATA_REG_ALTSTATUS);
}

/**
 *      bfin_ata_busy_wait - Wait for a port status register
 *      @ap: Port to wait for.
 *      @bits: bits that must be clear
 *      @max: number of 10uS waits to perform
 *
 *      Waits up to max*10 microseconds for the selected bits in the port's
 *      status register to be cleared.
 *      Returns final value of status register.
 *
 *      LOCKING:
 *      Inherited from caller.
 */
static inline u8 bfin_ata_busy_wait(struct ata_port *ap, unsigned int bits,
				unsigned int max, u8 usealtstatus)
{
	u8 status;

	do {
		udelay(10);
		if (usealtstatus)
			status = bfin_check_altstatus(ap);
		else
			status = bfin_check_status(ap);
		max--;
	} while (status != 0xff && (status & bits) && (max > 0));

	return status;
}

/**
 *	bfin_ata_busy_sleep - sleep until BSY clears, or timeout
 *	@ap: port containing status register to be polled
 *	@tmout_pat: impatience timeout in msecs
 *	@tmout: overall timeout in msecs
 *
 *	Sleep until ATA Status register bit BSY clears,
 *	or a timeout occurs.
 *
 *	RETURNS:
 *	0 on success, -errno otherwise.
 */
static int bfin_ata_busy_sleep(struct ata_port *ap,
		       long tmout_pat, unsigned long tmout)
{
	u8 status;

	status = bfin_ata_busy_wait(ap, ATA_BUSY, 300, 0);
	while (status != 0xff && (status & ATA_BUSY) && tmout_pat > 0) {
		msleep(50);
		tmout_pat -= 50;
		status = bfin_ata_busy_wait(ap, ATA_BUSY, 3, 0);
	}

	if (status != 0xff && (status & ATA_BUSY))
		printf("port is slow to respond, please be patient "
				"(Status 0x%x)\n", status);

	while (status != 0xff && (status & ATA_BUSY) && tmout_pat > 0) {
		msleep(50);
		tmout_pat -= 50;
		status = bfin_check_status(ap);
	}

	if (status == 0xff)
		return -ENODEV;

	if (status & ATA_BUSY) {
		printf("port failed to respond "
				"(%lu secs, Status 0x%x)\n",
				DIV_ROUND_UP(tmout, 1000), status);
		return -EBUSY;
	}

	return 0;
}

/**
 *	bfin_dev_select - Select device 0/1 on ATA bus
 *	@ap: ATA channel to manipulate
 *	@device: ATA device (numbered from zero) to select
 *
 *	Note: Original code is ata_sff_dev_select().
 */

static void bfin_dev_select(struct ata_port *ap, unsigned int device)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	u8 tmp;


	if (device == 0)
		tmp = ATA_DEVICE_OBS;
	else
		tmp = ATA_DEVICE_OBS | ATA_DEV1;

	write_atapi_register(base, ATA_REG_DEVICE, tmp);
	udelay(1);
}

/**
 *	bfin_devchk - PATA device presence detection
 *	@ap: ATA channel to examine
 *	@device: Device to examine (starting at zero)
 *
 *	Note: Original code is ata_devchk().
 */

static unsigned int bfin_devchk(struct ata_port *ap,
				unsigned int device)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	u8 nsect, lbal;

	bfin_dev_select(ap, device);

	write_atapi_register(base, ATA_REG_NSECT, 0x55);
	write_atapi_register(base, ATA_REG_LBAL, 0xaa);

	write_atapi_register(base, ATA_REG_NSECT, 0xaa);
	write_atapi_register(base, ATA_REG_LBAL, 0x55);

	write_atapi_register(base, ATA_REG_NSECT, 0x55);
	write_atapi_register(base, ATA_REG_LBAL, 0xaa);

	nsect = read_atapi_register(base, ATA_REG_NSECT);
	lbal = read_atapi_register(base, ATA_REG_LBAL);

	if ((nsect == 0x55) && (lbal == 0xaa))
		return 1;	/* we found a device */

	return 0;		/* nothing found */
}

/**
 *	bfin_bus_post_reset - PATA device post reset
 *
 *	Note: Original code is ata_bus_post_reset().
 */

static void bfin_bus_post_reset(struct ata_port *ap, unsigned int devmask)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	unsigned int dev0 = devmask & (1 << 0);
	unsigned int dev1 = devmask & (1 << 1);
	long deadline;

	/* if device 0 was found in ata_devchk, wait for its
	 * BSY bit to clear
	 */
	if (dev0)
		bfin_ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);

	/* if device 1 was found in ata_devchk, wait for
	 * register access, then wait for BSY to clear
	 */
	deadline = ATA_TMOUT_BOOT;
	while (dev1) {
		u8 nsect, lbal;

		bfin_dev_select(ap, 1);
		nsect = read_atapi_register(base, ATA_REG_NSECT);
		lbal = read_atapi_register(base, ATA_REG_LBAL);
		if ((nsect == 1) && (lbal == 1))
			break;
		if (deadline <= 0) {
			dev1 = 0;
			break;
		}
		msleep(50);	/* give drive a breather */
		deadline -= 50;
	}
	if (dev1)
		bfin_ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);

	/* is all this really necessary? */
	bfin_dev_select(ap, 0);
	if (dev1)
		bfin_dev_select(ap, 1);
	if (dev0)
		bfin_dev_select(ap, 0);
}

/**
 *	bfin_bus_softreset - PATA device software reset
 *
 *	Note: Original code is ata_bus_softreset().
 */

static unsigned int bfin_bus_softreset(struct ata_port *ap,
				       unsigned int devmask)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;

	/* software reset.  causes dev0 to be selected */
	write_atapi_register(base, ATA_REG_CTRL, ap->ctl_reg);
	udelay(20);
	write_atapi_register(base, ATA_REG_CTRL, ap->ctl_reg | ATA_SRST);
	udelay(20);
	write_atapi_register(base, ATA_REG_CTRL, ap->ctl_reg);

	/* spec mandates ">= 2ms" before checking status.
	 * We wait 150ms, because that was the magic delay used for
	 * ATAPI devices in Hale Landis's ATADRVR, for the period of time
	 * between when the ATA command register is written, and then
	 * status is checked.  Because waiting for "a while" before
	 * checking status is fine, post SRST, we perform this magic
	 * delay here as well.
	 *
	 * Old drivers/ide uses the 2mS rule and then waits for ready
	 */
	msleep(150);

	/* Before we perform post reset processing we want to see if
	 * the bus shows 0xFF because the odd clown forgets the D7
	 * pulldown resistor.
	 */
	if (bfin_check_status(ap) == 0xFF)
		return 0;

	bfin_bus_post_reset(ap, devmask);

	return 0;
}

/**
 *	bfin_softreset - reset host port via ATA SRST
 *	@ap: port to reset
 *
 *	Note: Original code is ata_sff_softreset().
 */

static int bfin_softreset(struct ata_port *ap)
{
	unsigned int err_mask;

	ap->dev_mask = 0;

	/* determine if device 0/1 are present.
	 * only one device is supported on one port by now.
	*/
	if (bfin_devchk(ap, 0))
		ap->dev_mask |= (1 << 0);
	else if (bfin_devchk(ap, 1))
		ap->dev_mask |= (1 << 1);
	else
		return -ENODEV;

	/* select device 0 again */
	bfin_dev_select(ap, 0);

	/* issue bus reset */
	err_mask = bfin_bus_softreset(ap, ap->dev_mask);
	if (err_mask) {
		printf("SRST failed (err_mask=0x%x)\n",
				err_mask);
		ap->dev_mask = 0;
		return -EIO;
	}

	return 0;
}

/**
 *	bfin_irq_clear - Clear ATAPI interrupt.
 *	@ap: Port associated with this ATA transaction.
 *
 *	Note: Original code is ata_sff_irq_clear().
 */

static void bfin_irq_clear(struct ata_port *ap)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;

	ATAPI_SET_INT_STATUS(base, ATAPI_GET_INT_STATUS(base)|ATAPI_DEV_INT
		| MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT
		| MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT);
}

static u8 bfin_wait_for_irq(struct ata_port *ap, unsigned int max)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;

	do {
		if (ATAPI_GET_INT_STATUS(base) & (ATAPI_DEV_INT
		| MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT
		| MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT)) {
			break;
		}
		udelay(1000);
		max--;
	} while ((max > 0));

	return max == 0;
}

/**
 *	bfin_ata_reset_port - initialize BFIN ATAPI port.
 */

static int bfin_ata_reset_port(struct ata_port *ap)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	int count;
	unsigned short status;

	/* Disable all ATAPI interrupts */
	ATAPI_SET_INT_MASK(base, 0);
	SSYNC();

	/* Assert the RESET signal 25us*/
	ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | DEV_RST);
	udelay(30);

	/* Negate the RESET signal for 2ms*/
	ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) & ~DEV_RST);
	msleep(2);

	/* Wait on Busy flag to clear */
	count = 10000000;
	do {
		status = read_atapi_register(base, ATA_REG_STATUS);
	} while (--count && (status & ATA_BUSY));

	/* Enable only ATAPI Device interrupt */
	ATAPI_SET_INT_MASK(base, 1);
	SSYNC();

	return !count;
}

/**
 *
 *	Function:       bfin_config_atapi_gpio
 *
 *	Description:    Configures the ATAPI pins for use
 *
 */
static int bfin_config_atapi_gpio(struct ata_port *ap)
{
	const unsigned short pins[] = {
		P_ATAPI_RESET, P_ATAPI_DIOR, P_ATAPI_DIOW, P_ATAPI_CS0,
		P_ATAPI_CS1, P_ATAPI_DMACK, P_ATAPI_DMARQ, P_ATAPI_INTRQ,
		P_ATAPI_IORDY, P_ATAPI_D0A, P_ATAPI_D1A, P_ATAPI_D2A,
		P_ATAPI_D3A, P_ATAPI_D4A, P_ATAPI_D5A, P_ATAPI_D6A,
		P_ATAPI_D7A, P_ATAPI_D8A, P_ATAPI_D9A, P_ATAPI_D10A,
		P_ATAPI_D11A, P_ATAPI_D12A, P_ATAPI_D13A, P_ATAPI_D14A,
		P_ATAPI_D15A, P_ATAPI_A0A, P_ATAPI_A1A, P_ATAPI_A2A, 0,
	};

	peripheral_request_list(pins, "pata_bfin");

	return 0;
}

/**
 *	bfin_atapi_probe	-	attach a bfin atapi interface
 *	@pdev: platform device
 *
 *	Register a bfin atapi interface.
 *
 *
 *	Platform devices are expected to contain 2 resources per port:
 *
 *		- I/O Base (IORESOURCE_IO)
 *		- IRQ	   (IORESOURCE_IRQ)
 *
 */
static int bfin_ata_probe_port(struct ata_port *ap)
{
	if (bfin_config_atapi_gpio(ap)) {
		printf("Requesting Peripherals faild\n");
		return -EFAULT;
	}

	if (bfin_ata_reset_port(ap)) {
		printf("Fail to reset ATAPI device\n");
		return -EFAULT;
	}

	if (ap->ata_mode >= XFER_PIO_0 && ap->ata_mode <= XFER_PIO_4)
		bfin_set_piomode(ap, ap->ata_mode);
	else {
		printf("Given ATA data transfer mode is not supported.\n");
		return -EFAULT;
	}

	return 0;
}

#define ATA_SECTOR_WORDS (ATA_SECT_SIZE/2)

static void bfin_ata_identify(struct ata_port *ap, int dev)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	u8 status = 0;
	static u16 iobuf[ATA_SECTOR_WORDS];
	u64 n_sectors = 0;
	hd_driveid_t *iop = (hd_driveid_t *)iobuf;

	memset(iobuf, 0, sizeof(iobuf));

	if (!(ap->dev_mask & (1 << dev)))
		return;

	debug("port=%d dev=%d\n", ap->port_no, dev);

	bfin_dev_select(ap, dev);

	status = 0;
	/* Device Identify Command */
	write_atapi_register(base, ATA_REG_CMD, ATA_CMD_ID_ATA);
	bfin_check_altstatus(ap);
	udelay(10);

	status = bfin_ata_busy_wait(ap, ATA_BUSY, 1000, 0);
	if (status & ATA_ERR) {
		printf("\ndevice not responding\n");
		ap->dev_mask &= ~(1 << dev);
		return;
	}

	read_atapi_data(base, ATA_SECTOR_WORDS, iobuf);

	ata_swap_buf_le16(iobuf, ATA_SECTOR_WORDS);

	/* we require LBA and DMA support (bits 8 & 9 of word 49) */
	if (!ata_id_has_dma(iobuf) || !ata_id_has_lba(iobuf))
		printf("ata%u: no dma/lba\n", ap->port_no);

#ifdef DEBUG
	ata_dump_id(iobuf);
#endif

	n_sectors = ata_id_n_sectors(iobuf);

	if (n_sectors == 0) {
		ap->dev_mask &= ~(1 << dev);
		return;
	}

	ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].revision,
			 ATA_ID_FW_REV, sizeof(sata_dev_desc[ap->port_no].revision));
	ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].vendor,
			 ATA_ID_PROD, sizeof(sata_dev_desc[ap->port_no].vendor));
	ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].product,
			 ATA_ID_SERNO, sizeof(sata_dev_desc[ap->port_no].product));

	if ((iop->config & 0x0080) == 0x0080)
		sata_dev_desc[ap->port_no].removable = 1;
	else
		sata_dev_desc[ap->port_no].removable = 0;

	sata_dev_desc[ap->port_no].lba = (u32) n_sectors;
	debug("lba=0x%lx\n", sata_dev_desc[ap->port_no].lba);

#ifdef CONFIG_LBA48
	if (iop->command_set_2 & 0x0400)
		sata_dev_desc[ap->port_no].lba48 = 1;
	else
		sata_dev_desc[ap->port_no].lba48 = 0;
#endif

	/* assuming HD */
	sata_dev_desc[ap->port_no].type = DEV_TYPE_HARDDISK;
	sata_dev_desc[ap->port_no].blksz = ATA_SECT_SIZE;
	sata_dev_desc[ap->port_no].log2blksz =
		LOG2(sata_dev_desc[ap->port_no].blksz);
	sata_dev_desc[ap->port_no].lun = 0;	/* just to fill something in... */

	printf("PATA device#%d %s is found on ata port#%d.\n",
		ap->port_no%PATA_DEV_NUM_PER_PORT,
		sata_dev_desc[ap->port_no].vendor,
		ap->port_no/PATA_DEV_NUM_PER_PORT);
}

static void bfin_ata_set_Feature_cmd(struct ata_port *ap, int dev)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	u8 status = 0;

	if (!(ap->dev_mask & (1 << dev)))
		return;

	bfin_dev_select(ap, dev);

	write_atapi_register(base, ATA_REG_FEATURE, SETFEATURES_XFER);
	write_atapi_register(base, ATA_REG_NSECT, ap->ata_mode);
	write_atapi_register(base, ATA_REG_LBAL, 0);
	write_atapi_register(base, ATA_REG_LBAM, 0);
	write_atapi_register(base, ATA_REG_LBAH, 0);

	write_atapi_register(base, ATA_REG_DEVICE, ATA_DEVICE_OBS);
	write_atapi_register(base, ATA_REG_CMD, ATA_CMD_SET_FEATURES);

	udelay(50);
	msleep(150);

	status = bfin_ata_busy_wait(ap, ATA_BUSY, 5000, 0);
	if ((status & (ATA_BUSY | ATA_ERR))) {
		printf("Error  : status 0x%02x\n", status);
		ap->dev_mask &= ~(1 << dev);
	}
}

int scan_sata(int dev)
{
	/* dev is the index of each ata device in the system. one PATA port
	 * contains 2 devices. one element in scan_done array indicates one
	 * PATA port. device connected to one PATA port is selected by
	 * bfin_dev_select() before access.
	 */
	struct ata_port *ap = &port[dev];
	static int scan_done[(CONFIG_SYS_SATA_MAX_DEVICE+1)/PATA_DEV_NUM_PER_PORT];

	if (scan_done[dev/PATA_DEV_NUM_PER_PORT])
		return 0;

	/* Check for attached device */
	if (!bfin_ata_probe_port(ap)) {
		if (bfin_softreset(ap)) {
			/* soft reset failed, try a hard one */
			bfin_ata_reset_port(ap);
			if (bfin_softreset(ap))
				scan_done[dev/PATA_DEV_NUM_PER_PORT] = 1;
		} else {
			scan_done[dev/PATA_DEV_NUM_PER_PORT] = 1;
		}
	}
	if (scan_done[dev/PATA_DEV_NUM_PER_PORT]) {
		/* Probe device and set xfer mode */
		bfin_ata_identify(ap, dev%PATA_DEV_NUM_PER_PORT);
		bfin_ata_set_Feature_cmd(ap, dev%PATA_DEV_NUM_PER_PORT);
		part_init(&sata_dev_desc[dev]);
		return 0;
	}

	printf("PATA device#%d is not present on ATA port#%d.\n",
		ap->port_no%PATA_DEV_NUM_PER_PORT,
		ap->port_no/PATA_DEV_NUM_PER_PORT);

	return -1;
}

int init_sata(int dev)
{
	struct ata_port *ap = &port[dev];
	static u8 init_done;
	int res = 1;

	if (init_done)
		return res;

	init_done = 1;

	switch (dev/PATA_DEV_NUM_PER_PORT) {
	case 0:
		ap->ioaddr.ctl_addr = ATAPI_CONTROL;
		ap->ata_mode = CONFIG_BFIN_ATA_MODE;
		break;
	default:
		printf("Tried to scan unknown port %d.\n", dev);
		return res;
	}

	if (ap->ata_mode < XFER_PIO_0 || ap->ata_mode > XFER_PIO_4) {
		ap->ata_mode = XFER_PIO_4;
		printf("DMA mode is not supported. Set to PIO mode 4.\n");
	}

	ap->port_no = dev;
	ap->ctl_reg = 0x8;	/*Default value of control reg */

	res = 0;
	return res;
}

int reset_sata(int dev)
{
	return 0;
}

/* Read up to 255 sectors
 *
 * Returns sectors read
*/
static u8 do_one_read(struct ata_port *ap, u64 blknr, u8 blkcnt, u16 *buffer,
			uchar lba48)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	u8 sr = 0;
	u8 status;
	u16 err = 0;

	if (!(bfin_check_status(ap) & ATA_DRDY)) {
		printf("Device ata%d not ready\n", ap->port_no);
		return 0;
	}

	/* Set up transfer */
#ifdef CONFIG_LBA48
	if (lba48) {
		/* write high bits */
		write_atapi_register(base, ATA_REG_NSECT, 0);
		write_atapi_register(base, ATA_REG_LBAL, (blknr >> 24) & 0xFF);
		write_atapi_register(base, ATA_REG_LBAM, (blknr >> 32) & 0xFF);
		write_atapi_register(base, ATA_REG_LBAH, (blknr >> 40) & 0xFF);
	}
#endif
	write_atapi_register(base, ATA_REG_NSECT, blkcnt);
	write_atapi_register(base, ATA_REG_LBAL, (blknr >> 0) & 0xFF);
	write_atapi_register(base, ATA_REG_LBAM, (blknr >> 8) & 0xFF);
	write_atapi_register(base, ATA_REG_LBAH, (blknr >> 16) & 0xFF);

#ifdef CONFIG_LBA48
	if (lba48) {
		write_atapi_register(base, ATA_REG_DEVICE, ATA_LBA);
		write_atapi_register(base, ATA_REG_CMD, ATA_CMD_PIO_READ_EXT);
	} else
#endif
	{
		write_atapi_register(base, ATA_REG_DEVICE, ATA_LBA | ((blknr >> 24) & 0xF));
		write_atapi_register(base, ATA_REG_CMD, ATA_CMD_PIO_READ);
	}
	status = bfin_ata_busy_wait(ap, ATA_BUSY, 500000, 1);

	if (status & (ATA_BUSY | ATA_ERR)) {
		printf("Device %d not responding status 0x%x.\n", ap->port_no, status);
		err = read_atapi_register(base, ATA_REG_ERR);
		printf("Error reg = 0x%x\n", err);
		return sr;
	}

	while (blkcnt--) {
		if (bfin_wait_for_irq(ap, 500)) {
			printf("ata%u irq failed\n", ap->port_no);
			return sr;
		}

		status = bfin_check_status(ap);
		if (status & ATA_ERR) {
			err = read_atapi_register(base, ATA_REG_ERR);
			printf("ata%u error %d\n", ap->port_no, err);
			return sr;
		}
		bfin_irq_clear(ap);

		/* Read one sector */
		read_atapi_data(base, ATA_SECTOR_WORDS, buffer);
		buffer += ATA_SECTOR_WORDS;
		sr++;
	}

	return sr;
}

ulong sata_read(int dev, ulong block, lbaint_t blkcnt, void *buff)
{
	struct ata_port *ap = &port[dev];
	ulong n = 0, sread;
	u16 *buffer = (u16 *) buff;
	u8 status = 0;
	u64 blknr = (u64) block;
	unsigned char lba48 = 0;

#ifdef CONFIG_LBA48
	if (blknr > 0xfffffff) {
		if (!sata_dev_desc[dev].lba48) {
			printf("Drive doesn't support 48-bit addressing\n");
			return 0;
		}
		/* more than 28 bits used, use 48bit mode */
		lba48 = 1;
	}
#endif
	bfin_dev_select(ap, dev%PATA_DEV_NUM_PER_PORT);

	while (blkcnt > 0) {

		if (blkcnt > 255)
			sread = 255;
		else
			sread = blkcnt;

		status = do_one_read(ap, blknr, sread, buffer, lba48);
		if (status != sread) {
			printf("Read failed\n");
			return n;
		}

		blkcnt -= sread;
		blknr += sread;
		n += sread;
		buffer += sread * ATA_SECTOR_WORDS;
	}
	return n;
}

ulong sata_write(int dev, ulong block, lbaint_t blkcnt, const void *buff)
{
	struct ata_port *ap = &port[dev];
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	ulong n = 0;
	u16 *buffer = (u16 *) buff;
	unsigned char status = 0;
	u64 blknr = (u64) block;
#ifdef CONFIG_LBA48
	unsigned char lba48 = 0;

	if (blknr > 0xfffffff) {
		if (!sata_dev_desc[dev].lba48) {
			printf("Drive doesn't support 48-bit addressing\n");
			return 0;
		}
		/* more than 28 bits used, use 48bit mode */
		lba48 = 1;
	}
#endif

	bfin_dev_select(ap, dev%PATA_DEV_NUM_PER_PORT);

	while (blkcnt-- > 0) {
		status = bfin_ata_busy_wait(ap, ATA_BUSY, 50000, 0);
		if (status & ATA_BUSY) {
			printf("ata%u failed to respond\n", ap->port_no);
			return n;
		}
#ifdef CONFIG_LBA48
		if (lba48) {
			/* write high bits */
			write_atapi_register(base, ATA_REG_NSECT, 0);
			write_atapi_register(base, ATA_REG_LBAL,
				(blknr >> 24) & 0xFF);
			write_atapi_register(base, ATA_REG_LBAM,
				(blknr >> 32) & 0xFF);
			write_atapi_register(base, ATA_REG_LBAH,
				(blknr >> 40) & 0xFF);
		}
#endif
		write_atapi_register(base, ATA_REG_NSECT, 1);
		write_atapi_register(base, ATA_REG_LBAL, (blknr >> 0) & 0xFF);
		write_atapi_register(base, ATA_REG_LBAM, (blknr >> 8) & 0xFF);
		write_atapi_register(base, ATA_REG_LBAH, (blknr >> 16) & 0xFF);
#ifdef CONFIG_LBA48
		if (lba48) {
			write_atapi_register(base, ATA_REG_DEVICE, ATA_LBA);
			write_atapi_register(base, ATA_REG_CMD,
				ATA_CMD_PIO_WRITE_EXT);
		} else
#endif
		{
			write_atapi_register(base, ATA_REG_DEVICE,
				ATA_LBA | ((blknr >> 24) & 0xF));
			write_atapi_register(base, ATA_REG_CMD,
				ATA_CMD_PIO_WRITE);
		}

		/*may take up to 5 sec */
		status = bfin_ata_busy_wait(ap, ATA_BUSY, 50000, 0);
		if ((status & (ATA_DRQ | ATA_BUSY | ATA_ERR)) != ATA_DRQ) {
			printf("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
				ap->port_no, (ulong) blknr, status);
			return n;
		}

		write_atapi_data(base, ATA_SECTOR_WORDS, buffer);
		bfin_check_altstatus(ap);
		udelay(1);

		++n;
		++blknr;
		buffer += ATA_SECTOR_WORDS;
	}
	return n;
}
