Commit 31fa2c1c authored by Jocelyn Falempe's avatar Jocelyn Falempe
Browse files

drm/panic: Move drawing functions to drm_draw



Move the color conversions, blit and fill functions to drm_draw.c,
so that they can be re-used by drm_log.
drm_draw is internal to the drm subsystem, and shouldn't be used by
gpu drivers.

Signed-off-by: default avatarJocelyn Falempe <jfalempe@redhat.com>
Reviewed-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20241204160014.1171469-2-jfalempe@redhat.com
parent 68573a56
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -102,10 +102,15 @@ config DRM_KMS_HELPER
	help
	  CRTC helpers for KMS drivers.

config DRM_DRAW
	bool
	depends on DRM

config DRM_PANIC
	bool "Display a user-friendly message when a kernel panic occurs"
	depends on DRM
	select FONT_SUPPORT
	select DRM_DRAW
	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
+1 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \
	drm_privacy_screen_x86.o
drm-$(CONFIG_DRM_ACCEL) += ../../accel/drm_accel.o
drm-$(CONFIG_DRM_PANIC) += drm_panic.o
drm-$(CONFIG_DRM_DRAW) += drm_draw.o
drm-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) += drm_panic_qr.o
obj-$(CONFIG_DRM)	+= drm.o

+233 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0 or MIT
/*
 * Copyright (c) 2023 Red Hat.
 * Author: Jocelyn Falempe <jfalempe@redhat.com>
 */

#include <linux/bits.h>
#include <linux/iosys-map.h>
#include <linux/types.h>

#include <drm/drm_fourcc.h>

#include "drm_draw_internal.h"

/*
 * Conversions from xrgb8888
 */

static u16 convert_xrgb8888_to_rgb565(u32 pix)
{
	return ((pix & 0x00F80000) >> 8) |
	       ((pix & 0x0000FC00) >> 5) |
	       ((pix & 0x000000F8) >> 3);
}

static u16 convert_xrgb8888_to_rgba5551(u32 pix)
{
	return ((pix & 0x00f80000) >> 8) |
	       ((pix & 0x0000f800) >> 5) |
	       ((pix & 0x000000f8) >> 2) |
	       BIT(0); /* set alpha bit */
}

static u16 convert_xrgb8888_to_xrgb1555(u32 pix)
{
	return ((pix & 0x00f80000) >> 9) |
	       ((pix & 0x0000f800) >> 6) |
	       ((pix & 0x000000f8) >> 3);
}

static u16 convert_xrgb8888_to_argb1555(u32 pix)
{
	return BIT(15) | /* set alpha bit */
	       ((pix & 0x00f80000) >> 9) |
	       ((pix & 0x0000f800) >> 6) |
	       ((pix & 0x000000f8) >> 3);
}

static u32 convert_xrgb8888_to_argb8888(u32 pix)
{
	return pix | GENMASK(31, 24); /* fill alpha bits */
}

static u32 convert_xrgb8888_to_xbgr8888(u32 pix)
{
	return ((pix & 0x00ff0000) >> 16) <<  0 |
	       ((pix & 0x0000ff00) >>  8) <<  8 |
	       ((pix & 0x000000ff) >>  0) << 16 |
	       ((pix & 0xff000000) >> 24) << 24;
}

static u32 convert_xrgb8888_to_abgr8888(u32 pix)
{
	return ((pix & 0x00ff0000) >> 16) <<  0 |
	       ((pix & 0x0000ff00) >>  8) <<  8 |
	       ((pix & 0x000000ff) >>  0) << 16 |
	       GENMASK(31, 24); /* fill alpha bits */
}

static u32 convert_xrgb8888_to_xrgb2101010(u32 pix)
{
	pix = ((pix & 0x000000FF) << 2) |
	      ((pix & 0x0000FF00) << 4) |
	      ((pix & 0x00FF0000) << 6);
	return pix | ((pix >> 8) & 0x00300C03);
}

static u32 convert_xrgb8888_to_argb2101010(u32 pix)
{
	pix = ((pix & 0x000000FF) << 2) |
	      ((pix & 0x0000FF00) << 4) |
	      ((pix & 0x00FF0000) << 6);
	return GENMASK(31, 30) /* set alpha bits */ | pix | ((pix >> 8) & 0x00300C03);
}

static u32 convert_xrgb8888_to_abgr2101010(u32 pix)
{
	pix = ((pix & 0x00FF0000) >> 14) |
	      ((pix & 0x0000FF00) << 4) |
	      ((pix & 0x000000FF) << 22);
	return GENMASK(31, 30) /* set alpha bits */ | pix | ((pix >> 8) & 0x00300C03);
}

/**
 * drm_draw_color_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.
 * Or 0 if the format is not supported.
 */
u32 drm_draw_color_from_xrgb8888(u32 color, u32 format)
{
	switch (format) {
	case DRM_FORMAT_RGB565:
		return convert_xrgb8888_to_rgb565(color);
	case DRM_FORMAT_RGBA5551:
		return convert_xrgb8888_to_rgba5551(color);
	case DRM_FORMAT_XRGB1555:
		return convert_xrgb8888_to_xrgb1555(color);
	case DRM_FORMAT_ARGB1555:
		return convert_xrgb8888_to_argb1555(color);
	case DRM_FORMAT_RGB888:
	case DRM_FORMAT_XRGB8888:
		return color;
	case DRM_FORMAT_ARGB8888:
		return convert_xrgb8888_to_argb8888(color);
	case DRM_FORMAT_XBGR8888:
		return convert_xrgb8888_to_xbgr8888(color);
	case DRM_FORMAT_ABGR8888:
		return convert_xrgb8888_to_abgr8888(color);
	case DRM_FORMAT_XRGB2101010:
		return convert_xrgb8888_to_xrgb2101010(color);
	case DRM_FORMAT_ARGB2101010:
		return convert_xrgb8888_to_argb2101010(color);
	case DRM_FORMAT_ABGR2101010:
		return convert_xrgb8888_to_abgr2101010(color);
	default:
		WARN_ONCE(1, "Can't convert to %p4cc\n", &format);
		return 0;
	}
}
EXPORT_SYMBOL(drm_draw_color_from_xrgb8888);

/*
 * Blit functions
 */
void drm_draw_blit16(struct iosys_map *dmap, unsigned int dpitch,
		     const u8 *sbuf8, unsigned int spitch,
		     unsigned int height, unsigned int width,
		     unsigned int scale, u16 fg16)
{
	unsigned int y, x;

	for (y = 0; y < height; y++)
		for (x = 0; x < width; x++)
			if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
				iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, fg16);
}
EXPORT_SYMBOL(drm_draw_blit16);

void drm_draw_blit24(struct iosys_map *dmap, unsigned int dpitch,
		     const u8 *sbuf8, unsigned int spitch,
		     unsigned int height, unsigned int width,
		     unsigned int scale, u32 fg32)
{
	unsigned int y, x;

	for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
			u32 off = y * dpitch + x * 3;

			if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) {
				/* write blue-green-red to output in little endianness */
				iosys_map_wr(dmap, off, u8, (fg32 & 0x000000FF) >> 0);
				iosys_map_wr(dmap, off + 1, u8, (fg32 & 0x0000FF00) >> 8);
				iosys_map_wr(dmap, off + 2, u8, (fg32 & 0x00FF0000) >> 16);
			}
		}
	}
}
EXPORT_SYMBOL(drm_draw_blit24);

void drm_draw_blit32(struct iosys_map *dmap, unsigned int dpitch,
		     const u8 *sbuf8, unsigned int spitch,
		     unsigned int height, unsigned int width,
		     unsigned int scale, u32 fg32)
{
	unsigned int y, x;

	for (y = 0; y < height; y++)
		for (x = 0; x < width; x++)
			if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
				iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, fg32);
}
EXPORT_SYMBOL(drm_draw_blit32);

/*
 * Fill functions
 */
void drm_draw_fill16(struct iosys_map *dmap, unsigned int dpitch,
		     unsigned int height, unsigned int width,
		     u16 color)
{
	unsigned int y, x;

	for (y = 0; y < height; y++)
		for (x = 0; x < width; x++)
			iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, color);
}
EXPORT_SYMBOL(drm_draw_fill16);

