Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/panic: Add support for drawing a monochrome graphical logo

Re-use the existing support for boot-up logos to draw a monochrome
graphical logo in the DRM panic handler. When no suitable graphical
logo is available, the code falls back to the ASCII art penguin logo.

Note that all graphical boot-up logos are freed during late kernel
initialization, hence a copy must be made for later use.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/3f1a5f56213f3e4584773eb2813e212b2dff6d14.1718305355.git.geert+renesas@glider.be

authored by

Geert Uytterhoeven and committed by
Jocelyn Falempe
294bbd1f a40d031d

+60 -7
+58 -7
drivers/gpu/drm/drm_panic.c
··· 7 7 */ 8 8 9 9 #include <linux/font.h> 10 + #include <linux/init.h> 10 11 #include <linux/iosys-map.h> 11 12 #include <linux/kdebug.h> 12 13 #include <linux/kmsg_dump.h> 14 + #include <linux/linux_logo.h> 13 15 #include <linux/list.h> 16 + #include <linux/math.h> 14 17 #include <linux/module.h> 18 + #include <linux/overflow.h> 15 19 #include <linux/printk.h> 16 20 #include <linux/types.h> 17 21 ··· 91 87 PANIC_LINE(" /'\\_ _/`\\ (_)"), 92 88 PANIC_LINE(" \\___)=(___/"), 93 89 }; 90 + 91 + #ifdef CONFIG_LOGO 92 + static const struct linux_logo *logo_mono; 93 + 94 + static int drm_panic_setup_logo(void) 95 + { 96 + const struct linux_logo *logo = fb_find_logo(1); 97 + const unsigned char *logo_data; 98 + struct linux_logo *logo_dup; 99 + 100 + if (!logo || logo->type != LINUX_LOGO_MONO) 101 + return 0; 102 + 103 + /* The logo is __init, so we must make a copy for later use */ 104 + logo_data = kmemdup(logo->data, 105 + size_mul(DIV_ROUND_UP(logo->width, BITS_PER_BYTE), logo->height), 106 + GFP_KERNEL); 107 + if (!logo_data) 108 + return -ENOMEM; 109 + 110 + logo_dup = kmemdup(logo, sizeof(*logo), GFP_KERNEL); 111 + if (!logo_dup) { 112 + kfree(logo_data); 113 + return -ENOMEM; 114 + } 115 + 116 + logo_dup->data = logo_data; 117 + logo_mono = logo_dup; 118 + 119 + return 0; 120 + } 121 + 122 + device_initcall(drm_panic_setup_logo); 123 + #else 124 + #define logo_mono ((const struct linux_logo *)NULL) 125 + #endif 94 126 95 127 /* 96 128 * Color conversion ··· 492 452 u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format); 493 453 const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); 494 454 struct drm_rect r_screen, r_logo, r_msg; 455 + unsigned int logo_width, logo_height; 495 456 496 457 if (!font) 497 458 return; 498 459 499 460 r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); 500 461 501 - r_logo = DRM_RECT_INIT(0, 0, 502 - get_max_line_len(logo_ascii, logo_ascii_lines) * font->width, 503 - logo_ascii_lines * font->height); 462 + if (logo_mono) { 463 + logo_width = logo_mono->width; 464 + logo_height = logo_mono->height; 465 + } else { 466 + logo_width = get_max_line_len(logo_ascii, logo_ascii_lines) * font->width; 467 + logo_height = logo_ascii_lines * font->height; 468 + } 469 + 470 + r_logo = DRM_RECT_INIT(0, 0, logo_width, logo_height); 504 471 r_msg = DRM_RECT_INIT(0, 0, 505 472 min(get_max_line_len(panic_msg, msg_lines) * font->width, sb->width), 506 473 min(msg_lines * font->height, sb->height)); ··· 518 471 /* Fill with the background color, and draw text on top */ 519 472 drm_panic_fill(sb, &r_screen, bg_color); 520 473 521 - if ((r_msg.x1 >= drm_rect_width(&r_logo) || r_msg.y1 >= drm_rect_height(&r_logo)) && 522 - drm_rect_width(&r_logo) <= sb->width && drm_rect_height(&r_logo) <= sb->height) { 523 - draw_txt_rectangle(sb, font, logo_ascii, logo_ascii_lines, false, &r_logo, 524 - fg_color); 474 + if ((r_msg.x1 >= logo_width || r_msg.y1 >= logo_height) && 475 + logo_width <= sb->width && logo_height <= sb->height) { 476 + if (logo_mono) 477 + drm_panic_blit(sb, &r_logo, logo_mono->data, DIV_ROUND_UP(logo_width, 8), 478 + fg_color); 479 + else 480 + draw_txt_rectangle(sb, font, logo_ascii, logo_ascii_lines, false, &r_logo, 481 + fg_color); 525 482 } 526 483 draw_txt_rectangle(sb, font, panic_msg, msg_lines, true, &r_msg, fg_color); 527 484 }
+2
drivers/video/logo/Kconfig
··· 8 8 depends on FB_CORE || SGI_NEWPORT_CONSOLE 9 9 help 10 10 Enable and select frame buffer bootup logos. 11 + Monochrome logos will also be used by the DRM panic handler, if 12 + enabled. 11 13 12 14 if LOGO 13 15