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

Reply via email to