]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Apr 2022 10:47:17 +0000 (12:47 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Apr 2022 10:47:17 +0000 (12:47 +0200)
added patches:
drm-amd-display-add-pstate-verification-and-recovery-for-dcn31.patch
drm-amd-display-fix-p-state-allow-debug-index-on-dcn31.patch

queue-5.15/drm-amd-display-add-pstate-verification-and-recovery-for-dcn31.patch [new file with mode: 0644]
queue-5.15/drm-amd-display-fix-p-state-allow-debug-index-on-dcn31.patch [new file with mode: 0644]
queue-5.15/series [new file with mode: 0644]

diff --git a/queue-5.15/drm-amd-display-add-pstate-verification-and-recovery-for-dcn31.patch b/queue-5.15/drm-amd-display-add-pstate-verification-and-recovery-for-dcn31.patch
new file mode 100644 (file)
index 0000000..1f3e883
--- /dev/null
@@ -0,0 +1,190 @@
+From e7031d8258f1b4d6d50e5e5b5d92ba16f66eb8b4 Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Fri, 17 Dec 2021 09:55:54 -0500
+Subject: drm/amd/display: Add pstate verification and recovery for DCN31
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+commit e7031d8258f1b4d6d50e5e5b5d92ba16f66eb8b4 upstream.
+
+[Why]
+To debug when p-state is being blocked and avoid PMFW hangs when
+it does occur.
+
+[How]
+Re-use the DCN10 hardware sequencer by adding a new interface for
+verifying p-state high on the hubbub. The interface is mostly the
+same as the DCN10 interface, but the bit definitions have changed for
+the debug bus.
+
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Reviewed-by: Eric Yang <Eric.Yang2@amd.com>
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c       |    1 
+ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c |   10 +-
+ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c       |    1 
+ drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.c     |    1 
+ drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c       |   60 ++++++++++++++
+ drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c     |    2 
+ drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h          |    2 
+ 7 files changed, 73 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
+@@ -940,6 +940,7 @@ static const struct hubbub_funcs hubbub1
+       .program_watermarks = hubbub1_program_watermarks,
+       .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
+       .allow_self_refresh_control = hubbub1_allow_self_refresh_control,
++      .verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
+ };
+ void hubbub1_construct(struct hubbub *hubbub,
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+@@ -1052,9 +1052,13 @@ static bool dcn10_hw_wa_force_recovery(s
+ void dcn10_verify_allow_pstate_change_high(struct dc *dc)
+ {
++      struct hubbub *hubbub = dc->res_pool->hubbub;
+       static bool should_log_hw_state; /* prevent hw state log by default */
+-      if (!hubbub1_verify_allow_pstate_change_high(dc->res_pool->hubbub)) {
++      if (!hubbub->funcs->verify_allow_pstate_change_high)
++              return;
++
++      if (!hubbub->funcs->verify_allow_pstate_change_high(hubbub)) {
+               int i = 0;
+               if (should_log_hw_state)
+@@ -1063,8 +1067,8 @@ void dcn10_verify_allow_pstate_change_hi
+               TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES);
+               BREAK_TO_DEBUGGER();
+               if (dcn10_hw_wa_force_recovery(dc)) {
+-              /*check again*/
+-                      if (!hubbub1_verify_allow_pstate_change_high(dc->res_pool->hubbub))
++                      /*check again*/
++                      if (!hubbub->funcs->verify_allow_pstate_change_high(hubbub))
+                               BREAK_TO_DEBUGGER();
+               }
+       }
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c
+@@ -448,6 +448,7 @@ static const struct hubbub_funcs hubbub3
+       .program_watermarks = hubbub3_program_watermarks,
+       .allow_self_refresh_control = hubbub1_allow_self_refresh_control,
+       .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
++      .verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
+       .force_wm_propagate_to_pipes = hubbub3_force_wm_propagate_to_pipes,
+       .force_pstate_change_control = hubbub3_force_pstate_change_control,
+       .init_watermarks = hubbub3_init_watermarks,
+--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_hubbub.c
+@@ -60,6 +60,7 @@ static const struct hubbub_funcs hubbub3
+       .program_watermarks = hubbub3_program_watermarks,
+       .allow_self_refresh_control = hubbub1_allow_self_refresh_control,
+       .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
++      .verify_allow_pstate_change_high = hubbub1_verify_allow_pstate_change_high,
+       .force_wm_propagate_to_pipes = hubbub3_force_wm_propagate_to_pipes,
+       .force_pstate_change_control = hubbub3_force_pstate_change_control,
+       .hubbub_read_state = hubbub2_read_state,
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c
+@@ -949,6 +949,65 @@ static void hubbub31_get_dchub_ref_freq(
+       }
+ }
++static bool hubbub31_verify_allow_pstate_change_high(struct hubbub *hubbub)
++{
++      struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
++
++      /*
++       * Pstate latency is ~20us so if we wait over 40us and pstate allow
++       * still not asserted, we are probably stuck and going to hang
++       */
++      const unsigned int pstate_wait_timeout_us = 100;
++      const unsigned int pstate_wait_expected_timeout_us = 40;
++
++      static unsigned int max_sampled_pstate_wait_us; /* data collection */
++      static bool forced_pstate_allow; /* help with revert wa */
++
++      unsigned int debug_data = 0;
++      unsigned int i;
++
++      if (forced_pstate_allow) {
++              /* we hacked to force pstate allow to prevent hang last time
++               * we verify_allow_pstate_change_high.  so disable force
++               * here so we can check status
++               */
++              REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
++                           DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
++                           DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0);
++              forced_pstate_allow = false;
++      }
++
++      REG_WRITE(DCHUBBUB_TEST_DEBUG_INDEX, hubbub2->debug_test_index_pstate);
++
++      for (i = 0; i < pstate_wait_timeout_us; i++) {
++              debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
++
++              /* Debug bit is specific to ASIC. */
++              if (debug_data & (1 << 26)) {
++                      if (i > pstate_wait_expected_timeout_us)
++                              DC_LOG_WARNING("pstate took longer than expected ~%dus\n", i);
++                      return true;
++              }
++              if (max_sampled_pstate_wait_us < i)
++                      max_sampled_pstate_wait_us = i;
++
++              udelay(1);
++      }
++
++      /* force pstate allow to prevent system hang
++       * and break to debugger to investigate
++       */
++      REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
++                   DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1,
++                   DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
++      forced_pstate_allow = true;
++
++      DC_LOG_WARNING("pstate TEST_DEBUG_DATA: 0x%X\n",
++                      debug_data);
++
++      return false;
++}
++
+ static const struct hubbub_funcs hubbub31_funcs = {
+       .update_dchub = hubbub2_update_dchub,
+       .init_dchub_sys_ctx = hubbub31_init_dchub_sys_ctx,
+@@ -961,6 +1020,7 @@ static const struct hubbub_funcs hubbub3
+       .program_watermarks = hubbub31_program_watermarks,
+       .allow_self_refresh_control = hubbub1_allow_self_refresh_control,
+       .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
++      .verify_allow_pstate_change_high = hubbub31_verify_allow_pstate_change_high,
+       .program_det_size = dcn31_program_det_size,
+       .program_compbuf_size = dcn31_program_compbuf_size,
+       .init_crb = dcn31_init_crb,
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+@@ -940,7 +940,7 @@ static const struct dc_debug_options deb
+       .max_downscale_src_width = 4096,/*upto true 4K*/
+       .disable_pplib_wm_range = false,
+       .scl_reset_length10 = true,
+-      .sanity_checks = false,
++      .sanity_checks = true,
+       .underflow_assert_delay_us = 0xFFFFFFFF,
+       .dwb_fi_phase = -1, // -1 = disable,
+       .dmub_command_table = true,
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
+@@ -154,6 +154,8 @@ struct hubbub_funcs {
+       bool (*is_allow_self_refresh_enabled)(struct hubbub *hubbub);
+       void (*allow_self_refresh_control)(struct hubbub *hubbub, bool allow);
++      bool (*verify_allow_pstate_change_high)(struct hubbub *hubbub);
++
+       void (*apply_DEDCN21_147_wa)(struct hubbub *hubbub);
+       void (*force_wm_propagate_to_pipes)(struct hubbub *hubbub);
diff --git a/queue-5.15/drm-amd-display-fix-p-state-allow-debug-index-on-dcn31.patch b/queue-5.15/drm-amd-display-fix-p-state-allow-debug-index-on-dcn31.patch
new file mode 100644 (file)
index 0000000..89f1328
--- /dev/null
@@ -0,0 +1,43 @@
+From 3107e1a7ae088ee94323fe9ab05dbefd65b3077f Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Fri, 18 Mar 2022 11:10:34 -0400
+Subject: drm/amd/display: Fix p-state allow debug index on dcn31
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+commit 3107e1a7ae088ee94323fe9ab05dbefd65b3077f upstream.
+
+[Why]
+It changed since dcn30 but the hubbub31 constructor hasn't been
+modified to reflect this.
+
+[How]
+Update the value in the constructor to 0x6 so we're checking the right
+bits for p-state allow.
+
+It worked before by accident, but can falsely assert 0 depending on HW
+state transitions. The most frequent of which appears to be when
+all pipes turn off during IGT tests.
+
+Cc: Harry Wentland <harry.wentland@amd.com>
+
+Fixes: e7031d8258f1b4 ("drm/amd/display: Add pstate verification and recovery for DCN31")
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Reviewed-by: Eric Yang <Eric.Yang2@amd.com>
+Acked-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c
+@@ -1042,5 +1042,7 @@ void hubbub31_construct(struct dcn20_hub
+       hubbub31->detile_buf_size = det_size_kb * 1024;
+       hubbub31->pixel_chunk_size = pixel_chunk_size_kb * 1024;
+       hubbub31->crb_size_segs = config_return_buffer_size_kb / DCN31_CRB_SEGMENT_SIZE_KB;
++
++      hubbub31->debug_test_index_pstate = 0x6;
+ }
diff --git a/queue-5.15/series b/queue-5.15/series
new file mode 100644 (file)
index 0000000..2ff433d
--- /dev/null
@@ -0,0 +1,2 @@
+drm-amd-display-add-pstate-verification-and-recovery-for-dcn31.patch
+drm-amd-display-fix-p-state-allow-debug-index-on-dcn31.patch