This adds panic support for DCE based IPs.

Signed-off-by: Alex Deucher <[email protected]>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 73 ++++++++++++++++---
 .../drm/amd/display/dc/dce/dce_mem_input.c    | 34 +++++++--
 .../gpu/drm/amd/display/dc/inc/hw/mem_input.h |  2 +
 3 files changed, 92 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 60606b36f07b..5421d48be9f1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1523,22 +1523,71 @@ static void amdgpu_dm_plane_panic_flush(struct 
drm_plane *plane)
        for (i = 0; i < dc->res_pool->pipe_count; i++) {
                struct pipe_ctx *pipe_ctx = 
&dc->current_state->res_ctx.pipe_ctx[i];
                struct hubp *hubp;
+               struct mem_input *mi;
 
                if (!pipe_ctx)
                        continue;
 
-               hubp = pipe_ctx->plane_res.hubp;
-               if (!hubp)
-                       continue;
-
-               /* if framebuffer is tiled, disable tiling */
-               if (fb->modifier && hubp->funcs->hubp_clear_tiling)
-                       hubp->funcs->hubp_clear_tiling(hubp);
-
-               /* force page flip to see the new content of the framebuffer */
-               hubp->funcs->hubp_program_surface_flip_and_addr(hubp,
-                                                               
&dc_plane_state->address,
-                                                               true);
+               switch (dc->ctx->dce_version) {
+#if defined(CONFIG_DRM_AMD_DC_SI)
+               case DCE_VERSION_6_0:
+               case DCE_VERSION_6_1:
+               case DCE_VERSION_6_4:
+#endif
+               case DCE_VERSION_8_0:
+               case DCE_VERSION_8_1:
+               case DCE_VERSION_8_3:
+               case DCE_VERSION_10_0:
+               case DCE_VERSION_11_0:
+               case DCE_VERSION_11_2:
+               case DCE_VERSION_11_22:
+               case DCE_VERSION_12_0:
+               case DCE_VERSION_12_1:
+                       mi = pipe_ctx->plane_res.mi;
+                       if (!mi)
+                               continue;
+                       /* if framebuffer is tiled, disable tiling */
+                       if (fb->modifier && mi->funcs->mem_input_clear_tiling)
+                               mi->funcs->mem_input_clear_tiling(mi);
+
+                       /* force page flip to see the new content of the 
framebuffer */
+                       mi->funcs->mem_input_program_surface_flip_and_addr(mi,
+                                                                          
&dc_plane_state->address,
+                                                                          
true);
+                       break;
+               case DCN_VERSION_1_0:
+               case DCN_VERSION_1_01:
+               case DCN_VERSION_2_0:
+               case DCN_VERSION_2_01:
+               case DCN_VERSION_2_1:
+               case DCN_VERSION_3_0:
+               case DCN_VERSION_3_01:
+               case DCN_VERSION_3_02:
+               case DCN_VERSION_3_03:
+               case DCN_VERSION_3_1:
+               case DCN_VERSION_3_14:
+               case DCN_VERSION_3_16:
+               case DCN_VERSION_3_15:
+               case DCN_VERSION_3_2:
+               case DCN_VERSION_3_21:
+               case DCN_VERSION_3_5:
+               case DCN_VERSION_3_51:
+               case DCN_VERSION_4_01:
+                       hubp = pipe_ctx->plane_res.hubp;
+                       if (!hubp)
+                               continue;
+                       /* if framebuffer is tiled, disable tiling */
+                       if (fb->modifier && hubp->funcs->hubp_clear_tiling)
+                               hubp->funcs->hubp_clear_tiling(hubp);
+
+                       /* force page flip to see the new content of the 
framebuffer */
+                       hubp->funcs->hubp_program_surface_flip_and_addr(hubp,
+                                                                       
&dc_plane_state->address,
+                                                                       true);
+                       break;
+               default:
+                       break;;
+               }
        }
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c 
b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
index f5e1d9caee4c..ebd174be5786 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
@@ -481,7 +481,6 @@ static void program_tiling(
        }
 }
 
