aboutsummaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/drm.h91
-rw-r--r--shared-core/i915_dma.c12
-rw-r--r--shared-core/i915_drm.h121
-rw-r--r--shared-core/i915_drv.h39
-rw-r--r--shared-core/i915_init.c39
-rw-r--r--shared-core/i915_irq.c70
6 files changed, 206 insertions, 166 deletions
diff --git a/shared-core/drm.h b/shared-core/drm.h
index 59cbbdd9..2d0f1f4d 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -993,84 +993,6 @@ struct drm_mm_info_arg {
uint64_t p_size;
};
-struct drm_gem_create {
- /**
- * Requested size for the object.
- *
- * The (page-aligned) allocated size for the object will be returned.
- */
- uint64_t size;
- /**
- * Returned handle for the object.
- *
- * Object handles are nonzero.
- */
- uint32_t handle;
- uint32_t pad;
-};
-
-struct drm_gem_close {
- /** Handle of the object to be closed. */
- uint32_t handle;
- uint32_t pad;
-};
-
-struct drm_gem_pread {
- /** Handle for the object being read. */
- uint32_t handle;
- uint32_t pad;
- /** Offset into the object to read from */
- uint64_t offset;
- /** Length of data to read */
- uint64_t size;
- /** Pointer to write the data into. */
- uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */
-};
-
-struct drm_gem_pwrite {
- /** Handle for the object being written to. */
- uint32_t handle;
- uint32_t pad;
- /** Offset into the object to write to */
- uint64_t offset;
- /** Length of data to write */
- uint64_t size;
- /** Pointer to read the data from. */
- uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */
-};
-
-struct drm_gem_mmap {
- /** Handle for the object being mapped. */
- uint32_t handle;
- uint32_t pad;
- /** Offset in the object to map. */
- uint64_t offset;
- /**
- * Length of data to map.
- *
- * The value will be page-aligned.
- */
- uint64_t size;
- /** Returned pointer the data was mapped at */
- uint64_t addr_ptr; /* void *, but pointers are not 32/64 compatible */
-};
-
-struct drm_gem_flink {
- /** Handle for the object being named */
- uint32_t handle;
- /** Returned global name */
- uint32_t name;
-};
-
-struct drm_gem_open {
- /** Name of object being opened */
- uint32_t name;
- /** Returned handle for the object */
- uint32_t handle;
- /** Returned size of the object */
- uint64_t size;
-};
-
struct drm_gem_set_domain {
/** Handle for the object */
uint32_t handle;
@@ -1298,6 +1220,10 @@ struct drm_mode_crtc_lut {
#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
+#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close)
+#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
+#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
+
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, struct drm_block)
@@ -1348,15 +1274,6 @@ struct drm_mode_crtc_lut {
#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw)
-#define DRM_IOCTL_GEM_CREATE DRM_IOWR(0x09, struct drm_gem_create)
-#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x0a, struct drm_gem_close)
-#define DRM_IOCTL_GEM_PREAD DRM_IOW (0x0b, struct drm_gem_pread)
-#define DRM_IOCTL_GEM_PWRITE DRM_IOW (0x0c, struct drm_gem_pwrite)
-#define DRM_IOCTL_GEM_MMAP DRM_IOWR(0x0d, struct drm_gem_mmap)
-#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0e, struct drm_gem_flink)
-#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0f, struct drm_gem_open)
-#define DRM_IOCTL_GEM_SET_DOMAIN DRM_IOW (0xb7, struct drm_gem_set_domain)
-
#define DRM_IOCTL_MM_INIT DRM_IOWR(0xc0, struct drm_mm_init_arg)
#define DRM_IOCTL_MM_TAKEDOWN DRM_IOWR(0xc1, struct drm_mm_type_arg)
#define DRM_IOCTL_MM_LOCK DRM_IOWR(0xc2, struct drm_mm_type_arg)
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c
index 0cd920de..5a94c156 100644
--- a/shared-core/i915_dma.c
+++ b/shared-core/i915_dma.c
@@ -121,7 +121,7 @@ int i915_dma_cleanup(struct drm_device * dev)
* may not have been called from userspace and after dev_private
* is freed, it's too late.
*/
- if (dev->irq)
+ if (dev->irq_enabled)
drm_irq_uninstall(dev);
if (dev_priv->ring.virtual_start) {
@@ -885,7 +885,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
switch (param->param) {
case I915_PARAM_IRQ_ACTIVE:
- value = dev->irq ? 1 : 0;
+ value = dev->irq_enabled ? 1 : 0;
break;
case I915_PARAM_ALLOW_BATCHBUFFER:
value = dev_priv->allow_batchbuffer ? 1 : 0;
@@ -1053,9 +1053,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
memset(dev_priv->hws_vaddr, 0, PAGE_SIZE);
I915_WRITE(HWS_PGA, dev_priv->hws_agpoffset);
- DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",
- dev_priv->hws_agpoffset);
DRM_DEBUG("load hws at %p\n", dev_priv->hws_vaddr);
+
return 0;
}
@@ -1089,6 +1088,11 @@ struct drm_ioctl_desc i915_ioctls[] = {
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),
+ DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0),
+ DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
+ DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
+ DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h
index 445bb279..d9ce2484 100644
--- a/shared-core/i915_drm.h
+++ b/shared-core/i915_drm.h
@@ -183,7 +183,12 @@ typedef struct drm_i915_sarea {
#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_I915_GEM_LEAVEVT 0x1a
+#define DRM_I915_GEM_CREATE 0x1b
+#define DRM_I915_GEM_PREAD 0x1c
+#define DRM_I915_GEM_PWRITE 0x1d
+#define DRM_I915_GEM_MMAP 0x1e
+#define DRM_I915_GEM_SET_DOMAIN 0x1f
#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)
@@ -211,6 +216,11 @@ typedef struct drm_i915_sarea {
#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)
+#define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
+#define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
+#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
+#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
+#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
/* Asynchronous page flipping:
*/
@@ -428,6 +438,73 @@ struct drm_i915_gem_init {
uint64_t gtt_end;
};
+struct drm_i915_gem_create {
+ /**
+ * Requested size for the object.
+ *
+ * The (page-aligned) allocated size for the object will be returned.
+ */
+ uint64_t size;
+ /**
+ * Returned handle for the object.
+ *
+ * Object handles are nonzero.
+ */
+ uint32_t handle;
+ uint32_t pad;
+};
+
+struct drm_i915_gem_pread {
+ /** Handle for the object being read. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset into the object to read from */
+ uint64_t offset;
+ /** Length of data to read */
+ uint64_t size;
+ /** Pointer to write the data into. */
+ uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */
+};
+
+struct drm_i915_gem_pwrite {
+ /** Handle for the object being written to. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset into the object to write to */
+ uint64_t offset;
+ /** Length of data to write */
+ uint64_t size;
+ /** Pointer to read the data from. */
+ uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */
+};
+
+struct drm_i915_gem_mmap {
+ /** Handle for the object being mapped. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset in the object to map. */
+ uint64_t offset;
+ /**
+ * Length of data to map.
+ *
+ * The value will be page-aligned.
+ */
+ uint64_t size;
+ /** Returned pointer the data was mapped at */
+ uint64_t addr_ptr; /* void *, but pointers are not 32/64 compatible */
+};
+
+struct drm_i915_gem_set_domain {
+ /** Handle for the object */
+ uint32_t handle;
+
+ /** New read domains */
+ uint32_t read_domains;
+
+ /** New write domain */
+ uint32_t write_domain;
+};
+
struct drm_i915_gem_relocation_entry {
/**
* Handle of the buffer being pointed to by this relocation entry.
@@ -473,20 +550,26 @@ struct drm_i915_gem_relocation_entry {
uint32_t write_domain;
};
-/**
+/** @{
* Intel memory domains
*
* Most of these just align with the various caches in
* the system and are used to flush and invalidate as
* objects end up cached in different domains.
*/
-
-/* 0x00000001 is DRM_GEM_DOMAIN_CPU */
-#define DRM_GEM_DOMAIN_I915_RENDER 0x00000002 /* Render cache, used by 2D and 3D drawing */
-#define DRM_GEM_DOMAIN_I915_SAMPLER 0x00000004 /* Sampler cache, used by texture engine */
-#define DRM_GEM_DOMAIN_I915_COMMAND 0x00000008 /* Command queue, used to load batch buffers */
-#define DRM_GEM_DOMAIN_I915_INSTRUCTION 0x00000010 /* Instruction cache, used by shader programs */
-#define DRM_GEM_DOMAIN_I915_VERTEX 0x00000020 /* Vertex address cache */
+/** CPU cache */
+#define I915_GEM_DOMAIN_CPU 0x00000001
+/** Render cache, used by 2D and 3D drawing */
+#define I915_GEM_DOMAIN_RENDER 0x00000002
+/** Sampler cache, used by texture engine */
+#define I915_GEM_DOMAIN_SAMPLER 0x00000004
+/** Command queue, used to load batch buffers */
+#define I915_GEM_DOMAIN_COMMAND 0x00000008
+/** Instruction cache, used by shader programs */
+#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
+/** Vertex address cache */
+#define I915_GEM_DOMAIN_VERTEX 0x00000020
+/** @} */
struct drm_i915_gem_exec_object {
/**
@@ -494,11 +577,15 @@ struct drm_i915_gem_exec_object {
* operation.
*/
uint32_t handle;
-
- /** List of relocations to be performed on this buffer */
+
+ /** Number of relocations to be performed on this buffer */
uint32_t relocation_count;
- uint64_t relocs_ptr; /* struct drm_i915_gem_relocation_entry *relocs */
-
+ /**
+ * Pointer to array of struct drm_i915_gem_relocation_entry containing
+ * the relocations to be performed in this buffer.
+ */
+ uint64_t relocs_ptr;
+
/** Required alignment in graphics aperture */
uint64_t alignment;
@@ -514,11 +601,13 @@ struct drm_i915_gem_execbuffer {
* List of buffers to be validated with their relocations to be
* performend on them.
*
+ * This is a pointer to an array of struct drm_i915_gem_validate_entry.
+ *
* These buffers must be listed in an order such that all relocations
* a buffer is performing refer to buffers that have already appeared
* in the validate list.
*/
- uint64_t buffers_ptr; /* struct drm_i915_gem_validate_entry *buffers */
+ uint64_t buffers_ptr;
uint32_t buffer_count;
/** Offset in the batchbuffer to start execution from. */
@@ -535,7 +624,7 @@ struct drm_i915_gem_pin {
/** Handle of the buffer to be pinned. */
uint32_t handle;
uint32_t pad;
-
+
/** alignment required within the aperture */
uint64_t alignment;
@@ -552,7 +641,7 @@ struct drm_i915_gem_unpin {
struct drm_i915_gem_busy {
/** Handle of the buffer to check for busy */
uint32_t handle;
-
+
/** Return busy status (1 if busy, 0 if idle) */
uint32_t busy;
};
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index 06aa00ab..ee5e9dfd 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -39,7 +39,7 @@
#define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics"
-#define DRIVER_DATE "20080312"
+#define DRIVER_DATE "20080611"
#if defined(__linux__)
#define I915_HAVE_FENCE
@@ -63,7 +63,7 @@
*/
#define DRIVER_MAJOR 1
#if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER)
-#define DRIVER_MINOR 13
+#define DRIVER_MINOR 14
#else
#define DRIVER_MINOR 6
#endif
@@ -162,7 +162,7 @@ struct drm_i915_private {
void *agp_iomap;
unsigned int max_validate_buffers;
struct mutex cmdbuf_mutex;
- size_t stolen_base;
+ u32 stolen_base;
struct drm_i915_validate_buffer *val_bufs;
#endif
@@ -231,8 +231,7 @@ struct drm_i915_private {
* fire periodically while the ring is running. When it
* fires, go retire requests.
*/
- struct timer_list retire_timer;
- struct work_struct retire_task;
+ struct delayed_work retire_work;
uint32_t next_gem_seqno;
@@ -339,6 +338,13 @@ struct drm_i915_private {
u8 saveCR[37];
};
+struct drm_i915_file_private {
+ struct {
+ uint32_t last_gem_seqno;
+ uint32_t last_gem_throttle_seqno;
+ } mm;
+};
+
enum intel_chip_family {
CHIP_I8XX = 0x01,
CHIP_I9XX = 0x02,
@@ -418,8 +424,11 @@ extern void i915_kernel_lost_context(struct drm_device * dev);
extern int i915_driver_load(struct drm_device *, unsigned long flags);
extern int i915_driver_unload(struct drm_device *dev);
extern void i915_driver_lastclose(struct drm_device * dev);
+extern int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv);
extern void i915_driver_preclose(struct drm_device *dev,
struct drm_file *file_priv);
+extern void i915_driver_postclose(struct drm_device *dev,
+ struct drm_file *file_priv);
extern int i915_driver_device_is_agp(struct drm_device * dev);
extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
@@ -461,7 +470,6 @@ extern int i915_vblank_swap(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern void i915_user_irq_on(struct drm_device *dev);
extern void i915_user_irq_off(struct drm_device *dev);
-extern void i915_user_interrupt_handler(struct work_struct *work);
/* i915_mem.c */
extern int i915_mem_alloc(struct drm_device *dev, void *data,
@@ -503,6 +511,16 @@ int i915_execbuffer(struct drm_device *dev, void *data,
/* i915_gem.c */
int i915_gem_init_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int i915_gem_create_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
int i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int i915_gem_pin_ioctl(struct drm_device *dev, void *data,
@@ -521,20 +539,13 @@ 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,
- uint32_t write_domain);
-int i915_gem_flush_pwrite(struct drm_gem_object *obj,
- uint64_t offset, uint64_t size);
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);
void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
int i915_gem_do_init(struct drm_device *dev, unsigned long start,
unsigned long end);
+void i915_gem_retire_work_handler(struct work_struct *work);
#endif
extern unsigned int i915_fbpercrtc;
diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c
index 3f310770..3a652e8d 100644
--- a/shared-core/i915_init.c
+++ b/shared-core/i915_init.c
@@ -294,10 +294,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (IS_I965G(dev) || IS_G33(dev))
dev_priv->cursor_needs_physical = false;
- if (IS_I9XX(dev)) {
+ if (IS_I9XX(dev))
pci_read_config_dword(dev->pdev, 0x5C, &dev_priv->stolen_base);
- DRM_DEBUG("stolen base %p\n", (void*)dev_priv->stolen_base);
- }
if (IS_I9XX(dev)) {
dev_priv->mmiobase = drm_get_resource_start(dev, 0);
@@ -329,13 +327,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
INIT_LIST_HEAD(&dev_priv->mm.request_list);
- dev_priv->mm.retire_timer.function = i915_gem_retire_timeout;
- dev_priv->mm.retire_timer.data = (unsigned long) dev;
- init_timer_deferrable (&dev_priv->mm.retire_timer);
- INIT_WORK(&dev_priv->mm.retire_task,
- i915_gem_retire_handler);
- INIT_WORK(&dev_priv->user_interrupt_task,
- i915_user_interrupt_handler);
+ INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
+ i915_gem_retire_work_handler);
dev_priv->mm.next_gem_seqno = 1;
#ifdef __linux__
@@ -457,6 +450,32 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
master->driver_priv = NULL;
}
+int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
+{
+ struct drm_i915_file_private *i915_file_priv;
+
+ DRM_DEBUG("\n");
+ i915_file_priv = (struct drm_i915_file_private *)
+ drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES);
+
+ if (!i915_file_priv)
+ return -ENOMEM;
+
+ file_priv->driver_priv = i915_file_priv;
+
+ i915_file_priv->mm.last_gem_seqno = 0;
+ i915_file_priv->mm.last_gem_throttle_seqno = 0;
+
+ return 0;
+}
+
+void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
+{
+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
+
+ drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES);
+}
+
void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
{
struct drm_i915_private *dev_priv = dev->dev_private;
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c
index bd11d37a..0dea6e56 100644
--- a/shared-core/i915_irq.c
+++ b/shared-core/i915_irq.c
@@ -35,6 +35,13 @@
#define MAX_NOPID ((u32)~0)
+/*
+ * These are the interrupts used by the driver
+ */
+#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
+ I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
+ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
+
/**
* i915_get_pipe - return the the pipe associated with a given plane
* @dev: DRM device
@@ -493,28 +500,13 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat)
return 0;
}
-void
-i915_user_interrupt_handler(struct work_struct *work)
-{
- struct drm_i915_private *dev_priv;
- struct drm_device *dev;
-
- dev_priv = container_of(work, struct drm_i915_private,
- user_interrupt_task);
- dev = dev_priv->dev;
-
- mutex_lock(&dev->struct_mutex);
- i915_gem_retire_requests(dev);
- mutex_unlock(&dev->struct_mutex);
-}
-
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
struct drm_i915_master_private *master_priv;
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
u32 iir;
- u32 pipea_stats = 0, pipeb_stats, tvdac;
+ u32 pipea_stats = 0, pipeb_stats = 0, tvdac;
int hotplug = 0;
int vblank = 0;
@@ -524,22 +516,11 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
else
iir = I915_READ16(IIR);
- iir &= (dev_priv->irq_mask_reg | I915_USER_INTERRUPT);
+ if (dev->pdev->msi_enabled)
+ I915_WRITE(IER, 0);
-#if 0
- DRM_DEBUG("flag=%08x\n", iir);
-#endif
- if (iir == 0) {
-#if 0
- DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n",
- iir,
- I915_READ(IMR),
- I915_READ(IER),
- I915_READ(PIPEASTAT),
- I915_READ(PIPEBSTAT));
-#endif
+ if (!iir)
return IRQ_NONE;
- }
/*
* Clear the PIPE(A|B)STAT regs before the IIR otherwise
@@ -598,10 +579,19 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
DRM_WAKEUP(&dev_priv->irq_queue);
#ifdef I915_HAVE_FENCE
i915_fence_handler(dev);
- schedule_work(&dev_priv->user_interrupt_task);
#endif
}
+ if (pipea_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
+ I915_VBLANK_INTERRUPT_STATUS)) {
+ vblank = 1;
+ drm_handle_vblank(dev, i915_get_plane(dev, 0));
+ }
+ if (pipeb_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
+ I915_VBLANK_INTERRUPT_STATUS)) {
+ vblank = 1;
+ drm_handle_vblank(dev, i915_get_plane(dev, 1));
+ }
if (vblank) {
if (dev_priv->swaps_pending > 0)
drm_locked_tasklet(dev, i915_vblank_tasklet);
@@ -626,6 +616,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
i915_run_hotplug_tasklet(dev, temp2);
}
+ if (dev->pdev->msi_enabled)
+ I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
+
return IRQ_HANDLED;
}
@@ -697,8 +690,17 @@ int i915_wait_irq(struct drm_device * dev, int irq_nr)
DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
READ_BREADCRUMB(dev_priv));
- if (READ_BREADCRUMB(dev_priv) >= irq_nr)
+ master_priv = dev->primary->master->driver_priv;
+
+ if (!master_priv) {
+ DRM_ERROR("no master priv?\n");
+ return -EINVAL;
+ }
+
+ if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
+ master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
return 0;
+ }
i915_user_irq_on(dev);
DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
@@ -710,10 +712,8 @@ int i915_wait_irq(struct drm_device * dev, int irq_nr)
READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
}
- if (dev->primary->master) {
- master_priv = dev->primary->master->driver_priv;
+ if (READ_BREADCRUMB(dev_priv) >= irq_nr)
master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
- }
return ret;
}