diff options
author | Ville Syrjälä <[email protected]> | 2021-02-16 18:00:35 +0200 |
---|---|---|
committer | Ville Syrjälä <[email protected]> | 2021-03-03 14:21:52 +0200 |
commit | 899f9d7bbc01bacefe3b124d4655678ad299177d (patch) | |
tree | 0c9008434b1f8f8c087f87be18a6e9a952140acd | |
parent | cec3295b246b5555f6de7570d25a13a2754de245 (diff) |
drm/i915: Readout conn_state->max_bpc
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 <[email protected]>
Reported-by: Chris Wilson <[email protected]>
Signed-off-by: Ville Syrjälä <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
Tested-by: Chris Wilson <[email protected]>
Reviewed-by: José Roberto de Souza <[email protected]>
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_display.c | 24 |
1 files 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 e1060076ac83..d7151a934e4c 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); |