aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1163-drm-amd-display-Enable-vblank-interrupt-during-CRC-c.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1163-drm-amd-display-Enable-vblank-interrupt-during-CRC-c.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/1163-drm-amd-display-Enable-vblank-interrupt-during-CRC-c.patch131
1 files changed, 131 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1163-drm-amd-display-Enable-vblank-interrupt-during-CRC-c.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1163-drm-amd-display-Enable-vblank-interrupt-during-CRC-c.patch
new file mode 100644
index 00000000..a46f100e
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1163-drm-amd-display-Enable-vblank-interrupt-during-CRC-c.patch
@@ -0,0 +1,131 @@
+From 6a2d1c9abb981fbeddb1fac7b997eea420f89857 Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Mon, 14 Jan 2019 16:04:10 -0500
+Subject: [PATCH 1163/2940] drm/amd/display: Enable vblank interrupt during CRC
+ capture
+
+[Why]
+In order to read CRC events when CRC capture is enabled the vblank
+interrput handler needs to be running for the CRTC. The handler is
+enabled while there is an active vblank reference.
+
+When running IGT tests there will often be no active vblank reference
+but the test expects to read a CRC value. This is valid usage (and
+works on i915 since they have a CRC interrupt handler) so the reference
+to the vblank should be grabbed while capture is active.
+
+This issue was found running:
+
+igt@kms_plane_multiple@atomic-pipe-b-tiling-none
+
+The pipe-b is the only one in the initial commit and was not previously
+active so no vblank reference is grabbed. The vblank interrupt is
+not enabled and the test times out.
+
+[How]
+Keep a reference to the vblank as long as CRC capture is enabled.
+If userspace never explicitly disables it then the reference is
+also dropped when removing the CRTC from the context (stream = NULL).
+
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
+Reviewed-by: Sun peng Li <Sunpeng.Li@amd.com>
+Acked-by: Leo Li <sunpeng.li@amd.com>
+Signed-off-by: Chaudhary Amit Kumar <Chaudharyamit.Kumar@amd.com>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 ++++++-
+ .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 42 +++++++++----------
+ 2 files changed, 34 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index f3ca446eb66d..f70d38361028 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -5047,10 +5047,22 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev,
+ */
+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ struct dm_crtc_state *dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
++ struct dm_crtc_state *dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
+
+- if (drm_atomic_crtc_needs_modeset(new_crtc_state) && dm_old_crtc_state->stream)
++ if (drm_atomic_crtc_needs_modeset(new_crtc_state)
++ && dm_old_crtc_state->stream) {
++ /*
++ * CRC capture was enabled but not disabled.
++ * Release the vblank reference.
++ */
++ if (dm_new_crtc_state->crc_enabled) {
++ drm_crtc_vblank_put(crtc);
++ dm_new_crtc_state->crc_enabled = false;
++ }
++
+ manage_dm_interrupts(adev, acrtc, false);
++ }
+ }
+ /* Add check here for SoC's that support hardware cursor plane, to
+ * unset legacy_cursor_update */
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
+index 09f813b726bd..993a83ecde64 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
+@@ -67,6 +67,7 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
+ struct amdgpu_device *adev = crtc->dev->dev_private;
+ struct dm_crtc_state *crtc_state = to_dm_crtc_state(crtc->state);
+ struct dc_stream_state *stream_state = crtc_state->stream;
++ bool enable;
+
+ enum amdgpu_dm_pipe_crc_source source = dm_parse_crc_source(src_name);
+
+@@ -81,28 +82,27 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
+ return -EINVAL;
+ }
+
++ enable = (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO);
++
++ if (!dc_stream_configure_crc(stream_state->ctx->dc, stream_state,
++ enable, enable))
++ return -EINVAL;
++
+ /* When enabling CRC, we should also disable dithering. */
+- if (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO) {
+- if (dc_stream_configure_crc(stream_state->ctx->dc,
+- stream_state,
+- true, true)) {
+- crtc_state->crc_enabled = true;
+- dc_stream_set_dither_option(stream_state,
+- DITHER_OPTION_TRUN8);
+- }
+- else
+- return -EINVAL;
+- } else {
+- if (dc_stream_configure_crc(stream_state->ctx->dc,
+- stream_state,
+- false, false)) {
+- crtc_state->crc_enabled = false;
+- dc_stream_set_dither_option(stream_state,
+- DITHER_OPTION_DEFAULT);
+- }
+- else
+- return -EINVAL;
+- }
++ dc_stream_set_dither_option(stream_state,
++ enable ? DITHER_OPTION_TRUN8
++ : DITHER_OPTION_DEFAULT);
++
++ /*
++ * Reading the CRC requires the vblank interrupt handler to be
++ * enabled. Keep a reference until CRC capture stops.
++ */
++ if (!crtc_state->crc_enabled && enable)
++ drm_crtc_vblank_get(crtc);
++ else if (crtc_state->crc_enabled && !enable)
++ drm_crtc_vblank_put(crtc);
++
++ crtc_state->crc_enabled = enable;
+
+ /* Reset crc_skipped on dm state */
+ crtc_state->crc_skip_count = 0;
+--
+2.17.1
+