void drm_draw_fill24(struct iosys_map *dmap, unsigned int dpitch,
		     unsigned int height, unsigned int width,
		     u16 color)
{
	unsigned int y, x;

	for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
			unsigned int off = y * dpitch + x * 3;

			/* write blue-green-red to output in little endianness */
			iosys_map_wr(dmap, off, u8, (color & 0x000000FF) >> 0);
			iosys_map_wr(dmap, off + 1, u8, (color & 0x0000FF00) >> 8);
			iosys_map_wr(dmap, off + 2, u8, (color & 0x00FF0000) >> 16);
		}
	}
}
EXPORT_SYMBOL(drm_draw_fill24);

void drm_draw_fill32(struct iosys_map *dmap, unsigned int dpitch,
		     unsigned int height, unsigned int width,
		     u32 color)
{
	unsigned int y, x;

	for (y = 0; y < height; y++)
		for (x = 0; x < width; x++)
			iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, color);
}
EXPORT_SYMBOL(drm_draw_fill32);
+56 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 or MIT */
/*
 * Copyright (c) 2023 Red Hat.
 * Author: Jocelyn Falempe <jfalempe@redhat.com>
 */

#ifndef __DRM_DRAW_INTERNAL_H__
#define __DRM_DRAW_INTERNAL_H__

#include <linux/font.h>
#include <linux/types.h>

struct iosys_map;

/* check if the pixel at coord x,y is 1 (foreground) or 0 (background) */
static inline bool drm_draw_is_pixel_fg(const u8 *sbuf8, unsigned int spitch, int x, int y)
{
	return (sbuf8[(y * spitch) + x / 8] & (0x80 >> (x % 8))) != 0;
}

static inline const u8 *drm_draw_get_char_bitmap(const struct font_desc *font,
						 char c, size_t font_pitch)
{
	return font->data + (c * font->height) * font_pitch;
}

u32 drm_draw_color_from_xrgb8888(u32 color, u32 format);

void drm_draw_blit16(struct iosys_map *dmap, unsigned int dpitch,
		     const u8 *sbuf8, unsigned int spitch,
		     unsigned int height, unsigned int width,
		     unsigned int scale, u16 fg16);

void drm_draw_blit24(struct iosys_map *dmap, unsigned int dpitch,
		     const u8 *sbuf8, unsigned int spitch,
		     unsigned int height, unsigned int width,
		     unsigned int scale, u32 fg32);

void drm_draw_blit32(struct iosys_map *dmap, unsigned int dpitch,
		     const u8 *sbuf8, unsigned int spitch,
		     unsigned int height, unsigned int width,
		     unsigned int scale, u32 fg32);

void drm_draw_fill16(struct iosys_map *dmap, unsigned int dpitch,
		     unsigned int height, unsigned int width,
		     u16 color);

void drm_draw_fill24(struct iosys_map *dmap, unsigned int dpitch,
		     unsigned int height, unsigned int width,
		     u16 color);

void drm_draw_fill32(struct iosys_map *dmap, unsigned int dpitch,
		     unsigned int height, unsigned int width,
		     u32 color);

#endif /* __DRM_DRAW_INTERNAL_H__ */
+29 −240
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <drm/drm_rect.h>

#include "drm_crtc_internal.h"
#include "drm_draw_internal.h"

MODULE_AUTHOR("Jocelyn Falempe");
MODULE_DESCRIPTION("DRM panic handler");
@@ -139,181 +140,8 @@ device_initcall(drm_panic_setup_logo);
#endif

/*
 * Color conversion
 *  Blit & Fill functions
 */

static u16 convert_xrgb8888_to_rgb565(u32 pix)
{
	return ((pix & 0x00F80000) >> 8) |
	       ((pix & 0x0000FC00) >> 5) |
	       ((pix & 0x000000F8) >> 3);
}

static u16 convert_xrgb8888_to_rgba5551(u32 pix)
{
	return ((pix & 0x00f80000) >> 8) |
	       ((pix & 0x0000f800) >> 5) |
	       ((pix & 0x000000f8) >> 2) |
	       BIT(0); /* set alpha bit */
}

