@@ -762,6 +762,49 @@ nouveau_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
return 0;
}
+static int
+nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, struct ttm_bus_placement *pl)
+{
+ struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
+ struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
+ struct drm_device *dev = dev_priv->dev;
+
+ pl->offset = 0;
+ pl->size = mem->num_pages << PAGE_SHIFT;
+ pl->base = 0;
+ pl->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_TT:
+ pl->offset = mem->mm_node->start << PAGE_SHIFT;
+#if __OS_HAS_AGP
+ if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) {
+ pl->base = dev_priv->gart_info.aper_base;
+ pl->is_iomem = true;
+ }
+#endif
+ return 0;
+ case TTM_PL_VRAM:
+ pl->offset = mem->mm_node->start << PAGE_SHIFT;
+ pl->base = drm_get_resource_start(dev, 1);
+ pl->is_iomem = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int
+nouveau_ttm_fault(struct ttm_buffer_object *bo, struct ttm_bus_placement *pl)
+{
+ return nouveau_ttm_io_mem_reserve(bo->bdev, &bo->mem, pl);
+}
+
struct ttm_bo_driver nouveau_bo_driver = {
.create_ttm_backend_entry = nouveau_bo_create_ttm_backend_entry,
.invalidate_caches = nouveau_bo_invalidate_caches,
@@ -774,5 +817,8 @@ struct ttm_bo_driver nouveau_bo_driver = {
.sync_obj_flush = nouveau_fence_flush,
.sync_obj_unref = nouveau_fence_unref,
.sync_obj_ref = nouveau_fence_ref,
+ .fault_reserve = &nouveau_ttm_fault,
+ .io_mem_reserve = &nouveau_ttm_io_mem_reserve,
+ .io_mem_free = NULL,
};