diff options
author | Richard Röjfors <richard.rojfors@mocean-labs.com> | 2009-09-22 19:45:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 10:39:38 -0400 |
commit | a13abc7b0814da7733c531453a207729b542ecf8 (patch) | |
tree | d79f576744191044e0f6f77d430c182e52f27fdf /drivers | |
parent | 996ad5686c5f868e67557cc1bfcb2cfdde1a18b4 (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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/host/sdhci-pci.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 38 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 4 |
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 */ |