dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [RFC][PATCH v5 0/6] drm/panic: Add a drm panic handler
@ 2023-11-03 14:53 Jocelyn Falempe
  2023-11-03 14:53 ` [PATCH v5 1/6] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill Jocelyn Falempe
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Jocelyn Falempe @ 2023-11-03 14:53 UTC (permalink / raw)
  To: dri-devel, tzimmermann, airlied, maarten.lankhorst, mripard,
	daniel, javierm, bluescreen_avenger, noralf
  Cc: gpiccoli, Jocelyn Falempe

This introduces a new drm panic handler, which displays a message when a panic occurs.
So when fbcon is disabled, you can still see a kernel panic.

This is one of the missing feature, when disabling VT/fbcon in the kernel:
https://www.reddit.com/r/linux/comments/10eccv9/config_vtn_in_2023/
Fbcon can be replaced by a userspace kms console, but the panic screen must be done in the kernel.

This is a proof of concept, and works with simpledrm and mgag200, using a new get_scanout_buffer() api

To test it, make sure you're using the simpledrm driver, and trigger a panic:
echo c > /proc/sysrq-trigger

v2:
 * Use get_scanout_buffer() instead of the drm client API. (Thomas Zimmermann)
 * Add the panic reason to the panic message (Nerdopolis)
 * Add an exclamation mark (Nerdopolis)
 
v3:
 * Rework the drawing functions, to write the pixels line by line and
 to use the drm conversion helper to support other formats.
 (Thomas Zimmermann)
 
v4:
 * Fully support all simpledrm formats using drm conversion helpers
 * Rename dpanic_* to drm_panic_*, and have more coherent function name.
   (Thomas Zimmermann)
 * Use drm_fb_r1_to_32bit for fonts (Thomas Zimmermann)
 * Remove the default y to DRM_PANIC config option (Thomas Zimmermann)
 * Add foreground/background color config option
 * Fix the bottom lines not painted if the framebuffer height
   is not a multiple of the font height.
 * Automatically register the driver to drm_panic, if the function
   get_scanout_buffer() exists. (Thomas Zimmermann)
 * Add mgag200 support.
 
v5:
 * Change the drawing API, use drm_fb_blit_from_r1() to draw the font.
   (Thomas Zimmermann)
 * Also add drm_fb_fill() to fill area with background color.
 * Add draw_pixel_xy() API for drivers that can't provide a linear buffer.
 * Add a flush() callback for drivers that needs to synchronize the buffer.
 * Add a void *private field, so drivers can pass private data to
   draw_pixel_xy() and flush(). 
 * Add ast support.
 * Add experimental imx/ipuv3 support, to test on an ARM hw. (Maxime Ripard)
 
 
With mgag200 support, I was able to test that the xrgb8888 to rgb565 conversion is working.

IMX/IPUV3 support is not complete, I wasn't able to have etnaviv working on my board.
But it shows that it can still work on ARM with DMA buffer in this case.

Best regards,


Jocelyn Falempe (6):
  drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill
  drm/panic: Add a drm panic handler
  drm/simpledrm: Add drm_panic support
  drm/mgag200: Add drm_panic support
  drm/ast: Add drm_panic support
  drm/imx: Add drm_panic support

 drivers/gpu/drm/Kconfig                  |  22 ++
 drivers/gpu/drm/Makefile                 |   1 +
 drivers/gpu/drm/ast/ast_drv.c            |   4 +-
 drivers/gpu/drm/ast/ast_drv.h            |   3 +
 drivers/gpu/drm/ast/ast_mode.c           |  26 ++
 drivers/gpu/drm/drm_drv.c                |   8 +
 drivers/gpu/drm/drm_format_helper.c      | 421 ++++++++++++++++++-----
 drivers/gpu/drm/drm_panic.c              | 368 ++++++++++++++++++++
 drivers/gpu/drm/imx/ipuv3/imx-drm-core.c |  30 ++
 drivers/gpu/drm/mgag200/mgag200_drv.c    |  25 ++
 drivers/gpu/drm/tiny/simpledrm.c         |  15 +
 include/drm/drm_drv.h                    |  21 ++
 include/drm/drm_format_helper.h          |   9 +
 include/drm/drm_panic.h                  |  96 ++++++
 14 files changed, 966 insertions(+), 83 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_panic.c
 create mode 100644 include/drm/drm_panic.h


base-commit: ffc253263a1375a65fa6c9f62a893e9767fbebfa
-- 
2.41.0


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v5 1/6] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill
  2023-11-03 14:53 [RFC][PATCH v5 0/6] drm/panic: Add a drm panic handler Jocelyn Falempe
@ 2023-11-03 14:53 ` Jocelyn Falempe
  2023-11-03 18:34   ` kernel test robot
  2023-11-04  6:04   ` kernel test robot
  2023-11-03 14:53 ` [PATCH v5 2/6] drm/panic: Add a drm panic handler Jocelyn Falempe
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 16+ messages in thread
From: Jocelyn Falempe @ 2023-11-03 14:53 UTC (permalink / raw)
  To: dri-devel, tzimmermann, airlied, maarten.lankhorst, mripard,
	daniel, javierm, bluescreen_avenger, noralf
  Cc: gpiccoli, Jocelyn Falempe

This is needed for drm_panic, to draw the font, and fill
the background color, in multiple color format.

v5:
 * Change the drawing API, use drm_fb_blit_from_r1() to draw the font.
 * Also add drm_fb_fill() to fill area with background color.

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
 drivers/gpu/drm/drm_format_helper.c | 421 ++++++++++++++++++++++------
 include/drm/drm_format_helper.h     |   9 +
 2 files changed, 349 insertions(+), 81 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c
index f93a4efcee90..c29495f51684 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -20,6 +20,147 @@
 #include <drm/drm_print.h>
 #include <drm/drm_rect.h>
 
+static inline u16 drm_format_xrgb8888_to_rgb565(u32 pix)
+{
+	u16 val16;
+
+	pix = le32_to_cpu(pix);
+	val16 = ((pix & 0x00F80000) >> 8) |
+		((pix & 0x0000FC00) >> 5) |
+		((pix & 0x000000F8) >> 3);
+	return cpu_to_le16(val16);
+}
+
+static inline u16 drm_format_xrgb8888_to_rgba5551(u32 pix)
+{
+	u16 val16;
+
+	pix = le32_to_cpu(pix);
+	val16 = ((pix & 0x00f80000) >> 8) |
+		((pix & 0x0000f800) >> 5) |
+		((pix & 0x000000f8) >> 2) |
+		BIT(0); /* set alpha bit */
+	return cpu_to_le16(val16);
+}
+
+static inline u16 drm_format_xrgb8888_to_xrgb1555(u32 pix)
+{
+	u16 val16;
+
+	pix = le32_to_cpu(pix);
+	val16 = ((pix & 0x00f80000) >> 9) |
+		((pix & 0x0000f800) >> 6) |
+		((pix & 0x000000f8) >> 3);
+	return cpu_to_le16(val16);
+}
+
+static inline u16 drm_format_xrgb8888_to_argb1555(u32 pix)
+{
+	u16 val16;
+
+	pix = le32_to_cpu(pix);
+	val16 = BIT(15) | /* set alpha bit */
+		((pix & 0x00f80000) >> 9) |
+		((pix & 0x0000f800) >> 6) |
+		((pix & 0x000000f8) >> 3);
+	return cpu_to_le16(val16);
+}
+
+static inline u32 drm_format_xrgb8888_to_argb8888(u32 pix)
+{
+	u32 val32;
+
+	val32 = le32_to_cpu(pix);
+	val32 |= GENMASK(31, 24); /* fill alpha bits */
+	return cpu_to_le32(val32);
+}
+
+static inline u32 drm_format_xrgb8888_to_xbgr8888(u32 pix)
+{
+	u32 val32;
+
+	pix = le32_to_cpu(pix);
+	val32 = ((pix & 0x00ff0000) >> 16) <<  0 |
+		((pix & 0x0000ff00) >>  8) <<  8 |
+		((pix & 0x000000ff) >>  0) << 16 |
+		((pix & 0xff000000) >> 24) << 24;
+	return cpu_to_le32(val32);
+}
+
+static inline u32 drm_format_xrgb8888_to_abgr8888(u32 pix)
+{
+	u32 val32;
+
+	pix = le32_to_cpu(pix);
+	val32 = ((pix & 0x00ff0000) >> 16) <<  0 |
+		((pix & 0x0000ff00) >>  8) <<  8 |
+		((pix & 0x000000ff) >>  0) << 16 |
+		GENMASK(31, 24); /* fill alpha bits */
+	return cpu_to_le32(val32);
+}
+
+static inline u32 drm_format_xrgb8888_to_xrgb2101010(u32 pix)
+{
+	u32 val32;
+
+	pix = le32_to_cpu(pix);
+	val32 = ((pix & 0x000000FF) << 2) |
+		((pix & 0x0000FF00) << 4) |
+		((pix & 0x00FF0000) << 6);
+	pix = val32 | ((val32 >> 8) & 0x00300C03);
+	return cpu_to_le32(pix);
+}
+
+static inline u32 drm_format_xrgb8888_to_argb2101010(u32 pix)
+{
+	u32 val32;
+
+	pix = le32_to_cpu(pix);
+	val32 = ((pix & 0x000000FF) << 2) |
+		((pix & 0x0000FF00) << 4) |
+		((pix & 0x00FF0000) << 6);
+	pix = GENMASK(31, 30) | /* set alpha bits */
+	      val32 | ((val32 >> 8) & 0x00300c03);
+	return cpu_to_le32(pix);
+}
+
+/**
+ * drm_fb_convert_from_xrgb8888 - convert one pixel from xrgb8888 to the desired format
+ * @color: input color, in xrgb8888 format
+ * @format: output format
+ *
+ * Returns:
+ * Color in the format specified, casted to u32.
+ */
+u32 drm_fb_convert_from_xrgb8888(u32 color, u32 format)
+{
+	switch (format) {
+	case DRM_FORMAT_RGB565:
+		return drm_format_xrgb8888_to_rgb565(color);
+	case DRM_FORMAT_RGBA5551:
+		return drm_format_xrgb8888_to_rgba5551(color);
+	case DRM_FORMAT_XRGB1555:
+		return drm_format_xrgb8888_to_xrgb1555(color);
+	case DRM_FORMAT_ARGB1555:
+		return drm_format_xrgb8888_to_argb1555(color);
+	case DRM_FORMAT_RGB888:
+	case DRM_FORMAT_XRGB8888:
+		return color;
+	case DRM_FORMAT_ARGB8888:
+		return drm_format_xrgb8888_to_argb8888(color);
+	case DRM_FORMAT_XBGR8888:
+		return drm_format_xrgb8888_to_xbgr8888(color);
+	case DRM_FORMAT_XRGB2101010:
+		return drm_format_xrgb8888_to_xrgb2101010(color);
+	case DRM_FORMAT_ARGB2101010:
+		return drm_format_xrgb8888_to_argb2101010(color);
+	default:
+		WARN_ONCE(1, "Can't convert to %p4cc\n", &format);
+		return color;
+	}
+}
+EXPORT_SYMBOL(drm_fb_convert_from_xrgb8888);
+
 static unsigned int clip_offset(const struct drm_rect *clip, unsigned int pitch, unsigned int cpp)
 {
 	return clip->y1 * pitch + clip->x1 * cpp;
@@ -272,6 +413,188 @@ void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch,
 }
 EXPORT_SYMBOL(drm_fb_swab);
 
+static void drm_fb_r1_to_16bit(struct iosys_map *dmap, unsigned int dpitch,
+			       const u8 *sbuf8, unsigned int spitch,
+			       unsigned int height, unsigned int width,
+			       u16 fg16, u16 bg16)
+{
+	unsigned int l, x;
+	u16 val16;
+
+	for (l = 0; l < height; l++) {
+		for (x = 0; x < width; x++) {
+			val16 = (sbuf8[(l * spitch) + x / 8] & (0x80 >> (x % 8))) ? fg16 : bg16;
+			iosys_map_wr(dmap, l * dpitch + x * sizeof(u16), u16, val16);
+		}
+	}
+}
+
+static void drm_fb_r1_to_24bit(struct iosys_map *dmap, unsigned int dpitch,
+			       const u8 *sbuf8, unsigned int spitch,
+			       unsigned int height, unsigned int width,
+			       u32 fg32, u32 bg32)
+{
+	unsigned int l, x;
+	u32 val32;
+
+	for (l = 0; l < height; l++) {
+		for (x = 0; x < width; x++) {
+			u32 off = l * dpitch + x * 3;
+
+			val32 = (sbuf8[(l * spitch) + x / 8] & (0x80 >> (x % 8))) ? fg32 : bg32;
+			val32 = le32_to_cpu(val32);
+
+			/* write blue-green-red to output in little endianness */
+			iosys_map_wr(dmap, off, u8, (val32 & 0x000000FF) >> 0);
+			iosys_map_wr(dmap, off + 1, u8, (val32 & 0x0000FF00) >> 8);
+			iosys_map_wr(dmap, off + 2, u8, (val32 & 0x00FF0000) >> 16);
+		}
+	}
+}
+
+static void drm_fb_r1_to_32bit(struct iosys_map *dmap, unsigned int dpitch,
+			       const u8 *sbuf8, unsigned int spitch,
+			       unsigned int height, unsigned int width,
+			       u32 fg32, u32 bg32)
+{
+	unsigned int l, x;
+	u32 val32;
+
+	for (l = 0; l < height; l++) {
+		for (x = 0; x < width; x++) {
+			val32 = (sbuf8[(l * spitch) + x / 8] & (0x80 >> (x % 8))) ? fg32 : bg32;
+			iosys_map_wr(dmap, l * dpitch + x * sizeof(u32), u32, val32);
+		}
+	}
+}
+
+/**
+ * drm_fb_blit_from_r1 - convert a monochrome image to a linear framebuffer
+ * @dmap: destination iosys_map
+ * @dpich: destination pitch in bytes
+ * @sbuf8: source buffer, in monochrome format, 8 pixels per byte.
+ * @spitch: source pitch in bytes
+ * @height: height of the image to copy, in pixels
+ * @width: width of the image to copy, in pixels
+ * @fg_color: foreground color, in destination format
+ * @bg_color: background color, in destination format
+ * @pixel_width: pixel width in bytes.
+ *
+ * This can be used to draw font which are monochrome images, to a framebuffer
+ * in other supported format.
+ */
+void drm_fb_blit_from_r1(struct iosys_map *dmap, unsigned int dpitch,
+			 const u8 *sbuf8, unsigned int spitch,
+			 unsigned int height, unsigned int width,
+			 u32 fg_color, u32 bg_color,
+			 unsigned int pixel_width)
+{
+	switch (pixel_width) {
+	case 2:
+		drm_fb_r1_to_16bit(dmap, dpitch, sbuf8, spitch,
+				   height, width, fg_color, bg_color);
+	break;
+	case 3:
+		drm_fb_r1_to_24bit(dmap, dpitch, sbuf8, spitch,
+				   height, width, fg_color, bg_color);
+	break;
+	case 4:
+		drm_fb_r1_to_32bit(dmap, dpitch, sbuf8, spitch,
+				   height, width, fg_color, bg_color);
+	break;
+	default:
+		WARN_ONCE(1, "Can't blit with pixel width %d\n", pixel_width);
+	}
+}
+EXPORT_SYMBOL(drm_fb_blit_from_r1);
+
+static void drm_fb_fill8(struct iosys_map *dmap, unsigned int dpitch,
+			 unsigned int height, unsigned int width,
+			 u8 color)
+{
+	unsigned int l, x;
+
+	for (l = 0; l < height; l++)
+		for (x = 0; x < width; x++)
+			iosys_map_wr(dmap, l * dpitch + x * sizeof(u8), u8, color);
+}
+
+static void drm_fb_fill16(struct iosys_map *dmap, unsigned int dpitch,
+			  unsigned int height, unsigned int width,
+			  u16 color)
+{
+	unsigned int l, x;
+
+	for (l = 0; l < height; l++)
+		for (x = 0; x < width; x++)
+			iosys_map_wr(dmap, l * dpitch + x * sizeof(u16), u16, color);
+}
+
+static void drm_fb_fill24(struct iosys_map *dmap, unsigned int dpitch,
+			  unsigned int height, unsigned int width,
+			  u32 color)
+{
+	unsigned int l, x;
+
+	for (l = 0; l < height; l++) {
+		for (x = 0; x < width; x++) {
+			unsigned int off = l * dpitch + x * 3;
+			u32 val32 = le32_to_cpu(color);
+
+			/* write blue-green-red to output in little endianness */
+			iosys_map_wr(dmap, off, u8, (val32 & 0x000000FF) >> 0);
+			iosys_map_wr(dmap, off + 1, u8, (val32 & 0x0000FF00) >> 8);
+			iosys_map_wr(dmap, off + 2, u8, (val32 & 0x00FF0000) >> 16);
+		}
+	}
+}
+
+static void drm_fb_fill32(struct iosys_map *dmap, unsigned int dpitch,
+			  unsigned int height, unsigned int width,
+			  u32 color)
+{
+	unsigned int l, x;
+
+	for (l = 0; l < height; l++)
+		for (x = 0; x < width; x++)
+			iosys_map_wr(dmap, l * dpitch + x * sizeof(u32), u32, color);
+}
+
+/**
+ * drm_fb_fill - Fill a rectangle with a color
+ * @dmap: destination iosys_map, pointing to the top left corner of the rectangle
+ * @dpich: destination pitch in bytes
+ * @height: height of the rectangle, in pixels
+ * @width: width of the rectangle, in pixels
+ * @fg_color: foreground color, in destination format
+ * @bg_color: background color, in destination format
+ * @pixel_width: pixel width in bytes
+ *
+ * Fill a rectangle with a color, in a linear framebuffer.
+ */
+void drm_fb_fill(struct iosys_map *dmap, unsigned int dpitch,
+			 unsigned int height, unsigned int width,
+			 u32 color, unsigned int pixel_width)
+{
+	switch (pixel_width) {
+	case 1:
+		drm_fb_fill8(dmap, dpitch, height, width, color);
+	break;
+	case 2:
+		drm_fb_fill16(dmap, dpitch, height, width, color);
+	break;
+	case 3:
+		drm_fb_fill24(dmap, dpitch, height, width, color);
+	break;
+	case 4:
+		drm_fb_fill32(dmap, dpitch, height, width, color);
+	break;
+	default:
+		WARN_ONCE(1, "Can't fill with pixel width %d\n", pixel_width);
+	}
+}
+EXPORT_SYMBOL(drm_fb_fill);
+
 static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigned int pixels)
 {
 	u8 *dbuf8 = dbuf;
@@ -325,15 +648,9 @@ static void drm_fb_xrgb8888_to_rgb565_line(void *dbuf, const void *sbuf, unsigne
 	__le16 *dbuf16 = dbuf;
 	const __le32 *sbuf32 = sbuf;
 	unsigned int x;
-	u16 val16;
-	u32 pix;
 
 	for (x = 0; x < pixels; x++) {
-		pix = le32_to_cpu(sbuf32[x]);
-		val16 = ((pix & 0x00F80000) >> 8) |
-			((pix & 0x0000FC00) >> 5) |
-			((pix & 0x000000F8) >> 3);
-		dbuf16[x] = cpu_to_le16(val16);
+		dbuf16[x] = drm_format_xrgb8888_to_rgb565(sbuf32[x]);
 	}
 }
 
@@ -401,16 +718,9 @@ static void drm_fb_xrgb8888_to_xrgb1555_line(void *dbuf, const void *sbuf, unsig
 	__le16 *dbuf16 = dbuf;
 	const __le32 *sbuf32 = sbuf;
 	unsigned int x;
-	u16 val16;
-	u32 pix;
 
-	for (x = 0; x < pixels; x++) {
-		pix = le32_to_cpu(sbuf32[x]);
-		val16 = ((pix & 0x00f80000) >> 9) |
-			((pix & 0x0000f800) >> 6) |
-			((pix & 0x000000f8) >> 3);
-		dbuf16[x] = cpu_to_le16(val16);
-	}
+	for (x = 0; x < pixels; x++)
+		dbuf16[x] = drm_format_xrgb8888_to_xrgb1555(sbuf32[x]);
 }
 
 /**
@@ -452,17 +762,9 @@ static void drm_fb_xrgb8888_to_argb1555_line(void *dbuf, const void *sbuf, unsig
 	__le16 *dbuf16 = dbuf;
 	const __le32 *sbuf32 = sbuf;
 	unsigned int x;
-	u16 val16;
-	u32 pix;
 
-	for (x = 0; x < pixels; x++) {
-		pix = le32_to_cpu(sbuf32[x]);
-		val16 = BIT(15) | /* set alpha bit */
-			((pix & 0x00f80000) >> 9) |
-			((pix & 0x0000f800) >> 6) |
-			((pix & 0x000000f8) >> 3);
-		dbuf16[x] = cpu_to_le16(val16);
-	}
+	for (x = 0; x < pixels; x++)
+		dbuf16[x] = drm_format_xrgb8888_to_argb1555(sbuf32[x]);
 }
 
 /**
@@ -504,17 +806,9 @@ static void drm_fb_xrgb8888_to_rgba5551_line(void *dbuf, const void *sbuf, unsig
 	__le16 *dbuf16 = dbuf;
 	const __le32 *sbuf32 = sbuf;
 	unsigned int x;
-	u16 val16;
-	u32 pix;
 
-	for (x = 0; x < pixels; x++) {
-		pix = le32_to_cpu(sbuf32[x]);
-		val16 = ((pix & 0x00f80000) >> 8) |
-			((pix & 0x0000f800) >> 5) |
-			((pix & 0x000000f8) >> 2) |
-			BIT(0); /* set alpha bit */
-		dbuf16[x] = cpu_to_le16(val16);
-	}
+	for (x = 0; x < pixels; x++)
+		dbuf16[x] = drm_format_xrgb8888_to_rgba5551(sbuf32[x]);
 }
 
 /**
@@ -606,13 +900,9 @@ static void drm_fb_xrgb8888_to_argb8888_line(void *dbuf, const void *sbuf, unsig
 	__le32 *dbuf32 = dbuf;
 	const __le32 *sbuf32 = sbuf;
 	unsigned int x;
-	u32 pix;
 
-	for (x = 0; x < pixels; x++) {
-		pix = le32_to_cpu(sbuf32[x]);
-		pix |= GENMASK(31, 24); /* fill alpha bits */
-		dbuf32[x] = cpu_to_le32(pix);
-	}
+	for (x = 0; x < pixels; x++)
+		dbuf32[x] = drm_format_xrgb8888_to_argb8888(sbuf32[x]);
 }
 
 /**
@@ -654,16 +944,9 @@ static void drm_fb_xrgb8888_to_abgr8888_line(void *dbuf, const void *sbuf, unsig
 	__le32 *dbuf32 = dbuf;
 	const __le32 *sbuf32 = sbuf;
 	unsigned int x;
-	u32 pix;
 
-	for (x = 0; x < pixels; x++) {
-		pix = le32_to_cpu(sbuf32[x]);
-		pix = ((pix & 0x00ff0000) >> 16) <<  0 |
-		      ((pix & 0x0000ff00) >>  8) <<  8 |
-		      ((pix & 0x000000ff) >>  0) << 16 |
-		      GENMASK(31, 24); /* fill alpha bits */
-		*dbuf32++ = cpu_to_le32(pix);
-	}
+	for (x = 0; x < pixels; x++)
+		*dbuf32++ = drm_format_xrgb8888_to_abgr8888(sbuf32[x]);
 }
 
 static void drm_fb_xrgb8888_to_abgr8888(struct iosys_map *dst, const unsigned int *dst_pitch,
@@ -684,16 +967,9 @@ static void drm_fb_xrgb8888_to_xbgr8888_line(void *dbuf, const void *sbuf, unsig
 	__le32 *dbuf32 = dbuf;
 	const __le32 *sbuf32 = sbuf;
 	unsigned int x;
-	u32 pix;
 
-	for (x = 0; x < pixels; x++) {
-		pix = le32_to_cpu(sbuf32[x]);
-		pix = ((pix & 0x00ff0000) >> 16) <<  0 |
-		      ((pix & 0x0000ff00) >>  8) <<  8 |
-		      ((pix & 0x000000ff) >>  0) << 16 |
-		      ((pix & 0xff000000) >> 24) << 24;
-		*dbuf32++ = cpu_to_le32(pix);
-	}
+	for (x = 0; x < pixels; x++)
+		*dbuf32++ = drm_format_xrgb8888_to_xbgr8888(sbuf32[x]);
 }
 
 static void drm_fb_xrgb8888_to_xbgr8888(struct iosys_map *dst, const unsigned int *dst_pitch,
@@ -714,17 +990,9 @@ static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, un
 	__le32 *dbuf32 = dbuf;
 	const __le32 *sbuf32 = sbuf;
 	unsigned int x;
-	u32 val32;
-	u32 pix;
 
-	for (x = 0; x < pixels; x++) {
-		pix = le32_to_cpu(sbuf32[x]);
-		val32 = ((pix & 0x000000FF) << 2) |
-			((pix & 0x0000FF00) << 4) |
-			((pix & 0x00FF0000) << 6);
-		pix = val32 | ((val32 >> 8) & 0x00300C03);
-		*dbuf32++ = cpu_to_le32(pix);
-	}
+	for (x = 0; x < pixels; x++)
+		*dbuf32++ = drm_format_xrgb8888_to_xrgb2101010(sbuf32[x]);
 }
 
 /**
@@ -766,18 +1034,9 @@ static void drm_fb_xrgb8888_to_argb2101010_line(void *dbuf, const void *sbuf, un
 	__le32 *dbuf32 = dbuf;
 	const __le32 *sbuf32 = sbuf;
 	unsigned int x;
-	u32 val32;
-	u32 pix;
 
-	for (x = 0; x < pixels; x++) {
-		pix = le32_to_cpu(sbuf32[x]);
-		val32 = ((pix & 0x000000ff) << 2) |
-			((pix & 0x0000ff00) << 4) |
-			((pix & 0x00ff0000) << 6);
-		pix = GENMASK(31, 30) | /* set alpha bits */
-		      val32 | ((val32 >> 8) & 0x00300c03);
-		*dbuf32++ = cpu_to_le32(pix);
-	}
+	for (x = 0; x < pixels; x++)
+		*dbuf32++ = drm_format_xrgb8888_to_argb2101010(sbuf32[x]);
 }
 
 /**
diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h
index 291deb09475b..7881cd46b9cc 100644
--- a/include/drm/drm_format_helper.h
+++ b/include/drm/drm_format_helper.h
@@ -15,6 +15,7 @@ struct drm_rect;
 
 struct iosys_map;
 
+u32 drm_fb_convert_from_xrgb8888(u32 color, u32 format);
 unsigned int drm_fb_clip_offset(unsigned int pitch, const struct drm_format_info *format,
 				const struct drm_rect *clip);
 
@@ -24,6 +25,14 @@ void drm_fb_memcpy(struct iosys_map *dst, const unsigned int *dst_pitch,
 void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch,
 		 const struct iosys_map *src, const struct drm_framebuffer *fb,
 		 const struct drm_rect *clip, bool cached);
+void drm_fb_blit_from_r1(struct iosys_map *dmap, unsigned int dpitch,
+			 const u8 *sbuf8, unsigned int spitch,
+			 unsigned int height, unsigned int width,
+			 u32 fg_color, u32 bg_color,
+			 unsigned int pixel_width);
+void drm_fb_fill(struct iosys_map *dmap, unsigned int dpitch,
+		 unsigned int height, unsigned int width,
+		 u32 color, unsigned int pixel_width);
 void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pitch,
 			       const struct iosys_map *src, const struct drm_framebuffer *fb,
 			       const struct drm_rect *clip);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 2/6] drm/panic: Add a drm panic handler
  2023-11-03 14:53 [RFC][PATCH v5 0/6] drm/panic: Add a drm panic handler Jocelyn Falempe
  2023-11-03 14:53 ` [PATCH v5 1/6] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill Jocelyn Falempe
