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

Commit b3dade15 authored by Asutosh Das's avatar Asutosh Das Committed by Sujit Reddy Thumma
Browse files

mmc: sdhci: Turn on controller clocks and card power at MMC_POWER_UP



Currently, the clock to the card is enabled prior to enabling
the power to card. Specification requires that the power be
supplied first and then a delay of 10ms and then clock be
provided to the card.

In this, during MMC_POWER_UP mode, the controller clocks would be
ON and the power would be supplied to the card. In the MMC_POWER_ON
mode, the clocks to the card would be enabled and the rate set.
A callback has been provided to facilitate the enabling of
controller clocks.

CRs-Fixed: 567658
Change-Id: I2d66eae1581b9b136faaba4cafc330aeb6a3f364
Signed-off-by: default avatarAsutosh Das <asutoshd@codeaurora.org>
parent bcb87d5a
Loading
Loading
Loading
Loading
+30 −4
Original line number Diff line number Diff line
@@ -1783,6 +1783,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
	unsigned long flags;
	int vdd_bit = -1;
	u8 ctrl;
	int ret;

	mutex_lock(&host->ios_mutex);
	if (host->flags & SDHCI_DEVICE_DEAD) {
@@ -1812,6 +1813,29 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
				 mmc_hostname(host->mmc), __func__);
		}
	}
	/*
	 * The controller clocks may be off during power-up and we may end up
	 * enabling card clock before giving power to the card. Hence, during
	 * MMC_POWER_UP enable the controller clock and turn-on the regulators.
	 * The mmc_power_up would provide the necessary delay before turning on
	 * the clocks to the card.
	 */
	if (ios->power_mode & MMC_POWER_UP) {
		if (host->ops->enable_controller_clock) {
			ret = host->ops->enable_controller_clock(host);
			if (ret) {
				pr_err("%s: enabling controller clock: failed: %d\n",
				       mmc_hostname(host->mmc), ret);
			} else {
				vdd_bit = sdhci_set_power(host, ios->vdd);

				if (host->vmmc && vdd_bit != -1)
					mmc_regulator_set_ocr(host->mmc,
							      host->vmmc,
							      vdd_bit);
			}
		}
	}
	spin_lock_irqsave(&host->lock, flags);
	if (!host->clock) {
		sdhci_cfg_irq(host, true);
@@ -1825,14 +1849,16 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
		(ios->power_mode == MMC_POWER_UP))
		sdhci_enable_preset_value(host, false);

	if (ios->power_mode & (MMC_POWER_UP | MMC_POWER_ON))
	if (!host->ops->enable_controller_clock && (ios->power_mode &
						    (MMC_POWER_UP |
						     MMC_POWER_ON))) {
		vdd_bit = sdhci_set_power(host, ios->vdd);

		if (host->vmmc && vdd_bit != -1)
			mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit);
	}

	spin_lock_irqsave(&host->lock, flags);

	if (host->ops->platform_send_init_74_clocks)
		host->ops->platform_send_init_74_clocks(host, ios->power_mode);

+1 −0
Original line number Diff line number Diff line
@@ -320,6 +320,7 @@ struct sdhci_ops {
	int	(*config_auto_tuning_cmd)(struct sdhci_host *host,
					  bool enable,
					  u32 type);
	int	(*enable_controller_clock)(struct sdhci_host *host);
};

#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS