diff options
| author | Jocelyn Falempe <jfalempe@redhat.com> | 2025-06-24 11:01:16 +0200 |
|---|---|---|
| committer | Maarten Lankhorst <dev@lankhorst.se> | 2025-06-27 11:48:22 +0200 |
| commit | 75fb60e5ad5f154ca88e8d05e764cceb787fbffb (patch) | |
| tree | 9e0c8a897cacb4ed68842f112ddf40bbec1f9a00 /drivers/gpu/drm/xe/display/intel_bo.c | |
| parent | da091afacb29b120929d181d7aea7275848ead81 (diff) | |
drm/i915: Add intel_bo_panic_setup() and intel_bo_panic_finish()
Implement both functions for i915 and xe, they prepare the work for
drm_panic support.
They both use kmap_try_from_panic(), and map one page at a time, to
write the panic screen on the framebuffer.
Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://lore.kernel.org/r/20250624091501.257661-8-jfalempe@redhat.com
Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
Diffstat (limited to 'drivers/gpu/drm/xe/display/intel_bo.c')
| -rw-r--r-- | drivers/gpu/drm/xe/display/intel_bo.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c index 926fcd9c86e1..bbb504f8e242 100644 --- a/drivers/gpu/drm/xe/display/intel_bo.c +++ b/drivers/gpu/drm/xe/display/intel_bo.c @@ -1,8 +1,11 @@ // SPDX-License-Identifier: MIT /* Copyright © 2024 Intel Corporation */ +#include <drm/drm_cache.h> #include <drm/drm_gem.h> +#include <drm/drm_panic.h> +#include "intel_fb.h" #include "intel_display_types.h" #include "xe_bo.h" @@ -73,6 +76,50 @@ struct xe_framebuffer { struct xe_panic_data panic; }; +static inline struct xe_panic_data *to_xe_panic_data(struct intel_framebuffer *fb) +{ + return &container_of_const(fb, struct xe_framebuffer, base)->panic; +} + +static void xe_panic_kunmap(struct xe_panic_data *panic) +{ + if (panic->vaddr) { + drm_clflush_virt_range(panic->vaddr, PAGE_SIZE); + kunmap_local(panic->vaddr); + panic->vaddr = NULL; + } +} + +/* + * The scanout buffer pages are not mapped, so for each pixel, + * use kmap_local_page_try_from_panic() to map the page, and write the pixel. + * Try to keep the map from the previous pixel, to avoid too much map/unmap. + */ +static void xe_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int x, + unsigned int y, u32 color) +{ + struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; + struct xe_panic_data *panic = to_xe_panic_data(fb); + struct xe_bo *bo = gem_to_xe_bo(intel_fb_bo(&fb->base)); + unsigned int new_page; + unsigned int offset; + + offset = y * sb->pitch[0] + x * sb->format->cpp[0]; + + new_page = offset >> PAGE_SHIFT; + offset = offset % PAGE_SIZE; + if (new_page != panic->page) { + xe_panic_kunmap(panic); + panic->page = new_page; + panic->vaddr = ttm_bo_kmap_try_from_panic(&bo->ttm, + panic->page); + } + if (panic->vaddr) { + u32 *pix = panic->vaddr + offset; + *pix = color; + } +} + struct intel_framebuffer *intel_bo_alloc_framebuffer(void) { struct xe_framebuffer *xe_fb; @@ -83,3 +130,20 @@ struct intel_framebuffer *intel_bo_alloc_framebuffer(void) return NULL; } +int intel_bo_panic_setup(struct drm_scanout_buffer *sb) +{ + struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; + struct xe_panic_data *panic = to_xe_panic_data(fb); + + panic->page = -1; + sb->set_pixel = xe_panic_page_set_pixel; + return 0; +} + +void intel_bo_panic_finish(struct intel_framebuffer *fb) +{ + struct xe_panic_data *panic = to_xe_panic_data(fb); + + xe_panic_kunmap(panic); + panic->page = -1; +} |