diff options
author | Mark Lord <mlord@pobox.com> | 2009-02-25 15:14:48 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2009-03-24 22:02:40 -0400 |
commit | c01e8a23128c746f23088db836bd4c820f3eb0b4 (patch) | |
tree | 952ccc19acb1f88c29e95c0a297e7e4fe944fe13 /drivers/ata/sata_mv.c | |
parent | 08da175937a35d34a83eaefbb3458472eb1a89d4 (diff) |
[libata] sata_mv: Enable use of (basic) DMA for ATAPI on GEN_IIE chips
This also gets rid of any need for mv_mode_filter().
Using basic DMA on GEN_IIE requires setting an undocumented
bit in an undocumented register. For safety, we clear that
bit again when switching back to EDMA mode.
To avoid a performance penalty when switching modes,
we cache the register in port_priv, as already done for other regs.
Signed-off-by: Mark Lord <mlord@pobox.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r-- | drivers/ata/sata_mv.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 146b8e67c44f..3bfe721ba766 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -345,7 +345,7 @@ enum { | |||
345 | EDMA_ARB_CFG_OFS = 0x38, | 345 | EDMA_ARB_CFG_OFS = 0x38, |
346 | 346 | ||
347 | EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */ | 347 | EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */ |
348 | 348 | EDMA_UNKNOWN_RSVD_OFS = 0x6C, /* GenIIe unknown/reserved */ | |
349 | 349 | ||
350 | BMDMA_CMD_OFS = 0x224, /* bmdma command register */ | 350 | BMDMA_CMD_OFS = 0x224, /* bmdma command register */ |
351 | BMDMA_STATUS_OFS = 0x228, /* bmdma status register */ | 351 | BMDMA_STATUS_OFS = 0x228, /* bmdma status register */ |
@@ -447,6 +447,7 @@ struct mv_cached_regs { | |||
447 | u32 fiscfg; | 447 | u32 fiscfg; |
448 | u32 ltmode; | 448 | u32 ltmode; |
449 | u32 haltcond; | 449 | u32 haltcond; |
450 | u32 unknown_rsvd; | ||
450 | }; | 451 | }; |
451 | 452 | ||
452 | struct mv_port_priv { | 453 | struct mv_port_priv { |
@@ -563,8 +564,6 @@ static void mv_pmp_error_handler(struct ata_port *ap); | |||
563 | static void mv_process_crpb_entries(struct ata_port *ap, | 564 | static void mv_process_crpb_entries(struct ata_port *ap, |
564 | struct mv_port_priv *pp); | 565 | struct mv_port_priv *pp); |
565 | 566 | ||
566 | static unsigned long mv_mode_filter(struct ata_device *dev, | ||
567 | unsigned long xfer_mask); | ||
568 | static void mv_sff_irq_clear(struct ata_port *ap); | 567 | static void mv_sff_irq_clear(struct ata_port *ap); |
569 | static int mv_check_atapi_dma(struct ata_queued_cmd *qc); | 568 | static int mv_check_atapi_dma(struct ata_queued_cmd *qc); |
570 | static void mv_bmdma_setup(struct ata_queued_cmd *qc); | 569 | static void mv_bmdma_setup(struct ata_queued_cmd *qc); |
@@ -626,7 +625,6 @@ static struct ata_port_operations mv6_ops = { | |||
626 | .bmdma_start = mv_bmdma_start, | 625 | .bmdma_start = mv_bmdma_start, |
627 | .bmdma_stop = mv_bmdma_stop, | 626 | .bmdma_stop = mv_bmdma_stop, |
628 | .bmdma_status = mv_bmdma_status, | 627 | .bmdma_status = mv_bmdma_status, |
629 | .mode_filter = mv_mode_filter, | ||
630 | }; | 628 | }; |
631 | 629 | ||
632 | static struct ata_port_operations mv_iie_ops = { | 630 | static struct ata_port_operations mv_iie_ops = { |
@@ -842,6 +840,7 @@ static void mv_save_cached_regs(struct ata_port *ap) | |||
842 | pp->cached.fiscfg = readl(port_mmio + FISCFG_OFS); | 840 | pp->cached.fiscfg = readl(port_mmio + FISCFG_OFS); |
843 | pp->cached.ltmode = readl(port_mmio + LTMODE_OFS); | 841 | pp->cached.ltmode = readl(port_mmio + LTMODE_OFS); |
844 | pp->cached.haltcond = readl(port_mmio + EDMA_HALTCOND_OFS); | 842 | pp->cached.haltcond = readl(port_mmio + EDMA_HALTCOND_OFS); |
843 | pp->cached.unknown_rsvd = readl(port_mmio + EDMA_UNKNOWN_RSVD_OFS); | ||
845 | } | 844 | } |
846 | 845 | ||
847 | /** | 846 | /** |
@@ -1252,6 +1251,30 @@ static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq) | |||
1252 | writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS); | 1251 | writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS); |
1253 | } | 1252 | } |
1254 | 1253 | ||
1254 | /** | ||
1255 | * mv_bmdma_enable - set a magic bit on GEN_IIE to allow bmdma | ||
1256 | * @ap: Port being initialized | ||
1257 | * | ||
1258 | * There are two DMA modes on these chips: basic DMA, and EDMA. | ||
1259 | * | ||
1260 | * Bit-0 of the "EDMA RESERVED" register enables/disables use | ||
1261 | * of basic DMA on the GEN_IIE versions of the chips. | ||
1262 | * | ||
1263 | * This bit survives EDMA resets, and must be set for basic DMA | ||
1264 | * to function, and should be cleared when EDMA is active. | ||
1265 | */ | ||
1266 | static void mv_bmdma_enable_iie(struct ata_port *ap, int enable_bmdma) | ||
1267 | { | ||
1268 | struct mv_port_priv *pp = ap->private_data; | ||
1269 | u32 new, *old = &pp->cached.unknown_rsvd; | ||
1270 | |||
1271 | if (enable_bmdma) | ||
1272 | new = *old | 1; | ||
1273 | else | ||
1274 | new = *old & ~1; | ||
1275 | mv_write_cached_reg(mv_ap_base(ap) + EDMA_UNKNOWN_RSVD_OFS, old, new); | ||
1276 | } | ||
1277 | |||
1255 | static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma) | 1278 | static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma) |
1256 | { | 1279 | { |
1257 | u32 cfg; | 1280 | u32 cfg; |
@@ -1297,6 +1320,7 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma) | |||
1297 | } | 1320 | } |
1298 | if (hpriv->hp_flags & MV_HP_CUT_THROUGH) | 1321 | if (hpriv->hp_flags & MV_HP_CUT_THROUGH) |
1299 | cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */ | 1322 | cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */ |
1323 | mv_bmdma_enable_iie(ap, !want_edma); | ||
1300 | } | 1324 | } |
1301 | 1325 | ||
1302 | if (want_ncq) { | 1326 | if (want_ncq) { |
@@ -1465,26 +1489,6 @@ static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last) | |||
1465 | } | 1489 | } |
1466 | 1490 | ||
1467 | /** | 1491 | /** |
1468 | * mv_mode_filter - Allow ATAPI DMA only on GenII chips. | ||
1469 | * @dev: device whose xfer modes are being configured. | ||
1470 | * | ||
1471 | * Only the GenII hardware can use DMA with ATAPI drives. | ||
1472 | */ | ||
1473 | static unsigned long mv_mode_filter(struct ata_device *adev, | ||
1474 | unsigned long xfer_mask) | ||
1475 | { | ||
1476 | if (adev->class == ATA_DEV_ATAPI) { | ||
1477 | struct mv_host_priv *hpriv = adev->link->ap->host->private_data; | ||
1478 | if (!IS_GEN_II(hpriv)) { | ||
1479 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); | ||
1480 | ata_dev_printk(adev, KERN_INFO, | ||
1481 | "ATAPI DMA not supported on this chipset\n"); | ||
1482 | } | ||
1483 | } | ||
1484 | return xfer_mask; | ||
1485 | } | ||
1486 | |||
1487 | /** | ||
1488 | * mv_sff_irq_clear - Clear hardware interrupt after DMA. | 1492 | * mv_sff_irq_clear - Clear hardware interrupt after DMA. |
1489 | * @ap: Port associated with this ATA transaction. | 1493 | * @ap: Port associated with this ATA transaction. |
1490 | * | 1494 | * |