|
@@ -1340,6 +1340,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
|
|
|
{
|
|
|
struct mmc_command cmd = {0};
|
|
|
int err = 0;
|
|
|
+ u32 clock;
|
|
|
|
|
|
BUG_ON(!host);
|
|
|
|
|
@@ -1347,20 +1348,82 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
|
|
|
* Send CMD11 only if the request is to switch the card to
|
|
|
* 1.8V signalling.
|
|
|
*/
|
|
|
- if (signal_voltage != MMC_SIGNAL_VOLTAGE_330) {
|
|
|
- cmd.opcode = SD_SWITCH_VOLTAGE;
|
|
|
- cmd.arg = 0;
|
|
|
- cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
|
|
|
+ if (signal_voltage == MMC_SIGNAL_VOLTAGE_330)
|
|
|
+ return __mmc_set_signal_voltage(host, signal_voltage);
|
|
|
|
|
|
- err = mmc_wait_for_cmd(host, &cmd, 0);
|
|
|
- if (err)
|
|
|
- return err;
|
|
|
+ /*
|
|
|
+ * If we cannot switch voltages, return failure so the caller
|
|
|
+ * can continue without UHS mode
|
|
|
+ */
|
|
|
+ if (!host->ops->start_signal_voltage_switch)
|
|
|
+ return -EPERM;
|
|
|
+ if (!host->ops->card_busy)
|
|
|
+ pr_warning("%s: cannot verify signal voltage switch\n",
|
|
|
+ mmc_hostname(host));
|
|
|
+
|
|
|
+ cmd.opcode = SD_SWITCH_VOLTAGE;
|
|
|
+ cmd.arg = 0;
|
|
|
+ cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
|
|
|
+
|
|
|
+ err = mmc_wait_for_cmd(host, &cmd, 0);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
|
|
|
- if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
|
|
|
- return -EIO;
|
|
|
+ if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
|
|
|
+ return -EIO;
|
|
|
+
|
|
|
+ mmc_host_clk_hold(host);
|
|
|
+ /*
|
|
|
+ * The card should drive cmd and dat[0:3] low immediately
|
|
|
+ * after the response of cmd11, but wait 1 ms to be sure
|
|
|
+ */
|
|
|
+ mmc_delay(1);
|
|
|
+ if (host->ops->card_busy && !host->ops->card_busy(host)) {
|
|
|
+ err = -EAGAIN;
|
|
|
+ goto power_cycle;
|
|
|
}
|
|
|
+ /*
|
|
|
+ * During a signal voltage level switch, the clock must be gated
|
|
|
+ * for 5 ms according to the SD spec
|
|
|
+ */
|
|
|
+ clock = host->ios.clock;
|
|
|
+ host->ios.clock = 0;
|
|
|
+ mmc_set_ios(host);
|
|
|
|
|
|
- return __mmc_set_signal_voltage(host, signal_voltage);
|
|
|
+ if (__mmc_set_signal_voltage(host, signal_voltage)) {
|
|
|
+ /*
|
|
|
+ * Voltages may not have been switched, but we've already
|
|
|
+ * sent CMD11, so a power cycle is required anyway
|
|
|
+ */
|
|
|
+ err = -EAGAIN;
|
|
|
+ goto power_cycle;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Keep clock gated for at least 5 ms */
|
|
|
+ mmc_delay(5);
|
|
|
+ host->ios.clock = clock;
|
|
|
+ mmc_set_ios(host);
|
|
|
+
|
|
|
+ /* Wait for at least 1 ms according to spec */
|
|
|
+ mmc_delay(1);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Failure to switch is indicated by the card holding
|
|
|
+ * dat[0:3] low
|
|
|
+ */
|
|
|
+ if (host->ops->card_busy && host->ops->card_busy(host))
|
|
|
+ err = -EAGAIN;
|
|
|
+
|
|
|
+power_cycle:
|
|
|
+ if (err) {
|
|
|
+ pr_debug("%s: Signal voltage switch failed, "
|
|
|
+ "power cycling card\n", mmc_hostname(host));
|
|
|
+ mmc_power_cycle(host);
|
|
|
+ }
|
|
|
+
|
|
|
+ mmc_host_clk_release(host);
|
|
|
+
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
/*
|