aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Röjfors <richard.rojfors@mocean-labs.com>2009-09-22 19:45:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 10:39:38 -0400
commita13abc7b0814da7733c531453a207729b542ecf8 (patch)
treed79f576744191044e0f6f77d430c182e52f27fdf
parent996ad5686c5f868e67557cc1bfcb2cfdde1a18b4 (diff)
sdhci: support for ADMA only hosts
Add support for ADMA on SDHCI hosts, not supporting SDMA. According to the SDHCI specifications a host can support ADMA but not SDMA Signed-off-by: Richard Röjfors <richard.rojfors@mocean-labs.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>
-rw-r--r--drivers/mmc/host/sdhci-pci.c2
-rw-r--r--drivers/mmc/host/sdhci.c38
-rw-r--r--drivers/mmc/host/sdhci.h4
3 files changed, 21 insertions, 23 deletions
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 63b9d2a6a452..e0356644d1aa 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -396,7 +396,7 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host)
396 396
397 if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) && 397 if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) &&
398 ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) && 398 ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) &&
399 (host->flags & SDHCI_USE_DMA)) { 399 (host->flags & SDHCI_USE_SDMA)) {
400 dev_warn(&pdev->dev, "Will use DMA mode even though HW " 400 dev_warn(&pdev->dev, "Will use DMA mode even though HW "
401 "doesn't fully claim to support it.\n"); 401 "doesn't fully claim to support it.\n");
402 } 402 }
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 38a78743fc51..9d0767687e12 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -655,7 +655,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
655 count = sdhci_calc_timeout(host, data); 655 count = sdhci_calc_timeout(host, data);
656 sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL); 656 sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
657 657
658 if (host->flags & SDHCI_USE_DMA) 658 if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))
659 host->flags |= SDHCI_REQ_USE_DMA; 659 host->flags |= SDHCI_REQ_USE_DMA;
660 660
661 /* 661 /*
@@ -1600,7 +1600,7 @@ int sdhci_resume_host(struct sdhci_host *host)
1600{ 1600{
1601 int ret; 1601 int ret;
1602 1602
1603 if (host->flags & SDHCI_USE_DMA) { 1603 if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
1604 if (host->ops->enable_dma) 1604 if (host->ops->enable_dma)
1605 host->ops->enable_dma(host); 1605 host->ops->enable_dma(host);
1606 } 1606 }
@@ -1681,23 +1681,20 @@ int sdhci_add_host(struct sdhci_host *host)
1681 caps = sdhci_readl(host, SDHCI_CAPABILITIES); 1681 caps = sdhci_readl(host, SDHCI_CAPABILITIES);
1682 1682
1683 if (host->quirks & SDHCI_QUIRK_FORCE_DMA) 1683 if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
1684 host->flags |= SDHCI_USE_DMA; 1684 host->flags |= SDHCI_USE_SDMA;
1685 else if (!(caps & SDHCI_CAN_DO_DMA)) 1685 else if (!(caps & SDHCI_CAN_DO_SDMA))
1686 DBG("Controller doesn't have DMA capability\n"); 1686 DBG("Controller doesn't have SDMA capability\n");
1687 else 1687 else
1688 host->flags |= SDHCI_USE_DMA; 1688 host->flags |= SDHCI_USE_SDMA;
1689 1689
1690 if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) && 1690 if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
1691 (host->flags & SDHCI_USE_DMA)) { 1691 (host->flags & SDHCI_USE_SDMA)) {
1692 DBG("Disabling DMA as it is marked broken\n"); 1692 DBG("Disabling DMA as it is marked broken\n");
1693 host->flags &= ~SDHCI_USE_DMA; 1693 host->flags &= ~SDHCI_USE_SDMA;
1694 } 1694 }
1695 1695
1696 if (host->flags & SDHCI_USE_DMA) { 1696 if ((host->version >= SDHCI_SPEC_200) && (caps & SDHCI_CAN_DO_ADMA2))
1697 if ((host->version >= SDHCI_SPEC_200) && 1697 host->flags |= SDHCI_USE_ADMA;
1698 (caps & SDHCI_CAN_DO_ADMA2))
1699 host->flags |= SDHCI_USE_ADMA;
1700 }
1701 1698
1702 if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) && 1699 if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
1703 (host->flags & SDHCI_USE_ADMA)) { 1700 (host->flags & SDHCI_USE_ADMA)) {
@@ -1705,13 +1702,14 @@ int sdhci_add_host(struct sdhci_host *host)
1705 host->flags &= ~SDHCI_USE_ADMA; 1702 host->flags &= ~SDHCI_USE_ADMA;
1706 } 1703 }
1707 1704
1708 if (host->flags & SDHCI_USE_DMA) { 1705 if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
1709 if (host->ops->enable_dma) { 1706 if (host->ops->enable_dma) {
1710 if (host->ops->enable_dma(host)) { 1707 if (host->ops->enable_dma(host)) {
1711 printk(KERN_WARNING "%s: No suitable DMA " 1708 printk(KERN_WARNING "%s: No suitable DMA "
1712 "available. Falling back to PIO.\n", 1709 "available. Falling back to PIO.\n",
1713 mmc_hostname(mmc)); 1710 mmc_hostname(mmc));
1714 host->flags &= ~(SDHCI_USE_DMA | SDHCI_USE_ADMA); 1711 host->flags &=
1712 ~(SDHCI_USE_SDMA | SDHCI_USE_ADMA);
1715 } 1713 }
1716 } 1714 }
1717 } 1715 }
@@ -1739,7 +1737,7 @@ int sdhci_add_host(struct sdhci_host *host)
1739 * mask, but PIO does not need the hw shim so we set a new 1737 * mask, but PIO does not need the hw shim so we set a new
1740 * mask here in that case. 1738 * mask here in that case.
1741 */ 1739 */
1742 if (!(host->flags & SDHCI_USE_DMA)) { 1740 if (!(host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))) {
1743 host->dma_mask = DMA_BIT_MASK(64); 1741 host->dma_mask = DMA_BIT_MASK(64);
1744 mmc_dev(host->mmc)->dma_mask = &host->dma_mask; 1742 mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
1745 } 1743 }
@@ -1816,7 +1814,7 @@ int sdhci_add_host(struct sdhci_host *host)
1816 */ 1814 */
1817 if (host->flags & SDHCI_USE_ADMA) 1815 if (host->flags & SDHCI_USE_ADMA)
1818 mmc->max_hw_segs = 128; 1816 mmc->max_hw_segs = 128;
1819 else if (host->flags & SDHCI_USE_DMA) 1817 else if (host->flags & SDHCI_USE_SDMA)
1820 mmc->max_hw_segs = 1; 1818 mmc->max_hw_segs = 1;
1821 else /* PIO */ 1819 else /* PIO */
1822 mmc->max_hw_segs = 128; 1820 mmc->max_hw_segs = 128;
@@ -1899,10 +1897,10 @@ int sdhci_add_host(struct sdhci_host *host)
1899 1897
1900 mmc_add_host(mmc); 1898 mmc_add_host(mmc);
1901 1899
1902 printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n", 1900 printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s\n",
1903 mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), 1901 mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
1904 (host->flags & SDHCI_USE_ADMA)?"A":"", 1902 (host->flags & SDHCI_USE_ADMA) ? "ADMA" :
1905 (host->flags & SDHCI_USE_DMA)?"DMA":"PIO"); 1903 (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO");
1906 1904
1907 sdhci_enable_card_detection(host); 1905 sdhci_enable_card_detection(host);
1908 1906
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index afda7f126e0d..ce5f1d73dc04 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -143,7 +143,7 @@
143#define SDHCI_CAN_DO_ADMA2 0x00080000 143#define SDHCI_CAN_DO_ADMA2 0x00080000
144#define SDHCI_CAN_DO_ADMA1 0x00100000 144#define SDHCI_CAN_DO_ADMA1 0x00100000
145#define SDHCI_CAN_DO_HISPD 0x00200000 145#define SDHCI_CAN_DO_HISPD 0x00200000
146#define SDHCI_CAN_DO_DMA 0x00400000 146#define SDHCI_CAN_DO_SDMA 0x00400000
147#define SDHCI_CAN_VDD_330 0x01000000 147#define SDHCI_CAN_VDD_330 0x01000000
148#define SDHCI_CAN_VDD_300 0x02000000 148#define SDHCI_CAN_VDD_300 0x02000000
149#define SDHCI_CAN_VDD_180 0x04000000 149#define SDHCI_CAN_VDD_180 0x04000000
@@ -252,7 +252,7 @@ struct sdhci_host {
252 spinlock_t lock; /* Mutex */ 252 spinlock_t lock; /* Mutex */
253 253
254 int flags; /* Host attributes */ 254 int flags; /* Host attributes */
255#define SDHCI_USE_DMA (1<<0) /* Host is DMA capable */ 255#define SDHCI_USE_SDMA (1<<0) /* Host is SDMA capable */
256#define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */ 256#define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */
257#define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */ 257#define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */
258#define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */ 258#define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */