Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/xe/display: Make panic support work on vram.

Add a special path for VRAM using xe_res iterators to ensure a panic
screen is shown on VRAM as well.

Acked-by: Jocelyn Falempe <jfalempe@redhat.com>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://lore.kernel.org/r/20251016075701.379023-3-jfalempe@redhat.com
Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
Acked-by: Jani Nikula <jani.nikula@linux.intel.com>

+36 -14
+36 -14
drivers/gpu/drm/xe/display/xe_panic.c
··· 8 8 #include "intel_fb.h" 9 9 #include "intel_panic.h" 10 10 #include "xe_bo.h" 11 + #include "xe_res_cursor.h" 11 12 12 13 struct intel_panic { 13 - struct page **pages; 14 + struct xe_res_cursor res; 15 + struct iosys_map vmap; 16 + 14 17 int page; 15 - void *vaddr; 16 18 }; 17 19 18 20 static void xe_panic_kunmap(struct intel_panic *panic) 19 21 { 20 - if (panic->vaddr) { 21 - drm_clflush_virt_range(panic->vaddr, PAGE_SIZE); 22 - kunmap_local(panic->vaddr); 23 - panic->vaddr = NULL; 22 + if (!panic->vmap.is_iomem && iosys_map_is_set(&panic->vmap)) { 23 + drm_clflush_virt_range(panic->vmap.vaddr, PAGE_SIZE); 24 + kunmap_local(panic->vmap.vaddr); 24 25 } 26 + iosys_map_clear(&panic->vmap); 27 + panic->page = -1; 25 28 } 26 29 27 30 /* ··· 49 46 new_page = offset >> PAGE_SHIFT; 50 47 offset = offset % PAGE_SIZE; 51 48 if (new_page != panic->page) { 52 - xe_panic_kunmap(panic); 49 + if (xe_bo_is_vram(bo)) { 50 + /* Display is always mapped on root tile */ 51 + struct xe_vram_region *vram = xe_bo_device(bo)->mem.vram; 52 + 53 + if (panic->page < 0 || new_page < panic->page) { 54 + xe_res_first(bo->ttm.resource, new_page * PAGE_SIZE, 55 + bo->ttm.base.size - new_page * PAGE_SIZE, &panic->res); 56 + } else { 57 + xe_res_next(&panic->res, PAGE_SIZE * (new_page - panic->page)); 58 + } 59 + iosys_map_set_vaddr_iomem(&panic->vmap, 60 + vram->mapping + panic->res.start); 61 + } else { 62 + xe_panic_kunmap(panic); 63 + iosys_map_set_vaddr(&panic->vmap, 64 + ttm_bo_kmap_try_from_panic(&bo->ttm, 65 + new_page)); 66 + } 53 67 panic->page = new_page; 54 - panic->vaddr = ttm_bo_kmap_try_from_panic(&bo->ttm, 55 - panic->page); 56 68 } 57 - if (panic->vaddr) { 58 - u32 *pix = panic->vaddr + offset; 59 - *pix = color; 60 - } 69 + 70 + if (iosys_map_is_set(&panic->vmap)) 71 + iosys_map_wr(&panic->vmap, offset, u32, color); 61 72 } 62 73 63 74 struct intel_panic *intel_panic_alloc(void) ··· 85 68 86 69 int intel_panic_setup(struct intel_panic *panic, struct drm_scanout_buffer *sb) 87 70 { 71 + struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; 72 + struct xe_bo *bo = gem_to_xe_bo(intel_fb_bo(&fb->base)); 73 + 74 + if (xe_bo_is_vram(bo) && !xe_bo_is_visible_vram(bo)) 75 + return -ENODEV; 76 + 88 77 panic->page = -1; 89 78 sb->set_pixel = xe_panic_page_set_pixel; 90 79 return 0; ··· 99 76 void intel_panic_finish(struct intel_panic *panic) 100 77 { 101 78 xe_panic_kunmap(panic); 102 - panic->page = -1; 103 79 }