mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +02:00 
			
		
		
		
	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: Jocelyn Falempe <jfalempe@redhat.com> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20241204160014.1171469-2-jfalempe@redhat.com
This commit is contained in:
		
							parent
							
								
									68573a5613
								
							
						
					
					
						commit
						31fa2c1ca0
					
				
					 5 changed files with 324 additions and 240 deletions
				
			
		|  | @ -102,10 +102,15 @@ config DRM_KMS_HELPER | ||||||
| 	help | 	help | ||||||
| 	  CRTC helpers for KMS drivers. | 	  CRTC helpers for KMS drivers. | ||||||
| 
 | 
 | ||||||
|  | config DRM_DRAW | ||||||
|  | 	bool | ||||||
|  | 	depends on DRM | ||||||
|  | 
 | ||||||
| config DRM_PANIC | config DRM_PANIC | ||||||
| 	bool "Display a user-friendly message when a kernel panic occurs" | 	bool "Display a user-friendly message when a kernel panic occurs" | ||||||
| 	depends on DRM | 	depends on DRM | ||||||
| 	select FONT_SUPPORT | 	select FONT_SUPPORT | ||||||
|  | 	select DRM_DRAW | ||||||
| 	help | 	help | ||||||
| 	  Enable a drm panic handler, which will display a user-friendly message | 	  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 | 	  when a kernel panic occurs. It's useful when using a user-space | ||||||
|  |  | ||||||
|  | @ -91,6 +91,7 @@ drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \ | ||||||
| 	drm_privacy_screen_x86.o | 	drm_privacy_screen_x86.o | ||||||
| drm-$(CONFIG_DRM_ACCEL) += ../../accel/drm_accel.o | drm-$(CONFIG_DRM_ACCEL) += ../../accel/drm_accel.o | ||||||
| drm-$(CONFIG_DRM_PANIC) += drm_panic.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 | drm-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) += drm_panic_qr.o | ||||||
| obj-$(CONFIG_DRM)	+= drm.o | obj-$(CONFIG_DRM)	+= drm.o | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										233
									
								
								drivers/gpu/drm/drm_draw.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								drivers/gpu/drm/drm_draw.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,233 @@ | ||||||
|  | // 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
									
								
								drivers/gpu/drm/drm_draw_internal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								drivers/gpu/drm/drm_draw_internal.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,56 @@ | ||||||
|  | /* 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__ */ | ||||||
|  | @ -31,6 +31,7 @@ | ||||||
| #include <drm/drm_rect.h> | #include <drm/drm_rect.h> | ||||||
| 
 | 
 | ||||||
| #include "drm_crtc_internal.h" | #include "drm_crtc_internal.h" | ||||||
|  | #include "drm_draw_internal.h" | ||||||
| 
 | 
 | ||||||
| MODULE_AUTHOR("Jocelyn Falempe"); | MODULE_AUTHOR("Jocelyn Falempe"); | ||||||
| MODULE_DESCRIPTION("DRM panic handler"); | MODULE_DESCRIPTION("DRM panic handler"); | ||||||
|  | @ -139,181 +140,8 @@ device_initcall(drm_panic_setup_logo); | ||||||
| #endif | #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, | static void drm_panic_blit_pixel(struct drm_scanout_buffer *sb, struct drm_rect *clip, | ||||||
| 				 const u8 *sbuf8, unsigned int spitch, unsigned int scale, | 				 const u8 *sbuf8, unsigned int spitch, unsigned int scale, | ||||||
| 				 u32 fg_color) | 				 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 (y = 0; y < drm_rect_height(clip); y++) | ||||||
| 		for (x = 0; x < drm_rect_width(clip); x++) | 		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); | 				sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, fg_color); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -354,62 +182,22 @@ static void drm_panic_blit(struct drm_scanout_buffer *sb, struct drm_rect *clip, | ||||||
| 
 | 
 | ||||||
| 	switch (sb->format->cpp[0]) { | 	switch (sb->format->cpp[0]) { | ||||||
| 	case 2: | 	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); | 				drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); | ||||||
| 	break; | 	break; | ||||||
| 	case 3: | 	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); | 				drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); | ||||||
| 	break; | 	break; | ||||||
| 	case 4: | 	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); | 				drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); | ||||||
| 	break; | 	break; | ||||||
| 	default: | 	default: | ||||||
| 		WARN_ONCE(1, "Can't blit with pixel width %d\n", sb->format->cpp[0]); | 		WARN_ONCE(1, "Can't blit with pixel width %d\n", sb->format->cpp[0]); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 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, | static void drm_panic_fill_pixel(struct drm_scanout_buffer *sb, | ||||||
| 				 struct drm_rect *clip, | 				 struct drm_rect *clip, | ||||||
| 				 u32 color) | 				 u32 color) | ||||||
|  | @ -442,27 +230,22 @@ static void drm_panic_fill(struct drm_scanout_buffer *sb, struct drm_rect *clip, | ||||||
| 
 | 
 | ||||||
| 	switch (sb->format->cpp[0]) { | 	switch (sb->format->cpp[0]) { | ||||||
| 	case 2: | 	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); | 				drm_rect_width(clip), color); | ||||||
| 	break; | 	break; | ||||||
| 	case 3: | 	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); | 				drm_rect_width(clip), color); | ||||||
| 	break; | 	break; | ||||||
| 	case 4: | 	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); | 				drm_rect_width(clip), color); | ||||||
| 	break; | 	break; | ||||||
| 	default: | 	default: | ||||||
| 		WARN_ONCE(1, "Can't fill with pixel width %d\n", sb->format->cpp[0]); | 		WARN_ONCE(1, "Can't fill with pixel width %d\n", sb->format->cpp[0]); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 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) | static unsigned int get_max_line_len(const struct drm_panic_line *lines, int len) | ||||||
| { | { | ||||||
| 	int i; | 	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; | 			rec.x1 += (drm_rect_width(clip) - (line_len * font->width)) / 2; | ||||||
| 
 | 
 | ||||||
| 		for (j = 0; j < line_len; j++) { | 		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; | 			rec.x2 = rec.x1 + font->width; | ||||||
| 			drm_panic_blit(sb, &rec, src, font_pitch, 1, color); | 			drm_panic_blit(sb, &rec, src, font_pitch, 1, color); | ||||||
| 			rec.x1 += font->width; | 			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) | 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 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, | ||||||
| 	u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format); | 						    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); | 	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 msg_width, msg_height; | 	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) | 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 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, | ||||||
| 	u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format); | 						    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); | 	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 drm_rect r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); | ||||||
| 	struct kmsg_dump_iter iter; | 	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) | 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 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, | ||||||
| 	u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format); | 						    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); | 	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; | 	struct drm_rect r_screen, r_logo, r_msg, r_qr, r_qr_canvas; | ||||||
| 	unsigned int max_qr_size, scale; | 	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) | 	if (format->num_planes != 1) | ||||||
| 		return false; | 		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) | static void draw_panic_dispatch(struct drm_scanout_buffer *sb) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Jocelyn Falempe
						Jocelyn Falempe