@ 2023-11-03 14:53 ` Jocelyn Falempe
  2023-11-03 14:53 ` [PATCH v5 3/6] drm/simpledrm: Add drm_panic support Jocelyn Falempe
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Jocelyn Falempe @ 2023-11-03 14:53 UTC (permalink / raw)
  To: dri-devel, tzimmermann, airlied, maarten.lankhorst, mripard,
	daniel, javierm, bluescreen_avenger, noralf
  Cc: gpiccoli, Jocelyn Falempe

This module displays a user friendly message when a kernel panic
occurs. It currently doesn't contain any debug information,
but that can be added later.

v2
 * Use get_scanout_buffer() instead of the drm client API.
  (Thomas Zimmermann)
 * Add the panic reason to the panic message (Nerdopolis)
 * Add an exclamation mark (Nerdopolis)

v3
 * Rework the drawing functions, to write the pixels line by line and
 to use the drm conversion helper to support other formats.
 (Thomas Zimmermann)

v4
 * Use drm_fb_r1_to_32bit for fonts (Thomas Zimmermann)
 * Remove the default y to DRM_PANIC config option (Thomas Zimmermann)
 * Add foreground/background color config option
 * Fix the bottom lines not painted if the framebuffer height
   is not a multiple of the font height.
 * Automatically register the device to drm_panic, if the function
   get_scanout_buffer exists. (Thomas Zimmermann)

