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