Lines Matching +full:tf +full:- +full:a

1 // SPDX-License-Identifier: GPL-2.0-only
12 * DMA engine support based on spi-ep93xx.c by Mika Westerberg.
21 * Heavily based on the ep93xx-ide.c driver:
48 #include <linux/platform_data/dma-ep93xx.h>
51 #define DRV_NAME "ep93xx-ide"
69 * ORed to the IDECTRL register, hence giving directly the A[2:0] and
167 * of HCLK cycles to hold the data bus after a PIO write operation.
201 * Based on delay loop found in mach-pxa/mp900.c.
224 * tA = 35ns after activation of DIOR-/DIOW-. Maximum IORDY pulse in ep93xx_pata_wait_for_iordy()
228 * DIOR-/DIOW-, so we set timeout to (1250 + 35) / 25 - t2 additional in ep93xx_pata_wait_for_iordy()
231 unsigned long start = (1250 + 35) / 25 - t2; in ep93xx_pata_wait_for_iordy()
234 while (!ep93xx_pata_check_iordy(base) && counter--) in ep93xx_pata_wait_for_iordy()
236 return start - counter; in ep93xx_pata_wait_for_iordy()
257 if (t0 > t2 && t0 - t2 > t2i) in ep93xx_pata_rw_end()
258 ep93xx_pata_delay(t0 - t2); in ep93xx_pata_rw_end()
267 void __iomem *base = drv_data->ide_base; in ep93xx_pata_read()
268 const struct ata_timing *t = &drv_data->t; in ep93xx_pata_read()
269 unsigned long t0 = reg ? t->cyc8b : t->cycle; in ep93xx_pata_read()
270 unsigned long t2 = reg ? t->act8b : t->active; in ep93xx_pata_read()
271 unsigned long t2i = reg ? t->rec8b : t->recover; in ep93xx_pata_read()
273 ep93xx_pata_rw_begin(base, addr, t->setup); in ep93xx_pata_read()
277 * edge of the DIORN signal. (EP93xx UG p27-14) in ep93xx_pata_read()
279 ep93xx_pata_rw_end(base, addr, drv_data->iordy, t0, t2, t2i); in ep93xx_pata_read()
301 void __iomem *base = drv_data->ide_base; in ep93xx_pata_write()
302 const struct ata_timing *t = &drv_data->t; in ep93xx_pata_write()
303 unsigned long t0 = reg ? t->cyc8b : t->cycle; in ep93xx_pata_write()
304 unsigned long t2 = reg ? t->act8b : t->active; in ep93xx_pata_write()
305 unsigned long t2i = reg ? t->rec8b : t->recover; in ep93xx_pata_write()
307 ep93xx_pata_rw_begin(base, addr, t->setup); in ep93xx_pata_write()
310 * DIOWN is low. (EP93xx UG p27-13) in ep93xx_pata_write()
314 ep93xx_pata_rw_end(base, addr, drv_data->iordy, t0, t2, t2i); in ep93xx_pata_write()
334 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_set_piomode()
339 * slower, we will wait a bit longer in each delay. in ep93xx_pata_set_piomode()
345 ata_timing_compute(adev, adev->pio_mode, &drv_data->t, T, 0); in ep93xx_pata_set_piomode()
346 if (pair && pair->pio_mode) { in ep93xx_pata_set_piomode()
348 ata_timing_compute(pair, pair->pio_mode, &t, T, 0); in ep93xx_pata_set_piomode()
349 ata_timing_merge(&t, &drv_data->t, &drv_data->t, in ep93xx_pata_set_piomode()
352 drv_data->iordy = ata_pio_need_iordy(adev); in ep93xx_pata_set_piomode()
354 ep93xx_pata_enable_pio(drv_data->ide_base, in ep93xx_pata_set_piomode()
355 adev->pio_mode - XFER_PIO_0); in ep93xx_pata_set_piomode()
361 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_check_status()
368 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_check_altstatus()
375 const struct ata_taskfile *tf) in ep93xx_pata_tf_load() argument
377 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_tf_load()
378 unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; in ep93xx_pata_tf_load()
380 if (tf->ctl != ap->last_ctl) { in ep93xx_pata_tf_load()
381 ep93xx_pata_write_reg(drv_data, tf->ctl, IDECTRL_ADDR_CTL); in ep93xx_pata_tf_load()
382 ap->last_ctl = tf->ctl; in ep93xx_pata_tf_load()
386 if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { in ep93xx_pata_tf_load()
387 ep93xx_pata_write_reg(drv_data, tf->hob_feature, in ep93xx_pata_tf_load()
389 ep93xx_pata_write_reg(drv_data, tf->hob_nsect, in ep93xx_pata_tf_load()
391 ep93xx_pata_write_reg(drv_data, tf->hob_lbal, in ep93xx_pata_tf_load()
393 ep93xx_pata_write_reg(drv_data, tf->hob_lbam, in ep93xx_pata_tf_load()
395 ep93xx_pata_write_reg(drv_data, tf->hob_lbah, in ep93xx_pata_tf_load()
400 ep93xx_pata_write_reg(drv_data, tf->feature, in ep93xx_pata_tf_load()
402 ep93xx_pata_write_reg(drv_data, tf->nsect, IDECTRL_ADDR_NSECT); in ep93xx_pata_tf_load()
403 ep93xx_pata_write_reg(drv_data, tf->lbal, IDECTRL_ADDR_LBAL); in ep93xx_pata_tf_load()
404 ep93xx_pata_write_reg(drv_data, tf->lbam, IDECTRL_ADDR_LBAM); in ep93xx_pata_tf_load()
405 ep93xx_pata_write_reg(drv_data, tf->lbah, IDECTRL_ADDR_LBAH); in ep93xx_pata_tf_load()
408 if (tf->flags & ATA_TFLAG_DEVICE) in ep93xx_pata_tf_load()
409 ep93xx_pata_write_reg(drv_data, tf->device, in ep93xx_pata_tf_load()
416 static void ep93xx_pata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) in ep93xx_pata_tf_read() argument
418 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_tf_read()
420 tf->status = ep93xx_pata_check_status(ap); in ep93xx_pata_tf_read()
421 tf->error = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_FEATURE); in ep93xx_pata_tf_read()
422 tf->nsect = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_NSECT); in ep93xx_pata_tf_read()
423 tf->lbal = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_LBAL); in ep93xx_pata_tf_read()
424 tf->lbam = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_LBAM); in ep93xx_pata_tf_read()
425 tf->lbah = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_LBAH); in ep93xx_pata_tf_read()
426 tf->device = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_DEVICE); in ep93xx_pata_tf_read()
428 if (tf->flags & ATA_TFLAG_LBA48) { in ep93xx_pata_tf_read()
429 ep93xx_pata_write_reg(drv_data, tf->ctl | ATA_HOB, in ep93xx_pata_tf_read()
431 tf->hob_feature = ep93xx_pata_read_reg(drv_data, in ep93xx_pata_tf_read()
433 tf->hob_nsect = ep93xx_pata_read_reg(drv_data, in ep93xx_pata_tf_read()
435 tf->hob_lbal = ep93xx_pata_read_reg(drv_data, in ep93xx_pata_tf_read()
437 tf->hob_lbam = ep93xx_pata_read_reg(drv_data, in ep93xx_pata_tf_read()
439 tf->hob_lbah = ep93xx_pata_read_reg(drv_data, in ep93xx_pata_tf_read()
441 ep93xx_pata_write_reg(drv_data, tf->ctl, IDECTRL_ADDR_CTL); in ep93xx_pata_tf_read()
442 ap->last_ctl = tf->ctl; in ep93xx_pata_tf_read()
448 const struct ata_taskfile *tf) in ep93xx_pata_exec_command() argument
450 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_exec_command()
452 ep93xx_pata_write_reg(drv_data, tf->command, in ep93xx_pata_exec_command()
460 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_dev_select()
473 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_set_devctl()
483 struct ata_port *ap = qc->dev->link->ap; in ep93xx_pata_data_xfer()
484 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_data_xfer()
489 while (words--) in ep93xx_pata_data_xfer()
502 buf += buflen - 1; in ep93xx_pata_data_xfer()
524 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_device_is_present()
527 ap->ops->sff_dev_select(ap, device); in ep93xx_pata_device_is_present()
552 struct ata_port *ap = link->ap; in ep93xx_pata_wait_after_reset()
553 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_wait_after_reset()
563 * -ENODEV means the odd clown forgot the D7 pulldown resistor in ep93xx_pata_wait_after_reset()
564 * and TF status is 0xff, bail out on it too. in ep93xx_pata_wait_after_reset()
576 ap->ops->sff_dev_select(ap, 1); in ep93xx_pata_wait_after_reset()
592 msleep(50); /* give drive a breather */ in ep93xx_pata_wait_after_reset()
597 if (rc != -ENODEV) in ep93xx_pata_wait_after_reset()
603 ap->ops->sff_dev_select(ap, 0); in ep93xx_pata_wait_after_reset()
605 ap->ops->sff_dev_select(ap, 1); in ep93xx_pata_wait_after_reset()
607 ap->ops->sff_dev_select(ap, 0); in ep93xx_pata_wait_after_reset()
616 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_bus_softreset()
618 ep93xx_pata_write_reg(drv_data, ap->ctl, IDECTRL_ADDR_CTL); in ep93xx_pata_bus_softreset()
620 ep93xx_pata_write_reg(drv_data, ap->ctl | ATA_SRST, IDECTRL_ADDR_CTL); in ep93xx_pata_bus_softreset()
622 ep93xx_pata_write_reg(drv_data, ap->ctl, IDECTRL_ADDR_CTL); in ep93xx_pata_bus_softreset()
623 ap->last_ctl = ap->ctl; in ep93xx_pata_bus_softreset()
625 return ep93xx_pata_wait_after_reset(&ap->link, devmask, deadline); in ep93xx_pata_bus_softreset()
630 if (drv_data->dma_rx_channel) { in ep93xx_pata_release_dma()
631 dma_release_channel(drv_data->dma_rx_channel); in ep93xx_pata_release_dma()
632 drv_data->dma_rx_channel = NULL; in ep93xx_pata_release_dma()
634 if (drv_data->dma_tx_channel) { in ep93xx_pata_release_dma()
635 dma_release_channel(drv_data->dma_tx_channel); in ep93xx_pata_release_dma()
636 drv_data->dma_tx_channel = NULL; in ep93xx_pata_release_dma()
645 chan->private = filter_param; in ep93xx_pata_dma_filter()
651 const struct platform_device *pdev = drv_data->pdev; in ep93xx_pata_dma_init()
663 drv_data->dma_rx_data.port = EP93XX_DMA_IDE; in ep93xx_pata_dma_init()
664 drv_data->dma_rx_data.direction = DMA_DEV_TO_MEM; in ep93xx_pata_dma_init()
665 drv_data->dma_rx_data.name = "ep93xx-pata-rx"; in ep93xx_pata_dma_init()
666 drv_data->dma_rx_channel = dma_request_channel(mask, in ep93xx_pata_dma_init()
667 ep93xx_pata_dma_filter, &drv_data->dma_rx_data); in ep93xx_pata_dma_init()
668 if (!drv_data->dma_rx_channel) in ep93xx_pata_dma_init()
671 drv_data->dma_tx_data.port = EP93XX_DMA_IDE; in ep93xx_pata_dma_init()
672 drv_data->dma_tx_data.direction = DMA_MEM_TO_DEV; in ep93xx_pata_dma_init()
673 drv_data->dma_tx_data.name = "ep93xx-pata-tx"; in ep93xx_pata_dma_init()
674 drv_data->dma_tx_channel = dma_request_channel(mask, in ep93xx_pata_dma_init()
675 ep93xx_pata_dma_filter, &drv_data->dma_tx_data); in ep93xx_pata_dma_init()
676 if (!drv_data->dma_tx_channel) { in ep93xx_pata_dma_init()
677 dma_release_channel(drv_data->dma_rx_channel); in ep93xx_pata_dma_init()
684 conf.src_addr = drv_data->udma_in_phys; in ep93xx_pata_dma_init()
686 if (dmaengine_slave_config(drv_data->dma_rx_channel, &conf)) { in ep93xx_pata_dma_init()
687 dev_err(&pdev->dev, "failed to configure rx dma channel\n"); in ep93xx_pata_dma_init()
695 conf.dst_addr = drv_data->udma_out_phys; in ep93xx_pata_dma_init()
697 if (dmaengine_slave_config(drv_data->dma_tx_channel, &conf)) { in ep93xx_pata_dma_init()
698 dev_err(&pdev->dev, "failed to configure tx dma channel\n"); in ep93xx_pata_dma_init()
706 struct ep93xx_pata_data *drv_data = qc->ap->host->private_data; in ep93xx_pata_dma_start()
707 void __iomem *base = drv_data->ide_base; in ep93xx_pata_dma_start()
708 struct ata_device *adev = qc->dev; in ep93xx_pata_dma_start()
709 u32 v = qc->dma_dir == DMA_TO_DEVICE ? IDEUDMAOP_RWOP : 0; in ep93xx_pata_dma_start()
710 struct dma_chan *channel = qc->dma_dir == DMA_TO_DEVICE in ep93xx_pata_dma_start()
711 ? drv_data->dma_tx_channel : drv_data->dma_rx_channel; in ep93xx_pata_dma_start()
713 txd = dmaengine_prep_slave_sg(channel, qc->sg, qc->n_elem, qc->dma_dir, in ep93xx_pata_dma_start()
716 dev_err(qc->ap->dev, "failed to prepare slave for sg dma\n"); in ep93xx_pata_dma_start()
719 txd->callback = NULL; in ep93xx_pata_dma_start()
720 txd->callback_param = NULL; in ep93xx_pata_dma_start()
723 dev_err(qc->ap->dev, "failed to submit dma transfer\n"); in ep93xx_pata_dma_start()
740 ((adev->xfer_mode - XFER_UDMA_0) << IDECFG_MODE_SHIFT), in ep93xx_pata_dma_start()
746 struct ep93xx_pata_data *drv_data = qc->ap->host->private_data; in ep93xx_pata_dma_stop()
747 void __iomem *base = drv_data->ide_base; in ep93xx_pata_dma_stop()
750 dmaengine_terminate_all(drv_data->dma_rx_channel); in ep93xx_pata_dma_stop()
751 dmaengine_terminate_all(drv_data->dma_tx_channel); in ep93xx_pata_dma_stop()
754 * To properly stop IDE-DMA, IDEUDMAOP register must to be cleared in ep93xx_pata_dma_stop()
761 ep93xx_pata_enable_pio(drv_data->ide_base, in ep93xx_pata_dma_stop()
762 qc->dev->pio_mode - XFER_PIO_0); in ep93xx_pata_dma_stop()
764 ata_sff_dma_pause(qc->ap); in ep93xx_pata_dma_stop()
769 qc->ap->ops->sff_exec_command(qc->ap, &qc->tf); in ep93xx_pata_dma_setup()
774 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_dma_status()
775 u32 val = readl(drv_data->ide_base + IDEUDMASTS); in ep93xx_pata_dma_status()
780 * DMAIDE - DMA request signal from UDMA state machine, in ep93xx_pata_dma_status()
781 * INTIDE - INT line generated by UDMA because of errors in the in ep93xx_pata_dma_status()
783 * SBUSY - UDMA state machine busy, not in idle state, in ep93xx_pata_dma_status()
784 * NDO - error for data-out not completed, in ep93xx_pata_dma_status()
785 * NDI - error for data-in not completed, in ep93xx_pata_dma_status()
786 * N4X - error for data transferred not multiplies of four in ep93xx_pata_dma_status()
787 * 32-bit words. in ep93xx_pata_dma_status()
788 * (EP93xx UG p27-17) in ep93xx_pata_dma_status()
795 if (readl(drv_data->ide_base + IDECTRL) & IDECTRL_INTRQ) in ep93xx_pata_dma_status()
808 struct ata_port *ap = al->ap; in ep93xx_pata_softreset()
809 unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; in ep93xx_pata_softreset()
821 ap->ops->sff_dev_select(al->ap, 0); in ep93xx_pata_softreset()
825 /* if link is ocuppied, -ENODEV too is an error */ in ep93xx_pata_softreset()
826 if (rc && (rc != -ENODEV || sata_scr_valid(al))) { in ep93xx_pata_softreset()
832 classes[0] = ata_sff_dev_classify(&al->device[0], devmask & (1 << 0), in ep93xx_pata_softreset()
835 classes[1] = ata_sff_dev_classify(&al->device[1], in ep93xx_pata_softreset()
848 /* We only need to flush incoming data when a command was running */ in ep93xx_pata_drain_fifo()
849 if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE) in ep93xx_pata_drain_fifo()
852 ap = qc->ap; in ep93xx_pata_drain_fifo()
853 drv_data = ap->host->private_data; in ep93xx_pata_drain_fifo()
855 for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ) in ep93xx_pata_drain_fifo()
866 struct ep93xx_pata_data *drv_data = ap->host->private_data; in ep93xx_pata_port_start()
872 drv_data->t = *ata_timing_find_mode(XFER_PIO_0); in ep93xx_pata_port_start()
947 drv_data = devm_kzalloc(&pdev->dev, sizeof(*drv_data), GFP_KERNEL); in ep93xx_pata_probe()
949 err = -ENOMEM; in ep93xx_pata_probe()
953 drv_data->pdev = pdev; in ep93xx_pata_probe()
954 drv_data->ide_base = ide_base; in ep93xx_pata_probe()
955 drv_data->udma_in_phys = mem_res->start + IDEUDMADATAIN; in ep93xx_pata_probe()
956 drv_data->udma_out_phys = mem_res->start + IDEUDMADATAOUT; in ep93xx_pata_probe()
960 host = ata_host_alloc(&pdev->dev, 1); in ep93xx_pata_probe()
962 err = -ENOMEM; in ep93xx_pata_probe()
968 host->private_data = drv_data; in ep93xx_pata_probe()
970 ap = host->ports[0]; in ep93xx_pata_probe()
971 ap->dev = &pdev->dev; in ep93xx_pata_probe()
972 ap->ops = &ep93xx_pata_port_ops; in ep93xx_pata_probe()
973 ap->flags |= ATA_FLAG_SLAVE_POSS; in ep93xx_pata_probe()
974 ap->pio_mask = ATA_PIO4; in ep93xx_pata_probe()
978 * EP931x rev.E0 - UDMA2 in ep93xx_pata_probe()
979 * EP931x rev.E1 - UDMA3 in ep93xx_pata_probe()
980 * EP931x rev.E2 - UDMA4 in ep93xx_pata_probe()
985 if (drv_data->dma_rx_channel && drv_data->dma_tx_channel) { in ep93xx_pata_probe()
990 ap->udma_mask = (unsigned int) match->data; in ep93xx_pata_probe()
992 ap->udma_mask = ATA_UDMA2; in ep93xx_pata_probe()
998 dev_info(&pdev->dev, "version " DRV_VERSION "\n"); in ep93xx_pata_probe()
1016 struct ep93xx_pata_data *drv_data = host->private_data; in ep93xx_pata_remove()
1020 ep93xx_pata_clear_regs(drv_data->ide_base); in ep93xx_pata_remove()
1036 MODULE_DESCRIPTION("low-level driver for cirrus ep93xx IDE controller");