Permalink
Browse files

MFC r236952:

 - 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.
  • Loading branch information...
1 parent 5f06ace commit 99b196446a2f912a65710b6ccc55a77a90621873 @amotin amotin committed Jun 21, 2012
Showing with 47 additions and 1 deletion.
  1. +40 −1 sys/dev/mvs/mvs.c
  2. +5 −0 sys/dev/mvs/mvs.h
  3. +2 −0 sys/dev/mvs/mvs_soc.c
View
@@ -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)
View
@@ -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];
View
@@ -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);

0 comments on commit 99b1964

Please sign in to comment.