From: Rodrigo Siqueira <[email protected]> When running the kms_writeback subtest writeback-check-output-XBGR2101010, this test always fails due to a CRC mismatch. For some reason, the test writeback-check-output-XBGR8888 was not failing, which triggered suspicion that something in the format manipulation during writeback might be wrong. When looking at how Intel handles the bpc, it checks the information from the EDID, and if there is no info about that (this is what happens in the writeback case), it sets the bpc to 8 (or 24 bpp) by default which would explains why the XBGR8888 test pass. On the other hand, 24bpp would not work for XBGR2101010, which requires 30bpp. With this idea in mind, this commit ensured that depths greater than 24 get 30 bpp in the writeback sequence.
Notice that to ensure the BPP gets updated, we must update the mode when there is a difference between what was requested and what is configured. We also have to consider the fastset path. Finally, to ensure any other part does not override this configuration, this commit added a callback implementation for compute_config_late. Signed-off-by: Rodrigo Siqueira <[email protected]> --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- .../gpu/drm/i915/display/intel_writeback.c | 25 ++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 35ca757c76e6..bc52eb0b2473 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5483,7 +5483,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_X(dsi_pll.div); if ((display->platform.g4x || DISPLAY_VER(display) >= 5) && - !is_writeback) + (!is_writeback || fastset)) PIPE_CONF_CHECK_I(pipe_bpp); if ((!fastset || !pipe_config->update_m_n) && !is_writeback) { diff --git a/drivers/gpu/drm/i915/display/intel_writeback.c b/drivers/gpu/drm/i915/display/intel_writeback.c index 064c6ff5bc73..9808ee2092ef 100644 --- a/drivers/gpu/drm/i915/display/intel_writeback.c +++ b/drivers/gpu/drm/i915/display/intel_writeback.c @@ -207,7 +207,7 @@ static int intel_writeback_atomic_check(struct drm_connector *connector, drm_atomic_get_new_connector_state(state, connector); struct drm_crtc_state *crtc_state; struct drm_framebuffer *fb; - int ret; + int ret, fb_bpp, intel_pipe_bpp; /* We return 0 since this is called while disabling writeback encoder */ if (!conn_state->crtc) @@ -233,6 +233,13 @@ static int intel_writeback_atomic_check(struct drm_connector *connector, return ret; } + // If the required bpc is different from the current one, we need to + // force an update + intel_pipe_bpp = to_intel_crtc_state(crtc_state)->pipe_bpp; + fb_bpp = fb->format->depth > 24 ? 30 : 24; + if (intel_pipe_bpp != fb_bpp) + crtc_state->mode_changed = true; + return 0; } @@ -475,6 +482,21 @@ intel_writeback_compute_config(struct intel_encoder *encoder, return 0; } +static int intel_writeback_compute_config_late(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state) +{ + if (!conn_state->writeback_job) + return 0; + + if (conn_state->writeback_job->fb->format->depth > 24) + pipe_config->pipe_bpp = 30; + else + pipe_config->pipe_bpp = 24; + + return 0; +} + static void intel_writeback_get_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) @@ -612,6 +634,7 @@ int intel_writeback_init(struct intel_display *display) encoder->get_config = intel_writeback_get_config; encoder->get_hw_state = intel_writeback_get_hw_state; encoder->compute_config = intel_writeback_compute_config; + encoder->compute_config_late = intel_writeback_compute_config_late; encoder->enable = intel_writeback_enable_encoder; encoder->disable = intel_writeback_disable_encoder; -- 2.43.0
