From nobody Fri Sep 25 21:40:20 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 4DB913A3E8C; Tue, 8 Sep 2026 07:54:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788854067; cv=none; b=OUSVJ5aiCnFQ4PW5wlWKDY/kipIB76IF4PUbCAbSvCsGOF9dduCCvPeMNB59R8P2bYd5mnV24pmv3qKwcO4H79Dgdu8IdsUuHxeiVO943c44u33u5emTxyzpdI+CCqEYFgTQD8rxn8M1pPKwgbpyB+fxDIt/QF2D0FP4khBEzh4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788854067; c=relaxed/simple; bh=ZTbrFbcZbwqV6X0pAC6SDmsRQ5lbf4n5kQVqt++PbVg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dh86zh2o+dg1I919cVM61ux08L6c3kNNl04Rsf7ennJjWiifRIBLZ79c7ai6drhOKtTW+7SV3ruKe6bLo7Yz1WoSAG0ps3mX/3C4NCRYyM8v1S0rnF5diwCk1abL1Kwk4aCb/Wr5KBmnSKpZ+k0oahrU2T5hzYe0Z2c3xLMgtGE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=e+cs5oH7; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="e+cs5oH7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1D0BB1F00A3E; Tue, 8 Sep 2026 07:54:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788854065; bh=HVvXYZHM/m8ynyTJN/l0O4HhP3zJLvT4O3YsJI9ghxE=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=e+cs5oH7//czkiQtAJftmfaK63NbTR/okl1pt3FTQVhkW/+cXNqAYQgQ7FIKlyhWL 3fj1YHX0DDVK+jRudNfbMWLE0cdLm93QKMvuMyMQ1VzUnmxdzlI6SleqFCl7RoI5vp 2uAh+tLoGEcpl2REonleaI/QYRmF9uU4WzXwHMMN1X7y6/G4qUktCqc3KpwxTUtNso +CWJ2ddzvxDue4eLCU1zB0qKxgejSmFZMBmAxsNLmtX7hBgPXa0ud97uFkf5T7Um2u UILhRe1xQjuoAz3xFL6+Jjc6BN6JP7TgsxyFCD2QTU3mGz3LtH5gknA0n8INh4qq9n 9RCgj/TD1r1bw== From: Konrad Dybcio Date: Tue, 08 Sep 2026 09:54:05 +0200 Subject: [PATCH v5 1/5] dt-bindings: phy: qcom,qmp-usb3-dp: Extend X1E description for USB4 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: <20260908-topic-usb4phy-v5-1-73aac69578ef@oss.qualcomm.com> References: <20260908-topic-usb4phy-v5-0-73aac69578ef@oss.qualcomm.com> In-Reply-To: <20260908-topic-usb4phy-v5-0-73aac69578ef@oss.qualcomm.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam Cc: linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, usb4-upstream@oss.qualcomm.com, Raghavendra Thoorpu , Mika Westerberg , Sven Peter , Konrad Dybcio , Krzysztof Kozlowski , Manivannan Sadhasivam X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788854054; l=3476; i=konrad.dybcio@oss.qualcomm.com; s=20230215; h=from:subject:message-id; bh=/ttJwCXk6D832t5qMZlO9Nw3aJA1EFXBUMTLzeBgQc0=; b=2c+VctWte3n71f03+UtnpBspq0+RPCByGId5TWQdXziaWxAv2jkHTWmKMnze91QQ/2jleBb8X uFl7W4xKv4vCrAdXmh5Rz1+0wbaT/aIqvZq37iKRIdsIq9MOI8NUeaJ X-Developer-Key: i=konrad.dybcio@oss.qualcomm.com; a=ed25519; pk=iclgkYvtl2w05SSXO5EjjSYlhFKsJ+5OSZBjOkQuEms= From: Konrad Dybcio Some instances of the QMP combo PHY (called USB43DP) feature a third functional sub-block, responsible for USB4/Thunderbolt 3 communication. Compared to the today's state of the binding, one more clock (P2RR2P - PHY-to-Router, Router-to-PHY) needs to be enabled for the PHY to be able to switch to USB4 mode. Allow that for X1E. Also, add a bindings define to let consumers access it. Assisted-by: Claude:sonnet-5 Reviewed-by: Krzysztof Kozlowski Acked-by: Manivannan Sadhasivam Signed-off-by: Konrad Dybcio --- .../phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml | 55 +++++++++++++++++-= ---- include/dt-bindings/phy/phy-qcom-qmp.h | 1 + 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43d= p-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43d= p-phy.yaml index 8adfc78108fe..94a4fbff428f 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.y= aml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.y= aml @@ -53,12 +53,7 @@ properties: =20 clock-names: minItems: 4 - items: - - const: aux - - const: ref - - const: com_aux - - const: usb3_pipe - - const: cfg_ahb + maxItems: 5 =20 power-domains: maxItems: 1 @@ -189,21 +184,59 @@ allOf: - if: properties: compatible: - enum: - - qcom,sc7180-qmp-usb3-dp-phy - - qcom,sdm845-qmp-usb3-dp-phy + contains: + enum: + - qcom,x1e80100-qmp-usb3-dp-phy then: properties: clocks: maxItems: 5 clock-names: + items: + - const: aux + - const: ref + - const: com_aux + - const: usb3_pipe + - const: p2rr2p_pipe + + - if: + properties: + compatible: + contains: + enum: + - qcom,sc7180-qmp-usb3-dp-phy + - qcom,sdm845-qmp-usb3-dp-phy + then: + properties: + clocks: maxItems: 5 - else: + clock-names: + items: + - const: aux + - const: ref + - const: com_aux + - const: usb3_pipe + - const: cfg_ahb + + - if: + not: + properties: + compatible: + contains: + enum: + - qcom,x1e80100-qmp-usb3-dp-phy + - qcom,sc7180-qmp-usb3-dp-phy + - qcom,sdm845-qmp-usb3-dp-phy + then: properties: clocks: maxItems: 4 clock-names: - maxItems: 4 + items: + - const: aux + - const: ref + - const: com_aux + - const: usb3_pipe =20 - if: properties: diff --git a/include/dt-bindings/phy/phy-qcom-qmp.h b/include/dt-bindings/p= hy/phy-qcom-qmp.h index 6b43ea9e0051..1c3ce0c02b0c 100644 --- a/include/dt-bindings/phy/phy-qcom-qmp.h +++ b/include/dt-bindings/phy/phy-qcom-qmp.h @@ -16,6 +16,7 @@ /* QMP USB4-USB3-DP PHYs */ #define QMP_USB43DP_USB3_PHY 0 #define QMP_USB43DP_DP_PHY 1 +#define QMP_USB43DP_USB4_PHY 2 =20 /* QMP PCIE PHYs */ #define QMP_PCIE_PIPE_CLK 0 --=20 2.55.0 From nobody Fri Sep 25 21:40:20 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 465C83A75BB; Tue, 8 Sep 2026 07:54:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788854072; cv=none; b=YULAFFPtM8ZrZkdXfjBJ6Dlzd3Dk8PIZwer+K8b0wVOpJEhJ79imEkpzHg6LjQHOPWzG1agzVBLK3JUtupU0XLLl4F6QvZyLSoh1un/Tu5z34N3YuQny9Zp7hZUqim1aRaZ4eSxmSAMpgyMiNUE97fsPhG0FuPgA4vJkexh5a9M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788854072; c=relaxed/simple; bh=E9yMmleXOTM9DrTMSOmecTwJucO7kDBC3W1TZzoR0hc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NfOVoWYkRzqP88BR912023uCGGuiy3w1N+MumczyneurtV8gN7bWa+LIgMt9uFgDzAlBBeKtyzCZmlbLzpGTfm/P/bpYLQkRE55x21qmyy2u0RKfXmzXLPicawAwAERBvN89tkpfC3a+vCJ71llTs/H7ONyRa0t36wBolPxw7IU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=atj82x0J; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="atj82x0J" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6A4371F00A3A; Tue, 8 Sep 2026 07:54:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788854070; bh=aHh8YnkpdvGLGzXjrKPt+ZqsL8ZCEOOEbyoUUXuCA0o=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=atj82x0J6FZcnPOO9V2QBFrZVMLnXV6+L7gRTrxJCDFWwGLuKskR9FYkcO99T2tY6 Av39A1LR01EvQY6lk96zHGh+3Awo+RF4RqzElWvJVzqL8s/rBmSOwWBQWj24LpJNjg 9x34/qhMzybjs8ltW2tOYha6//AYSZz8ng8zklI+29JfT26RaiBgl/QfORB5CrDEbL GgCxniKm4TEH3nwgNsDYY6nbHGbHFcyqCUWEYk3shIfdHDUUE1xtnq9y/qJq96zpIJ lMR6+G4+uUO29CZ2XnPI5GkxIq/sdttn+p98b0t6DPRSLUUqPnM1vyYqZie9kgFRtX R0nWdh2xvy21A== From: Konrad Dybcio Date: Tue, 08 Sep 2026 09:54:06 +0200 Subject: [PATCH v5 2/5] phy: core: Define TBT phy_mode 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: <20260908-topic-usb4phy-v5-2-73aac69578ef@oss.qualcomm.com> References: <20260908-topic-usb4phy-v5-0-73aac69578ef@oss.qualcomm.com> In-Reply-To: <20260908-topic-usb4phy-v5-0-73aac69578ef@oss.qualcomm.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam Cc: linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, usb4-upstream@oss.qualcomm.com, Raghavendra Thoorpu , Mika Westerberg , Sven Peter , Konrad Dybcio , Dmitry Baryshkov , Manivannan Sadhasivam X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788854054; l=1957; i=konrad.dybcio@oss.qualcomm.com; s=20230215; h=from:subject:message-id; bh=DA0DJZNhVBAei58r6kWRym01jHw8XXps7yp+Nt6anW4=; b=pqWCXETOl9wgh85URVM7rBQfJCqCz7QdX+LklhlehiaqCPqzN6B36KQi9M8BnAZiMwmqNKez7 ZeZ9szP9WUYAEjhCVP1fxLL/zzhdeuhvnNtkVENBVcvlTncN0Cb6zxH X-Developer-Key: i=konrad.dybcio@oss.qualcomm.com; a=ed25519; pk=iclgkYvtl2w05SSXO5EjjSYlhFKsJ+5OSZBjOkQuEms= From: Konrad Dybcio There exist OS-accessible USB4 and Thunderbolt PHYs that need specific configuration. Define a new phy_mode for them. Currently, USB4 and TBT3 are defined as submodes, because they're quite distinct, most visibly in the electrical/analog aspects (slightly different frequencies, timings, etc.). This results in a need to make the PHY aware of the actual mode needed (at least in the Qualcomm implementation, but I believe that'll be a general need). Newer versions of TBT are basically supersets of USB4 with higher host-side requirements, so these are not defined. This can always be changed as necessary. Reviewed-by: Dmitry Baryshkov Reviewed-by: Manivannan Sadhasivam Signed-off-by: Konrad Dybcio --- include/linux/phy/phy-thunderbolt.h | 14 ++++++++++++++ include/linux/phy/phy.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/include/linux/phy/phy-thunderbolt.h b/include/linux/phy/phy-th= underbolt.h new file mode 100644 index 000000000000..5f48059814e1 --- /dev/null +++ b/include/linux/phy/phy-thunderbolt.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __PHY_TBT_H_ +#define __PHY_TBT_H_ + +enum tbt_phy_submode { + PHY_SUBMODE_TBT3, + PHY_SUBMODE_USB4, +}; + +#endif diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index ea47975e288a..3a2ace2cadff 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -20,6 +20,7 @@ #include #include #include +#include =20 struct phy; =20 @@ -45,6 +46,7 @@ enum phy_mode { PHY_MODE_LVDS, PHY_MODE_DP, PHY_MODE_HDMI, + PHY_MODE_TBT, }; =20 enum phy_media { --=20 2.55.0 From nobody Fri Sep 25 21:40:20 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 65C023A6407; Tue, 8 Sep 2026 07:54:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788854078; cv=none; b=Dnia8pmCXxMKN6sfYSfE5BYqbkTFCp8qlTojtdhjsRcOO5Rf6Y8MmWYOiLGqAGBmTW/23r+SNPpE196qF84Em0o+TTn/s+gd72Atv4NP3uZIYiuLx4VdWEPfGcrQVE33cP4x/6QHjRwJSluKUYEJvDOtvqT3SR8RSh52FLKkH/w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788854078; c=relaxed/simple; bh=DBIpCJqPx7bvd4ficNp49WRI2KRXKIN+ojok+rAMBOA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TOk9nnyLjuDOmJaIZwnVT1TgTWVgh70zM9jiduYy+HDFnK4u7PUWWA5PBFlnN+OoAvVL0KMTR6dsVJU8RfkMxKfqmFmqCT19H4Gx8XfveCQ7sQy0nBqvmeqHUBvdzavt9WCnbyhBeK/KyKaS5ooH3LCtgPdUJzyrD/ys6qC7xIE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KqC+VCd8; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KqC+VCd8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 56A831F00A3D; Tue, 8 Sep 2026 07:54:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788854076; bh=tsnyn5UlyRyISNSIZ2F9Ufco6GI9pmhcEQO0hBWK9fM=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=KqC+VCd8ZPw6cgq71s1vdMUkVN8RFJUFVhJFVU4yafSP4TE1Uyp43mCY9al2Fwd3O BCBwQgfVcBsNpDd849Pgc3X/eRel+FSeP2arwbSRBugsZEa0yIdK8HRpFum1mN/DHW KHRq7kNLs4FBtMRNSenZBMeQod9z33l+/CYIAtK/HvqNmJ2I3ZTpJbC2+iFW4btZph lY2F7t+s2SElcYT7YIo+5rqBeIjLvnVLMpaF81KoXlnyKX2mhTU2MBsKPORe3eQV4P eDGK84vl50GOLbYCqbf6TKmf3HvLwv5hccrQ0taUH70WmgrxQiKqF2OhoAaiTvImw4 34MwoSLPZXA8g== From: Konrad Dybcio Date: Tue, 08 Sep 2026 09:54:07 +0200 Subject: [PATCH v5 3/5] phy: qualcomm: qmp-combo: Add preliminary USB4 support 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: <20260908-topic-usb4phy-v5-3-73aac69578ef@oss.qualcomm.com> References: <20260908-topic-usb4phy-v5-0-73aac69578ef@oss.qualcomm.com> In-Reply-To: <20260908-topic-usb4phy-v5-0-73aac69578ef@oss.qualcomm.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam Cc: linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, usb4-upstream@oss.qualcomm.com, Raghavendra Thoorpu , Mika Westerberg , Sven Peter , Konrad Dybcio , Abel Vesa , Dmitry Baryshkov , Manivannan Sadhasivam X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788854054; l=23528; i=konrad.dybcio@oss.qualcomm.com; s=20230215; h=from:subject:message-id; bh=fnknFqzW/zLt6F4v/dqvCnBhIB8E5GOcfbVwDw/xGBQ=; b=FcfsLxluWrK7LhuF5MHn8P9udwjJ/xrWH0kDQEvNO6JcAEf5P45f1DD/omTEtGpmEpAA6Md1l 5D0k9AAI+T3AmPgFPba9ho/tO3R1OdlEBs2gyIFgfwJXmjOSYqw9rtK X-Developer-Key: i=konrad.dybcio@oss.qualcomm.com; a=ed25519; pk=iclgkYvtl2w05SSXO5EjjSYlhFKsJ+5OSZBjOkQuEms= From: Konrad Dybcio Some Combo PHYs (so far only on SC8280XP, X1E80100 and Glymur), come in a flavor called USB43DP, which as the name implies, features USB4, USB3 and DP signal processing capabilities. In that architecture, USB3 and USB4 PHYs share the same USB_PLL while featuring separate logic spaces. The DP part is roughly the same as on the instances without USB4. The USB4 and USB3/DP operation modes of the PHY are mutually exclusive. Only one USB protocol (and flavor of pipe clock) can be active at a given moment (not to be confused with USB3 not being able to be tunneled as USB4 packets - that of course remains possible). The DP PLL is still used for clocking tunneled DP links. It may be turned off to save power when no tunnels are active, but that's left as a TODO item for now. Due to the nature of USB4, the Type-C handling happens entirely inside the Host Router, and as such the QMPPHY's mux_set() function is nullified for the period when USB4 PHY remains active. This is strictly necessary, as the Host Router driver is going to excercise manual control over the USB4 PHY's power state, which is needed by the suspend and resume flows. Failure to control that synchronously with other parts of the code results in a SoC crash by unlocked access. Because of that, a new struct phy is spawned to expose the USB4 mode, along with a .set_mode callback to allow toggling between USB4 and TBT3 submodes. Thunderbolt 3, having a number of differences vs USB4, requires a couple specific overrides, pertaining to electrical characteristics, which are easily accommodated for. Reviewed-by: Abel Vesa Reviewed-by: Dmitry Baryshkov Reviewed-by: Manivannan Sadhasivam Signed-off-by: Konrad Dybcio --- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 402 ++++++++++++++++++++++++--= ---- 1 file changed, 332 insertions(+), 70 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualco= mm/phy-qcom-qmp-combo.c index c39ced168d03..a4f130fc33e3 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -22,6 +22,7 @@ #include #include #include +#include =20 #include =20 @@ -66,10 +67,14 @@ #define SW_USB3PHY_RESET BIT(2) /* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */ #define SW_USB3PHY_RESET_MUX BIT(3) +#define SW_USB4PHY_RESET BIT(4) +#define SW_USB4PHY_RESET_MUX BIT(5) =20 /* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */ #define USB3_MODE BIT(0) /* enables USB3 mode */ #define DP_MODE BIT(1) /* enables DP mode */ +#define USB4_MODE BIT(2) /* mutually exclusive with the above */ +#define DP_TUNNELING_CLOCK_GEN_EN BIT(3) =20 /* QPHY_V3_DP_COM_TYPEC_CTRL register bits */ #define SW_PORTSELECT_VAL BIT(0) @@ -82,6 +87,8 @@ enum qmpphy_mode { QMPPHY_MODE_USB3DP =3D 0, QMPPHY_MODE_DP_ONLY, QMPPHY_MODE_USB3_ONLY, + /* USB4 QMPPHY mode refers to both USB4 and TBT3 */ + QMPPHY_MODE_USB4, }; =20 /* set of registers with offsets different per-PHY */ @@ -94,6 +101,7 @@ enum qphy_reg_layout { QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR, QPHY_PCS_POWER_DOWN_CONTROL, QPHY_PCS_CLAMP_ENABLE, + QPHY_PCS_USB4_CLAMP_ENABLE, =20 QPHY_COM_RESETSM_CNTRL, QPHY_COM_C_READY_STATUS, @@ -2489,6 +2497,8 @@ struct qmp_combo_offsets { u16 dp_txb; u16 dp_dp_phy; u16 aon_toggle; + u16 usb4_serdes; + u16 usb4_pcs; }; =20 struct qmp_phy_cfg { @@ -2536,6 +2546,18 @@ struct qmp_phy_cfg { int (*calibrate_dp_phy)(struct qmp_combo *qmp); void (*dp_aux_init)(struct qmp_combo *qmp); =20 + /* USB4 specifics */ + const struct qmp_phy_init_tbl *usb4_serdes_tbl; + int usb4_serdes_tbl_num; + const struct qmp_phy_init_tbl *usb4_serdes_tb3_ovrd_tbl; + int usb4_serdes_tb3_ovrd_num; + const struct qmp_phy_init_tbl *usb4_tx_tbl; + int usb4_tx_tbl_num; + const struct qmp_phy_init_tbl *usb4_rx_tbl; + int usb4_rx_tbl_num; + const struct qmp_phy_init_tbl *usb4_pcs_tbl; + int usb4_pcs_tbl_num; + /* resets to be requested */ const char * const *reset_list; int num_resets; @@ -2578,8 +2600,12 @@ struct qmp_combo { void __iomem *dp_tx2; void __iomem *dp_dp_phy; =20 + void __iomem *usb4_serdes; + void __iomem *usb4_pcs; + struct clk *pipe_clk; struct clk_bulk_data *clks; + struct clk *p2rr2p_pipe_clk; int num_clks; struct reset_control_bulk_data *resets; struct regulator_bulk_data *vregs; @@ -2598,6 +2624,10 @@ struct qmp_combo { unsigned int dp_init_count; bool dp_powered_on; =20 + struct phy *usb4_phy; + enum tbt_phy_submode usb4_phy_submode; + unsigned int usb4_init_count; + struct clk_fixed_rate pipe_clk_fixed; struct clk_hw dp_link_hw; struct clk_hw dp_pixel_hw; @@ -4006,6 +4036,9 @@ static int qmp_combo_dp_calibrate(struct phy *phy) static int qmp_combo_com_init(struct qmp_combo *qmp, bool force) { const struct qmp_phy_cfg *cfg =3D qmp->cfg; + u32 dp_reset_val =3D SW_DPPHY_RESET_MUX | SW_DPPHY_RESET; + void __iomem *pcs_aon =3D qmp->pcs_aon; + void __iomem *pcs =3D qmp->pcs; void __iomem *com =3D qmp->com; void __iomem *aon_toggle; int ret; @@ -4019,6 +4052,16 @@ static int qmp_combo_com_init(struct qmp_combo *qmp,= bool force) else aon_toggle =3D qmp->pcs_aon; =20 + if (qmp->qmpphy_mode =3D=3D QMPPHY_MODE_USB4) { + pcs =3D qmp->usb4_pcs; + + qphy_setbits(pcs_aon, cfg->regs[QPHY_PCS_USB4_CLAMP_ENABLE], CLAMP_EN); + + /* Do not disturb the DP PLL in case there's an active DP tunnel */ + if (readl(com + QPHY_V3_DP_COM_RESET_OVRD_CTRL) & DP_TUNNELING_CLOCK_GEN= _EN) + dp_reset_val &=3D ~SW_DPPHY_RESET_MUX; + } + ret =3D regulator_bulk_enable(cfg->num_vregs, qmp->vregs); if (ret) { dev_err(qmp->dev, "failed to enable regulators, err=3D%d\n", ret); @@ -4052,8 +4095,9 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, = bool force) =20 /* override hardware control for reset of qmp phy */ qphy_setbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL, - SW_DPPHY_RESET_MUX | SW_DPPHY_RESET | - SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); + dp_reset_val | + SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET | + SW_USB4PHY_RESET_MUX | SW_USB4PHY_RESET); =20 /* override hardware control for reset of qmp phy */ if (aon_toggle && cfg->regs[QPHY_AON_TOGGLE_ENABLE]) { @@ -4069,6 +4113,10 @@ static int qmp_combo_com_init(struct qmp_combo *qmp,= bool force) if (cfg->invert_cc_polarity) val |=3D INVERT_CC_POLARITY; =20 + /* + * Note that in USB4 mode, the router controls pin assignments instead + * and the values of the PORTSELECT registers are ignored. + */ writel(val, com + QPHY_V3_DP_COM_TYPEC_CTRL); =20 switch (qmp->qmpphy_mode) { @@ -4096,12 +4144,24 @@ static int qmp_combo_com_init(struct qmp_combo *qmp= , bool force) qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL, SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); break; + case QMPPHY_MODE_USB4: + writel(USB4_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL); + + /* bring both QMP USB and QMP DP PHYs PCS block out of reset */ + /* + * TODO: disable the DP PLL to save power if there are no + * active DP tunnels after router setup has concluded + */ + qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL, + SW_USB4PHY_RESET_MUX | SW_USB4PHY_RESET | + SW_DPPHY_RESET_MUX | SW_DPPHY_RESET); + break; } =20 qphy_clrbits(com, QPHY_V3_DP_COM_SWI_CTRL, 0x03); qphy_clrbits(com, QPHY_V3_DP_COM_SW_RESET, SW_RESET); =20 - qphy_setbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], + qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); =20 return 0; @@ -4219,6 +4279,10 @@ static int qmp_combo_usb_power_on(struct phy *phy) struct qmp_combo *qmp =3D phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg =3D qmp->cfg; void __iomem *serdes =3D qmp->serdes; + const struct qmp_phy_init_tbl *pcs_tbl; + const struct qmp_phy_init_tbl *rx_tbl; + const struct qmp_phy_init_tbl *serdes_tbl; + const struct qmp_phy_init_tbl *tx_tbl; void __iomem *tx =3D qmp->tx; void __iomem *rx =3D qmp->rx; void __iomem *tx2 =3D qmp->tx2; @@ -4226,23 +4290,54 @@ static int qmp_combo_usb_power_on(struct phy *phy) void __iomem *pcs =3D qmp->pcs; void __iomem *pcs_usb =3D qmp->pcs_usb; void __iomem *status; + int pcs_tbl_num, rx_tbl_num, serdes_tbl_num, tx_tbl_num; unsigned int val; int ret; =20 - qmp_configure(qmp->dev, serdes, cfg->serdes_tbl, cfg->serdes_tbl_num); + if (qmp->qmpphy_mode =3D=3D QMPPHY_MODE_USB4) { + pcs =3D qmp->usb4_pcs; + serdes =3D qmp->usb4_serdes; + pcs_tbl =3D cfg->usb4_pcs_tbl; + pcs_tbl_num =3D cfg->usb4_pcs_tbl_num; + + serdes_tbl =3D cfg->usb4_serdes_tbl; + serdes_tbl_num =3D cfg->usb4_serdes_tbl_num; + + rx_tbl =3D cfg->usb4_rx_tbl; + rx_tbl_num =3D cfg->usb4_rx_tbl_num; + + tx_tbl =3D cfg->usb4_tx_tbl; + tx_tbl_num =3D cfg->usb4_tx_tbl_num; + } else { + pcs_tbl =3D cfg->pcs_tbl; + pcs_tbl_num =3D cfg->pcs_tbl_num; + + serdes_tbl =3D cfg->serdes_tbl; + serdes_tbl_num =3D cfg->serdes_tbl_num; + + rx_tbl =3D cfg->rx_tbl; + rx_tbl_num =3D cfg->rx_tbl_num; + + tx_tbl =3D cfg->tx_tbl; + tx_tbl_num =3D cfg->tx_tbl_num; + } + + qmp_configure(qmp->dev, serdes, serdes_tbl, serdes_tbl_num); =20 /* Tx, Rx, and PCS configurations */ - qmp_configure_lane(qmp->dev, tx, cfg->tx_tbl, cfg->tx_tbl_num, 1); - qmp_configure_lane(qmp->dev, tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2); + qmp_configure_lane(qmp->dev, tx, tx_tbl, tx_tbl_num, 1); + qmp_configure_lane(qmp->dev, tx2, tx_tbl, tx_tbl_num, 2); =20 - qmp_configure_lane(qmp->dev, rx, cfg->rx_tbl, cfg->rx_tbl_num, 1); - qmp_configure_lane(qmp->dev, rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2); + qmp_configure_lane(qmp->dev, rx, rx_tbl, rx_tbl_num, 1); + qmp_configure_lane(qmp->dev, rx2, rx_tbl, rx_tbl_num, 2); =20 - qmp_configure(qmp->dev, pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); + qmp_configure(qmp->dev, pcs, pcs_tbl, pcs_tbl_num); qmp_configure(qmp->dev, qmp->pcs_misc, cfg->pcs_misc_tbl, cfg->pcs_misc_t= bl_num); =20 - - if (pcs_usb) + if (qmp->qmpphy_mode =3D=3D QMPPHY_MODE_USB4 && qmp->usb4_phy_submode =3D= =3D PHY_SUBMODE_TBT3) + qmp_configure(qmp->dev, serdes, cfg->usb4_serdes_tb3_ovrd_tbl, + cfg->usb4_serdes_tb3_ovrd_num); + else if (qmp->qmpphy_mode !=3D QMPPHY_MODE_USB4 && pcs_usb) qmp_configure(qmp->dev, pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num); =20 @@ -4275,16 +4370,20 @@ static int qmp_combo_usb_power_off(struct phy *phy) { struct qmp_combo *qmp =3D phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg =3D qmp->cfg; + void __iomem *pcs =3D qmp->pcs; + + if (qmp->usb4_init_count) + pcs =3D qmp->usb4_pcs; =20 /* PHY reset */ - qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); + qphy_setbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); =20 /* stop SerDes and Phy-Coding-Sublayer */ - qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], + qphy_clrbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START); =20 /* Put PHY into POWER DOWN state: active low */ - qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], + qphy_clrbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); =20 return 0; @@ -4295,21 +4394,27 @@ static int qmp_combo_usb_init(struct phy *phy) struct qmp_combo *qmp =3D phy_get_drvdata(phy); int ret; =20 - mutex_lock(&qmp->phy_mutex); + guard(mutex)(&qmp->phy_mutex); + + /* USB4 mode takes precedence, do not reprogram the PHY in that case */ + if (qmp->usb4_init_count) { + qmp->init_count++; + qmp->usb_init_count++; + return 0; + } + ret =3D qmp_combo_com_init(qmp, false); if (ret) - goto out_unlock; + return ret; =20 ret =3D qmp_combo_usb_power_on(phy); if (ret) { qmp_combo_com_exit(qmp, false); - goto out_unlock; + return ret; } =20 qmp->usb_init_count++; =20 -out_unlock: - mutex_unlock(&qmp->phy_mutex); return ret; } =20 @@ -4318,20 +4423,26 @@ static int qmp_combo_usb_exit(struct phy *phy) struct qmp_combo *qmp =3D phy_get_drvdata(phy); int ret; =20 - mutex_lock(&qmp->phy_mutex); + guard(mutex)(&qmp->phy_mutex); + + /* USB4 mode takes precedence, do not reprogram the PHY in that case */ + if (qmp->usb4_init_count) { + qmp->init_count--; + qmp->usb_init_count--; + return 0; + } + ret =3D qmp_combo_usb_power_off(phy); if (ret) - goto out_unlock; + return ret; =20 ret =3D qmp_combo_com_exit(qmp, false); if (ret) - goto out_unlock; + return ret; =20 qmp->usb_init_count--; =20 -out_unlock: - mutex_unlock(&qmp->phy_mutex); - return ret; + return 0; } =20 static int qmp_combo_usb_set_mode(struct phy *phy, enum phy_mode mode, int= submode) @@ -4343,6 +4454,125 @@ static int qmp_combo_usb_set_mode(struct phy *phy, = enum phy_mode mode, int submo return 0; } =20 +static int qmp_combo_reconfigure_phy(struct qmp_combo *qmp, enum qmpphy_mo= de new_mode) +{ + dev_dbg(qmp->dev, "qmp_combo_reconfigure_phy: switching from qmpphy mode = %d to %d\n", + qmp->qmpphy_mode, new_mode); + + if (qmp->usb_init_count || qmp->usb4_init_count) + qmp_combo_usb_power_off(qmp->usb_phy); + + if (qmp->dp_init_count) + writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); + + qmp_combo_com_exit(qmp, true); + + qmp->qmpphy_mode =3D new_mode; + + /* Now everything's powered down, power up the right PHYs */ + qmp_combo_com_init(qmp, true); + + if ((qmp->usb_init_count || qmp->usb4_init_count) && + new_mode !=3D QMPPHY_MODE_DP_ONLY) + qmp_combo_usb_power_on(qmp->usb_phy); + + if ((new_mode =3D=3D QMPPHY_MODE_USB3DP || new_mode =3D=3D QMPPHY_MODE_DP= _ONLY) && + qmp->dp_init_count) + qmp->cfg->dp_aux_init(qmp); + + return 0; +} + +static int qmp_combo_usb4_init(struct phy *phy) +{ + struct qmp_combo *qmp =3D phy_get_drvdata(phy); + int ret; + + guard(mutex)(&qmp->phy_mutex); + + if (!qmp->p2rr2p_pipe_clk) { + dev_err(qmp->dev, "missing p2rr2p_pipe clock handle. Update your Device = Tree.\n"); + return -EINVAL; + } + + ret =3D clk_prepare_enable(qmp->p2rr2p_pipe_clk); + if (ret) { + dev_err(qmp->dev, "p2rr2p_pipe enable failed: %d\n", ret); + return ret; + } + + ret =3D qmp_combo_com_init(qmp, false); + if (ret) { + clk_disable_unprepare(qmp->p2rr2p_pipe_clk); + return ret; + } + + /* USB4 mode takes precedence to USB3(+DP), force reconfigure the PHY */ + ret =3D qmp_combo_reconfigure_phy(qmp, QMPPHY_MODE_USB4); + if (ret) { + clk_disable_unprepare(qmp->p2rr2p_pipe_clk); + qmp_combo_com_exit(qmp, false); + return ret; + } + + ret =3D qmp_combo_usb_power_on(phy); + if (ret) { + clk_disable_unprepare(qmp->p2rr2p_pipe_clk); + qmp_combo_com_exit(qmp, false); + return ret; + } + + /* + * Due to the SoC design, the PHY only has a single valid consumer and + * preventing it from having sole ownership of the PHY's power state + * makes suspending/resuming the router impossible. + */ + WARN_ON(qmp->usb4_init_count++); + + return 0; +} + +static int qmp_combo_usb4_exit(struct phy *phy) +{ + struct qmp_combo *qmp =3D phy_get_drvdata(phy); + int ret; + + guard(mutex)(&qmp->phy_mutex); + + ret =3D qmp_combo_usb_power_off(qmp->usb_phy); + if (ret) + return ret; + + ret =3D qmp_combo_com_exit(qmp, false); + if (ret) + return ret; + + /* + * Mark the USB4 PHY uninitialized and wait for a mux_set event to determ= ine the correct + * setting. This will always be possible because USB4 requires Type-C. + */ + qmp->usb4_init_count--; + + clk_disable_unprepare(qmp->p2rr2p_pipe_clk); + + return 0; +} + +static int qmp_combo_usb4_set_mode(struct phy *phy, enum phy_mode mode, in= t submode) +{ + struct qmp_combo *qmp =3D phy_get_drvdata(phy); + + if (mode !=3D PHY_MODE_TBT) + return -EINVAL; + + if (submode !=3D PHY_SUBMODE_USB4 && submode !=3D PHY_SUBMODE_TBT3) + return -EINVAL; + + qmp->usb4_phy_submode =3D submode; + + return 0; +} + static const struct phy_ops qmp_combo_usb_phy_ops =3D { .init =3D qmp_combo_usb_init, .exit =3D qmp_combo_usb_exit, @@ -4350,6 +4580,13 @@ static const struct phy_ops qmp_combo_usb_phy_ops = =3D { .owner =3D THIS_MODULE, }; =20 +static const struct phy_ops qmp_combo_usb4_phy_ops =3D { + .init =3D qmp_combo_usb4_init, + .exit =3D qmp_combo_usb4_exit, + .set_mode =3D qmp_combo_usb4_set_mode, + .owner =3D THIS_MODULE, +}; + static const struct phy_ops qmp_combo_dp_phy_ops =3D { .init =3D qmp_combo_dp_init, .configure =3D qmp_combo_dp_configure, @@ -4389,9 +4626,12 @@ static void qmp_combo_enable_autonomous_mode(struct = qmp_combo *qmp) * Enable i/o clamp_n for autonomous mode * V6 and later versions use pcs aon clamp register */ - if (pcs_aon) - qphy_clrbits(pcs_aon, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); - else if (pcs_misc) + if (pcs_aon) { + if (qmp->qmpphy_mode =3D=3D QMPPHY_MODE_USB4) + qphy_clrbits(pcs_aon, cfg->regs[QPHY_PCS_USB4_CLAMP_ENABLE], CLAMP_EN); + else + qphy_clrbits(pcs_aon, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); + } else if (pcs_misc) qphy_clrbits(pcs_misc, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); } =20 @@ -4403,9 +4643,12 @@ static void qmp_combo_disable_autonomous_mode(struct= qmp_combo *qmp) void __iomem *pcs_aon =3D qmp->pcs_aon; =20 /* Disable i/o clamp_n on resume for normal mode */ - if (pcs_aon) - qphy_setbits(pcs_aon, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); - else if (pcs_misc) + if (pcs_aon) { + if (qmp->qmpphy_mode =3D=3D QMPPHY_MODE_USB4) + qphy_setbits(pcs_aon, cfg->regs[QPHY_PCS_USB4_CLAMP_ENABLE], CLAMP_EN); + else + qphy_setbits(pcs_aon, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); + } else if (pcs_misc) qphy_setbits(pcs_misc, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); =20 qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], @@ -4779,24 +5022,29 @@ static int qmp_combo_typec_switch_set(struct typec_= switch_dev *sw, struct qmp_combo *qmp =3D typec_switch_get_drvdata(sw); const struct qmp_phy_cfg *cfg =3D qmp->cfg; =20 + if (qmp->qmpphy_mode =3D=3D QMPPHY_MODE_USB4) { + /* QMPPHY has no orientation handling in USB4 mode, don't cache the sett= ing */ + qmp->orientation =3D TYPEC_ORIENTATION_NONE; + return 0; + } + if (orientation =3D=3D qmp->orientation || orientation =3D=3D TYPEC_ORIEN= TATION_NONE) return 0; =20 - mutex_lock(&qmp->phy_mutex); + guard(mutex)(&qmp->phy_mutex); qmp->orientation =3D orientation; =20 if (qmp->init_count) { - if (qmp->usb_init_count) + if (qmp->usb_init_count || qmp->usb4_init_count) qmp_combo_usb_power_off(qmp->usb_phy); qmp_combo_com_exit(qmp, true); =20 qmp_combo_com_init(qmp, true); - if (qmp->usb_init_count) + if (qmp->usb_init_count || qmp->usb4_init_count) qmp_combo_usb_power_on(qmp->usb_phy); if (qmp->dp_init_count) cfg->dp_aux_init(qmp); } - mutex_unlock(&qmp->phy_mutex); =20 return 0; } @@ -4804,7 +5052,6 @@ static int qmp_combo_typec_switch_set(struct typec_sw= itch_dev *sw, static int qmp_combo_typec_mux_set(struct typec_mux_dev *mux, struct typec= _mux_state *state) { struct qmp_combo *qmp =3D typec_mux_get_drvdata(mux); - const struct qmp_phy_cfg *cfg =3D qmp->cfg; enum qmpphy_mode new_mode; unsigned int svid; =20 @@ -4815,6 +5062,29 @@ static int qmp_combo_typec_mux_set(struct typec_mux_= dev *mux, struct typec_mux_s else svid =3D 0; =20 + /* + * The USB4 router driver must excercise fine-grained control over the ti= ming of + * USB4 QMPPHY mode entry/exit, which is difficult to otherwise ensure wi= thin Linux's + * Type-C framework if the PHY acts as a self-decisive mode mux in parall= el. + * + * Keep the hardware in QMPPHY_MODE_USB4 at all times between .init and .= exit of the + * (Linux) USB4 PHY and wait for the router driver to turn it off at its = discretion. + * Once that happens, fall back to the usual USB3/DP/Combo mode logic. + * + * After the QMPPHY has been turned off through phy_exit(usb4_phy), the n= ext mux_set + * will initialize it in the right mode. + */ + if (qmp->usb4_init_count) + return 0; + + /* + * Explicitly ignore TBT/USB4 mode requests that may come if the USB4 PHY= hasn't been + * initialized, either due to the USB4 drivers being disabled or due to t= his PHY instance + * lacking USB4 support. + */ + if (svid =3D=3D USB_TYPEC_TBT_SID || (!state->alt && state->mode =3D=3D T= YPEC_MODE_USB4)) + return 0; + if (svid =3D=3D USB_TYPEC_DP_SID) { switch (state->mode) { /* DP Only */ @@ -4847,41 +5117,11 @@ static int qmp_combo_typec_mux_set(struct typec_mux= _dev *mux, struct typec_mux_s return 0; } =20 - dev_dbg(qmp->dev, "typec_mux_set: switching from qmpphy mode %d to %d\n", - qmp->qmpphy_mode, new_mode); + /* The mux still receives Type-C events, even if all PHYs are uninitializ= ed */ + if (!qmp->init_count) + return 0; =20 - qmp->qmpphy_mode =3D new_mode; - - if (qmp->init_count) { - if (qmp->usb_init_count) - qmp_combo_usb_power_off(qmp->usb_phy); - - if (qmp->dp_init_count) - writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); - - qmp_combo_com_exit(qmp, true); - - /* Now everything's powered down, power up the right PHYs */ - qmp_combo_com_init(qmp, true); - - if (new_mode =3D=3D QMPPHY_MODE_DP_ONLY) { - if (qmp->usb_init_count) - qmp->usb_init_count--; - } - - if (new_mode =3D=3D QMPPHY_MODE_USB3DP || new_mode =3D=3D QMPPHY_MODE_US= B3_ONLY) { - qmp_combo_usb_power_on(qmp->usb_phy); - if (!qmp->usb_init_count) - qmp->usb_init_count++; - } - - if (new_mode =3D=3D QMPPHY_MODE_DP_ONLY || new_mode =3D=3D QMPPHY_MODE_U= SB3DP) { - if (qmp->dp_init_count) - cfg->dp_aux_init(qmp); - } - } - - return 0; + return qmp_combo_reconfigure_phy(qmp, new_mode); } =20 static void qmp_combo_typec_switch_unregister(void *data) @@ -5088,6 +5328,9 @@ static int qmp_combo_parse_dt(struct qmp_combo *qmp) if (offs->aon_toggle) qmp->aon_toggle =3D base + offs->aon_toggle; =20 + qmp->usb4_serdes =3D base + offs->usb4_serdes; + qmp->usb4_pcs =3D base + offs->usb4_pcs; + ret =3D qmp_combo_clk_init(qmp); if (ret) return ret; @@ -5098,6 +5341,12 @@ static int qmp_combo_parse_dt(struct qmp_combo *qmp) "failed to get usb3_pipe clock\n"); } =20 + qmp->p2rr2p_pipe_clk =3D devm_clk_get_optional(dev, "p2rr2p_pipe"); + if (IS_ERR(qmp->p2rr2p_pipe_clk)) { + return dev_err_probe(dev, PTR_ERR(qmp->p2rr2p_pipe_clk), + "failed to get p2rr2p_pipe clock\n"); + } + return 0; } =20 @@ -5113,6 +5362,8 @@ static struct phy *qmp_combo_phy_xlate(struct device = *dev, const struct of_phand return qmp->usb_phy; case QMP_USB43DP_DP_PHY: return qmp->dp_phy; + case QMP_USB43DP_USB4_PHY: + return qmp->usb4_phy ?: ERR_PTR(-EINVAL); } =20 return ERR_PTR(-EINVAL); @@ -5325,6 +5576,17 @@ static int qmp_combo_probe(struct platform_device *p= dev) =20 phy_set_drvdata(qmp->dp_phy, qmp); =20 + if (qmp->cfg->usb4_serdes_tbl) { + qmp->usb4_phy =3D devm_phy_create(dev, dev->of_node, &qmp_combo_usb4_phy= _ops); + if (IS_ERR(qmp->usb4_phy)) { + ret =3D PTR_ERR(qmp->usb4_phy); + dev_err(dev, "failed to create USB4 PHY: %d\n", ret); + goto err_node_put; + } + + phy_set_drvdata(qmp->usb4_phy, qmp); + } + if (usb_np =3D=3D dev->of_node) phy_provider =3D devm_of_phy_provider_register(dev, qmp_combo_phy_xlate); else --=20 2.55.0 From nobody Fri Sep 25 21:40:20 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 3CDF83A8755; Tue, 8 Sep 2026 07:54:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788854083; cv=none; b=r2MLN2GmfilXeVHVlent68aaBTzI8RiC3vzP+RkiJcPJZ0VcNgvn3IpDroPBfsI8n+kYdxCrao0ttm/fa21fFdML8Y4tsjMtZ5+HcyUAjxBFnimUp9eLpjlvu1emsLicAGtPZo8zsL4H+RGOP/AgOoyqmCIoGS1bjwvQlM7MZM4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788854083; c=relaxed/simple; bh=NMnGj8a72CJBnDUxa5ESlzqfxyzDM3FaD7pN+XTTyBs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UfVlN770TocBjBMZ84BxORCLWxucaDcb+5JtqqBrB1YnWB4KhoHx20buhgUFCrATiNHBJmMs5rbY+v8fUSnemYiDjWbm0UtOQ7U2QJL8pYyE0PS0mSnphEwR0zBXaQJ3HFbr7bJA4qw96eJ+r4FcqFOM25qLqFQ/k9oPJprGYTs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=O14XKe0A; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="O14XKe0A" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 904A41F00A3A; Tue, 8 Sep 2026 07:54:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788854081; bh=h4Nza8UjAHn/jG2yIK7hhXYEmzslwKIbRSPeSQqKXSM=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=O14XKe0A79KdY11jL6RyOkJWJ/cnKjrkzyeQ72wts6PGhwTicm0rf9NJdAZJCd7qk GIHFv27BrEwlSgMfGdqMkH2l7+FJHS6YQI/dhusJN67kwRVafRw+KHIWB3Kea68jj1 QePIWPm8CxpiWfZOHkxD789omSftNUSMI2IDF7mY42p2j0su8s+sph27XetgxOJy2e 5DTYzZ2gCAbUhAIn3ASWcj60zoHF0XuNXj+CtbNxPcRTVCqm6MWceTWvMItkDu0wPv ZcQFFbwAxroNyh6FfmOmnrBu6rSEXy0oOxL+SXR1zn8UpmaaVGiDcvKkGzSNrTHexb CjsYAVDuy/TKg== From: Konrad Dybcio Date: Tue, 08 Sep 2026 09:54:08 +0200 Subject: [PATCH v5 4/5] phy: qualcomm: qmp-combo: Add USB4/TBT3 configuration data for Hamoa 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: <20260908-topic-usb4phy-v5-4-73aac69578ef@oss.qualcomm.com> References: <20260908-topic-usb4phy-v5-0-73aac69578ef@oss.qualcomm.com> In-Reply-To: <20260908-topic-usb4phy-v5-0-73aac69578ef@oss.qualcomm.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam Cc: linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, usb4-upstream@oss.qualcomm.com, Raghavendra Thoorpu , Mika Westerberg , Sven Peter , Konrad Dybcio , Dmitry Baryshkov , Abel Vesa , Manivannan Sadhasivam X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788854054; l=20097; i=konrad.dybcio@oss.qualcomm.com; s=20230215; h=from:subject:message-id; bh=NcWnM6MI8BN+L93GAV/11pVL3gEmlnX6FsBaokKeHRA=; b=llV3gvCOXvR533WywE8oW5JDk73r3ZPtVmIT7ZEwXQsED3BTYb9C3E8WceXJGnjz1F665SsDe BQXovKCfzhnBYVeCAhn64Xh9dzoKSQ1WfiG36P6RBXv+OeAptI+xV3M X-Developer-Key: i=konrad.dybcio@oss.qualcomm.com; a=ed25519; pk=iclgkYvtl2w05SSXO5EjjSYlhFKsJ+5OSZBjOkQuEms= From: Konrad Dybcio Add the offsets and configuration tables to support USB4 and Thunderbolt 3 operation on the USB4-capable PHYs found on Hamoa chips. Reviewed-by: Dmitry Baryshkov Reviewed-by: Abel Vesa Reviewed-by: Manivannan Sadhasivam Signed-off-by: Konrad Dybcio --- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 200 +++++++++++++++++= +++- drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h | 2 + drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v6.h | 15 ++ .../phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_n4.h | 45 +++++ 4 files changed, 256 insertions(+), 6 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualco= mm/phy-qcom-qmp-combo.c index a4f130fc33e3..284efc3f23d4 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -240,6 +240,7 @@ static const unsigned int qmp_v6_n4_usb3phy_regs_layout= [QPHY_LAYOUT_SIZE] =3D { [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] =3D QPHY_V6_PCS_USB3_LFPS_RXTERM_IRQ_CLE= AR, =20 [QPHY_PCS_CLAMP_ENABLE] =3D QPHY_V6_PCS_AON_CLAMP_ENABLE, + [QPHY_PCS_USB4_CLAMP_ENABLE] =3D QPHY_V6_PCS_AON_USB4_CLAMP_ENABLE, =20 [QPHY_COM_RESETSM_CNTRL] =3D QSERDES_V6_COM_RESETSM_CNTRL, [QPHY_COM_C_READY_STATUS] =3D QSERDES_V6_COM_C_READY_STATUS, @@ -1967,7 +1968,85 @@ static const struct qmp_phy_init_tbl sc8280xp_usb43d= p_pcs_tbl[] =3D { QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07), }; =20 -static const struct qmp_phy_init_tbl x1e80100_usb43dp_serdes_tbl[] =3D { +static const struct qmp_phy_init_tbl x1e80100_usb4_serdes_tbl[] =3D { + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xd9), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0xb2), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_BUF_ENABLE, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_CFG, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x43), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x82), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MSB_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x86), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MSB_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0xa7), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE1_MODE0, 0xba), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE1_MODE1, 0x3c), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE2_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x76), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0xb0), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x7f), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO_MODE1, 0x7f), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE0, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE1, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x17), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SVS_MODE_CLK_SEL, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MODE, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_VCO_DC_LEVEL_CTRL, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_ADDITIONAL_MISC_2, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAXVAL2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_POST_DIV_MUX, 0x60), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a), +}; + +static const struct qmp_phy_init_tbl x1e80100_usb4_tb3_serdes_tbl[] =3D { + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x54), +}; + +static const struct qmp_phy_init_tbl x1e80100_usb4_tx_tbl[] =3D { + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_LANE_MODE_1, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_LANE_MODE_2, 0x50), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_LANE_MODE_3, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RES_CODE_LANE_OFFSET_TX, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RES_CODE_LANE_OFFSET_RX, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RX_MARG_COARSE_THRESH1_RATE210, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RX_MARG_COARSE_THRESH1_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RX_MARG_COARSE_THRESH2_RATE210, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RX_MARG_COARSE_THRESH2_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RX_MARG_COARSE_THRESH3_RATE210, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RX_MARG_COARSE_THRESH3_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_TX_LDO_TIMER_CTRL, 0x03), +}; + +static const struct qmp_phy_init_tbl x1e80100_usb3dp_serdes_tbl[] =3D { QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01), QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x62), QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02), @@ -2028,6 +2107,68 @@ static const struct qmp_phy_init_tbl x1e80100_usb43d= p_tx_tbl[] =3D { QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RES_CODE_LANE_OFFSET_RX, 0x0a), }; =20 +static const struct qmp_phy_init_tbl x1e80100_usb4_rx_tbl[] =3D { + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_SIGDET_CNTRL, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_SIGDET_ENABLES, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_MODE_RATE2_B0, 0xd3), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_MODE_RATE2_B1, 0xee), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_MODE_RATE2_B2, 0x58), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_MODE_RATE2_B4, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_MODE_RATE3_B0, 0xbf), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_MODE_RATE3_B1, 0x7f), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_MODE_RATE3_B2, 0xa2), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_MODE_RATE3_B3, 0xdd), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_MODE_RATE3_B4, 0x6a), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_MODE_RATE3_B5, 0xdb), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_MODE_RATE3_B6, 0xe3), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_UCDR_FASTLOCK_COUNTER_LOW_RATE2, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_UCDR_FASTLOCK_COUNTER_HIGH_RATE2, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_UCDR_FASTLOCK_COUNTER_LOW_RATE3, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_UCDR_FASTLOCK_COUNTER_HIGH_RATE3, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_PI_CTRL1, 0xd0), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_PI_CTRL2, 0x48), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_SB2_THRESH1_RATE3, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_SB2_GAIN2_RATE2, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_SB2_GAIN1_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_SB2_GAIN2_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_IVCM_CAL_CODE_OVERRIDE, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_RX_IVCM_CAL_CTRL2, 0x80), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_RX_SUMMER_CAL_SPD_MODE, 0x2f), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_DCC_CMUX_POSTCAL_OFFSET, 0x1d), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_FO_GAIN_RATE2, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_FO_GAIN_RATE3, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_SO_GAIN_RATE2, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_SO_GAIN_RATE3, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_PI_CONTROLS, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_FASTLOCK_FO_GAIN_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_FASTLOCK_SO_GAIN_RATE3, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_UCDR_SO_SATURATION, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_RX_IVCM_POSTCAL_OFFSET, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_VGA_CAL_CNTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_VGA_CAL_MAN_VAL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_DFE_DAC_ENABLE1, 0x88), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_DFE_DAC_ENABLE2, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_DFE_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_DFE_2, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_DFE_3, 0x45), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_DFE_TAP3_CTRL, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_DFE_TAP4_CTRL, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_DFE_TAP5_CTRL, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_GM_CAL, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_RX_OFFSET_ADAPTOR_CNTRL3, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_EOM_CTRL1, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_EOM_CTRL2, 0x21), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_DFE_TAP3_MANVAL_KTAP, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_DFE_TAP4_MANVAL_KTAP, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_DFE_TAP5_MANVAL_KTAP, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_VTHRESH_CAL_MAN_VAL_RATE3, 0x78), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_Q_PI_INTRINSIC_BIAS_RATE32, 0x27), + QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_RX_BKUP_CTRL1, 0x14), +}; + static const struct qmp_phy_init_tbl x1e80100_usb43dp_rx_tbl[] =3D { QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_SIGDET_CNTRL, 0x04), QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e), @@ -2066,6 +2207,23 @@ static const struct qmp_phy_init_tbl x1e80100_usb43d= p_rx_tbl[] =3D { QMP_PHY_INIT_CFG(QSERDES_V6_N4_RX_RX_BKUP_CTRL1, 0x14), }; =20 +static const struct qmp_phy_init_tbl x1e80100_usb4_pcs_tbl[] =3D { + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_POWER_STATE_CONFIG3, 0x4f), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_LOCK_DETECT_CONFIG1, 0x03), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_LOCK_DETECT_CONFIG2, 0xc0), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_RX_SIGDET_LVL, 0x55), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_PCS_PCS_TX_RX_CONFIG1, 0x51), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_EQ_CONFIG1, 0x2e), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_G3_EQ_CONFIG1, 0x4b), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_G3_EQ_CONFIG5, 0x1e), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_G2_FOM_EQ_CONFIG1, 0x83), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_G2_FOM_EQ_CONFIG3, 0x2e), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_G2_FOM_EQ_CONFIG5, 0x10), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_G3_FOM_EQ_CONFIG3, 0x25), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_G3_FOM_EQ_CONFIG5, 0x22), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_USB4_LPFS_TX_ECSTART, 0x0f), +}; + static const struct qmp_phy_init_tbl x1e80100_usb43dp_pcs_tbl[] =3D { QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), @@ -2720,6 +2878,23 @@ static const struct qmp_combo_offsets qmp_combo_offs= ets_v5 =3D { .dp_dp_phy =3D 0x2200, }; =20 +static const struct qmp_combo_offsets qmp_combo_offsets_v6_n4 =3D { + .com =3D 0x0000, + .usb3_pcs_aon =3D 0x0100, + .txa =3D 0x0400, + .rxa =3D 0x0600, + .txb =3D 0x0a00, + .rxb =3D 0x0c00, + .usb3_serdes =3D 0x1000, + .usb3_pcs_misc =3D 0x1200, + .usb3_pcs =3D 0x1400, + .usb3_pcs_usb =3D 0x1700, + .dp_serdes =3D 0x2000, + .dp_dp_phy =3D 0x2200, + .usb4_serdes =3D 0x3000, + .usb4_pcs =3D 0x3400, +}; + static const struct qmp_combo_offsets qmp_combo_offsets_v8 =3D { .com =3D 0x0000, .txa =3D 0x1400, @@ -2995,11 +3170,11 @@ static const struct qmp_phy_cfg sc8280xp_usb43dpphy= _cfg =3D { .regs =3D qmp_v5_5nm_usb3phy_regs_layout, }; =20 -static const struct qmp_phy_cfg x1e80100_usb3dpphy_cfg =3D { - .offsets =3D &qmp_combo_offsets_v5, +static const struct qmp_phy_cfg x1e80100_usb43dpphy_cfg =3D { + .offsets =3D &qmp_combo_offsets_v6_n4, =20 - .serdes_tbl =3D x1e80100_usb43dp_serdes_tbl, - .serdes_tbl_num =3D ARRAY_SIZE(x1e80100_usb43dp_serdes_tbl), + .serdes_tbl =3D x1e80100_usb3dp_serdes_tbl, + .serdes_tbl_num =3D ARRAY_SIZE(x1e80100_usb3dp_serdes_tbl), .tx_tbl =3D x1e80100_usb43dp_tx_tbl, .tx_tbl_num =3D ARRAY_SIZE(x1e80100_usb43dp_tx_tbl), .rx_tbl =3D x1e80100_usb43dp_rx_tbl, @@ -3033,6 +3208,19 @@ static const struct qmp_phy_cfg x1e80100_usb3dpphy_c= fg =3D { .configure_dp_clocks =3D qmp_v3_configure_dp_clocks, .configure_dp_phy =3D qmp_v4_configure_dp_phy, =20 + .usb4_serdes_tbl =3D x1e80100_usb4_serdes_tbl, + .usb4_serdes_tbl_num =3D ARRAY_SIZE(x1e80100_usb4_serdes_tbl), + .usb4_serdes_tb3_ovrd_tbl =3D x1e80100_usb4_tb3_serdes_tbl, + .usb4_serdes_tb3_ovrd_num =3D ARRAY_SIZE(x1e80100_usb4_tb3_serdes_tbl), + + .usb4_tx_tbl =3D x1e80100_usb4_tx_tbl, + .usb4_tx_tbl_num =3D ARRAY_SIZE(x1e80100_usb4_tx_tbl), + .usb4_rx_tbl =3D x1e80100_usb4_rx_tbl, + .usb4_rx_tbl_num =3D ARRAY_SIZE(x1e80100_usb4_rx_tbl), + + .usb4_pcs_tbl =3D x1e80100_usb4_pcs_tbl, + .usb4_pcs_tbl_num =3D ARRAY_SIZE(x1e80100_usb4_pcs_tbl), + .reset_list =3D msm8996_usb3phy_reset_l, .num_resets =3D ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list =3D qmp_phy_vreg_l, @@ -5683,7 +5871,7 @@ static const struct of_device_id qmp_combo_of_match_t= able[] =3D { }, { .compatible =3D "qcom,x1e80100-qmp-usb3-dp-phy", - .data =3D &x1e80100_usb3dpphy_cfg, + .data =3D &x1e80100_usb43dpphy_cfg, }, { } }; diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h b/drivers/phy/q= ualcomm/phy-qcom-qmp-pcs-aon-v6.h index 52db31a7cf22..f19f461297b6 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h @@ -8,5 +8,7 @@ =20 /* Only for QMP V6 PHY - PCS_AON registers */ #define QPHY_V6_PCS_AON_CLAMP_ENABLE 0x00 +/* Valid only for USB43DP variants */ +#define QPHY_V6_PCS_AON_USB4_CLAMP_ENABLE 0x04 =20 #endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v6.h b/drivers/phy/q= ualcomm/phy-qcom-qmp-pcs-usb-v6.h index df670143feb1..30fdb437146c 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v6.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v6.h @@ -14,4 +14,19 @@ #define QPHY_V6_PCS_USB3_RCVR_DTCT_DLY_U3_L 0x40 #define QPHY_V6_PCS_USB3_RCVR_DTCT_DLY_U3_H 0x44 =20 +#define QPHY_V6_PCS_USB4_POWER_STATE_CONFIG3 0x98 +#define QPHY_V6_PCS_USB4_LOCK_DETECT_CONFIG1 0xd0 +#define QPHY_V6_PCS_USB4_LOCK_DETECT_CONFIG2 0xd4 +#define QPHY_V6_PCS_USB4_RX_SIGDET_LVL 0x17c +#define QPHY_V6_PCS_USB4_PCS_PCS_TX_RX_CONFIG1 0x1a8 +#define QPHY_V6_PCS_USB4_EQ_CONFIG1 0x1b8 +#define QPHY_V6_PCS_USB4_G3_EQ_CONFIG1 0x1d8 +#define QPHY_V6_PCS_USB4_G3_EQ_CONFIG5 0x1e8 +#define QPHY_V6_PCS_USB4_G2_FOM_EQ_CONFIG1 0x1f4 +#define QPHY_V6_PCS_USB4_G2_FOM_EQ_CONFIG3 0x1fc +#define QPHY_V6_PCS_USB4_G2_FOM_EQ_CONFIG5 0x204 +#define QPHY_V6_PCS_USB4_G3_FOM_EQ_CONFIG3 0x210 +#define QPHY_V6_PCS_USB4_G3_FOM_EQ_CONFIG5 0x218 +#define QPHY_V6_PCS_USB4_LPFS_TX_ECSTART 0x220 + #endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_n4.h b/drive= rs/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_n4.h index d37cc0d4fd36..e72ae2cb460a 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_n4.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_n4.h @@ -23,27 +23,63 @@ #define QSERDES_V6_N4_TX_TRAN_DRVR_EMP_EN 0xac #define QSERDES_V6_N4_TX_TX_BAND 0xd8 #define QSERDES_V6_N4_TX_INTERFACE_SELECT 0xe4 +#define QSERDES_V6_N4_TX_RX_MARG_COARSE_THRESH1_RATE210 0xe8 +#define QSERDES_V6_N4_TX_RX_MARG_COARSE_THRESH1_RATE3 0xec +#define QSERDES_V6_N4_TX_RX_MARG_COARSE_THRESH2_RATE210 0xf0 +#define QSERDES_V6_N4_TX_RX_MARG_COARSE_THRESH2_RATE3 0xf4 +#define QSERDES_V6_N4_TX_RX_MARG_COARSE_THRESH3_RATE210 0xf8 +#define QSERDES_V6_N4_TX_RX_MARG_COARSE_THRESH3_RATE3 0xfc #define QSERDES_V6_N4_TX_VMODE_CTRL1 0xb0 +#define QSERDES_V6_TX_LDO_TIMER_CTRL 0x120 =20 #define QSERDES_V6_N4_RX_UCDR_FO_GAIN_RATE2 0x8 +#define QSERDES_V6_N4_RX_UCDR_FO_GAIN_RATE3 0xc +#define QSERDES_V6_N4_RX_UCDR_SO_GAIN_RATE3 0x1c #define QSERDES_V6_N4_RX_UCDR_SO_GAIN_RATE2 0x18 #define QSERDES_V6_N4_RX_UCDR_PI_CONTROLS 0x20 +#define QSERDES_V6_N4_RX_EOM_CTRL1 0x44 +#define QSERDES_V6_N4_RX_EOM_CTRL2 0x48 #define QSERDES_V6_N4_RX_IVCM_CAL_CODE_OVERRIDE 0x94 #define QSERDES_V6_N4_RX_RX_IVCM_CAL_CTRL2 0x9c #define QSERDES_V6_N4_RX_RX_IVCM_POSTCAL_OFFSET 0xa0 +#define QSERDES_V6_N4_RX_DFE_1 0xac +#define QSERDES_V6_N4_RX_DFE_2 0xb0 #define QSERDES_V6_N4_RX_DFE_3 0xb4 +#define QSERDES_V6_N4_RX_DFE_TAP3_CTRL 0xbc +#define QSERDES_V6_N4_RX_DFE_TAP3_MANVAL_KTAP 0xc0 +#define QSERDES_V6_N4_RX_DFE_TAP4_CTRL 0xc4 +#define QSERDES_V6_N4_RX_DFE_TAP4_MANVAL_KTAP 0xc8 +#define QSERDES_V6_N4_RX_DFE_TAP5_CTRL 0xcc +#define QSERDES_V6_N4_RX_DFE_TAP5_MANVAL_KTAP 0xd0 #define QSERDES_V6_N4_RX_VGA_CAL_CNTRL1 0xe0 #define QSERDES_V6_N4_RX_VGA_CAL_MAN_VAL 0xe8 +#define QSERDES_V6_N4_RX_VTHRESH_CAL_MAN_VAL_RATE3 0x108 #define QSERDES_V6_N4_RX_GM_CAL 0x10c +#define QSERDES_V6_N4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x13c +#define QSERDES_V6_N4_RX_RX_OFFSET_ADAPTOR_CNTRL3 0x144 #define QSERDES_V6_N4_RX_SIGDET_ENABLES 0x148 #define QSERDES_V6_N4_RX_SIGDET_CNTRL 0x14c #define QSERDES_V6_N4_RX_SIGDET_DEGLITCH_CNTRL 0x154 #define QSERDES_V6_N4_RX_DFE_CTLE_POST_CAL_OFFSET 0x194 +#define QSERDES_V6_N4_RX_DCC_CMUX_POSTCAL_OFFSET 0x1a8 #define QSERDES_V6_N4_RX_Q_PI_INTRINSIC_BIAS_RATE32 0x1dc +#define QSERDES_V6_N4_RX_UCDR_FASTLOCK_FO_GAIN_RATE3 0x200 +#define QSERDES_V6_N4_RX_UCDR_FASTLOCK_SO_GAIN_RATE3 0x210 +#define QSERDES_V6_N4_RX_UCDR_SO_SATURATION 0x214 +#define QSERDES_V6_N4_TX_UCDR_FASTLOCK_COUNTER_LOW_RATE1 0x224 +#define QSERDES_V6_N4_TX_UCDR_FASTLOCK_COUNTER_HIGH_RATE1 0x228 +#define QSERDES_V6_N4_TX_UCDR_FASTLOCK_COUNTER_LOW_RATE2 0x22c +#define QSERDES_V6_N4_TX_UCDR_FASTLOCK_COUNTER_HIGH_RATE2 0x230 +#define QSERDES_V6_N4_TX_UCDR_FASTLOCK_COUNTER_LOW_RATE3 0x234 +#define QSERDES_V6_N4_TX_UCDR_FASTLOCK_COUNTER_HIGH_RATE3 0x238 #define QSERDES_V6_N4_RX_UCDR_PI_CTRL1 0x23c #define QSERDES_V6_N4_RX_UCDR_PI_CTRL2 0x240 +#define QSERDES_V6_N4_RX_UCDR_SB2_THRESH1_RATE3 0x250 +#define QSERDES_V6_N4_RX_UCDR_SB2_GAIN1_RATE3 0x270 #define QSERDES_V6_N4_RX_UCDR_SB2_GAIN2_RATE2 0x27c +#define QSERDES_V6_N4_RX_UCDR_SB2_GAIN2_RATE3 0x280 #define QSERDES_V6_N4_RX_DFE_DAC_ENABLE1 0x298 +#define QSERDES_V6_N4_RX_DFE_DAC_ENABLE2 0x29c #define QSERDES_V6_N4_RX_MODE_RATE_0_1_B0 0x2b8 #define QSERDES_V6_N4_RX_MODE_RATE_0_1_B1 0x2bc #define QSERDES_V6_N4_RX_MODE_RATE_0_1_B2 0x2c0 @@ -58,6 +94,15 @@ #define QSERDES_V6_N4_RX_MODE_RATE2_B4 0x2e4 #define QSERDES_V6_N4_RX_MODE_RATE2_B5 0x2e8 #define QSERDES_V6_N4_RX_MODE_RATE2_B6 0x2ec + +#define QSERDES_V6_N4_RX_MODE_RATE3_B0 0x2f0 +#define QSERDES_V6_N4_RX_MODE_RATE3_B1 0x2f4 +#define QSERDES_V6_N4_RX_MODE_RATE3_B2 0x2f8 +#define QSERDES_V6_N4_RX_MODE_RATE3_B3 0x2fc +#define QSERDES_V6_N4_RX_MODE_RATE3_B4 0x300 +#define QSERDES_V6_N4_RX_MODE_RATE3_B5 0x304 +#define QSERDES_V6_N4_RX_MODE_RATE3_B6 0x308 + #define QSERDES_V6_N4_RX_RX_SUMMER_CAL_SPD_MODE 0x30c #define QSERDES_V6_N4_RX_RX_BKUP_CTRL1 0x310 =20 --=20 2.55.0 From nobody Fri Sep 25 21:40:20 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 130C93AAF50; Tue, 8 Sep 2026 07:54:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788854087; cv=none; b=XqSXXij777T7FZc/xZL3I0kA6skMQC9ZoKzQUzBp1gYyRaxwy83ySScG9/wQ5++xuyr6iZp0s72Mxy5xpyn2MeNQkolwqx4tT03m1HPAGSA28EMLYrVwWexNmHItWFRVLwdyVwQOJbDCC/IRBE8bh4T6mHDNypC+HP7oBqAODcs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788854087; c=relaxed/simple; bh=SlQO7rIdYY9yChl+hzFYsm/XNTniMdBGjio63bOFMe8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XGiGAwUQuV3z7nKQn8Bv1fpYThpBIGZi2io1pXtpcxgsk9XFL2FOi26Cf/+Ls8A6VdisJnP/dWkNWRTtlWWeoGXPhQ2bDwzBRNWWQl4KWO/dDzWHDwJbLoHqlz7QZoLevDHiy8L9qnTQTJscxVB4ipk5GKaX5p1OSxYT2kKHlLI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cyhNdHaj; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cyhNdHaj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 942B81F00A3D; Tue, 8 Sep 2026 07:54:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788854085; bh=omC+ADQGhWrV5MgDpbp1XKLolbL8X6xWihEXky/crWg=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=cyhNdHaj6xj+bEH2TkiQWZhfuwTaLD6O7vmNeKruGlcq/r2IRFvICieCn4N7WqmoO hcG0nCCeraWrE2eqDxUC+xwBDkczEkTlO1y5J8jfTGAJ8uANBnhhO8xXUYlC3reT5+ T7xoUE7PprtGijQIdMH3KrYwT3TJbeUJzmD5SMLWuuIZ00M+5pmvmdJuEVbVLUIjWd nzlYotIDFr/Gl95hxrNmIBeuaUF2txKk4jmEBEuilOA0Tsccp4gWn2t6OgNCXlO0c1 TApbb1/7b6eH+Fn2TR40+S4YNrsAE8eIFAqWshNfOXHb5mbXItBZuDW3c78wt/8ERl WDI3xtxEGA3tQ== From: Konrad Dybcio Date: Tue, 08 Sep 2026 09:54:09 +0200 Subject: [PATCH v5 5/5] arm64: dts: qcom: hamoa: Extend QMPPHY description for USB4 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: <20260908-topic-usb4phy-v5-5-73aac69578ef@oss.qualcomm.com> References: <20260908-topic-usb4phy-v5-0-73aac69578ef@oss.qualcomm.com> In-Reply-To: <20260908-topic-usb4phy-v5-0-73aac69578ef@oss.qualcomm.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam Cc: linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, usb4-upstream@oss.qualcomm.com, Raghavendra Thoorpu , Mika Westerberg , Sven Peter , Konrad Dybcio , Dmitry Baryshkov , Abel Vesa , Manivannan Sadhasivam X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788854054; l=2316; i=konrad.dybcio@oss.qualcomm.com; s=20230215; h=from:subject:message-id; bh=lN4nrDTYMJmLAv8lVb0zQ5OyT2boIMiMRaDRPS2FlMA=; b=OULxaJdMiV36Wi43wmfNiyFhIBLDMt1SpTV7xco8S34QpuFOTtsb7sYNmkaHPBGEIKPrUr/SW WEfSH8lwJB4BZXjPqsr6mXZDJ8RruhKehjlElaa8J/Ei2G8nzdVjXur X-Developer-Key: i=konrad.dybcio@oss.qualcomm.com; a=ed25519; pk=iclgkYvtl2w05SSXO5EjjSYlhFKsJ+5OSZBjOkQuEms= From: Konrad Dybcio The USB4 part of the QMPPHY requires that one more GCC clock (P2RR2P - PHY-to-Router, Router-to-PHY) is enabled for the PHY to initialize successfully. Describe that. Reviewed-by: Dmitry Baryshkov Reviewed-by: Abel Vesa Acked-by: Manivannan Sadhasivam Signed-off-by: Konrad Dybcio --- arch/arm64/boot/dts/qcom/hamoa.dtsi | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom= /hamoa.dtsi index 5e92645c5c3c..4df45d9176f7 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -2838,11 +2838,13 @@ usb_1_ss0_qmpphy: phy@fd5000 { clocks =3D <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>, <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>, - <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; + <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>, + <&gcc GCC_USB4_0_PHY_P2RR2P_PIPE_CLK>; clock-names =3D "aux", "ref", "com_aux", - "usb3_pipe"; + "usb3_pipe", + "p2rr2p_pipe"; =20 power-domains =3D <&gcc GCC_USB_0_PHY_GDSC>; =20 @@ -2909,11 +2911,13 @@ usb_1_ss1_qmpphy: phy@fda000 { clocks =3D <&gcc GCC_USB3_SEC_PHY_AUX_CLK>, <&tcsr TCSR_USB4_1_CLKREF_EN>, <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>, - <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>; + <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>, + <&gcc GCC_USB4_1_PHY_P2RR2P_PIPE_CLK>; clock-names =3D "aux", "ref", "com_aux", - "usb3_pipe"; + "usb3_pipe", + "p2rr2p_pipe"; =20 power-domains =3D <&gcc GCC_USB_1_PHY_GDSC>; =20 @@ -2980,11 +2984,13 @@ usb_1_ss2_qmpphy: phy@fdf000 { clocks =3D <&gcc GCC_USB3_TERT_PHY_AUX_CLK>, <&tcsr TCSR_USB4_2_CLKREF_EN>, <&gcc GCC_USB3_TERT_PHY_COM_AUX_CLK>, - <&gcc GCC_USB3_TERT_PHY_PIPE_CLK>; + <&gcc GCC_USB3_TERT_PHY_PIPE_CLK>, + <&gcc GCC_USB4_2_PHY_P2RR2P_PIPE_CLK>; clock-names =3D "aux", "ref", "com_aux", - "usb3_pipe"; + "usb3_pipe", + "p2rr2p_pipe"; =20 power-domains =3D <&gcc GCC_USB_2_PHY_GDSC>; =20 --=20 2.55.0