From: Jocelyn Falempe <jfalempe@xxxxxxxxxx> Add support for the drm_panic module, which displays a pretty user friendly message on the screen when a Linux kernel panic occurs. It doesn't work yet on laptop panels, maybe due to PSR. Adapted from Jocelyn's original patch to add DC drm_panic support. Signed-off-by: Jocelyn Falempe <jfalempe@xxxxxxxxxx> Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx> Cc: Lu Yao <yaolu@xxxxxxxxxx> Cc: Jocelyn Falempe <jfalempe@xxxxxxxxxx> --- .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 103 +++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) 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 495e3cd70426..5ba64e7ad3f3 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 @@ -26,6 +26,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_blend.h> +#include "drm/drm_framebuffer.h" #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_plane_helper.h> #include <drm/drm_gem_framebuffer_helper.h> @@ -1421,6 +1422,93 @@ static void amdgpu_dm_plane_atomic_async_update(struct drm_plane *plane, amdgpu_dm_plane_handle_cursor_update(plane, old_state); } +static void amdgpu_dm_plane_panic_flush(struct drm_plane *plane) +{ + struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane->state); + struct drm_framebuffer *fb = plane->state->fb; + struct dc_plane_state *dc_plane_state; + struct dc *dc; + int i; + + if (!dm_plane_state || !dm_plane_state->dc_state) + return; + + dc_plane_state = dm_plane_state->dc_state; + dc = dc_plane_state->ctx->dc; + if (!dc || !dc->current_state) + return; + + 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; + + 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; + } + } +} + static const struct drm_plane_helper_funcs dm_plane_helper_funcs = { .prepare_fb = amdgpu_dm_plane_helper_prepare_fb, .cleanup_fb = amdgpu_dm_plane_helper_cleanup_fb, @@ -1429,6 +1517,16 @@ static const struct drm_plane_helper_funcs dm_plane_helper_funcs = { .atomic_async_update = amdgpu_dm_plane_atomic_async_update }; +static const struct drm_plane_helper_funcs dm_primary_plane_helper_funcs = { + .prepare_fb = amdgpu_dm_plane_helper_prepare_fb, + .cleanup_fb = amdgpu_dm_plane_helper_cleanup_fb, + .atomic_check = amdgpu_dm_plane_atomic_check, + .atomic_async_check = amdgpu_dm_plane_atomic_async_check, + .atomic_async_update = amdgpu_dm_plane_atomic_async_update, + .get_scanout_buffer = amdgpu_display_get_scanout_buffer, + .panic_flush = amdgpu_dm_plane_panic_flush, +}; + static void amdgpu_dm_plane_drm_plane_reset(struct drm_plane *plane) { struct dm_plane_state *amdgpu_state = NULL; @@ -1855,7 +1953,10 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, plane->type != DRM_PLANE_TYPE_CURSOR) drm_plane_enable_fb_damage_clips(plane); - drm_plane_helper_add(plane, &dm_plane_helper_funcs); + if (plane->type == DRM_PLANE_TYPE_PRIMARY) + drm_plane_helper_add(plane, &dm_primary_plane_helper_funcs); + else + drm_plane_helper_add(plane, &dm_plane_helper_funcs); #ifdef AMD_PRIVATE_COLOR dm_atomic_plane_attach_color_mgmt_properties(dm, plane); -- 2.47.0