From patchwork Fri Apr 19 11:25:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 10909741 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D256C14DB for ; Fri, 19 Apr 2019 20:05:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5AB626E4A for ; Fri, 19 Apr 2019 20:05:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BA1C325223; Fri, 19 Apr 2019 20:05:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1B15E26E4A for ; Fri, 19 Apr 2019 20:05:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728112AbfDSUFx (ORCPT ); Fri, 19 Apr 2019 16:05:53 -0400 Received: from dc8-smtprelay2.synopsys.com ([198.182.47.102]:36752 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727257AbfDSUFw (ORCPT ); Fri, 19 Apr 2019 16:05:52 -0400 Received: from mailhost.synopsys.com (dc2-mailhost1.synopsys.com [10.12.135.161]) (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 46264C1203; Fri, 19 Apr 2019 11:25:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1555673112; bh=nHZb6BEg/sWCfZRiQSWSnGXYYMJNsG0OdKLH9KIbiEc=; h=From:To:CC:Subject:Date:References:In-Reply-To:From; b=LYcEvE0ZkwTEKaUgFpk6qOoaQ3/WXDDQzRWn3frXnJhMtwR/gPfyL1q5/VVsO0u72 TRi579WO0PMLCI9stvo5h2PjIjhDQ7Keygc+JJzay41hXhnZQh8dC0+XiTbkS5han2 xR3yKHMOcpm0nl3RW+dNa1B7XKyEbbh89pZ66lNs4YTeF1dGOxN/R5u9cjwWP6gO2+ H6RxxmCu6hTLSYCKvzMkEidhKtZTd3cvJcKl1ZkWQRf9cxIVsglV+MHs5LiFpsDDI0 J9mKyL6WoK5GOaQHPKRjiI/ExZOTot+venhB5oPKUrMmI/8VgwpZctRW0zz+OgZZSN DSFZ/6L8KmcHw== Received: from us01wehtc1.internal.synopsys.com (us01wehtc1-vip.internal.synopsys.com [10.12.239.236]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPS id 90F99A005A; Fri, 19 Apr 2019 11:25:11 +0000 (UTC) Received: from US01HYBRID2.internal.synopsys.com (10.15.246.24) by us01wehtc1.internal.synopsys.com (10.12.239.235) with Microsoft SMTP Server (TLS) id 14.3.408.0; Fri, 19 Apr 2019 04:25:11 -0700 Received: from NAM01-SN1-obe.outbound.protection.outlook.com (10.13.134.195) by mrs.synopsys.com (10.15.246.24) with Microsoft SMTP Server (TLS) id 14.3.408.0; Fri, 19 Apr 2019 04:25:11 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=synopsys.onmicrosoft.com; s=selector1-synopsys-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=nHZb6BEg/sWCfZRiQSWSnGXYYMJNsG0OdKLH9KIbiEc=; b=pUkeG/fbitK58Up3evZn7JSfiMC3qJq1J/Gagks+arpveykb/CVFZUhjqYGQ1Mw6LCOd9Rzp36LMEyvI5BLyh63HBxImmlzwXi4caG5FQ76Tg7/vi+WoQqLaiR9YqIO5j9MJObutYpvwxndvY4Aw2veIGAgFPZtI82TjIYp1RW4= Received: from SN1PR12MB2431.namprd12.prod.outlook.com (52.132.195.146) by SN1PR12MB2383.namprd12.prod.outlook.com (52.132.194.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1813.14; Fri, 19 Apr 2019 11:25:09 +0000 Received: from SN1PR12MB2431.namprd12.prod.outlook.com ([fe80::5ca6:ee5f:1147:df5a]) by SN1PR12MB2431.namprd12.prod.outlook.com ([fe80::5ca6:ee5f:1147:df5a%4]) with mapi id 15.20.1813.013; Fri, 19 Apr 2019 11:25:09 +0000 From: Artur Petrosyan To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , "linux-usb@vger.kernel.org" CC: John Youn , Artur Petrosyan Subject: [PATCH v1 10/14] usb: dwc2: Fix hibernation between host and device modes. Thread-Topic: [PATCH v1 10/14] usb: dwc2: Fix hibernation between host and device modes. Thread-Index: AQHU9qKMWXS7HJ+dKkOk/Fgbf3TpOw== Date: Fri, 19 Apr 2019 11:25:09 +0000 Message-ID: <40708a6888d43ff5e29b5d06f0c53beda840b096.1555672441.git.arturp@synopsys.com> References: In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: VI1PR0302CA0024.eurprd03.prod.outlook.com (2603:10a6:800:e9::34) To SN1PR12MB2431.namprd12.prod.outlook.com (2603:10b6:802:27::18) authentication-results: spf=none (sender IP is ) smtp.mailfrom=arturp@synopsys.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [84.53.141.195] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: e3f5ded4-589c-43d7-e69f-08d6c4b9adca x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(5600141)(711020)(4605104)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020);SRVR:SN1PR12MB2383; x-ms-traffictypediagnostic: SN1PR12MB2383: x-microsoft-antispam-prvs: x-forefront-prvs: 0012E6D357 x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(366004)(136003)(39850400004)(396003)(376002)(346002)(189003)(199004)(6436002)(102836004)(486006)(26005)(186003)(386003)(4326008)(305945005)(2906002)(6506007)(446003)(76176011)(7736002)(97736004)(5660300002)(81156014)(66476007)(11346002)(81166006)(66556008)(6486002)(476003)(256004)(14444005)(53936002)(25786009)(107886003)(71190400001)(71200400001)(86362001)(6512007)(99286004)(54906003)(110136005)(316002)(2616005)(68736007)(8676002)(66066001)(6116002)(36756003)(14454004)(478600001)(2501003)(8936002)(118296001)(3846002)(66446008)(52116002)(64756008)(66946007)(73956011);DIR:OUT;SFP:1102;SCL:1;SRVR:SN1PR12MB2383;H:SN1PR12MB2431.namprd12.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: synopsys.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: nlNWRMRK7vZj/1LSEpHMVixggSt/9lJnfv2SaZQx9vTU7zg8b1FSCB/ZeVpLrSSUjpXu5zA875yQ/y0HtXxa1a/+kNlQLtfenPZ64N6zLwXQtxQsbey0rTR6UEyIMww5Ejvd8YvGvNDzKh4EAuuTlfGInVPjoKeZRBrD5G+ApndJSD85hss6KzuWCB7bFjfQkwq2t/EJzOmddo4BID4TrgVqO3u05UzOvu7muA9/V5mrIwm9EbJH50wxRiUXuUcPEovPHKqH30dbc34QgNklJnbzE8hcQ1lfuYDZ1i6qefZqvER1UNa1JZh8S67oMGLZrWfBcVB3VJX7UqPQ5Tc09eOrS9fampEaTbFcc1nqGH5q+MsMwpa8cdfFCbZ6xAItUh+xQCYVOLqIamre6OLvrN1oGGuoU9DTugdpYNLjDPA= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-Network-Message-Id: e3f5ded4-589c-43d7-e69f-08d6c4b9adca X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Apr 2019 11:25:09.6633 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: c33c9f88-1eb7-4099-9700-16013fd9e8aa X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB2383 X-OriginatorOrg: synopsys.com Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When core is in hibernation in host mode and a device cable was connected than driver exited from device hibernation. However, registers saved for host mode and when exited from device hibernation register restore would be done for device register which was wrong because there was no device registers stored to restore. - Added dwc_handle_gpwrdn_disc_det() function which handles gpwrdn disconnect detect flow and exits hibernation without restoring the registers. - Updated exiting from hibernation in GPWRDN_STS_CHGINT with calling dwc_handle_gpwrdn_disc_det() function. Here no register is restored which is the solution described above. - Increased the waiting timeout for HPRT0.PrtSusp register field to be set. Because on HiKey 960 board HPRT0.PrtSusp wasn't generated with the existing timeout. Signed-off-by: Artur Petrosyan Signed-off-by: Minas Harutyunyan --- drivers/usb/dwc2/core_intr.c | 139 ++++++++++++++++++++++++------------------- drivers/usb/dwc2/hcd.c | 2 +- 2 files changed, 80 insertions(+), 61 deletions(-) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index fc465707b7a1..40d296d9b6fb 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -662,6 +662,70 @@ static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg) return 0; } +/** + * This function handles the gpwrdn disconnect detect. + * Exits hibernation without restoring registers. + * + * @hsotg: Programming view of DWC_otg controller + * @gpwrdn: GPWRDN register + */ +static inline void dwc_handle_gpwrdn_disc_det(struct dwc2_hsotg *hsotg, + u32 gpwrdn) +{ + u32 gpwrdn_tmp; + + /* Switch-on voltage to the core */ + gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN); + gpwrdn_tmp &= ~GPWRDN_PWRDNSWTCH; + dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); + udelay(10); + + /* Reset core */ + gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN); + gpwrdn_tmp &= ~GPWRDN_PWRDNRSTN; + dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); + udelay(10); + + /* Disable Power Down Clamp */ + gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN); + gpwrdn_tmp &= ~GPWRDN_PWRDNCLMP; + dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); + udelay(10); + + /* Deassert reset core */ + gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN); + gpwrdn_tmp |= GPWRDN_PWRDNRSTN; + dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); + udelay(10); + + /* Disable PMU interrupt */ + gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN); + gpwrdn_tmp &= ~GPWRDN_PMUINTSEL; + dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); + + /* De-assert Wakeup Logic */ + gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN); + gpwrdn_tmp &= ~GPWRDN_PMUACTV; + dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); + + hsotg->hibernated = 0; + + if (gpwrdn & GPWRDN_IDSTS) { + hsotg->op_state = OTG_STATE_B_PERIPHERAL; + dwc2_core_init(hsotg, false); + dwc2_enable_global_interrupts(hsotg); + dwc2_hsotg_core_init_disconnected(hsotg, false); + dwc2_hsotg_core_connect(hsotg); + } else { + hsotg->op_state = OTG_STATE_A_HOST; + + /* Initialize the Core for Host mode */ + dwc2_core_init(hsotg, false); + dwc2_enable_global_interrupts(hsotg); + dwc2_hcd_start(hsotg); + } +} + /* * GPWRDN interrupt handler. * @@ -683,60 +747,12 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg) if ((gpwrdn & GPWRDN_DISCONN_DET) && (gpwrdn & GPWRDN_DISCONN_DET_MSK) && !linestate) { - u32 gpwrdn_tmp; - dev_dbg(hsotg->dev, "%s: GPWRDN_DISCONN_DET\n", __func__); - - /* Switch-on voltage to the core */ - gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN); - gpwrdn_tmp &= ~GPWRDN_PWRDNSWTCH; - dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); - udelay(10); - - /* Reset core */ - gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN); - gpwrdn_tmp &= ~GPWRDN_PWRDNRSTN; - dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); - udelay(10); - - /* Disable Power Down Clamp */ - gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN); - gpwrdn_tmp &= ~GPWRDN_PWRDNCLMP; - dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); - udelay(10); - - /* Deassert reset core */ - gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN); - gpwrdn_tmp |= GPWRDN_PWRDNRSTN; - dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); - udelay(10); - - /* Disable PMU interrupt */ - gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN); - gpwrdn_tmp &= ~GPWRDN_PMUINTSEL; - dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); - - /* De-assert Wakeup Logic */ - gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN); - gpwrdn_tmp &= ~GPWRDN_PMUACTV; - dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); - - hsotg->hibernated = 0; - - if (gpwrdn & GPWRDN_IDSTS) { - hsotg->op_state = OTG_STATE_B_PERIPHERAL; - dwc2_core_init(hsotg, false); - dwc2_enable_global_interrupts(hsotg); - dwc2_hsotg_core_init_disconnected(hsotg, false); - dwc2_hsotg_core_connect(hsotg); - } else { - hsotg->op_state = OTG_STATE_A_HOST; - - /* Initialize the Core for Host mode */ - dwc2_core_init(hsotg, false); - dwc2_enable_global_interrupts(hsotg); - dwc2_hcd_start(hsotg); - } + /* + * Call disconnect detect function to exit from + * hibernation + */ + dwc_handle_gpwrdn_disc_det(hsotg, gpwrdn); } if ((gpwrdn & GPWRDN_LNSTSCHG) && @@ -752,22 +768,25 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg) } } } + if ((gpwrdn & GPWRDN_RST_DET) && (gpwrdn & GPWRDN_RST_DET_MSK)) { dev_dbg(hsotg->dev, "%s: GPWRDN_RST_DET\n", __func__); if (!linestate && (gpwrdn & GPWRDN_BSESSVLD)) dwc2_exit_hibernation(hsotg, 0, 1, 0); } + if ((gpwrdn & GPWRDN_STS_CHGINT) && - (gpwrdn & GPWRDN_STS_CHGINT_MSK) && linestate) { + (gpwrdn & GPWRDN_STS_CHGINT_MSK)) { dev_dbg(hsotg->dev, "%s: GPWRDN_STS_CHGINT\n", __func__); if (hsotg->hw_params.hibernation && hsotg->hibernated) { - if (gpwrdn & GPWRDN_IDSTS) { - dwc2_exit_hibernation(hsotg, 0, 0, 0); - call_gadget(hsotg, resume); - } else { - dwc2_exit_hibernation(hsotg, 1, 0, 1); - } + /* + * As GPWRDN_STS_CHGINT exit from hibernation flow is + * the same as in GPWRDN_DISCONN_DET flow. Call + * disconnect detect helper function to exit from + * hibernation. + */ + dwc_handle_gpwrdn_disc_det(hsotg, gpwrdn); } } } diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 54450fa352cf..45d4a3e1ebd2 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -5570,7 +5570,7 @@ int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg) dwc2_writel(hsotg, hprt0, HPRT0); /* Wait for the HPRT0.PrtSusp register field to be set */ - if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 3000)) + if (dwc2_hsotg_wait_bit_set(hsotg, HPRT0, HPRT0_SUSP, 5000)) dev_warn(hsotg->dev, "Suspend wasn't generated\n"); /*