Author: mav
Date: Tue Jun 12 11:08:51 2012
New Revision: 236952
URL: http://svn.freebsd.org/changeset/base/236952

Log:
   - Limit r214102 workaround to only x86. On arm it causes more problems
  then solves because of cache coherency issues. This fixes periodic error
  messages on console and command timeouts.
   - Patch SATA PHY configuration for 65nm SoCs to improve SNR same as
  Linux does.
  
  MFC after:    2 weeks

Modified:
  head/sys/dev/mvs/mvs.c
  head/sys/dev/mvs/mvs.h
  head/sys/dev/mvs/mvs_soc.c

Modified: head/sys/dev/mvs/mvs.c
==============================================================================
--- head/sys/dev/mvs/mvs.c      Tue Jun 12 10:44:09 2012        (r236951)
+++ head/sys/dev/mvs/mvs.c      Tue Jun 12 11:08:51 2012        (r236952)
@@ -1048,14 +1048,19 @@ mvs_crbq_intr(device_t dev)
                 * Handle only successfull completions here.
                 * Errors will be handled by main intr handler.
                 */
+#if defined(__i386__) || defined(__amd64__)
                if (crpb->id == 0xffff && crpb->rspflg == 0xffff) {
                        device_printf(dev, "Unfilled CRPB "
                            "%d (%d->%d) tag %d flags %04x rs %08x\n",
                            cin_idx, fin_idx, in_idx, slot, flags, ch->rslots);
-               } else if (ch->numtslots != 0 ||
+               } else
+#endif
+               if (ch->numtslots != 0 ||
                    (flags & EDMA_IE_EDEVERR) == 0) {
+#if defined(__i386__) || defined(__amd64__)
                        crpb->id = 0xffff;
                        crpb->rspflg = 0xffff;
+#endif
                        if (ch->slot[slot].state >= MVS_SLOT_RUNNING) {
                                ccb = ch->slot[slot].ccb;
                                ccb->ataio.res.status =
@@ -1999,6 +2004,39 @@ mvs_reset_to(void *arg)
 }
 
 static void
+mvs_errata(device_t dev)
+{
+       struct mvs_channel *ch = device_get_softc(dev);
+       uint32_t val;
+
+       if (ch->quirks & MVS_Q_SOC65) {
+               val = ATA_INL(ch->r_mem, SATA_PHYM3);
+               val &= ~(0x3 << 27);    /* SELMUPF = 1 */
+               val |= (0x1 << 27);
+               val &= ~(0x3 << 29);    /* SELMUPI = 1 */
+               val |= (0x1 << 29);
+               ATA_OUTL(ch->r_mem, SATA_PHYM3, val);
+
+               val = ATA_INL(ch->r_mem, SATA_PHYM4);
+               val &= ~0x1;            /* SATU_OD8 = 0 */
+               val |= (0x1 << 16);     /* reserved bit 16 = 1 */
+               ATA_OUTL(ch->r_mem, SATA_PHYM4, val);
+
+               val = ATA_INL(ch->r_mem, SATA_PHYM9_GEN2);
+               val &= ~0xf;            /* TXAMP[3:0] = 8 */
+               val |= 0x8;
+               val &= ~(0x1 << 14);    /* TXAMP[4] = 0 */
+               ATA_OUTL(ch->r_mem, SATA_PHYM9_GEN2, val);
+
+               val = ATA_INL(ch->r_mem, SATA_PHYM9_GEN1);
+               val &= ~0xf;            /* TXAMP[3:0] = 8 */
+               val |= 0x8;
+               val &= ~(0x1 << 14);    /* TXAMP[4] = 0 */
+               ATA_OUTL(ch->r_mem, SATA_PHYM9_GEN1, val);
+       }
+}
+
+static void
 mvs_reset(device_t dev)
 {
        struct mvs_channel *ch = device_get_softc(dev);
@@ -2044,6 +2082,7 @@ mvs_reset(device_t dev)
        ATA_OUTL(ch->r_mem, EDMA_CMD, EDMA_CMD_EATARST);
        DELAY(25);
        ATA_OUTL(ch->r_mem, EDMA_CMD, 0);
+       mvs_errata(dev);
        /* Reset and reconnect PHY, */
        if (!mvs_sata_phy_reset(dev)) {
                if (bootverbose)

Modified: head/sys/dev/mvs/mvs.h
==============================================================================
--- head/sys/dev/mvs/mvs.h      Tue Jun 12 10:44:09 2012        (r236951)
+++ head/sys/dev/mvs/mvs.h      Tue Jun 12 11:08:51 2012        (r236952)
@@ -382,6 +382,10 @@
 #define SATA_FISDW5                    0x384   /* FIS DW5 */
 #define SATA_FISDW6                    0x388   /* FIS DW6 */
 
+#define SATA_PHYM9_GEN2                        0x398
+#define SATA_PHYM9_GEN1                        0x39c
+#define SATA_PHYCFG_OFS                        0x3a0   /* 65nm SoCs only */
+
 #define MVS_MAX_PORTS                  8
 #define MVS_MAX_SLOTS                  32
 
@@ -537,6 +541,7 @@ struct mvs_channel {
 #define MVS_Q_GENIIE   4
 #define MVS_Q_SOC      8
 #define MVS_Q_CT       16
+#define MVS_Q_SOC65    32
        int                     pm_level;       /* power management level */
 
        struct mvs_slot         slot[MVS_MAX_SLOTS];

Modified: head/sys/dev/mvs/mvs_soc.c
==============================================================================
--- head/sys/dev/mvs/mvs_soc.c  Tue Jun 12 10:44:09 2012        (r236951)
+++ head/sys/dev/mvs/mvs_soc.c  Tue Jun 12 11:08:51 2012        (r236952)
@@ -135,6 +135,8 @@ mvs_attach(device_t dev)
        if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
            &ctlr->r_rid, RF_ACTIVE)))
                return ENXIO;
+       if (ATA_INL(ctlr->r_mem, PORT_BASE(0) + SATA_PHYCFG_OFS) != 0)
+               ctlr->quirks |= MVS_Q_SOC65;
        /* Setup our own memory management for channels. */
        ctlr->sc_iomem.rm_start = rman_get_start(ctlr->r_mem);
        ctlr->sc_iomem.rm_end = rman_get_end(ctlr->r_mem);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to