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

Commit 685e444b authored by Chunyan Zhang's avatar Chunyan Zhang Committed by Ulf Hansson
Browse files

mmc: sdhci: Add ADMA2 64-bit addressing support for V4 mode



ADMA2 64-bit addressing support is divided into V3 mode and V4 mode.
So there are two kinds of descriptors for ADMA2 64-bit addressing
i.e. 96-bit Descriptor for V3 mode, and 128-bit Descriptor for V4
mode. 128-bit Descriptor is aligned to 8-byte.

For V4 mode, ADMA2 64-bit addressing is enabled via Host Control 2
register.

Signed-off-by: default avatarChunyan Zhang <zhang.chunyan@linaro.org>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
[Ulf: Fixed conflict while applying]
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 917a0c52
Loading
Loading
Loading
Loading
+68 −24
Original line number Diff line number Diff line
@@ -266,6 +266,52 @@ static void sdhci_set_default_irqs(struct sdhci_host *host)
	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
}

static void sdhci_config_dma(struct sdhci_host *host)
{
	u8 ctrl;
	u16 ctrl2;

	if (host->version < SDHCI_SPEC_200)
		return;

	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);

	/*
	 * Always adjust the DMA selection as some controllers
	 * (e.g. JMicron) can't do PIO properly when the selection
	 * is ADMA.
	 */
	ctrl &= ~SDHCI_CTRL_DMA_MASK;
	if (!(host->flags & SDHCI_REQ_USE_DMA))
		goto out;

	/* Note if DMA Select is zero then SDMA is selected */
	if (host->flags & SDHCI_USE_ADMA)
		ctrl |= SDHCI_CTRL_ADMA32;

	if (host->flags & SDHCI_USE_64_BIT_DMA) {
		/*
		 * If v4 mode, all supported DMA can be 64-bit addressing if
		 * controller supports 64-bit system address, otherwise only
		 * ADMA can support 64-bit addressing.
		 */
		if (host->v4_mode) {
			ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
			ctrl2 |= SDHCI_CTRL_64BIT_ADDR;
			sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2);
		} else if (host->flags & SDHCI_USE_ADMA) {
			/*
			 * Don't need to undo SDHCI_CTRL_ADMA32 in order to
			 * set SDHCI_CTRL_ADMA64.
			 */
			ctrl |= SDHCI_CTRL_ADMA64;
		}
	}

out:
	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
}

static void sdhci_init(struct sdhci_host *host, int soft)
{
	struct mmc_host *mmc = host->mmc;
@@ -922,7 +968,6 @@ static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)

static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
{
	u8 ctrl;
	struct mmc_data *data = cmd->data;

	host->data_timeout = 0;
@@ -1018,25 +1063,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
		}
	}

	/*
	 * Always adjust the DMA selection as some controllers
	 * (e.g. JMicron) can't do PIO properly when the selection
	 * is ADMA.
	 */
	if (host->version >= SDHCI_SPEC_200) {
		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
		ctrl &= ~SDHCI_CTRL_DMA_MASK;
		if ((host->flags & SDHCI_REQ_USE_DMA) &&
			(host->flags & SDHCI_USE_ADMA)) {
			if (host->flags & SDHCI_USE_64_BIT_DMA)
				ctrl |= SDHCI_CTRL_ADMA64;
			else
				ctrl |= SDHCI_CTRL_ADMA32;
		} else {
			ctrl |= SDHCI_CTRL_SDMA;
		}
		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
	}
	sdhci_config_dma(host);

	if (!(host->flags & SDHCI_REQ_USE_DMA)) {
		int flags;
@@ -3527,6 +3554,19 @@ static int sdhci_allocate_bounce_buffer(struct sdhci_host *host)
	return 0;
}

