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
  • Loading branch information
Imre Deak committed Mar 5, 2024
1 parent a0d1cf4 commit a62e145
Show file tree
Hide file tree
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
Expand Up @@ -613,6 +613,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;

Expand Down
13 changes: 13 additions & 0 deletions drivers/gpu/drm/i915/display/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5942,6 +5942,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));
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/display/intel_dp.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
const struct intel_crtc_state *crtc_state);
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,
Expand Down
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
Expand Up @@ -1554,6 +1554,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);
Expand Down
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
Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
Expand All @@ -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,
Expand Down

0 comments on commit a62e145

Please sign in to comment.