static u16 convert_xrgb8888_to_xrgb1555(u32 pix)
{
	return ((pix & 0x00f80000) >> 9) |
	       ((pix & 0x0000f800) >> 6) |
	       ((pix & 0x000000f8) >> 3);
}

static u16 convert_xrgb8888_to_argb1555(u32 pix)
{
	return BIT(15) | /* set alpha bit */
	       ((pix & 0x00f80000) >> 9) |
	       ((pix & 0x0000f800) >> 6) |
	       ((pix & 0x000000f8) >> 3);
}

static u32 convert_xrgb8888_to_argb8888(u32 pix)
{
	return pix | GENMASK(31, 24); /* fill alpha bits */
}

static u32 convert_xrgb8888_to_xbgr8888(u32 pix)
{
	return ((pix & 0x00ff0000) >> 16) <<  0 |
	       ((pix & 0x0000ff00) >>  8) <<  8 |
	       ((pix & 0x000000ff) >>  0) << 16 |
	       ((pix & 0xff000000) >> 24) << 24;
}

static u32 convert_xrgb8888_to_abgr8888(u32 pix)
{
	return ((pix & 0x00ff0000) >> 16) <<  0 |
	       ((pix & 0x0000ff00) >>  8) <<  8 |
	       ((pix & 0x000000ff) >>  0) << 16 |
	       GENMASK(31, 24); /* fill alpha bits */
}

static u32 convert_xrgb8888_to_xrgb2101010(u32 pix)
{
	pix = ((pix & 0x000000FF) << 2) |
	      ((pix & 0x0000FF00) << 4) |
	      ((pix & 0x00FF0000) << 6);
	return pix | ((pix >> 8) & 0x00300C03);
}

static u32 convert_xrgb8888_to_argb2101010(u32 pix)
{
	pix = ((pix & 0x000000FF) << 2) |
	      ((pix & 0x0000FF00) << 4) |
	      ((pix & 0x00FF0000) << 6);
	return GENMASK(31, 30) /* set alpha bits */ | pix | ((pix >> 8) & 0x00300C03);
}

static u32 convert_xrgb8888_to_abgr2101010(u32 pix)
{
	pix = ((pix & 0x00FF0000) >> 14) |
	      ((pix & 0x0000FF00) << 4) |
	      ((pix & 0x000000FF) << 22);
	return GENMASK(31, 30) /* set alpha bits */ | pix | ((pix >> 8) & 0x00300C03);
}

/*
 * 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.
 * Or 0 if the format is not supported.
 */
static u32 convert_from_xrgb8888(u32 color, u32 format)
{
	switch (format) {
	case DRM_FORMAT_RGB565:
		return convert_xrgb8888_to_rgb565(color);
	case DRM_FORMAT_RGBA5551:
		return convert_xrgb8888_to_rgba5551(color);
	case DRM_FORMAT_XRGB1555:
		return convert_xrgb8888_to_xrgb1555(color);
	case DRM_FORMAT_ARGB1555:
		return convert_xrgb8888_to_argb1555(color);
	case DRM_FORMAT_RGB888:
	case DRM_FORMAT_XRGB8888:
		return color;
	case DRM_FORMAT_ARGB8888:
		return convert_xrgb8888_to_argb8888(color);
	case DRM_FORMAT_XBGR8888:
		return convert_xrgb8888_to_xbgr8888(color);
	case DRM_FORMAT_ABGR8888:
		return convert_xrgb8888_to_abgr8888(color);
	case DRM_FORMAT_XRGB2101010:
		return convert_xrgb8888_to_xrgb2101010(color);
	case DRM_FORMAT_ARGB2101010:
		return convert_xrgb8888_to_argb2101010(color);
	case DRM_FORMAT_ABGR2101010:
		return convert_xrgb8888_to_abgr2101010(color);
	default:
		WARN_ONCE(1, "Can't convert to %p4cc\n", &format);
		return 0;
	}
}

/*
 * Blit & Fill
 */
