drm: Add drm_gem_vram_{pin/unpin}_reserved() and convert mgag200

The new interfaces drm_gem_vram_{pin/unpin}_reserved() are variants of the
GEM VRAM pin/unpin functions that do not reserve the BO during validation.
The mgag200 driver requires this behavior for its cursor handling. The
patch also converts the driver to use the new interfaces.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: http://patchwork.freedesktop.org/patch/msgid/20190516162746.11636-2-tzimmermann@suse.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Thomas Zimmermann 2019-05-16 18:27:45 +02:00 committed by Gerd Hoffmann
parent f569aa9b1c
commit 82ff2fb5d1
3 changed files with 88 additions and 8 deletions

View File

@ -254,6 +254,47 @@ int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag)
} }
EXPORT_SYMBOL(drm_gem_vram_pin); EXPORT_SYMBOL(drm_gem_vram_pin);
/**
* drm_gem_vram_pin_reserved() - Pins a GEM VRAM object in a region.
* @gbo: the GEM VRAM object
* @pl_flag: a bitmask of possible memory regions
*
* Pinning a buffer object ensures that it is not evicted from
* a memory region. A pinned buffer object has to be unpinned before
* it can be pinned to another region.
*
* This function pins a GEM VRAM object that has already been
* reserved. Use drm_gem_vram_pin() if possible.
*
* Returns:
* 0 on success, or
* a negative error code otherwise.
*/
int drm_gem_vram_pin_reserved(struct drm_gem_vram_object *gbo,
unsigned long pl_flag)
{
int i, ret;
struct ttm_operation_ctx ctx = { false, false };
if (gbo->pin_count) {
++gbo->pin_count;
return 0;
}
drm_gem_vram_placement(gbo, pl_flag);
for (i = 0; i < gbo->placement.num_placement; ++i)
gbo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
if (ret < 0)
return ret;
gbo->pin_count = 1;
return 0;
}
EXPORT_SYMBOL(drm_gem_vram_pin_reserved);
/** /**
* drm_gem_vram_unpin() - Unpins a GEM VRAM object * drm_gem_vram_unpin() - Unpins a GEM VRAM object
* @gbo: the GEM VRAM object * @gbo: the GEM VRAM object
@ -285,6 +326,40 @@ int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo)
} }
EXPORT_SYMBOL(drm_gem_vram_unpin); EXPORT_SYMBOL(drm_gem_vram_unpin);
/**
* drm_gem_vram_unpin_reserved() - Unpins a GEM VRAM object
* @gbo: the GEM VRAM object
*
* This function unpins a GEM VRAM object that has already been
* reserved. Use drm_gem_vram_unpin() if possible.
*
* Returns:
* 0 on success, or
* a negative error code otherwise.
*/
int drm_gem_vram_unpin_reserved(struct drm_gem_vram_object *gbo)
{
int i, ret;
struct ttm_operation_ctx ctx = { false, false };
if (WARN_ON_ONCE(!gbo->pin_count))
return 0;
--gbo->pin_count;
if (gbo->pin_count)
return 0;
for (i = 0; i < gbo->placement.num_placement ; ++i)
gbo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
if (ret < 0)
return ret;
return 0;
}
EXPORT_SYMBOL(drm_gem_vram_unpin_reserved);
/** /**
* drm_gem_vram_push_to_system() - \ * drm_gem_vram_push_to_system() - \
Unpins a GEM VRAM object and moves it to system memory Unpins a GEM VRAM object and moves it to system memory

View File

@ -23,9 +23,9 @@ static void mga_hide_cursor(struct mga_device *mdev)
WREG8(MGA_CURPOSXL, 0); WREG8(MGA_CURPOSXL, 0);
WREG8(MGA_CURPOSXH, 0); WREG8(MGA_CURPOSXH, 0);
if (mdev->cursor.pixels_1->pin_count) if (mdev->cursor.pixels_1->pin_count)
drm_gem_vram_unpin(mdev->cursor.pixels_1); drm_gem_vram_unpin_reserved(mdev->cursor.pixels_1);
if (mdev->cursor.pixels_2->pin_count) if (mdev->cursor.pixels_2->pin_count)
drm_gem_vram_unpin(mdev->cursor.pixels_2); drm_gem_vram_unpin_reserved(mdev->cursor.pixels_2);
} }
int mga_crtc_cursor_set(struct drm_crtc *crtc, int mga_crtc_cursor_set(struct drm_crtc *crtc,
@ -96,26 +96,28 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc,
/* Move cursor buffers into VRAM if they aren't already */ /* Move cursor buffers into VRAM if they aren't already */
if (!pixels_1->pin_count) { if (!pixels_1->pin_count) {
ret = drm_gem_vram_pin(pixels_1, DRM_GEM_VRAM_PL_FLAG_VRAM); ret = drm_gem_vram_pin_reserved(pixels_1,
DRM_GEM_VRAM_PL_FLAG_VRAM);
if (ret) if (ret)
goto out1; goto out1;
gpu_addr = drm_gem_vram_offset(pixels_1); gpu_addr = drm_gem_vram_offset(pixels_1);
if (gpu_addr < 0) { if (gpu_addr < 0) {
drm_gem_vram_unpin(pixels_1); drm_gem_vram_unpin_reserved(pixels_1);
goto out1; goto out1;
} }
mdev->cursor.pixels_1_gpu_addr = gpu_addr; mdev->cursor.pixels_1_gpu_addr = gpu_addr;
} }
if (!pixels_2->pin_count) { if (!pixels_2->pin_count) {
ret = drm_gem_vram_pin(pixels_2, DRM_GEM_VRAM_PL_FLAG_VRAM); ret = drm_gem_vram_pin_reserved(pixels_2,
DRM_GEM_VRAM_PL_FLAG_VRAM);
if (ret) { if (ret) {
drm_gem_vram_unpin(pixels_1); drm_gem_vram_unpin_reserved(pixels_1);
goto out1; goto out1;
} }
gpu_addr = drm_gem_vram_offset(pixels_2); gpu_addr = drm_gem_vram_offset(pixels_2);
if (gpu_addr < 0) { if (gpu_addr < 0) {
drm_gem_vram_unpin(pixels_1); drm_gem_vram_unpin_reserved(pixels_1);
drm_gem_vram_unpin(pixels_2); drm_gem_vram_unpin_reserved(pixels_2);
goto out1; goto out1;
} }
mdev->cursor.pixels_2_gpu_addr = gpu_addr; mdev->cursor.pixels_2_gpu_addr = gpu_addr;

View File

@ -82,7 +82,10 @@ void drm_gem_vram_unreserve(struct drm_gem_vram_object *gbo);
u64 drm_gem_vram_mmap_offset(struct drm_gem_vram_object *gbo); u64 drm_gem_vram_mmap_offset(struct drm_gem_vram_object *gbo);
s64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo); s64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo);
int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag); int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag);
int drm_gem_vram_pin_reserved(struct drm_gem_vram_object *gbo,
unsigned long pl_flag);
int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo); int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo);
int drm_gem_vram_unpin_reserved(struct drm_gem_vram_object *gbo);
int drm_gem_vram_push_to_system(struct drm_gem_vram_object *gbo); int drm_gem_vram_push_to_system(struct drm_gem_vram_object *gbo);
void *drm_gem_vram_kmap_at(struct drm_gem_vram_object *gbo, bool map, void *drm_gem_vram_kmap_at(struct drm_gem_vram_object *gbo, bool map,
bool *is_iomem, struct ttm_bo_kmap_obj *kmap); bool *is_iomem, struct ttm_bo_kmap_obj *kmap);