static inline bool sdhci_can_64bit_dma(struct sdhci_host *host)
{
	/*
	 * According to SD Host Controller spec v4.10, bit[27] added from
	 * version 4.10 in Capabilities Register is used as 64-bit System
	 * Address support for V4 mode.
	 */
	if (host->version >= SDHCI_SPEC_410 && host->v4_mode)
		return host->caps & SDHCI_CAN_64BIT_V4;

	return host->caps & SDHCI_CAN_64BIT;
}

int sdhci_setup_host(struct sdhci_host *host)
{
	struct mmc_host *mmc;
@@ -3598,7 +3638,7 @@ int sdhci_setup_host(struct sdhci_host *host)
	 * SDHCI_QUIRK2_BROKEN_64_BIT_DMA must be left to the drivers to
	 * implement.
	 */
	if (host->caps & SDHCI_CAN_64BIT)
	if (sdhci_can_64bit_dma(host))
		host->flags |= SDHCI_USE_64_BIT_DMA;

	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
@@ -3626,8 +3666,8 @@ int sdhci_setup_host(struct sdhci_host *host)

		if (host->flags & SDHCI_USE_64_BIT_DMA) {
			host->adma_table_sz = host->adma_table_cnt *
					      SDHCI_ADMA2_64_DESC_SZ;
			host->desc_sz = SDHCI_ADMA2_64_DESC_SZ;
					      SDHCI_ADMA2_64_DESC_SZ(host);
			host->desc_sz = SDHCI_ADMA2_64_DESC_SZ(host);
		} else {
			host->adma_table_sz = host->adma_table_cnt *
					      SDHCI_ADMA2_32_DESC_SZ;
@@ -3635,7 +3675,11 @@ int sdhci_setup_host(struct sdhci_host *host)
		}

		host->align_buffer_sz = SDHCI_MAX_SEGS * SDHCI_ADMA2_ALIGN;
		buf = dma_alloc_coherent(mmc_dev(mmc), host->align_buffer_sz +
		/*
		 * Use zalloc to zero the reserved high 32-bits of 128-bit
		 * descriptors so that they never need to be written.
		 */
		buf = dma_zalloc_coherent(mmc_dev(mmc), host->align_buffer_sz +
					 host->adma_table_sz, &dma, GFP_KERNEL);
		if (!buf) {
			pr_warn("%s: Unable to allocate ADMA buffers - falling back to standard DMA\n",
+10 −2
Original line number Diff line number Diff line
@@ -185,6 +185,7 @@
#define  SDHCI_CTRL_EXEC_TUNING		0x0040
#define  SDHCI_CTRL_TUNED_CLK		0x0080
#define  SDHCI_CTRL_V4_MODE		0x1000
#define  SDHCI_CTRL_64BIT_ADDR		0x2000
#define  SDHCI_CTRL_PRESET_VAL_ENABLE	0x8000

#define SDHCI_CAPABILITIES	0x40
@@ -205,6 +206,7 @@
#define  SDHCI_CAN_VDD_330	0x01000000
#define  SDHCI_CAN_VDD_300	0x02000000
#define  SDHCI_CAN_VDD_180	0x04000000
#define  SDHCI_CAN_64BIT_V4	0x08000000
#define  SDHCI_CAN_64BIT	0x10000000

#define  SDHCI_SUPPORT_SDR50	0x00000001
@@ -309,8 +311,14 @@ struct sdhci_adma2_32_desc {
 */
#define SDHCI_ADMA2_DESC_ALIGN	8

/* ADMA2 64-bit DMA descriptor size */
#define SDHCI_ADMA2_64_DESC_SZ	12
/*
 * ADMA2 64-bit DMA descriptor size
 * According to SD Host Controller spec v4.10, there are two kinds of
 * descriptors for 64-bit addressing mode: 96-bit Descriptor and 128-bit
 * Descriptor, if Host Version 4 Enable is set in the Host Control 2
 * register, 128-bit Descriptor will be selected.
 */
#define SDHCI_ADMA2_64_DESC_SZ(host)	((host)->v4_mode ? 16 : 12)

/*
 * ADMA2 64-bit descriptor. Note 12-byte descriptor can't always be 8-byte