summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/arm
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-27 10:14:44 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-27 10:14:44 +0200
commitef5d536f840e01cb7a9edfd9f72dd0f058fb62aa (patch)
tree3c3d09f9788fce5ac86c84e93066eecca5581782 /freebsd/sys/arm
parentat91_mci: Get rid of bounce buffer (diff)
downloadrtems-libbsd-ef5d536f840e01cb7a9edfd9f72dd0f058fb62aa.tar.bz2
at91_mci: Simplify XDMA usage
Diffstat (limited to 'freebsd/sys/arm')
-rw-r--r--freebsd/sys/arm/at91/at91_mci.c70
1 files changed, 27 insertions, 43 deletions
diff --git a/freebsd/sys/arm/at91/at91_mci.c b/freebsd/sys/arm/at91/at91_mci.c
index 557efa80..206f782d 100644
--- a/freebsd/sys/arm/at91/at91_mci.c
+++ b/freebsd/sys/arm/at91/at91_mci.c
@@ -147,7 +147,7 @@ static sXdmad *pXdmad = &XDMAD_Instance;
/* FIXME: It would be better to split the DMA up in that case like in the
* original driver. But that would need some rework. */
#else /* __rtems__ */
-#define MAX_BLOCKS 32
+#define MAX_BLOCKS 256
#endif /* __rtems__ */
#ifndef __rtems__
@@ -190,6 +190,7 @@ struct at91_mci_softc {
uint32_t bbuf_curidx; /* which bbuf is the active DMA buffer */
uint32_t xfer_offset; /* offset so far into caller's buf */
#else /* __rtems__ */
+ LinkedListDescriporView1 xdma_desc;
uint32_t xdma_tx_channel;
uint32_t xdma_rx_channel;
uint8_t xdma_tx_perid;
@@ -770,69 +771,54 @@ at91_mci_update_ios(device_t brdev, device_t reqdev)
}
#ifdef __rtems__
-static LinkedListDescriporView1 dma_desc[MAX_BLOCKS];
-
static void
-at91_mci_setup_xdma(struct at91_mci_softc *sc, bool read, uint32_t block_size,
- uint32_t block_count, void *data, uint32_t len)
+at91_mci_setup_xdma(struct at91_mci_softc *sc, bool read, void *data,
+ uint32_t len)
{
- sXdmadCfg *xdma_cfg;
- uint32_t xdma_channel;
const uint32_t xdma_cndc = XDMAC_CNDC_NDVIEW_NDV1 |
XDMAC_CNDC_NDE_DSCR_FETCH_EN |
XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED |
XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
- const uint32_t sa_rdr = (uint32_t)(sc->mem_res->r_bushandle + MCI_RDR);
- const uint32_t da_tdr = (uint32_t)(sc->mem_res->r_bushandle + MCI_TDR);
const uint32_t xdma_interrupt = XDMAC_CIE_BIE | XDMAC_CIE_DIE |
XDMAC_CIE_FIE | XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE;
+ sXdmadCfg *xdma_cfg;
+ uint32_t xdma_channel;
eXdmadRC rc;
- size_t i;
+
+ if (len % 4 != 0)
+ panic("invalid XDMA transfer length");
if (read) {
xdma_cfg = &sc->xdma_rx_cfg;
xdma_channel = sc->xdma_rx_channel;
+ sc->xdma_desc.mbr_sa = (uint32_t)(sc->mem_res->r_bushandle +
+ MCI_RDR);
+ sc->xdma_desc.mbr_da = (uint32_t)data;
+ rtems_cache_invalidate_multiple_data_lines(data, len);
} else {
xdma_cfg = &sc->xdma_tx_cfg;
xdma_channel = sc->xdma_tx_channel;
+ sc->xdma_desc.mbr_sa = (uint32_t)data;
+ sc->xdma_desc.mbr_da = (uint32_t)(sc->mem_res->r_bushandle +
+ MCI_TDR);
+ rtems_cache_flush_multiple_data_lines(data, len);
}
- for (i = 0; i < block_count; ++i) {
- if (read) {
- dma_desc[i].mbr_sa = sa_rdr;
- dma_desc[i].mbr_da = ((uint32_t)data) + i * block_size;
- } else {
- dma_desc[i].mbr_sa = ((uint32_t)data) + i * block_size;
- dma_desc[i].mbr_da = da_tdr;
- }
- dma_desc[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
- XDMA_UBC_NDEN_UPDATED | (block_size/4);
- if (i == block_count - 1) {
- dma_desc[i].mbr_ubc |= XDMA_UBC_NDE_FETCH_DIS;
- dma_desc[i].mbr_nda = 0;
- } else {
- dma_desc[i].mbr_ubc |= XDMA_UBC_NDE_FETCH_EN;
- dma_desc[i].mbr_nda = (uint32_t) &dma_desc[i+1];
- }
- }
+ sc->xdma_desc.mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
+ XDMA_UBC_NDEN_UPDATED | (len / 4);
+ sc->xdma_desc.mbr_ubc |= XDMA_UBC_NDE_FETCH_DIS;
+ sc->xdma_desc.mbr_nda = 0;
rc = XDMAD_ConfigureTransfer(pXdmad, xdma_channel, xdma_cfg, xdma_cndc,
- (uint32_t)dma_desc, xdma_interrupt);
+ (uint32_t)&sc->xdma_desc, xdma_interrupt);
if (rc != XDMAD_OK)
- panic("Could not configure XDMA: %d.", rc);
+ panic("configure XDMA failed: %d", rc);
- /* FIXME: Is that correct? */
- if (read) {
- rtems_cache_invalidate_multiple_data_lines(data, len);
- } else {
- rtems_cache_flush_multiple_data_lines(data, len);
- }
- rtems_cache_flush_multiple_data_lines(dma_desc, sizeof(dma_desc));
+ rtems_cache_flush_multiple_data_lines(&sc->xdma_desc, sizeof(sc->xdma_desc));
rc = XDMAD_StartTransfer(pXdmad, xdma_channel);
if (rc != XDMAD_OK)
- panic("Could not start XDMA: %d.", rc);
-
+ panic("start XDMA failed: %d", rc);
}
#endif /* __rtems__ */
static void
@@ -1031,8 +1017,7 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
}
WR4(sc, PDC_PTCR, PDC_PTCR_RXTEN);
#else /* __rtems__ */
- at91_mci_setup_xdma(sc, true, block_size, block_count,
- data->data, data->len);
+ at91_mci_setup_xdma(sc, true, data->data, data->len);
#endif /* __rtems__ */
} else {
#ifndef __rtems__
@@ -1074,8 +1059,7 @@ at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
}
/* do not enable PDC xfer until CMDRDY asserted */
#else /* __rtems__ */
- at91_mci_setup_xdma(sc, false, block_size, block_count,
- data->data, data->len);
+ at91_mci_setup_xdma(sc, false, data->data, data->len);
#endif /* __rtems__ */
}
data->xfer_len = 0; /* XXX what's this? appears to be unused. */