From nobody Thu Dec 18 12:51:08 2025 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 74D3528AB0C; Wed, 7 May 2025 13:08:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746623295; cv=pass; b=G418T4YqKst8O4JX07kqWj1as5YPWNd295gA95BVcw4JPIwQb3JCmOM+g0lxYLCOlaXRx2YYmrYRSATXwRXEQ3Y2sFxTjHVQboYkF6nJdY7qqtkDrfWFlnKke3iqfru5AyZ0aqqlvQjxU0GDKOElM9VEUyFKnYzqVReBAevmXNE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746623295; c=relaxed/simple; bh=VW4aB7Eci+66CKEdrWizM7NfU5WhMJaGMzLxapw8WDg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HforumwY2zM+Nu3n4C1Jc22G8lgCwOYnz96YOx50XzYAcHQeexI57rtUpMZzHncnikI1L5UCvfuKirfaRgw2YJSd1RoMhL8qoDUfKhM/h81ley8SR8jDco5MYTTLbDUPH9pGY1w7Ewr9gIQSXEtvOD8fm/EDaRGkWu+0CsPQ3MQ= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b=JMlYb0/Z; arc=pass smtp.client-ip=136.143.188.112 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="JMlYb0/Z" ARC-Seal: i=1; a=rsa-sha256; t=1746623266; cv=none; d=zohomail.com; s=zohoarc; b=Wis9voALlCGx1G3zRE6fd7kgqLT1nRdkT2lhV3GCXwb7q52/sxWJSnJYZPrRe8emZHEcGkoCl9VsHw+nGhhVXEZyHMqcO0aL2CJCAcYa2ay2wziB+umk2ppPDNLJTFUKmWiG9PNWycZSaZ836XOqm8/sR9zwkXg64Oit1QR7zJs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1746623266; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=JTB3v+x8w/FUL8jly8m0hmcJty/2pFiwNyr1NhvSBfc=; b=P+Vg/Ic03Hdxv6xu4C6BrXO3noHQqsiUP4oG4249maL/tdEj2Wyy14TtiHsuAYHap1+yYeNRACbkgjolkWF/tIwT/Pzb/Txh1soKFeEiQQ7pGeSuA3PYQnE1awSYwnPpL9rORpoCIZxUUsuzyXFtQm87/3NCrjo9DztOACa1bJ4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1746623266; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=JTB3v+x8w/FUL8jly8m0hmcJty/2pFiwNyr1NhvSBfc=; b=JMlYb0/ZPABoXpa8LTtqCfcotGKCLxCZO/LCzyfs8IqBsWA/WyEfdAIWkZ7XgrYR nIRVbg7rRV3Dg2HJXPonVVE8T+1yvarx57m6T6r2mTkueS29LQTxx1PFBDJSqO2H13n PoeW8K5ssMMPBMftVt+LBwSUbP6SBZr9jTq7aFaU= Received: by mx.zohomail.com with SMTPS id 1746623264940513.8779431523127; Wed, 7 May 2025 06:07:44 -0700 (PDT) From: Nicolas Frattaroli Date: Wed, 07 May 2025 15:07:23 +0200 Subject: [PATCH v3 3/4] phy: rockchip: usbdp: reset USB3 and reinit on orientation switch Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250507-rk3576-sige5-usb-v3-3-89bf5a614ccf@collabora.com> References: <20250507-rk3576-sige5-usb-v3-0-89bf5a614ccf@collabora.com> In-Reply-To: <20250507-rk3576-sige5-usb-v3-0-89bf5a614ccf@collabora.com> To: Vinod Koul , Kishon Vijay Abraham I , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Kever Yang , Frank Wang Cc: Sebastian Reichel , kernel@collabora.com, linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.2 Until now, super speed on Type-C only worked in one orientation. This is because on an orientation switch, the UDPHY was never reinitialised. Heiko presented a patch to do this[1], but there were concerns over the correctness of it[2]. Experimentally using Heiko's patch on RK3576 did make me run into issues, though they seemed to be related to the orientation switch actually happening while a clock driving a GRF register was disabled. The key issue is that the hardware wants the USB 3 controller to be held in reset while the PHY is being reconfigured, otherwise we may run into hard-to-catch race conditions. Either way, this patch implements the required ordering in a somewhat unpleasant way: we get the USB 3 controller from the DT, and use runtime power management to forcibly suspend it while the UDPHY is being reconfigured, and then forcibly resume it later. As an added pain in the rear, the suspend/resume of the USB 3 controller also tries fiddling with the USB 3 PHY part of the UDPHY, which means we introduce an atomic flag to skip suspending/resuming the UDPHY if we're resetting the USB 3 controller. We may just need to skip trying to acquire the mutex again, but both ways work for me in practice. This solution may in fact be complete rubbish, but it works to get USB 3 Super Speed working in both cable orientations on my board. Link: https://lore.kernel.org/all/20250226103810.3746018-3-heiko@sntech.de/= [1] Link: https://lore.kernel.org/linux-rockchip/h57ok2hw6os7bcafqkrqknfvm7hnu2= 5m2oe54qmrsuzdwqlos3@m4och2fcdm7s/ [2] Signed-off-by: Nicolas Frattaroli --- drivers/phy/rockchip/phy-rockchip-usbdp.c | 54 +++++++++++++++++++++++++++= ++++ 1 file changed, 54 insertions(+) diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockch= ip/phy-rockchip-usbdp.c index fff54900feea601c8fe6bf4c7123dfebc5661a15..5cd6bbc367f69bca15c2a94a07e= 72f850b381ae3 100644 --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c @@ -200,6 +200,10 @@ struct rk_udphy { /* PHY devices */ struct phy *phy_dp; struct phy *phy_u3; + + /* USB 3 controller device */ + struct device *ctrl_u3; + atomic_t ctrl_resetting; }; =20 static const struct rk_udphy_dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_rbr_hbr[= 4][4] =3D { @@ -1255,6 +1259,9 @@ static int rk_udphy_usb3_phy_init(struct phy *phy) struct rk_udphy *udphy =3D phy_get_drvdata(phy); int ret =3D 0; =20 + if (atomic_read(&udphy->ctrl_resetting)) + return 0; + mutex_lock(&udphy->mutex); /* DP only or high-speed, disable U3 port */ if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs) { @@ -1273,6 +1280,9 @@ static int rk_udphy_usb3_phy_exit(struct phy *phy) { struct rk_udphy *udphy =3D phy_get_drvdata(phy); =20 + if (atomic_read(&udphy->ctrl_resetting)) + return 0; + mutex_lock(&udphy->mutex); /* DP only or high-speed */ if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs) @@ -1401,10 +1411,31 @@ static struct phy *rk_udphy_phy_xlate(struct device= *dev, const struct of_phandl return ERR_PTR(-EINVAL); } =20 +static struct device_node *rk_udphy_to_controller(struct rk_udphy *udphy) +{ + struct device_node *np; + + for_each_node_with_property(np, "phys") { + struct of_phandle_iterator it; + int ret; + + of_for_each_phandle(&it, ret, np, "phys", NULL, 0) { + if (it.node !=3D udphy->dev->of_node) + continue; + + of_node_put(it.node); + return np; + } + } + + return NULL; +} + static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw, enum typec_orientation orien) { struct rk_udphy *udphy =3D typec_switch_get_drvdata(sw); + int ret; =20 mutex_lock(&udphy->mutex); =20 @@ -1420,6 +1451,18 @@ static int rk_udphy_orien_sw_set(struct typec_switch= _dev *sw, rk_udphy_set_typec_default_mapping(udphy); rk_udphy_usb_bvalid_enable(udphy, true); =20 + if (udphy->status !=3D UDPHY_MODE_NONE && udphy->ctrl_u3) { + atomic_set(&udphy->ctrl_resetting, 1); + pm_runtime_force_suspend(udphy->ctrl_u3); + + ret =3D rk_udphy_setup(udphy); + if (!ret) + clk_bulk_disable_unprepare(udphy->num_clks, udphy->clks); + + pm_runtime_force_resume(udphy->ctrl_u3); + atomic_set(&udphy->ctrl_resetting, 0); + } + unlock_ret: mutex_unlock(&udphy->mutex); return 0; @@ -1430,12 +1473,22 @@ static void rk_udphy_orien_switch_unregister(void *= data) struct rk_udphy *udphy =3D data; =20 typec_switch_unregister(udphy->sw); + put_device(udphy->ctrl_u3); } =20 static int rk_udphy_setup_orien_switch(struct rk_udphy *udphy) { + struct device_node *ctrl =3D rk_udphy_to_controller(udphy); struct typec_switch_desc sw_desc =3D { }; =20 + if (ctrl) { + udphy->ctrl_u3 =3D bus_find_device_by_of_node(udphy->dev->bus, ctrl); + of_node_put(ctrl); + } + + if (!udphy->ctrl_u3) + dev_info(udphy->dev, "couldn't find this PHY's USB3 controller\n"); + sw_desc.drvdata =3D udphy; sw_desc.fwnode =3D dev_fwnode(udphy->dev); sw_desc.set =3D rk_udphy_orien_sw_set; @@ -1499,6 +1552,7 @@ static int rk_udphy_probe(struct platform_device *pde= v) return ret; =20 mutex_init(&udphy->mutex); + atomic_set(&udphy->ctrl_resetting, 0); platform_set_drvdata(pdev, udphy); =20 if (device_property_present(dev, "orientation-switch")) { --=20 2.49.0