v5
 * Change the drawing API, use drm_fb_blit_from_r1() to draw the font.
 * Also add drm_fb_fill() to fill area with background color.
 * Add draw_pixel_xy() API for drivers that can't provide a linear buffer.
 * Add a flush() callback for drivers that needs to synchronize the buffer.
 * Add a void *private field, so drivers can pass private data to
   draw_pixel_xy() and flush().

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
 drivers/gpu/drm/Kconfig     |  22 +++
 drivers/gpu/drm/Makefile    |   1 +
 drivers/gpu/drm/drm_drv.c   |   8 +
 drivers/gpu/drm/drm_panic.c | 368 ++++++++++++++++++++++++++++++++++++
 include/drm/drm_drv.h       |  21 ++
 include/drm/drm_panic.h     |  96 ++++++++++
 6 files changed, 516 insertions(+)
 create mode 100644 drivers/gpu/drm/drm_panic.c
 create mode 100644 include/drm/drm_panic.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 3caa020391c7..9f76cc47d0f3 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -102,6 +102,28 @@ config DRM_KMS_HELPER
 	help
 	  CRTC helpers for KMS drivers.
 
+config DRM_PANIC
+	bool "Display a user-friendly message when a kernel panic occurs"
+	depends on DRM && !FRAMEBUFFER_CONSOLE
+	select FONT_SUPPORT
+	help
+	  Enable a drm panic handler, which will display a user-friendly message
+	  when a kernel panic occurs. It's useful when using a user-space
+	  console instead of fbcon.
+	  It will only work if your graphic driver supports this feature.
+	  To support Hi-DPI Display, you can enable bigger fonts like
+	  FONT_TER16x32
+
+config DRM_PANIC_FOREGROUND_COLOR
+	hex "Drm panic screen foreground color, in RGB"
+	depends on DRM_PANIC
+	default 0xffffff
+
+config DRM_PANIC_BACKGROUND_COLOR
+	hex "Drm panic screen background color, in RGB"
+	depends on DRM_PANIC
+	default 0x000000
+
 config DRM_DEBUG_DP_MST_TOPOLOGY_REFS
         bool "Enable refcount backtrace history in the DP MST helpers"
 	depends on STACKTRACE_SUPPORT
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 215e78e79125..2c793326c893 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -73,6 +73,7 @@ drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \
 	drm_privacy_screen_x86.o
 drm-$(CONFIG_DRM_ACCEL) += ../../accel/drm_accel.o
 obj-$(CONFIG_DRM)	+= drm.o
+drm-$(CONFIG_DRM_PANIC) += drm_panic.o
 
 obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
 
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 3eda026ffac6..d4230e5a472b 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -43,6 +43,7 @@
 #include <drm/drm_file.h>
 #include <drm/drm_managed.h>
 #include <drm/drm_mode_object.h>
+#include <drm/drm_panic.h>
 #include <drm/drm_print.h>
 #include <drm/drm_privacy_screen_machine.h>
 
@@ -943,6 +944,9 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
 	if (drm_core_check_feature(dev, DRIVER_MODESET))
 		drm_modeset_register_all(dev);
 
+	if (driver->get_scanout_buffer)
+		drm_panic_register(dev);
+
 	DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
 		 driver->name, driver->major, driver->minor,
 		 driver->patchlevel, driver->date,
@@ -986,6 +990,8 @@ void drm_dev_unregister(struct drm_device *dev)
 
 	dev->registered = false;
 
+	drm_panic_unregister(dev);
+
 	drm_client_dev_unregister(dev);
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET))
@@ -1067,6 +1073,7 @@ static void drm_core_exit(void)
 	unregister_chrdev(DRM_MAJOR, "drm");
 	debugfs_remove(drm_debugfs_root);
 	drm_sysfs_destroy();
+	drm_panic_exit();
 	idr_destroy(&drm_minors_idr);
 	drm_connector_ida_destroy();
 }
@@ -1078,6 +1085,7 @@ static int __init drm_core_init(void)
 	drm_connector_ida_init();
 	idr_init(&drm_minors_idr);
 	drm_memcpy_init_early();
