diff options
-rw-r--r-- | sys/dev/pci/drm/i915_dma.c | 64 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_drm.h | 19 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_drv.h | 80 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_irq.c | 161 |
4 files changed, 95 insertions, 229 deletions
diff --git a/sys/dev/pci/drm/i915_dma.c b/sys/dev/pci/drm/i915_dma.c index 036d95c65fe..480f1dbc91b 100644 --- a/sys/dev/pci/drm/i915_dma.c +++ b/sys/dev/pci/drm/i915_dma.c @@ -142,21 +142,19 @@ static int i915_dma_cleanup(struct drm_device * dev) if (dev_priv->ring.virtual_start) { drm_core_ioremapfree(&dev_priv->ring.map, dev); - dev_priv->ring.virtual_start = 0; - dev_priv->ring.map.handle = 0; + dev_priv->ring.virtual_start = NULL; + dev_priv->ring.map.handle = NULL; dev_priv->ring.map.size = 0; } - /* Clear the HWS virtual address as teardown */ + /* Clear the HWS virtual address at teardown */ if (I915_NEED_GFX_HWS(dev)) i915_free_hws(dev); return 0; } -static int i915_initialize(struct drm_device * dev, - struct drm_file *file_priv, - drm_i915_init_t * init) +static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -176,8 +174,6 @@ static int i915_initialize(struct drm_device * dev, dev_priv->sarea_priv = NULL; } - dev_priv->ring.Start = init->ring_start; - dev_priv->ring.End = init->ring_end; dev_priv->ring.Size = init->ring_size; dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; @@ -239,9 +235,9 @@ static int i915_dma_resume(struct drm_device * dev) DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); if (dev_priv->status_gfx_addr != 0) - I915_WRITE(0x02080, dev_priv->status_gfx_addr); + I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); else - I915_WRITE(0x02080, dev_priv->dma_status_page); + I915_WRITE(HWS_PGA, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); return 0; @@ -255,8 +251,7 @@ int i915_dma_init(struct drm_device *dev, void *data, switch (init->func) { case I915_INIT_DMA: - case I915_INIT_DMA2: - retcode = i915_initialize(dev, file_priv, init); + retcode = i915_initialize(dev, init); break; case I915_CLEANUP_DMA: retcode = i915_dma_cleanup(dev); @@ -446,7 +441,7 @@ void i915_emit_breadcrumb(struct drm_device *dev) BEGIN_LP_RING(4); OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(20); + OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); OUT_RING(dev_priv->counter); OUT_RING(0); ADVANCE_LP_RING(); @@ -542,7 +537,6 @@ int i915_dispatch_batchbuffer(struct drm_device * dev, OUT_RING(batch->start | MI_BATCH_NON_SECURE); } ADVANCE_LP_RING(); - } else { BEGIN_LP_RING(4); OUT_RING(MI_BATCH_BUFFER); @@ -554,6 +548,7 @@ int i915_dispatch_batchbuffer(struct drm_device * dev, } i915_emit_breadcrumb(dev); + return 0; } @@ -631,7 +626,7 @@ int i915_quiescent(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; i915_kernel_lost_context(dev); - return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__); + return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__); } int i915_flush_ioctl(struct drm_device *dev, void *data, @@ -679,9 +674,8 @@ int i915_batchbuffer(struct drm_device *dev, void *data, int i915_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) - dev_priv->sarea_priv; + drm_i915_private_t *dev_priv = (drm_i915_private_t *)dev->dev_private; + drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)dev_priv->sarea_priv; drm_i915_cmdbuffer_t *cmdbuf = data; int ret; @@ -711,12 +705,6 @@ int i915_cmdbuffer(struct drm_device *dev, void *data, return 0; } -#if defined(DRM_DEBUG_CODE) -#define DRM_DEBUG_RELOCATION (drm_debug != 0) -#else -#define DRM_DEBUG_RELOCATION 0 -#endif - static int i915_do_cleanup_pageflip(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -918,7 +906,7 @@ int i915_set_status_page(struct drm_device *dev, void *data, memset(dev_priv->hw_status_page, 0, PAGE_SIZE); I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); - DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n", + DRM_DEBUG("load hws HWS_PGA with gfx mem 0x%x\n", dev_priv->status_gfx_addr); DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page); return 0; @@ -953,13 +941,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) mtx_init(&dev_priv->swaps_lock, IPL_BIO); DRM_SPININIT(&dev_priv->user_irq_lock, "I915 irq lock"); -#ifdef __linux__ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) - intel_init_chipset_flush_compat(dev); -#endif - intel_opregion_init(dev); -#endif - return ret; } @@ -975,17 +956,8 @@ int i915_driver_unload(struct drm_device *dev) DRM_SPINUNINIT(&dev_priv->swaps_lock); DRM_SPINUNINIT(&dev_priv->user_irq_lock); -#ifdef __linux__ - intel_opregion_free(dev); -#endif - - drm_free(dev->dev_private, sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); -#ifdef __linux__ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) - intel_fini_chipset_flush_compat(dev); -#endif -#endif + drm_free(dev->dev_private, sizeof(drm_i915_private_t), DRM_MEM_DRIVER); + return 0; } @@ -1003,6 +975,7 @@ void i915_driver_lastclose(struct drm_device * dev) if (dev_priv->agp_heap) i915_mem_takedown(&(dev_priv->agp_heap)); + i915_dma_cleanup(dev); } @@ -1028,8 +1001,3 @@ int i915_driver_device_is_agp(struct drm_device * dev) { return 1; } - -int i915_driver_firstopen(struct drm_device *dev) -{ - return 0; -} diff --git a/sys/dev/pci/drm/i915_drm.h b/sys/dev/pci/drm/i915_drm.h index 97e77428692..111a1ca1d30 100644 --- a/sys/dev/pci/drm/i915_drm.h +++ b/sys/dev/pci/drm/i915_drm.h @@ -43,12 +43,7 @@ typedef struct _drm_i915_init { enum { I915_INIT_DMA = 0x01, I915_CLEANUP_DMA = 0x02, - I915_RESUME_DMA = 0x03, - - /* Since this struct isn't versioned, just used a new - * 'func' code to indicate the presence of dri2 sarea - * info. */ - I915_INIT_DMA2 = 0x04 + I915_RESUME_DMA = 0x03 } func; unsigned int mmio_offset; int sarea_priv_offset; @@ -66,7 +61,6 @@ typedef struct _drm_i915_init { unsigned int depth_pitch; unsigned int cpp; unsigned int chipset; - unsigned int sarea_handle; } drm_i915_init_t; typedef struct drm_i915_sarea { @@ -175,7 +169,6 @@ typedef struct drm_i915_sarea { #define DRM_I915_VBLANK_SWAP 0x0f #define DRM_I915_MMIO 0x10 #define DRM_I915_HWS_ADDR 0x11 -#define DRM_I915_EXECBUFFER 0x12 #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) @@ -194,7 +187,6 @@ typedef struct drm_i915_sarea { #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) #define DRM_IOCTL_I915_MMIO DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_MMIO, drm_i915_mmio) -#define DRM_IOCTL_I915_EXECBUFFER DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_EXECBUFFER, struct drm_i915_execbuffer) /* Asynchronous page flipping: */ @@ -386,13 +378,4 @@ struct drm_i915_op_arg { } d; }; - -struct drm_i915_execbuffer { - uint64_t ops_list; - uint32_t num_buffers; - struct drm_i915_batchbuffer batch; - drm_context_t context; /* for lockless use in the future */ - struct drm_fence_arg fence_arg; -}; - #endif /* _I915_DRM_H_ */ diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h index f7d255cb5ec..3a728c411ca 100644 --- a/sys/dev/pci/drm/i915_drv.h +++ b/sys/dev/pci/drm/i915_drv.h @@ -39,6 +39,11 @@ #define DRIVER_DESC "Intel Graphics" #define DRIVER_DATE "20080312" +enum pipe { + PIPE_A = 0, + PIPE_B, +}; + /* Interface history: * * 1.1: Original. @@ -48,25 +53,13 @@ * 1.5: Add vblank pipe configuration * 1.6: - New ioctl for scheduling buffer swaps on vertical blank * - Support vertical blank on secondary display pipe - * 1.8: New ioctl for ARB_Occlusion_Query - * 1.9: Usable page flipping and triple buffering - * 1.10: Plane/pipe disentangling - * 1.11: TTM superioctl - * 1.12: TTM relocation optimization */ #define DRIVER_MAJOR 1 #define DRIVER_MINOR 6 #define DRIVER_PATCHLEVEL 0 -enum pipe { - PIPE_A = 0, - PIPE_B, -}; - typedef struct _drm_i915_ring_buffer { int tail_mask; - unsigned long Start; - unsigned long End; unsigned long Size; u8 *virtual_start; int head; @@ -91,22 +84,6 @@ typedef struct _drm_i915_vbl_swap { int flip; } drm_i915_vbl_swap_t; -#ifdef __linux__ -struct opregion_header; -struct opregion_acpi; -struct opregion_swsci; -struct opregion_asle; - -struct intel_opregion { - struct opregion_header *header; - struct opregion_acpi *acpi; - struct opregion_swsci *swsci; - struct opregion_asle *asle; - - int enabled; -}; -#endif - typedef struct drm_i915_private { drm_local_map_t *sarea; drm_local_map_t *mmio_map; @@ -125,14 +102,12 @@ typedef struct drm_i915_private { wait_queue_head_t irq_queue; atomic_t irq_received; - atomic_t irq_emitted; /* Protects user_irq_refcount and irq_mask reg */ DRM_SPINTYPE user_irq_lock; /* Refcount for user irq, only enabled when needed */ int user_irq_refcount; /* Cached value of IMR to avoid reads in updating the bitfield */ u_int32_t irq_mask_reg; - int irq_enabled; int tex_lru_log_granularity; int allow_batchbuffer; @@ -144,10 +119,6 @@ typedef struct drm_i915_private { drm_i915_vbl_swap_t vbl_swaps; unsigned int swaps_pending; -#ifdef __linux__ - struct intel_opregion opregion; -#endif - /* Register state */ u8 saveLBB; u32 saveDSPACNTR; @@ -273,7 +244,6 @@ extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); extern void i915_driver_irq_preinstall(struct drm_device * dev); extern int i915_driver_irq_postinstall(struct drm_device * dev); extern void i915_driver_irq_uninstall(struct drm_device * dev); -extern void i915_enable_interrupt(struct drm_device *dev); extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, @@ -284,8 +254,8 @@ extern void i915_disable_vblank(struct drm_device *dev, int crtc); extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); extern int i915_vblank_swap(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern void i915_user_irq_on(drm_i915_private_t *dev_priv); -extern void i915_user_irq_off(drm_i915_private_t *dev_priv); +extern void i915_user_irq_get(struct drm_device *dev); +extern void i915_user_irq_put(struct drm_device *dev); /* i915_mem.c */ extern int i915_mem_alloc(struct drm_device *dev, void *data, @@ -305,21 +275,6 @@ extern void i915_mem_release(struct drm_device * dev, extern int i915_save_state(struct drm_device *dev); extern int i915_restore_state(struct drm_device *dev); -#ifdef __linux__ -/* i915_opregion.c */ -extern int intel_opregion_init(struct drm_device *dev); -extern void intel_opregion_free(struct drm_device *dev); -extern void opregion_asle_intr(struct drm_device *dev); -extern void opregion_enable_asle(struct drm_device *dev); -#endif - -#ifdef __linux__ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) -extern void intel_init_chipset_flush_compat(struct drm_device *dev); -extern void intel_fini_chipset_flush_compat(struct drm_device *dev); -#endif -#endif - /* ioctls */ extern int i915_dma_init(struct drm_device *, void *, struct drm_file *); extern int i915_flush_ioctl(struct drm_device *, void *, struct drm_file *); @@ -338,23 +293,16 @@ extern int i915_set_status_page(struct drm_device *, void *, struct drm_file *); #define I915_READ8(reg) DRM_READ8(dev_priv->mmio_map, (reg)) #define I915_WRITE8(reg,val) DRM_WRITE8(dev_priv->mmio_map, (reg), (val)) -#if defined(__FreeBSD__) -typedef boolean_t bool; -#endif - #define I915_VERBOSE 0 -#define PRIMARY_RINGBUFFER_SIZE (128*1024) - #define RING_LOCALS unsigned int outring, ringmask, outcount; \ volatile char *virt; #define BEGIN_LP_RING(n) do { \ if (I915_VERBOSE) \ - DRM_DEBUG("BEGIN_LP_RING(%d)\n", \ - (n)); \ - if (dev_priv->ring.space < (n)*4) \ - i915_wait_ring(dev, (n)*4, __FUNCTION__); \ + DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ + if (dev_priv->ring.space < (n)*4) \ + i915_wait_ring(dev, (n)*4, __func__); \ outcount = 0; \ outring = dev_priv->ring.tail; \ ringmask = dev_priv->ring.tail_mask; \ @@ -363,7 +311,7 @@ typedef boolean_t bool; #define OUT_RING(n) do { \ if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = (n); \ + *(volatile unsigned int *)(virt + outring) = (n); \ outcount++; \ outring += 4; \ outring &= ringmask; \ @@ -478,6 +426,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) +#define MI_STORE_DWORD_INDEX_SHIFT 2 #define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1) #define MI_BATCH_BUFFER MI_INSTR(0x30, 1) #define MI_BATCH_NON_SECURE (1) @@ -487,8 +436,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define BREADCRUMB_BITS 31 #define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) -#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5]) - /** * Reads a dword out of the status page, which is written to from the command * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or @@ -503,6 +450,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); * The area from dword 0x10 to 0x3ff is available for driver usage. */ #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) +#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5) #define I915_GEM_HWS_INDEX 0x10 /* @@ -1804,4 +1752,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev)) +#define PRIMARY_RINGBUFFER_SIZE (128*1024) + #endif diff --git a/sys/dev/pci/drm/i915_irq.c b/sys/dev/pci/drm/i915_irq.c index 604178ebe0e..7c01183b7fe 100644 --- a/sys/dev/pci/drm/i915_irq.c +++ b/sys/dev/pci/drm/i915_irq.c @@ -403,8 +403,9 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane) low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; if (!i915_pipe_enabled(dev, pipe)) { - DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe); - return 0; + DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", + pipe); + return 0; } /* @@ -431,11 +432,11 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; u32 iir; - u32 pipea_stats = 0, pipeb_stats = 0; + u32 pipea_stats, pipeb_stats; int vblank = 0; - iir = I915_READ(IIR); atomic_inc(&dev_priv->irq_received); + iir = I915_READ(IIR); if (iir == 0) return IRQ_NONE; @@ -446,8 +447,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) { pipea_stats = I915_READ(PIPEASTAT); if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| - PIPE_VBLANK_INTERRUPT_STATUS)) - { + PIPE_VBLANK_INTERRUPT_STATUS)) { vblank++; drm_handle_vblank(dev, i915_get_plane(dev, 0)); } @@ -459,36 +459,21 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) /* Ack the event */ I915_WRITE(PIPEBSTAT, pipeb_stats); - /* The vblank interrupt gets enabled even if we didn't ask for - it, so make sure it's shut down again */ - if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)) - pipeb_stats &= ~(I915_VBLANK_INTERRUPT_ENABLE); - if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| - PIPE_VBLANK_INTERRUPT_STATUS)) - { + PIPE_VBLANK_INTERRUPT_STATUS)) { vblank++; drm_handle_vblank(dev, i915_get_plane(dev, 1)); } -#ifdef __linux__ - if (pipeb_stats & I915_LEGACY_BLC_EVENT_ENABLE) - opregion_asle_intr(dev); -#endif I915_WRITE(PIPEBSTAT, pipeb_stats); } -#ifdef __linux__ - if (iir & I915_ASLE_INTERRUPT) - opregion_asle_intr(dev); -#endif - - if (dev_priv->sarea_priv) - dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); - I915_WRITE(IIR, iir); (void) I915_READ(IIR); /* Flush posted writes */ + if (dev_priv->sarea_priv) + dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); + if (iir & I915_USER_INTERRUPT) { DRM_WAKEUP(&dev_priv->irq_queue); } @@ -520,19 +505,23 @@ int i915_emit_irq(struct drm_device *dev) return dev_priv->counter; } -void i915_user_irq_on(drm_i915_private_t *dev_priv) +void i915_user_irq_get(struct drm_device *dev) { + drm_i915_private_t *dev_priv = (drm_i915_private_t *)dev->dev_private; + DRM_SPINLOCK(&dev_priv->user_irq_lock); - if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)) + if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) i915_enable_irq(dev_priv, I915_USER_INTERRUPT); DRM_SPINUNLOCK(&dev_priv->user_irq_lock); } -void i915_user_irq_off(drm_i915_private_t *dev_priv) +void i915_user_irq_put(struct drm_device *dev) { + drm_i915_private_t *dev_priv = (drm_i915_private_t *)dev->dev_private; + DRM_SPINLOCK(&dev_priv->user_irq_lock); - if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) + if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) i915_disable_irq(dev_priv, I915_USER_INTERRUPT); DRM_SPINUNLOCK(&dev_priv->user_irq_lock); } @@ -543,25 +532,21 @@ int i915_wait_irq(struct drm_device * dev, int irq_nr) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 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)); if (READ_BREADCRUMB(dev_priv) >= irq_nr) { - if (dev_priv->sarea_priv) + if (dev_priv->sarea_priv) { dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); + } return 0; } - i915_user_irq_on(dev_priv); + i915_user_irq_get(dev); DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, READ_BREADCRUMB(dev_priv) >= irq_nr); - i915_user_irq_off(dev_priv); + i915_user_irq_put(dev); if (ret == EBUSY) { DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", @@ -621,44 +606,42 @@ int i915_enable_vblank(struct drm_device *dev, int plane) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; int pipe = i915_get_pipe(dev, plane); u32 pipestat_reg = 0; - u32 mask_reg = 0; u32 pipestat; + u32 interrupt = 0; switch (pipe) { case 0: pipestat_reg = PIPEASTAT; - mask_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; + interrupt = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; break; case 1: pipestat_reg = PIPEBSTAT; - mask_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; + interrupt = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; break; default: DRM_ERROR("tried to enable vblank on non-existent pipe %d\n", pipe); - break; + return (0); } - if (pipestat_reg) - { - pipestat = I915_READ (pipestat_reg); - /* - * Older chips didn't have the start vblank interrupt, - * but - */ - if (IS_I965G (dev)) - pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE; - else - pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE; - /* - * Clear any pending status - */ - pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | - PIPE_VBLANK_INTERRUPT_STATUS); - I915_WRITE(pipestat_reg, pipestat); - } + pipestat = I915_READ (pipestat_reg); + /* + * Older chips didn't have the start vblank interrupt, + * but + */ + if (IS_I965G (dev)) + pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE; + else + pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE; + /* + * Clear any pending status + */ + pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | + PIPE_VBLANK_INTERRUPT_STATUS); + I915_WRITE(pipestat_reg, pipestat); + DRM_SPINLOCK(&dev_priv->user_irq_lock); - i915_enable_irq(dev_priv, mask_reg); + i915_enable_irq(dev_priv, interrupt); DRM_SPINUNLOCK(&dev_priv->user_irq_lock); return 0; @@ -669,57 +652,38 @@ void i915_disable_vblank(struct drm_device *dev, int plane) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; int pipe = i915_get_pipe(dev, plane); u32 pipestat_reg = 0; - u32 mask_reg = 0; u32 pipestat; + u32 interrupt = 0; switch (pipe) { case 0: pipestat_reg = PIPEASTAT; - mask_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; + interrupt = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; break; case 1: pipestat_reg = PIPEBSTAT; - mask_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; + interrupt = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; break; default: DRM_ERROR("tried to disable vblank on non-existent pipe %d\n", pipe); - break; + return; } DRM_SPINLOCK(&dev_priv->user_irq_lock); - i915_disable_irq(dev_priv, mask_reg); + i915_disable_irq(dev_priv, interrupt); DRM_SPINUNLOCK(&dev_priv->user_irq_lock); - if (pipestat_reg) - { - pipestat = I915_READ (pipestat_reg); - pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | - PIPE_VBLANK_INTERRUPT_ENABLE); - /* - * Clear any pending status - */ - pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | - PIPE_VBLANK_INTERRUPT_STATUS); - I915_WRITE(pipestat_reg, pipestat); - (void)I915_READ(pipestat_reg); - } -} - -void i915_enable_interrupt (struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - - dev_priv->irq_mask_reg = ~0; - I915_WRITE(IMR, dev_priv->irq_mask_reg); - I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK); - (void)I915_READ(IER); - -#ifdef __linux__ - opregion_enable_asle(dev); -#endif - - dev_priv->irq_enabled = 1; + pipestat = I915_READ (pipestat_reg); + pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | + PIPE_VBLANK_INTERRUPT_ENABLE); + /* + * Clear any pending status + */ + pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS | + PIPE_VBLANK_INTERRUPT_STATUS); + I915_WRITE(pipestat_reg, pipestat); + (void)I915_READ(pipestat_reg); } /* Set the vblank monitor pipe @@ -919,7 +883,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; I915_WRITE(HWSTAM, 0xeffe); - I915_WRITE(IMR, 0x0); + I915_WRITE(IMR, 0xffffffff); I915_WRITE(IER, 0x0); } @@ -931,7 +895,6 @@ int i915_driver_irq_postinstall(struct drm_device * dev) INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); dev_priv->swaps_pending = 0; - dev_priv->user_irq_refcount = 0; dev_priv->irq_mask_reg = ~0; ret = drm_vblank_init(dev, num_pipes); @@ -941,7 +904,10 @@ int i915_driver_irq_postinstall(struct drm_device * dev) dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ - i915_enable_interrupt(dev); + I915_WRITE(IMR, dev_priv->irq_mask_reg); + I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK); + (void)I915_READ(IER); + DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); /* @@ -962,7 +928,6 @@ void i915_driver_irq_uninstall(struct drm_device * dev) dev_priv->vblank_pipe = 0; - dev_priv->irq_enabled = 0; I915_WRITE(HWSTAM, 0xffffffff); I915_WRITE(IMR, 0xffffffff); I915_WRITE(IER, 0x0); |