aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/atmel-mci.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/mmc/host/atmel-mci.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/mmc/host/atmel-mci.c')
-rw-r--r--drivers/mmc/host/atmel-mci.c160
1 files changed, 122 insertions, 38 deletions
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index fc25586b7ee1..fb279f4ed8b3 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -22,9 +22,12 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/scatterlist.h> 23#include <linux/scatterlist.h>
24#include <linux/seq_file.h> 24#include <linux/seq_file.h>
25#include <linux/slab.h>
25#include <linux/stat.h> 26#include <linux/stat.h>
26 27
27#include <linux/mmc/host.h> 28#include <linux/mmc/host.h>
29
30#include <mach/atmel-mci.h>
28#include <linux/atmel-mci.h> 31#include <linux/atmel-mci.h>
29 32
30#include <asm/io.h> 33#include <asm/io.h>
@@ -92,6 +95,7 @@ struct atmel_mci_dma {
92 * @need_clock_update: Update the clock rate before the next request. 95 * @need_clock_update: Update the clock rate before the next request.
93 * @need_reset: Reset controller before next request. 96 * @need_reset: Reset controller before next request.
94 * @mode_reg: Value of the MR register. 97 * @mode_reg: Value of the MR register.
98 * @cfg_reg: Value of the CFG register.
95 * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus 99 * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus
96 * rate and timeout calculations. 100 * rate and timeout calculations.
97 * @mapbase: Physical address of the MMIO registers. 101 * @mapbase: Physical address of the MMIO registers.
@@ -155,6 +159,7 @@ struct atmel_mci {
155 bool need_clock_update; 159 bool need_clock_update;
156 bool need_reset; 160 bool need_reset;
157 u32 mode_reg; 161 u32 mode_reg;
162 u32 cfg_reg;
158 unsigned long bus_hz; 163 unsigned long bus_hz;
159 unsigned long mapbase; 164 unsigned long mapbase;
160 struct clk *mck; 165 struct clk *mck;
@@ -223,6 +228,19 @@ static bool mci_has_rwproof(void)
223} 228}
224 229
225/* 230/*
231 * The new MCI2 module isn't 100% compatible with the old MCI module,
232 * and it has a few nice features which we want to use...
233 */
234static inline bool atmci_is_mci2(void)
235{
236 if (cpu_is_at91sam9g45())
237 return true;
238
239 return false;
240}
241
242
243/*
226 * The debugfs stuff below is mostly optimized away when 244 * The debugfs stuff below is mostly optimized away when
227 * CONFIG_DEBUG_FS is not set. 245 * CONFIG_DEBUG_FS is not set.
228 */ 246 */
@@ -248,7 +266,7 @@ static int atmci_req_show(struct seq_file *s, void *v)
248 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", 266 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
249 cmd->opcode, cmd->arg, cmd->flags, 267 cmd->opcode, cmd->arg, cmd->flags,
250 cmd->resp[0], cmd->resp[1], cmd->resp[2], 268 cmd->resp[0], cmd->resp[1], cmd->resp[2],
251 cmd->resp[2], cmd->error); 269 cmd->resp[3], cmd->error);
252 if (data) 270 if (data)
253 seq_printf(s, "DATA %u / %u * %u flg %x err %d\n", 271 seq_printf(s, "DATA %u / %u * %u flg %x err %d\n",
254 data->bytes_xfered, data->blocks, 272 data->bytes_xfered, data->blocks,
@@ -258,7 +276,7 @@ static int atmci_req_show(struct seq_file *s, void *v)
258 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", 276 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
259 stop->opcode, stop->arg, stop->flags, 277 stop->opcode, stop->arg, stop->flags,
260 stop->resp[0], stop->resp[1], stop->resp[2], 278 stop->resp[0], stop->resp[1], stop->resp[2],
261 stop->resp[2], stop->error); 279 stop->resp[3], stop->error);
262 } 280 }
263 281
264 spin_unlock_bh(&slot->host->lock); 282 spin_unlock_bh(&slot->host->lock);
@@ -357,12 +375,33 @@ static int atmci_regs_show(struct seq_file *s, void *v)
357 buf[MCI_BLKR / 4], 375 buf[MCI_BLKR / 4],
358 buf[MCI_BLKR / 4] & 0xffff, 376 buf[MCI_BLKR / 4] & 0xffff,
359 (buf[MCI_BLKR / 4] >> 16) & 0xffff); 377 (buf[MCI_BLKR / 4] >> 16) & 0xffff);
378 if (atmci_is_mci2())
379 seq_printf(s, "CSTOR:\t0x%08x\n", buf[MCI_CSTOR / 4]);
360 380
361 /* Don't read RSPR and RDR; it will consume the data there */ 381 /* Don't read RSPR and RDR; it will consume the data there */
362 382
363 atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]); 383 atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]);
364 atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]); 384 atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]);
365 385
386 if (atmci_is_mci2()) {
387 u32 val;
388
389 val = buf[MCI_DMA / 4];
390 seq_printf(s, "DMA:\t0x%08x OFFSET=%u CHKSIZE=%u%s\n",
391 val, val & 3,
392 ((val >> 4) & 3) ?
393 1 << (((val >> 4) & 3) + 1) : 1,
394 val & MCI_DMAEN ? " DMAEN" : "");
395
396 val = buf[MCI_CFG / 4];
397 seq_printf(s, "CFG:\t0x%08x%s%s%s%s\n",
398 val,
399 val & MCI_CFG_FIFOMODE_1DATA ? " FIFOMODE_ONE_DATA" : "",
400 val & MCI_CFG_FERRCTRL_COR ? " FERRCTRL_CLEAR_ON_READ" : "",
401 val & MCI_CFG_HSMODE ? " HSMODE" : "",
402 val & MCI_CFG_LSYNC ? " LSYNC" : "");
403 }
404
366 kfree(buf); 405 kfree(buf);
367 406
368 return 0; 407 return 0;
@@ -530,9 +569,10 @@ static void atmci_dma_cleanup(struct atmel_mci *host)
530{ 569{
531 struct mmc_data *data = host->data; 570 struct mmc_data *data = host->data;
532 571
533 dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, 572 if (data)
534 ((data->flags & MMC_DATA_WRITE) 573 dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len,
535 ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); 574 ((data->flags & MMC_DATA_WRITE)
575 ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
536} 576}
537 577
538static void atmci_stop_dma(struct atmel_mci *host) 578static void atmci_stop_dma(struct atmel_mci *host)
@@ -557,6 +597,10 @@ static void atmci_dma_complete(void *arg)
557 597
558 dev_vdbg(&host->pdev->dev, "DMA complete\n"); 598 dev_vdbg(&host->pdev->dev, "DMA complete\n");
559 599
600 if (atmci_is_mci2())
601 /* Disable DMA hardware handshaking on MCI */
602 mci_writel(host, DMA, mci_readl(host, DMA) & ~MCI_DMAEN);
603
560 atmci_dma_cleanup(host); 604 atmci_dma_cleanup(host);
561 605
562 /* 606 /*
@@ -592,7 +636,7 @@ static void atmci_dma_complete(void *arg)
592} 636}
593 637
594static int 638static int
595atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data) 639atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
596{ 640{
597 struct dma_chan *chan; 641 struct dma_chan *chan;
598 struct dma_async_tx_descriptor *desc; 642 struct dma_async_tx_descriptor *desc;
@@ -624,6 +668,9 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
624 if (!chan) 668 if (!chan)
625 return -ENODEV; 669 return -ENODEV;
626 670
671 if (atmci_is_mci2())
672 mci_writel(host, DMA, MCI_DMA_CHKSIZE(3) | MCI_DMAEN);
673
627 if (data->flags & MMC_DATA_READ) 674 if (data->flags & MMC_DATA_READ)
628 direction = DMA_FROM_DEVICE; 675 direction = DMA_FROM_DEVICE;
629 else 676 else
@@ -641,10 +688,6 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
641 host->dma.data_desc = desc; 688 host->dma.data_desc = desc;
642 desc->callback = atmci_dma_complete; 689 desc->callback = atmci_dma_complete;
643 desc->callback_param = host; 690 desc->callback_param = host;
644 desc->tx_submit(desc);
645
646 /* Go! */
647 chan->device->device_issue_pending(chan);
648 691
649 return 0; 692 return 0;
650unmap_exit: 693unmap_exit:
@@ -652,13 +695,26 @@ unmap_exit:
652 return -ENOMEM; 695 return -ENOMEM;
653} 696}
654 697
698static void atmci_submit_data(struct atmel_mci *host)
699{
700 struct dma_chan *chan = host->data_chan;
701 struct dma_async_tx_descriptor *desc = host->dma.data_desc;
702
703 if (chan) {
704 desc->tx_submit(desc);
705 chan->device->device_issue_pending(chan);
706 }
707}
708
655#else /* CONFIG_MMC_ATMELMCI_DMA */ 709#else /* CONFIG_MMC_ATMELMCI_DMA */
656 710
657static int atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data) 711static int atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data)
658{ 712{
659 return -ENOSYS; 713 return -ENOSYS;
660} 714}
661 715
716static void atmci_submit_data(struct atmel_mci *host) {}
717
662static void atmci_stop_dma(struct atmel_mci *host) 718static void atmci_stop_dma(struct atmel_mci *host)
663{ 719{
664 /* Data transfer was stopped by the interrupt handler */ 720 /* Data transfer was stopped by the interrupt handler */
@@ -672,7 +728,7 @@ static void atmci_stop_dma(struct atmel_mci *host)
672 * Returns a mask of interrupt flags to be enabled after the whole 728 * Returns a mask of interrupt flags to be enabled after the whole
673 * request has been prepared. 729 * request has been prepared.
674 */ 730 */
675static u32 atmci_submit_data(struct atmel_mci *host, struct mmc_data *data) 731static u32 atmci_prepare_data(struct atmel_mci *host, struct mmc_data *data)
676{ 732{
677 u32 iflags; 733 u32 iflags;
678 734
@@ -683,7 +739,7 @@ static u32 atmci_submit_data(struct atmel_mci *host, struct mmc_data *data)
683 host->data = data; 739 host->data = data;
684 740
685 iflags = ATMCI_DATA_ERROR_FLAGS; 741 iflags = ATMCI_DATA_ERROR_FLAGS;
686 if (atmci_submit_data_dma(host, data)) { 742 if (atmci_prepare_data_dma(host, data)) {
687 host->data_chan = NULL; 743 host->data_chan = NULL;
688 744
689 /* 745 /*
@@ -729,6 +785,8 @@ static void atmci_start_request(struct atmel_mci *host,
729 mci_writel(host, CR, MCI_CR_SWRST); 785 mci_writel(host, CR, MCI_CR_SWRST);
730 mci_writel(host, CR, MCI_CR_MCIEN); 786 mci_writel(host, CR, MCI_CR_MCIEN);
731 mci_writel(host, MR, host->mode_reg); 787 mci_writel(host, MR, host->mode_reg);
788 if (atmci_is_mci2())
789 mci_writel(host, CFG, host->cfg_reg);
732 host->need_reset = false; 790 host->need_reset = false;
733 } 791 }
734 mci_writel(host, SDCR, slot->sdc_reg); 792 mci_writel(host, SDCR, slot->sdc_reg);
@@ -744,6 +802,7 @@ static void atmci_start_request(struct atmel_mci *host,
744 while (!(mci_readl(host, SR) & MCI_CMDRDY)) 802 while (!(mci_readl(host, SR) & MCI_CMDRDY))
745 cpu_relax(); 803 cpu_relax();
746 } 804 }
805 iflags = 0;
747 data = mrq->data; 806 data = mrq->data;
748 if (data) { 807 if (data) {
749 atmci_set_timeout(host, slot, data); 808 atmci_set_timeout(host, slot, data);
@@ -753,15 +812,17 @@ static void atmci_start_request(struct atmel_mci *host,
753 | MCI_BLKLEN(data->blksz)); 812 | MCI_BLKLEN(data->blksz));
754 dev_vdbg(&slot->mmc->class_dev, "BLKR=0x%08x\n", 813 dev_vdbg(&slot->mmc->class_dev, "BLKR=0x%08x\n",
755 MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz)); 814 MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz));
815
816 iflags |= atmci_prepare_data(host, data);
756 } 817 }
757 818
758 iflags = MCI_CMDRDY; 819 iflags |= MCI_CMDRDY;
759 cmd = mrq->cmd; 820 cmd = mrq->cmd;
760 cmdflags = atmci_prepare_command(slot->mmc, cmd); 821 cmdflags = atmci_prepare_command(slot->mmc, cmd);
761 atmci_start_command(host, cmd, cmdflags); 822 atmci_start_command(host, cmd, cmdflags);
762 823
763 if (data) 824 if (data)
764 iflags |= atmci_submit_data(host, data); 825 atmci_submit_data(host);
765 826
766 if (mrq->stop) { 827 if (mrq->stop) {
767 host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop); 828 host->stop_cmdr = atmci_prepare_command(slot->mmc, mrq->stop);
@@ -857,6 +918,8 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
857 clk_enable(host->mck); 918 clk_enable(host->mck);
858 mci_writel(host, CR, MCI_CR_SWRST); 919 mci_writel(host, CR, MCI_CR_SWRST);
859 mci_writel(host, CR, MCI_CR_MCIEN); 920 mci_writel(host, CR, MCI_CR_MCIEN);
921 if (atmci_is_mci2())
922 mci_writel(host, CFG, host->cfg_reg);
860 } 923 }
861 924
862 /* 925 /*
@@ -1037,8 +1100,8 @@ static void atmci_command_complete(struct atmel_mci *host,
1037 "command error: status=0x%08x\n", status); 1100 "command error: status=0x%08x\n", status);
1038 1101
1039 if (cmd->data) { 1102 if (cmd->data) {
1040 host->data = NULL;
1041 atmci_stop_dma(host); 1103 atmci_stop_dma(host);
1104 host->data = NULL;
1042 mci_writel(host, IDR, MCI_NOTBUSY 1105 mci_writel(host, IDR, MCI_NOTBUSY
1043 | MCI_TXRDY | MCI_RXRDY 1106 | MCI_TXRDY | MCI_RXRDY
1044 | ATMCI_DATA_ERROR_FLAGS); 1107 | ATMCI_DATA_ERROR_FLAGS);
@@ -1095,6 +1158,8 @@ static void atmci_detect_change(unsigned long data)
1095 mci_writel(host, CR, MCI_CR_SWRST); 1158 mci_writel(host, CR, MCI_CR_SWRST);
1096 mci_writel(host, CR, MCI_CR_MCIEN); 1159 mci_writel(host, CR, MCI_CR_MCIEN);
1097 mci_writel(host, MR, host->mode_reg); 1160 mci_writel(host, MR, host->mode_reg);
1161 if (atmci_is_mci2())
1162 mci_writel(host, CFG, host->cfg_reg);
1098 1163
1099 host->data = NULL; 1164 host->data = NULL;
1100 host->cmd = NULL; 1165 host->cmd = NULL;
@@ -1229,6 +1294,7 @@ static void atmci_tasklet_func(unsigned long priv)
1229 } else { 1294 } else {
1230 data->bytes_xfered = data->blocks * data->blksz; 1295 data->bytes_xfered = data->blocks * data->blksz;
1231 data->error = 0; 1296 data->error = 0;
1297 mci_writel(host, IDR, ATMCI_DATA_ERROR_FLAGS);
1232 } 1298 }
1233 1299
1234 if (!data->stop) { 1300 if (!data->stop) {
@@ -1584,14 +1650,47 @@ static void __exit atmci_cleanup_slot(struct atmel_mci_slot *slot,
1584#ifdef CONFIG_MMC_ATMELMCI_DMA 1650#ifdef CONFIG_MMC_ATMELMCI_DMA
1585static bool filter(struct dma_chan *chan, void *slave) 1651static bool filter(struct dma_chan *chan, void *slave)
1586{ 1652{
1587 struct dw_dma_slave *dws = slave; 1653 struct mci_dma_data *sl = slave;
1588 1654
1589 if (dws->dma_dev == chan->device->dev) { 1655 if (sl && find_slave_dev(sl) == chan->device->dev) {
1590 chan->private = dws; 1656 chan->private = slave_data_ptr(sl);
1591 return true; 1657 return true;
1592 } else 1658 } else {
1593 return false; 1659 return false;
1660 }
1594} 1661}
1662
1663static void atmci_configure_dma(struct atmel_mci *host)
1664{
1665 struct mci_platform_data *pdata;
1666
1667 if (host == NULL)
1668 return;
1669
1670 pdata = host->pdev->dev.platform_data;
1671
1672 if (pdata && find_slave_dev(pdata->dma_slave)) {
1673 dma_cap_mask_t mask;
1674
1675 setup_dma_addr(pdata->dma_slave,
1676 host->mapbase + MCI_TDR,
1677 host->mapbase + MCI_RDR);
1678
1679 /* Try to grab a DMA channel */
1680 dma_cap_zero(mask);
1681 dma_cap_set(DMA_SLAVE, mask);
1682 host->dma.chan =
1683 dma_request_channel(mask, filter, pdata->dma_slave);
1684 }
1685 if (!host->dma.chan)
1686 dev_notice(&host->pdev->dev, "DMA not available, using PIO\n");
1687 else
1688 dev_info(&host->pdev->dev,
1689 "Using %s for DMA transfers\n",
1690 dma_chan_name(host->dma.chan));
1691}
1692#else
1693static void atmci_configure_dma(struct atmel_mci *host) {}
1595#endif 1694#endif
1596 1695
1597static int __init atmci_probe(struct platform_device *pdev) 1696static int __init atmci_probe(struct platform_device *pdev)
@@ -1645,22 +1744,7 @@ static int __init atmci_probe(struct platform_device *pdev)
1645 if (ret) 1744 if (ret)
1646 goto err_request_irq; 1745 goto err_request_irq;
1647 1746
1648#ifdef CONFIG_MMC_ATMELMCI_DMA 1747 atmci_configure_dma(host);
1649 if (pdata->dma_slave.dma_dev) {
1650 struct dw_dma_slave *dws = &pdata->dma_slave;
1651 dma_cap_mask_t mask;
1652
1653 dws->tx_reg = regs->start + MCI_TDR;
1654 dws->rx_reg = regs->start + MCI_RDR;
1655
1656 /* Try to grab a DMA channel */
1657 dma_cap_zero(mask);
1658 dma_cap_set(DMA_SLAVE, mask);
1659 host->dma.chan = dma_request_channel(mask, filter, dws);
1660 }
1661 if (!host->dma.chan)
1662 dev_notice(&pdev->dev, "DMA not available, using PIO\n");
1663#endif /* CONFIG_MMC_ATMELMCI_DMA */
1664 1748
1665 platform_set_drvdata(pdev, host); 1749 platform_set_drvdata(pdev, host);
1666 1750
@@ -1669,13 +1753,13 @@ static int __init atmci_probe(struct platform_device *pdev)
1669 ret = -ENODEV; 1753 ret = -ENODEV;
1670 if (pdata->slot[0].bus_width) { 1754 if (pdata->slot[0].bus_width) {
1671 ret = atmci_init_slot(host, &pdata->slot[0], 1755 ret = atmci_init_slot(host, &pdata->slot[0],
1672 MCI_SDCSEL_SLOT_A, 0); 1756 0, MCI_SDCSEL_SLOT_A);
1673 if (!ret) 1757 if (!ret)
1674 nr_slots++; 1758 nr_slots++;
1675 } 1759 }
1676 if (pdata->slot[1].bus_width) { 1760 if (pdata->slot[1].bus_width) {
1677 ret = atmci_init_slot(host, &pdata->slot[1], 1761 ret = atmci_init_slot(host, &pdata->slot[1],
1678 MCI_SDCSEL_SLOT_B, 1); 1762 1, MCI_SDCSEL_SLOT_B);
1679 if (!ret) 1763 if (!ret)
1680 nr_slots++; 1764 nr_slots++;
1681 } 1765 }