Lines Matching +full:udma +full:- +full:c

2  * drivers/ata/pata_mpc52xx.c
4 * libata driver for the Freescale MPC52xx on-chip IDE interface
6 * Copyright (C) 2006 Sylvain Munaut <[email protected]>
7 * Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
9 * UDMA support based on patches by Freescale (Bernard Kuhn, John Rigby),
68 /* ATAPI-4 PIO specs (in ns) */
77 #define CALC_CLKCYC(c,v) ((((v)+(c)-1)/(c))) argument
81 /* ATAPI-4 MDMA specs (in clocks) */
104 /* ATAPI-4 UDMA specs (in clocks) */
188 #define MPC52xx_ATA_HOSTSTAT_UREP 0x40000000UL /* UDMA Read Extended Pause */
197 #define MPC52xx_ATA_DMAMODE_UDMA 0x04 /* UDMA enabled */
201 #define MPC52xx_ATA_DMAMODE_HUT 0x40 /* Host UDMA burst terminate */
216 u32 udma1; /* ATA + 0x18 UDMA Timing 1 */
217 u32 udma2; /* ATA + 0x1c UDMA Timing 2 */
218 u32 udma3; /* ATA + 0x20 UDMA Timing 3 */
219 u32 udma4; /* ATA + 0x24 UDMA Timing 4 */
220 u32 udma5; /* ATA + 0x28 UDMA Timing 5 */
273 struct mpc52xx_ata_timings *timing = &priv->timings[dev]; in mpc52xx_ata_compute_pio_timings()
274 unsigned int ipb_period = priv->ipb_period; in mpc52xx_ata_compute_pio_timings()
278 return -EINVAL; in mpc52xx_ata_compute_pio_timings()
288 timing->pio1 = (t0 << 24) | (t2_8 << 16) | (t2_16 << 8) | (t2i); in mpc52xx_ata_compute_pio_timings()
289 timing->pio2 = (t4 << 24) | (t1 << 16) | (ta << 8); in mpc52xx_ata_compute_pio_timings()
298 struct mpc52xx_ata_timings *t = &priv->timings[dev]; in mpc52xx_ata_compute_mdma_timings()
299 const struct mdmaspec *s = &priv->mdmaspec[speed]; in mpc52xx_ata_compute_mdma_timings()
302 return -EINVAL; in mpc52xx_ata_compute_mdma_timings()
304 t->mdma1 = ((u32)s->t0M << 24) | ((u32)s->td << 16) | ((u32)s->tkw << 8) | s->tm; in mpc52xx_ata_compute_mdma_timings()
305 t->mdma2 = ((u32)s->th << 24) | ((u32)s->tj << 16) | ((u32)s->tn << 8); in mpc52xx_ata_compute_mdma_timings()
306 t->using_udma = 0; in mpc52xx_ata_compute_mdma_timings()
315 struct mpc52xx_ata_timings *t = &priv->timings[dev]; in mpc52xx_ata_compute_udma_timings()
316 const struct udmaspec *s = &priv->udmaspec[speed]; in mpc52xx_ata_compute_udma_timings()
319 return -EINVAL; in mpc52xx_ata_compute_udma_timings()
321 t->udma1 = ((u32)s->t2cyc << 24) | ((u32)s->tcyc << 16) | ((u32)s->tds << 8) | s->tdh; in mpc52xx_ata_compute_udma_timings()
322 t->udma2 = ((u32)s->tdvs << 24) | ((u32)s->tdvh << 16) | ((u32)s->tfs << 8) | s->tli; in mpc52xx_ata_compute_udma_timings()
323 t->udma3 = ((u32)s->tmli << 24) | ((u32)s->taz << 16) | ((u32)s->tenv << 8) | s->tsr; in mpc52xx_ata_compute_udma_timings()
324 t->udma4 = ((u32)s->tss << 24) | ((u32)s->trfs << 16) | ((u32)s->trp << 8) | s->tack; in mpc52xx_ata_compute_udma_timings()
325 t->udma5 = (u32)s->tzah << 24; in mpc52xx_ata_compute_udma_timings()
326 t->using_udma = 1; in mpc52xx_ata_compute_udma_timings()
334 struct mpc52xx_ata __iomem *regs = priv->ata_regs; in mpc52xx_ata_apply_timings()
335 struct mpc52xx_ata_timings *timing = &priv->timings[device]; in mpc52xx_ata_apply_timings()
337 out_be32(&regs->pio1, timing->pio1); in mpc52xx_ata_apply_timings()
338 out_be32(&regs->pio2, timing->pio2); in mpc52xx_ata_apply_timings()
339 out_be32(&regs->mdma1, timing->mdma1); in mpc52xx_ata_apply_timings()
340 out_be32(&regs->mdma2, timing->mdma2); in mpc52xx_ata_apply_timings()
341 out_be32(&regs->udma1, timing->udma1); in mpc52xx_ata_apply_timings()
342 out_be32(&regs->udma2, timing->udma2); in mpc52xx_ata_apply_timings()
343 out_be32(&regs->udma3, timing->udma3); in mpc52xx_ata_apply_timings()
344 out_be32(&regs->udma4, timing->udma4); in mpc52xx_ata_apply_timings()
345 out_be32(&regs->udma5, timing->udma5); in mpc52xx_ata_apply_timings()
346 priv->csel = device; in mpc52xx_ata_apply_timings()
352 struct mpc52xx_ata __iomem *regs = priv->ata_regs; in mpc52xx_ata_hw_init()
356 out_be32(&regs->share_cnt, 0); in mpc52xx_ata_hw_init()
359 out_be32(&regs->config, in mpc52xx_ata_hw_init()
367 out_be32(&regs->config, in mpc52xx_ata_hw_init()
372 tslot = CALC_CLKCYC(priv->ipb_period, 1000000); in mpc52xx_ata_hw_init()
373 out_be32(&regs->share_cnt, tslot << 16); in mpc52xx_ata_hw_init()
376 memset(priv->timings, 0x00, 2*sizeof(struct mpc52xx_ata_timings)); in mpc52xx_ata_hw_init()
394 struct mpc52xx_ata_priv *priv = ap->host->private_data; in mpc52xx_ata_set_piomode()
397 pio = adev->pio_mode - XFER_PIO_0; in mpc52xx_ata_set_piomode()
399 rv = mpc52xx_ata_compute_pio_timings(priv, adev->devno, pio); in mpc52xx_ata_set_piomode()
402 dev_err(ap->dev, "error: invalid PIO mode: %d\n", pio); in mpc52xx_ata_set_piomode()
406 mpc52xx_ata_apply_timings(priv, adev->devno); in mpc52xx_ata_set_piomode()
412 struct mpc52xx_ata_priv *priv = ap->host->private_data; in mpc52xx_ata_set_dmamode()
415 if (adev->dma_mode >= XFER_UDMA_0) { in mpc52xx_ata_set_dmamode()
416 int dma = adev->dma_mode - XFER_UDMA_0; in mpc52xx_ata_set_dmamode()
417 rv = mpc52xx_ata_compute_udma_timings(priv, adev->devno, dma); in mpc52xx_ata_set_dmamode()
419 int dma = adev->dma_mode - XFER_MW_DMA_0; in mpc52xx_ata_set_dmamode()
420 rv = mpc52xx_ata_compute_mdma_timings(priv, adev->devno, dma); in mpc52xx_ata_set_dmamode()
424 dev_alert(ap->dev, in mpc52xx_ata_set_dmamode()
426 adev->dma_mode); in mpc52xx_ata_set_dmamode()
430 mpc52xx_ata_apply_timings(priv, adev->devno); in mpc52xx_ata_set_dmamode()
436 struct mpc52xx_ata_priv *priv = ap->host->private_data; in mpc52xx_ata_dev_select()
438 if (device != priv->csel) in mpc52xx_ata_dev_select()
447 struct ata_port *ap = qc->ap; in mpc52xx_ata_build_dmatable()
448 struct mpc52xx_ata_priv *priv = ap->host->private_data; in mpc52xx_ata_build_dmatable()
450 unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE), si; in mpc52xx_ata_build_dmatable()
455 bcom_ata_rx_prepare(priv->dmatsk); in mpc52xx_ata_build_dmatable()
457 bcom_ata_tx_prepare(priv->dmatsk); in mpc52xx_ata_build_dmatable()
459 for_each_sg(qc->sg, sg, qc->n_elem, si) { in mpc52xx_ata_build_dmatable()
466 bcom_prepare_next_buffer(priv->dmatsk); in mpc52xx_ata_build_dmatable()
469 bd->status = tc; in mpc52xx_ata_build_dmatable()
470 bd->src_pa = (__force u32) priv->ata_regs_pa + in mpc52xx_ata_build_dmatable()
472 bd->dst_pa = (__force u32) cur_addr; in mpc52xx_ata_build_dmatable()
474 bd->status = tc; in mpc52xx_ata_build_dmatable()
475 bd->src_pa = (__force u32) cur_addr; in mpc52xx_ata_build_dmatable()
476 bd->dst_pa = (__force u32) priv->ata_regs_pa + in mpc52xx_ata_build_dmatable()
480 bcom_submit_next_buffer(priv->dmatsk, NULL); in mpc52xx_ata_build_dmatable()
483 cur_len -= tc; in mpc52xx_ata_build_dmatable()
487 dev_alert(ap->dev, "dma table" in mpc52xx_ata_build_dmatable()
496 bcom_ata_reset_bd(priv->dmatsk); in mpc52xx_ata_build_dmatable()
503 struct ata_port *ap = qc->ap; in mpc52xx_bmdma_setup()
504 struct mpc52xx_ata_priv *priv = ap->host->private_data; in mpc52xx_bmdma_setup()
505 struct mpc52xx_ata __iomem *regs = priv->ata_regs; in mpc52xx_bmdma_setup()
507 unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE); in mpc52xx_bmdma_setup()
511 dev_alert(ap->dev, "%s: %i, return 1?\n", in mpc52xx_bmdma_setup()
515 if (in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR) in mpc52xx_bmdma_setup()
516 dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n", in mpc52xx_bmdma_setup()
517 __func__, in_8(&priv->ata_regs->fifo_status)); in mpc52xx_bmdma_setup()
524 if (priv->mpc52xx_ata_dma_last_write != 0) { in mpc52xx_bmdma_setup()
525 priv->mpc52xx_ata_dma_last_write = 0; in mpc52xx_bmdma_setup()
528 out_8(&regs->fifo_control, 7); in mpc52xx_bmdma_setup()
529 out_be16(&regs->fifo_alarm, 128); in mpc52xx_bmdma_setup()
532 out_8(&regs->dma_mode, MPC52xx_ATA_DMAMODE_FR); in mpc52xx_bmdma_setup()
538 if (priv->mpc52xx_ata_dma_last_write != 1) { in mpc52xx_bmdma_setup()
539 priv->mpc52xx_ata_dma_last_write = 1; in mpc52xx_bmdma_setup()
542 out_8(&regs->fifo_control, 4); in mpc52xx_bmdma_setup()
543 out_be16(&regs->fifo_alarm, 128); in mpc52xx_bmdma_setup()
547 if (priv->timings[qc->dev->devno].using_udma) in mpc52xx_bmdma_setup()
550 out_8(&regs->dma_mode, dma_mode); in mpc52xx_bmdma_setup()
551 priv->waiting_for_dma = ATA_DMA_ACTIVE; in mpc52xx_bmdma_setup()
554 ap->ops->sff_exec_command(ap, &qc->tf); in mpc52xx_bmdma_setup()
560 struct ata_port *ap = qc->ap; in mpc52xx_bmdma_start()
561 struct mpc52xx_ata_priv *priv = ap->host->private_data; in mpc52xx_bmdma_start()
563 bcom_set_task_auto_start(priv->dmatsk->tasknum, priv->dmatsk->tasknum); in mpc52xx_bmdma_start()
564 bcom_enable(priv->dmatsk); in mpc52xx_bmdma_start()
570 struct ata_port *ap = qc->ap; in mpc52xx_bmdma_stop()
571 struct mpc52xx_ata_priv *priv = ap->host->private_data; in mpc52xx_bmdma_stop()
573 bcom_disable(priv->dmatsk); in mpc52xx_bmdma_stop()
574 bcom_ata_reset_bd(priv->dmatsk); in mpc52xx_bmdma_stop()
575 priv->waiting_for_dma = 0; in mpc52xx_bmdma_stop()
578 if (in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR) in mpc52xx_bmdma_stop()
579 dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n", in mpc52xx_bmdma_stop()
580 __func__, in_8(&priv->ata_regs->fifo_status)); in mpc52xx_bmdma_stop()
586 struct mpc52xx_ata_priv *priv = ap->host->private_data; in mpc52xx_bmdma_status()
589 if (in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR) { in mpc52xx_bmdma_status()
590 dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n", in mpc52xx_bmdma_status()
591 __func__, in_8(&priv->ata_regs->fifo_status)); in mpc52xx_bmdma_status()
592 return priv->waiting_for_dma | ATA_DMA_ERR; in mpc52xx_bmdma_status()
595 return priv->waiting_for_dma; in mpc52xx_bmdma_status()
602 while (bcom_buffer_done(priv->dmatsk)) in mpc52xx_ata_task_irq()
603 bcom_retrieve_buffer(priv->dmatsk, NULL, NULL); in mpc52xx_ata_task_irq()
605 priv->waiting_for_dma |= ATA_DMA_INTR; in mpc52xx_ata_task_irq()
636 return -ENOMEM; in mpc52xx_ata_init_one()
638 ap = host->ports[0]; in mpc52xx_ata_init_one()
639 ap->flags |= ATA_FLAG_SLAVE_POSS; in mpc52xx_ata_init_one()
640 ap->pio_mask = ATA_PIO4; in mpc52xx_ata_init_one()
641 ap->mwdma_mask = mwdma_mask; in mpc52xx_ata_init_one()
642 ap->udma_mask = udma_mask; in mpc52xx_ata_init_one()
643 ap->ops = &mpc52xx_ata_port_ops; in mpc52xx_ata_init_one()
644 host->private_data = priv; in mpc52xx_ata_init_one()
646 aio = &ap->ioaddr; in mpc52xx_ata_init_one()
647 aio->cmd_addr = NULL; /* Don't have a classic reg block */ in mpc52xx_ata_init_one()
648 aio->altstatus_addr = &priv->ata_regs->tf_control; in mpc52xx_ata_init_one()
649 aio->ctl_addr = &priv->ata_regs->tf_control; in mpc52xx_ata_init_one()
650 aio->data_addr = &priv->ata_regs->tf_data; in mpc52xx_ata_init_one()
651 aio->error_addr = &priv->ata_regs->tf_features; in mpc52xx_ata_init_one()
652 aio->feature_addr = &priv->ata_regs->tf_features; in mpc52xx_ata_init_one()
653 aio->nsect_addr = &priv->ata_regs->tf_sec_count; in mpc52xx_ata_init_one()
654 aio->lbal_addr = &priv->ata_regs->tf_sec_num; in mpc52xx_ata_init_one()
655 aio->lbam_addr = &priv->ata_regs->tf_cyl_low; in mpc52xx_ata_init_one()
656 aio->lbah_addr = &priv->ata_regs->tf_cyl_high; in mpc52xx_ata_init_one()
657 aio->device_addr = &priv->ata_regs->tf_dev_head; in mpc52xx_ata_init_one()
658 aio->status_addr = &priv->ata_regs->tf_command; in mpc52xx_ata_init_one()
659 aio->command_addr = &priv->ata_regs->tf_command; in mpc52xx_ata_init_one()
664 return ata_host_activate(host, priv->ata_irq, ata_bmdma_interrupt, 0, in mpc52xx_ata_init_one()
686 ipb_freq = mpc5xxx_get_bus_frequency(&op->dev); in mpc52xx_ata_probe()
688 dev_err(&op->dev, "could not determine IPB bus frequency\n"); in mpc52xx_ata_probe()
689 return -ENODEV; in mpc52xx_ata_probe()
694 rv = of_address_to_resource(op->dev.of_node, 0, &res_mem); in mpc52xx_ata_probe()
696 dev_err(&op->dev, "could not determine device base address\n"); in mpc52xx_ata_probe()
700 if (!devm_request_mem_region(&op->dev, res_mem.start, in mpc52xx_ata_probe()
702 dev_err(&op->dev, "error requesting register region\n"); in mpc52xx_ata_probe()
703 return -EBUSY; in mpc52xx_ata_probe()
706 ata_regs = devm_ioremap(&op->dev, res_mem.start, sizeof(*ata_regs)); in mpc52xx_ata_probe()
708 dev_err(&op->dev, "error mapping device registers\n"); in mpc52xx_ata_probe()
709 return -ENOMEM; in mpc52xx_ata_probe()
716 * with UDMA if it is used at the same time as the LocalPlus bus. in mpc52xx_ata_probe()
720 * UDMA/MWDMA modes can also be forced by adding "libata.force=<mode>" in mpc52xx_ata_probe()
724 * UDMA modes 0, 1 and 2. in mpc52xx_ata_probe()
726 prop = of_get_property(op->dev.of_node, "mwdma-mode", &proplen); in mpc52xx_ata_probe()
728 mwdma_mask = ATA_MWDMA2 & ((1 << (*prop + 1)) - 1); in mpc52xx_ata_probe()
729 prop = of_get_property(op->dev.of_node, "udma-mode", &proplen); in mpc52xx_ata_probe()
731 udma_mask = ATA_UDMA2 & ((1 << (*prop + 1)) - 1); in mpc52xx_ata_probe()
733 ata_irq = irq_of_parse_and_map(op->dev.of_node, 0); in mpc52xx_ata_probe()
735 dev_err(&op->dev, "error mapping irq\n"); in mpc52xx_ata_probe()
736 return -EINVAL; in mpc52xx_ata_probe()
740 priv = devm_kzalloc(&op->dev, sizeof(*priv), GFP_KERNEL); in mpc52xx_ata_probe()
742 rv = -ENOMEM; in mpc52xx_ata_probe()
746 priv->ipb_period = 1000000000 / (ipb_freq / 1000); in mpc52xx_ata_probe()
747 priv->ata_regs = ata_regs; in mpc52xx_ata_probe()
748 priv->ata_regs_pa = res_mem.start; in mpc52xx_ata_probe()
749 priv->ata_irq = ata_irq; in mpc52xx_ata_probe()
750 priv->csel = -1; in mpc52xx_ata_probe()
751 priv->mpc52xx_ata_dma_last_write = -1; in mpc52xx_ata_probe()
754 priv->mdmaspec = mdmaspec66; in mpc52xx_ata_probe()
755 priv->udmaspec = udmaspec66; in mpc52xx_ata_probe()
757 priv->mdmaspec = mdmaspec132; in mpc52xx_ata_probe()
758 priv->udmaspec = udmaspec132; in mpc52xx_ata_probe()
764 dev_err(&op->dev, "bestcomm initialization failed\n"); in mpc52xx_ata_probe()
765 rv = -ENOMEM; in mpc52xx_ata_probe()
770 rv = devm_request_irq(&op->dev, task_irq, &mpc52xx_ata_task_irq, 0, in mpc52xx_ata_probe()
773 dev_err(&op->dev, "error requesting DMA IRQ\n"); in mpc52xx_ata_probe()
776 priv->dmatsk = dmatsk; in mpc52xx_ata_probe()
781 dev_err(&op->dev, "error initializing hardware\n"); in mpc52xx_ata_probe()
786 rv = mpc52xx_ata_init_one(&op->dev, priv, res_mem.start, in mpc52xx_ata_probe()
789 dev_err(&op->dev, "error registering with ATA layer\n"); in mpc52xx_ata_probe()
806 struct mpc52xx_ata_priv *priv = host->private_data; in mpc52xx_ata_remove()
813 task_irq = bcom_get_task_irq(priv->dmatsk); in mpc52xx_ata_remove()
815 bcom_ata_release(priv->dmatsk); in mpc52xx_ata_remove()
816 irq_dispose_mapping(priv->ata_irq); in mpc52xx_ata_remove()
833 struct mpc52xx_ata_priv *priv = host->private_data; in mpc52xx_ata_resume()
838 dev_err(host->dev, "error initializing hardware\n"); in mpc52xx_ata_resume()
849 { .compatible = "fsl,mpc5200-ata", },
850 { .compatible = "mpc5200-ata", },