From patchwork Mon Nov 8 17:09:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Peter X-Patchwork-Id: 12608893 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A824EC433FE for ; Mon, 8 Nov 2021 17:10:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 86A9561130 for ; Mon, 8 Nov 2021 17:10:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239605AbhKHRMw (ORCPT ); Mon, 8 Nov 2021 12:12:52 -0500 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:43653 "EHLO out1-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232922AbhKHRMv (ORCPT ); Mon, 8 Nov 2021 12:12:51 -0500 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id CACBA5C01B0; Mon, 8 Nov 2021 12:09:58 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Mon, 08 Nov 2021 12:09:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=svenpeter.dev; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; s=fm2; bh=Ac01M78HVVhymN796EnmiJqYFD Y+9Lkga4k+OMsqtcI=; b=QQVqrjxJksTewDwfJheHFr7xtjwamMCBS0l65m8gsB 2lGzelknadwD0QORItBLsASN5QEeOThV7YPupyo5nZ5Q+AFL0jVwwpE7XkJKNu+w fG5LvdZdg7SsgRhx3aadMMmvKfp8YmqD4s2IEmDb2VMXi9AeM4Mi0ML3SJJ7SkYX QXVO3gmb4Zr5xWxZxRKITVKQbWYwgdLJzH3HNm5qrvPZynD+X5G1eqj1VGlAznEu R7ypo2EGed15YoHtgUpT10r+hyqpcBZWiBBDJQGSb+9IChotof00tgCmhSEkP2zo AowVQzQO7mcZ+JUCnDsN/ZV2YD4hhK4aoPDrCxsKpdlA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :message-id:mime-version:subject:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=Ac01M78HVVhymN796 EnmiJqYFDY+9Lkga4k+OMsqtcI=; b=kSZa2Z/rrFyJenUy9r41JyLPg8DsnpP4J P/+MLjt05xA76fAFLIjhp+wIPwFtywFGHioqvuKov5vYN6a32hN0TA/v5i/n5RmW KCbJ8/b3nQDneJYmdzIEFFZHERgZzF7MKhUh4/PL2I/F+uq05GuQ6/ut/+H8fUFn lJVxxRFr7DXouF10jOR64XyDfBGVYsAuZVvAfr/HiVDJ/iSJTicCC4rqqy+TK0G9 XWLICHx7OK9ITcmv+cS6rlLWFvXYRWUeaQuhJ7angc2JVschOO9gsEGgWUO3p3/4 +uQhyf1LY6pCYNM0IMjm8GNrxFm96rxNN3naPH8YJ2OBqEfXeAH/A== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvuddruddvgdeliecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgggfestdekredtredttdenucfhrhhomhepufhvvghnucfrvght vghruceoshhvvghnsehsvhgvnhhpvghtvghrrdguvghvqeenucggtffrrghtthgvrhhnpe efjefgjeelveelledtiefhteetfeevudejledvieelvdejffeujeejtefgkedvudenucff ohhmrghinhepuggvvhhitggvthhrvggvrdhorhhgpdhgihhthhhusgdrtghomhenucevlh hushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehsvhgvnhesshhv vghnphgvthgvrhdruggvvh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 8 Nov 2021 12:09:56 -0500 (EST) From: Sven Peter To: Rob Herring Cc: Sven Peter , Felipe Balbi , Greg Kroah-Hartman , Hector Martin , Alyssa Rosenzweig , Mark Kettenis , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/2] dt-bindings: usb: Add Apple dwc3 bindings Date: Mon, 8 Nov 2021 18:09:45 +0100 Message-Id: <20211108170946.49689-1-sven@svenpeter.dev> X-Mailer: git-send-email 2.30.1 (Apple Git-130) MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Apple Silicon SoCs such as the M1 have multiple USB controllers based on the Synopsys DesignWare USB3 controller. References to the ATC PHY required for SuperSpeed are left out for now until support has been upstreamed as well. Signed-off-by: Sven Peter --- v1 -> v2: - added apple,dwc3 bindings instead of a property for the reset quirk as requested by robh I think I have to use GPL-2.0 for this binding since it's based on and references snps,dwc3.yaml which is also only GPL-2.0. Otherwise I'd be fine with the usual GPL/BSD dual license as well. .../devicetree/bindings/usb/apple,dwc3.yaml | 64 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 65 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/apple,dwc3.yaml diff --git a/Documentation/devicetree/bindings/usb/apple,dwc3.yaml b/Documentation/devicetree/bindings/usb/apple,dwc3.yaml new file mode 100644 index 000000000000..fb3b3489e6b2 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/apple,dwc3.yaml @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/apple,dwc3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple Silicon DWC3 USB controller + +maintainers: + - Sven Peter + +description: + On Apple Silicon SoCs such as the M1 each Type-C port has a corresponding + USB controller based on the Synopsys DesignWare USB3 controller. + + The common content of this binding is defined in snps,dwc3.yaml. + +allOf: + - $ref: snps,dwc3.yaml# + +select: + properties: + compatible: + contains: + const: apple,dwc3 + required: + - compatible + +properties: + compatible: + items: + - enum: + - apple,t8103-dwc3 + - apple,t6000-dwc3 + - const: apple,dwc3 + - const: snps,dwc3 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | + #include + #include + + usb@82280000 { + compatible = "apple,t8103-dwc3", "apple,dwc3", "snps,dwc3"; + reg = <0x82280000 0x10000>; + interrupts = ; + + dr_mode = "otg"; + usb-role-switch; + role-switch-default-mode = "host"; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 3b79fd441dde..03e7cc48877a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1724,6 +1724,7 @@ T: git https://github.com/AsahiLinux/linux.git F: Documentation/devicetree/bindings/arm/apple.yaml F: Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml +F: Documentation/devicetree/bindings/usb/apple,dwc3.yaml F: arch/arm64/boot/dts/apple/ F: drivers/irqchip/irq-apple-aic.c F: include/dt-bindings/interrupt-controller/apple-aic.h From patchwork Mon Nov 8 17:09:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Peter X-Patchwork-Id: 12608895 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7945FC433EF for ; Mon, 8 Nov 2021 17:10:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4D91661242 for ; Mon, 8 Nov 2021 17:10:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241442AbhKHRMw (ORCPT ); Mon, 8 Nov 2021 12:12:52 -0500 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:40757 "EHLO out1-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236413AbhKHRMv (ORCPT ); Mon, 8 Nov 2021 12:12:51 -0500 Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailout.nyi.internal (Postfix) with ESMTP id B20ED5C01A8; Mon, 8 Nov 2021 12:10:00 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Mon, 08 Nov 2021 12:10:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=svenpeter.dev; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm2; bh=MU0pudiomOBk1 BhCOEiNgrv+VzG0+79jlfAXlUbLYZo=; b=bBkFbRDq4FysP7uICMfwI0w0c6EIO +WnwaUzkQtM6ie6YRZMqS1lPGfYD5dORjkqYXOcMTQ89Ih/jSDDbQOQb2RzUUZR9 ol06DJLLpmExm76gfNBRYWvchFZ1QFfLDpNwlyNChZ3O7sowQR316Jx0/GNKOyNH /wLEHun4CdhPaV0WUCTJgsUAYqXvEGLO5exW45JrJ11+Pz1OjTq/DmFY1nfK2Pk7 9ALYTlIuG3Faa9oXfyMocU5pEhdoQ0QHF1ZqmhjdkrCYM9JjUBvZhnKOCU+Uba+p T6W3pj2Z9NLj8gKHjmg8b15lq7A+MUd74Xs23mnXtOGyAPUgmKxogw6cg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=MU0pudiomOBk1BhCOEiNgrv+VzG0+79jlfAXlUbLYZo=; b=fDRtFySg t9CONshaSQzNUsOm/tixzxcHwGCBepagPWJJ+urs9YwbbMaMsBHB1kN4NxYBYDKw DaxBXxfql0uPyXaTTZxTLXP7WEg4oXEbtIRRGRKmu1nFG90hNgUSFKl2fDAQZNV+ nRNJ2fX/UwtSCElg3zJuPLEAV/T/oJO5fyO98z7ftCEM9+A8tgftkBp5zaALFsUU N25Um3WoZs8pgWQ2xXOI/TzhtVIVNdL0IF6GR+FxH9AbwLUmfpPgDttjqO14naOo KtVT1vTh+ng2uNbdH1J7mogWpstKwMNlfk8PQbrZAqJ2ztG5ivtRR4xxsn3xBNXN crD3+mZaAvd3IA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvuddruddvgdeliecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepufhvvghnucfr vghtvghruceoshhvvghnsehsvhgvnhhpvghtvghrrdguvghvqeenucggtffrrghtthgvrh hnpeetvdekteeluefffffhkeetteffgefggfevheeileeufedvtdeuffevveelhfefjeen ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehsvhgvnh esshhvvghnphgvthgvrhdruggvvh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 8 Nov 2021 12:09:58 -0500 (EST) From: Sven Peter To: Felipe Balbi Cc: Sven Peter , Greg Kroah-Hartman , Hector Martin , Alyssa Rosenzweig , Mark Kettenis , Rob Herring , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/2] usb: dwc3: Add role switch reset quirk for Apple DWC3 Date: Mon, 8 Nov 2021 18:09:46 +0100 Message-Id: <20211108170946.49689-2-sven@svenpeter.dev> X-Mailer: git-send-email 2.30.1 (Apple Git-130) In-Reply-To: <20211108170946.49689-1-sven@svenpeter.dev> References: <20211108170946.49689-1-sven@svenpeter.dev> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org As mad as it sounds, the dwc3 controller present on Apple SoCs must be reset and reinitialized whenever a device is unplugged from the root port and triggers a role switch notification from the USB PD controller. This is required for at least two reasons: - The USB2 D+/D- lines are connected through a stateful eUSB2 repeater which in turn is controlled by a variant of the TI TPS6598x USB PD chip. When the USB PD controller detects a hotplug event it resets the eUSB2 repeater. Afterwards, no new device is recognized before the DWC3 core and PHY are reset as well. - It's possible to completely break the dwc3 controller by switching it to device mode and unplugging the cable at just the wrong time. Even a CORESOFTRESET is not enough to allow new devices again. The only workaround is to trigger a hard reset of the entire dwc3 core. This also happens when running macOS on these machines. Signed-off-by: Sven Peter Tested-by: Janne Grunau --- v1 -> v2: - enable the quirk based on the compatible instead of a property as requested by robh drivers/usb/dwc3/core.c | 39 ++++++++++++++++++++++++++++++++++++--- drivers/usb/dwc3/core.h | 6 ++++++ drivers/usb/dwc3/drd.c | 7 +++++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 0104a80b185e..b76d7536eafe 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -115,6 +115,8 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode) } static int dwc3_core_soft_reset(struct dwc3 *dwc); +static void dwc3_core_exit(struct dwc3 *dwc); +static int dwc3_core_init_for_resume(struct dwc3 *dwc); static void __dwc3_set_mode(struct work_struct *work) { @@ -130,10 +132,11 @@ static void __dwc3_set_mode(struct work_struct *work) if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG) dwc3_otg_update(dwc, 0); - if (!dwc->desired_dr_role) + if (!dwc->desired_dr_role && !dwc->role_switch_reset_quirk) goto out; - if (dwc->desired_dr_role == dwc->current_dr_role) + if (dwc->desired_dr_role == dwc->current_dr_role && + !dwc->role_switch_reset_quirk) goto out; if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev) @@ -158,6 +161,34 @@ static void __dwc3_set_mode(struct work_struct *work) break; } + if (dwc->role_switch_reset_quirk) { + if (dwc->current_dr_role) { + dwc->current_dr_role = 0; + dwc3_core_exit(dwc); + } + + if (dwc->desired_dr_role) { + /* + * the first call to __dwc3_set_mode comes from + * dwc3_drd_init. In that case dwc3_core_init has been + * called but dwc->current_dr_role is zero such that + * we must not reinitialize the core again here. + */ + if (dwc->role_switch_reset_quirk_initialized) { + ret = dwc3_core_init_for_resume(dwc); + if (ret) { + dev_err(dwc->dev, + "failed to reinitialize core\n"); + goto out; + } + } + + dwc->role_switch_reset_quirk_initialized = 1; + } else { + goto out; + } + } + /* For DRD host or device mode only */ if (dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) { reg = dwc3_readl(dwc->regs, DWC3_GCTL); @@ -1586,6 +1617,8 @@ static int dwc3_probe(struct platform_device *pdev) else dwc->num_clks = ret; + if (of_device_is_compatible(dev->of_node, "apple,dwc3")) + dwc->role_switch_reset_quirk = true; } ret = reset_control_deassert(dwc->reset); @@ -1715,7 +1748,6 @@ static int dwc3_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM static int dwc3_core_init_for_resume(struct dwc3 *dwc) { int ret; @@ -1742,6 +1774,7 @@ static int dwc3_core_init_for_resume(struct dwc3 *dwc) return ret; } +#ifdef CONFIG_PM static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) { unsigned long flags; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 5612bfdf37da..3fc5c5bc4c57 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1080,6 +1080,9 @@ struct dwc3_scratchpad_array { * 3 - Reserved * @dis_metastability_quirk: set to disable metastability quirk. * @dis_split_quirk: set to disable split boundary. + * @role_switch_reset_quirk: set to force reinitialization after any role switch + * @role_switch_reset_quirk_initialized: set to true after the first role switch + * which is triggered from dwc3_drd_init directly * @imod_interval: set the interrupt moderation interval in 250ns * increments or 0 to disable. * @max_cfg_eps: current max number of IN eps used across all USB configs. @@ -1291,6 +1294,9 @@ struct dwc3 { unsigned dis_split_quirk:1; unsigned async_callbacks:1; + unsigned role_switch_reset_quirk:1; + unsigned role_switch_reset_quirk_initialized:1; + u16 imod_interval; int max_cfg_eps; diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c index d7f76835137f..403e88a72f0e 100644 --- a/drivers/usb/dwc3/drd.c +++ b/drivers/usb/dwc3/drd.c @@ -506,6 +506,9 @@ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw, break; } + if (dwc->role_switch_reset_quirk && role == USB_ROLE_NONE) + mode = 0; + dwc3_set_mode(dwc, mode); return 0; } @@ -534,6 +537,10 @@ static enum usb_role dwc3_usb_role_switch_get(struct usb_role_switch *sw) role = USB_ROLE_DEVICE; break; } + + if (dwc->role_switch_reset_quirk && !dwc->current_dr_role) + role = USB_ROLE_NONE; + spin_unlock_irqrestore(&dwc->lock, flags); return role; }