- 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
This commit is contained in:
Alexander Motin 2012-06-12 11:08:51 +00:00
parent 776b728856
commit b30c7d5167
3 changed files with 47 additions and 1 deletions

View File

@ -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 =
@ -1998,6 +2003,39 @@ mvs_reset_to(void *arg)
callout_schedule(&ch->reset_timer, hz / 10);
}
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)
{
@ -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 File

@ -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 File

@ -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);