From patchwork Thu Mar 21 17:17:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evan Green X-Patchwork-Id: 10864131 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 D40CF1515 for ; Thu, 21 Mar 2019 17:19:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF50B2A3F0 for ; Thu, 21 Mar 2019 17:19:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A3B6F2A3F1; Thu, 21 Mar 2019 17:19:02 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 37FB12A3F3 for ; Thu, 21 Mar 2019 17:19:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728753AbfCURST (ORCPT ); Thu, 21 Mar 2019 13:18:19 -0400 Received: from mail-pg1-f195.google.com ([209.85.215.195]:37737 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728749AbfCURSS (ORCPT ); Thu, 21 Mar 2019 13:18:18 -0400 Received: by mail-pg1-f195.google.com with SMTP id q206so4644695pgq.4 for ; Thu, 21 Mar 2019 10:18:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5VTcVo1Chs4XGa35tec1xGg2FL/05IcVUKqdSKt+U9Q=; b=Kr1Bi0ytzlIExrHApFqy1i2jPUQf5/OokIJmBfy88t6HmBn28AzgN6842rJUZ2wmQx LCQ0JbLwZpGjnZIYqJaa2e5V2i/f+jtne9UBW62i8YsOzXXWUy91ZxTlU4Em4XNQ2krG Z3n2muBhDqKmlKuIu8zh5BF2z13WJk+9N3Zek= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5VTcVo1Chs4XGa35tec1xGg2FL/05IcVUKqdSKt+U9Q=; b=tMHNrl5g49JGfD7BdOYi1UjgO67E4fplFEOAVnqZ3o8WNkr3Gk9nnFBh/Djis2i9xY 8ucipnJV+HThkkpx/KJy8EoMQ/F2+cxuT2NRH2hcKSYj6wBNCBowp+ZjLzlSPJM8Lquv 5bGGYk6AN7t4Lz3lKdueN7ea4qgxBfMl6XFmf0nzXXoQzDWNEds7aGBXpAUsgP697tRP cNo6P8vuJJT131gUs0PdkIoFvhizrGC+ae9zN2AQcgV0SurRXfe/NV0c1R2yWvF+EQ+g CSnGjolhkypVoVZfCMHW9jZ823fzWyqC1jL16nVJH6mgMAO5hSZfqElLoX37JQmLBK0r 1Bgg== X-Gm-Message-State: APjAAAVAnMFsGyCsXwdmjkRE1sCi/edo/uW2IOeRPqqa7IC4QbzyEaBA f4tSQ9k+cIlfKbzPeE9sQlJufw== X-Google-Smtp-Source: APXvYqwVkUQOfEPbsJoytpmNSpCN+m2u6x55lnqBlfVlHlhBkUsE+bGCQubPjDMcBfyYPanRj2vq8A== X-Received: by 2002:a62:a219:: with SMTP id m25mr4396024pff.197.1553188697650; Thu, 21 Mar 2019 10:18:17 -0700 (PDT) Received: from evgreen2.mtv.corp.google.com ([2620:15c:202:201:ffda:7716:9afc:1301]) by smtp.gmail.com with ESMTPSA id z6sm20953866pgo.31.2019.03.21.10.18.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Mar 2019 10:18:17 -0700 (PDT) From: Evan Green To: Kishon Vijay Abraham I Cc: Stephen Boyd , Marc Gonzalez , Can Guo , Vivek Gautam , Douglas Anderson , Asutosh Das , Evan Green , Rob Herring , devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Andy Gross , David Brown , Mark Rutland , Rob Herring Subject: [PATCH v5 2/8] dt-bindings: phy-qcom-qmp: Add UFS PHY reset Date: Thu, 21 Mar 2019 10:17:54 -0700 Message-Id: <20190321171800.104681-3-evgreen@chromium.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321171800.104681-1-evgreen@chromium.org> References: <20190321171800.104681-1-evgreen@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a required reset to the SDM845 UFS phy to express the PHY reset bit inside the UFS controller register space. Before this change, this reset was not expressed in the DT, and the driver utilized two different callbacks (phy_init and phy_poweron) to implement a two-phase initialization procedure that involved deasserting this reset between init and poweron. This abused the two callbacks and diluted their purpose. That scheme does not work as regulators cannot be turned off in phy_poweroff because they were turned on in init, rather than poweron. The net result is that regulators are left on in suspend that shouldn't be. This new scheme gives the UFS reset to the PHY, so that it can fully initialize itself in a single callback. We can then turn regulators on during poweron and off during poweroff. Signed-off-by: Evan Green Reviewed-by: Rob Herring Reviewed-by: Stephen Boyd --- Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt index 5d181fc3cc18..4a78ba8b85bc 100644 --- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt +++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt @@ -59,7 +59,8 @@ Required properties: one for each entry in reset-names. - reset-names: "phy" for reset of phy block, "common" for phy common block reset, - "cfg" for phy's ahb cfg block reset. + "cfg" for phy's ahb cfg block reset, + "ufsphy" for the PHY reset in the UFS controller. For "qcom,ipq8074-qmp-pcie-phy" must contain: "phy", "common". @@ -74,7 +75,8 @@ Required properties: "phy", "common". For "qcom,sdm845-qmp-usb3-uni-phy" must contain: "phy", "common". - For "qcom,sdm845-qmp-ufs-phy": no resets are listed. + For "qcom,sdm845-qmp-ufs-phy": must contain: + "ufsphy". - vdda-phy-supply: Phandle to a regulator supply to PHY core block. - vdda-pll-supply: Phandle to 1.8V regulator supply to PHY refclk pll block. From patchwork Thu Mar 21 17:17:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evan Green X-Patchwork-Id: 10864115 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 72001139A for ; Thu, 21 Mar 2019 17:18:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4C83C2A064 for ; Thu, 21 Mar 2019 17:18:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 405EC2A3EF; Thu, 21 Mar 2019 17:18:27 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 E081B2A3F0 for ; Thu, 21 Mar 2019 17:18:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728784AbfCURSY (ORCPT ); Thu, 21 Mar 2019 13:18:24 -0400 Received: from mail-pg1-f195.google.com ([209.85.215.195]:45560 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728777AbfCURSY (ORCPT ); Thu, 21 Mar 2019 13:18:24 -0400 Received: by mail-pg1-f195.google.com with SMTP id y3so4623049pgk.12 for ; Thu, 21 Mar 2019 10:18:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QhKCahgOarX4GDkR5QSVNqxMg4FAl0Xz9vcCv1+uBfE=; b=e7HGjSOLBUK8HUyErB1b0bO5zYYUaeBbO6f6RAOjLah7VvhMjDfLmiHyJ4QfbOd7RU medBnmXeDSOrpZNrgKVJkkGxav6VT+XuCvW4nz/LviRw5PfyuceirS3rVOysvlSKWwnS bSQF+KDLNcTkPovjGxVCBDUBtrGEk0qAjhvVo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QhKCahgOarX4GDkR5QSVNqxMg4FAl0Xz9vcCv1+uBfE=; b=DAiUoOYYqkm6jXdsUU9A4MW4jqwh7FRNjXu3UlCw1HGBQnpVrILIZmnsCOgS6fo+GZ 3jbCXevqiDcOEsFWWdrIBtRNN09fFIgNtJNaxji2taovSaZv5jYzc4BRaSwklZEjZtqS Iy28yp0uAKwkeVN2481HhNsKjmM+0Wbhs1slv7uezr8MApE53zRyfPBVoNWE/AC0Lsvt ssn5FNoYiVVblvFBZJnIIoe3Ah/+TMuEjOu52qtuCgS2JcFNtVfnNYoiJlQ26XgaTWIU 5X7oQaIfxilDcHOsNXW2kjqtC5I+VY3MeSl9fcDI2dI30edl6dpZpJIFGuN9aRNad346 XyVQ== X-Gm-Message-State: APjAAAXILI0hjHdOXvgKAmyAZWQFIT86sqHdlgEcruUMr3tALKPkBNsM QXyAXjC10yqIslkYT3WBuphqpg== X-Google-Smtp-Source: APXvYqxX0VrbWoT5JwygmTltad4nA6wGJ5vIDvwYoQBgStrNGIstUPO/lhz1A6BPQ3KO3mtfJ+yb5g== X-Received: by 2002:a17:902:bb94:: with SMTP id m20mr4674500pls.255.1553188702128; Thu, 21 Mar 2019 10:18:22 -0700 (PDT) Received: from evgreen2.mtv.corp.google.com ([2620:15c:202:201:ffda:7716:9afc:1301]) by smtp.gmail.com with ESMTPSA id z6sm20953866pgo.31.2019.03.21.10.18.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Mar 2019 10:18:21 -0700 (PDT) From: Evan Green To: Kishon Vijay Abraham I Cc: Stephen Boyd , Marc Gonzalez , Can Guo , Vivek Gautam , Douglas Anderson , Asutosh Das , Evan Green , devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Andy Gross , Rob Herring , David Brown , Mark Rutland Subject: [PATCH v5 4/8] arm64: dts: sdm845: Add UFS PHY reset Date: Thu, 21 Mar 2019 10:17:56 -0700 Message-Id: <20190321171800.104681-5-evgreen@chromium.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321171800.104681-1-evgreen@chromium.org> References: <20190321171800.104681-1-evgreen@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Wire up the reset controller in the Qcom UFS controller for the PHY. This will be used to toggle PHY reset during initialization of the PHY. Signed-off-by: Evan Green Reviewed-by: Stephen Boyd --- Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None arch/arm64/boot/dts/qcom/sdm845.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index 5308f1671824..66c77146585b 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -1033,6 +1033,7 @@ phy-names = "ufsphy"; lanes-per-direction = <2>; power-domains = <&gcc UFS_PHY_GDSC>; + #reset-cells = <1>; iommus = <&apps_smmu 0x100 0xf>; @@ -1078,6 +1079,8 @@ clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>, <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; + resets = <&ufs_mem_hc 0>; + reset-names = "ufsphy"; status = "disabled"; ufs_mem_phy_lanes: lanes@1d87400 { From patchwork Thu Mar 21 17:17:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evan Green X-Patchwork-Id: 10864129 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 2B2E21515 for ; Thu, 21 Mar 2019 17:18:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 06E0029E65 for ; Thu, 21 Mar 2019 17:18:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EF8332A085; Thu, 21 Mar 2019 17:18:52 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 A133029E65 for ; Thu, 21 Mar 2019 17:18:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728776AbfCURS0 (ORCPT ); Thu, 21 Mar 2019 13:18:26 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:43305 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728783AbfCURSZ (ORCPT ); Thu, 21 Mar 2019 13:18:25 -0400 Received: by mail-pg1-f194.google.com with SMTP id l11so4618430pgq.10 for ; Thu, 21 Mar 2019 10:18:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cDhjjnKzvciBPxRXKZr8yRdui7H/ilutHNcJeHVcKgI=; b=fIHNMaC8pGvkwOaoBEGA2ai2qQa3B9rXlzrmbPcvcpiuyiJjYWjemS5GcbLDv4kIqX UC7ufYVo9qSSo1rESa7Gg3z2tUnDljs56HM5euZnZlig49IY7IOvK73Vuc5ogRqXjcz7 rdAELindMhvI4k1AgS1DWppXriQeoMX8oAPNQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cDhjjnKzvciBPxRXKZr8yRdui7H/ilutHNcJeHVcKgI=; b=U3CP+gZnYP0PTMgSWP4wIZqqhLvz/1h406xbWYcxp07836sw5WRLTNsTHSmRLNYCcT vxVWur1KTZwjHOA9td7lAU3F4bf926RyVb6J5njwkU9WL8cI7trrGXzM3u4kYunrJy4d tnVsDtQXufearQ0iLcw8KfIUtp+7TUG+adY88nNTeL9SjmL9n5xiP65wJFf8Xt+Pcoq3 XGE0XrcqJWlhIICahbSoMVdSzLk9pCrkgqjKY/gfPGJI+kJHnFJzd0x7vdl6MgOuXt0W aVKoxWxcTuRnUQ4j37PruBQofeN48fss1L01rO4GGnufW02AXNzsOdORumznW6gnatC+ IBsg== X-Gm-Message-State: APjAAAUmLMO4FUkFSGn0cdRoafOddcaHJEEn79gnoUke6ke2+LoZr51G g+fcT3/5Nww8tNHcp6yw7G1y2g== X-Google-Smtp-Source: APXvYqwxhb6mZUoUO6R5/Lgjj1/wAv5hsGMB9kb1bL6lyz6TPrbafGmDcA0Sv9EbmeykDlW7rzfRpw== X-Received: by 2002:a17:902:2a89:: with SMTP id j9mr4540987plb.272.1553188704349; Thu, 21 Mar 2019 10:18:24 -0700 (PDT) Received: from evgreen2.mtv.corp.google.com ([2620:15c:202:201:ffda:7716:9afc:1301]) by smtp.gmail.com with ESMTPSA id z6sm20953866pgo.31.2019.03.21.10.18.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Mar 2019 10:18:23 -0700 (PDT) From: Evan Green To: Kishon Vijay Abraham I Cc: Stephen Boyd , Marc Gonzalez , Can Guo , Vivek Gautam , Douglas Anderson , Asutosh Das , Evan Green , devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Andy Gross , Rob Herring , David Brown , Mark Rutland Subject: [PATCH v5 5/8] arm64: dts: msm8996: Add UFS PHY reset controller Date: Thu, 21 Mar 2019 10:17:57 -0700 Message-Id: <20190321171800.104681-6-evgreen@chromium.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321171800.104681-1-evgreen@chromium.org> References: <20190321171800.104681-1-evgreen@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add the reset controller for the UFS controller, and wire it up so that the UFS PHY can initialize itself without relying on implicit sequencing between the two drivers. Signed-off-by: Evan Green Reviewed-by: Stephen Boyd --- Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None arch/arm64/boot/dts/qcom/msm8996.dtsi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index c761269caf80..5683b727283e 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -697,10 +697,11 @@ clock-names = "ref_clk_src", "ref_clk"; clocks = <&rpmcc RPM_SMD_LN_BB_CLK>, <&gcc GCC_UFS_CLKREF_CLK>; + resets = <&ufshc 0>; status = "disabled"; }; - ufshc@624000 { + ufshc: ufshc@624000 { compatible = "qcom,ufshc"; reg = <0x624000 0x2500>; interrupts = ; @@ -756,6 +757,7 @@ <0 0>; lanes-per-direction = <1>; + #reset-cells = <1>; status = "disabled"; ufs_variant { From patchwork Thu Mar 21 17:17:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evan Green X-Patchwork-Id: 10864127 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 42C431823 for ; Thu, 21 Mar 2019 17:18:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 23A502A3F1 for ; Thu, 21 Mar 2019 17:18:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1708C2A3F2; Thu, 21 Mar 2019 17:18:49 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 902632A3F4 for ; Thu, 21 Mar 2019 17:18:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728804AbfCURS2 (ORCPT ); Thu, 21 Mar 2019 13:18:28 -0400 Received: from mail-pg1-f196.google.com ([209.85.215.196]:37756 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728795AbfCURS2 (ORCPT ); Thu, 21 Mar 2019 13:18:28 -0400 Received: by mail-pg1-f196.google.com with SMTP id q206so4644980pgq.4 for ; Thu, 21 Mar 2019 10:18:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Gkb3tnV0qMd4Ne3aoYOTyvlq73DUH0GrlinS6O1XmHA=; b=DCIks/jiQzgwPAS3ruS2/RQPV3klMjdYu2l5PUxfG1xHKlAtBx2AQIqdhO4kGJvuYF n0uwo3AYPsyLlGNIbODXTLxOWlYH6xiiqGP7p9f0w1gwgF9EoXKgS+aS/z0/lPBSA65/ 078pd5zhJZ01JuvKjZ4+MVAGFkeq9admQQQI8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Gkb3tnV0qMd4Ne3aoYOTyvlq73DUH0GrlinS6O1XmHA=; b=s44Vm/fQvz5v6EZScJYw/UbsP4Ffn85iRL6bfwuSFrHtzBlQ32xGXpjZsXeAodBnoT B1LAU/yDkIJ1ChY5tWZ/EWT2L7hcT/zxcd5KrqF5KalQ8I7moRM7v6E78qppWP8kH18L cWkkpzW+ajBTIo0Go3gYISQKZVM6c+wc7w+A7kCCYmUBL2rGITkYYq5I3CPCm2xgnYOf EkWXVQbZGVqGjwF3Dp4lbyCApbmx6hlWGTSGIP/ySu28eL2yg/zYl49zSQSKUBwpc/o9 zNwkKf/eTwP+RAFJ/yyE5jf+TQKNOhjFx5Xh/Rw++Jyu6zBwImYx7MO3PHNQNkMwvRIg 8yjw== X-Gm-Message-State: APjAAAUOWeHtN0EspWq/tkVYjukXiTrvyDmjYJtUBmGyK0bBoezT91iG Cvm27k+C0waG7Gz23URY09AOyQ== X-Google-Smtp-Source: APXvYqx0CPbbpeDEKiTX4wK/9rPR7Tbg07mjUpBF1iJdY7rlzdjGLxviaMv5zAg8ZWI6MlrTXBE2AQ== X-Received: by 2002:aa7:8818:: with SMTP id c24mr4366387pfo.129.1553188707059; Thu, 21 Mar 2019 10:18:27 -0700 (PDT) Received: from evgreen2.mtv.corp.google.com ([2620:15c:202:201:ffda:7716:9afc:1301]) by smtp.gmail.com with ESMTPSA id z6sm20953866pgo.31.2019.03.21.10.18.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Mar 2019 10:18:26 -0700 (PDT) From: Evan Green To: Kishon Vijay Abraham I Cc: Stephen Boyd , Marc Gonzalez , Can Guo , Vivek Gautam , Douglas Anderson , Asutosh Das , Evan Green , Pedro Sousa , liwei , linux-scsi@vger.kernel.org, linux-arm-msm@vger.kernel.org, Bart Van Assche , linux-kernel@vger.kernel.org, Alim Akhtar , Andy Gross , "Martin K. Petersen" , Avri Altman , "James E.J. Bottomley" , Janek Kotas , David Brown Subject: [PATCH v5 6/8] scsi: ufs: qcom: Expose the reset controller for PHY Date: Thu, 21 Mar 2019 10:17:58 -0700 Message-Id: <20190321171800.104681-7-evgreen@chromium.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321171800.104681-1-evgreen@chromium.org> References: <20190321171800.104681-1-evgreen@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Expose a reset controller that the phy will later use to control its own PHY reset in the UFS controller. This will enable the combining of PHY init functionality into a single function. Signed-off-by: Evan Green Reviewed-by: Stephen Boyd --- Note: The remaining changes in this series need this change, since the PHYs now depend on getting the reset controller. Changes in v5: None Changes in v4: None Changes in v3: - Refactor to only expose the reset controller in one change (Stephen). - Add period to comment (Stephen). - Reset err to 0 in ignored error case (Stephen). - Add include of reset-controller.h (Stephen) Changes in v2: - Remove include of reset.h (Stephen) - Fix error print of phy_power_on (Stephen) - Comment for reset controller warnings on id != 0 (Stephen) - Add static to ufs_qcom_reset_ops (Stephen). drivers/scsi/ufs/Kconfig | 1 + drivers/scsi/ufs/ufs-qcom.c | 52 +++++++++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs-qcom.h | 4 +++ 3 files changed, 57 insertions(+) diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index 6db37cf306b0..179bda374544 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -99,6 +99,7 @@ config SCSI_UFS_DWC_TC_PLATFORM config SCSI_UFS_QCOM tristate "QCOM specific hooks to UFS controller platform driver" depends on SCSI_UFSHCD_PLATFORM && ARCH_QCOM + select RESET_CONTROLLER help This selects the QCOM specific additions to UFSHCD platform driver. UFS host on QCOM needs some vendor specific configuration before diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 3aeadb14aae1..ab05ef5cfdcd 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "ufshcd.h" #include "ufshcd-pltfrm.h" @@ -49,6 +50,11 @@ static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host); static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba, u32 clk_cycles); +static struct ufs_qcom_host *rcdev_to_ufs_host(struct reset_controller_dev *rcd) +{ + return container_of(rcd, struct ufs_qcom_host, rcdev); +} + static void ufs_qcom_dump_regs_wrapper(struct ufs_hba *hba, int offset, int len, const char *prefix, void *priv) { @@ -1147,6 +1153,41 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on, return err; } +static int +ufs_qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) +{ + struct ufs_qcom_host *host = rcdev_to_ufs_host(rcdev); + + /* Currently this code only knows about a single reset. */ + WARN_ON(id); + ufs_qcom_assert_reset(host->hba); + /* provide 1ms delay to let the reset pulse propagate. */ + usleep_range(1000, 1100); + return 0; +} + +static int +ufs_qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) +{ + struct ufs_qcom_host *host = rcdev_to_ufs_host(rcdev); + + /* Currently this code only knows about a single reset. */ + WARN_ON(id); + ufs_qcom_deassert_reset(host->hba); + + /* + * after reset deassertion, phy will need all ref clocks, + * voltage, current to settle down before starting serdes. + */ + usleep_range(1000, 1100); + return 0; +} + +static const struct reset_control_ops ufs_qcom_reset_ops = { + .assert = ufs_qcom_reset_assert, + .deassert = ufs_qcom_reset_deassert, +}; + #define ANDROID_BOOT_DEV_MAX 30 static char android_boot_dev[ANDROID_BOOT_DEV_MAX]; @@ -1191,6 +1232,17 @@ static int ufs_qcom_init(struct ufs_hba *hba) host->hba = hba; ufshcd_set_variant(hba, host); + /* Fire up the reset controller. Failure here is non-fatal. */ + host->rcdev.of_node = dev->of_node; + host->rcdev.ops = &ufs_qcom_reset_ops; + host->rcdev.owner = dev->driver->owner; + host->rcdev.nr_resets = 1; + err = devm_reset_controller_register(dev, &host->rcdev); + if (err) { + dev_warn(dev, "Failed to register reset controller\n"); + err = 0; + } + /* * voting/devoting device ref_clk source is time consuming hence * skip devoting it during aggressive clock gating. This clock diff --git a/drivers/scsi/ufs/ufs-qcom.h b/drivers/scsi/ufs/ufs-qcom.h index c114826316eb..68a880185752 100644 --- a/drivers/scsi/ufs/ufs-qcom.h +++ b/drivers/scsi/ufs/ufs-qcom.h @@ -14,6 +14,8 @@ #ifndef UFS_QCOM_H_ #define UFS_QCOM_H_ +#include + #define MAX_UFS_QCOM_HOSTS 1 #define MAX_U32 (~(u32)0) #define MPHY_TX_FSM_STATE 0x41 @@ -237,6 +239,8 @@ struct ufs_qcom_host { /* Bitmask for enabling debug prints */ u32 dbg_print_en; struct ufs_qcom_testbus testbus; + + struct reset_controller_dev rcdev; }; static inline u32 From patchwork Thu Mar 21 17:17:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evan Green X-Patchwork-Id: 10864119 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 CD601139A for ; Thu, 21 Mar 2019 17:18:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A2F752A06A for ; Thu, 21 Mar 2019 17:18:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 970522A307; Thu, 21 Mar 2019 17:18:35 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 CF7E32A2FF for ; Thu, 21 Mar 2019 17:18:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728823AbfCURSd (ORCPT ); Thu, 21 Mar 2019 13:18:33 -0400 Received: from mail-pg1-f195.google.com ([209.85.215.195]:45574 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728797AbfCURSb (ORCPT ); Thu, 21 Mar 2019 13:18:31 -0400 Received: by mail-pg1-f195.google.com with SMTP id y3so4623270pgk.12 for ; Thu, 21 Mar 2019 10:18:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7H3DpHBIxx7V0A+4gso0aej7NFfv4olWpq7ScgM4iMI=; b=X665VWjC3F1uzdLlRDlHJBof73/t6gc91gV4kSKXIjVnP9Kb2EtH9CPBDUqaTiRLJp DREzWyJeLJKLODkFpxuGCgvC/a3C30htHhyOHQGs1skrhomViZMqIpwdlKYNvkVAjodf mJ8WcX8gBoC3RYMdfXY+QN57FV6GbR8D7zng4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7H3DpHBIxx7V0A+4gso0aej7NFfv4olWpq7ScgM4iMI=; b=bcSyJ4llPgI9PSIvnuPPJo8hZI9VosigfQor050JT6aru3f36UyBQlp4L2yvyfKLC2 tT3kdxvpf1VI+LMaYJjCHRHmk3O/X/QIgcJmkuBIKAUTRDc16j0kBmdMpvUUnExBCDuc TGJXUsaZoPSnoBAIB675yT7nXlzkKqMYryx8nT2o4JyDX/cxluEeIZl85nXTHipPUors /kkhl5E5nJunCjQjySfED8FJF3qQHli4gjrreOD6fS/cdzgL2SETAiQ4iQBqzr8WcMTD PJ1TOAA/+kmH6yYpyY9apEC208x9zNQWalMqZN7J8cGOqnTCUczOeNfyErsk4REKWmap kDoQ== X-Gm-Message-State: APjAAAVndF3urshCJnIfygKML1d/A4oDMvmMNhqqNlYWz/dtUADwXRIg 9I7f9o/eBLTarpTdVVYnXxrTRw== X-Google-Smtp-Source: APXvYqwuQNNctOS7CTOVec/RALvv4mC3Ndrh5epqNf2TW0gEH3/P174e2kp8sGL4m8bA/XL4v/0wdg== X-Received: by 2002:aa7:8299:: with SMTP id s25mr4447337pfm.56.1553188709895; Thu, 21 Mar 2019 10:18:29 -0700 (PDT) Received: from evgreen2.mtv.corp.google.com ([2620:15c:202:201:ffda:7716:9afc:1301]) by smtp.gmail.com with ESMTPSA id z6sm20953866pgo.31.2019.03.21.10.18.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Mar 2019 10:18:29 -0700 (PDT) From: Evan Green To: Kishon Vijay Abraham I Cc: Stephen Boyd , Marc Gonzalez , Can Guo , Vivek Gautam , Douglas Anderson , Asutosh Das , Evan Green , "James E.J. Bottomley" , linux-scsi@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Alim Akhtar , Avri Altman , Andy Gross , David Brown , Pedro Sousa , "Martin K. Petersen" Subject: [PATCH v5 7/8] phy: qcom: Utilize UFS reset controller Date: Thu, 21 Mar 2019 10:17:59 -0700 Message-Id: <20190321171800.104681-8-evgreen@chromium.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321171800.104681-1-evgreen@chromium.org> References: <20190321171800.104681-1-evgreen@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Move the PHY reset from ufs-qcom into the respective PHYs. This will allow us to merge the two phases of UFS PHY initialization. Signed-off-by: Evan Green Reviewed-by: Stephen Boyd --- Changes in v5: None Changes in v4: - Do reset_control_* unconditionally since null is handled (Stephen). Changes in v3: - Refactored to move reset control in a single commit (Stephen) - Use no_pcs_sw_reset as an indicator of UFS reset in qmp-phy (Stephen). - Assign ret = PTR_ERR() earlier, for better reuse (Stephen). Changes in v2: - Use devm_* to get the reset (Stephen) - Clear ufs_reset on error getting it - Remove needless error print (Stephen) drivers/phy/qualcomm/phy-qcom-qmp.c | 34 ++++++++++++++++++++ drivers/phy/qualcomm/phy-qcom-ufs-i.h | 3 ++ drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c | 8 +++++ drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c | 8 +++++ drivers/phy/qualcomm/phy-qcom-ufs.c | 23 +++++++++++++ drivers/scsi/ufs/ufs-qcom.c | 18 ----------- 6 files changed, 76 insertions(+), 18 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c index 08d6f6f7f039..a808887ab4e2 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -897,6 +897,7 @@ struct qmp_phy { * @init_count: phy common block initialization count * @phy_initialized: indicate if PHY has been initialized * @mode: current PHY mode + * @ufs_reset: optional UFS PHY reset handle */ struct qcom_qmp { struct device *dev; @@ -914,6 +915,8 @@ struct qcom_qmp { int init_count; bool phy_initialized; enum phy_mode mode; + + struct reset_control *ufs_reset; }; static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val) @@ -1314,6 +1317,7 @@ static int qcom_qmp_phy_com_exit(struct qcom_qmp *qmp) return 0; } + reset_control_assert(qmp->ufs_reset); if (cfg->has_phy_com_ctrl) { qphy_setbits(serdes, cfg->regs[QPHY_COM_START_CONTROL], SERDES_START | PCS_START); @@ -1351,6 +1355,33 @@ static int qcom_qmp_phy_init(struct phy *phy) dev_vdbg(qmp->dev, "Initializing QMP phy\n"); + if (cfg->no_pcs_sw_reset) { + /* + * Get UFS reset, which is delayed until now to avoid a + * circular dependency where UFS needs its PHY, but the PHY + * needs this UFS reset. + */ + if (!qmp->ufs_reset) { + qmp->ufs_reset = + devm_reset_control_get_exclusive(qmp->dev, + "ufsphy"); + + if (IS_ERR(qmp->ufs_reset)) { + ret = PTR_ERR(qmp->ufs_reset); + dev_err(qmp->dev, + "failed to get UFS reset: %d\n", + ret); + + qmp->ufs_reset = NULL; + return ret; + } + } + + ret = reset_control_assert(qmp->ufs_reset); + if (ret) + goto err_lane_rst; + } + ret = qcom_qmp_phy_com_init(qphy); if (ret) return ret; @@ -1383,6 +1414,9 @@ static int qcom_qmp_phy_init(struct phy *phy) cfg->rx_tbl, cfg->rx_tbl_num); qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num); + ret = reset_control_deassert(qmp->ufs_reset); + if (ret) + goto err_lane_rst; /* * UFS PHY requires the deassert of software reset before serdes start. diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-i.h b/drivers/phy/qualcomm/phy-qcom-ufs-i.h index f798fb64de94..ba77348d807c 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-i.h +++ b/drivers/phy/qualcomm/phy-qcom-ufs-i.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -101,6 +102,7 @@ struct ufs_qcom_phy { struct ufs_qcom_phy_specific_ops *phy_spec_ops; enum phy_mode mode; + struct reset_control *ufs_reset; }; /** @@ -132,6 +134,7 @@ struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev, struct ufs_qcom_phy *common_cfg, const struct phy_ops *ufs_qcom_phy_gen_ops, struct ufs_qcom_phy_specific_ops *phy_spec_ops); +int ufs_qcom_phy_get_reset(struct ufs_qcom_phy *phy_common); int ufs_qcom_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy, struct ufs_qcom_phy_calibration *tbl_A, int tbl_size_A, struct ufs_qcom_phy_calibration *tbl_B, int tbl_size_B, diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c index 1e0d4f2046a4..cc343517a2ca 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c @@ -48,6 +48,14 @@ static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy) bool is_rate_B = false; int ret; + ret = ufs_qcom_phy_get_reset(phy_common); + if (ret) + return ret; + + ret = reset_control_assert(phy_common->ufs_reset); + if (ret) + return ret; + if (phy_common->mode == PHY_MODE_UFS_HS_B) is_rate_B = true; diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c index aef40f7a41d4..54b2af9d8702 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c @@ -67,6 +67,14 @@ static int ufs_qcom_phy_qmp_20nm_init(struct phy *generic_phy) bool is_rate_B = false; int ret; + ret = ufs_qcom_phy_get_reset(phy_common); + if (ret) + return ret; + + ret = reset_control_assert(phy_common->ufs_reset); + if (ret) + return ret; + if (phy_common->mode == PHY_MODE_UFS_HS_B) is_rate_B = true; diff --git a/drivers/phy/qualcomm/phy-qcom-ufs.c b/drivers/phy/qualcomm/phy-qcom-ufs.c index f2979ccad00a..fe59785a55f2 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs.c @@ -147,6 +147,22 @@ struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev, } EXPORT_SYMBOL_GPL(ufs_qcom_phy_generic_probe); +int ufs_qcom_phy_get_reset(struct ufs_qcom_phy *phy_common) +{ + struct reset_control *reset; + + if (phy_common->ufs_reset) + return 0; + + reset = devm_reset_control_get_exclusive_by_index(phy_common->dev, 0); + if (IS_ERR(reset)) + return PTR_ERR(reset); + + phy_common->ufs_reset = reset; + return 0; +} +EXPORT_SYMBOL_GPL(ufs_qcom_phy_get_reset); + static int __ufs_qcom_phy_clk_get(struct device *dev, const char *name, struct clk **clk_out, bool err_print) { @@ -533,6 +549,12 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy) if (phy_common->is_powered_on) return 0; + err = reset_control_deassert(phy_common->ufs_reset); + if (err) { + dev_err(dev, "Failed to assert UFS PHY reset"); + return err; + } + if (!phy_common->is_started) { err = ufs_qcom_phy_start_serdes(phy_common); if (err) @@ -620,6 +642,7 @@ int ufs_qcom_phy_power_off(struct phy *generic_phy) ufs_qcom_phy_disable_vreg(phy_common->dev, &phy_common->vdda_pll); ufs_qcom_phy_disable_vreg(phy_common->dev, &phy_common->vdda_phy); + reset_control_assert(phy_common->ufs_reset); phy_common->is_powered_on = false; return 0; diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index ab05ef5cfdcd..1c25b1c82314 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -261,11 +261,6 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba) if (is_rate_B) phy_set_mode(phy, PHY_MODE_UFS_HS_B); - /* Assert PHY reset and apply PHY calibration values */ - ufs_qcom_assert_reset(hba); - /* provide 1ms delay to let the reset pulse propagate */ - usleep_range(1000, 1100); - /* phy initialization - calibrate the phy */ ret = phy_init(phy); if (ret) { @@ -274,15 +269,6 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba) goto out; } - /* De-assert PHY reset and start serdes */ - ufs_qcom_deassert_reset(hba); - - /* - * after reset deassertion, phy will need all ref clocks, - * voltage, current to settle down before starting serdes. - */ - usleep_range(1000, 1100); - /* power on phy - start serdes and phy's power and clocks */ ret = phy_power_on(phy); if (ret) { @@ -296,7 +282,6 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba) return 0; out_disable_phy: - ufs_qcom_assert_reset(hba); phy_exit(phy); out: return ret; @@ -559,9 +544,6 @@ static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) */ ufs_qcom_disable_lane_clks(host); phy_power_off(phy); - - /* Assert PHY soft reset */ - ufs_qcom_assert_reset(hba); goto out; } From patchwork Thu Mar 21 17:18:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evan Green X-Patchwork-Id: 10864123 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 D44DB1515 for ; Thu, 21 Mar 2019 17:18:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B61C62A3F0 for ; Thu, 21 Mar 2019 17:18:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A981E2A3F2; Thu, 21 Mar 2019 17:18: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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,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 A1FCE2A3F1 for ; Thu, 21 Mar 2019 17:18:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728818AbfCURSe (ORCPT ); Thu, 21 Mar 2019 13:18:34 -0400 Received: from mail-pg1-f196.google.com ([209.85.215.196]:33466 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728819AbfCURSd (ORCPT ); Thu, 21 Mar 2019 13:18:33 -0400 Received: by mail-pg1-f196.google.com with SMTP id b12so4667349pgk.0 for ; Thu, 21 Mar 2019 10:18:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=EvJ7ZMS7OMnoMzO16VCde6puE4OhyhCqPphRNP4XmJs=; b=KS1gir9hq77S58Vy/G6riq2+RxBwLqYQ7DRWS+R4cXoGN6SVvaihg3p+QHtmJMa8JZ NZxnbf7rz3D8fQJSRwWTUZVcMjFzJEmR10x4paWNBY4sGFVPILIZdFfeBgPCUC+w+dmB CElSILRRTgRJ0z3KdvPmFpSSRZne1ItCBM+3c= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=EvJ7ZMS7OMnoMzO16VCde6puE4OhyhCqPphRNP4XmJs=; b=Ejbp8a0pPhBKu7CFixbGz4vHLDwc0341IO0hz8iF68Mj2/b67wYqSB6hlZNvef5iR1 W2Ml/r3c84yJjc2nlDXW/u55v/PUAlo2GSIOTEJPWMG80JoxZiiYARfzr00J167SOdzR gmw8q6jgy4QbFAn7IhJPAwSK0iyyrqPGyt+7cBw8jSsxFZBnGQwg1CJPnEsNR6pUtxxt DyLNnbvo0MzaLrzAxW/ZNwPBBEtleJn5mZBSOZP+hao0m+eUlsGeVq9YpxVdO+0hHQxb Qz58HRIQD39d/8o43xyvX7hBBQBkkqxjFzPaa/zyCQJTx+zvpfStqEP0Vbb/4KLhtLvQ FLmQ== X-Gm-Message-State: APjAAAXmVovY00YkXtjRrQOcEcTHXnGlcsvkxB2Vmgdhv5U86krOxVV1 AOHx4GmZvsrRlYGrR+l3r7fibA== X-Google-Smtp-Source: APXvYqyqOfYW/rkZ1JXgz9keD8beH/U9ZZXED7n1dx9Wc9dB32HSEHXlXadY8OelJpzbvmONy/Z4vA== X-Received: by 2002:a17:902:7896:: with SMTP id q22mr4791559pll.66.1553188712657; Thu, 21 Mar 2019 10:18:32 -0700 (PDT) Received: from evgreen2.mtv.corp.google.com ([2620:15c:202:201:ffda:7716:9afc:1301]) by smtp.gmail.com with ESMTPSA id z6sm20953866pgo.31.2019.03.21.10.18.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Mar 2019 10:18:31 -0700 (PDT) From: Evan Green To: Kishon Vijay Abraham I Cc: Stephen Boyd , Marc Gonzalez , Can Guo , Vivek Gautam , Douglas Anderson , Asutosh Das , Evan Green , "James E.J. Bottomley" , linux-scsi@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Alim Akhtar , Avri Altman , Andy Gross , David Brown , Pedro Sousa , "Martin K. Petersen" Subject: [PATCH v5 8/8] phy: ufs-qcom: Refactor all init steps into phy_poweron Date: Thu, 21 Mar 2019 10:18:00 -0700 Message-Id: <20190321171800.104681-9-evgreen@chromium.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190321171800.104681-1-evgreen@chromium.org> References: <20190321171800.104681-1-evgreen@chromium.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The phy code was using implicit sequencing between the PHY driver and the UFS driver to implement certain hardware requirements. Specifically, the PHY reset register in the UFS controller needs to be deasserted before serdes start occurs in the PHY. Before this change, the code was doing this by utilizing the two phy callbacks, phy_init() and phy_poweron(), as "init step 1" and "init step 2", where the UFS driver would deassert reset between these two steps. This makes it challenging to power off the regulators in suspend, as regulators are initialized in init, not in poweron(), but only poweroff() is called during suspend, not exit(). For UFS, move the actual firing up of the PHY to phy_poweron() and phy_poweroff() callbacks, rather than init()/exit(). UFS calls phy_poweroff() during suspend, so now all clocks and regulators for the phy can be powered down during suspend. QMP is a little tricky because the PHY is also shared with PCIe and USB3, which have their own definitions for init() and poweron(). Rename the meaty functions to _enable() and _disable() to disentangle from the PHY core names, and then create two different ops structures: one for UFS and one for the other PHY types. In phy-qcom-ufs, remove the 'is_powered_on' and 'is_started' guards, as the generic PHY code does the reference counting. The 14/20nm-specific init functions get collapsed into the generic power_on() function, with the addition of a calibrate() callback specific to 14/20nm. Signed-off-by: Evan Green Reviewed-by: Stephen Boyd --- Changes in v5: - Updated tags Changes in v4: - Keep doing reset_control* unconditionally through refactor (Stephen). Changes in v3: - Refactor init => poweron for all PHYs and UFS in one step (Stephen) Changes in v2: - Use devm_ to get the reset (Stephen) - Removed whitespace changes (Stephen) drivers/phy/qualcomm/phy-qcom-qmp.c | 78 ++++++-------------- drivers/phy/qualcomm/phy-qcom-ufs-i.h | 4 +- drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c | 33 +-------- drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c | 33 +-------- drivers/phy/qualcomm/phy-qcom-ufs.c | 42 ++++++----- drivers/scsi/ufs/ufs-qcom.c | 44 +++++------ 6 files changed, 64 insertions(+), 170 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c index a808887ab4e2..3b01ebf76f66 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -1339,8 +1339,7 @@ static int qcom_qmp_phy_com_exit(struct qcom_qmp *qmp) return 0; } -/* PHY Initialization */ -static int qcom_qmp_phy_init(struct phy *phy) +static int qcom_qmp_phy_enable(struct phy *phy) { struct qmp_phy *qphy = phy_get_drvdata(phy); struct qcom_qmp *qmp = qphy->qmp; @@ -1418,14 +1417,6 @@ static int qcom_qmp_phy_init(struct phy *phy) if (ret) goto err_lane_rst; - /* - * UFS PHY requires the deassert of software reset before serdes start. - * For UFS PHYs that do not have software reset control bits, defer - * starting serdes until the power on callback. - */ - if ((cfg->type == PHY_TYPE_UFS) && cfg->no_pcs_sw_reset) - goto out; - /* * Pull out PHY from POWER DOWN state. * This is active low enable signal to power-down PHY. @@ -1437,7 +1428,9 @@ static int qcom_qmp_phy_init(struct phy *phy) usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max); /* Pull PHY out of reset state */ - qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); + if (!cfg->no_pcs_sw_reset) + qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); + if (cfg->has_phy_dp_com_ctrl) qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET); @@ -1454,11 +1447,10 @@ static int qcom_qmp_phy_init(struct phy *phy) goto err_pcs_ready; } qmp->phy_initialized = true; - -out: - return ret; + return 0; err_pcs_ready: + reset_control_assert(qmp->ufs_reset); clk_disable_unprepare(qphy->pipe_clk); err_clk_enable: if (cfg->has_lane_rst) @@ -1469,7 +1461,7 @@ static int qcom_qmp_phy_init(struct phy *phy) return ret; } -static int qcom_qmp_phy_exit(struct phy *phy) +static int qcom_qmp_phy_disable(struct phy *phy) { struct qmp_phy *qphy = phy_get_drvdata(phy); struct qcom_qmp *qmp = qphy->qmp; @@ -1497,44 +1489,6 @@ static int qcom_qmp_phy_exit(struct phy *phy) return 0; } -static int qcom_qmp_phy_poweron(struct phy *phy) -{ - struct qmp_phy *qphy = phy_get_drvdata(phy); - struct qcom_qmp *qmp = qphy->qmp; - const struct qmp_phy_cfg *cfg = qmp->cfg; - void __iomem *pcs = qphy->pcs; - void __iomem *status; - unsigned int mask, val; - int ret = 0; - - if (cfg->type != PHY_TYPE_UFS) - return 0; - - /* - * For UFS PHY that has not software reset control, serdes start - * should only happen when UFS driver explicitly calls phy_power_on - * after it deasserts software reset. - */ - if (cfg->no_pcs_sw_reset && !qmp->phy_initialized && - (qmp->init_count != 0)) { - /* start SerDes and Phy-Coding-Sublayer */ - qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl); - - status = pcs + cfg->regs[QPHY_PCS_READY_STATUS]; - mask = cfg->mask_pcs_ready; - - ret = readl_poll_timeout(status, val, !(val & mask), 1, - PHY_INIT_COMPLETE_TIMEOUT); - if (ret) { - dev_err(qmp->dev, "phy initialization timed-out\n"); - return ret; - } - qmp->phy_initialized = true; - } - - return ret; -} - static int qcom_qmp_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) { @@ -1784,9 +1738,15 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np) } static const struct phy_ops qcom_qmp_phy_gen_ops = { - .init = qcom_qmp_phy_init, - .exit = qcom_qmp_phy_exit, - .power_on = qcom_qmp_phy_poweron, + .init = qcom_qmp_phy_enable, + .exit = qcom_qmp_phy_disable, + .set_mode = qcom_qmp_phy_set_mode, + .owner = THIS_MODULE, +}; + +static const struct phy_ops qcom_qmp_ufs_ops = { + .power_on = qcom_qmp_phy_enable, + .power_off = qcom_qmp_phy_disable, .set_mode = qcom_qmp_phy_set_mode, .owner = THIS_MODULE, }; @@ -1797,6 +1757,7 @@ int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id) struct qcom_qmp *qmp = dev_get_drvdata(dev); struct phy *generic_phy; struct qmp_phy *qphy; + const struct phy_ops *ops = &qcom_qmp_phy_gen_ops; char prop_name[MAX_PROP_NAME]; int ret; @@ -1883,7 +1844,10 @@ int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id) } } - generic_phy = devm_phy_create(dev, np, &qcom_qmp_phy_gen_ops); + if (qmp->cfg->type == PHY_TYPE_UFS) + ops = &qcom_qmp_ufs_ops; + + generic_phy = devm_phy_create(dev, np, ops); if (IS_ERR(generic_phy)) { ret = PTR_ERR(generic_phy); dev_err(dev, "failed to create qphy %d\n", ret); diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-i.h b/drivers/phy/qualcomm/phy-qcom-ufs-i.h index ba77348d807c..109ddd67be82 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-i.h +++ b/drivers/phy/qualcomm/phy-qcom-ufs-i.h @@ -97,8 +97,6 @@ struct ufs_qcom_phy { char name[UFS_QCOM_PHY_NAME_LEN]; struct ufs_qcom_phy_calibration *cached_regs; int cached_regs_table_size; - bool is_powered_on; - bool is_started; struct ufs_qcom_phy_specific_ops *phy_spec_ops; enum phy_mode mode; @@ -117,6 +115,7 @@ struct ufs_qcom_phy { * and writes to QSERDES_RX_SIGDET_CNTRL attribute */ struct ufs_qcom_phy_specific_ops { + int (*calibrate)(struct ufs_qcom_phy *ufs_qcom_phy, bool is_rate_B); void (*start_serdes)(struct ufs_qcom_phy *phy); int (*is_physical_coding_sublayer_ready)(struct ufs_qcom_phy *phy); void (*set_tx_lane_enable)(struct ufs_qcom_phy *phy, u32 val); @@ -134,7 +133,6 @@ struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev, struct ufs_qcom_phy *common_cfg, const struct phy_ops *ufs_qcom_phy_gen_ops, struct ufs_qcom_phy_specific_ops *phy_spec_ops); -int ufs_qcom_phy_get_reset(struct ufs_qcom_phy *phy_common); int ufs_qcom_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy, struct ufs_qcom_phy_calibration *tbl_A, int tbl_size_A, struct ufs_qcom_phy_calibration *tbl_B, int tbl_size_B, diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c index cc343517a2ca..4815546f228c 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-14nm.c @@ -42,36 +42,6 @@ void ufs_qcom_phy_qmp_14nm_advertise_quirks(struct ufs_qcom_phy *phy_common) UFS_QCOM_PHY_QUIRK_HIBERN8_EXIT_AFTER_PHY_PWR_COLLAPSE; } -static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy) -{ - struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy); - bool is_rate_B = false; - int ret; - - ret = ufs_qcom_phy_get_reset(phy_common); - if (ret) - return ret; - - ret = reset_control_assert(phy_common->ufs_reset); - if (ret) - return ret; - - if (phy_common->mode == PHY_MODE_UFS_HS_B) - is_rate_B = true; - - ret = ufs_qcom_phy_qmp_14nm_phy_calibrate(phy_common, is_rate_B); - if (!ret) - /* phy calibrated, but yet to be started */ - phy_common->is_started = false; - - return ret; -} - -static int ufs_qcom_phy_qmp_14nm_exit(struct phy *generic_phy) -{ - return 0; -} - static int ufs_qcom_phy_qmp_14nm_set_mode(struct phy *generic_phy, enum phy_mode mode, int submode) @@ -132,8 +102,6 @@ static int ufs_qcom_phy_qmp_14nm_is_pcs_ready(struct ufs_qcom_phy *phy_common) } static const struct phy_ops ufs_qcom_phy_qmp_14nm_phy_ops = { - .init = ufs_qcom_phy_qmp_14nm_init, - .exit = ufs_qcom_phy_qmp_14nm_exit, .power_on = ufs_qcom_phy_power_on, .power_off = ufs_qcom_phy_power_off, .set_mode = ufs_qcom_phy_qmp_14nm_set_mode, @@ -141,6 +109,7 @@ static const struct phy_ops ufs_qcom_phy_qmp_14nm_phy_ops = { }; static struct ufs_qcom_phy_specific_ops phy_14nm_ops = { + .calibrate = ufs_qcom_phy_qmp_14nm_phy_calibrate, .start_serdes = ufs_qcom_phy_qmp_14nm_start_serdes, .is_physical_coding_sublayer_ready = ufs_qcom_phy_qmp_14nm_is_pcs_ready, .set_tx_lane_enable = ufs_qcom_phy_qmp_14nm_set_tx_lane_enable, diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c index 54b2af9d8702..f1cf819e12ea 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs-qmp-20nm.c @@ -61,36 +61,6 @@ void ufs_qcom_phy_qmp_20nm_advertise_quirks(struct ufs_qcom_phy *phy_common) UFS_QCOM_PHY_QUIRK_HIBERN8_EXIT_AFTER_PHY_PWR_COLLAPSE; } -static int ufs_qcom_phy_qmp_20nm_init(struct phy *generic_phy) -{ - struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy); - bool is_rate_B = false; - int ret; - - ret = ufs_qcom_phy_get_reset(phy_common); - if (ret) - return ret; - - ret = reset_control_assert(phy_common->ufs_reset); - if (ret) - return ret; - - if (phy_common->mode == PHY_MODE_UFS_HS_B) - is_rate_B = true; - - ret = ufs_qcom_phy_qmp_20nm_phy_calibrate(phy_common, is_rate_B); - if (!ret) - /* phy calibrated, but yet to be started */ - phy_common->is_started = false; - - return ret; -} - -static int ufs_qcom_phy_qmp_20nm_exit(struct phy *generic_phy) -{ - return 0; -} - static int ufs_qcom_phy_qmp_20nm_set_mode(struct phy *generic_phy, enum phy_mode mode, int submode) @@ -190,8 +160,6 @@ static int ufs_qcom_phy_qmp_20nm_is_pcs_ready(struct ufs_qcom_phy *phy_common) } static const struct phy_ops ufs_qcom_phy_qmp_20nm_phy_ops = { - .init = ufs_qcom_phy_qmp_20nm_init, - .exit = ufs_qcom_phy_qmp_20nm_exit, .power_on = ufs_qcom_phy_power_on, .power_off = ufs_qcom_phy_power_off, .set_mode = ufs_qcom_phy_qmp_20nm_set_mode, @@ -199,6 +167,7 @@ static const struct phy_ops ufs_qcom_phy_qmp_20nm_phy_ops = { }; static struct ufs_qcom_phy_specific_ops phy_20nm_ops = { + .calibrate = ufs_qcom_phy_qmp_20nm_phy_calibrate, .start_serdes = ufs_qcom_phy_qmp_20nm_start_serdes, .is_physical_coding_sublayer_ready = ufs_qcom_phy_qmp_20nm_is_pcs_ready, .set_tx_lane_enable = ufs_qcom_phy_qmp_20nm_set_tx_lane_enable, diff --git a/drivers/phy/qualcomm/phy-qcom-ufs.c b/drivers/phy/qualcomm/phy-qcom-ufs.c index fe59785a55f2..0a9f50f086b6 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs.c @@ -147,7 +147,7 @@ struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev, } EXPORT_SYMBOL_GPL(ufs_qcom_phy_generic_probe); -int ufs_qcom_phy_get_reset(struct ufs_qcom_phy *phy_common) +static int ufs_qcom_phy_get_reset(struct ufs_qcom_phy *phy_common) { struct reset_control *reset; @@ -161,7 +161,6 @@ int ufs_qcom_phy_get_reset(struct ufs_qcom_phy *phy_common) phy_common->ufs_reset = reset; return 0; } -EXPORT_SYMBOL_GPL(ufs_qcom_phy_get_reset); static int __ufs_qcom_phy_clk_get(struct device *dev, const char *name, struct clk **clk_out, bool err_print) @@ -544,10 +543,23 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy) { struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy); struct device *dev = phy_common->dev; + bool is_rate_B = false; int err; - if (phy_common->is_powered_on) - return 0; + err = ufs_qcom_phy_get_reset(phy_common); + if (err) + return err; + + err = reset_control_assert(phy_common->ufs_reset); + if (err) + return err; + + if (phy_common->mode == PHY_MODE_UFS_HS_B) + is_rate_B = true; + + err = phy_common->phy_spec_ops->calibrate(phy_common, is_rate_B); + if (err) + return err; err = reset_control_deassert(phy_common->ufs_reset); if (err) { @@ -555,17 +567,13 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy) return err; } - if (!phy_common->is_started) { - err = ufs_qcom_phy_start_serdes(phy_common); - if (err) - return err; - - err = ufs_qcom_phy_is_pcs_ready(phy_common); - if (err) - return err; + err = ufs_qcom_phy_start_serdes(phy_common); + if (err) + return err; - phy_common->is_started = true; - } + err = ufs_qcom_phy_is_pcs_ready(phy_common); + if (err) + return err; err = ufs_qcom_phy_enable_vreg(dev, &phy_common->vdda_phy); if (err) { @@ -609,7 +617,6 @@ int ufs_qcom_phy_power_on(struct phy *generic_phy) } } - phy_common->is_powered_on = true; goto out; out_disable_ref_clk: @@ -629,9 +636,6 @@ int ufs_qcom_phy_power_off(struct phy *generic_phy) { struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy); - if (!phy_common->is_powered_on) - return 0; - phy_common->phy_spec_ops->power_control(phy_common, false); if (phy_common->vddp_ref_clk.reg) @@ -643,8 +647,6 @@ int ufs_qcom_phy_power_off(struct phy *generic_phy) ufs_qcom_phy_disable_vreg(phy_common->dev, &phy_common->vdda_pll); ufs_qcom_phy_disable_vreg(phy_common->dev, &phy_common->vdda_phy); reset_control_assert(phy_common->ufs_reset); - phy_common->is_powered_on = false; - return 0; } EXPORT_SYMBOL_GPL(ufs_qcom_phy_power_off); diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 1c25b1c82314..de9d3f56b58c 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -544,19 +544,11 @@ static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) */ ufs_qcom_disable_lane_clks(host); phy_power_off(phy); - goto out; - } - /* - * If UniPro link is not active, PHY ref_clk, main PHY analog power - * rail and low noise analog power rail for PLL can be switched off. - */ - if (!ufs_qcom_is_link_active(hba)) { + } else if (!ufs_qcom_is_link_active(hba)) { ufs_qcom_disable_lane_clks(host); - phy_power_off(phy); } -out: return ret; } @@ -566,21 +558,26 @@ static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) struct phy *phy = host->generic_phy; int err; - err = phy_power_on(phy); - if (err) { - dev_err(hba->dev, "%s: failed enabling regs, err = %d\n", - __func__, err); - goto out; - } + if (ufs_qcom_is_link_off(hba)) { + err = phy_power_on(phy); + if (err) { + dev_err(hba->dev, "%s: failed PHY power on: %d\n", + __func__, err); + return err; + } - err = ufs_qcom_enable_lane_clks(host); - if (err) - goto out; + err = ufs_qcom_enable_lane_clks(host); + if (err) + return err; - hba->is_sys_suspended = false; + } else if (!ufs_qcom_is_link_active(hba)) { + err = ufs_qcom_enable_lane_clks(host); + if (err) + return err; + } -out: - return err; + hba->is_sys_suspended = false; + return 0; } struct ufs_qcom_dev_params { @@ -1106,8 +1103,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on, return 0; if (on && (status == POST_CHANGE)) { - phy_power_on(host->generic_phy); - /* enable the device ref clock for HS mode*/ if (ufshcd_is_hs_mode(&hba->pwr_info)) ufs_qcom_dev_ref_clk_ctrl(host, true); @@ -1119,9 +1114,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on, if (!ufs_qcom_is_link_active(hba)) { /* disable device ref_clk */ ufs_qcom_dev_ref_clk_ctrl(host, false); - - /* powering off PHY during aggressive clk gating */ - phy_power_off(host->generic_phy); } vote = host->bus_vote.min_bw_vote;