aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-07-30 14:29:03 -0400
committerHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-10-05 14:39:21 -0400
commit65e8b083fc8ec303499baa1924ae032d46d29990 (patch)
tree4c3e1b4cb6c18e2abe55e590b75e97edf4243cc7 /arch
parent965ebf33ea5afb6386f5b57cc71e6572253746b3 (diff)
atmel-mci: Add experimental DMA support
This adds support for DMA transfers through the generic DMA engine framework with the DMA slave extensions. The driver has been tested using mmc-block and ext3fs on several SD, SDHC and MMC+ cards. Reads and writes work fine, with read transfer rates up to 7.5 MiB/s on fast cards with debugging disabled. Unfortunately, the driver has been known to lock up from time to time with DMA enabled, so DMA support is currently optional and marked EXPERIMENTAL. However, I didn't see any problems while testing 13 different cards (MMC, SD and SDHC of different brands and sizes), so I suspect the "Initialize BLKR before sending data transfer command" fix that was posted earlier fixed this as well. Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/avr32/include/asm/atmel-mci.h4
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c16
2 files changed, 20 insertions, 0 deletions
diff --git a/arch/avr32/include/asm/atmel-mci.h b/arch/avr32/include/asm/atmel-mci.h
index 5d5ae1295cfd..59f3fadd0b68 100644
--- a/arch/avr32/include/asm/atmel-mci.h
+++ b/arch/avr32/include/asm/atmel-mci.h
@@ -3,6 +3,8 @@
3 3
4#define ATMEL_MCI_MAX_NR_SLOTS 2 4#define ATMEL_MCI_MAX_NR_SLOTS 2
5 5
6struct dma_slave;
7
6/** 8/**
7 * struct mci_slot_pdata - board-specific per-slot configuration 9 * struct mci_slot_pdata - board-specific per-slot configuration
8 * @bus_width: Number of data lines wired up the slot 10 * @bus_width: Number of data lines wired up the slot
@@ -26,9 +28,11 @@ struct mci_slot_pdata {
26 28
27/** 29/**
28 * struct mci_platform_data - board-specific MMC/SDcard configuration 30 * struct mci_platform_data - board-specific MMC/SDcard configuration
31 * @dma_slave: DMA slave interface to use in data transfers, or NULL.
29 * @slot: Per-slot configuration data. 32 * @slot: Per-slot configuration data.
30 */ 33 */
31struct mci_platform_data { 34struct mci_platform_data {
35 struct dma_slave *dma_slave;
32 struct mci_slot_pdata slot[ATMEL_MCI_MAX_NR_SLOTS]; 36 struct mci_slot_pdata slot[ATMEL_MCI_MAX_NR_SLOTS];
33}; 37};
34 38
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index 9967d5a3b6eb..f1b9a3ac2733 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -1273,6 +1273,7 @@ struct platform_device *__init
1273at32_add_device_mci(unsigned int id, struct mci_platform_data *data) 1273at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
1274{ 1274{
1275 struct platform_device *pdev; 1275 struct platform_device *pdev;
1276 struct dw_dma_slave *dws;
1276 1277
1277 if (id != 0 || !data) 1278 if (id != 0 || !data)
1278 return NULL; 1279 return NULL;
@@ -1289,6 +1290,21 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
1289 ARRAY_SIZE(atmel_mci0_resource))) 1290 ARRAY_SIZE(atmel_mci0_resource)))
1290 goto fail; 1291 goto fail;
1291 1292
1293 if (data->dma_slave)
1294 dws = kmemdup(to_dw_dma_slave(data->dma_slave),
1295 sizeof(struct dw_dma_slave), GFP_KERNEL);
1296 else
1297 dws = kzalloc(sizeof(struct dw_dma_slave), GFP_KERNEL);
1298
1299 dws->slave.dev = &pdev->dev;
1300 dws->slave.dma_dev = &dw_dmac0_device.dev;
1301 dws->slave.reg_width = DMA_SLAVE_WIDTH_32BIT;
1302 dws->cfg_hi = (DWC_CFGH_SRC_PER(0)
1303 | DWC_CFGH_DST_PER(1));
1304 dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL
1305 | DWC_CFGL_HS_SRC_POL);
1306
1307 data->dma_slave = &dws->slave;
1292 1308
1293 if (platform_device_add_data(pdev, data, 1309 if (platform_device_add_data(pdev, data,
1294 sizeof(struct mci_platform_data))) 1310 sizeof(struct mci_platform_data)))