aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_dwc_460ex.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/sata_dwc_460ex.c')
-rwxr-xr-x[-rw-r--r--]drivers/ata/sata_dwc_460ex.c72
1 files changed, 54 insertions, 18 deletions
diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
index 69f7cde49c6b..937aeb34b310 100644..100755
--- a/drivers/ata/sata_dwc_460ex.c
+++ b/drivers/ata/sata_dwc_460ex.c
@@ -158,6 +158,7 @@ enum {
158/* Assign HW handshaking interface (x) to destination / source peripheral */ 158/* Assign HW handshaking interface (x) to destination / source peripheral */
159#define DMA_CFG_HW_HS_DEST(int_num) (((int_num) & 0xF) << 11) 159#define DMA_CFG_HW_HS_DEST(int_num) (((int_num) & 0xF) << 11)
160#define DMA_CFG_HW_HS_SRC(int_num) (((int_num) & 0xF) << 7) 160#define DMA_CFG_HW_HS_SRC(int_num) (((int_num) & 0xF) << 7)
161#define DMA_CFG_HW_CH_PRIOR(int_num) (((int_num) & 0xF) << 5)
161#define DMA_LLP_LMS(addr, master) (((addr) & 0xfffffffc) | (master)) 162#define DMA_LLP_LMS(addr, master) (((addr) & 0xfffffffc) | (master))
162 163
163/* 164/*
@@ -318,6 +319,7 @@ struct sata_dwc_host_priv {
318 u32 dma_interrupt_count; 319 u32 dma_interrupt_count;
319 struct ahb_dma_regs *sata_dma_regs; 320 struct ahb_dma_regs *sata_dma_regs;
320 struct device *dwc_dev; 321 struct device *dwc_dev;
322 int dma_channel;
321}; 323};
322struct sata_dwc_host_priv host_pvt; 324struct sata_dwc_host_priv host_pvt;
323/* 325/*
@@ -437,15 +439,12 @@ static void clear_chan_interrupts(int c)
437 */ 439 */
438static int dma_request_channel(void) 440static int dma_request_channel(void)
439{ 441{
440 int i; 442 /* Check if the channel is not currently in use */
441 443 if (!(in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low)) &
442 for (i = 0; i < DMA_NUM_CHANS; i++) { 444 DMA_CHANNEL(host_pvt.dma_channel)))
443 if (!(in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low)) &\ 445 return host_pvt.dma_channel;
444 DMA_CHANNEL(i))) 446 dev_err(host_pvt.dwc_dev, "%s Channel %d is currently in use\n",
445 return i; 447 __func__, host_pvt.dma_channel);
446 }
447 dev_err(host_pvt.dwc_dev, "%s NO channel chan_en: 0x%08x\n", __func__,
448 in_le32(&(host_pvt.sata_dma_regs->dma_chan_en.low)));
449 return -1; 448 return -1;
450} 449}
451 450
@@ -481,7 +480,8 @@ static irqreturn_t dma_dwc_interrupt(int irq, void *hsdev_instance)
481 dev_dbg(ap->dev, "eot=0x%08x err=0x%08x pending=%d active port=%d\n", 480 dev_dbg(ap->dev, "eot=0x%08x err=0x%08x pending=%d active port=%d\n",
482 tfr_reg, err_reg, hsdevp->dma_pending[tag], port); 481 tfr_reg, err_reg, hsdevp->dma_pending[tag], port);
584 (u32)dmadr_addr);
@@ -635,8 +638,8 @@ static int map_sg_to_lli(struct scatterlist *sg, int num_elems,
635 638
636 lli[idx].ctl.low = cpu_to_le32( 639 lli[idx].ctl.low = cpu_to_le32(
637 DMA_CTL_TTFC(DMA_CTL_TTFC_P2M_DMAC) | 640 DMA_CTL_TTFC(DMA_CTL_TTFC_P2M_DMAC) |
638 DMA_CTL_SMS(0) | 641 DMA_CTL_SMS(sms_val) |
639 DMA_CTL_DMS(1) | 642 DMA_CTL_DMS(dms_val) |
640 DMA_CTL_SRC_MSIZE(bl) | 643 DMA_CTL_SRC_MSIZE(bl) |
641 DMA_CTL_DST_MSIZE(bl) | 644 DMA_CTL_DST_MSIZE(bl) |
642 DMA_CTL_SINC_NOCHANGE | 645 DMA_CTL_SINC_NOCHANGE |
@@ -651,8 +654,8 @@ static int map_sg_to_lli(struct scatterlist *sg, int num_elems,
651 654
652 lli[idx].ctl.low = cpu_to_le32( 655 lli[idx].ctl.low = cpu_to_le32(
653 DMA_CTL_TTFC(DMA_CTL_TTFC_M2P_PER) | 656 DMA_CTL_TTFC(DMA_CTL_TTFC_M2P_PER) |
654 DMA_CTL_SMS(1) | 657 DMA_CTL_SMS(dms_val) |
655 DMA_CTL_DMS(0) | 658 DMA_CTL_DMS(sms_val) |
656 DMA_CTL_SRC_MSIZE(bl) | 659 DMA_CTL_SRC_MSIZE(bl) |
657 DMA_CTL_DST_MSIZE(bl) | 660 DMA_CTL_DST_MSIZE(bl) |
658 DMA_CTL_DINC_NOCHANGE | 661 DMA_CTL_DINC_NOCHANGE |
@@ -744,8 +747,10 @@ static int dma_dwc_xfer_setup(struct scatterlist *sg, int num_elems,
744 747
745 /* Program the CFG register. */ 748 /* Program the CFG register. */
746 out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].cfg.high), 749 out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].cfg.high),
750 DMA_CFG_HW_HS_SRC(dma_ch) | DMA_CFG_HW_HS_DEST(dma_ch) |
747 DMA_CFG_PROTCTL | DMA_CFG_FCMOD_REQ); 751 DMA_CFG_PROTCTL | DMA_CFG_FCMOD_REQ);
748 out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].cfg.low), 0); 752 out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].cfg.low),
753 DMA_CFG_HW_CH_PRIOR(dma_ch));
749 754
750 /* Program the address of the linked list */ 755 /* Program the address of the linked list */
751 out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].llp.low), 756 out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].llp.low),
@@ -1581,10 +1586,31 @@ static void sata_dwc_qc_prep(struct ata_queued_cmd *qc)
1581 1586
1582static void sata_dwc_error_handler(struct ata_port *ap) 1587static void sata_dwc_error_handler(struct ata_port *ap)
1583{ 1588{
1584 ap->link.flags |= ATA_LFLAG_NO_HRST;
1585 ata_sff_error_handler(ap); 1589 ata_sff_error_handler(ap);
1586} 1590}
1587 1591
1592int sata_dwc_hardreset(struct ata_link *link, unsigned int *class,
1593 unsigned long deadline)
1594{
1595 struct sata_dwc_device *hsdev = HSDEV_FROM_AP(link->ap);
1596 int ret;
1597
1598 ret = sata_sff_hardreset(link, class, deadline);
1599
1600 sata_dwc_enable_interrupts(hsdev);
1601
1602 /* Reconfigure the DMA control register */
1603 out_le32(&hsdev->sata_dwc_regs->dmacr,
1604 SATA_DWC_DMACR_TXRXCH_CLEAR);
1605
1606 /* Reconfigure the DMA Burst Transaction Size register */
1607 out_le32(&hsdev->sata_dwc_regs->dbtsr,
1608 SATA_DWC_DBTSR_MWR(AHB_DMA_BRST_DFLT) |
1609 SATA_DWC_DBTSR_MRD(AHB_DMA_BRST_DFLT));
1610
1611 return ret;
1612}
1613
1588/* 1614/*
1589 * scsi mid-layer and libata interface structures 1615 * scsi mid-layer and libata interface structures
1590 */ 1616 */
@@ -1604,6 +1630,7 @@ static struct ata_port_operations sata_dwc_ops = {
1604 .inherits = &ata_sff_port_ops, 1630 .inherits = &ata_sff_port_ops,
1605 1631
1606 .error_handler = sata_dwc_error_handler, 1632 .error_handler = sata_dwc_error_handler,
1633 .hardreset = sata_dwc_hardreset,
1607 1634
1608 .qc_prep = sata_dwc_qc_prep, 1635 .qc_prep = sata_dwc_qc_prep,
1609 .qc_issue = sata_dwc_qc_issue, 1636 .qc_issue = sata_dwc_qc_issue,
@@ -1638,6 +1665,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)
1638 struct ata_host *host; 1665 struct ata_host *host;
1639 struct ata_port_info pi = sata_dwc_port_info[0]; 1666 struct ata_port_info pi = sata_dwc_port_info[0];
1640 const struct ata_port_info *ppi[] = { &pi, NULL }; 1667 const struct ata_port_info *ppi[] = { &pi, NULL };
1668 struct device_node *np = ofdev->dev.of_node;
1669 u32 dma_chan;
1641 1670
1642 /* Allocate DWC SATA device */ 1671 /* Allocate DWC SATA device */
1643 hsdev = kzalloc(sizeof(*hsdev), GFP_KERNEL); 1672 hsdev = kzalloc(sizeof(*hsdev), GFP_KERNEL);
@@ -1647,6 +1676,13 @@ static int sata_dwc_probe(struct platform_device *ofdev)
1647 goto error; 1676 goto error;
1648 } 1677 }
1649 1678
1679 if (of_property_read_u32(np, "dma-channel", &dma_chan)) {
1680 dev_warn(&ofdev->dev, "no dma-channel property set."
1681 " Use channel 0\n");
1682 dma_chan = 0;
1683 }
1684 host_pvt.dma_channel = dma_chan;
1685
1650 /* Ioremap SATA registers */ 1686 /* Ioremap SATA registers */
1651 base = of_iomap(ofdev->dev.of_node, 0); 1687 base = of_iomap(ofdev->dev.of_node, 0);
1652 if (!base) { 1688 if (!base) {