diff options
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r-- | drivers/ata/sata_mv.c | 101 |
1 files changed, 49 insertions, 52 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index fb81f0c7a8c2..60391e9a84db 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -72,7 +72,7 @@ | |||
72 | #include <linux/libata.h> | 72 | #include <linux/libata.h> |
73 | 73 | ||
74 | #define DRV_NAME "sata_mv" | 74 | #define DRV_NAME "sata_mv" |
75 | #define DRV_VERSION "1.21" | 75 | #define DRV_VERSION "1.24" |
76 | 76 | ||
77 | enum { | 77 | enum { |
78 | /* BAR's are enumerated in terms of pci_resource_start() terms */ | 78 | /* BAR's are enumerated in terms of pci_resource_start() terms */ |
@@ -122,8 +122,6 @@ enum { | |||
122 | /* Host Flags */ | 122 | /* Host Flags */ |
123 | MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ | 123 | MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ |
124 | MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ | 124 | MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ |
125 | /* SoC integrated controllers, no PCI interface */ | ||
126 | MV_FLAG_SOC = (1 << 28), | ||
127 | 125 | ||
128 | MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 126 | MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
129 | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | | 127 | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | |
@@ -226,6 +224,11 @@ enum { | |||
226 | 224 | ||
227 | PHY_MODE3 = 0x310, | 225 | PHY_MODE3 = 0x310, |
228 | PHY_MODE4 = 0x314, | 226 | PHY_MODE4 = 0x314, |
227 | PHY_MODE4_CFG_MASK = 0x00000003, /* phy internal config field */ | ||
228 | PHY_MODE4_CFG_VALUE = 0x00000001, /* phy internal config field */ | ||
229 | PHY_MODE4_RSVD_ZEROS = 0x5de3fffa, /* Gen2e always write zeros */ | ||
230 | PHY_MODE4_RSVD_ONES = 0x00000005, /* Gen2e always write ones */ | ||
231 | |||
229 | PHY_MODE2 = 0x330, | 232 | PHY_MODE2 = 0x330, |
230 | SATA_IFCTL_OFS = 0x344, | 233 | SATA_IFCTL_OFS = 0x344, |
231 | SATA_TESTCTL_OFS = 0x348, | 234 | SATA_TESTCTL_OFS = 0x348, |
@@ -356,12 +359,12 @@ enum { | |||
356 | MV_HP_ERRATA_50XXB2 = (1 << 2), | 359 | MV_HP_ERRATA_50XXB2 = (1 << 2), |
357 | MV_HP_ERRATA_60X1B2 = (1 << 3), | 360 | MV_HP_ERRATA_60X1B2 = (1 << 3), |
358 | MV_HP_ERRATA_60X1C0 = (1 << 4), | 361 | MV_HP_ERRATA_60X1C0 = (1 << 4), |
359 | MV_HP_ERRATA_XX42A0 = (1 << 5), | ||
360 | MV_HP_GEN_I = (1 << 6), /* Generation I: 50xx */ | 362 | MV_HP_GEN_I = (1 << 6), /* Generation I: 50xx */ |
361 | MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */ | 363 | MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */ |
362 | MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */ | 364 | MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */ |
363 | MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */ | 365 | MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */ |
364 | MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */ | 366 | MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */ |
367 | MV_HP_FLAG_SOC = (1 << 11), /* SystemOnChip, no PCI */ | ||
365 | 368 | ||
366 | /* Port private flags (pp_flags) */ | 369 | /* Port private flags (pp_flags) */ |
367 | MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */ | 370 | MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */ |
@@ -374,7 +377,7 @@ enum { | |||
374 | #define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II) | 377 | #define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II) |
375 | #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) | 378 | #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) |
376 | #define IS_PCIE(hpriv) ((hpriv)->hp_flags & MV_HP_PCIE) | 379 | #define IS_PCIE(hpriv) ((hpriv)->hp_flags & MV_HP_PCIE) |
377 | #define HAS_PCI(host) (!((host)->ports[0]->flags & MV_FLAG_SOC)) | 380 | #define IS_SOC(hpriv) ((hpriv)->hp_flags & MV_HP_FLAG_SOC) |
378 | 381 | ||
379 | #define WINDOW_CTRL(i) (0x20030 + ((i) << 4)) | 382 | #define WINDOW_CTRL(i) (0x20030 + ((i) << 4)) |
380 | #define WINDOW_BASE(i) (0x20034 + ((i) << 4)) | 383 | #define WINDOW_BASE(i) (0x20034 + ((i) << 4)) |
@@ -652,7 +655,7 @@ static const struct ata_port_info mv_port_info[] = { | |||
652 | .port_ops = &mv_iie_ops, | 655 | .port_ops = &mv_iie_ops, |
653 | }, | 656 | }, |
654 | { /* chip_soc */ | 657 | { /* chip_soc */ |
655 | .flags = MV_GENIIE_FLAGS | MV_FLAG_SOC, | 658 | .flags = MV_GENIIE_FLAGS, |
656 | .pio_mask = 0x1f, /* pio0-4 */ | 659 | .pio_mask = 0x1f, /* pio0-4 */ |
657 | .udma_mask = ATA_UDMA6, | 660 | .udma_mask = ATA_UDMA6, |
658 | .port_ops = &mv_iie_ops, | 661 | .port_ops = &mv_iie_ops, |
@@ -812,12 +815,7 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio, | |||
812 | writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS); | 815 | writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS); |
813 | writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | index, | 816 | writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | index, |
814 | port_mmio + EDMA_REQ_Q_IN_PTR_OFS); | 817 | port_mmio + EDMA_REQ_Q_IN_PTR_OFS); |
815 | 818 | writelfl(index, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS); | |
816 | if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0) | ||
817 | writelfl((pp->crqb_dma & 0xffffffff) | index, | ||
818 | port_mmio + EDMA_REQ_Q_OUT_PTR_OFS); | ||
819 | else | ||
820 | writelfl(index, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS); | ||
821 | 819 | ||
822 | /* | 820 | /* |
823 | * initialize response queue | 821 | * initialize response queue |
@@ -827,13 +825,7 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio, | |||
827 | 825 | ||
828 | WARN_ON(pp->crpb_dma & 0xff); | 826 | WARN_ON(pp->crpb_dma & 0xff); |
829 | writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS); | 827 | writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS); |
830 | 828 | writelfl(index, port_mmio + EDMA_RSP_Q_IN_PTR_OFS); | |
831 | if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0) | ||
832 | writelfl((pp->crpb_dma & 0xffffffff) | index, | ||
833 | port_mmio + EDMA_RSP_Q_IN_PTR_OFS); | ||
834 | else | ||
835 | writelfl(index, port_mmio + EDMA_RSP_Q_IN_PTR_OFS); | ||
836 | |||
837 | writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | index, | 829 | writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | index, |
838 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); | 830 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); |
839 | } | 831 | } |
@@ -1254,7 +1246,7 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq) | |||
1254 | 1246 | ||
1255 | cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ | 1247 | cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ |
1256 | cfg |= (1 << 22); /* enab 4-entry host queue cache */ | 1248 | cfg |= (1 << 22); /* enab 4-entry host queue cache */ |
1257 | if (HAS_PCI(ap->host)) | 1249 | if (!IS_SOC(hpriv)) |
1258 | cfg |= (1 << 18); /* enab early completion */ | 1250 | cfg |= (1 << 18); /* enab early completion */ |
1259 | if (hpriv->hp_flags & MV_HP_CUT_THROUGH) | 1251 | if (hpriv->hp_flags & MV_HP_CUT_THROUGH) |
1260 | cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */ | 1252 | cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */ |
@@ -2225,7 +2217,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) | |||
2225 | * a bogus register value which can indicate HW removal or PCI fault. | 2217 | * a bogus register value which can indicate HW removal or PCI fault. |
2226 | */ | 2218 | */ |
2227 | if (pending_irqs && main_irq_cause != 0xffffffffU) { | 2219 | if (pending_irqs && main_irq_cause != 0xffffffffU) { |
2228 | if (unlikely((pending_irqs & PCI_ERR) && HAS_PCI(host))) | 2220 | if (unlikely((pending_irqs & PCI_ERR) && !IS_SOC(hpriv))) |
2229 | handled = mv_pci_error(host, hpriv->base); | 2221 | handled = mv_pci_error(host, hpriv->base); |
2230 | else | 2222 | else |
2231 | handled = mv_host_intr(host, pending_irqs); | 2223 | handled = mv_host_intr(host, pending_irqs); |
@@ -2547,7 +2539,7 @@ static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, | |||
2547 | hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); | 2539 | hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); |
2548 | int fix_phy_mode4 = | 2540 | int fix_phy_mode4 = |
2549 | hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); | 2541 | hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); |
2550 | u32 m2, tmp; | 2542 | u32 m2, m3; |
2551 | 2543 | ||
2552 | if (fix_phy_mode2) { | 2544 | if (fix_phy_mode2) { |
2553 | m2 = readl(port_mmio + PHY_MODE2); | 2545 | m2 = readl(port_mmio + PHY_MODE2); |
@@ -2564,28 +2556,36 @@ static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, | |||
2564 | udelay(200); | 2556 | udelay(200); |
2565 | } | 2557 | } |
2566 | 2558 | ||
2567 | /* who knows what this magic does */ | 2559 | /* |
2568 | tmp = readl(port_mmio + PHY_MODE3); | 2560 | * Gen-II/IIe PHY_MODE3 errata RM#2: |
2569 | tmp &= ~0x7F800000; | 2561 | * Achieves better receiver noise performance than the h/w default: |
2570 | tmp |= 0x2A800000; | 2562 | */ |
2571 | writel(tmp, port_mmio + PHY_MODE3); | 2563 | m3 = readl(port_mmio + PHY_MODE3); |
2572 | 2564 | m3 = (m3 & 0x1f) | (0x5555601 << 5); | |
2573 | if (fix_phy_mode4) { | ||
2574 | u32 m4; | ||
2575 | |||
2576 | m4 = readl(port_mmio + PHY_MODE4); | ||
2577 | |||
2578 | if (hp_flags & MV_HP_ERRATA_60X1B2) | ||
2579 | tmp = readl(port_mmio + PHY_MODE3); | ||
2580 | 2565 | ||
2581 | /* workaround for errata FEr SATA#10 (part 1) */ | 2566 | /* Guideline 88F5182 (GL# SATA-S11) */ |
2582 | m4 = (m4 & ~(1 << 1)) | (1 << 0); | 2567 | if (IS_SOC(hpriv)) |
2568 | m3 &= ~0x1c; | ||
2583 | 2569 | ||
2570 | if (fix_phy_mode4) { | ||
2571 | u32 m4 = readl(port_mmio + PHY_MODE4); | ||
2572 | /* | ||
2573 | * Enforce reserved-bit restrictions on GenIIe devices only. | ||
2574 | * For earlier chipsets, force only the internal config field | ||
2575 | * (workaround for errata FEr SATA#10 part 1). | ||
2576 | */ | ||
2577 | if (IS_GEN_IIE(hpriv)) | ||
2578 | m4 = (m4 & ~PHY_MODE4_RSVD_ZEROS) | PHY_MODE4_RSVD_ONES; | ||
2579 | else | ||
2580 | m4 = (m4 & ~PHY_MODE4_CFG_MASK) | PHY_MODE4_CFG_VALUE; | ||
2584 | writel(m4, port_mmio + PHY_MODE4); | 2581 | writel(m4, port_mmio + PHY_MODE4); |
2585 | |||
2586 | if (hp_flags & MV_HP_ERRATA_60X1B2) | ||
2587 | writel(tmp, port_mmio + PHY_MODE3); | ||
2588 | } | 2582 | } |
2583 | /* | ||
2584 | * Workaround for 60x1-B2 errata SATA#13: | ||
2585 | * Any write to PHY_MODE4 (above) may corrupt PHY_MODE3, | ||
2586 | * so we must always rewrite PHY_MODE3 after PHY_MODE4. | ||
2587 | */ | ||
2588 | writel(m3, port_mmio + PHY_MODE3); | ||
2589 | 2589 | ||
2590 | /* Revert values of pre-emphasis and signal amps to the saved ones */ | 2590 | /* Revert values of pre-emphasis and signal amps to the saved ones */ |
2591 | m2 = readl(port_mmio + PHY_MODE2); | 2591 | m2 = readl(port_mmio + PHY_MODE2); |
@@ -2876,7 +2876,7 @@ static unsigned int mv_in_pcix_mode(struct ata_host *host) | |||
2876 | void __iomem *mmio = hpriv->base; | 2876 | void __iomem *mmio = hpriv->base; |
2877 | u32 reg; | 2877 | u32 reg; |
2878 | 2878 | ||
2879 | if (!HAS_PCI(host) || !IS_PCIE(hpriv)) | 2879 | if (IS_SOC(hpriv) || !IS_PCIE(hpriv)) |
2880 | return 0; /* not PCI-X capable */ | 2880 | return 0; /* not PCI-X capable */ |
2881 | reg = readl(mmio + MV_PCI_MODE_OFS); | 2881 | reg = readl(mmio + MV_PCI_MODE_OFS); |
2882 | if ((reg & MV_PCI_MODE_MASK) == 0) | 2882 | if ((reg & MV_PCI_MODE_MASK) == 0) |
@@ -3003,10 +3003,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) | |||
3003 | hp_flags |= MV_HP_CUT_THROUGH; | 3003 | hp_flags |= MV_HP_CUT_THROUGH; |
3004 | 3004 | ||
3005 | switch (pdev->revision) { | 3005 | switch (pdev->revision) { |
3006 | case 0x0: | 3006 | case 0x2: /* Rev.B0: the first/only public release */ |
3007 | hp_flags |= MV_HP_ERRATA_XX42A0; | ||
3008 | break; | ||
3009 | case 0x1: | ||
3010 | hp_flags |= MV_HP_ERRATA_60X1C0; | 3007 | hp_flags |= MV_HP_ERRATA_60X1C0; |
3011 | break; | 3008 | break; |
3012 | default: | 3009 | default: |
@@ -3018,7 +3015,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) | |||
3018 | break; | 3015 | break; |
3019 | case chip_soc: | 3016 | case chip_soc: |
3020 | hpriv->ops = &mv_soc_ops; | 3017 | hpriv->ops = &mv_soc_ops; |
3021 | hp_flags |= MV_HP_ERRATA_60X1C0; | 3018 | hp_flags |= MV_HP_FLAG_SOC | MV_HP_ERRATA_60X1C0; |
3022 | break; | 3019 | break; |
3023 | 3020 | ||
3024 | default: | 3021 | default: |
@@ -3062,12 +3059,12 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
3062 | if (rc) | 3059 | if (rc) |
3063 | goto done; | 3060 | goto done; |
3064 | 3061 | ||
3065 | if (HAS_PCI(host)) { | 3062 | if (IS_SOC(hpriv)) { |
3066 | hpriv->main_irq_cause_addr = mmio + PCI_HC_MAIN_IRQ_CAUSE_OFS; | ||
3067 | hpriv->main_irq_mask_addr = mmio + PCI_HC_MAIN_IRQ_MASK_OFS; | ||
3068 | } else { | ||
3069 | hpriv->main_irq_cause_addr = mmio + SOC_HC_MAIN_IRQ_CAUSE_OFS; | 3063 | hpriv->main_irq_cause_addr = mmio + SOC_HC_MAIN_IRQ_CAUSE_OFS; |
3070 | hpriv->main_irq_mask_addr = mmio + SOC_HC_MAIN_IRQ_MASK_OFS; | 3064 | hpriv->main_irq_mask_addr = mmio + SOC_HC_MAIN_IRQ_MASK_OFS; |
3065 | } else { | ||
3066 | hpriv->main_irq_cause_addr = mmio + PCI_HC_MAIN_IRQ_CAUSE_OFS; | ||
3067 | hpriv->main_irq_mask_addr = mmio + PCI_HC_MAIN_IRQ_MASK_OFS; | ||
3071 | } | 3068 | } |
3072 | 3069 | ||
3073 | /* global interrupt mask: 0 == mask everything */ | 3070 | /* global interrupt mask: 0 == mask everything */ |
@@ -3093,7 +3090,7 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
3093 | mv_port_init(&ap->ioaddr, port_mmio); | 3090 | mv_port_init(&ap->ioaddr, port_mmio); |
3094 | 3091 | ||
3095 | #ifdef CONFIG_PCI | 3092 | #ifdef CONFIG_PCI |
3096 | if (HAS_PCI(host)) { | 3093 | if (!IS_SOC(hpriv)) { |
3097 | unsigned int offset = port_mmio - mmio; | 3094 | unsigned int offset = port_mmio - mmio; |
3098 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); | 3095 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); |
3099 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); | 3096 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); |
@@ -3113,7 +3110,7 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
3113 | writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS); | 3110 | writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS); |
3114 | } | 3111 | } |
3115 | 3112 | ||
3116 | if (HAS_PCI(host)) { | 3113 | if (!IS_SOC(hpriv)) { |
3117 | /* Clear any currently outstanding host interrupt conditions */ | 3114 | /* Clear any currently outstanding host interrupt conditions */ |
3118 | writelfl(0, mmio + hpriv->irq_cause_ofs); | 3115 | writelfl(0, mmio + hpriv->irq_cause_ofs); |
3119 | 3116 | ||