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>
This commit is contained in:
parent
996ad5686c
commit
a13abc7b08
3 changed files with 21 additions and 23 deletions
|
@ -396,7 +396,7 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host)
|
|||
|
||||
if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) &&
|
||||
((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 "
|
||||
"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)
|
|||
count = sdhci_calc_timeout(host, data);
|
||||
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;
|
||||
|
||||
/*
|
||||
|
@ -1600,7 +1600,7 @@ int sdhci_resume_host(struct sdhci_host *host)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (host->flags & SDHCI_USE_DMA) {
|
||||
if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
|
||||
if (host->ops->enable_dma)
|
||||
host->ops->enable_dma(host);
|
||||
}
|
||||
|
@ -1681,23 +1681,20 @@ int sdhci_add_host(struct sdhci_host *host)
|
|||
caps = sdhci_readl(host, SDHCI_CAPABILITIES);
|
||||
|
||||
if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
|
||||
host->flags |= SDHCI_USE_DMA;
|
||||
else if (!(caps & SDHCI_CAN_DO_DMA))
|
||||
DBG("Controller doesn't have DMA capability\n");
|
||||
host->flags |= SDHCI_USE_SDMA;
|
||||
else if (!(caps & SDHCI_CAN_DO_SDMA))
|
||||
DBG("Controller doesn't have SDMA capability\n");
|
||||
else
|
||||
host->flags |= SDHCI_USE_DMA;
|
||||
host->flags |= SDHCI_USE_SDMA;
|
||||
|
||||
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");
|
||||
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))
|
||||
host->flags |= SDHCI_USE_ADMA;
|
||||
}
|
||||
if ((host->version >= SDHCI_SPEC_200) && (caps & SDHCI_CAN_DO_ADMA2))
|
||||
host->flags |= SDHCI_USE_ADMA;
|
||||
|
||||
if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
|
||||
(host->flags & SDHCI_USE_ADMA)) {
|
||||
|
@ -1705,13 +1702,14 @@ int sdhci_add_host(struct sdhci_host *host)
|
|||
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(host)) {
|
||||
printk(KERN_WARNING "%s: No suitable DMA "
|
||||
"available. Falling back to PIO.\n",
|
||||
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)
|
|||
* mask, but PIO does not need the hw shim so we set a new
|
||||
* 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);
|
||||
mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
|
||||
}
|
||||
|
@ -1816,7 +1814,7 @@ int sdhci_add_host(struct sdhci_host *host)
|
|||
*/
|
||||
if (host->flags & SDHCI_USE_ADMA)
|
||||
mmc->max_hw_segs = 128;
|
||||
else if (host->flags & SDHCI_USE_DMA)
|
||||
else if (host->flags & SDHCI_USE_SDMA)
|
||||
mmc->max_hw_segs = 1;
|
||||
else /* PIO */
|
||||
mmc->max_hw_segs = 128;
|
||||
|
@ -1899,10 +1897,10 @@ int sdhci_add_host(struct sdhci_host *host)
|
|||
|
||||
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)),
|
||||
(host->flags & SDHCI_USE_ADMA)?"A":"",
|
||||
(host->flags & SDHCI_USE_DMA)?"DMA":"PIO");
|
||||
(host->flags & SDHCI_USE_ADMA) ? "ADMA" :
|
||||
(host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO");
|
||||
|
||||
sdhci_enable_card_detection(host);
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@
|
|||
#define SDHCI_CAN_DO_ADMA2 0x00080000
|
||||
#define SDHCI_CAN_DO_ADMA1 0x00100000
|
||||
#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_300 0x02000000
|
||||
#define SDHCI_CAN_VDD_180 0x04000000
|
||||
|
@ -252,7 +252,7 @@ struct sdhci_host {
|
|||
spinlock_t lock; /* Mutex */
|
||||
|
||||
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_REQ_USE_DMA (1<<2) /* Use DMA for this req. */
|
||||
#define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */
|
||||
|
|
Loading…
Reference in a new issue