+	drm_panic_init();
 
 	ret = drm_sysfs_init();
 	if (ret < 0) {
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
new file mode 100644
index 000000000000..70afc153065b
--- /dev/null
+++ b/drivers/gpu/drm/drm_panic.c
@@ -0,0 +1,368 @@
+// SPDX-License-Identifier: GPL-2.0 or MIT
+/*
+ * Copyright (c) 2023 Jocelyn Falempe <jfalempe@redhat.com>
+ * inspired by the drm_log driver from David Herrmann <dh.herrmann@gmail.com>
+ * Tux Ascii art taken from cowsay written by Tony Monroe
+ */
+
+#include <linux/font.h>
+#include <linux/iosys-map.h>
+#include <linux/kdebug.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/panic_notifier.h>
+#include <linux/types.h>
+
+#include <drm/drm_drv.h>
+#include <drm/drm_format_helper.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_panic.h>
+#include <drm/drm_print.h>
+
+
+MODULE_AUTHOR("Jocelyn Falempe");
+MODULE_DESCRIPTION("DRM panic handler");
+MODULE_LICENSE("GPL");
+
+/**
+ * DOC: DRM Panic
+ *
+ * This module displays a user friendly message on screen when a kernel panic
+ * occurs. This is conflicting with fbcon, so you can only enable it when fbcon
+ * is disabled.
+ * It's intended for end-user, so have minimal technical/debug information.
+ */
+
+/*
+ * Implementation details:
+ *
+ * It is a panic handler, so it can't take lock, allocate memory, run tasks/irq,
+ * or attempt to sleep. It's a best effort, and it may not be able to display
+ * the message in all situations (like if the panic occurs in the middle of a
+ * modesetting).
+ * It will display only one static frame, so performance optimizations are low
+ * priority as the machine is already in an unusable state.
+ */
+
+/*
+ * List of active drm devices that can render a panic
+ */
+struct drm_panic_device {
+	struct list_head head;
+	struct drm_device *dev;
+};
+
+struct drm_panic_line {
+	u32 len;
+	const char *txt;
+};
+
+#define PANIC_LINE(s) {.len = sizeof(s) - 1, .txt = s}
+
+struct drm_panic_line panic_msg[] = {
+	PANIC_LINE("KERNEL PANIC !"),
+	PANIC_LINE(""),
+	PANIC_LINE("Please reboot your computer."),
+	PANIC_LINE(""),
+	PANIC_LINE(""), /* overwritten with panic reason */
+};
+
+const struct drm_panic_line logo[] = {
+	PANIC_LINE("     .--.        _"),
+	PANIC_LINE("    |o_o |      | |"),
+	PANIC_LINE("    |:_/ |      | |"),
+	PANIC_LINE("   //   \\ \\     |_|"),
+	PANIC_LINE("  (|     | )     _"),
+	PANIC_LINE(" /'\\_   _/`\\    (_)"),
+	PANIC_LINE(" \\___)=(___/"),
+};
+
+static LIST_HEAD(drm_panic_devices);
+static DEFINE_MUTEX(drm_panic_lock);
+
+static void draw_empty_line_map(struct drm_scanout_buffer *sb, size_t top, size_t height, u32 color)
+{
+	struct iosys_map dst = sb->map;
+
+	iosys_map_incr(&dst, top * sb->pitch);
+	drm_fb_fill(&dst, sb->pitch, height, sb->width, color, sb->format->cpp[0]);
+}
+
+static void draw_txt_line_map(const struct drm_panic_line *msg, size_t left, size_t top,
+			      struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color,
+			      const struct font_desc *font)
+{
+	size_t i;
+	const u8 *src;
+	size_t src_stride = DIV_ROUND_UP(font->width, 8);
+	struct iosys_map dst = sb->map;
+	size_t end_text;
+	unsigned int px_width = sb->format->cpp[0];
+
+	iosys_map_incr(&dst, top * sb->pitch);
+	drm_fb_fill(&dst, sb->pitch, font->height, left, bg_color, px_width);
+	iosys_map_incr(&dst, left * px_width);
+	for (i = 0; i < msg->len; i++) {
+		src = font->data + (msg->txt[i] * font->height) * src_stride;
+		drm_fb_blit_from_r1(&dst, sb->pitch, src, src_stride, font->height, font->width,
+				    fg_color, bg_color, px_width);
+		iosys_map_incr(&dst, font->width * px_width);
+	}
+	end_text = (msg->len * font->width) + left;
+	if (sb->width > end_text)
+		drm_fb_fill(&dst, sb->pitch, font->height, sb->width - end_text,
+			    bg_color, px_width);
+}
+
+static void draw_empty_line_px(struct drm_scanout_buffer *sb, size_t top, size_t height, u32 color)
+{
+	unsigned int x, y;
+
+	for (y = 0; y < height; y++)
+		for (x = 0; x < sb->width; x++)
+			sb->draw_pixel_xy(x, y + top, color, sb->private);
+}
+
+static void draw_txt_line_px(const struct drm_panic_line *msg, size_t left, size_t top,
+			     struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color,
+			     const struct font_desc *font)
+{
+	unsigned int x, y, i;
+	const u8 *src;
+	u32 color;
+	size_t src_stride = DIV_ROUND_UP(font->width, 8);
+	size_t end_text = msg->len * font->width + left;
+	size_t right = sb->width > end_text ? sb->width - end_text : 0;
+
+	for (y = 0; y < font->height; y++) {
+		for (x = 0; x < left; x++)
+			sb->draw_pixel_xy(x, y + top, bg_color, sb->private);
+
+		for (i = 0; i < msg->len; i++) {
+			src = font->data + (msg->txt[i] * font->height + y) * src_stride;
+			for (x = 0; x < font->width; x++) {
+				color = (src[x / 8] & (0x80 >> (x % 8))) ? fg_color : bg_color;
+				sb->draw_pixel_xy(x + left + font->width * i, y + top, color,
+						  sb->private);
+			}
+		}
+
+		for (x = 0; x < right; x++)
+			sb->draw_pixel_xy(x + end_text, y + top, bg_color, sb->private);
+	}
+}
+
+static void draw_empty_line(struct drm_scanout_buffer *sb, size_t top, size_t height, u32 color)
+{
+	if (sb->draw_pixel_xy)
+		draw_empty_line_px(sb, top, height, color);
+	else
+		draw_empty_line_map(sb, top, height, color);
+}
+
+static void draw_txt_line(const struct drm_panic_line *msg, size_t left, size_t top,
+			  struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color,
+			  const struct font_desc *font)
+{
+	if (sb->draw_pixel_xy)
+		draw_txt_line_px(msg, left, top, sb, fg_color, bg_color, font);
+	else
+		draw_txt_line_map(msg, left, top, sb, fg_color, bg_color, font);
+}
+
+
+static size_t panic_msg_needed_lines(size_t chars_per_line)
+{
+	size_t msg_len = ARRAY_SIZE(panic_msg);
+	size_t lines = 0;
+	size_t i;
+
+	for (i = 0; i < msg_len; i++)
+		lines += panic_msg[i].len ? DIV_ROUND_UP(panic_msg[i].len, chars_per_line) : 1;
+	return lines;
+}
+
+static bool can_draw_logo(size_t chars_per_line, size_t lines, size_t msg_lines)
+{
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(logo); i++) {
+		if (logo[i].len > chars_per_line)
+			return false;
+	}
+	if (lines < msg_lines + ARRAY_SIZE(logo))
+		return false;
+	return true;
+}
+
+static size_t get_start_line(size_t lines, size_t msg_lines, bool draw_logo)
+{
+	size_t remaining;
+	size_t logo_len = ARRAY_SIZE(logo);
+
+	if (lines < msg_lines)
+		return 0;
+	remaining = lines - msg_lines;
+	if (draw_logo && remaining / 2 <= logo_len)
+		return logo_len + (remaining - logo_len) / 4;
+	return remaining / 2;
+}
+
+/*
+ * Draw the panic message at the center of the screen
+ */
+static void draw_panic_static(struct drm_scanout_buffer *sb, const char *msg)
+{
+	size_t lines, msg_lines, l, msg_start_line, remaining, msgi;
+	size_t chars_per_line;
+	bool draw_logo;
+	struct drm_panic_line panic_line;
+	size_t msg_len = ARRAY_SIZE(panic_msg);
+	size_t logo_len = ARRAY_SIZE(logo);
+	u32 fg_color = CONFIG_DRM_PANIC_FOREGROUND_COLOR;
+	u32 bg_color = CONFIG_DRM_PANIC_BACKGROUND_COLOR;
+	const struct font_desc *font = get_default_font(sb->width, sb->height, 0x8080, 0x8080);
+
+	if (!font)
+		return;
+
+	/* Set the panic reason */
+	panic_msg[msg_len - 1].len = strlen(msg);
+	panic_msg[msg_len - 1].txt = msg;
+
+	lines = sb->height / font->height;
+	chars_per_line = sb->width / font->width;
+
+	msg_lines = panic_msg_needed_lines(chars_per_line);
+	draw_logo = can_draw_logo(chars_per_line, lines, msg_lines);
+	msg_start_line = get_start_line(lines, msg_lines, draw_logo);
+
+	fg_color = drm_fb_convert_from_xrgb8888(fg_color, sb->format->format);
+	bg_color = drm_fb_convert_from_xrgb8888(bg_color, sb->format->format);
+
+	msgi = 0;
+	panic_line.len = 0;
+	for (l = 0; l < lines; l++) {
+		if (draw_logo && l < logo_len)
+			draw_txt_line(&logo[l], 0, l * font->height, sb, fg_color, bg_color, font);
+		else if (l >= msg_start_line && msgi < msg_len) {
+			if (!panic_line.len) {
+				panic_line.txt = panic_msg[msgi].txt;
+				panic_line.len = panic_msg[msgi].len;
+			}
+			if (!panic_line.len) {
+				draw_empty_line(sb, l * font->height, font->height, bg_color);
+				msgi++;
+			} else if (panic_line.len > chars_per_line) {
+				remaining = panic_line.len - chars_per_line;
+				panic_line.len = chars_per_line;
+				draw_txt_line(&panic_line, 0, l * font->height, sb, fg_color,
+					      bg_color, font);
+				panic_line.txt += chars_per_line;
+				panic_line.len = remaining;
+			} else {
+				draw_txt_line(&panic_line,
+					      font->width * (chars_per_line - panic_line.len) / 2,
+					      l * font->height, sb, fg_color, bg_color, font);
+				panic_line.len = 0;
+				msgi++;
+			}
+		} else {
+			draw_empty_line(sb, l * font->height, font->height, bg_color);
+		}
+	}
+	/* Fill the bottom of the screen, if sb->height is not a multiple of font->height */
+	if (sb->height % font->height)
+		draw_empty_line(sb, l * font->height, sb->height - l * font->height, bg_color);
+}
+
+static void draw_panic_device(struct drm_device *dev, const char *msg)
+{
+	struct drm_scanout_buffer sb = {0};
+
+	if (dev->driver->get_scanout_buffer(dev, &sb))
+		return;
+	draw_panic_static(&sb, msg);
+	if (sb.flush)
+		sb.flush(sb.private);
+}
+
+static int drm_panic(struct notifier_block *this, unsigned long event,
+		     void *ptr)
+{
+	struct drm_panic_device *drm_panic_device;
+
+	list_for_each_entry(drm_panic_device, &drm_panic_devices, head) {
+		draw_panic_device(drm_panic_device->dev, ptr);
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block drm_panic_notifier = {
+	.notifier_call = drm_panic,
+};
+
+/**
+ * drm_panic_register() - Initialize DRM panic for a device
+ * @dev: the DRM device on which the panic screen will be displayed.
+ */
+void drm_panic_register(struct drm_device *dev)
+{
+	struct drm_panic_device *new;
+
+	new = kzalloc(sizeof(*new), GFP_KERNEL);
+	if (!new)
+		return;
+
+	new->dev = dev;
+	mutex_lock(&drm_panic_lock);
+	list_add_tail(&new->head, &drm_panic_devices);
+	mutex_unlock(&drm_panic_lock);
+
+	drm_info(dev, "Registered with drm panic\n");
+}
+EXPORT_SYMBOL(drm_panic_register);
+
+/**
+ * drm_panic_unregister()
+ * @dev: the DRM device previously registered.
+ */
+void drm_panic_unregister(struct drm_device *dev)
+{
+	struct drm_panic_device *drm_panic_device;
+	struct drm_panic_device *found = NULL;
+
+	mutex_lock(&drm_panic_lock);
+	list_for_each_entry(drm_panic_device, &drm_panic_devices, head) {
+		if (drm_panic_device->dev == dev)
+			found = drm_panic_device;
+	}
+	if (found) {
+		list_del(&found->head);
+		kfree(found);
+		drm_info(dev, "Unregistered with drm panic\n");
+	}
+	mutex_unlock(&drm_panic_lock);
+}
+EXPORT_SYMBOL(drm_panic_unregister);
+
+/**
+ * drm_panic_init() - Initialize drm-panic subsystem
+ *
+ * register the panic notifier
+ */
+void drm_panic_init(void)
+{
+	atomic_notifier_chain_register(&panic_notifier_list,
+				       &drm_panic_notifier);
+}
+
+/**
+ * drm_panic_exit() - Shutdown drm-panic subsystem
+ */
+void drm_panic_exit(void)
+{
+	atomic_notifier_chain_unregister(&panic_notifier_list,
+					 &drm_panic_notifier);
+}
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 9813fa759b75..30bacae32715 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -43,6 +43,7 @@ struct dma_buf_attachment;
 struct drm_display_mode;
 struct drm_mode_create_dumb;
 struct drm_printer;
+struct drm_scanout_buffer;
 struct sg_table;
 
 /**
@@ -392,6 +393,26 @@ struct drm_driver {
 	 */
 	void (*show_fdinfo)(struct drm_printer *p, struct drm_file *f);
 
+	/**
+	 * @get_scanout_buffer:
+	 *
+	 * Get the current scanout buffer, to display a panic message with drm_panic.
+	 * The driver should do the minimum changes to provide a linear buffer, that
+	 * can be used to display the panic screen.
+	 * It is called from a panic callback, and must follow its restrictions.
+	 * (no locks, no memory allocation, no sleep, no thread/workqueue, ...)
+	 * It's a best effort mode, so it's expected that in some complex cases the
+	 * panic screen won't be displayed.
+	 * Some hardware cannot provide a linear buffer, so there is a draw_pixel_xy()
+	 * callback in the struct drm_scanout_buffer that can be used in this case.
+	 *
+	 * Returns:
+	 *
+	 * Zero on success, negative errno on failure.
+	 */
+	int (*get_scanout_buffer)(struct drm_device *dev,
+				  struct drm_scanout_buffer *sb);
+
 	/** @major: driver major number */
 	int major;
 	/** @minor: driver minor number */
diff --git a/include/drm/drm_panic.h b/include/drm/drm_panic.h
new file mode 100644
index 000000000000..c977ab77fba8
--- /dev/null
+++ b/include/drm/drm_panic.h
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: GPL-2.0 or MIT */
+#ifndef __DRM_PANIC_H__
+#define __DRM_PANIC_H__
+
+/*
+ * Copyright (c) 2023 Jocelyn Falempe <jfalempe@redhat.com>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/iosys-map.h>
+
+struct drm_device;
+
+/**
+ * struct drm_scanout_buffer - DRM scanout buffer
+ *
+ * This structure holds the information necessary for drm_panic to draw the
+ * panic screen, and display it.
+ * If the driver can't provide a linear buffer, it must clear @map with
+ * iosys_map_clear() and provide a draw_pixel_xy() function.
+ */
+struct drm_scanout_buffer {
+	/**
+	 * @format:
+	 *
+	 * drm format of the scanout buffer.
+	 */
+	const struct drm_format_info *format;
+	/**
+	 * @map:
+	 *
+	 * Virtual address of the scanout buffer, either in memory or iomem.
+	 * The scanout buffer should be in linear format, and can be directly
+	 * sent to the display hardware. Tearing is not an issue for the panic
+	 * screen.
+	 */
+	struct iosys_map map;
+	/**
+	 * @width: Width of the scanout buffer, in pixels.
+	 */
+	unsigned int width;
+	/**
+	 * @height: Height of the scanout buffer, in pixels.
+	 */
+	unsigned int height;
+	/**
+	 * @pitch: Length in bytes between the start of two consecutive lines.
+	 */
+	unsigned int pitch;
+	/**
+	 * @private:
+	 *
+	 * In case the driver can't provide a linear buffer, this is a pointer to
+	 * some private data, that will be passed when calling @draw_pixel_xy()
+	 * and @flush()
+	 */
+	void *private;
+	/**
+	 * @draw_pixel_xy:
+	 *
+	 * In case the driver can't provide a linear buffer, this is a function
+	 * that drm_panic will call for each pixel to draw.
+	 * Color will be converted to the format specified by @format.
+	 */
+	void (*draw_pixel_xy)(unsigned int x, unsigned int y, u32 color, void *private);
+	/**
+	 * @flush:
+	 *
+	 * This function is called after the panic screen is drawn, either using
+	 * the iosys_map or the draw_pixel_xy path. In this function, the driver
+	 * can send additional commands to the hardware, to make the buffer
+	 * visible.
+	 */
+	void (*flush)(void *private);
+};
+
+#ifdef CONFIG_DRM_PANIC
+
+void drm_panic_init(void);
+void drm_panic_exit(void);
+
+void drm_panic_register(struct drm_device *dev);
+void drm_panic_unregister(struct drm_device *dev);
+
+#else
+
+static inline void drm_panic_init(void) {}
+static inline void drm_panic_exit(void) {}
+
+static inline void drm_panic_register(struct drm_device *dev) {}
+static inline void drm_panic_unregister(struct drm_device *dev) {}
+
+#endif
+
+#endif /* __DRM_LOG_H__ */
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 3/6] drm/simpledrm: Add drm_panic support
  2023-11-03 14:53 [RFC][PATCH v5 0/6] drm/panic: Add a drm panic handler Jocelyn Falempe
  2023-11-03 14:53 ` [PATCH v5 1/6] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill Jocelyn Falempe
  2023-11-03 14:53 ` [PATCH v5 2/6] drm/panic: Add a drm panic handler Jocelyn Falempe
@ 2023-11-03 14:53 ` Jocelyn Falempe
  2023-11-03 14:53 ` [PATCH v5 4/6] drm/mgag200: " Jocelyn Falempe
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Jocelyn Falempe @ 2023-11-03 14:53 UTC (permalink / raw)
  To: dri-devel, tzimmermann, airlied, maarten.lankhorst, mripard,
	daniel, javierm, bluescreen_avenger, noralf
  Cc: gpiccoli, Jocelyn Falempe

Add support for the drm_panic module, which displays a user-friendly
message to the screen when a kernel panic occurs.

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
 drivers/gpu/drm/tiny/simpledrm.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 8ea120eb8674..e5070b82703a 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -23,6 +23,7 @@
 #include <drm/drm_gem_shmem_helper.h>
 #include <drm/drm_managed.h>
 #include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_panic.h>
 #include <drm/drm_plane_helper.h>
 #include <drm/drm_probe_helper.h>
 
@@ -842,6 +843,19 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
 	return sdev;
 }
 
+static int simpledrm_get_scanout_buffer(struct drm_device *dev,
+					struct drm_scanout_buffer *sb)
+{
+	struct simpledrm_device *sdev = simpledrm_device_of_dev(dev);
+
+	sb->width = sdev->mode.hdisplay;
+	sb->height = sdev->mode.vdisplay;
+	sb->pitch = sdev->pitch;
+	sb->format = sdev->format;
+	sb->map = sdev->screen_base;
+	return 0;
+}
+
 /*
  * DRM driver
  */
@@ -857,6 +871,7 @@ static struct drm_driver simpledrm_driver = {
 	.minor			= DRIVER_MINOR,
 	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
 	.fops			= &simpledrm_fops,
+	.get_scanout_buffer	= simpledrm_get_scanout_buffer,
 };
 
 /*
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 4/6] drm/mgag200: Add drm_panic support
  2023-11-03 14:53 [RFC][PATCH v5 0/6] drm/panic: Add a drm panic handler Jocelyn Falempe
                   ` (2 preceding siblings ...)
  2023-11-03 14:53 ` [PATCH v5 3/6] drm/simpledrm: Add drm_panic support Jocelyn Falempe
@ 2023-11-03 14:53 ` Jocelyn Falempe
  2023-11-03 14:53 ` [PATCH v5 5/6] drm/ast: " Jocelyn Falempe
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Jocelyn Falempe @ 2023-11-03 14:53 UTC (permalink / raw)
  To: dri-devel, tzimmermann, airlied, maarten.lankhorst, mripard,
	daniel, javierm, bluescreen_avenger, noralf
  Cc: gpiccoli, Jocelyn Falempe

Add support for the drm_panic module, which displays a message to
the screen when a kernel panic occurs.

v5:
 * Also check that the plane is visible and primary. (Thomas Zimmermann)

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
 drivers/gpu/drm/mgag200/mgag200_drv.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index abddf37f0ea1..7bfcc66485db 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -12,10 +12,12 @@
 #include <drm/drm_aperture.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_fbdev_generic.h>
+#include <drm/drm_framebuffer.h>
 #include <drm/drm_file.h>
 #include <drm/drm_ioctl.h>
 #include <drm/drm_managed.h>
 #include <drm/drm_module.h>
+#include <drm/drm_panic.h>
 #include <drm/drm_pciids.h>
 
 #include "mgag200_drv.h"
@@ -83,6 +85,28 @@ resource_size_t mgag200_probe_vram(void __iomem *mem, resource_size_t size)
 	return offset - 65536;
 }
 
+static int mgag200_get_scanout_buffer(struct drm_device *dev,
+				      struct drm_scanout_buffer *sb)
+{
+	struct drm_plane *plane;
+	struct mga_device *mdev = to_mga_device(dev);
+	struct iosys_map map = IOSYS_MAP_INIT_VADDR_IOMEM(mdev->vram);
+
+	/* find the primary and visible plane */
+	drm_for_each_plane(plane, dev) {
+		if (!plane->state || !plane->state->visible || !plane->state->fb ||
+		    plane->type != DRM_PLANE_TYPE_PRIMARY)
+			continue;
+		sb->format = plane->state->fb->format;
+		sb->width = plane->state->fb->width;
+		sb->height = plane->state->fb->height;
+		sb->pitch = plane->state->fb->pitches[0];
+		sb->map = map;
+		return 0;
+	}
+	return -ENODEV;
+}
+
 /*
  * DRM driver
  */
