drm/i915/dp_link_training: Introduce link training state struct

Start isolating the link training state from the generic DP code by
introducing a separate intel_dp_link_training state struct.

Allocate the state so it can remain opaque within its own module.

Follow-up changes will move link training fields from the DP struct to
the link training state.

v2: Remove unnecessary function documentation. (Jani)

Cc: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Link: https://patch.msgid.link/20260601093836.3057345-2-imre.deak@intel.com
This commit is contained in:
Imre Deak
2026-06-01 12:38:14 +03:00
parent 04bfc500ad
commit 6b48cb3cb5
7 changed files with 71 additions and 3 deletions

View File

@@ -1252,10 +1252,13 @@ static void g4x_dp_suspend_complete(struct intel_encoder *encoder)
static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
{
struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder));
intel_dp_encoder_flush_work(encoder);
drm_encoder_cleanup(encoder);
kfree(enc_to_dig_port(to_intel_encoder(encoder)));
intel_dp_link_cleanup(&dig_port->dp);
kfree(dig_port);
}
static void intel_dp_encoder_reset(struct drm_encoder *encoder)
@@ -1350,6 +1353,9 @@ bool g4x_dp_init(struct intel_display *display,
intel_encoder->audio_enable = g4x_dp_audio_enable;
intel_encoder->audio_disable = g4x_dp_audio_disable;
if (intel_dp_link_init(&dig_port->dp) != 0)
goto err_dp_init;
if ((display->platform.ivybridge && port == PORT_A) ||
(HAS_PCH_CPT(display) && port != PORT_A)) {
dig_port->dp.set_link_train = cpt_set_link_train;
@@ -1419,6 +1425,8 @@ bool g4x_dp_init(struct intel_display *display,
return true;
err_init_connector:
intel_dp_link_cleanup(&dig_port->dp);
err_dp_init:
drm_encoder_cleanup(encoder);
err_encoder_init:
kfree(intel_connector);

View File

@@ -4654,6 +4654,7 @@ static void intel_ddi_encoder_destroy(struct drm_encoder *encoder)
drm_encoder_cleanup(encoder);
kfree(dig_port->hdcp.port_data.streams);
intel_dp_link_cleanup(&dig_port->dp);
kfree(dig_port);
}
@@ -4691,11 +4692,16 @@ static int intel_ddi_init_dp_connector(struct intel_digital_port *dig_port)
struct intel_display *display = to_intel_display(dig_port);
struct intel_connector *connector;
enum port port = dig_port->base.port;
int err;
connector = intel_connector_alloc();
if (!connector)
return -ENOMEM;
err = intel_dp_link_init(&dig_port->dp);
if (err)
goto err_dp_init;
dig_port->dp.output_reg = DDI_BUF_CTL(port);
if (DISPLAY_VER(display) >= 14)
dig_port->dp.prepare_link_retrain = mtl_ddi_prepare_link_retrain;
@@ -4708,8 +4714,9 @@ static int intel_ddi_init_dp_connector(struct intel_digital_port *dig_port)
dig_port->dp.preemph_max = intel_ddi_dp_preemph_max;
if (!intel_dp_init_connector(dig_port, connector)) {
kfree(connector);
return -EINVAL;
err = -EINVAL;
goto err_init_connector;
}
if (dig_port->base.type == INTEL_OUTPUT_EDP) {
@@ -4725,6 +4732,13 @@ static int intel_ddi_init_dp_connector(struct intel_digital_port *dig_port)
}
return 0;
err_init_connector:
intel_dp_link_cleanup(&dig_port->dp);
err_dp_init:
kfree(connector);
return err;
}
static void intel_ddi_cleanup_dp_connector(struct intel_digital_port *dig_port)
@@ -4733,6 +4747,7 @@ static void intel_ddi_cleanup_dp_connector(struct intel_digital_port *dig_port)
struct intel_connector *connector = intel_dp->attached_connector;
intel_dp_cleanup_connector(dig_port, connector);
intel_dp_link_cleanup(intel_dp);
kfree(connector);
}

View File

@@ -58,6 +58,7 @@ struct cec_notifier;
struct drm_printer;
struct intel_connector;
struct intel_ddi_buf_trans;
struct intel_dp_link_training;
struct intel_fbc;
struct intel_global_objs_state;
struct intel_hdcp_shim;
@@ -1858,6 +1859,7 @@ struct intel_dp {
int seq_train_failures;
int force_train_failure;
bool force_retrain;
struct intel_dp_link_training *training;
} link;
bool reset_link_params;
int mso_link_count;

View File

@@ -7649,3 +7649,17 @@ u8 intel_dp_as_sdp_transmission_time(void)
return DP_PR_AS_SDP_SETUP_TIME_T1;
}
int intel_dp_link_init(struct intel_dp *intel_dp)
{
intel_dp->link.training = intel_dp_link_training_init(intel_dp);
if (!intel_dp->link.training)
return -ENOMEM;
return 0;
}
void intel_dp_link_cleanup(struct intel_dp *intel_dp)
{
intel_dp_link_training_cleanup(intel_dp->link.training);
}

View File

@@ -243,4 +243,7 @@ bool intel_dp_joiner_candidate_valid(struct intel_connector *connector,
u8 intel_dp_as_sdp_transmission_time(void);
int intel_dp_link_init(struct intel_dp *intel_dp);
void intel_dp_link_cleanup(struct intel_dp *intel_dp);
#endif /* __INTEL_DP_H__ */

View File

@@ -62,6 +62,10 @@
#define MAX_SEQ_TRAIN_FAILURES 2
struct intel_dp_link_training {
struct intel_dp *dp;
};
static void intel_dp_reset_lttpr_common_caps(struct intel_dp *intel_dp)
{
memset(intel_dp->lttpr_common_caps, 0, sizeof(intel_dp->lttpr_common_caps));
@@ -2233,3 +2237,21 @@ void intel_dp_link_training_debugfs_add(struct intel_connector *connector)
debugfs_create_file("i915_dp_link_retrain_disabled", 0444, root,
connector, &i915_dp_link_retrain_disabled_fops);
}
struct intel_dp_link_training *intel_dp_link_training_init(struct intel_dp *intel_dp)
{
struct intel_dp_link_training *link_training;
link_training = kzalloc_obj(*link_training);
if (!link_training)
return NULL;
link_training->dp = intel_dp;
return link_training;
}
void intel_dp_link_training_cleanup(struct intel_dp_link_training *link_training)
{
kfree(link_training);
}

View File

@@ -12,6 +12,7 @@ struct intel_atomic_state;
struct intel_connector;
struct intel_crtc_state;
struct intel_dp;
struct intel_dp_link_training;
int intel_dp_read_dprx_caps(struct intel_dp *intel_dp, u8 dpcd[DP_RECEIVER_CAP_SIZE]);
int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp);
@@ -56,4 +57,7 @@ void intel_dp_128b132b_sdp_crc16(struct intel_dp *intel_dp,
void intel_dp_link_training_debugfs_add(struct intel_connector *connector);
struct intel_dp_link_training *intel_dp_link_training_init(struct intel_dp *intel_dp);
void intel_dp_link_training_cleanup(struct intel_dp_link_training *link_training);
#endif /* __INTEL_DP_LINK_TRAINING_H__ */