summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/drm.h70
-rw-r--r--shared-core/i915_dma.c49
-rw-r--r--shared-core/i915_drv.h1
-rw-r--r--shared-core/i915_init.c9
4 files changed, 78 insertions, 51 deletions
diff --git a/shared-core/drm.h b/shared-core/drm.h
index d609fdda..5c8acfa6 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -675,6 +675,14 @@ struct drm_fence_arg {
*/
/*
+ * Mask: Never evict this buffer. Not even with force. This type of buffer is only
+ * available to root and must be manually removed before buffer manager shutdown
+ * or lock.
+ * Flags: Acknowledge
+ */
+#define DRM_BO_FLAG_NO_EVICT (1ULL << 4)
+
+/*
* Mask: Require that the buffer is placed in mappable memory when validated.
* If not set the buffer may or may not be in mappable memory when validated.
* Flags: If set, the buffer is in mappable memory.
@@ -716,6 +724,7 @@ struct drm_fence_arg {
* Flags: Acknowledge.
*/
#define DRM_BO_FLAG_FORCE_MAPPABLE (1ULL << 14)
+#define DRM_BO_FLAG_TILE (1ULL << 15)
/*
* Memory type flags that can be or'ed together in the mask, but only
@@ -748,11 +757,11 @@ struct drm_fence_arg {
/* Don't place this buffer on the unfenced list.*/
#define DRM_BO_HINT_DONT_FENCE 0x00000004
#define DRM_BO_HINT_WAIT_LAZY 0x00000008
-#define DRM_BO_HINT_ALLOW_UNFENCED_MAP 0x00000010
#define DRM_BO_INIT_MAGIC 0xfe769812
-#define DRM_BO_INIT_MAJOR 0
-#define DRM_BO_INIT_MINOR 1
+#define DRM_BO_INIT_MAJOR 1
+#define DRM_BO_INIT_MINOR 0
+#define DRM_BO_INIT_PATCH 0
struct drm_bo_info_req {
@@ -761,6 +770,8 @@ struct drm_bo_info_req {
unsigned int handle;
unsigned int hint;
unsigned int fence_class;
+ unsigned int desired_tile_stride;
+ unsigned int tile_info;
unsigned int pad64;
};
@@ -772,27 +783,6 @@ struct drm_bo_create_req {
unsigned int page_alignment;
};
-struct drm_bo_op_req {
- enum {
- drm_bo_validate,
- drm_bo_fence,
- drm_bo_ref_fence,
- } op;
- unsigned int arg_handle;
- struct drm_bo_info_req bo_req;
-};
-
-struct drm_bo_set_pin_req {
- /** Buffer object ID */
- unsigned int handle;
- /**
- * - 0: Unpin the given buffer object.
- * - 1: Pin the given buffer object, requiring that its offset and
- * memory area stay constant until unpin. The intended use is for
- * scanout buffers.
- */
- unsigned int pin;
-};
/*
* Reply flags
@@ -849,6 +839,17 @@ struct drm_bo_map_wait_idle_arg {
} d;
};
+struct drm_bo_op_req {
+ enum {
+ drm_bo_validate,
+ drm_bo_fence,
+ drm_bo_ref_fence,
+ } op;
+ unsigned int arg_handle;
+ struct drm_bo_info_req bo_req;
+};
+
+
struct drm_bo_op_arg {
uint64_t next;
union {
@@ -859,12 +860,6 @@ struct drm_bo_op_arg {
unsigned int pad64;
};
-struct drm_bo_set_pin_arg {
- union {
- struct drm_bo_set_pin_req req;
- struct drm_bo_info_rep rep;
- } d;
-};
#define DRM_BO_MEM_LOCAL 0
#define DRM_BO_MEM_TT 1
@@ -877,8 +872,18 @@ struct drm_bo_set_pin_arg {
#define DRM_BO_MEM_TYPES 8 /* For now. */
+#define DRM_BO_LOCK_UNLOCK_BM (1 << 0)
+#define DRM_BO_LOCK_IGNORE_NO_EVICT (1 << 1)
+
+struct drm_bo_version_arg {
+ uint32_t major;
+ uint32_t minor;
+ uint32_t patchlevel;
+};
+
struct drm_mm_type_arg {
unsigned int mem_type;
+ unsigned int lock_flags;
};
struct drm_mm_init_arg {
@@ -1069,10 +1074,11 @@ struct drm_mode_mode_cmd {
#define DRM_IOCTL_BO_UNMAP DRM_IOWR(0xd0, struct drm_bo_handle_arg)
#define DRM_IOCTL_BO_REFERENCE DRM_IOWR(0xd1, struct drm_bo_reference_info_arg)
#define DRM_IOCTL_BO_UNREFERENCE DRM_IOWR(0xd2, struct drm_bo_handle_arg)
-#define DRM_IOCTL_BO_OP DRM_IOWR(0xd3, struct drm_bo_op_arg)
+#define DRM_IOCTL_BO_SETSTATUS DRM_IOWR(0xd3, struct drm_bo_map_wait_idle_arg)
#define DRM_IOCTL_BO_INFO DRM_IOWR(0xd4, struct drm_bo_reference_info_arg)
#define DRM_IOCTL_BO_WAIT_IDLE DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg)
-#define DRM_IOCTL_BO_SET_PIN DRM_IOWR(0xd6, struct drm_bo_set_pin_arg)
+#define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg)
+
#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c
index 0be48024..07b3a35b 100644
--- a/shared-core/i915_dma.c
+++ b/shared-core/i915_dma.c
@@ -180,6 +180,7 @@ static int i915_initialize(struct drm_device * dev,
}
DRM_DEBUG("Enabled hardware status page\n");
dev->dev_private = (void *)dev_priv;
+ mutex_init(&dev_priv->cmdbuf_mutex);
return 0;
}
@@ -461,7 +462,7 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev,
int i = 0, count, ret;
if (cmd->sz & 0x3) {
- DRM_ERROR("alignment");
+ DRM_ERROR("alignment\n");
return -EINVAL;
}
@@ -499,7 +500,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
RING_LOCALS;
if ((batch->start | batch->used) & 0x7) {
- DRM_ERROR("alignment");
+ DRM_ERROR("alignment\n");
return -EINVAL;
}
@@ -831,6 +832,9 @@ int i915_process_relocs(struct drm_file *file_priv,
} while (reloc_offset != reloc_end);
out:
+ drm_bo_kunmap(&relocatee->kmap);
+ relocatee->data_page = NULL;
+
drm_bo_kunmap(&reloc_kmap);
mutex_lock(&dev->struct_mutex);
@@ -868,7 +872,6 @@ static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle,
}
}
- drm_bo_kunmap(&relocatee.kmap);
mutex_lock(&dev->struct_mutex);
drm_bo_usage_deref_locked(&relocatee.buf);
mutex_unlock(&dev->struct_mutex);
@@ -929,11 +932,19 @@ int i915_validate_buffer_list(struct drm_file *file_priv,
buf_handle = req->bo_req.handle;
buf_reloc_handle = arg.reloc_handle;
+ if (buf_reloc_handle) {
+ ret = i915_exec_reloc(file_priv, buf_handle, buf_reloc_handle, buffers, buf_count);
+ if (ret)
+ goto out_err;
+ DRM_MEMORYBARRIER();
+ }
+
rep.ret = drm_bo_handle_validate(file_priv, req->bo_req.handle,
req->bo_req.fence_class,
req->bo_req.flags,
req->bo_req.mask,
req->bo_req.hint,
+ 0,
&rep.bo_info,
&buffers[buf_count]);
@@ -953,11 +964,6 @@ int i915_validate_buffer_list(struct drm_file *file_priv,
data = next;
buf_count++;
- if (buf_reloc_handle) {
- ret = i915_exec_reloc(file_priv, buf_handle, buf_reloc_handle, buffers, buf_count);
- if (ret)
- goto out_err;
- }
} while (next != 0);
*num_buffers = buf_count;
return 0;
@@ -989,8 +995,6 @@ static int i915_execbuffer(struct drm_device *dev, void *data,
}
- LOCK_TEST_WITH_RETURN(dev, file_priv);
-
if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
batch->num_cliprects *
sizeof(struct drm_clip_rect)))
@@ -999,11 +1003,30 @@ static int i915_execbuffer(struct drm_device *dev, void *data,
if (exec_buf->num_buffers > dev_priv->max_validate_buffers)
return -EINVAL;
+
+ ret = drm_bo_read_lock(&dev->bm.bm_lock);
+ if (ret)
+ return ret;
+
+ /*
+ * The cmdbuf_mutex makes sure the validate-submit-fence
+ * operation is atomic.
+ */
+
+ ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
+ if (ret) {
+ drm_bo_read_unlock(&dev->bm.bm_lock);
+ return -EAGAIN;
+ }
+
num_buffers = exec_buf->num_buffers;
buffers = drm_calloc(num_buffers, sizeof(struct drm_buffer_object *), DRM_MEM_DRIVER);
- if (!buffers)
+ if (!buffers) {
+ drm_bo_read_unlock(&dev->bm.bm_lock);
+ mutex_unlock(&dev_priv->cmdbuf_mutex);
return -ENOMEM;
+ }
/* validate buffer list + fixup relocations */
ret = i915_validate_buffer_list(file_priv, 0, exec_buf->ops_list,
@@ -1012,7 +1035,7 @@ static int i915_execbuffer(struct drm_device *dev, void *data,
goto out_free;
/* make sure all previous memory operations have passed */
- asm volatile("mfence":::"memory");
+ DRM_MEMORYBARRIER();
/* submit buffer */
batch->start = buffers[num_buffers-1]->offset;
@@ -1051,6 +1074,8 @@ out_err0:
out_free:
drm_free(buffers, (exec_buf->num_buffers * sizeof(struct drm_buffer_object *)), DRM_MEM_DRIVER);
+ mutex_unlock(&dev_priv->cmdbuf_mutex);
+ drm_bo_read_unlock(&dev->bm.bm_lock);
return ret;
}
#endif
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index 12ac8b6e..be3212d1 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -143,6 +143,7 @@ struct drm_i915_private {
#ifdef I915_HAVE_BUFFER
void *agp_iomap;
unsigned int max_validate_buffers;
+ struct mutex cmdbuf_mutex;
#endif
DRM_SPINTYPE swaps_lock;
diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c
index 8e419b8a..3b43c722 100644
--- a/shared-core/i915_init.c
+++ b/shared-core/i915_init.c
@@ -188,16 +188,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel,
DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
DRM_BO_FLAG_MEM_VRAM |
+ DRM_BO_FLAG_NO_EVICT |
DRM_BO_HINT_DONT_FENCE, 0, 0x1, 0,
&dev_priv->ring_buffer);
if (ret < 0) {
- DRM_ERROR("Unable to allocate ring buffer\n");
- return -EINVAL;
- }
-
- ret = drm_bo_set_pin(dev, dev_priv->ring_buffer, 1);
- if (ret < 0) {
- DRM_ERROR("Unable to pin ring buffer\n");
+ DRM_ERROR("Unable to allocate or pin ring buffer\n");
return -EINVAL;
}