aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorAnatolij Gustschin <agust@denx.de>2013-04-08 17:28:09 -0400
committerChris Ball <cjb@laptop.org>2013-04-12 15:13:41 -0400
commite48fc15aa205f380b2fc6d565724a55b1efd8083 (patch)
treeea229dfbfaeeabe15f606734959eeb76f3f34c18 /drivers/mmc
parent42477053c389900f28e200c198830c838989809f (diff)
mmc: mxcmmc: enable DMA support on mpc512x
Add SDHC DMA channel description to the mpc512x device tree to enable slave channel requesting in the mxcmmc driver. mpc512x DMA engine doesn't support endianness conversion when reading/writing data from peripheral's FIFO, so we have to swap data buffers before each DMA write and after each DMA read transfer manually. Since chained SDHC DMA transfers are not supported on mpc512x, limit 'max_segs' tunable parameter to one and initialise it to 64 only when running on i.MX platforms. Signed-off-by: Anatolij Gustschin <agust@denx.de> Acked-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/mxcmmc.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 5d528269587f..d5036353bddc 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -301,6 +301,29 @@ static void mxcmci_softreset(struct mxcmci_host *host)
301} 301}
302static int mxcmci_setup_dma(struct mmc_host *mmc); 302static int mxcmci_setup_dma(struct mmc_host *mmc);
303 303
304#if IS_ENABLED(CONFIG_PPC_MPC512x)
305static inline void buffer_swap32(u32 *buf, int len)
306{
307 int i;
308
309 for (i = 0; i < ((len + 3) / 4); i++) {
310 st_le32(buf, *buf);
311 buf++;
312 }
313}
314
315static void mxcmci_swap_buffers(struct mmc_data *data)
316{
317 struct scatterlist *sg;
318 int i;
319
320 for_each_sg(data->sg, sg, data->sg_len, i)
321 buffer_swap32(sg_virt(sg), sg->length);
322}
323#else
324static inline void mxcmci_swap_buffers(struct mmc_data *data) {}
325#endif
326
304static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) 327static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
305{ 328{
306 unsigned int nob = data->blocks; 329 unsigned int nob = data->blocks;
@@ -336,6 +359,8 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
336 } else { 359 } else {
337 host->dma_dir = DMA_TO_DEVICE; 360 host->dma_dir = DMA_TO_DEVICE;
338 slave_dirn = DMA_MEM_TO_DEV; 361 slave_dirn = DMA_MEM_TO_DEV;
362
363 mxcmci_swap_buffers(data);
339 } 364 }
340 365
341 nents = dma_map_sg(host->dma->device->dev, data->sg, 366 nents = dma_map_sg(host->dma->device->dev, data->sg,
@@ -461,9 +486,11 @@ static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
461 struct mmc_data *data = host->data; 486 struct mmc_data *data = host->data;
462 int data_error; 487 int data_error;
463 488
464 if (mxcmci_use_dma(host)) 489 if (mxcmci_use_dma(host)) {
465 dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len, 490 dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len,
466 host->dma_dir); 491 host->dma_dir);
492 mxcmci_swap_buffers(data);
493 }
467 494
468 if (stat & STATUS_ERR_MASK) { 495 if (stat & STATUS_ERR_MASK) {
469 dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n", 496 dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
@@ -1050,7 +1077,6 @@ static int mxcmci_probe(struct platform_device *pdev)
1050 mmc->caps |= MMC_CAP_SDIO_IRQ; 1077 mmc->caps |= MMC_CAP_SDIO_IRQ;
1051 1078
1052 /* MMC core transfer sizes tunable parameters */ 1079 /* MMC core transfer sizes tunable parameters */
1053 mmc->max_segs = 64;
1054 mmc->max_blk_size = 2048; 1080 mmc->max_blk_size = 2048;
1055 mmc->max_blk_count = 65535; 1081 mmc->max_blk_count = 65535;
1056 mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; 1082 mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
@@ -1069,6 +1095,11 @@ static int mxcmci_probe(struct platform_device *pdev)
1069 } else { 1095 } else {
1070 host->devtype = pdev->id_entry->driver_data; 1096 host->devtype = pdev->id_entry->driver_data;
1071 } 1097 }
1098
1099 /* adjust max_segs after devtype detection */
1100 if (!is_mpc512x_mmc(host))
1101 mmc->max_segs = 64;
1102
1072 host->mmc = mmc; 1103 host->mmc = mmc;
1073 host->pdata = pdata; 1104 host->pdata = pdata;
1074 spin_lock_init(&host->lock); 1105 spin_lock_init(&host->lock);