From patchwork Sat Dec 8 02:28:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 10719129 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 9A8EC14E2 for ; Sat, 8 Dec 2018 02:28:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 861F92D5C9 for ; Sat, 8 Dec 2018 02:28:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 75A722D5D3; Sat, 8 Dec 2018 02:28:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E793A2D5C9 for ; Sat, 8 Dec 2018 02:28:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726073AbeLHC2v (ORCPT ); Fri, 7 Dec 2018 21:28:51 -0500 Received: from smtprelay.synopsys.com ([198.182.47.9]:45540 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726065AbeLHC2v (ORCPT ); Fri, 7 Dec 2018 21:28:51 -0500 Received: from mailhost.synopsys.com (mailhost1.synopsys.com [10.12.238.239]) by smtprelay.synopsys.com (Postfix) with ESMTP id E91CF24E062E; Fri, 7 Dec 2018 18:28:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1544236130; bh=O0XAu76lfTNQ9vtJJMCIXTB01SVj9lQag8vrzrRNP4M=; h=Date:In-Reply-To:References:From:Subject:To:CC:From; b=FeCxYau8Ngri9DboQOI8liwOd+AAe155Iece4insjX0adqJI2l3SSIjYwtfsXBKeV gYZ8Ernl3RV0InMoKZzukKrd/WwlGNpm84VDipZGpjjQ+VYylPFNzZtfipn70PBhY1 0t6ipb/EJnWNynzeOmpg6boJp7GNB7QYYSZiEQWH4/W1JrzgRh+oGaFMIcwdC5OyIb pw45hoCfFdcEmsxlTT7CrVXvU1AHxd7xHm7Ei9pJSTpVDsdoN81JvyZWYjmH2y254+ PP6nQsUOv3MUTxa+LsjM51vSDHVtL+qYFFcNOhIKjbBN6ka/CTnnY8IIaix3kSSIgf 6QOeH9FwSJVJg== Received: from US01WXQAHTC1.internal.synopsys.com (us01wxqahtc1.internal.synopsys.com [10.12.238.230]) by mailhost.synopsys.com (Postfix) with ESMTP id D6B4B5444; Fri, 7 Dec 2018 18:28:50 -0800 (PST) Received: from US01WEHTC1.internal.synopsys.com (10.12.239.236) by US01WXQAHTC1.internal.synopsys.com (10.12.238.230) with Microsoft SMTP Server (TLS) id 14.3.408.0; Fri, 7 Dec 2018 18:28:50 -0800 Received: from te-lab16 (10.13.184.20) by us01wehtc1.internal.synopsys.com (10.12.239.236) with Microsoft SMTP Server (TLS) id 14.3.408.0; Fri, 7 Dec 2018 18:28:49 -0800 Received: by te-lab16 (sSMTP sendmail emulation); Fri, 07 Dec 2018 18:28:49 -0800 Date: Fri, 7 Dec 2018 18:28:49 -0800 Message-ID: In-Reply-To: References: From: Thinh Nguyen Subject: [PATCH v2 4/4] usb: dwc3: Enable frame number tracking based on reference clock To: Felipe Balbi , CC: John Youn MIME-Version: 1.0 X-Originating-IP: [10.13.184.20] 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 Version 1.80a of the DWC_usb31 peripheral controller introduced a feature to track the frame number based the reference clock. This patch checks and enables this feature. When operating in USB 2.0 mode, the peripheral controller uses the USB2 PHY clocks to track the frame number. This prevents the controller from suspending the USB2 PHY when the device goes into low power. This feature allows the controller to suspend the USB2 PHY when the device enters low power. This improves power saving for devices that have isochronous endpoints. Signed-off-by: Thinh Nguyen --- Changes in v2: - Revise commit message - Properly check for version and controller type drivers/usb/dwc3/core.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/dwc3/core.h | 12 ++++++++++++ 2 files changed, 63 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 32c38f71f874..38597a32cb20 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -882,6 +882,39 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, cfg); } +/** + * dwc3_enable_refclk_sof - Enable frame number tracking based on ref_clk + * @dwc: Pointer to our controller context structure + * + * Returns 0 on success, otherwise negative errno. + */ +static int dwc3_enable_refclk_sof(struct dwc3 *dwc) +{ + u8 refclk_period_ns; + u32 reg; + + reg = dwc3_readl(dwc->regs, DWC3_GUCTL); + refclk_period_ns = DWC3_GUCTL_GET_REFCLKPER(reg); + + /* Only valid for the following reference clock periods */ + switch (refclk_period_ns) { + case DWC3_GUCTL_REFCLKPER_25NS: + case DWC3_GUCTL_REFCLKPER_41NS: + case DWC3_GUCTL_REFCLKPER_50NS: + case DWC3_GUCTL_REFCLKPER_52NS: + case DWC3_GUCTL_REFCLKPER_58NS: + case DWC3_GUCTL_REFCLKPER_62NS: + break; + default: + return -EINVAL; + } + + reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); + reg |= DWC3_GFLADJ_REFCLK_FLADJ; + dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); + return 0; +} + /** * dwc3_core_init - Low-level initialization of DWC3 Core * @dwc: Pointer to our controller context structure @@ -969,6 +1002,22 @@ static int dwc3_core_init(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GUCTL, reg); } + /* + * For peripheral controller, frame number tracking based on reference + * clock is only introduced after DWC_usb31 version 1.80a. + */ + if (dwc->enable_refclk_sof && + (dwc->dr_mode != USB_DR_MODE_PERIPHERAL || + (dwc->dr_mode == USB_DR_MODE_PERIPHERAL && + dwc->revision >= DWC3_USB31_REVISION_180A))) { + ret = dwc3_enable_refclk_sof(dwc); + if (ret) { + dev_err(dwc->dev, + "can't enable ref_clk frame tracking\n"); + goto err4; + } + } + /* * ENDXFER polling is available on version 3.10a and later of * the DWC_usb3 controller. It is NOT available in the @@ -1261,6 +1310,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) "snps,usb3_lpm_capable"); dwc->usb2_lpm_disable = device_property_read_bool(dev, "snps,usb2-lpm-disable"); + dwc->enable_refclk_sof = device_property_read_bool(dev, + "snps,enable-refclk-sof"); device_property_read_u8(dev, "snps,refclk-period-ns", &dwc->refclk_period_ns); device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd", diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index e190728104e0..dae2f918a932 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -248,6 +248,14 @@ /* Global User Control Register */ #define DWC3_GUCTL_HSTINAUTORETRY BIT(14) #define DWC3_GUCTL_REFCLKPER(n) (((n) & 0x3ff) << 22) +#define DWC3_GUCTL_GET_REFCLKPER(n) (((n) & (0x3ff << 22)) >> 22) + +#define DWC3_GUCTL_REFCLKPER_25NS 25 +#define DWC3_GUCTL_REFCLKPER_41NS 41 +#define DWC3_GUCTL_REFCLKPER_50NS 50 +#define DWC3_GUCTL_REFCLKPER_52NS 52 +#define DWC3_GUCTL_REFCLKPER_58NS 58 +#define DWC3_GUCTL_REFCLKPER_62NS 62 /* Global User Control 1 Register */ #define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28) @@ -365,6 +373,7 @@ #define DWC3_GHWPARAMS7_RAM2_DEPTH(n) (((n) >> 16) & 0xffff) /* Global Frame Length Adjustment Register */ +#define DWC3_GFLADJ_REFCLK_FLADJ BIT(23) #define DWC3_GFLADJ_30MHZ_SDBND_SEL BIT(7) #define DWC3_GFLADJ_30MHZ_MASK 0x3f @@ -1020,6 +1029,7 @@ struct dwc3_scratchpad_array { * check during HS transmit. * @refclk_period_ns: if set, inform the controller this value as the reference * clock period in nanoseconds. + * @enable_refclk_sof: set to enable frame number tracking based on the ref_clk * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk * @tx_de_emphasis: Tx de-emphasis value * 0 - -6dB de-emphasis @@ -1135,6 +1145,7 @@ struct dwc3 { #define DWC3_USB31_REVISION_120A (0x3132302a | DWC3_REVISION_IS_DWC31) #define DWC3_USB31_REVISION_160A (0x3136302a | DWC3_REVISION_IS_DWC31) #define DWC3_USB31_REVISION_170A (0x3137302a | DWC3_REVISION_IS_DWC31) +#define DWC3_USB31_REVISION_180A (0x3138302a | DWC3_REVISION_IS_DWC31) u32 version_type; @@ -1192,6 +1203,7 @@ struct dwc3 { unsigned dis_start_transfer_quirk:1; unsigned usb3_lpm_capable:1; unsigned usb2_lpm_disable:1; + unsigned enable_refclk_sof:1; unsigned disable_scramble_quirk:1; unsigned u2exit_lfps_quirk:1;