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 <kevinbr...@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 <kevinbr...@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 <kevinbr...@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 <kevinbr...@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 <jsimm...@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 <kevinbr...@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 <jsimm...@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 <kevinbr...@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,
+};
_______________________________________________
openchrome-devel mailing list
openchrome-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/openchrome-devel

Reply via email to