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