bcm2835_sdhci: roll back r354823

r354823 kicked DATA_END handling out of the DMA interrupt path "to make
things easy", but this was likely a mistake -- if we know we're done after
we've finished pending DMA operations, we should go ahead and acknowledge
it rather than waiting for the controller to finalize it. If it's not ready,
we'll simply re-enable interrupts and wait for it anyways, to be re-entered
in sdhci_data_intr.
This commit is contained in:
Kyle Evans 2019-11-21 02:47:55 +00:00
parent e68976d877
commit b61ac06706
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=354932

View File

@ -87,6 +87,7 @@ __FBSDID("$FreeBSD$");
rounddown(BCM_SDHCI_SLOT_LEFT(slot), BCM_SDHCI_BUFFER_SIZE))
#define DATA_PENDING_MASK (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)
#define DATA_XFER_MASK (DATA_PENDING_MASK | SDHCI_INT_DATA_END)
#ifdef DEBUG
static int bcm2835_sdhci_debug = 0;
@ -579,7 +580,7 @@ bcm_sdhci_start_dma_seg(struct bcm_sdhci_softc *sc)
if (idx == 0) {
bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, sync_op);
slot->intmask &= ~DATA_PENDING_MASK;
slot->intmask &= ~DATA_XFER_MASK;
bcm_sdhci_write_4(sc->sc_dev, slot, SDHCI_SIGNAL_ENABLE,
slot->intmask);
}
@ -600,7 +601,7 @@ bcm_sdhci_dma_exit(struct bcm_sdhci_softc *sc)
mtx_assert(&slot->mtx, MA_OWNED);
/* Re-enable interrupts */
slot->intmask |= DATA_PENDING_MASK;
slot->intmask |= DATA_XFER_MASK;
bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE,
slot->intmask);
}
@ -625,6 +626,8 @@ bcm_sdhci_dma_intr(int ch, void *arg)
goto out;
}
if (sc->dmamap_seg_count == 0)
return;
if ((slot->curcmd->data->flags & MMC_DATA_READ) != 0)
bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map,
BUS_DMASYNC_POSTREAD);
@ -654,6 +657,12 @@ bcm_sdhci_dma_intr(int ch, void *arg)
sdhci_finish_data(slot);
bcm_sdhci_dma_exit(sc);
}
} else if ((reg & SDHCI_INT_DATA_END) != 0) {
bcm_sdhci_dma_exit(sc);
bcm_sdhci_write_4(slot->bus, slot, SDHCI_INT_STATUS,
reg);
slot->flags &= ~PLATFORM_DATA_STARTED;
sdhci_finish_data(slot);
} else {
bcm_sdhci_dma_exit(sc);
}
@ -732,7 +741,11 @@ bcm_sdhci_finish_transfer(device_t dev, struct sdhci_slot *slot)
{
struct bcm_sdhci_softc *sc = device_get_softc(slot->bus);
/* Clean up */
/*
* Clean up. Interrupts are clearly enabled, because we received an
* SDHCI_INT_DATA_END to get this far -- just make sure we don't leave
* anything laying around.
*/
if (sc->dmamap_seg_count != 0) {
/*
* Our segment math should have worked out such that we would
@ -753,7 +766,6 @@ bcm_sdhci_finish_transfer(device_t dev, struct sdhci_slot *slot)
sc->dmamap_seg_index = 0;
}
bcm_sdhci_dma_exit(sc);
sdhci_finish_data(slot);
}