From 22caf4860a8a73a2f218125a12765affef88d9c3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Imre=20Vad=C3=A1sz?= Date: Thu, 5 Jan 2017 19:34:24 +0100 Subject: [PATCH] sdhci - Use bus_dmamem_coherent for allocating memory for sdma DMA. * While there, rename various constants which are related to SDMA (and not going to be used for ADMA2) from *_DMA_* names to *_SDMA_*. --- sys/dev/disk/sdhci/sdhci.c | 121 +++++++++++++++++------------------------ sys/dev/disk/sdhci/sdhci.h | 15 ++--- sys/dev/disk/sdhci/sdhci_pci.c | 6 +- 3 files changed, 59 insertions(+), 83 deletions(-) diff --git a/sys/dev/disk/sdhci/sdhci.c b/sys/dev/disk/sdhci/sdhci.c index cb64e5a631..451cbec868 100644 --- a/sys/dev/disk/sdhci/sdhci.c +++ b/sys/dev/disk/sdhci/sdhci.c @@ -99,16 +99,6 @@ static void sdhci_card_task(void *, int); #define BCM577XX_CTRL_CLKSEL_64MHZ 0x3 -static void -sdhci_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) -{ - if (error != 0) { - kprintf("getaddr: error %d\n", error); - return; - } - *(bus_addr_t *)arg = segs[0].ds_addr; -} - static int slot_printf(struct sdhci_slot *slot, const char * fmt, ...) { @@ -130,8 +120,8 @@ sdhci_dumpregs(struct sdhci_slot *slot) slot_printf(slot, "============== REGISTER DUMP ==============\n"); - slot_printf(slot, "Sys addr: 0x%08x | Version: 0x%08x\n", - RD4(slot, SDHCI_DMA_ADDRESS), RD2(slot, SDHCI_HOST_VERSION)); + slot_printf(slot, "SDMA addr: 0x%08x | Version: 0x%08x\n", + RD4(slot, SDHCI_SDMA_ADDRESS), RD2(slot, SDHCI_HOST_VERSION)); slot_printf(slot, "Blk size: 0x%08x | Blk cnt: 0x%08x\n", RD2(slot, SDHCI_BLOCK_SIZE), RD2(slot, SDHCI_BLOCK_COUNT)); slot_printf(slot, "Argument: 0x%08x | Trn mode: 0x%08x\n", @@ -517,38 +507,16 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num) slot->num = num; slot->bus = dev; - /* Allocate DMA tag. */ - err = bus_dma_tag_create(bus_get_dma_tag(dev), - DMA_BLOCK_SIZE, 0, BUS_SPACE_MAXADDR_32BIT, - BUS_SPACE_MAXADDR, NULL, NULL, - DMA_BLOCK_SIZE, 1, DMA_BLOCK_SIZE, - BUS_DMA_ALLOCNOW, - &slot->dmatag); - if (err != 0) { - device_printf(dev, "Can't create DMA tag\n"); - SDHCI_LOCK_DESTROY(slot); - return (err); - } - /* Allocate DMA memory. */ - err = bus_dmamem_alloc(slot->dmatag, (void **)&slot->dmamem, - BUS_DMA_NOWAIT, &slot->dmamap); + /* Allocate DMA memory for SDMA. */ + err = bus_dmamem_coherent(bus_get_dma_tag(dev), + DMA_BLOCK_SIZE, 0, BUS_SPACE_MAXADDR_32BIT, + BUS_SPACE_MAXADDR, DMA_BLOCK_SIZE, BUS_DMA_NOWAIT, + &slot->sdma_mem); if (err != 0) { - device_printf(dev, "Can't alloc DMA memory\n"); + device_printf(dev, "Can't alloc DMA memory for SDMA\n"); SDHCI_LOCK_DESTROY(slot); return (err); } - /* Map the memory. */ - err = bus_dmamap_load(slot->dmatag, slot->dmamap, - (void *)slot->dmamem, DMA_BLOCK_SIZE, - sdhci_getaddr, &slot->paddr, 0); - if (err != 0 || slot->paddr == 0) { - device_printf(dev, "Can't load DMA memory\n"); - SDHCI_LOCK_DESTROY(slot); - if(err) - return (err); - else - return (EFAULT); - } /* Initialize slot. */ sdhci_init(slot); @@ -617,19 +585,19 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num) slot->host.caps |= MMC_CAP_HSPEED; /* Decide if we have usable DMA. */ if (caps & SDHCI_CAN_DO_DMA) - slot->opt |= SDHCI_HAVE_DMA; + slot->opt |= SDHCI_HAVE_SDMA; if (slot->quirks & SDHCI_QUIRK_BROKEN_DMA) - slot->opt &= ~SDHCI_HAVE_DMA; - if (slot->quirks & SDHCI_QUIRK_FORCE_DMA) - slot->opt |= SDHCI_HAVE_DMA; + slot->opt &= ~SDHCI_HAVE_SDMA; + if (slot->quirks & SDHCI_QUIRK_FORCE_SDMA) + slot->opt |= SDHCI_HAVE_SDMA; /* * Use platform-provided transfer backend * with PIO as a fallback mechanism */ if (slot->opt & SDHCI_PLATFORM_TRANSFER) - slot->opt &= ~SDHCI_HAVE_DMA; + slot->opt &= ~SDHCI_HAVE_SDMA; if (bootverbose || sdhci_debug) { slot_printf(slot, "%uMHz%s %s%s%s%s %s\n", @@ -640,7 +608,7 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num) (caps & SDHCI_CAN_VDD_330) ? " 3.3V" : "", (caps & SDHCI_CAN_VDD_300) ? " 3.0V" : "", (caps & SDHCI_CAN_VDD_180) ? " 1.8V" : "", - (slot->opt & SDHCI_HAVE_DMA) ? "DMA" : "PIO"); + (slot->opt & SDHCI_HAVE_SDMA) ? "SDMA" : "PIO"); sdhci_dumpregs(slot); } @@ -666,6 +634,7 @@ int sdhci_cleanup_slot(struct sdhci_slot *slot) { device_t d; + bus_dmamem_t *sdma; callout_drain(&slot->timeout_callout); callout_drain(&slot->card_callout); @@ -681,9 +650,11 @@ sdhci_cleanup_slot(struct sdhci_slot *slot) SDHCI_LOCK(slot); sdhci_reset(slot, SDHCI_RESET_ALL); SDHCI_UNLOCK(slot); - bus_dmamap_unload(slot->dmatag, slot->dmamap); - bus_dmamem_free(slot->dmatag, slot->dmamem, slot->dmamap); - bus_dma_tag_destroy(slot->dmatag); + + sdma = &slot->sdma_mem; + bus_dmamap_unload(sdma->dmem_tag, sdma->dmem_map); + bus_dmamem_free(sdma->dmem_tag, sdma->dmem_addr, sdma->dmem_map); + bus_dma_tag_destroy(sdma->dmem_tag); SDHCI_LOCK_DESTROY(slot); @@ -804,7 +775,7 @@ sdhci_set_transfer_mode(struct sdhci_slot *slot, mode |= SDHCI_TRNS_READ; if (slot->req->stop) mode |= SDHCI_TRNS_ACMD12; - if (slot->flags & SDHCI_USE_DMA) + if (slot->flags & SDHCI_USE_SDMA) mode |= SDHCI_TRNS_DMA; WR2(slot, SDHCI_TRANSFER_MODE, mode); @@ -1000,29 +971,31 @@ sdhci_start_data(struct sdhci_slot *slot, struct mmc_data *data) return; /* Use DMA if possible. */ - if ((slot->opt & SDHCI_HAVE_DMA)) - slot->flags |= SDHCI_USE_DMA; - /* If data is small, broken DMA may return zeroes instead of data, */ + if ((slot->opt & SDHCI_HAVE_SDMA)) + slot->flags |= SDHCI_USE_SDMA; + /* If data is small, broken DMA may return zeroes instead of data. */ if ((slot->quirks & SDHCI_QUIRK_BROKEN_TIMINGS) && (data->len <= 512)) - slot->flags &= ~SDHCI_USE_DMA; + slot->flags &= ~SDHCI_USE_SDMA; /* Some controllers require even block sizes. */ if ((slot->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE) && ((data->len) & 0x3)) - slot->flags &= ~SDHCI_USE_DMA; + slot->flags &= ~SDHCI_USE_SDMA; /* Load DMA buffer. */ - if (slot->flags & SDHCI_USE_DMA) { + if (slot->flags & SDHCI_USE_SDMA) { + bus_dmamem_t *sdma = &slot->sdma_mem; + if (data->flags & MMC_DATA_READ) { - bus_dmamap_sync(slot->dmatag, slot->dmamap, + bus_dmamap_sync(sdma->dmem_tag, sdma->dmem_map, BUS_DMASYNC_PREREAD); } else { - memcpy(slot->dmamem, data->data, + memcpy(sdma->dmem_addr, data->data, (data->len < DMA_BLOCK_SIZE) ? data->len : DMA_BLOCK_SIZE); - bus_dmamap_sync(slot->dmatag, slot->dmamap, + bus_dmamap_sync(sdma->dmem_tag, sdma->dmem_map, BUS_DMASYNC_PREWRITE); } - WR4(slot, SDHCI_DMA_ADDRESS, slot->paddr); + WR4(slot, SDHCI_SDMA_ADDRESS, sdma->dmem_busaddr); /* Interrupt aggregation: Mask border interrupt * for the last page and unmask else. */ if (data->len == DMA_BLOCK_SIZE) @@ -1053,15 +1026,18 @@ sdhci_finish_data(struct sdhci_slot *slot) slot->intmask |= SDHCI_INT_RESPONSE); } /* Unload rest of data from DMA buffer. */ - if (!slot->data_done && (slot->flags & SDHCI_USE_DMA)) { + if (!slot->data_done && (slot->flags & SDHCI_USE_SDMA)) { + bus_dmamem_t *sdma = &slot->sdma_mem; + if (data->flags & MMC_DATA_READ) { size_t left = data->len - slot->offset; - bus_dmamap_sync(slot->dmatag, slot->dmamap, + bus_dmamap_sync(sdma->dmem_tag, sdma->dmem_map, BUS_DMASYNC_POSTREAD); - memcpy((u_char*)data->data + slot->offset, slot->dmamem, + memcpy((u_char*)data->data + slot->offset, + sdma->dmem_addr, (left < DMA_BLOCK_SIZE)?left:DMA_BLOCK_SIZE); } else - bus_dmamap_sync(slot->dmatag, slot->dmamap, + bus_dmamap_sync(sdma->dmem_tag, sdma->dmem_map, BUS_DMASYNC_POSTWRITE); } slot->data_done = 1; @@ -1247,29 +1223,32 @@ sdhci_data_irq(struct sdhci_slot *slot, uint32_t intmask) /* Handle DMA border. */ if (intmask & SDHCI_INT_DMA_END) { struct mmc_data *data = slot->curcmd->data; + bus_dmamem_t *sdma = &slot->sdma_mem; size_t left; /* Unload DMA buffer... */ left = data->len - slot->offset; if (data->flags & MMC_DATA_READ) { - bus_dmamap_sync(slot->dmatag, slot->dmamap, + bus_dmamap_sync(sdma->dmem_tag, sdma->dmem_map, BUS_DMASYNC_POSTREAD); - memcpy((u_char*)data->data + slot->offset, slot->dmamem, + memcpy((u_char*)data->data + slot->offset, + sdma->dmem_addr, (left < DMA_BLOCK_SIZE)?left:DMA_BLOCK_SIZE); } else { - bus_dmamap_sync(slot->dmatag, slot->dmamap, + bus_dmamap_sync(sdma->dmem_tag, sdma->dmem_map, BUS_DMASYNC_POSTWRITE); } /* ... and reload it again. */ slot->offset += DMA_BLOCK_SIZE; left = data->len - slot->offset; if (data->flags & MMC_DATA_READ) { - bus_dmamap_sync(slot->dmatag, slot->dmamap, + bus_dmamap_sync(sdma->dmem_tag, sdma->dmem_map, BUS_DMASYNC_PREREAD); } else { - memcpy(slot->dmamem, (u_char*)data->data + slot->offset, + memcpy(sdma->dmem_addr, + (u_char*)data->data + slot->offset, (left < DMA_BLOCK_SIZE)?left:DMA_BLOCK_SIZE); - bus_dmamap_sync(slot->dmatag, slot->dmamap, + bus_dmamap_sync(sdma->dmem_tag, sdma->dmem_map, BUS_DMASYNC_PREWRITE); } /* Interrupt aggregation: Mask border interrupt @@ -1279,7 +1258,7 @@ sdhci_data_irq(struct sdhci_slot *slot, uint32_t intmask) WR4(slot, SDHCI_SIGNAL_ENABLE, slot->intmask); } /* Restart DMA. */ - WR4(slot, SDHCI_DMA_ADDRESS, slot->paddr); + WR4(slot, SDHCI_SDMA_ADDRESS, sdma->dmem_busaddr); } /* We have got all data. */ if (intmask & SDHCI_INT_DATA_END) { diff --git a/sys/dev/disk/sdhci/sdhci.h b/sys/dev/disk/sdhci/sdhci.h index ca9e67d181..dc67692637 100644 --- a/sys/dev/disk/sdhci/sdhci.h +++ b/sys/dev/disk/sdhci/sdhci.h @@ -33,8 +33,8 @@ /* Controller doesn't honor resets unless we touch the clock register */ #define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) -/* Controller really supports DMA */ -#define SDHCI_QUIRK_FORCE_DMA (1<<1) +/* Controller really supports SDMA */ +#define SDHCI_QUIRK_FORCE_SDMA (1<<1) /* Controller has unusable DMA engine */ #define SDHCI_QUIRK_BROKEN_DMA (1<<2) /* Controller doesn't like to be reset when there is no card inserted. */ @@ -69,7 +69,7 @@ /* * Controller registers */ -#define SDHCI_DMA_ADDRESS 0x00 +#define SDHCI_SDMA_ADDRESS 0x00 #define SDHCI_BLOCK_SIZE 0x04 #define SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF)) @@ -269,17 +269,14 @@ struct sdhci_slot { device_t dev; /* Slot device */ u_char num; /* Slot number */ u_char opt; /* Slot options */ -#define SDHCI_HAVE_DMA 1 +#define SDHCI_HAVE_SDMA 1 #define SDHCI_PLATFORM_TRANSFER 2 u_char version; int timeout; /* Transfer timeout */ int failures; /* N Failures in a row */ uint32_t max_clk; /* Max possible freq */ uint32_t timeout_clk; /* Timeout freq */ - bus_dma_tag_t dmatag; - bus_dmamap_t dmamap; - u_char *dmamem; - bus_addr_t paddr; /* DMA buffer address */ + bus_dmamem_t sdma_mem; /* DMA block for SDMA */ struct task card_task; /* Card presence check task */ struct callout card_callout; /* Card insert delay callout */ struct callout timeout_callout;/* Card command/data response timeout */ @@ -298,7 +295,7 @@ struct sdhci_slot { u_char flags; /* Request execution flags */ #define CMD_STARTED 1 #define STOP_STARTED 2 -#define SDHCI_USE_DMA 4 /* Use DMA for this req. */ +#define SDHCI_USE_SDMA 4 /* Use SDMA for this req. */ #define PLATFORM_DATA_STARTED 8 /* Data transfer is handled by platform */ struct lock lock; /* Slot mutex */ }; diff --git a/sys/dev/disk/sdhci/sdhci_pci.c b/sys/dev/disk/sdhci/sdhci_pci.c index 7cd741c3a7..1cd4d738a5 100644 --- a/sys/dev/disk/sdhci/sdhci_pci.c +++ b/sys/dev/disk/sdhci/sdhci_pci.c @@ -80,14 +80,14 @@ static const struct sdhci_device { u_int quirks; } sdhci_devices[] = { { 0x08221180, 0xffff, "RICOH R5C822 SD", - SDHCI_QUIRK_FORCE_DMA }, + SDHCI_QUIRK_FORCE_SDMA }, { 0xe8221180, 0xffff, "RICOH R5CE822 SD", - SDHCI_QUIRK_FORCE_DMA | + SDHCI_QUIRK_FORCE_SDMA | SDHCI_QUIRK_LOWER_FREQUENCY }, { 0xe8231180, 0xffff, "RICOH R5CE823 SD", SDHCI_QUIRK_LOWER_FREQUENCY }, { 0x8034104c, 0xffff, "TI XX21/XX11 SD", - SDHCI_QUIRK_FORCE_DMA }, + SDHCI_QUIRK_FORCE_SDMA }, { 0x05501524, 0xffff, "ENE CB712 SD", SDHCI_QUIRK_BROKEN_TIMINGS }, { 0x05511524, 0xffff, "ENE CB712 SD 2", -- 2.11.4.GIT