[PATCH RFC 12/12] drm/mediatek: Use dp_connector helpers to report link training state

Kory Maincent
2026-04-09T17:09:42Z

Set DRM_BRIDGE_OP_DP and populate dp_link_train_caps with the supported
link rates, lane counts, voltage swing and pre-emphasis levels so the
bridge connector uses drmm_connector_dp_init() and exposes the link
training state properties to userspace.

Store per-lane voltage swing and pre-emphasis values in
mtk_dp_train_info and report the negotiated link parameters via
drm_connector_dp_set_link_train_properties() on training completion.
Clear them via drm_connector_dp_reset_link_train_properties() when a
disconnect is detected in the HPD event thread.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

This patch has still not been tested. I am in the process of finding the
hardware for that.
---
drivers/gpu/drm/mediatek/mtk_dp.c | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index c52cc7c2e2006..119718c1374c5 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -10,6 +10,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_crtc.h>
+#include <drm/drm_dp_connector.h>
#include <drm/drm_edid.h>
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
@@ -72,6 +73,8 @@ struct mtk_dp_train_info {
/* link_rate is in multiple of 0.27Gbps */
int link_rate;
int lane_count;
+ u8 vswing[4];
+ u8 preemphasis[4];
unsigned int channel_eq_pattern;
};

@@ -1561,6 +1564,9 @@ static void mtk_dp_train_update_swing_pre(struct mtk_dp *mtk_dp, int lanes,
mtk_dp_set_swing_pre_emphasis(mtk_dp, lane, swing, preemphasis);
drm_dp_dpcd_writeb(&mtk_dp->aux, DP_TRAINING_LANE0_SET + lane,
val);
+
+ mtk_dp->train_info.vswing[lane] = swing;
+ mtk_dp->train_info.preemphasis[lane] = preemphasis;
}
}

@@ -1812,6 +1818,21 @@ static void mtk_dp_train_change_mode(struct mtk_dp *mtk_dp)
mtk_dp_reset_swing_pre_emphasis(mtk_dp);
}

+static int mtk_dp_report_link_train(struct mtk_dp *mtk_dp)
+{
+ struct drm_connector_dp_link_train dp_link_train;
+
+ dp_link_train.rate = drm_dp_bw_code_to_link_rate(mtk_dp->train_info.link_rate);
+ dp_link_train.nlanes = mtk_dp->train_info.lane_count;
+
+ for (int i = 0; i < mtk_dp->train_info.lane_count; i++) {
+ dp_link_train.v_swing[i] = 1 << mtk_dp->train_info.vswing[i];
+ dp_link_train.pre_emph[i] = 1 << mtk_dp->train_info.preemphasis[i];
+ }
+
+ return drm_connector_dp_set_link_train_properties(mtk_dp->conn, &dp_link_train);
+}
+
static int mtk_dp_training(struct mtk_dp *mtk_dp)
{
int ret;
@@ -1892,7 +1913,7 @@ static int mtk_dp_training(struct mtk_dp *mtk_dp)
mtk_dp_training_set_scramble(mtk_dp, true);
mtk_dp_set_enhanced_frame_mode(mtk_dp);

- return 0;
+ return mtk_dp_report_link_train(mtk_dp);
}

static void mtk_dp_video_enable(struct mtk_dp *mtk_dp, bool enable)
@@ -2004,6 +2025,7 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
mtk_dp->need_debounce = false;
mod_timer(&mtk_dp->debounce_timer,
jiffies + msecs_to_jiffies(100) - 1);
+ drm_connector_dp_reset_link_train_properties(mtk_dp->conn);
} else {
mtk_dp_aux_panel_poweron(mtk_dp, true);

@@ -2742,6 +2764,14 @@ static int mtk_dp_edp_link_panel(struct drm_dp_aux *mtk_aux)

static int mtk_dp_probe(struct platform_device *pdev)
{
+ static const u32 dp_rates[] = {162000, 270000, 540000, 810000};
+ static const struct drm_connector_dp_link_train_caps dp_link_train_caps = {
+ .nlanes = DRM_DP_1LANE | DRM_DP_2LANE | DRM_DP_4LANE,
+ .nrates = ARRAY_SIZE(dp_rates),
+ .rates = dp_rates,
+ .v_swings = DRM_DP_VOLTAGE_SWING_LEVEL_MASK,
+ .pre_emphs = DRM_DP_PRE_EMPH_LEVEL_MASK,
+ };
struct mtk_dp *mtk_dp;
struct device *dev = &pdev->dev;
int ret;
@@ -2809,6 +2839,8 @@ static int mtk_dp_probe(struct platform_device *pdev)

mtk_dp->bridge.of_node = dev->of_node;
mtk_dp->bridge.type = mtk_dp->data->bridge_type;
+ mtk_dp->bridge.dp_link_train_caps = &dp_link_train_caps;
+ mtk_dp->bridge.ops = DRM_BRIDGE_OP_DP;

if (mtk_dp->bridge.type == DRM_MODE_CONNECTOR_eDP) {
/*

--
2.43.0