forked from mirrors/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
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