]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amd/display: add non-DC drm_panic support
authorAlex Deucher <alexander.deucher@amd.com>
Thu, 31 Oct 2024 17:51:35 +0000 (13:51 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 18 Dec 2024 17:16:01 +0000 (12:16 -0500)
Add support for the drm_panic module, which displays a pretty user
friendly message on the screen when a Linux kernel panic occurs.

Adapt Lu Yao's code to use common helpers derived from
Jocelyn's patch.  This extends the non-DC code to enable
access to non-CPU accessible VRAM and adds support for
other DCE versions.

Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: Lu Yao <yaolu@kylinos.cn>
Cc: Jocelyn Falempe <jfalempe@redhat.com>
Cc: Harry Wentland <harry.wentland@amd.com>
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c

index 8bc997b664244b1d1df0ad5c7338b0578fd435c1..c5e3d2251b18cf02f9bb406fc90a395cc862b653 100644 (file)
@@ -2687,6 +2687,32 @@ static const struct drm_crtc_helper_funcs dce_v10_0_crtc_helper_funcs = {
        .get_scanout_position = amdgpu_crtc_get_scanout_position,
 };
 
+static void dce_v10_0_panic_flush(struct drm_plane *plane)
+{
+       struct drm_framebuffer *fb;
+       struct amdgpu_crtc *amdgpu_crtc;
+       struct amdgpu_device *adev;
+       uint32_t fb_format;
+
+       if (!plane->fb)
+               return;
+
+       fb = plane->fb;
+       amdgpu_crtc = to_amdgpu_crtc(plane->crtc);
+       adev = drm_to_adev(fb->dev);
+
+       /* Disable DC tiling */
+       fb_format = RREG32(mmGRPH_CONTROL + amdgpu_crtc->crtc_offset);
+       fb_format &= ~GRPH_CONTROL__GRPH_ARRAY_MODE_MASK;
+       WREG32(mmGRPH_CONTROL + amdgpu_crtc->crtc_offset, fb_format);
+
+}
+
+static const struct drm_plane_helper_funcs dce_v10_0_drm_primary_plane_helper_funcs = {
+       .get_scanout_buffer = amdgpu_display_get_scanout_buffer,
+       .panic_flush = dce_v10_0_panic_flush,
+};
+
 static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)
 {
        struct amdgpu_crtc *amdgpu_crtc;
@@ -2734,6 +2760,7 @@ static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)
        amdgpu_crtc->encoder = NULL;
        amdgpu_crtc->connector = NULL;
        drm_crtc_helper_add(&amdgpu_crtc->base, &dce_v10_0_crtc_helper_funcs);
+       drm_plane_helper_add(amdgpu_crtc->base.primary, &dce_v10_0_drm_primary_plane_helper_funcs);
 
        return 0;
 }
index 504939e3c0c3613a2ae052aa58b479ffa14d1938..ea42a4472bf6c915425a01915ee8e1f6d148b667 100644 (file)
@@ -2800,6 +2800,32 @@ static const struct drm_crtc_helper_funcs dce_v11_0_crtc_helper_funcs = {
        .get_scanout_position = amdgpu_crtc_get_scanout_position,
 };
 
+static void dce_v11_0_panic_flush(struct drm_plane *plane)
+{
+       struct drm_framebuffer *fb;
+       struct amdgpu_crtc *amdgpu_crtc;
+       struct amdgpu_device *adev;
+       uint32_t fb_format;
+
+       if (!plane->fb)
+               return;
+
+       fb = plane->fb;
+       amdgpu_crtc = to_amdgpu_crtc(plane->crtc);
+       adev = drm_to_adev(fb->dev);
+
+       /* Disable DC tiling */
+       fb_format = RREG32(mmGRPH_CONTROL + amdgpu_crtc->crtc_offset);
+       fb_format &= ~GRPH_CONTROL__GRPH_ARRAY_MODE_MASK;
+       WREG32(mmGRPH_CONTROL + amdgpu_crtc->crtc_offset, fb_format);
+
+}
+
+static const struct drm_plane_helper_funcs dce_v11_0_drm_primary_plane_helper_funcs = {
+       .get_scanout_buffer = amdgpu_display_get_scanout_buffer,
+       .panic_flush = dce_v11_0_panic_flush,
+};
+
 static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index)
 {
        struct amdgpu_crtc *amdgpu_crtc;
@@ -2847,6 +2873,7 @@ static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index)
        amdgpu_crtc->encoder = NULL;
        amdgpu_crtc->connector = NULL;
        drm_crtc_helper_add(&amdgpu_crtc->base, &dce_v11_0_crtc_helper_funcs);
