drm/fb_dma: Add generic get_scanout_buffer() for drm_panic

This was initialy done for imx6, but should work on most drivers
using drm_fb_dma_helper.

v8:
 * Replace get_scanout_buffer() logic with drm_panic_set_buffer()
   (Thomas Zimmermann)

v9:
 * go back to get_scanout_buffer()
 * move get_scanout_buffer() to plane helper functions

v12:
 * Rename drm_panic_gem_get_scanout_buffer to drm_fb_dma_get_scanout_buffer
   (Thomas Zimmermann)
 * Remove the #ifdef CONFIG_DRM_PANIC, and build it unconditionnaly, as
   it's a small function. (Thomas Zimmermann)

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240409163432.352518-6-jfalempe@redhat.com
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
Jocelyn Falempe 2024-04-09 18:30:44 +02:00
parent 813ca3aa8f
commit 879b3b6511
2 changed files with 46 additions and 0 deletions

View File

@ -15,6 +15,7 @@
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_panic.h>
#include <drm/drm_plane.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
@ -148,3 +149,44 @@ void drm_fb_dma_sync_non_coherent(struct drm_device *drm,
}
}
EXPORT_SYMBOL_GPL(drm_fb_dma_sync_non_coherent);
/**
* drm_fb_dma_get_scanout_buffer - Provide a scanout buffer in case of panic
* @plane: DRM primary plane
* @drm_scanout_buffer: scanout buffer for the panic handler
* Returns: 0 or negative error code
*
* Generic get_scanout_buffer() implementation, for drivers that uses the
* drm_fb_dma_helper. It won't call vmap in the panic context, so the driver
* should make sure the primary plane is vmapped, otherwise the panic screen
* won't get displayed.
*/
int drm_fb_dma_get_scanout_buffer(struct drm_plane *plane,
struct drm_scanout_buffer *sb)
{
struct drm_gem_dma_object *dma_obj;
struct drm_framebuffer *fb;
fb = plane->state->fb;
/* Only support linear modifier */
if (fb->modifier != DRM_FORMAT_MOD_LINEAR)
return -ENODEV;
dma_obj = drm_fb_dma_get_gem_obj(fb, 0);
/* Buffer should be accessible from the CPU */
if (dma_obj->base.import_attach)
return -ENODEV;
/* Buffer should be already mapped to CPU */
if (!dma_obj->vaddr)
return -ENODEV;
iosys_map_set_vaddr(&sb->map[0], dma_obj->vaddr);
sb->format = fb->format;
sb->height = fb->height;
sb->width = fb->width;
sb->pitch[0] = fb->pitches[0];
return 0;
}
EXPORT_SYMBOL(drm_fb_dma_get_scanout_buffer);

View File

@ -7,6 +7,7 @@
struct drm_device;
struct drm_framebuffer;
struct drm_plane_state;
struct drm_scanout_buffer;
struct drm_gem_dma_object *drm_fb_dma_get_gem_obj(struct drm_framebuffer *fb,
unsigned int plane);
@ -19,5 +20,8 @@ void drm_fb_dma_sync_non_coherent(struct drm_device *drm,
struct drm_plane_state *old_state,
struct drm_plane_state *state);
int drm_panic_gem_get_scanout_buffer(struct drm_plane *plane,
struct drm_scanout_buffer *sb);
#endif