diff --git a/patches.kernel.org/6.2.12-003-drm-i915-Workaround-ICL-CSC_MODE-sticky-arming.patch b/patches.kernel.org/6.2.12-003-drm-i915-Workaround-ICL-CSC_MODE-sticky-arming.patch new file mode 100644 index 0000000..1365fb0 --- /dev/null +++ b/patches.kernel.org/6.2.12-003-drm-i915-Workaround-ICL-CSC_MODE-sticky-arming.patch @@ -0,0 +1,123 @@ +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Mon, 20 Mar 2023 11:54:36 +0200 +Subject: [PATCH] drm/i915: Workaround ICL CSC_MODE sticky arming +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +References: bsc#1012628 +Patch-mainline: 6.2.12 +Git-commit: 4d4e766f8b7dbdefa7a78e91eb9c7a29d0d818b8 + +commit 4d4e766f8b7dbdefa7a78e91eb9c7a29d0d818b8 upstream. + +Unlike SKL/GLK the ICL CSC unit suffers from a new issue where +CSC_MODE arming is sticky. That is, once armed it remains armed +causing the CSC coeff/offset registers to become effectively +self-arming. + +CSC coeff/offset registers writes no longer disarm the CSC, +but fortunately register read still do. So we can use that +to disarm the CSC unit once the registers for the current +frame have been latched. This avoid s the self-arming behaviour +from persisting into the next frame's .color_commit_noarm() +call. + +Cc: #v5.19+ +Cc: Manasi Navare +Cc: Drew Davenport +Cc: Imre Deak +Cc: Jouni Högander +Fixes: d13dde449580 ("drm/i915: Split pipe+output CSC programming to noarm+arm pair") +Signed-off-by: Ville Syrjälä +Link: https://patchwork.freedesktop.org/patch/msgid/20230320095438.17328-5-ville.syrjala@linux.intel.com +Reviewed-by: Imre Deak +(cherry picked from commit 92736f1b452bbb8a66bdb5b1d263ad00e04dd3b8) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Jiri Slaby +--- + drivers/gpu/drm/i915/display/intel_color.c | 43 +++++++++++++++++++++- + 1 file changed, 42 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c +index 85a38d79..c9c9af79 100644 +--- a/drivers/gpu/drm/i915/display/intel_color.c ++++ b/drivers/gpu/drm/i915/display/intel_color.c +@@ -516,6 +516,14 @@ static void ilk_lut_12p4_pack(struct drm_color_lut *entry, u32 ldw, u32 udw) + + static void icl_color_commit_noarm(const struct intel_crtc_state *crtc_state) + { ++ /* ++ * Despite Wa_1406463849, ICL no longer suffers from the SKL ++ * DC5/PSR CSC black screen issue (see skl_color_commit_noarm()). ++ * Possibly due to the extra sticky CSC arming ++ * (see icl_color_post_update()). ++ * ++ * On TGL+ all CSC arming issues have been properly fixed. ++ */ + icl_load_csc_matrix(crtc_state); + } + +@@ -617,6 +625,28 @@ static void icl_color_commit_arm(const struct intel_crtc_state *crtc_state) + crtc_state->csc_mode); + } + ++static void icl_color_post_update(const struct intel_crtc_state *crtc_state) ++{ ++ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); ++ struct drm_i915_private *i915 = to_i915(crtc->base.dev); ++ ++ /* ++ * Despite Wa_1406463849, ICL CSC is no longer disarmed by ++ * coeff/offset register *writes*. Instead, once CSC_MODE ++ * is armed it stays armed, even after it has been latched. ++ * Afterwards the coeff/offset registers become effectively ++ * self-arming. That self-arming must be disabled before the ++ * next icl_color_commit_noarm() tries to write the next set ++ * of coeff/offset registers. Fortunately register *reads* ++ * do still disarm the CSC. Naturally this must not be done ++ * until the previously written CSC registers have actually ++ * been latched. ++ * ++ * TGL+ no longer need this workaround. ++ */ ++ intel_de_read_fw(i915, PIPE_CSC_PREOFF_HI(crtc->pipe)); ++} ++ + static struct drm_property_blob * + create_linear_lut(struct drm_i915_private *i915, int lut_size) + { +@@ -2345,10 +2375,19 @@ static const struct intel_color_funcs i9xx_color_funcs = { + .read_luts = i9xx_read_luts, + }; + ++static const struct intel_color_funcs tgl_color_funcs = { ++ .color_check = icl_color_check, ++ .color_commit_noarm = icl_color_commit_noarm, ++ .color_commit_arm = icl_color_commit_arm, ++ .load_luts = icl_load_luts, ++ .read_luts = icl_read_luts, ++}; ++ + static const struct intel_color_funcs icl_color_funcs = { + .color_check = icl_color_check, + .color_commit_noarm = icl_color_commit_noarm, + .color_commit_arm = icl_color_commit_arm, ++ .color_post_update = icl_color_post_update, + .load_luts = icl_load_luts, + .read_luts = icl_read_luts, + }; +@@ -2440,7 +2479,9 @@ void intel_color_init_hooks(struct drm_i915_private *i915) + else + i915->display.funcs.color = &i9xx_color_funcs; + } else { +- if (DISPLAY_VER(i915) >= 11) ++ if (DISPLAY_VER(i915) >= 12) ++ i915->display.funcs.color = &tgl_color_funcs; ++ else if (DISPLAY_VER(i915) == 11) + i915->display.funcs.color = &icl_color_funcs; + else if (DISPLAY_VER(i915) == 10) + i915->display.funcs.color = &glk_color_funcs; +-- +2.35.3 + diff --git a/series.conf b/series.conf index 81b6edb..2bc47b1 100644 --- a/series.conf +++ b/series.conf @@ -2230,6 +2230,7 @@ patches.kernel.org/6.2.11-174-Linux-6.2.11.patch patches.kernel.org/6.2.12-001-Revert-pinctrl-amd-Disable-and-mask-interrupts.patch patches.kernel.org/6.2.12-002-drm-amd-display-Pass-the-right-info-to-drm_dp_.patch + patches.kernel.org/6.2.12-003-drm-i915-Workaround-ICL-CSC_MODE-sticky-arming.patch ######################################################## # Build fixes that apply to the vanilla kernel too.