From nobody Mon May 25 05:12:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 B37063ED5B6; Mon, 18 May 2026 10:32:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779100375; cv=none; b=JytD4rxbsYO2sgxo1Z48Ec5xH1O5HOTa29mr6co8L3JF3C/5vti+WRqA2oi2ycX09Hh1iyFaJKOnPKkBgbFsOL2y2uocMtP441PPN9qM8Yxy/ZpddKgs/R9Vb5Qx0eKmayK2gjes8TPUnYH9R47revZociDj+dHIXG8wlugwITY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779100375; c=relaxed/simple; bh=Bx+uK0De2e8QKsDbMgINkrI+kBC4yYhtPUn60fv3ne0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aZb3m1IhjcrWgGIJvaRO4Awbqw5wvauK8fG6iC0BvCkf2XORGRrVNxRb+AIH/FQB34RPP1rc87s0ZlYg/6hciRcVlH7oVNMGebZjhKI6R92hiHMykLBhsJjfcXKntzE8Rj7lMVGi0wDlcvgHOCw5V7ob7s/RmPnPclcnBqa6vrA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hpjC0vNG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hpjC0vNG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F2DBEC2BCB8; Mon, 18 May 2026 10:32:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1779100375; bh=Bx+uK0De2e8QKsDbMgINkrI+kBC4yYhtPUn60fv3ne0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hpjC0vNGT49oMapbw3QF4sY1siLZmwzxAKWYJZZAbbqd9tK4YVApCi5160gwA51B1 rlTXJsCRxTZqS34ni3XF+w8RofJ0tP4GQpyLQ0rPwotL3difYOXs7QPvYTXtnVd7w3 0BRjHT5dEzA1kZ+nJ4qqQm/Ru7JLKjGnrHAZHXzaYJbPU/zTwIXJh0n2v5lEo5LSOs OQBq+4tkHTRyEmeBzGDh+/NrnoyjXMgW9y9AKYOxbFrPlQy5aP2M5wonS4KdK/d9GF b0SsLF1MIDtut0K7NdHDmesq/4SjoTptSkoaSj/hyLgzmn9IusmX3091rywq0zv7N4 9BQEAd+PX1hvA== From: Konrad Dybcio Date: Mon, 18 May 2026 12:29:48 +0200 Subject: [PATCH 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: <20260518-topic-usb4phy-v1-1-71d827c49dca@oss.qualcomm.com> References: <20260518-topic-usb4phy-v1-0-71d827c49dca@oss.qualcomm.com> In-Reply-To: <20260518-topic-usb4phy-v1-0-71d827c49dca@oss.qualcomm.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio 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 X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1779100365; l=1927; i=konrad.dybcio@oss.qualcomm.com; s=20230215; h=from:subject:message-id; bh=pSMLt5sTaDAUG12dp7QckV1kipkrWLzLV1rYLCisTNU=; b=RhurK+mAgHAvX0Ecu9GE8VFqhRDtVVBt+tphD/OVy7nmVSYy3fz4Qn/qL6Z2RB/dmk8ubTDtl IBDNDYMUm3DDrSzq1NtOmWtfRNYOEzhplY34C1qxGn6oa6s9GNPhVAV 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. Signed-off-by: Konrad Dybcio --- .../devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml | 3= ++- include/dt-bindings/phy/phy-qcom-qmp.h | 1= + 2 files changed, 3 insertions(+), 1 deletion(-) 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 3d537b7f9985..eba4bee474fb 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 @@ -52,7 +52,7 @@ properties: - const: ref - const: com_aux - const: usb3_pipe - - const: cfg_ahb + - enum: [ p2rr2p_pipe, cfg_ahb ] =20 power-domains: maxItems: 1 @@ -186,6 +186,7 @@ allOf: enum: - qcom,sc7180-qmp-usb3-dp-phy - qcom,sdm845-qmp-usb3-dp-phy + - qcom,x1e80100-qmp-usb3-dp-phy then: properties: clocks: 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.54.0 From nobody Mon May 25 05:12:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 39D373E95B2; Mon, 18 May 2026 10:33:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779100381; cv=none; b=qTc1SSjksl8+R5DAJTEllFIJhcQNi6R1kl5eg6R9u1IfQEatfJ+ccC/u/owMUq6CoyQw2vcXw4Jjuprh5e8qz/bOGmaOf7WT3a/PvwzyMPGggVtSRB0Ovo0pSbNF/nAZh+nXGRLQS8lvX0iRP7lqWl/SpTEKLh4jezObhuYGun4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779100381; c=relaxed/simple; bh=u4mlMQuiRSVOJoZk0W9VqXiNcwQBWqJwQpwyGvpon/w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ru12k/9LW8U52ynUWEmnlU5AQYkNIGfy5ncIupAgCRc2Nq4jyHbogDMRIB9nZA+utQgvq4t4ZJwKf3nlEZyhxVG2Nik5Tj+Ty8zQK8GXIiMWZGdFTGwRhDQffNbxJ2OZZB1mQeNuaUVXZ4Dbs2bJ6BLUZuzgdeoVsNPrXyAmzi4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZJPqUXk9; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZJPqUXk9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B2286C2BCC6; Mon, 18 May 2026 10:32:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1779100380; bh=u4mlMQuiRSVOJoZk0W9VqXiNcwQBWqJwQpwyGvpon/w=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ZJPqUXk9C7D6Skr2TewVA109U1nl6rojJkb3hOnerw8JaFH01t7Jp0RxNIwADMh+L gcyI0My5UXZFeWnFGu9DEwpbDtJy8ySc2xY5Zs6glEeeibD0WalAaLP7qQhMBRi6QG LLt0CdJpCx45pk+mFaSIzyee30qnNghStmR1a20KYwoH9oDfGpjjaq1E6PoTR1RLoU DO3l6ohZZQMfs6+0ndlpYSjD9J5RwJQ+XpKN7qGuUWpWPsYM4LZWCipo3KB7nwgrom Fr0pbXNUau8GHVDBC57KvT1e+tSeK8BweVTh+PxpWlvYTMTv4TIXKkcwP9QEvBx+N6 gWM/EwdAAqu+g== From: Konrad Dybcio Date: Mon, 18 May 2026 12:29:49 +0200 Subject: [PATCH 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: <20260518-topic-usb4phy-v1-2-71d827c49dca@oss.qualcomm.com> References: <20260518-topic-usb4phy-v1-0-71d827c49dca@oss.qualcomm.com> In-Reply-To: <20260518-topic-usb4phy-v1-0-71d827c49dca@oss.qualcomm.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio 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 X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1779100365; l=1765; i=konrad.dybcio@oss.qualcomm.com; s=20230215; h=from:subject:message-id; bh=RMwhfzMTBEbqo12DI9ixrBoeEOqCH1NR2RKBf/hbieM=; b=AlyKt6pSJ+eYUl4BNy94aQsgcx84VvCq8TLQuBoxvud08RayFKVzo9wrDoixbllXq8g/RVP2d DdYg++MadnIDHHLqs0yjHVPDGwobA/FTD3UPon58ucRoFN5ESPsdOX/ 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. Signed-off-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov --- include/linux/phy/phy-tbt.h | 14 ++++++++++++++ include/linux/phy/phy.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/include/linux/phy/phy-tbt.h b/include/linux/phy/phy-tbt.h new file mode 100644 index 000000000000..5f48059814e1 --- /dev/null +++ b/include/linux/phy/phy-tbt.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..26a91c070f8c 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.54.0 From nobody Mon May 25 05:12:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 EBBC83ED5A9; Mon, 18 May 2026 10:33:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779100390; cv=none; b=PXRyGL5qzUo69MZDGm/b04S4pIpgYVV0Vn9a1R1b0r9d0UpEvTGPiJhSmaEaUCzo4lmVF2frxC3PoVdXiwJMVlLKbaVul4wfg+j5OM/ok5wI1eJ9AFXEGLaD9FaKoX0QRwvvOrruEHYCF1dHxPAu8X59/mmqeefEiRH4LUvCgD4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779100390; c=relaxed/simple; bh=M7QM8+uaEwca/mAYvXP9Zxb0ywesKSGpaV0u8FK8FBc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=G75HJNhlvzYAT3m/Lki/6eiieqgGfrVF+GXFEGev7LnkdnitjyBbhnStTp/t5uVkDDbjG4yXm1ZlXrWM3rFK3xB6MsZHMN7BGFXnKv2MBrioi0g6AuAnAOdBMSfODFJXgqIG7VdXfHVgwtr3owFmQSno4wuBOdMmOc1xHHBUIEI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bYGfYRh+; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bYGfYRh+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 59C50C2BCB8; Mon, 18 May 2026 10:33:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1779100386; bh=M7QM8+uaEwca/mAYvXP9Zxb0ywesKSGpaV0u8FK8FBc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bYGfYRh+52BRwN8NLMS21ZrycIsjtL8jBDb3UT91LYB5TTyHqIWTrdnoxaIVO8FIE T64hTcPGn77IKp88QAnzGYCXEy1YLRMGSNgIcNjD9W79q3LTJ/BUJr8Sk2BC756Ccn o6Hf2tEJip+ixA5PdzEJlcGLuMe/MBhhrJVFpr1BJAQaZ6LoR1yl88LPbqA/Ca1ezq I1y19mctGUP1sc+f8WAeWzbG+cTXNRO+TjaiTVLdMcvypk/f9hHgnhkLAYGMOp52HO m5IyoZZVGyfmlJ/qQ4IfuLG37S1KMnAq7y6C0VJ+c+QY9Tmc38WOuz4lcdw59qa37n zZ/c+sgdCGJRQ== From: Konrad Dybcio Date: Mon, 18 May 2026 12:29:50 +0200 Subject: [PATCH 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: <20260518-topic-usb4phy-v1-3-71d827c49dca@oss.qualcomm.com> References: <20260518-topic-usb4phy-v1-0-71d827c49dca@oss.qualcomm.com> In-Reply-To: <20260518-topic-usb4phy-v1-0-71d827c49dca@oss.qualcomm.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio 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 X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1779100365; l=23183; i=konrad.dybcio@oss.qualcomm.com; s=20230215; h=from:subject:message-id; bh=Vv7DNTXdWoblbl02zHXDTUX4bh/QPzbVQ0uNT/+6gTE=; b=uBznFoGtf4Bi2u8nxHWKTRVYz/fCwqBFzh9SQGDlpA+l/6psxSkbawV8fJcmUX9aheWabqKFc XTgBz72LrppC6jmVYOqf45cIn5rHvnVxzcWS2VzwrcI65vvksFDGjtv 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. Signed-off-by: Konrad Dybcio --- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 392 ++++++++++++++++++++++++--= ---- 1 file changed, 322 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 93f1aa10d400..898f42de4a08 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 @@ -61,10 +62,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) @@ -77,6 +82,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 */ @@ -89,6 +96,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, @@ -2198,6 +2206,8 @@ struct qmp_combo_offsets { u16 dp_txa; u16 dp_txb; u16 dp_dp_phy; + u16 usb4_serdes; + u16 usb4_pcs; }; =20 struct qmp_phy_cfg { @@ -2245,6 +2255,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; @@ -2286,8 +2308,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; @@ -2306,6 +2332,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 usb4phy_init_count; + struct clk_fixed_rate pipe_clk_fixed; struct clk_hw dp_link_hw; struct clk_hw dp_pixel_hw; @@ -3661,14 +3691,26 @@ 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 *com =3D qmp->com; void __iomem *pcs_aon =3D qmp->pcs_aon; + void __iomem *pcs =3D qmp->pcs; int ret; u32 val; =20 if (!force && qmp->init_count++) return 0; =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); @@ -3695,8 +3737,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 (pcs_aon && cfg->regs[QPHY_AON_TOGGLE_ENABLE]) { @@ -3712,6 +3755,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) { @@ -3739,12 +3786,21 @@ 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 DP PLL if there are no active tunnels after router setu= p */ + 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; @@ -3859,6 +3915,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; @@ -3866,10 +3926,39 @@ 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 ret =3D clk_prepare_enable(qmp->pipe_clk); if (ret) { @@ -3878,17 +3967,19 @@ static int qmp_combo_usb_power_on(struct phy *phy) } =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 @@ -3921,18 +4012,22 @@ 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->usb4phy_init_count) + pcs =3D qmp->usb4_pcs; =20 clk_disable_unprepare(qmp->pipe_clk); =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; @@ -3943,21 +4038,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->usb4phy_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 @@ -3966,20 +4067,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->usb4phy_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) @@ -3991,6 +4098,119 @@ 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->usb4phy_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->usb4phy_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) + 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) + return ret; + + ret =3D qmp_combo_usb_power_on(phy); + if (ret) { + 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->usb4phy_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->usb4phy_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=3D PHY_SUBMODE_USB4 || submode =3D=3D PHY_SUBMODE_TBT3) { + qmp->usb4_phy_submode =3D submode; + return 0; + } + + return -EINVAL; +} + static const struct phy_ops qmp_combo_usb_phy_ops =3D { .init =3D qmp_combo_usb_init, .exit =3D qmp_combo_usb_exit, @@ -3998,6 +4218,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, @@ -4037,9 +4264,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 @@ -4051,9 +4281,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], @@ -4427,24 +4660,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->usb4phy_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->usb4phy_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; } @@ -4452,7 +4690,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 @@ -4463,6 +4700,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->usb4phy_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 */ @@ -4495,41 +4755,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) @@ -4733,6 +4963,9 @@ static int qmp_combo_parse_dt(struct qmp_combo *qmp) } qmp->dp_dp_phy =3D base + offs->dp_dp_phy; =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; @@ -4743,6 +4976,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 @@ -4758,6 +4997,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); @@ -4965,6 +5206,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.54.0 From nobody Mon May 25 05:12:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 945AB3F0A91; Mon, 18 May 2026 10:33:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779100391; cv=none; b=rZ5duNaR4NnJwRWDEgqTnHPfXCgTmf/s5uyqznCNJ03EewwNYS5OxuX5hUAsp/z+a6I5F7tUleiqtuQGhj0w72+gRYpNAx2cu/kwgx1pdAJ3owkH2ClyJHXKHHWy/Cob+8R+RAzTeOnvPqwzz1BiIJ3Ji03lSdTYuSUlwipk6RQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779100391; c=relaxed/simple; bh=Lto80FV9XLO8w8CT7E6/SeI9mh0aebiItcDXoSXw4aM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=D8ZT6hIZsP7g0YKlLkGmqK4kpOqTZQtNb79e+cY4xW0XzN1sA5XG9KFJ8MaVK6XjyzzX05FixeflWW6dvSi62mKr+8y6IokEKFjw4y+/Ws+WFu/urtiMUj1rw/6HfGqtYJMmDyqiqUkBf1THNXXoJy+vl1g8x4L5IhHAPLUh0SU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JgbaSZUm; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JgbaSZUm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 05611C2BCC6; Mon, 18 May 2026 10:33:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1779100390; bh=Lto80FV9XLO8w8CT7E6/SeI9mh0aebiItcDXoSXw4aM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JgbaSZUmv3UJHhtg1UYTw37T+UNH7xPFwYm2JV01zPDzxZCYYF66vgJJ0e2YsC/Ne bW9LP3DRVJDGSrM+dF87mYgRzgdHJarX/lQv4GiZfpIkFtJNTdVPj7pYMZcIOPbROg 2bHIh2k1JvyWy+ebo7cP53EczSG2uHoAWc8h1X4vMbnBWmWCO9hE0dn2HB1oDgtNNm vVjKpKgwhWoz2hpIZm39ssKCO5H60D4SxdF4RJjbl6w3g6/SUyu8SXNaMirBQiMX9g n+SHqON4R/wKZOBQSynvffcKCNGjKv+lfwrkxmrwAxGYN2SYzPybR0SegZZnm68lTP bXvsJkG1N8ebQ== From: Konrad Dybcio Date: Mon, 18 May 2026 12:29:51 +0200 Subject: [PATCH 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: <20260518-topic-usb4phy-v1-4-71d827c49dca@oss.qualcomm.com> References: <20260518-topic-usb4phy-v1-0-71d827c49dca@oss.qualcomm.com> In-Reply-To: <20260518-topic-usb4phy-v1-0-71d827c49dca@oss.qualcomm.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio 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 X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1779100365; l=19894; i=konrad.dybcio@oss.qualcomm.com; s=20230215; h=from:subject:message-id; bh=7sucHOq4upL6BQiyJczh25Wph2pP6NC9RTXlO1emwd8=; b=F4wf8MXkfOAVqfV9JKgO5ulZboVu4AhCwklO8Sj8CuSChAhLdiFQdbrUwQKwzvPHMZ/yu0a+N n5W55ycLRR2CAL2Fx+XUEJQiLmtrWkFjzWtvsQqIW9gfV9wNWtZycnF 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. 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 898f42de4a08..0916d9a4599e 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -235,6 +235,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, @@ -1812,7 +1813,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), @@ -1873,6 +1952,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), @@ -1911,6 +2052,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), @@ -2429,6 +2587,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, @@ -2689,11 +2864,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, @@ -2728,6 +2903,19 @@ static const struct qmp_phy_cfg x1e80100_usb3dpphy_c= fg =3D { .configure_dp_phy =3D qmp_v4_configure_dp_phy, .calibrate_dp_phy =3D qmp_v4_calibrate_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, @@ -5296,7 +5484,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.54.0 From nobody Mon May 25 05:12:28 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 413A93F1650; Mon, 18 May 2026 10:33:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779100396; cv=none; b=NQHRvq2+Z/Ch7wf+JKwOlK9dgRksYKkCtOc+YK0FjAQcD7+DMr/lsxDg7bGvZugOw3A3MKNzPHbQE5iHadBBE0XhliUhmv+7mO78Wtwg/bwPXOOO4SeMTT/1NuM9hOGSg61bTNf8PhkvznQnOdkAbBMMhIJp75nF4wOtYdJ3rHA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779100396; c=relaxed/simple; bh=Ni9fQvmbrgzkq9Jn7zqHNgRT1E+F5kIfL7a6vKy9HWE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kP+DA6OBKHyy5dOFQVb0vGIqrRyz3zHLGgfdRwROg/LJ7SZ5J6O+m5lqHJVM356jihiWiMA4B7OGP27pnoko+S9VFTuPSXBR3rvQ+0t0Y2NaTN0xKMwl6q5vvmDoQA0nvA9rvoL0ut004UMsWViOTXH6YrTA6WFSjJBDOd8cxCU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Qzl36VC6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Qzl36VC6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1C5A1C2BCB8; Mon, 18 May 2026 10:33:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1779100394; bh=Ni9fQvmbrgzkq9Jn7zqHNgRT1E+F5kIfL7a6vKy9HWE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Qzl36VC6NQ+H2cueH7saMlIS4JGN5VwNcEuWdJLeeR7LDspbnwNZ48rC5OiBceJxe XwUxzN07D6+I1xOeE1ulP0weOLX1JbzI3uRW7NB0nQ7wEnALshZlwYmD3dCZ4RyFY5 hTvYdTJ6AoSKwutNSHaN0FXoijti04gTcP+BxuSTCm33d/KQ+APECDQNA+xgHh4jqo tZGJcjKboq8JqOuRUzQCgKo5BmYlagGt4XhatrGjaHnFpXA9bRZY7SQ3bm9vyDCeE/ xTPGuC+ME3ROq7FJckU/0qMwCAEzE7e17++w1SV4LUeC5BPX/4hFYb8rAibE0QQL/x ym/H7BPR6z2yA== From: Konrad Dybcio Date: Mon, 18 May 2026 12:29:52 +0200 Subject: [PATCH 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: <20260518-topic-usb4phy-v1-5-71d827c49dca@oss.qualcomm.com> References: <20260518-topic-usb4phy-v1-0-71d827c49dca@oss.qualcomm.com> In-Reply-To: <20260518-topic-usb4phy-v1-0-71d827c49dca@oss.qualcomm.com> To: Vinod Koul , Neil Armstrong , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio 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 X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1779100365; l=2122; i=konrad.dybcio@oss.qualcomm.com; s=20230215; h=from:subject:message-id; bh=NxiWYOiKuL7FnNRrsrEKfegkS+O2u9GgOYEUAAJlDz4=; b=AOd7m6fqje/mnmm+RIuJqH2HF80M35P0IB4uPwFUCtSdk5scTkiVAPGoC3VAMSt99DCRVXM+P clIMsnFuvXTCJXktngrxtMdT4ipwtiD7YJKsCL8EDjQDc14ltb9ndMY 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. 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 4ba751a65142..63430f49ba2a 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi @@ -2883,11 +2883,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 @@ -2954,11 +2956,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 @@ -3025,11 +3029,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.54.0