Skip to content

Commit

Permalink
drm/i915/display: Disable audio, DRRS and PSR before planes
Browse files Browse the repository at this point in the history
HDMI and DisplayPort sequences states that audio and PSR should be
disabled before planes are disabled.
Not following it did not caused any problems up to Alderlake-P but
for this platform it causes underruns during the PSR2 disable
sequence.

Specification don't mention that DRRS should be disabled before planes
but it looks safer to switch back to the default refresh rate before
following with the rest of the pipe disable sequence.

BSpec: 49191
BSpec: 49190
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210726181559.80855-1-jose.souza@intel.com
  • Loading branch information
José Roberto de Souza committed Jul 27, 2021
1 parent 192fbfb commit 84030ad
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 13 deletions.
30 changes: 20 additions & 10 deletions drivers/gpu/drm/i915/display/intel_ddi.c
Original file line number Diff line number Diff line change
Expand Up @@ -3204,12 +3204,6 @@ static void intel_disable_ddi_dp(struct intel_atomic_state *state,

intel_dp->link_trained = false;

if (old_crtc_state->has_audio)
intel_audio_codec_disable(encoder,
old_crtc_state, old_conn_state);

intel_edp_drrs_disable(intel_dp, old_crtc_state);
intel_psr_disable(intel_dp, old_crtc_state);
intel_edp_backlight_off(old_conn_state);
/* Disable the decompression in DP Sink */
intel_dp_sink_set_decompression_state(intel_dp, old_crtc_state,
Expand All @@ -3227,17 +3221,32 @@ static void intel_disable_ddi_hdmi(struct intel_atomic_state *state,
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct drm_connector *connector = old_conn_state->connector;

if (old_crtc_state->has_audio)
intel_audio_codec_disable(encoder,
old_crtc_state, old_conn_state);

if (!intel_hdmi_handle_sink_scrambling(encoder, connector,
false, false))
drm_dbg_kms(&i915->drm,
"[CONNECTOR:%d:%s] Failed to reset sink scrambling/TMDS bit clock ratio\n",
connector->base.id, connector->name);
}

static void intel_pre_disable_ddi(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state,
const struct drm_connector_state *old_conn_state)
{
struct intel_dp *intel_dp;

if (old_crtc_state->has_audio)
intel_audio_codec_disable(encoder, old_crtc_state,
old_conn_state);

if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
return;

intel_dp = enc_to_intel_dp(encoder);
intel_edp_drrs_disable(intel_dp, old_crtc_state);
intel_psr_disable(intel_dp, old_crtc_state);
}

static void intel_disable_ddi(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state,
Expand Down Expand Up @@ -4590,6 +4599,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->enable = intel_enable_ddi;
encoder->pre_pll_enable = intel_ddi_pre_pll_enable;
encoder->pre_enable = intel_ddi_pre_enable;
encoder->pre_disable = intel_pre_disable_ddi;
encoder->disable = intel_disable_ddi;
encoder->post_disable = intel_ddi_post_disable;
encoder->update_pipe = intel_ddi_update_pipe;
Expand Down
24 changes: 24 additions & 0 deletions drivers/gpu/drm/i915/display/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -3192,6 +3192,28 @@ static void intel_encoders_enable(struct intel_atomic_state *state,
}
}

static void intel_encoders_pre_disable(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
const struct drm_connector_state *old_conn_state;
struct drm_connector *conn;
int i;

for_each_old_connector_in_state(&state->base, conn, old_conn_state, i) {
struct intel_encoder *encoder =
to_intel_encoder(old_conn_state->best_encoder);

if (old_conn_state->crtc != &crtc->base)
continue;

if (encoder->pre_disable)
encoder->pre_disable(state, encoder, old_crtc_state,
old_conn_state);
}
}

static void intel_encoders_disable(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
Expand Down Expand Up @@ -10324,6 +10346,8 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,

drm_WARN_ON(&dev_priv->drm, old_crtc_state->bigjoiner_slave);

intel_encoders_pre_disable(state, crtc);

intel_crtc_disable_planes(state, crtc);

/*
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/i915/display/intel_display_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ struct intel_encoder {
void (*update_complete)(struct intel_atomic_state *,
struct intel_encoder *,
struct intel_crtc *);
void (*pre_disable)(struct intel_atomic_state *,
struct intel_encoder *,
const struct intel_crtc_state *,
const struct drm_connector_state *);
void (*disable)(struct intel_atomic_state *,
struct intel_encoder *,
const struct intel_crtc_state *,
Expand Down
14 changes: 11 additions & 3 deletions drivers/gpu/drm/i915/display/intel_dp_mst.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,16 @@ static void wait_for_act_sent(struct intel_encoder *encoder,
drm_dp_check_act_status(&intel_dp->mst_mgr);
}

static void intel_mst_pre_disable_dp(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state,
const struct drm_connector_state *old_conn_state)
{
if (old_crtc_state->has_audio)
intel_audio_codec_disable(encoder, old_crtc_state,
old_conn_state);
}

static void intel_mst_disable_dp(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state,
Expand All @@ -372,9 +382,6 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
if (ret) {
drm_dbg_kms(&i915->drm, "failed to update payload %d\n", ret);
}
if (old_crtc_state->has_audio)
intel_audio_codec_disable(encoder,
old_crtc_state, old_conn_state);
}

static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
Expand Down Expand Up @@ -903,6 +910,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe

intel_encoder->compute_config = intel_dp_mst_compute_config;
intel_encoder->compute_config_late = intel_dp_mst_compute_config_late;
intel_encoder->pre_disable = intel_mst_pre_disable_dp;
intel_encoder->disable = intel_mst_disable_dp;
intel_encoder->post_disable = intel_mst_post_disable_dp;
intel_encoder->update_pipe = intel_ddi_update_pipe;
Expand Down

0 comments on commit 84030ad

Please sign in to comment.