mirror of
https://github.com/torvalds/linux.git
synced 2026-09-27 11:02:03 +02:00
drm/i915/panic: split out i915_gem_panic.[ch]
The panic handling is a bit special and isolated part of i915_gem_pages.c. Split it out to i915_gem_panic.[ch]. Cc: Jocelyn Falempe <jfalempe@redhat.com> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patch.msgid.link/f2093946e723aa27e856987d13692eb0308a4d85.1780394867.git.jani.nikula@intel.com Signed-off-by: Jani Nikula <jani.nikula@intel.com>
This commit is contained in:
parent
de28bb67e2
commit
d711dafc4a
|
|
@ -167,6 +167,7 @@ gem-y += \
|
|||
gem/i915_gem_object.o \
|
||||
gem/i915_gem_object_frontbuffer.o \
|
||||
gem/i915_gem_pages.o \
|
||||
gem/i915_gem_panic.o \
|
||||
gem/i915_gem_phys.o \
|
||||
gem/i915_gem_pm.o \
|
||||
gem/i915_gem_region.o \
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@
|
|||
#include "i915_vma_types.h"
|
||||
|
||||
enum intel_region_id;
|
||||
struct drm_scanout_buffer;
|
||||
struct intel_panic;
|
||||
|
||||
#define obj_to_i915(obj__) to_i915((obj__)->base.dev)
|
||||
|
||||
|
|
@ -693,11 +691,6 @@ i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
|
|||
int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
|
||||
int i915_gem_object_truncate(struct drm_i915_gem_object *obj);
|
||||
|
||||
struct intel_panic *i915_gem_object_alloc_panic(void);
|
||||
int i915_gem_object_panic_setup(struct intel_panic *panic, struct drm_scanout_buffer *sb,
|
||||
struct drm_gem_object *_obj, bool panic_tiling);
|
||||
void i915_gem_object_panic_finish(struct intel_panic *panic);
|
||||
|
||||
/**
|
||||
* i915_gem_object_pin_map - return a contiguous mapping of the entire object
|
||||
* @obj: the object to map into kernel address space
|
||||
|
|
|
|||
|
|
@ -6,11 +6,8 @@
|
|||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <drm/drm_cache.h>
|
||||
#include <drm/drm_panic.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "display/intel_fb.h"
|
||||
#include "display/intel_display_types.h"
|
||||
#include "gt/intel_gt.h"
|
||||
#include "gt/intel_tlb.h"
|
||||
|
||||
|
|
@ -359,131 +356,6 @@ static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj,
|
|||
return vaddr ?: ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
struct intel_panic {
|
||||
struct page **pages;
|
||||
int page;
|
||||
void *vaddr;
|
||||
};
|
||||
|
||||
static void i915_panic_kunmap(struct intel_panic *panic)
|
||||
{
|
||||
if (panic->vaddr) {
|
||||
drm_clflush_virt_range(panic->vaddr, PAGE_SIZE);
|
||||
kunmap_local(panic->vaddr);
|
||||
panic->vaddr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct page **i915_gem_object_panic_pages(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
unsigned long n_pages = obj->base.size >> PAGE_SHIFT, i;
|
||||
struct page *page;
|
||||
struct page **pages;
|
||||
struct sgt_iter iter;
|
||||
|
||||
/* For a 3840x2160 32 bits Framebuffer, this should require ~64K */
|
||||
pages = kmalloc_objs(*pages, n_pages, GFP_ATOMIC);
|
||||
if (!pages)
|
||||
return NULL;
|
||||
|
||||
i = 0;
|
||||
for_each_sgt_page(page, iter, obj->mm.pages)
|
||||
pages[i++] = page;
|
||||
return pages;
|
||||
}
|
||||
|
||||
static void i915_gem_object_panic_map_set_pixel(struct drm_scanout_buffer *sb, unsigned int x,
|
||||
unsigned int y, u32 color)
|
||||
{
|
||||
struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private;
|
||||
unsigned int offset = fb->panic_tiling(sb->width, x, y);
|
||||
|
||||
iosys_map_wr(&sb->map[0], offset, u32, color);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 i915_gem_object_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int x,
|
||||
unsigned int y, u32 color)
|
||||
{
|
||||
unsigned int new_page;
|
||||
unsigned int offset;
|
||||
struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private;
|
||||
struct intel_panic *panic = fb->panic;
|
||||
|
||||
if (fb->panic_tiling)
|
||||
offset = fb->panic_tiling(sb->width, x, y);
|
||||
else
|
||||
offset = y * sb->pitch[0] + x * sb->format->cpp[0];
|
||||
|
||||
new_page = offset >> PAGE_SHIFT;
|
||||
offset = offset % PAGE_SIZE;
|
||||
if (new_page != panic->page) {
|
||||
i915_panic_kunmap(panic);
|
||||
panic->page = new_page;
|
||||
panic->vaddr =
|
||||
kmap_local_page_try_from_panic(panic->pages[panic->page]);
|
||||
}
|
||||
if (panic->vaddr) {
|
||||
u32 *pix = panic->vaddr + offset;
|
||||
*pix = color;
|
||||
}
|
||||
}
|
||||
|
||||
struct intel_panic *i915_gem_object_alloc_panic(void)
|
||||
{
|
||||
struct intel_panic *panic;
|
||||
|
||||
panic = kzalloc_obj(*panic);
|
||||
|
||||
return panic;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the gem framebuffer for drm_panic access.
|
||||
* Use current vaddr if it exists, or setup a list of pages.
|
||||
* pfn is not supported yet.
|
||||
*/
|
||||
int i915_gem_object_panic_setup(struct intel_panic *panic, struct drm_scanout_buffer *sb,
|
||||
struct drm_gem_object *_obj, bool panic_tiling)
|
||||
{
|
||||
enum i915_map_type has_type;
|
||||
struct drm_i915_gem_object *obj = to_intel_bo(_obj);
|
||||
void *ptr;
|
||||
|
||||
ptr = page_unpack_bits(obj->mm.mapping, &has_type);
|
||||
if (ptr) {
|
||||
if (i915_gem_object_has_iomem(obj))
|
||||
iosys_map_set_vaddr_iomem(&sb->map[0], (void __iomem *)ptr);
|
||||
else
|
||||
iosys_map_set_vaddr(&sb->map[0], ptr);
|
||||
|
||||
if (panic_tiling)
|
||||
sb->set_pixel = i915_gem_object_panic_map_set_pixel;
|
||||
return 0;
|
||||
}
|
||||
if (i915_gem_object_has_struct_page(obj)) {
|
||||
panic->pages = i915_gem_object_panic_pages(obj);
|
||||
if (!panic->pages)
|
||||
return -ENOMEM;
|
||||
panic->page = -1;
|
||||
sb->set_pixel = i915_gem_object_panic_page_set_pixel;
|
||||
return 0;
|
||||
}
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
void i915_gem_object_panic_finish(struct intel_panic *panic)
|
||||
{
|
||||
i915_panic_kunmap(panic);
|
||||
panic->page = -1;
|
||||
kfree(panic->pages);
|
||||
panic->pages = NULL;
|
||||
}
|
||||
|
||||
/* get, pin, and map the pages of the object into kernel space */
|
||||
void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
|
||||
enum i915_map_type type)
|
||||
|
|
|
|||
135
drivers/gpu/drm/i915/gem/i915_gem_panic.c
Normal file
135
drivers/gpu/drm/i915/gem/i915_gem_panic.c
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
/* Copyright © 2026 Intel Corporation */
|
||||
|
||||
#include <drm/drm_cache.h>
|
||||
#include <drm/drm_panic.h>
|
||||
|
||||
#include "display/intel_fb.h"
|
||||
#include "display/intel_display_types.h"
|
||||
#include "i915_gem_object.h"
|
||||
#include "i915_gem_panic.h"
|
||||
|
||||
struct intel_panic {
|
||||
struct page **pages;
|
||||
int page;
|
||||
void *vaddr;
|
||||
};
|
||||
|
||||
static void i915_panic_kunmap(struct intel_panic *panic)
|
||||
{
|
||||
if (panic->vaddr) {
|
||||
drm_clflush_virt_range(panic->vaddr, PAGE_SIZE);
|
||||
kunmap_local(panic->vaddr);
|
||||
panic->vaddr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct page **i915_gem_object_panic_pages(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
unsigned long n_pages = obj->base.size >> PAGE_SHIFT, i;
|
||||
struct page *page;
|
||||
struct page **pages;
|
||||
struct sgt_iter iter;
|
||||
|
||||
/* For a 3840x2160 32 bits Framebuffer, this should require ~64K */
|
||||
pages = kmalloc_objs(*pages, n_pages, GFP_ATOMIC);
|
||||
if (!pages)
|
||||
return NULL;
|
||||
|
||||
i = 0;
|
||||
for_each_sgt_page(page, iter, obj->mm.pages)
|
||||
pages[i++] = page;
|
||||
return pages;
|
||||
}
|
||||
|
||||
static void i915_gem_object_panic_map_set_pixel(struct drm_scanout_buffer *sb, unsigned int x,
|
||||
unsigned int y, u32 color)
|
||||
{
|
||||
struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private;
|
||||
unsigned int offset = fb->panic_tiling(sb->width, x, y);
|
||||
|
||||
iosys_map_wr(&sb->map[0], offset, u32, color);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 i915_gem_object_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int x,
|
||||
unsigned int y, u32 color)
|
||||
{
|
||||
unsigned int new_page;
|
||||
unsigned int offset;
|
||||
struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private;
|
||||
struct intel_panic *panic = fb->panic;
|
||||
|
||||
if (fb->panic_tiling)
|
||||
offset = fb->panic_tiling(sb->width, x, y);
|
||||
else
|
||||
offset = y * sb->pitch[0] + x * sb->format->cpp[0];
|
||||
|
||||
new_page = offset >> PAGE_SHIFT;
|
||||
offset = offset % PAGE_SIZE;
|
||||
if (new_page != panic->page) {
|
||||
i915_panic_kunmap(panic);
|
||||
panic->page = new_page;
|
||||
panic->vaddr =
|
||||
kmap_local_page_try_from_panic(panic->pages[panic->page]);
|
||||
}
|
||||
if (panic->vaddr) {
|
||||
u32 *pix = panic->vaddr + offset;
|
||||
*pix = color;
|
||||
}
|
||||
}
|
||||
|
||||
struct intel_panic *i915_gem_object_alloc_panic(void)
|
||||
{
|
||||
struct intel_panic *panic;
|
||||
|
||||
panic = kzalloc_obj(*panic);
|
||||
|
||||
return panic;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the gem framebuffer for drm_panic access.
|
||||
* Use current vaddr if it exists, or setup a list of pages.
|
||||
* pfn is not supported yet.
|
||||
*/
|
||||
int i915_gem_object_panic_setup(struct intel_panic *panic, struct drm_scanout_buffer *sb,
|
||||
struct drm_gem_object *_obj, bool panic_tiling)
|
||||
{
|
||||
enum i915_map_type has_type;
|
||||
struct drm_i915_gem_object *obj = to_intel_bo(_obj);
|
||||
void *ptr;
|
||||
|
||||
ptr = page_unpack_bits(obj->mm.mapping, &has_type);
|
||||
if (ptr) {
|
||||
if (i915_gem_object_has_iomem(obj))
|
||||
iosys_map_set_vaddr_iomem(&sb->map[0], (void __iomem *)ptr);
|
||||
else
|
||||
iosys_map_set_vaddr(&sb->map[0], ptr);
|
||||
|
||||
if (panic_tiling)
|
||||
sb->set_pixel = i915_gem_object_panic_map_set_pixel;
|
||||
return 0;
|
||||
}
|
||||
if (i915_gem_object_has_struct_page(obj)) {
|
||||
panic->pages = i915_gem_object_panic_pages(obj);
|
||||
if (!panic->pages)
|
||||
return -ENOMEM;
|
||||
panic->page = -1;
|
||||
sb->set_pixel = i915_gem_object_panic_page_set_pixel;
|
||||
return 0;
|
||||
}
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
void i915_gem_object_panic_finish(struct intel_panic *panic)
|
||||
{
|
||||
i915_panic_kunmap(panic);
|
||||
panic->page = -1;
|
||||
kfree(panic->pages);
|
||||
panic->pages = NULL;
|
||||
}
|
||||
18
drivers/gpu/drm/i915/gem/i915_gem_panic.h
Normal file
18
drivers/gpu/drm/i915/gem/i915_gem_panic.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/* Copyright © 2026 Intel Corporation */
|
||||
|
||||
#ifndef __I915_GEM_PANIC_H__
|
||||
#define __I915_GEM_PANIC_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct drm_gem_object;
|
||||
struct drm_scanout_buffer;
|
||||
struct intel_panic;
|
||||
|
||||
struct intel_panic *i915_gem_object_alloc_panic(void);
|
||||
int i915_gem_object_panic_setup(struct intel_panic *panic, struct drm_scanout_buffer *sb,
|
||||
struct drm_gem_object *_obj, bool panic_tiling);
|
||||
void i915_gem_object_panic_finish(struct intel_panic *panic);
|
||||
|
||||
#endif /* __I915_GEM_PANIC_H__ */
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "display/intel_display_types.h"
|
||||
#include "display/intel_fb.h"
|
||||
#include "gem/i915_gem_object.h"
|
||||
#include "gem/i915_gem_panic.h"
|
||||
|
||||
#include "i915_panic.h"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user