Lines Matching +full:tx +full:- +full:swing +full:- +full:low

1 // SPDX-License-Identifier: GPL-2.0
7 #include <linux/clk-provider.h>
26 #include <dt-bindings/phy/phy-qcom-qmp.h>
28 #include "phy-qcom-qmp.h"
29 #include "phy-qcom-qmp-pcs-misc-v3.h"
30 #include "phy-qcom-qmp-pcs-usb-v4.h"
31 #include "phy-qcom-qmp-pcs-usb-v5.h"
32 #include "phy-qcom-qmp-pcs-usb-v6.h"
99 /* set of registers with offsets different per-PHY */
1218 { .name = "vdda-phy", .enable_load = 21800 },
1219 { .name = "vdda-pll", .enable_load = 36000 },
1327 /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
1354 /* DP PHY swing and pre_emphasis tables */
1392 void __iomem *tx; member
1887 if (!(t->lane_mask & lane_mask)) in qmp_combo_configure_lane()
1890 writel(t->val, base + t->offset); in qmp_combo_configure_lane()
1903 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_dp_serdes_init()
1904 void __iomem *serdes = qmp->dp_serdes; in qmp_combo_dp_serdes_init()
1905 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; in qmp_combo_dp_serdes_init()
1907 qmp_combo_configure(serdes, cfg->dp_serdes_tbl, cfg->dp_serdes_tbl_num); in qmp_combo_dp_serdes_init()
1909 switch (dp_opts->link_rate) { in qmp_combo_dp_serdes_init()
1911 qmp_combo_configure(serdes, cfg->serdes_tbl_rbr, in qmp_combo_dp_serdes_init()
1912 cfg->serdes_tbl_rbr_num); in qmp_combo_dp_serdes_init()
1915 qmp_combo_configure(serdes, cfg->serdes_tbl_hbr, in qmp_combo_dp_serdes_init()
1916 cfg->serdes_tbl_hbr_num); in qmp_combo_dp_serdes_init()
1919 qmp_combo_configure(serdes, cfg->serdes_tbl_hbr2, in qmp_combo_dp_serdes_init()
1920 cfg->serdes_tbl_hbr2_num); in qmp_combo_dp_serdes_init()
1923 qmp_combo_configure(serdes, cfg->serdes_tbl_hbr3, in qmp_combo_dp_serdes_init()
1924 cfg->serdes_tbl_hbr3_num); in qmp_combo_dp_serdes_init()
1928 return -EINVAL; in qmp_combo_dp_serdes_init()
1936 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_v3_dp_aux_init()
1940 qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); in qmp_v3_dp_aux_init()
1945 qmp->dp_serdes + cfg->regs[QPHY_COM_BIAS_EN_CLKBUFLR_EN]); in qmp_v3_dp_aux_init()
1947 writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); in qmp_v3_dp_aux_init()
1953 qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); in qmp_v3_dp_aux_init()
1959 qmp->dp_serdes + cfg->regs[QPHY_COM_BIAS_EN_CLKBUFLR_EN]); in qmp_v3_dp_aux_init()
1961 writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG0); in qmp_v3_dp_aux_init()
1962 writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); in qmp_v3_dp_aux_init()
1963 writel(0x24, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2); in qmp_v3_dp_aux_init()
1964 writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG3); in qmp_v3_dp_aux_init()
1965 writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG4); in qmp_v3_dp_aux_init()
1966 writel(0x26, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG5); in qmp_v3_dp_aux_init()
1967 writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG6); in qmp_v3_dp_aux_init()
1968 writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7); in qmp_v3_dp_aux_init()
1969 writel(0xbb, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8); in qmp_v3_dp_aux_init()
1970 writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9); in qmp_v3_dp_aux_init()
1971 qmp->dp_aux_cfg = 0; in qmp_v3_dp_aux_init()
1976 qmp->dp_dp_phy + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK); in qmp_v3_dp_aux_init()
1981 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; in qmp_combo_configure_dp_swing()
1982 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_configure_dp_swing()
1987 for (i = 0; i < dp_opts->lanes; i++) { in qmp_combo_configure_dp_swing()
1988 v_level = max(v_level, dp_opts->voltage[i]); in qmp_combo_configure_dp_swing()
1989 p_level = max(p_level, dp_opts->pre[i]); in qmp_combo_configure_dp_swing()
1992 if (dp_opts->link_rate <= 2700) { in qmp_combo_configure_dp_swing()
1993 voltage_swing_cfg = (*cfg->swing_hbr_rbr)[v_level][p_level]; in qmp_combo_configure_dp_swing()
1994 pre_emphasis_cfg = (*cfg->pre_emphasis_hbr_rbr)[v_level][p_level]; in qmp_combo_configure_dp_swing()
1996 voltage_swing_cfg = (*cfg->swing_hbr3_hbr2)[v_level][p_level]; in qmp_combo_configure_dp_swing()
1997 pre_emphasis_cfg = (*cfg->pre_emphasis_hbr3_hbr2)[v_level][p_level]; in qmp_combo_configure_dp_swing()
2002 return -EINVAL; in qmp_combo_configure_dp_swing()
2008 writel(voltage_swing_cfg, qmp->dp_tx + cfg->regs[QPHY_TX_TX_DRV_LVL]); in qmp_combo_configure_dp_swing()
2009 writel(pre_emphasis_cfg, qmp->dp_tx + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); in qmp_combo_configure_dp_swing()
2010 writel(voltage_swing_cfg, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_DRV_LVL]); in qmp_combo_configure_dp_swing()
2011 writel(pre_emphasis_cfg, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); in qmp_combo_configure_dp_swing()
2018 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; in qmp_v3_configure_dp_tx()
2024 if (dp_opts->lanes == 1) { in qmp_v3_configure_dp_tx()
2032 writel(drvr_en, qmp->dp_tx + QSERDES_V3_TX_HIGHZ_DRVR_EN); in qmp_v3_configure_dp_tx()
2033 writel(bias_en, qmp->dp_tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN); in qmp_v3_configure_dp_tx()
2034 writel(drvr_en, qmp->dp_tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN); in qmp_v3_configure_dp_tx()
2035 writel(bias_en, qmp->dp_tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN); in qmp_v3_configure_dp_tx()
2040 bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE); in qmp_combo_configure_dp_mode()
2041 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; in qmp_combo_configure_dp_mode()
2047 if (dp_opts->lanes == 4 || reverse) in qmp_combo_configure_dp_mode()
2049 if (dp_opts->lanes == 4 || !reverse) in qmp_combo_configure_dp_mode()
2052 writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); in qmp_combo_configure_dp_mode()
2055 writel(0x4c, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE); in qmp_combo_configure_dp_mode()
2057 writel(0x5c, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE); in qmp_combo_configure_dp_mode()
2064 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; in qmp_combo_configure_dp_clocks()
2067 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_configure_dp_clocks()
2069 switch (dp_opts->link_rate) { in qmp_combo_configure_dp_clocks()
2088 return -EINVAL; in qmp_combo_configure_dp_clocks()
2090 writel(phy_vco_div, qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_VCO_DIV]); in qmp_combo_configure_dp_clocks()
2092 clk_set_rate(qmp->dp_link_hw.clk, dp_opts->link_rate * 100000); in qmp_combo_configure_dp_clocks()
2093 clk_set_rate(qmp->dp_pixel_hw.clk, pixel_freq); in qmp_combo_configure_dp_clocks()
2100 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_v3_configure_dp_phy()
2106 writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL); in qmp_v3_configure_dp_phy()
2107 writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL); in qmp_v3_configure_dp_phy()
2113 writel(0x04, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2); in qmp_v3_configure_dp_phy()
2114 writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v3_configure_dp_phy()
2115 writel(0x05, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v3_configure_dp_phy()
2116 writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v3_configure_dp_phy()
2117 writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v3_configure_dp_phy()
2119 writel(0x20, qmp->dp_serdes + cfg->regs[QPHY_COM_RESETSM_CNTRL]); in qmp_v3_configure_dp_phy()
2121 if (readl_poll_timeout(qmp->dp_serdes + cfg->regs[QPHY_COM_C_READY_STATUS], in qmp_v3_configure_dp_phy()
2126 return -ETIMEDOUT; in qmp_v3_configure_dp_phy()
2128 writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v3_configure_dp_phy()
2130 if (readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS], in qmp_v3_configure_dp_phy()
2135 return -ETIMEDOUT; in qmp_v3_configure_dp_phy()
2137 writel(0x18, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v3_configure_dp_phy()
2139 writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v3_configure_dp_phy()
2141 return readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS], in qmp_v3_configure_dp_phy()
2157 qmp->dp_aux_cfg++; in qmp_v3_calibrate_dp_phy()
2158 qmp->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings); in qmp_v3_calibrate_dp_phy()
2159 val = cfg1_settings[qmp->dp_aux_cfg]; in qmp_v3_calibrate_dp_phy()
2161 writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); in qmp_v3_calibrate_dp_phy()
2168 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_v4_dp_aux_init()
2172 qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); in qmp_v4_dp_aux_init()
2175 writel(0x17, qmp->dp_serdes + cfg->regs[QPHY_COM_BIAS_EN_CLKBUFLR_EN]); in qmp_v4_dp_aux_init()
2177 writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG0); in qmp_v4_dp_aux_init()
2178 writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); in qmp_v4_dp_aux_init()
2179 writel(0xa4, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2); in qmp_v4_dp_aux_init()
2180 writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG3); in qmp_v4_dp_aux_init()
2181 writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG4); in qmp_v4_dp_aux_init()
2182 writel(0x26, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG5); in qmp_v4_dp_aux_init()
2183 writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG6); in qmp_v4_dp_aux_init()
2184 writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7); in qmp_v4_dp_aux_init()
2185 writel(0xb7, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8); in qmp_v4_dp_aux_init()
2186 writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9); in qmp_v4_dp_aux_init()
2187 qmp->dp_aux_cfg = 0; in qmp_v4_dp_aux_init()
2192 qmp->dp_dp_phy + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK); in qmp_v4_dp_aux_init()
2197 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_v4_configure_dp_tx()
2200 writel(0x27, qmp->dp_tx + cfg->regs[QPHY_TX_TX_DRV_LVL]); in qmp_v4_configure_dp_tx()
2201 writel(0x27, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_DRV_LVL]); in qmp_v4_configure_dp_tx()
2203 writel(0x20, qmp->dp_tx + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); in qmp_v4_configure_dp_tx()
2204 writel(0x20, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); in qmp_v4_configure_dp_tx()
2211 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_v456_configure_dp_phy()
2215 writel(0x0f, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_CFG_1); in qmp_v456_configure_dp_phy()
2219 writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); in qmp_v456_configure_dp_phy()
2220 writel(0xa4, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2); in qmp_v456_configure_dp_phy()
2222 writel(0x05, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL); in qmp_v456_configure_dp_phy()
2223 writel(0x05, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL); in qmp_v456_configure_dp_phy()
2229 writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v456_configure_dp_phy()
2230 writel(0x05, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v456_configure_dp_phy()
2231 writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v456_configure_dp_phy()
2232 writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v456_configure_dp_phy()
2234 writel(0x20, qmp->dp_serdes + cfg->regs[QPHY_COM_RESETSM_CNTRL]); in qmp_v456_configure_dp_phy()
2236 if (readl_poll_timeout(qmp->dp_serdes + cfg->regs[QPHY_COM_C_READY_STATUS], in qmp_v456_configure_dp_phy()
2241 return -ETIMEDOUT; in qmp_v456_configure_dp_phy()
2243 if (readl_poll_timeout(qmp->dp_serdes + cfg->regs[QPHY_COM_CMN_STATUS], in qmp_v456_configure_dp_phy()
2248 return -ETIMEDOUT; in qmp_v456_configure_dp_phy()
2250 if (readl_poll_timeout(qmp->dp_serdes + cfg->regs[QPHY_COM_CMN_STATUS], in qmp_v456_configure_dp_phy()
2255 return -ETIMEDOUT; in qmp_v456_configure_dp_phy()
2257 writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v456_configure_dp_phy()
2259 if (readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS], in qmp_v456_configure_dp_phy()
2264 return -ETIMEDOUT; in qmp_v456_configure_dp_phy()
2266 if (readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS], in qmp_v456_configure_dp_phy()
2271 return -ETIMEDOUT; in qmp_v456_configure_dp_phy()
2278 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_v4_configure_dp_phy()
2279 bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE); in qmp_v4_configure_dp_phy()
2280 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; in qmp_v4_configure_dp_phy()
2294 if (dp_opts->lanes == 1) { in qmp_v4_configure_dp_phy()
2299 } else if (dp_opts->lanes == 2) { in qmp_v4_configure_dp_phy()
2311 writel(drvr0_en, qmp->dp_tx + cfg->regs[QPHY_TX_HIGHZ_DRVR_EN]); in qmp_v4_configure_dp_phy()
2312 writel(bias0_en, qmp->dp_tx + cfg->regs[QPHY_TX_TRANSCEIVER_BIAS_EN]); in qmp_v4_configure_dp_phy()
2313 writel(drvr1_en, qmp->dp_tx2 + cfg->regs[QPHY_TX_HIGHZ_DRVR_EN]); in qmp_v4_configure_dp_phy()
2314 writel(bias1_en, qmp->dp_tx2 + cfg->regs[QPHY_TX_TRANSCEIVER_BIAS_EN]); in qmp_v4_configure_dp_phy()
2316 writel(0x18, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v4_configure_dp_phy()
2318 writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); in qmp_v4_configure_dp_phy()
2320 if (readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS], in qmp_v4_configure_dp_phy()
2325 return -ETIMEDOUT; in qmp_v4_configure_dp_phy()
2327 writel(0x0a, qmp->dp_tx + cfg->regs[QPHY_TX_TX_POL_INV]); in qmp_v4_configure_dp_phy()
2328 writel(0x0a, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_POL_INV]); in qmp_v4_configure_dp_phy()
2330 writel(0x27, qmp->dp_tx + cfg->regs[QPHY_TX_TX_DRV_LVL]); in qmp_v4_configure_dp_phy()
2331 writel(0x27, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_DRV_LVL]); in qmp_v4_configure_dp_phy()
2333 writel(0x20, qmp->dp_tx + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); in qmp_v4_configure_dp_phy()
2334 writel(0x20, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); in qmp_v4_configure_dp_phy()
2348 qmp->dp_aux_cfg++; in qmp_v4_calibrate_dp_phy()
2349 qmp->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings); in qmp_v4_calibrate_dp_phy()
2350 val = cfg1_settings[qmp->dp_aux_cfg]; in qmp_v4_calibrate_dp_phy()
2352 writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); in qmp_v4_calibrate_dp_phy()
2359 const struct phy_configure_opts_dp *dp_opts = &opts->dp; in qmp_combo_dp_configure()
2361 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_dp_configure()
2363 mutex_lock(&qmp->phy_mutex); in qmp_combo_dp_configure()
2365 memcpy(&qmp->dp_opts, dp_opts, sizeof(*dp_opts)); in qmp_combo_dp_configure()
2366 if (qmp->dp_opts.set_voltages) { in qmp_combo_dp_configure()
2367 cfg->configure_dp_tx(qmp); in qmp_combo_dp_configure()
2368 qmp->dp_opts.set_voltages = 0; in qmp_combo_dp_configure()
2371 mutex_unlock(&qmp->phy_mutex); in qmp_combo_dp_configure()
2379 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_dp_calibrate()
2382 mutex_lock(&qmp->phy_mutex); in qmp_combo_dp_calibrate()
2384 if (cfg->calibrate_dp_phy) in qmp_combo_dp_calibrate()
2385 ret = cfg->calibrate_dp_phy(qmp); in qmp_combo_dp_calibrate()
2387 mutex_unlock(&qmp->phy_mutex); in qmp_combo_dp_calibrate()
2394 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_com_init()
2395 void __iomem *com = qmp->com; in qmp_combo_com_init()
2399 if (!force && qmp->init_count++) in qmp_combo_com_init()
2402 ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); in qmp_combo_com_init()
2404 dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret); in qmp_combo_com_init()
2408 ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets); in qmp_combo_com_init()
2410 dev_err(qmp->dev, "reset assert failed\n"); in qmp_combo_com_init()
2414 ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets); in qmp_combo_com_init()
2416 dev_err(qmp->dev, "reset deassert failed\n"); in qmp_combo_com_init()
2420 ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks); in qmp_combo_com_init()
2433 if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) in qmp_combo_com_init()
2446 qphy_setbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], in qmp_combo_com_init()
2452 reset_control_bulk_assert(cfg->num_resets, qmp->resets); in qmp_combo_com_init()
2454 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); in qmp_combo_com_init()
2456 qmp->init_count--; in qmp_combo_com_init()
2463 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_com_exit()
2465 if (!force && --qmp->init_count) in qmp_combo_com_exit()
2468 reset_control_bulk_assert(cfg->num_resets, qmp->resets); in qmp_combo_com_exit()
2470 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); in qmp_combo_com_exit()
2472 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); in qmp_combo_com_exit()
2480 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_dp_init()
2483 mutex_lock(&qmp->phy_mutex); in qmp_combo_dp_init()
2489 cfg->dp_aux_init(qmp); in qmp_combo_dp_init()
2491 qmp->dp_init_count++; in qmp_combo_dp_init()
2494 mutex_unlock(&qmp->phy_mutex); in qmp_combo_dp_init()
2502 mutex_lock(&qmp->phy_mutex); in qmp_combo_dp_exit()
2506 qmp->dp_init_count--; in qmp_combo_dp_exit()
2508 mutex_unlock(&qmp->phy_mutex); in qmp_combo_dp_exit()
2516 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_dp_power_on()
2517 void __iomem *tx = qmp->dp_tx; in qmp_combo_dp_power_on() local
2518 void __iomem *tx2 = qmp->dp_tx2; in qmp_combo_dp_power_on()
2520 mutex_lock(&qmp->phy_mutex); in qmp_combo_dp_power_on()
2524 qmp_combo_configure_lane(tx, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 1); in qmp_combo_dp_power_on()
2525 qmp_combo_configure_lane(tx2, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 2); in qmp_combo_dp_power_on()
2527 /* Configure special DP tx tunings */ in qmp_combo_dp_power_on()
2528 cfg->configure_dp_tx(qmp); in qmp_combo_dp_power_on()
2530 /* Configure link rate, swing, etc. */ in qmp_combo_dp_power_on()
2531 cfg->configure_dp_phy(qmp); in qmp_combo_dp_power_on()
2533 mutex_unlock(&qmp->phy_mutex); in qmp_combo_dp_power_on()
2542 mutex_lock(&qmp->phy_mutex); in qmp_combo_dp_power_off()
2545 writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); in qmp_combo_dp_power_off()
2547 mutex_unlock(&qmp->phy_mutex); in qmp_combo_dp_power_off()
2555 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_usb_power_on()
2556 void __iomem *serdes = qmp->serdes; in qmp_combo_usb_power_on()
2557 void __iomem *tx = qmp->tx; in qmp_combo_usb_power_on() local
2558 void __iomem *rx = qmp->rx; in qmp_combo_usb_power_on()
2559 void __iomem *tx2 = qmp->tx2; in qmp_combo_usb_power_on()
2560 void __iomem *rx2 = qmp->rx2; in qmp_combo_usb_power_on()
2561 void __iomem *pcs = qmp->pcs; in qmp_combo_usb_power_on()
2562 void __iomem *pcs_usb = qmp->pcs_usb; in qmp_combo_usb_power_on()
2567 qmp_combo_configure(serdes, cfg->serdes_tbl, cfg->serdes_tbl_num); in qmp_combo_usb_power_on()
2569 ret = clk_prepare_enable(qmp->pipe_clk); in qmp_combo_usb_power_on()
2571 dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret); in qmp_combo_usb_power_on()
2575 /* Tx, Rx, and PCS configurations */ in qmp_combo_usb_power_on()
2576 qmp_combo_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1); in qmp_combo_usb_power_on()
2577 qmp_combo_configure_lane(tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2); in qmp_combo_usb_power_on()
2579 qmp_combo_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1); in qmp_combo_usb_power_on()
2580 qmp_combo_configure_lane(rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2); in qmp_combo_usb_power_on()
2582 qmp_combo_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); in qmp_combo_usb_power_on()
2585 qmp_combo_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num); in qmp_combo_usb_power_on()
2587 if (cfg->has_pwrdn_delay) in qmp_combo_usb_power_on()
2591 qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); in qmp_combo_usb_power_on()
2593 /* start SerDes and Phy-Coding-Sublayer */ in qmp_combo_usb_power_on()
2594 qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START); in qmp_combo_usb_power_on()
2596 status = pcs + cfg->regs[QPHY_PCS_STATUS]; in qmp_combo_usb_power_on()
2600 dev_err(qmp->dev, "phy initialization timed-out\n"); in qmp_combo_usb_power_on()
2607 clk_disable_unprepare(qmp->pipe_clk); in qmp_combo_usb_power_on()
2615 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_usb_power_off()
2617 clk_disable_unprepare(qmp->pipe_clk); in qmp_combo_usb_power_off()
2620 qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); in qmp_combo_usb_power_off()
2622 /* stop SerDes and Phy-Coding-Sublayer */ in qmp_combo_usb_power_off()
2623 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], in qmp_combo_usb_power_off()
2626 /* Put PHY into POWER DOWN state: active low */ in qmp_combo_usb_power_off()
2627 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], in qmp_combo_usb_power_off()
2638 mutex_lock(&qmp->phy_mutex); in qmp_combo_usb_init()
2649 qmp->usb_init_count++; in qmp_combo_usb_init()
2652 mutex_unlock(&qmp->phy_mutex); in qmp_combo_usb_init()
2661 mutex_lock(&qmp->phy_mutex); in qmp_combo_usb_exit()
2670 qmp->usb_init_count--; in qmp_combo_usb_exit()
2673 mutex_unlock(&qmp->phy_mutex); in qmp_combo_usb_exit()
2681 qmp->mode = mode; in qmp_combo_usb_set_mode()
2705 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_enable_autonomous_mode()
2706 void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs; in qmp_combo_enable_autonomous_mode()
2707 void __iomem *pcs_misc = qmp->pcs_misc; in qmp_combo_enable_autonomous_mode()
2710 if (qmp->mode == PHY_MODE_USB_HOST_SS || in qmp_combo_enable_autonomous_mode()
2711 qmp->mode == PHY_MODE_USB_DEVICE_SS) in qmp_combo_enable_autonomous_mode()
2717 qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR); in qmp_combo_enable_autonomous_mode()
2719 qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR); in qmp_combo_enable_autonomous_mode()
2721 qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], in qmp_combo_enable_autonomous_mode()
2725 qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask); in qmp_combo_enable_autonomous_mode()
2734 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_disable_autonomous_mode()
2735 void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs; in qmp_combo_disable_autonomous_mode()
2736 void __iomem *pcs_misc = qmp->pcs_misc; in qmp_combo_disable_autonomous_mode()
2742 qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], in qmp_combo_disable_autonomous_mode()
2745 qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR); in qmp_combo_disable_autonomous_mode()
2747 qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR); in qmp_combo_disable_autonomous_mode()
2754 dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode); in qmp_combo_runtime_suspend()
2756 if (!qmp->init_count) { in qmp_combo_runtime_suspend()
2763 clk_disable_unprepare(qmp->pipe_clk); in qmp_combo_runtime_suspend()
2764 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); in qmp_combo_runtime_suspend()
2774 dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode); in qmp_combo_runtime_resume()
2776 if (!qmp->init_count) { in qmp_combo_runtime_resume()
2781 ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks); in qmp_combo_runtime_resume()
2785 ret = clk_prepare_enable(qmp->pipe_clk); in qmp_combo_runtime_resume()
2788 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); in qmp_combo_runtime_resume()
2804 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_vreg_init()
2805 struct device *dev = qmp->dev; in qmp_combo_vreg_init()
2806 int num = cfg->num_vregs; in qmp_combo_vreg_init()
2809 qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); in qmp_combo_vreg_init()
2810 if (!qmp->vregs) in qmp_combo_vreg_init()
2811 return -ENOMEM; in qmp_combo_vreg_init()
2814 qmp->vregs[i].supply = cfg->vreg_list[i].name; in qmp_combo_vreg_init()
2816 ret = devm_regulator_bulk_get(dev, num, qmp->vregs); in qmp_combo_vreg_init()
2823 ret = regulator_set_load(qmp->vregs[i].consumer, in qmp_combo_vreg_init()
2824 cfg->vreg_list[i].enable_load); in qmp_combo_vreg_init()
2827 qmp->vregs[i].supply); in qmp_combo_vreg_init()
2837 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_reset_init()
2838 struct device *dev = qmp->dev; in qmp_combo_reset_init()
2842 qmp->resets = devm_kcalloc(dev, cfg->num_resets, in qmp_combo_reset_init()
2843 sizeof(*qmp->resets), GFP_KERNEL); in qmp_combo_reset_init()
2844 if (!qmp->resets) in qmp_combo_reset_init()
2845 return -ENOMEM; in qmp_combo_reset_init()
2847 for (i = 0; i < cfg->num_resets; i++) in qmp_combo_reset_init()
2848 qmp->resets[i].id = cfg->reset_list[i]; in qmp_combo_reset_init()
2850 ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets, qmp->resets); in qmp_combo_reset_init()
2859 struct device *dev = qmp->dev; in qmp_combo_clk_init()
2863 qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL); in qmp_combo_clk_init()
2864 if (!qmp->clks) in qmp_combo_clk_init()
2865 return -ENOMEM; in qmp_combo_clk_init()
2868 qmp->clks[i].id = qmp_combo_phy_clk_l[i]; in qmp_combo_clk_init()
2870 qmp->num_clks = num; in qmp_combo_clk_init()
2872 return devm_clk_bulk_get_optional(dev, num, qmp->clks); in qmp_combo_clk_init()
2890 * +---------------+
2891 * | PHY block |<<---------------------------------------+
2893 * | +-------+ | +-----+ |
2894 * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
2895 * clk | +-------+ | +-----+
2896 * +---------------+
2900 struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed; in phy_pipe_clk_register()
2904 snprintf(name, sizeof(name), "%s::pipe_clk", dev_name(qmp->dev)); in phy_pipe_clk_register()
2909 fixed->fixed_rate = 125000000; in phy_pipe_clk_register()
2910 fixed->hw.init = &init; in phy_pipe_clk_register()
2912 return devm_clk_hw_register(qmp->dev, &fixed->hw); in phy_pipe_clk_register()
2918 * +------------------------------+
2921 * | +-------------------+ |
2923 * | +---------+---------+ |
2925 * | +----------+-----------+ |
2927 * | +----------+-----------+ |
2928 * +------------------------------+
2930 * +---------<---------v------------>----------+
2932 * +--------v----------------+ |
2935 * +--------+----------------+ |
2944 * +--------<------------+-----------------+---<---+
2946 * +----v---------+ +--------v-----+ +--------v------+
2951 * +-------+------+ +-----+--------+ +--------+------+
2953 * v---->----------v-------------<------v
2955 * +----------+-----------------+
2957 * +---------+------------------+
2966 switch (req->rate) { in qmp_dp_pixel_clk_determine_rate()
2972 return -EINVAL; in qmp_dp_pixel_clk_determine_rate()
2982 dp_opts = &qmp->dp_opts; in qmp_dp_pixel_clk_recalc_rate()
2984 switch (dp_opts->link_rate) { in qmp_dp_pixel_clk_recalc_rate()
3005 switch (req->rate) { in qmp_dp_link_clk_determine_rate()
3012 return -EINVAL; in qmp_dp_link_clk_determine_rate()
3022 dp_opts = &qmp->dp_opts; in qmp_dp_link_clk_recalc_rate()
3024 switch (dp_opts->link_rate) { in qmp_dp_link_clk_recalc_rate()
3029 return dp_opts->link_rate * 100000; in qmp_dp_link_clk_recalc_rate()
3043 unsigned int idx = clkspec->args[0]; in qmp_dp_clks_hw_get()
3047 return ERR_PTR(-EINVAL); in qmp_dp_clks_hw_get()
3051 return &qmp->dp_link_hw; in qmp_dp_clks_hw_get()
3053 return &qmp->dp_pixel_hw; in qmp_dp_clks_hw_get()
3062 snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev)); in phy_dp_clks_register()
3065 qmp->dp_link_hw.init = &init; in phy_dp_clks_register()
3066 ret = devm_clk_hw_register(qmp->dev, &qmp->dp_link_hw); in phy_dp_clks_register()
3070 snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev)); in phy_dp_clks_register()
3073 qmp->dp_pixel_hw.init = &init; in phy_dp_clks_register()
3074 ret = devm_clk_hw_register(qmp->dev, &qmp->dp_pixel_hw); in phy_dp_clks_register()
3085 switch (clkspec->args[0]) { in qmp_combo_clk_hw_get()
3087 return &qmp->pipe_clk_fixed.hw; in qmp_combo_clk_hw_get()
3089 return &qmp->dp_link_hw; in qmp_combo_clk_hw_get()
3091 return &qmp->dp_pixel_hw; in qmp_combo_clk_hw_get()
3094 return ERR_PTR(-EINVAL); in qmp_combo_clk_hw_get()
3113 if (usb_np == qmp->dev->of_node) in qmp_combo_register_clocks()
3114 return devm_of_clk_add_hw_provider(qmp->dev, qmp_combo_clk_hw_get, qmp); in qmp_combo_register_clocks()
3120 &qmp->pipe_clk_fixed.hw); in qmp_combo_register_clocks()
3128 ret = devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, usb_np); in qmp_combo_register_clocks()
3136 return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, dp_np); in qmp_combo_register_clocks()
3144 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_typec_switch_set()
3146 if (orientation == qmp->orientation || orientation == TYPEC_ORIENTATION_NONE) in qmp_combo_typec_switch_set()
3149 mutex_lock(&qmp->phy_mutex); in qmp_combo_typec_switch_set()
3150 qmp->orientation = orientation; in qmp_combo_typec_switch_set()
3152 if (qmp->init_count) { in qmp_combo_typec_switch_set()
3153 if (qmp->usb_init_count) in qmp_combo_typec_switch_set()
3154 qmp_combo_usb_power_off(qmp->usb_phy); in qmp_combo_typec_switch_set()
3158 if (qmp->usb_init_count) in qmp_combo_typec_switch_set()
3159 qmp_combo_usb_power_on(qmp->usb_phy); in qmp_combo_typec_switch_set()
3160 if (qmp->dp_init_count) in qmp_combo_typec_switch_set()
3161 cfg->dp_aux_init(qmp); in qmp_combo_typec_switch_set()
3163 mutex_unlock(&qmp->phy_mutex); in qmp_combo_typec_switch_set()
3172 typec_switch_unregister(qmp->sw); in qmp_combo_typec_unregister()
3178 struct device *dev = qmp->dev; in qmp_combo_typec_switch_register()
3181 sw_desc.fwnode = dev->fwnode; in qmp_combo_typec_switch_register()
3183 qmp->sw = typec_switch_register(dev, &sw_desc); in qmp_combo_typec_switch_register()
3184 if (IS_ERR(qmp->sw)) { in qmp_combo_typec_switch_register()
3185 dev_err(dev, "Unable to register typec switch: %pe\n", qmp->sw); in qmp_combo_typec_switch_register()
3186 return PTR_ERR(qmp->sw); in qmp_combo_typec_switch_register()
3206 return -EINVAL; in qmp_combo_bridge_attach()
3208 next_bridge = devm_drm_of_get_bridge(qmp->dev, qmp->dev->of_node, 0, 0); in qmp_combo_bridge_attach()
3210 dev_err(qmp->dev, "failed to acquire drm_bridge: %pe\n", next_bridge); in qmp_combo_bridge_attach()
3214 return drm_bridge_attach(bridge->encoder, next_bridge, bridge, in qmp_combo_bridge_attach()
3224 qmp->bridge.funcs = &qmp_combo_bridge_funcs; in qmp_combo_dp_register_bridge()
3225 qmp->bridge.of_node = qmp->dev->of_node; in qmp_combo_dp_register_bridge()
3227 return devm_drm_bridge_add(qmp->dev, &qmp->bridge); in qmp_combo_dp_register_bridge()
3238 struct device *dev = qmp->dev; in qmp_combo_parse_dt_lecacy_dp()
3242 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2; in qmp_combo_parse_dt_lecacy_dp()
3243 * tx2 -> 3; rx2 -> 4 in qmp_combo_parse_dt_lecacy_dp()
3245 * Note that only tx/tx2 and pcs (dp_phy) are used by the DP in qmp_combo_parse_dt_lecacy_dp()
3248 qmp->dp_tx = devm_of_iomap(dev, np, 0, NULL); in qmp_combo_parse_dt_lecacy_dp()
3249 if (IS_ERR(qmp->dp_tx)) in qmp_combo_parse_dt_lecacy_dp()
3250 return PTR_ERR(qmp->dp_tx); in qmp_combo_parse_dt_lecacy_dp()
3252 qmp->dp_dp_phy = devm_of_iomap(dev, np, 2, NULL); in qmp_combo_parse_dt_lecacy_dp()
3253 if (IS_ERR(qmp->dp_dp_phy)) in qmp_combo_parse_dt_lecacy_dp()
3254 return PTR_ERR(qmp->dp_dp_phy); in qmp_combo_parse_dt_lecacy_dp()
3256 qmp->dp_tx2 = devm_of_iomap(dev, np, 3, NULL); in qmp_combo_parse_dt_lecacy_dp()
3257 if (IS_ERR(qmp->dp_tx2)) in qmp_combo_parse_dt_lecacy_dp()
3258 return PTR_ERR(qmp->dp_tx2); in qmp_combo_parse_dt_lecacy_dp()
3265 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_parse_dt_lecacy_usb()
3266 struct device *dev = qmp->dev; in qmp_combo_parse_dt_lecacy_usb()
3270 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2; in qmp_combo_parse_dt_lecacy_usb()
3271 * tx2 -> 3; rx2 -> 4; pcs_misc (optional) -> 5 in qmp_combo_parse_dt_lecacy_usb()
3273 qmp->tx = devm_of_iomap(dev, np, 0, NULL); in qmp_combo_parse_dt_lecacy_usb()
3274 if (IS_ERR(qmp->tx)) in qmp_combo_parse_dt_lecacy_usb()
3275 return PTR_ERR(qmp->tx); in qmp_combo_parse_dt_lecacy_usb()
3277 qmp->rx = devm_of_iomap(dev, np, 1, NULL); in qmp_combo_parse_dt_lecacy_usb()
3278 if (IS_ERR(qmp->rx)) in qmp_combo_parse_dt_lecacy_usb()
3279 return PTR_ERR(qmp->rx); in qmp_combo_parse_dt_lecacy_usb()
3281 qmp->pcs = devm_of_iomap(dev, np, 2, NULL); in qmp_combo_parse_dt_lecacy_usb()
3282 if (IS_ERR(qmp->pcs)) in qmp_combo_parse_dt_lecacy_usb()
3283 return PTR_ERR(qmp->pcs); in qmp_combo_parse_dt_lecacy_usb()
3285 if (cfg->pcs_usb_offset) in qmp_combo_parse_dt_lecacy_usb()
3286 qmp->pcs_usb = qmp->pcs + cfg->pcs_usb_offset; in qmp_combo_parse_dt_lecacy_usb()
3288 qmp->tx2 = devm_of_iomap(dev, np, 3, NULL); in qmp_combo_parse_dt_lecacy_usb()
3289 if (IS_ERR(qmp->tx2)) in qmp_combo_parse_dt_lecacy_usb()
3290 return PTR_ERR(qmp->tx2); in qmp_combo_parse_dt_lecacy_usb()
3292 qmp->rx2 = devm_of_iomap(dev, np, 4, NULL); in qmp_combo_parse_dt_lecacy_usb()
3293 if (IS_ERR(qmp->rx2)) in qmp_combo_parse_dt_lecacy_usb()
3294 return PTR_ERR(qmp->rx2); in qmp_combo_parse_dt_lecacy_usb()
3296 qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL); in qmp_combo_parse_dt_lecacy_usb()
3297 if (IS_ERR(qmp->pcs_misc)) { in qmp_combo_parse_dt_lecacy_usb()
3298 dev_vdbg(dev, "PHY pcs_misc-reg not used\n"); in qmp_combo_parse_dt_lecacy_usb()
3299 qmp->pcs_misc = NULL; in qmp_combo_parse_dt_lecacy_usb()
3302 qmp->pipe_clk = devm_get_clk_from_child(dev, np, NULL); in qmp_combo_parse_dt_lecacy_usb()
3303 if (IS_ERR(qmp->pipe_clk)) { in qmp_combo_parse_dt_lecacy_usb()
3304 return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk), in qmp_combo_parse_dt_lecacy_usb()
3314 struct platform_device *pdev = to_platform_device(qmp->dev); in qmp_combo_parse_dt_legacy()
3317 qmp->serdes = devm_platform_ioremap_resource(pdev, 0); in qmp_combo_parse_dt_legacy()
3318 if (IS_ERR(qmp->serdes)) in qmp_combo_parse_dt_legacy()
3319 return PTR_ERR(qmp->serdes); in qmp_combo_parse_dt_legacy()
3321 qmp->com = devm_platform_ioremap_resource(pdev, 1); in qmp_combo_parse_dt_legacy()
3322 if (IS_ERR(qmp->com)) in qmp_combo_parse_dt_legacy()
3323 return PTR_ERR(qmp->com); in qmp_combo_parse_dt_legacy()
3325 qmp->dp_serdes = devm_platform_ioremap_resource(pdev, 2); in qmp_combo_parse_dt_legacy()
3326 if (IS_ERR(qmp->dp_serdes)) in qmp_combo_parse_dt_legacy()
3327 return PTR_ERR(qmp->dp_serdes); in qmp_combo_parse_dt_legacy()
3337 ret = devm_clk_bulk_get_all(qmp->dev, &qmp->clks); in qmp_combo_parse_dt_legacy()
3341 qmp->num_clks = ret; in qmp_combo_parse_dt_legacy()
3348 struct platform_device *pdev = to_platform_device(qmp->dev); in qmp_combo_parse_dt()
3349 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_combo_parse_dt()
3350 const struct qmp_combo_offsets *offs = cfg->offsets; in qmp_combo_parse_dt()
3351 struct device *dev = qmp->dev; in qmp_combo_parse_dt()
3356 return -EINVAL; in qmp_combo_parse_dt()
3362 qmp->com = base + offs->com; in qmp_combo_parse_dt()
3363 qmp->tx = base + offs->txa; in qmp_combo_parse_dt()
3364 qmp->rx = base + offs->rxa; in qmp_combo_parse_dt()
3365 qmp->tx2 = base + offs->txb; in qmp_combo_parse_dt()
3366 qmp->rx2 = base + offs->rxb; in qmp_combo_parse_dt()
3368 qmp->serdes = base + offs->usb3_serdes; in qmp_combo_parse_dt()
3369 qmp->pcs_misc = base + offs->usb3_pcs_misc; in qmp_combo_parse_dt()
3370 qmp->pcs = base + offs->usb3_pcs; in qmp_combo_parse_dt()
3371 qmp->pcs_usb = base + offs->usb3_pcs_usb; in qmp_combo_parse_dt()
3373 qmp->dp_serdes = base + offs->dp_serdes; in qmp_combo_parse_dt()
3374 if (offs->dp_txa) { in qmp_combo_parse_dt()
3375 qmp->dp_tx = base + offs->dp_txa; in qmp_combo_parse_dt()
3376 qmp->dp_tx2 = base + offs->dp_txb; in qmp_combo_parse_dt()
3378 qmp->dp_tx = base + offs->txa; in qmp_combo_parse_dt()
3379 qmp->dp_tx2 = base + offs->txb; in qmp_combo_parse_dt()
3381 qmp->dp_dp_phy = base + offs->dp_dp_phy; in qmp_combo_parse_dt()
3387 qmp->pipe_clk = devm_clk_get(dev, "usb3_pipe"); in qmp_combo_parse_dt()
3388 if (IS_ERR(qmp->pipe_clk)) { in qmp_combo_parse_dt()
3389 return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk), in qmp_combo_parse_dt()
3400 if (args->args_count == 0) in qmp_combo_phy_xlate()
3401 return ERR_PTR(-EINVAL); in qmp_combo_phy_xlate()
3403 switch (args->args[0]) { in qmp_combo_phy_xlate()
3405 return qmp->usb_phy; in qmp_combo_phy_xlate()
3407 return qmp->dp_phy; in qmp_combo_phy_xlate()
3410 return ERR_PTR(-EINVAL); in qmp_combo_phy_xlate()
3416 struct device *dev = &pdev->dev; in qmp_combo_probe()
3423 return -ENOMEM; in qmp_combo_probe()
3425 qmp->dev = dev; in qmp_combo_probe()
3427 qmp->orientation = TYPEC_ORIENTATION_NORMAL; in qmp_combo_probe()
3429 qmp->cfg = of_device_get_match_data(dev); in qmp_combo_probe()
3430 if (!qmp->cfg) in qmp_combo_probe()
3431 return -EINVAL; in qmp_combo_probe()
3433 mutex_init(&qmp->phy_mutex); in qmp_combo_probe()
3452 usb_np = of_get_child_by_name(dev->of_node, "usb3-phy"); in qmp_combo_probe()
3454 dp_np = of_get_child_by_name(dev->of_node, "dp-phy"); in qmp_combo_probe()
3457 return -EINVAL; in qmp_combo_probe()
3462 usb_np = of_node_get(dev->of_node); in qmp_combo_probe()
3463 dp_np = of_node_get(dev->of_node); in qmp_combo_probe()
3484 qmp->usb_phy = devm_phy_create(dev, usb_np, &qmp_combo_usb_phy_ops); in qmp_combo_probe()
3485 if (IS_ERR(qmp->usb_phy)) { in qmp_combo_probe()
3486 ret = PTR_ERR(qmp->usb_phy); in qmp_combo_probe()
3491 phy_set_drvdata(qmp->usb_phy, qmp); in qmp_combo_probe()
3493 qmp->dp_phy = devm_phy_create(dev, dp_np, &qmp_combo_dp_phy_ops); in qmp_combo_probe()
3494 if (IS_ERR(qmp->dp_phy)) { in qmp_combo_probe()
3495 ret = PTR_ERR(qmp->dp_phy); in qmp_combo_probe()
3500 phy_set_drvdata(qmp->dp_phy, qmp); in qmp_combo_probe()
3504 if (usb_np == dev->of_node) in qmp_combo_probe()
3522 .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
3526 .compatible = "qcom,sc7280-qmp-usb3-dp-phy",
3530 .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
3534 .compatible = "qcom,sc8280xp-qmp-usb43dp-phy",
3538 .compatible = "qcom,sdm845-qmp-usb3-dp-phy",
3542 .compatible = "qcom,sm6350-qmp-usb3-dp-phy",
3546 .compatible = "qcom,sm8150-qmp-usb3-dp-phy",
3550 .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
3554 .compatible = "qcom,sm8350-qmp-usb3-dp-phy",
3558 .compatible = "qcom,sm8450-qmp-usb3-dp-phy",
3562 .compatible = "qcom,sm8550-qmp-usb3-dp-phy",
3572 .name = "qcom-qmp-combo-phy",