From bb0417288ea40a5f57676529cae95f3c20bd697c Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 21 Sep 2026 13:47:07 +0200 Subject: [PATCH] phy: qcom: qmp-combo: Add USB3+DP PHY support for Nord Nord SoC provides two USB3+DP combo PHYs. Their initialisation sequences are identical to sm8550, but the sub-blocks are not laid out the same way: Nord adds a dedicated USB3_PCS_AON region at offset 0x1e00 and leaves everything else where sm8550 has it. None of the existing offsets tables describe that, so add a v6 table which is the v3 layout plus usb3_pcs_aon. Populating usb3_pcs_aon changes where the driver drives the I/O clamp when entering and leaving autonomous mode: it now uses the real AON region rather than falling back to PCS_MISC, which is what platforms with no AON region do. Signed-off-by: Bartosz Golaszewski Assisted-by: LLM Reviewed-by: Abel Vesa Signed-off-by: Shawn Guo Reviewed-by: Manivannan Sadhasivam Link: https://patch.msgid.link/20260921-nord-usb-phy-v3-3-68aa02b12b96@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 80 +++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c index f38c3db2039c..187f0cd11f6c 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -2356,6 +2356,20 @@ static const struct qmp_phy_init_tbl hawi_usb3_pcs_usb_tbl[] = { QMP_PHY_INIT_CFG(QPHY_V10_PCS_USB3_RCVR_DTCT_DLY_U3_H, 0x00), }; +static const struct qmp_phy_init_tbl nord_usb3_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_TX, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_RX, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0xf5), + QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_3, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_4, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_5, 0x5f), + QMP_PHY_INIT_CFG(QSERDES_V6_TX_RCV_DETECT_LVL_2, 0x14), + QMP_PHY_INIT_CFG_LANE(QSERDES_V6_TX_PI_QEC_CTRL, 0x21, 1), + QMP_PHY_INIT_CFG_LANE(QSERDES_V6_TX_PI_QEC_CTRL, 0x05, 2), +}; + /* list of regulators */ static struct regulator_bulk_data qmp_phy_vreg_l[] = { { .supply = "vdda-phy", .init_load_uA = 21800, }, @@ -2696,6 +2710,23 @@ static const struct qmp_combo_offsets qmp_combo_offsets_v5 = { .dp_dp_phy = 0x2200, }; +static const struct qmp_combo_offsets qmp_combo_offsets_v6 = { + .com = 0x0000, + .txa = 0x1200, + .rxa = 0x1400, + .txb = 0x1600, + .rxb = 0x1800, + .usb3_serdes = 0x1000, + .usb3_pcs_misc = 0x1a00, + .usb3_pcs = 0x1c00, + .usb3_pcs_aon = 0x1e00, + .usb3_pcs_usb = 0x1f00, + .dp_serdes = 0x2000, + .dp_txa = 0x2200, + .dp_txb = 0x2600, + .dp_dp_phy = 0x2a00, +}; + static const struct qmp_combo_offsets qmp_combo_offsets_v8 = { .com = 0x0000, .txa = 0x1400, @@ -3400,6 +3431,51 @@ static const struct qmp_phy_cfg glymur_usb3dpphy_cfg = { .num_vregs = ARRAY_SIZE(qmp_phy_vreg_refgen), }; +static const struct qmp_phy_cfg nord_usb3dpphy_cfg = { + .offsets = &qmp_combo_offsets_v6, + + .serdes_tbl = sm8550_usb3_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(sm8550_usb3_serdes_tbl), + .tx_tbl = nord_usb3_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(nord_usb3_tx_tbl), + .rx_tbl = sm8550_usb3_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(sm8550_usb3_rx_tbl), + .pcs_tbl = sm8550_usb3_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(sm8550_usb3_pcs_tbl), + .pcs_usb_tbl = sm8550_usb3_pcs_usb_tbl, + .pcs_usb_tbl_num = ARRAY_SIZE(sm8550_usb3_pcs_usb_tbl), + + .dp_serdes_tbl = qmp_v6_dp_serdes_tbl, + .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl), + .dp_tx_tbl = qmp_v6_dp_tx_tbl, + .dp_tx_tbl_num = ARRAY_SIZE(qmp_v6_dp_tx_tbl), + + .serdes_tbl_rbr = qmp_v6_dp_serdes_tbl_rbr, + .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_rbr), + .serdes_tbl_hbr = qmp_v6_dp_serdes_tbl_hbr, + .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr), + .serdes_tbl_hbr2 = qmp_v6_dp_serdes_tbl_hbr2, + .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr2), + .serdes_tbl_hbr3 = qmp_v6_dp_serdes_tbl_hbr3, + .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr3), + + .swing_hbr_rbr = &qmp_dp_v5_voltage_swing_hbr_rbr, + .pre_emphasis_hbr_rbr = &qmp_dp_v6_pre_emphasis_hbr_rbr, + .swing_hbr3_hbr2 = &qmp_dp_v5_voltage_swing_hbr3_hbr2, + .pre_emphasis_hbr3_hbr2 = &qmp_dp_v5_pre_emphasis_hbr3_hbr2, + + .dp_aux_init = qmp_v4_dp_aux_init, + .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, + .configure_dp_phy = qmp_v4_configure_dp_phy, + + .regs = qmp_v6_usb3phy_regs_layout, + .reset_list = msm8996_usb3phy_reset_l, + .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), +}; + static int qmp_combo_dp_serdes_init(struct qmp_combo *qmp) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -5597,6 +5673,10 @@ static const struct of_device_id qmp_combo_of_match_table[] = { .compatible = "qcom,hawi-qmp-usb3-dp-phy", .data = &hawi_usb3dpphy_cfg, }, + { + .compatible = "qcom,nord-qmp-usb3-dp-phy", + .data = &nord_usb3dpphy_cfg, + }, { .compatible = "qcom,sar2130p-qmp-usb3-dp-phy", .data = &sar2130p_usb3dpphy_cfg,