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

Commit 0c758bb6 authored by Asutosh Das's avatar Asutosh Das Committed by Subhash Jadavani
Browse files

mmc: core: add clock-scaling support to HS400 cards



This patch adds clock scaling support to HS400 cards.
Scaling down to 52MHz from HS400 involves:
 - switching the bus-speed mode to HS at 52MHz

Scaling up to HS400 would require all of the initialization
process upto HS400 mode selection.

Change-Id: I8196d6666bcc0ef327659253df53a17792fa51f7
Signed-off-by: default avatarAsutosh Das <asutoshd@codeaurora.org>
Signed-off-by: default avatarKrishna Konda <kkonda@codeaurora.org>
[venkatg@codeaurora.org: fix mmc_select_hs args and MAX_DTRs
as used in 3.14 kernel]
Signed-off-by: default avatarVenkat Gopalakrishnan <venkatg@codeaurora.org>
[subhashj@codeaurora.org: fixed merge conflicts]
Signed-off-by: default avatarSubhash Jadavani <subhashj@codeaurora.org>
parent 3f3e47cf
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -2689,13 +2689,19 @@ EXPORT_SYMBOL_GPL(mmc_reset_clk_scale_stats);
unsigned long mmc_get_max_frequency(struct mmc_host *host)
{
	unsigned long freq;
	unsigned char timing;

	if (host->ops && host->ops->get_max_frequency) {
		freq = host->ops->get_max_frequency(host);
		goto out;
	}

	switch (host->ios.timing) {
	if (mmc_card_hs400(host->card))
		timing = MMC_TIMING_MMC_HS400;
	else
		timing = host->ios.timing;

	switch (timing) {
	case MMC_TIMING_UHS_SDR50:
		freq = UHS_SDR50_MAX_DTR;
		break;
@@ -2708,6 +2714,9 @@ unsigned long mmc_get_max_frequency(struct mmc_host *host)
	case MMC_TIMING_UHS_DDR50:
		freq = UHS_DDR50_MAX_DTR;
		break;
	case MMC_TIMING_MMC_HS400:
		freq = MMC_HS200_MAX_DTR;
		break;
	default:
		mmc_host_clk_hold(host);
		freq = host->ios.clock;
@@ -2748,6 +2757,9 @@ static unsigned long mmc_get_min_frequency(struct mmc_host *host)
	case MMC_TIMING_MMC_HS200:
		freq = MMC_HIGH_52_MAX_DTR;
		break;
	case MMC_TIMING_MMC_HS400:
		freq = MMC_HIGH_52_MAX_DTR;
		break;
	case MMC_TIMING_UHS_DDR50:
		freq = UHS_DDR50_MAX_DTR / 2;
		break;
+28 −1
Original line number Diff line number Diff line
@@ -624,6 +624,7 @@ static int mmc_read_ext_csd(struct mmc_card *card)
		return err;
	}

	memcpy(&card->cached_ext_csd, ext_csd, sizeof(card->ext_csd));
	err = mmc_decode_ext_csd(card, ext_csd);
	kfree(ext_csd);
	return err;
@@ -1299,6 +1300,26 @@ err:
	return err;
}

int mmc_set_clock_bus_speed(struct mmc_card *card, unsigned long freq)
{
	int err;

	if (freq < MMC_HS200_MAX_DTR) {
		/*
		 * Lower the clock and adjust the timing to be able
		 * to switch to HighSpeed mode
		 */
		mmc_set_timing(card->host, MMC_TIMING_LEGACY);
		mmc_set_clock(card->host, MMC_HIGH_26_MAX_DTR);

		err = mmc_select_hs(card);
	} else {
		err = mmc_select_hs400(card);
	}

	return err;
}

/**
 * mmc_change_bus_speed() - Change MMC card bus frequency at runtime
 * @host: pointer to mmc host structure
@@ -1340,7 +1361,13 @@ static int mmc_change_bus_speed(struct mmc_host *host, unsigned long *freq)
	if (*freq < host->f_min)
		*freq = host->f_min;

	if (mmc_card_hs400(card)) {
		err = mmc_set_clock_bus_speed(card, *freq);
		if (err)
			goto out;
	} else {
		mmc_set_clock(host, (unsigned int) (*freq));
	}

	if (mmc_card_hs200(card) && card->host->ops->execute_tuning) {
		/*
+1 −0
Original line number Diff line number Diff line
@@ -345,6 +345,7 @@ struct mmc_card {
	struct mmc_wr_pack_stats wr_pack_stats; /* packed commands stats*/
	struct notifier_block        reboot_notify;
	bool issue_long_pon;
	u8 cached_ext_csd;
};

/*