]> err.no Git - linux-2.6/commitdiff
sata_mv fix ifctl handling
authorMark Lord <liml@rtr.ca>
Mon, 31 Mar 2008 23:35:13 +0000 (19:35 -0400)
committerJeff Garzik <jgarzik@redhat.com>
Thu, 17 Apr 2008 19:44:21 +0000 (15:44 -0400)
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>
drivers/ata/sata_mv.c

index 5b9f937d0f87e2acce89ca88b894429edec83493..16c15ed3536ea032cddaaf6ae0d12ccab4223a15 100644 (file)
@@ -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);
@@ -2710,19 +2719,6 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
        hpriv->ops->reset_bus(host, mmio);
        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);