From patchwork Thu Apr 8 09:44:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12190445 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS 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 9B362C433B4 for ; Thu, 8 Apr 2021 09:44:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 60D0A61154 for ; Thu, 8 Apr 2021 09:44:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231255AbhDHJop (ORCPT ); Thu, 8 Apr 2021 05:44:45 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:37524 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231210AbhDHJoo (ORCPT ); Thu, 8 Apr 2021 05:44:44 -0400 Received: from mailhost.synopsys.com (mdc-mailhost2.synopsys.com [10.225.0.210]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 219394051F; Thu, 8 Apr 2021 09:44:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617875073; bh=0PxDWJIpQtC257oJRHAJSE2XYl24PZfxWI+JLKX2I+E=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=cZE0rCwJNL9sxQeLKmKJYe1NAqziJUH9ofwQ/PK97xzCDHykIqW5sX6sSR0rR0ftb pSb9Wn2pyZ2Px7nlvnsIykNbZd9kTWGUpgryn7zpbyw8x6ZKikuu5j5LyBeV+xUR4/ zZ4wXqVy1POatUr2dTBoZYf+cTBo+lBcvEi1UgmJNpV+m1Hvz22UnSXvqVusCQzqJO zO0EBDRVAQzYmOnY2Rx7C/RItst6e0NV2fE533shgvDaek6iB556Am7OsVrdZGtTjj wN0d+MdbE76MY1I9bx9KgeIuA+xlVpGG1LZTHjFME5BAmHA9UAvYlbejAfOyiN/1z/ ODXW/KXKejZQA== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 383B9A0094; Thu, 8 Apr 2021 09:44:30 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Thu, 08 Apr 2021 13:44:29 +0400 Date: Thu, 08 Apr 2021 13:44:29 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v3 01/14] usb: dwc2: Add device partial power down functions To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: John Youn , Artur Petrosyan , Minas Harutyunyan Message-Id: <20210408094430.383B9A0094@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org For device mode Partial Power Down entering and exiting separate functions are needed to implement the logic. Earlier the logic was implemented in one function. Which was confusing the readability. Also both host and device implementations were in the same function. - Added device partial power down functions which must be called by dwc2_enter_partial_power_down()/dwc2_exit_partial_power_down() functions. - Added "in_ppd" flag in "dwc2_hsotg" struct to indicate the core state after entering into partial power down mode. Added function names: dwc2_gadget_enter_partial_power_down() dwc2_gadget_exit_partial_power_down() NOTE: There is a checkpatch "CHECK" warning on "udelay(100)". The delay is needed to properly exit gadget Partial Power Down A delay less than 100 doesn't work. Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- drivers/usb/dwc2/core.h | 10 +++ drivers/usb/dwc2/gadget.c | 128 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index d0ebe721fb98..ed54d834138d 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -865,6 +865,7 @@ struct dwc2_hregs_backup { * @gadget_enabled: Peripheral mode sub-driver initialization indicator. * @ll_hw_enabled: Status of low-level hardware resources. * @hibernated: True if core is hibernated + * @in_ppd: True if core is partial power down mode. * @reset_phy_on_wake: Quirk saying that we should assert PHY reset on a * remote wakeup. * @phy_off_for_suspend: Status of whether we turned the PHY off at suspend. @@ -1060,6 +1061,7 @@ struct dwc2_hsotg { unsigned int gadget_enabled:1; unsigned int ll_hw_enabled:1; unsigned int hibernated:1; + unsigned int in_ppd:1; unsigned int reset_phy_on_wake:1; unsigned int need_phy_for_wake:1; unsigned int phy_off_for_suspend:1; @@ -1409,6 +1411,9 @@ int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, int remote_wakeup); int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg); int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup, int reset); +int dwc2_gadget_enter_partial_power_down(struct dwc2_hsotg *hsotg); +int dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg, + bool restore); int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg); int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg); int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg); @@ -1442,6 +1447,11 @@ static inline int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg) static inline int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup, int reset) { return 0; } +static inline int dwc2_gadget_enter_partial_power_down(struct dwc2_hsotg *hsotg) +{ return 0; } +static inline int dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg, + bool restore) +{ return 0; } static inline int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg) { return 0; } static inline int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index ad4c94366dad..98a2a63c67ae 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -5351,3 +5351,131 @@ int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg, return ret; } + +/** + * dwc2_gadget_enter_partial_power_down() - Put controller in partial + * power down. + * + * @hsotg: Programming view of the DWC_otg controller + * + * Return: non-zero if failed to enter device partial power down. + * + * This function is for entering device mode partial power down. + */ +int dwc2_gadget_enter_partial_power_down(struct dwc2_hsotg *hsotg) +{ + u32 pcgcctl; + int ret = 0; + + dev_dbg(hsotg->dev, "Entering device partial power down started.\n"); + + /* Backup all registers */ + ret = dwc2_backup_global_registers(hsotg); + if (ret) { + dev_err(hsotg->dev, "%s: failed to backup global registers\n", + __func__); + return ret; + } + + ret = dwc2_backup_device_registers(hsotg); + if (ret) { + dev_err(hsotg->dev, "%s: failed to backup device registers\n", + __func__); + return ret; + } + + /* + * Clear any pending interrupts since dwc2 will not be able to + * clear them after entering partial_power_down. + */ + dwc2_writel(hsotg, 0xffffffff, GINTSTS); + + /* Put the controller in low power state */ + pcgcctl = dwc2_readl(hsotg, PCGCTL); + + pcgcctl |= PCGCTL_PWRCLMP; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + udelay(5); + + pcgcctl |= PCGCTL_RSTPDWNMODULE; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + udelay(5); + + pcgcctl |= PCGCTL_STOPPCLK; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + + /* Set in_ppd flag to 1 as here core enters suspend. */ + hsotg->in_ppd = 1; + hsotg->lx_state = DWC2_L2; + + dev_dbg(hsotg->dev, "Entering device partial power down completed.\n"); + + return ret; +} + +/* + * dwc2_gadget_exit_partial_power_down() - Exit controller from device partial + * power down. + * + * @hsotg: Programming view of the DWC_otg controller + * @restore: indicates whether need to restore the registers or not. + * + * Return: non-zero if failed to exit device partial power down. + * + * This function is for exiting from device mode partial power down. + */ +int dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg, + bool restore) +{ + u32 pcgcctl; + u32 dctl; + struct dwc2_dregs_backup *dr; + int ret = 0; + + dr = &hsotg->dr_backup; + + dev_dbg(hsotg->dev, "Exiting device partial Power Down started.\n"); + + pcgcctl = dwc2_readl(hsotg, PCGCTL); + pcgcctl &= ~PCGCTL_STOPPCLK; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + + pcgcctl = dwc2_readl(hsotg, PCGCTL); + pcgcctl &= ~PCGCTL_PWRCLMP; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + + pcgcctl = dwc2_readl(hsotg, PCGCTL); + pcgcctl &= ~PCGCTL_RSTPDWNMODULE; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + + udelay(100); + if (restore) { + ret = dwc2_restore_global_registers(hsotg); + if (ret) { + dev_err(hsotg->dev, "%s: failed to restore registers\n", + __func__); + return ret; + } + /* Restore DCFG */ + dwc2_writel(hsotg, dr->dcfg, DCFG); + + ret = dwc2_restore_device_registers(hsotg, 0); + if (ret) { + dev_err(hsotg->dev, "%s: failed to restore device registers\n", + __func__); + return ret; + } + } + + /* Set the Power-On Programming done bit */ + dctl = dwc2_readl(hsotg, DCTL); + dctl |= DCTL_PWRONPRGDONE; + dwc2_writel(hsotg, dctl, DCTL); + + /* Set in_ppd flag to 0 as here core exits from suspend. */ + hsotg->in_ppd = 0; + hsotg->lx_state = DWC2_L0; + + dev_dbg(hsotg->dev, "Exiting device partial Power Down completed.\n"); + return ret; +} From patchwork Thu Apr 8 09:44:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12190447 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS 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 612CAC433ED for ; Thu, 8 Apr 2021 09:44:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3AE1161155 for ; Thu, 8 Apr 2021 09:44:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231305AbhDHJow (ORCPT ); Thu, 8 Apr 2021 05:44:52 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:36552 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231269AbhDHJow (ORCPT ); Thu, 8 Apr 2021 05:44:52 -0400 Received: from mailhost.synopsys.com (mdc-mailhost1.synopsys.com [10.225.0.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 7DBC8C09BA; Thu, 8 Apr 2021 09:44:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617875081; bh=u6F+fXW2qz+tbASMRsPqsckjpuRhyQDO1KmGr9q5n0M=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=Z3oES2lMqcLJpVaMIb37jCZmSx2FT12Zr1DNgxixE5PUaDHqq8UT3d90TTaB3kOnh rBSk30Z4dUycVv9oh5mJ4aj8BC50FwWUwKOKKe3Xw6xoQ63hKDACOxFKgGlwr8bzzU KRb95Wr3Vis7kRXxvf97Dy3u6KYjH6mf51DQpp4wAlthoO+Lt8ED3/UT3oZdgR2xxf aOxSHLfi080bXACQv2WHrJVJREOsuO3vQRuOFOTn+5E7mJJfocywiTOA+x+NRUc9vz DWrIk0DZ32+6gXexcWHYNvwIyJVEnQFkAlmtlFX6hF6tU8UtRbaU3v1pDVU/80LRMb EuxLZX5AbMqbQ== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 56CFBA022E; Thu, 8 Apr 2021 09:44:38 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Thu, 08 Apr 2021 13:44:37 +0400 Date: Thu, 08 Apr 2021 13:44:37 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v3 02/14] usb: dwc2: Add host partial power down functions To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: John Youn , Artur Petrosyan , Minas Harutyunyan Message-Id: <20210408094438.56CFBA022E@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org For host mode Partial Power Down entering and exiting separate functions are needed to implement the logic. Earlier the logic was implemented in one function. Which was confusing the readability. Also both host and device implementations were in the same function. - Added host partial power down functions which must be called by dwc2_enter_partial_power_down()/dwc2_exit_partial_power_down() functions. Added function names: dwc2_host_enter_partial_power_down() dwc2_host_exit_partial_power_down() NOTE: There is a checkpatch "CHECK" warning on "udelay(100)". The delay is needed to properly exit gadget Partial Power Down A delay less than 100 doesn't work. Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- drivers/usb/dwc2/core.h | 8 ++ drivers/usb/dwc2/hcd.c | 160 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index ed54d834138d..1a97df8bf5cb 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -1474,6 +1474,9 @@ int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg); int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg); int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup, int reset); +int dwc2_host_enter_partial_power_down(struct dwc2_hsotg *hsotg); +int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg, + int rem_wakeup, bool restore); bool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2); static inline void dwc2_host_schedule_phy_reset(struct dwc2_hsotg *hsotg) { schedule_work(&hsotg->phy_reset_work); } @@ -1500,6 +1503,11 @@ static inline int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg) static inline int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup, int reset) { return 0; } +static inline int dwc2_host_enter_partial_power_down(struct dwc2_hsotg *hsotg) +{ return 0; } +static inline int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg, + int rem_wakeup, bool restore) +{ return 0; } static inline bool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2) { return false; } static inline void dwc2_host_schedule_phy_reset(struct dwc2_hsotg *hsotg) {} diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 1a9789ec5847..35e617be4bc3 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -5607,3 +5607,163 @@ bool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2) /* No reason to keep the PHY powered, so allow poweroff */ return true; } + +/** + * dwc2_host_enter_partial_power_down() - Put controller in partial + * power down. + * + * @hsotg: Programming view of the DWC_otg controller + * + * Return: non-zero if failed to enter host partial power down. + * + * This function is for entering Host mode partial power down. + */ +int dwc2_host_enter_partial_power_down(struct dwc2_hsotg *hsotg) +{ + u32 pcgcctl; + u32 hprt0; + int ret = 0; + + dev_dbg(hsotg->dev, "Entering host partial power down started.\n"); + + /* Put this port in suspend mode. */ + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_SUSP; + dwc2_writel(hsotg, hprt0, HPRT0); + udelay(5); + + /* Wait for the HPRT0.PrtSusp register field to be set */ + if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 3000)) + dev_warn(hsotg->dev, "Suspend wasn't generated\n"); + + /* Backup all registers */ + ret = dwc2_backup_global_registers(hsotg); + if (ret) { + dev_err(hsotg->dev, "%s: failed to backup global registers\n", + __func__); + return ret; + } + + ret = dwc2_backup_host_registers(hsotg); + if (ret) { + dev_err(hsotg->dev, "%s: failed to backup host registers\n", + __func__); + return ret; + } + + /* + * Clear any pending interrupts since dwc2 will not be able to + * clear them after entering partial_power_down. + */ + dwc2_writel(hsotg, 0xffffffff, GINTSTS); + + /* Put the controller in low power state */ + pcgcctl = dwc2_readl(hsotg, PCGCTL); + + pcgcctl |= PCGCTL_PWRCLMP; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + udelay(5); + + pcgcctl |= PCGCTL_RSTPDWNMODULE; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + udelay(5); + + pcgcctl |= PCGCTL_STOPPCLK; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + + /* Set in_ppd flag to 1 as here core enters suspend. */ + hsotg->in_ppd = 1; + hsotg->lx_state = DWC2_L2; + hsotg->bus_suspended = true; + + dev_dbg(hsotg->dev, "Entering host partial power down completed.\n"); + + return ret; +} + +/* + * dwc2_host_exit_partial_power_down() - Exit controller from host partial + * power down. + * + * @hsotg: Programming view of the DWC_otg controller + * @rem_wakeup: indicates whether resume is initiated by Reset. + * @restore: indicates whether need to restore the registers or not. + * + * Return: non-zero if failed to exit host partial power down. + * + * This function is for exiting from Host mode partial power down. + */ +int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg, + int rem_wakeup, bool restore) +{ + u32 pcgcctl; + int ret = 0; + u32 hprt0; + + dev_dbg(hsotg->dev, "Exiting host partial power down started.\n"); + + pcgcctl = dwc2_readl(hsotg, PCGCTL); + pcgcctl &= ~PCGCTL_STOPPCLK; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + udelay(5); + + pcgcctl = dwc2_readl(hsotg, PCGCTL); + pcgcctl &= ~PCGCTL_PWRCLMP; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + udelay(5); + + pcgcctl = dwc2_readl(hsotg, PCGCTL); + pcgcctl &= ~PCGCTL_RSTPDWNMODULE; + dwc2_writel(hsotg, pcgcctl, PCGCTL); + + udelay(100); + if (restore) { + ret = dwc2_restore_global_registers(hsotg); + if (ret) { + dev_err(hsotg->dev, "%s: failed to restore registers\n", + __func__); + return ret; + } + + ret = dwc2_restore_host_registers(hsotg); + if (ret) { + dev_err(hsotg->dev, "%s: failed to restore host registers\n", + __func__); + return ret; + } + } + + /* Drive resume signaling and exit suspend mode on the port. */ + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_RES; + hprt0 &= ~HPRT0_SUSP; + dwc2_writel(hsotg, hprt0, HPRT0); + udelay(5); + + if (!rem_wakeup) { + /* Stop driveing resume signaling on the port. */ + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 &= ~HPRT0_RES; + dwc2_writel(hsotg, hprt0, HPRT0); + + hsotg->bus_suspended = false; + } else { + /* Turn on the port power bit. */ + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_PWR; + dwc2_writel(hsotg, hprt0, HPRT0); + + /* Connect hcd. */ + dwc2_hcd_connect(hsotg); + + mod_timer(&hsotg->wkp_timer, + jiffies + msecs_to_jiffies(71)); + } + + /* Set lx_state to and in_ppd to 0 as here core exits from suspend. */ + hsotg->in_ppd = 0; + hsotg->lx_state = DWC2_L0; + + dev_dbg(hsotg->dev, "Exiting host partial power down completed.\n"); + return ret; +} From patchwork Thu Apr 8 09:44:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12190449 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS 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 D3058C433B4 for ; Thu, 8 Apr 2021 09:44:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B2AC061041 for ; Thu, 8 Apr 2021 09:44:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229686AbhDHJpB (ORCPT ); Thu, 8 Apr 2021 05:45:01 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:36564 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231269AbhDHJpA (ORCPT ); Thu, 8 Apr 2021 05:45:00 -0400 Received: from mailhost.synopsys.com (mdc-mailhost1.synopsys.com [10.225.0.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 55C23C09B1; Thu, 8 Apr 2021 09:44:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617875089; bh=WzuyIoK/ht3m7Z4eAuhGfdS7mckRrxq8N1eY7NCgEtM=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=hDhxJ6PmsUNjyMz4KW/RHcagl8a82HSTNRuzU2dNr9h1B7qcFP4WTgggpTIF12GKh NS0UraeU2nTVcnaJMTaaVsl7gtcpXvF1z4Wq3mu+CidUEdjtYFRQb5RH8SVUxipC0b W0zg6vvmuGWSYizXsfOnWINRIt/XaHTVgz2eEdEGHX3M90dAf2y6Sqa/jWUKeuBguH CkRv+tmSRu561mooT4ECeeaSd7HG2eXHO1SF4Sg+SrpU51ZkPG+qhB9EfTtFe1aQKt whruheuRYkGUjvdr385RvEkpNWv8dOeuvGaNG3CSbgyJnJs5SAJuPtwi140ojM0AWB nWqMciEmeSemQ== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 6491BA022E; Thu, 8 Apr 2021 09:44:46 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Thu, 08 Apr 2021 13:44:45 +0400 Date: Thu, 08 Apr 2021 13:44:45 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v3 03/14] usb: dwc2: Update enter and exit partial power down functions To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: John Youn , Artur Petrosyan , Minas Harutyunyan Message-Id: <20210408094446.6491BA022E@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org These are wrapper functions which are calling device or host enter/exit partial power down functions. This change is done because we need to separate device and host partial power down functions as the programming flow has a lot of difference between host and device. With this update during partial power down exit driver relies on backup value of "GOTGCTL_CURMODE_HOST" to determine the mode of core before entering to PPD. Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- drivers/usb/dwc2/core.c | 113 ++++++----------------------------- drivers/usb/dwc2/core.h | 3 +- drivers/usb/dwc2/core_intr.c | 21 ++++--- drivers/usb/dwc2/gadget.c | 20 ++++--- drivers/usb/dwc2/hcd.c | 2 +- drivers/usb/dwc2/hw.h | 1 + 6 files changed, 45 insertions(+), 115 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index fec17a2d2447..cb65f7f60573 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -131,54 +131,26 @@ int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg) * dwc2_exit_partial_power_down() - Exit controller from Partial Power Down. * * @hsotg: Programming view of the DWC_otg controller + * @rem_wakeup: indicates whether resume is initiated by Reset. * @restore: Controller registers need to be restored */ -int dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, bool restore) +int dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, int rem_wakeup, + bool restore) { - u32 pcgcctl; - int ret = 0; - - if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL) - return -ENOTSUPP; - - pcgcctl = dwc2_readl(hsotg, PCGCTL); - pcgcctl &= ~PCGCTL_STOPPCLK; - dwc2_writel(hsotg, pcgcctl, PCGCTL); - - pcgcctl = dwc2_readl(hsotg, PCGCTL); - pcgcctl &= ~PCGCTL_PWRCLMP; - dwc2_writel(hsotg, pcgcctl, PCGCTL); - - pcgcctl = dwc2_readl(hsotg, PCGCTL); - pcgcctl &= ~PCGCTL_RSTPDWNMODULE; - dwc2_writel(hsotg, pcgcctl, PCGCTL); + struct dwc2_gregs_backup *gr; - udelay(100); - if (restore) { - ret = dwc2_restore_global_registers(hsotg); - if (ret) { - dev_err(hsotg->dev, "%s: failed to restore registers\n", - __func__); - return ret; - } - if (dwc2_is_host_mode(hsotg)) { - ret = dwc2_restore_host_registers(hsotg); - if (ret) { - dev_err(hsotg->dev, "%s: failed to restore host registers\n", - __func__); - return ret; - } - } else { - ret = dwc2_restore_device_registers(hsotg, 0); - if (ret) { - dev_err(hsotg->dev, "%s: failed to restore device registers\n", - __func__); - return ret; - } - } - } + gr = &hsotg->gr_backup; - return ret; + /* + * Restore host or device regisers with the same mode core enterted + * to partial power down by checking "GOTGCTL_CURMODE_HOST" backup + * value of the "gotgctl" register. + */ + if (gr->gotgctl & GOTGCTL_CURMODE_HOST) + return dwc2_host_exit_partial_power_down(hsotg, rem_wakeup, + restore); + else + return dwc2_gadget_exit_partial_power_down(hsotg, restore); } /** @@ -188,57 +160,10 @@ int dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, bool restore) */ int dwc2_enter_partial_power_down(struct dwc2_hsotg *hsotg) { - u32 pcgcctl; - int ret = 0; - - if (!hsotg->params.power_down) - return -ENOTSUPP; - - /* Backup all registers */ - ret = dwc2_backup_global_registers(hsotg); - if (ret) { - dev_err(hsotg->dev, "%s: failed to backup global registers\n", - __func__); - return ret; - } - - if (dwc2_is_host_mode(hsotg)) { - ret = dwc2_backup_host_registers(hsotg); - if (ret) { - dev_err(hsotg->dev, "%s: failed to backup host registers\n", - __func__); - return ret; - } - } else { - ret = dwc2_backup_device_registers(hsotg); - if (ret) { - dev_err(hsotg->dev, "%s: failed to backup device registers\n", - __func__); - return ret; - } - } - - /* - * Clear any pending interrupts since dwc2 will not be able to - * clear them after entering partial_power_down. - */ - dwc2_writel(hsotg, 0xffffffff, GINTSTS); - - /* Put the controller in low power state */ - pcgcctl = dwc2_readl(hsotg, PCGCTL); - - pcgcctl |= PCGCTL_PWRCLMP; - dwc2_writel(hsotg, pcgcctl, PCGCTL); - ndelay(20); - - pcgcctl |= PCGCTL_RSTPDWNMODULE; - dwc2_writel(hsotg, pcgcctl, PCGCTL); - ndelay(20); - - pcgcctl |= PCGCTL_STOPPCLK; - dwc2_writel(hsotg, pcgcctl, PCGCTL); - - return ret; + if (dwc2_is_host_mode(hsotg)) + return dwc2_host_enter_partial_power_down(hsotg); + else + return dwc2_gadget_enter_partial_power_down(hsotg); } /** diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 1a97df8bf5cb..39037709a2ad 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -1303,7 +1303,8 @@ static inline bool dwc2_is_hs_iot(struct dwc2_hsotg *hsotg) */ int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait); int dwc2_enter_partial_power_down(struct dwc2_hsotg *hsotg); -int dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, bool restore); +int dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, int rem_wakeup, + bool restore); int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg, int is_host); int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup, int reset, int is_host); diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 55f1d14fc414..1fb957ce6c25 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -315,9 +315,10 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) hsotg->lx_state); if (dwc2_is_device_mode(hsotg)) { - if (hsotg->lx_state == DWC2_L2) { - ret = dwc2_exit_partial_power_down(hsotg, true); - if (ret && (ret != -ENOTSUPP)) + if (hsotg->lx_state == DWC2_L2 && hsotg->in_ppd) { + ret = dwc2_exit_partial_power_down(hsotg, 0, + true); + if (ret) dev_err(hsotg->dev, "exit power_down failed\n"); } @@ -406,18 +407,16 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) if (dwc2_is_device_mode(hsotg)) { dev_dbg(hsotg->dev, "DSTS=0x%0x\n", dwc2_readl(hsotg, DSTS)); - if (hsotg->lx_state == DWC2_L2) { + if (hsotg->lx_state == DWC2_L2 && hsotg->in_ppd) { u32 dctl = dwc2_readl(hsotg, DCTL); - /* Clear Remote Wakeup Signaling */ dctl &= ~DCTL_RMTWKUPSIG; dwc2_writel(hsotg, dctl, DCTL); - ret = dwc2_exit_partial_power_down(hsotg, true); - if (ret && (ret != -ENOTSUPP)) - dev_err(hsotg->dev, "exit power_down failed\n"); - - /* Change to L0 state */ - hsotg->lx_state = DWC2_L0; + ret = dwc2_exit_partial_power_down(hsotg, 1, + true); + if (ret) + dev_err(hsotg->dev, + "exit partial_power_down failed\n"); call_gadget(hsotg, resume); } else { /* Change to L0 state */ diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 98a2a63c67ae..e08baee4987b 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3689,10 +3689,10 @@ static irqreturn_t dwc2_hsotg_irq(int irq, void *pw) dwc2_writel(hsotg, GINTSTS_RESETDET, GINTSTS); /* This event must be used only if controller is suspended */ - if (hsotg->lx_state == DWC2_L2) { - dwc2_exit_partial_power_down(hsotg, true); - hsotg->lx_state = DWC2_L0; - } + if (hsotg->in_ppd && hsotg->lx_state == DWC2_L2) + dwc2_exit_partial_power_down(hsotg, 0, true); + + hsotg->lx_state = DWC2_L0; } if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) { @@ -4615,11 +4615,15 @@ static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) spin_lock_irqsave(&hsotg->lock, flags); /* - * If controller is hibernated, it must exit from power_down - * before being initialized / de-initialized + * If controller is in partial power down state, it must exit from + * that state before being initialized / de-initialized */ - if (hsotg->lx_state == DWC2_L2) - dwc2_exit_partial_power_down(hsotg, false); + if (hsotg->lx_state == DWC2_L2 && hsotg->in_ppd) + /* + * No need to check the return value as + * registers are not being restored. + */ + dwc2_exit_partial_power_down(hsotg, 0, false); if (is_active) { hsotg->op_state = OTG_STATE_B_PERIPHERAL; diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 35e617be4bc3..dd0362e07444 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -4418,7 +4418,7 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) /* Exit partial_power_down */ - ret = dwc2_exit_partial_power_down(hsotg, true); + ret = dwc2_exit_partial_power_down(hsotg, 0, true); if (ret && (ret != -ENOTSUPP)) dev_err(hsotg->dev, "exit partial_power_down failed\n"); } else { diff --git a/drivers/usb/dwc2/hw.h b/drivers/usb/dwc2/hw.h index c3d6dde2aca4..6b16fbf98bc6 100644 --- a/drivers/usb/dwc2/hw.h +++ b/drivers/usb/dwc2/hw.h @@ -44,6 +44,7 @@ #define GOTGCTL_CHIRPEN BIT(27) #define GOTGCTL_MULT_VALID_BC_MASK (0x1f << 22) #define GOTGCTL_MULT_VALID_BC_SHIFT 22 +#define GOTGCTL_CURMODE_HOST BIT(21) #define GOTGCTL_OTGVER BIT(20) #define GOTGCTL_BSESVLD BIT(19) #define GOTGCTL_ASESVLD BIT(18) From patchwork Thu Apr 8 09:44:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12190451 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS 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 07C4CC433ED for ; Thu, 8 Apr 2021 09:45:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C5356610A6 for ; Thu, 8 Apr 2021 09:45:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231380AbhDHJpP (ORCPT ); Thu, 8 Apr 2021 05:45:15 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:37546 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231358AbhDHJpJ (ORCPT ); Thu, 8 Apr 2021 05:45:09 -0400 Received: from mailhost.synopsys.com (mdc-mailhost2.synopsys.com [10.225.0.210]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 3D02540829; Thu, 8 Apr 2021 09:44:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617875097; bh=Gd6RpJYfHcJtTprhTBHDNtSWQfOmDM4ekWqCTpUJyiw=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=MVI+lX+aeluFNiHFgHK+ZIfFPaUReoDY9IO//B7JPIcG4o7awS7DNmWuB4g4rp38a b5t2zjxex9k1fy3GPFGADwZCMB5CBDGBEME8Mh/pFHVh40VUZywCon0xtyiNdAHKMd okYyY6u0u6+lAX8FPzwGAnHQjplYH3oq9/dOEQBWwKBI4p2Nly0W1K0Q32F5Rgedwb XwcZrCTOJSpLuv9noTRkyKF0+yUTzOz+nX2ygoD7gY8c+o8CQ6hph4xYn3teq9EjfD ++q4vssFHh8Lq7MmEGJVPuD4yyMhVOGkMoQ34wWYdli5Z0J1m5IFvfyPlQwCqZ7dr8 GE/OocWAvHAeQ== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 5BBCBA0094; Thu, 8 Apr 2021 09:44:54 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Thu, 08 Apr 2021 13:44:53 +0400 Date: Thu, 08 Apr 2021 13:44:53 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v3 04/14] usb: dwc2: Add partial power down exit flow in wakeup intr. To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: John Youn , Artur Petrosyan , Minas Harutyunyan Message-Id: <20210408094454.5BBCBA0094@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org According to programming guide added host partial power down exit flow in wakeup detected interrupt handler. Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- drivers/usb/dwc2/core_intr.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 1fb957ce6c25..0a7f9330907f 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -423,15 +423,14 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) hsotg->lx_state = DWC2_L0; } } else { - if (hsotg->params.power_down) - return; - - if (hsotg->lx_state != DWC2_L1) { - u32 pcgcctl = dwc2_readl(hsotg, PCGCTL); - - /* Restart the Phy Clock */ - pcgcctl &= ~PCGCTL_STOPPCLK; - dwc2_writel(hsotg, pcgcctl, PCGCTL); + if (hsotg->lx_state == DWC2_L2) { + if (hsotg->in_ppd) { + ret = dwc2_exit_partial_power_down(hsotg, 1, + true); + if (ret) + dev_err(hsotg->dev, + "exit partial_power_down failed\n"); + } /* * If we've got this quirk then the PHY is stuck upon From patchwork Thu Apr 8 09:45:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12190453 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS 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 40ADFC43461 for ; Thu, 8 Apr 2021 09:45:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0FECD610A6 for ; Thu, 8 Apr 2021 09:45:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231383AbhDHJpT (ORCPT ); Thu, 8 Apr 2021 05:45:19 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:36578 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231341AbhDHJpQ (ORCPT ); Thu, 8 Apr 2021 05:45:16 -0400 Received: from mailhost.synopsys.com (mdc-mailhost1.synopsys.com [10.225.0.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 5FF00C09B1; Thu, 8 Apr 2021 09:45:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617875105; bh=E+igUESaPhpjVDVosLwHHiXN8svhMPcuxQoNubRH1OU=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=dp7VQazFb1G5qk8dvpvKujIjq90JhZNaRG8t6/mnQRQWwd/Ki5ZpRRmh6CQH1Ed4t xIxOJjjpTh0qOM8cyCThQvoXqGcocxKnq8xxjAbOT67L7IPedyE7Kz7hpf3Dvzx2bA emyEOi5NSDsDNOaeMlaY/GesUYwuh5aLFcSKb+CLY4yta+0GBBCcH3UANDjl0qo7b1 11IgA8iaWRWthUVtdHkYnCk+wqDmKew3ziT9F/Ixi3JqxmrhmxVHR+MiP6N+SoiKmI JYEaPqwT0xl+D6wICQMpr3SzaIDjIcr/f3UhhjVg6hkv3l9aBumglyYJ6u8s3VjCLZ /gzsZHqnrxZwA== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 61D18A0232; Thu, 8 Apr 2021 09:45:02 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Thu, 08 Apr 2021 13:45:01 +0400 Date: Thu, 08 Apr 2021 13:45:01 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v3 05/14] usb: dwc2: Update port suspend/resume function definitions. To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: John Youn , Artur Petrosyan Message-Id: <20210408094502.61D18A0232@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Earlier "dwc2_port_suspend()" and "dwc2_port_resume()" functions were implemented without proper description and host or device mode difference. - Added "dwc2_port_suspend" and "dwc2_port_resume" functions to "core.h" header file. - Updated function description in documentation. Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- Changes in v3: - None Changes in v2: - None drivers/usb/dwc2/core.h | 4 ++++ drivers/usb/dwc2/hcd.c | 25 +++++++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 39037709a2ad..b7d99cf9e84c 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -1470,6 +1470,8 @@ void dwc2_hcd_connect(struct dwc2_hsotg *hsotg); void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force); void dwc2_hcd_start(struct dwc2_hsotg *hsotg); int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup); +void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex); +void dwc2_port_resume(struct dwc2_hsotg *hsotg); int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg); int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg); int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg); @@ -1493,6 +1495,8 @@ static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} static inline int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup) { return 0; } +static inline void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) {} +static inline void dwc2_port_resume(struct dwc2_hsotg *hsotg) {} static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg) { return 0; } static inline int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index dd0362e07444..f4247a66c2b2 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -56,8 +56,6 @@ #include "core.h" #include "hcd.h" -static void dwc2_port_resume(struct dwc2_hsotg *hsotg); - /* * ========================================================================= * Host Core Layer Functions @@ -3277,8 +3275,16 @@ static int dwc2_host_is_b_hnp_enabled(struct dwc2_hsotg *hsotg) return hcd->self.b_hnp_enable; } -/* Must NOT be called with interrupt disabled or spinlock held */ -static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) +/** + * dwc2_port_suspend() - Put controller in suspend mode for host. + * + * @hsotg: Programming view of the DWC_otg controller + * @windex: The control request wIndex field + * + * This function is for entering Host mode suspend. + * Must NOT be called with interrupt disabled or spinlock held. + */ +void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) { unsigned long flags; u32 hprt0; @@ -3328,8 +3334,15 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) } } -/* Must NOT be called with interrupt disabled or spinlock held */ -static void dwc2_port_resume(struct dwc2_hsotg *hsotg) +/** + * dwc2_port_resume() - Exit controller from suspend mode for host. + * + * @hsotg: Programming view of the DWC_otg controller + * + * This function is for exiting Host mode suspend. + * Must NOT be called with interrupt disabled or spinlock held. + */ +void dwc2_port_resume(struct dwc2_hsotg *hsotg) { unsigned long flags; u32 hprt0; From patchwork Thu Apr 8 09:45:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12190455 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS 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 5B4FEC433B4 for ; Thu, 8 Apr 2021 09:45:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 31441610A6 for ; Thu, 8 Apr 2021 09:45:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231422AbhDHJpe (ORCPT ); Thu, 8 Apr 2021 05:45:34 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:37576 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231341AbhDHJpY (ORCPT ); Thu, 8 Apr 2021 05:45:24 -0400 Received: from mailhost.synopsys.com (mdc-mailhost1.synopsys.com [10.225.0.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 675344051F; Thu, 8 Apr 2021 09:45:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617875113; bh=2ECs4iyrkEFhuwCrAjvTGLneI7YBEwV7A8GEtnwY84M=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=MhSR6MjnZutKtP/6AnC+2zFeZFsU5Yp0uLsDdJGhTrlxg5vXuvVMP9UofhEbA6Y30 sB9oJQHBlgl4hyZj6U1U7PvFexDGl4zHc0Lcu2ZsmtS3V7V7NrX2OXEUnV8T+73WLH Thp9n7oi8Sf9+qZx0q3Rl6MbnPdLI+aPhDMeKANUh3E1KwoElXOtCshYERDQzjaTpw //fZJZj8fZMQOeQc52YGwVGiyJEQ0x3pfJTkOw7xwCd7kEcDWEbqVIQ2oAEDRz94wA QOI+rd3z6aGXUyH3ckPkMNzIiMJgOcfkdSlB7+7F0xvLyn+UWHsEaDz6RvRpobe3kv lq73JdlBE7+Dg== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 6C4E9A022E; Thu, 8 Apr 2021 09:45:10 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Thu, 08 Apr 2021 13:45:09 +0400 Date: Thu, 08 Apr 2021 13:45:09 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v3 06/14] usb: dwc2: Add enter partial power down when port is suspended To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: John Youn , Artur Petrosyan Message-Id: <20210408094510.6C4E9A022E@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Adds flow of entering Partial Power Down in "dwc2_port_suspend()" function when core receives suspend. NOTE: Switch case statement is used for hibernation partial power down and clock gating mode determination. In this patch only Partial Power Down is implemented the Hibernation and clock gating implementations are planned to be added. Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- Changes in v3: - None Changes in v2: - None drivers/usb/dwc2/core.h | 5 +++-- drivers/usb/dwc2/hcd.c | 48 ++++++++++++++++++++++++++--------------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index b7d99cf9e84c..76807abd753b 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -1470,7 +1470,7 @@ void dwc2_hcd_connect(struct dwc2_hsotg *hsotg); void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force); void dwc2_hcd_start(struct dwc2_hsotg *hsotg); int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup); -void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex); +int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex); void dwc2_port_resume(struct dwc2_hsotg *hsotg); int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg); int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg); @@ -1495,7 +1495,8 @@ static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {} static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {} static inline int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup) { return 0; } -static inline void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) {} +static inline int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) +{ return 0; } static inline void dwc2_port_resume(struct dwc2_hsotg *hsotg) {} static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg) { return 0; } diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index f4247a66c2b2..e7fb0d5940bc 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -3281,15 +3281,18 @@ static int dwc2_host_is_b_hnp_enabled(struct dwc2_hsotg *hsotg) * @hsotg: Programming view of the DWC_otg controller * @windex: The control request wIndex field * + * Return: non-zero if failed to enter suspend mode for host. + * * This function is for entering Host mode suspend. * Must NOT be called with interrupt disabled or spinlock held. */ -void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) +int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) { unsigned long flags; u32 hprt0; u32 pcgctl; u32 gotgctl; + int ret = 0; dev_dbg(hsotg->dev, "%s()\n", __func__); @@ -3302,22 +3305,31 @@ void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) hsotg->op_state = OTG_STATE_A_SUSPEND; } - hprt0 = dwc2_read_hprt0(hsotg); - hprt0 |= HPRT0_SUSP; - dwc2_writel(hsotg, hprt0, HPRT0); - - hsotg->bus_suspended = true; - - /* - * If power_down is supported, Phy clock will be suspended - * after registers are backuped. - */ - if (!hsotg->params.power_down) { - /* Suspend the Phy Clock */ - pcgctl = dwc2_readl(hsotg, PCGCTL); - pcgctl |= PCGCTL_STOPPCLK; - dwc2_writel(hsotg, pcgctl, PCGCTL); - udelay(10); + switch (hsotg->params.power_down) { + case DWC2_POWER_DOWN_PARAM_PARTIAL: + ret = dwc2_enter_partial_power_down(hsotg); + if (ret) + dev_err(hsotg->dev, + "enter partial_power_down failed.\n"); + break; + case DWC2_POWER_DOWN_PARAM_HIBERNATION: + case DWC2_POWER_DOWN_PARAM_NONE: + default: + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_SUSP; + dwc2_writel(hsotg, hprt0, HPRT0); + hsotg->bus_suspended = true; + /* + * If power_down is supported, Phy clock will be suspended + * after registers are backuped. + */ + if (!hsotg->params.power_down) { + /* Suspend the Phy Clock */ + pcgctl = dwc2_readl(hsotg, PCGCTL); + pcgctl |= PCGCTL_STOPPCLK; + dwc2_writel(hsotg, pcgctl, PCGCTL); + udelay(10); + } } /* For HNP the bus must be suspended for at least 200ms */ @@ -3332,6 +3344,8 @@ void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) } else { spin_unlock_irqrestore(&hsotg->lock, flags); } + + return ret; } /** From patchwork Thu Apr 8 09:45:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12190457 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS 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 D8436C433B4 for ; Thu, 8 Apr 2021 09:45:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A442661157 for ; Thu, 8 Apr 2021 09:45:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231454AbhDHJpi (ORCPT ); Thu, 8 Apr 2021 05:45:38 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:37584 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231461AbhDHJpc (ORCPT ); Thu, 8 Apr 2021 05:45:32 -0400 Received: from mailhost.synopsys.com (mdc-mailhost1.synopsys.com [10.225.0.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 40749407FC; Thu, 8 Apr 2021 09:45:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617875121; bh=su60XZzjEqTjvgGpWeRzNnkBW31xb/VNaoOv/jEIpE0=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=DiaUzR5Hpm9TGBHVVYFW5boeNGD9fcQXlBV7Q9ECvkqVHHBqzQJ4aWdr6H0QB/tWv FAkPAKsYLVR0AXHnAE4J+uAr3RiLGhvoRYFG6Y/bbG1Bo/2g8euKWAmMD0hQwuDwVn +XIUuxiW+fVBJ3Z6UMXo3MaaX0DQGGyVJm8/84cn47wehipcd6rTAl9uQHu0ZsCyou 17rGn4qOkWsItM6DiARG/F8zSNyzg30FvVwXdwSk5sB/L4mGmX7PMskTKwxubV+Y4x HlAL8Zh1ARFUMdEoNH3Pl+JdLAgffnDJoMTQsO4gS5WX5QlembtXKz7eST9yojrTT7 WST4H0E3F3BRw== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 6DA1DA022E; Thu, 8 Apr 2021 09:45:18 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Thu, 08 Apr 2021 13:45:17 +0400 Date: Thu, 08 Apr 2021 13:45:17 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v3 07/14] usb: dwc2: Add exit partial power down when port is resumed To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: John Youn , Artur Petrosyan Message-Id: <20210408094518.6DA1DA022E@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Added flow of exiting Partial Power Down in "dwc2_port_resume()" function when core receives resume. NOTE: Switch case statement is used for hibernation partial power down and clock gating mode determination. In this patch only Partial Power Down is implemented the Hibernation and clock gating implementations are planned to be added. Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- Changes in v3: - None Changes in v2: - None drivers/usb/dwc2/core.h | 5 ++-- drivers/usb/dwc2/hcd.c | 61 ++++++++++++++++++++++++++--------------- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 76807abd753b..5a7850482e57 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -1471,7 +1471,7 @@ void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force); void dwc2_hcd_start(struct dwc2_hsotg *hsotg); int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup); int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex); -void dwc2_port_resume(struct dwc2_hsotg *hsotg); +int dwc2_port_resume(struct dwc2_hsotg *hsotg); int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg); int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg); int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg); @@ -1497,7 +1497,8 @@ static inline int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup) { return 0; } static inline int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) { return 0; } -static inline void dwc2_port_resume(struct dwc2_hsotg *hsotg) {} +static inline int dwc2_port_resume(struct dwc2_hsotg *hsotg) +{ return 0; } static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg) { return 0; } static inline int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index e7fb0d5940bc..720354df014b 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -3353,44 +3353,61 @@ int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) * * @hsotg: Programming view of the DWC_otg controller * + * Return: non-zero if failed to exit suspend mode for host. + * * This function is for exiting Host mode suspend. * Must NOT be called with interrupt disabled or spinlock held. */ -void dwc2_port_resume(struct dwc2_hsotg *hsotg) +int dwc2_port_resume(struct dwc2_hsotg *hsotg) { unsigned long flags; u32 hprt0; u32 pcgctl; + int ret = 0; spin_lock_irqsave(&hsotg->lock, flags); - /* - * If power_down is supported, Phy clock is already resumed - * after registers restore. - */ - if (!hsotg->params.power_down) { - pcgctl = dwc2_readl(hsotg, PCGCTL); - pcgctl &= ~PCGCTL_STOPPCLK; - dwc2_writel(hsotg, pcgctl, PCGCTL); + switch (hsotg->params.power_down) { + case DWC2_POWER_DOWN_PARAM_PARTIAL: + ret = dwc2_exit_partial_power_down(hsotg, 0, true); + if (ret) + dev_err(hsotg->dev, + "exit partial_power_down failed.\n"); + break; + case DWC2_POWER_DOWN_PARAM_HIBERNATION: + case DWC2_POWER_DOWN_PARAM_NONE: + default: + /* + * If power_down is supported, Phy clock is already resumed + * after registers restore. + */ + if (!hsotg->params.power_down) { + pcgctl = dwc2_readl(hsotg, PCGCTL); + pcgctl &= ~PCGCTL_STOPPCLK; + dwc2_writel(hsotg, pcgctl, PCGCTL); + spin_unlock_irqrestore(&hsotg->lock, flags); + msleep(20); + spin_lock_irqsave(&hsotg->lock, flags); + } + + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_RES; + hprt0 &= ~HPRT0_SUSP; + dwc2_writel(hsotg, hprt0, HPRT0); spin_unlock_irqrestore(&hsotg->lock, flags); - msleep(20); + + msleep(USB_RESUME_TIMEOUT); + spin_lock_irqsave(&hsotg->lock, flags); + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 &= ~(HPRT0_RES | HPRT0_SUSP); + dwc2_writel(hsotg, hprt0, HPRT0); + hsotg->bus_suspended = false; } - hprt0 = dwc2_read_hprt0(hsotg); - hprt0 |= HPRT0_RES; - hprt0 &= ~HPRT0_SUSP; - dwc2_writel(hsotg, hprt0, HPRT0); spin_unlock_irqrestore(&hsotg->lock, flags); - msleep(USB_RESUME_TIMEOUT); - - spin_lock_irqsave(&hsotg->lock, flags); - hprt0 = dwc2_read_hprt0(hsotg); - hprt0 &= ~(HPRT0_RES | HPRT0_SUSP); - dwc2_writel(hsotg, hprt0, HPRT0); - hsotg->bus_suspended = false; - spin_unlock_irqrestore(&hsotg->lock, flags); + return ret; } /* Handles hub class-specific requests */ From patchwork Thu Apr 8 09:45:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12190459 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS 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 4FA82C433B4 for ; Thu, 8 Apr 2021 09:45:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 193A261158 for ; Thu, 8 Apr 2021 09:45:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231441AbhDHJpm (ORCPT ); Thu, 8 Apr 2021 05:45:42 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:37594 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231472AbhDHJpk (ORCPT ); Thu, 8 Apr 2021 05:45:40 -0400 Received: from mailhost.synopsys.com (mdc-mailhost1.synopsys.com [10.225.0.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 40948407FC; Thu, 8 Apr 2021 09:45:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617875129; bh=lPCDsZcRhusTFDeg15mXbONSbqTeAeoBYV574nrxvCU=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=EB4iR7h+v/MNgrocS9YbkPHZJ3jLe45pROc0WrS7JOlTpUIBOCQ+lV4FABTg3mVVb nImszTwIeFOK5sxdjFUXqYtc0FR7jQsQn5gob2k9OmjC7E2kQXaO33fbSPywBm9zBN Ex6Ql2Tpp60hFKpJICckv6EuZjRWNaPw9LvhM0pBOCjUN65LlwQDi4F9RinrUt+fF3 S5zUAZTkMN+9fTLmMsxUc4z3ESuDmsors7p7eaurBijb1gqfAWcSZoWIdBnglTlIKo O1tDQh+iojRG4imXN6bhhBZ8DTHUwZwR6rx4ImNMUxI/HW7LShVML0ke/dMcgiXQv1 Pd+LmxEqRyPpQ== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 4DD7AA022E; Thu, 8 Apr 2021 09:45:26 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Thu, 08 Apr 2021 13:45:25 +0400 Date: Thu, 08 Apr 2021 13:45:25 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v3 08/14] usb: dwc2: Add exit partial power down when port reset is asserted To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: John Youn , Artur Petrosyan Message-Id: <20210408094526.4DD7AA022E@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Adds Partial Power Down exiting flow when set port feature reset is received in suspended state. Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- Changes in v3: - None Changes in v2: - None drivers/usb/dwc2/hcd.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 720354df014b..7c7496719152 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -3694,6 +3694,15 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_HIBERNATION && hsotg->hibernated) dwc2_exit_hibernation(hsotg, 0, 1, 1); + + if (hsotg->in_ppd) { + retval = dwc2_exit_partial_power_down(hsotg, 1, + true); + if (retval) + dev_err(hsotg->dev, + "exit partial_power_down failed\n"); + } + hprt0 = dwc2_read_hprt0(hsotg); dev_dbg(hsotg->dev, "SetPortFeature - USB_PORT_FEAT_RESET\n"); From patchwork Thu Apr 8 09:45:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12190461 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS 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 1B3ECC433ED for ; Thu, 8 Apr 2021 09:45:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D152661157 for ; Thu, 8 Apr 2021 09:45:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231483AbhDHJpx (ORCPT ); Thu, 8 Apr 2021 05:45:53 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:36612 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231474AbhDHJps (ORCPT ); Thu, 8 Apr 2021 05:45:48 -0400 Received: from mailhost.synopsys.com (mdc-mailhost1.synopsys.com [10.225.0.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 3C4D8C09B6; Thu, 8 Apr 2021 09:45:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617875137; bh=udgwLz5bv1zt3AIAh0DMinAYsayGC48qOFuI+SZpOFc=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=UFNLpXAmFuMqmveQ8H0v2eG63jRuXzIINr6qcZLqAVm/2a3mHw3xBtprv0PU7oWkp slphKZ9JpchQijcE/uTHXL/uhHAjrjVBK7R3KExHv9bSzTec4+5jNfAZ4foSuihRgx LcyIzVmoKWm/KrchvkM3vY0cp1ymtdKwiPEafWr90dFL4IPmzMWkaCFK9f/gOoWWBy ZPy6rfj+TL5TVUATdOmbWzpgZV/EBjcAPkMsY+2TzXOFcofsd2Omb3Z4nBJPBq0bsk hYtcb+oSs06TROxx2TAEPHpZNbIEuGw81mVPup+quUt1x9Q/82rGzCblxbRkBh6lxP 2GobwtxQfOEVw== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 4AA7AA022E; Thu, 8 Apr 2021 09:45:34 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Thu, 08 Apr 2021 13:45:33 +0400 Date: Thu, 08 Apr 2021 13:45:33 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v3 09/14] usb: dwc2: Add part. power down exit from dwc2_conn_id_status_change(). To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: John Youn , Artur Petrosyan , Minas Harutyunyan Message-Id: <20210408094534.4AA7AA022E@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Before changing to connector B exiting from Partial Power Down is required. - Added exiting from Partial Power Down mode when connector ID status changes to "connId B". Because if connector ID status changed to B connector while core was in partial power down mode, HANG would accrue from a soft reset. Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- drivers/usb/dwc2/hcd.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 7c7496719152..9529e9839961 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -3206,6 +3206,15 @@ static void dwc2_conn_id_status_change(struct work_struct *work) if (count > 250) dev_err(hsotg->dev, "Connection id status change timed out\n"); + + /* + * Exit Partial Power Down without restoring registers. + * No need to check the return value as registers + * are not being restored. + */ + if (hsotg->in_ppd && hsotg->lx_state == DWC2_L2) + dwc2_exit_partial_power_down(hsotg, 0, false); + hsotg->op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false); dwc2_enable_global_interrupts(hsotg); From patchwork Thu Apr 8 09:45:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12190463 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED 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 7A0E2C43460 for ; Thu, 8 Apr 2021 09:45:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4D67061155 for ; Thu, 8 Apr 2021 09:45:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231485AbhDHJp4 (ORCPT ); Thu, 8 Apr 2021 05:45:56 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:37622 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231478AbhDHJp4 (ORCPT ); Thu, 8 Apr 2021 05:45:56 -0400 Received: from mailhost.synopsys.com (mdc-mailhost2.synopsys.com [10.225.0.210]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 4202F4051F; Thu, 8 Apr 2021 09:45:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617875145; bh=ftbyk00YEvJSEIL+T7rY2QGF6NNFxPT9bL5QU6rM9KI=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=ZwB5fZoQXN6MqbC41fLhmdMBGryeaK+0k4qwYxWJMrVGe44bRPRveVjBBkSo+Aj2T USDLD6ZSK+3Ngh5XXQMXSdCl2MpMLK3Fdirnl78zaU2ZbjOMShTApQOQvXR6cX14CJ FQBeWrs3Xg6GflteSmvDqKcJbBYSdXNVIMrhDJ46MG8f7DK4XCkt2c1atN8GXNzTUB u+3nmIH3CJUocPxnlLll4pWQn+foYjisyyDugLVNv+CSxE3LoaVZi7xH87ApAxfa9r sg7tAzZUgNk2icqdrKpSMhiFqXgaCxBdDRkHww/rLkrwlGIKeh/7IDjwajYMWHxab/ 3DsXVB9EvBZKg== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 685BAA0094; Thu, 8 Apr 2021 09:45:42 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Thu, 08 Apr 2021 13:45:41 +0400 Date: Thu, 08 Apr 2021 13:45:41 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v3 10/14] usb: dwc2: Allow exit partial power down in urb enqueue To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: John Youn , Artur Petrosyan Message-Id: <20210408094542.685BAA0094@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org When core is in partial power down state and an external hub is connected, upper layer sends URB enqueue request, which results in port reset issue. Added exit from partial power down state to avoid port reset issue and process upper layer request correctly. Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- Changes in v3: - None Changes in v2: - None drivers/usb/dwc2/hcd.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 9529e9839961..cb52bc41bfb8 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -4633,6 +4633,13 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, dwc2_dump_urb_info(hcd, urb, "urb_enqueue"); } + if (hsotg->in_ppd) { + retval = dwc2_exit_partial_power_down(hsotg, 0, true); + if (retval) + dev_err(hsotg->dev, + "exit partial_power_down failed\n"); + } + if (!ep) return -EINVAL; From patchwork Thu Apr 8 09:45:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12190465 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS 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 78311C433B4 for ; Thu, 8 Apr 2021 09:45:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 224B861157 for ; Thu, 8 Apr 2021 09:45:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231336AbhDHJqG (ORCPT ); Thu, 8 Apr 2021 05:46:06 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:36630 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231500AbhDHJqF (ORCPT ); Thu, 8 Apr 2021 05:46:05 -0400 Received: from mailhost.synopsys.com (mdc-mailhost2.synopsys.com [10.225.0.210]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 1ADDAC09B1; Thu, 8 Apr 2021 09:45:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617875154; bh=xhxpjgTpa9pFuo9pJIVEGylg0epbNh6oZH7CA1L2gdc=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=XwhmdZ+cHK82HfuPZpbrVajJB7gaG6sEgI5MkcbfqwFCEGwcoWENtex6/3WTza2bL zGXWzWm3Z/e+z1+iLCP9YIsxGhL0RjIRyLqxRZFOzL+q5kvgTEdRPsatidjBv51Gj9 /stm0yw6iBRoAY8BqjW7yiBOsQu6YwfL4HTXndPXIm7cZhRzKhV6zXNexkb9EIgl9G TQYoVQFWUnmlR4Rg/91qqkkfvf0qhL/7I4tJn+slSTZDZxRKGobOa0xgzj6dzKMNyz HjTkHdJhHcwCrnBG/QS7Urv4L8nqvk2gTUyx5GZDCSzhu/8u2dA/jmvRkW/RtbsnXY icPLptyHBDV3w== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 75484A0094; Thu, 8 Apr 2021 09:45:50 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Thu, 08 Apr 2021 13:45:49 +0400 Date: Thu, 08 Apr 2021 13:45:49 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v3 11/14] usb: dwc2: Fix session request interrupt handler To: John Youn , Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Mian Yousaf Kaukab , Gregory Herrero Cc: Artur Petrosyan , Minas Harutyunyan , , Robert Baldyga Message-Id: <20210408094550.75484A0094@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org According to programming guide in host mode, port power must be turned on in session request interrupt handlers. Cc: Fixes: 21795c826a45 ("usb: dwc2: exit hibernation on session request") Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- drivers/usb/dwc2/core_intr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 0a7f9330907f..8c0152b514be 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -307,6 +307,7 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) { int ret; + u32 hprt0; /* Clear interrupt */ dwc2_writel(hsotg, GINTSTS_SESSREQINT, GINTSTS); @@ -328,6 +329,13 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) * established */ dwc2_hsotg_disconnect(hsotg); + } else { + /* Turn on the port power bit. */ + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_PWR; + dwc2_writel(hsotg, hprt0, HPRT0); + /* Connect hcd after port power is set. */ + dwc2_hcd_connect(hsotg); } } From patchwork Thu Apr 8 09:45:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12190467 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS 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 C1324C433B4 for ; Thu, 8 Apr 2021 09:46:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9E20B61157 for ; Thu, 8 Apr 2021 09:46:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231532AbhDHJqN (ORCPT ); Thu, 8 Apr 2021 05:46:13 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:37640 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231500AbhDHJqN (ORCPT ); Thu, 8 Apr 2021 05:46:13 -0400 Received: from mailhost.synopsys.com (mdc-mailhost1.synopsys.com [10.225.0.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 1019340806; Thu, 8 Apr 2021 09:46:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617875162; bh=QpZJUwqksrvxljluCFgrIzDH+wfZNuUqYSwN0TUMTt4=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=a0PXgEseuoQiz6ZPg8EGxIO9MhezCJYyGHBwrHisw4i9TNx7E5Oe7p+8VydakBrkx S70LmGGXJdV3So4CPw2Lwd5tGZPPVfmVRjTxsgHFZmD8FPQL6JQ2HDZOq4vXS8GWXW Es7TfT5u5V0j71XZwlB88qw776Ekue4Yw6IUz5aehlfAXqEKIMp1tTrBKnMdM0ICFc G+EjnLxTQm8RFu/cvEYBIMcZUDO5qUmFU9DF22uuCr6aOEU1nz1ZtoSCX370jnr8Ve BO1dqdKcPOgMzfq0dv1WUz/CxxNHAElv2qhrcOgr3CeZ8MfVDJz/NrKXqwyFAs6n+n zQSbrj7XOyz4g== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 33541A022E; Thu, 8 Apr 2021 09:45:59 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Thu, 08 Apr 2021 13:45:58 +0400 Date: Thu, 08 Apr 2021 13:45:58 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v3 12/14] usb: dwc2: Update partial power down entering by system suspend To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: John Youn , Artur Petrosyan Message-Id: <20210408094559.33541A022E@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org With current implementation the port power is being disabled, which is not required by the programming guide. Also, if there is a system which works only in "DWC2_POWER_DOWN_PARAM_NONE" (clock gating) mode the current implementation does not set Gate hclk bit in pcgctl register. Rearranges and updates the implementation of entering to partial power down power saving mode when PC is suspended to get rid of many "if" statements and removes disabling of port power. NOTE: Switch case statement is used for hibernation partial power down and clock gating mode determination. In this patch only Partial Power Down is implemented the Hibernation and clock gating implementations are planned to be added. Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- Changes in v3: - None Changes in v2: - None drivers/usb/dwc2/hcd.c | 53 ++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 35 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index cb52bc41bfb8..34030bafdff4 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -4367,8 +4367,6 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); unsigned long flags; int ret = 0; - u32 hprt0; - u32 pcgctl; spin_lock_irqsave(&hsotg->lock, flags); @@ -4384,47 +4382,32 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) if (hsotg->op_state == OTG_STATE_B_PERIPHERAL) goto unlock; - if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL || - hsotg->flags.b.port_connect_status == 0) + if (hsotg->bus_suspended) goto skip_power_saving; - /* - * Drive USB suspend and disable port Power - * if usb bus is not suspended. - */ - if (!hsotg->bus_suspended) { - hprt0 = dwc2_read_hprt0(hsotg); - if (hprt0 & HPRT0_CONNSTS) { - hprt0 |= HPRT0_SUSP; - if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) - hprt0 &= ~HPRT0_PWR; - dwc2_writel(hsotg, hprt0, HPRT0); - } - if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) { - spin_unlock_irqrestore(&hsotg->lock, flags); - dwc2_vbus_supply_exit(hsotg); - spin_lock_irqsave(&hsotg->lock, flags); - } else { - pcgctl = readl(hsotg->regs + PCGCTL); - pcgctl |= PCGCTL_STOPPCLK; - writel(pcgctl, hsotg->regs + PCGCTL); - } - } + if (hsotg->flags.b.port_connect_status == 0) + goto skip_power_saving; - if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) { + switch (hsotg->params.power_down) { + case DWC2_POWER_DOWN_PARAM_PARTIAL: /* Enter partial_power_down */ ret = dwc2_enter_partial_power_down(hsotg); - if (ret) { - if (ret != -ENOTSUPP) - dev_err(hsotg->dev, - "enter partial_power_down failed\n"); - goto skip_power_saving; - } - - /* After entering partial_power_down, hardware is no more accessible */ + if (ret) + dev_err(hsotg->dev, + "enter partial_power_down failed\n"); + /* After entering suspend, hardware is not accessible */ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + break; + case DWC2_POWER_DOWN_PARAM_HIBERNATION: + case DWC2_POWER_DOWN_PARAM_NONE: + default: + goto skip_power_saving; } + spin_unlock_irqrestore(&hsotg->lock, flags); + dwc2_vbus_supply_exit(hsotg); + spin_lock_irqsave(&hsotg->lock, flags); + /* Ask phy to be suspended */ if (!IS_ERR_OR_NULL(hsotg->uphy)) { spin_unlock_irqrestore(&hsotg->lock, flags); From patchwork Wed Apr 7 10:08:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12187623 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.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED 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 E9827C433ED for ; Wed, 7 Apr 2021 10:09:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A7C5661382 for ; Wed, 7 Apr 2021 10:09:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234601AbhDGKJG (ORCPT ); Wed, 7 Apr 2021 06:09:06 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:39802 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234217AbhDGKJF (ORCPT ); Wed, 7 Apr 2021 06:09:05 -0400 Received: from mailhost.synopsys.com (mdc-mailhost1.synopsys.com [10.225.0.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 64685404A3; Wed, 7 Apr 2021 10:08:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617790136; bh=eu1McAw//AVG679Rm99KEM81EeYNu+rSRmUeWBUkbUU=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=TalrV//l2s8hN09XkplmdN901X7vspjNSQ1t0CzlQLkUtLGUexeUjBz/jsGBP8/+3 E7aJD8MTFviEyxBNaU0kujh/+Wx8YOv9eScsD5yOPcNo9P2LdnmVO1Ds8SI4+QrWS9 Cxqw1Vyh3x0ejTPFXA6H+SPqp/Wb5JdpQLU7h+XhsWKqdFMc6AELnpcdagbH5ALGmC HVZsq7xClUJhwoRMVF9aTGxlh6iUY6RirNk+KZq96eEmgh6PZNDVp3EcsHVwJc0LKR flt5lYKCWCbI4SM7bKlj75b43FRUgOdcWOBwu45huAf1hKRJf3YXIdF7u91FaiJgWU xCe6qNCMPT1Eg== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 4E974A022E; Wed, 7 Apr 2021 10:08:53 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Wed, 07 Apr 2021 14:08:52 +0400 Date: Wed, 07 Apr 2021 14:08:52 +0400 Message-Id: In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH 13/14] usb: dwc2: Fix partial power down exiting by system resume To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Douglas Anderson Cc: John Youn , Artur Petrosyan , Paul Zimmerman , , Kever Yang Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Fixes the implementation of exiting from partial power down power saving mode when PC is resumed. Added port connection status checking which prevents exiting from Partial Power Down mode from _dwc2_hcd_resume() if not in Partial Power Down mode. Rearranged the implementation to get rid of many "if" statements. NOTE: Switch case statement is used for hibernation partial power down and clock gating mode determination. In this patch only Partial Power Down is implemented the Hibernation and clock gating implementations are planned to be added. Cc: Fixes: 6f6d70597c15 ("usb: dwc2: bus suspend/resume for hosts with DWC2_POWER_DOWN_PARAM_NONE") Signed-off-by: Artur Petrosyan --- drivers/usb/dwc2/hcd.c | 90 +++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 34030bafdff4..f096006df96f 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -4427,7 +4427,7 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) { struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); unsigned long flags; - u32 pcgctl; + u32 hprt0; int ret = 0; spin_lock_irqsave(&hsotg->lock, flags); @@ -4438,11 +4438,40 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) if (hsotg->lx_state != DWC2_L2) goto unlock; - if (hsotg->params.power_down > DWC2_POWER_DOWN_PARAM_PARTIAL) { + hprt0 = dwc2_read_hprt0(hsotg); + + /* + * Added port connection status checking which prevents exiting from + * Partial Power Down mode from _dwc2_hcd_resume() if not in Partial + * Power Down mode. + */ + if (hprt0 & HPRT0_CONNSTS) { + hsotg->lx_state = DWC2_L0; + goto unlock; + } + + switch (hsotg->params.power_down) { + case DWC2_POWER_DOWN_PARAM_PARTIAL: + ret = dwc2_exit_partial_power_down(hsotg, 0, true); + if (ret) + dev_err(hsotg->dev, + "exit partial_power_down failed\n"); + /* + * Set HW accessible bit before powering on the controller + * since an interrupt may rise. + */ + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + break; + case DWC2_POWER_DOWN_PARAM_HIBERNATION: + case DWC2_POWER_DOWN_PARAM_NONE: + default: hsotg->lx_state = DWC2_L0; goto unlock; } + /* Change Root port status, as port status change occurred after resume.*/ + hsotg->flags.b.port_suspend_change = 1; + /* * Enable power if not already done. * This must not be spinlocked since duration @@ -4454,52 +4483,25 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) spin_lock_irqsave(&hsotg->lock, flags); } - if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) { - /* - * Set HW accessible bit before powering on the controller - * since an interrupt may rise. - */ - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - - - /* Exit partial_power_down */ - ret = dwc2_exit_partial_power_down(hsotg, 0, true); - if (ret && (ret != -ENOTSUPP)) - dev_err(hsotg->dev, "exit partial_power_down failed\n"); - } else { - pcgctl = readl(hsotg->regs + PCGCTL); - pcgctl &= ~PCGCTL_STOPPCLK; - writel(pcgctl, hsotg->regs + PCGCTL); - } - - hsotg->lx_state = DWC2_L0; - + /* Enable external vbus supply after resuming the port. */ spin_unlock_irqrestore(&hsotg->lock, flags); + dwc2_vbus_supply_init(hsotg); - if (hsotg->bus_suspended) { - spin_lock_irqsave(&hsotg->lock, flags); - hsotg->flags.b.port_suspend_change = 1; - spin_unlock_irqrestore(&hsotg->lock, flags); - dwc2_port_resume(hsotg); - } else { - if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_PARTIAL) { - dwc2_vbus_supply_init(hsotg); - - /* Wait for controller to correctly update D+/D- level */ - usleep_range(3000, 5000); - } + /* Wait for controller to correctly update D+/D- level */ + usleep_range(3000, 5000); + spin_lock_irqsave(&hsotg->lock, flags); - /* - * Clear Port Enable and Port Status changes. - * Enable Port Power. - */ - dwc2_writel(hsotg, HPRT0_PWR | HPRT0_CONNDET | - HPRT0_ENACHG, HPRT0); - /* Wait for controller to detect Port Connect */ - usleep_range(5000, 7000); - } + /* + * Clear Port Enable and Port Status changes. + * Enable Port Power. + */ + dwc2_writel(hsotg, HPRT0_PWR | HPRT0_CONNDET | + HPRT0_ENACHG, HPRT0); - return ret; + /* Wait for controller to detect Port Connect */ + spin_unlock_irqrestore(&hsotg->lock, flags); + usleep_range(5000, 7000); + spin_lock_irqsave(&hsotg->lock, flags); unlock: spin_unlock_irqrestore(&hsotg->lock, flags); From patchwork Thu Apr 8 09:46:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 12190471 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS 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 A0137C433ED for ; Thu, 8 Apr 2021 09:46:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 50E64610A6 for ; Thu, 8 Apr 2021 09:46:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231569AbhDHJqd (ORCPT ); Thu, 8 Apr 2021 05:46:33 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:37664 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231210AbhDHJq3 (ORCPT ); Thu, 8 Apr 2021 05:46:29 -0400 Received: from mailhost.synopsys.com (mdc-mailhost2.synopsys.com [10.225.0.210]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 50BA140806; Thu, 8 Apr 2021 09:46:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1617875178; bh=3WPQXRrxUY4EWlLwQjuK0lXjFiPQbgHDqifXJNP6F0o=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=M0SCpTSJ4QgfnFQigvbi+j9b03RQ6A+jt7LexTrU0v3FiQ/q75mF+7LZiGQ5Dzpnf 9DgzQyQN5FRMYugx7JPjbs23XTb8IhQzoe6Ife8oBOp7+rXzLUXq6gQZ5VSpKLgTeo Oo5mtekph74JeeEauE3dqFuKm+aUHGMg8EjEfBlTye0tcXMPbqxfgEJ4EKVwBEZBom /bpn1dUYVmv4gfQa52dot6WTH23c2uuxRu8Mqv02/1KN2vVE348jVYnSrDDuedYjsj 5RSAimBu+bdc6giszu8InO5TCIU1RB9IaNVM0jSxLMk/MI4cd8wBWi55TT70jIrHhA wvtD++u+u2B0A== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 8AE35A0094; Thu, 8 Apr 2021 09:46:15 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Thu, 08 Apr 2021 13:46:14 +0400 Date: Thu, 08 Apr 2021 13:46:14 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v3 14/14] usb: dwc2: Add exit partial power down before removing driver To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: John Youn , Artur Petrosyan Message-Id: <20210408094615.8AE35A0094@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org When dwc2 core is in partial power down mode loading driver again causes driver fail. Because in that mode registers are not accessible. Added a flow of exiting the partial power down mode to avoid the driver reload failure. Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- Changes in v3: - None Changes in v2: - None drivers/usb/dwc2/platform.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 5f18acac7406..b28b8cd45799 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -316,6 +316,15 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) static int dwc2_driver_remove(struct platform_device *dev) { struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); + int ret = 0; + + /* Exit Partial Power Down when driver is removed. */ + if (hsotg->in_ppd) { + ret = dwc2_exit_partial_power_down(hsotg, 0, true); + if (ret) + dev_err(hsotg->dev, + "exit partial_power_down failed\n"); + } dwc2_debugfs_exit(hsotg); if (hsotg->hcd_enabled) @@ -334,7 +343,7 @@ static int dwc2_driver_remove(struct platform_device *dev) reset_control_assert(hsotg->reset); reset_control_assert(hsotg->reset_ecc); - return 0; + return ret; } /**