Skip to content

Commit c8081b2

Browse files
committed
drm/i915/dp: Track source OUI validity explicitly
While updating the source OUI on the sink the driver should avoid writing the OUI if it's already up-to-date to prevent the sink from resetting itself in response to the update. On eDP - the only output type where the OUI was updated so far - the driver ensured this by comparing the current source OUI DPCD register values with the expected Intel OUI value, skipping the update in case of a match. On some non-eDP sinks - at least on Synaptics branch devices - this method doesn't work, since the source OUI DPCD registers read back as all 0, even after updating the registers. Handle the above kind of sinks by tracking when the OUI was updated and so should be valid, regardless of what the DPCD registers contain. eDP sinks reset the written source OUI value when the panel power is disabled, invalidate the OUI state accordingly. This is required by a follow-up patch updating the source OUI for non-eDP sink types as well. v2: Fix setting intel_dp::oui_valid=true, if the DPCD register contains already the expected value. Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241025160259.3088727-5-imre.deak@intel.com
1 parent 5861258 commit c8081b2

File tree

6 files changed

+34
-14
lines changed

6 files changed

+34
-14
lines changed

drivers/gpu/drm/i915/display/g4x_dp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,6 +1249,7 @@ static void intel_dp_encoder_reset(struct drm_encoder *encoder)
12491249
intel_dp->DP = intel_de_read(display, intel_dp->output_reg);
12501250

12511251
intel_dp->reset_link_params = true;
1252+
intel_dp_invalidate_source_oui(intel_dp);
12521253

12531254
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
12541255
vlv_pps_pipe_reset(intel_dp);

drivers/gpu/drm/i915/display/intel_ddi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4392,6 +4392,7 @@ static void intel_ddi_encoder_reset(struct drm_encoder *encoder)
43924392
struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder));
43934393

43944394
intel_dp->reset_link_params = true;
4395+
intel_dp_invalidate_source_oui(intel_dp);
43954396

43964397
intel_pps_encoder_reset(intel_dp);
43974398

drivers/gpu/drm/i915/display/intel_display_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,6 +1765,7 @@ struct intel_dp {
17651765

17661766
/* When we last wrote the OUI for eDP */
17671767
unsigned long last_oui_write;
1768+
bool oui_valid;
17681769

17691770
bool colorimetry_support;
17701771

drivers/gpu/drm/i915/display/intel_dp.c

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3404,33 +3404,46 @@ void intel_dp_sink_disable_decompression(struct intel_atomic_state *state,
34043404
}
34053405

34063406
static void
3407-
intel_edp_init_source_oui(struct intel_dp *intel_dp, bool careful)
3407+
intel_dp_init_source_oui(struct intel_dp *intel_dp)
34083408
{
34093409
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
34103410
u8 oui[] = { 0x00, 0xaa, 0x01 };
34113411
u8 buf[3] = {};
34123412

3413+
if (!intel_dp_is_edp(intel_dp))
3414+
return;
3415+
3416+
if (READ_ONCE(intel_dp->oui_valid))
3417+
return;
3418+
3419+
WRITE_ONCE(intel_dp->oui_valid, true);
3420+
34133421
/*
34143422
* During driver init, we want to be careful and avoid changing the source OUI if it's
34153423
* already set to what we want, so as to avoid clearing any state by accident
34163424
*/
3417-
if (careful) {
3418-
if (drm_dp_dpcd_read(&intel_dp->aux, DP_SOURCE_OUI, buf, sizeof(buf)) < 0)
3419-
drm_err(&i915->drm, "Failed to read source OUI\n");
3425+
if (drm_dp_dpcd_read(&intel_dp->aux, DP_SOURCE_OUI, buf, sizeof(buf)) < 0)
3426+
drm_err(&i915->drm, "Failed to read source OUI\n");
34203427

3421-
if (memcmp(oui, buf, sizeof(oui)) == 0) {
3422-
/* Assume the OUI was written now. */
3423-
intel_dp->last_oui_write = jiffies;
3424-
return;
3425-
}
3428+
if (memcmp(oui, buf, sizeof(oui)) == 0) {
3429+
/* Assume the OUI was written now. */
3430+
intel_dp->last_oui_write = jiffies;
3431+
return;
34263432
}
34273433

3428-
if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0)
3434+
if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0) {
34293435
drm_info(&i915->drm, "Failed to write source OUI\n");
3436+
WRITE_ONCE(intel_dp->oui_valid, false);
3437+
}
34303438

34313439
intel_dp->last_oui_write = jiffies;
34323440
}
34333441

3442+
void intel_dp_invalidate_source_oui(struct intel_dp *intel_dp)
3443+
{
3444+
WRITE_ONCE(intel_dp->oui_valid, false);
3445+
}
3446+
34343447
void intel_dp_wait_source_oui(struct intel_dp *intel_dp)
34353448
{
34363449
struct intel_connector *connector = intel_dp->attached_connector;
@@ -3466,8 +3479,7 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode)
34663479
lspcon_resume(dp_to_dig_port(intel_dp));
34673480

34683481
/* Write the source OUI as early as possible */
3469-
if (intel_dp_is_edp(intel_dp))
3470-
intel_edp_init_source_oui(intel_dp, false);
3482+
intel_dp_init_source_oui(intel_dp);
34713483

34723484
/*
34733485
* When turning on, we need to retry for 1ms to give the sink
@@ -4188,7 +4200,7 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
41884200
* If needed, program our source OUI so we can make various Intel-specific AUX services
41894201
* available (such as HDR backlight controls)
41904202
*/
4191-
intel_edp_init_source_oui(intel_dp, true);
4203+
intel_dp_init_source_oui(intel_dp);
41924204

41934205
return true;
41944206
}

drivers/gpu/drm/i915/display/intel_dp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ void intel_dp_check_frl_training(struct intel_dp *intel_dp);
189189
void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp,
190190
const struct intel_crtc_state *crtc_state);
191191

192+
void intel_dp_invalidate_source_oui(struct intel_dp *intel_dp);
192193
void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
193194
int intel_dp_output_bpp(enum intel_output_format output_format, int bpp);
194195

drivers/gpu/drm/i915/display/intel_pps.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -857,8 +857,10 @@ static void intel_pps_vdd_off_sync_unlocked(struct intel_dp *intel_dp)
857857
intel_de_read(display, pp_stat_reg),
858858
intel_de_read(display, pp_ctrl_reg));
859859

860-
if ((pp & PANEL_POWER_ON) == 0)
860+
if ((pp & PANEL_POWER_ON) == 0) {
861861
intel_dp->pps.panel_power_off_time = ktime_get_boottime();
862+
intel_dp_invalidate_source_oui(intel_dp);
863+
}
862864

863865
intel_display_power_put(dev_priv,
864866
intel_aux_power_domain(dig_port),
@@ -1068,6 +1070,8 @@ void intel_pps_off_unlocked(struct intel_dp *intel_dp)
10681070
wait_panel_off(intel_dp);
10691071
intel_dp->pps.panel_power_off_time = ktime_get_boottime();
10701072

1073+
intel_dp_invalidate_source_oui(intel_dp);
1074+
10711075
/* We got a reference when we enabled the VDD. */
10721076
intel_display_power_put(dev_priv,
10731077
intel_aux_power_domain(dig_port),

0 commit comments

Comments
 (0)