From patchwork Fri Sep 28 07:35:43 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johan Rudholm X-Patchwork-Id: 11837 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 436B523E42 for ; Fri, 28 Sep 2012 07:37:17 +0000 (UTC) Received: from mail-ie0-f180.google.com (mail-ie0-f180.google.com [209.85.223.180]) by fiordland.canonical.com (Postfix) with ESMTP id DCABBA18CAC for ; Fri, 28 Sep 2012 07:37:16 +0000 (UTC) Received: by mail-ie0-f180.google.com with SMTP id e10so6264756iej.11 for ; Fri, 28 Sep 2012 00:37:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:mime-version:content-type :x-gm-message-state; bh=2YPpWe1ZwkZXlbn/32luoFUvAalqT2vHqr7ZjadyNUw=; b=Jp8SBFhjfJWEjHTDtrTdkcnJmQg5w+ZHwW6n2Yzu6V16X6HUlLKxT1ss9NSDDBmWf8 /oMu0wbKAmJ/oIIIr0D5cfaEEkcWQyDgcovbFOwV24k9MgK86h3CVS4hvA2lUILbvwfB KzVkiBHaPnd6WxvtLd1BOlvl9pJSSuzI4HhcjGfO+bs1oRKSPzt5b+cPd8XYofMK3SWD CUBEUIDcdv7IQetLVazGnFMHd2sFMEuxCmUa1A/GFUiTuQ+3RyA4VD8qTZzFD3gwgT3R 3e8O79B2gjCb9zKOnNM/nlbO0/hoW87OCZu6+ovWGUaFbWKeLu9TT9m9anfy56ZG5xnk wfUw== Received: by 10.50.154.227 with SMTP id vr3mr820228igb.43.1348817836612; Fri, 28 Sep 2012 00:37:16 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.184.232 with SMTP id ex8csp456975igc; Fri, 28 Sep 2012 00:37:15 -0700 (PDT) Received: by 10.14.209.129 with SMTP id s1mr8892227eeo.24.1348817834842; Fri, 28 Sep 2012 00:37:14 -0700 (PDT) Received: from eu1sys200aog118.obsmtp.com (eu1sys200aog118.obsmtp.com [207.126.144.145]) by mx.google.com with SMTP id y1si6873969eep.66.2012.09.28.00.37.09 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 28 Sep 2012 00:37:14 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.145 is neither permitted nor denied by best guess record for domain of johan.rudholm@stericsson.com) client-ip=207.126.144.145; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.145 is neither permitted nor denied by best guess record for domain of johan.rudholm@stericsson.com) smtp.mail=johan.rudholm@stericsson.com Received: from beta.dmz-eu.st.com ([164.129.1.35]) (using TLSv1) by eu1sys200aob118.postini.com ([207.126.147.11]) with SMTP ID DSNKUGVTpKk83BOcDqN/CY0aZS+16+HI38Jn@postini.com; Fri, 28 Sep 2012 07:37:14 UTC Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id B3C05E4; Fri, 28 Sep 2012 07:37:04 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id ABDD724E9; Fri, 28 Sep 2012 07:36:17 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id F0975A8083; Fri, 28 Sep 2012 09:36:08 +0200 (CEST) Received: from steludxu1610.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.3.83.0; Fri, 28 Sep 2012 09:36:11 +0200 From: Johan Rudholm To: , Chris Ball Cc: Per Forlin , Ulf Hansson , Fredrik Soderstedt , Kevin Liu , Philip Rakity , Johan Rudholm Subject: [RFC] mmc: sdhci: Let core handle UHS switch failure Date: Fri, 28 Sep 2012 09:35:43 +0200 Message-ID: <1348817743-1391-1-git-send-email-johan.rudholm@stericsson.com> X-Mailer: git-send-email 1.7.10 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQmvPH6eA1aX/ETxtC6eYJIKLr/10Pdvrh5C+kV2UdWyG8ZmOCXyIz8unxFlAjhWrk1tByUF Let the upper layers handle the details of the UHS signal voltage switch, such as timings and detection and handling of failure states. Implement the card_busy host_ops function to let the upper layers check if the card is signaling busy. Signed-off-by: Johan Rudholm --- This is a humble attempt to adapt the sdhci driver so it will work with [RFC/PATCH] mmc: core: Fixup signal voltage switch The patch is untested as I don't have the proper hardware. Furthermore, I don't have any particular insight into how the sdhci controller works, so quite possibly mistakes have been made, but the idea should hopefully be clear. I hope I can get some help at testing this, and I'm grateful for any comments. --- drivers/mmc/host/sdhci.c | 102 ++++++++++++++++------------------------------ 1 file changed, 36 insertions(+), 66 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 0e15c79..01eed72 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1639,80 +1639,32 @@ static int sdhci_do_3_3v_signal_voltage_switch(struct sdhci_host *host, static int sdhci_do_1_8v_signal_voltage_switch(struct sdhci_host *host, u16 ctrl) { - u8 pwr; - u16 clk; - u32 present_state; int ret; - /* Stop SDCLK */ - clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); - clk &= ~SDHCI_CLOCK_CARD_EN; - sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); - - /* Check whether DAT[3:0] is 0000 */ - present_state = sdhci_readl(host, SDHCI_PRESENT_STATE); - if (!((present_state & SDHCI_DATA_LVL_MASK) >> - SDHCI_DATA_LVL_SHIFT)) { - /* - * Enable 1.8V Signal Enable in the Host Control2 - * register - */ - if (host->vqmmc) - ret = regulator_set_voltage(host->vqmmc, - 1800000, 1800000); - else - ret = 0; - - if (!ret) { - ctrl |= SDHCI_CTRL_VDD_180; - sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); - - /* Wait for 5ms */ - usleep_range(5000, 5500); - - ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); - if (ctrl & SDHCI_CTRL_VDD_180) { - /* Provide SDCLK again and wait for 1ms */ - clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); - clk |= SDHCI_CLOCK_CARD_EN; - sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); - usleep_range(1000, 1500); - - /* - * If DAT[3:0] level is 1111b, then the card - * was successfully switched to 1.8V signaling. - */ - present_state = sdhci_readl(host, - SDHCI_PRESENT_STATE); - if ((present_state & SDHCI_DATA_LVL_MASK) == - SDHCI_DATA_LVL_MASK) - return 0; - } + if (host->vqmmc) { + ret = regulator_set_voltage(host->vqmmc, 1800000, 1800000); + if (ret) { + pr_warning("%s: Switching to 1.8V signalling voltage " + " failed\n", mmc_hostname(host->mmc)); + return -EIO; } } - /* - * If we are here, that means the switch to 1.8V signaling - * failed. We power cycle the card, and retry initialization - * sequence by setting S18R to 0. - */ - pwr = sdhci_readb(host, SDHCI_POWER_CONTROL); - pwr &= ~SDHCI_POWER_ON; - sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); - if (host->vmmc) - regulator_disable(host->vmmc); + /* Enable 1.8V Signal Enable in the Host Control2 register */ + ctrl |= SDHCI_CTRL_VDD_180; + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); - /* Wait for 1ms as per the spec */ - usleep_range(1000, 1500); - pwr |= SDHCI_POWER_ON; - sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); - if (host->vmmc) - regulator_enable(host->vmmc); + /* Wait for 5ms */ + usleep_range(5000, 5500); - pr_warning("%s: Switching to 1.8V signalling voltage failed, " - "retrying with S18R set to 0\n", mmc_hostname(host->mmc)); + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + if (ctrl & SDHCI_CTRL_VDD_180) + return 0; + + pr_warning("%s: 1.8V regulator output did not become stable\n", + mmc_hostname(host->mmc)); - return -EAGAIN; + return -EIO; } static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host, @@ -1991,6 +1943,23 @@ static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable) sdhci_runtime_pm_put(host); } +static void sdhci_card_busy(struct mmc_host *mmc, bool keep_busy) +{ + u32 present_state; + struct sdhci_host *host = mmc_priv(mmc); + + /* Check whether DAT[3:0] is 0000 */ + sdhci_runtime_pm_get(host); + present_state = sdhci_readl(host, SDHCI_PRESENT_STATE); + sdhci_runtime_pm_put(host); + + if (!((present_state & SDHCI_DATA_LVL_MASK) >> SDHCI_DATA_LVL_SHIFT)) + return 1; + else + return 0; + +} + static const struct mmc_host_ops sdhci_ops = { .request = sdhci_request, .set_ios = sdhci_set_ios, @@ -2000,6 +1969,7 @@ static const struct mmc_host_ops sdhci_ops = { .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, .execute_tuning = sdhci_execute_tuning, .enable_preset_value = sdhci_enable_preset_value, + .card_busy = sdhci_card_busy, }; /*****************************************************************************\