From patchwork Fri Aug 28 01:10:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: JC Kuo X-Patchwork-Id: 258739 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6AECDC433E2 for ; Fri, 28 Aug 2020 01:13:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4A72D2080C for ; Fri, 28 Aug 2020 01:13:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="aSHLmvQR" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728274AbgH1BMB (ORCPT ); Thu, 27 Aug 2020 21:12:01 -0400 Received: from hqnvemgate24.nvidia.com ([216.228.121.143]:9885 "EHLO hqnvemgate24.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728223AbgH1BL7 (ORCPT ); Thu, 27 Aug 2020 21:11:59 -0400 Received: from hqpgpgate102.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate24.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Thu, 27 Aug 2020 18:09:56 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate102.nvidia.com (PGP Universal service); Thu, 27 Aug 2020 18:11:58 -0700 X-PGP-Universal: processed; by hqpgpgate102.nvidia.com on Thu, 27 Aug 2020 18:11:58 -0700 Received: from HQMAIL101.nvidia.com (172.20.187.10) by HQMAIL111.nvidia.com (172.20.187.18) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Fri, 28 Aug 2020 01:11:55 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Fri, 28 Aug 2020 01:11:55 +0000 Received: from jckuo-lt.nvidia.com (Not Verified[10.19.101.4]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7, 5, 8, 10121) id ; Thu, 27 Aug 2020 18:11:54 -0700 From: JC Kuo To: , , , , CC: , , , , , JC Kuo Subject: [PATCH 01/12] clk: tegra: Add PLLE HW power sequencer control Date: Fri, 28 Aug 2020 09:10:45 +0800 Message-ID: <20200828011056.1067559-2-jckuo@nvidia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200828011056.1067559-1-jckuo@nvidia.com> References: <20200828011056.1067559-1-jckuo@nvidia.com> MIME-Version: 1.0 X-NVConfidentiality: public DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1598576996; bh=z9aKw1vyHrzjJiun8JEcoFXSJ50fQe9EfkdaKJIYd9U=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:MIME-Version:X-NVConfidentiality: Content-Transfer-Encoding:Content-Type; b=aSHLmvQRMK82RBen91xzSUpEy7rFZA38MPvC1aZnKNq9iXJQUtMjnRM42l5NpGIC4 QOx5d6guECBSf8yB8eApZnQotsjFgI6Frk/zjNV2Sh14G67N0Wfy5w9nDR9PylcIvn 8lusAPNOlP7P+lgmZaKMmMRiYuAAwjWh2AcplXDbkjy8buUzOS95JVJRhiWztXsNJG hl2j2EOvpnZpcljZlehejJpMKci4heNnQhpEwGxZwTVP1xnXskZgTQ6fSOPWBBYAwz DQOVHfDECKMQZwjs9mgJBC8aDaOOS6kSguEbW+/N7/I5uBcjHcpTt0R99+KVB5C+/Z sYSHYPQ6poyhQ== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org PLLE has a hardware power sequencer logic which is a state machine that can power on/off PLLE without any software intervention. The sequencer has two inputs, one from XUSB UPHY PLL and the other from SATA UPHY PLL. PLLE provides reference clock to XUSB and SATA UPHY PLLs. When both of the downstream PLLs are powered-off, PLLE hardware power sequencer will automatically power off PLLE for power saving. XUSB and SATA UPHY PLLs also have their own hardware power sequencer logic. XUSB UPHY PLL is shared between XUSB SuperSpeed ports and PCIE controllers. The XUSB UPHY PLL hardware power sequencer has inputs from XUSB and PCIE. When all of the XUSB SuperSpeed ports and PCIE controllers are in low power state, XUSB UPHY PLL hardware power sequencer automatically power off PLL and flags idle to PLLE hardware power sequencer. Similar applies to SATA UPHY PLL. PLLE hardware power sequencer has to be enabled after both downstream sequencers are enabled. This commit adds two helper functions: 1. tegra210_plle_hw_sequence_start() for XUSB PADCTL driver to enable PLLE hardware sequencer at proper time. 2. tegra210_plle_hw_sequence_is_enabled() for XUSB PADCTL driver to check whether PLLE hardware sequencer has been enabled or not. Signed-off-by: JC Kuo --- drivers/clk/tegra/clk-tegra210.c | 51 ++++++++++++++++++++++++++++++++ include/linux/clk/tegra.h | 2 ++ 2 files changed, 53 insertions(+) diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 68cbb98af567..255de6c23c67 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -403,6 +403,14 @@ static unsigned long tegra210_input_freq[] = { #define PLLRE_BASE_DEFAULT_MASK 0x1c000000 #define PLLRE_MISC0_WRITE_MASK 0x67ffffff +/* PLLE */ +#define PLLE_MISC_IDDQ_SW_CTRL (1 << 14) +#define PLLE_AUX_USE_LOCKDET (1 << 3) +#define PLLE_AUX_SS_SEQ_INCLUDE (1 << 31) +#define PLLE_AUX_ENABLE_SWCTL (1 << 4) +#define PLLE_AUX_SS_SWCTL (1 << 6) +#define PLLE_AUX_SEQ_ENABLE (1 << 24) + /* PLLX */ #define PLLX_USE_DYN_RAMP 1 #define PLLX_BASE_LOCK (1 << 27) @@ -489,6 +497,49 @@ static unsigned long tegra210_input_freq[] = { #define PLLU_MISC0_WRITE_MASK 0xbfffffff #define PLLU_MISC1_WRITE_MASK 0x00000007 +bool tegra210_plle_hw_sequence_is_enabled(void) +{ + u32 val; + + val = readl_relaxed(clk_base + PLLE_AUX); + if (val & PLLE_AUX_SEQ_ENABLE) + return true; + + return false; +} +EXPORT_SYMBOL_GPL(tegra210_plle_hw_sequence_is_enabled); + +int tegra210_plle_hw_sequence_start(void) +{ + u32 val; + + if (tegra210_plle_hw_sequence_is_enabled()) + return 0; + + /* skip if PLLE is not enabled yet */ + val = readl_relaxed(clk_base + PLLE_MISC0); + if (!(val & PLLE_MISC_LOCK)) + return -EIO; + + val &= ~PLLE_MISC_IDDQ_SW_CTRL; + writel_relaxed(val, clk_base + PLLE_MISC0); + + val = readl_relaxed(clk_base + PLLE_AUX); + val |= (PLLE_AUX_USE_LOCKDET | PLLE_AUX_SS_SEQ_INCLUDE); + val &= ~(PLLE_AUX_ENABLE_SWCTL | PLLE_AUX_SS_SWCTL); + writel_relaxed(val, clk_base + PLLE_AUX); + + fence_udelay(1, clk_base); + + val |= PLLE_AUX_SEQ_ENABLE; + writel_relaxed(val, clk_base + PLLE_AUX); + + fence_udelay(1, clk_base); + + return 0; +} +EXPORT_SYMBOL_GPL(tegra210_plle_hw_sequence_start); + void tegra210_xusb_pll_hw_control_enable(void) { u32 val; diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h index 3f01d43f0598..7a6b29ca3040 100644 --- a/include/linux/clk/tegra.h +++ b/include/linux/clk/tegra.h @@ -123,6 +123,8 @@ static inline void tegra_cpu_clock_resume(void) } #endif +extern int tegra210_plle_hw_sequence_start(void); +extern bool tegra210_plle_hw_sequence_is_enabled(void); extern void tegra210_xusb_pll_hw_control_enable(void); extern void tegra210_xusb_pll_hw_sequence_start(void); extern void tegra210_sata_pll_hw_control_enable(void); From patchwork Fri Aug 28 01:10:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: JC Kuo X-Patchwork-Id: 258740 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C1AC0C433E7 for ; Fri, 28 Aug 2020 01:13:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9CACD2080C for ; Fri, 28 Aug 2020 01:13:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="YvfSerXk" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728447AbgH1BNJ (ORCPT ); Thu, 27 Aug 2020 21:13:09 -0400 Received: from hqnvemgate25.nvidia.com ([216.228.121.64]:15010 "EHLO hqnvemgate25.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728324AbgH1BMJ (ORCPT ); Thu, 27 Aug 2020 21:12:09 -0400 Received: from hqpgpgate102.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate25.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Thu, 27 Aug 2020 18:11:25 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate102.nvidia.com (PGP Universal service); Thu, 27 Aug 2020 18:12:08 -0700 X-PGP-Universal: processed; by hqpgpgate102.nvidia.com on Thu, 27 Aug 2020 18:12:08 -0700 Received: from HQMAIL107.nvidia.com (172.20.187.13) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Fri, 28 Aug 2020 01:12:04 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Fri, 28 Aug 2020 01:12:04 +0000 Received: from jckuo-lt.nvidia.com (Not Verified[10.19.101.4]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7, 5, 8, 10121) id ; Thu, 27 Aug 2020 18:12:04 -0700 From: JC Kuo To: , , , , CC: , , , , , JC Kuo Subject: [PATCH 05/12] phy: tegra: xusb: add sleepwalk and suspend/resume Date: Fri, 28 Aug 2020 09:10:49 +0800 Message-ID: <20200828011056.1067559-6-jckuo@nvidia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200828011056.1067559-1-jckuo@nvidia.com> References: <20200828011056.1067559-1-jckuo@nvidia.com> MIME-Version: 1.0 X-NVConfidentiality: public DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1598577085; bh=kX0RwgveLiINhWbSkybtsDBLi2N6bZpxn7iuTnuZPAY=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:MIME-Version:X-NVConfidentiality: Content-Transfer-Encoding:Content-Type; b=YvfSerXkhclGj0RSn+rxvV6JPnNNZ2F643vhhpk66ZYWJPkFrXI1OGkApULndR0RM 9DJOtXRORudac/F/cfGL5urUG+RyRPv6ZCzaKLPqMUbkG3qbDlJkEJrNw6ITDnlAp5 cBSKTmGH7100W8RP1x+9f8ZpljGERKVKUuN6/LsqUkOaIKrP2Ije3AntxFsdfCe406 WYuwdRK9JSTznp46HLSK4ZKfwh5fLTjiCcRiEoRyqYoDM8k2KB4aKQpHD9cUF9VNXT 2wGXiCpVyvBZ3eoNlGOidR08X5O5MLDJQQcsYXgceBj/qNr/2/9hipKps9p1SnIEnm M/DZNA8Mnm1Jw== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org This commit adds sleepwalk/wake and suspend/resume interfaces to Tegra XUSB PHY driver. Tegra XUSB host controller driver makes use of sleepwalk functions to enable/disable sleepwalk circuit which is in always-on partition can respond to USB resume signals when controller is not powered. Sleepwalk can be enabled/disabled for any USB phy individually. - tegra_xusb_padctl_enable_phy_sleepwalk() - tegra_xusb_padctl_disable_phy_sleepwalk() Tegra XUSB host controller driver makes use of wake functions to enable/disable/query wake circuit which is in always-on partition can wake system up when USB resume happens. Wake circuit can be enabled/disabled for any USB phy individually. - tegra_xusb_padctl_enable_phy_wake() - tegra_xusb_padctl_disable_phy_wake() - tegra_xusb_padctl_remote_wake_detected() This commit also adds two system suspend stubs that can be used to save and restore XUSB PADCTL context during system suspend and resume. - tegra_xusb_padctl_suspend_noirq() - tegra_xusb_padctl_resume_noirq() Signed-off-by: JC Kuo --- drivers/phy/tegra/xusb.c | 78 ++++++++++++++++++++++++++++++++++ drivers/phy/tegra/xusb.h | 13 ++++++ include/linux/phy/tegra/xusb.h | 13 ++++++ 3 files changed, 104 insertions(+) diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index 74abd67e3a31..3a1551c42c29 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -1274,10 +1274,36 @@ static int tegra_xusb_padctl_remove(struct platform_device *pdev) return err; } +static int tegra_xusb_padctl_suspend_noirq(struct device *dev) +{ + struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev); + + if (padctl->soc && padctl->soc->ops && padctl->soc->ops->suspend_noirq) + return padctl->soc->ops->suspend_noirq(padctl); + + return 0; +} + +static int tegra_xusb_padctl_resume_noirq(struct device *dev) +{ + struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev); + + if (padctl->soc && padctl->soc->ops && padctl->soc->ops->resume_noirq) + return padctl->soc->ops->resume_noirq(padctl); + + return 0; +} + +static const struct dev_pm_ops tegra_xusb_padctl_pm_ops = { + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(tegra_xusb_padctl_suspend_noirq, + tegra_xusb_padctl_resume_noirq) +}; + static struct platform_driver tegra_xusb_padctl_driver = { .driver = { .name = "tegra-xusb-padctl", .of_match_table = tegra_xusb_padctl_of_match, + .pm = &tegra_xusb_padctl_pm_ops, }, .probe = tegra_xusb_padctl_probe, .remove = tegra_xusb_padctl_remove, @@ -1344,6 +1370,58 @@ int tegra_xusb_padctl_hsic_set_idle(struct tegra_xusb_padctl *padctl, } EXPORT_SYMBOL_GPL(tegra_xusb_padctl_hsic_set_idle); +int tegra_xusb_padctl_enable_phy_sleepwalk(struct tegra_xusb_padctl *padctl, + struct phy *phy, + enum usb_device_speed speed) +{ + if (padctl->soc->ops->enable_phy_sleepwalk) + return padctl->soc->ops->enable_phy_sleepwalk(padctl, phy, + speed); + + return -ENOTSUPP; +} +EXPORT_SYMBOL_GPL(tegra_xusb_padctl_enable_phy_sleepwalk); + +int tegra_xusb_padctl_disable_phy_sleepwalk(struct tegra_xusb_padctl *padctl, + struct phy *phy) +{ + if (padctl->soc->ops->disable_phy_sleepwalk) + return padctl->soc->ops->disable_phy_sleepwalk(padctl, phy); + + return -ENOTSUPP; +} +EXPORT_SYMBOL_GPL(tegra_xusb_padctl_disable_phy_sleepwalk); + +int tegra_xusb_padctl_enable_phy_wake(struct tegra_xusb_padctl *padctl, + struct phy *phy) +{ + if (padctl->soc->ops->enable_phy_wake) + return padctl->soc->ops->enable_phy_wake(padctl, phy); + + return -ENOTSUPP; +} +EXPORT_SYMBOL_GPL(tegra_xusb_padctl_enable_phy_wake); + +int tegra_xusb_padctl_disable_phy_wake(struct tegra_xusb_padctl *padctl, + struct phy *phy) +{ + if (padctl->soc->ops->disable_phy_wake) + return padctl->soc->ops->disable_phy_wake(padctl, phy); + + return -ENOTSUPP; +} +EXPORT_SYMBOL_GPL(tegra_xusb_padctl_disable_phy_wake); + +int tegra_xusb_padctl_remote_wake_detected(struct tegra_xusb_padctl *padctl, + struct phy *phy) +{ + if (padctl->soc->ops->remote_wake_detected) + return padctl->soc->ops->remote_wake_detected(phy); + + return -ENOTSUPP; +} +EXPORT_SYMBOL_GPL(tegra_xusb_padctl_remote_wake_detected); + int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl, unsigned int port, bool enable) { diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h index 485b692a3b15..c1c4ea3ce050 100644 --- a/drivers/phy/tegra/xusb.h +++ b/drivers/phy/tegra/xusb.h @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -392,6 +393,8 @@ struct tegra_xusb_padctl_ops { const struct tegra_xusb_padctl_soc *soc); void (*remove)(struct tegra_xusb_padctl *padctl); + int (*suspend_noirq)(struct tegra_xusb_padctl *padctl); + int (*resume_noirq)(struct tegra_xusb_padctl *padctl); int (*usb3_save_context)(struct tegra_xusb_padctl *padctl, unsigned int index); int (*hsic_set_idle)(struct tegra_xusb_padctl *padctl, @@ -400,6 +403,16 @@ struct tegra_xusb_padctl_ops { unsigned int index, bool enable); int (*vbus_override)(struct tegra_xusb_padctl *padctl, bool set); int (*utmi_port_reset)(struct phy *phy); + int (*enable_phy_sleepwalk)(struct tegra_xusb_padctl *padctl, + struct phy *phy, + enum usb_device_speed speed); + int (*disable_phy_sleepwalk)(struct tegra_xusb_padctl *padctl, + struct phy *phy); + int (*enable_phy_wake)(struct tegra_xusb_padctl *padctl, + struct phy *phy); + int (*disable_phy_wake)(struct tegra_xusb_padctl *padctl, + struct phy *phy); + int (*remote_wake_detected)(struct phy *phy); }; struct tegra_xusb_padctl_soc { diff --git a/include/linux/phy/tegra/xusb.h b/include/linux/phy/tegra/xusb.h index 71d956935405..9621e69067e1 100644 --- a/include/linux/phy/tegra/xusb.h +++ b/include/linux/phy/tegra/xusb.h @@ -8,6 +8,7 @@ struct tegra_xusb_padctl; struct device; +enum usb_device_speed; struct tegra_xusb_padctl *tegra_xusb_padctl_get(struct device *dev); void tegra_xusb_padctl_put(struct tegra_xusb_padctl *padctl); @@ -23,4 +24,16 @@ int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl, int tegra_phy_xusb_utmi_port_reset(struct phy *phy); int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl, unsigned int port); +int tegra_xusb_padctl_enable_phy_sleepwalk(struct tegra_xusb_padctl *padctl, + struct phy *phy, + enum usb_device_speed speed); +int tegra_xusb_padctl_disable_phy_sleepwalk(struct tegra_xusb_padctl *padctl, + struct phy *phy); +int tegra_xusb_padctl_enable_phy_wake(struct tegra_xusb_padctl *padctl, + struct phy *phy); +int tegra_xusb_padctl_disable_phy_wake(struct tegra_xusb_padctl *padctl, + struct phy *phy); +int tegra_xusb_padctl_remote_wake_detected(struct tegra_xusb_padctl *padctl, + struct phy *phy); + #endif /* PHY_TEGRA_XUSB_H */ From patchwork Fri Aug 28 01:10:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: JC Kuo X-Patchwork-Id: 258744 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3AE8BC433E6 for ; Fri, 28 Aug 2020 01:12:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1A07E20848 for ; Fri, 28 Aug 2020 01:12:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="NG02nycr" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728335AbgH1BML (ORCPT ); Thu, 27 Aug 2020 21:12:11 -0400 Received: from hqnvemgate26.nvidia.com ([216.228.121.65]:6722 "EHLO hqnvemgate26.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728238AbgH1BMJ (ORCPT ); Thu, 27 Aug 2020 21:12:09 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate26.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Thu, 27 Aug 2020 18:11:54 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Thu, 27 Aug 2020 18:12:08 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Thu, 27 Aug 2020 18:12:08 -0700 Received: from HQMAIL101.nvidia.com (172.20.187.10) by HQMAIL111.nvidia.com (172.20.187.18) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Fri, 28 Aug 2020 01:12:07 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Fri, 28 Aug 2020 01:12:06 +0000 Received: from jckuo-lt.nvidia.com (Not Verified[10.19.101.4]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7, 5, 8, 10121) id ; Thu, 27 Aug 2020 18:12:06 -0700 From: JC Kuo To: , , , , CC: , , , , , JC Kuo Subject: [PATCH 06/12] soc/tegra: pmc: provide usb sleepwalk register map Date: Fri, 28 Aug 2020 09:10:50 +0800 Message-ID: <20200828011056.1067559-7-jckuo@nvidia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200828011056.1067559-1-jckuo@nvidia.com> References: <20200828011056.1067559-1-jckuo@nvidia.com> MIME-Version: 1.0 X-NVConfidentiality: public DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1598577114; bh=EzKtAqrTodjOgiCWDpwa2azXqcgYUJqoExowR8pSCHk=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:MIME-Version:X-NVConfidentiality: Content-Transfer-Encoding:Content-Type; b=NG02nycr78ZponyOSE7NNI0xviuAKnc0N6YV3Nq4x1G2zLBz3rgsxgoTqjm7JlGO/ W6G0aDKhD7NL2EzoMtDXSgG3YPBS/qkEBINckkv6T8U9C2CYJI1ZzXu6E8IMXsqVBv L+NhA3jej4GVfq0LDKG0e0tj4LcEiPCdqur5zSbwT8iINJ1ubrSMYsAtvbTe4oxp1p QDRuh/aEhkZsZA9wsBGa3myf/ndJoJmdfZwx1ZHK6ZdO/ZCHQbI6fTDleBtHLpPfUl /xhkjFCzxDZJQn1wdtrhsud/aZ+E8xAhhhVDDcn7PWJaGxwrcupJi7Ssu/ohnx09rB QMcau8wQd4uTg== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org This commit implements a register map which grants USB (UTMI and HSIC) sleepwalk registers access to USB phy drivers. The USB sleepwalk logic is in PMC hardware block but USB phy drivers have the best knowledge of proper programming sequence. This approach prevents using custom pmc APIs. Signed-off-by: JC Kuo --- drivers/soc/tegra/pmc.c | 89 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index d332e5d9abac..81504559b62d 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -102,6 +103,9 @@ #define PMC_PWR_DET_VALUE 0xe4 +#define PMC_USB_DEBOUNCE_DEL 0xec +#define PMC_USB_AO 0xf0 + #define PMC_SCRATCH41 0x140 #define PMC_WAKE2_MASK 0x160 @@ -133,6 +137,13 @@ #define IO_DPD2_STATUS 0x1c4 #define SEL_DPD_TIM 0x1c8 +#define PMC_UTMIP_UHSIC_TRIGGERS 0x1ec +#define PMC_UTMIP_UHSIC_SAVED_STATE 0x1f0 + +#define PMC_UTMIP_TERM_PAD_CFG 0x1f8 +#define PMC_UTMIP_UHSIC_SLEEP_CFG 0x1fc +#define PMC_UTMIP_UHSIC_FAKE 0x218 + #define PMC_SCRATCH54 0x258 #define PMC_SCRATCH54_DATA_SHIFT 8 #define PMC_SCRATCH54_ADDR_SHIFT 0 @@ -145,8 +156,18 @@ #define PMC_SCRATCH55_CHECKSUM_SHIFT 16 #define PMC_SCRATCH55_I2CSLV1_SHIFT 0 +#define PMC_UTMIP_UHSIC_LINE_WAKEUP 0x26c + +#define PMC_UTMIP_BIAS_MASTER_CNTRL 0x270 +#define PMC_UTMIP_MASTER_CONFIG 0x274 +#define PMC_UTMIP_UHSIC2_TRIGGERS 0x27c +#define PMC_UTMIP_MASTER2_CONFIG 0x29c + #define GPU_RG_CNTRL 0x2d4 +#define PMC_UTMIP_PAD_CFG0 0x4c0 +#define PMC_UTMIP_UHSIC_SLEEP_CFG1 0x4d0 +#define PMC_UTMIP_SLEEPWALK_P3 0x4e0 /* Tegra186 and later */ #define WAKE_AOWAKE_CNTRL(x) (0x000 + ((x) << 2)) #define WAKE_AOWAKE_CNTRL_LEVEL (1 << 3) @@ -334,6 +355,7 @@ struct tegra_pmc_soc { const struct pmc_clk_init_data *pmc_clks_data; unsigned int num_pmc_clks; bool has_blink_output; + bool has_usb_sleepwalk; }; static const char * const tegra186_reset_sources[] = { @@ -2495,6 +2517,67 @@ static void tegra_pmc_clock_register(struct tegra_pmc *pmc, err); } +#define regmap_reg(x) regmap_reg_range(x, x) +static const struct regmap_range pmc_usb_sleepwalk_ranges[] = { + regmap_reg_range(PMC_USB_DEBOUNCE_DEL, PMC_USB_AO), + regmap_reg_range(PMC_UTMIP_UHSIC_TRIGGERS, PMC_UTMIP_UHSIC_SAVED_STATE), + regmap_reg_range(PMC_UTMIP_TERM_PAD_CFG, PMC_UTMIP_UHSIC_FAKE), + regmap_reg(PMC_UTMIP_UHSIC_LINE_WAKEUP), + regmap_reg_range(PMC_UTMIP_BIAS_MASTER_CNTRL, PMC_UTMIP_MASTER_CONFIG), + regmap_reg_range(PMC_UTMIP_UHSIC2_TRIGGERS, PMC_UTMIP_MASTER2_CONFIG), + regmap_reg_range(PMC_UTMIP_PAD_CFG0, PMC_UTMIP_UHSIC_SLEEP_CFG1), + regmap_reg(PMC_UTMIP_SLEEPWALK_P3), +}; + +static const struct regmap_access_table pmc_usb_sleepwalk_table = { + .yes_ranges = pmc_usb_sleepwalk_ranges, + .n_yes_ranges = ARRAY_SIZE(pmc_usb_sleepwalk_ranges), +}; + +int tegra_pmc_regmap_readl(void *context, unsigned int reg, unsigned int *val) +{ + struct tegra_pmc *pmc = context; + + *val = tegra_pmc_readl(pmc, reg); + return 0; +} + +int tegra_pmc_regmap_writel(void *context, unsigned int reg, unsigned int val) +{ + struct tegra_pmc *pmc = context; + + tegra_pmc_writel(pmc, val, reg); + return 0; +} + +static const struct regmap_config usb_sleepwalk_regmap_config = { + .name = "usb_sleepwalk", + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .fast_io = true, + .rd_table = &pmc_usb_sleepwalk_table, + .wr_table = &pmc_usb_sleepwalk_table, + .reg_read = tegra_pmc_regmap_readl, + .reg_write = tegra_pmc_regmap_writel, +}; + +static int tegra_pmc_regmap_init(struct tegra_pmc *pmc) +{ + struct regmap *regmap; + + if (pmc->soc->has_usb_sleepwalk) { + regmap = devm_regmap_init(pmc->dev, NULL, (__force void *)pmc, + &usb_sleepwalk_regmap_config); + if (IS_ERR(regmap)) { + dev_err(pmc->dev, "failed to allocate register map\n"); + return PTR_ERR(regmap); + } + } + + return 0; +} + static int tegra_pmc_probe(struct platform_device *pdev) { void __iomem *base; @@ -2613,6 +2696,10 @@ static int tegra_pmc_probe(struct platform_device *pdev) pmc->base = base; mutex_unlock(&pmc->powergates_lock); + err = tegra_pmc_regmap_init(pmc); + if (err < 0) + goto cleanup_powergates; + tegra_pmc_clock_register(pmc, pdev->dev.of_node); platform_set_drvdata(pdev, pmc); @@ -2976,6 +3063,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = { .pmc_clks_data = tegra_pmc_clks_data, .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data), .has_blink_output = true, + .has_usb_sleepwalk = true, }; static const char * const tegra210_powergates[] = { @@ -3094,6 +3182,7 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { .pmc_clks_data = tegra_pmc_clks_data, .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data), .has_blink_output = true, + .has_usb_sleepwalk = true, }; #define TEGRA186_IO_PAD_TABLE(_pad) \ From patchwork Fri Aug 28 01:10:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: JC Kuo X-Patchwork-Id: 258742 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F3200C433E7 for ; Fri, 28 Aug 2020 01:12:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CACD920872 for ; Fri, 28 Aug 2020 01:12:44 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="TF6l2YFW" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728372AbgH1BMU (ORCPT ); Thu, 27 Aug 2020 21:12:20 -0400 Received: from hqnvemgate26.nvidia.com ([216.228.121.65]:6745 "EHLO hqnvemgate26.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728295AbgH1BMN (ORCPT ); Thu, 27 Aug 2020 21:12:13 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate26.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Thu, 27 Aug 2020 18:11:59 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Thu, 27 Aug 2020 18:12:13 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Thu, 27 Aug 2020 18:12:13 -0700 Received: from HQMAIL109.nvidia.com (172.20.187.15) by HQMAIL111.nvidia.com (172.20.187.18) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Fri, 28 Aug 2020 01:12:09 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL109.nvidia.com (172.20.187.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Fri, 28 Aug 2020 01:12:09 +0000 Received: from jckuo-lt.nvidia.com (Not Verified[10.19.101.4]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7, 5, 8, 10121) id ; Thu, 27 Aug 2020 18:12:08 -0700 From: JC Kuo To: , , , , CC: , , , , , JC Kuo Subject: [PATCH 07/12] arm64: tegra210: XUSB PADCTL add "nvidia,pmc" prop Date: Fri, 28 Aug 2020 09:10:51 +0800 Message-ID: <20200828011056.1067559-8-jckuo@nvidia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200828011056.1067559-1-jckuo@nvidia.com> References: <20200828011056.1067559-1-jckuo@nvidia.com> MIME-Version: 1.0 X-NVConfidentiality: public DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1598577119; bh=ULNJL432P9gTH+qGQQEOhfds0zQ9eDoNC9eYcP0k/AM=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:MIME-Version:X-NVConfidentiality: Content-Transfer-Encoding:Content-Type; b=TF6l2YFWFo+kbP7Gy0fnvBNTSIxfbX96sVWoXGOpU3pzBqjOn0+IYYVrJKjmFFsJx 0vlS/i6CzML1vJ0F9jfoD7fH+VbntBEgA1iYYk7yvEBBRM+TKfNvDinfQtPbGDOw7J BaajsNDQZ4gpuIiSJbjyRsH6hEHMkFVsQiFtYy98j06YWPC2KXfeRlRI2xblqxn0sN PTvJC2fiqrXMbG+csZnUPifZx9zeE5bAiNhemSDU+3a3UPFnGwIBEZZlgHsgM4ykpt 2koX/8hnbIlGB06x2m2hI5KRGMml4z3cV6zURnHwW+uFPm6QeRP5SxTrwkFuEP1bKo Mz0fmuiO0ZMTQ== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org PMC driver provides USB sleepwalk registers access to XUSB PADCTL driver. This commit adds a "nvidia,pmc" property which points to PMC node to XUSB PADCTL device node. Signed-off-by: JC Kuo --- arch/arm64/boot/dts/nvidia/tegra210.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index 829f786af133..67c90a0ea32e 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -1040,6 +1040,7 @@ padctl: padctl@7009f000 { reg = <0x0 0x7009f000 0x0 0x1000>; resets = <&tegra_car 142>; reset-names = "padctl"; + nvidia,pmc = <&tegra_pmc>; status = "disabled"; From patchwork Fri Aug 28 01:10:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: JC Kuo X-Patchwork-Id: 258741 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 98D0DC433E2 for ; Fri, 28 Aug 2020 01:12:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 769AA2080C for ; Fri, 28 Aug 2020 01:12:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="PDsM7ei1" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728463AbgH1BMw (ORCPT ); Thu, 27 Aug 2020 21:12:52 -0400 Received: from hqnvemgate26.nvidia.com ([216.228.121.65]:6772 "EHLO hqnvemgate26.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728251AbgH1BMS (ORCPT ); Thu, 27 Aug 2020 21:12:18 -0400 Received: from hqpgpgate102.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate26.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Thu, 27 Aug 2020 18:12:04 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate102.nvidia.com (PGP Universal service); Thu, 27 Aug 2020 18:12:18 -0700 X-PGP-Universal: processed; by hqpgpgate102.nvidia.com on Thu, 27 Aug 2020 18:12:18 -0700 Received: from HQMAIL109.nvidia.com (172.20.187.15) by HQMAIL105.nvidia.com (172.20.187.12) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Fri, 28 Aug 2020 01:12:16 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL109.nvidia.com (172.20.187.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Fri, 28 Aug 2020 01:12:16 +0000 Received: from jckuo-lt.nvidia.com (Not Verified[10.19.101.4]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7, 5, 8, 10121) id ; Thu, 27 Aug 2020 18:12:15 -0700 From: JC Kuo To: , , , , CC: , , , , , JC Kuo Subject: [PATCH 10/12] arm64: tegra210/tegra186/tegra194: XUSB PADCTL irq Date: Fri, 28 Aug 2020 09:10:54 +0800 Message-ID: <20200828011056.1067559-11-jckuo@nvidia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200828011056.1067559-1-jckuo@nvidia.com> References: <20200828011056.1067559-1-jckuo@nvidia.com> MIME-Version: 1.0 X-NVConfidentiality: public DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1598577124; bh=5xHfZPttdwW7Er6d1zUMfgP3rWvN2dNH9BKH/oThNWo=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:MIME-Version:X-NVConfidentiality: Content-Transfer-Encoding:Content-Type; b=PDsM7ei1l8uxxgf63WsYrPojptM5wjoH9ZWvjpUukakuZIXuE8wNWnBbhv/l8GJ1j yWlhR8VOX55VNXLxCSJzuSfbqTpL9Al0WlguVcJdg7yHbhEhvzop4pPZEHpSVVjN2N YI5562sjKcv0oMvZHSQLRdLqnFLjTVfGUIns8251u3t8ywixjS/F4N00/oP1JbwBCB zoRXDFOk3ZX5lGqy+x8veQ29It7mgIi7OYVTsiq4xHVQnHpV8BmnBq69z1Z9cQPRip 4UkWj3IbO+bbKE0gQ8uQo5ygRW4x0D/5i46cYEQEHZd5q48SduYo4lIFim6UrSqkL+ PvbbUipAxx4Eg== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org This commit adds "interrupts" property to Tegra210/Tegra186/Tegra194 XUSB PADCTL node. XUSB PADCTL interrupt will be raised when USB wake event happens. This is required for supporting XUSB host controller ELPG. Signed-off-by: JC Kuo --- arch/arm64/boot/dts/nvidia/tegra186.dtsi | 1 + arch/arm64/boot/dts/nvidia/tegra194.dtsi | 1 + arch/arm64/boot/dts/nvidia/tegra210.dtsi | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 34d249d85da7..454a857e5e56 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -466,6 +466,7 @@ padctl: padctl@3520000 { reg = <0x0 0x03520000 0x0 0x1000>, <0x0 0x03540000 0x0 0x1000>; reg-names = "padctl", "ao"; + interrupts = ; resets = <&bpmp TEGRA186_RESET_XUSB_PADCTL>; reset-names = "padctl"; diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi index 48160f48003a..2b5216a34c06 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi @@ -561,6 +561,7 @@ xusb_padctl: padctl@3520000 { reg = <0x03520000 0x1000>, <0x03540000 0x1000>; reg-names = "padctl", "ao"; + interrupts = ; resets = <&bpmp TEGRA194_RESET_XUSB_PADCTL>; reset-names = "padctl"; diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index 67c90a0ea32e..2ba526779ee5 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -1041,6 +1041,7 @@ padctl: padctl@7009f000 { resets = <&tegra_car 142>; reset-names = "padctl"; nvidia,pmc = <&tegra_pmc>; + interrupts = ; status = "disabled"; From patchwork Fri Aug 28 01:10:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: JC Kuo X-Patchwork-Id: 258743 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79550C433E6 for ; Fri, 28 Aug 2020 01:12:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 510C120848 for ; Fri, 28 Aug 2020 01:12:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="MKmC9O3F" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728397AbgH1BMZ (ORCPT ); Thu, 27 Aug 2020 21:12:25 -0400 Received: from hqnvemgate25.nvidia.com ([216.228.121.64]:15038 "EHLO hqnvemgate25.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728387AbgH1BMY (ORCPT ); Thu, 27 Aug 2020 21:12:24 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate25.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Thu, 27 Aug 2020 18:11:40 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Thu, 27 Aug 2020 18:12:23 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Thu, 27 Aug 2020 18:12:23 -0700 Received: from HQMAIL101.nvidia.com (172.20.187.10) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Fri, 28 Aug 2020 01:12:18 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Fri, 28 Aug 2020 01:12:18 +0000 Received: from jckuo-lt.nvidia.com (Not Verified[10.19.101.4]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7, 5, 8, 10121) id ; Thu, 27 Aug 2020 18:12:18 -0700 From: JC Kuo To: , , , , CC: , , , , , JC Kuo Subject: [PATCH 11/12] usb: host: xhci-tegra: unlink power domain devices Date: Fri, 28 Aug 2020 09:10:55 +0800 Message-ID: <20200828011056.1067559-12-jckuo@nvidia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200828011056.1067559-1-jckuo@nvidia.com> References: <20200828011056.1067559-1-jckuo@nvidia.com> MIME-Version: 1.0 X-NVConfidentiality: public DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1598577100; bh=0CTHi9mIhl9G6jvo2lJZ946QRa9r6dmOL3TNK2XctPQ=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:MIME-Version:X-NVConfidentiality: Content-Transfer-Encoding:Content-Type; b=MKmC9O3FChYVa7LT+0dg7kXTTrJhTd6eBGT7RBJaAj6FiCp+bS9BknFEKyBOuU23r F2+WxBR7+bvysDNF+2ZwDpg3C3AD2DQ5EbIYWB4pRFKNr0jG1g1X6Dq2bNwIJp9EwW DkO/zeaqsXWuv3K50kFBIvNo2e1cOhMpGHMtTXaa36d91zSMNpfn9JNylHxU5WGW+b OzVctFRE9KvNlZkwrhd70ruOjRH2axrUt1Hiry/93i4KiiHXLvtroK+W/uiYkW6TcL 3IJqjkHiY1z0zlCKUfQftCAVw2f0Ob+ZKVlWql7VfJyP7KzuVilH6qRZX6gFflQeLv FPAy0UxQoXgzQ== Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org This commit unlinks xhci-tegra platform device with ss/host power domain devices. Reasons for this change is - at elpg entry, phy sleepwalk and wake configuration need to be done before powering down ss/host partitions, and phy need be powered off after powering down ss/host partitions. Sequence looks like roughly below: tegra_xusb_enter_elpg() -> xhci_suspend() -> enable phy sleepwalk and wake if needed -> power down ss/host partitions -> power down phy If ss/host power domains are linked to xhci-tegra platform device, we are not able to perform the sequence like above. This commit introduces: 1. tegra_xusb_unpowergate_partitions() to power up ss and host partitions together. If ss/host power domain devices are available, it invokes pm_runtime_get_sync() to request power driver to power up partitions; If power domain devices are not available, tegra_powergate_sequence_power_up() will be used to power up partitions. 2. tegra_xusb_powergate_partitions() to power down ss and host partitions together. If ss/host power domain devices are available, it invokes pm_runtime_put_sync() to request power driver to power down partitions; If power domain devices are not available, tegra_powergate_power_off() will be used to power down partitions. Signed-off-by: JC Kuo --- drivers/usb/host/xhci-tegra.c | 202 +++++++++++++++++++--------------- 1 file changed, 111 insertions(+), 91 deletions(-) diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 934be1686352..ce6526c2caf6 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -249,8 +249,6 @@ struct tegra_xusb { struct device *genpd_dev_host; struct device *genpd_dev_ss; - struct device_link *genpd_dl_host; - struct device_link *genpd_dl_ss; struct phy **phys; unsigned int num_phys; @@ -814,36 +812,12 @@ static void tegra_xusb_phy_disable(struct tegra_xusb *tegra) static int tegra_xusb_runtime_suspend(struct device *dev) { - struct tegra_xusb *tegra = dev_get_drvdata(dev); - - regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies); - tegra_xusb_clk_disable(tegra); - return 0; } static int tegra_xusb_runtime_resume(struct device *dev) { - struct tegra_xusb *tegra = dev_get_drvdata(dev); - int err; - - err = tegra_xusb_clk_enable(tegra); - if (err) { - dev_err(dev, "failed to enable clocks: %d\n", err); - return err; - } - - err = regulator_bulk_enable(tegra->soc->num_supplies, tegra->supplies); - if (err) { - dev_err(dev, "failed to enable regulators: %d\n", err); - goto disable_clk; - } - return 0; - -disable_clk: - tegra_xusb_clk_disable(tegra); - return err; } #ifdef CONFIG_PM_SLEEP @@ -1019,10 +993,6 @@ static int tegra_xusb_load_firmware(struct tegra_xusb *tegra) static void tegra_xusb_powerdomain_remove(struct device *dev, struct tegra_xusb *tegra) { - if (tegra->genpd_dl_ss) - device_link_del(tegra->genpd_dl_ss); - if (tegra->genpd_dl_host) - device_link_del(tegra->genpd_dl_host); if (!IS_ERR_OR_NULL(tegra->genpd_dev_ss)) dev_pm_domain_detach(tegra->genpd_dev_ss, true); if (!IS_ERR_OR_NULL(tegra->genpd_dev_host)) @@ -1048,20 +1018,88 @@ static int tegra_xusb_powerdomain_init(struct device *dev, return err; } - tegra->genpd_dl_host = device_link_add(dev, tegra->genpd_dev_host, - DL_FLAG_PM_RUNTIME | - DL_FLAG_STATELESS); - if (!tegra->genpd_dl_host) { - dev_err(dev, "adding host device link failed!\n"); - return -ENODEV; + return 0; +} + +static int tegra_xusb_unpowergate_partitions(struct tegra_xusb *tegra) +{ + struct device *dev = tegra->dev; + bool use_genpd; + int rc; + + use_genpd = of_property_read_bool(dev->of_node, "power-domains"); + + if (use_genpd) { + rc = pm_runtime_get_sync(tegra->genpd_dev_ss); + if (rc < 0) { + dev_err(dev, "failed to enable XUSB SS partition\n"); + return rc; + } + + rc = pm_runtime_get_sync(tegra->genpd_dev_host); + if (rc < 0) { + dev_err(dev, "failed to enable XUSB Host partition\n"); + pm_runtime_put_sync(tegra->genpd_dev_ss); + return rc; + } + } else { + rc = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_XUSBA, + tegra->ss_clk, + tegra->ss_rst); + if (rc < 0) { + dev_err(dev, "failed to enable XUSB SS partition\n"); + return rc; + } + + rc = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_XUSBC, + tegra->host_clk, + tegra->host_rst); + if (rc < 0) { + dev_err(dev, "failed to enable XUSB Host partition\n"); + tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA); + return rc; + } } - tegra->genpd_dl_ss = device_link_add(dev, tegra->genpd_dev_ss, - DL_FLAG_PM_RUNTIME | - DL_FLAG_STATELESS); - if (!tegra->genpd_dl_ss) { - dev_err(dev, "adding superspeed device link failed!\n"); - return -ENODEV; + return 0; +} + +static int tegra_xusb_powergate_partitions(struct tegra_xusb *tegra) +{ + struct device *dev = tegra->dev; + bool use_genpd; + int rc; + + use_genpd = of_property_read_bool(dev->of_node, "power-domains"); + + if (use_genpd) { + rc = pm_runtime_put_sync(tegra->genpd_dev_host); + if (rc < 0) { + dev_err(dev, "failed to disable XUSB Host partition\n"); + return rc; + } + + rc = pm_runtime_put_sync(tegra->genpd_dev_ss); + if (rc < 0) { + dev_err(dev, "failed to disable XUSB SS partition\n"); + pm_runtime_get_sync(tegra->genpd_dev_host); + return rc; + } + } else { + rc = tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC); + if (rc < 0) { + dev_err(dev, "failed to disable XUSB Host partition\n"); + return rc; + } + + rc = tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA); + if (rc < 0) { + dev_err(dev, "failed to disable XUSB SS partition\n"); + tegra_powergate_sequence_power_up(TEGRA_POWERGATE_XUSBC, + tegra->host_clk, + tegra->host_rst); + return rc; + } } return 0; @@ -1425,25 +1463,6 @@ static int tegra_xusb_probe(struct platform_device *pdev) err); goto put_padctl; } - - err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_XUSBA, - tegra->ss_clk, - tegra->ss_rst); - if (err) { - dev_err(&pdev->dev, - "failed to enable XUSBA domain: %d\n", err); - goto put_padctl; - } - - err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_XUSBC, - tegra->host_clk, - tegra->host_rst); - if (err) { - tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA); - dev_err(&pdev->dev, - "failed to enable XUSBC domain: %d\n", err); - goto put_padctl; - } } else { err = tegra_xusb_powerdomain_init(&pdev->dev, tegra); if (err) @@ -1518,10 +1537,22 @@ static int tegra_xusb_probe(struct platform_device *pdev) */ platform_set_drvdata(pdev, tegra); + err = tegra_xusb_clk_enable(tegra); + if (err) { + dev_err(tegra->dev, "failed to enable clocks: %d\n", err); + goto put_hcd; + } + + err = regulator_bulk_enable(tegra->soc->num_supplies, tegra->supplies); + if (err) { + dev_err(tegra->dev, "failed to enable regulators: %d\n", err); + goto disable_clk; + } + err = tegra_xusb_phy_enable(tegra); if (err < 0) { dev_err(&pdev->dev, "failed to enable PHYs: %d\n", err); - goto put_hcd; + goto disable_regulator; } /* @@ -1540,30 +1571,22 @@ static int tegra_xusb_probe(struct platform_device *pdev) goto disable_phy; } - pm_runtime_enable(&pdev->dev); - - if (!pm_runtime_enabled(&pdev->dev)) - err = tegra_xusb_runtime_resume(&pdev->dev); - else - err = pm_runtime_get_sync(&pdev->dev); - - if (err < 0) { - dev_err(&pdev->dev, "failed to enable device: %d\n", err); + err = tegra_xusb_unpowergate_partitions(tegra); + if (err) goto free_firmware; - } tegra_xusb_config(tegra); err = tegra_xusb_load_firmware(tegra); if (err < 0) { dev_err(&pdev->dev, "failed to load firmware: %d\n", err); - goto put_rpm; + goto powergate; } err = usb_add_hcd(tegra->hcd, tegra->xhci_irq, IRQF_SHARED); if (err < 0) { dev_err(&pdev->dev, "failed to add USB HCD: %d\n", err); - goto put_rpm; + goto powergate; } device_wakeup_enable(tegra->hcd->self.controller); @@ -1615,24 +1638,21 @@ static int tegra_xusb_probe(struct platform_device *pdev) usb_put_hcd(xhci->shared_hcd); remove_usb2: usb_remove_hcd(tegra->hcd); -put_rpm: - if (!pm_runtime_status_suspended(&pdev->dev)) - tegra_xusb_runtime_suspend(&pdev->dev); -put_hcd: - usb_put_hcd(tegra->hcd); +powergate: + tegra_xusb_powergate_partitions(tegra); free_firmware: dma_free_coherent(&pdev->dev, tegra->fw.size, tegra->fw.virt, tegra->fw.phys); disable_phy: tegra_xusb_phy_disable(tegra); - pm_runtime_disable(&pdev->dev); +disable_regulator: + regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies); +disable_clk: + tegra_xusb_clk_disable(tegra); +put_hcd: + usb_put_hcd(tegra->hcd); put_powerdomains: - if (!of_property_read_bool(pdev->dev.of_node, "power-domains")) { - tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC); - tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA); - } else { - tegra_xusb_powerdomain_remove(&pdev->dev, tegra); - } + tegra_xusb_powerdomain_remove(&pdev->dev, tegra); put_padctl: tegra_xusb_padctl_put(tegra->padctl); return err; @@ -1657,15 +1677,15 @@ static int tegra_xusb_remove(struct platform_device *pdev) pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); - if (!of_property_read_bool(pdev->dev.of_node, "power-domains")) { - tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC); - tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA); - } else { + tegra_xusb_powergate_partitions(tegra); + + if (of_property_read_bool(pdev->dev.of_node, "power-domains")) { tegra_xusb_powerdomain_remove(&pdev->dev, tegra); } tegra_xusb_phy_disable(tegra); - + tegra_xusb_clk_disable(tegra); + regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies); tegra_xusb_padctl_put(tegra->padctl); return 0;