Lines Matching refs:qmp
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"
1356 int (*configure_dp_phy)(struct qmp_combo *qmp);
1357 void (*configure_dp_tx)(struct qmp_combo *qmp);
1358 int (*calibrate_dp_phy)(struct qmp_combo *qmp);
1359 void (*dp_aux_init)(struct qmp_combo *qmp);
1428 static void qmp_v3_dp_aux_init(struct qmp_combo *qmp);
1429 static void qmp_v3_configure_dp_tx(struct qmp_combo *qmp);
1430 static int qmp_v3_configure_dp_phy(struct qmp_combo *qmp);
1431 static int qmp_v3_calibrate_dp_phy(struct qmp_combo *qmp);
1433 static void qmp_v4_dp_aux_init(struct qmp_combo *qmp);
1434 static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp);
1435 static int qmp_v4_configure_dp_phy(struct qmp_combo *qmp);
1436 static int qmp_v4_calibrate_dp_phy(struct qmp_combo *qmp);
1896 static int qmp_combo_dp_serdes_init(struct qmp_combo *qmp)
1898 const struct qmp_phy_cfg *cfg = qmp->cfg;
1899 void __iomem *serdes = qmp->dp_serdes;
1900 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
1929 static void qmp_v3_dp_aux_init(struct qmp_combo *qmp)
1931 const struct qmp_phy_cfg *cfg = qmp->cfg;
1935 qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
1940 qmp->dp_serdes + cfg->regs[QPHY_COM_BIAS_EN_CLKBUFLR_EN]);
1942 writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
1948 qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
1954 qmp->dp_serdes + cfg->regs[QPHY_COM_BIAS_EN_CLKBUFLR_EN]);
1956 writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG0);
1957 writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1);
1958 writel(0x24, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2);
1959 writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG3);
1960 writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG4);
1961 writel(0x26, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG5);
1962 writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG6);
1963 writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7);
1964 writel(0xbb, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8);
1965 writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9);
1966 qmp->dp_aux_cfg = 0;
1971 qmp->dp_dp_phy + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK);
1974 static int qmp_combo_configure_dp_swing(struct qmp_combo *qmp)
1976 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
1977 const struct qmp_phy_cfg *cfg = qmp->cfg;
2003 writel(voltage_swing_cfg, qmp->dp_tx + cfg->regs[QPHY_TX_TX_DRV_LVL]);
2004 writel(pre_emphasis_cfg, qmp->dp_tx + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]);
2005 writel(voltage_swing_cfg, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_DRV_LVL]);
2006 writel(pre_emphasis_cfg, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]);
2011 static void qmp_v3_configure_dp_tx(struct qmp_combo *qmp)
2013 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
2016 if (qmp_combo_configure_dp_swing(qmp) < 0)
2027 writel(drvr_en, qmp->dp_tx + QSERDES_V3_TX_HIGHZ_DRVR_EN);
2028 writel(bias_en, qmp->dp_tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
2029 writel(drvr_en, qmp->dp_tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN);
2030 writel(bias_en, qmp->dp_tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
2033 static bool qmp_combo_configure_dp_mode(struct qmp_combo *qmp)
2035 bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE);
2036 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
2047 writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
2050 writel(0x4c, qmp->pcs + QSERDES_DP_PHY_MODE);
2052 writel(0x5c, qmp->pcs + QSERDES_DP_PHY_MODE);
2057 static int qmp_combo_configure_dp_clocks(struct qmp_combo *qmp)
2059 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
2084 writel(phy_vco_div, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_VCO_DIV);
2086 clk_set_rate(qmp->dp_link_hw.clk, dp_opts->link_rate * 100000);
2087 clk_set_rate(qmp->dp_pixel_hw.clk, pixel_freq);
2092 static int qmp_v3_configure_dp_phy(struct qmp_combo *qmp)
2094 const struct qmp_phy_cfg *cfg = qmp->cfg;
2098 qmp_combo_configure_dp_mode(qmp);
2100 writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL);
2101 writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL);
2103 ret = qmp_combo_configure_dp_clocks(qmp);
2107 writel(0x04, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2);
2108 writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2109 writel(0x05, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2110 writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2111 writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2113 writel(0x20, qmp->dp_serdes + cfg->regs[QPHY_COM_RESETSM_CNTRL]);
2115 if (readl_poll_timeout(qmp->dp_serdes + cfg->regs[QPHY_COM_C_READY_STATUS],
2122 writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2124 if (readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS],
2131 writel(0x18, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2133 writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2135 return readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS],
2146 static int qmp_v3_calibrate_dp_phy(struct qmp_combo *qmp)
2151 qmp->dp_aux_cfg++;
2152 qmp->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
2153 val = cfg1_settings[qmp->dp_aux_cfg];
2155 writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1);
2160 static void qmp_v4_dp_aux_init(struct qmp_combo *qmp)
2162 const struct qmp_phy_cfg *cfg = qmp->cfg;
2166 qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
2169 writel(0x17, qmp->dp_serdes + cfg->regs[QPHY_COM_BIAS_EN_CLKBUFLR_EN]);
2171 writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG0);
2172 writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1);
2173 writel(0xa4, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2);
2174 writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG3);
2175 writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG4);
2176 writel(0x26, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG5);
2177 writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG6);
2178 writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7);
2179 writel(0xb7, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8);
2180 writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9);
2181 qmp->dp_aux_cfg = 0;
2186 qmp->dp_dp_phy + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK);
2189 static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp)
2191 const struct qmp_phy_cfg *cfg = qmp->cfg;
2194 writel(0x27, qmp->dp_tx + cfg->regs[QPHY_TX_TX_DRV_LVL]);
2195 writel(0x27, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_DRV_LVL]);
2197 writel(0x20, qmp->dp_tx + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]);
2198 writel(0x20, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]);
2200 qmp_combo_configure_dp_swing(qmp);
2203 static int qmp_v456_configure_dp_phy(struct qmp_combo *qmp)
2205 const struct qmp_phy_cfg *cfg = qmp->cfg;
2209 writel(0x0f, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_CFG_1);
2211 qmp_combo_configure_dp_mode(qmp);
2213 writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1);
2214 writel(0xa4, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2);
2216 writel(0x05, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL);
2217 writel(0x05, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL);
2219 ret = qmp_combo_configure_dp_clocks(qmp);
2223 writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2224 writel(0x05, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2225 writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2226 writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2228 writel(0x20, qmp->dp_serdes + cfg->regs[QPHY_COM_RESETSM_CNTRL]);
2230 if (readl_poll_timeout(qmp->dp_serdes + cfg->regs[QPHY_COM_C_READY_STATUS],
2237 if (readl_poll_timeout(qmp->dp_serdes + cfg->regs[QPHY_COM_CMN_STATUS],
2244 if (readl_poll_timeout(qmp->dp_serdes + cfg->regs[QPHY_COM_CMN_STATUS],
2251 writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2253 if (readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS],
2260 if (readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS],
2270 static int qmp_v4_configure_dp_phy(struct qmp_combo *qmp)
2272 const struct qmp_phy_cfg *cfg = qmp->cfg;
2273 bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE);
2274 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
2279 ret = qmp_v456_configure_dp_phy(qmp);
2305 writel(drvr0_en, qmp->dp_tx + cfg->regs[QPHY_TX_HIGHZ_DRVR_EN]);
2306 writel(bias0_en, qmp->dp_tx + cfg->regs[QPHY_TX_TRANSCEIVER_BIAS_EN]);
2307 writel(drvr1_en, qmp->dp_tx2 + cfg->regs[QPHY_TX_HIGHZ_DRVR_EN]);
2308 writel(bias1_en, qmp->dp_tx2 + cfg->regs[QPHY_TX_TRANSCEIVER_BIAS_EN]);
2310 writel(0x18, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2312 writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG);
2314 if (readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS],
2321 writel(0x0a, qmp->dp_tx + cfg->regs[QPHY_TX_TX_POL_INV]);
2322 writel(0x0a, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_POL_INV]);
2324 writel(0x27, qmp->dp_tx + cfg->regs[QPHY_TX_TX_DRV_LVL]);
2325 writel(0x27, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_DRV_LVL]);
2327 writel(0x20, qmp->dp_tx + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]);
2328 writel(0x20, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]);
2339 static int qmp_v4_calibrate_dp_phy(struct qmp_combo *qmp)
2344 qmp->dp_aux_cfg++;
2345 qmp->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
2346 val = cfg1_settings[qmp->dp_aux_cfg];
2348 writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1);
2356 struct qmp_combo *qmp = phy_get_drvdata(phy);
2357 const struct qmp_phy_cfg *cfg = qmp->cfg;
2359 mutex_lock(&qmp->phy_mutex);
2361 memcpy(&qmp->dp_opts, dp_opts, sizeof(*dp_opts));
2362 if (qmp->dp_opts.set_voltages) {
2363 cfg->configure_dp_tx(qmp);
2364 qmp->dp_opts.set_voltages = 0;
2367 mutex_unlock(&qmp->phy_mutex);
2374 struct qmp_combo *qmp = phy_get_drvdata(phy);
2375 const struct qmp_phy_cfg *cfg = qmp->cfg;
2378 mutex_lock(&qmp->phy_mutex);
2381 ret = cfg->calibrate_dp_phy(qmp);
2383 mutex_unlock(&qmp->phy_mutex);
2388 static int qmp_combo_com_init(struct qmp_combo *qmp, bool force)
2390 const struct qmp_phy_cfg *cfg = qmp->cfg;
2391 void __iomem *com = qmp->com;
2395 if (!force && qmp->init_count++)
2398 ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
2400 dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
2404 ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets);
2406 dev_err(qmp->dev, "reset assert failed\n");
2410 ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
2412 dev_err(qmp->dev, "reset deassert failed\n");
2416 ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks);
2422 /* override hardware control for reset of qmp phy */
2429 if (qmp->orientation == TYPEC_ORIENTATION_REVERSE)
2442 qphy_setbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
2448 reset_control_bulk_assert(cfg->num_resets, qmp->resets);
2450 regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
2452 qmp->init_count--;
2457 static int qmp_combo_com_exit(struct qmp_combo *qmp, bool force)
2459 const struct qmp_phy_cfg *cfg = qmp->cfg;
2461 if (!force && --qmp->init_count)
2464 reset_control_bulk_assert(cfg->num_resets, qmp->resets);
2466 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
2468 regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
2475 struct qmp_combo *qmp = phy_get_drvdata(phy);
2476 const struct qmp_phy_cfg *cfg = qmp->cfg;
2479 mutex_lock(&qmp->phy_mutex);
2481 ret = qmp_combo_com_init(qmp, false);
2485 cfg->dp_aux_init(qmp);
2487 qmp->dp_init_count++;
2490 mutex_unlock(&qmp->phy_mutex);
2496 struct qmp_combo *qmp = phy_get_drvdata(phy);
2498 mutex_lock(&qmp->phy_mutex);
2500 qmp_combo_com_exit(qmp, false);
2502 qmp->dp_init_count--;
2504 mutex_unlock(&qmp->phy_mutex);
2511 struct qmp_combo *qmp = phy_get_drvdata(phy);
2512 const struct qmp_phy_cfg *cfg = qmp->cfg;
2513 void __iomem *tx = qmp->dp_tx;
2514 void __iomem *tx2 = qmp->dp_tx2;
2516 mutex_lock(&qmp->phy_mutex);
2518 qmp_combo_dp_serdes_init(qmp);
2524 cfg->configure_dp_tx(qmp);
2527 cfg->configure_dp_phy(qmp);
2529 mutex_unlock(&qmp->phy_mutex);
2536 struct qmp_combo *qmp = phy_get_drvdata(phy);
2538 mutex_lock(&qmp->phy_mutex);
2541 writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL);
2543 mutex_unlock(&qmp->phy_mutex);
2550 struct qmp_combo *qmp = phy_get_drvdata(phy);
2551 const struct qmp_phy_cfg *cfg = qmp->cfg;
2552 void __iomem *serdes = qmp->serdes;
2553 void __iomem *tx = qmp->tx;
2554 void __iomem *rx = qmp->rx;
2555 void __iomem *tx2 = qmp->tx2;
2556 void __iomem *rx2 = qmp->rx2;
2557 void __iomem *pcs = qmp->pcs;
2558 void __iomem *pcs_usb = qmp->pcs_usb;
2565 ret = clk_prepare_enable(qmp->pipe_clk);
2567 dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
2596 dev_err(qmp->dev, "phy initialization timed-out\n");
2603 clk_disable_unprepare(qmp->pipe_clk);
2610 struct qmp_combo *qmp = phy_get_drvdata(phy);
2611 const struct qmp_phy_cfg *cfg = qmp->cfg;
2613 clk_disable_unprepare(qmp->pipe_clk);
2616 qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
2619 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL],
2623 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
2631 struct qmp_combo *qmp = phy_get_drvdata(phy);
2634 mutex_lock(&qmp->phy_mutex);
2635 ret = qmp_combo_com_init(qmp, false);
2641 qmp_combo_com_exit(qmp, false);
2645 qmp->usb_init_count++;
2648 mutex_unlock(&qmp->phy_mutex);
2654 struct qmp_combo *qmp = phy_get_drvdata(phy);
2657 mutex_lock(&qmp->phy_mutex);
2662 ret = qmp_combo_com_exit(qmp, false);
2666 qmp->usb_init_count--;
2669 mutex_unlock(&qmp->phy_mutex);
2675 struct qmp_combo *qmp = phy_get_drvdata(phy);
2677 qmp->mode = mode;
2699 static void qmp_combo_enable_autonomous_mode(struct qmp_combo *qmp)
2701 const struct qmp_phy_cfg *cfg = qmp->cfg;
2702 void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs;
2703 void __iomem *pcs_misc = qmp->pcs_misc;
2706 if (qmp->mode == PHY_MODE_USB_HOST_SS ||
2707 qmp->mode == PHY_MODE_USB_DEVICE_SS)
2728 static void qmp_combo_disable_autonomous_mode(struct qmp_combo *qmp)
2730 const struct qmp_phy_cfg *cfg = qmp->cfg;
2731 void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs;
2732 void __iomem *pcs_misc = qmp->pcs_misc;
2748 struct qmp_combo *qmp = dev_get_drvdata(dev);
2750 dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
2752 if (!qmp->init_count) {
2757 qmp_combo_enable_autonomous_mode(qmp);
2759 clk_disable_unprepare(qmp->pipe_clk);
2760 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
2767 struct qmp_combo *qmp = dev_get_drvdata(dev);
2770 dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
2772 if (!qmp->init_count) {
2777 ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks);
2781 ret = clk_prepare_enable(qmp->pipe_clk);
2784 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
2788 qmp_combo_disable_autonomous_mode(qmp);
2798 static int qmp_combo_vreg_init(struct qmp_combo *qmp)
2800 const struct qmp_phy_cfg *cfg = qmp->cfg;
2801 struct device *dev = qmp->dev;
2805 qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
2806 if (!qmp->vregs)
2810 qmp->vregs[i].supply = cfg->vreg_list[i].name;
2812 ret = devm_regulator_bulk_get(dev, num, qmp->vregs);
2819 ret = regulator_set_load(qmp->vregs[i].consumer,
2823 qmp->vregs[i].supply);
2831 static int qmp_combo_reset_init(struct qmp_combo *qmp)
2833 const struct qmp_phy_cfg *cfg = qmp->cfg;
2834 struct device *dev = qmp->dev;
2838 qmp->resets = devm_kcalloc(dev, cfg->num_resets,
2839 sizeof(*qmp->resets), GFP_KERNEL);
2840 if (!qmp->resets)
2844 qmp->resets[i].id = cfg->reset_list[i];
2846 ret = devm_reset_control_bulk_get_exclusive(dev, cfg->num_resets, qmp->resets);
2853 static int qmp_combo_clk_init(struct qmp_combo *qmp)
2855 struct device *dev = qmp->dev;
2859 qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
2860 if (!qmp->clks)
2864 qmp->clks[i].id = qmp_combo_phy_clk_l[i];
2866 qmp->num_clks = num;
2868 return devm_clk_bulk_get_optional(dev, num, qmp->clks);
2894 static int phy_pipe_clk_register(struct qmp_combo *qmp, struct device_node *np)
2896 struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed;
2900 snprintf(name, sizeof(name), "%s::pipe_clk", dev_name(qmp->dev));
2908 return devm_clk_hw_register(qmp->dev, &fixed->hw);
2974 const struct qmp_combo *qmp;
2977 qmp = container_of(hw, struct qmp_combo, dp_pixel_hw);
2978 dp_opts = &qmp->dp_opts;
3014 const struct qmp_combo *qmp;
3017 qmp = container_of(hw, struct qmp_combo, dp_link_hw);
3018 dp_opts = &qmp->dp_opts;
3038 struct qmp_combo *qmp = data;
3047 return &qmp->dp_link_hw;
3049 return &qmp->dp_pixel_hw;
3052 static int phy_dp_clks_register(struct qmp_combo *qmp, struct device_node *np)
3058 snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev));
3061 qmp->dp_link_hw.init = &init;
3062 ret = devm_clk_hw_register(qmp->dev, &qmp->dp_link_hw);
3066 snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev));
3069 qmp->dp_pixel_hw.init = &init;
3070 ret = devm_clk_hw_register(qmp->dev, &qmp->dp_pixel_hw);
3079 struct qmp_combo *qmp = data;
3083 return &qmp->pipe_clk_fixed.hw;
3085 return &qmp->dp_link_hw;
3087 return &qmp->dp_pixel_hw;
3093 static int qmp_combo_register_clocks(struct qmp_combo *qmp, struct device_node *usb_np,
3098 ret = phy_pipe_clk_register(qmp, usb_np);
3102 ret = phy_dp_clks_register(qmp, dp_np);
3109 if (usb_np == qmp->dev->of_node)
3110 return devm_of_clk_add_hw_provider(qmp->dev, qmp_combo_clk_hw_get, qmp);
3116 &qmp->pipe_clk_fixed.hw);
3124 ret = devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, usb_np);
3128 ret = of_clk_add_hw_provider(dp_np, qmp_dp_clks_hw_get, qmp);
3132 return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, dp_np);
3139 struct qmp_combo *qmp = typec_switch_get_drvdata(sw);
3140 const struct qmp_phy_cfg *cfg = qmp->cfg;
3142 if (orientation == qmp->orientation || orientation == TYPEC_ORIENTATION_NONE)
3145 mutex_lock(&qmp->phy_mutex);
3146 qmp->orientation = orientation;
3148 if (qmp->init_count) {
3149 if (qmp->usb_init_count)
3150 qmp_combo_usb_power_off(qmp->usb_phy);
3151 qmp_combo_com_exit(qmp, true);
3153 qmp_combo_com_init(qmp, true);
3154 if (qmp->usb_init_count)
3155 qmp_combo_usb_power_on(qmp->usb_phy);
3156 if (qmp->dp_init_count)
3157 cfg->dp_aux_init(qmp);
3159 mutex_unlock(&qmp->phy_mutex);
3166 struct qmp_combo *qmp = data;
3168 typec_switch_unregister(qmp->sw);
3171 static int qmp_combo_typec_switch_register(struct qmp_combo *qmp)
3174 struct device *dev = qmp->dev;
3176 sw_desc.drvdata = qmp;
3179 qmp->sw = typec_switch_register(dev, &sw_desc);
3180 if (IS_ERR(qmp->sw)) {
3181 dev_err(dev, "Unable to register typec switch: %pe\n", qmp->sw);
3182 return PTR_ERR(qmp->sw);
3185 return devm_add_action_or_reset(dev, qmp_combo_typec_unregister, qmp);
3188 static int qmp_combo_typec_switch_register(struct qmp_combo *qmp)
3198 struct qmp_combo *qmp = container_of(bridge, struct qmp_combo, bridge);
3204 next_bridge = devm_drm_of_get_bridge(qmp->dev, qmp->dev->of_node, 0, 0);
3206 dev_err(qmp->dev, "failed to acquire drm_bridge: %pe\n", next_bridge);
3218 static int qmp_combo_dp_register_bridge(struct qmp_combo *qmp)
3220 qmp->bridge.funcs = &qmp_combo_bridge_funcs;
3221 qmp->bridge.of_node = qmp->dev->of_node;
3223 return devm_drm_bridge_add(qmp->dev, &qmp->bridge);
3226 static int qmp_combo_dp_register_bridge(struct qmp_combo *qmp)
3232 static int qmp_combo_parse_dt_lecacy_dp(struct qmp_combo *qmp, struct device_node *np)
3234 struct device *dev = qmp->dev;
3244 qmp->dp_tx = devm_of_iomap(dev, np, 0, NULL);
3245 if (IS_ERR(qmp->dp_tx))
3246 return PTR_ERR(qmp->dp_tx);
3248 qmp->dp_dp_phy = devm_of_iomap(dev, np, 2, NULL);
3249 if (IS_ERR(qmp->dp_dp_phy))
3250 return PTR_ERR(qmp->dp_dp_phy);
3252 qmp->dp_tx2 = devm_of_iomap(dev, np, 3, NULL);
3253 if (IS_ERR(qmp->dp_tx2))
3254 return PTR_ERR(qmp->dp_tx2);
3259 static int qmp_combo_parse_dt_lecacy_usb(struct qmp_combo *qmp, struct device_node *np)
3261 const struct qmp_phy_cfg *cfg = qmp->cfg;
3262 struct device *dev = qmp->dev;
3269 qmp->tx = devm_of_iomap(dev, np, 0, NULL);
3270 if (IS_ERR(qmp->tx))
3271 return PTR_ERR(qmp->tx);
3273 qmp->rx = devm_of_iomap(dev, np, 1, NULL);
3274 if (IS_ERR(qmp->rx))
3275 return PTR_ERR(qmp->rx);
3277 qmp->pcs = devm_of_iomap(dev, np, 2, NULL);
3278 if (IS_ERR(qmp->pcs))
3279 return PTR_ERR(qmp->pcs);
3282 qmp->pcs_usb = qmp->pcs + cfg->pcs_usb_offset;
3284 qmp->tx2 = devm_of_iomap(dev, np, 3, NULL);
3285 if (IS_ERR(qmp->tx2))
3286 return PTR_ERR(qmp->tx2);
3288 qmp->rx2 = devm_of_iomap(dev, np, 4, NULL);
3289 if (IS_ERR(qmp->rx2))
3290 return PTR_ERR(qmp->rx2);
3292 qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
3293 if (IS_ERR(qmp->pcs_misc)) {
3295 qmp->pcs_misc = NULL;
3298 qmp->pipe_clk = devm_get_clk_from_child(dev, np, NULL);
3299 if (IS_ERR(qmp->pipe_clk)) {
3300 return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
3307 static int qmp_combo_parse_dt_legacy(struct qmp_combo *qmp, struct device_node *usb_np,
3310 struct platform_device *pdev = to_platform_device(qmp->dev);
3313 qmp->serdes = devm_platform_ioremap_resource(pdev, 0);
3314 if (IS_ERR(qmp->serdes))
3315 return PTR_ERR(qmp->serdes);
3317 qmp->com = devm_platform_ioremap_resource(pdev, 1);
3318 if (IS_ERR(qmp->com))
3319 return PTR_ERR(qmp->com);
3321 qmp->dp_serdes = devm_platform_ioremap_resource(pdev, 2);
3322 if (IS_ERR(qmp->dp_serdes))
3323 return PTR_ERR(qmp->dp_serdes);
3325 ret = qmp_combo_parse_dt_lecacy_usb(qmp, usb_np);
3329 ret = qmp_combo_parse_dt_lecacy_dp(qmp, dp_np);
3333 ret = devm_clk_bulk_get_all(qmp->dev, &qmp->clks);
3337 qmp->num_clks = ret;
3342 static int qmp_combo_parse_dt(struct qmp_combo *qmp)
3344 struct platform_device *pdev = to_platform_device(qmp->dev);
3345 const struct qmp_phy_cfg *cfg = qmp->cfg;
3347 struct device *dev = qmp->dev;
3358 qmp->com = base + offs->com;
3359 qmp->tx = base + offs->txa;
3360 qmp->rx = base + offs->rxa;
3361 qmp->tx2 = base + offs->txb;
3362 qmp->rx2 = base + offs->rxb;
3364 qmp->serdes = base + offs->usb3_serdes;
3365 qmp->pcs_misc = base + offs->usb3_pcs_misc;
3366 qmp->pcs = base + offs->usb3_pcs;
3367 qmp->pcs_usb = base + offs->usb3_pcs_usb;
3369 qmp->dp_serdes = base + offs->dp_serdes;
3371 qmp->dp_tx = base + offs->dp_txa;
3372 qmp->dp_tx2 = base + offs->dp_txb;
3374 qmp->dp_tx = base + offs->txa;
3375 qmp->dp_tx2 = base + offs->txb;
3377 qmp->dp_dp_phy = base + offs->dp_dp_phy;
3379 ret = qmp_combo_clk_init(qmp);
3383 qmp->pipe_clk = devm_clk_get(dev, "usb3_pipe");
3384 if (IS_ERR(qmp->pipe_clk)) {
3385 return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
3394 struct qmp_combo *qmp = dev_get_drvdata(dev);
3401 return qmp->usb_phy;
3403 return qmp->dp_phy;
3411 struct qmp_combo *qmp;
3417 qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
3418 if (!qmp)
3421 qmp->dev = dev;
3423 qmp->orientation = TYPEC_ORIENTATION_NORMAL;
3425 qmp->cfg = of_device_get_match_data(dev);
3426 if (!qmp->cfg)
3429 mutex_init(&qmp->phy_mutex);
3431 ret = qmp_combo_reset_init(qmp);
3435 ret = qmp_combo_vreg_init(qmp);
3439 ret = qmp_combo_typec_switch_register(qmp);
3443 ret = qmp_combo_dp_register_bridge(qmp);
3456 ret = qmp_combo_parse_dt_legacy(qmp, usb_np, dp_np);
3461 ret = qmp_combo_parse_dt(qmp);
3476 ret = qmp_combo_register_clocks(qmp, usb_np, dp_np);
3480 qmp->usb_phy = devm_phy_create(dev, usb_np, &qmp_combo_usb_phy_ops);
3481 if (IS_ERR(qmp->usb_phy)) {
3482 ret = PTR_ERR(qmp->usb_phy);
3487 phy_set_drvdata(qmp->usb_phy, qmp);
3489 qmp->dp_phy = devm_phy_create(dev, dp_np, &qmp_combo_dp_phy_ops);
3490 if (IS_ERR(qmp->dp_phy)) {
3491 ret = PTR_ERR(qmp->dp_phy);
3496 phy_set_drvdata(qmp->dp_phy, qmp);
3498 dev_set_drvdata(dev, qmp);
3518 .compatible = "qcom,sc7180-qmp-usb3-dp-phy",
3522 .compatible = "qcom,sc7280-qmp-usb3-dp-phy",
3526 .compatible = "qcom,sc8180x-qmp-usb3-dp-phy",
3530 .compatible = "qcom,sc8280xp-qmp-usb43dp-phy",
3534 .compatible = "qcom,sdm845-qmp-usb3-dp-phy",
3538 .compatible = "qcom,sm6350-qmp-usb3-dp-phy",
3542 .compatible = "qcom,sm8150-qmp-usb3-dp-phy",
3546 .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
3550 .compatible = "qcom,sm8350-qmp-usb3-dp-phy",
3554 .compatible = "qcom,sm8450-qmp-usb3-dp-phy",
3558 .compatible = "qcom,sm8550-qmp-usb3-dp-phy",
3568 .name = "qcom-qmp-combo-phy",