mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-06 04:24:21 -04:00
drm/amdgpu: add generic display panic helper code
Pull this out of Jocelyn's patch and make it generic. Reviewed-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: Lu Yao <yaolu@kylinos.cn> Cc: Jocelyn Falempe <jfalempe@redhat.com> Cc: Harry Wentland <harry.wentland@amd.com>
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
#include "soc15_common.h"
|
#include "soc15_common.h"
|
||||||
#include "gc/gc_11_0_0_offset.h"
|
#include "gc/gc_11_0_0_offset.h"
|
||||||
#include "gc/gc_11_0_0_sh_mask.h"
|
#include "gc/gc_11_0_0_sh_mask.h"
|
||||||
|
#include "bif/bif_4_1_d.h"
|
||||||
#include <asm/div64.h>
|
#include <asm/div64.h>
|
||||||
|
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
@@ -1788,3 +1789,82 @@ int amdgpu_display_resume_helper(struct amdgpu_device *adev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* panic_bo is set in amdgpu_dm_plane_get_scanout_buffer() and only used in amdgpu_dm_set_pixel()
|
||||||
|
* they are called from the panic handler, and protected by the drm_panic spinlock.
|
||||||
|
*/
|
||||||
|
static struct amdgpu_bo *panic_abo;
|
||||||
|
|
||||||
|
/* Use the indirect MMIO to write each pixel to the GPU VRAM,
|
||||||
|
* This is a simplified version of amdgpu_device_mm_access()
|
||||||
|
*/
|
||||||
|
static void amdgpu_display_set_pixel(struct drm_scanout_buffer *sb,
|
||||||
|
unsigned int x,
|
||||||
|
unsigned int y,
|
||||||
|
u32 color)
|
||||||
|
{
|
||||||
|
struct amdgpu_res_cursor cursor;
|
||||||
|
unsigned long offset;
|
||||||
|
struct amdgpu_bo *abo = panic_abo;
|
||||||
|
struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev);
|
||||||
|
uint32_t tmp;
|
||||||
|
|
||||||
|
offset = x * 4 + y * sb->pitch[0];
|
||||||
|
amdgpu_res_first(abo->tbo.resource, offset, 4, &cursor);
|
||||||
|
|
||||||
|
tmp = cursor.start >> 31;
|
||||||
|
WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t) cursor.start) | 0x80000000);
|
||||||
|
if (tmp != 0xffffffff)
|
||||||
|
WREG32_NO_KIQ(mmMM_INDEX_HI, tmp);
|
||||||
|
WREG32_NO_KIQ(mmMM_DATA, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
int amdgpu_display_get_scanout_buffer(struct drm_plane *plane,
|
||||||
|
struct drm_scanout_buffer *sb)
|
||||||
|
{
|
||||||
|
struct amdgpu_bo *abo;
|
||||||
|
struct drm_framebuffer *fb = plane->state->fb;
|
||||||
|
|
||||||
|
if (!fb)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
DRM_DEBUG_KMS("Framebuffer %dx%d %p4cc\n", fb->width, fb->height, &fb->format->format);
|
||||||
|
|
||||||
|
abo = gem_to_amdgpu_bo(fb->obj[0]);
|
||||||
|
if (!abo)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
sb->width = fb->width;
|
||||||
|
sb->height = fb->height;
|
||||||
|
/* Use the generic linear format, because tiling will be disabled in panic_flush() */
|
||||||
|
sb->format = drm_format_info(fb->format->format);
|
||||||
|
if (!sb->format)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
sb->pitch[0] = fb->pitches[0];
|
||||||
|
|
||||||
|
if (abo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) {
|
||||||
|
if (abo->tbo.resource->mem_type != TTM_PL_VRAM) {
|
||||||
|
drm_warn(plane->dev, "amdgpu panic, framebuffer not in VRAM\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
/* Only handle 32bits format, to simplify mmio access */
|
||||||
|
if (fb->format->cpp[0] != 4) {
|
||||||
|
drm_warn(plane->dev, "amdgpu panic, pixel format is not 32bits\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
sb->set_pixel = amdgpu_display_set_pixel;
|
||||||
|
panic_abo = abo;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!abo->kmap.virtual &&
|
||||||
|
ttm_bo_kmap(&abo->tbo, 0, PFN_UP(abo->tbo.base.size), &abo->kmap)) {
|
||||||
|
drm_warn(plane->dev, "amdgpu bo map failed, panic won't be displayed\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
if (abo->kmap.bo_kmap_type & TTM_BO_MAP_IOMEM_MASK)
|
||||||
|
iosys_map_set_vaddr_iomem(&sb->map[0], abo->kmap.virtual);
|
||||||
|
else
|
||||||
|
iosys_map_set_vaddr(&sb->map[0], abo->kmap.virtual);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
#ifndef __AMDGPU_DISPLAY_H__
|
#ifndef __AMDGPU_DISPLAY_H__
|
||||||
#define __AMDGPU_DISPLAY_H__
|
#define __AMDGPU_DISPLAY_H__
|
||||||
|
|
||||||
|
#include <drm/drm_panic.h>
|
||||||
|
|
||||||
#define amdgpu_display_vblank_get_counter(adev, crtc) (adev)->mode_info.funcs->vblank_get_counter((adev), (crtc))
|
#define amdgpu_display_vblank_get_counter(adev, crtc) (adev)->mode_info.funcs->vblank_get_counter((adev), (crtc))
|
||||||
#define amdgpu_display_backlight_set_level(adev, e, l) (adev)->mode_info.funcs->backlight_set_level((e), (l))
|
#define amdgpu_display_backlight_set_level(adev, e, l) (adev)->mode_info.funcs->backlight_set_level((e), (l))
|
||||||
#define amdgpu_display_backlight_get_level(adev, e) (adev)->mode_info.funcs->backlight_get_level((e))
|
#define amdgpu_display_backlight_get_level(adev, e) (adev)->mode_info.funcs->backlight_get_level((e))
|
||||||
@@ -49,4 +51,7 @@ amdgpu_lookup_format_info(u32 format, uint64_t modifier);
|
|||||||
int amdgpu_display_suspend_helper(struct amdgpu_device *adev);
|
int amdgpu_display_suspend_helper(struct amdgpu_device *adev);
|
||||||
int amdgpu_display_resume_helper(struct amdgpu_device *adev);
|
int amdgpu_display_resume_helper(struct amdgpu_device *adev);
|
||||||
|
|
||||||
|
int amdgpu_display_get_scanout_buffer(struct drm_plane *plane,
|
||||||
|
struct drm_scanout_buffer *sb);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user