[openchrome-devel] drm-openchrome: Branch 'drm-next-5.1' - 2 commits - drivers/gpu/drm

Kevin Brace kevinbrace at kemper.freedesktop.org
Sun Mar 17 05:26:48 UTC 2019


 drivers/gpu/drm/openchrome/Makefile             |    2 
 drivers/gpu/drm/openchrome/openchrome_crtc.c    |  198 ++++++++---
 drivers/gpu/drm/openchrome/openchrome_display.h |    2 
 drivers/gpu/drm/openchrome/openchrome_drv.c     |  252 ++++++++++----
 drivers/gpu/drm/openchrome/openchrome_drv.h     |   95 +----
 drivers/gpu/drm/openchrome/openchrome_fb.c      |  117 ++++--
 drivers/gpu/drm/openchrome/openchrome_gem.c     |  120 ------
 drivers/gpu/drm/openchrome/openchrome_init.c    |   23 -
 drivers/gpu/drm/openchrome/openchrome_ioc32.c   |  140 ++++----
 drivers/gpu/drm/openchrome/openchrome_object.c  |  233 +++++++++++++
 drivers/gpu/drm/openchrome/openchrome_ttm.c     |  417 +++++-------------------
 11 files changed, 874 insertions(+), 725 deletions(-)

New commits:
commit be8e17570db5bdea1c79fe238df4712e07145200
Author: Kevin Brace <kevinbrace at gmx.com>
Date:   Sat Mar 16 17:55:03 2019 -0700

    drm/openchrome: Version bumped to 3.1.6
    
    Replaced the TTM memory allocator code.
    
    Signed-off-by: Kevin Brace <kevinbrace at gmx.com>

diff --git a/drivers/gpu/drm/openchrome/openchrome_drv.h b/drivers/gpu/drm/openchrome/openchrome_drv.h
index af912336ed57..9a78de1ad4f2 100644
--- a/drivers/gpu/drm/openchrome/openchrome_drv.h
+++ b/drivers/gpu/drm/openchrome/openchrome_drv.h
@@ -51,7 +51,7 @@
 
 #define DRIVER_MAJOR		3
 #define DRIVER_MINOR		1
-#define DRIVER_PATCHLEVEL	5
+#define DRIVER_PATCHLEVEL	6
 #define DRIVER_NAME		"openchrome"
 #define DRIVER_DESC		"OpenChrome DRM for VIA Technologies Chrome IGP"
 #define DRIVER_DATE		"20190316"
commit fb290240fd06172e034654b4b125497bed47b2f2
Author: Kevin Brace <kevinbrace at gmx.com>
Date:   Sat Mar 16 17:52:24 2019 -0700

    drm/openchrome: New TTM memory allocator
    
    A basic implementation with no DMA support.
    
    Signed-off-by: Kevin Brace <kevinbrace at gmx.com>

diff --git a/drivers/gpu/drm/openchrome/Makefile b/drivers/gpu/drm/openchrome/Makefile
index 3ed2912e75f5..261c40f8e3eb 100644
--- a/drivers/gpu/drm/openchrome/Makefile
+++ b/drivers/gpu/drm/openchrome/Makefile
@@ -12,11 +12,11 @@ openchrome-y := openchrome_analog.o \
 		openchrome_encoder.o \
 		openchrome_fb.o \
 		openchrome_fp.o \
-		openchrome_gem.o \
 		openchrome_hdmi.o \
 		openchrome_i2c.o \
 		openchrome_init.o \
 		openchrome_ioc32.o \
+		openchrome_object.o \
 		openchrome_pm.o \
 		openchrome_sii164.o \
 		openchrome_tmds.o \
diff --git a/drivers/gpu/drm/openchrome/openchrome_crtc.c b/drivers/gpu/drm/openchrome/openchrome_crtc.c
index 91d008213c23..9427b6ad163f 100644
--- a/drivers/gpu/drm/openchrome/openchrome_crtc.c
+++ b/drivers/gpu/drm/openchrome/openchrome_crtc.c
@@ -255,7 +255,7 @@ static void via_cursor_address(struct drm_crtc *crtc)
 	struct openchrome_drm_private *dev_private =
 						crtc->dev->dev_private;
 
-	if (!iga->cursor_kmap.bo) {
+	if (!iga->cursor_bo->kmap.bo) {
 		return;
 	}
 
@@ -269,13 +269,13 @@ static void via_cursor_address(struct drm_crtc *crtc)
 	case PCI_DEVICE_ID_VIA_VX900_VGA:
 		/* Program the HI offset. */
 		if (iga->index) {
-			VIA_WRITE(HI_FBOFFSET, iga->cursor_kmap.bo->offset);
+			VIA_WRITE(HI_FBOFFSET, iga->cursor_bo->kmap.bo->offset);
 		} else {
-			VIA_WRITE(PRIM_HI_FBOFFSET, iga->cursor_kmap.bo->offset);
+			VIA_WRITE(PRIM_HI_FBOFFSET, iga->cursor_bo->kmap.bo->offset);
 		}
 		break;
 	default:
-		VIA_WRITE(HI_FBOFFSET, iga->cursor_kmap.bo->offset);
+		VIA_WRITE(HI_FBOFFSET, iga->cursor_bo->kmap.bo->offset);
 		break;
 	}
 }
