aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorNicolas Ferre <nicolas.ferre@atmel.com>2009-12-14 21:01:31 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-15 11:53:35 -0500
commit74791a2dc8dc2af3feeaf3242d642ff58d33bd30 (patch)
tree2062b23a6bd0063f4999e73bb0fb9bd22839ffb7 /drivers/mmc
parent2635d1ba711560d521f6218c585a3e0401f566e1 (diff)
mmc: atmel-mci: new MCI2 module support in atmel-mci driver
This new revision of the IP adds some improvements to the MCI already present in several Atmel SOC. Some new registers are added and a particular way of handling DMA interaction lead to a new sequence in function call which is backward compatible: On MCI2, we must set the DMAEN bit to enable the DMA handshaking interface. This must happen before the data transfer command is sent. A new function is able to differentiate MCI2 code and is based on knowledge of processor id (cpu_is_xxx()). Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com> Cc: <linux-mmc@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/atmel-mci.c85
1 files changed, 75 insertions, 10 deletions
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index ba8b219d44c1..8072128e933b 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -94,6 +94,7 @@ struct atmel_mci_dma {
94 * @need_clock_update: Update the clock rate before the next request. 94 * @need_clock_update: Update the clock rate before the next request.
95 * @need_reset: Reset controller before next request. 95 * @need_reset: Reset controller before next request.
96 * @mode_reg: Value of the MR register. 96 * @mode_reg: Value of the MR register.
97 * @cfg_reg: Value of the CFG register.
97 * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus 98 * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus
98 * rate and timeout calculations. 99 * rate and timeout calculations.
99 * @mapbase: Physical address of the MMIO registers. 100 * @mapbase: Physical address of the MMIO registers.
@@ -157,6 +158,7 @@ struct atmel_mci {
157 bool need_clock_update; 158 bool need_clock_update;
158 bool need_reset; 159 bool need_reset;
159 u32 mode_reg; 160 u32 mode_reg;
161 u32 cfg_reg;
160 unsigned long bus_hz; 162 unsigned long bus_hz;
161 unsigned long mapbase; 163 unsigned long mapbase;
162 struct clk *mck; 164 struct clk *mck;
@@ -225,6 +227,19 @@ static bool mci_has_rwproof(void)
225} 227}
226 228
227/* 229/*
230 * The new MCI2 module isn't 100% compatible with the old MCI module,
231 * and it has a few nice features which we want to use...
232 */
233static inline bool atmci_is_mci2(void)
234{
235 if (cpu_is_at91sam9g45())
236 return true;
237
238 return false;
239}
240
241
242/*
228 * The debugfs stuff below is mostly optimized away when 243 * The debugfs stuff below is mostly optimized away when
229 * CONFIG_DEBUG_FS is not set. 244 * CONFIG_DEBUG_FS is not set.
230 */ 245 */
@@ -359,12 +374,33 @@ static int atmci_regs_show(struct seq_file *s, void *v)
359 buf[MCI_BLKR / 4], 374 buf[MCI_BLKR / 4],
360 buf[MCI_BLKR / 4] & 0xffff, 375 buf[MCI_BLKR / 4] & 0xffff,
361 (buf[MCI_BLKR / 4] >> 16) & 0xffff); 376 (buf[MCI_BLKR / 4] >> 16) & 0xffff);
377 if (atmci_is_mci2())
378 seq_printf(s, "CSTOR:\t0x%08x\n", buf[MCI_CSTOR / 4]);
362 379
363 /* Don't read RSPR and RDR; it will consume the data there */ 380 /* Don't read RSPR and RDR; it will consume the data there */
364 381
365 atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]); 382 atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]);
366 atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]); 383 atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]);
367 384
385 if (atmci_is_mci2()) {
386 u32 val;
387
388 val = buf[MCI_DMA / 4];
389 seq_printf(s, "DMA:\t0x%08x OFFSET=%u CHKSIZE=%u%s\n",
390 val, val & 3,
391 ((val >> 4) & 3) ?
392 1 << (((val >> 4) & 3) + 1) : 1,
393 val & MCI_DMAEN ? " DMAEN" : "");
394
395 val = buf[MCI_CFG / 4];
396 seq_printf(s, "CFG:\t0x%08x%s%s%s%s\n",
397 val,
398 val & MCI_CFG_FIFOMODE_1DATA ? " FIFOMODE_ONE_DATA" : "",
399 val & MCI_CFG_FERRCTRL_COR ? " FERRCTRL_CLEAR_ON_READ" : "",
400 val & MCI_CFG_HSMODE ? " HSMODE" : "",
401 val & MCI_CFG_LSYNC ? " LSYNC" : "");
402 }
403
368 kfree(buf); 404 kfree(buf);
369 405
370 return 0; 406 return 0;
@@ -559,6 +595,10 @@ static void atmci_dma_complete(void *arg)
559 595
560 dev_vdbg(&host->pdev->dev, "DMA complete\n"); 596 dev_vdbg(&host->pdev->dev, "DMA complete\n");
561 597
598 if (atmci_is_mci2())
599 /* Disable DMA hardware handshaking on MCI */
600 mci_writel(host, DMA, mci_readl(host, DMA) & ~MCI_DMAEN);
601
562 atmci_dma_cleanup(host); 602 atmci_dma_cleanup(host);
563 603
564 /* 604 /*
@@ -594,7 +634,7 @@ static void atmci_dma_complete(void *arg)
594} 634}
595 635
596static int 636static int
597atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data) 637atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
598{ 638{
599 struct dma_chan *chan; 639 struct dma_chan *chan;
600 struct dma_async_tx_descriptor *desc; 640 struct dma_async_tx_descriptor *desc;
@@ -626,6 +666,9 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
626 if (!chan) 666 if (!chan)
627 return -ENODEV; 667 return -ENODEV;
628 668
669 if (atmci_is_mci2())
670 mci_writel(host, DMA, MCI_DMA_CHKSIZE(3) | MCI_DMAEN);
671
629 if (data->flags & MMC_DATA_READ) 672 if (data->flags & MMC_DATA_READ)
630 direction = DMA_FROM_DEVICE; 673 direction = DMA_FROM_DEVICE;
631 else 674 else
@@ -643,10 +686,6 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
643 host->dma.data_desc = desc; 686 host->dma.data_desc = desc;
644 desc->callback = atmci_dma_complete; 687 desc->callback = atmci_dma_complete;
645 desc->callback_param = host; 688 desc->callback_param = host;
646 desc->tx_submit(desc);
647
648 /* Go! */
649 chan->device->device_issue_pending(chan);
650 689
651 return 0; 690 return 0;
652unmap_exit: 691unmap_exit:
@@ -654,13 +693,26 @@ unmap_exit:
654 return -ENOMEM; 693 return -ENOMEM;
655} 694}
656 695
696static void atmci_submit_data(struct atmel_mci *host)
697{
698 struct dma_chan *chan = host->data_chan;
699 struct dma_async_tx_descriptor *desc = host->dma.data_desc;
700
701 if (chan) {
702 desc->tx_submit(desc);
703 chan->device->device_issue_pending(chan);
704 }
705}
706
657#else /* CONFIG_MMC_ATMELMCI_DMA */ 707#else /* CONFIG_MMC_ATMELMCI_DMA */
658 708
659static int atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data) 709static int atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
660{ 710{
661 return -ENOSYS; 711 return -ENOSYS;
662} 712}
663 713
714static void atmci_submit_data(struct atmel_mci *host) {}
715
664static void atmci_stop_dma(struct atmel_mci *host) 716static void atmci_stop_dma(struct atmel_mci *host)
665{ 717{
666 /* Data transfer was stopped by the interrupt handler */ 718 /* Data transfer was stopped by the interrupt handler */
@@ -674,7 +726,7 @@ static void atmci_stop_dma(struct atmel_mci *host)
674 * Returns a mask of interrupt flags to be enabled after the whole 726 * Returns a mask of interrupt flags to be enabled after the whole
675 * request has been prepared. 727 * request has been prepared.
676 */ 728 */
677static u32 atmci_submit_data(struct atmel_mci *host, struct mmc_data *data) 729static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data)
678{ 730{
679 u32 iflags; 731 u32 iflags;
680 732
@@ -685,7 +737,7 @@ static u32 atmci_submit_data(struct atmel_mci *host, struct mmc_data *data)
685 host->data = data; 737 host->data = data;
686 738
687 iflags = ATMCI_DATA_ERROR_FLAGS; 739 iflags = ATMCI_DATA_ERROR_FLAGS;
688 if (atmci_submit_data_dma(host, data)) { 740 if (atmci_prepare_data_dma(host, data)) {
689 host->data_chan = NULL; 741 host->data_chan = NULL;
690 742
691 /* 743 /*
@@ -731,6 +783,8 @@ static void atmci_start_request(struct atmel_mci *host,
731 mci_writel(host, CR, MCI_CR_SWRST); 783 mci_writel(host, CR, MCI_CR_SWRST);
732 mci_writel(host, CR, MCI_CR_MCIEN); 784 mci_writel(host, CR, MCI_CR_MCIEN);
733 mci_writel(host, MR, host->mode_reg); 785 mci_writel(host, MR, host->mode_reg);
786 if (atmci_is_mci2())
787 mci_writel(host, CFG, host->cfg_reg);
734 host->need_reset = false; 788 host->need_reset = false;
735 } 789 }
736 mci_writel(host, SDCR, slot->sdc_reg); 790 mci_writel(host, SDCR, slot->sdc_reg);
@@ -746,6 +800,7 @@ static void atmci_start_request(struct atmel_mci *host,
746 while (!(mci_readl(host, SR) & MCI_CMDRDY)) 800 while (!(mci_readl(host, SR) & MCI_CMDRDY))
747 cpu_relax(); 801 cpu_relax();
748 } 802 }
803 iflags = 0;
749 data = mrq->data; 804 data = mrq->data;
750 if (data) { 805 if (data) {
751 atmci_set_timeout(host, slot, data); 806 atmci_set_timeout(host, slot, data);
@@ -755,15 +810,17 @@ static void atmci_start_request(struct atmel_mci *host,
755 | MCI_BLKLEN(data->blksz)); 810 | MCI_BLKLEN(data->blksz));
756 dev_vdbg(&slot->mmc->class_dev, "BLKR=0x%08x\n", 811 dev_vdbg(&slot->mmc->class_dev, "BLKR=0x%08x\n",
757 MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz)); 812 MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz));
813
814 iflags |= atmci_prepare_data(host, data);
758 } 815 }
759 816
760 iflags = MCI_CMDRDY; 817 iflags |= MCI_CMDRDY;
761 cmd = mrq->cmd; 818 cmd = mrq->cmd;
762 cmdflags = atmci_prepare_command(slot->mmc, cmd); 819 cmdflags = atmci_prepare_command(slot->mmc, cmd);
763 atmci_start_command(host, cmd, cmdflags); 820 atmci_start_command(host, cmd, cmdflags);
764 821
765 if (data) 822 if (data)
766 iflags |= atmci_submit_data(host, data); 823 atmci_submit_data(host);
767 824
768 if (mrq->stop) { 825 if (mrq->stop) {
769 host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop); 826 host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop);
@@ -859,6 +916,8 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
859 clk_enable(host->mck); 916 clk_enable(host->mck);
860 mci_writel(host, CR, MCI_CR_SWRST); 917 mci_writel(host, CR, MCI_CR_SWRST);
861 mci_writel(host, CR, MCI_CR_MCIEN); 918 mci_writel(host, CR, MCI_CR_MCIEN);
919 if (atmci_is_mci2())
920 mci_writel(host, CFG, host->cfg_reg);
862 } 921 }
863 922
864 /* 923 /*
@@ -1097,6 +1156,8 @@ static void atmci_detect_change(unsigned long data)
1097 mci_writel(host, CR, MCI_CR_SWRST); 1156 mci_writel(host, CR, MCI_CR_SWRST);
1098 mci_writel(host, CR, MCI_CR_MCIEN); 1157 mci_writel(host, CR, MCI_CR_MCIEN);
1099 mci_writel(host, MR, host->mode_reg); 1158 mci_writel(host, MR, host->mode_reg);
1159 if (atmci_is_mci2())
1160 mci_writel(host, CFG, host->cfg_reg);
1100 1161
1101 host->data = NULL; 1162 host->data = NULL;
1102 host->cmd = NULL; 1163 host->cmd = NULL;
@@ -1620,6 +1681,10 @@ static void atmci_configure_dma(struct atmel_mci *host)
1620 } 1681 }
1621 if (!host->dma.chan) 1682 if (!host->dma.chan)
1622 dev_notice(&host->pdev->dev, "DMA not available, using PIO\n"); 1683 dev_notice(&host->pdev->dev, "DMA not available, using PIO\n");
1684 else
1685 dev_info(&host->pdev->dev,
1686 "Using %s for DMA transfers\n",
1687 dma_chan_name(host->dma.chan));
1623} 1688}
1624#else 1689#else
1625static void atmci_configure_dma(struct atmel_mci *host) {} 1690static void atmci_configure_dma(struct atmel_mci *host) {}