aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Lord <liml@rtr.ca>2008-05-02 02:08:32 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-06 11:37:38 -0400
commit616d4a98ad8749ebe17a8fcac67df65c321350ac (patch)
treeb7b94f059367586ad8bef1bc8db9a536a898f337
parent8e7decdb8b132ee970a2636931b7653dec6af472 (diff)
sata_mv pci features
Some of the GenIIe EDMA optimizations should not be used for non-PCI (SOC) devices, and nor for certain configurations of conventional PCI (non PCI-X, PCIe) buses. Logic taken/simplified from that in the Marvell proprietary driver. Signed-off-by: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--drivers/ata/sata_mv.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 4eabb737a48d..10ef9683f048 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -361,6 +361,7 @@ enum {
361 MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */ 361 MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */
362 MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */ 362 MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */
363 MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */ 363 MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */
364 MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */
364 365
365 /* Port private flags (pp_flags) */ 366 /* Port private flags (pp_flags) */
366 MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */ 367 MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */
@@ -1110,8 +1111,10 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
1110 else if (IS_GEN_IIE(hpriv)) { 1111 else if (IS_GEN_IIE(hpriv)) {
1111 cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ 1112 cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */
1112 cfg |= (1 << 22); /* enab 4-entry host queue cache */ 1113 cfg |= (1 << 22); /* enab 4-entry host queue cache */
1113 cfg |= (1 << 18); /* enab early completion */ 1114 if (HAS_PCI(ap->host))
1114 cfg |= (1 << 17); /* enab cut-through (dis stor&forwrd) */ 1115 cfg |= (1 << 18); /* enab early completion */
1116 if (hpriv->hp_flags & MV_HP_CUT_THROUGH)
1117 cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */
1115 1118
1116 if (want_ncq && sata_pmp_attached(ap)) { 1119 if (want_ncq && sata_pmp_attached(ap)) {
1117 cfg |= EDMA_CFG_EDMA_FBS; /* FIS-based switching */ 1120 cfg |= EDMA_CFG_EDMA_FBS; /* FIS-based switching */
@@ -2496,6 +2499,34 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
2496 readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS)); 2499 readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS));
2497} 2500}
2498 2501
2502static unsigned int mv_in_pcix_mode(struct ata_host *host)
2503{
2504 struct mv_host_priv *hpriv = host->private_data;
2505 void __iomem *mmio = hpriv->base;
2506 u32 reg;
2507
2508 if (!HAS_PCI(host) || !IS_PCIE(hpriv))
2509 return 0; /* not PCI-X capable */
2510 reg = readl(mmio + MV_PCI_MODE_OFS);
2511 if ((reg & MV_PCI_MODE_MASK) == 0)
2512 return 0; /* conventional PCI mode */
2513 return 1; /* chip is in PCI-X mode */
2514}
2515
2516static int mv_pci_cut_through_okay(struct ata_host *host)
2517{
2518 struct mv_host_priv *hpriv = host->private_data;
2519 void __iomem *mmio = hpriv->base;
2520 u32 reg;
2521
2522 if (!mv_in_pcix_mode(host)) {
2523 reg = readl(mmio + PCI_COMMAND_OFS);
2524 if (reg & PCI_COMMAND_MRDTRIG)
2525 return 0; /* not okay */
2526 }
2527 return 1; /* okay */
2528}
2529
2499static int mv_chip_id(struct ata_host *host, unsigned int board_idx) 2530static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
2500{ 2531{
2501 struct pci_dev *pdev = to_pci_dev(host->dev); 2532 struct pci_dev *pdev = to_pci_dev(host->dev);
@@ -2563,7 +2594,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
2563 break; 2594 break;
2564 2595
2565 case chip_7042: 2596 case chip_7042:
2566 hp_flags |= MV_HP_PCIE; 2597 hp_flags |= MV_HP_PCIE | MV_HP_CUT_THROUGH;
2567 if (pdev->vendor == PCI_VENDOR_ID_TTI && 2598 if (pdev->vendor == PCI_VENDOR_ID_TTI &&
2568 (pdev->device == 0x2300 || pdev->device == 0x2310)) 2599 (pdev->device == 0x2300 || pdev->device == 0x2310))
2569 { 2600 {
@@ -2597,6 +2628,8 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
2597 case chip_6042: 2628 case chip_6042:
2598 hpriv->ops = &mv6xxx_ops; 2629 hpriv->ops = &mv6xxx_ops;
2599 hp_flags |= MV_HP_GEN_IIE; 2630 hp_flags |= MV_HP_GEN_IIE;
2631 if (board_idx == chip_6042 && mv_pci_cut_through_okay(host))
2632 hp_flags |= MV_HP_CUT_THROUGH;
2600 2633
2601 switch (pdev->revision) { 2634 switch (pdev->revision) {
2602 case 0x0: 2635 case 0x0: