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
|
@ -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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
* 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)
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
|
|
||||||
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 @@
|
||||||
#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 {
|
||||||
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 */
|
||||||
|
|
Loading…
Reference in a new issue