mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	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
This commit is contained in:
		
							parent
							
								
									a40d031d7b
								
							
						
					
					
						commit
						294bbd1f26
					
				
					 2 changed files with 60 additions and 7 deletions
				
			
		|  | @ -7,11 +7,15 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <linux/font.h> | #include <linux/font.h> | ||||||
|  | #include <linux/init.h> | ||||||
| #include <linux/iosys-map.h> | #include <linux/iosys-map.h> | ||||||
| #include <linux/kdebug.h> | #include <linux/kdebug.h> | ||||||
| #include <linux/kmsg_dump.h> | #include <linux/kmsg_dump.h> | ||||||
|  | #include <linux/linux_logo.h> | ||||||
| #include <linux/list.h> | #include <linux/list.h> | ||||||
|  | #include <linux/math.h> | ||||||
| #include <linux/module.h> | #include <linux/module.h> | ||||||
|  | #include <linux/overflow.h> | ||||||
| #include <linux/printk.h> | #include <linux/printk.h> | ||||||
| #include <linux/types.h> | #include <linux/types.h> | ||||||
| 
 | 
 | ||||||
|  | @ -88,6 +92,42 @@ static const struct drm_panic_line logo_ascii[] = { | ||||||
| 	PANIC_LINE(" \\___)=(___/"), | 	PANIC_LINE(" \\___)=(___/"), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | #ifdef CONFIG_LOGO | ||||||
|  | static const struct linux_logo *logo_mono; | ||||||
|  | 
 | ||||||
|  | static int drm_panic_setup_logo(void) | ||||||
|  | { | ||||||
|  | 	const struct linux_logo *logo = fb_find_logo(1); | ||||||
|  | 	const unsigned char *logo_data; | ||||||
|  | 	struct linux_logo *logo_dup; | ||||||
|  | 
 | ||||||
|  | 	if (!logo || logo->type != LINUX_LOGO_MONO) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
|  | 	/* The logo is __init, so we must make a copy for later use */ | ||||||
|  | 	logo_data = kmemdup(logo->data, | ||||||
|  | 			    size_mul(DIV_ROUND_UP(logo->width, BITS_PER_BYTE), logo->height), | ||||||
|  | 			    GFP_KERNEL); | ||||||
|  | 	if (!logo_data) | ||||||
|  | 		return -ENOMEM; | ||||||
|  | 
 | ||||||
|  | 	logo_dup = kmemdup(logo, sizeof(*logo), GFP_KERNEL); | ||||||
|  | 	if (!logo_dup) { | ||||||
|  | 		kfree(logo_data); | ||||||
|  | 		return -ENOMEM; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	logo_dup->data = logo_data; | ||||||
|  | 	logo_mono = logo_dup; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | device_initcall(drm_panic_setup_logo); | ||||||
|  | #else | ||||||
|  | #define logo_mono	((const struct linux_logo *)NULL) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Color conversion |  * Color conversion | ||||||
|  */ |  */ | ||||||
|  | @ -452,15 +492,22 @@ static void draw_panic_static_user(struct drm_scanout_buffer *sb) | ||||||
| 	u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format); | 	u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format); | ||||||
| 	const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); | 	const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); | ||||||
| 	struct drm_rect r_screen, r_logo, r_msg; | 	struct drm_rect r_screen, r_logo, r_msg; | ||||||
|  | 	unsigned int logo_width, logo_height; | ||||||
| 
 | 
 | ||||||
| 	if (!font) | 	if (!font) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); | 	r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); | ||||||
| 
 | 
 | ||||||
| 	r_logo = DRM_RECT_INIT(0, 0, | 	if (logo_mono) { | ||||||
| 			       get_max_line_len(logo_ascii, logo_ascii_lines) * font->width, | 		logo_width = logo_mono->width; | ||||||
| 			       logo_ascii_lines * font->height); | 		logo_height = logo_mono->height; | ||||||
|  | 	} else { | ||||||
|  | 		logo_width = get_max_line_len(logo_ascii, logo_ascii_lines) * font->width; | ||||||
|  | 		logo_height = logo_ascii_lines * font->height; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	r_logo = DRM_RECT_INIT(0, 0, logo_width, logo_height); | ||||||
| 	r_msg = DRM_RECT_INIT(0, 0, | 	r_msg = DRM_RECT_INIT(0, 0, | ||||||
| 			      min(get_max_line_len(panic_msg, msg_lines) * font->width, sb->width), | 			      min(get_max_line_len(panic_msg, msg_lines) * font->width, sb->width), | ||||||
| 			      min(msg_lines * font->height, sb->height)); | 			      min(msg_lines * font->height, sb->height)); | ||||||
|  | @ -471,10 +518,14 @@ static void draw_panic_static_user(struct drm_scanout_buffer *sb) | ||||||
| 	/* Fill with the background color, and draw text on top */ | 	/* Fill with the background color, and draw text on top */ | ||||||
| 	drm_panic_fill(sb, &r_screen, bg_color); | 	drm_panic_fill(sb, &r_screen, bg_color); | ||||||
| 
 | 
 | ||||||
| 	if ((r_msg.x1 >= drm_rect_width(&r_logo) || r_msg.y1 >= drm_rect_height(&r_logo)) && | 	if ((r_msg.x1 >= logo_width || r_msg.y1 >= logo_height) && | ||||||
| 	    drm_rect_width(&r_logo) <= sb->width && drm_rect_height(&r_logo) <= sb->height) { | 	    logo_width <= sb->width && logo_height <= sb->height) { | ||||||
| 		draw_txt_rectangle(sb, font, logo_ascii, logo_ascii_lines, false, &r_logo, | 		if (logo_mono) | ||||||
| 				   fg_color); | 			drm_panic_blit(sb, &r_logo, logo_mono->data, DIV_ROUND_UP(logo_width, 8), | ||||||
|  | 				       fg_color); | ||||||
|  | 		else | ||||||
|  | 			draw_txt_rectangle(sb, font, logo_ascii, logo_ascii_lines, false, &r_logo, | ||||||
|  | 					   fg_color); | ||||||
| 	} | 	} | ||||||
| 	draw_txt_rectangle(sb, font, panic_msg, msg_lines, true, &r_msg, fg_color); | 	draw_txt_rectangle(sb, font, panic_msg, msg_lines, true, &r_msg, fg_color); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ menuconfig LOGO | ||||||
| 	depends on FB_CORE || SGI_NEWPORT_CONSOLE | 	depends on FB_CORE || SGI_NEWPORT_CONSOLE | ||||||
| 	help | 	help | ||||||
| 	  Enable and select frame buffer bootup logos. | 	  Enable and select frame buffer bootup logos. | ||||||
|  | 	  Monochrome logos will also be used by the DRM panic handler, if | ||||||
|  | 	  enabled. | ||||||
| 
 | 
 | ||||||
| if LOGO | if LOGO | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Geert Uytterhoeven
						Geert Uytterhoeven