Commit 879b3b65 authored by Jocelyn Falempe's avatar Jocelyn Falempe
Browse files

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: default avatarJocelyn Falempe <jfalempe@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240409163432.352518-6-jfalempe@redhat.com


Acked-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 813ca3aa
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -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);
+4 −0
Original line number Diff line number Diff line
@@ -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