/* check if the pixel at coord x,y is 1 (foreground) or 0 (background) */
static bool drm_panic_is_pixel_fg(const u8 *sbuf8, unsigned int spitch, int x, int y)
{
	return (sbuf8[(y * spitch) + x / 8] & (0x80 >> (x % 8))) != 0;
}

static void drm_panic_blit16(struct iosys_map *dmap, unsigned int dpitch,
			     const u8 *sbuf8, unsigned int spitch,
			     unsigned int height, unsigned int width,
			     unsigned int scale, u16 fg16)
{
	unsigned int y, x;

	for (y = 0; y < height; y++)
		for (x = 0; x < width; x++)
			if (drm_panic_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
				iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, fg16);
}

static void drm_panic_blit24(struct iosys_map *dmap, unsigned int dpitch,
			     const u8 *sbuf8, unsigned int spitch,
			     unsigned int height, unsigned int width,
			     unsigned int scale, u32 fg32)
{
	unsigned int y, x;

	for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
			u32 off = y * dpitch + x * 3;

			if (drm_panic_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) {
				/* write blue-green-red to output in little endianness */
				iosys_map_wr(dmap, off, u8, (fg32 & 0x000000FF) >> 0);
				iosys_map_wr(dmap, off + 1, u8, (fg32 & 0x0000FF00) >> 8);
				iosys_map_wr(dmap, off + 2, u8, (fg32 & 0x00FF0000) >> 16);
			}
		}
	}
}

static void drm_panic_blit32(struct iosys_map *dmap, unsigned int dpitch,
			     const u8 *sbuf8, unsigned int spitch,
			     unsigned int height, unsigned int width,
			     unsigned int scale, u32 fg32)
{
	unsigned int y, x;

	for (y = 0; y < height; y++)
		for (x = 0; x < width; x++)
			if (drm_panic_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
				iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, fg32);
}

static void drm_panic_blit_pixel(struct drm_scanout_buffer *sb, struct drm_rect *clip,
				 const u8 *sbuf8, unsigned int spitch, unsigned int scale,
				 u32 fg_color)
@@ -322,7 +150,7 @@ static void drm_panic_blit_pixel(struct drm_scanout_buffer *sb, struct drm_rect

	for (y = 0; y < drm_rect_height(clip); y++)
		for (x = 0; x < drm_rect_width(clip); x++)
			if (drm_panic_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
			if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
				sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, fg_color);
}

@@ -354,15 +182,15 @@ static void drm_panic_blit(struct drm_scanout_buffer *sb, struct drm_rect *clip,

	switch (sb->format->cpp[0]) {
	case 2:
		drm_panic_blit16(&map, sb->pitch[0], sbuf8, spitch,
		drm_draw_blit16(&map, sb->pitch[0], sbuf8, spitch,
				drm_rect_height(clip), drm_rect_width(clip), scale, fg_color);
	break;
	case 3:
		drm_panic_blit24(&map, sb->pitch[0], sbuf8, spitch,
		drm_draw_blit24(&map, sb->pitch[0], sbuf8, spitch,
				drm_rect_height(clip), drm_rect_width(clip), scale, fg_color);
	break;
	case 4:
		drm_panic_blit32(&map, sb->pitch[0], sbuf8, spitch,
		drm_draw_blit32(&map, sb->pitch[0], sbuf8, spitch,
				drm_rect_height(clip), drm_rect_width(clip), scale, fg_color);
	break;
	default:
@@ -370,46 +198,6 @@ static void drm_panic_blit(struct drm_scanout_buffer *sb, struct drm_rect *clip,
	}
}

static void drm_panic_fill16(struct iosys_map *dmap, unsigned int dpitch,
			     unsigned int height, unsigned int width,
			     u16 color)
{
	unsigned int y, x;

	for (y = 0; y < height; y++)
		for (x = 0; x < width; x++)
			iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, color);
}

static void drm_panic_fill24(struct iosys_map *dmap, unsigned int dpitch,
			     unsigned int height, unsigned int width,
			     u32 color)
{
	unsigned int y, x;

	for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
			unsigned int off = y * dpitch + x * 3;

			/* write blue-green-red to output in little endianness */
			iosys_map_wr(dmap, off, u8, (color & 0x000000FF) >> 0);
			iosys_map_wr(dmap, off + 1, u8, (color & 0x0000FF00) >> 8);
			iosys_map_wr(dmap, off + 2, u8, (color & 0x00FF0000) >> 16);
		}
	}
}

static void drm_panic_fill32(struct iosys_map *dmap, unsigned int dpitch,
			     unsigned int height, unsigned int width,
			     u32 color)
{
	unsigned int y, x;

	for (y = 0; y < height; y++)
		for (x = 0; x < width; x++)
			iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, color);
}