@@ -98,6 +122,7 @@ static const struct drm_driver mgag200_driver = {
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
+	.get_scanout_buffer = mgag200_get_scanout_buffer,
 	DRM_GEM_SHMEM_DRIVER_OPS,
 };
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 5/6] drm/ast: Add drm_panic support
  2023-11-03 14:53 [RFC][PATCH v5 0/6] drm/panic: Add a drm panic handler Jocelyn Falempe
                   ` (3 preceding siblings ...)
  2023-11-03 14:53 ` [PATCH v5 4/6] drm/mgag200: " Jocelyn Falempe
@ 2023-11-03 14:53 ` Jocelyn Falempe
  2023-11-03 18:52   ` kernel test robot
  2023-11-04  3:57   ` kernel test robot
  2023-11-03 14:53 ` [PATCH v5 6/6] drm/imx: " Jocelyn Falempe
  2023-11-13 13:59 ` [RFC][PATCH v5 0/6] drm/panic: Add a drm panic handler nerdopolis
  6 siblings, 2 replies; 16+ messages in thread
From: Jocelyn Falempe @ 2023-11-03 14:53 UTC (permalink / raw)
  To: dri-devel, tzimmermann, airlied, maarten.lankhorst, mripard,
	daniel, javierm, bluescreen_avenger, noralf
  Cc: gpiccoli, Jocelyn Falempe

Add support for the drm_panic module, which displays a message to
the screen when a kernel panic occurs.

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
 drivers/gpu/drm/ast/ast_drv.c  |  4 ++--
 drivers/gpu/drm/ast/ast_drv.h  |  3 +++
 drivers/gpu/drm/ast/ast_mode.c | 26 ++++++++++++++++++++++++++
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index e1224ef4ad83..da60d2e237f5 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -62,8 +62,8 @@ static const struct drm_driver ast_driver = {
 	.major = DRIVER_MAJOR,
 	.minor = DRIVER_MINOR,
 	.patchlevel = DRIVER_PATCHLEVEL,
-
-	DRM_GEM_SHMEM_DRIVER_OPS
+	.get_scanout_buffer = ast_get_scanout_buffer,
+	DRM_GEM_SHMEM_DRIVER_OPS,
 };
 
 /*
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 848a9f1403e8..b9c62d18e14e 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -504,6 +504,9 @@ int ast_mode_config_init(struct ast_device *ast);
 #define ASTDP_1366x768_60		0x1E
 #define ASTDP_1152x864_75		0x1F
 
+int ast_get_scanout_buffer(struct drm_device *dev,
+			   struct drm_scanout_buffer *sb);
+
 int ast_mm_init(struct ast_device *ast);
 
 /* ast post */
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 32f04ec6c386..3653e65a135b 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -43,6 +43,7 @@
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_gem_shmem_helper.h>
 #include <drm/drm_managed.h>
+#include <drm/drm_panic.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_simple_kms_helper.h>
 
@@ -1930,3 +1931,28 @@ int ast_mode_config_init(struct ast_device *ast)
 
 	return 0;
 }
+
+int ast_get_scanout_buffer(struct drm_device *dev,
+			   struct drm_scanout_buffer *sb)
+{
+	struct drm_plane *plane;
+	struct ast_plane *ast_plane;
+	struct iosys_map map;
+
+	drm_for_each_plane(plane, dev) {
+		if (!plane->state || !plane->state->visible || !plane->state->fb ||
+		    plane->type != DRM_PLANE_TYPE_PRIMARY)
+			continue;
+		ast_plane = to_ast_plane(plane);
+		if (!ast_plane->vaddr)
+			continue;
+
+		sb->format = plane->state->fb->format;
+		sb->width = plane->state->fb->width;
+		sb->height = plane->state->fb->height;
+		sb->pitch = plane->state->fb->pitches[0];
+		iosys_map_set_vaddr_iomem(&sb->map, ast_plane->vaddr);
+		return 0;
+	}
+	return -ENODEV;
+}
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v5 6/6] drm/imx: Add drm_panic support
  2023-11-03 14:53 [RFC][PATCH v5 0/6] drm/panic: Add a drm panic handler Jocelyn Falempe
                   ` (4 preceding siblings ...)
  2023-11-03 14:53 ` [PATCH v5 5/6] drm/ast: " Jocelyn Falempe
@ 2023-11-03 14:53 ` Jocelyn Falempe
  2023-12-14 13:48   ` Maxime Ripard
  2023-11-13 13:59 ` [RFC][PATCH v5 0/6] drm/panic: Add a drm panic handler nerdopolis
  6 siblings, 1 reply; 16+ messages in thread
From: Jocelyn Falempe @ 2023-11-03 14:53 UTC (permalink / raw)
  To: dri-devel, tzimmermann, airlied, maarten.lankhorst, mripard,
	daniel, javierm, bluescreen_avenger, noralf
  Cc: gpiccoli, Jocelyn Falempe

Proof of concept to add drm_panic support on an arm based GPU.
I've tested it with X11/llvmpipe, because I wasn't able to have
3d rendering with etnaviv on my imx6 board.

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
 drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 30 ++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
index 4a866ac60fff..db24b4976c61 100644
--- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
@@ -10,6 +10,7 @@
 #include <linux/dma-buf.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/iosys-map.h>
 
 #include <video/imx-ipu-v3.h>
 
@@ -17,9 +18,12 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_fbdev_dma.h>
+#include <drm/drm_fb_dma_helper.h>
+#include <drm/drm_framebuffer.h>
 #include <drm/drm_gem_dma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_managed.h>
+#include <drm/drm_panic.h>
 #include <drm/drm_of.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
@@ -160,6 +164,31 @@ static int imx_drm_dumb_create(struct drm_file *file_priv,
 	return ret;
 }
 
+static int imx_drm_get_scanout_buffer(struct drm_device *dev,
+				      struct drm_scanout_buffer *sb)
+{
+	struct drm_plane *plane;
+	struct drm_gem_dma_object *dma_obj;
+
+	drm_for_each_plane(plane, dev) {
+		if (!plane->state || !plane->state->fb || !plane->state->visible ||
+		    plane->type != DRM_PLANE_TYPE_PRIMARY)
+			continue;
+
+		dma_obj = drm_fb_dma_get_gem_obj(plane->state->fb, 0);
+		if (!dma_obj->vaddr)
+			continue;
+
+		iosys_map_set_vaddr(&sb->map, dma_obj->vaddr);
+		sb->format = plane->state->fb->format;
+		sb->height = plane->state->fb->height;
+		sb->width = plane->state->fb->width;
+		sb->pitch = plane->state->fb->pitches[0];
+		return 0;
+	}
+	return -ENODEV;
+}
+
 static const struct drm_driver imx_drm_driver = {
 	.driver_features	= DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
 	DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(imx_drm_dumb_create),
@@ -172,6 +201,7 @@ static const struct drm_driver imx_drm_driver = {
 	.major			= 1,
 	.minor			= 0,
 	.patchlevel		= 0,
+	.get_scanout_buffer	= imx_drm_get_scanout_buffer,
 };
 
 static int compare_of(struct device *dev, void *data)
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v5 1/6] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill
  2023-11-03 14:53 ` [PATCH v5 1/6] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill Jocelyn Falempe
@ 2023-11-03 18:34   ` kernel test robot
  2023-11-04  6:04   ` kernel test robot
  1 sibling, 0 replies; 16+ messages in thread
From: kernel test robot @ 2023-11-03 18:34 UTC (permalink / raw)
  To: Jocelyn Falempe, dri-devel, tzimmermann, airlied,
	maarten.lankhorst, mripard, daniel, javierm, bluescreen_avenger,
	noralf
  Cc: gpiccoli, Jocelyn Falempe, oe-kbuild-all

Hi Jocelyn,

kernel test robot noticed the following build warnings:

[auto build test WARNING on ffc253263a1375a65fa6c9f62a893e9767fbebfa]

url:    https://github.com/intel-lab-lkp/linux/commits/Jocelyn-Falempe/drm-format-helper-Add-drm_fb_blit_from_r1-and-drm_fb_fill/20231103-225824
base:   ffc253263a1375a65fa6c9f62a893e9767fbebfa
patch link:    https://lore.kernel.org/r/20231103145526.628138-2-jfalempe%40redhat.com
patch subject: [PATCH v5 1/6] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill
config: csky-randconfig-002-20231104 (https://download.01.org/0day-ci/archive/20231104/202311040208.JqcG6ZbK-lkp@intel.com/config)
compiler: csky-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231104/202311040208.JqcG6ZbK-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311040208.JqcG6ZbK-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/drm_format_helper.c:491: warning: Function parameter or member 'dpitch' not described in 'drm_fb_blit_from_r1'
>> drivers/gpu/drm/drm_format_helper.c:491: warning: Excess function parameter 'dpich' description in 'drm_fb_blit_from_r1'
>> drivers/gpu/drm/drm_format_helper.c:578: warning: Function parameter or member 'dpitch' not described in 'drm_fb_fill'
>> drivers/gpu/drm/drm_format_helper.c:578: warning: Function parameter or member 'color' not described in 'drm_fb_fill'
>> drivers/gpu/drm/drm_format_helper.c:578: warning: Excess function parameter 'dpich' description in 'drm_fb_fill'
>> drivers/gpu/drm/drm_format_helper.c:578: warning: Excess function parameter 'fg_color' description in 'drm_fb_fill'
>> drivers/gpu/drm/drm_format_helper.c:578: warning: Excess function parameter 'bg_color' description in 'drm_fb_fill'


vim +491 drivers/gpu/drm/drm_format_helper.c

   470	
   471	/**
   472	 * drm_fb_blit_from_r1 - convert a monochrome image to a linear framebuffer
   473	 * @dmap: destination iosys_map
   474	 * @dpich: destination pitch in bytes
   475	 * @sbuf8: source buffer, in monochrome format, 8 pixels per byte.
   476	 * @spitch: source pitch in bytes
   477	 * @height: height of the image to copy, in pixels
   478	 * @width: width of the image to copy, in pixels
   479	 * @fg_color: foreground color, in destination format
   480	 * @bg_color: background color, in destination format
   481	 * @pixel_width: pixel width in bytes.
   482	 *
   483	 * This can be used to draw font which are monochrome images, to a framebuffer
   484	 * in other supported format.
   485	 */
   486	void drm_fb_blit_from_r1(struct iosys_map *dmap, unsigned int dpitch,
   487				 const u8 *sbuf8, unsigned int spitch,
   488				 unsigned int height, unsigned int width,
   489				 u32 fg_color, u32 bg_color,
   490				 unsigned int pixel_width)
 > 491	{
   492		switch (pixel_width) {
   493		case 2:
   494			drm_fb_r1_to_16bit(dmap, dpitch, sbuf8, spitch,
   495					   height, width, fg_color, bg_color);
   496		break;
   497		case 3:
   498			drm_fb_r1_to_24bit(dmap, dpitch, sbuf8, spitch,
   499					   height, width, fg_color, bg_color);
   500		break;
   501		case 4:
   502			drm_fb_r1_to_32bit(dmap, dpitch, sbuf8, spitch,
   503					   height, width, fg_color, bg_color);
   504		break;
   505		default:
   506			WARN_ONCE(1, "Can't blit with pixel width %d\n", pixel_width);
   507		}
   508	}
   509	EXPORT_SYMBOL(drm_fb_blit_from_r1);
   510	
   511	static void drm_fb_fill8(struct iosys_map *dmap, unsigned int dpitch,
   512				 unsigned int height, unsigned int width,
   513				 u8 color)
   514	{
   515		unsigned int l, x;
   516	
   517		for (l = 0; l < height; l++)
   518			for (x = 0; x < width; x++)
   519				iosys_map_wr(dmap, l * dpitch + x * sizeof(u8), u8, color);
   520	}
   521	
   522	static void drm_fb_fill16(struct iosys_map *dmap, unsigned int dpitch,
   523				  unsigned int height, unsigned int width,
   524				  u16 color)
   525	{
   526		unsigned int l, x;
   527	
   528		for (l = 0; l < height; l++)
   529			for (x = 0; x < width; x++)
   530				iosys_map_wr(dmap, l * dpitch + x * sizeof(u16), u16, color);
   531	}
   532	
   533	static void drm_fb_fill24(struct iosys_map *dmap, unsigned int dpitch,
   534				  unsigned int height, unsigned int width,
   535				  u32 color)
   536	{
   537		unsigned int l, x;
   538	
   539		for (l = 0; l < height; l++) {
   540			for (x = 0; x < width; x++) {
   541				unsigned int off = l * dpitch + x * 3;
   542				u32 val32 = le32_to_cpu(color);
   543	
   544				/* write blue-green-red to output in little endianness */
   545				iosys_map_wr(dmap, off, u8, (val32 & 0x000000FF) >> 0);
   546				iosys_map_wr(dmap, off + 1, u8, (val32 & 0x0000FF00) >> 8);
   547				iosys_map_wr(dmap, off + 2, u8, (val32 & 0x00FF0000) >> 16);
   548			}
   549		}
   550	}
   551	
   552	static void drm_fb_fill32(struct iosys_map *dmap, unsigned int dpitch,
   553				  unsigned int height, unsigned int width,
   554				  u32 color)
   555	{
   556		unsigned int l, x;
   557	
   558		for (l = 0; l < height; l++)
   559			for (x = 0; x < width; x++)
   560				iosys_map_wr(dmap, l * dpitch + x * sizeof(u32), u32, color);
   561	}
   562	
   563	/**
   564	 * drm_fb_fill - Fill a rectangle with a color
   565	 * @dmap: destination iosys_map, pointing to the top left corner of the rectangle
   566	 * @dpich: destination pitch in bytes
   567	 * @height: height of the rectangle, in pixels
   568	 * @width: width of the rectangle, in pixels
   569	 * @fg_color: foreground color, in destination format
   570	 * @bg_color: background color, in destination format
   571	 * @pixel_width: pixel width in bytes
   572	 *
   573	 * Fill a rectangle with a color, in a linear framebuffer.
   574	 */
   575	void drm_fb_fill(struct iosys_map *dmap, unsigned int dpitch,
   576				 unsigned int height, unsigned int width,
   577				 u32 color, unsigned int pixel_width)
 > 578	{
   579		switch (pixel_width) {
   580		case 1:
   581			drm_fb_fill8(dmap, dpitch, height, width, color);
   582		break;
   583		case 2:
   584			drm_fb_fill16(dmap, dpitch, height, width, color);
   585		break;
   586		case 3:
   587			drm_fb_fill24(dmap, dpitch, height, width, color);
   588		break;
   589		case 4:
   590			drm_fb_fill32(dmap, dpitch, height, width, color);
   591		break;
   592		default:
   593			WARN_ONCE(1, "Can't fill with pixel width %d\n", pixel_width);
   594		}
   595	}
   596	EXPORT_SYMBOL(drm_fb_fill);
   597	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v5 5/6] drm/ast: Add drm_panic support
  2023-11-03 14:53 ` [PATCH v5 5/6] drm/ast: " Jocelyn Falempe