+       drm_plane_helper_add(amdgpu_crtc->base.primary, &dce_v11_0_drm_primary_plane_helper_funcs);
 
        return 0;
 }
index a33e33743a93b037c477791e0cd8fca45ddda9b9..915804a6a1d7df978268753e78dba08c35cb891d 100644 (file)
@@ -2602,6 +2602,32 @@ static const struct drm_crtc_helper_funcs dce_v6_0_crtc_helper_funcs = {
        .get_scanout_position = amdgpu_crtc_get_scanout_position,
 };
 
+static void dce_v6_0_panic_flush(struct drm_plane *plane)
+{
+       struct drm_framebuffer *fb;
+       struct amdgpu_crtc *amdgpu_crtc;
+       struct amdgpu_device *adev;
+       uint32_t fb_format;
+
+       if (!plane->fb)
+               return;
+
+       fb = plane->fb;
+       amdgpu_crtc = to_amdgpu_crtc(plane->crtc);
+       adev = drm_to_adev(fb->dev);
+
+       /* Disable DC tiling */
+       fb_format = RREG32(mmGRPH_CONTROL + amdgpu_crtc->crtc_offset);
+       fb_format &= ~GRPH_ARRAY_MODE(0x7);
+       WREG32(mmGRPH_CONTROL + amdgpu_crtc->crtc_offset, fb_format);
+
+}
+
+static const struct drm_plane_helper_funcs dce_v6_0_drm_primary_plane_helper_funcs = {
+       .get_scanout_buffer = amdgpu_display_get_scanout_buffer,
+       .panic_flush = dce_v6_0_panic_flush,
+};
+
 static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)
 {
        struct amdgpu_crtc *amdgpu_crtc;
@@ -2629,6 +2655,7 @@ static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)
        amdgpu_crtc->encoder = NULL;
        amdgpu_crtc->connector = NULL;
        drm_crtc_helper_add(&amdgpu_crtc->base, &dce_v6_0_crtc_helper_funcs);
+       drm_plane_helper_add(amdgpu_crtc->base.primary, &dce_v6_0_drm_primary_plane_helper_funcs);
 
        return 0;
 }
index aff58d56864af1895d979e7247abe0e95c83f929..f2edc0fece5bfe195dfb7a03f4133b2cf65cabf7 100644 (file)
@@ -2613,6 +2613,31 @@ static const struct drm_crtc_helper_funcs dce_v8_0_crtc_helper_funcs = {
        .get_scanout_position = amdgpu_crtc_get_scanout_position,
 };
 
+static void dce_v8_0_panic_flush(struct drm_plane *plane)
+{
+       struct drm_framebuffer *fb;
+       struct amdgpu_crtc *amdgpu_crtc;
+       struct amdgpu_device *adev;
+       uint32_t fb_format;
+
+       if (!plane->fb)
+               return;
+
+       fb = plane->fb;
+       amdgpu_crtc = to_amdgpu_crtc(plane->crtc);
+       adev = drm_to_adev(fb->dev);
+
+       /* Disable DC tiling */
+       fb_format = RREG32(mmGRPH_CONTROL + amdgpu_crtc->crtc_offset);
+       fb_format &= ~GRPH_CONTROL__GRPH_ARRAY_MODE_MASK;
+       WREG32(mmGRPH_CONTROL + amdgpu_crtc->crtc_offset, fb_format);
+}
+
+static const struct drm_plane_helper_funcs dce_v8_0_drm_primary_plane_helper_funcs = {
+       .get_scanout_buffer = amdgpu_display_get_scanout_buffer,
+       .panic_flush = dce_v8_0_panic_flush,
+};
+
 static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)
 {
        struct amdgpu_crtc *amdgpu_crtc;
@@ -2640,6 +2665,7 @@ static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)
        amdgpu_crtc->encoder = NULL;
        amdgpu_crtc->connector = NULL;
        drm_crtc_helper_add(&amdgpu_crtc->base, &dce_v8_0_crtc_helper_funcs);
+       drm_plane_helper_add(amdgpu_crtc->base.primary, &dce_v8_0_drm_primary_plane_helper_funcs);
 
        return 0;
 }