Skip to content

Commit

Permalink
drm/i915/dp: Fix connector DSC HW state readout
Browse files Browse the repository at this point in the history
The DSC HW state of DP connectors is read out during driver loading and
system resume in intel_modeset_update_connector_atomic_state(). This
function is called for all connectors though and so the state of DSI
connectors will also get updated incorrectly, triggering a WARN there
wrt. the DSC decompression AUX device.

Fix the above by moving the DSC state readout to a new DP connector
specific sync_state() hook. This is anyway the logical place to update
the connector object's state vs. the connector's atomic state.

Fixes: b2608c6 ("drm/i915/dp_mst: Enable MST DSC decompression for all streams")
Reported-and-tested-by: Drew Davenport <ddavenport@chromium.org>
Closes: https://lore.kernel.org/all/Zb0q8IDVXS0HxJyj@chromium.org
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240205132631.1588577-1-imre.deak@intel.com
(cherry picked from commit a62e145)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Imre Deak authored and Joonas Lahtinen committed Mar 6, 2024
1 parent 26d2b75 commit 0848814
Showing 5 changed files with 29 additions and 7 deletions.
7 changes: 7 additions & 0 deletions drivers/gpu/drm/i915/display/intel_display_types.h
Original file line number Diff line number Diff line change
@@ -609,6 +609,13 @@ struct intel_connector {
* and active (i.e. dpms ON state). */
bool (*get_hw_state)(struct intel_connector *);

/*
* Optional hook called during init/resume to sync any state
* stored in the connector (eg. DSC state) wrt. the HW state.
*/
void (*sync_state)(struct intel_connector *connector,
const struct intel_crtc_state *crtc_state);

/* Panel info for eDP and LVDS */
struct intel_panel panel;

13 changes: 13 additions & 0 deletions drivers/gpu/drm/i915/display/intel_dp.c
Original file line number Diff line number Diff line change
@@ -5859,6 +5859,19 @@ intel_dp_connector_unregister(struct drm_connector *connector)
intel_connector_unregister(connector);
}

void intel_dp_connector_sync_state(struct intel_connector *connector,
const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);

if (crtc_state && crtc_state->dsc.compression_enable) {
drm_WARN_ON(&i915->drm, !connector->dp.dsc_decompression_aux);
connector->dp.dsc_decompression_enabled = true;
} else {
connector->dp.dsc_decompression_enabled = false;
}
}

void intel_dp_encoder_flush_work(struct drm_encoder *encoder)
{
struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder));
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/display/intel_dp.h
Original file line number Diff line number Diff line change
@@ -45,6 +45,8 @@ bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state,
int intel_dp_min_bpp(enum intel_output_format output_format);
bool intel_dp_init_connector(struct intel_digital_port *dig_port,
struct intel_connector *intel_connector);
void intel_dp_connector_sync_state(struct intel_connector *connector,
const struct intel_crtc_state *crtc_state);
void intel_dp_set_link_params(struct intel_dp *intel_dp,
int link_rate, int lane_count);
int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/display/intel_dp_mst.c
Original file line number Diff line number Diff line change
@@ -1534,6 +1534,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
return NULL;

intel_connector->get_hw_state = intel_dp_mst_get_hw_state;
intel_connector->sync_state = intel_dp_connector_sync_state;
intel_connector->mst_port = intel_dp;
intel_connector->port = port;
drm_dp_mst_get_port_malloc(port);
13 changes: 6 additions & 7 deletions drivers/gpu/drm/i915/display/intel_modeset_setup.c
Original file line number Diff line number Diff line change
@@ -318,12 +318,6 @@ static void intel_modeset_update_connector_atomic_state(struct drm_i915_private
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);

if (crtc_state->dsc.compression_enable) {
drm_WARN_ON(&i915->drm, !connector->dp.dsc_decompression_aux);
connector->dp.dsc_decompression_enabled = true;
} else {
connector->dp.dsc_decompression_enabled = false;
}
conn_state->max_bpc = (crtc_state->pipe_bpp ?: 24) / 3;
}
}
@@ -775,8 +769,9 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)

drm_connector_list_iter_begin(&i915->drm, &conn_iter);
for_each_intel_connector_iter(connector, &conn_iter) {
struct intel_crtc_state *crtc_state = NULL;

if (connector->get_hw_state(connector)) {
struct intel_crtc_state *crtc_state;
struct intel_crtc *crtc;

connector->base.dpms = DRM_MODE_DPMS_ON;
@@ -802,6 +797,10 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
connector->base.dpms = DRM_MODE_DPMS_OFF;
connector->base.encoder = NULL;
}

if (connector->sync_state)
connector->sync_state(connector, crtc_state);

drm_dbg_kms(&i915->drm,
"[CONNECTOR:%d:%s] hw state readout: %s\n",
connector->base.base.id, connector->base.name,

0 comments on commit 0848814

Please sign in to comment.