@ 2023-11-03 18:52   ` kernel test robot
  2023-11-04  3:57   ` kernel test robot
  1 sibling, 0 replies; 16+ messages in thread
From: kernel test robot @ 2023-11-03 18:52 UTC (permalink / raw)
  To: Jocelyn Falempe, dri-devel, tzimmermann, airlied,
	maarten.lankhorst, mripard, daniel, javierm, bluescreen_avenger,
	noralf
  Cc: gpiccoli, Jocelyn Falempe, oe-kbuild-all

Hi Jocelyn,

kernel test robot noticed the following build warnings:

[auto build test WARNING on ffc253263a1375a65fa6c9f62a893e9767fbebfa]

url:    https://github.com/intel-lab-lkp/linux/commits/Jocelyn-Falempe/drm-format-helper-Add-drm_fb_blit_from_r1-and-drm_fb_fill/20231103-225824
base:   ffc253263a1375a65fa6c9f62a893e9767fbebfa
patch link:    https://lore.kernel.org/r/20231103145526.628138-6-jfalempe%40redhat.com
patch subject: [PATCH v5 5/6] drm/ast: Add drm_panic support
config: csky-randconfig-001-20231104 (https://download.01.org/0day-ci/archive/20231104/202311040239.qKjutDxj-lkp@intel.com/config)
compiler: csky-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231104/202311040239.qKjutDxj-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311040239.qKjutDxj-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/ast/ast_i2c.c:27:
>> drivers/gpu/drm/ast/ast_drv.h:508:35: warning: 'struct drm_scanout_buffer' declared inside parameter list will not be visible outside of this definition or declaration
     508 |                            struct drm_scanout_buffer *sb);
         |                                   ^~~~~~~~~~~~~~~~~~
--
   drivers/gpu/drm/ast/ast_mode.c: In function 'ast_get_scanout_buffer':
>> drivers/gpu/drm/ast/ast_mode.c:1940:26: warning: unused variable 'map' [-Wunused-variable]
    1940 |         struct iosys_map map;
         |                          ^~~


vim +508 drivers/gpu/drm/ast/ast_drv.h

   506	
   507	int ast_get_scanout_buffer(struct drm_device *dev,
 > 508				   struct drm_scanout_buffer *sb);
   509	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v5 5/6] drm/ast: Add drm_panic support
  2023-11-03 14:53 ` [PATCH v5 5/6] drm/ast: " Jocelyn Falempe
  2023-11-03 18:52   ` kernel test robot
@ 2023-11-04  3:57   ` kernel test robot
  1 sibling, 0 replies; 16+ messages in thread
From: kernel test robot @ 2023-11-04  3:57 UTC (permalink / raw)
  To: Jocelyn Falempe, dri-devel, tzimmermann, airlied,
	maarten.lankhorst, mripard, daniel, javierm, bluescreen_avenger,
	noralf
  Cc: gpiccoli, Jocelyn Falempe, llvm, oe-kbuild-all

Hi Jocelyn,

kernel test robot noticed the following build warnings:

[auto build test WARNING on ffc253263a1375a65fa6c9f62a893e9767fbebfa]

url:    https://github.com/intel-lab-lkp/linux/commits/Jocelyn-Falempe/drm-format-helper-Add-drm_fb_blit_from_r1-and-drm_fb_fill/20231103-225824
base:   ffc253263a1375a65fa6c9f62a893e9767fbebfa
patch link:    https://lore.kernel.org/r/20231103145526.628138-6-jfalempe%40redhat.com
patch subject: [PATCH v5 5/6] drm/ast: Add drm_panic support
config: x86_64-rhel-8.3-rust (https://download.01.org/0day-ci/archive/20231104/202311041116.Madu45VI-lkp@intel.com/config)
compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231104/202311041116.Madu45VI-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311041116.Madu45VI-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/ast/ast_i2c.c:27:
>> drivers/gpu/drm/ast/ast_drv.h:508:14: warning: declaration of 'struct drm_scanout_buffer' will not be visible outside of this function [-Wvisibility]
                              struct drm_scanout_buffer *sb);
                                     ^
   1 warning generated.


vim +508 drivers/gpu/drm/ast/ast_drv.h

   506	
   507	int ast_get_scanout_buffer(struct drm_device *dev,
 > 508				   struct drm_scanout_buffer *sb);
   509	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v5 1/6] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill
  2023-11-03 14:53 ` [PATCH v5 1/6] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill Jocelyn Falempe
  2023-11-03 18:34   ` kernel test robot
@ 2023-11-04  6:04   ` kernel test robot
  1 sibling, 0 replies; 16+ messages in thread
From: kernel test robot @ 2023-11-04  6:04 UTC (permalink / raw)
  To: Jocelyn Falempe, dri-devel, tzimmermann, airlied,
	maarten.lankhorst, mripard, daniel, javierm, bluescreen_avenger,
	noralf
  Cc: gpiccoli, Jocelyn Falempe, oe-kbuild-all

Hi Jocelyn,

kernel test robot noticed the following build warnings:

[auto build test WARNING on ffc253263a1375a65fa6c9f62a893e9767fbebfa]

