aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_mv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r--drivers/ata/sata_mv.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index ef385451ffd5..47184567248d 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1016,7 +1016,7 @@ static void mv_set_irq_coalescing(struct ata_host *host,
1016 void __iomem *mmio = hpriv->base, *hc_mmio; 1016 void __iomem *mmio = hpriv->base, *hc_mmio;
1017 u32 coal_enable = 0; 1017 u32 coal_enable = 0;
1018 unsigned long flags; 1018 unsigned long flags;
1019 unsigned int clks; 1019 unsigned int clks, is_dual_hc = hpriv->n_ports > MV_PORTS_PER_HC;
1020 const u32 coal_disable = PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | 1020 const u32 coal_disable = PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE |
1021 ALL_PORTS_COAL_DONE; 1021 ALL_PORTS_COAL_DONE;
1022 1022
@@ -1033,37 +1033,41 @@ static void mv_set_irq_coalescing(struct ata_host *host,
1033 } 1033 }
1034 1034
1035 spin_lock_irqsave(&host->lock, flags); 1035 spin_lock_irqsave(&host->lock, flags);
1036 mv_set_main_irq_mask(host, coal_disable, 0);
1036 1037
1037#if 0 /* disabled pending functional clarification from Marvell */ 1038 if (is_dual_hc && !IS_GEN_I(hpriv)) {
1038 if (!IS_GEN_I(hpriv)) {
1039 /* 1039 /*
1040 * GEN_II/GEN_IIE: global thresholds for the entire chip. 1040 * GEN_II/GEN_IIE with dual host controllers:
1041 * one set of global thresholds for the entire chip.
1041 */ 1042 */
1042 writel(clks, mmio + MV_IRQ_COAL_TIME_THRESHOLD); 1043 writel(clks, mmio + MV_IRQ_COAL_TIME_THRESHOLD);
1043 writel(count, mmio + MV_IRQ_COAL_IO_THRESHOLD); 1044 writel(count, mmio + MV_IRQ_COAL_IO_THRESHOLD);
1044 /* clear leftover coal IRQ bit */ 1045 /* clear leftover coal IRQ bit */
1045 writelfl(~ALL_PORTS_COAL_IRQ, mmio + MV_IRQ_COAL_CAUSE); 1046 writel(~ALL_PORTS_COAL_IRQ, mmio + MV_IRQ_COAL_CAUSE);
1046 clks = count = 0; /* so as to clear the alternate regs below */ 1047 if (count)
1047 coal_enable = ALL_PORTS_COAL_DONE; 1048 coal_enable = ALL_PORTS_COAL_DONE;
1049 clks = count = 0; /* force clearing of regular regs below */
1048 } 1050 }
1049#endif 1051
1050 /* 1052 /*
1051 * All chips: independent thresholds for each HC on the chip. 1053 * All chips: independent thresholds for each HC on the chip.
1052 */ 1054 */
1053 hc_mmio = mv_hc_base_from_port(mmio, 0); 1055 hc_mmio = mv_hc_base_from_port(mmio, 0);
1054 writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS); 1056 writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS);
1055 writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS); 1057 writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS);
1056 coal_enable |= PORTS_0_3_COAL_DONE; 1058 writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE_OFS);
1057 if (hpriv->n_ports > 4) { 1059 if (count)
1060 coal_enable |= PORTS_0_3_COAL_DONE;
1061 if (is_dual_hc) {
1058 hc_mmio = mv_hc_base_from_port(mmio, MV_PORTS_PER_HC); 1062 hc_mmio = mv_hc_base_from_port(mmio, MV_PORTS_PER_HC);
1059 writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS); 1063 writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS);
1060 writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS); 1064 writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS);
1061 coal_enable |= PORTS_4_7_COAL_DONE; 1065 writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE_OFS);
1066 if (count)
1067 coal_enable |= PORTS_4_7_COAL_DONE;
1062 } 1068 }
1063 if (!count)
1064 coal_enable = 0;
1065 mv_set_main_irq_mask(host, coal_disable, coal_enable);
1066 1069
1070 mv_set_main_irq_mask(host, 0, coal_enable);
1067 spin_unlock_irqrestore(&host->lock, flags); 1071 spin_unlock_irqrestore(&host->lock, flags);
1068} 1072}
1069 1073