static void drm_panic_fill_pixel(struct drm_scanout_buffer *sb,
				 struct drm_rect *clip,
				 u32 color)
@@ -442,15 +230,15 @@ static void drm_panic_fill(struct drm_scanout_buffer *sb, struct drm_rect *clip,

	switch (sb->format->cpp[0]) {
	case 2:
		drm_panic_fill16(&map, sb->pitch[0], drm_rect_height(clip),
		drm_draw_fill16(&map, sb->pitch[0], drm_rect_height(clip),
				drm_rect_width(clip), color);
	break;
	case 3:
		drm_panic_fill24(&map, sb->pitch[0], drm_rect_height(clip),
		drm_draw_fill24(&map, sb->pitch[0], drm_rect_height(clip),
				drm_rect_width(clip), color);
	break;
	case 4:
		drm_panic_fill32(&map, sb->pitch[0], drm_rect_height(clip),
		drm_draw_fill32(&map, sb->pitch[0], drm_rect_height(clip),
				drm_rect_width(clip), color);
	break;
	default:
@@ -458,11 +246,6 @@ static void drm_panic_fill(struct drm_scanout_buffer *sb, struct drm_rect *clip,
	}
}

static const u8 *get_char_bitmap(const struct font_desc *font, char c, size_t font_pitch)
{
	return font->data + (c * font->height) * font_pitch;
}

static unsigned int get_max_line_len(const struct drm_panic_line *lines, int len)
{
	int i;
@@ -501,7 +284,7 @@ static void draw_txt_rectangle(struct drm_scanout_buffer *sb,
			rec.x1 += (drm_rect_width(clip) - (line_len * font->width)) / 2;

		for (j = 0; j < line_len; j++) {
			src = get_char_bitmap(font, msg[i].txt[j], font_pitch);
			src = drm_draw_get_char_bitmap(font, msg[i].txt[j], font_pitch);
			rec.x2 = rec.x1 + font->width;
			drm_panic_blit(sb, &rec, src, font_pitch, 1, color);
			rec.x1 += font->width;
@@ -533,8 +316,10 @@ static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *

static void draw_panic_static_user(struct drm_scanout_buffer *sb)
{
	u32 fg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, sb->format->format);
	u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format);
	u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR,
						    sb->format->format);
	u32 bg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR,
						    sb->format->format);
	const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
	struct drm_rect r_screen, r_logo, r_msg;
	unsigned int msg_width, msg_height;
@@ -600,8 +385,10 @@ static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_
 */
static void draw_panic_static_kmsg(struct drm_scanout_buffer *sb)
{
	u32 fg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, sb->format->format);
	u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format);
	u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR,
						    sb->format->format);
	u32 bg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR,
						    sb->format->format);
	const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
	struct drm_rect r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
	struct kmsg_dump_iter iter;
@@ -791,8 +578,10 @@ static int drm_panic_get_qr_code(u8 **qr_image)
 */
static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
{
	u32 fg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, sb->format->format);
	u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format);
	u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR,
						    sb->format->format);
	u32 bg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR,
						    sb->format->format);
	const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
	struct drm_rect r_screen, r_logo, r_msg, r_qr, r_qr_canvas;
	unsigned int max_qr_size, scale;
@@ -878,7 +667,7 @@ static bool drm_panic_is_format_supported(const struct drm_format_info *format)
{
	if (format->num_planes != 1)
		return false;
	return convert_from_xrgb8888(0xffffff, format->format) != 0;
	return drm_draw_color_from_xrgb8888(0xffffff, format->format) != 0;
}

static void draw_panic_dispatch(struct drm_scanout_buffer *sb)