-
 static void program_size_and_rotation(
        struct dce_mem_input *dce_mi,
        enum dc_rotation_angle rotation,
@@ -627,6 +626,27 @@ static void program_grph_pixel_format(
                        GRPH_PRESCALE_B_SIGN, sign);
 }
 
+static void dce_mi_clear_tiling(
+       struct mem_input *mi)
+{
+       struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
+
+       if (dce_mi->masks->GRPH_SW_MODE) { /* GFX9 */
+               REG_UPDATE(GRPH_CONTROL,
+                          GRPH_SW_MODE, DC_SW_LINEAR);
+       }
+
+       if (dce_mi->masks->GRPH_MICRO_TILE_MODE) { /* GFX8 */
+               REG_UPDATE(GRPH_CONTROL,
+                          GRPH_ARRAY_MODE, DC_SW_LINEAR);
+       }
+
+       if (dce_mi->masks->GRPH_ARRAY_MODE) { /* GFX6 but reuses gfx8 struct */
+               REG_UPDATE(GRPH_CONTROL,
+                          GRPH_ARRAY_MODE, DC_SW_LINEAR);
+       }
+}
+
 static void dce_mi_program_surface_config(
        struct mem_input *mi,
        enum surface_pixel_format format,
@@ -884,7 +904,8 @@ static const struct mem_input_funcs dce_mi_funcs = {
        .mem_input_program_pte_vm = dce_mi_program_pte_vm,
        .mem_input_program_surface_config =
                        dce_mi_program_surface_config,
-       .mem_input_is_flip_pending = dce_mi_is_flip_pending
+       .mem_input_is_flip_pending = dce_mi_is_flip_pending,
+       .mem_input_clear_tiling = dce_mi_clear_tiling,
 };
 
 #if defined(CONFIG_DRM_AMD_DC_SI)
@@ -897,7 +918,8 @@ static const struct mem_input_funcs dce60_mi_funcs = {
        .mem_input_program_pte_vm = dce_mi_program_pte_vm,
        .mem_input_program_surface_config =
                        dce60_mi_program_surface_config,
-       .mem_input_is_flip_pending = dce_mi_is_flip_pending
+       .mem_input_is_flip_pending = dce_mi_is_flip_pending,
+       .mem_input_clear_tiling = dce_mi_clear_tiling,
 };
 #endif
 
@@ -910,7 +932,8 @@ static const struct mem_input_funcs dce112_mi_funcs = {
        .mem_input_program_pte_vm = dce_mi_program_pte_vm,
        .mem_input_program_surface_config =
                        dce_mi_program_surface_config,
-       .mem_input_is_flip_pending = dce_mi_is_flip_pending
+       .mem_input_is_flip_pending = dce_mi_is_flip_pending,
+       .mem_input_clear_tiling = dce_mi_clear_tiling,
 };
 
 static const struct mem_input_funcs dce120_mi_funcs = {
@@ -922,7 +945,8 @@ static const struct mem_input_funcs dce120_mi_funcs = {
        .mem_input_program_pte_vm = dce_mi_program_pte_vm,
        .mem_input_program_surface_config =
                        dce_mi_program_surface_config,
-       .mem_input_is_flip_pending = dce_mi_is_flip_pending
+       .mem_input_is_flip_pending = dce_mi_is_flip_pending,
+       .mem_input_clear_tiling = dce_mi_clear_tiling,
 };
 
 void dce_mem_input_construct(
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
index a8b44f398ce6..4f5d102455ca 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
@@ -187,6 +187,8 @@ struct mem_input_funcs {
                        const struct dc_cursor_position *pos,
                        const struct dc_cursor_mi_param *param);
 
+       void (*mem_input_clear_tiling)(
+               struct mem_input *mem_input);
 };
 
 #endif
-- 
2.47.0

Reply via email to