mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-20 23:35:02 +00:00
Make this work on the AT91SAM9G20:
o Disable multi-block operations: they sometimes fail. o Don't use the PROOF bits yet: they hang the system hard. o Disable the the multi-block operations for !rm9200, but it still doesn't help. o Fix writing < 12 bytes errata to actually work. o Enable, for the moment, reporting extra bytes soaked up.
This commit is contained in:
parent
683bb97c9f
commit
f22f156e0b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=239805
|
@ -309,8 +309,8 @@ at91_mci_init(device_t dev)
|
|||
WR4(sc, MCI_DTOR, MCI_DTOR_DTOMUL_1M | 1);
|
||||
val = MCI_MR_PDCMODE;
|
||||
val |= 0x34a; /* PWSDIV = 3; CLKDIV = 74 */
|
||||
if (sc->sc_cap & CAP_MCI1_REV2XX)
|
||||
val |= MCI_MR_RDPROOF | MCI_MR_WRPROOF;
|
||||
// if (sc->sc_cap & CAP_MCI1_REV2XX)
|
||||
// val |= MCI_MR_RDPROOF | MCI_MR_WRPROOF;
|
||||
WR4(sc, MCI_MR, val);
|
||||
#ifndef AT91_MCI_SLOT_B
|
||||
WR4(sc, MCI_SDCR, 0); /* SLOT A, 1 bit bus */
|
||||
|
@ -778,9 +778,9 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
|
|||
* a work-around for the "Data Write Operation and
|
||||
* number of bytes" erratum.
|
||||
*/
|
||||
if ((sc->sc_cap & CAP_MCI1_REV2XX) && data->len < 12) {
|
||||
if ((sc->sc_cap & CAP_MCI1_REV2XX) && len < 12) {
|
||||
len = 12;
|
||||
memset(data->data, 0, 12);
|
||||
memset(sc->bbuf_vaddr[0], 0, 12);
|
||||
}
|
||||
at91_bswap_buf(sc, sc->bbuf_vaddr[0], data->data, len);
|
||||
err = bus_dmamap_load(sc->dmatag, sc->bbuf_map[0],
|
||||
|
@ -1034,8 +1034,11 @@ at91_mci_stop_done(struct at91_mci_softc *sc, uint32_t sr)
|
|||
*
|
||||
* After doing the reset, wait for a NOTBUSY interrupt before
|
||||
* continuing with the next operation.
|
||||
*
|
||||
* This workaround breaks multiwrite on the rev2xx parts, but some other
|
||||
* workaround is needed.
|
||||
*/
|
||||
if (sc->flags & CMD_MULTIWRITE) {
|
||||
if ((sc->flags & CMD_MULTIWRITE) && (sc->sc_cap & CAP_NEEDS_BYTESWAP)) {
|
||||
at91_mci_reset(sc);
|
||||
WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_NOTBUSY);
|
||||
return;
|
||||
|
@ -1051,8 +1054,10 @@ at91_mci_stop_done(struct at91_mci_softc *sc, uint32_t sr)
|
|||
* additional words of data get buffered up in some unmentioned
|
||||
* internal fifo and if we don't read and discard them here they end
|
||||
* up on the front of the next read DMA transfer we do.
|
||||
*
|
||||
* This appears to be unnecessary for rev2xx parts.
|
||||
*/
|
||||
if (sc->flags & CMD_MULTIREAD) {
|
||||
if ((sc->flags & CMD_MULTIREAD) && (sc->sc_cap & CAP_NEEDS_BYTESWAP)) {
|
||||
uint32_t sr;
|
||||
int count = 0;
|
||||
|
||||
|
@ -1064,8 +1069,8 @@ at91_mci_stop_done(struct at91_mci_softc *sc, uint32_t sr)
|
|||
}
|
||||
} while (sr & MCI_SR_RXRDY);
|
||||
at91_mci_reset(sc);
|
||||
// if (count != 0)
|
||||
// printf("Had to soak up %d words after read\n", count);
|
||||
if (count != 0)
|
||||
printf("Had to soak up %d words after read\n", count);
|
||||
}
|
||||
|
||||
cmd->error = MMC_ERR_NONE;
|
||||
|
@ -1306,7 +1311,15 @@ at91_mci_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
|
|||
*(int *)result = sc->host.caps;
|
||||
break;
|
||||
case MMCBR_IVAR_MAX_DATA:
|
||||
*(int *)result = MAX_BLOCKS;
|
||||
/*
|
||||
* Something is wrong with the 2x parts and multiblock, so
|
||||
* just do 1 block at a time for now, which really kills
|
||||
* performance.
|
||||
*/
|
||||
if (sc->sc_cap & CAP_MCI1_REV2XX)
|
||||
*(int *)result = 1;
|
||||
else
|
||||
*(int *)result = MAX_BLOCKS;
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
|
|
Loading…
Reference in a new issue