]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.7
authorSasha Levin <sashal@kernel.org>
Mon, 29 Jan 2024 00:17:57 +0000 (19:17 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 29 Jan 2024 00:17:57 +0000 (19:17 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
27 files changed:
queue-6.7/btrfs-zoned-factor-out-prepare_allocation_zoned.patch [new file with mode: 0644]
queue-6.7/btrfs-zoned-optimize-hint-byte-for-zoned-allocator.patch [new file with mode: 0644]
queue-6.7/drm-amd-display-add-logging-resource-checks.patch [new file with mode: 0644]
queue-6.7/drm-amd-display-clear-optc-mem-select-on-disable.patch [new file with mode: 0644]
queue-6.7/drm-amd-display-disconnect-phantom-pipe-opp-from-opt.patch [new file with mode: 0644]
queue-6.7/drm-amd-display-do-not-send-commands-to-dmub-if-dmub.patch [new file with mode: 0644]
queue-6.7/drm-amd-display-fix-conversions-between-bytes-and-kb.patch [new file with mode: 0644]
queue-6.7/drm-amd-display-fix-hang-underflow-when-transitionin.patch [new file with mode: 0644]
queue-6.7/drm-amd-display-init-link-enc-resources-in-dc_state-.patch [new file with mode: 0644]
queue-6.7/drm-amd-display-refactor-dmcub-enter-exit-idle-inter.patch [new file with mode: 0644]
queue-6.7/drm-amd-display-update-pixel-clock-params-after-stre.patch [new file with mode: 0644]
queue-6.7/drm-amd-display-wake-dmcub-before-executing-gpint-co.patch [new file with mode: 0644]
queue-6.7/drm-amd-display-wake-dmcub-before-sending-a-command.patch [new file with mode: 0644]
queue-6.7/drm-amdgpu-enable-tunneling-on-high-priority-compute.patch [new file with mode: 0644]
queue-6.7/drm-amdgpu-gfx10-set-unord_dispatch-in-compute-mqds.patch [new file with mode: 0644]
queue-6.7/drm-amdgpu-gfx11-set-unord_dispatch-in-compute-mqds.patch [new file with mode: 0644]
queue-6.7/drm-panel-edp-add-auo-b116xtn02-boe-nt116whm-n21-836.patch [new file with mode: 0644]
queue-6.7/drm-panel-edp-drm-panel-edp-fix-auo-b116xak01-name-a.patch [new file with mode: 0644]
queue-6.7/drm-panel-edp-drm-panel-edp-fix-auo-b116xtn02-name.patch [new file with mode: 0644]
queue-6.7/media-i2c-imx290-properly-encode-registers-as-little.patch [new file with mode: 0644]
queue-6.7/media-v4l-cci-add-macros-to-obtain-register-width-an.patch [new file with mode: 0644]
queue-6.7/media-v4l-cci-include-linux-bits.h.patch [new file with mode: 0644]
queue-6.7/media-v4l2-cci-add-support-for-little-endian-encoded.patch [new file with mode: 0644]
queue-6.7/series
queue-6.7/thermal-intel-hfi-add-syscore-callbacks-for-system-w.patch [new file with mode: 0644]
queue-6.7/thermal-intel-hfi-disable-an-hfi-instance-when-all-i.patch [new file with mode: 0644]
queue-6.7/thermal-intel-hfi-refactor-enabling-code-into-helper.patch [new file with mode: 0644]

diff --git a/queue-6.7/btrfs-zoned-factor-out-prepare_allocation_zoned.patch b/queue-6.7/btrfs-zoned-factor-out-prepare_allocation_zoned.patch
new file mode 100644 (file)
index 0000000..9585f08
--- /dev/null
@@ -0,0 +1,75 @@
+From a317a45f938cea69bcf7dcac8eca6a09058d63cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Dec 2023 01:02:28 +0900
+Subject: btrfs: zoned: factor out prepare_allocation_zoned()
+
+From: Naohiro Aota <naohiro.aota@wdc.com>
+
+[ Upstream commit b271fee9a41ca1474d30639fd6cc912c9901d0f8 ]
+
+Factor out prepare_allocation_zoned() for further extension. While at
+it, optimize the if-branch a bit.
+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 02444f2ac26e ("btrfs: zoned: optimize hint byte for zoned allocator")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/extent-tree.c | 32 +++++++++++++++++++-------------
+ 1 file changed, 19 insertions(+), 13 deletions(-)
+
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 9c8b00a917bd..9307891b4a85 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -4301,6 +4301,24 @@ static int prepare_allocation_clustered(struct btrfs_fs_info *fs_info,
+       return 0;
+ }
++static int prepare_allocation_zoned(struct btrfs_fs_info *fs_info,
++                                  struct find_free_extent_ctl *ffe_ctl)
++{
++      if (ffe_ctl->for_treelog) {
++              spin_lock(&fs_info->treelog_bg_lock);
++              if (fs_info->treelog_bg)
++                      ffe_ctl->hint_byte = fs_info->treelog_bg;
++              spin_unlock(&fs_info->treelog_bg_lock);
++      } else if (ffe_ctl->for_data_reloc) {
++              spin_lock(&fs_info->relocation_bg_lock);
++              if (fs_info->data_reloc_bg)
++                      ffe_ctl->hint_byte = fs_info->data_reloc_bg;
++              spin_unlock(&fs_info->relocation_bg_lock);
++      }
++
++      return 0;
++}
++
+ static int prepare_allocation(struct btrfs_fs_info *fs_info,
+                             struct find_free_extent_ctl *ffe_ctl,
+                             struct btrfs_space_info *space_info,
+@@ -4311,19 +4329,7 @@ static int prepare_allocation(struct btrfs_fs_info *fs_info,
+               return prepare_allocation_clustered(fs_info, ffe_ctl,
+                                                   space_info, ins);
+       case BTRFS_EXTENT_ALLOC_ZONED:
+-              if (ffe_ctl->for_treelog) {
+-                      spin_lock(&fs_info->treelog_bg_lock);
+-                      if (fs_info->treelog_bg)
+-                              ffe_ctl->hint_byte = fs_info->treelog_bg;
+-                      spin_unlock(&fs_info->treelog_bg_lock);
+-              }
+-              if (ffe_ctl->for_data_reloc) {
+-                      spin_lock(&fs_info->relocation_bg_lock);
+-                      if (fs_info->data_reloc_bg)
+-                              ffe_ctl->hint_byte = fs_info->data_reloc_bg;
+-                      spin_unlock(&fs_info->relocation_bg_lock);
+-              }
+-              return 0;
++              return prepare_allocation_zoned(fs_info, ffe_ctl);
+       default:
+               BUG();
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.7/btrfs-zoned-optimize-hint-byte-for-zoned-allocator.patch b/queue-6.7/btrfs-zoned-optimize-hint-byte-for-zoned-allocator.patch
new file mode 100644 (file)
index 0000000..a167097
--- /dev/null
@@ -0,0 +1,63 @@
+From 1f1a0d7981c1ff0b900725a9b72082d2469358e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Dec 2023 01:02:29 +0900
+Subject: btrfs: zoned: optimize hint byte for zoned allocator
+
+From: Naohiro Aota <naohiro.aota@wdc.com>
+
+[ Upstream commit 02444f2ac26eae6385a65fcd66915084d15dffba ]
+
+Writing sequentially to a huge file on btrfs on a SMR HDD revealed a
+decline of the performance (220 MiB/s to 30 MiB/s after 500 minutes).
+
+The performance goes down because of increased latency of the extent
+allocation, which is induced by a traversing of a lot of full block groups.
+
+So, this patch optimizes the ffe_ctl->hint_byte by choosing a block group
+with sufficient size from the active block group list, which does not
+contain full block groups.
+
+After applying the patch, the performance is maintained well.
+
+Fixes: 2eda57089ea3 ("btrfs: zoned: implement sequential extent allocation")
+CC: stable@vger.kernel.org # 5.15+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/extent-tree.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 9307891b4a85..31d64812bb60 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -4314,6 +4314,24 @@ static int prepare_allocation_zoned(struct btrfs_fs_info *fs_info,
+               if (fs_info->data_reloc_bg)
+                       ffe_ctl->hint_byte = fs_info->data_reloc_bg;
+               spin_unlock(&fs_info->relocation_bg_lock);
++      } else if (ffe_ctl->flags & BTRFS_BLOCK_GROUP_DATA) {
++              struct btrfs_block_group *block_group;
++
++              spin_lock(&fs_info->zone_active_bgs_lock);
++              list_for_each_entry(block_group, &fs_info->zone_active_bgs, active_bg_list) {
++                      /*
++                       * No lock is OK here because avail is monotinically
++                       * decreasing, and this is just a hint.
++                       */
++                      u64 avail = block_group->zone_capacity - block_group->alloc_offset;
++
++                      if (block_group_bits(block_group, ffe_ctl->flags) &&
++                          avail >= ffe_ctl->num_bytes) {
++                              ffe_ctl->hint_byte = block_group->start;
++                              break;
++                      }
++              }
++              spin_unlock(&fs_info->zone_active_bgs_lock);
+       }
+       return 0;
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amd-display-add-logging-resource-checks.patch b/queue-6.7/drm-amd-display-add-logging-resource-checks.patch
new file mode 100644 (file)
index 0000000..429bf7b
--- /dev/null
@@ -0,0 +1,76 @@
+From c5c83cba01f9edd822739b084a53a8744d777b9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Dec 2023 13:19:33 -0500
+Subject: drm/amd/display: Add logging resource checks
+
+From: Charlene Liu <charlene.liu@amd.com>
+
+[ Upstream commit 8a51cc097dd590a86e8eec5398934ef389ff9a7b ]
+
+[Why]
+When mapping resources, resources could be unavailable.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Sung joon Kim <sungjoon.kim@amd.com>
+Acked-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Charlene Liu <charlene.liu@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c          | 4 +++-
+ drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 7 ++++++-
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index c535ddb45a36..bc098098345c 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -3626,7 +3626,7 @@ static void commit_planes_for_stream(struct dc *dc,
+       top_pipe_to_program = resource_get_otg_master_for_stream(
+                               &context->res_ctx,
+                               stream);
+-
++      ASSERT(top_pipe_to_program != NULL);
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+@@ -4457,6 +4457,8 @@ static bool should_commit_minimal_transition_for_windowed_mpo_odm(struct dc *dc,
+       cur_pipe = resource_get_otg_master_for_stream(&dc->current_state->res_ctx, stream);
+       new_pipe = resource_get_otg_master_for_stream(&context->res_ctx, stream);
++      if (!cur_pipe || !new_pipe)
++              return false;
+       cur_is_odm_in_use = resource_get_odm_slice_count(cur_pipe) > 1;
+       new_is_odm_in_use = resource_get_odm_slice_count(new_pipe) > 1;
+       if (cur_is_odm_in_use == new_is_odm_in_use)
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+index e4bb1e25ee3b..ae275f1780d5 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+@@ -2170,6 +2170,10 @@ void resource_log_pipe_topology_update(struct dc *dc, struct dc_state *state)
+       for (stream_idx = 0; stream_idx < state->stream_count; stream_idx++) {
+               otg_master = resource_get_otg_master_for_stream(
+                               &state->res_ctx, state->streams[stream_idx]);
++              if (!otg_master || otg_master->stream_res.tg == NULL) {
++                      DC_LOG_DC("topology update: otg_master NULL stream_idx %d!\n", stream_idx);
++                      return;
++              }
+               slice_count = resource_get_opp_heads_for_otg_master(otg_master,
+                               &state->res_ctx, opp_heads);
+               for (slice_idx = 0; slice_idx < slice_count; slice_idx++) {
+@@ -2990,7 +2994,8 @@ bool dc_add_plane_to_context(
+       otg_master_pipe = resource_get_otg_master_for_stream(
+                       &context->res_ctx, stream);
+-      added = resource_append_dpp_pipes_for_plane_composition(context,
++      if (otg_master_pipe)
++              added = resource_append_dpp_pipes_for_plane_composition(context,
+                       dc->current_state, pool, otg_master_pipe, plane_state);
+       if (added) {
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amd-display-clear-optc-mem-select-on-disable.patch b/queue-6.7/drm-amd-display-clear-optc-mem-select-on-disable.patch
new file mode 100644 (file)
index 0000000..ceef734
--- /dev/null
@@ -0,0 +1,62 @@
+From aaad8d7273b03ba4bd2f2450015fed77700a347c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 09:42:04 -0500
+Subject: drm/amd/display: Clear OPTC mem select on disable
+
+From: Ilya Bakoulin <ilya.bakoulin@amd.com>
+
+[ Upstream commit 3ba2a0bfd8cf94eb225e1c60dff16e5c35bde1da ]
+
+[Why]
+Not clearing the memory select bits prior to OPTC disable can cause DSC
+corruption issues when attempting to reuse a memory instance for another
+OPTC that enables ODM.
+
+[How]
+Clear the memory select bits prior to disabling an OPTC.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Charlene Liu <charlene.liu@amd.com>
+Acked-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Ilya Bakoulin <ilya.bakoulin@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c | 3 +++
+ drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c | 3 +++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
+index 1788eb29474b..823493543325 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
+@@ -173,6 +173,9 @@ static bool optc32_disable_crtc(struct timing_generator *optc)
+                       OPTC_SEG3_SRC_SEL, 0xf,
+                       OPTC_NUM_OF_INPUT_SEGMENT, 0);
++      REG_UPDATE(OPTC_MEMORY_CONFIG,
++                      OPTC_MEM_SEL, 0);
++
+       /* disable otg request until end of the first line
+        * in the vertical blank region
+        */
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
+index 3d6c1b2c2b4d..5b1547508850 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
+@@ -145,6 +145,9 @@ static bool optc35_disable_crtc(struct timing_generator *optc)
+                       OPTC_SEG3_SRC_SEL, 0xf,
+                       OPTC_NUM_OF_INPUT_SEGMENT, 0);
++      REG_UPDATE(OPTC_MEMORY_CONFIG,
++                      OPTC_MEM_SEL, 0);
++
+       /* disable otg request until end of the first line
+        * in the vertical blank region
+        */
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amd-display-disconnect-phantom-pipe-opp-from-opt.patch b/queue-6.7/drm-amd-display-disconnect-phantom-pipe-opp-from-opt.patch
new file mode 100644 (file)
index 0000000..0b235b2
--- /dev/null
@@ -0,0 +1,109 @@
+From d72780123c58fdaa42a4f60119ccf69668af4d17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Dec 2023 17:17:57 -0500
+Subject: drm/amd/display: Disconnect phantom pipe OPP from OPTC being disabled
+
+From: George Shen <george.shen@amd.com>
+
+[ Upstream commit 7bdbfb4e36e34eb788e44f27666bf0a2b3b90803 ]
+
+[Why]
+If an OPP is used for a different OPTC without first being disconnected
+from the previous OPTC, unexpected behaviour can occur. This also
+applies to phantom pipes, which is what the current logic missed.
+
+[How]
+Disconnect OPPs from OPTC for phantom pipes before disabling OTG master.
+
+Also move the disconnection to before the OTG master disable, since the
+register is double buffered.
+
+Reviewed-by: Dillon Varone <dillon.varone@amd.com>
+Acked-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
+Signed-off-by: George Shen <george.shen@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 3ba2a0bfd8cf ("drm/amd/display: Clear OPTC mem select on disable")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/dc/dcn32/dcn32_optc.c | 19 +++++++++++++------
+ .../gpu/drm/amd/display/dc/dcn35/dcn35_optc.c | 12 ++++++------
+ 2 files changed, 19 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
+index 91ea0d4da06a..1788eb29474b 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
+@@ -166,12 +166,6 @@ static bool optc32_disable_crtc(struct timing_generator *optc)
+ {
+       struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-      /* disable otg request until end of the first line
+-       * in the vertical blank region
+-       */
+-      REG_UPDATE(OTG_CONTROL,
+-                      OTG_MASTER_EN, 0);
+-
+       REG_UPDATE_5(OPTC_DATA_SOURCE_SELECT,
+                       OPTC_SEG0_SRC_SEL, 0xf,
+                       OPTC_SEG1_SRC_SEL, 0xf,
+@@ -179,6 +173,12 @@ static bool optc32_disable_crtc(struct timing_generator *optc)
+                       OPTC_SEG3_SRC_SEL, 0xf,
+                       OPTC_NUM_OF_INPUT_SEGMENT, 0);
++      /* disable otg request until end of the first line
++       * in the vertical blank region
++       */
++      REG_UPDATE(OTG_CONTROL,
++                      OTG_MASTER_EN, 0);
++
+       REG_UPDATE(CONTROL,
+                       VTG0_ENABLE, 0);
+@@ -205,6 +205,13 @@ static void optc32_disable_phantom_otg(struct timing_generator *optc)
+ {
+       struct optc *optc1 = DCN10TG_FROM_TG(optc);
++      REG_UPDATE_5(OPTC_DATA_SOURCE_SELECT,
++                      OPTC_SEG0_SRC_SEL, 0xf,
++                      OPTC_SEG1_SRC_SEL, 0xf,
++                      OPTC_SEG2_SRC_SEL, 0xf,
++                      OPTC_SEG3_SRC_SEL, 0xf,
++                      OPTC_NUM_OF_INPUT_SEGMENT, 0);
++
+       REG_UPDATE(OTG_CONTROL, OTG_MASTER_EN, 0);
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
+index 08a59cf449ca..3d6c1b2c2b4d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
+@@ -138,12 +138,6 @@ static bool optc35_disable_crtc(struct timing_generator *optc)
+ {
+       struct optc *optc1 = DCN10TG_FROM_TG(optc);
+-      /* disable otg request until end of the first line
+-       * in the vertical blank region
+-       */
+-      REG_UPDATE(OTG_CONTROL,
+-                      OTG_MASTER_EN, 0);
+-
+       REG_UPDATE_5(OPTC_DATA_SOURCE_SELECT,
+                       OPTC_SEG0_SRC_SEL, 0xf,
+                       OPTC_SEG1_SRC_SEL, 0xf,
+@@ -151,6 +145,12 @@ static bool optc35_disable_crtc(struct timing_generator *optc)
+                       OPTC_SEG3_SRC_SEL, 0xf,
+                       OPTC_NUM_OF_INPUT_SEGMENT, 0);
++      /* disable otg request until end of the first line
++       * in the vertical blank region
++       */
++      REG_UPDATE(OTG_CONTROL,
++                      OTG_MASTER_EN, 0);
++
+       REG_UPDATE(CONTROL,
+                       VTG0_ENABLE, 0);
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amd-display-do-not-send-commands-to-dmub-if-dmub.patch b/queue-6.7/drm-amd-display-do-not-send-commands-to-dmub-if-dmub.patch
new file mode 100644 (file)
index 0000000..5356737
--- /dev/null
@@ -0,0 +1,188 @@
+From 8134e950367e2fdc64ba284b01989421d5c41d1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Nov 2023 16:53:12 -0500
+Subject: drm/amd/display: do not send commands to DMUB if DMUB is inactive
+ from S3
+
+From: Samson Tam <samson.tam@amd.com>
+
+[ Upstream commit 0f657938e4345a77be871d906f3e0de3c58a7a49 ]
+
+[Why]
+On resume from S3, may get apply_idle_optimizations call while DMUB
+is inactive which will just time out.
+
+[How]
+Set and track power state in dmub_srv and check power state before
+sending commands to DMUB.  Add interface in both dmub_srv and
+dc_dmub_srv
+
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Acked-by: Wayne Lin <wayne.lin@amd.com>
+Signed-off-by: Samson Tam <samson.tam@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 8892780834ae ("drm/amd/display: Wake DMCUB before sending a command")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  3 +++
+ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  | 14 +++++++++++++
+ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h  |  2 ++
+ drivers/gpu/drm/amd/display/dmub/dmub_srv.h   | 21 +++++++++++++++++++
+ .../gpu/drm/amd/display/dmub/src/dmub_srv.c   | 15 +++++++++++++
+ 5 files changed, 55 insertions(+)
+
+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 a9bd020b165a..4d534ac18356 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -2656,6 +2656,7 @@ static int dm_suspend(void *handle)
+       hpd_rx_irq_work_suspend(dm);
+       dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
++      dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D3);
+       return 0;
+ }
+@@ -2851,6 +2852,7 @@ static int dm_resume(void *handle)
+               if (r)
+                       DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r);
++              dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D0);
+               dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
+               dc_resume(dm->dc);
+@@ -2901,6 +2903,7 @@ static int dm_resume(void *handle)
+       }
+       /* power on hardware */
++      dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D0);
+       dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
+       /* program HPD filter */
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+index 0e07699c1e83..0c963dfd6061 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+@@ -1251,3 +1251,17 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
+               ASSERT(0);
+ }
++void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state powerState)
++{
++      struct dmub_srv *dmub;
++
++      if (!dc_dmub_srv)
++              return;
++
++      dmub = dc_dmub_srv->dmub;
++
++      if (powerState == DC_ACPI_CM_POWER_STATE_D0)
++              dmub_srv_set_power_state(dmub, DMUB_POWER_STATE_D0);
++      else
++              dmub_srv_set_power_state(dmub, DMUB_POWER_STATE_D3);
++}
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+index d4a60f53faab..c25ce7546f71 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+@@ -102,4 +102,6 @@ void dc_dmub_srv_subvp_save_surf_addr(const struct dc_dmub_srv *dc_dmub_srv, con
+ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait);
+ void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle);
+ void dc_dmub_srv_exit_low_power_state(const struct dc *dc);
++
++void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state powerState);
+ #endif /* _DMUB_DC_SRV_H_ */
+diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+index df63aa8f01e9..d1a4ed6f5916 100644
+--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
++++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+@@ -150,6 +150,13 @@ enum dmub_memory_access_type {
+       DMUB_MEMORY_ACCESS_DMA
+ };
++/* enum dmub_power_state type - to track DC power state in dmub_srv */
++enum dmub_srv_power_state_type {
++      DMUB_POWER_STATE_UNDEFINED = 0,
++      DMUB_POWER_STATE_D0 = 1,
++      DMUB_POWER_STATE_D3 = 8
++};
++
+ /**
+  * struct dmub_region - dmub hw memory region
+  * @base: base address for region, must be 256 byte aligned
+@@ -485,6 +492,8 @@ struct dmub_srv {
+       /* Feature capabilities reported by fw */
+       struct dmub_feature_caps feature_caps;
+       struct dmub_visual_confirm_color visual_confirm_color;
++
++      enum dmub_srv_power_state_type power_state;
+ };
+ /**
+@@ -889,6 +898,18 @@ enum dmub_status dmub_srv_clear_inbox0_ack(struct dmub_srv *dmub);
+  */
+ void dmub_srv_subvp_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_address *addr, uint8_t subvp_index);
++/**
++ * dmub_srv_set_power_state() - Track DC power state in dmub_srv
++ * @dmub: The dmub service
++ * @power_state: DC power state setting
++ *
++ * Store DC power state in dmub_srv.  If dmub_srv is in D3, then don't send messages to DMUB
++ *
++ * Return:
++ *   void
++ */
++void dmub_srv_set_power_state(struct dmub_srv *dmub, enum dmub_srv_power_state_type dmub_srv_power_state);
++
+ #if defined(__cplusplus)
+ }
+ #endif
+diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+index 38360adc53d9..59d4e64845ca 100644
+--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
++++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+@@ -713,6 +713,7 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
+               dmub->hw_funcs.reset_release(dmub);
+       dmub->hw_init = true;
++      dmub->power_state = DMUB_POWER_STATE_D0;
+       return DMUB_STATUS_OK;
+ }
+@@ -766,6 +767,9 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub,
+       if (!dmub->hw_init)
+               return DMUB_STATUS_INVALID;
++      if (dmub->power_state != DMUB_POWER_STATE_D0)
++              return DMUB_STATUS_INVALID;
++
+       if (dmub->inbox1_rb.rptr > dmub->inbox1_rb.capacity ||
+           dmub->inbox1_rb.wrpt > dmub->inbox1_rb.capacity) {
+               return DMUB_STATUS_HW_FAILURE;
+@@ -784,6 +788,9 @@ enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub)
+       if (!dmub->hw_init)
+               return DMUB_STATUS_INVALID;
++      if (dmub->power_state != DMUB_POWER_STATE_D0)
++              return DMUB_STATUS_INVALID;
++
+       /**
+        * Read back all the queued commands to ensure that they've
+        * been flushed to framebuffer memory. Otherwise DMCUB might
+@@ -1100,3 +1107,11 @@ void dmub_srv_subvp_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_
+                               subvp_index);
+       }
+ }
++
++void dmub_srv_set_power_state(struct dmub_srv *dmub, enum dmub_srv_power_state_type dmub_srv_power_state)
++{
++      if (!dmub || !dmub->hw_init)
++              return;
++
++      dmub->power_state = dmub_srv_power_state;
++}
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amd-display-fix-conversions-between-bytes-and-kb.patch b/queue-6.7/drm-amd-display-fix-conversions-between-bytes-and-kb.patch
new file mode 100644 (file)
index 0000000..0db050c
--- /dev/null
@@ -0,0 +1,105 @@
+From adfaf31b4d2d066f808bda9de05a7bb8fed9d8e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Nov 2023 10:15:28 -0500
+Subject: drm/amd/display: Fix conversions between bytes and KB
+
+From: Taimur Hassan <syed.hassan@amd.com>
+
+[ Upstream commit 22136ff27c4e01fae81f6588033363a46c72ed8c ]
+
+[Why]
+There are a number of instances where we convert HostVMMinPageSize or
+GPUVMMinPageSize from bytes to KB by dividing (rather than multiplying) and
+vice versa.
+Additionally, in some cases, a parameter is passed through DML in KB but
+later checked as if it were in bytes.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Acked-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
+Signed-off-by: Taimur Hassan <syed.hassan@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/display/dc/dml2/display_mode_core.c  | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c
+index 4899e9e8c163..62ce95bac8f2 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c
++++ b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c
+@@ -6329,7 +6329,7 @@ static void dml_prefetch_check(struct display_mode_lib_st *mode_lib)
+                               mode_lib->ms.NoOfDPPThisState,
+                               mode_lib->ms.dpte_group_bytes,
+                               s->HostVMInefficiencyFactor,
+-                              mode_lib->ms.soc.hostvm_min_page_size_kbytes,
++                              mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
+                               mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels);
+               s->NextMaxVStartup = s->MaxVStartupAllPlanes[j];
+@@ -6542,7 +6542,7 @@ static void dml_prefetch_check(struct display_mode_lib_st *mode_lib)
+                                               mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
+                                               mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels,
+                                               mode_lib->ms.cache_display_cfg.plane.GPUVMEnable,
+-                                              mode_lib->ms.soc.hostvm_min_page_size_kbytes,
++                                              mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
+                                               mode_lib->ms.PDEAndMetaPTEBytesPerFrame[j][k],
+                                               mode_lib->ms.MetaRowBytes[j][k],
+                                               mode_lib->ms.DPTEBytesPerRow[j][k],
+@@ -7687,7 +7687,7 @@ dml_bool_t dml_core_mode_support(struct display_mode_lib_st *mode_lib)
+               CalculateVMRowAndSwath_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
+               CalculateVMRowAndSwath_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
+               CalculateVMRowAndSwath_params->GPUVMMinPageSizeKBytes = mode_lib->ms.cache_display_cfg.plane.GPUVMMinPageSizeKBytes;
+-              CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
++              CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
+               CalculateVMRowAndSwath_params->PTEBufferModeOverrideEn = mode_lib->ms.cache_display_cfg.plane.PTEBufferModeOverrideEn;
+               CalculateVMRowAndSwath_params->PTEBufferModeOverrideVal = mode_lib->ms.cache_display_cfg.plane.PTEBufferMode;
+               CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = mode_lib->ms.PTEBufferSizeNotExceededPerState;
+@@ -7957,7 +7957,7 @@ dml_bool_t dml_core_mode_support(struct display_mode_lib_st *mode_lib)
+               UseMinimumDCFCLK_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
+               UseMinimumDCFCLK_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable;
+               UseMinimumDCFCLK_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes;
+-              UseMinimumDCFCLK_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
++              UseMinimumDCFCLK_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
+               UseMinimumDCFCLK_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
+               UseMinimumDCFCLK_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled;
+               UseMinimumDCFCLK_params->ImmediateFlipRequirement = s->ImmediateFlipRequiredFinal;
+@@ -8699,7 +8699,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
+       CalculateVMRowAndSwath_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
+       CalculateVMRowAndSwath_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
+       CalculateVMRowAndSwath_params->GPUVMMinPageSizeKBytes = mode_lib->ms.cache_display_cfg.plane.GPUVMMinPageSizeKBytes;
+-      CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
++      CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
+       CalculateVMRowAndSwath_params->PTEBufferModeOverrideEn = mode_lib->ms.cache_display_cfg.plane.PTEBufferModeOverrideEn;
+       CalculateVMRowAndSwath_params->PTEBufferModeOverrideVal = mode_lib->ms.cache_display_cfg.plane.PTEBufferMode;
+       CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = s->dummy_boolean_array[0];
+@@ -8805,7 +8805,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
+                       mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
+                       locals->dpte_group_bytes,
+                       s->HostVMInefficiencyFactor,
+-                      mode_lib->ms.soc.hostvm_min_page_size_kbytes,
++                      mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
+                       mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels);
+       locals->TCalc = 24.0 / locals->DCFCLKDeepSleep;
+@@ -8995,7 +8995,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
+                       CalculatePrefetchSchedule_params->GPUVMEnable = mode_lib->ms.cache_display_cfg.plane.GPUVMEnable;
+                       CalculatePrefetchSchedule_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable;
+                       CalculatePrefetchSchedule_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
+-                      CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
++                      CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
+                       CalculatePrefetchSchedule_params->DynamicMetadataEnable = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataEnable[k];
+                       CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled;
+                       CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataLinesBeforeActiveRequired[k];
+@@ -9240,7 +9240,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
+                                               mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
+                                               mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels,
+                                               mode_lib->ms.cache_display_cfg.plane.GPUVMEnable,
+-                                              mode_lib->ms.soc.hostvm_min_page_size_kbytes,
++                                              mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
+                                               locals->PDEAndMetaPTEBytesFrame[k],
+                                               locals->MetaRowByte[k],
+                                               locals->PixelPTEBytesPerRow[k],
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amd-display-fix-hang-underflow-when-transitionin.patch b/queue-6.7/drm-amd-display-fix-hang-underflow-when-transitionin.patch
new file mode 100644 (file)
index 0000000..b43576c
--- /dev/null
@@ -0,0 +1,68 @@
+From cd9cde88c70653798c347b09555d9ef6ac86b9a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Dec 2023 12:19:33 -0500
+Subject: drm/amd/display: Fix hang/underflow when transitioning to ODM4:1
+
+From: Ilya Bakoulin <ilya.bakoulin@amd.com>
+
+[ Upstream commit e7b2b108cdeab76a7e7324459e50b0c1214c0386 ]
+
+[Why]
+Under some circumstances, disabling an OPTC and attempting to reclaim
+its OPP(s) for a different OPTC could cause a hang/underflow due to OPPs
+not being properly disconnected from the disabled OPTC.
+
+[How]
+Ensure that all OPPs are unassigned from an OPTC when it gets disabled.
+
+Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
+Acked-by: Wayne Lin <wayne.lin@amd.com>
+Signed-off-by: Ilya Bakoulin <ilya.bakoulin@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 3ba2a0bfd8cf ("drm/amd/display: Clear OPTC mem select on disable")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c | 7 +++++++
+ drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c | 7 +++++++
+ 2 files changed, 14 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
+index a2c4db2cebdd..91ea0d4da06a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
+@@ -172,6 +172,13 @@ static bool optc32_disable_crtc(struct timing_generator *optc)
+       REG_UPDATE(OTG_CONTROL,
+                       OTG_MASTER_EN, 0);
++      REG_UPDATE_5(OPTC_DATA_SOURCE_SELECT,
++                      OPTC_SEG0_SRC_SEL, 0xf,
++                      OPTC_SEG1_SRC_SEL, 0xf,
++                      OPTC_SEG2_SRC_SEL, 0xf,
++                      OPTC_SEG3_SRC_SEL, 0xf,
++                      OPTC_NUM_OF_INPUT_SEGMENT, 0);
++
+       REG_UPDATE(CONTROL,
+                       VTG0_ENABLE, 0);
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
+index a4a39f1638cf..08a59cf449ca 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
+@@ -144,6 +144,13 @@ static bool optc35_disable_crtc(struct timing_generator *optc)
+       REG_UPDATE(OTG_CONTROL,
+                       OTG_MASTER_EN, 0);
++      REG_UPDATE_5(OPTC_DATA_SOURCE_SELECT,
++                      OPTC_SEG0_SRC_SEL, 0xf,
++                      OPTC_SEG1_SRC_SEL, 0xf,
++                      OPTC_SEG2_SRC_SEL, 0xf,
++                      OPTC_SEG3_SRC_SEL, 0xf,
++                      OPTC_NUM_OF_INPUT_SEGMENT, 0);
++
+       REG_UPDATE(CONTROL,
+                       VTG0_ENABLE, 0);
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amd-display-init-link-enc-resources-in-dc_state-.patch b/queue-6.7/drm-amd-display-init-link-enc-resources-in-dc_state-.patch
new file mode 100644 (file)
index 0000000..7941881
--- /dev/null
@@ -0,0 +1,45 @@
+From 88a32cde75f9b2fa211cab3ede41a177fef63397 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Dec 2023 21:36:39 -0500
+Subject: drm/amd/display: Init link enc resources in dc_state only if res_pool
+ presents
+
+From: Dillon Varone <dillon.varone@amd.com>
+
+[ Upstream commit aa36d8971fccb55ef3241cbfff9d1799e31d8628 ]
+
+[Why & How]
+res_pool is not initialized in all situations such as virtual
+environments, and therefore link encoder resources should not be
+initialized if res_pool is NULL.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Martin Leung <martin.leung@amd.com>
+Acked-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Dillon Varone <dillon.varone@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+index c16190a10883..990d775e4cea 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+@@ -3774,7 +3774,8 @@ void dc_resource_state_construct(
+       dst_ctx->clk_mgr = dc->clk_mgr;
+       /* Initialise DIG link encoder resource tracking variables. */
+-      link_enc_cfg_init(dc, dst_ctx);
++      if (dc->res_pool)
++              link_enc_cfg_init(dc, dst_ctx);
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amd-display-refactor-dmcub-enter-exit-idle-inter.patch b/queue-6.7/drm-amd-display-refactor-dmcub-enter-exit-idle-inter.patch
new file mode 100644 (file)
index 0000000..aeeba82
--- /dev/null
@@ -0,0 +1,205 @@
+From 3f7d674fd70342b8208e439bb5838cbae7ce33db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Dec 2023 14:10:05 -0500
+Subject: drm/amd/display: Refactor DMCUB enter/exit idle interface
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit 8e57c06bf4b0f51a4d6958e15e1a99c9520d00fa ]
+
+[Why]
+We can hang in place trying to send commands when the DMCUB isn't
+powered on.
+
+[How]
+We need to exit out of the idle state prior to sending a command,
+but the process that performs the exit also invokes a command itself.
+
+Fixing this issue involves the following:
+
+1. Using a software state to track whether or not we need to start
+   the process to exit idle or notify idle.
+
+It's possible for the hardware to have exited an idle state without
+driver knowledge, but entering one is always restricted to a driver
+allow - which makes the SW state vs HW state mismatch issue purely one
+of optimization, which should seldomly be hit, if at all.
+
+2. Refactor any instances of exit/notify idle to use a single wrapper
+   that maintains this SW state.
+
+This works simialr to dc_allow_idle_optimizations, but works at the
+DMCUB level and makes sure the state is marked prior to any notify/exit
+idle so we don't enter an infinite loop.
+
+3. Make sure we exit out of idle prior to sending any commands or
+   waiting for DMCUB idle.
+
+This patch takes care of 1/2. A future patch will take care of wrapping
+DMCUB command submission with calls to this new interface.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Hansen Dsouza <hansen.dsouza@amd.com>
+Acked-by: Wayne Lin <wayne.lin@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 8892780834ae ("drm/amd/display: Wake DMCUB before sending a command")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  4 +-
+ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  | 37 ++++++++++++++++++-
+ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h  |  6 ++-
+ .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c   |  8 +---
+ 4 files changed, 43 insertions(+), 12 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 4d534ac18356..292335b7145c 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -2825,7 +2825,7 @@ static int dm_resume(void *handle)
+       bool need_hotplug = false;
+       if (dm->dc->caps.ips_support) {
+-              dc_dmub_srv_exit_low_power_state(dm->dc);
++              dc_dmub_srv_apply_idle_power_optimizations(dm->dc, false);
+       }
+       if (amdgpu_in_reset(adev)) {
+@@ -8771,7 +8771,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+                       if (new_con_state->crtc &&
+                               new_con_state->crtc->state->active &&
+                               drm_atomic_crtc_needs_modeset(new_con_state->crtc->state)) {
+-                              dc_dmub_srv_exit_low_power_state(dm->dc);
++                              dc_dmub_srv_apply_idle_power_optimizations(dm->dc, false);
+                               break;
+                       }
+               }
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+index 0c963dfd6061..9488f739737e 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+@@ -1143,6 +1143,9 @@ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait)
+       struct dc_context *dc_ctx = dc_dmub_srv->ctx;
+       enum dmub_status status;
++      if (!dc_dmub_srv || !dc_dmub_srv->dmub)
++              return true;
++
+       if (dc_dmub_srv->ctx->dc->debug.dmcub_emulation)
+               return true;
+@@ -1158,7 +1161,7 @@ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait)
+       return true;
+ }
+-void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle)
++static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle)
+ {
+       union dmub_rb_cmd cmd = {0};
+@@ -1182,7 +1185,7 @@ void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle)
+       dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+-void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
++static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
+ {
+       const uint32_t max_num_polls = 10000;
+       uint32_t allow_state = 0;
+@@ -1195,6 +1198,9 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
+       if (!dc->idle_optimizations_allowed)
+               return;
++      if (!dc->ctx->dmub_srv || !dc->ctx->dmub_srv->dmub)
++              return;
++
+       if (dc->hwss.get_idle_state &&
+               dc->hwss.set_idle_state &&
+               dc->clk_mgr->funcs->exit_low_power_state) {
+@@ -1265,3 +1271,30 @@ void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_c
+       else
+               dmub_srv_set_power_state(dmub, DMUB_POWER_STATE_D3);
+ }
++
++void dc_dmub_srv_apply_idle_power_optimizations(const struct dc *dc, bool allow_idle)
++{
++      struct dc_dmub_srv *dc_dmub_srv = dc->ctx->dmub_srv;
++
++      if (!dc_dmub_srv || !dc_dmub_srv->dmub)
++              return;
++
++      if (dc_dmub_srv->idle_allowed == allow_idle)
++              return;
++
++      /*
++       * Entering a low power state requires a driver notification.
++       * Powering up the hardware requires notifying PMFW and DMCUB.
++       * Clearing the driver idle allow requires a DMCUB command.
++       * DMCUB commands requires the DMCUB to be powered up and restored.
++       *
++       * Exit out early to prevent an infinite loop of DMCUB commands
++       * triggering exit low power - use software state to track this.
++       */
++      dc_dmub_srv->idle_allowed = allow_idle;
++
++      if (!allow_idle)
++              dc_dmub_srv_exit_low_power_state(dc);
++      else
++              dc_dmub_srv_notify_idle(dc, allow_idle);
++}
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+index c25ce7546f71..b63cba6235fc 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+@@ -50,6 +50,8 @@ struct dc_dmub_srv {
+       struct dc_context *ctx;
+       void *dm;
++
++      bool idle_allowed;
+ };
+ void dc_dmub_srv_wait_idle(struct dc_dmub_srv *dc_dmub_srv);
+@@ -100,8 +102,8 @@ void dc_dmub_srv_enable_dpia_trace(const struct dc *dc);
+ void dc_dmub_srv_subvp_save_surf_addr(const struct dc_dmub_srv *dc_dmub_srv, const struct dc_plane_address *addr, uint8_t subvp_index);
+ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait);
+-void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle);
+-void dc_dmub_srv_exit_low_power_state(const struct dc *dc);
++
++void dc_dmub_srv_apply_idle_power_optimizations(const struct dc *dc, bool allow_idle);
+ void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state powerState);
+ #endif /* _DMUB_DC_SRV_H_ */
+diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
+index 5a8258287438..cf26d2ad4008 100644
+--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
+@@ -671,11 +671,7 @@ bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable)
+       }
+       // TODO: review other cases when idle optimization is allowed
+-
+-      if (!enable)
+-              dc_dmub_srv_exit_low_power_state(dc);
+-      else
+-              dc_dmub_srv_notify_idle(dc, enable);
++      dc_dmub_srv_apply_idle_power_optimizations(dc, enable);
+       return true;
+ }
+@@ -685,7 +681,7 @@ void dcn35_z10_restore(const struct dc *dc)
+       if (dc->debug.disable_z10)
+               return;
+-      dc_dmub_srv_exit_low_power_state(dc);
++      dc_dmub_srv_apply_idle_power_optimizations(dc, false);
+       dcn31_z10_restore(dc);
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amd-display-update-pixel-clock-params-after-stre.patch b/queue-6.7/drm-amd-display-update-pixel-clock-params-after-stre.patch
new file mode 100644 (file)
index 0000000..2650b2d
--- /dev/null
@@ -0,0 +1,168 @@
+From 56127ad7a9086bce14ece3deb9a393ac7fc833e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Nov 2023 14:59:13 -0400
+Subject: drm/amd/display: update pixel clock params after stream slice count
+ change in context
+
+From: Wenjing Liu <wenjing.liu@amd.com>
+
+[ Upstream commit cfab803884f426b36b58dbe1f86f99742767c208 ]
+
+[why]
+When ODM slice count is changed, otg master pipe's pixel clock params is
+no longer valid as the value is dependent on ODM slice count.
+
+Reviewed-by: Chaitanya Dhere <chaitanya.dhere@amd.com>
+Acked-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
+Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: aa36d8971fcc ("drm/amd/display: Init link enc resources in dc_state only if res_pool presents")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/dc/core/dc_resource.c    |  9 ++++++---
+ .../drm/amd/display/dc/dcn20/dcn20_resource.c    | 16 ++++++++++------
+ .../drm/amd/display/dc/dcn20/dcn20_resource.h    |  1 +
+ .../drm/amd/display/dc/dcn32/dcn32_resource.c    |  1 +
+ .../drm/amd/display/dc/dcn321/dcn321_resource.c  |  1 +
+ .../gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c |  6 +-----
+ drivers/gpu/drm/amd/display/dc/inc/core_types.h  |  1 +
+ 7 files changed, 21 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+index ae275f1780d5..c16190a10883 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+@@ -2237,7 +2237,7 @@ static struct pipe_ctx *get_last_dpp_pipe_in_mpcc_combine(
+ }
+ static bool update_pipe_params_after_odm_slice_count_change(
+-              const struct dc_stream_state *stream,
++              struct pipe_ctx *otg_master,
+               struct dc_state *context,
+               const struct resource_pool *pool)
+ {
+@@ -2247,9 +2247,12 @@ static bool update_pipe_params_after_odm_slice_count_change(
+       for (i = 0; i < pool->pipe_count && result; i++) {
+               pipe = &context->res_ctx.pipe_ctx[i];
+-              if (pipe->stream == stream && pipe->plane_state)
++              if (pipe->stream == otg_master->stream && pipe->plane_state)
+                       result = resource_build_scaling_params(pipe);
+       }
++
++      if (pool->funcs->build_pipe_pix_clk_params)
++              pool->funcs->build_pipe_pix_clk_params(otg_master);
+       return result;
+ }
+@@ -2932,7 +2935,7 @@ bool resource_update_pipes_for_stream_with_slice_count(
+                                       otg_master, new_ctx, pool);
+       if (result)
+               result = update_pipe_params_after_odm_slice_count_change(
+-                              otg_master->stream, new_ctx, pool);
++                              otg_master, new_ctx, pool);
+       return result;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+index 0a422fbb14bc..e73e59754837 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+@@ -1273,15 +1273,19 @@ static void build_clamping_params(struct dc_stream_state *stream)
+       stream->clamping.pixel_encoding = stream->timing.pixel_encoding;
+ }
+-static enum dc_status build_pipe_hw_param(struct pipe_ctx *pipe_ctx)
++void dcn20_build_pipe_pix_clk_params(struct pipe_ctx *pipe_ctx)
+ {
+-
+       get_pixel_clock_parameters(pipe_ctx, &pipe_ctx->stream_res.pix_clk_params);
+-
+       pipe_ctx->clock_source->funcs->get_pix_clk_dividers(
+-              pipe_ctx->clock_source,
+-              &pipe_ctx->stream_res.pix_clk_params,
+-              &pipe_ctx->pll_settings);
++                      pipe_ctx->clock_source,
++                      &pipe_ctx->stream_res.pix_clk_params,
++                      &pipe_ctx->pll_settings);
++}
++
++static enum dc_status build_pipe_hw_param(struct pipe_ctx *pipe_ctx)
++{
++
++      dcn20_build_pipe_pix_clk_params(pipe_ctx);
+       pipe_ctx->stream->clamping.pixel_encoding = pipe_ctx->stream->timing.pixel_encoding;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
+index 37ecaccc5d12..4cee3fa11a7f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
+@@ -165,6 +165,7 @@ enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx,
+ enum dc_status dcn20_add_dsc_to_stream_resource(struct dc *dc, struct dc_state *dc_ctx, struct dc_stream_state *dc_stream);
+ enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream);
+ enum dc_status dcn20_patch_unknown_plane_state(struct dc_plane_state *plane_state);
++void dcn20_build_pipe_pix_clk_params(struct pipe_ctx *pipe_ctx);
+ #endif /* __DC_RESOURCE_DCN20_H__ */
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+index 89b072447dba..e940dd0f92b7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+@@ -2041,6 +2041,7 @@ static struct resource_funcs dcn32_res_pool_funcs = {
+       .retain_phantom_pipes = dcn32_retain_phantom_pipes,
+       .save_mall_state = dcn32_save_mall_state,
+       .restore_mall_state = dcn32_restore_mall_state,
++      .build_pipe_pix_clk_params = dcn20_build_pipe_pix_clk_params,
+ };
+ static uint32_t read_pipe_fuses(struct dc_context *ctx)
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
+index f7de3eca1225..4156a8cc2bc7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
+@@ -1609,6 +1609,7 @@ static struct resource_funcs dcn321_res_pool_funcs = {
+       .retain_phantom_pipes = dcn32_retain_phantom_pipes,
+       .save_mall_state = dcn32_save_mall_state,
+       .restore_mall_state = dcn32_restore_mall_state,
++      .build_pipe_pix_clk_params = dcn20_build_pipe_pix_clk_params,
+ };
+ static uint32_t read_pipe_fuses(struct dc_context *ctx)
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+index b46cde525066..92e2ddc9ab7e 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+@@ -1237,15 +1237,11 @@ static void update_pipes_with_slice_table(struct dc *dc, struct dc_state *contex
+ {
+       int i;
+-      for (i = 0; i < table->odm_combine_count; i++) {
++      for (i = 0; i < table->odm_combine_count; i++)
+               resource_update_pipes_for_stream_with_slice_count(context,
+                               dc->current_state, dc->res_pool,
+                               table->odm_combines[i].stream,
+                               table->odm_combines[i].slice_count);
+-              /* TODO: move this into the function above */
+-              dcn20_build_mapped_resource(dc, context,
+-                              table->odm_combines[i].stream);
+-      }
+       for (i = 0; i < table->mpc_combine_count; i++)
+               resource_update_pipes_for_plane_with_slice_count(context,
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+index bac1420b1de8..10397d4dfb07 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+@@ -205,6 +205,7 @@ struct resource_funcs {
+       void (*get_panel_config_defaults)(struct dc_panel_config *panel_config);
+       void (*save_mall_state)(struct dc *dc, struct dc_state *context, struct mall_temp_config *temp_config);
+       void (*restore_mall_state)(struct dc *dc, struct dc_state *context, struct mall_temp_config *temp_config);
++      void (*build_pipe_pix_clk_params)(struct pipe_ctx *pipe_ctx);
+ };
+ struct audio_support{
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amd-display-wake-dmcub-before-executing-gpint-co.patch b/queue-6.7/drm-amd-display-wake-dmcub-before-executing-gpint-co.patch
new file mode 100644 (file)
index 0000000..fd8ece2
--- /dev/null
@@ -0,0 +1,216 @@
+From 16a05ec8f2b548e5774b97506ef4de2bd9d20f14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 11:22:56 -0500
+Subject: drm/amd/display: Wake DMCUB before executing GPINT commands
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit e5ffd1263dd5b44929c676171802e7b6af483f21 ]
+
+[Why]
+DMCUB can be in idle when we attempt to interface with the HW through
+the GPINT mailbox resulting in a system hang.
+
+[How]
+Add dc_wake_and_execute_gpint() to wrap the wake, execute, sleep
+sequence.
+
+If the GPINT executes successfully then DMCUB will be put back into
+sleep after the optional response is returned.
+
+It functions similar to the inbox command interface.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Hansen Dsouza <hansen.dsouza@amd.com>
+Acked-by: Wayne Lin <wayne.lin@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  | 72 ++++++++++++++-----
+ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h  | 11 +++
+ drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 19 ++---
+ 3 files changed, 72 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+index 50f1e6d5321e..61d1b4eadbee 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+@@ -282,17 +282,11 @@ bool dc_dmub_srv_optimized_init_done(struct dc_dmub_srv *dc_dmub_srv)
+ bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv,
+                                   unsigned int stream_mask)
+ {
+-      struct dmub_srv *dmub;
+-      const uint32_t timeout = 30;
+-
+       if (!dc_dmub_srv || !dc_dmub_srv->dmub)
+               return false;
+-      dmub = dc_dmub_srv->dmub;
+-
+-      return dmub_srv_send_gpint_command(
+-                     dmub, DMUB_GPINT__IDLE_OPT_NOTIFY_STREAM_MASK,
+-                     stream_mask, timeout) == DMUB_STATUS_OK;
++      return dc_wake_and_execute_gpint(dc_dmub_srv->ctx, DMUB_GPINT__IDLE_OPT_NOTIFY_STREAM_MASK,
++                                       stream_mask, NULL, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ bool dc_dmub_srv_is_restore_required(struct dc_dmub_srv *dc_dmub_srv)
+@@ -1107,25 +1101,20 @@ bool dc_dmub_check_min_version(struct dmub_srv *srv)
+ void dc_dmub_srv_enable_dpia_trace(const struct dc *dc)
+ {
+       struct dc_dmub_srv *dc_dmub_srv = dc->ctx->dmub_srv;
+-      struct dmub_srv *dmub;
+-      enum dmub_status status;
+-      static const uint32_t timeout_us = 30;
+       if (!dc_dmub_srv || !dc_dmub_srv->dmub) {
+               DC_LOG_ERROR("%s: invalid parameters.", __func__);
+               return;
+       }
+-      dmub = dc_dmub_srv->dmub;
+-
+-      status = dmub_srv_send_gpint_command(dmub, DMUB_GPINT__SET_TRACE_BUFFER_MASK_WORD1, 0x0010, timeout_us);
+-      if (status != DMUB_STATUS_OK) {
++      if (!dc_wake_and_execute_gpint(dc->ctx, DMUB_GPINT__SET_TRACE_BUFFER_MASK_WORD1,
++                                     0x0010, NULL, DM_DMUB_WAIT_TYPE_WAIT)) {
+               DC_LOG_ERROR("timeout updating trace buffer mask word\n");
+               return;
+       }
+-      status = dmub_srv_send_gpint_command(dmub, DMUB_GPINT__UPDATE_TRACE_BUFFER_MASK, 0x0000, timeout_us);
+-      if (status != DMUB_STATUS_OK) {
++      if (!dc_wake_and_execute_gpint(dc->ctx, DMUB_GPINT__UPDATE_TRACE_BUFFER_MASK,
++                                     0x0000, NULL, DM_DMUB_WAIT_TYPE_WAIT)) {
+               DC_LOG_ERROR("timeout updating trace buffer mask word\n");
+               return;
+       }
+@@ -1337,3 +1326,52 @@ bool dc_wake_and_execute_dmub_cmd_list(const struct dc_context *ctx, unsigned in
+       return result;
+ }
++
++static bool dc_dmub_execute_gpint(const struct dc_context *ctx, enum dmub_gpint_command command_code,
++                                uint16_t param, uint32_t *response, enum dm_dmub_wait_type wait_type)
++{
++      struct dc_dmub_srv *dc_dmub_srv = ctx->dmub_srv;
++      const uint32_t wait_us = wait_type == DM_DMUB_WAIT_TYPE_NO_WAIT ? 0 : 30;
++      enum dmub_status status;
++
++      if (response)
++              *response = 0;
++
++      if (!dc_dmub_srv || !dc_dmub_srv->dmub)
++              return false;
++
++      status = dmub_srv_send_gpint_command(dc_dmub_srv->dmub, command_code, param, wait_us);
++      if (status != DMUB_STATUS_OK) {
++              if (status == DMUB_STATUS_TIMEOUT && wait_type == DM_DMUB_WAIT_TYPE_NO_WAIT)
++                      return true;
++
++              return false;
++      }
++
++      if (response && wait_type == DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)
++              dmub_srv_get_gpint_response(dc_dmub_srv->dmub, response);
++
++      return true;
++}
++
++bool dc_wake_and_execute_gpint(const struct dc_context *ctx, enum dmub_gpint_command command_code,
++                             uint16_t param, uint32_t *response, enum dm_dmub_wait_type wait_type)
++{
++      struct dc_dmub_srv *dc_dmub_srv = ctx->dmub_srv;
++      bool result = false, reallow_idle = false;
++
++      if (!dc_dmub_srv || !dc_dmub_srv->dmub)
++              return false;
++
++      if (dc_dmub_srv->idle_allowed) {
++              dc_dmub_srv_apply_idle_power_optimizations(ctx->dc, false);
++              reallow_idle = true;
++      }
++
++      result = dc_dmub_execute_gpint(ctx, command_code, param, response, wait_type);
++
++      if (result && reallow_idle)
++              dc_dmub_srv_apply_idle_power_optimizations(ctx->dc, true);
++
++      return result;
++}
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+index 784ca3e44414..952bfb368886 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+@@ -145,5 +145,16 @@ bool dc_wake_and_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cm
+ bool dc_wake_and_execute_dmub_cmd_list(const struct dc_context *ctx, unsigned int count,
+                                      union dmub_rb_cmd *cmd, enum dm_dmub_wait_type wait_type);
++/**
++ * dc_wake_and_execute_gpint()
++ *
++ * @ctx: DC context
++ * @command_code: The command ID to send to DMCUB
++ * @param: The parameter to message DMCUB
++ * @response: Optional response out value - may be NULL.
++ * @wait_type: The wait behavior for the execution
++ */
++bool dc_wake_and_execute_gpint(const struct dc_context *ctx, enum dmub_gpint_command command_code,
++                             uint16_t param, uint32_t *response, enum dm_dmub_wait_type wait_type);
+ #endif /* _DMUB_DC_SRV_H_ */
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+index 3d7cef17f881..3e243e407bb8 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+@@ -105,23 +105,18 @@ static enum dc_psr_state convert_psr_state(uint32_t raw_state)
+  */
+ static void dmub_psr_get_state(struct dmub_psr *dmub, enum dc_psr_state *state, uint8_t panel_inst)
+ {
+-      struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub;
+       uint32_t raw_state = 0;
+       uint32_t retry_count = 0;
+-      enum dmub_status status;
+       do {
+               // Send gpint command and wait for ack
+-              status = dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, panel_inst, 30);
+-
+-              if (status == DMUB_STATUS_OK) {
+-                      // GPINT was executed, get response
+-                      dmub_srv_get_gpint_response(srv, &raw_state);
++              if (dc_wake_and_execute_gpint(dmub->ctx, DMUB_GPINT__GET_PSR_STATE, panel_inst, &raw_state,
++                                            DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) {
+                       *state = convert_psr_state(raw_state);
+-              } else
++              } else {
+                       // Return invalid state when GPINT times out
+                       *state = PSR_STATE_INVALID;
+-
++              }
+       } while (++retry_count <= 1000 && *state == PSR_STATE_INVALID);
+       // Assert if max retry hit
+@@ -452,13 +447,11 @@ static void dmub_psr_force_static(struct dmub_psr *dmub, uint8_t panel_inst)
+  */
+ static void dmub_psr_get_residency(struct dmub_psr *dmub, uint32_t *residency, uint8_t panel_inst)
+ {
+-      struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub;
+       uint16_t param = (uint16_t)(panel_inst << 8);
+       /* Send gpint command and wait for ack */
+-      dmub_srv_send_gpint_command(srv, DMUB_GPINT__PSR_RESIDENCY, param, 30);
+-
+-      dmub_srv_get_gpint_response(srv, residency);
++      dc_wake_and_execute_gpint(dmub->ctx, DMUB_GPINT__PSR_RESIDENCY, param, residency,
++                                DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY);
+ }
+ static const struct dmub_psr_funcs psr_funcs = {
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amd-display-wake-dmcub-before-sending-a-command.patch b/queue-6.7/drm-amd-display-wake-dmcub-before-sending-a-command.patch
new file mode 100644 (file)
index 0000000..3f38fa9
--- /dev/null
@@ -0,0 +1,826 @@
+From 50b2a6438405c05737873cedb22cffed6722079b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Dec 2023 16:35:04 -0500
+Subject: drm/amd/display: Wake DMCUB before sending a command
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit 8892780834ae294bc3697c7d0e056d7743900b39 ]
+
+[Why]
+We can hang in place trying to send commands when the DMCUB isn't
+powered on.
+
+[How]
+For functions that execute within a DC context or DC lock we can
+wrap the direct calls to dm_execute_dmub_cmd/list with code that
+exits idle power optimizations and reallows once we're done with
+the command submission on success.
+
+For DM direct submissions the DM will need to manage the enter/exit
+sequencing manually.
+
+We cannot invoke a DMCUB command directly within the DM execution
+helper or we can deadlock.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Hansen Dsouza <hansen.dsouza@amd.com>
+Acked-by: Wayne Lin <wayne.lin@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  2 +-
+ .../drm/amd/display/dc/bios/command_table2.c  | 12 ++---
+ .../display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c  |  2 +-
+ .../dc/clk_mgr/dcn314/dcn314_clk_mgr.c        |  2 +-
+ .../dc/clk_mgr/dcn315/dcn315_clk_mgr.c        |  2 +-
+ .../dc/clk_mgr/dcn316/dcn316_clk_mgr.c        |  2 +-
+ .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c  |  2 +-
+ drivers/gpu/drm/amd/display/dc/core/dc.c      | 12 ++---
+ .../drm/amd/display/dc/core/dc_hw_sequencer.c |  2 +-
+ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  | 53 ++++++++++++++++---
+ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h  | 40 ++++++++++++++
+ drivers/gpu/drm/amd/display/dc/dc_helper.c    |  6 +--
+ .../gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c | 14 ++---
+ .../drm/amd/display/dc/dce/dmub_hw_lock_mgr.c |  2 +-
+ .../gpu/drm/amd/display/dc/dce/dmub_outbox.c  |  2 +-
+ drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 14 ++---
+ .../gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c |  2 +-
+ .../display/dc/dcn31/dcn31_dio_link_encoder.c |  4 +-
+ .../amd/display/dc/dcn31/dcn31_panel_cntl.c   |  4 +-
+ .../amd/display/dc/hwss/dcn21/dcn21_hwseq.c   |  4 +-
+ .../amd/display/dc/hwss/dcn30/dcn30_hwseq.c   |  8 +--
+ .../amd/display/dc/hwss/dcn31/dcn31_hwseq.c   |  4 +-
+ .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c   |  6 +--
+ .../dc/link/protocols/link_dp_capability.c    |  2 +-
+ .../display/dc/link/protocols/link_dp_dpia.c  |  3 +-
+ 25 files changed, 143 insertions(+), 63 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 292335b7145c..9dbbaeb8c6cf 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -10620,7 +10620,7 @@ static bool dm_edid_parser_send_cea(struct amdgpu_display_manager *dm,
+       input->cea_total_length = total_length;
+       memcpy(input->payload, data, length);
+-      res = dm_execute_dmub_cmd(dm->dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY);
++      res = dc_wake_and_execute_dmub_cmd(dm->dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY);
+       if (!res) {
+               DRM_ERROR("EDID CEA parser failed\n");
+               return false;
+diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
+index ab0adabf9dd4..293a919d605d 100644
+--- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
+@@ -123,7 +123,7 @@ static void encoder_control_dmcub(
+               sizeof(cmd.digx_encoder_control.header);
+       cmd.digx_encoder_control.encoder_control.dig.stream_param = *dig;
+-      dm_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ static enum bp_result encoder_control_digx_v1_5(
+@@ -259,7 +259,7 @@ static void transmitter_control_dmcub(
+               sizeof(cmd.dig1_transmitter_control.header);
+       cmd.dig1_transmitter_control.transmitter_control.dig = *dig;
+-      dm_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ static enum bp_result transmitter_control_v1_6(
+@@ -321,7 +321,7 @@ static void transmitter_control_dmcub_v1_7(
+               sizeof(cmd.dig1_transmitter_control.header);
+       cmd.dig1_transmitter_control.transmitter_control.dig_v1_7 = *dig;
+-      dm_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ static enum bp_result transmitter_control_v1_7(
+@@ -429,7 +429,7 @@ static void set_pixel_clock_dmcub(
+               sizeof(cmd.set_pixel_clock.header);
+       cmd.set_pixel_clock.pixel_clock.clk = *clk;
+-      dm_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ static enum bp_result set_pixel_clock_v7(
+@@ -796,7 +796,7 @@ static void enable_disp_power_gating_dmcub(
+               sizeof(cmd.enable_disp_power_gating.header);
+       cmd.enable_disp_power_gating.power_gating.pwr = *pwr;
+-      dm_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ static enum bp_result enable_disp_power_gating_v2_1(
+@@ -1006,7 +1006,7 @@ static void enable_lvtma_control_dmcub(
+                       pwrseq_instance;
+       cmd.lvtma_control.data.bypass_panel_control_wait =
+                       bypass_panel_control_wait;
+-      dm_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ static enum bp_result enable_lvtma_control(
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
+index 3db4ef564b99..ce1386e22576 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
+@@ -253,7 +253,7 @@ void dcn31_update_clocks(struct clk_mgr *clk_mgr_base,
+       cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz;
+       cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz;
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ static int get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr)
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
+index 2618504e260e..59c2a3545db3 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
+@@ -281,7 +281,7 @@ void dcn314_update_clocks(struct clk_mgr *clk_mgr_base,
+       cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz;
+       cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz;
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ static int get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr)
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c
+index 8776055bbeaa..644da4637320 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c
+@@ -232,7 +232,7 @@ static void dcn315_update_clocks(struct clk_mgr *clk_mgr_base,
+       cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz;
+       cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz;
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ static void dcn315_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass,
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c
+index 09151cc56ce4..12f3e8aa46d8 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c
+@@ -239,7 +239,7 @@ static void dcn316_update_clocks(struct clk_mgr *clk_mgr_base,
+       cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz;
+       cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz;
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ static void dcn316_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass,
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
+index d5fde7d23fbf..45ede6440a79 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
+@@ -349,7 +349,7 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
+       cmd.notify_clocks.clocks.dispclk_khz = clk_mgr_base->clks.dispclk_khz;
+       cmd.notify_clocks.clocks.dppclk_khz = clk_mgr_base->clks.dppclk_khz;
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ static int get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr)
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 5c1185206645..c535ddb45a36 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -519,7 +519,7 @@ dc_stream_forward_dmub_crc_window(struct dc_dmub_srv *dmub_srv,
+               cmd.secure_display.roi_info.y_end = rect->y + rect->height;
+       }
+-      dm_execute_dmub_cmd(dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
++      dc_wake_and_execute_dmub_cmd(dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
+ }
+ static inline void
+@@ -3386,7 +3386,7 @@ void dc_dmub_update_dirty_rect(struct dc *dc,
+                       update_dirty_rect->panel_inst = panel_inst;
+                       update_dirty_rect->pipe_idx = j;
+-                      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
++                      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
+               }
+       }
+ }
+@@ -5213,7 +5213,7 @@ bool dc_process_dmub_aux_transfer_async(struct dc *dc,
+                       );
+       }
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+ }
+@@ -5267,7 +5267,7 @@ bool dc_process_dmub_set_config_async(struct dc *dc,
+       cmd.set_config_access.set_config_control.cmd_pkt.msg_type = payload->msg_type;
+       cmd.set_config_access.set_config_control.cmd_pkt.msg_data = payload->msg_data;
+-      if (!dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) {
++      if (!dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) {
+               /* command is not processed by dmub */
+               notify->sc_status = SET_CONFIG_UNKNOWN_ERROR;
+               return is_cmd_complete;
+@@ -5310,7 +5310,7 @@ enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc,
+       cmd.set_mst_alloc_slots.mst_slots_control.instance = dc->links[link_index]->ddc_hw_inst;
+       cmd.set_mst_alloc_slots.mst_slots_control.mst_alloc_slots = mst_alloc_slots;
+-      if (!dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
++      if (!dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
+               /* command is not processed by dmub */
+               return DC_ERROR_UNEXPECTED;
+@@ -5348,7 +5348,7 @@ void dc_process_dmub_dpia_hpd_int_enable(const struct dc *dc,
+       cmd.dpia_hpd_int_enable.header.type = DMUB_CMD__DPIA_HPD_INT_ENABLE;
+       cmd.dpia_hpd_int_enable.enable = hpd_int_enable;
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       DC_LOG_DEBUG("%s: hpd_int_enable(%d)\n", __func__, hpd_int_enable);
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+index fe07160932d6..fc18b9dc946f 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+@@ -724,7 +724,7 @@ void hwss_send_dmcub_cmd(union block_sequence_params *params)
+       union dmub_rb_cmd *cmd = params->send_dmcub_cmd_params.cmd;
+       enum dm_dmub_wait_type wait_type = params->send_dmcub_cmd_params.wait_type;
+-      dm_execute_dmub_cmd(ctx, cmd, wait_type);
++      dc_wake_and_execute_dmub_cmd(ctx, cmd, wait_type);
+ }
+ void hwss_program_manual_trigger(union block_sequence_params *params)
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+index 9488f739737e..50f1e6d5321e 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+@@ -341,7 +341,7 @@ void dc_dmub_srv_drr_update_cmd(struct dc *dc, uint32_t tg_inst, uint32_t vtotal
+       cmd.drr_update.header.payload_bytes = sizeof(cmd.drr_update) - sizeof(cmd.drr_update.header);
+       // Send the command to the DMCUB.
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ void dc_dmub_srv_set_drr_manual_trigger_cmd(struct dc *dc, uint32_t tg_inst)
+@@ -355,7 +355,7 @@ void dc_dmub_srv_set_drr_manual_trigger_cmd(struct dc *dc, uint32_t tg_inst)
+       cmd.drr_update.header.payload_bytes = sizeof(cmd.drr_update) - sizeof(cmd.drr_update.header);
+       // Send the command to the DMCUB.
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ static uint8_t dc_dmub_srv_get_pipes_for_stream(struct dc *dc, struct dc_stream_state *stream)
+@@ -448,7 +448,7 @@ bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, stru
+               sizeof(cmd.fw_assisted_mclk_switch) - sizeof(cmd.fw_assisted_mclk_switch.header);
+       // Send the command to the DMCUB.
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+ }
+@@ -469,7 +469,7 @@ void dc_dmub_srv_query_caps_cmd(struct dc_dmub_srv *dc_dmub_srv)
+       cmd.query_feature_caps.header.payload_bytes = sizeof(struct dmub_cmd_query_feature_caps_data);
+       /* If command was processed, copy feature caps to dmub srv */
+-      if (dm_execute_dmub_cmd(dc_dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) &&
++      if (dc_wake_and_execute_dmub_cmd(dc_dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) &&
+           cmd.query_feature_caps.header.ret_status == 0) {
+               memcpy(&dc_dmub_srv->dmub->feature_caps,
+                      &cmd.query_feature_caps.query_feature_caps_data,
+@@ -494,7 +494,7 @@ void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc *dc, struct pipe_ctx *pi
+       cmd.visual_confirm_color.visual_confirm_color_data.visual_confirm_color.panel_inst = panel_inst;
+       // If command was processed, copy feature caps to dmub srv
+-      if (dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) &&
++      if (dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) &&
+               cmd.visual_confirm_color.header.ret_status == 0) {
+               memcpy(&dc->ctx->dmub_srv->dmub->visual_confirm_color,
+                       &cmd.visual_confirm_color.visual_confirm_color_data,
+@@ -856,7 +856,7 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,
+               cmd.fw_assisted_mclk_switch_v2.config_data.watermark_a_cache = wm_val_refclk < 0xFFFF ? wm_val_refclk : 0xFFFF;
+       }
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ bool dc_dmub_srv_get_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv, struct dmub_diagnostic_data *diag_data)
+@@ -1093,7 +1093,7 @@ void dc_send_update_cursor_info_to_dmu(
+                               pipe_idx, pCtx->plane_res.hubp, pCtx->plane_res.dpp);
+               /* Combine 2nd cmds update_curosr_info to DMU */
+-              dm_execute_dmub_cmd_list(pCtx->stream->ctx, 2, cmd, DM_DMUB_WAIT_TYPE_WAIT);
++              dc_wake_and_execute_dmub_cmd_list(pCtx->stream->ctx, 2, cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       }
+ }
+@@ -1182,6 +1182,7 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle)
+                       dc->hwss.set_idle_state(dc, true);
+       }
++      /* NOTE: This does not use the "wake" interface since this is part of the wake path. */
+       dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+@@ -1298,3 +1299,41 @@ void dc_dmub_srv_apply_idle_power_optimizations(const struct dc *dc, bool allow_
+       else
+               dc_dmub_srv_notify_idle(dc, allow_idle);
+ }
++
++bool dc_wake_and_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmd *cmd,
++                                enum dm_dmub_wait_type wait_type)
++{
++      return dc_wake_and_execute_dmub_cmd_list(ctx, 1, cmd, wait_type);
++}
++
++bool dc_wake_and_execute_dmub_cmd_list(const struct dc_context *ctx, unsigned int count,
++                                     union dmub_rb_cmd *cmd, enum dm_dmub_wait_type wait_type)
++{
++      struct dc_dmub_srv *dc_dmub_srv = ctx->dmub_srv;
++      bool result = false, reallow_idle = false;
++
++      if (!dc_dmub_srv || !dc_dmub_srv->dmub)
++              return false;
++
++      if (count == 0)
++              return true;
++
++      if (dc_dmub_srv->idle_allowed) {
++              dc_dmub_srv_apply_idle_power_optimizations(ctx->dc, false);
++              reallow_idle = true;
++      }
++
++      /*
++       * These may have different implementations in DM, so ensure
++       * that we guide it to the expected helper.
++       */
++      if (count > 1)
++              result = dm_execute_dmub_cmd_list(ctx, count, cmd, wait_type);
++      else
++              result = dm_execute_dmub_cmd(ctx, cmd, wait_type);
++
++      if (result && reallow_idle)
++              dc_dmub_srv_apply_idle_power_optimizations(ctx->dc, true);
++
++      return result;
++}
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+index b63cba6235fc..784ca3e44414 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+@@ -106,4 +106,44 @@ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait);
+ void dc_dmub_srv_apply_idle_power_optimizations(const struct dc *dc, bool allow_idle);
+ void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state powerState);
++
++/**
++ * dc_wake_and_execute_dmub_cmd() - Wrapper for DMUB command execution.
++ *
++ * Refer to dc_wake_and_execute_dmub_cmd_list() for usage and limitations,
++ * This function is a convenience wrapper for a single command execution.
++ *
++ * @ctx: DC context
++ * @cmd: The command to send/receive
++ * @wait_type: The wait behavior for the execution
++ *
++ * Return: true on command submission success, false otherwise
++ */
++bool dc_wake_and_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmd *cmd,
++                                enum dm_dmub_wait_type wait_type);
++
++/**
++ * dc_wake_and_execute_dmub_cmd_list() - Wrapper for DMUB command list execution.
++ *
++ * If the DMCUB hardware was asleep then it wakes the DMUB before
++ * executing the command and attempts to re-enter if the command
++ * submission was successful.
++ *
++ * This should be the preferred command submission interface provided
++ * the DC lock is acquired.
++ *
++ * Entry/exit out of idle power optimizations would need to be
++ * manually performed otherwise through dc_allow_idle_optimizations().
++ *
++ * @ctx: DC context
++ * @count: Number of commands to send/receive
++ * @cmd: Array of commands to send
++ * @wait_type: The wait behavior for the execution
++ *
++ * Return: true on command submission success, false otherwise
++ */
++bool dc_wake_and_execute_dmub_cmd_list(const struct dc_context *ctx, unsigned int count,
++                                     union dmub_rb_cmd *cmd, enum dm_dmub_wait_type wait_type);
++
++
+ #endif /* _DMUB_DC_SRV_H_ */
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_helper.c b/drivers/gpu/drm/amd/display/dc/dc_helper.c
+index cb6eaddab720..8f9a67825615 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_helper.c
++++ b/drivers/gpu/drm/amd/display/dc/dc_helper.c
+@@ -50,7 +50,7 @@ static inline void submit_dmub_read_modify_write(
+       cmd_buf->header.payload_bytes =
+                       sizeof(struct dmub_cmd_read_modify_write_sequence) * offload->reg_seq_count;
+-      dm_execute_dmub_cmd(ctx, &offload->cmd_data, DM_DMUB_WAIT_TYPE_NO_WAIT);
++      dc_wake_and_execute_dmub_cmd(ctx, &offload->cmd_data, DM_DMUB_WAIT_TYPE_NO_WAIT);
+       memset(cmd_buf, 0, sizeof(*cmd_buf));
+@@ -67,7 +67,7 @@ static inline void submit_dmub_burst_write(
+       cmd_buf->header.payload_bytes =
+                       sizeof(uint32_t) * offload->reg_seq_count;
+-      dm_execute_dmub_cmd(ctx, &offload->cmd_data, DM_DMUB_WAIT_TYPE_NO_WAIT);
++      dc_wake_and_execute_dmub_cmd(ctx, &offload->cmd_data, DM_DMUB_WAIT_TYPE_NO_WAIT);
+       memset(cmd_buf, 0, sizeof(*cmd_buf));
+@@ -80,7 +80,7 @@ static inline void submit_dmub_reg_wait(
+ {
+       struct dmub_rb_cmd_reg_wait *cmd_buf = &offload->cmd_data.reg_wait;
+-      dm_execute_dmub_cmd(ctx, &offload->cmd_data, DM_DMUB_WAIT_TYPE_NO_WAIT);
++      dc_wake_and_execute_dmub_cmd(ctx, &offload->cmd_data, DM_DMUB_WAIT_TYPE_NO_WAIT);
+       memset(cmd_buf, 0, sizeof(*cmd_buf));
+       offload->reg_seq_count = 0;
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
+index 42c802afc468..4cff36351f40 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
+@@ -76,7 +76,7 @@ static void dmub_abm_enable_fractional_pwm(struct dc_context *dc)
+       cmd.abm_set_pwm_frac.abm_set_pwm_frac_data.panel_mask = panel_mask;
+       cmd.abm_set_pwm_frac.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pwm_frac_data);
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ void dmub_abm_init(struct abm *abm, uint32_t backlight)
+@@ -155,7 +155,7 @@ bool dmub_abm_set_level(struct abm *abm, uint32_t level, uint8_t panel_mask)
+       cmd.abm_set_level.abm_set_level_data.panel_mask = panel_mask;
+       cmd.abm_set_level.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_level_data);
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+ }
+@@ -186,7 +186,7 @@ void dmub_abm_init_config(struct abm *abm,
+       cmd.abm_init_config.header.payload_bytes = sizeof(struct dmub_cmd_abm_init_config_data);
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+@@ -203,7 +203,7 @@ bool dmub_abm_set_pause(struct abm *abm, bool pause, unsigned int panel_inst, un
+       cmd.abm_pause.abm_pause_data.panel_mask = panel_mask;
+       cmd.abm_set_level.header.payload_bytes = sizeof(struct dmub_cmd_abm_pause_data);
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+ }
+@@ -246,7 +246,7 @@ bool dmub_abm_save_restore(
+       cmd.abm_save_restore.header.payload_bytes = sizeof(struct dmub_rb_cmd_abm_save_restore);
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       // Copy iramtable data into local structure
+       memcpy((void *)pData, dc->dmub_srv->dmub->scratch_mem_fb.cpu_addr, bytes);
+@@ -274,7 +274,7 @@ bool dmub_abm_set_pipe(struct abm *abm,
+       cmd.abm_set_pipe.abm_set_pipe_data.ramping_boundary = ramping_boundary;
+       cmd.abm_set_pipe.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pipe_data);
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+ }
+@@ -296,7 +296,7 @@ bool dmub_abm_set_backlight_level(struct abm *abm,
+       cmd.abm_set_backlight.abm_set_backlight_data.panel_mask = (0x01 << panel_inst);
+       cmd.abm_set_backlight.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_backlight_data);
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c
+index 2aa0e01a6891..ba1fec3016d5 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c
+@@ -47,7 +47,7 @@ void dmub_hw_lock_mgr_cmd(struct dc_dmub_srv *dmub_srv,
+       if (!lock)
+               cmd.lock_hw.lock_hw_data.should_release = 1;
+-      dm_execute_dmub_cmd(dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ void dmub_hw_lock_mgr_inbox0_cmd(struct dc_dmub_srv *dmub_srv,
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c
+index d8009b2dc56a..98a778996e1a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c
+@@ -48,5 +48,5 @@ void dmub_enable_outbox_notification(struct dc_dmub_srv *dmub_srv)
+               sizeof(cmd.outbox1_enable.header);
+       cmd.outbox1_enable.enable = true;
+-      dm_execute_dmub_cmd(dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+index 9d4170a356a2..3d7cef17f881 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+@@ -171,7 +171,7 @@ static bool dmub_psr_set_version(struct dmub_psr *dmub, struct dc_stream_state *
+       cmd.psr_set_version.psr_set_version_data.panel_inst = panel_inst;
+       cmd.psr_set_version.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_version_data);
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+ }
+@@ -199,7 +199,7 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait, uint8
+       cmd.psr_enable.header.payload_bytes = 0; // Send header only
+-      dm_execute_dmub_cmd(dc->dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       /* Below loops 1000 x 500us = 500 ms.
+        *  Exit PSR may need to wait 1-2 frames to power up. Timeout after at
+@@ -248,7 +248,7 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level, uint8_
+       cmd.psr_set_level.psr_set_level_data.psr_level = psr_level;
+       cmd.psr_set_level.psr_set_level_data.cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
+       cmd.psr_set_level.psr_set_level_data.panel_inst = panel_inst;
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ /*
+@@ -267,7 +267,7 @@ static void dmub_psr_set_sink_vtotal_in_psr_active(struct dmub_psr *dmub,
+       cmd.psr_set_vtotal.psr_set_vtotal_data.psr_vtotal_idle = psr_vtotal_idle;
+       cmd.psr_set_vtotal.psr_set_vtotal_data.psr_vtotal_su = psr_vtotal_su;
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ /*
+@@ -286,7 +286,7 @@ static void dmub_psr_set_power_opt(struct dmub_psr *dmub, unsigned int power_opt
+       cmd.psr_set_power_opt.psr_set_power_opt_data.power_opt = power_opt;
+       cmd.psr_set_power_opt.psr_set_power_opt_data.panel_inst = panel_inst;
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ /*
+@@ -423,7 +423,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
+               copy_settings_data->relock_delay_frame_cnt = 2;
+       copy_settings_data->dsc_slice_height = psr_context->dsc_slice_height;
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+ }
+@@ -444,7 +444,7 @@ static void dmub_psr_force_static(struct dmub_psr *dmub, uint8_t panel_inst)
+       cmd.psr_force_static.header.sub_type = DMUB_CMD__PSR_FORCE_STATIC;
+       cmd.psr_enable.header.payload_bytes = 0;
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ /*
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
+index 68cad55c72ab..e13d69a22c1c 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
+@@ -691,7 +691,7 @@ static void dmcub_PLAT_54186_wa(struct hubp *hubp,
+       cmd.PLAT_54186_wa.flip.flip_params.vmid = flip_regs->vmid;
+       PERF_TRACE();  // TODO: remove after performance is stable.
+-      dm_execute_dmub_cmd(hubp->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(hubp->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       PERF_TRACE();  // TODO: remove after performance is stable.
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
+index 4596f3bac1b4..26be5fee7411 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
+@@ -125,7 +125,7 @@ static bool query_dp_alt_from_dmub(struct link_encoder *enc,
+       cmd->query_dp_alt.header.payload_bytes = sizeof(cmd->query_dp_alt.data);
+       cmd->query_dp_alt.data.phy_id = phy_id_from_transmitter(enc10->base.transmitter);
+-      if (!dm_execute_dmub_cmd(enc->ctx, cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
++      if (!dc_wake_and_execute_dmub_cmd(enc->ctx, cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
+               return false;
+       return true;
+@@ -436,7 +436,7 @@ static bool link_dpia_control(struct dc_context *dc_ctx,
+       cmd.dig1_dpia_control.dpia_control = *dpia_control;
+-      dm_execute_dmub_cmd(dc_ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc_ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c
+index d849b1eaa4a5..03248422d6ff 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c
+@@ -52,7 +52,7 @@ static bool dcn31_query_backlight_info(struct panel_cntl *panel_cntl, union dmub
+       cmd->panel_cntl.header.payload_bytes = sizeof(cmd->panel_cntl.data);
+       cmd->panel_cntl.data.pwrseq_inst = dcn31_panel_cntl->base.pwrseq_inst;
+-      return dm_execute_dmub_cmd(dc_dmub_srv->ctx, cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY);
++      return dc_wake_and_execute_dmub_cmd(dc_dmub_srv->ctx, cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY);
+ }
+ static uint32_t dcn31_get_16_bit_backlight_from_pwm(struct panel_cntl *panel_cntl)
+@@ -85,7 +85,7 @@ static uint32_t dcn31_panel_cntl_hw_init(struct panel_cntl *panel_cntl)
+               panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV;
+       cmd.panel_cntl.data.bl_pwm_ref_div2 =
+               panel_cntl->stored_backlight_registers.PANEL_PWRSEQ_REF_DIV2;
+-      if (!dm_execute_dmub_cmd(dc_dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
++      if (!dc_wake_and_execute_dmub_cmd(dc_dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
+               return 0;
+       panel_cntl->stored_backlight_registers.BL_PWM_CNTL = cmd.panel_cntl.data.bl_pwm_cntl;
+diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c
+index 08783ad097d2..8e88dcaf88f5 100644
+--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c
+@@ -154,7 +154,7 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst,
+       cmd.abm_set_pipe.abm_set_pipe_data.ramping_boundary = ramping_boundary;
+       cmd.abm_set_pipe.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pipe_data);
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+ }
+@@ -173,7 +173,7 @@ static void dmub_abm_set_backlight(struct dc_context *dc, uint32_t backlight_pwm
+       cmd.abm_set_backlight.abm_set_backlight_data.panel_mask = (0x01 << panel_inst);
+       cmd.abm_set_backlight.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_backlight_data);
+-      dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
+diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
+index d71faf2ecd41..772dc0db916f 100644
+--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
+@@ -750,7 +750,7 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
+                               cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_NO_DF_REQ;
+                               cmd.mall.header.payload_bytes = sizeof(cmd.mall) - sizeof(cmd.mall.header);
+-                              dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
++                              dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
+                               return true;
+                       }
+@@ -872,7 +872,7 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
+                                       cmd.mall.cursor_height = cursor_attr.height;
+                                       cmd.mall.cursor_pitch = cursor_attr.pitch;
+-                                      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++                                      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+                                       /* Use copied cursor, and it's okay to not switch back */
+                                       cursor_attr.address.quad_part = cmd.mall.cursor_copy_dst.quad_part;
+@@ -888,7 +888,7 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
+                               cmd.mall.tmr_scale = tmr_scale;
+                               cmd.mall.debug_bits = dc->debug.mall_error_as_fatal;
+-                              dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
++                              dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
+                               return true;
+                       }
+@@ -905,7 +905,7 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
+       cmd.mall.header.payload_bytes =
+               sizeof(cmd.mall) - sizeof(cmd.mall.header);
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
+index 97798cee876e..52656691ae48 100644
+--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
+@@ -415,7 +415,7 @@ void dcn31_z10_save_init(struct dc *dc)
+       cmd.dcn_restore.header.type = DMUB_CMD__IDLE_OPT;
+       cmd.dcn_restore.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_SAVE_INIT;
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ void dcn31_z10_restore(const struct dc *dc)
+@@ -433,7 +433,7 @@ void dcn31_z10_restore(const struct dc *dc)
+       cmd.dcn_restore.header.type = DMUB_CMD__IDLE_OPT;
+       cmd.dcn_restore.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_RESTORE;
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+ }
+ void dcn31_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
+diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+index c1a9b746c43f..5bf9e7c1e052 100644
+--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+@@ -277,7 +277,7 @@ bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable)
+                               cmd.cab.header.sub_type = DMUB_CMD__CAB_NO_DCN_REQ;
+                               cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);
+-                              dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
++                              dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
+                               return true;
+                       }
+@@ -311,7 +311,7 @@ bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable)
+                               cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);
+                               cmd.cab.cab_alloc_ways = (uint8_t)ways;
+-                              dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
++                              dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
+                               return true;
+                       }
+@@ -327,7 +327,7 @@ bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable)
+       cmd.cab.header.payload_bytes =
+                       sizeof(cmd.cab) - sizeof(cmd.cab.header);
+-      dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
++      dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+       return true;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
+index db87aa7b5c90..2f11eaabbe5f 100644
+--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
+@@ -1392,7 +1392,7 @@ static bool get_usbc_cable_id(struct dc_link *link, union dp_cable_id *cable_id)
+       cmd.cable_id.header.payload_bytes = sizeof(cmd.cable_id.data);
+       cmd.cable_id.data.input.phy_inst = resource_transmitter_to_phy_idx(
+                       link->dc, link->link_enc->transmitter);
+-      if (dm_execute_dmub_cmd(link->dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) &&
++      if (dc_wake_and_execute_dmub_cmd(link->dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) &&
+                       cmd.cable_id.header.ret_status == 1) {
+               cable_id->raw = cmd.cable_id.data.output_raw;
+               DC_LOG_DC("usbc_cable_id = %d.\n", cable_id->raw);
+diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c
+index 0bb749133909..982eda3c46f5 100644
+--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c
++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia.c
+@@ -90,7 +90,8 @@ bool dpia_query_hpd_status(struct dc_link *link)
+       cmd.query_hpd.data.ch_type = AUX_CHANNEL_DPIA;
+       /* Return HPD status reported by DMUB if query successfully executed. */
+-      if (dm_execute_dmub_cmd(dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) && cmd.query_hpd.data.status == AUX_RET_SUCCESS)
++      if (dc_wake_and_execute_dmub_cmd(dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) &&
++          cmd.query_hpd.data.status == AUX_RET_SUCCESS)
+               is_hpd_high = cmd.query_hpd.data.result;
+       DC_LOG_DEBUG("%s: link(%d) dpia(%d) cmd_status(%d) result(%d)\n",
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amdgpu-enable-tunneling-on-high-priority-compute.patch b/queue-6.7/drm-amdgpu-enable-tunneling-on-high-priority-compute.patch
new file mode 100644 (file)
index 0000000..fc3882d
--- /dev/null
@@ -0,0 +1,122 @@
+From a643ef69b7e867d6acfc957b15087a396a093f54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Dec 2023 01:17:40 +0100
+Subject: drm/amdgpu: Enable tunneling on high-priority compute queues
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Friedrich Vock <friedrich.vock@gmx.de>
+
+[ Upstream commit 91963397c49aa2907aeafa52d929555dcbc9cd07 ]
+
+This improves latency if the GPU is already busy with other work.
+This is useful for VR compositors that submit highly latency-sensitive
+compositing work on high-priority compute queues while the GPU is busy
+rendering the next frame.
+
+Userspace merge request:
+https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26462
+
+v2: bump driver version (Alex)
+
+Reviewed-by: Marek Olšák <marek.olsak@amd.com>
+Signed-off-by: Friedrich Vock <friedrich.vock@gmx.de>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 03ff6d7238b7 ("drm/amdgpu/gfx10: set UNORD_DISPATCH in compute MQDs")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h      |  1 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  |  3 ++-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 10 ++++++----
+ drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c   |  3 ++-
+ drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c   |  3 ++-
+ 5 files changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 9d92ca157677..50f57d4dfd8f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -757,6 +757,7 @@ struct amdgpu_mqd_prop {
+       uint64_t eop_gpu_addr;
+       uint32_t hqd_pipe_priority;
+       uint32_t hqd_queue_priority;
++      bool allow_tunneling;
+       bool hqd_active;
+ };
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index c0e8e030b96f..a7ad77ed09ca 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -115,9 +115,10 @@
+  *   3.54.0 - Add AMDGPU_CTX_QUERY2_FLAGS_RESET_IN_PROGRESS support
+  * - 3.55.0 - Add AMDGPU_INFO_GPUVM_FAULT query
+  * - 3.56.0 - Update IB start address and size alignment for decode and encode
++ * - 3.57.0 - Compute tunneling on GFX10+
+  */
+ #define KMS_DRIVER_MAJOR      3
+-#define KMS_DRIVER_MINOR      56
++#define KMS_DRIVER_MINOR      57
+ #define KMS_DRIVER_PATCHLEVEL 0
+ /*
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+index 6a80d3ec887e..45424ebf9681 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+@@ -642,6 +642,10 @@ static void amdgpu_ring_to_mqd_prop(struct amdgpu_ring *ring,
+                                   struct amdgpu_mqd_prop *prop)
+ {
+       struct amdgpu_device *adev = ring->adev;
++      bool is_high_prio_compute = ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE &&
++                                  amdgpu_gfx_is_high_priority_compute_queue(adev, ring);
++      bool is_high_prio_gfx = ring->funcs->type == AMDGPU_RING_TYPE_GFX &&
++                              amdgpu_gfx_is_high_priority_graphics_queue(adev, ring);
+       memset(prop, 0, sizeof(*prop));
+@@ -659,10 +663,8 @@ static void amdgpu_ring_to_mqd_prop(struct amdgpu_ring *ring,
+        */
+       prop->hqd_active = ring->funcs->type == AMDGPU_RING_TYPE_KIQ;
+-      if ((ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE &&
+-           amdgpu_gfx_is_high_priority_compute_queue(adev, ring)) ||
+-          (ring->funcs->type == AMDGPU_RING_TYPE_GFX &&
+-           amdgpu_gfx_is_high_priority_graphics_queue(adev, ring))) {
++      prop->allow_tunneling = is_high_prio_compute;
++      if (is_high_prio_compute || is_high_prio_gfx) {
+               prop->hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH;
+               prop->hqd_queue_priority = AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM;
+       }
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+index 67c198ea8211..d63cab294883 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+@@ -6590,7 +6590,8 @@ static int gfx_v10_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, ENDIAN_SWAP, 1);
+ #endif
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0);
+-      tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, 0);
++      tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH,
++                          prop->allow_tunneling);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1);
+       mqd->cp_hqd_pq_control = tmp;
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+index cddf3737e8a3..4824a4c04d35 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+@@ -3839,7 +3839,8 @@ static int gfx_v11_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, RPTR_BLOCK_SIZE,
+                           (order_base_2(AMDGPU_GPU_PAGE_SIZE / 4) - 1));
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0);
+-      tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, 0);
++      tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH,
++                          prop->allow_tunneling);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1);
+       mqd->cp_hqd_pq_control = tmp;
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amdgpu-gfx10-set-unord_dispatch-in-compute-mqds.patch b/queue-6.7/drm-amdgpu-gfx10-set-unord_dispatch-in-compute-mqds.patch
new file mode 100644 (file)
index 0000000..686fe63
--- /dev/null
@@ -0,0 +1,52 @@
+From 014670a36f0be40246f1111064020ecbbf409ab0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jan 2024 12:23:55 -0500
+Subject: drm/amdgpu/gfx10: set UNORD_DISPATCH in compute MQDs
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 03ff6d7238b77e5fb2b85dc5fe01d2db9eb893bd ]
+
+This needs to be set to 1 to avoid a potential deadlock in
+the GC 10.x and newer.  On GC 9.x and older, this needs
+to be set to 0.  This can lead to hangs in some mixed
+graphics and compute workloads.  Updated firmware is also
+required for AQL.
+
+Reviewed-by: Feifei Xu <Feifei.Xu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c           | 2 +-
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+index d63cab294883..ecb622b7f970 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+@@ -6589,7 +6589,7 @@ static int gfx_v10_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
+ #ifdef __BIG_ENDIAN
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, ENDIAN_SWAP, 1);
+ #endif
+-      tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0);
++      tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 1);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH,
+                           prop->allow_tunneling);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1);
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
+index 8b7fed913526..22cbfa1bdadd 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
+@@ -170,6 +170,7 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
+       m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT;
+       m->cp_hqd_pq_control |=
+                       ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1;
++      m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK;
+       pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control);
+       m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-amdgpu-gfx11-set-unord_dispatch-in-compute-mqds.patch b/queue-6.7/drm-amdgpu-gfx11-set-unord_dispatch-in-compute-mqds.patch
new file mode 100644 (file)
index 0000000..970d7cf
--- /dev/null
@@ -0,0 +1,52 @@
+From c5e4df9a64e2a43992704435b8caec6d6422c929 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jan 2024 12:32:59 -0500
+Subject: drm/amdgpu/gfx11: set UNORD_DISPATCH in compute MQDs
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 3380fcad2c906872110d31ddf7aa1fdea57f9df6 ]
+
+This needs to be set to 1 to avoid a potential deadlock in
+the GC 10.x and newer.  On GC 9.x and older, this needs
+to be set to 0. This can lead to hangs in some mixed
+graphics and compute workloads. Updated firmware is also
+required for AQL.
+
+Reviewed-by: Feifei Xu <Feifei.Xu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c           | 2 +-
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+index 4824a4c04d35..806a8cf90487 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+@@ -3838,7 +3838,7 @@ static int gfx_v11_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
+                           (order_base_2(prop->queue_size / 4) - 1));
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, RPTR_BLOCK_SIZE,
+                           (order_base_2(AMDGPU_GPU_PAGE_SIZE / 4) - 1));
+-      tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0);
++      tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 1);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH,
+                           prop->allow_tunneling);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1);
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
+index 15277f1d5cf0..d722cbd31783 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
+@@ -224,6 +224,7 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
+       m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT;
+       m->cp_hqd_pq_control |=
+                       ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1;
++      m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK;
+       pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control);
+       m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-panel-edp-add-auo-b116xtn02-boe-nt116whm-n21-836.patch b/queue-6.7/drm-panel-edp-add-auo-b116xtn02-boe-nt116whm-n21-836.patch
new file mode 100644 (file)
index 0000000..b644e35
--- /dev/null
@@ -0,0 +1,50 @@
+From fef3cfe36b19aff9c98113f58e26c5f77b7a1bf2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Oct 2023 11:04:56 +0800
+Subject: drm/panel-edp: Add AUO B116XTN02, BOE NT116WHM-N21,836X2,
+ NV116WHM-N49 V8.0
+
+From: Sheng-Liang Pan <sheng-liang.pan@quanta.corp-partner.google.com>
+
+[ Upstream commit 3db2420422a5912d97966e0176050bb0fc9aa63e ]
+
+Add panel identification entry for
+- AUO B116XTN02 family (product ID:0x235c)
+- BOE NT116WHM-N21,836X2 (product ID:0x09c3)
+- BOE NV116WHM-N49 V8.0 (product ID:0x0979)
+
+Signed-off-by: Sheng-Liang Pan <sheng-liang.pan@quanta.corp-partner.google.com>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231027110435.1.Ia01fe9ec1c0953e0050a232eaa782fef2c037516@changeid
+Stable-dep-of: fc6e76792965 ("drm/panel-edp: drm/panel-edp: Fix AUO B116XAK01 name and timing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/panel-edp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
+index 95c8472d878a..5bf28c8443ef 100644
+--- a/drivers/gpu/drm/panel/panel-edp.c
++++ b/drivers/gpu/drm/panel/panel-edp.c
+@@ -1840,6 +1840,7 @@ static const struct edp_panel_entry edp_panels[] = {
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x145c, &delay_200_500_e50, "B116XAB01.4"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x1e9b, &delay_200_500_e50, "B133UAN02.1"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x1ea5, &delay_200_500_e50, "B116XAK01.6"),
++      EDP_PANEL_ENTRY('A', 'U', 'O', 0x235c, &delay_200_500_e50, "B116XTN02"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x405c, &auo_b116xak01.delay, "B116XAK01"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x582d, &delay_200_500_e50, "B133UAN01.0"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x615c, &delay_200_500_e50, "B116XAN06.1"),
+@@ -1848,8 +1849,10 @@ static const struct edp_panel_entry edp_panels[] = {
+       EDP_PANEL_ENTRY('B', 'O', 'E', 0x0786, &delay_200_500_p2e80, "NV116WHM-T01"),
+       EDP_PANEL_ENTRY('B', 'O', 'E', 0x07d1, &boe_nv133fhm_n61.delay, "NV133FHM-N61"),
+       EDP_PANEL_ENTRY('B', 'O', 'E', 0x082d, &boe_nv133fhm_n61.delay, "NV133FHM-N62"),
++      EDP_PANEL_ENTRY('B', 'O', 'E', 0x09c3, &delay_200_500_e50, "NT116WHM-N21,836X2"),
+       EDP_PANEL_ENTRY('B', 'O', 'E', 0x094b, &delay_200_500_e50, "NT116WHM-N21"),
+       EDP_PANEL_ENTRY('B', 'O', 'E', 0x095f, &delay_200_500_e50, "NE135FBM-N41 v8.1"),
++      EDP_PANEL_ENTRY('B', 'O', 'E', 0x0979, &delay_200_500_e50, "NV116WHM-N49 V8.0"),
+       EDP_PANEL_ENTRY('B', 'O', 'E', 0x098d, &boe_nv110wtm_n61.delay, "NV110WTM-N61"),
+       EDP_PANEL_ENTRY('B', 'O', 'E', 0x09dd, &delay_200_500_e50, "NT116WHM-N21"),
+       EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a5d, &delay_200_500_e50, "NV116WHM-N45"),
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-panel-edp-drm-panel-edp-fix-auo-b116xak01-name-a.patch b/queue-6.7/drm-panel-edp-drm-panel-edp-fix-auo-b116xak01-name-a.patch
new file mode 100644 (file)
index 0000000..922f959
--- /dev/null
@@ -0,0 +1,50 @@
+From e0a3e41ba3a1ad22a9241ce78386a20e0509d782 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Nov 2023 12:41:51 -0800
+Subject: drm/panel-edp: drm/panel-edp: Fix AUO B116XAK01 name and timing
+
+From: Hsin-Yi Wang <hsinyi@chromium.org>
+
+[ Upstream commit fc6e7679296530106ee0954e8ddef1aa58b2e0b5 ]
+
+Rename AUO 0x405c B116XAK01 to B116XAK01.0 and adjust the timing of
+auo_b116xak01: T3=200, T12=500, T7_max = 50 according to decoding edid
+and datasheet.
+
+Fixes: da458286a5e2 ("drm/panel: Add support for AUO B116XAK01 panel")
+Cc: stable@vger.kernel.org
+Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Acked-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231107204611.3082200-2-hsinyi@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/panel-edp.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
+index 5bf28c8443ef..e93e54a98260 100644
+--- a/drivers/gpu/drm/panel/panel-edp.c
++++ b/drivers/gpu/drm/panel/panel-edp.c
+@@ -973,6 +973,8 @@ static const struct panel_desc auo_b116xak01 = {
+       },
+       .delay = {
+               .hpd_absent = 200,
++              .unprepare = 500,
++              .enable = 50,
+       },
+ };
+@@ -1841,7 +1843,7 @@ static const struct edp_panel_entry edp_panels[] = {
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x1e9b, &delay_200_500_e50, "B133UAN02.1"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x1ea5, &delay_200_500_e50, "B116XAK01.6"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x235c, &delay_200_500_e50, "B116XTN02"),
+-      EDP_PANEL_ENTRY('A', 'U', 'O', 0x405c, &auo_b116xak01.delay, "B116XAK01"),
++      EDP_PANEL_ENTRY('A', 'U', 'O', 0x405c, &auo_b116xak01.delay, "B116XAK01.0"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x582d, &delay_200_500_e50, "B133UAN01.0"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x615c, &delay_200_500_e50, "B116XAN06.1"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x8594, &delay_200_500_e50, "B133UAN01.0"),
+-- 
+2.43.0
+
diff --git a/queue-6.7/drm-panel-edp-drm-panel-edp-fix-auo-b116xtn02-name.patch b/queue-6.7/drm-panel-edp-drm-panel-edp-fix-auo-b116xtn02-name.patch
new file mode 100644 (file)
index 0000000..b7b1ac2
--- /dev/null
@@ -0,0 +1,39 @@
+From 04ef1054362241ee73d186893ad8d7be4edeb23e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Nov 2023 12:41:52 -0800
+Subject: drm/panel-edp: drm/panel-edp: Fix AUO B116XTN02 name
+
+From: Hsin-Yi Wang <hsinyi@chromium.org>
+
+[ Upstream commit 962845c090c4f85fa4f6872a5b6c89ee61f53cc0 ]
+
+Rename AUO 0x235c B116XTN02 to B116XTN02.3 according to decoding edid.
+
+Fixes: 3db2420422a5 ("drm/panel-edp: Add AUO B116XTN02, BOE NT116WHM-N21,836X2, NV116WHM-N49 V8.0")
+Cc: stable@vger.kernel.org
+Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Acked-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231107204611.3082200-3-hsinyi@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/panel-edp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
+index e93e54a98260..7dc6fb7308ce 100644
+--- a/drivers/gpu/drm/panel/panel-edp.c
++++ b/drivers/gpu/drm/panel/panel-edp.c
+@@ -1842,7 +1842,7 @@ static const struct edp_panel_entry edp_panels[] = {
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x145c, &delay_200_500_e50, "B116XAB01.4"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x1e9b, &delay_200_500_e50, "B133UAN02.1"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x1ea5, &delay_200_500_e50, "B116XAK01.6"),
+-      EDP_PANEL_ENTRY('A', 'U', 'O', 0x235c, &delay_200_500_e50, "B116XTN02"),
++      EDP_PANEL_ENTRY('A', 'U', 'O', 0x235c, &delay_200_500_e50, "B116XTN02.3"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x405c, &auo_b116xak01.delay, "B116XAK01.0"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x582d, &delay_200_500_e50, "B133UAN01.0"),
+       EDP_PANEL_ENTRY('A', 'U', 'O', 0x615c, &delay_200_500_e50, "B116XAN06.1"),
+-- 
+2.43.0
+
diff --git a/queue-6.7/media-i2c-imx290-properly-encode-registers-as-little.patch b/queue-6.7/media-i2c-imx290-properly-encode-registers-as-little.patch
new file mode 100644 (file)
index 0000000..3bf9137
--- /dev/null
@@ -0,0 +1,102 @@
+From 4a67eff61fc9ba951bb2ccc45dadad9efef47cbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Nov 2023 10:50:48 +0100
+Subject: media: i2c: imx290: Properly encode registers as little-endian
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 60fc87a69523c294eb23a1316af922f6665a6f8c ]
+
+The conversion to CCI also converted the multi-byte register access to
+big-endian. Correct the register definition by using the correct
+little-endian ones.
+
+Fixes: af73323b9770 ("media: imx290: Convert to new CCI register access helpers")
+Cc: stable@vger.kernel.org
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+[Sakari Ailus: Fixed the Fixes: tag.]
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/imx290.c | 42 +++++++++++++++++++-------------------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
+index 29098612813c..c6fea5837a19 100644
+--- a/drivers/media/i2c/imx290.c
++++ b/drivers/media/i2c/imx290.c
+@@ -41,18 +41,18 @@
+ #define IMX290_WINMODE_720P                           (1 << 4)
+ #define IMX290_WINMODE_CROP                           (4 << 4)
+ #define IMX290_FR_FDG_SEL                             CCI_REG8(0x3009)
+-#define IMX290_BLKLEVEL                                       CCI_REG16(0x300a)
++#define IMX290_BLKLEVEL                                       CCI_REG16_LE(0x300a)
+ #define IMX290_GAIN                                   CCI_REG8(0x3014)
+-#define IMX290_VMAX                                   CCI_REG24(0x3018)
++#define IMX290_VMAX                                   CCI_REG24_LE(0x3018)
+ #define IMX290_VMAX_MAX                                       0x3ffff
+-#define IMX290_HMAX                                   CCI_REG16(0x301c)
++#define IMX290_HMAX                                   CCI_REG16_LE(0x301c)
+ #define IMX290_HMAX_MAX                                       0xffff
+-#define IMX290_SHS1                                   CCI_REG24(0x3020)
++#define IMX290_SHS1                                   CCI_REG24_LE(0x3020)
+ #define IMX290_WINWV_OB                                       CCI_REG8(0x303a)
+-#define IMX290_WINPV                                  CCI_REG16(0x303c)
+-#define IMX290_WINWV                                  CCI_REG16(0x303e)
+-#define IMX290_WINPH                                  CCI_REG16(0x3040)
+-#define IMX290_WINWH                                  CCI_REG16(0x3042)
++#define IMX290_WINPV                                  CCI_REG16_LE(0x303c)
++#define IMX290_WINWV                                  CCI_REG16_LE(0x303e)
++#define IMX290_WINPH                                  CCI_REG16_LE(0x3040)
++#define IMX290_WINWH                                  CCI_REG16_LE(0x3042)
+ #define IMX290_OUT_CTRL                                       CCI_REG8(0x3046)
+ #define IMX290_ODBIT_10BIT                            (0 << 0)
+ #define IMX290_ODBIT_12BIT                            (1 << 0)
+@@ -78,28 +78,28 @@
+ #define IMX290_ADBIT2                                 CCI_REG8(0x317c)
+ #define IMX290_ADBIT2_10BIT                           0x12
+ #define IMX290_ADBIT2_12BIT                           0x00
+-#define IMX290_CHIP_ID                                        CCI_REG16(0x319a)
++#define IMX290_CHIP_ID                                        CCI_REG16_LE(0x319a)
+ #define IMX290_ADBIT3                                 CCI_REG8(0x31ec)
+ #define IMX290_ADBIT3_10BIT                           0x37
+ #define IMX290_ADBIT3_12BIT                           0x0e
+ #define IMX290_REPETITION                             CCI_REG8(0x3405)
+ #define IMX290_PHY_LANE_NUM                           CCI_REG8(0x3407)
+ #define IMX290_OPB_SIZE_V                             CCI_REG8(0x3414)
+-#define IMX290_Y_OUT_SIZE                             CCI_REG16(0x3418)
+-#define IMX290_CSI_DT_FMT                             CCI_REG16(0x3441)
++#define IMX290_Y_OUT_SIZE                             CCI_REG16_LE(0x3418)
++#define IMX290_CSI_DT_FMT                             CCI_REG16_LE(0x3441)
+ #define IMX290_CSI_DT_FMT_RAW10                               0x0a0a
+ #define IMX290_CSI_DT_FMT_RAW12                               0x0c0c
+ #define IMX290_CSI_LANE_MODE                          CCI_REG8(0x3443)
+-#define IMX290_EXTCK_FREQ                             CCI_REG16(0x3444)
+-#define IMX290_TCLKPOST                                       CCI_REG16(0x3446)
+-#define IMX290_THSZERO                                        CCI_REG16(0x3448)
+-#define IMX290_THSPREPARE                             CCI_REG16(0x344a)
+-#define IMX290_TCLKTRAIL                              CCI_REG16(0x344c)
+-#define IMX290_THSTRAIL                                       CCI_REG16(0x344e)
+-#define IMX290_TCLKZERO                                       CCI_REG16(0x3450)
+-#define IMX290_TCLKPREPARE                            CCI_REG16(0x3452)
+-#define IMX290_TLPX                                   CCI_REG16(0x3454)
+-#define IMX290_X_OUT_SIZE                             CCI_REG16(0x3472)
++#define IMX290_EXTCK_FREQ                             CCI_REG16_LE(0x3444)
++#define IMX290_TCLKPOST                                       CCI_REG16_LE(0x3446)
++#define IMX290_THSZERO                                        CCI_REG16_LE(0x3448)
++#define IMX290_THSPREPARE                             CCI_REG16_LE(0x344a)
++#define IMX290_TCLKTRAIL                              CCI_REG16_LE(0x344c)
++#define IMX290_THSTRAIL                                       CCI_REG16_LE(0x344e)
++#define IMX290_TCLKZERO                                       CCI_REG16_LE(0x3450)
++#define IMX290_TCLKPREPARE                            CCI_REG16_LE(0x3452)
++#define IMX290_TLPX                                   CCI_REG16_LE(0x3454)
++#define IMX290_X_OUT_SIZE                             CCI_REG16_LE(0x3472)
+ #define IMX290_INCKSEL7                                       CCI_REG8(0x3480)
+ #define IMX290_PGCTRL_REGEN                           BIT(0)
+-- 
+2.43.0
+
diff --git a/queue-6.7/media-v4l-cci-add-macros-to-obtain-register-width-an.patch b/queue-6.7/media-v4l-cci-add-macros-to-obtain-register-width-an.patch
new file mode 100644 (file)
index 0000000..929d683
--- /dev/null
@@ -0,0 +1,79 @@
+From dfa1d7061bf7ad69ab4d8bcc1d0b62825122176a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Nov 2023 17:42:40 +0200
+Subject: media: v4l: cci: Add macros to obtain register width and address
+
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+
+[ Upstream commit cd93cc245dfe334c38da98c14b34f9597e1b4ea6 ]
+
+Add CCI_REG_WIDTH() macro to obtain register width in bits and similarly,
+CCI_REG_WIDTH_BYTES() to obtain it in bytes.
+
+Also add CCI_REG_ADDR() macro to obtain the address of a register.
+
+Use both macros in v4l2-cci.c, too.
+
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Stable-dep-of: d92e7a013ff3 ("media: v4l2-cci: Add support for little-endian encoded registers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/v4l2-core/v4l2-cci.c | 8 ++++----
+ include/media/v4l2-cci.h           | 5 +++++
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-cci.c b/drivers/media/v4l2-core/v4l2-cci.c
+index bc2dbec019b0..3179160abde3 100644
+--- a/drivers/media/v4l2-core/v4l2-cci.c
++++ b/drivers/media/v4l2-core/v4l2-cci.c
+@@ -25,8 +25,8 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
+       if (err && *err)
+               return *err;
+-      len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
+-      reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
++      len = CCI_REG_WIDTH_BYTES(reg);
++      reg = CCI_REG_ADDR(reg);
+       ret = regmap_bulk_read(map, reg, buf, len);
+       if (ret) {
+@@ -75,8 +75,8 @@ int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
+       if (err && *err)
+               return *err;
+-      len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
+-      reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
++      len = CCI_REG_WIDTH_BYTES(reg);
++      reg = CCI_REG_ADDR(reg);
+       switch (len) {
+       case 1:
+diff --git a/include/media/v4l2-cci.h b/include/media/v4l2-cci.h
+index f2c2962e936b..a2835a663df5 100644
+--- a/include/media/v4l2-cci.h
++++ b/include/media/v4l2-cci.h
+@@ -7,6 +7,7 @@
+ #ifndef _V4L2_CCI_H
+ #define _V4L2_CCI_H
++#include <linux/bitfield.h>
+ #include <linux/bits.h>
+ #include <linux/types.h>
+@@ -34,6 +35,10 @@ struct cci_reg_sequence {
+ #define CCI_REG_WIDTH_SHIFT           16
+ #define CCI_REG_WIDTH_MASK            GENMASK(19, 16)
++#define CCI_REG_WIDTH_BYTES(x)                FIELD_GET(CCI_REG_WIDTH_MASK, x)
++#define CCI_REG_WIDTH(x)              (CCI_REG_WIDTH_BYTES(x) << 3)
++#define CCI_REG_ADDR(x)                       FIELD_GET(CCI_REG_ADDR_MASK, x)
++
+ #define CCI_REG8(x)                   ((1 << CCI_REG_WIDTH_SHIFT) | (x))
+ #define CCI_REG16(x)                  ((2 << CCI_REG_WIDTH_SHIFT) | (x))
+ #define CCI_REG24(x)                  ((3 << CCI_REG_WIDTH_SHIFT) | (x))
+-- 
+2.43.0
+
diff --git a/queue-6.7/media-v4l-cci-include-linux-bits.h.patch b/queue-6.7/media-v4l-cci-include-linux-bits.h.patch
new file mode 100644 (file)
index 0000000..5eb2695
--- /dev/null
@@ -0,0 +1,36 @@
+From e14680ec8098db5252e77579073aabf9fe1ce260 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Nov 2023 10:45:30 +0200
+Subject: media: v4l: cci: Include linux/bits.h
+
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+
+[ Upstream commit eba5058633b4d11e2a4d65eae9f1fce0b96365d9 ]
+
+linux/bits.h is needed for GENMASK(). Include it.
+
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Stable-dep-of: d92e7a013ff3 ("media: v4l2-cci: Add support for little-endian encoded registers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/media/v4l2-cci.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/media/v4l2-cci.h b/include/media/v4l2-cci.h
+index 0f6803e4b17e..f2c2962e936b 100644
+--- a/include/media/v4l2-cci.h
++++ b/include/media/v4l2-cci.h
+@@ -7,6 +7,7 @@
+ #ifndef _V4L2_CCI_H
+ #define _V4L2_CCI_H
++#include <linux/bits.h>
+ #include <linux/types.h>
+ struct i2c_client;
+-- 
+2.43.0
+
diff --git a/queue-6.7/media-v4l2-cci-add-support-for-little-endian-encoded.patch b/queue-6.7/media-v4l2-cci-add-support-for-little-endian-encoded.patch
new file mode 100644 (file)
index 0000000..cecca4e
--- /dev/null
@@ -0,0 +1,154 @@
+From 8a9bd313a0dcd8a144265640d7100a3842d3acba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Nov 2023 10:50:47 +0100
+Subject: media: v4l2-cci: Add support for little-endian encoded registers
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit d92e7a013ff33f4e0b31bbf768d0c85a8acefebf ]
+
+Some sensors, e.g. Sony IMX290, are using little-endian registers. Add
+support for those by encoding the endianness into Bit 20 of the register
+address.
+
+Fixes: af73323b9770 ("media: imx290: Convert to new CCI register access helpers")
+Cc: stable@vger.kernel.org
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+[Sakari Ailus: Fixed commit message.]
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/v4l2-core/v4l2-cci.c | 44 ++++++++++++++++++++++++------
+ include/media/v4l2-cci.h           |  5 ++++
+ 2 files changed, 41 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-cci.c b/drivers/media/v4l2-core/v4l2-cci.c
+index 3179160abde3..10005c80f43b 100644
+--- a/drivers/media/v4l2-core/v4l2-cci.c
++++ b/drivers/media/v4l2-core/v4l2-cci.c
+@@ -18,6 +18,7 @@
+ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
+ {
++      bool little_endian;
+       unsigned int len;
+       u8 buf[8];
+       int ret;
+@@ -25,6 +26,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
+       if (err && *err)
+               return *err;
++      little_endian = reg & CCI_REG_LE;
+       len = CCI_REG_WIDTH_BYTES(reg);
+       reg = CCI_REG_ADDR(reg);
+@@ -40,16 +42,28 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
+               *val = buf[0];
+               break;
+       case 2:
+-              *val = get_unaligned_be16(buf);
++              if (little_endian)
++                      *val = get_unaligned_le16(buf);
++              else
++                      *val = get_unaligned_be16(buf);
+               break;
+       case 3:
+-              *val = get_unaligned_be24(buf);
++              if (little_endian)
++                      *val = get_unaligned_le24(buf);
++              else
++                      *val = get_unaligned_be24(buf);
+               break;
+       case 4:
+-              *val = get_unaligned_be32(buf);
++              if (little_endian)
++                      *val = get_unaligned_le32(buf);
++              else
++                      *val = get_unaligned_be32(buf);
+               break;
+       case 8:
+-              *val = get_unaligned_be64(buf);
++              if (little_endian)
++                      *val = get_unaligned_le64(buf);
++              else
++                      *val = get_unaligned_be64(buf);
+               break;
+       default:
+               dev_err(regmap_get_device(map), "Error invalid reg-width %u for reg 0x%04x\n",
+@@ -68,6 +82,7 @@ EXPORT_SYMBOL_GPL(cci_read);
+ int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
+ {
++      bool little_endian;
+       unsigned int len;
+       u8 buf[8];
+       int ret;
+@@ -75,6 +90,7 @@ int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
+       if (err && *err)
+               return *err;
++      little_endian = reg & CCI_REG_LE;
+       len = CCI_REG_WIDTH_BYTES(reg);
+       reg = CCI_REG_ADDR(reg);
+@@ -83,16 +99,28 @@ int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
+               buf[0] = val;
+               break;
+       case 2:
+-              put_unaligned_be16(val, buf);
++              if (little_endian)
++                      put_unaligned_le16(val, buf);
++              else
++                      put_unaligned_be16(val, buf);
+               break;
+       case 3:
+-              put_unaligned_be24(val, buf);
++              if (little_endian)
++                      put_unaligned_le24(val, buf);
++              else
++                      put_unaligned_be24(val, buf);
+               break;
+       case 4:
+-              put_unaligned_be32(val, buf);
++              if (little_endian)
++                      put_unaligned_le32(val, buf);
++              else
++                      put_unaligned_be32(val, buf);
+               break;
+       case 8:
+-              put_unaligned_be64(val, buf);
++              if (little_endian)
++                      put_unaligned_le64(val, buf);
++              else
++                      put_unaligned_be64(val, buf);
+               break;
+       default:
+               dev_err(regmap_get_device(map), "Error invalid reg-width %u for reg 0x%04x\n",
+diff --git a/include/media/v4l2-cci.h b/include/media/v4l2-cci.h
+index a2835a663df5..8b0b361b464c 100644
+--- a/include/media/v4l2-cci.h
++++ b/include/media/v4l2-cci.h
+@@ -38,12 +38,17 @@ struct cci_reg_sequence {
+ #define CCI_REG_WIDTH_BYTES(x)                FIELD_GET(CCI_REG_WIDTH_MASK, x)
+ #define CCI_REG_WIDTH(x)              (CCI_REG_WIDTH_BYTES(x) << 3)
+ #define CCI_REG_ADDR(x)                       FIELD_GET(CCI_REG_ADDR_MASK, x)
++#define CCI_REG_LE                    BIT(20)
+ #define CCI_REG8(x)                   ((1 << CCI_REG_WIDTH_SHIFT) | (x))
+ #define CCI_REG16(x)                  ((2 << CCI_REG_WIDTH_SHIFT) | (x))
+ #define CCI_REG24(x)                  ((3 << CCI_REG_WIDTH_SHIFT) | (x))
+ #define CCI_REG32(x)                  ((4 << CCI_REG_WIDTH_SHIFT) | (x))
+ #define CCI_REG64(x)                  ((8 << CCI_REG_WIDTH_SHIFT) | (x))
++#define CCI_REG16_LE(x)                       (CCI_REG_LE | (2U << CCI_REG_WIDTH_SHIFT) | (x))
++#define CCI_REG24_LE(x)                       (CCI_REG_LE | (3U << CCI_REG_WIDTH_SHIFT) | (x))
++#define CCI_REG32_LE(x)                       (CCI_REG_LE | (4U << CCI_REG_WIDTH_SHIFT) | (x))
++#define CCI_REG64_LE(x)                       (CCI_REG_LE | (8U << CCI_REG_WIDTH_SHIFT) | (x))
+ /**
+  * cci_read() - Read a value from a single CCI register
+-- 
+2.43.0
+
index 5839844e30dbbbcfdeccd6422321e444b8af58f0..7cafca00433d3459d2bef6e9e748ccf128d943a3 100644 (file)
@@ -277,3 +277,29 @@ drm-amdgpu-show-vram-vendor-only-if-available.patch
 drm-amd-pm-update-the-power-cap-setting.patch
 drm-amdgpu-pm-fix-the-power-source-flag-error.patch
 drm-amd-display-fix-uninitialized-variable-usage-in-core_link_-read_dpcd-write_dpcd-functions.patch
+thermal-intel-hfi-refactor-enabling-code-into-helper.patch
+thermal-intel-hfi-disable-an-hfi-instance-when-all-i.patch
+thermal-intel-hfi-add-syscore-callbacks-for-system-w.patch
+media-v4l-cci-include-linux-bits.h.patch
+media-v4l-cci-add-macros-to-obtain-register-width-an.patch
+media-v4l2-cci-add-support-for-little-endian-encoded.patch
+media-i2c-imx290-properly-encode-registers-as-little.patch
+btrfs-zoned-factor-out-prepare_allocation_zoned.patch
+btrfs-zoned-optimize-hint-byte-for-zoned-allocator.patch
+drm-amd-display-do-not-send-commands-to-dmub-if-dmub.patch
+drm-amd-display-refactor-dmcub-enter-exit-idle-inter.patch
+drm-amd-display-wake-dmcub-before-sending-a-command.patch
+drm-amd-display-wake-dmcub-before-executing-gpint-co.patch
+drm-amd-display-fix-conversions-between-bytes-and-kb.patch
+drm-panel-edp-add-auo-b116xtn02-boe-nt116whm-n21-836.patch
+drm-panel-edp-drm-panel-edp-fix-auo-b116xak01-name-a.patch
+drm-panel-edp-drm-panel-edp-fix-auo-b116xtn02-name.patch
+drm-amd-display-fix-hang-underflow-when-transitionin.patch
+drm-amd-display-disconnect-phantom-pipe-opp-from-opt.patch
+drm-amd-display-clear-optc-mem-select-on-disable.patch
+drm-amd-display-add-logging-resource-checks.patch
+drm-amd-display-update-pixel-clock-params-after-stre.patch
+drm-amd-display-init-link-enc-resources-in-dc_state-.patch
+drm-amdgpu-enable-tunneling-on-high-priority-compute.patch
+drm-amdgpu-gfx10-set-unord_dispatch-in-compute-mqds.patch
+drm-amdgpu-gfx11-set-unord_dispatch-in-compute-mqds.patch
diff --git a/queue-6.7/thermal-intel-hfi-add-syscore-callbacks-for-system-w.patch b/queue-6.7/thermal-intel-hfi-add-syscore-callbacks-for-system-w.patch
new file mode 100644 (file)
index 0000000..1d4dd9d
--- /dev/null
@@ -0,0 +1,101 @@
+From 49cd51dd1a6c35f57633ae76718ba7e45b1dded0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jan 2024 19:07:04 -0800
+Subject: thermal: intel: hfi: Add syscore callbacks for system-wide PM
+
+From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
+
+[ Upstream commit 97566d09fd02d2ab329774bb89a2cdf2267e86d9 ]
+
+The kernel allocates a memory buffer and provides its location to the
+hardware, which uses it to update the HFI table. This allocation occurs
+during boot and remains constant throughout runtime.
+
+When resuming from hibernation, the restore kernel allocates a second
+memory buffer and reprograms the HFI hardware with the new location as
+part of a normal boot. The location of the second memory buffer may
+differ from the one allocated by the image kernel.
+
+When the restore kernel transfers control to the image kernel, its HFI
+buffer becomes invalid, potentially leading to memory corruption if the
+hardware writes to it (the hardware continues to use the buffer from the
+restore kernel).
+
+It is also possible that the hardware "forgets" the address of the memory
+buffer when resuming from "deep" suspend. Memory corruption may also occur
+in such a scenario.
+
+To prevent the described memory corruption, disable HFI when preparing to
+suspend or hibernate. Enable it when resuming.
+
+Add syscore callbacks to handle the package of the boot CPU (packages of
+non-boot CPUs are handled via CPU offline). Syscore ops always run on the
+boot CPU. Additionally, HFI only needs to be disabled during "deep" suspend
+and hibernation. Syscore ops only run in these cases.
+
+Cc: 6.1+ <stable@vger.kernel.org> # 6.1+
+Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
+[ rjw: Comment adjustment, subject and changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/intel/intel_hfi.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/drivers/thermal/intel/intel_hfi.c b/drivers/thermal/intel/intel_hfi.c
+index bb25c75acd45..1c5a429b2e3e 100644
+--- a/drivers/thermal/intel/intel_hfi.c
++++ b/drivers/thermal/intel/intel_hfi.c
+@@ -35,7 +35,9 @@
+ #include <linux/processor.h>
+ #include <linux/slab.h>
+ #include <linux/spinlock.h>
++#include <linux/suspend.h>
+ #include <linux/string.h>
++#include <linux/syscore_ops.h>
+ #include <linux/topology.h>
+ #include <linux/workqueue.h>
+@@ -568,6 +570,30 @@ static __init int hfi_parse_features(void)
+       return 0;
+ }
++static void hfi_do_enable(void)
++{
++      /* This code runs only on the boot CPU. */
++      struct hfi_cpu_info *info = &per_cpu(hfi_cpu_info, 0);
++      struct hfi_instance *hfi_instance = info->hfi_instance;
++
++      /* No locking needed. There is no concurrency with CPU online. */
++      hfi_set_hw_table(hfi_instance);
++      hfi_enable();
++}
++
++static int hfi_do_disable(void)
++{
++      /* No locking needed. There is no concurrency with CPU offline. */
++      hfi_disable();
++
++      return 0;
++}
++
++static struct syscore_ops hfi_pm_ops = {
++      .resume = hfi_do_enable,
++      .suspend = hfi_do_disable,
++};
++
+ void __init intel_hfi_init(void)
+ {
+       struct hfi_instance *hfi_instance;
+@@ -599,6 +625,8 @@ void __init intel_hfi_init(void)
+       if (!hfi_updates_wq)
+               goto err_nomem;
++      register_syscore_ops(&hfi_pm_ops);
++
+       return;
+ err_nomem:
+-- 
+2.43.0
+
diff --git a/queue-6.7/thermal-intel-hfi-disable-an-hfi-instance-when-all-i.patch b/queue-6.7/thermal-intel-hfi-disable-an-hfi-instance-when-all-i.patch
new file mode 100644 (file)
index 0000000..16a2559
--- /dev/null
@@ -0,0 +1,98 @@
+From b4b1a43d74d6acd1d9924bf0fb72c6c5a87c2a47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jan 2024 20:14:58 -0800
+Subject: thermal: intel: hfi: Disable an HFI instance when all its CPUs go
+ offline
+
+From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
+
+[ Upstream commit 1c53081d773c2cb4461636559b0d55b46559ceec ]
+
+In preparation to support hibernation, add functionality to disable an HFI
+instance during CPU offline. The last CPU of an instance that goes offline
+will disable such instance.
+
+The Intel Software Development Manual states that the operating system must
+wait for the hardware to set MSR_IA32_PACKAGE_THERM_STATUS[26] after
+disabling an HFI instance to ensure that it will no longer write on the HFI
+memory. Some processors, however, do not ever set such bit. Wait a minimum
+of 2ms to give time hardware to complete any pending memory writes.
+
+Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 97566d09fd02 ("thermal: intel: hfi: Add syscore callbacks for system-wide PM")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/intel/intel_hfi.c | 35 +++++++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+diff --git a/drivers/thermal/intel/intel_hfi.c b/drivers/thermal/intel/intel_hfi.c
+index 820613e293cd..bb25c75acd45 100644
+--- a/drivers/thermal/intel/intel_hfi.c
++++ b/drivers/thermal/intel/intel_hfi.c
+@@ -24,6 +24,7 @@
+ #include <linux/bitops.h>
+ #include <linux/cpufeature.h>
+ #include <linux/cpumask.h>
++#include <linux/delay.h>
+ #include <linux/gfp.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
+@@ -367,6 +368,32 @@ static void hfi_set_hw_table(struct hfi_instance *hfi_instance)
+       wrmsrl(MSR_IA32_HW_FEEDBACK_PTR, msr_val);
+ }
++/* Caller must hold hfi_instance_lock. */
++static void hfi_disable(void)
++{
++      u64 msr_val;
++      int i;
++
++      rdmsrl(MSR_IA32_HW_FEEDBACK_CONFIG, msr_val);
++      msr_val &= ~HW_FEEDBACK_CONFIG_HFI_ENABLE_BIT;
++      wrmsrl(MSR_IA32_HW_FEEDBACK_CONFIG, msr_val);
++
++      /*
++       * Wait for hardware to acknowledge the disabling of HFI. Some
++       * processors may not do it. Wait for ~2ms. This is a reasonable
++       * time for hardware to complete any pending actions on the HFI
++       * memory.
++       */
++      for (i = 0; i < 2000; i++) {
++              rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
++              if (msr_val & PACKAGE_THERM_STATUS_HFI_UPDATED)
++                      break;
++
++              udelay(1);
++              cpu_relax();
++      }
++}
++
+ /**
+  * intel_hfi_online() - Enable HFI on @cpu
+  * @cpu:      CPU in which the HFI will be enabled
+@@ -421,6 +448,10 @@ void intel_hfi_online(unsigned int cpu)
+       /*
+        * Hardware is programmed with the physical address of the first page
+        * frame of the table. Hence, the allocated memory must be page-aligned.
++       *
++       * Some processors do not forget the initial address of the HFI table
++       * even after having been reprogrammed. Keep using the same pages. Do
++       * not free them.
+        */
+       hfi_instance->hw_table = alloc_pages_exact(hfi_features.nr_table_pages,
+                                                  GFP_KERNEL | __GFP_ZERO);
+@@ -485,6 +516,10 @@ void intel_hfi_offline(unsigned int cpu)
+       mutex_lock(&hfi_instance_lock);
+       cpumask_clear_cpu(cpu, hfi_instance->cpus);
++
++      if (!cpumask_weight(hfi_instance->cpus))
++              hfi_disable();
++
+       mutex_unlock(&hfi_instance_lock);
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.7/thermal-intel-hfi-refactor-enabling-code-into-helper.patch b/queue-6.7/thermal-intel-hfi-refactor-enabling-code-into-helper.patch
new file mode 100644 (file)
index 0000000..6b1f57c
--- /dev/null
@@ -0,0 +1,108 @@
+From 3f92b215d8655b6745095ad5f194b5935a5e8096 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jan 2024 20:14:56 -0800
+Subject: thermal: intel: hfi: Refactor enabling code into helper functions
+
+From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
+
+[ Upstream commit 8a8b6bb93c704776c4b05cb517c3fa8baffb72f5 ]
+
+In preparation for the addition of a suspend notifier, wrap the logic to
+enable HFI and program its memory buffer into helper functions. Both the
+CPU hotplug callback and the suspend notifier will use them.
+
+This refactoring does not introduce functional changes.
+
+Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 97566d09fd02 ("thermal: intel: hfi: Add syscore callbacks for system-wide PM")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/intel/intel_hfi.c | 43 ++++++++++++++++---------------
+ 1 file changed, 22 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/thermal/intel/intel_hfi.c b/drivers/thermal/intel/intel_hfi.c
+index c69db6c90869..820613e293cd 100644
+--- a/drivers/thermal/intel/intel_hfi.c
++++ b/drivers/thermal/intel/intel_hfi.c
+@@ -347,6 +347,26 @@ static void init_hfi_instance(struct hfi_instance *hfi_instance)
+       hfi_instance->data = hfi_instance->hdr + hfi_features.hdr_size;
+ }
++/* Caller must hold hfi_instance_lock. */
++static void hfi_enable(void)
++{
++      u64 msr_val;
++
++      rdmsrl(MSR_IA32_HW_FEEDBACK_CONFIG, msr_val);
++      msr_val |= HW_FEEDBACK_CONFIG_HFI_ENABLE_BIT;
++      wrmsrl(MSR_IA32_HW_FEEDBACK_CONFIG, msr_val);
++}
++
++static void hfi_set_hw_table(struct hfi_instance *hfi_instance)
++{
++      phys_addr_t hw_table_pa;
++      u64 msr_val;
++
++      hw_table_pa = virt_to_phys(hfi_instance->hw_table);
++      msr_val = hw_table_pa | HW_FEEDBACK_PTR_VALID_BIT;
++      wrmsrl(MSR_IA32_HW_FEEDBACK_PTR, msr_val);
++}
++
+ /**
+  * intel_hfi_online() - Enable HFI on @cpu
+  * @cpu:      CPU in which the HFI will be enabled
+@@ -364,8 +384,6 @@ void intel_hfi_online(unsigned int cpu)
+ {
+       struct hfi_instance *hfi_instance;
+       struct hfi_cpu_info *info;
+-      phys_addr_t hw_table_pa;
+-      u64 msr_val;
+       u16 die_id;
+       /* Nothing to do if hfi_instances are missing. */
+@@ -409,8 +427,6 @@ void intel_hfi_online(unsigned int cpu)
+       if (!hfi_instance->hw_table)
+               goto unlock;
+-      hw_table_pa = virt_to_phys(hfi_instance->hw_table);
+-
+       /*
+        * Allocate memory to keep a local copy of the table that
+        * hardware generates.
+@@ -420,16 +436,6 @@ void intel_hfi_online(unsigned int cpu)
+       if (!hfi_instance->local_table)
+               goto free_hw_table;
+-      /*
+-       * Program the address of the feedback table of this die/package. On
+-       * some processors, hardware remembers the old address of the HFI table
+-       * even after having been reprogrammed and re-enabled. Thus, do not free
+-       * the pages allocated for the table or reprogram the hardware with a
+-       * new base address. Namely, program the hardware only once.
+-       */
+-      msr_val = hw_table_pa | HW_FEEDBACK_PTR_VALID_BIT;
+-      wrmsrl(MSR_IA32_HW_FEEDBACK_PTR, msr_val);
+-
+       init_hfi_instance(hfi_instance);
+       INIT_DELAYED_WORK(&hfi_instance->update_work, hfi_update_work_fn);
+@@ -438,13 +444,8 @@ void intel_hfi_online(unsigned int cpu)
+       cpumask_set_cpu(cpu, hfi_instance->cpus);
+-      /*
+-       * Enable the hardware feedback interface and never disable it. See
+-       * comment on programming the address of the table.
+-       */
+-      rdmsrl(MSR_IA32_HW_FEEDBACK_CONFIG, msr_val);
+-      msr_val |= HW_FEEDBACK_CONFIG_HFI_ENABLE_BIT;
+-      wrmsrl(MSR_IA32_HW_FEEDBACK_CONFIG, msr_val);
++      hfi_set_hw_table(hfi_instance);
++      hfi_enable();
+ unlock:
+       mutex_unlock(&hfi_instance_lock);
+-- 
+2.43.0
+