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>
  • Loading branch information
Imre Deak authored and Joonas Lahtinen committed Mar 6, 2024
1 parent 26d2b75 commit 0848814
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 @@ -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;

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 @@ -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));
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 @@ -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,
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 @@ -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);
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 0848814

Please sign in to comment.