summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/qxl/qxl_ttm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/qxl/qxl_ttm.c')
-rw-r--r--drivers/gpu/drm/qxl/qxl_ttm.c265
1 files changed, 81 insertions, 184 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c
index f09a712b1ed2..1a40590077dd 100644
--- a/drivers/gpu/drm/qxl/qxl_ttm.c
+++ b/drivers/gpu/drm/qxl/qxl_ttm.c
@@ -28,17 +28,17 @@
#include <drm/drm.h>
#include <drm/drm_file.h>
#include <drm/drm_debugfs.h>
+#include <drm/drm_print.h>
#include <drm/qxl_drm.h>
-#include <drm/ttm/ttm_bo_api.h>
-#include <drm/ttm/ttm_bo_driver.h>
-#include <drm/ttm/ttm_module.h>
-#include <drm/ttm/ttm_page_alloc.h>
+#include <drm/ttm/ttm_bo.h>
#include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_range_manager.h>
+#include <drm/ttm/ttm_tt.h>
#include "qxl_drv.h"
#include "qxl_object.h"
-static struct qxl_device *qxl_get_qdev(struct ttm_bo_device *bdev)
+static struct qxl_device *qxl_get_qdev(struct ttm_device *bdev)
{
struct qxl_mman *mman;
struct qxl_device *qdev;
@@ -48,41 +48,6 @@ static struct qxl_device *qxl_get_qdev(struct ttm_bo_device *bdev)
return qdev;
}
-static int qxl_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
- struct ttm_mem_type_manager *man)
-{
- struct qxl_device *qdev = qxl_get_qdev(bdev);
- unsigned int gpu_offset_shift =
- 64 - (qdev->rom->slot_gen_bits + qdev->rom->slot_id_bits + 8);
- struct qxl_memslot *slot;
-
- switch (type) {
- case TTM_PL_SYSTEM:
- /* System memory */
- man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
- man->available_caching = TTM_PL_MASK_CACHING;
- man->default_caching = TTM_PL_FLAG_CACHED;
- break;
- case TTM_PL_VRAM:
- case TTM_PL_PRIV:
- /* "On-card" video ram */
- slot = (type == TTM_PL_VRAM) ?
- &qdev->main_slot : &qdev->surfaces_slot;
- slot->gpu_offset = (uint64_t)type << gpu_offset_shift;
- man->func = &ttm_bo_manager_func;
- man->gpu_offset = slot->gpu_offset;
- man->flags = TTM_MEMTYPE_FLAG_FIXED |
- TTM_MEMTYPE_FLAG_MAPPABLE;
- man->available_caching = TTM_PL_MASK_CACHING;
- man->default_caching = TTM_PL_FLAG_CACHED;
- break;
- default:
- DRM_ERROR("Unsupported memory type %u\n", (unsigned int)type);
- return -EINVAL;
- }
- return 0;
-}
-
static void qxl_evict_flags(struct ttm_buffer_object *bo,
struct ttm_placement *placement)
{
@@ -90,47 +55,39 @@ static void qxl_evict_flags(struct ttm_buffer_object *bo,
static const struct ttm_place placements = {
.fpfn = 0,
.lpfn = 0,
- .flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM
+ .mem_type = TTM_PL_SYSTEM,
+ .flags = 0
};
if (!qxl_ttm_bo_is_qxl_bo(bo)) {
placement->placement = &placements;
- placement->busy_placement = &placements;
placement->num_placement = 1;
- placement->num_busy_placement = 1;
return;
}
qbo = to_qxl_bo(bo);
- qxl_ttm_placement_from_domain(qbo, QXL_GEM_DOMAIN_CPU, false);
+ qxl_ttm_placement_from_domain(qbo, QXL_GEM_DOMAIN_CPU);
*placement = qbo->placement;
}
-int qxl_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
- struct ttm_mem_reg *mem)
+int qxl_ttm_io_mem_reserve(struct ttm_device *bdev,
+ struct ttm_resource *mem)
{
- struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
struct qxl_device *qdev = qxl_get_qdev(bdev);
- mem->bus.addr = NULL;
- mem->bus.offset = 0;
- mem->bus.size = mem->num_pages << PAGE_SHIFT;
- mem->bus.base = 0;
- mem->bus.is_iomem = false;
- if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
- return -EINVAL;
switch (mem->mem_type) {
case TTM_PL_SYSTEM:
/* system memory */
return 0;
case TTM_PL_VRAM:
mem->bus.is_iomem = true;
- mem->bus.base = qdev->vram_base;
- mem->bus.offset = mem->start << PAGE_SHIFT;
+ mem->bus.offset = (mem->start << PAGE_SHIFT) + qdev->vram_base;
+ mem->bus.caching = ttm_write_combined;
break;
case TTM_PL_PRIV:
mem->bus.is_iomem = true;
- mem->bus.base = qdev->surfaceram_base;
- mem->bus.offset = mem->start << PAGE_SHIFT;
+ mem->bus.offset = (mem->start << PAGE_SHIFT) +
+ qdev->surfaceram_base;
+ mem->bus.caching = ttm_write_combined;
break;
default:
return -EINVAL;
@@ -138,153 +95,122 @@ int qxl_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
return 0;
}
-static void qxl_ttm_io_mem_free(struct ttm_bo_device *bdev,
- struct ttm_mem_reg *mem)
-{
-}
-
/*
* TTM backend functions.
*/
-struct qxl_ttm_tt {
- struct ttm_tt ttm;
- struct qxl_device *qdev;
- u64 offset;
-};
-
-static int qxl_ttm_backend_bind(struct ttm_tt *ttm,
- struct ttm_mem_reg *bo_mem)
+static void qxl_ttm_backend_destroy(struct ttm_device *bdev, struct ttm_tt *ttm)
{
- struct qxl_ttm_tt *gtt = (void *)ttm;
-
- gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT);
- if (!ttm->num_pages) {
- WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n",
- ttm->num_pages, bo_mem, ttm);
- }
- /* Not implemented */
- return -1;
+ ttm_tt_fini(ttm);
+ kfree(ttm);
}
-static int qxl_ttm_backend_unbind(struct ttm_tt *ttm)
-{
- /* Not implemented */
- return -1;
-}
-
-static void qxl_ttm_backend_destroy(struct ttm_tt *ttm)
-{
- struct qxl_ttm_tt *gtt = (void *)ttm;
-
- ttm_tt_fini(&gtt->ttm);
- kfree(gtt);
-}
-
-static struct ttm_backend_func qxl_backend_func = {
- .bind = &qxl_ttm_backend_bind,
- .unbind = &qxl_ttm_backend_unbind,
- .destroy = &qxl_ttm_backend_destroy,
-};
-
static struct ttm_tt *qxl_ttm_tt_create(struct ttm_buffer_object *bo,
uint32_t page_flags)
{
- struct qxl_device *qdev;
- struct qxl_ttm_tt *gtt;
+ struct ttm_tt *ttm;
- qdev = qxl_get_qdev(bo->bdev);
- gtt = kzalloc(sizeof(struct qxl_ttm_tt), GFP_KERNEL);
- if (gtt == NULL)
+ ttm = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL);
+ if (ttm == NULL)
return NULL;
- gtt->ttm.func = &qxl_backend_func;
- gtt->qdev = qdev;
- if (ttm_tt_init(&gtt->ttm, bo, page_flags)) {
- kfree(gtt);
+ if (ttm_tt_init(ttm, bo, page_flags, ttm_cached, 0)) {
+ kfree(ttm);
return NULL;
}
- return &gtt->ttm;
+ return ttm;
}
-static void qxl_move_null(struct ttm_buffer_object *bo,
- struct ttm_mem_reg *new_mem)
+static void qxl_bo_move_notify(struct ttm_buffer_object *bo,
+ struct ttm_resource *new_mem)
{
- struct ttm_mem_reg *old_mem = &bo->mem;
+ struct qxl_bo *qbo;
+ struct qxl_device *qdev;
+
+ if (!qxl_ttm_bo_is_qxl_bo(bo) || !bo->resource)
+ return;
+ qbo = to_qxl_bo(bo);
+ qdev = to_qxl(qbo->tbo.base.dev);
- BUG_ON(old_mem->mm_node != NULL);
- *old_mem = *new_mem;
- new_mem->mm_node = NULL;
+ if (bo->resource->mem_type == TTM_PL_PRIV && qbo->surface_id)
+ qxl_surface_evict(qdev, qbo, new_mem ? true : false);
}
static int qxl_bo_move(struct ttm_buffer_object *bo, bool evict,
struct ttm_operation_ctx *ctx,
- struct ttm_mem_reg *new_mem)
+ struct ttm_resource *new_mem,
+ struct ttm_place *hop)
{
- struct ttm_mem_reg *old_mem = &bo->mem;
+ struct ttm_resource *old_mem = bo->resource;
int ret;
- ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu);
+ if (!old_mem) {
+ if (new_mem->mem_type != TTM_PL_SYSTEM) {
+ hop->mem_type = TTM_PL_SYSTEM;
+ hop->flags = TTM_PL_FLAG_TEMPORARY;
+ return -EMULTIHOP;
+ }
+
+ ttm_bo_move_null(bo, new_mem);
+ return 0;
+ }
+
+ qxl_bo_move_notify(bo, new_mem);
+
+ ret = ttm_bo_wait_ctx(bo, ctx);
if (ret)
return ret;
if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) {
- qxl_move_null(bo, new_mem);
+ ttm_bo_move_null(bo, new_mem);
return 0;
}
return ttm_bo_move_memcpy(bo, ctx, new_mem);
}
-static void qxl_bo_move_notify(struct ttm_buffer_object *bo,
- bool evict,
- struct ttm_mem_reg *new_mem)
+static void qxl_bo_delete_mem_notify(struct ttm_buffer_object *bo)
{
- struct qxl_bo *qbo;
- struct qxl_device *qdev;
-
- if (!qxl_ttm_bo_is_qxl_bo(bo))
- return;
- qbo = to_qxl_bo(bo);
- qdev = to_qxl(qbo->tbo.base.dev);
-
- if (bo->mem.mem_type == TTM_PL_PRIV && qbo->surface_id)
- qxl_surface_evict(qdev, qbo, new_mem ? true : false);
+ qxl_bo_move_notify(bo, NULL);
}
-static struct ttm_bo_driver qxl_bo_driver = {
+static struct ttm_device_funcs qxl_bo_driver = {
.ttm_tt_create = &qxl_ttm_tt_create,
- .init_mem_type = &qxl_init_mem_type,
+ .ttm_tt_destroy = &qxl_ttm_backend_destroy,
.eviction_valuable = ttm_bo_eviction_valuable,
.evict_flags = &qxl_evict_flags,
.move = &qxl_bo_move,
.io_mem_reserve = &qxl_ttm_io_mem_reserve,
- .io_mem_free = &qxl_ttm_io_mem_free,
- .move_notify = &qxl_bo_move_notify,
+ .delete_mem_notify = &qxl_bo_delete_mem_notify,
};
+static int qxl_ttm_init_mem_type(struct qxl_device *qdev,
+ unsigned int type,
+ uint64_t size)
+{
+ return ttm_range_man_init(&qdev->mman.bdev, type, false, size);
+}
+
int qxl_ttm_init(struct qxl_device *qdev)
{
int r;
int num_io_pages; /* != rom->num_io_pages, we include surface0 */
/* No others user of address space so set it to 0 */
- r = ttm_bo_device_init(&qdev->mman.bdev,
- &qxl_bo_driver,
- qdev->ddev.anon_inode->i_mapping,
- qdev->ddev.vma_offset_manager,
- false);
+ r = ttm_device_init(&qdev->mman.bdev, &qxl_bo_driver, NULL,
+ qdev->ddev.anon_inode->i_mapping,
+ qdev->ddev.vma_offset_manager,
+ 0);
if (r) {
DRM_ERROR("failed initializing buffer object driver(%d).\n", r);
return r;
}
/* NOTE: this includes the framebuffer (aka surface 0) */
num_io_pages = qdev->rom->ram_header_offset / PAGE_SIZE;
- r = ttm_bo_init_mm(&qdev->mman.bdev, TTM_PL_VRAM,
- num_io_pages);
+ r = qxl_ttm_init_mem_type(qdev, TTM_PL_VRAM, num_io_pages);
if (r) {
DRM_ERROR("Failed initializing VRAM heap.\n");
return r;
}
- r = ttm_bo_init_mm(&qdev->mman.bdev, TTM_PL_PRIV,
- qdev->surfaceram_size / PAGE_SIZE);
+ r = qxl_ttm_init_mem_type(qdev, TTM_PL_PRIV,
+ qdev->surfaceram_size / PAGE_SIZE);
if (r) {
DRM_ERROR("Failed initializing Surfaces heap.\n");
return r;
@@ -300,49 +226,20 @@ int qxl_ttm_init(struct qxl_device *qdev)
void qxl_ttm_fini(struct qxl_device *qdev)
{
- ttm_bo_clean_mm(&qdev->mman.bdev, TTM_PL_VRAM);
- ttm_bo_clean_mm(&qdev->mman.bdev, TTM_PL_PRIV);
- ttm_bo_device_release(&qdev->mman.bdev);
+ ttm_range_man_fini(&qdev->mman.bdev, TTM_PL_VRAM);
+ ttm_range_man_fini(&qdev->mman.bdev, TTM_PL_PRIV);
+ ttm_device_fini(&qdev->mman.bdev);
DRM_INFO("qxl: ttm finalized\n");
}
-#define QXL_DEBUGFS_MEM_TYPES 2
-
-#if defined(CONFIG_DEBUG_FS)
-static int qxl_mm_dump_table(struct seq_file *m, void *data)
-{
- struct drm_info_node *node = (struct drm_info_node *)m->private;
- struct drm_mm *mm = (struct drm_mm *)node->info_ent->data;
- struct drm_printer p = drm_seq_file_printer(m);
-
- spin_lock(&ttm_bo_glob.lru_lock);
- drm_mm_print(mm, &p);
- spin_unlock(&ttm_bo_glob.lru_lock);
- return 0;
-}
-#endif
-
void qxl_ttm_debugfs_init(struct qxl_device *qdev)
{
#if defined(CONFIG_DEBUG_FS)
- static struct drm_info_list qxl_mem_types_list[QXL_DEBUGFS_MEM_TYPES];
- static char qxl_mem_types_names[QXL_DEBUGFS_MEM_TYPES][32];
- unsigned int i;
-
- for (i = 0; i < QXL_DEBUGFS_MEM_TYPES; i++) {
- if (i == 0)
- sprintf(qxl_mem_types_names[i], "qxl_mem_mm");
- else
- sprintf(qxl_mem_types_names[i], "qxl_surf_mm");
- qxl_mem_types_list[i].name = qxl_mem_types_names[i];
- qxl_mem_types_list[i].show = &qxl_mm_dump_table;
- qxl_mem_types_list[i].driver_features = 0;
- if (i == 0)
- qxl_mem_types_list[i].data = qdev->mman.bdev.man[TTM_PL_VRAM].priv;
- else
- qxl_mem_types_list[i].data = qdev->mman.bdev.man[TTM_PL_PRIV].priv;
-
- }
- qxl_debugfs_add_files(qdev, qxl_mem_types_list, i);
+ ttm_resource_manager_create_debugfs(ttm_manager_type(&qdev->mman.bdev,
+ TTM_PL_VRAM),
+ qdev->ddev.primary->debugfs_root, "qxl_mem_mm");
+ ttm_resource_manager_create_debugfs(ttm_manager_type(&qdev->mman.bdev,
+ TTM_PL_PRIV),
+ qdev->ddev.primary->debugfs_root, "qxl_surf_mm");
#endif
}