/*
 * 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/io.h>
#include <asm/errno.h>
#include <asm/portmux.h>
#include <asm/mach-common/bits/pata.h>
#include <ata.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%x\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].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);
		init_part(&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;
}

/* 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, ulong 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, ulong 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;
}
