aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/mxcmmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/mxcmmc.c')
-rw-r--r--drivers/mmc/host/mxcmmc.c181
1 files changed, 104 insertions, 77 deletions
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 4428594261c5..cc20e0259325 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -32,16 +32,14 @@
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/gpio.h> 33#include <linux/gpio.h>
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35#include <linux/dmaengine.h>
35 36
36#include <asm/dma.h> 37#include <asm/dma.h>
37#include <asm/irq.h> 38#include <asm/irq.h>
38#include <asm/sizes.h> 39#include <asm/sizes.h>
39#include <mach/mmc.h> 40#include <mach/mmc.h>
40 41
41#ifdef CONFIG_ARCH_MX2 42#include <mach/dma.h>
42#include <mach/dma-mx1-mx2.h>
43#define HAS_DMA
44#endif
45 43
46#define DRIVER_NAME "mxc-mmc" 44#define DRIVER_NAME "mxc-mmc"
47 45
@@ -118,7 +116,8 @@ struct mxcmci_host {
118 void __iomem *base; 116 void __iomem *base;
119 int irq; 117 int irq;
120 int detect_irq; 118 int detect_irq;
121 int dma; 119 struct dma_chan *dma;
120 struct dma_async_tx_descriptor *desc;
122 int do_dma; 121 int do_dma;
123 int default_irq_mask; 122 int default_irq_mask;
124 int use_sdio; 123 int use_sdio;
@@ -129,7 +128,6 @@ struct mxcmci_host {
129 struct mmc_command *cmd; 128 struct mmc_command *cmd;
130 struct mmc_data *data; 129 struct mmc_data *data;
131 130
132 unsigned int dma_nents;
133 unsigned int datasize; 131 unsigned int datasize;
134 unsigned int dma_dir; 132 unsigned int dma_dir;
135 133
@@ -144,6 +142,11 @@ struct mxcmci_host {
144 spinlock_t lock; 142 spinlock_t lock;
145 143
146 struct regulator *vcc; 144 struct regulator *vcc;
145
146 int burstlen;
147 int dmareq;
148 struct dma_slave_config dma_slave_config;
149 struct imx_dma_data dma_data;
147}; 150};
148 151
149static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios); 152static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
@@ -206,17 +209,16 @@ static void mxcmci_softreset(struct mxcmci_host *host)
206 209
207 writew(0xff, host->base + MMC_REG_RES_TO); 210 writew(0xff, host->base + MMC_REG_RES_TO);
208} 211}
212static int mxcmci_setup_dma(struct mmc_host *mmc);
209 213
210static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) 214static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
211{ 215{
212 unsigned int nob = data->blocks; 216 unsigned int nob = data->blocks;
213 unsigned int blksz = data->blksz; 217 unsigned int blksz = data->blksz;
214 unsigned int datasize = nob * blksz; 218 unsigned int datasize = nob * blksz;
215#ifdef HAS_DMA
216 struct scatterlist *sg; 219 struct scatterlist *sg;
217 int i; 220 int i, nents;
218 int ret; 221
219#endif
220 if (data->flags & MMC_DATA_STREAM) 222 if (data->flags & MMC_DATA_STREAM)
221 nob = 0xffff; 223 nob = 0xffff;
222 224
@@ -227,7 +229,9 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
227 writew(blksz, host->base + MMC_REG_BLK_LEN); 229 writew(blksz, host->base + MMC_REG_BLK_LEN);
228 host->datasize = datasize; 230 host->datasize = datasize;
229 231
230#ifdef HAS_DMA 232 if (!mxcmci_use_dma(host))
233 return 0;
234
231 for_each_sg(data->sg, sg, data->sg_len, i) { 235 for_each_sg(data->sg, sg, data->sg_len, i) {
232 if (sg->offset & 3 || sg->length & 3) { 236 if (sg->offset & 3 || sg->length & 3) {
233 host->do_dma = 0; 237 host->do_dma = 0;
@@ -235,34 +239,30 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
235 } 239 }
236 } 240 }
237 241
238 if (data->flags & MMC_DATA_READ) { 242 if (data->flags & MMC_DATA_READ)
239 host->dma_dir = DMA_FROM_DEVICE; 243 host->dma_dir = DMA_FROM_DEVICE;
240 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, 244 else
241 data->sg_len, host->dma_dir);
242
243 ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents,
244 datasize,
245 host->res->start + MMC_REG_BUFFER_ACCESS,
246 DMA_MODE_READ);
247 } else {
248 host->dma_dir = DMA_TO_DEVICE; 245 host->dma_dir = DMA_TO_DEVICE;
249 host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
250 data->sg_len, host->dma_dir);
251 246
252 ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, 247 nents = dma_map_sg(host->dma->device->dev, data->sg,
253 datasize, 248 data->sg_len, host->dma_dir);
254 host->res->start + MMC_REG_BUFFER_ACCESS, 249 if (nents != data->sg_len)
255 DMA_MODE_WRITE); 250 return -EINVAL;
256 } 251
252 host->desc = host->dma->device->device_prep_slave_sg(host->dma,
253 data->sg, data->sg_len, host->dma_dir,
254 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
257 255
258 if (ret) { 256 if (!host->desc) {
259 dev_err(mmc_dev(host->mmc), "failed to setup DMA : %d\n", ret); 257 dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len,
260 return ret; 258 host->dma_dir);
259 host->do_dma = 0;
260 return 0; /* Fall back to PIO */
261 } 261 }
262 wmb(); 262 wmb();
263 263
264 imx_dma_enable(host->dma); 264 dmaengine_submit(host->desc);
265#endif /* HAS_DMA */ 265
266 return 0; 266 return 0;
267} 267}
268 268
@@ -337,13 +337,11 @@ static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
337 struct mmc_data *data = host->data; 337 struct mmc_data *data = host->data;
338 int data_error; 338 int data_error;
339 339
340#ifdef HAS_DMA
341 if (mxcmci_use_dma(host)) { 340 if (mxcmci_use_dma(host)) {
342 imx_dma_disable(host->dma); 341 dmaengine_terminate_all(host->dma);
343 dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents, 342 dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len,
344 host->dma_dir); 343 host->dma_dir);
345 } 344 }
346#endif
347 345
348 if (stat & STATUS_ERR_MASK) { 346 if (stat & STATUS_ERR_MASK) {
349 dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n", 347 dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
@@ -545,7 +543,6 @@ static void mxcmci_datawork(struct work_struct *work)
545 } 543 }
546} 544}
547 545
548#ifdef HAS_DMA
549static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat) 546static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat)
550{ 547{
551 struct mmc_data *data = host->data; 548 struct mmc_data *data = host->data;
@@ -568,7 +565,6 @@ static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat)
568 mxcmci_finish_request(host, host->req); 565 mxcmci_finish_request(host, host->req);
569 } 566 }
570} 567}
571#endif /* HAS_DMA */
572 568
573static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat) 569static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)
574{ 570{
@@ -606,12 +602,10 @@ static irqreturn_t mxcmci_irq(int irq, void *devid)
606 sdio_irq = (stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio; 602 sdio_irq = (stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio;
607 spin_unlock_irqrestore(&host->lock, flags); 603 spin_unlock_irqrestore(&host->lock, flags);
608 604
609#ifdef HAS_DMA
610 if (mxcmci_use_dma(host) && 605 if (mxcmci_use_dma(host) &&
611 (stat & (STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE))) 606 (stat & (STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE)))
612 writel(STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE, 607 writel(STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE,
613 host->base + MMC_REG_STATUS); 608 host->base + MMC_REG_STATUS);
614#endif
615 609
616 if (sdio_irq) { 610 if (sdio_irq) {
617 writel(STATUS_SDIO_INT_ACTIVE, host->base + MMC_REG_STATUS); 611 writel(STATUS_SDIO_INT_ACTIVE, host->base + MMC_REG_STATUS);
@@ -621,14 +615,14 @@ static irqreturn_t mxcmci_irq(int irq, void *devid)
621 if (stat & STATUS_END_CMD_RESP) 615 if (stat & STATUS_END_CMD_RESP)
622 mxcmci_cmd_done(host, stat); 616 mxcmci_cmd_done(host, stat);
623 617
624#ifdef HAS_DMA
625 if (mxcmci_use_dma(host) && 618 if (mxcmci_use_dma(host) &&
626 (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE))) 619 (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
627 mxcmci_data_done(host, stat); 620 mxcmci_data_done(host, stat);
628#endif 621
629 if (host->default_irq_mask && 622 if (host->default_irq_mask &&
630 (stat & (STATUS_CARD_INSERTION | STATUS_CARD_REMOVAL))) 623 (stat & (STATUS_CARD_INSERTION | STATUS_CARD_REMOVAL)))
631 mmc_detect_change(host->mmc, msecs_to_jiffies(200)); 624 mmc_detect_change(host->mmc, msecs_to_jiffies(200));
625
632 return IRQ_HANDLED; 626 return IRQ_HANDLED;
633} 627}
634 628
@@ -642,9 +636,10 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
642 636
643 host->req = req; 637 host->req = req;
644 host->cmdat &= ~CMD_DAT_CONT_INIT; 638 host->cmdat &= ~CMD_DAT_CONT_INIT;
645#ifdef HAS_DMA 639
646 host->do_dma = 1; 640 if (host->dma)
647#endif 641 host->do_dma = 1;
642
648 if (req->data) { 643 if (req->data) {
649 error = mxcmci_setup_data(host, req->data); 644 error = mxcmci_setup_data(host, req->data);
650 if (error) { 645 if (error) {
@@ -660,6 +655,7 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
660 } 655 }
661 656
662 error = mxcmci_start_cmd(host, req->cmd, cmdat); 657 error = mxcmci_start_cmd(host, req->cmd, cmdat);
658
663out: 659out:
664 if (error) 660 if (error)
665 mxcmci_finish_request(host, req); 661 mxcmci_finish_request(host, req);
@@ -698,22 +694,46 @@ static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
698 prescaler, divider, clk_in, clk_ios); 694 prescaler, divider, clk_in, clk_ios);
699} 695}
700 696
697static int mxcmci_setup_dma(struct mmc_host *mmc)
698{
699 struct mxcmci_host *host = mmc_priv(mmc);
700 struct dma_slave_config *config = &host->dma_slave_config;
701
702 config->dst_addr = host->res->start + MMC_REG_BUFFER_ACCESS;
703 config->src_addr = host->res->start + MMC_REG_BUFFER_ACCESS;
704 config->dst_addr_width = 4;
705 config->src_addr_width = 4;
706 config->dst_maxburst = host->burstlen;
707 config->src_maxburst = host->burstlen;
708
709 return dmaengine_slave_config(host->dma, config);
710}
711
701static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 712static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
702{ 713{
703 struct mxcmci_host *host = mmc_priv(mmc); 714 struct mxcmci_host *host = mmc_priv(mmc);
704#ifdef HAS_DMA 715 int burstlen, ret;
705 unsigned int blen; 716
706 /* 717 /*
707 * use burstlen of 64 in 4 bit mode (--> reg value 0) 718 * use burstlen of 64 in 4 bit mode (--> reg value 0)
708 * use burstlen of 16 in 1 bit mode (--> reg value 16) 719 * use burstlen of 16 in 1 bit mode (--> reg value 16)
709 */ 720 */
710 if (ios->bus_width == MMC_BUS_WIDTH_4) 721 if (ios->bus_width == MMC_BUS_WIDTH_4)
711 blen = 0; 722 burstlen = 64;
712 else 723 else
713 blen = 16; 724 burstlen = 16;
725
726 if (mxcmci_use_dma(host) && burstlen != host->burstlen) {
727 host->burstlen = burstlen;
728 ret = mxcmci_setup_dma(mmc);
729 if (ret) {
730 dev_err(mmc_dev(host->mmc),
731 "failed to config DMA channel. Falling back to PIO\n");
732 dma_release_channel(host->dma);
733 host->do_dma = 0;
734 }
735 }
714 736
715 imx_dma_config_burstlen(host->dma, blen);
716#endif
717 if (ios->bus_width == MMC_BUS_WIDTH_4) 737 if (ios->bus_width == MMC_BUS_WIDTH_4)
718 host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4; 738 host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;
719 else 739 else
@@ -794,6 +814,18 @@ static void mxcmci_init_card(struct mmc_host *host, struct mmc_card *card)
794 host->caps |= MMC_CAP_4_BIT_DATA; 814 host->caps |= MMC_CAP_4_BIT_DATA;
795} 815}
796 816
817static bool filter(struct dma_chan *chan, void *param)
818{
819 struct mxcmci_host *host = param;
820
821 if (!imx_dma_is_general_purpose(chan))
822 return false;
823
824 chan->private = &host->dma_data;
825
826 return true;
827}
828
797static const struct mmc_host_ops mxcmci_ops = { 829static const struct mmc_host_ops mxcmci_ops = {
798 .request = mxcmci_request, 830 .request = mxcmci_request,
799 .set_ios = mxcmci_set_ios, 831 .set_ios = mxcmci_set_ios,
@@ -808,6 +840,7 @@ static int mxcmci_probe(struct platform_device *pdev)
808 struct mxcmci_host *host = NULL; 840 struct mxcmci_host *host = NULL;
809 struct resource *iores, *r; 841 struct resource *iores, *r;
810 int ret = 0, irq; 842 int ret = 0, irq;
843 dma_cap_mask_t mask;
811 844
812 printk(KERN_INFO "i.MX SDHC driver\n"); 845 printk(KERN_INFO "i.MX SDHC driver\n");
813 846
@@ -883,29 +916,23 @@ static int mxcmci_probe(struct platform_device *pdev)
883 916
884 writel(host->default_irq_mask, host->base + MMC_REG_INT_CNTR); 917 writel(host->default_irq_mask, host->base + MMC_REG_INT_CNTR);
885 918
886#ifdef HAS_DMA
887 host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW);
888 if (host->dma < 0) {
889 dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n");
890 ret = -EBUSY;
891 goto out_clk_put;
892 }
893
894 r = platform_get_resource(pdev, IORESOURCE_DMA, 0); 919 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
895 if (!r) { 920 if (r) {
896 ret = -EINVAL; 921 host->dmareq = r->start;
897 goto out_free_dma; 922 host->dma_data.peripheral_type = IMX_DMATYPE_SDHC;
923 host->dma_data.priority = DMA_PRIO_LOW;
924 host->dma_data.dma_request = host->dmareq;
925 dma_cap_zero(mask);
926 dma_cap_set(DMA_SLAVE, mask);
927 host->dma = dma_request_channel(mask, filter, host);
928 if (host->dma)
929 mmc->max_seg_size = dma_get_max_seg_size(
930 host->dma->device->dev);
898 } 931 }
899 932
900 ret = imx_dma_config_channel(host->dma, 933 if (!host->dma)
901 IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_FIFO, 934 dev_info(mmc_dev(host->mmc), "dma not available. Using PIO\n");
902 IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR, 935
903 r->start, 0);
904 if (ret) {
905 dev_err(mmc_dev(host->mmc), "failed to config DMA channel\n");
906 goto out_free_dma;
907 }
908#endif
909 INIT_WORK(&host->datawork, mxcmci_datawork); 936 INIT_WORK(&host->datawork, mxcmci_datawork);
910 937
911 ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host); 938 ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host);
@@ -928,9 +955,8 @@ static int mxcmci_probe(struct platform_device *pdev)
928out_free_irq: 955out_free_irq:
929 free_irq(host->irq, host); 956 free_irq(host->irq, host);
930out_free_dma: 957out_free_dma:
931#ifdef HAS_DMA 958 if (host->dma)
932 imx_dma_free(host->dma); 959 dma_release_channel(host->dma);
933#endif
934out_clk_put: 960out_clk_put:
935 clk_disable(host->clk); 961 clk_disable(host->clk);
936 clk_put(host->clk); 962 clk_put(host->clk);
@@ -960,9 +986,10 @@ static int mxcmci_remove(struct platform_device *pdev)
960 986
961 free_irq(host->irq, host); 987 free_irq(host->irq, host);
962 iounmap(host->base); 988 iounmap(host->base);
963#ifdef HAS_DMA 989
964 imx_dma_free(host->dma); 990 if (host->dma)
965#endif 991 dma_release_channel(host->dma);
992
966 clk_disable(host->clk); 993 clk_disable(host->clk);
967 clk_put(host->clk); 994 clk_put(host->clk);
968 995