aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_mv.c
diff options
context:
space:
mode:
authorMark Lord <liml@rtr.ca>2009-01-30 18:47:51 -0500
committerJeff Garzik <jgarzik@redhat.com>2009-03-24 22:02:38 -0400
commit00b81235aa0368f84c0e704bec4142cd8c516ad5 (patch)
treefcb89d62f439d7233a926ff79800f598a68680e8 /drivers/ata/sata_mv.c
parent91b1a84c10869e2e46a576e5367de3166bff8ecc (diff)
sata_mv: rearrange mv_start_dma() and friends
Rearrange mv_start_dma() and friends, in preparation for adding non-EDMA DMA modes, and non-EDMA interrupts, to the driver. 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.c66
1 files changed, 38 insertions, 28 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 3dc35543fb3d..fb3288bbd9fb 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -536,7 +536,7 @@ static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
536 unsigned int port_no); 536 unsigned int port_no);
537static int mv_stop_edma(struct ata_port *ap); 537static int mv_stop_edma(struct ata_port *ap);
538static int mv_stop_edma_engine(void __iomem *port_mmio); 538static int mv_stop_edma_engine(void __iomem *port_mmio);
539static void mv_edma_cfg(struct ata_port *ap, int want_ncq); 539static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma);
540 540
541static void mv_pmp_select(struct ata_port *ap, int pmp); 541static void mv_pmp_select(struct ata_port *ap, int pmp);
542static int mv_pmp_hardreset(struct ata_link *link, unsigned int *class, 542static int mv_pmp_hardreset(struct ata_link *link, unsigned int *class,
@@ -849,8 +849,32 @@ static void mv_enable_port_irqs(struct ata_port *ap,
849 mv_set_main_irq_mask(ap->host, disable_bits, enable_bits); 849 mv_set_main_irq_mask(ap->host, disable_bits, enable_bits);
850} 850}
851 851
852static void mv_clear_and_enable_port_irqs(struct ata_port *ap,
853 void __iomem *port_mmio,
854 unsigned int port_irqs)
855{
856 struct mv_host_priv *hpriv = ap->host->private_data;
857 int hardport = mv_hardport_from_port(ap->port_no);
858 void __iomem *hc_mmio = mv_hc_base_from_port(
859 mv_host_base(ap->host), ap->port_no);
860 u32 hc_irq_cause;
861
862 /* clear EDMA event indicators, if any */
863 writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
864
865 /* clear pending irq events */
866 hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
867 writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
868
869 /* clear FIS IRQ Cause */
870 if (IS_GEN_IIE(hpriv))
871 writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
872
873 mv_enable_port_irqs(ap, port_irqs);
874}
875
852/** 876/**
853 * mv_start_dma - Enable eDMA engine 877 * mv_start_edma - Enable eDMA engine
854 * @base: port base address 878 * @base: port base address
855 * @pp: port private data 879 * @pp: port private data
856 * 880 *
@@ -860,7 +884,7 @@ static void mv_enable_port_irqs(struct ata_port *ap,
860 * LOCKING: 884 * LOCKING:
861 * Inherited from caller. 885 * Inherited from caller.
862 */ 886 */
863static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, 887static void mv_start_edma(struct ata_port *ap, void __iomem *port_mmio,
864 struct mv_port_priv *pp, u8 protocol) 888 struct mv_port_priv *pp, u8 protocol)
865{ 889{
866 int want_ncq = (protocol == ATA_PROT_NCQ); 890 int want_ncq = (protocol == ATA_PROT_NCQ);
@@ -872,26 +896,11 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
872 } 896 }
873 if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) { 897 if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) {
874 struct mv_host_priv *hpriv = ap->host->private_data; 898 struct mv_host_priv *hpriv = ap->host->private_data;
875 int hardport = mv_hardport_from_port(ap->port_no);
876 void __iomem *hc_mmio = mv_hc_base_from_port(
877 mv_host_base(ap->host), ap->port_no);
878 u32 hc_irq_cause;
879
880 /* clear EDMA event indicators, if any */
881 writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
882
883 /* clear pending irq events */
884 hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
885 writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
886 899
887 mv_edma_cfg(ap, want_ncq); 900 mv_edma_cfg(ap, want_ncq, 1);
888
889 /* clear FIS IRQ Cause */
890 if (IS_GEN_IIE(hpriv))
891 writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
892 901
893 mv_set_edma_ptrs(port_mmio, hpriv, pp); 902 mv_set_edma_ptrs(port_mmio, hpriv, pp);
894 mv_enable_port_irqs(ap, DONE_IRQ|ERR_IRQ); 903 mv_clear_and_enable_port_irqs(ap, port_mmio, DONE_IRQ|ERR_IRQ);
895 904
896 writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS); 905 writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS);
897 pp->pp_flags |= MV_PP_FLAG_EDMA_EN; 906 pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
@@ -1173,7 +1182,7 @@ static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq)
1173 writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS); 1182 writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS);
1174} 1183}
1175 1184
1176static void mv_edma_cfg(struct ata_port *ap, int want_ncq) 1185static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma)
1177{ 1186{
1178 u32 cfg; 1187 u32 cfg;
1179 struct mv_port_priv *pp = ap->private_data; 1188 struct mv_port_priv *pp = ap->private_data;
@@ -1182,7 +1191,7 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
1182 1191
1183 /* set up non-NCQ EDMA configuration */ 1192 /* set up non-NCQ EDMA configuration */
1184 cfg = EDMA_CFG_Q_DEPTH; /* always 0x1f for *all* chips */ 1193 cfg = EDMA_CFG_Q_DEPTH; /* always 0x1f for *all* chips */
1185 pp->pp_flags &= ~MV_PP_FLAG_FBS_EN; 1194 pp->pp_flags &= ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN);
1186 1195
1187 if (IS_GEN_I(hpriv)) 1196 if (IS_GEN_I(hpriv))
1188 cfg |= (1 << 8); /* enab config burst size mask */ 1197 cfg |= (1 << 8); /* enab config burst size mask */
@@ -1211,9 +1220,11 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
1211 } 1220 }
1212 1221
1213 cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ 1222 cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */
1214 cfg |= (1 << 22); /* enab 4-entry host queue cache */ 1223 if (want_edma) {
1215 if (!IS_SOC(hpriv)) 1224 cfg |= (1 << 22); /* enab 4-entry host queue cache */
1216 cfg |= (1 << 18); /* enab early completion */ 1225 if (!IS_SOC(hpriv))
1226 cfg |= (1 << 18); /* enab early completion */
1227 }
1217 if (hpriv->hp_flags & MV_HP_CUT_THROUGH) 1228 if (hpriv->hp_flags & MV_HP_CUT_THROUGH)
1218 cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */ 1229 cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */
1219 } 1230 }
@@ -1221,8 +1232,7 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
1221 if (want_ncq) { 1232 if (want_ncq) {
1222 cfg |= EDMA_CFG_NCQ; 1233 cfg |= EDMA_CFG_NCQ;
1223 pp->pp_flags |= MV_PP_FLAG_NCQ_EN; 1234 pp->pp_flags |= MV_PP_FLAG_NCQ_EN;
1224 } else 1235 }
1225 pp->pp_flags &= ~MV_PP_FLAG_NCQ_EN;
1226 1236
1227 writelfl(cfg, port_mmio + EDMA_CFG_OFS); 1237 writelfl(cfg, port_mmio + EDMA_CFG_OFS);
1228} 1238}
@@ -1591,7 +1601,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
1591 return ata_sff_qc_issue(qc); 1601 return ata_sff_qc_issue(qc);
1592 } 1602 }
1593 1603
1594 mv_start_dma(ap, port_mmio, pp, qc->tf.protocol); 1604 mv_start_edma(ap, port_mmio, pp, qc->tf.protocol);
1595 1605
1596 pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK; 1606 pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK;
1597 in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT; 1607 in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT;