From 899f9d7bbc01bacefe3b124d4655678ad299177d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 16 Feb 2021 18:00:35 +0200 Subject: [PATCH] drm/i915: Readout conn_state->max_bpc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Populate conn_state->max_bpc with something sensible from the start. Otherwise it's possible that we get to compute_sink_pipe_bpp() with max_bpc==0. The specific scenario goes as follows: 1. Initial connector state allocated with max_bpc==0 2. Trigger a modeset on the crtc feeding the connector, without actually adding the connector to the commit 3. drm_atomic_connector_check() is skipped because the connector has not yet been added, hence conn_state->max_bpc retains its current value 4. drm_atomic_helper_check_modeset() -> drm_atomic_add_affected_connectors() -> the connector is now part of the commit 5. compute_baseline_pipe_bpp() -> MISSING_CASE(max_bpc==0) Note that pipe_bpp itself may not be populated on pre-g4x machines, in which case we just fall back to max_bpc==8 and let .compute_config() limit the resulting pipe_bpp further if necessary. Cc: Daniel Vetter Reported-by: Chris Wilson Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210216160035.4780-1-ville.syrjala@linux.intel.com Tested-by: Chris Wilson Reviewed-by: José Roberto de Souza --- drivers/gpu/drm/i915/display/intel_display.c | 24 +++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e1060076ac83f..d7151a934e4cf 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7991,19 +7991,27 @@ static void intel_modeset_update_connector_atomic_state(struct drm_device *dev) drm_connector_list_iter_begin(dev, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { - if (connector->base.state->crtc) + struct drm_connector_state *conn_state = connector->base.state; + struct intel_encoder *encoder = + to_intel_encoder(connector->base.encoder); + + if (conn_state->crtc) drm_connector_put(&connector->base); - if (connector->base.encoder) { - connector->base.state->best_encoder = - connector->base.encoder; - connector->base.state->crtc = - connector->base.encoder->crtc; + if (encoder) { + struct intel_crtc *crtc = + to_intel_crtc(encoder->base.crtc); + const struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->base.state); + + conn_state->best_encoder = &encoder->base; + conn_state->crtc = &crtc->base; + conn_state->max_bpc = (crtc_state->pipe_bpp ?: 24) / 3; drm_connector_get(&connector->base); } else { - connector->base.state->best_encoder = NULL; - connector->base.state->crtc = NULL; + conn_state->best_encoder = NULL; + conn_state->crtc = NULL; } } drm_connector_list_iter_end(&conn_iter);