[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