/* * 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 #include #include #include #include #include #include #include #include #include #include #include #include "pata_bfin.h" static struct ata_port port[CONFIG_SYS_SATA_MAX_DEVICE]; /** * PIO Mode - Frequency compatibility */ /* mode: 0 1 2 3 4 */ static const u32 pio_fsclk[] = { 33333333, 33333333, 33333333, 33333333, 33333333 }; /** * MDMA Mode - Frequency compatibility */ /* mode: 0 1 2 */ static const u32 mdma_fsclk[] = { 33333333, 33333333, 33333333 }; /** * UDMA Mode - Frequency compatibility * * UDMA5 - 100 MB/s - SCLK = 133 MHz * UDMA4 - 66 MB/s - SCLK >= 80 MHz * UDMA3 - 44.4 MB/s - SCLK >= 50 MHz * UDMA2 - 33 MB/s - SCLK >= 40 MHz */ /* mode: 0 1 2 3 4 5 */ static const u32 udma_fsclk[] = { 33333333, 33333333, 40000000, 50000000, 80000000, 133333333 }; /** * Register transfer timing table */ /* mode: 0 1 2 3 4 */ /* Cycle Time */ static const u32 reg_t0min[] = { 600, 383, 330, 180, 120 }; /* DIOR/DIOW to end cycle */ static const u32 reg_t2min[] = { 290, 290, 290, 70, 25 }; /* DIOR/DIOW asserted pulse width */ static const u32 reg_teocmin[] = { 290, 290, 290, 80, 70 }; /** * PIO timing table */ /* mode: 0 1 2 3 4 */ /* Cycle Time */ static const u32 pio_t0min[] = { 600, 383, 240, 180, 120 }; /* Address valid to DIOR/DIORW */ static const u32 pio_t1min[] = { 70, 50, 30, 30, 25 }; /* DIOR/DIOW to end cycle */ static const u32 pio_t2min[] = { 165, 125, 100, 80, 70 }; /* DIOR/DIOW asserted pulse width */ static const u32 pio_teocmin[] = { 165, 125, 100, 70, 25 }; /* DIOW data hold */ static const u32 pio_t4min[] = { 30, 20, 15, 10, 10 }; /* ****************************************************************** * Multiword DMA timing table * ****************************************************************** */ /* mode: 0 1 2 */ /* Cycle Time */ static const u32 mdma_t0min[] = { 480, 150, 120 }; /* DIOR/DIOW asserted pulse width */ static const u32 mdma_tdmin[] = { 215, 80, 70 }; /* DMACK to read data released */ static const u32 mdma_thmin[] = { 20, 15, 10 }; /* DIOR/DIOW to DMACK hold */ static const u32 mdma_tjmin[] = { 20, 5, 5 }; /* DIOR negated pulse width */ static const u32 mdma_tkrmin[] = { 50, 50, 25 }; /* DIOR negated pulse width */ static const u32 mdma_tkwmin[] = { 215, 50, 25 }; /* CS[1:0] valid to DIOR/DIOW */ static const u32 mdma_tmmin[] = { 50, 30, 25 }; /* DMACK to read data released */ static const u32 mdma_tzmax[] = { 20, 25, 25 }; /** * Ultra DMA timing table */ /* mode: 0 1 2 3 4 5 */ static const u32 udma_tcycmin[] = { 112, 73, 54, 39, 25, 17 }; static const u32 udma_tdvsmin[] = { 70, 48, 31, 20, 7, 5 }; static const u32 udma_tenvmax[] = { 70, 70, 70, 55, 55, 50 }; static const u32 udma_trpmin[] = { 160, 125, 100, 100, 100, 85 }; static const u32 udma_tmin[] = { 5, 5, 5, 5, 3, 3 }; static const u32 udma_tmlimin = 20; static const u32 udma_tzahmin = 20; static const u32 udma_tenvmin = 20; static const u32 udma_tackmin = 20; static const u32 udma_tssmin = 50; static void msleep(int count) { int i; for (i = 0; i < count; i++) udelay(1000); } /** * * Function: num_clocks_min * * Description: * calculate number of SCLK cycles to meet minimum timing */ static unsigned short num_clocks_min(unsigned long tmin, unsigned long fsclk) { unsigned long tmp ; unsigned short result; tmp = tmin * (fsclk/1000/1000) / 1000; result = (unsigned short)tmp; if ((tmp*1000*1000) < (tmin*(fsclk/1000))) result++; return result; } /** * bfin_set_piomode - Initialize host controller PATA PIO timings * @ap: Port whose timings we are configuring * @pio_mode: mode * * Set PIO mode for device. * * LOCKING: * None (inherited from caller). */ static void bfin_set_piomode(struct ata_port *ap, int pio_mode) { int mode = pio_mode - XFER_PIO_0; void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; unsigned int fsclk = get_sclk(); unsigned short teoc_reg, t2_reg, teoc_pio; unsigned short t4_reg, t2_pio, t1_reg; unsigned short n0, n6, t6min = 5; /* the most restrictive timing value is t6 and tc, the DIOW - data hold * If one SCLK pulse is longer than this minimum value then register * transfers cannot be supported at this frequency. */ n6 = num_clocks_min(t6min, fsclk); if (mode >= 0 && mode <= 4 && n6 >= 1) { debug("set piomode: mode=%d, fsclk=%ud\n", mode, fsclk); /* calculate the timing values for register transfers. */ while (mode > 0 && pio_fsclk[mode] > fsclk) mode--; /* DIOR/DIOW to end cycle time */ t2_reg = num_clocks_min(reg_t2min[mode], fsclk); /* DIOR/DIOW asserted pulse width */ teoc_reg = num_clocks_min(reg_teocmin[mode], fsclk); /* Cycle Time */ n0 = num_clocks_min(reg_t0min[mode], fsclk); /* increase t2 until we meed the minimum cycle length */ if (t2_reg + teoc_reg < n0) t2_reg = n0 - teoc_reg; /* calculate the timing values for pio transfers. */ /* DIOR/DIOW to end cycle time */ t2_pio = num_clocks_min(pio_t2min[mode], fsclk); /* DIOR/DIOW asserted pulse width */ teoc_pio = num_clocks_min(pio_teocmin[mode], fsclk); /* Cycle Time */ n0 = num_clocks_min(pio_t0min[mode], fsclk); /* increase t2 until we meed the minimum cycle length */ if (t2_pio + teoc_pio < n0) t2_pio = n0 - teoc_pio; /* Address valid to DIOR/DIORW */ t1_reg = num_clocks_min(pio_t1min[mode], fsclk); /* DIOW data hold */ t4_reg = num_clocks_min(pio_t4min[mode], fsclk); ATAPI_SET_REG_TIM_0(base, (teoc_reg<<8 | t2_reg)); ATAPI_SET_PIO_TIM_0(base, (t4_reg<<12 | t2_pio<<4 | t1_reg)); ATAPI_SET_PIO_TIM_1(base, teoc_pio); if (mode > 2) { ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | IORDY_EN); } else { ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) & ~IORDY_EN); } /* Disable host ATAPI PIO interrupts */ ATAPI_SET_INT_MASK(base, ATAPI_GET_INT_MASK(base) & ~(PIO_DONE_MASK | HOST_TERM_XFER_MASK)); SSYNC(); } } /** * * Function: wait_complete * * Description: Waits the interrupt from device * */ static inline void wait_complete(void __iomem *base, unsigned short mask) { unsigned short status; unsigned int i = 0; for (i = 0; i < PATA_BFIN_WAIT_TIMEOUT; i++) { status = ATAPI_GET_INT_STATUS(base) & mask; if (status) break; } ATAPI_SET_INT_STATUS(base, mask); } /** * * Function: write_atapi_register * * Description: Writes to ATA Device Resgister * */ static void write_atapi_register(void __iomem *base, unsigned long ata_reg, unsigned short value) { /* Program the ATA_DEV_TXBUF register with write data (to be * written into the device). */ ATAPI_SET_DEV_TXBUF(base, value); /* Program the ATA_DEV_ADDR register with address of the * device register (0x01 to 0x0F). */ ATAPI_SET_DEV_ADDR(base, ata_reg); /* Program the ATA_CTRL register with dir set to write (1) */ ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | XFER_DIR)); /* ensure PIO DMA is not set */ ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA)); /* and start the transfer */ ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START)); /* Wait for the interrupt to indicate the end of the transfer. * (We need to wait on and clear rhe ATA_DEV_INT interrupt status) */ wait_complete(base, PIO_DONE_INT); } /** * * Function: read_atapi_register * *Description: Reads from ATA Device Resgister * */ static unsigned short read_atapi_register(void __iomem *base, unsigned long ata_reg) { /* Program the ATA_DEV_ADDR register with address of the * device register (0x01 to 0x0F). */ ATAPI_SET_DEV_ADDR(base, ata_reg); /* Program the ATA_CTRL register with dir set to read (0) and */ ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~XFER_DIR)); /* ensure PIO DMA is not set */ ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA)); /* and start the transfer */ ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START)); /* Wait for the interrupt to indicate the end of the transfer. * (PIO_DONE interrupt is set and it doesn't seem to matter * that we don't clear it) */ wait_complete(base, PIO_DONE_INT); /* Read the ATA_DEV_RXBUF register with write data (to be * written into the device). */ return ATAPI_GET_DEV_RXBUF(base); } /** * * Function: write_atapi_register_data * * Description: Writes to ATA Device Resgister * */ static void write_atapi_data(void __iomem *base, int len, unsigned short *buf) { int i; /* Set transfer length to 1 */ ATAPI_SET_XFER_LEN(base, 1); /* Program the ATA_DEV_ADDR register with address of the * ATA_REG_DATA */ ATAPI_SET_DEV_ADDR(base, ATA_REG_DATA); /* Program the ATA_CTRL register with dir set to write (1) */ ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | XFER_DIR)); /* ensure PIO DMA is not set */ ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA)); for (i = 0; i < len; i++) { /* Program the ATA_DEV_TXBUF register with write data (to be * written into the device). */ ATAPI_SET_DEV_TXBUF(base, buf[i]); /* and start the transfer */ ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START)); /* Wait for the interrupt to indicate the end of the transfer. * (We need to wait on and clear rhe ATA_DEV_INT * interrupt status) */ wait_complete(base, PIO_DONE_INT); } } /** * * Function: read_atapi_register_data * * Description: Reads from ATA Device Resgister * */ static void read_atapi_data(void __iomem *base, int len, unsigned short *buf) { int i; /* Set transfer length to 1 */ ATAPI_SET_XFER_LEN(base, 1); /* Program the ATA_DEV_ADDR register with address of the * ATA_REG_DATA */ ATAPI_SET_DEV_ADDR(base, ATA_REG_DATA); /* Program the ATA_CTRL register with dir set to read (0) and */ ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~XFER_DIR)); /* ensure PIO DMA is not set */ ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA)); for (i = 0; i < len; i++) { /* and start the transfer */ ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START)); /* Wait for the interrupt to indicate the end of the transfer. * (PIO_DONE interrupt is set and it doesn't seem to matter * that we don't clear it) */ wait_complete(base, PIO_DONE_INT); /* Read the ATA_DEV_RXBUF register with write data (to be * written into the device). */ buf[i] = ATAPI_GET_DEV_RXBUF(base); } } /** * bfin_check_status - Read device status reg & clear interrupt * @ap: port where the device is * * Note: Original code is ata_check_status(). */ static u8 bfin_check_status(struct ata_port *ap) { void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; return read_atapi_register(base, ATA_REG_STATUS); } /** * bfin_check_altstatus - Read device alternate status reg * @ap: port where the device is */ static u8 bfin_check_altstatus(struct ata_port *ap) { void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; return read_atapi_register(base, ATA_REG_ALTSTATUS); } /** * bfin_ata_busy_wait - Wait for a port status register * @ap: Port to wait for. * @bits: bits that must be clear * @max: number of 10uS waits to perform * * Waits up to max*10 microseconds for the selected bits in the port's * status register to be cleared. * Returns final value of status register. * * LOCKING: * Inherited from caller. */ static inline u8 bfin_ata_busy_wait(struct ata_port *ap, unsigned int bits, unsigned int max, u8 usealtstatus) { u8 status; do { udelay(10); if (usealtstatus) status = bfin_check_altstatus(ap); else status = bfin_check_status(ap); max--; } while (status != 0xff && (status & bits) && (max > 0)); return status; } /** * bfin_ata_busy_sleep - sleep until BSY clears, or timeout * @ap: port containing status register to be polled * @tmout_pat: impatience timeout in msecs * @tmout: overall timeout in msecs * * Sleep until ATA Status register bit BSY clears, * or a timeout occurs. * * RETURNS: * 0 on success, -errno otherwise. */ static int bfin_ata_busy_sleep(struct ata_port *ap, long tmout_pat, unsigned long tmout) { u8 status; status = bfin_ata_busy_wait(ap, ATA_BUSY, 300, 0); while (status != 0xff && (status & ATA_BUSY) && tmout_pat > 0) { msleep(50); tmout_pat -= 50; status = bfin_ata_busy_wait(ap, ATA_BUSY, 3, 0); } if (status != 0xff && (status & ATA_BUSY)) printf("port is slow to respond, please be patient " "(Status 0x%x)\n", status); while (status != 0xff && (status & ATA_BUSY) && tmout_pat > 0) { msleep(50); tmout_pat -= 50; status = bfin_check_status(ap); } if (status == 0xff) return -ENODEV; if (status & ATA_BUSY) { printf("port failed to respond " "(%lu secs, Status 0x%x)\n", DIV_ROUND_UP(tmout, 1000), status); return -EBUSY; } return 0; } /** * bfin_dev_select - Select device 0/1 on ATA bus * @ap: ATA channel to manipulate * @device: ATA device (numbered from zero) to select * * Note: Original code is ata_sff_dev_select(). */ static void bfin_dev_select(struct ata_port *ap, unsigned int device) { void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; u8 tmp; if (device == 0) tmp = ATA_DEVICE_OBS; else tmp = ATA_DEVICE_OBS | ATA_DEV1; write_atapi_register(base, ATA_REG_DEVICE, tmp); udelay(1); } /** * bfin_devchk - PATA device presence detection * @ap: ATA channel to examine * @device: Device to examine (starting at zero) * * Note: Original code is ata_devchk(). */ static unsigned int bfin_devchk(struct ata_port *ap, unsigned int device) { void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; u8 nsect, lbal; bfin_dev_select(ap, device); write_atapi_register(base, ATA_REG_NSECT, 0x55); write_atapi_register(base, ATA_REG_LBAL, 0xaa); write_atapi_register(base, ATA_REG_NSECT, 0xaa); write_atapi_register(base, ATA_REG_LBAL, 0x55); write_atapi_register(base, ATA_REG_NSECT, 0x55); write_atapi_register(base, ATA_REG_LBAL, 0xaa); nsect = read_atapi_register(base, ATA_REG_NSECT); lbal = read_atapi_register(base, ATA_REG_LBAL); if ((nsect == 0x55) && (lbal == 0xaa)) return 1; /* we found a device */ return 0; /* nothing found */ } /** * bfin_bus_post_reset - PATA device post reset * * Note: Original code is ata_bus_post_reset(). */ static void bfin_bus_post_reset(struct ata_port *ap, unsigned int devmask) { void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; unsigned int dev0 = devmask & (1 << 0); unsigned int dev1 = devmask & (1 << 1); long deadline; /* if device 0 was found in ata_devchk, wait for its * BSY bit to clear */ if (dev0) bfin_ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); /* if device 1 was found in ata_devchk, wait for * register access, then wait for BSY to clear */ deadline = ATA_TMOUT_BOOT; while (dev1) { u8 nsect, lbal; bfin_dev_select(ap, 1); nsect = read_atapi_register(base, ATA_REG_NSECT); lbal = read_atapi_register(base, ATA_REG_LBAL); if ((nsect == 1) && (lbal == 1)) break; if (deadline <= 0) { dev1 = 0; break; } msleep(50); /* give drive a breather */ deadline -= 50; } if (dev1) bfin_ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); /* is all this really necessary? */ bfin_dev_select(ap, 0); if (dev1) bfin_dev_select(ap, 1); if (dev0) bfin_dev_select(ap, 0); } /** * bfin_bus_softreset - PATA device software reset * * Note: Original code is ata_bus_softreset(). */ static unsigned int bfin_bus_softreset(struct ata_port *ap, unsigned int devmask) { void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; /* software reset. causes dev0 to be selected */ write_atapi_register(base, ATA_REG_CTRL, ap->ctl_reg); udelay(20); write_atapi_register(base, ATA_REG_CTRL, ap->ctl_reg | ATA_SRST); udelay(20); write_atapi_register(base, ATA_REG_CTRL, ap->ctl_reg); /* spec mandates ">= 2ms" before checking status. * We wait 150ms, because that was the magic delay used for * ATAPI devices in Hale Landis's ATADRVR, for the period of time * between when the ATA command register is written, and then * status is checked. Because waiting for "a while" before * checking status is fine, post SRST, we perform this magic * delay here as well. * * Old drivers/ide uses the 2mS rule and then waits for ready */ msleep(150); /* Before we perform post reset processing we want to see if * the bus shows 0xFF because the odd clown forgets the D7 * pulldown resistor. */ if (bfin_check_status(ap) == 0xFF) return 0; bfin_bus_post_reset(ap, devmask); return 0; } /** * bfin_softreset - reset host port via ATA SRST * @ap: port to reset * * Note: Original code is ata_sff_softreset(). */ static int bfin_softreset(struct ata_port *ap) { unsigned int err_mask; ap->dev_mask = 0; /* determine if device 0/1 are present. * only one device is supported on one port by now. */ if (bfin_devchk(ap, 0)) ap->dev_mask |= (1 << 0); else if (bfin_devchk(ap, 1)) ap->dev_mask |= (1 << 1); else return -ENODEV; /* select device 0 again */ bfin_dev_select(ap, 0); /* issue bus reset */ err_mask = bfin_bus_softreset(ap, ap->dev_mask); if (err_mask) { printf("SRST failed (err_mask=0x%x)\n", err_mask); ap->dev_mask = 0; return -EIO; } return 0; } /** * bfin_irq_clear - Clear ATAPI interrupt. * @ap: Port associated with this ATA transaction. * * Note: Original code is ata_sff_irq_clear(). */ static void bfin_irq_clear(struct ata_port *ap) { void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; ATAPI_SET_INT_STATUS(base, ATAPI_GET_INT_STATUS(base)|ATAPI_DEV_INT | MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT | MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT); } static u8 bfin_wait_for_irq(struct ata_port *ap, unsigned int max) { void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; do { if (ATAPI_GET_INT_STATUS(base) & (ATAPI_DEV_INT | MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT | MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT)) { break; } udelay(1000); max--; } while ((max > 0)); return max == 0; } /** * bfin_ata_reset_port - initialize BFIN ATAPI port. */ static int bfin_ata_reset_port(struct ata_port *ap) { void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; int count; unsigned short status; /* Disable all ATAPI interrupts */ ATAPI_SET_INT_MASK(base, 0); SSYNC(); /* Assert the RESET signal 25us*/ ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | DEV_RST); udelay(30); /* Negate the RESET signal for 2ms*/ ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) & ~DEV_RST); msleep(2); /* Wait on Busy flag to clear */ count = 10000000; do { status = read_atapi_register(base, ATA_REG_STATUS); } while (--count && (status & ATA_BUSY)); /* Enable only ATAPI Device interrupt */ ATAPI_SET_INT_MASK(base, 1); SSYNC(); return !count; } /** * * Function: bfin_config_atapi_gpio * * Description: Configures the ATAPI pins for use * */ static int bfin_config_atapi_gpio(struct ata_port *ap) { const unsigned short pins[] = { P_ATAPI_RESET, P_ATAPI_DIOR, P_ATAPI_DIOW, P_ATAPI_CS0, P_ATAPI_CS1, P_ATAPI_DMACK, P_ATAPI_DMARQ, P_ATAPI_INTRQ, P_ATAPI_IORDY, P_ATAPI_D0A, P_ATAPI_D1A, P_ATAPI_D2A, P_ATAPI_D3A, P_ATAPI_D4A, P_ATAPI_D5A, P_ATAPI_D6A, P_ATAPI_D7A, P_ATAPI_D8A, P_ATAPI_D9A, P_ATAPI_D10A, P_ATAPI_D11A, P_ATAPI_D12A, P_ATAPI_D13A, P_ATAPI_D14A, P_ATAPI_D15A, P_ATAPI_A0A, P_ATAPI_A1A, P_ATAPI_A2A, 0, }; peripheral_request_list(pins, "pata_bfin"); return 0; } /** * bfin_atapi_probe - attach a bfin atapi interface * @pdev: platform device * * Register a bfin atapi interface. * * * Platform devices are expected to contain 2 resources per port: * * - I/O Base (IORESOURCE_IO) * - IRQ (IORESOURCE_IRQ) * */ static int bfin_ata_probe_port(struct ata_port *ap) { if (bfin_config_atapi_gpio(ap)) { printf("Requesting Peripherals faild\n"); return -EFAULT; } if (bfin_ata_reset_port(ap)) { printf("Fail to reset ATAPI device\n"); return -EFAULT; } if (ap->ata_mode >= XFER_PIO_0 && ap->ata_mode <= XFER_PIO_4) bfin_set_piomode(ap, ap->ata_mode); else { printf("Given ATA data transfer mode is not supported.\n"); return -EFAULT; } return 0; } #define ATA_SECTOR_WORDS (ATA_SECT_SIZE/2) static void bfin_ata_identify(struct ata_port *ap, int dev) { void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; u8 status = 0; static u16 iobuf[ATA_SECTOR_WORDS]; u64 n_sectors = 0; hd_driveid_t *iop = (hd_driveid_t *)iobuf; memset(iobuf, 0, sizeof(iobuf)); if (!(ap->dev_mask & (1 << dev))) return; debug("port=%d dev=%d\n", ap->port_no, dev); bfin_dev_select(ap, dev); status = 0; /* Device Identify Command */ write_atapi_register(base, ATA_REG_CMD, ATA_CMD_ID_ATA); bfin_check_altstatus(ap); udelay(10); status = bfin_ata_busy_wait(ap, ATA_BUSY, 1000, 0); if (status & ATA_ERR) { printf("\ndevice not responding\n"); ap->dev_mask &= ~(1 << dev); return; } read_atapi_data(base, ATA_SECTOR_WORDS, iobuf); ata_swap_buf_le16(iobuf, ATA_SECTOR_WORDS); /* we require LBA and DMA support (bits 8 & 9 of word 49) */ if (!ata_id_has_dma(iobuf) || !ata_id_has_lba(iobuf)) printf("ata%u: no dma/lba\n", ap->port_no); #ifdef DEBUG ata_dump_id(iobuf); #endif n_sectors = ata_id_n_sectors(iobuf); if (n_sectors == 0) { ap->dev_mask &= ~(1 << dev); return; } ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].revision, ATA_ID_FW_REV, sizeof(sata_dev_desc[ap->port_no].revision)); ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].vendor, ATA_ID_PROD, sizeof(sata_dev_desc[ap->port_no].vendor)); ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].product, ATA_ID_SERNO, sizeof(sata_dev_desc[ap->port_no].product)); if ((iop->config & 0x0080) == 0x0080) sata_dev_desc[ap->port_no].removable = 1; else sata_dev_desc[ap->port_no].removable = 0; sata_dev_desc[ap->port_no].lba = (u32) n_sectors; debug("lba=0x%lx\n", sata_dev_desc[ap->port_no].lba); #ifdef CONFIG_LBA48 if (iop->command_set_2 & 0x0400) sata_dev_desc[ap->port_no].lba48 = 1; else sata_dev_desc[ap->port_no].lba48 = 0; #endif /* assuming HD */ sata_dev_desc[ap->port_no].type = DEV_TYPE_HARDDISK; sata_dev_desc[ap->port_no].blksz = ATA_SECT_SIZE; sata_dev_desc[ap->port_no].log2blksz = LOG2(sata_dev_desc[ap->port_no].blksz); sata_dev_desc[ap->port_no].lun = 0; /* just to fill something in... */ printf("PATA device#%d %s is found on ata port#%d.\n", ap->port_no%PATA_DEV_NUM_PER_PORT, sata_dev_desc[ap->port_no].vendor, ap->port_no/PATA_DEV_NUM_PER_PORT); } static void bfin_ata_set_Feature_cmd(struct ata_port *ap, int dev) { void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; u8 status = 0; if (!(ap->dev_mask & (1 << dev))) return; bfin_dev_select(ap, dev); write_atapi_register(base, ATA_REG_FEATURE, SETFEATURES_XFER); write_atapi_register(base, ATA_REG_NSECT, ap->ata_mode); write_atapi_register(base, ATA_REG_LBAL, 0); write_atapi_register(base, ATA_REG_LBAM, 0); write_atapi_register(base, ATA_REG_LBAH, 0); write_atapi_register(base, ATA_REG_DEVICE, ATA_DEVICE_OBS); write_atapi_register(base, ATA_REG_CMD, ATA_CMD_SET_FEATURES); udelay(50); msleep(150); status = bfin_ata_busy_wait(ap, ATA_BUSY, 5000, 0); if ((status & (ATA_BUSY | ATA_ERR))) { printf("Error : status 0x%02x\n", status); ap->dev_mask &= ~(1 << dev); } } int scan_sata(int dev) { /* dev is the index of each ata device in the system. one PATA port * contains 2 devices. one element in scan_done array indicates one * PATA port. device connected to one PATA port is selected by * bfin_dev_select() before access. */ struct ata_port *ap = &port[dev]; static int scan_done[(CONFIG_SYS_SATA_MAX_DEVICE+1)/PATA_DEV_NUM_PER_PORT]; if (scan_done[dev/PATA_DEV_NUM_PER_PORT]) return 0; /* Check for attached device */ if (!bfin_ata_probe_port(ap)) { if (bfin_softreset(ap)) { /* soft reset failed, try a hard one */ bfin_ata_reset_port(ap); if (bfin_softreset(ap)) scan_done[dev/PATA_DEV_NUM_PER_PORT] = 1; } else { scan_done[dev/PATA_DEV_NUM_PER_PORT] = 1; } } if (scan_done[dev/PATA_DEV_NUM_PER_PORT]) { /* Probe device and set xfer mode */ bfin_ata_identify(ap, dev%PATA_DEV_NUM_PER_PORT); bfin_ata_set_Feature_cmd(ap, dev%PATA_DEV_NUM_PER_PORT); part_init(&sata_dev_desc[dev]); return 0; } printf("PATA device#%d is not present on ATA port#%d.\n", ap->port_no%PATA_DEV_NUM_PER_PORT, ap->port_no/PATA_DEV_NUM_PER_PORT); return -1; } int init_sata(int dev) { struct ata_port *ap = &port[dev]; static u8 init_done; int res = 1; if (init_done) return res; init_done = 1; switch (dev/PATA_DEV_NUM_PER_PORT) { case 0: ap->ioaddr.ctl_addr = ATAPI_CONTROL; ap->ata_mode = CONFIG_BFIN_ATA_MODE; break; default: printf("Tried to scan unknown port %d.\n", dev); return res; } if (ap->ata_mode < XFER_PIO_0 || ap->ata_mode > XFER_PIO_4) { ap->ata_mode = XFER_PIO_4; printf("DMA mode is not supported. Set to PIO mode 4.\n"); } ap->port_no = dev; ap->ctl_reg = 0x8; /*Default value of control reg */ res = 0; return res; } int reset_sata(int dev) { return 0; } /* Read up to 255 sectors * * Returns sectors read */ static u8 do_one_read(struct ata_port *ap, u64 blknr, u8 blkcnt, u16 *buffer, uchar lba48) { void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; u8 sr = 0; u8 status; u16 err = 0; if (!(bfin_check_status(ap) & ATA_DRDY)) { printf("Device ata%d not ready\n", ap->port_no); return 0; } /* Set up transfer */ #ifdef CONFIG_LBA48 if (lba48) { /* write high bits */ write_atapi_register(base, ATA_REG_NSECT, 0); write_atapi_register(base, ATA_REG_LBAL, (blknr >> 24) & 0xFF); write_atapi_register(base, ATA_REG_LBAM, (blknr >> 32) & 0xFF); write_atapi_register(base, ATA_REG_LBAH, (blknr >> 40) & 0xFF); } #endif write_atapi_register(base, ATA_REG_NSECT, blkcnt); write_atapi_register(base, ATA_REG_LBAL, (blknr >> 0) & 0xFF); write_atapi_register(base, ATA_REG_LBAM, (blknr >> 8) & 0xFF); write_atapi_register(base, ATA_REG_LBAH, (blknr >> 16) & 0xFF); #ifdef CONFIG_LBA48 if (lba48) { write_atapi_register(base, ATA_REG_DEVICE, ATA_LBA); write_atapi_register(base, ATA_REG_CMD, ATA_CMD_PIO_READ_EXT); } else #endif { write_atapi_register(base, ATA_REG_DEVICE, ATA_LBA | ((blknr >> 24) & 0xF)); write_atapi_register(base, ATA_REG_CMD, ATA_CMD_PIO_READ); } status = bfin_ata_busy_wait(ap, ATA_BUSY, 500000, 1); if (status & (ATA_BUSY | ATA_ERR)) { printf("Device %d not responding status 0x%x.\n", ap->port_no, status); err = read_atapi_register(base, ATA_REG_ERR); printf("Error reg = 0x%x\n", err); return sr; } while (blkcnt--) { if (bfin_wait_for_irq(ap, 500)) { printf("ata%u irq failed\n", ap->port_no); return sr; } status = bfin_check_status(ap); if (status & ATA_ERR) { err = read_atapi_register(base, ATA_REG_ERR); printf("ata%u error %d\n", ap->port_no, err); return sr; } bfin_irq_clear(ap); /* Read one sector */ read_atapi_data(base, ATA_SECTOR_WORDS, buffer); buffer += ATA_SECTOR_WORDS; sr++; } return sr; } ulong sata_read(int dev, ulong block, lbaint_t blkcnt, void *buff) { struct ata_port *ap = &port[dev]; ulong n = 0, sread; u16 *buffer = (u16 *) buff; u8 status = 0; u64 blknr = (u64) block; unsigned char lba48 = 0; #ifdef CONFIG_LBA48 if (blknr > 0xfffffff) { if (!sata_dev_desc[dev].lba48) { printf("Drive doesn't support 48-bit addressing\n"); return 0; } /* more than 28 bits used, use 48bit mode */ lba48 = 1; } #endif bfin_dev_select(ap, dev%PATA_DEV_NUM_PER_PORT); while (blkcnt > 0) { if (blkcnt > 255) sread = 255; else sread = blkcnt; status = do_one_read(ap, blknr, sread, buffer, lba48); if (status != sread) { printf("Read failed\n"); return n; } blkcnt -= sread; blknr += sread; n += sread; buffer += sread * ATA_SECTOR_WORDS; } return n; } ulong sata_write(int dev, ulong block, lbaint_t blkcnt, const void *buff) { struct ata_port *ap = &port[dev]; void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; ulong n = 0; u16 *buffer = (u16 *) buff; unsigned char status = 0; u64 blknr = (u64) block; #ifdef CONFIG_LBA48 unsigned char lba48 = 0; if (blknr > 0xfffffff) { if (!sata_dev_desc[dev].lba48) { printf("Drive doesn't support 48-bit addressing\n"); return 0; } /* more than 28 bits used, use 48bit mode */ lba48 = 1; } #endif bfin_dev_select(ap, dev%PATA_DEV_NUM_PER_PORT); while (blkcnt-- > 0) { status = bfin_ata_busy_wait(ap, ATA_BUSY, 50000, 0); if (status & ATA_BUSY) { printf("ata%u failed to respond\n", ap->port_no); return n; } #ifdef CONFIG_LBA48 if (lba48) { /* write high bits */ write_atapi_register(base, ATA_REG_NSECT, 0); write_atapi_register(base, ATA_REG_LBAL, (blknr >> 24) & 0xFF); write_atapi_register(base, ATA_REG_LBAM, (blknr >> 32) & 0xFF); write_atapi_register(base, ATA_REG_LBAH, (blknr >> 40) & 0xFF); } #endif write_atapi_register(base, ATA_REG_NSECT, 1); write_atapi_register(base, ATA_REG_LBAL, (blknr >> 0) & 0xFF); write_atapi_register(base, ATA_REG_LBAM, (blknr >> 8) & 0xFF); write_atapi_register(base, ATA_REG_LBAH, (blknr >> 16) & 0xFF); #ifdef CONFIG_LBA48 if (lba48) { write_atapi_register(base, ATA_REG_DEVICE, ATA_LBA); write_atapi_register(base, ATA_REG_CMD, ATA_CMD_PIO_WRITE_EXT); } else #endif { write_atapi_register(base, ATA_REG_DEVICE, ATA_LBA | ((blknr >> 24) & 0xF)); write_atapi_register(base, ATA_REG_CMD, ATA_CMD_PIO_WRITE); } /*may take up to 5 sec */ status = bfin_ata_busy_wait(ap, ATA_BUSY, 50000, 0); if ((status & (ATA_DRQ | ATA_BUSY | ATA_ERR)) != ATA_DRQ) { printf("Error no DRQ dev %d blk %ld: sts 0x%02x\n", ap->port_no, (ulong) blknr, status); return n; } write_atapi_data(base, ATA_SECTOR_WORDS, buffer); bfin_check_altstatus(ap); udelay(1); ++n; ++blknr; buffer += ATA_SECTOR_WORDS; } return n; }