From patchwork Mon Oct 8 13:18:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Veerabhadrarao Badiganti X-Patchwork-Id: 10630723 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7425414BD for ; Mon, 8 Oct 2018 13:22:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 62485291B2 for ; Mon, 8 Oct 2018 13:22:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 55C522928B; Mon, 8 Oct 2018 13:22:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E24A6291B2 for ; Mon, 8 Oct 2018 13:22:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726056AbeJHUeE (ORCPT ); Mon, 8 Oct 2018 16:34:04 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:36812 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726014AbeJHUeD (ORCPT ); Mon, 8 Oct 2018 16:34:03 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 004D960769; Mon, 8 Oct 2018 13:22:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1539004941; bh=fgqo74zOcHyf4Bte0NwVayfSzF1zdMXTrDJZBGbTJ0Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jZRBbOFI7t2MyxZgERgbNoV2L0TqCt33250JRhBZde46xImg1qCGa6LyGsSN6RpMS gn1e3hF50fhx/zKmYk8o9AZbGDckRbOMMMFy1fzjS8SfdRBGFAahwvOmoOdX54A2ZD xhNaDelmpGHuDZUW2G9JZtoSNDAclROVtwKsaKEQ= Received: from vbadigan-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: vbadigan@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id B2D5060769; Mon, 8 Oct 2018 13:22:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1539004940; bh=fgqo74zOcHyf4Bte0NwVayfSzF1zdMXTrDJZBGbTJ0Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=U+wW/if9zpU+E8+uTtTtjHDnPtJCQ3frf8C8MfgBdYc/RURT+khl3grityVFeDPvU XF4L6wNADcFx+KXpqy8KMGWHbCGoURvOGf0Fi2NOBVDOAu2QKzVy4ZTmkVhE3L7+y/ 3tt9lj5Cv79ej6QqsRRcRDlNnNdxtfHkyWAhrIDg= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org B2D5060769 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=vbadigan@codeaurora.org From: Veerabhadrarao Badiganti To: adrian.hunter@intel.com, ulf.hansson@linaro.org, robh+dt@kernel.org, evgreen@chromium.org, dianders@google.com Cc: asutoshd@codeaurora.org, riteshh@codeaurora.org, stummala@codeaurora.org, sayalil@codeaurora.org, linux-mmc@vger.kernel.org, linux-arm-msm@vger.kernel.org, Vijay Viswanath , Veerabhadrarao Badiganti , linux-kernel@vger.kernel.org (open list) Subject: [PATCH V3 1/3] mmc: sdhci: Allow platform controlled voltage switching Date: Mon, 8 Oct 2018 18:48:57 +0530 Message-Id: <1539004739-32060-2-git-send-email-vbadigan@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1539004739-32060-1-git-send-email-vbadigan@codeaurora.org> References: <1539004739-32060-1-git-send-email-vbadigan@codeaurora.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Vijay Viswanath Some controllers can have internal mechanism to inform the SW that it is ready for voltage switching. For such controllers, changing voltage before the HW is ready can result in various issues. During setup/cleanup of host, check whether regulator enable/disable was already done by platform driver. Signed-off-by: Vijay Viswanath Signed-off-by: Veerabhadrarao Badiganti --- drivers/mmc/host/sdhci.c | 32 +++++++++++++++++++------------- drivers/mmc/host/sdhci.h | 1 + 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 99bdae5..ea7ce1d 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -3616,6 +3616,7 @@ int sdhci_setup_host(struct sdhci_host *host) unsigned int override_timeout_clk; u32 max_clk; int ret; + bool enable_vqmmc = false; WARN_ON(host == NULL); if (host == NULL) @@ -3629,9 +3630,12 @@ int sdhci_setup_host(struct sdhci_host *host) * the host can take the appropriate action if regulators are not * available. */ - ret = mmc_regulator_get_supply(mmc); - if (ret) - return ret; + if (!mmc->supply.vqmmc) { + ret = mmc_regulator_get_supply(mmc); + if (ret) + return ret; + enable_vqmmc = true; + } DBG("Version: 0x%08x | Present: 0x%08x\n", sdhci_readw(host, SDHCI_HOST_VERSION), @@ -3880,7 +3884,15 @@ int sdhci_setup_host(struct sdhci_host *host) mmc->caps |= MMC_CAP_NEEDS_POLL; if (!IS_ERR(mmc->supply.vqmmc)) { - ret = regulator_enable(mmc->supply.vqmmc); + if (enable_vqmmc) { + ret = regulator_enable(mmc->supply.vqmmc); + if (ret) { + pr_warn("%s: Failed to enable vqmmc regulator: %d\n", + mmc_hostname(mmc), ret); + mmc->supply.vqmmc = ERR_PTR(-EINVAL); + } + host->vqmmc_enabled = !ret; + } /* If vqmmc provides no 1.8V signalling, then there's no UHS */ if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 1700000, @@ -3893,12 +3905,6 @@ int sdhci_setup_host(struct sdhci_host *host) if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 2700000, 3600000)) host->flags &= ~SDHCI_SIGNALING_330; - - if (ret) { - pr_warn("%s: Failed to enable vqmmc regulator: %d\n", - mmc_hostname(mmc), ret); - mmc->supply.vqmmc = ERR_PTR(-EINVAL); - } } if (host->quirks2 & SDHCI_QUIRK2_NO_1_8_V) { @@ -4136,7 +4142,7 @@ int sdhci_setup_host(struct sdhci_host *host) return 0; unreg: - if (!IS_ERR(mmc->supply.vqmmc)) + if (host->vqmmc_enabled) regulator_disable(mmc->supply.vqmmc); undma: if (host->align_buffer) @@ -4154,7 +4160,7 @@ void sdhci_cleanup_host(struct sdhci_host *host) { struct mmc_host *mmc = host->mmc; - if (!IS_ERR(mmc->supply.vqmmc)) + if (host->vqmmc_enabled) regulator_disable(mmc->supply.vqmmc); if (host->align_buffer) @@ -4287,7 +4293,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) tasklet_kill(&host->finish_tasklet); - if (!IS_ERR(mmc->supply.vqmmc)) + if (host->vqmmc_enabled) regulator_disable(mmc->supply.vqmmc); if (host->align_buffer) diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index b001cf4..3c28152 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -524,6 +524,7 @@ struct sdhci_host { bool pending_reset; /* Cmd/data reset is pending */ bool irq_wake_enabled; /* IRQ wakeup is enabled */ bool v4_mode; /* Host Version 4 Enable */ + bool vqmmc_enabled; /* Vqmmc is enabled */ struct mmc_request *mrqs_done[SDHCI_MAX_MRQS]; /* Requests done */ struct mmc_command *cmd; /* Current command */ From patchwork Mon Oct 8 13:18:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Veerabhadrarao Badiganti X-Patchwork-Id: 10630725 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9858C14BD for ; Mon, 8 Oct 2018 13:22:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D69AD291B2 for ; Mon, 8 Oct 2018 13:22:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C85EF29234; Mon, 8 Oct 2018 13:22:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6965B291B2 for ; Mon, 8 Oct 2018 13:22:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726075AbeJHUeW (ORCPT ); Mon, 8 Oct 2018 16:34:22 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:37150 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726014AbeJHUeW (ORCPT ); Mon, 8 Oct 2018 16:34:22 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 7980060C1D; Mon, 8 Oct 2018 13:22:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1539004959; bh=nSLT5lHo5MhIbh9ymFOKPVTgS1R7enMrsy0vHjPgusE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=km9+3ZIJ9OIZFsaJYwenK8Il1HXmqa4hI/WBfDa8FbD3lvCCScyNUcEdG14wNTJ+w QZ/7rkVlQbHpi59FgNBOgyIx/Xu0CVD+lce6CXwuIhweXsyFu0dYhWI0kLHUODVdPo K6biAAVJCNd2ArMbxq+5OlNfoAwJxrYLoAt84+C4= Received: from vbadigan-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: vbadigan@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id C375D6083C; Mon, 8 Oct 2018 13:22:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1539004958; bh=nSLT5lHo5MhIbh9ymFOKPVTgS1R7enMrsy0vHjPgusE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BLUOELN5lM3QoZ3sBhJRnDLCHRWrsAiWFBjwzc4hTOqK3XrZa9sOlwhbREVUlmpjN AR0EFfSlND/UGI0HmqKcI1GHk0XM3k+JBCVAfN/HpdHK4ixBxC1CLY5LRnSgQjTF9H td14PULluBX0+k0g438yMdyYgv30q9LnD3LIrwDI= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org C375D6083C Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=vbadigan@codeaurora.org From: Veerabhadrarao Badiganti To: adrian.hunter@intel.com, ulf.hansson@linaro.org, robh+dt@kernel.org, evgreen@chromium.org, dianders@google.com Cc: asutoshd@codeaurora.org, riteshh@codeaurora.org, stummala@codeaurora.org, sayalil@codeaurora.org, linux-mmc@vger.kernel.org, linux-arm-msm@vger.kernel.org, Vijay Viswanath , Veerabhadrarao Badiganti , Mark Rutland , devicetree@vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS), linux-kernel@vger.kernel.org (open list) Subject: [PATCH V3 2/3] dt-bindings: mmc: sdhci-msm: Add entries for passing load values Date: Mon, 8 Oct 2018 18:48:58 +0530 Message-Id: <1539004739-32060-3-git-send-email-vbadigan@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1539004739-32060-1-git-send-email-vbadigan@codeaurora.org> References: <1539004739-32060-1-git-send-email-vbadigan@codeaurora.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Vijay Viswanath The load a particular sdhc controller should request from a regulator is device specific and hence each device should individually vote for the required load. Signed-off-by: Vijay Viswanath Signed-off-by: Veerabhadrarao Badiganti --- Documentation/devicetree/bindings/mmc/sdhci-msm.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt index 502b3b8..cb22178 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt @@ -25,6 +25,10 @@ Required properties: "xo" - TCXO clock (optional) "cal" - reference clock for RCLK delay calibration (optional) "sleep" - sleep clock for RCLK delay calibration (optional) +- qcom,-current-level-microamp - specifies load levels for supply during BUS_ON and + BUS_OFF states in power irq. Should be specified in + pairs (lpm, hpm), for BUS_OFF and BUS_ON respectively. + Units uA. Example: @@ -36,7 +40,9 @@ Example: non-removable; vmmc-supply = <&pm8941_l20>; + qcom,vmmc-current-level-microamp = <200 570000>; vqmmc-supply = <&pm8941_s3>; + qcom,vqmmc-current-level-microamp = <200 325000>; pinctrl-names = "default"; pinctrl-0 = <&sdc1_clk &sdc1_cmd &sdc1_data>; @@ -53,7 +59,9 @@ Example: cd-gpios = <&msmgpio 62 0x1>; vmmc-supply = <&pm8941_l21>; + qcom,vmmc-current-level-microamp = <200 800000>; vqmmc-supply = <&pm8941_l13>; + qcom,vqmmc-current-level-microamp = <200 22000>; pinctrl-names = "default"; pinctrl-0 = <&sdc2_clk &sdc2_cmd &sdc2_data>; From patchwork Mon Oct 8 13:18:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Veerabhadrarao Badiganti X-Patchwork-Id: 10630731 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 452F613BB for ; Mon, 8 Oct 2018 13:23:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2DF1E2920F for ; Mon, 8 Oct 2018 13:23:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 211D02927F; Mon, 8 Oct 2018 13:23:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 655542920F for ; Mon, 8 Oct 2018 13:23:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726476AbeJHUek (ORCPT ); Mon, 8 Oct 2018 16:34:40 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:37450 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726014AbeJHUek (ORCPT ); Mon, 8 Oct 2018 16:34:40 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 8DC3A60B7A; Mon, 8 Oct 2018 13:22:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1539004976; bh=/v5IABfBgn1hYcq94CSp6yIxArubLkxZNqflIrtxe78=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jqNKvOstAEE281aOlBp8QxyyhCer4kWODOJ5wNCumH3SaB/6lulmrPNTnrX12qGRa bcJSIRy/9qxzjOHE3ONC/z2XssB8RRV/N6Ktms0DP6Z+gca9KpG7J5wJ3HpC9wQCoQ MqV8qCJRlIrZgN6D9pPpRregJkvXHnUjyCLf//ag= Received: from vbadigan-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: vbadigan@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id A94A960769; Mon, 8 Oct 2018 13:22:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1539004975; bh=/v5IABfBgn1hYcq94CSp6yIxArubLkxZNqflIrtxe78=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bB0Ovi5ggO284mWViYUDS1a/8YQXKq80jbjj0kZo+cFnNuG9JP6hYTD1NnrAkOa31 E+bKbKFx8kL4zdewRvLXuN1ptRxDugB6ek9SFhLSxMQEMsr/wJ3OMzZX4t+tnj/ZN/ YIdNSfVgo0GRvorhvXX3xXpPW++750WG9nQxqv2M= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org A94A960769 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=vbadigan@codeaurora.org From: Veerabhadrarao Badiganti To: adrian.hunter@intel.com, ulf.hansson@linaro.org, robh+dt@kernel.org, evgreen@chromium.org, dianders@google.com Cc: asutoshd@codeaurora.org, riteshh@codeaurora.org, stummala@codeaurora.org, sayalil@codeaurora.org, linux-mmc@vger.kernel.org, linux-arm-msm@vger.kernel.org, Vijay Viswanath , Venkat Gopalakrishnan , Veerabhadrarao Badiganti , linux-kernel@vger.kernel.org (open list) Subject: [PATCH V3 3/3] mmc: sdhci-msm: Use internal voltage control Date: Mon, 8 Oct 2018 18:48:59 +0530 Message-Id: <1539004739-32060-4-git-send-email-vbadigan@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1539004739-32060-1-git-send-email-vbadigan@codeaurora.org> References: <1539004739-32060-1-git-send-email-vbadigan@codeaurora.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Vijay Viswanath Some sdhci-msm controllers require that voltage switching be done after the HW is ready for it. The HW informs its readiness through power irq. The voltage switching should happen only then. Use the quirk for internal voltage switching and then control the voltage switching using power irq. Signed-off-by: Asutosh Das Signed-off-by: Venkat Gopalakrishnan Signed-off-by: Vijay Viswanath Signed-off-by: Veerabhadrarao Badiganti --- drivers/mmc/host/sdhci-msm.c | 212 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 204 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 3cc8bfe..6918e70 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -43,7 +43,9 @@ #define CORE_PWRCTL_IO_LOW BIT(2) #define CORE_PWRCTL_IO_HIGH BIT(3) #define CORE_PWRCTL_BUS_SUCCESS BIT(0) +#define CORE_PWRCTL_BUS_FAIL BIT(1) #define CORE_PWRCTL_IO_SUCCESS BIT(2) +#define CORE_PWRCTL_IO_FAIL BIT(3) #define REQ_BUS_OFF BIT(0) #define REQ_BUS_ON BIT(1) #define REQ_IO_LOW BIT(2) @@ -258,6 +260,10 @@ struct sdhci_msm_host { bool mci_removed; const struct sdhci_msm_variant_ops *var_ops; const struct sdhci_msm_offset *offset; + bool vmmc_load; + u32 vmmc_level[2]; + bool vqmmc_load; + u32 vqmmc_level[2]; }; static const struct sdhci_msm_offset *sdhci_priv_msm_offset(struct sdhci_host *host) @@ -1211,6 +1217,74 @@ static void sdhci_msm_set_uhs_signaling(struct sdhci_host *host, sdhci_msm_hs400(host, &mmc->ios); } +static int sdhci_msm_set_vmmc(struct sdhci_msm_host *msm_host, + struct mmc_host *mmc, int level) +{ + int load = msm_host->vmmc_level[level]; + int ret; + + if (IS_ERR(mmc->supply.vmmc)) + return 0; + + if (msm_host->vmmc_load) { + ret = regulator_set_load(mmc->supply.vmmc, load); + if (ret) + goto out; + } + + ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, mmc->ios.vdd); +out: + if (ret) + pr_err("%s: vmmc set load/ocr failed: %d\n", + mmc_hostname(mmc), ret); + + return ret; +} + +static int sdhci_msm_set_vqmmc(struct sdhci_msm_host *msm_host, + struct mmc_host *mmc, int level) +{ + int load = msm_host->vqmmc_level[level]; + int ret; + struct mmc_ios ios; + + if (IS_ERR(mmc->supply.vqmmc)) + return 0; + + if (msm_host->vqmmc_load) { + ret = regulator_set_load(mmc->supply.vqmmc, load); + if (ret) + goto out; + } + + /* + * The IO voltage regulator may not always support a voltage close to + * vdd. Set IO voltage based on capability of the regulator. + */ + if (level) { + if (msm_host->caps_0 & CORE_3_0V_SUPPORT) + ios.signal_voltage = MMC_SIGNAL_VOLTAGE_330; + else if (msm_host->caps_0 & CORE_1_8V_SUPPORT) + ios.signal_voltage = MMC_SIGNAL_VOLTAGE_180; + if (msm_host->caps_0 & CORE_VOLT_SUPPORT) { + pr_debug("%s: %s: setting signal voltage: %d\n", + mmc_hostname(mmc), __func__, + ios.signal_voltage); + ret = mmc_regulator_set_vqmmc(mmc, &ios); + if (ret) + goto out; + } + ret = regulator_enable(mmc->supply.vqmmc); + } else { + ret = regulator_disable(mmc->supply.vqmmc); + } +out: + if (ret) + pr_err("%s: vqmmc failed: %d\n", mmc_hostname(mmc), ret); + + return ret; +} + static inline void sdhci_msm_init_pwr_irq_wait(struct sdhci_msm_host *msm_host) { init_waitqueue_head(&msm_host->pwr_irq_wait); @@ -1314,8 +1388,9 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); + struct mmc_host *mmc = host->mmc; u32 irq_status, irq_ack = 0; - int retry = 10; + int retry = 10, ret = 0; u32 pwr_state = 0, io_level = 0; u32 config; const struct sdhci_msm_offset *msm_offset = msm_host->offset; @@ -1351,14 +1426,35 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) /* Handle BUS ON/OFF*/ if (irq_status & CORE_PWRCTL_BUS_ON) { - pwr_state = REQ_BUS_ON; - io_level = REQ_IO_HIGH; - irq_ack |= CORE_PWRCTL_BUS_SUCCESS; + ret = sdhci_msm_set_vmmc(msm_host, mmc, 1); + if (!ret) + ret = sdhci_msm_set_vqmmc(msm_host, mmc, 1); + + if (!ret) { + pwr_state = REQ_BUS_ON; + io_level = REQ_IO_HIGH; + irq_ack |= CORE_PWRCTL_BUS_SUCCESS; + } else { + pr_err("%s: BUS_ON req failed(%d). irq_status: 0x%08x\n", + mmc_hostname(mmc), ret, irq_status); + irq_ack |= CORE_PWRCTL_BUS_FAIL; + sdhci_msm_set_vmmc(msm_host, mmc, 0); + } } if (irq_status & CORE_PWRCTL_BUS_OFF) { - pwr_state = REQ_BUS_OFF; - io_level = REQ_IO_LOW; - irq_ack |= CORE_PWRCTL_BUS_SUCCESS; + ret = sdhci_msm_set_vmmc(msm_host, mmc, 0); + if (!ret) + ret = sdhci_msm_set_vqmmc(msm_host, mmc, 0); + + if (!ret) { + pwr_state = REQ_BUS_OFF; + io_level = REQ_IO_LOW; + irq_ack |= CORE_PWRCTL_BUS_SUCCESS; + } else { + pr_err("%s: BUS_ON req failed(%d). irq_status: 0x%08x\n", + mmc_hostname(mmc), ret, irq_status); + irq_ack |= CORE_PWRCTL_BUS_FAIL; + } } /* Handle IO LOW/HIGH */ if (irq_status & CORE_PWRCTL_IO_LOW) { @@ -1370,6 +1466,15 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) irq_ack |= CORE_PWRCTL_IO_SUCCESS; } + if (io_level && !IS_ERR(mmc->supply.vqmmc) && !pwr_state) { + ret = mmc_regulator_set_vqmmc(mmc, &mmc->ios); + if (ret) + pr_err("%s: IO_level setting failed(%d). signal_voltage: %d, vdd: %d irq_status: 0x%08x\n", + mmc_hostname(mmc), ret, + mmc->ios.signal_voltage, mmc->ios.vdd, + irq_status); + } + /* * The driver has to acknowledge the interrupt, switch voltages and * report back if it succeded or not to this register. The voltage @@ -1605,6 +1710,91 @@ static void sdhci_msm_set_regulator_caps(struct sdhci_msm_host *msm_host) pr_debug("%s: supported caps: 0x%08x\n", mmc_hostname(mmc), caps); } +static int sdhci_msm_register_vreg(struct sdhci_msm_host *msm_host) +{ + int ret = 0; + + ret = mmc_regulator_get_supply(msm_host->mmc); + if (ret) + return ret; + if (device_property_read_u32_array(&msm_host->pdev->dev, + "qcom,vmmc-current-level-microamp", + msm_host->vmmc_level, 2) >= 0) + msm_host->vmmc_load = true; + if (device_property_read_u32_array(&msm_host->pdev->dev, + "qcom,vqmmc-current-level-microamp", + msm_host->vqmmc_level, 2) >= 0) + msm_host->vqmmc_load = true; + + sdhci_msm_set_regulator_caps(msm_host); + + return 0; + +} + +static int sdhci_msm_start_signal_voltage_switch(struct mmc_host *mmc, + struct mmc_ios *ios) +{ + struct sdhci_host *host = mmc_priv(mmc); + u16 ctrl; + + /* + * Signal Voltage Switching is only applicable for Host Controllers + * v3.00 and above. + */ + if (host->version < SDHCI_SPEC_300) + return 0; + + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + + switch (ios->signal_voltage) { + case MMC_SIGNAL_VOLTAGE_330: + if (!(host->flags & SDHCI_SIGNALING_330)) + return -EINVAL; + /* Set 1.8V Signal Enable in the Host Control2 register to 0 */ + ctrl &= ~SDHCI_CTRL_VDD_180; + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); + + /* 3.3V regulator output should be stable within 5 ms */ + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + if (!(ctrl & SDHCI_CTRL_VDD_180)) + return 0; + + pr_warn("%s: 3.3V regulator output did not became stable\n", + mmc_hostname(mmc)); + + return -EAGAIN; + case MMC_SIGNAL_VOLTAGE_180: + if (!(host->flags & SDHCI_SIGNALING_180)) + return -EINVAL; + + /* + * Enable 1.8V Signal Enable in the Host Control2 + * register + */ + ctrl |= SDHCI_CTRL_VDD_180; + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); + + /* 1.8V regulator output should be stable within 5 ms */ + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + if (ctrl & SDHCI_CTRL_VDD_180) + return 0; + + pr_warn("%s: 1.8V regulator output did not became stable\n", + mmc_hostname(mmc)); + + return -EAGAIN; + case MMC_SIGNAL_VOLTAGE_120: + if (!(host->flags & SDHCI_SIGNALING_120)) + return -EINVAL; + return 0; + default: + /* No signal voltage switch required */ + return 0; + } + +} + static const struct sdhci_msm_variant_ops mci_var_ops = { .msm_readl_relaxed = sdhci_msm_mci_variant_readl_relaxed, .msm_writel_relaxed = sdhci_msm_mci_variant_writel_relaxed, @@ -1644,6 +1834,7 @@ static void sdhci_msm_set_regulator_caps(struct sdhci_msm_host *msm_host) .set_uhs_signaling = sdhci_msm_set_uhs_signaling, .write_w = sdhci_msm_writew, .write_b = sdhci_msm_writeb, + .set_power = sdhci_set_power_noreg, }; static const struct sdhci_pltfm_data sdhci_msm_pdata = { @@ -1818,6 +2009,10 @@ static int sdhci_msm_probe(struct platform_device *pdev) msm_offset->core_vendor_spec_capabilities0); } + ret = sdhci_msm_register_vreg(msm_host); + if (ret) + goto clk_disable; + /* * Power on reset state may trigger power irq if previous status of * PWRCTL was either BUS_ON or IO_HIGH_V. So before enabling pwr irq @@ -1862,11 +2057,12 @@ static int sdhci_msm_probe(struct platform_device *pdev) MSM_MMC_AUTOSUSPEND_DELAY_MS); pm_runtime_use_autosuspend(&pdev->dev); + host->mmc_host_ops.start_signal_voltage_switch = + sdhci_msm_start_signal_voltage_switch; host->mmc_host_ops.execute_tuning = sdhci_msm_execute_tuning; ret = sdhci_add_host(host); if (ret) goto pm_runtime_disable; - sdhci_msm_set_regulator_caps(msm_host); pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_put_autosuspend(&pdev->dev);