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

Commit 4c4cb171 authored by Philip Rakity's avatar Philip Rakity Committed by Chris Ball
Browse files

mmc: core: add support for eMMC Dual Data Rate



eMMC voltage change not required for 1.8V.  3.3V and 1.8V vcc
are capable of doing DDR. vccq of 1.8v is not required.

Signed-off-by: default avatarPhilip Rakity <prakity@marvell.com>
Reviewed-by: default avatarArindam Nath <arindam.nath@amd.com>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 261bbd46
Loading
Loading
Loading
Loading
+2 −12
Original line number Diff line number Diff line
@@ -717,23 +717,13 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
	mmc_set_ios(host);
}

/*
 * Change data bus width and DDR mode of a host.
 */
void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,
			   unsigned int ddr)
{
	host->ios.bus_width = width;
	host->ios.ddr = ddr;
	mmc_set_ios(host);
}

/*
 * Change data bus width of a host.
 */
void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
{
	mmc_set_bus_width_ddr(host, width, MMC_SDR_MODE);
	host->ios.bus_width = width;
	mmc_set_ios(host);
}

/**
+0 −2
Original line number Diff line number Diff line
@@ -38,8 +38,6 @@ void mmc_ungate_clock(struct mmc_host *host);
void mmc_set_ungated(struct mmc_host *host);
void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);
void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,
			   unsigned int ddr);
u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage,
			   bool cmd11);
+30 −5
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include "core.h"
#include "bus.h"
#include "mmc_ops.h"
#include "sd_ops.h"

static const unsigned int tran_exp[] = {
	10000,		100000,		1000000,	10000000,
@@ -633,10 +634,14 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
	 */
	if (mmc_card_highspeed(card)) {
		if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V)
			&& (host->caps & (MMC_CAP_1_8V_DDR)))
			&& ((host->caps & (MMC_CAP_1_8V_DDR |
			     MMC_CAP_UHS_DDR50))
				== (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50)))
				ddr = MMC_1_8V_DDR_MODE;
		else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V)
			&& (host->caps & (MMC_CAP_1_2V_DDR)))
			&& ((host->caps & (MMC_CAP_1_2V_DDR |
			     MMC_CAP_UHS_DDR50))
				== (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50)))
				ddr = MMC_1_2V_DDR_MODE;
	}

@@ -670,8 +675,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
					 ext_csd_bits[idx][0],
					 0);
			if (!err) {
				mmc_set_bus_width_ddr(card->host,
						      bus_width, MMC_SDR_MODE);
				mmc_set_bus_width(card->host, bus_width);
				/*
				 * If controller can't handle bus width test,
				 * use the highest bus width to maintain
@@ -697,8 +701,29 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
				1 << bus_width, ddr);
			goto free_card;
		} else if (ddr) {
			/*
			 * eMMC cards can support 3.3V to 1.2V i/o (vccq)
			 * signaling.
			 *
			 * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq.
			 *
			 * 1.8V vccq at 3.3V core voltage (vcc) is not required
			 * in the JEDEC spec for DDR.
			 *
			 * Do not force change in vccq since we are obviously
			 * working and no change to vccq is needed.
			 *
			 * WARNING: eMMC rules are NOT the same as SD DDR
			 */
			if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) {
				err = mmc_set_signal_voltage(host,
					MMC_SIGNAL_VOLTAGE_120, 0);
				if (err)
					goto err;
			}
			mmc_card_set_ddr_mode(card);
			mmc_set_bus_width_ddr(card->host, bus_width, ddr);
			mmc_set_timing(card->host, MMC_TIMING_UHS_DDR50);
			mmc_set_bus_width(card->host, bus_width);
		}
	}

+1 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ struct mmc_ios {

#define MMC_SIGNAL_VOLTAGE_330	0
#define MMC_SIGNAL_VOLTAGE_180	1
#define MMC_SIGNAL_VOLTAGE_120	2

	unsigned char	drv_type;		/* driver type (A, B, C, D) */