Commit a13abc7b authored by Richard Röjfors's avatar Richard Röjfors Committed by Linus Torvalds

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: default avatarRichard Röjfors <richard.rojfors@mocean-labs.com>
Cc: <linux-mmc@vger.kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 996ad568
...@@ -396,7 +396,7 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host) ...@@ -396,7 +396,7 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host)
if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) && if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) &&
((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) && ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) &&
(host->flags & SDHCI_USE_DMA)) { (host->flags & SDHCI_USE_SDMA)) {
dev_warn(&pdev->dev, "Will use DMA mode even though HW " dev_warn(&pdev->dev, "Will use DMA mode even though HW "
"doesn't fully claim to support it.\n"); "doesn't fully claim to support it.\n");
} }
......
...@@ -655,7 +655,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) ...@@ -655,7 +655,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
count = sdhci_calc_timeout(host, data); count = sdhci_calc_timeout(host, data);
sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL); sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
if (host->flags & SDHCI_USE_DMA) if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))
host->flags |= SDHCI_REQ_USE_DMA; host->flags |= SDHCI_REQ_USE_DMA;
/* /*
...@@ -1600,7 +1600,7 @@ int sdhci_resume_host(struct sdhci_host *host) ...@@ -1600,7 +1600,7 @@ int sdhci_resume_host(struct sdhci_host *host)
{ {
int ret; int ret;
if (host->flags & SDHCI_USE_DMA) { if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
if (host->ops->enable_dma) if (host->ops->enable_dma)
host->ops->enable_dma(host); host->ops->enable_dma(host);
} }
...@@ -1681,23 +1681,20 @@ int sdhci_add_host(struct sdhci_host *host) ...@@ -1681,23 +1681,20 @@ int sdhci_add_host(struct sdhci_host *host)
caps = sdhci_readl(host, SDHCI_CAPABILITIES); caps = sdhci_readl(host, SDHCI_CAPABILITIES);
if (host->quirks & SDHCI_QUIRK_FORCE_DMA) if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
host->flags |= SDHCI_USE_DMA; host->flags |= SDHCI_USE_SDMA;
else if (!(caps & SDHCI_CAN_DO_DMA)) else if (!(caps & SDHCI_CAN_DO_SDMA))
DBG("Controller doesn't have DMA capability\n"); DBG("Controller doesn't have SDMA capability\n");
else else
host->flags |= SDHCI_USE_DMA; host->flags |= SDHCI_USE_SDMA;
if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) && if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
(host->flags & SDHCI_USE_DMA)) { (host->flags & SDHCI_USE_SDMA)) {
DBG("Disabling DMA as it is marked broken\n"); DBG("Disabling DMA as it is marked broken\n");
host->flags &= ~SDHCI_USE_DMA; host->flags &= ~SDHCI_USE_SDMA;
} }
if (host->flags & SDHCI_USE_DMA) { if ((host->version >= SDHCI_SPEC_200) && (caps & SDHCI_CAN_DO_ADMA2))
if ((host->version >= SDHCI_SPEC_200) && host->flags |= SDHCI_USE_ADMA;
(caps & SDHCI_CAN_DO_ADMA2))
host->flags |= SDHCI_USE_ADMA;
}
if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) && if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
(host->flags & SDHCI_USE_ADMA)) { (host->flags & SDHCI_USE_ADMA)) {
...@@ -1705,13 +1702,14 @@ int sdhci_add_host(struct sdhci_host *host) ...@@ -1705,13 +1702,14 @@ int sdhci_add_host(struct sdhci_host *host)
host->flags &= ~SDHCI_USE_ADMA; host->flags &= ~SDHCI_USE_ADMA;
} }
if (host->flags & SDHCI_USE_DMA) { if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
if (host->ops->enable_dma) { if (host->ops->enable_dma) {
if (host->ops->enable_dma(host)) { if (host->ops->enable_dma(host)) {
printk(KERN_WARNING "%s: No suitable DMA " printk(KERN_WARNING "%s: No suitable DMA "
"available. Falling back to PIO.\n", "available. Falling back to PIO.\n",
mmc_hostname(mmc)); mmc_hostname(mmc));
host->flags &= ~(SDHCI_USE_DMA | SDHCI_USE_ADMA); host->flags &=
~(SDHCI_USE_SDMA | SDHCI_USE_ADMA);
} }
} }
} }
...@@ -1739,7 +1737,7 @@ int sdhci_add_host(struct sdhci_host *host) ...@@ -1739,7 +1737,7 @@ int sdhci_add_host(struct sdhci_host *host)
* mask, but PIO does not need the hw shim so we set a new * mask, but PIO does not need the hw shim so we set a new
* mask here in that case. * mask here in that case.
*/ */
if (!(host->flags & SDHCI_USE_DMA)) { if (!(host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))) {
host->dma_mask = DMA_BIT_MASK(64); host->dma_mask = DMA_BIT_MASK(64);
mmc_dev(host->mmc)->dma_mask = &host->dma_mask; mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
} }
...@@ -1816,7 +1814,7 @@ int sdhci_add_host(struct sdhci_host *host) ...@@ -1816,7 +1814,7 @@ int sdhci_add_host(struct sdhci_host *host)
*/ */
if (host->flags & SDHCI_USE_ADMA) if (host->flags & SDHCI_USE_ADMA)
mmc->max_hw_segs = 128; mmc->max_hw_segs = 128;
else if (host->flags & SDHCI_USE_DMA) else if (host->flags & SDHCI_USE_SDMA)
mmc->max_hw_segs = 1; mmc->max_hw_segs = 1;
else /* PIO */ else /* PIO */
mmc->max_hw_segs = 128; mmc->max_hw_segs = 128;
...@@ -1899,10 +1897,10 @@ int sdhci_add_host(struct sdhci_host *host) ...@@ -1899,10 +1897,10 @@ int sdhci_add_host(struct sdhci_host *host)
mmc_add_host(mmc); mmc_add_host(mmc);
printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n", printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s\n",
mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
(host->flags & SDHCI_USE_ADMA)?"A":"", (host->flags & SDHCI_USE_ADMA) ? "ADMA" :
(host->flags & SDHCI_USE_DMA)?"DMA":"PIO"); (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO");
sdhci_enable_card_detection(host); sdhci_enable_card_detection(host);
......
...@@ -143,7 +143,7 @@ ...@@ -143,7 +143,7 @@
#define SDHCI_CAN_DO_ADMA2 0x00080000 #define SDHCI_CAN_DO_ADMA2 0x00080000
#define SDHCI_CAN_DO_ADMA1 0x00100000 #define SDHCI_CAN_DO_ADMA1 0x00100000
#define SDHCI_CAN_DO_HISPD 0x00200000 #define SDHCI_CAN_DO_HISPD 0x00200000
#define SDHCI_CAN_DO_DMA 0x00400000 #define SDHCI_CAN_DO_SDMA 0x00400000
#define SDHCI_CAN_VDD_330 0x01000000 #define SDHCI_CAN_VDD_330 0x01000000
#define SDHCI_CAN_VDD_300 0x02000000 #define SDHCI_CAN_VDD_300 0x02000000
#define SDHCI_CAN_VDD_180 0x04000000 #define SDHCI_CAN_VDD_180 0x04000000
...@@ -252,7 +252,7 @@ struct sdhci_host { ...@@ -252,7 +252,7 @@ struct sdhci_host {
spinlock_t lock; /* Mutex */ spinlock_t lock; /* Mutex */
int flags; /* Host attributes */ int flags; /* Host attributes */
#define SDHCI_USE_DMA (1<<0) /* Host is DMA capable */ #define SDHCI_USE_SDMA (1<<0) /* Host is SDMA capable */
#define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */ #define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */
#define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */ #define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */
#define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */ #define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment