[PATCH v2 07/12] phy: phy-mtk-dp: Support setting volt swing and preemphasis values
AngeloGioacchino Del Regno
angelogioacchino.delregno at collabora.com
Tue Jul 7 07:19:26 PDT 2026
Add support for honoring the set_voltages request to set the
voltage swing and preemphasis values in the .configure() callback.
For proper hardware cleanup, reset both in the .reset() callback.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
drivers/phy/mediatek/phy-mtk-dp.c | 44 ++++++++++++++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/mediatek/phy-mtk-dp.c b/drivers/phy/mediatek/phy-mtk-dp.c
index 2f3ec3fa384d..270825f130a9 100644
--- a/drivers/phy/mediatek/phy-mtk-dp.c
+++ b/drivers/phy/mediatek/phy-mtk-dp.c
@@ -48,6 +48,11 @@
/* DP_PHYD_TX_CTL_0 */
#define PHYD_TX_LN_EN GENMASK(7, 4)
+/* DP_PHYD_DRIVING_FORCE */
+#define PHYD_DP_TX_FORCE_VOLT_SWING_EN BIT(0)
+#define PHYD_DP_TX_FORCE_VOLT_SWING_VAL GENMASK(2, 1)
+#define PHYD_DP_TX_FORCE_PRE_EMPH_VAL GENMASK(4, 3)
+
#define XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT BIT(4)
#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT (BIT(10) | BIT(12))
#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT GENMASK(20, 19)
@@ -101,6 +106,7 @@ enum mtk_dp_phya_ana_glb_regidx {
};
enum mtk_dp_phyd_dig_lane_regidx {
+ DP_PHYD_LAN_DRIVING_FORCE,
DP_PHYD_LAN_DRIVING_PARAM_0,
DP_PHYD_LAN_MAX
};
@@ -121,6 +127,7 @@ static const u8 mt8195_phy_ana_glb_regs[DP_PHYA_GLOBAL_MAX] = {
};
static const u8 mt8195_phy_dig_lane_regs[DP_PHYD_LAN_MAX] = {
+ [DP_PHYD_LAN_DRIVING_FORCE] = 0x18,
[DP_PHYD_LAN_DRIVING_PARAM_0] = 0x2c,
};
@@ -235,6 +242,30 @@ static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
PHYD_TX_LN_EN, val);
}
+ if (opts->dp.set_voltages) {
+ const u32 reg_drv_force = pdata->regs_dig_lane[DP_PHYD_LAN_DRIVING_FORCE];
+
+ if (opts->dp.lanes > 4) {
+ dev_err(&phy->dev, "Wrong lanes config %u\n", opts->dp.lanes);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < opts->dp.lanes; i++) {
+ const u32 off_dig_lane = pdata->off_dig_lane[i];
+ u32 val;
+
+ val = FIELD_PREP(PHYD_DP_TX_FORCE_VOLT_SWING_VAL, opts->dp.voltage[i]);
+ val |= FIELD_PREP(PHYD_DP_TX_FORCE_PRE_EMPH_VAL, opts->dp.pre[i]);
+ val |= PHYD_DP_TX_FORCE_VOLT_SWING_EN;
+
+ regmap_update_bits(dp_phy->regmap, off_dig_lane + reg_drv_force,
+ PHYD_DP_TX_FORCE_VOLT_SWING_EN |
+ PHYD_DP_TX_FORCE_VOLT_SWING_VAL |
+ PHYD_DP_TX_FORCE_PRE_EMPH_VAL,
+ val);
+ }
+ }
+
regmap_update_bits(dp_phy->regmap,
pdata->off_dig_glb + pdata->regs_dig_glb[DP_PHYD_PLL_CTL_1],
TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
@@ -337,7 +368,8 @@ static int mtk_dp_phy_reset(struct phy *phy)
struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
const struct mtk_dp_phy_pdata *pdata = dp_phy->pdata;
const u32 reg_rst = pdata->regs_dig_glb[DP_PHYD_SW_RST];
- int ret;
+ const u32 reg_drv_force = pdata->regs_dig_lane[DP_PHYD_LAN_DRIVING_FORCE];
+ int i, ret;
/* Clearing bits sets reset state */
regmap_clear_bits(dp_phy->regmap, pdata->off_dig_glb + reg_rst, DP_GLB_SW_RST_PHYD);
@@ -353,6 +385,16 @@ static int mtk_dp_phy_reset(struct phy *phy)
if (ret)
dev_err(dp_phy->dev, "Could not disable lanes during reset!\n");
+ /* Reset Voltage Swing and Preemphasis values */
+ for (i = 0; i < MTK_DP_PHY_MAX_LANES; i++) {
+ const u32 off_dig_lane = pdata->off_dig_lane[i];
+
+ regmap_clear_bits(dp_phy->regmap, off_dig_lane + reg_drv_force,
+ PHYD_DP_TX_FORCE_VOLT_SWING_EN |
+ PHYD_DP_TX_FORCE_VOLT_SWING_VAL |
+ PHYD_DP_TX_FORCE_PRE_EMPH_VAL);
+ }
+
return 0;
}
--
2.54.0
More information about the linux-arm-kernel
mailing list