HUBP only exists on DCN. On ASICs that use DCE, such as Vega20, the display
pipe never owns a HUBP, so pipe_ctx->plane_res.hubp stays NULL.

The block sequence rework now fills mpcc_id inside the generic helpers in
dc_hw_sequencer.c by reading pipe_ctx->plane_res.hubp->inst. On a DCE ASIC
that read follows the NULL pointer and faults at offset 0x88, where the
inst field sits in struct hubp, and the box dies on the first modeset:

  BUG: kernel NULL pointer dereference, address: 0000000000000088
  #PF: supervisor read access in kernel mode
  Oops: 0000 [#1] SMP NOPTI
  CPU: 14 UID: 0 PID: 531 Comm: plymouthd Not tainted 7.1.0 #70
  RIP: 0010:hwss_set_output_transfer_func+0x69/0xc0 [amdgpu]
  Call Trace:
   dce110_program_front_end_for_pipe+0x4d7/0x5c0 [amdgpu]
   dce110_apply_ctx_for_surface+0xf1/0x270 [amdgpu]
   commit_planes_for_stream+0xba1/0x1c80 [amdgpu]
   update_planes_and_stream_v2+0x297/0x6f0 [amdgpu]
   dc_update_state_prepare+0x6f/0x1c0 [amdgpu]
   dc_update_state+0x41/0x60 [amdgpu]
   dc_update_planes_and_stream+0x43/0x70 [amdgpu]
   amdgpu_dm_atomic_commit_tail+0x1a6f/0x4120 [amdgpu]
   commit_tail+0xc5/0x1a0
   drm_atomic_helper_commit+0x137/0x160
   drm_atomic_commit+0xaf/0xf0
   drm_client_modeset_commit_atomic+0x1ec/0x230
   drm_client_modeset_commit_locked+0x5b/0x170
   drm_client_modeset_commit+0x27/0x50
   __drm_fb_helper_restore_fbdev_mode_unlocked+0xe8/0x110
   drm_fbdev_client_restore+0x12/0x20
   drm_client_dev_restore+0xbb/0x100

DCE never uses mpcc_id, so 0 is a fine value when there is no HUBP. Add a
small helper that returns the HUBP instance, or 0 when it is missing, and
use it for every mpcc_id assignment. DCN is unchanged since HUBP is always
there.

Fixes: f879f53407f0 ("drm/amd/display: Refactor DPP_SET_OUTPUT_TRANSFER_FUNC to 
drop pipe_ctx")
Fixes: 9403e15b2ab1 ("drm/amd/display: Refactor DPP_PROGRAM_GAMUT_REMAP to drop 
pipe_ctx param")
Cc: Tomasz Siemek <[email protected]>
Cc: Wayne Lin <[email protected]>
Cc: Alvin Lee <[email protected]>
Signed-off-by: Honglei Huang <[email protected]>
---
 .../drm/amd/display/dc/core/dc_hw_sequencer.c | 26 +++++++++++++------
 1 file changed, 18 insertions(+), 8 deletions(-)

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 11411fa946..7676aa4485 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
@@ -729,6 +729,16 @@ void get_fams2_visual_confirm_color(
        }
 }
 
+/*
+ * Return the MPCC instance for a pipe. On DCN it matches the HUBP instance.
+ * DCE has no HUBP and ignores mpcc_id, so return 0 there instead of chasing a
+ * NULL pointer.
+ */
+static int hwss_pipe_mpcc_id(const struct pipe_ctx *pipe_ctx)
+{
+       return pipe_ctx->plane_res.hubp ? pipe_ctx->plane_res.hubp->inst : 0;
+}
+
 void hwss_build_fast_sequence(struct dc *dc,
                struct dc_dmub_cmd *dc_dmub_cmd,
                unsigned int dmub_cmd_count,
@@ -1073,7 +1083,7 @@ void hwss_build_fast_sequence(struct dc *dc,
                                        params->dpp = 
current_mpc_pipe->plane_res.dpp;
                                        params->mpc = dc->res_pool->mpc;
                                        params->xfm = 
current_mpc_pipe->plane_res.xfm;
-                                       params->mpcc_id = 
current_mpc_pipe->plane_res.hubp->inst;
+                                       params->mpcc_id = 
hwss_pipe_mpcc_id(current_mpc_pipe);
                                        params->plane = 
current_mpc_pipe->plane_state;
                                        params->stream = 
current_mpc_pipe->stream;
                                        params->is_top_pipe = 
current_mpc_pipe->top_pipe == NULL;
@@ -1118,7 +1128,7 @@ void hwss_build_fast_sequence(struct dc *dc,
                                otf_params->dpp = 
current_mpc_pipe->plane_res.dpp;
                                otf_params->xfm = 
current_mpc_pipe->plane_res.xfm;
                                otf_params->mpc = dc->res_pool->mpc;
-                               otf_params->mpcc_id = 
current_mpc_pipe->plane_res.hubp->inst;
+                               otf_params->mpcc_id = 
hwss_pipe_mpcc_id(current_mpc_pipe);
                                otf_params->is_top_pipe = 
resource_is_pipe_type(current_mpc_pipe, OPP_HEAD);
                                otf_params->stream = current_mpc_pipe->stream;
                                block_sequence[*num_steps].func = 
DPP_SET_OUTPUT_TRANSFER_FUNC;
@@ -1128,13 +1138,13 @@ void hwss_build_fast_sequence(struct dc *dc,
                                dc->hwss.update_visual_confirm_color) {
                                
block_sequence[*num_steps].params.update_visual_confirm_params.dc = dc;
                                
block_sequence[*num_steps].params.update_visual_confirm_params.pipe_ctx = 
current_mpc_pipe;
-                               
block_sequence[*num_steps].params.update_visual_confirm_params.mpcc_id = 
current_mpc_pipe->plane_res.hubp->inst;
+                               
block_sequence[*num_steps].params.update_visual_confirm_params.mpcc_id = 
hwss_pipe_mpcc_id(current_mpc_pipe);
                                block_sequence[*num_steps].func = 
MPC_UPDATE_VISUAL_CONFIRM;
                                (*num_steps)++;
                        }
                        if 
(current_mpc_pipe->stream->update_flags.bits.out_csc) {
                                
block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.mpc = 
dc->res_pool->mpc;
-                               
block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.mpcc_id = 
current_mpc_pipe->plane_res.hubp->inst;
+                               
block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.mpcc_id = 
hwss_pipe_mpcc_id(current_mpc_pipe);
                                
block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.power_on = true;
                                block_sequence[*num_steps].func = 
MPC_POWER_ON_MPC_MEM_PWR;
                                (*num_steps)++;
@@ -1837,7 +1847,7 @@ void hwss_add_dpp_program_gamut_remap(struct 
block_sequence_state *seq_state,
                params->xfm = pipe_ctx->plane_res.xfm;
                params->dpp = pipe_ctx->plane_res.dpp;
                params->mpc = pipe_ctx->stream->ctx->dc->res_pool->mpc;
-               params->mpcc_id = pipe_ctx->plane_res.hubp->inst;
+               params->mpcc_id = hwss_pipe_mpcc_id(pipe_ctx);
                params->plane = pipe_ctx->plane_state;
                params->stream = pipe_ctx->stream;
                params->is_top_pipe = pipe_ctx->top_pipe == NULL;
@@ -1883,7 +1893,7 @@ void hwss_add_dpp_set_output_transfer_func(struct 
block_sequence_state *seq_stat
                        .xfm = pipe_ctx->plane_res.xfm,
                        .dpp = pipe_ctx->plane_res.dpp,
                        .mpc = dc->res_pool->mpc,
-                       .mpcc_id = pipe_ctx->plane_res.hubp->inst,
+                       .mpcc_id = hwss_pipe_mpcc_id(pipe_ctx),
                        .is_top_pipe = resource_is_pipe_type(pipe_ctx, 
OPP_HEAD),
                        .stream = pipe_ctx->stream,
                };
@@ -1900,7 +1910,7 @@ void hwss_set_output_transfer_func(struct dc *dc, struct 
pipe_ctx *pipe_ctx)
                                .xfm = pipe_ctx->plane_res.xfm,
                                .dpp = pipe_ctx->plane_res.dpp,
                                .mpc = dc->res_pool->mpc,
-                               .mpcc_id = pipe_ctx->plane_res.hubp->inst,
+                               .mpcc_id = hwss_pipe_mpcc_id(pipe_ctx),
                                .is_top_pipe = resource_is_pipe_type(pipe_ctx, 
OPP_HEAD),
                                .stream = pipe_ctx->stream,
                        }
@@ -3840,7 +3850,7 @@ void hwss_program_gamut_remap(struct pipe_ctx *pipe_ctx)
                        .xfm = pipe_ctx->plane_res.xfm,
                        .dpp = pipe_ctx->plane_res.dpp,
                        .mpc = dc->res_pool->mpc,
-                       .mpcc_id = pipe_ctx->plane_res.hubp->inst,
+                       .mpcc_id = hwss_pipe_mpcc_id(pipe_ctx),
                        .stream = pipe_ctx->stream,
                        .plane = pipe_ctx->plane_state,
                        .is_top_pipe = pipe_ctx->top_pipe == NULL,
-- 
2.34.1

Reply via email to