Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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");
	}
+18 −20
Original line number Diff line number Diff line
@@ -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))
	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);

+2 −2
Original line number Diff line number Diff line
@@ -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 */