Lines Matching +full:clip +full:- +full:x +full:- +full:low
1 // SPDX-License-Identifier: GPL-2.0 or MIT
11 #include <linux/iosys-map.h>
64 * It's intended for end-user, so have minimal technical/debug information.
72 * It will display only one static frame, so performance optimizations are low
81 #define PANIC_LINE(s) {.len = sizeof(s) - 1, .txt = s}
94 PANIC_LINE(" .--. _"),
114 if (!logo || logo->type != LINUX_LOGO_MONO) in drm_panic_setup_logo()
118 logo_data = kmemdup(logo->data, in drm_panic_setup_logo()
119 size_mul(DIV_ROUND_UP(logo->width, BITS_PER_BYTE), logo->height), in drm_panic_setup_logo()
122 return -ENOMEM; in drm_panic_setup_logo()
127 return -ENOMEM; in drm_panic_setup_logo()
130 logo_dup->data = logo_data; in drm_panic_setup_logo()
213 * convert_from_xrgb8888 - convert one pixel from xrgb8888 to the desired format
254 /* check if the pixel at coord x,y is 1 (foreground) or 0 (background) */
255 static bool drm_panic_is_pixel_fg(const u8 *sbuf8, unsigned int spitch, int x, int y) in drm_panic_is_pixel_fg() argument
257 return (sbuf8[(y * spitch) + x / 8] & (0x80 >> (x % 8))) != 0; in drm_panic_is_pixel_fg()
265 unsigned int y, x; in drm_panic_blit16() local
268 for (x = 0; x < width; x++) in drm_panic_blit16()
269 if (drm_panic_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) in drm_panic_blit16()
270 iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, fg16); in drm_panic_blit16()
278 unsigned int y, x; in drm_panic_blit24() local
281 for (x = 0; x < width; x++) { in drm_panic_blit24()
282 u32 off = y * dpitch + x * 3; in drm_panic_blit24()
284 if (drm_panic_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) { in drm_panic_blit24()
285 /* write blue-green-red to output in little endianness */ in drm_panic_blit24()
299 unsigned int y, x; in drm_panic_blit32() local
302 for (x = 0; x < width; x++) in drm_panic_blit32()
303 if (drm_panic_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) in drm_panic_blit32()
304 iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, fg32); in drm_panic_blit32()
307 static void drm_panic_blit_pixel(struct drm_scanout_buffer *sb, struct drm_rect *clip, in drm_panic_blit_pixel() argument
311 unsigned int y, x; in drm_panic_blit_pixel() local
313 for (y = 0; y < drm_rect_height(clip); y++) in drm_panic_blit_pixel()
314 for (x = 0; x < drm_rect_width(clip); x++) in drm_panic_blit_pixel()
315 if (drm_panic_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) in drm_panic_blit_pixel()
316 sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, fg_color); in drm_panic_blit_pixel()
320 * drm_panic_blit - convert a monochrome image to a linear framebuffer
322 * @clip: destination rectangle
332 static void drm_panic_blit(struct drm_scanout_buffer *sb, struct drm_rect *clip, in drm_panic_blit() argument
339 if (sb->set_pixel) in drm_panic_blit()
340 return drm_panic_blit_pixel(sb, clip, sbuf8, spitch, scale, fg_color); in drm_panic_blit()
342 map = sb->map[0]; in drm_panic_blit()
343 iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]); in drm_panic_blit()
345 switch (sb->format->cpp[0]) { in drm_panic_blit()
347 drm_panic_blit16(&map, sb->pitch[0], sbuf8, spitch, in drm_panic_blit()
348 drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); in drm_panic_blit()
351 drm_panic_blit24(&map, sb->pitch[0], sbuf8, spitch, in drm_panic_blit()
352 drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); in drm_panic_blit()
355 drm_panic_blit32(&map, sb->pitch[0], sbuf8, spitch, in drm_panic_blit()
356 drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); in drm_panic_blit()
359 WARN_ONCE(1, "Can't blit with pixel width %d\n", sb->format->cpp[0]); in drm_panic_blit()
367 unsigned int y, x; in drm_panic_fill16() local
370 for (x = 0; x < width; x++) in drm_panic_fill16()
371 iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, color); in drm_panic_fill16()
378 unsigned int y, x; in drm_panic_fill24() local
381 for (x = 0; x < width; x++) { in drm_panic_fill24()
382 unsigned int off = y * dpitch + x * 3; in drm_panic_fill24()
384 /* write blue-green-red to output in little endianness */ in drm_panic_fill24()
396 unsigned int y, x; in drm_panic_fill32() local
399 for (x = 0; x < width; x++) in drm_panic_fill32()
400 iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, color); in drm_panic_fill32()
404 struct drm_rect *clip, in drm_panic_fill_pixel() argument
407 unsigned int y, x; in drm_panic_fill_pixel() local
409 for (y = 0; y < drm_rect_height(clip); y++) in drm_panic_fill_pixel()
410 for (x = 0; x < drm_rect_width(clip); x++) in drm_panic_fill_pixel()
411 sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, color); in drm_panic_fill_pixel()
415 * drm_panic_fill - Fill a rectangle with a color
417 * @clip: destination rectangle
422 static void drm_panic_fill(struct drm_scanout_buffer *sb, struct drm_rect *clip, in drm_panic_fill() argument
427 if (sb->set_pixel) in drm_panic_fill()
428 return drm_panic_fill_pixel(sb, clip, color); in drm_panic_fill()
430 map = sb->map[0]; in drm_panic_fill()
431 iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]); in drm_panic_fill()
433 switch (sb->format->cpp[0]) { in drm_panic_fill()
435 drm_panic_fill16(&map, sb->pitch[0], drm_rect_height(clip), in drm_panic_fill()
436 drm_rect_width(clip), color); in drm_panic_fill()
439 drm_panic_fill24(&map, sb->pitch[0], drm_rect_height(clip), in drm_panic_fill()
440 drm_rect_width(clip), color); in drm_panic_fill()
443 drm_panic_fill32(&map, sb->pitch[0], drm_rect_height(clip), in drm_panic_fill()
444 drm_rect_width(clip), color); in drm_panic_fill()
447 WARN_ONCE(1, "Can't fill with pixel width %d\n", sb->format->cpp[0]); in drm_panic_fill()
453 return font->data + (c * font->height) * font_pitch; in get_char_bitmap()
474 struct drm_rect *clip, in draw_txt_rectangle() argument
479 size_t font_pitch = DIV_ROUND_UP(font->width, 8); in draw_txt_rectangle()
482 msg_lines = min(msg_lines, drm_rect_height(clip) / font->height); in draw_txt_rectangle()
484 size_t line_len = min(msg[i].len, drm_rect_width(clip) / font->width); in draw_txt_rectangle()
486 rec.y1 = clip->y1 + i * font->height; in draw_txt_rectangle()
487 rec.y2 = rec.y1 + font->height; in draw_txt_rectangle()
488 rec.x1 = clip->x1; in draw_txt_rectangle()
491 rec.x1 += (drm_rect_width(clip) - (line_len * font->width)) / 2; in draw_txt_rectangle()
495 rec.x2 = rec.x1 + font->width; in draw_txt_rectangle()
497 rec.x1 += font->width; in draw_txt_rectangle()
505 drm_rect_init(rect, 0, 0, logo_mono->width, logo_mono->height); in drm_panic_logo_rect()
507 int logo_width = get_max_line_len(logo_ascii, logo_ascii_lines) * font->width; in drm_panic_logo_rect()
509 drm_rect_init(rect, 0, 0, logo_width, logo_ascii_lines * font->height); in drm_panic_logo_rect()
517 drm_panic_blit(sb, rect, logo_mono->data, in drm_panic_logo_draw()
526 u32 fg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, sb->format->format); in draw_panic_static_user()
527 u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format); in draw_panic_static_user()
528 const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); in draw_panic_static_user()
535 r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); in draw_panic_static_user()
538 msg_width = min(get_max_line_len(panic_msg, panic_msg_lines) * font->width, sb->width); in draw_panic_static_user()
539 msg_height = min(panic_msg_lines * font->height, sb->height); in draw_panic_static_user()
543 drm_rect_translate(&r_msg, (sb->width - r_msg.x2) / 2, (sb->height - r_msg.y2) / 2); in draw_panic_static_user()
556 * Return the y-offset of the next line.
561 int chars_per_row = sb->width / font->width; in draw_line_with_wrap()
562 struct drm_rect r_txt = DRM_RECT_INIT(0, yoffset, sb->width, sb->height); in draw_line_with_wrap()
565 if (line->len > chars_per_row) { in draw_line_with_wrap()
566 line_wrap.len = line->len % chars_per_row; in draw_line_with_wrap()
567 line_wrap.txt = line->txt + line->len - line_wrap.len; in draw_line_with_wrap()
569 r_txt.y1 -= font->height; in draw_line_with_wrap()
572 while (line_wrap.txt > line->txt) { in draw_line_with_wrap()
573 line_wrap.txt -= chars_per_row; in draw_line_with_wrap()
576 r_txt.y1 -= font->height; in draw_line_with_wrap()
582 r_txt.y1 -= font->height; in draw_line_with_wrap()
593 u32 fg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, sb->format->format); in draw_panic_static_kmsg()
594 u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format); in draw_panic_static_kmsg()
595 const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); in draw_panic_static_kmsg()
596 struct drm_rect r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); in draw_panic_static_kmsg()
606 yoffset = sb->height - font->height - (sb->height % font->height) / 2; in draw_panic_static_kmsg()
617 start = kmsg_buf + kmsg_len - 2; in draw_panic_static_kmsg()
618 end = kmsg_buf + kmsg_len - 1; in draw_panic_static_kmsg()
621 start--; in draw_panic_static_kmsg()
624 line.len = end - line.txt; in draw_panic_static_kmsg()
628 start--; in draw_panic_static_kmsg()
636 * pre-allocated. Only 2 buffers and the zlib workspace are needed.
639 * 2) kmsg is zlib-compressed into buffer2
640 * 3) compressed kmsg is encoded as QR-code Numeric stream in buffer1
641 * 4) QR-code image is generated in buffer2
646 * a V40 QR-code (177x177).
652 * 3) QR-code image is generated in buffer1
706 utsname()->machine, utsname()->release); in drm_panic_get_qr_code_url()
716 return -ENODATA; in drm_panic_get_qr_code_url()
722 return -EINVAL; in drm_panic_get_qr_code_url()
732 return -EINVAL; in drm_panic_get_qr_code_url()
735 return -EINVAL; in drm_panic_get_qr_code_url()
741 return -EINVAL; in drm_panic_get_qr_code_url()
764 return -ENODATA; in drm_panic_get_qr_code_raw()
784 u32 fg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, sb->format->format); in _draw_panic_static_qr_code()
785 u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format); in _draw_panic_static_qr_code()
786 const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); in _draw_panic_static_qr_code()
794 return -ENOMEM; in _draw_panic_static_qr_code()
796 r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); in _draw_panic_static_qr_code()
800 msg_width = min(get_max_line_len(panic_msg, panic_msg_lines) * font->width, sb->width); in _draw_panic_static_qr_code()
801 msg_height = min(panic_msg_lines * font->height, sb->height); in _draw_panic_static_qr_code()
804 max_qr_size = min(3 * sb->width / 4, 3 * sb->height / 4); in _draw_panic_static_qr_code()
808 return -ENOSPC; in _draw_panic_static_qr_code()
814 return -ENOSPC; in _draw_panic_static_qr_code()
819 v_margin = (sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg)) / 5; in _draw_panic_static_qr_code()
821 drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin); in _draw_panic_static_qr_code()
826 drm_rect_translate(&r_msg, (sb->width - r_msg.x2) / 2, in _draw_panic_static_qr_code()
869 if (format->num_planes != 1) in drm_panic_is_format_supported()
871 return convert_from_xrgb8888(0xffffff, format->format) != 0; in drm_panic_is_format_supported()
890 struct drm_panic_line *desc_line = &panic_msg[panic_msg_lines - 1]; in drm_panic_set_description()
892 desc_line->txt = description; in drm_panic_set_description()
895 if (len && description[len - 1] == '\n') in drm_panic_set_description()
896 len -= 1; in drm_panic_set_description()
897 desc_line->len = len; in drm_panic_set_description()
903 struct drm_panic_line *desc_line = &panic_msg[panic_msg_lines - 1]; in drm_panic_clear_description()
905 desc_line->len = 0; in drm_panic_clear_description()
906 desc_line->txt = NULL; in drm_panic_clear_description()
915 if (!drm_panic_trylock(plane->dev, flags)) in draw_panic_plane()
920 ret = plane->helper_private->get_scanout_buffer(plane, &sb); in draw_panic_plane()
924 if (plane->helper_private->panic_flush) in draw_panic_plane()
925 plane->helper_private->panic_flush(plane); in draw_panic_plane()
928 drm_panic_unlock(plane->dev, flags); in draw_panic_plane()
940 if (detail->reason == KMSG_DUMP_PANIC) in drm_panic()
941 draw_panic_plane(plane, detail->description); in drm_panic()
959 struct drm_plane *plane = file->private_data; in debugfs_trigger_write()
977 debugfs_create_file(fname, 0200, plane->dev->debugfs_root, in debugfs_register_plane()
994 if (!dev->mode_config.num_total_plane) in drm_panic_is_enabled()
998 if (plane->helper_private && plane->helper_private->get_scanout_buffer) in drm_panic_is_enabled()
1005 * drm_panic_register() - Initialize DRM panic for a device
1013 if (!dev->mode_config.num_total_plane) in drm_panic_register()
1017 if (!plane->helper_private || !plane->helper_private->get_scanout_buffer) in drm_panic_register()
1019 plane->kmsg_panic.dump = drm_panic; in drm_panic_register()
1020 plane->kmsg_panic.max_reason = KMSG_DUMP_PANIC; in drm_panic_register()
1021 if (kmsg_dump_register(&plane->kmsg_panic)) in drm_panic_register()
1040 if (!dev->mode_config.num_total_plane) in drm_panic_unregister()
1044 if (!plane->helper_private || !plane->helper_private->get_scanout_buffer) in drm_panic_unregister()
1046 kmsg_dump_unregister(&plane->kmsg_panic); in drm_panic_unregister()
1051 * drm_panic_init() - initialize DRM panic.
1059 * drm_panic_exit() - Free the resources taken by drm_panic_exit()