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

Commit 2385049d authored by Seungwon Jeon's avatar Seungwon Jeon Committed by Chris Ball
Browse files

mmc: step power class after final selection of bus mode



Power class is changed once only after selection of bus modes
including speed and bus-width finishes finally.

Signed-off-by: default avatarSeungwon Jeon <tgih.jun@samsung.com>
Tested-by: default avatarJaehoon Chung <jh80.chung@samsung.com>
Acked-by: default avatarJaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Signed-off-by: default avatarChris Ball <chris@printf.net>
parent 2415c0ef
Loading
Loading
Loading
Loading
+55 −41
Original line number Diff line number Diff line
@@ -724,17 +724,13 @@ static struct device_type mmc_type = {
 * extended CSD register, select it by executing the
 * mmc_switch command.
 */
static int mmc_select_powerclass(struct mmc_card *card,
static int __mmc_select_powerclass(struct mmc_card *card,
				   unsigned int bus_width)
{
	int err = 0;
	struct mmc_host *host = card->host;
	struct mmc_ext_csd *ext_csd = &card->ext_csd;
	unsigned int pwrclass_val = 0;
	struct mmc_host *host;

	BUG_ON(!card);

	host = card->host;
	BUG_ON(!host);
	int err = 0;

	/* Power class selection is supported for versions >= 4.0 */
	if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
@@ -746,14 +742,14 @@ static int mmc_select_powerclass(struct mmc_card *card,

	switch (1 << host->ios.vdd) {
	case MMC_VDD_165_195:
		if (host->ios.clock <= 26000000)
			pwrclass_val = card->ext_csd.raw_pwr_cl_26_195;
		else if	(host->ios.clock <= 52000000)
		if (host->ios.clock <= MMC_HIGH_26_MAX_DTR)
			pwrclass_val = ext_csd->raw_pwr_cl_26_195;
		else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR)
			pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
				card->ext_csd.raw_pwr_cl_52_195 :
				card->ext_csd.raw_pwr_cl_ddr_52_195;
		else if (host->ios.clock <= 200000000)
			pwrclass_val = card->ext_csd.raw_pwr_cl_200_195;
				ext_csd->raw_pwr_cl_52_195 :
				ext_csd->raw_pwr_cl_ddr_52_195;
		else if (host->ios.clock <= MMC_HS200_MAX_DTR)
			pwrclass_val = ext_csd->raw_pwr_cl_200_195;
		break;
	case MMC_VDD_27_28:
	case MMC_VDD_28_29:
@@ -764,14 +760,14 @@ static int mmc_select_powerclass(struct mmc_card *card,
	case MMC_VDD_33_34:
	case MMC_VDD_34_35:
	case MMC_VDD_35_36:
		if (host->ios.clock <= 26000000)
			pwrclass_val = card->ext_csd.raw_pwr_cl_26_360;
		else if	(host->ios.clock <= 52000000)
		if (host->ios.clock <= MMC_HIGH_26_MAX_DTR)
			pwrclass_val = ext_csd->raw_pwr_cl_26_360;
		else if (host->ios.clock <= MMC_HIGH_52_MAX_DTR)
			pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
				card->ext_csd.raw_pwr_cl_52_360 :
				card->ext_csd.raw_pwr_cl_ddr_52_360;
		else if (host->ios.clock <= 200000000)
			pwrclass_val = card->ext_csd.raw_pwr_cl_200_360;
				ext_csd->raw_pwr_cl_52_360 :
				ext_csd->raw_pwr_cl_ddr_52_360;
		else if (host->ios.clock <= MMC_HS200_MAX_DTR)
			pwrclass_val = ext_csd->raw_pwr_cl_200_360;
		break;
	default:
		pr_warning("%s: Voltage range not supported "
@@ -797,6 +793,37 @@ static int mmc_select_powerclass(struct mmc_card *card,
	return err;
}

static int mmc_select_powerclass(struct mmc_card *card)
{
	struct mmc_host *host = card->host;
	u32 bus_width, ext_csd_bits;
	int err, ddr;

	/* Power class selection is supported for versions >= 4.0 */
	if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
		return 0;

	bus_width = host->ios.bus_width;
	/* Power class values are defined only for 4/8 bit bus */
	if (bus_width == MMC_BUS_WIDTH_1)
		return 0;

	ddr = card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52;
	if (ddr)
		ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
			EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4;
	else
		ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
			EXT_CSD_BUS_WIDTH_8 :  EXT_CSD_BUS_WIDTH_4;

	err = __mmc_select_powerclass(card, ext_csd_bits);
	if (err)
		pr_warn("%s: power class selection to bus width %d ddr %d failed\n",
			mmc_hostname(host), 1 << bus_width, ddr);

	return err;
}

/*
 * Selects the desired buswidth and switch to the HS200 mode
 * if bus width set without error
@@ -1158,11 +1185,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,

		ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
				EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
		err = mmc_select_powerclass(card, ext_csd_bits);
		if (err)
			pr_warning("%s: power class selection to bus width %d"
				   " failed\n", mmc_hostname(card->host),
				   1 << bus_width);
	}

	/*
@@ -1191,12 +1213,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
			bus_width = bus_widths[idx];
			if (bus_width == MMC_BUS_WIDTH_1)
				ddr = 0; /* no DDR for 1-bit width */
			err = mmc_select_powerclass(card, ext_csd_bits[idx][0]);
			if (err)
				pr_warning("%s: power class selection to "
					   "bus width %d failed\n",
					   mmc_hostname(card->host),
					   1 << bus_width);

			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
					 EXT_CSD_BUS_WIDTH,
@@ -1221,13 +1237,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
		}

		if (!err && ddr) {
			err = mmc_select_powerclass(card, ext_csd_bits[idx][1]);
			if (err)
				pr_warning("%s: power class selection to "
					   "bus width %d ddr %d failed\n",
					   mmc_hostname(card->host),
					   1 << bus_width, ddr);

			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
					 EXT_CSD_BUS_WIDTH,
					 ext_csd_bits[idx][1],
@@ -1264,6 +1273,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
		}
	}

	/*
	 * Choose the power class with selected bus interface
	 */
	mmc_select_powerclass(card);

	/*
	 * Enable HPI feature (if supported)
	 */