summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Lord <liml@rtr.ca>2008-03-31 19:35:13 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-17 15:44:21 -0400
commitb67a1064cb1c1d3b43e01e8b43a6a8dcdefed733 (patch)
tree8db97228fbc4b331cfc8fa25d8fc0169aff2ab31
parentb562468cc3bd0c81decba1f5f39a7173f839e57e (diff)
downloadlinux-b67a1064cb1c1d3b43e01e8b43a6a8dcdefed733.tar.gz
linux-b67a1064cb1c1d3b43e01e8b43a6a8dcdefed733.tar.bz2
linux-b67a1064cb1c1d3b43e01e8b43a6a8dcdefed733.zip
sata_mv fix ifctl handling
Fix handling of the SATA_INTERFACE_CFG register to match datasheet requirements. Signed-off-by: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/sata_mv.c42
1 files changed, 19 insertions, 23 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 5b9f937d0f87..16c15ed3536e 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -2242,6 +2242,16 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
return;
}
+static void mv_setup_ifctl(void __iomem *port_mmio, int want_gen2i)
+{
+ u32 ifctl = readl(port_mmio + SATA_INTERFACE_CFG);
+
+ ifctl = (ifctl & 0xf7f) | 0x9b1000; /* from chip spec */
+ if (want_gen2i)
+ ifctl |= (1 << 7); /* enable gen2i speed */
+ writelfl(ifctl, port_mmio + SATA_INTERFACE_CFG);
+}
+
/*
* Caller must ensure that EDMA is not active,
* by first doing mv_stop_edma() where needed.
@@ -2253,18 +2263,17 @@ static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
- if (IS_GEN_II(hpriv)) {
- u32 ifctl = readl(port_mmio + SATA_INTERFACE_CFG);
- ifctl |= (1 << 7); /* enable gen2i speed */
- ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */
- writelfl(ifctl, port_mmio + SATA_INTERFACE_CFG);
+ if (!IS_GEN_I(hpriv)) {
+ /* Enable 3.0gb/s link speed */
+ mv_setup_ifctl(port_mmio, 1);
}
-
- udelay(25); /* allow reset propagation */
-
- /* Spec never mentions clearing the bit. Marvell's driver does
- * clear the bit, however.
+ /*
+ * Strobing ATA_RST here causes a hard reset of the SATA transport,
+ * link, and physical layers. It resets all SATA interface registers
+ * (except for SATA_INTERFACE_CFG), and issues a COMRESET to the dev.
*/
+ writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
+ udelay(25); /* allow reset propagation */
writelfl(0, port_mmio + EDMA_CMD_OFS);
hpriv->ops->phy_errata(hpriv, mmio, port_no);
@@ -2711,19 +2720,6 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
hpriv->ops->enable_leds(hpriv, mmio);
for (port = 0; port < host->n_ports; port++) {
- if (IS_GEN_II(hpriv)) {
- void __iomem *port_mmio = mv_port_base(mmio, port);
-
- u32 ifctl = readl(port_mmio + SATA_INTERFACE_CFG);
- ifctl |= (1 << 7); /* enable gen2i speed */
- ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */
- writelfl(ifctl, port_mmio + SATA_INTERFACE_CFG);
- }
-
- hpriv->ops->phy_errata(hpriv, mmio, port);
- }
-
- for (port = 0; port < host->n_ports; port++) {
struct ata_port *ap = host->ports[port];
void __iomem *port_mmio = mv_port_base(mmio, port);