* [PATCH 1/5] dt-bindings: phy: qcom,qmp-usb: Add IPQ9650 USB3 PHY
2026-08-24 6:37 [PATCH 0/5] Add support for USB phys in IPQ9650 Varadarajan Narayanan
@ 2026-08-24 6:37 ` Varadarajan Narayanan
2026-08-24 6:37 ` [PATCH 2/5] dt-bindings: phy: qcom,usb-snps-femto-v2: Add IPQ9650 compatible Varadarajan Narayanan
` (3 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Varadarajan Narayanan @ 2026-08-24 6:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Wesley Cheng
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Varadarajan Narayanan
Document the Qualcomm IPQ9650 USB3 QMP PHY compatible.
Use a standalone compatible because the IPQ9650 PHY has register
configuration data that differs from the currently supported SoCs and
should not fall back to an existing definition.
Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
.../devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml
index 01342823e57f..746c5a331f48 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml
@@ -23,6 +23,7 @@ properties:
- qcom,ipq6018-qmp-usb3-phy
- qcom,ipq8074-qmp-usb3-phy
- qcom,ipq9574-qmp-usb3-phy
+ - qcom,ipq9650-qmp-usb3-phy
- qcom,msm8996-qmp-usb3-phy
- qcom,qcs8300-qmp-usb3-uni-phy
- qcom,qdu1000-qmp-usb3-uni-phy
@@ -102,6 +103,7 @@ allOf:
- qcom,ipq6018-qmp-usb3-phy
- qcom,ipq8074-qmp-usb3-phy
- qcom,ipq9574-qmp-usb3-phy
+ - qcom,ipq9650-qmp-usb3-phy
- qcom,msm8996-qmp-usb3-phy
- qcom,sdx55-qmp-usb3-uni-phy
- qcom,sdx65-qmp-usb3-uni-phy
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 2/5] dt-bindings: phy: qcom,usb-snps-femto-v2: Add IPQ9650 compatible
2026-08-24 6:37 [PATCH 0/5] Add support for USB phys in IPQ9650 Varadarajan Narayanan
2026-08-24 6:37 ` [PATCH 1/5] dt-bindings: phy: qcom,qmp-usb: Add IPQ9650 USB3 PHY Varadarajan Narayanan
@ 2026-08-24 6:37 ` Varadarajan Narayanan
2026-08-24 6:37 ` [PATCH 3/5] phy: qcom: qmp-usb: Add IPQ9650 USB3 PHY configuration Varadarajan Narayanan
` (2 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Varadarajan Narayanan @ 2026-08-24 6:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Wesley Cheng
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Varadarajan Narayanan
Document the IPQ9650 USB high-speed PHY compatible. The PHY uses the SNPS
HS 6 nm PHY fallback, so allow it in the binding.
Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml b/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
index 661759b25064..405bfad2080e 100644
--- a/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
@@ -20,6 +20,10 @@ properties:
- qcom,sa8775p-usb-hs-phy
- qcom,sc8280xp-usb-hs-phy
- const: qcom,usb-snps-hs-5nm-phy
+ - items:
+ - enum:
+ - qcom,ipq9650-usb-hs-phy
+ - const: qcom,usb-snps-hs-6nm-phy
- items:
- enum:
- qcom,qcs8300-usb-hs-phy
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 3/5] phy: qcom: qmp-usb: Add IPQ9650 USB3 PHY configuration
2026-08-24 6:37 [PATCH 0/5] Add support for USB phys in IPQ9650 Varadarajan Narayanan
2026-08-24 6:37 ` [PATCH 1/5] dt-bindings: phy: qcom,qmp-usb: Add IPQ9650 USB3 PHY Varadarajan Narayanan
2026-08-24 6:37 ` [PATCH 2/5] dt-bindings: phy: qcom,usb-snps-femto-v2: Add IPQ9650 compatible Varadarajan Narayanan
@ 2026-08-24 6:37 ` Varadarajan Narayanan
2026-08-24 6:37 ` [PATCH 4/5] phy: qcom: snps-femto-v2: Move PHY init registers to config tables Varadarajan Narayanan
2026-08-24 6:37 ` [PATCH 5/5] phy: qcom: snps-femto-v2: Add IPQ9650 support Varadarajan Narayanan
4 siblings, 0 replies; 11+ messages in thread
From: Varadarajan Narayanan @ 2026-08-24 6:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Wesley Cheng
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Varadarajan Narayanan
Add the USB3 QMP PHY configuration for IPQ9650, including the SoC-specific
init tables and compatible data.
IPQ9650 uses settings that do not match any existing supported SoC, so add
a dedicated configuration to allow the driver to support it.
Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 118 ++++++++++++++++++++++++++++++++
1 file changed, 118 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
index b0790bcf0bc8..e772e1fa27cf 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
@@ -400,6 +400,101 @@ static const struct qmp_phy_init_tbl ipq8074_usb3_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
};
+static const struct qmp_phy_init_tbl ipq9650_usb3_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x7d),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xd4),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x68),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xaa),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xa2),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x01),
+};
+
+static const struct qmp_phy_init_tbl ipq9650_usb3_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xb5),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_2, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x00),
+};
+
+static const struct qmp_phy_init_tbl ipq9650_usb3_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x99),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x54),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x47),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe4),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x64),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xf6),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x89),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x35),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c),
+};
+
+static const struct qmp_phy_init_tbl ipq9650_usb3_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1, 0xd0),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2, 0x07),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3, 0x20),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6, 0x13),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG, 0x0c),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_FLL_CNTRL2, 0x83),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_FLL_CNTRL1, 0x02),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_FLL_CNT_VAL_L, 0x09),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_FLL_MAN_CODE, 0x40),
+};
+
+static const struct qmp_phy_init_tbl ipq9650_usb3_pcs_usb_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8),
+};
+
static const struct qmp_phy_init_tbl msm8996_usb3_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V2_COM_SYSCLK_EN_SEL, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V2_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
@@ -1596,6 +1691,26 @@ static const struct qmp_phy_cfg ipq9574_usb3phy_cfg = {
.regs = qmp_v3_usb3phy_regs_layout,
};
+static const struct qmp_phy_cfg ipq9650_usb3phy_cfg = {
+ .offsets = &qmp_usb_offsets_v4,
+
+ .serdes_tbl = ipq9650_usb3_serdes_tbl,
+ .serdes_tbl_num = ARRAY_SIZE(ipq9650_usb3_serdes_tbl),
+ .tx_tbl = ipq9650_usb3_tx_tbl,
+ .tx_tbl_num = ARRAY_SIZE(ipq9650_usb3_tx_tbl),
+ .rx_tbl = ipq9650_usb3_rx_tbl,
+ .rx_tbl_num = ARRAY_SIZE(ipq9650_usb3_rx_tbl),
+ .pcs_tbl = ipq9650_usb3_pcs_tbl,
+ .pcs_tbl_num = ARRAY_SIZE(ipq9650_usb3_pcs_tbl),
+ .pcs_usb_tbl = ipq9650_usb3_pcs_usb_tbl,
+ .pcs_usb_tbl_num = ARRAY_SIZE(ipq9650_usb3_pcs_usb_tbl),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = qmp_v4_usb3phy_regs_layout,
+
+ .has_pwrdn_delay = true,
+};
+
static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
.offsets = &qmp_usb_offsets_v3_msm8996,
@@ -2483,6 +2598,9 @@ static const struct of_device_id qmp_usb_of_match_table[] = {
}, {
.compatible = "qcom,ipq9574-qmp-usb3-phy",
.data = &ipq9574_usb3phy_cfg,
+ }, {
+ .compatible = "qcom,ipq9650-qmp-usb3-phy",
+ .data = &ipq9650_usb3phy_cfg,
}, {
.compatible = "qcom,msm8996-qmp-usb3-phy",
.data = &msm8996_usb3phy_cfg,
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 4/5] phy: qcom: snps-femto-v2: Move PHY init registers to config tables
2026-08-24 6:37 [PATCH 0/5] Add support for USB phys in IPQ9650 Varadarajan Narayanan
` (2 preceding siblings ...)
2026-08-24 6:37 ` [PATCH 3/5] phy: qcom: qmp-usb: Add IPQ9650 USB3 PHY configuration Varadarajan Narayanan
@ 2026-08-24 6:37 ` Varadarajan Narayanan
2026-08-24 6:49 ` sashiko-bot
` (2 more replies)
2026-08-24 6:37 ` [PATCH 5/5] phy: qcom: snps-femto-v2: Add IPQ9650 support Varadarajan Narayanan
4 siblings, 3 replies; 11+ messages in thread
From: Varadarajan Narayanan @ 2026-08-24 6:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Wesley Cheng
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Varadarajan Narayanan
The driver currently programs the common PHY register sequence directly in
qcom_snps_hsphy_init(), with the fixed register writes split around the
override parameter handling. This makes it hard to support SoCs that need a
different sequence or different values.
Move the fixed pre- and post-override register programming into per-
compatible configuration tables, and keep the 7 nm override parameters in
the same match-data structure. This allows the driver to share the common
sequence while adding SoC-specific sequences for future platforms such as
IPQ9650.
Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 120 ++++++++++++++++----------
1 file changed, 74 insertions(+), 46 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
index 980ad1fb1e2e..5ffbe1a77dd4 100644
--- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
+++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
@@ -104,6 +104,18 @@ struct phy_override_seq {
u8 mask;
};
+struct phy_reg_config {
+ u32 offset;
+ u32 mask;
+ u32 val;
+};
+
+struct phy_config_data {
+ const struct phy_reg_config *pre;
+ const struct override_param_map *override;
+ const struct phy_reg_config *post;
+};
+
#define NUM_HSPHY_TUNING_PARAMS (9)
/**
@@ -383,13 +395,42 @@ static const struct override_param_map sc7280_snps_7nm_phy[] = {
{},
};
+static const struct phy_reg_config hs_5nm_phy_pre[] = {
+ { USB2_PHY_USB_PHY_CFG0, UTMI_PHY_CMN_CTRL_OVERRIDE_EN, UTMI_PHY_CMN_CTRL_OVERRIDE_EN },
+ { USB2_PHY_USB_PHY_UTMI_CTRL5, POR, POR },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0, FSEL_MASK, 0 },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1, PLLBTUNE, PLLBTUNE },
+ { USB2_PHY_USB_PHY_REFCLK_CTRL, REFCLK_SEL_DEFAULT, REFCLK_SEL_MASK },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1, VBUSVLDEXTSEL0, VBUSVLDEXTSEL0 },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL1, VBUSVLDEXT0, VBUSVLDEXT0 },
+ { UINT_MAX, 0, 0 },
+};
+
+static const struct phy_reg_config hs_5nm_phy_post[] = {
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2, VREGBYPASS, VREGBYPASS },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL2, USB2_SUSPEND_N_SEL | USB2_SUSPEND_N,
+ USB2_SUSPEND_N_SEL | USB2_SUSPEND_N },
+ { USB2_PHY_USB_PHY_UTMI_CTRL0, SLEEPM, SLEEPM },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0, SIDDQ, 0 },
+ { USB2_PHY_USB_PHY_UTMI_CTRL5, POR, 0 },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL2, USB2_SUSPEND_N_SEL, 0 },
+ { USB2_PHY_USB_PHY_CFG0, UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 0 },
+ { UINT_MAX, 0, 0 },
+};
+
static int qcom_snps_hsphy_init(struct phy *phy)
{
struct qcom_snps_hsphy *hsphy = phy_get_drvdata(phy);
+ const struct phy_config_data *data;
+ const struct phy_reg_config *tmp;
int ret, i;
dev_vdbg(&phy->dev, "%s(): Initializing SNPS HS phy\n", __func__);
+ data = of_device_get_match_data(hsphy->dev);
+ if (!data)
+ return -ENODEV;
+
ret = regulator_bulk_enable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs);
if (ret)
return ret;
@@ -414,24 +455,8 @@ static int qcom_snps_hsphy_init(struct phy *phy)
goto disable_clks;
}
- qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_CFG0,
- UTMI_PHY_CMN_CTRL_OVERRIDE_EN,
- UTMI_PHY_CMN_CTRL_OVERRIDE_EN);
- qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_UTMI_CTRL5,
- POR, POR);
- qcom_snps_hsphy_write_mask(hsphy->base,
- USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0,
- FSEL_MASK, 0);
- qcom_snps_hsphy_write_mask(hsphy->base,
- USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1,
- PLLBTUNE, PLLBTUNE);
- qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_REFCLK_CTRL,
- REFCLK_SEL_DEFAULT, REFCLK_SEL_MASK);
- qcom_snps_hsphy_write_mask(hsphy->base,
- USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1,
- VBUSVLDEXTSEL0, VBUSVLDEXTSEL0);
- qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL1,
- VBUSVLDEXT0, VBUSVLDEXT0);
+ for (tmp = data->pre; tmp->offset != UINT_MAX; tmp++)
+ qcom_snps_hsphy_write_mask(hsphy->base, tmp->offset, tmp->mask, tmp->val);
for (i = 0; i < ARRAY_SIZE(hsphy->update_seq_cfg); i++) {
if (hsphy->update_seq_cfg[i].need_update)
@@ -441,28 +466,8 @@ static int qcom_snps_hsphy_init(struct phy *phy)
hsphy->update_seq_cfg[i].value);
}
- qcom_snps_hsphy_write_mask(hsphy->base,
- USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2,
- VREGBYPASS, VREGBYPASS);
-
- qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2,
- USB2_SUSPEND_N_SEL | USB2_SUSPEND_N,
- USB2_SUSPEND_N_SEL | USB2_SUSPEND_N);
-
- qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_UTMI_CTRL0,
- SLEEPM, SLEEPM);
-
- qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0,
- SIDDQ, 0);
-
- qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_UTMI_CTRL5,
- POR, 0);
-
- qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2,
- USB2_SUSPEND_N_SEL, 0);
-
- qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_CFG0,
- UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 0);
+ for (tmp = data->post; tmp->offset != UINT_MAX; tmp++)
+ qcom_snps_hsphy_write_mask(hsphy->base, tmp->offset, tmp->mask, tmp->val);
hsphy->phy_initialized = true;
@@ -495,14 +500,34 @@ static const struct phy_ops qcom_snps_hsphy_gen_ops = {
.owner = THIS_MODULE,
};
+static const struct phy_config_data hs_5nm_phy = {
+ .pre = hs_5nm_phy_pre,
+ .post = hs_5nm_phy_post,
+};
+
+static const struct phy_config_data hs_7nm_phy = {
+ .pre = hs_5nm_phy_pre,
+ .override = sc7280_snps_7nm_phy,
+ .post = hs_5nm_phy_post,
+};
+
static const struct of_device_id qcom_snps_hsphy_of_match_table[] = {
- { .compatible = "qcom,sm8150-usb-hs-phy", },
- { .compatible = "qcom,usb-snps-hs-5nm-phy", },
+ {
+ .compatible = "qcom,sm8150-usb-hs-phy",
+ .data = &hs_5nm_phy,
+ },
+ {
+ .compatible = "qcom,usb-snps-hs-5nm-phy",
+ .data = &hs_5nm_phy,
+ },
{
.compatible = "qcom,usb-snps-hs-7nm-phy",
- .data = &sc7280_snps_7nm_phy,
+ .data = &hs_7nm_phy,
+ },
+ {
+ .compatible = "qcom,usb-snps-femto-v2-phy",
+ .data = &hs_5nm_phy,
},
- { .compatible = "qcom,usb-snps-femto-v2-phy", },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_snps_hsphy_of_match_table);
@@ -541,11 +566,14 @@ static void qcom_snps_hsphy_read_override_param_seq(struct device *dev)
s32 val;
int ret, i;
struct qcom_snps_hsphy *hsphy;
- const struct override_param_map *cfg = of_device_get_match_data(dev);
+ const struct phy_config_data *data = of_device_get_match_data(dev);
+ const struct override_param_map *cfg;
- if (!cfg)
+ if (!data || !data->override)
return;
+ cfg = data->override;
+
hsphy = dev_get_drvdata(dev);
for (i = 0; cfg[i].prop_name != NULL; i++) {
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH 4/5] phy: qcom: snps-femto-v2: Move PHY init registers to config tables
2026-08-24 6:37 ` [PATCH 4/5] phy: qcom: snps-femto-v2: Move PHY init registers to config tables Varadarajan Narayanan
@ 2026-08-24 6:49 ` sashiko-bot
2026-08-25 8:54 ` Konrad Dybcio
2026-08-25 8:56 ` Konrad Dybcio
2 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-08-24 6:49 UTC (permalink / raw)
To: Varadarajan Narayanan
Cc: vkoul, robh, linux-phy, neil.armstrong, olteanv, conor+dt,
devicetree
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] The mask and value arguments for the `USB2_PHY_USB_PHY_REFCLK_CTRL` register write are swapped in the `hs_5nm_phy_pre` configuration table.
- [High] The `USB2_AUTO_RESUME` bit is never cleared in `qcom_snps_hsphy_suspend()` due to an incorrect mask of 0.
--
--- Patch [4]: [PATCH 4/5] phy: qcom: snps-femto-v2: Move PHY init registers to config tables ---
commit 5e719820e4a23178ca8190ffc88ff2f741947939
Author: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
phy: qcom: snps-femto-v2: Move PHY init registers to config tables
This commit refactors the SNPS Femto v2 PHY driver to use per-compatible
configuration tables for fixed pre- and post-override register sequences.
This allows the driver to share the common sequence while adding SoC-specific
sequences for future platforms.
> diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
> index eb0b0f61d98e0..a34027b215f9b 100644
> --- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
> +++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
[ ... ]
> @@ -383,13 +395,42 @@ static const struct override_param_map sc7280_snps_7nm_phy[] = {
> {},
> };
>
> +static const struct phy_reg_config hs_5nm_phy_pre[] = {
> + { USB2_PHY_USB_PHY_CFG0, UTMI_PHY_CMN_CTRL_OVERRIDE_EN, UTMI_PHY_CMN_CTRL_OVERRIDE_EN },
> + { USB2_PHY_USB_PHY_UTMI_CTRL5, POR, POR },
> + { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0, FSEL_MASK, 0 },
> + { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1, PLLBTUNE, PLLBTUNE },
> + { USB2_PHY_USB_PHY_REFCLK_CTRL, REFCLK_SEL_DEFAULT, REFCLK_SEL_MASK },
[Severity: High]
This is a pre-existing issue, but are the mask and value arguments swapped
here?
The phy_reg_config structure expects the order { offset, mask, val }. By
passing REFCLK_SEL_DEFAULT as the mask and REFCLK_SEL_MASK as the value,
qcom_snps_hsphy_write_mask() will evaluate:
reg &= ~REFCLK_SEL_DEFAULT;
reg |= REFCLK_SEL_MASK & REFCLK_SEL_DEFAULT;
Because REFCLK_SEL_DEFAULT is 0x2 and REFCLK_SEL_MASK is 0x3, bit 0 is excluded
from the mask and remains unchanged. If bit 0 was set by the bootloader, the
final register value incorrectly becomes 0x3 instead of 0x2, selecting the
wrong reference clock.
(Notice that in another patch of this series, hs_6nm_phy_pre correctly uses
REFCLK_SEL_MASK as the mask, but hs_5nm_phy_pre was not corrected here.)
> + { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1, VBUSVLDEXTSEL0, VBUSVLDEXTSEL0 },
> + { USB2_PHY_USB_PHY_HS_PHY_CTRL1, VBUSVLDEXT0, VBUSVLDEXT0 },
> + { UINT_MAX, 0, 0 },
> +};
[ ... ]
While looking at how qcom_snps_hsphy_write_mask() is used in the driver, I
noticed another pre-existing issue in qcom_snps_hsphy_suspend(), which is not
modified by this patch:
[Severity: High]
This isn't a bug introduced by this patch, but does qcom_snps_hsphy_suspend()
fail to clear the USB2_AUTO_RESUME bit?
drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c:qcom_snps_hsphy_suspend() {
...
qcom_snps_hsphy_write_mask(hsphy->base,
USB2_PHY_USB_PHY_HS_PHY_CTRL2,
0, USB2_AUTO_RESUME);
...
}
By passing 0 as the mask, qcom_snps_hsphy_write_mask() will do:
reg &= ~0;
reg |= USB2_AUTO_RESUME & 0;
This leaves the register entirely unaffected, and the auto-resume bit is
left set indefinitely instead of being cleared.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260824-phy-v1-0-257d68a3210b@oss.qualcomm.com?part=4
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 4/5] phy: qcom: snps-femto-v2: Move PHY init registers to config tables
2026-08-24 6:37 ` [PATCH 4/5] phy: qcom: snps-femto-v2: Move PHY init registers to config tables Varadarajan Narayanan
2026-08-24 6:49 ` sashiko-bot
@ 2026-08-25 8:54 ` Konrad Dybcio
2026-08-27 4:29 ` Varadarajan Narayanan
2026-08-25 8:56 ` Konrad Dybcio
2 siblings, 1 reply; 11+ messages in thread
From: Konrad Dybcio @ 2026-08-25 8:54 UTC (permalink / raw)
To: Varadarajan Narayanan, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Wesley Cheng
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel
On 8/24/26 8:37 AM, Varadarajan Narayanan wrote:
> The driver currently programs the common PHY register sequence directly in
> qcom_snps_hsphy_init(), with the fixed register writes split around the
> override parameter handling. This makes it hard to support SoCs that need a
> different sequence or different values.
>
> Move the fixed pre- and post-override register programming into per-
> compatible configuration tables, and keep the 7 nm override parameters in
> the same match-data structure. This allows the driver to share the common
> sequence while adding SoC-specific sequences for future platforms such as
> IPQ9650.
>
> Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
> ---
[...]
> + for (tmp = data->pre; tmp->offset != UINT_MAX; tmp++)
"pre"/"post" alone are not descriptive - perhaps pre_tuning/post_tuning?
Or do we maybe know whether the order matters at all?
> + qcom_snps_hsphy_write_mask(hsphy->base, tmp->offset, tmp->mask, tmp->val);
Custom termination is both error-prone and memory-inefficient, add
another int to size the arrays
Konrad
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/5] phy: qcom: snps-femto-v2: Move PHY init registers to config tables
2026-08-25 8:54 ` Konrad Dybcio
@ 2026-08-27 4:29 ` Varadarajan Narayanan
0 siblings, 0 replies; 11+ messages in thread
From: Varadarajan Narayanan @ 2026-08-27 4:29 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Wesley Cheng, linux-arm-msm,
linux-phy, devicetree, linux-kernel
On Tue, Aug 25, 2026 at 10:54:58AM +0200, Konrad Dybcio wrote:
> On 8/24/26 8:37 AM, Varadarajan Narayanan wrote:
> > The driver currently programs the common PHY register sequence directly in
> > qcom_snps_hsphy_init(), with the fixed register writes split around the
> > override parameter handling. This makes it hard to support SoCs that need a
> > different sequence or different values.
> >
> > Move the fixed pre- and post-override register programming into per-
> > compatible configuration tables, and keep the 7 nm override parameters in
> > the same match-data structure. This allows the driver to share the common
> > sequence while adding SoC-specific sequences for future platforms such as
> > IPQ9650.
> >
> > Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
> > ---
>
> [...]
>
> > + for (tmp = data->pre; tmp->offset != UINT_MAX; tmp++)
>
> "pre"/"post" alone are not descriptive - perhaps pre_tuning/post_tuning?
Will change.
> Or do we maybe know whether the order matters at all?
I believe so. This seems to follow the order given in the hardware
programming guide.
> > + qcom_snps_hsphy_write_mask(hsphy->base, tmp->offset, tmp->mask, tmp->val);
>
> Custom termination is both error-prone and memory-inefficient, add
> another int to size the arrays
Ok.
Thanks
Varada
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/5] phy: qcom: snps-femto-v2: Move PHY init registers to config tables
2026-08-24 6:37 ` [PATCH 4/5] phy: qcom: snps-femto-v2: Move PHY init registers to config tables Varadarajan Narayanan
2026-08-24 6:49 ` sashiko-bot
2026-08-25 8:54 ` Konrad Dybcio
@ 2026-08-25 8:56 ` Konrad Dybcio
2 siblings, 0 replies; 11+ messages in thread
From: Konrad Dybcio @ 2026-08-25 8:56 UTC (permalink / raw)
To: Varadarajan Narayanan, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Wesley Cheng
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel
On 8/24/26 8:37 AM, Varadarajan Narayanan wrote:
> The driver currently programs the common PHY register sequence directly in
> qcom_snps_hsphy_init(), with the fixed register writes split around the
> override parameter handling. This makes it hard to support SoCs that need a
> different sequence or different values.
[...]
> + { USB2_PHY_USB_PHY_REFCLK_CTRL, REFCLK_SEL_DEFAULT, REFCLK_SEL_MASK },
This seems to be a pre-existing bug (swapped mask/val)
Konrad
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 5/5] phy: qcom: snps-femto-v2: Add IPQ9650 support
2026-08-24 6:37 [PATCH 0/5] Add support for USB phys in IPQ9650 Varadarajan Narayanan
` (3 preceding siblings ...)
2026-08-24 6:37 ` [PATCH 4/5] phy: qcom: snps-femto-v2: Move PHY init registers to config tables Varadarajan Narayanan
@ 2026-08-24 6:37 ` Varadarajan Narayanan
2026-08-24 6:50 ` sashiko-bot
4 siblings, 1 reply; 11+ messages in thread
From: Varadarajan Narayanan @ 2026-08-24 6:37 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Manivannan Sadhasivam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Wesley Cheng
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Varadarajan Narayanan
Add the 6 nm SNPS femto USB2 PHY configuration needed by IPQ9650. The PHYs
on this SoC require a dedicated init sequence and override parameters
before they can be enabled.
Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 62 +++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
index 5ffbe1a77dd4..c18171f9464b 100644
--- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
+++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
@@ -29,12 +29,15 @@
#define USB2_PHY_USB_PHY_UTMI_CTRL5 (0x50)
#define POR BIT(1)
+#define ATERESET BIT(0)
#define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0 (0x54)
#define SIDDQ BIT(2)
#define RETENABLEN BIT(3)
#define FSEL_MASK GENMASK(6, 4)
#define FSEL_DEFAULT (0x3 << 4)
+#define FSEL_24MHZ (0x2 << 4)
+#define VATESTENB_MASK GENMASK(1, 0)
#define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1 (0x58)
#define VBUSVLDEXTSEL0 BIT(4)
@@ -57,6 +60,13 @@
#define USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X3 (0x78)
#define PARAM_OVRD_MASK 0xFF
+#define USB2_PHY_USB_PHY_HS_PHY_TEST0 0x80
+#define TESTDATAIN_MASK GENMASK(7, 0)
+
+#define USB2_PHY_USB_PHY_HS_PHY_TEST1 0x84
+#define TESTDATAOUTSEL BIT(4)
+#define TESTCLK BIT(6)
+
#define USB2_PHY_USB_PHY_CFG0 (0x94)
#define UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN BIT(0)
#define UTMI_PHY_CMN_CTRL_OVERRIDE_EN BIT(1)
@@ -78,6 +88,9 @@
#define LS_FS_OUTPUT_IMPEDANCE_MASK GENMASK(3, 0)
+#define USB2_PHY_USB_PHY_FSEL_SEL 0xb8
+#define FSEL_SEL BIT(0)
+
static const char * const qcom_snps_hsphy_vreg_names[] = {
"vdda-pll", "vdda33", "vdda18",
};
@@ -328,6 +341,17 @@ static const struct override_param ls_fs_output_impedance_sc7280[] = {
{ 1310, 0 },
};
+static const struct override_param_map ipq9650_snps_6nm_phy[] = {
+ {
+ "qcom,pre-emphasis-amplitude-bp",
+ preemphasis_amplitude_sc7280,
+ ARRAY_SIZE(preemphasis_amplitude_sc7280),
+ USB2_PHY_USB_PHY_HS_PHY_OVERRIDE_X1,
+ PREEMPHASIS_AMPLITUDE_MASK,
+ },
+ {},
+};
+
static const struct override_param_map sc7280_snps_7nm_phy[] = {
{
"qcom,hs-disconnect-bp",
@@ -418,6 +442,34 @@ static const struct phy_reg_config hs_5nm_phy_post[] = {
{ UINT_MAX, 0, 0 },
};
+static const struct phy_reg_config hs_6nm_phy_pre[] = {
+ { USB2_PHY_USB_PHY_CFG0, UTMI_PHY_CMN_CTRL_OVERRIDE_EN, UTMI_PHY_CMN_CTRL_OVERRIDE_EN },
+ { USB2_PHY_USB_PHY_UTMI_CTRL5, POR, POR },
+ { USB2_PHY_USB_PHY_FSEL_SEL, FSEL_SEL, FSEL_SEL },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0, FSEL_MASK, FSEL_24MHZ },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1, PLLBTUNE, PLLBTUNE },
+ { USB2_PHY_USB_PHY_REFCLK_CTRL, REFCLK_SEL_MASK, REFCLK_SEL_DEFAULT },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1, VBUSVLDEXTSEL0, VBUSVLDEXTSEL0 },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL1, VBUSVLDEXT0, VBUSVLDEXT0 },
+ { UINT_MAX, 0, 0 },
+};
+
+static const struct phy_reg_config hs_6nm_phy_post[] = {
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2, VREGBYPASS, VREGBYPASS },
+ { USB2_PHY_USB_PHY_UTMI_CTRL5, ATERESET, 0 },
+ { USB2_PHY_USB_PHY_HS_PHY_TEST1, TESTDATAOUTSEL, 0 },
+ { USB2_PHY_USB_PHY_HS_PHY_TEST1, TESTCLK, 0 },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0, VATESTENB_MASK, 0 },
+ { USB2_PHY_USB_PHY_HS_PHY_TEST0, TESTDATAIN_MASK, 0 },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL2, USB2_SUSPEND_N_SEL | USB2_SUSPEND_N,
+ USB2_SUSPEND_N_SEL | USB2_SUSPEND_N },
+ { USB2_PHY_USB_PHY_UTMI_CTRL0, SLEEPM, SLEEPM },
+ { USB2_PHY_USB_PHY_UTMI_CTRL5, POR, 0 },
+ { USB2_PHY_USB_PHY_HS_PHY_CTRL2, USB2_SUSPEND_N_SEL, 0 },
+ { USB2_PHY_USB_PHY_CFG0, UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 0 },
+ { UINT_MAX, 0, 0 },
+};
+
static int qcom_snps_hsphy_init(struct phy *phy)
{
struct qcom_snps_hsphy *hsphy = phy_get_drvdata(phy);
@@ -505,6 +557,12 @@ static const struct phy_config_data hs_5nm_phy = {
.post = hs_5nm_phy_post,
};
+static const struct phy_config_data hs_6nm_phy = {
+ .pre = hs_6nm_phy_pre,
+ .override = ipq9650_snps_6nm_phy,
+ .post = hs_6nm_phy_post,
+};
+
static const struct phy_config_data hs_7nm_phy = {
.pre = hs_5nm_phy_pre,
.override = sc7280_snps_7nm_phy,
@@ -520,6 +578,10 @@ static const struct of_device_id qcom_snps_hsphy_of_match_table[] = {
.compatible = "qcom,usb-snps-hs-5nm-phy",
.data = &hs_5nm_phy,
},
+ {
+ .compatible = "qcom,usb-snps-hs-6nm-phy",
+ .data = &hs_6nm_phy,
+ },
{
.compatible = "qcom,usb-snps-hs-7nm-phy",
.data = &hs_7nm_phy,
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH 5/5] phy: qcom: snps-femto-v2: Add IPQ9650 support
2026-08-24 6:37 ` [PATCH 5/5] phy: qcom: snps-femto-v2: Add IPQ9650 support Varadarajan Narayanan
@ 2026-08-24 6:50 ` sashiko-bot
0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-08-24 6:50 UTC (permalink / raw)
To: Varadarajan Narayanan
Cc: neil.armstrong, vkoul, linux-phy, olteanv, conor+dt, robh,
devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] The `hs_5nm_phy_pre` array incorrectly swaps the mask and value parameters for `USB2_PHY_USB_PHY_REFCLK_CTRL`, resulting in incomplete bit clearing.
--
--- Patch [5]: [PATCH 5/5] phy: qcom: snps-femto-v2: Add IPQ9650 support ---
commit 5cb516a1d2d452ce8939f49955704babc0701171
Author: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
phy: qcom: snps-femto-v2: Add IPQ9650 support
This commit adds the 6nm SNPS femto USB2 PHY configuration needed by
IPQ9650. The PHYs on this SoC require a dedicated init sequence and override
parameters before they can be enabled.
> diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
> index a34027b215f9b..7e8b346c61896 100644
> --- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
> +++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
[ ... ]
> @@ -418,6 +442,34 @@ static const struct phy_reg_config hs_5nm_phy_post[] = {
> { UINT_MAX, 0, 0 },
> };
>
> +static const struct phy_reg_config hs_6nm_phy_pre[] = {
> + { USB2_PHY_USB_PHY_CFG0, UTMI_PHY_CMN_CTRL_OVERRIDE_EN, UTMI_PHY_CMN_CTRL_OVERRIDE_EN },
> + { USB2_PHY_USB_PHY_UTMI_CTRL5, POR, POR },
> + { USB2_PHY_USB_PHY_FSEL_SEL, FSEL_SEL, FSEL_SEL },
> + { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0, FSEL_MASK, FSEL_24MHZ },
> + { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1, PLLBTUNE, PLLBTUNE },
> + { USB2_PHY_USB_PHY_REFCLK_CTRL, REFCLK_SEL_MASK, REFCLK_SEL_DEFAULT },
[Severity: High]
This isn't a bug introduced by this patch, but while reviewing it I noticed a
discrepancy between the new hs_6nm_phy_pre array and the existing
hs_5nm_phy_pre array.
The newly introduced hs_6nm_phy_pre array correctly orders the mask and value
parameters:
{ USB2_PHY_USB_PHY_REFCLK_CTRL, REFCLK_SEL_MASK, REFCLK_SEL_DEFAULT },
However, the existing hs_5nm_phy_pre array appears to have the mask and value
swapped:
drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c:hs_5nm_phy_pre[]
{ USB2_PHY_USB_PHY_REFCLK_CTRL, REFCLK_SEL_DEFAULT, REFCLK_SEL_MASK },
Since the phy_reg_config struct expects { offset, mask, val }, passing
REFCLK_SEL_DEFAULT (0x2) as the mask and REFCLK_SEL_MASK (0x3) as the value
means qcom_snps_hsphy_write_mask() will execute:
reg &= ~0x2
reg |= (0x3 & 0x2)
This sets bit 1 to 1 but fails to clear bit 0.
If bit 0 was already set by the bootloader, the register will hold 0x3
instead of 0x2, which could result in an incorrect reference clock
configuration and prevent the USB PHY PLL from locking.
Does this swapped mask and value in hs_5nm_phy_pre need to be corrected in a
separate patch?
> + { USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1, VBUSVLDEXTSEL0, VBUSVLDEXTSEL0 },
> + { USB2_PHY_USB_PHY_HS_PHY_CTRL1, VBUSVLDEXT0, VBUSVLDEXT0 },
> + { UINT_MAX, 0, 0 },
> +};
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260824-phy-v1-0-257d68a3210b@oss.qualcomm.com?part=5
^ permalink raw reply [flat|nested] 11+ messages in thread