@@ -288,10 +288,11 @@ static int via_crtc_cursor_set(struct drm_crtc *crtc,
 	struct via_crtc *iga = container_of(crtc, struct via_crtc, base);
 	int max_height = 64, max_width = 64, ret = 0, i;
 	struct drm_device *dev = crtc->dev;
-	struct drm_gem_object *obj = NULL;
+	struct drm_gem_object *gem;
 	struct ttm_bo_kmap_obj user_kmap;
+	struct openchrome_bo *bo;
 
-	if (!iga->cursor_kmap.bo)
+	if (!iga->cursor_bo->kmap.bo)
 		return -ENXIO;
 
 	if (!handle) {
@@ -312,20 +313,23 @@ static int via_crtc_cursor_set(struct drm_crtc *crtc,
 		return -EINVAL;
 	}
 
-	obj = drm_gem_object_lookup(file_priv, handle);
-	if (!obj) {
+	gem = drm_gem_object_lookup(file_priv, handle);
+	if (!gem) {
 		DRM_ERROR("Cannot find cursor object %x for crtc %d\n",
 				handle, crtc->base.id);
 		return -ENOENT;
 	}
 
-	user_kmap.bo = ttm_gem_mapping(obj);
-	ret = ttm_bo_kmap(user_kmap.bo, 0, user_kmap.bo->num_pages, &user_kmap);
+	bo = container_of(gem, struct openchrome_bo, gem);
+	user_kmap.bo = &bo->ttm_bo;
+	ret = ttm_bo_kmap(user_kmap.bo, 0, user_kmap.bo->num_pages,
+				&user_kmap);
 	if (!ret) {
 		/* Copy data from userland to cursor memory region */
-		u32 *dst = iga->cursor_kmap.virtual, *src = user_kmap.virtual;
+		u32 *dst = iga->cursor_bo->kmap.virtual,
+				*src = user_kmap.virtual;
 
-		memset_io(dst, 0x0, iga->cursor_kmap.bo->mem.size);
+		memset_io(dst, 0x0, iga->cursor_bo->kmap.bo->mem.size);
 		for (i = 0; i < height; i++) {
 			__iowrite32_copy(dst, src, width);
 			dst += max_width;
@@ -333,7 +337,7 @@ static int via_crtc_cursor_set(struct drm_crtc *crtc,
 		}
 		ttm_bo_kunmap(&user_kmap);
 	}
-	drm_gem_object_put_unlocked(obj);
+	drm_gem_object_put_unlocked(gem);
 	via_cursor_address(crtc);
 	via_show_cursor(crtc);
 
@@ -533,11 +537,27 @@ static int via_iga2_gamma_set(struct drm_crtc *crtc,
 static void via_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct via_crtc *iga = container_of(crtc, struct via_crtc, base);
+	int ret;
+
+	if (iga->cursor_bo->kmap.bo) {
+		ret = ttm_bo_reserve(iga->cursor_bo->kmap.bo,
+					true, false, NULL);
+		if (ret) {
+			goto exit;
+		}
+
+		ttm_bo_kunmap(&iga->cursor_bo->kmap);
 
-	if (iga->cursor_kmap.bo) {
-		via_bo_unpin(iga->cursor_kmap.bo, &iga->cursor_kmap);
-		ttm_bo_put(iga->cursor_kmap.bo);
+		ret = openchrome_bo_unpin(iga->cursor_bo);
+		ttm_bo_unreserve(iga->cursor_bo->kmap.bo);
+		if (ret) {
+			goto exit;
+		}
+
+		ttm_bo_put(iga->cursor_bo->kmap.bo);
 	}
+
+exit:
 	drm_crtc_cleanup(crtc);
 }
 
@@ -1876,12 +1896,13 @@ static int
 via_iga1_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 				struct drm_framebuffer *old_fb)
 {
-	struct ttm_buffer_object *bo;
 	struct via_framebuffer *via_fb = container_of(crtc->primary->fb,
 					struct via_framebuffer, fb);
 	struct drm_framebuffer *new_fb = &via_fb->fb;
-	struct drm_gem_object *gem_obj = via_fb->gem_obj;
+	struct openchrome_bo *bo;
+	struct drm_gem_object *gem;
 	int ret = 0;
+	int fake_ret = 0;
 
 	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
@@ -1892,11 +1913,18 @@ via_iga1_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 		goto exit;
 	}
 
-	gem_obj = via_fb->gem_obj;
-	bo = ttm_gem_mapping(gem_obj);
+	gem = via_fb->gem;
+	bo = container_of(gem, struct openchrome_bo, gem);
 
-	ret = via_bo_pin(bo, NULL);
-	if (unlikely(ret)) {
+	ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL);
+	if (ret) {
+		DRM_DEBUG_KMS("Failed to reserve FB.\n");
+		goto exit;
+	}
+
+	ret = openchrome_bo_pin(bo, TTM_PL_FLAG_VRAM);
+	ttm_bo_unreserve(&bo->ttm_bo);
+	if (ret) {
 		DRM_DEBUG_KMS("Failed to pin FB.\n");
 		goto exit;
 	}
@@ -1906,19 +1934,34 @@ via_iga1_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 						ENTER_ATOMIC_MODE_SET);
 	if (unlikely(ret)) {
 		DRM_DEBUG_KMS("Failed to set a new FB.\n");
-		via_bo_unpin(bo, NULL);
+		fake_ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL);
+		if (fake_ret) {
+			goto exit;
+		}
+
+		fake_ret = openchrome_bo_unpin(bo);
+		ttm_bo_unreserve(&bo->ttm_bo);
 		goto exit;
 	}
 
-	/* Free the old framebuffer if it exist */
+	/*
+	 * Free the old framebuffer if it exists.
+	 */
 	if (old_fb) {
 		via_fb = container_of(old_fb,
 					struct via_framebuffer, fb);
-		gem_obj = via_fb->gem_obj;
-		bo = ttm_gem_mapping(gem_obj);
+		gem = via_fb->gem;
+		bo = container_of(gem, struct openchrome_bo, gem);
 
-		ret = via_bo_unpin(bo, NULL);
-		if (unlikely(ret)) {
+		ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL);
+		if (ret) {
+			DRM_DEBUG_KMS("FB still locked.\n");
+			goto exit;
+		}
+
+		ret = openchrome_bo_unpin(bo);
+		ttm_bo_unreserve(&bo->ttm_bo);
+		if (ret) {
 			DRM_DEBUG_KMS("FB still locked.\n");
 			goto exit;
 		}
@@ -2032,8 +2075,9 @@ via_iga1_mode_set_base_atomic(struct drm_crtc *crtc,
 						crtc->dev->dev_private;
 	struct via_framebuffer *via_fb = container_of(fb,
 					struct via_framebuffer, fb);
-	struct drm_gem_object *gem_obj = via_fb->gem_obj;
-	struct ttm_buffer_object *bo = ttm_gem_mapping(gem_obj);
+	struct drm_gem_object *gem = via_fb->gem;
+	struct openchrome_bo *bo = container_of(gem,
+					struct openchrome_bo, gem);
 
 	if ((fb->format->depth != 8) && (fb->format->depth != 16) &&
 		(fb->format->depth != 24) && (fb->format->depth != 32)) {
@@ -2050,7 +2094,7 @@ via_iga1_mode_set_base_atomic(struct drm_crtc *crtc,
 	via_iga1_set_color_depth(dev_private, fb->format->depth);
 
 	/* Set the framebuffer offset */
-	addr = round_up(bo->offset + pitch, 16) >> 1;
+	addr = round_up(bo->ttm_bo.offset + pitch, 16) >> 1;
 	vga_wcrt(VGABASE, 0x0D, addr & 0xFF);
 	vga_wcrt(VGABASE, 0x0C, (addr >> 8) & 0xFF);
 	/* Yes order of setting these registers matters on some hardware */
@@ -2155,12 +2199,13 @@ static int
 via_iga2_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 				struct drm_framebuffer *old_fb)
 {
-	struct ttm_buffer_object *bo;
 	struct via_framebuffer *via_fb = container_of(crtc->primary->fb,
 					struct via_framebuffer, fb);
 	struct drm_framebuffer *new_fb = &via_fb->fb;
-	struct drm_gem_object *gem_obj = via_fb->gem_obj;
+	struct openchrome_bo *bo;
+	struct drm_gem_object *gem;
 	int ret = 0;
+	int fake_ret = 0;
 
 	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
@@ -2171,11 +2216,18 @@ via_iga2_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 		goto exit;
 	}
 
-	gem_obj = via_fb->gem_obj;
-	bo = ttm_gem_mapping(gem_obj);
+	gem = via_fb->gem;
+	bo = container_of(gem, struct openchrome_bo, gem);
 
-	ret = via_bo_pin(bo, NULL);
-	if (unlikely(ret)) {
+	ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL);
+	if (ret) {
+		DRM_DEBUG_KMS("Failed to reserve FB.\n");
+		goto exit;
+	}
+
+	ret = openchrome_bo_pin(bo, TTM_PL_FLAG_VRAM);
+	ttm_bo_unreserve(&bo->ttm_bo);
+	if (ret) {
 		DRM_DEBUG_KMS("Failed to pin FB.\n");
 		goto exit;
 	}
@@ -2184,19 +2236,34 @@ via_iga2_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 			ENTER_ATOMIC_MODE_SET);
 	if (unlikely(ret)) {
 		DRM_DEBUG_KMS("Failed to set a new FB.\n");
-		via_bo_unpin(bo, NULL);
+		fake_ret = ttm_bo_reserve(&bo->ttm_bo, true, false,
+						NULL);
+		if (fake_ret) {
+			goto exit;
+		}
+
+		fake_ret = openchrome_bo_unpin(bo);
+		ttm_bo_unreserve(&bo->ttm_bo);
 		goto exit;
 	}
 
-	/* Free the old framebuffer if it exist */
+	/*
+	 * Free the old framebuffer if it exists.
+	 */
 	if (old_fb) {
 		via_fb = container_of(old_fb,
-				struct via_framebuffer, fb);
-		gem_obj = via_fb->gem_obj;
-		bo = ttm_gem_mapping(gem_obj);
+					struct via_framebuffer, fb);
+		gem = via_fb->gem;
+		bo = container_of(gem, struct openchrome_bo, gem);
+		ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL);
+		if (ret) {
+			DRM_DEBUG_KMS("FB still locked.\n");
+			goto exit;
+		}
 
-		ret = via_bo_unpin(bo, NULL);
-		if (unlikely(ret)) {
+		ret = openchrome_bo_unpin(bo);
+		ttm_bo_unreserve(&bo->ttm_bo);
+		if (ret) {
 			DRM_DEBUG_KMS("FB still locked.\n");
 			goto exit;
 		}
@@ -2342,8 +2409,9 @@ via_iga2_mode_set_base_atomic(struct drm_crtc *crtc,
 						crtc->dev->dev_private;
 	struct via_framebuffer *via_fb = container_of(fb,
 					struct via_framebuffer, fb);
-	struct drm_gem_object *gem_obj = via_fb->gem_obj;
-	struct ttm_buffer_object *bo = ttm_gem_mapping(gem_obj);
+	struct drm_gem_object *gem = via_fb->gem;
+	struct openchrome_bo *bo = container_of(gem,
+					struct openchrome_bo, gem);
 
 	if ((fb->format->depth != 8) && (fb->format->depth != 16) &&
 		(fb->format->depth != 24) && (fb->format->depth != 32)) {
@@ -2360,7 +2428,7 @@ via_iga2_mode_set_base_atomic(struct drm_crtc *crtc,
 	via_iga2_set_color_depth(dev_private, fb->format->depth);
 
 	/* Set the framebuffer offset */
-	addr = round_up(bo->offset + pitch, 16);
+	addr = round_up(bo->ttm_bo.offset + pitch, 16);
 	/* Bits 9 to 3 of the frame buffer go into bits 7 to 1
 	 * of the register. Bit 0 is for setting tile mode or
 	 * linear mode. A value of zero sets it to linear mode */
@@ -2408,6 +2476,7 @@ int via_crtc_init(struct drm_device *dev, int index)
 						dev->dev_private;
 	struct via_crtc *iga = &dev_private->iga[index];
 	struct drm_crtc *crtc = &iga->base;
+	struct openchrome_bo *bo;
 	int cursor_size = 64 * 64 * 4, i;
 	u16 *gamma;
 	int ret;
@@ -2582,11 +2651,36 @@ int via_crtc_init(struct drm_device *dev, int index)
 			|| dev->pdev->device == PCI_DEVICE_ID_VIA_KM400)
 		cursor_size = 32 * 32 * 4;
 
-	ret = via_ttm_allocate_kernel_buffer(&dev_private->ttm.bdev,
-				cursor_size, 16,
-				TTM_PL_FLAG_VRAM, &iga->cursor_kmap);
-	if (ret)
-		DRM_ERROR("failed to create cursor\n");
+	ret = openchrome_bo_create(dev,
+					&dev_private->bdev,
+					cursor_size,
+					ttm_bo_type_kernel,
+					TTM_PL_FLAG_VRAM,
+					&bo);
+	if (ret) {
+		DRM_ERROR("Failed to create cursor.\n");
+		goto exit;
+	}
+
+	ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL);
+	if (ret) {
+		goto exit;
+	}
 
+	ret = openchrome_bo_pin(bo, TTM_PL_FLAG_VRAM);
+	if (ret) {
+		ttm_bo_unreserve(&bo->ttm_bo);
+		goto exit;
+	}
+
+	ret = ttm_bo_kmap(&bo->ttm_bo, 0, bo->ttm_bo.num_pages,
+				&bo->kmap);
+	ttm_bo_unreserve(&bo->ttm_bo);
+	if (ret) {
+		goto exit;
+	}
+
+	iga->cursor_bo = bo;
+exit:
 	return ret;
 }
diff --git a/drivers/gpu/drm/openchrome/openchrome_display.h b/drivers/gpu/drm/openchrome/openchrome_display.h
index db34df3dd10d..29e7e8046ef8 100644
--- a/drivers/gpu/drm/openchrome/openchrome_display.h
+++ b/drivers/gpu/drm/openchrome/openchrome_display.h
@@ -88,7 +88,7 @@ typedef struct _via_fp_info {
 
 struct via_crtc {
 	struct drm_crtc base;
-	struct ttm_bo_kmap_obj cursor_kmap;
+	struct openchrome_bo *cursor_bo;
 	struct crtc_timings pixel_timings;
 	struct crtc_timings timings;
 	struct vga_registers display_queue;
diff --git a/drivers/gpu/drm/openchrome/openchrome_drv.c b/drivers/gpu/drm/openchrome/openchrome_drv.c
index babb593ddbbc..1a23111dbde9 100644
--- a/drivers/gpu/drm/openchrome/openchrome_drv.c
+++ b/drivers/gpu/drm/openchrome/openchrome_drv.c
@@ -50,65 +50,83 @@ MODULE_DEVICE_TABLE(pci, via_pci_table);
 #define SGDMA_MEMORY (256*1024)
 #define VQ_MEMORY (256*1024)
 
-static int via_dumb_create(struct drm_file *filp,
-				struct drm_device *dev,
-				struct drm_mode_create_dumb *args)
+
+void openchrome_drm_driver_gem_free_object_unlocked (
+					struct drm_gem_object *obj)
 {
-	struct openchrome_drm_private *dev_private = dev->dev_private;
-	struct drm_gem_object *obj;
-	int ret;
+	struct openchrome_bo *bo = container_of(obj,
+					struct openchrome_bo, gem);
 
 	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
-	args->pitch = round_up(args->width * (args->bpp >> 3), 16);
-	args->size = args->pitch * args->height;
-	obj = ttm_gem_create(dev, &dev_private->ttm.bdev, args->size,
-				ttm_bo_type_device, TTM_PL_FLAG_VRAM,
-				16, PAGE_SIZE, false);
-	if (IS_ERR(obj))
-		return PTR_ERR(obj);
-
-	ret = drm_gem_handle_create(filp, obj, &args->handle);
-	/* drop reference from allocate - handle holds it now */
-	drm_gem_object_put_unlocked(obj);
+	ttm_bo_put(&bo->ttm_bo);
 
 	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
-	return ret;
 }
 
-static int via_dumb_mmap(struct drm_file *filp, struct drm_device *dev,
-				uint32_t handle, uint64_t *offset_p)
+static int openchrome_drm_driver_dumb_create(
+				struct drm_file *file_priv,
+				struct drm_device *dev,
+				struct drm_mode_create_dumb *args)
 {
-	struct ttm_buffer_object *bo;
-	struct drm_gem_object *obj;
-	int rc = -ENOENT;
+	struct openchrome_drm_private *dev_private = dev->dev_private;
+	struct openchrome_bo *bo;
+	u32 handle;
+	int ret;
 
 	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
-	obj = drm_gem_object_lookup(filp, handle);
-	if (obj == NULL)
-		return rc;
+	/*
+	 * Calculate the parameters for the dumb buffer.
+	 */
+	args->pitch = args->width * ((args->bpp + 7) >> 3);
+	args->size = args->pitch * args->height;
 
-	bo = ttm_gem_mapping(obj);
-	if (bo != NULL) {
-		*offset_p = drm_vma_node_offset_addr(&bo->vma_node);
-		rc = 0;
+	ret = openchrome_bo_create(dev,
+					&dev_private->bdev,
+					args->size,
+					ttm_bo_type_device,
+					TTM_PL_FLAG_VRAM,
+					&bo);
+	if (ret) {
+		goto exit;
 	}
-	drm_gem_object_put_unlocked(obj);
 
+	ret = drm_gem_handle_create(file_priv, &bo->gem, &handle);
+	drm_gem_object_put_unlocked(&bo->gem);
+	if (ret) {
+		goto exit;
+	}
+
+	args->handle = handle;
+exit:
 	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
-	return rc;
+	return ret;
 }
 
-static int gem_dumb_destroy(struct drm_file *filp,
-				struct drm_device *dev, uint32_t handle)
+static int openchrome_drm_driver_dumb_map_offset(
+				struct drm_file *file_priv,
+				struct drm_device *dev,
+				uint32_t handle,
+				uint64_t *offset)
 {
-	int ret;
+	struct drm_gem_object *gem;
+	struct openchrome_bo *bo;
+	int ret = 0;
 
 	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
-	ret = drm_gem_handle_delete(filp, handle);
+	gem = drm_gem_object_lookup(file_priv, handle);
+	if (!gem) {
+		ret = -ENOENT;
+		goto exit;
+	}
+
+	bo = container_of(gem, struct openchrome_bo, gem);
+	*offset = drm_vma_node_offset_addr(&bo->ttm_bo.vma_node);
 
+	drm_gem_object_put_unlocked(gem);
+exit:
 	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
 	return ret;
 }
@@ -116,29 +134,56 @@ static int gem_dumb_destroy(struct drm_file *filp,
 static void via_driver_unload(struct drm_device *dev)
 {
 	struct openchrome_drm_private *dev_private = dev->dev_private;
-	struct ttm_buffer_object *bo;
+	int ret;
 
 	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET))
 		via_modeset_fini(dev);
 
-	bo = dev_private->vq.bo;
-	if (bo) {
-		via_bo_unpin(bo, &dev_private->vq);
-		ttm_bo_put(bo);
+	if (dev_private->vq_bo) {
+		ret = ttm_bo_reserve(&dev_private->vq_bo->ttm_bo,
+					true, false, NULL);
+		if (ret) {
+			goto exit_vq;
+		}
+
+		ttm_bo_kunmap(&dev_private->vq_bo->kmap);
+
+		ret = openchrome_bo_unpin(dev_private->vq_bo);
+		ttm_bo_unreserve(&dev_private->vq_bo->ttm_bo);
+		if (ret) {
+			goto exit_vq;
+		}
+
+		ttm_bo_put(&dev_private->vq_bo->ttm_bo);
 	}
 
-	bo = dev_private->gart.bo;
-	if (bo) {
+exit_vq:
+	if (dev_private->gart_bo) {
 		/* enable gtt write */
 		if (pci_is_pcie(dev->pdev))
 			svga_wseq_mask(VGABASE, 0x6C, 0, BIT(7));
-		via_bo_unpin(bo, &dev_private->gart);
-		ttm_bo_put(bo);
+
+		ret = ttm_bo_reserve(&dev_private->gart_bo->ttm_bo,
+					true, false, NULL);
+		if (ret) {
+			goto exit_gart;
+		}
+
+		ttm_bo_kunmap(&dev_private->gart_bo->kmap);
+
+		ret = openchrome_bo_unpin(dev_private->gart_bo);
+		ttm_bo_unreserve(&dev_private->gart_bo->ttm_bo);
+		if (ret) {
+			goto exit_gart;
+		}
+
+		ttm_bo_put(&dev_private->gart_bo->ttm_bo);
 	}
 
-	via_mm_fini(dev);
+exit_gart:
+	openchrome_mm_fini(dev_private);
 
 	/*
 	 * Unmap VRAM.
@@ -157,6 +202,7 @@ static int via_driver_load(struct drm_device *dev,
 				unsigned long chipset)
 {
 	struct openchrome_drm_private *dev_private;
+	struct openchrome_bo *bo;
 	int ret = 0;
 
 	DRM_DEBUG_KMS("Entered %s.\n", __func__);
@@ -181,7 +227,7 @@ static int via_driver_load(struct drm_device *dev,
 		goto init_error;
 	}
 
-	ret = via_mm_init(dev_private);
+	ret = openchrome_mm_init(dev_private);
 	if (ret) {
 		DRM_ERROR("Failed to initialize TTM.\n");
 		goto init_error;
@@ -191,34 +237,75 @@ static int via_driver_load(struct drm_device *dev,
 
 	if (pci_is_pcie(dev->pdev)) {
 		/* Allocate GART. */
-		ret = via_ttm_allocate_kernel_buffer(
-						&dev_private->ttm.bdev,
-						SGDMA_MEMORY, 16,
+		ret = openchrome_bo_create(dev,
+						&dev_private->bdev,
+						SGDMA_MEMORY,
+						ttm_bo_type_kernel,
 						TTM_PL_FLAG_VRAM,
-						&dev_private->gart);
-		if (likely(!ret)) {
-			DRM_INFO("Allocated %u KB of DMA memory.\n",
-					SGDMA_MEMORY >> 10);
-		} else {
+						&bo);
+		if (ret) {
 			DRM_ERROR("Failed to allocate DMA memory.\n");
 			goto init_error;
 		}
+
+		ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL);
+		if (ret) {
+			goto init_error;
+		}
+
+		ret = openchrome_bo_pin(bo, TTM_PL_FLAG_VRAM);
+		if (ret) {
+			ttm_bo_unreserve(&bo->ttm_bo);
+			goto init_error;
+		}
+
+		ret = ttm_bo_kmap(&bo->ttm_bo, 0, bo->ttm_bo.num_pages,
+					&bo->kmap);
+		ttm_bo_unreserve(&bo->ttm_bo);
+		if (ret) {
+			goto init_error;
+		}
+
+		dev_private->gart_bo = bo;
+		DRM_INFO("Allocated %u KB of DMA memory.\n",
+				SGDMA_MEMORY >> 10);
 	}
 
 	/* Allocate VQ. (Virtual Queue) */
-	ret = via_ttm_allocate_kernel_buffer(&dev_private->ttm.bdev,
-					VQ_MEMORY, 16,
+	ret = openchrome_bo_create(dev,
+					&dev_private->bdev,
+					VQ_MEMORY,
+					ttm_bo_type_kernel,
 					TTM_PL_FLAG_VRAM,
-					&dev_private->vq);
-	if (likely(!ret)) {
-		DRM_INFO("Allocated %u KB of VQ (Virtual Queue) "
-				"memory.\n", VQ_MEMORY >> 10);
-	} else {
+					&bo);
+	if (ret) {
 		DRM_ERROR("Failed to allocate VQ (Virtual Queue) "
 				"memory.\n");
 		goto init_error;
 	}
 
+	ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL);
+	if (ret) {
+		goto init_error;
+	}
+
+	ret = openchrome_bo_pin(bo, TTM_PL_FLAG_VRAM);
+	if (ret) {
+		ttm_bo_unreserve(&bo->ttm_bo);
+		goto init_error;
+	}
+
+	ret = ttm_bo_kmap(&bo->ttm_bo, 0, bo->ttm_bo.num_pages,
+				&bo->kmap);
+	ttm_bo_unreserve(&bo->ttm_bo);
+	if (ret) {
+		goto init_error;
+	}
+
+	dev_private->vq_bo = bo;
+	DRM_INFO("Allocated %u KB of VQ (Virtual Queue) memory.\n",
+			VQ_MEMORY >> 10);
+
 	via_engine_init(dev);
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
@@ -249,6 +336,35 @@ static void via_driver_lastclose(struct drm_device *dev)
 	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
 }
 
+static int openchrome_drm_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct drm_file *file_priv;
+	struct openchrome_drm_private *dev_private;
+	int ret = -EINVAL;
+
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
+
+	if (vma->vm_pgoff < DRM_FILE_PAGE_OFFSET) {
+		DRM_DEBUG_KMS("VMA Error.\n");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	file_priv = filp->private_data;
+	dev_private = file_priv->minor->dev->dev_private;
+	if (!dev_private) {
+		DRM_DEBUG_KMS("No device private data.\n");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	ret = ttm_bo_mmap(filp, vma, &dev_private->bdev);
+exit:
+	DRM_DEBUG_KMS("ret: %d\n", ret);
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
+	return ret;
+}
+
 static const struct dev_pm_ops openchrome_dev_pm_ops = {
 	.suspend	= openchrome_dev_pm_ops_suspend,
 	.resume		= openchrome_dev_pm_ops_resume,
@@ -259,7 +375,7 @@ static const struct file_operations via_driver_fops = {
 	.open		= drm_open,
 	.release	= drm_release,
 	.unlocked_ioctl = drm_ioctl,
-	.mmap		= ttm_mmap,
+	.mmap		= openchrome_drm_mmap,
 	.poll		= drm_poll,
 	.llseek		= noop_llseek,
 };
@@ -271,11 +387,11 @@ static struct drm_driver via_driver = {
 	.load = via_driver_load,
 	.unload = via_driver_unload,
 	.lastclose = via_driver_lastclose,
-	.gem_open_object = ttm_gem_open_object,
-	.gem_free_object = ttm_gem_free_object,
-	.dumb_create = via_dumb_create,
-	.dumb_map_offset = via_dumb_mmap,
-	.dumb_destroy = gem_dumb_destroy,
+	.gem_free_object_unlocked =
+		openchrome_drm_driver_gem_free_object_unlocked,
+	.dumb_create = openchrome_drm_driver_dumb_create,
+	.dumb_map_offset =
+				openchrome_drm_driver_dumb_map_offset,
 	.ioctls = via_ioctls,
 	.fops = &via_driver_fops,
 	.name = DRIVER_NAME,
diff --git a/drivers/gpu/drm/openchrome/openchrome_drv.h b/drivers/gpu/drm/openchrome/openchrome_drv.h
index e4fc71f3963a..af912336ed57 100644
--- a/drivers/gpu/drm/openchrome/openchrome_drv.h
+++ b/drivers/gpu/drm/openchrome/openchrome_drv.h
@@ -58,6 +58,8 @@
 #define DRIVER_AUTHOR		"OpenChrome Project"
 
 
+#define OPENCHROME_TTM_PL_NUM	2
+
 #define VIA_MM_ALIGN_SIZE	16
 
 #define DRM_FILE_PAGE_OFFSET	(0x100000000ULL >> PAGE_SHIFT)
@@ -96,30 +98,23 @@ struct via_state {
 	struct vga_regset seq_regs[256];
 };
 
-struct via_ttm {
-	struct ttm_bo_device bdev;
-};
-
-struct ttm_heap {
-	struct ttm_buffer_object bo;
-	struct ttm_place busy_placements[TTM_NUM_MEM_TYPES];
-	struct ttm_place placements[TTM_NUM_MEM_TYPES];
-};
-
-struct ttm_gem_object {
-	struct drm_gem_object gem;
-	struct ttm_heap *heap;
+struct openchrome_bo {
+	struct ttm_buffer_object	ttm_bo;
+	struct ttm_bo_kmap_obj		kmap;
+	struct ttm_placement		placement;
+	struct ttm_place		placements[OPENCHROME_TTM_PL_NUM];
+	struct drm_gem_object		gem;
 };
 
 struct via_framebuffer {
-	struct drm_framebuffer fb;
-	struct drm_gem_object *gem_obj;
+	struct drm_framebuffer		fb;
+	struct drm_gem_object		*gem;
 };
 
 struct via_framebuffer_device {
-	struct drm_fb_helper helper;
-	struct ttm_bo_kmap_obj kmap;
-	struct via_framebuffer via_fb;
+	struct drm_fb_helper		helper;
+	struct via_framebuffer		via_fb;
+	struct openchrome_bo		*bo;
 };
 
 enum via_engine {
@@ -133,12 +128,15 @@ enum via_engine {
 struct openchrome_drm_private {
 	struct drm_device *dev;
 
-	struct via_ttm ttm;
+	struct ttm_bo_device		bdev;
+
+	/* Set this flag for ttm_bo_device_init. */
+	bool need_dma32;
 
 	int revision;
 
-	struct ttm_bo_kmap_obj gart;
-	struct ttm_bo_kmap_obj vq;
+	struct openchrome_bo		*gart_bo;
+	struct openchrome_bo		*vq_bo;
 
 	struct via_framebuffer_device *via_fbdev;
 	u8 vram_type;
@@ -260,6 +258,8 @@ extern int via_max_ioctl;
 
 extern int via_hdmi_audio;
 
+extern struct ttm_bo_driver openchrome_bo_driver;
+
 int openchrome_mmio_init(struct openchrome_drm_private *dev_private);
 void openchrome_mmio_fini(struct openchrome_drm_private *dev_private);
 void openchrome_graphics_unlock(
@@ -279,46 +279,19 @@ extern int openchrome_vram_init(
 extern void openchrome_vram_fini(
 			struct openchrome_drm_private *dev_private);
 
-extern int via_mm_init(struct openchrome_drm_private *dev_private);
-void via_mm_fini(struct drm_device *dev);
-extern void ttm_placement_from_domain(struct ttm_buffer_object *bo,
-			struct ttm_placement *placement,
-			u32 domains, struct ttm_bo_device *bdev);
-extern int via_bo_create(struct ttm_bo_device *bdev,
-				struct ttm_buffer_object **p_bo,
-				unsigned long size,
+void openchrome_bo_destroy(struct ttm_buffer_object *tbo);
+void openchrome_ttm_domain_to_placement(struct openchrome_bo *bo,
+					uint32_t ttm_domain);
+int openchrome_bo_create(struct drm_device *dev,
+				struct ttm_bo_device *bdev,
+				uint64_t size,
 				enum ttm_bo_type type,
-				uint32_t domains,
-				uint32_t byte_alignment,
-				uint32_t page_alignment,
-				bool interruptible,
-				struct sg_table *sg,
-				struct reservation_object *resv);
-extern int via_bo_pin(struct ttm_buffer_object *bo,
-				struct ttm_bo_kmap_obj *kmap);
-extern int via_bo_unpin(struct ttm_buffer_object *bo,
-				struct ttm_bo_kmap_obj *kmap);
-extern int via_ttm_allocate_kernel_buffer(struct ttm_bo_device *bdev,
-				unsigned long size,
-				uint32_t alignment, uint32_t domain,
-				struct ttm_bo_kmap_obj *kmap);
-
-
-extern int ttm_mmap(struct file *filp, struct vm_area_struct *vma);
-
-extern int ttm_gem_open_object(struct drm_gem_object *obj,
-				struct drm_file *file_priv);
-extern void ttm_gem_free_object(struct drm_gem_object *obj);
-extern struct drm_gem_object* ttm_gem_create(struct drm_device *dev,
-					struct ttm_bo_device *bdev,
-					unsigned long size,
-					enum ttm_bo_type type,
-					uint32_t domains,
-					uint32_t byte_alignment,
-					uint32_t page_alignment,
-					bool interruptible);
-extern struct ttm_buffer_object* ttm_gem_mapping(
-					struct drm_gem_object *obj);
+				uint32_t ttm_domain,
+				struct openchrome_bo **bo_ptr);
+int openchrome_bo_pin(struct openchrome_bo *bo, uint32_t ttm_domain);
+int openchrome_bo_unpin(struct openchrome_bo *bo);
+int openchrome_mm_init(struct openchrome_drm_private *dev_private);
+void openchrome_mm_fini(struct openchrome_drm_private *dev_private);
 
 void openchrome_transmitter_io_pad_state(
 			struct openchrome_drm_private *dev_private,
diff --git a/drivers/gpu/drm/openchrome/openchrome_fb.c b/drivers/gpu/drm/openchrome/openchrome_fb.c
index ae4191131f37..2b4981ae23ab 100644
--- a/drivers/gpu/drm/openchrome/openchrome_fb.c
+++ b/drivers/gpu/drm/openchrome/openchrome_fb.c
@@ -951,27 +951,35 @@ via_user_framebuffer_create_handle(struct drm_framebuffer *fb,
 					struct drm_file *file_priv,
 					unsigned int *handle)
 {
-	struct via_framebuffer *via_fb =
-						container_of(fb, struct via_framebuffer, fb);
-	struct drm_gem_object *gem_obj = via_fb->gem_obj;
+	struct via_framebuffer *via_fb = container_of(fb,
+					struct via_framebuffer, fb);
+	int ret;
+
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
-	return drm_gem_handle_create(file_priv, gem_obj, handle);
+	ret = drm_gem_handle_create(file_priv, via_fb->gem, handle);
+
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
+	return ret;
 }
 
 static void
 via_user_framebuffer_destroy(struct drm_framebuffer *fb)
 {
-	struct via_framebuffer *via_fb =
-						container_of(fb, struct via_framebuffer, fb);
-	struct drm_gem_object *gem_obj = via_fb->gem_obj;
+	struct via_framebuffer *via_fb = container_of(fb,
+					struct via_framebuffer, fb);
 
-	if (gem_obj) {
-		drm_gem_object_put_unlocked(gem_obj);
-		via_fb->gem_obj = NULL;
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
+
+	if (via_fb->gem) {
+		drm_gem_object_put_unlocked(via_fb->gem);
+		via_fb->gem = NULL;
 	}
 
 	drm_framebuffer_cleanup(fb);
 	kfree(via_fb);
+
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
 }
 
 static const struct drm_framebuffer_funcs via_fb_funcs = {
@@ -993,11 +1001,11 @@ via_user_framebuffer_create(struct drm_device *dev,
 				const struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	struct via_framebuffer *via_fb;
-	struct drm_gem_object *gem_obj;
+	struct drm_gem_object *gem;
 	int ret;
 
-	gem_obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]);
-	if (!gem_obj) {
+	gem = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]);
+	if (!gem) {
 		DRM_ERROR("No GEM object found for handle 0x%08X\n",
 				mode_cmd->handles[0]);
 		return ERR_PTR(-ENOENT);
@@ -1008,12 +1016,13 @@ via_user_framebuffer_create(struct drm_device *dev,
 		return ERR_PTR(-ENOMEM);
 	}
 
-	via_fb->gem_obj = gem_obj;
+	via_fb->gem = gem;
 
 	drm_helper_mode_fill_fb_struct(dev, &via_fb->fb, mode_cmd);
 	ret = drm_framebuffer_init(dev, &via_fb->fb, &via_fb_funcs);
 	if (ret) {
-		drm_gem_object_put(gem_obj);
+		drm_gem_object_put_unlocked(via_fb->gem);
+		via_fb->gem = NULL;
 		kfree(via_fb);
 		return ERR_PTR(ret);
 	}
@@ -1087,15 +1096,15 @@ via_fb_probe(struct drm_fb_helper *helper,
 					helper->dev->dev_private;
 	struct via_framebuffer_device *via_fbdev = container_of(helper,
 				struct via_framebuffer_device, helper);
-	struct ttm_bo_kmap_obj *kmap = &via_fbdev->kmap;
 	struct via_framebuffer *via_fb = &via_fbdev->via_fb;
 	struct drm_framebuffer *fb = &via_fbdev->via_fb.fb;
 	struct fb_info *info = helper->fbdev;
-	struct drm_gem_object *gem_obj;
+	struct openchrome_bo *bo;
 	struct drm_mode_fb_cmd2 mode_cmd;
 	struct apertures_struct *ap;
 	int size, cpp;
 	int ret = 0;
+	int fake_ret = 0;
 
 	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
@@ -1110,24 +1119,36 @@ via_fb_probe(struct drm_fb_helper *helper,
 	size = mode_cmd.pitches[0] * mode_cmd.height;
 	size = ALIGN(size, PAGE_SIZE);
 
-	gem_obj = ttm_gem_create(dev, &dev_private->ttm.bdev, size,
-				ttm_bo_type_kernel, TTM_PL_FLAG_VRAM,
-				1, PAGE_SIZE, false);
-	if (unlikely(IS_ERR(gem_obj))) {
-		ret = PTR_ERR(gem_obj);
+	ret = openchrome_bo_create(dev,
+					&dev_private->bdev,
+					size,
+					ttm_bo_type_kernel,
+					TTM_PL_FLAG_VRAM,
+					&bo);
+	if (ret) {
+		goto exit;
+	}
+
+	ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL);
+	if (ret) {
 		goto out_err;
 	}
 
-	kmap->bo = ttm_gem_mapping(gem_obj);
-	if (!kmap->bo) {
+	ret = openchrome_bo_pin(bo, TTM_PL_FLAG_VRAM);
+	if (ret) {
+		ttm_bo_unreserve(&bo->ttm_bo);
 		goto out_err;
 	}
 
-	ret = via_bo_pin(kmap->bo, kmap);
-	if (unlikely(ret)) {
+	ret = ttm_bo_kmap(&bo->ttm_bo, 0, bo->ttm_bo.num_pages,
+				&bo->kmap);
+	ttm_bo_unreserve(&bo->ttm_bo);
+	if (ret) {
 		goto out_err;
 	}
 
+	via_fbdev->bo = bo;
+
 	info = drm_fb_helper_alloc_fbi(helper);
 	if (IS_ERR(info)) {
 		ret = PTR_ERR(info);
@@ -1143,7 +1164,7 @@ via_fb_probe(struct drm_fb_helper *helper,
 		goto out_err;
 	}
 
-	via_fb->gem_obj = gem_obj;
+	via_fb->gem = &bo->gem;
 	via_fbdev->helper.fb = fb;
 	via_fbdev->helper.fbdev = info;
 
@@ -1152,10 +1173,10 @@ via_fb_probe(struct drm_fb_helper *helper,
 
 	info->fbops = &via_fb_ops;
 
-	info->fix.smem_start = kmap->bo->mem.bus.base +
-				kmap->bo->mem.bus.offset;
+	info->fix.smem_start = bo->kmap.bo->mem.bus.base +
+				bo->kmap.bo->mem.bus.offset;
 	info->fix.smem_len = size;
-	info->screen_base = kmap->virtual;
+	info->screen_base = bo->kmap.virtual;
 	info->screen_size = size;
 
 	/* Setup aperture base / size for takeover (i.e., vesafb). */
@@ -1165,9 +1186,9 @@ via_fb_probe(struct drm_fb_helper *helper,
 		goto out_err;
 	}
 
-	ap->ranges[0].size = kmap->bo->bdev->
-				man[kmap->bo->mem.mem_type].size;
-	ap->ranges[0].base = kmap->bo->mem.bus.base;
+	ap->ranges[0].size = bo->kmap.bo->bdev->
+				man[bo->kmap.bo->mem.mem_type].size;
+	ap->ranges[0].base = bo->kmap.bo->mem.bus.base;
 	info->apertures = ap;
 
 	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
@@ -1175,14 +1196,26 @@ via_fb_probe(struct drm_fb_helper *helper,
 				sizes->fb_width, sizes->fb_height);
 	goto exit;
 out_err:
-	if (kmap->bo) {
-		via_bo_unpin(kmap->bo, kmap);
-		ttm_bo_put(kmap->bo);
+	if (bo->kmap.bo) {
+		fake_ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL);
+		if (fake_ret) {
+			goto exit;
+		}
+
+		ttm_bo_kunmap(&bo->kmap);
+
+		fake_ret = openchrome_bo_unpin(bo);
+		if (fake_ret) {
+			ttm_bo_unreserve(&bo->ttm_bo);
+			goto exit;
+		}
+
+		ttm_bo_put(&bo->ttm_bo);
 	}
 
-	if (gem_obj) {
-		drm_gem_object_put_unlocked(gem_obj);
-		via_fb->gem_obj = NULL;
+	if (via_fb->gem) {
+		drm_gem_object_put_unlocked(via_fb->gem);
+		via_fb->gem = NULL;
 	}
 exit:
 	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
@@ -1264,9 +1297,9 @@ void via_fbdev_fini(struct drm_device *dev)
 		fb_helper->fbdev = NULL;
 	}
 
-	if (via_fb->gem_obj) {
-		drm_gem_object_put_unlocked(via_fb->gem_obj);
-		via_fb->gem_obj = NULL;
+	if (via_fb->gem) {
+		drm_gem_object_put_unlocked(via_fb->gem);
+		via_fb->gem = NULL;
 	}
 
 	drm_fb_helper_fini(&dev_private->via_fbdev->helper);
diff --git a/drivers/gpu/drm/openchrome/openchrome_gem.c b/drivers/gpu/drm/openchrome/openchrome_gem.c
deleted file mode 100644
index bb18f957fe1c..000000000000
--- a/drivers/gpu/drm/openchrome/openchrome_gem.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2012 James Simmons <jsimmons at infradead.org>. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sub license,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#include <drm/drmP.h>
-
-#include "openchrome_drv.h"
-
-/*
- * initialize the gem buffer object
- */
-int ttm_gem_open_object(struct drm_gem_object *obj, struct drm_file *file_priv)
-{
-	return 0;
-}
-
-/*
- * free the gem buffer object
- */
-void ttm_gem_free_object(struct drm_gem_object *obj)
-{
-	struct ttm_gem_object *gem = container_of(obj, struct ttm_gem_object, gem);
-	struct ttm_buffer_object *bo;
-
-	if (gem->heap != NULL) {
-		bo = &gem->heap->bo;
-		ttm_bo_put(bo);
-		gem->heap = NULL;
-	}
-	drm_gem_object_release(obj);
-	kfree(gem);
-}
-
-struct ttm_buffer_object *
-ttm_gem_mapping(struct drm_gem_object *obj)
-{
-	struct ttm_gem_object *gem;
-
-	gem = container_of(obj, struct ttm_gem_object, gem);
-	if (gem->heap == NULL)
-		return NULL;
-	return &gem->heap->bo;
-}
-
-/*
- * file operation mmap
- */
-int ttm_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-	struct openchrome_drm_private *dev_private;
-	struct drm_file *file_priv;
-
-	if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET))
-		return -EINVAL;
-
-	file_priv = filp->private_data;
-	dev_private = file_priv->minor->dev->dev_private;
-	if (!dev_private)
-		return -EINVAL;
-
-	return ttm_bo_mmap(filp, vma, &dev_private->ttm.bdev);
-}
-
-struct drm_gem_object *
-ttm_gem_create(struct drm_device *dev,
-		struct ttm_bo_device *bdev,
-		unsigned long size,
-		enum ttm_bo_type type,
-		uint32_t domains,
-		uint32_t byte_alignment,
-		uint32_t page_alignment,
-		bool interruptible)
-{
-	struct ttm_buffer_object *bo = NULL;
-	struct ttm_gem_object *obj;
-	int ret;
-
-	obj = kzalloc(sizeof(struct ttm_gem_object), GFP_KERNEL);
-	if (!obj) {
-		return ERR_PTR(-ENOMEM);
-	}
-
-	size = round_up(size, byte_alignment);
-	size = ALIGN(size, page_alignment);
-	ret = via_bo_create(bdev, &bo, size, type, domains,
-				byte_alignment, page_alignment,
-				interruptible, NULL, NULL);
-	if (ret) {
-		DRM_ERROR("Failed to create buffer object\n");
-		return ERR_PTR(ret);
-	}
-
-	ret = drm_gem_object_init(dev, &obj->gem, size);
-	if (unlikely(ret)) {
-		ttm_bo_put(bo);
-		return ERR_PTR(ret);
-	}
-
-	obj->heap = container_of(bo, struct ttm_heap, bo);
-	bo->persistent_swap_storage = obj->gem.filp;
-	return &obj->gem;
-}
diff --git a/drivers/gpu/drm/openchrome/openchrome_init.c b/drivers/gpu/drm/openchrome/openchrome_init.c
index 6bcd434a464f..9b5aaef09640 100644
--- a/drivers/gpu/drm/openchrome/openchrome_init.c
+++ b/drivers/gpu/drm/openchrome/openchrome_init.c
@@ -259,6 +259,9 @@ void openchrome_flag_init(struct openchrome_drm_private *dev_private)
 {
 	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
+	/* Set this flag for ttm_bo_device_init. */
+	dev_private->need_dma32 = true;
+
 	/*
 	 * Special handling flags for a few special models.
 	 */
@@ -453,18 +456,18 @@ static void via_init_vq(struct openchrome_drm_private *dev_private)
 {
 	unsigned long vq_start_addr, vq_end_addr, vqlen;
 	unsigned long vqstartl, vqendl, vqstart_endh;
-	struct ttm_buffer_object *bo = dev_private->vq.bo;
+	struct openchrome_bo *bo = dev_private->vq_bo;
 
-	if (!bo)
+	if (!bo->kmap.bo)
 		return;
 
-	vq_start_addr = bo->offset;
-	vq_end_addr = vq_start_addr + bo->mem.size - 1;
+	vq_start_addr = bo->kmap.bo->offset;
+	vq_end_addr = vq_start_addr + bo->kmap.bo->mem.size - 1;
 	vqstartl = 0x70000000 | (vq_start_addr & 0xFFFFFF);
 	vqendl = 0x71000000 | (vq_end_addr & 0xFFFFFF);
 	vqstart_endh = 0x72000000 | ((vq_start_addr & 0xFF000000) >> 24) |
 			((vq_end_addr & 0xFF000000) >> 16);
-	vqlen = 0x73000000 | (bo->mem.size >> 3);
+	vqlen = 0x73000000 | (bo->kmap.bo->mem.size >> 3);
 
 	VIA_WRITE(0x41c, 0x00100000);
 	VIA_WRITE(0x420, vqstart_endh);
@@ -479,24 +482,24 @@ static void via_init_pcie_gart_table(
 			struct openchrome_drm_private *dev_private,
 			struct pci_dev *pdev)
 {
-	struct ttm_buffer_object *bo = dev_private->gart.bo;
+	struct openchrome_bo *bo = dev_private->gart_bo;
 	u8 value;
 
-	if (!pci_is_pcie(pdev) || !bo)
+	if (!pci_is_pcie(pdev) || !bo->kmap.bo)
 		return;
 
 	/* enable gtt write */
 	svga_wseq_mask(VGABASE, 0x6C, 0x00, BIT(7));
 
 	/* set the base address of gart table */
-	value = (bo->offset & 0xff000) >> 12;
+	value = (bo->kmap.bo->offset & 0xff000) >> 12;
 	vga_wseq(VGABASE, 0x6A, value);
 
-	value = (bo->offset & 0xff000) >> 20;
+	value = (bo->kmap.bo->offset & 0xff000) >> 20;
 	vga_wseq(VGABASE, 0x6B, value);
 
 	value = vga_rseq(VGABASE, 0x6C);
-	value |= ((bo->offset >> 28) & 0x01);
+	value |= ((bo->kmap.bo->offset >> 28) & 0x01);
 	vga_wseq(VGABASE, 0x6C, value);
 
 	/* flush the gtt cache */
diff --git a/drivers/gpu/drm/openchrome/openchrome_ioc32.c b/drivers/gpu/drm/openchrome/openchrome_ioc32.c
index 4675249118c0..42bc54238da4 100644
--- a/drivers/gpu/drm/openchrome/openchrome_ioc32.c
+++ b/drivers/gpu/drm/openchrome/openchrome_ioc32.c
@@ -63,102 +63,132 @@ static int
 via_gem_alloc(struct drm_device *dev, void *data,
 		struct drm_file *filp)
 {
-	struct openchrome_drm_private *dev_private = dev->dev_private;
 	struct drm_via_gem_object *args = data;
-	struct drm_gem_object *obj;
-	int ret = -ENOMEM;
-
-	obj = ttm_gem_create(dev, &dev_private->ttm.bdev, args->size,
-				ttm_bo_type_device, args->domains,
-				args->alignment, PAGE_SIZE, false);
-	if (obj != NULL) {
-		ret = drm_gem_handle_create(filp, obj, &args->handle);
-		/* drop reference from allocate - handle holds it now */
-		drm_gem_object_put_unlocked(obj);
-		if (!ret) {
-			struct ttm_buffer_object *bo = ttm_gem_mapping(obj);
+	struct openchrome_drm_private *dev_private = dev->dev_private;
+	struct openchrome_bo *bo;
+	uint32_t handle;
+	int ret;
 
-			args->map_handle = drm_vma_node_offset_addr(&bo->vma_node);
-			args->domains = bo->mem.placement & TTM_PL_MASK_MEM;
-			args->offset = bo->offset;
-			args->size = bo->mem.size;
-			args->version = 1;
-		}
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
+
+	ret = openchrome_bo_create(dev,
+					&dev_private->bdev,
+					args->size,
+					ttm_bo_type_device,
+					args->domains,
+					&bo);
+
+	if (ret) {
+		goto exit;
+	}
+
+	ret = drm_gem_handle_create(filp, &bo->gem,
+					&handle);
+
+	/* Drop reference from allocate; handle holds it now. */
+	drm_gem_object_put_unlocked(&bo->gem);
+
+	if (ret) {
+		ttm_bo_put(&bo->ttm_bo);
+		goto exit;
 	}
+
+	args->size		= bo->ttm_bo.mem.size;
+	args->domains		= bo->ttm_bo.mem.placement &
+						TTM_PL_MASK_MEM;
+	args->offset		= bo->ttm_bo.offset;
+	args->map_handle	= drm_vma_node_offset_addr(
+						&bo->ttm_bo.vma_node);
+	args->handle		= handle;
+	args->version		= 1;
+
+exit:
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
 	return ret;
 }
 
 static int
 via_gem_state(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
-	struct drm_via_gem_object *args = data;
-	struct ttm_buffer_object *bo = NULL;
-	struct drm_gem_object *obj = NULL;
-	struct ttm_placement placement;
 	struct ttm_operation_ctx ctx = {.interruptible = false,
 					.no_wait_gpu = false};
+	struct drm_gem_object *gem;
+	struct drm_via_gem_object *args = data;
+	struct openchrome_bo *bo;
 	int ret = -EINVAL;
 
-	obj = drm_gem_object_lookup(file_priv, args->handle);
-	if (obj == NULL)
-		return ret;
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
+
+	gem = drm_gem_object_lookup(file_priv, args->handle);
+	if (!gem) {
+		goto exit;
+	}
 
-	bo = ttm_gem_mapping(obj);
-	if (bo == NULL)
-		return ret;
+	bo = container_of(gem, struct openchrome_bo, gem);
 
 	/* Don't bother to migrate to same domain */
-	args->domains &= ~(bo->mem.placement & TTM_PL_MASK_MEM);
+	args->domains &= ~(bo->ttm_bo.mem.placement & TTM_PL_MASK_MEM);
 	if (args->domains) {
-		ret = ttm_bo_reserve(bo, true, false, NULL);
-		if (unlikely(ret))
-			return ret;
+		ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL);
+		if (ret) {
+			goto exit;
+		}
 
-		ttm_placement_from_domain(bo, &placement, args->domains, bo->bdev);
-		ret = ttm_bo_validate(bo, &placement, &ctx);
-		ttm_bo_unreserve(bo);
+		openchrome_ttm_domain_to_placement(bo, args->domains);
+		ret = ttm_bo_validate(&bo->ttm_bo, &bo->placement,
+					&ctx);
+		ttm_bo_unreserve(&bo->ttm_bo);
 
 		if (!ret) {
-			args->map_handle = drm_vma_node_offset_addr(&bo->vma_node);
-			args->domains = bo->mem.placement & TTM_PL_MASK_MEM;
-			args->offset = bo->offset;
-			args->size = bo->mem.size;
+			args->size = bo->ttm_bo.mem.size;
+			args->domains = bo->ttm_bo.mem.placement &
+						TTM_PL_MASK_MEM;
+			args->offset = bo->ttm_bo.offset;
+			args->map_handle = drm_vma_node_offset_addr(
+						&bo->ttm_bo.vma_node);
 		}
 	}
+
 	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_put(obj);
+	drm_gem_object_put(gem);
 	mutex_unlock(&dev->struct_mutex);
+exit:
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
 	return ret;
 }
 
 static int
 via_gem_wait(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
+	struct drm_gem_object *gem;
 	struct drm_via_gem_wait *args = data;
-	struct ttm_buffer_object *bo;
-	struct drm_gem_object *obj;
+	struct openchrome_bo *bo;
 	int ret = -EINVAL;
 	bool no_wait;
 
-	obj = drm_gem_object_lookup(file_priv, args->handle);
-	if (obj == NULL)
-		return ret;
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
-	bo = ttm_gem_mapping(obj);
-	if (bo == NULL)
-		return ret;
+	gem = drm_gem_object_lookup(file_priv, args->handle);
+	if (!gem) {
+		goto exit;
+	}
+
+	bo = container_of(gem, struct openchrome_bo, gem);
 
 	no_wait = (args->no_wait != 0);
-	ret = ttm_bo_reserve(bo, true, no_wait, NULL);
-	if (unlikely(ret != 0))
-		return ret;
+	ret = ttm_bo_reserve(&bo->ttm_bo, true, no_wait, NULL);
+	if (ret) {
+		goto exit;
+	}
 
-	ret = ttm_bo_wait(bo, true, no_wait);
-	ttm_bo_unreserve(bo);
+	ret = ttm_bo_wait(&bo->ttm_bo, true, no_wait);
+	ttm_bo_unreserve(&bo->ttm_bo);
 
 	mutex_lock(&dev->struct_mutex);
-	drm_gem_object_put(obj);
+	drm_gem_object_put(gem);
 	mutex_unlock(&dev->struct_mutex);
+exit:
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/openchrome/openchrome_object.c b/drivers/gpu/drm/openchrome/openchrome_object.c
new file mode 100644
index 000000000000..2cd8d2ebe195
--- /dev/null
+++ b/drivers/gpu/drm/openchrome/openchrome_object.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright © 2018-2019 Kevin Brace
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including
+ * the next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * Author(s):
+ *
+ * Kevin Brace <kevinbrace at gmx.com>
+ */
+/*
+ * openchrome_object.c
+ *
+ * Manages Buffer Objects (BO) via TTM.
+ * Part of the TTM memory allocator.
+ *
+ */
+
+#include <drm/ttm/ttm_bo_api.h>
+#include <drm/ttm/ttm_bo_driver.h>
+
+#include "openchrome_drv.h"
+
+
+void openchrome_bo_destroy(struct ttm_buffer_object *tbo)
+{
+	struct openchrome_bo *bo = container_of(tbo,
+					struct openchrome_bo, ttm_bo);
+
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
+
+	drm_gem_object_release(&bo->gem);
+	kfree(bo);
+
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
+}
+
+void openchrome_ttm_domain_to_placement(struct openchrome_bo *bo,
+					uint32_t ttm_domain)
+{
+	unsigned i = 0;
+
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
+
+	bo->placement.placement = bo->placements;
+	bo->placement.busy_placement = bo->placements;
+
+	if (ttm_domain & TTM_PL_FLAG_SYSTEM) {
+		bo->placements[i].fpfn = 0;
+		bo->placements[i].lpfn = 0;
+		bo->placements[i].flags = TTM_PL_FLAG_CACHED |
+						TTM_PL_FLAG_SYSTEM;
+		i++;
+	}
+
+	if (ttm_domain & TTM_PL_FLAG_TT) {
+		bo->placements[i].fpfn = 0;
+		bo->placements[i].lpfn = 0;
+		bo->placements[i].flags = TTM_PL_FLAG_CACHED |
+						TTM_PL_FLAG_TT;
+		i++;
+	}
+
+	if (ttm_domain & TTM_PL_FLAG_VRAM) {
+		bo->placements[i].fpfn = 0;
+		bo->placements[i].lpfn = 0;
+		bo->placements[i].flags = TTM_PL_FLAG_WC |
+						TTM_PL_FLAG_UNCACHED |
+						TTM_PL_FLAG_VRAM;
+		i++;
+	}
+
+	bo->placement.num_placement = i;
+	bo->placement.num_busy_placement = i;
+
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
+}
+
+int openchrome_bo_create(struct drm_device *dev,
+				struct ttm_bo_device *bdev,
+				uint64_t size,
+				enum ttm_bo_type type,
+				uint32_t ttm_domain,
+				struct openchrome_bo **bo_ptr)
+{
+	struct openchrome_drm_private *dev_private = dev->dev_private;
+	struct openchrome_bo *bo;
+	size_t acc_size;
+	int ret;
+
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
+
+//	bo = kzalloc(sizeof(struct openchrome_bo), GFP_KERNEL);
+	bo = kzalloc(sizeof(*bo), GFP_KERNEL);
+	if (!bo) {
+		DRM_ERROR("Cannot allocate a TTM buffer object.\n");
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	size = ALIGN(size, PAGE_SIZE);
+	openchrome_ttm_domain_to_placement(bo, ttm_domain);
+	acc_size = ttm_bo_dma_acc_size(&dev_private->bdev, size,
+					sizeof(struct openchrome_bo));
+	ret = ttm_bo_init(&dev_private->bdev,
+				&bo->ttm_bo,
+				size,
+				type,
+				&bo->placement,
+				PAGE_SIZE, false, acc_size,
+				NULL, NULL,
+				openchrome_bo_destroy);
+	if (ret) {
+		DRM_ERROR("Cannot initialize a TTM object.\n");
+		goto error;
+	}
+
+	ret = drm_gem_object_init(dev, &bo->gem, size);
+	if (ret) {
+		ttm_bo_put(&bo->ttm_bo);
+		DRM_ERROR("Cannot initialize a GEM object.\n");
+		goto error;
+	}
+
+	*bo_ptr = bo;
+	goto exit;
+error:
+	kfree(bo);
+exit:
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
+	return ret;
+}
+
+int openchrome_bo_pin(struct openchrome_bo *bo,
+			uint32_t ttm_domain)
+{
+	struct ttm_operation_ctx ctx = {false, false};
+	uint32_t i;
+	int ret;
+
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
+
+	openchrome_ttm_domain_to_placement(bo, ttm_domain);
+	for (i = 0; i < bo->placement.num_placement; i++) {
+		bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
+	}
+
+	ret = ttm_bo_validate(&bo->ttm_bo, &bo->placement, &ctx);
+
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
+	return ret;
+}
+
+int openchrome_bo_unpin(struct openchrome_bo *bo)
+{
+	struct ttm_operation_ctx ctx = {false, false};
+	uint32_t i;
+	int ret;
+
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
+
+	for (i = 0; i < bo->placement.num_placement; i++) {
+		bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
+	}
+
+	ret = ttm_bo_validate(&bo->ttm_bo, &bo->placement, &ctx);
+
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
+	return ret;
+}
+
+int openchrome_mm_init(struct openchrome_drm_private *dev_private)
+{
+	struct drm_device *dev = dev_private->dev;
+	int ret;
+
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
+
+	/*
+	 * Initialize bdev ttm_bo_device struct.
+	 */
+	ret = ttm_bo_device_init(&dev_private->bdev,
+				&openchrome_bo_driver,
+				dev->anon_inode->i_mapping,
+				DRM_FILE_PAGE_OFFSET,
+				dev_private->need_dma32);
+	if (ret) {
+		DRM_ERROR("Failed initializing buffer object driver.\n");
+		goto exit;
+	}
+
+	/*
+	 * Initialize TTM memory manager for VRAM management.
+	 */
+	ret = ttm_bo_init_mm(&dev_private->bdev, TTM_PL_VRAM,
+				dev_private->vram_size >> PAGE_SHIFT);
+	if (ret) {
+		DRM_ERROR("Failed initializing TTM VRAM memory manager.\n");
+		goto exit;
+	}
+
+exit:
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
+	return ret;
+}
+
+void openchrome_mm_fini(struct openchrome_drm_private *dev_private)
+{
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
+
+	ttm_bo_device_release(&dev_private->bdev);
+
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
+}
diff --git a/drivers/gpu/drm/openchrome/openchrome_ttm.c b/drivers/gpu/drm/openchrome/openchrome_ttm.c
index 8baf1fce55ee..9a4bfdf4c86f 100644
--- a/drivers/gpu/drm/openchrome/openchrome_ttm.c
+++ b/drivers/gpu/drm/openchrome/openchrome_ttm.c
@@ -1,386 +1,173 @@
 /*
- * Copyright 2012 James Simmons <jsimmons at infradead.org>. All Rights Reserved.
+ * Copyright © 2018-2019 Kevin Brace
  *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sub license,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
+ * The above copyright notice and this permission notice (including
+ * the next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
+/*
+ * Author(s):
+ *
+ * Kevin Brace <kevinbrace at gmx.com>
+ */
+/*
+ * openchrome_ttm.c
+ *
+ * TTM code as part of the TTM memory allocator.
+ * Currently a basic implementation with no DMA support.
+ *
+ */
 
-#include <linux/dma-mapping.h>
-#ifdef CONFIG_SWIOTLB
-#include <linux/swiotlb.h>
-#endif
 
 #include "openchrome_drv.h"
 
 
-#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
-
-static void via_ttm_bo_destroy(struct ttm_buffer_object *bo)
+static int openchrome_bo_init_mem_type(struct ttm_bo_device *bdev,
+				uint32_t type,
+				struct ttm_mem_type_manager *man)
 {
-	struct ttm_heap *heap = container_of(bo, struct ttm_heap, bo);
+	int ret = 0;
 
-	kfree(heap);
-	heap = NULL;
-}
-
-static int via_invalidate_caches(struct ttm_bo_device *bdev,
-					uint32_t flags)
-{
-	/*
-	 * FIXME: Invalidate texture caches here.
-	 */
-	return 0;
-}
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
-static int via_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
-				struct ttm_mem_type_manager *man)
-{
 	switch (type) {
 	case TTM_PL_SYSTEM:
-		/* System memory */
 		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
-		man->available_caching = TTM_PL_MASK_CACHING;
+		man->available_caching = TTM_PL_FLAG_CACHED;
 		man->default_caching = TTM_PL_FLAG_CACHED;
 		break;
-
-	case TTM_PL_TT:
-		man->func = &ttm_bo_manager_func;
-
-		/* By default we handle PCI/PCIe DMA. */
-		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
-				TTM_MEMTYPE_FLAG_CMA;
-		man->available_caching = TTM_PL_MASK_CACHING;
-		man->default_caching = TTM_PL_FLAG_CACHED;
-		break;
-
 	case TTM_PL_VRAM:
-		/* "On-card" video ram */
-		man->func = &ttm_bo_manager_func;
 		man->flags = TTM_MEMTYPE_FLAG_FIXED |
 				TTM_MEMTYPE_FLAG_MAPPABLE;
+		man->gpu_offset = 0;
 		man->available_caching = TTM_PL_FLAG_UNCACHED |
 						TTM_PL_FLAG_WC;
 		man->default_caching = TTM_PL_FLAG_WC;
-		/* The display base address does not always equal the start of
-		 * the memory region of the VRAM. In our case it is */
-		man->gpu_offset = 0;
-		break;
-
-	case TTM_PL_PRIV:
-		/* MMIO region */
 		man->func = &ttm_bo_manager_func;
-		man->flags = TTM_MEMTYPE_FLAG_FIXED |
-				TTM_MEMTYPE_FLAG_MAPPABLE;
-		man->available_caching = TTM_PL_FLAG_UNCACHED;
-		man->default_caching = TTM_PL_FLAG_UNCACHED;
 		break;
-
 	default:
-		DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static void via_evict_flags(struct ttm_buffer_object *bo,
-				struct ttm_placement *placement)
-{
-	switch (bo->mem.mem_type) {
-	case TTM_PL_VRAM:
-		ttm_placement_from_domain(bo, placement,
-				TTM_PL_FLAG_TT | TTM_PL_FLAG_SYSTEM,
-				bo->bdev);
-		break;
-
-	case TTM_PL_TT:
-	default:
-		ttm_placement_from_domain(bo, placement,
-						TTM_PL_FLAG_SYSTEM,
-						bo->bdev);
-		break;
-	}
-}
-
-static int via_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
-					struct ttm_mem_reg *mem)
-{
-	struct openchrome_drm_private *dev_private =
-					container_of(bdev,
-					struct openchrome_drm_private,
-					ttm.bdev);
-	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
-	struct drm_device *dev = dev_private->dev;
-
-	mem->bus.base = 0;
-	mem->bus.addr = NULL;
-	mem->bus.offset = mem->start << PAGE_SHIFT;
-	mem->bus.size = mem->num_pages << PAGE_SHIFT;
-	mem->bus.is_iomem = true;
-	if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
-		return -EINVAL;
-
-	switch (mem->mem_type) {
-	case TTM_PL_SYSTEM:
-		/* system memory */
-		mem->bus.is_iomem = false;
-		mem->bus.offset = 0;
-		return 0;
-
-	case TTM_PL_TT:
+		DRM_ERROR("Unsupported TTM memory type.\n");
+		ret = -EINVAL;
 		break;
-
-	case TTM_PL_PRIV:
-		mem->bus.base = pci_resource_start(dev->pdev, 1);
-		break;
-
-	case TTM_PL_VRAM:
-		if (dev->pdev->device == PCI_DEVICE_ID_VIA_VX900_VGA)
-			mem->bus.base = pci_resource_start(dev->pdev, 2);
-		else
-			mem->bus.base = pci_resource_start(dev->pdev, 0);
-		break;
-
-	default:
-		return -EINVAL;
 	}
-	return 0;
-}
 
-static void via_ttm_io_mem_free(struct ttm_bo_device *bdev,
-				struct ttm_mem_reg *mem)
-{
-}
-
-static int via_verify_access(struct ttm_buffer_object *bo,
-				struct file *filp)
-{
-	return 0;
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
+	return ret;
 }
 
-static struct ttm_bo_driver via_bo_driver = {
-	.invalidate_caches	= via_invalidate_caches,
-	.init_mem_type		= via_init_mem_type,
-	.evict_flags		= via_evict_flags,
-	.verify_access		= via_verify_access,
-	.io_mem_reserve		= via_ttm_io_mem_reserve,
-	.io_mem_free		= via_ttm_io_mem_free,
-};
-
-int via_mm_init(struct openchrome_drm_private *dev_private)
+static void openchrome_bo_evict_flags(struct ttm_buffer_object *bo,
+					struct ttm_placement *placement)
 {
-	struct drm_device *dev = dev_private->dev;
-	int ret;
+	struct openchrome_bo *driver_bo = container_of(bo,
+					struct openchrome_bo, ttm_bo);
 
 	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
-	dev_private->ttm.bdev.dev_mapping = dev->anon_inode->i_mapping;
-
-	ret = ttm_bo_device_init(&dev_private->ttm.bdev,
-				&via_bo_driver,
-				dev->anon_inode->i_mapping,
-				DRM_FILE_PAGE_OFFSET,
-				false);
-	if (ret) {
-		DRM_ERROR("Error initialising bo driver: %d\n", ret);
+	if (bo->destroy == &openchrome_bo_destroy) {
 		goto exit;
 	}
 
-	ret = ttm_bo_init_mm(&dev_private->ttm.bdev, TTM_PL_VRAM,
-				dev_private->vram_size >> PAGE_SHIFT);
-	if (ret) {
-		DRM_ERROR("Failed to map video RAM: %d\n", ret);
-		goto exit;
+	switch (bo->mem.mem_type) {
+	case TTM_PL_VRAM:
+		openchrome_ttm_domain_to_placement(driver_bo,
+						TTM_PL_FLAG_VRAM);
+		break;
+	default:
+		openchrome_ttm_domain_to_placement(driver_bo,
+						TTM_PL_FLAG_SYSTEM);
+		break;
 	}
 
+	*placement = driver_bo->placement;
 exit:
 	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
-	return ret;
 }
 
-void via_mm_fini(struct drm_device *dev)
+static int openchrome_bo_verify_access(struct ttm_buffer_object *bo,
+					struct file *filp)
 {
-	struct openchrome_drm_private *dev_private = dev->dev_private;
-
 	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
-	ttm_bo_device_release(&dev_private->ttm.bdev);
-
 	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
+	return 0;
 }
 
-/*
- * the buffer object domain
- */
-void ttm_placement_from_domain(struct ttm_buffer_object *bo,
-				struct ttm_placement *placement,
-				u32 domains,
-				struct ttm_bo_device *bdev)
-{
-	struct ttm_heap *heap = container_of(bo, struct ttm_heap, bo);
-	int cnt = 0, i = 0;
-
-	if (!(domains & TTM_PL_MASK_MEM))
-		domains = TTM_PL_FLAG_SYSTEM;
-
-	do {
-		int domain = (domains & (1 << i));
-
-		if (domain) {
-			heap->busy_placements[cnt].flags =
-				(domain | bdev->man[i].default_caching);
-			heap->busy_placements[cnt].fpfn =
-				heap->busy_placements[cnt].lpfn = 0;
-			heap->placements[cnt].flags =
-				(domain | bdev->man[i].available_caching);
-			heap->placements[cnt].fpfn =
-				heap->placements[cnt].lpfn = 0;
-			cnt++;
-		}
-	} while (i++ < TTM_NUM_MEM_TYPES);
-
-	placement->num_busy_placement = placement->num_placement = cnt;
-	placement->busy_placement = heap->busy_placements;
-	placement->placement = heap->placements;
-}
-
-int via_bo_create(struct ttm_bo_device *bdev,
-			struct ttm_buffer_object **p_bo,
-			unsigned long size,
-			enum ttm_bo_type type,
-			uint32_t domains,
-			uint32_t byte_alignment,
-			uint32_t page_alignment,
-			bool interruptible,
-			struct sg_table *sg,
-			struct reservation_object *resv)
+static int openchrome_bo_io_mem_reserve(struct ttm_bo_device *bdev,
+					struct ttm_mem_reg *mem)
 {
-	struct ttm_buffer_object *bo = NULL;
-	struct ttm_placement placement;
-	struct ttm_heap *heap;
-	size_t acc_size;
-	int ret = -ENOMEM;
+	struct openchrome_drm_private *dev_private = container_of(bdev,
+					struct openchrome_drm_private, bdev);
+	struct drm_device *dev = dev_private->dev;
+	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
+	int ret = 0;
 
 	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
-	size = round_up(size, byte_alignment);
-	size = ALIGN(size, page_alignment);
-
-	heap = kzalloc(sizeof(struct ttm_heap), GFP_KERNEL);
-	if (unlikely(!heap)) {
-		DRM_ERROR("Failed to allocate kernel memory.");
+	if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) {
+		ret= -EINVAL;
 		goto exit;
 	}
 
-	bo = &heap->bo;
-
-	ttm_placement_from_domain(bo, &placement, domains, bdev);
-
-	acc_size = ttm_bo_dma_acc_size(bdev, size,
-					sizeof(struct ttm_heap));
-
-	ret = ttm_bo_init(bdev, bo, size, type, &placement,
-				page_alignment >> PAGE_SHIFT,
-				interruptible, acc_size,
-				sg, NULL, via_ttm_bo_destroy);
+	switch (mem->mem_type) {
+	case TTM_PL_SYSTEM:
+		mem->bus.addr = NULL;
+		mem->bus.base = 0;
+		mem->bus.size = mem->num_pages << PAGE_SHIFT;
+		mem->bus.offset = 0;
+		mem->bus.is_iomem = false;
+		break;
+	case TTM_PL_VRAM:
+		mem->bus.addr = NULL;
+		if (dev->pdev->device == PCI_DEVICE_ID_VIA_VX900_VGA) {
+			mem->bus.base = pci_resource_start(dev->pdev, 2);
+		} else {
+			mem->bus.base = pci_resource_start(dev->pdev, 0);
+		}
 
-	if (unlikely(ret)) {
-		DRM_ERROR("Failed to initialize a TTM Buffer Object.");
-		goto error;
+		mem->bus.size = mem->num_pages << PAGE_SHIFT;
+		mem->bus.offset = mem->start << PAGE_SHIFT;
+		mem->bus.is_iomem = true;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
 	}
 
-	*p_bo = bo;
-	goto exit;
-error:
-	kfree(heap);
 exit:
 	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
 	return ret;
 }
 
-int via_bo_pin(struct ttm_buffer_object *bo,
-		struct ttm_bo_kmap_obj *kmap)
-{
-	struct ttm_heap *heap = container_of(bo, struct ttm_heap, bo);
-	struct ttm_placement placement;
-	struct ttm_operation_ctx ctx = {
-					.interruptible = false,
-					.no_wait_gpu = false
-					};
-	int ret;
-
-	ret = ttm_bo_reserve(bo, true, false, NULL);
-	if (!ret) {
-		placement.placement = heap->placements;
-		placement.num_placement = 1;
-
-		heap->placements[0].flags = (bo->mem.placement | TTM_PL_FLAG_NO_EVICT);
-		ret = ttm_bo_validate(bo, &placement, &ctx);
-		if (!ret && kmap)
-			ret = ttm_bo_kmap(bo, 0, bo->num_pages, kmap);
-		ttm_bo_unreserve(bo);
-	}
-	return ret;
-}
-
-int via_bo_unpin(struct ttm_buffer_object *bo,
-			struct ttm_bo_kmap_obj *kmap)
+static void openchrome_bo_io_mem_free(struct ttm_bo_device *bdev,
+					struct ttm_mem_reg *mem)
 {
-	struct ttm_heap *heap = container_of(bo, struct ttm_heap, bo);
-	struct ttm_placement placement;
-	struct ttm_operation_ctx ctx = {
-					.interruptible = false,
-					.no_wait_gpu = false
-					};
-	int ret;
-
-	ret = ttm_bo_reserve(bo, true, false, NULL);
-	if (!ret) {
-		if (kmap)
-			ttm_bo_kunmap(kmap);
-
-		placement.placement = heap->placements;
-		placement.num_placement = 1;
+	DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
-		heap->placements[0].flags = (bo->mem.placement & ~TTM_PL_FLAG_NO_EVICT);
-		ret = ttm_bo_validate(bo, &placement, &ctx);
-		ttm_bo_unreserve(bo);
-	}
-	return ret;
+	DRM_DEBUG_KMS("Exiting %s.\n", __func__);
 }
 
-int via_ttm_allocate_kernel_buffer(struct ttm_bo_device *bdev,
-					unsigned long size,
-					uint32_t alignment,
-					uint32_t domain,
-					struct ttm_bo_kmap_obj *kmap)
-{
-	int ret = via_bo_create(bdev, &kmap->bo, size,
-				ttm_bo_type_kernel, domain,
-				alignment, PAGE_SIZE,
-				false, NULL, NULL);
-	if (likely(!ret)) {
-		ret = via_bo_pin(kmap->bo, kmap);
-		if (unlikely(ret)) {
-			DRM_ERROR("failed to mmap the buffer\n");
-			ttm_bo_put(kmap->bo);
-			kmap->bo = NULL;
-		}
-	}
-	return ret;
-}
+struct ttm_bo_driver openchrome_bo_driver = {
+	.init_mem_type = openchrome_bo_init_mem_type,
+	.eviction_valuable = ttm_bo_eviction_valuable,
+	.evict_flags = openchrome_bo_evict_flags,
+	.verify_access = openchrome_bo_verify_access,
+	.io_mem_reserve = openchrome_bo_io_mem_reserve,
+	.io_mem_free = openchrome_bo_io_mem_free,
+};


More information about the openchrome-devel mailing list