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 "gc/gc_11_0_0_offset.h"
|
||||
#include "gc/gc_11_0_0_sh_mask.h"
|
||||
#include "bif/bif_4_1_d.h"
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include <linux/pci.h>
|
||||
@@ -1788,3 +1789,82 @@ int amdgpu_display_resume_helper(struct amdgpu_device *adev)
|
||||
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__
|
||||
#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_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))
|
||||
@@ -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_resume_helper(struct amdgpu_device *adev);
|
||||
|
||||
int amdgpu_display_get_scanout_buffer(struct drm_plane *plane,
|
||||
struct drm_scanout_buffer *sb);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user