url:    https://github.com/intel-lab-lkp/linux/commits/Jocelyn-Falempe/drm-format-helper-Add-drm_fb_blit_from_r1-and-drm_fb_fill/20231103-225824
base:   ffc253263a1375a65fa6c9f62a893e9767fbebfa
patch link:    https://lore.kernel.org/r/20231103145526.628138-2-jfalempe%40redhat.com
patch subject: [PATCH v5 1/6] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill
config: i386-randconfig-062-20231104 (https://download.01.org/0day-ci/archive/20231104/202311041300.X5kh1Yvx-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-12) 11.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231104/202311041300.X5kh1Yvx-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311041300.X5kh1Yvx-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/gpu/drm/drm_format_helper.c:445:33: sparse: sparse: cast to restricted __le32
   drivers/gpu/drm/drm_format_helper.c:542:37: sparse: sparse: cast to restricted __le32
>> drivers/gpu/drm/drm_format_helper.c:653:65: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected unsigned int [usertype] pix @@     got restricted __le32 const [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:653:65: sparse:     expected unsigned int [usertype] pix
   drivers/gpu/drm/drm_format_helper.c:653:65: sparse:     got restricted __le32 const [usertype]
>> drivers/gpu/drm/drm_format_helper.c:653:27: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [usertype] @@     got unsigned short @@
   drivers/gpu/drm/drm_format_helper.c:653:27: sparse:     expected restricted __le16 [usertype]
   drivers/gpu/drm/drm_format_helper.c:653:27: sparse:     got unsigned short
   drivers/gpu/drm/drm_format_helper.c:723:67: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected unsigned int [usertype] pix @@     got restricted __le32 const [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:723:67: sparse:     expected unsigned int [usertype] pix
   drivers/gpu/drm/drm_format_helper.c:723:67: sparse:     got restricted __le32 const [usertype]
   drivers/gpu/drm/drm_format_helper.c:723:27: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [usertype] @@     got unsigned short @@
   drivers/gpu/drm/drm_format_helper.c:723:27: sparse:     expected restricted __le16 [usertype]
   drivers/gpu/drm/drm_format_helper.c:723:27: sparse:     got unsigned short
   drivers/gpu/drm/drm_format_helper.c:767:67: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected unsigned int [usertype] pix @@     got restricted __le32 const [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:767:67: sparse:     expected unsigned int [usertype] pix
   drivers/gpu/drm/drm_format_helper.c:767:67: sparse:     got restricted __le32 const [usertype]
   drivers/gpu/drm/drm_format_helper.c:767:27: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [usertype] @@     got unsigned short @@
   drivers/gpu/drm/drm_format_helper.c:767:27: sparse:     expected restricted __le16 [usertype]
   drivers/gpu/drm/drm_format_helper.c:767:27: sparse:     got unsigned short
   drivers/gpu/drm/drm_format_helper.c:811:67: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected unsigned int [usertype] pix @@     got restricted __le32 const [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:811:67: sparse:     expected unsigned int [usertype] pix
   drivers/gpu/drm/drm_format_helper.c:811:67: sparse:     got restricted __le32 const [usertype]
   drivers/gpu/drm/drm_format_helper.c:811:27: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le16 [usertype] @@     got unsigned short @@
   drivers/gpu/drm/drm_format_helper.c:811:27: sparse:     expected restricted __le16 [usertype]
   drivers/gpu/drm/drm_format_helper.c:811:27: sparse:     got unsigned short
   drivers/gpu/drm/drm_format_helper.c:905:67: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected unsigned int [usertype] pix @@     got restricted __le32 const [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:905:67: sparse:     expected unsigned int [usertype] pix
   drivers/gpu/drm/drm_format_helper.c:905:67: sparse:     got restricted __le32 const [usertype]
>> drivers/gpu/drm/drm_format_helper.c:905:27: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le32 [usertype] @@     got unsigned int @@
   drivers/gpu/drm/drm_format_helper.c:905:27: sparse:     expected restricted __le32 [usertype]
   drivers/gpu/drm/drm_format_helper.c:905:27: sparse:     got unsigned int
   drivers/gpu/drm/drm_format_helper.c:949:67: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected unsigned int [usertype] pix @@     got restricted __le32 const [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:949:67: sparse:     expected unsigned int [usertype] pix
   drivers/gpu/drm/drm_format_helper.c:949:67: sparse:     got restricted __le32 const [usertype]
   drivers/gpu/drm/drm_format_helper.c:949:27: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le32 [usertype] @@     got unsigned int @@
   drivers/gpu/drm/drm_format_helper.c:949:27: sparse:     expected restricted __le32 [usertype]
   drivers/gpu/drm/drm_format_helper.c:949:27: sparse:     got unsigned int
   drivers/gpu/drm/drm_format_helper.c:972:67: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected unsigned int [usertype] pix @@     got restricted __le32 const [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:972:67: sparse:     expected unsigned int [usertype] pix
   drivers/gpu/drm/drm_format_helper.c:972:67: sparse:     got restricted __le32 const [usertype]
   drivers/gpu/drm/drm_format_helper.c:972:27: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le32 [usertype] @@     got unsigned int @@
   drivers/gpu/drm/drm_format_helper.c:972:27: sparse:     expected restricted __le32 [usertype]
   drivers/gpu/drm/drm_format_helper.c:972:27: sparse:     got unsigned int
   drivers/gpu/drm/drm_format_helper.c:995:70: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected unsigned int [usertype] pix @@     got restricted __le32 const [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:995:70: sparse:     expected unsigned int [usertype] pix
   drivers/gpu/drm/drm_format_helper.c:995:70: sparse:     got restricted __le32 const [usertype]
   drivers/gpu/drm/drm_format_helper.c:995:27: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le32 [usertype] @@     got unsigned int @@
   drivers/gpu/drm/drm_format_helper.c:995:27: sparse:     expected restricted __le32 [usertype]
   drivers/gpu/drm/drm_format_helper.c:995:27: sparse:     got unsigned int
   drivers/gpu/drm/drm_format_helper.c:1039:70: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected unsigned int [usertype] pix @@     got restricted __le32 const [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:1039:70: sparse:     expected unsigned int [usertype] pix
   drivers/gpu/drm/drm_format_helper.c:1039:70: sparse:     got restricted __le32 const [usertype]
   drivers/gpu/drm/drm_format_helper.c:1039:27: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le32 [usertype] @@     got unsigned int @@
   drivers/gpu/drm/drm_format_helper.c:1039:27: sparse:     expected restricted __le32 [usertype]
   drivers/gpu/drm/drm_format_helper.c:1039:27: sparse:     got unsigned int
   drivers/gpu/drm/drm_format_helper.c:27:15: sparse: sparse: cast to restricted __le32
>> drivers/gpu/drm/drm_format_helper.c:31:16: sparse: sparse: incorrect type in return expression (different base types) @@     expected unsigned short @@     got restricted __le16 [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:31:16: sparse:     expected unsigned short
   drivers/gpu/drm/drm_format_helper.c:31:16: sparse:     got restricted __le16 [usertype]
   drivers/gpu/drm/drm_format_helper.c:38:15: sparse: sparse: cast to restricted __le32
   drivers/gpu/drm/drm_format_helper.c:43:16: sparse: sparse: incorrect type in return expression (different base types) @@     expected unsigned short @@     got restricted __le16 [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:43:16: sparse:     expected unsigned short
   drivers/gpu/drm/drm_format_helper.c:43:16: sparse:     got restricted __le16 [usertype]
   drivers/gpu/drm/drm_format_helper.c:50:15: sparse: sparse: cast to restricted __le32
   drivers/gpu/drm/drm_format_helper.c:54:16: sparse: sparse: incorrect type in return expression (different base types) @@     expected unsigned short @@     got restricted __le16 [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:54:16: sparse:     expected unsigned short
   drivers/gpu/drm/drm_format_helper.c:54:16: sparse:     got restricted __le16 [usertype]
   drivers/gpu/drm/drm_format_helper.c:61:15: sparse: sparse: cast to restricted __le32
   drivers/gpu/drm/drm_format_helper.c:66:16: sparse: sparse: incorrect type in return expression (different base types) @@     expected unsigned short @@     got restricted __le16 [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:66:16: sparse:     expected unsigned short
   drivers/gpu/drm/drm_format_helper.c:66:16: sparse:     got restricted __le16 [usertype]
   drivers/gpu/drm/drm_format_helper.c:73:17: sparse: sparse: cast to restricted __le32
>> drivers/gpu/drm/drm_format_helper.c:75:16: sparse: sparse: incorrect type in return expression (different base types) @@     expected unsigned int @@     got restricted __le32 [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:75:16: sparse:     expected unsigned int
   drivers/gpu/drm/drm_format_helper.c:75:16: sparse:     got restricted __le32 [usertype]
   drivers/gpu/drm/drm_format_helper.c:82:15: sparse: sparse: cast to restricted __le32
   drivers/gpu/drm/drm_format_helper.c:87:16: sparse: sparse: incorrect type in return expression (different base types) @@     expected unsigned int @@     got restricted __le32 [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:87:16: sparse:     expected unsigned int
   drivers/gpu/drm/drm_format_helper.c:87:16: sparse:     got restricted __le32 [usertype]
   drivers/gpu/drm/drm_format_helper.c:106:15: sparse: sparse: cast to restricted __le32
   drivers/gpu/drm/drm_format_helper.c:111:16: sparse: sparse: incorrect type in return expression (different base types) @@     expected unsigned int @@     got restricted __le32 [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:111:16: sparse:     expected unsigned int
   drivers/gpu/drm/drm_format_helper.c:111:16: sparse:     got restricted __le32 [usertype]
   drivers/gpu/drm/drm_format_helper.c:118:15: sparse: sparse: cast to restricted __le32
   drivers/gpu/drm/drm_format_helper.c:124:16: sparse: sparse: incorrect type in return expression (different base types) @@     expected unsigned int @@     got restricted __le32 [usertype] @@
   drivers/gpu/drm/drm_format_helper.c:124:16: sparse:     expected unsigned int
   drivers/gpu/drm/drm_format_helper.c:124:16: sparse:     got restricted __le32 [usertype]

vim +445 drivers/gpu/drm/drm_format_helper.c

   431	
   432	static void drm_fb_r1_to_24bit(struct iosys_map *dmap, unsigned int dpitch,
   433				       const u8 *sbuf8, unsigned int spitch,
   434				       unsigned int height, unsigned int width,
   435				       u32 fg32, u32 bg32)
   436	{
   437		unsigned int l, x;
   438		u32 val32;
   439	
   440		for (l = 0; l < height; l++) {
   441			for (x = 0; x < width; x++) {
   442				u32 off = l * dpitch + x * 3;
   443	
   444				val32 = (sbuf8[(l * spitch) + x / 8] & (0x80 >> (x % 8))) ? fg32 : bg32;
 > 445				val32 = le32_to_cpu(val32);
   446	
   447				/* write blue-green-red to output in little endianness */
   448				iosys_map_wr(dmap, off, u8, (val32 & 0x000000FF) >> 0);
   449				iosys_map_wr(dmap, off + 1, u8, (val32 & 0x0000FF00) >> 8);
   450				iosys_map_wr(dmap, off + 2, u8, (val32 & 0x00FF0000) >> 16);
   451			}
   452		}
   453	}
   454	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC][PATCH v5 0/6] drm/panic: Add a drm panic handler
  2023-11-03 14:53 [RFC][PATCH v5 0/6] drm/panic: Add a drm panic handler Jocelyn Falempe
                   ` (5 preceding siblings ...)
  2023-11-03 14:53 ` [PATCH v5 6/6] drm/imx: " Jocelyn Falempe
@ 2023-11-13 13:59 ` nerdopolis
  6 siblings, 0 replies; 16+ messages in thread
From: nerdopolis @ 2023-11-13 13:59 UTC (permalink / raw)
  To: dri-devel, tzimmermann, airlied, maarten.lankhorst, mripard,
	daniel, javierm, noralf, Jocelyn Falempe
  Cc: gpiccoli

On Friday, November 3, 2023 10:53:24 AM EST Jocelyn Falempe wrote:
> This introduces a new drm panic handler, which displays a message when a panic occurs.
> So when fbcon is disabled, you can still see a kernel panic.
> 
> This is one of the missing feature, when disabling VT/fbcon in the kernel:
> https://www.reddit.com/r/linux/comments/10eccv9/config_vtn_in_2023/
> Fbcon can be replaced by a userspace kms console, but the panic screen must be done in the kernel.
> 
> This is a proof of concept, and works with simpledrm and mgag200, using a new get_scanout_buffer() api
> 
> To test it, make sure you're using the simpledrm driver, and trigger a panic:
> echo c > /proc/sysrq-trigger
> 
> v2:
>  * Use get_scanout_buffer() instead of the drm client API. (Thomas Zimmermann)
>  * Add the panic reason to the panic message (Nerdopolis)
>  * Add an exclamation mark (Nerdopolis)
>  
> v3:
>  * Rework the drawing functions, to write the pixels line by line and
>  to use the drm conversion helper to support other formats.
>  (Thomas Zimmermann)
>  
> v4:
>  * Fully support all simpledrm formats using drm conversion helpers
>  * Rename dpanic_* to drm_panic_*, and have more coherent function name.
>    (Thomas Zimmermann)
>  * Use drm_fb_r1_to_32bit for fonts (Thomas Zimmermann)
>  * Remove the default y to DRM_PANIC config option (Thomas Zimmermann)
>  * Add foreground/background color config option
>  * Fix the bottom lines not painted if the framebuffer height
>    is not a multiple of the font height.
>  * Automatically register the driver to drm_panic, if the function
>    get_scanout_buffer() exists. (Thomas Zimmermann)
>  * Add mgag200 support.
>  
> v5:
>  * Change the drawing API, use drm_fb_blit_from_r1() to draw the font.
>    (Thomas Zimmermann)
>  * Also add drm_fb_fill() to fill area with background color.
>  * Add draw_pixel_xy() API for drivers that can't provide a linear buffer.
>  * Add a flush() callback for drivers that needs to synchronize the buffer.
>  * Add a void *private field, so drivers can pass private data to
>    draw_pixel_xy() and flush(). 
>  * Add ast support.
>  * Add experimental imx/ipuv3 support, to test on an ARM hw. (Maxime Ripard)
>  
>  
> With mgag200 support, I was able to test that the xrgb8888 to rgb565 conversion is working.
> 
I am unable to test with that hardware, but I am able to test with simpledrm, and it works pretty good
> IMX/IPUV3 support is not complete, I wasn't able to have etnaviv working on my board.
> But it shows that it can still work on ARM with DMA buffer in this case.
> 
> Best regards,
> 
> 
> Jocelyn Falempe (6):
>   drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill
>   drm/panic: Add a drm panic handler
>   drm/simpledrm: Add drm_panic support
>   drm/mgag200: Add drm_panic support
>   drm/ast: Add drm_panic support
>   drm/imx: Add drm_panic support
> 
>  drivers/gpu/drm/Kconfig                  |  22 ++
>  drivers/gpu/drm/Makefile                 |   1 +
>  drivers/gpu/drm/ast/ast_drv.c            |   4 +-
>  drivers/gpu/drm/ast/ast_drv.h            |   3 +
>  drivers/gpu/drm/ast/ast_mode.c           |  26 ++
>  drivers/gpu/drm/drm_drv.c                |   8 +
>  drivers/gpu/drm/drm_format_helper.c      | 421 ++++++++++++++++++-----
>  drivers/gpu/drm/drm_panic.c              | 368 ++++++++++++++++++++
>  drivers/gpu/drm/imx/ipuv3/imx-drm-core.c |  30 ++
>  drivers/gpu/drm/mgag200/mgag200_drv.c    |  25 ++
>  drivers/gpu/drm/tiny/simpledrm.c         |  15 +
>  include/drm/drm_drv.h                    |  21 ++
>  include/drm/drm_format_helper.h          |   9 +
>  include/drm/drm_panic.h                  |  96 ++++++
>  14 files changed, 966 insertions(+), 83 deletions(-)
>  create mode 100644 drivers/gpu/drm/drm_panic.c
>  create mode 100644 include/drm/drm_panic.h
> 
> 
> base-commit: ffc253263a1375a65fa6c9f62a893e9767fbebfa
> 





^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v5 6/6] drm/imx: Add drm_panic support
  2023-11-03 14:53 ` [PATCH v5 6/6] drm/imx: " Jocelyn Falempe
@ 2023-12-14 13:48   ` Maxime Ripard
  2023-12-14 14:36     ` Maxime Ripard
  2023-12-14 15:03     ` Jocelyn Falempe
  0 siblings, 2 replies; 16+ messages in thread
From: Maxime Ripard @ 2023-12-14 13:48 UTC (permalink / raw)
  To: Jocelyn Falempe
  Cc: bluescreen_avenger, tzimmermann, javierm, dri-devel, gpiccoli,
	noralf, airlied

[-- Attachment #1: Type: text/plain, Size: 3430 bytes --]

Hi,

On Fri, Nov 03, 2023 at 03:53:30PM +0100, Jocelyn Falempe wrote:
> Proof of concept to add drm_panic support on an arm based GPU.
> I've tested it with X11/llvmpipe, because I wasn't able to have
> 3d rendering with etnaviv on my imx6 board.
> 
> Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>

Like I said in the v6, this shouldn't be dropped because it also kind of
documents and shows what we are expecting from a "real" driver.

> ---
>  drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 30 ++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> index 4a866ac60fff..db24b4976c61 100644
> --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> @@ -10,6 +10,7 @@
>  #include <linux/dma-buf.h>
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
> +#include <linux/iosys-map.h>
>  
>  #include <video/imx-ipu-v3.h>
>  
> @@ -17,9 +18,12 @@
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_drv.h>
>  #include <drm/drm_fbdev_dma.h>
> +#include <drm/drm_fb_dma_helper.h>
> +#include <drm/drm_framebuffer.h>
>  #include <drm/drm_gem_dma_helper.h>
>  #include <drm/drm_gem_framebuffer_helper.h>
>  #include <drm/drm_managed.h>
> +#include <drm/drm_panic.h>
>  #include <drm/drm_of.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/drm_vblank.h>
> @@ -160,6 +164,31 @@ static int imx_drm_dumb_create(struct drm_file *file_priv,
>  	return ret;
>  }
>  
> +static int imx_drm_get_scanout_buffer(struct drm_device *dev,
> +				      struct drm_scanout_buffer *sb)
> +{
> +	struct drm_plane *plane;
> +	struct drm_gem_dma_object *dma_obj;
> +
> +	drm_for_each_plane(plane, dev) {
> +		if (!plane->state || !plane->state->fb || !plane->state->visible ||
> +		    plane->type != DRM_PLANE_TYPE_PRIMARY)
> +			continue;
> +
> +		dma_obj = drm_fb_dma_get_gem_obj(plane->state->fb, 0);
> +		if (!dma_obj->vaddr)
> +			continue;
> +
> +		iosys_map_set_vaddr(&sb->map, dma_obj->vaddr);
> +		sb->format = plane->state->fb->format;

Planes can be using a framebuffer in one of the numerous YUV format the
driver advertises.

> +		sb->height = plane->state->fb->height;
> +		sb->width = plane->state->fb->width;
> +		sb->pitch = plane->state->fb->pitches[0];

And your code assumes that the buffer will be large enough for an RGB
buffer, which probably isn't the case for a single-planar YUV format,
and certainly not the case for a multi-planar one.

When the driver gives back its current framebuffer, the code should check:

  * If the buffer backed by an actual buffer (and not a dma-buf handle)
  * If the buffer is mappable by the CPU
  * If the buffer is in a format that the panic code can handle
  * If the buffer uses a linear modifier

Failing that, your code cannot work at the moment. We need to be clear
about that and "gracefully" handle things instead of going forward and
writing pixels to places we might not be able to write to.

Which kind of makes me think, why do we need to involve the driver at
all there?

If in the panic code, we're going over all enabled CRTCs, finding the
primary plane currently setup for them and getting the drm_framebuffer
assigned to them, it should be enough to get us all the informations we
need, right?

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v5 6/6] drm/imx: Add drm_panic support
  2023-12-14 13:48   ` Maxime Ripard
@ 2023-12-14 14:36     ` Maxime Ripard
  2023-12-14 15:03     ` Jocelyn Falempe
  1 sibling, 0 replies; 16+ messages in thread
From: Maxime Ripard @ 2023-12-14 14:36 UTC (permalink / raw)
  To: Jocelyn Falempe
  Cc: bluescreen_avenger, tzimmermann, javierm, dri-devel, gpiccoli,
	noralf, airlied

[-- Attachment #1: Type: text/plain, Size: 3902 bytes --]

On Thu, Dec 14, 2023 at 02:48:21PM +0100, Maxime Ripard wrote:
> Hi,
> 
> On Fri, Nov 03, 2023 at 03:53:30PM +0100, Jocelyn Falempe wrote:
> > Proof of concept to add drm_panic support on an arm based GPU.
> > I've tested it with X11/llvmpipe, because I wasn't able to have
> > 3d rendering with etnaviv on my imx6 board.
> > 
> > Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
> 
> Like I said in the v6, this shouldn't be dropped because it also kind of
> documents and shows what we are expecting from a "real" driver.
> 
> > ---
> >  drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 30 ++++++++++++++++++++++++
> >  1 file changed, 30 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> > index 4a866ac60fff..db24b4976c61 100644
> > --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> > +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> > @@ -10,6 +10,7 @@
> >  #include <linux/dma-buf.h>
> >  #include <linux/module.h>
> >  #include <linux/platform_device.h>
> > +#include <linux/iosys-map.h>
> >  
> >  #include <video/imx-ipu-v3.h>
> >  
> > @@ -17,9 +18,12 @@
> >  #include <drm/drm_atomic_helper.h>
> >  #include <drm/drm_drv.h>
> >  #include <drm/drm_fbdev_dma.h>
> > +#include <drm/drm_fb_dma_helper.h>
> > +#include <drm/drm_framebuffer.h>
> >  #include <drm/drm_gem_dma_helper.h>
> >  #include <drm/drm_gem_framebuffer_helper.h>
> >  #include <drm/drm_managed.h>
> > +#include <drm/drm_panic.h>
> >  #include <drm/drm_of.h>
> >  #include <drm/drm_probe_helper.h>
> >  #include <drm/drm_vblank.h>
> > @@ -160,6 +164,31 @@ static int imx_drm_dumb_create(struct drm_file *file_priv,
> >  	return ret;
> >  }
> >  
> > +static int imx_drm_get_scanout_buffer(struct drm_device *dev,
> > +				      struct drm_scanout_buffer *sb)
> > +{
> > +	struct drm_plane *plane;
> > +	struct drm_gem_dma_object *dma_obj;
> > +
> > +	drm_for_each_plane(plane, dev) {
> > +		if (!plane->state || !plane->state->fb || !plane->state->visible ||
> > +		    plane->type != DRM_PLANE_TYPE_PRIMARY)
> > +			continue;
> > +
> > +		dma_obj = drm_fb_dma_get_gem_obj(plane->state->fb, 0);
> > +		if (!dma_obj->vaddr)
> > +			continue;
> > +
> > +		iosys_map_set_vaddr(&sb->map, dma_obj->vaddr);
> > +		sb->format = plane->state->fb->format;
> 
> Planes can be using a framebuffer in one of the numerous YUV format the
> driver advertises.
> 
> > +		sb->height = plane->state->fb->height;
> > +		sb->width = plane->state->fb->width;
> > +		sb->pitch = plane->state->fb->pitches[0];
> 
> And your code assumes that the buffer will be large enough for an RGB
> buffer, which probably isn't the case for a single-planar YUV format,
> and certainly not the case for a multi-planar one.
> 
> When the driver gives back its current framebuffer, the code should check:

Oh, and also, you need to keep an eye on the solid fill support:

https://lore.kernel.org/all/20231027-solid-fill-v7-0-780188bfa7b2@quicinc.com/

Because with that, a plane might not have a framebuffer anymore.

>   * If the buffer backed by an actual buffer (and not a dma-buf handle)
>   * If the buffer is mappable by the CPU
>   * If the buffer is in a format that the panic code can handle
>   * If the buffer uses a linear modifier
> 
> Failing that, your code cannot work at the moment. We need to be clear
> about that and "gracefully" handle things instead of going forward and
> writing pixels to places we might not be able to write to.
> 
> Which kind of makes me think, why do we need to involve the driver at
> all there?
> 
> If in the panic code, we're going over all enabled CRTCs, finding the
> primary plane currently setup for them and getting the drm_framebuffer
> assigned to them, it should be enough to get us all the informations we
> need, right?
> 
> Maxime



[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v5 6/6] drm/imx: Add drm_panic support
  2023-12-14 13:48   ` Maxime Ripard
  2023-12-14 14:36     ` Maxime Ripard
@ 2023-12-14 15:03     ` Jocelyn Falempe
  2023-12-14 18:37       ` Maxime Ripard
  1 sibling, 1 reply; 16+ messages in thread
From: Jocelyn Falempe @ 2023-12-14 15:03 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: bluescreen_avenger, tzimmermann, javierm, dri-devel, gpiccoli,
	noralf, airlied



On 14/12/2023 14:48, Maxime Ripard wrote:
> Hi,
> 
> On Fri, Nov 03, 2023 at 03:53:30PM +0100, Jocelyn Falempe wrote:
>> Proof of concept to add drm_panic support on an arm based GPU.
>> I've tested it with X11/llvmpipe, because I wasn't able to have
>> 3d rendering with etnaviv on my imx6 board.
>>
>> Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
> 
> Like I said in the v6, this shouldn't be dropped because it also kind of
> documents and shows what we are expecting from a "real" driver.

Ok, I can bring it back in v7.

> 
>> ---
>>   drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 30 ++++++++++++++++++++++++
>>   1 file changed, 30 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
>> index 4a866ac60fff..db24b4976c61 100644
>> --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
>> +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
>> @@ -10,6 +10,7 @@
>>   #include <linux/dma-buf.h>
>>   #include <linux/module.h>
>>   #include <linux/platform_device.h>
>> +#include <linux/iosys-map.h>
>>   
>>   #include <video/imx-ipu-v3.h>
>>   
>> @@ -17,9 +18,12 @@
>>   #include <drm/drm_atomic_helper.h>
>>   #include <drm/drm_drv.h>
>>   #include <drm/drm_fbdev_dma.h>
>> +#include <drm/drm_fb_dma_helper.h>
>> +#include <drm/drm_framebuffer.h>
>>   #include <drm/drm_gem_dma_helper.h>
>>   #include <drm/drm_gem_framebuffer_helper.h>
>>   #include <drm/drm_managed.h>
>> +#include <drm/drm_panic.h>
>>   #include <drm/drm_of.h>
>>   #include <drm/drm_probe_helper.h>
>>   #include <drm/drm_vblank.h>
>> @@ -160,6 +164,31 @@ static int imx_drm_dumb_create(struct drm_file *file_priv,
>>   	return ret;
>>   }
>>   
>> +static int imx_drm_get_scanout_buffer(struct drm_device *dev,
>> +				      struct drm_scanout_buffer *sb)
>> +{
>> +	struct drm_plane *plane;
>> +	struct drm_gem_dma_object *dma_obj;
>> +
>> +	drm_for_each_plane(plane, dev) {
>> +		if (!plane->state || !plane->state->fb || !plane->state->visible ||
>> +		    plane->type != DRM_PLANE_TYPE_PRIMARY)
>> +			continue;
>> +
>> +		dma_obj = drm_fb_dma_get_gem_obj(plane->state->fb, 0);
>> +		if (!dma_obj->vaddr)
>> +			continue;
>> +
>> +		iosys_map_set_vaddr(&sb->map, dma_obj->vaddr);
>> +		sb->format = plane->state->fb->format;
> 
> Planes can be using a framebuffer in one of the numerous YUV format the
> driver advertises.
> 
>> +		sb->height = plane->state->fb->height;
>> +		sb->width = plane->state->fb->width;
>> +		sb->pitch = plane->state->fb->pitches[0];
> 
> And your code assumes that the buffer will be large enough for an RGB
> buffer, which probably isn't the case for a single-planar YUV format,
> and certainly not the case for a multi-planar one.

Yes, this code is a bit hacky, and on my test setup the framebuffer was 
in RGB, so I didn't handle other formats.
Also it should be possible to add YUV format later, but I would like to 
have a minimal drm_panic merged, before adding more features.
> 
> When the driver gives back its current framebuffer, the code should check:
> 
>    * If the buffer backed by an actual buffer (and not a dma-buf handle)

Regarding the struct drm_framebuffer, I'm not sure how do you 
differentiate an actual buffer from a dma-buf handle ?

>    * If the buffer is mappable by the CPU

If "dma_obj->vaddr" is not null, then it's already mapped by the CPU right ?
>    * If the buffer is in a format that the panic code can handle
>    * If the buffer uses a linear modifier

Yes, that must be checked too.

> 
> Failing that, your code cannot work at the moment. We need to be clear
> about that and "gracefully" handle things instead of going forward and
> writing pixels to places we might not be able to write to.
> 
> Which kind of makes me think, why do we need to involve the driver at
> all there?
> 
> If in the panic code, we're going over all enabled CRTCs, finding the
> primary plane currently setup for them and getting the drm_framebuffer
> assigned to them, it should be enough to get us all the informations we
> need, right?

Yes, I think I can do a generic implementation for the drivers using the 
drm_gem_dma helper like imx6.
But for simpledrm, ast, or mgag200, I need to retrieve the VRAM address, 
because it's not in the drm_framebuffer struct, so they won't be able to 
use this generic implementation.

> 
> Maxime

Thanks for the review,

-- 

Jocelyn


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v5 6/6] drm/imx: Add drm_panic support
  2023-12-14 15:03     ` Jocelyn Falempe
@ 2023-12-14 18:37       ` Maxime Ripard
  0 siblings, 0 replies; 16+ messages in thread
From: Maxime Ripard @ 2023-12-14 18:37 UTC (permalink / raw)
  To: Jocelyn Falempe
  Cc: bluescreen_avenger, tzimmermann, javierm, dri-devel, gpiccoli,
	noralf, airlied

[-- Attachment #1: Type: text/plain, Size: 3778 bytes --]

On Thu, Dec 14, 2023 at 04:03:04PM +0100, Jocelyn Falempe wrote:
> > > +static int imx_drm_get_scanout_buffer(struct drm_device *dev,
> > > +				      struct drm_scanout_buffer *sb)
> > > +{
> > > +	struct drm_plane *plane;
> > > +	struct drm_gem_dma_object *dma_obj;
> > > +
> > > +	drm_for_each_plane(plane, dev) {
> > > +		if (!plane->state || !plane->state->fb || !plane->state->visible ||
> > > +		    plane->type != DRM_PLANE_TYPE_PRIMARY)
> > > +			continue;
> > > +
> > > +		dma_obj = drm_fb_dma_get_gem_obj(plane->state->fb, 0);
> > > +		if (!dma_obj->vaddr)
> > > +			continue;
> > > +
> > > +		iosys_map_set_vaddr(&sb->map, dma_obj->vaddr);
> > > +		sb->format = plane->state->fb->format;
> > 
> > Planes can be using a framebuffer in one of the numerous YUV format the
> > driver advertises.
> > 
> > > +		sb->height = plane->state->fb->height;
> > > +		sb->width = plane->state->fb->width;
> > > +		sb->pitch = plane->state->fb->pitches[0];
> > 
> > And your code assumes that the buffer will be large enough for an RGB
> > buffer, which probably isn't the case for a single-planar YUV format,
> > and certainly not the case for a multi-planar one.
> 
> Yes, this code is a bit hacky, and on my test setup the framebuffer was in
> RGB, so I didn't handle other formats.
> Also it should be possible to add YUV format later, but I would like to have
> a minimal drm_panic merged, before adding more features.

Sure. Having a minimal panic code is reasonable, but we should properly
handle not supporting them still :)

There's cases where, with the current architecture anyway, you just
won't be able to print a panic message and that's fine. The important
part is not crashing the kernel further and being as loud as we can that
we couldn't print a panic message on the screen because of the setup.

> > When the driver gives back its current framebuffer, the code should check:
> > 
> >    * If the buffer backed by an actual buffer (and not a dma-buf handle)
> 
> Regarding the struct drm_framebuffer, I'm not sure how do you differentiate
> an actual buffer from a dma-buf handle ?

Its backing drm_gem_object should be set and have the field import_attach set

> >    * If the buffer is mappable by the CPU
> 
> If "dma_obj->vaddr" is not null, then it's already mapped by the CPU right ?

I'm not sure. drm_gem_dma_create will only ever create CPU-mappable
buffers, but drm_gem_dma_prime_import_sg_table won't for example.

> >    * If the buffer is in a format that the panic code can handle
> >    * If the buffer uses a linear modifier
> 
> Yes, that must be checked too.
> 
> > 
> > Failing that, your code cannot work at the moment. We need to be clear
> > about that and "gracefully" handle things instead of going forward and
> > writing pixels to places we might not be able to write to.
> > 
> > Which kind of makes me think, why do we need to involve the driver at
> > all there?
> > 
> > If in the panic code, we're going over all enabled CRTCs, finding the
> > primary plane currently setup for them and getting the drm_framebuffer
> > assigned to them, it should be enough to get us all the informations we
> > need, right?
> 
> Yes, I think I can do a generic implementation for the drivers using the
> drm_gem_dma helper like imx6.
> But for simpledrm, ast, or mgag200, I need to retrieve the VRAM address,
> because it's not in the drm_framebuffer struct, so they won't be able to use
> this generic implementation.

Sure :)

I guess we could have a CRTC function then that by default will just
return the current primary plane framebuffer (or could be a plane
function?), and if it's not there just grabs the one from the current
active state.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2023-12-14 18:37 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-03 14:53 [RFC][PATCH v5 0/6] drm/panic: Add a drm panic handler Jocelyn Falempe
2023-11-03 14:53 ` [PATCH v5 1/6] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill Jocelyn Falempe
2023-11-03 18:34   ` kernel test robot
2023-11-04  6:04   ` kernel test robot
2023-11-03 14:53 ` [PATCH v5 2/6] drm/panic: Add a drm panic handler Jocelyn Falempe
2023-11-03 14:53 ` [PATCH v5 3/6] drm/simpledrm: Add drm_panic support Jocelyn Falempe
2023-11-03 14:53 ` [PATCH v5 4/6] drm/mgag200: " Jocelyn Falempe
2023-11-03 14:53 ` [PATCH v5 5/6] drm/ast: " Jocelyn Falempe
2023-11-03 18:52   ` kernel test robot
2023-11-04  3:57   ` kernel test robot
2023-11-03 14:53 ` [PATCH v5 6/6] drm/imx: " Jocelyn Falempe
2023-12-14 13:48   ` Maxime Ripard
2023-12-14 14:36     ` Maxime Ripard
2023-12-14 15:03     ` Jocelyn Falempe
2023-12-14 18:37       ` Maxime Ripard
2023-11-13 13:59 ` [RFC][PATCH v5 0/6] drm/panic: Add a drm panic handler nerdopolis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).