summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_dp.c
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2024-10-25 19:02:55 +0300
committerImre Deak <imre.deak@intel.com>2024-10-31 18:10:11 +0200
commitc8081b2a8ac5aba91d75bc0ed0a442cbe568b36c (patch)
treed7f6040469f963c0ac5fbadcabfef2f55d8d3b7d /drivers/gpu/drm/i915/display/intel_dp.c
parent5861258c4e6a829a10200b41ba3fb4d7d1a4054f (diff)
downloadlinux-c8081b2a8ac5aba91d75bc0ed0a442cbe568b36c.tar.gz
linux-c8081b2a8ac5aba91d75bc0ed0a442cbe568b36c.tar.bz2
linux-c8081b2a8ac5aba91d75bc0ed0a442cbe568b36c.zip
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
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 735890334de3..c2682b7ae867 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3404,33 +3404,46 @@ void intel_dp_sink_disable_decompression(struct intel_atomic_state *state,
}
static void
-intel_edp_init_source_oui(struct intel_dp *intel_dp, bool careful)
+intel_dp_init_source_oui(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 oui[] = { 0x00, 0xaa, 0x01 };
u8 buf[3] = {};
+ if (!intel_dp_is_edp(intel_dp))
+ return;
+
+ if (READ_ONCE(intel_dp->oui_valid))
+ return;
+
+ WRITE_ONCE(intel_dp->oui_valid, true);
+
/*
* During driver init, we want to be careful and avoid changing the source OUI if it's
* already set to what we want, so as to avoid clearing any state by accident
*/
- if (careful) {
- if (drm_dp_dpcd_read(&intel_dp->aux, DP_SOURCE_OUI, buf, sizeof(buf)) < 0)
- drm_err(&i915->drm, "Failed to read source OUI\n");
+ if (drm_dp_dpcd_read(&intel_dp->aux, DP_SOURCE_OUI, buf, sizeof(buf)) < 0)
+ drm_err(&i915->drm, "Failed to read source OUI\n");
- if (memcmp(oui, buf, sizeof(oui)) == 0) {
- /* Assume the OUI was written now. */
- intel_dp->last_oui_write = jiffies;
- return;
- }
+ if (memcmp(oui, buf, sizeof(oui)) == 0) {
+ /* Assume the OUI was written now. */
+ intel_dp->last_oui_write = jiffies;
+ return;
}
- if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0)
+ if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0) {
drm_info(&i915->drm, "Failed to write source OUI\n");
+ WRITE_ONCE(intel_dp->oui_valid, false);
+ }
intel_dp->last_oui_write = jiffies;
}
+void intel_dp_invalidate_source_oui(struct intel_dp *intel_dp)
+{
+ WRITE_ONCE(intel_dp->oui_valid, false);
+}
+
void intel_dp_wait_source_oui(struct intel_dp *intel_dp)
{
struct intel_connector *connector = intel_dp->attached_connector;
@@ -3466,8 +3479,7 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode)
lspcon_resume(dp_to_dig_port(intel_dp));
/* Write the source OUI as early as possible */
- if (intel_dp_is_edp(intel_dp))
- intel_edp_init_source_oui(intel_dp, false);
+ intel_dp_init_source_oui(intel_dp);
/*
* 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
* If needed, program our source OUI so we can make various Intel-specific AUX services
* available (such as HDR backlight controls)
*/
- intel_edp_init_source_oui(intel_dp, true);
+ intel_dp_init_source_oui(intel_dp);
return true;
}