summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/i915_dma.c11
-rw-r--r--shared-core/i915_drm.h4
-rw-r--r--shared-core/i915_drv.h20
-rw-r--r--shared-core/i915_init.c48
-rw-r--r--shared-core/i915_irq.c7
5 files changed, 36 insertions, 54 deletions
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c
index 86881ab8..1e51e702 100644
--- a/shared-core/i915_dma.c
+++ b/shared-core/i915_dma.c
@@ -232,20 +232,16 @@ static int i915_initialize(struct drm_device * dev,
}
#endif
- if (!dev_priv->ring.Size) {
- dev_priv->ring.Start = init->ring_start;
- dev_priv->ring.End = init->ring_end;
+ if (init->ring_size != 0) {
dev_priv->ring.Size = init->ring_size;
dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
-
dev_priv->ring.map.offset = init->ring_start;
dev_priv->ring.map.size = init->ring_size;
dev_priv->ring.map.type = 0;
dev_priv->ring.map.flags = 0;
dev_priv->ring.map.mtrr = 0;
-
drm_core_ioremap(&dev_priv->ring.map, dev);
-
+
if (dev_priv->ring.map.handle == NULL) {
i915_dma_cleanup(dev);
DRM_ERROR("can not ioremap virtual address for"
@@ -255,7 +251,6 @@ static int i915_initialize(struct drm_device * dev,
dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
}
-
dev_priv->cpp = init->cpp;
master_priv->sarea_priv->pf_current_page = 0;
@@ -1091,6 +1086,8 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH),
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h
index bb551d84..445bb279 100644
--- a/shared-core/i915_drm.h
+++ b/shared-core/i915_drm.h
@@ -182,6 +182,8 @@ typedef struct drm_i915_sarea {
#define DRM_I915_GEM_UNPIN 0x16
#define DRM_I915_GEM_BUSY 0x17
#define DRM_I915_GEM_THROTTLE 0x18
+#define DRM_I915_GEM_ENTERVT 0x19
+#define DRM_I915_GEM_LEAVEVT 0x20
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -207,6 +209,8 @@ typedef struct drm_i915_sarea {
#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
#define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
+#define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
+#define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
/* Asynchronous page flipping:
*/
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index eab51e39..cfb064ff 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -81,14 +81,13 @@ struct drm_i915_validate_buffer;
struct drm_i915_ring_buffer {
int tail_mask;
- unsigned long Start;
- unsigned long End;
unsigned long Size;
u8 *virtual_start;
int head;
int tail;
int space;
drm_local_map_t map;
+ struct drm_gem_object *ring_obj;
};
struct mem_block {
@@ -236,6 +235,16 @@ struct drm_i915_private {
struct work_struct retire_task;
uint32_t next_gem_seqno;
+
+ /**
+ * Flag if the X Server, and thus DRM, is not currently in
+ * control of the device.
+ *
+ * This is set between LeaveVT and EnterVT. It needs to be
+ * replaced with a semaphore. It also needs to be
+ * transitioned away from for kernel modesetting.
+ */
+ int suspended;
} mm;
struct work_struct user_interrupt_task;
@@ -502,8 +511,14 @@ int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
int i915_gem_init_object(struct drm_gem_object *obj);
void i915_gem_free_object(struct drm_gem_object *obj);
+int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
+void i915_gem_object_unpin(struct drm_gem_object *obj);
int i915_gem_set_domain(struct drm_gem_object *obj,
struct drm_file *file_priv,
uint32_t read_domains,
@@ -514,6 +529,7 @@ void i915_gem_lastclose(struct drm_device *dev);
void i915_gem_retire_requests(struct drm_device *dev);
void i915_gem_retire_timeout(unsigned long data);
void i915_gem_retire_handler(struct work_struct *work);
+int i915_gem_init_ringbuffer(struct drm_device *dev);
#endif
extern unsigned int i915_fbpercrtc;
diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c
index e13d12fc..ba02f485 100644
--- a/shared-core/i915_init.c
+++ b/shared-core/i915_init.c
@@ -109,47 +109,9 @@ int i915_load_modeset_init(struct drm_device *dev)
i915_probe_agp(dev->pdev, &agp_size, &prealloc_size);
printk("setting up %ld bytes of VRAM space\n", prealloc_size);
printk("setting up %ld bytes of TT space\n", (agp_size - prealloc_size));
-
- drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, prealloc_size >> PAGE_SHIFT, 1);
- drm_bo_init_mm(dev, DRM_BO_MEM_TT, prealloc_size >> PAGE_SHIFT,
- (agp_size - prealloc_size) >> PAGE_SHIFT, 1);
- I915_WRITE(PRB0_CTL, 0);
- I915_WRITE(PRB0_HEAD, 0);
- I915_WRITE(PRB0_TAIL, 0);
-
- size = PRIMARY_RINGBUFFER_SIZE;
- 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, 0x1, 0,
- &dev_priv->ring_buffer);
- if (ret < 0) {
- DRM_ERROR("Unable to allocate or pin ring buffer\n");
- goto clean_mm;
- }
-
- /* remap the buffer object properly */
- dev_priv->ring.Start = dev_priv->ring_buffer->offset;
- dev_priv->ring.End = dev_priv->ring.Start + size;
- dev_priv->ring.Size = size;
- dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
-
- /* FIXME: need wrapper with PCI mem checks */
- ret = drm_mem_reg_ioremap(dev, &dev_priv->ring_buffer->mem,
- (void **) &dev_priv->ring.virtual_start);
- if (ret) {
- DRM_ERROR("error mapping ring buffer: %d\n", ret);
- goto destroy_ringbuffer;
- }
-
- DRM_DEBUG("ring start %08lX, %p, %08lX\n", dev_priv->ring.Start,
- dev_priv->ring.virtual_start, dev_priv->ring.Size);
-
- memset((void *)(dev_priv->ring.virtual_start), 0, dev_priv->ring.Size);
- I915_WRITE(PRB0_START, dev_priv->ring.Start);
- I915_WRITE(PRB0_CTL, ((dev_priv->ring.Size - 4096) & RING_NR_PAGES) |
- (RING_NO_REPORT | RING_VALID));
+ ret = i915_gem_init_ringbuffer(dev);
+ if (ret)
+ goto out;
/* Allow hardware batchbuffers unless told otherwise.
*/
@@ -262,9 +224,7 @@ destroy_ringbuffer:
dev_priv->ring.virtual_start);
if (dev_priv->ring_buffer)
drm_bo_usage_deref_unlocked(&dev_priv->ring_buffer);
-clean_mm:
- drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM, 1);
- drm_bo_clean_mm(dev, DRM_BO_MEM_TT, 1);
+out:
return ret;
}
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c
index d36a3691..bd11d37a 100644
--- a/shared-core/i915_irq.c
+++ b/shared-core/i915_irq.c
@@ -670,7 +670,7 @@ void i915_user_irq_off(struct drm_device *dev)
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
DRM_SPINLOCK(&dev_priv->user_irq_lock);
- BUG_ON(dev_priv->user_irq_refcount <= 0);
+ BUG_ON(dev_priv->irq_enabled && dev_priv->user_irq_refcount <= 0);
if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
dev_priv->irq_mask_reg |= I915_USER_INTERRUPT;
if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev))
@@ -689,6 +689,11 @@ int i915_wait_irq(struct drm_device * dev, int irq_nr)
struct drm_i915_master_private *master_priv;
int ret = 0;
+ if (!dev_priv) {
+ DRM_ERROR("called with no initialization\n");
+ return -EINVAL;
+ }
+
DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
READ_BREADCRUMB(dev_priv));