drm/i915: use PIPE_CONTROL instruction on 965+
Subsystems (2)
PATCH 1/1 drm/i915: use PIPE_CONTROL instruction on 965+
...and hang your box even faster.
Signature · 1 line
Jesse Barnes, Intel Open Source Technology Center
drivers/gpu/drm/i915/i915_drv.h +3 -0
@@ -240,11 +240,14 @@ typedef struct drm_i915_private {drm_dma_handle_t *status_page_dmah;void *hw_status_page; +void *seqno_page;dma_addr_t dma_status_page;uint32_t counter;unsigned int status_gfx_addr; +unsigned int seqno_gfx_addr;drm_local_map_t hws_map;struct drm_gem_object *hws_obj; +struct drm_gem_object *seqno_obj;struct drm_gem_object *pwrctx;struct resource mch_res;
drivers/gpu/drm/i915/i915_gem.c +105 -27
183 lines not on this page · raw message
drivers/gpu/drm/i915/i915_irq.c +27 -10
@@ -51,9 +51,6 @@ I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT | \ I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) -/** Interrupts that we mask and unmask at runtime. */ -#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) -#define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\ PIPE_VBLANK_INTERRUPT_STATUS)
@@ -352,7 +349,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)READ_BREADCRUMB (dev_priv); } -if (gt_iir >_USER_INTERRUPT ) { +if (gt_iir >_PIPE_NOTIFY ) {u32 seqno =i915_get_gem_seqno (dev); dev_priv->mm.irq_gem_seqno = seqno;trace_i915_gem_request_complete (dev, seqno);
@@ -361,6 +358,9 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)mod_timer (&dev_priv->hangcheck_timer, jiffies +DRM_I915_HANGCHECK_PERIOD ); } +if (gt_iir >_SYNC_STATUS ) +DRM_ERROR ("sync status interrupt\n" ); +if (de_iir &DE_GSE )ironlake_opregion_gse_intr (dev);
@@ -1005,13 +1005,19 @@ void i915_user_irq_get(struct drm_device *dev) {drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;unsigned long irqflags; +u32 irq; + +if (IS_I965G (dev)) + irq =I915_PIPE_CONTROL_NOTIFY_INTERRUPT ; +else + irq =I915_USER_INTERRUPT ;spin_lock_irqsave (&dev_priv->user_irq_lock, irqflags);if (dev->irq_enabled && (++dev_priv->user_irq_refcount ==1 )) {if (HAS_PCH_SPLIT (dev)) -ironlake_enable_graphics_irq (dev_priv,GT_USER_INTERRUPT ); +ironlake_enable_graphics_irq (dev_priv,GT_SYNC_STATUS |GT_PIPE_NOTIFY );else -i915_enable_irq (dev_priv,I915_USER_INTERRUPT ); +i915_enable_irq (dev_priv, irq); }spin_unlock_irqrestore (&dev_priv->user_irq_lock, irqflags); }
@@ -1020,14 +1026,20 @@ void i915_user_irq_put(struct drm_device *dev) {drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;unsigned long irqflags; +u32 irq; + +if (IS_I965G (dev)) + irq =I915_PIPE_CONTROL_NOTIFY_INTERRUPT ; +else + irq =I915_USER_INTERRUPT ;spin_lock_irqsave (&dev_priv->user_irq_lock, irqflags);BUG_ON (dev->irq_enabled && dev_priv->user_irq_refcount <=0 );if (dev->irq_enabled && (--dev_priv->user_irq_refcount ==0 )) {if (HAS_PCH_SPLIT (dev)) -ironlake_disable_graphics_irq (dev_priv,GT_USER_INTERRUPT ); +ironlake_disable_graphics_irq (dev_priv,GT_SYNC_STATUS |GT_PIPE_NOTIFY );else -i915_disable_irq (dev_priv,I915_USER_INTERRUPT ); +i915_disable_irq (dev_priv, irq); }spin_unlock_irqrestore (&dev_priv->user_irq_lock, irqflags); }
@@ -1309,7 +1321,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)/* enable kind of interrupts always enabled */ u32 display_mask =DE_MASTER_IRQ_CONTROL |DE_GSE |DE_PCH_EVENT |DE_PLANEA_FLIP_DONE |DE_PLANEB_FLIP_DONE ; -u32 render_mask =GT_USER_INTERRUPT ; +u32 render_mask =GT_SYNC_STATUS |GT_PIPE_NOTIFY ;u32 hotplug_mask =SDE_CRT_HOTPLUG |SDE_PORTB_HOTPLUG |SDE_PORTC_HOTPLUG |SDE_PORTD_HOTPLUG ;
@@ -1383,7 +1395,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev)int i915_driver_irq_postinstall (struct drm_device *dev) {drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; -u32 enable_mask =I915_INTERRUPT_ENABLE_FIX |I915_INTERRUPT_ENABLE_VAR ; +u32 enable_mask =I915_INTERRUPT_ENABLE_FIX ;u32 error_mask;DRM_INIT_WAITQUEUE (&dev_priv->irq_queue);
@@ -1393,6 +1405,11 @@ int i915_driver_irq_postinstall(struct drm_device *dev)if (HAS_PCH_SPLIT (dev))return ironlake_irq_postinstall (dev); +if (IS_I965G (dev)) + enable_mask |=I915_PIPE_CONTROL_NOTIFY_INTERRUPT ; +else + enable_mask |=I915_USER_INTERRUPT ; +/* Unmask the interrupts that we always want on. */ dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX ;
drivers/gpu/drm/i915/i915_reg.h +9 -0
@@ -230,6 +230,14 @@#define ASYNC_FLIP (1<<22)#define DISPLAY_PLANE_A (0<<20)#define DISPLAY_PLANE_B (1<<20) +#define GFX_OP_PIPE_CONTROL ((0x3<<29)|(0x3<<27)|(0x2<<24)|2) +#define PIPE_CONTROL_QW_WRITE (1<<14) +#define PIPE_CONTROL_WC_FLUSH (1<<12) +#define PIPE_CONTROL_IS_FLUSH (1<<11)/* MBZ on Ironlake */ +#define PIPE_CONTROL_TC_FLUSH (1<<10)/* GM45+ only */ +#define PIPE_CONTROL_ISP_DIS (1<<9) +#define PIPE_CONTROL_NOTIFY (1<<8) +#define PIPE_CONTROL_GLOBAL_GTT (1<<2)/* in addr dword */ /* * Fence registers
@@ -2339,6 +2347,7 @@#define DEIER 0x4400c/* GT interrupt */ +#define GT_PIPE_NOTIFY (1 << 4)#define GT_SYNC_STATUS (1 << 2)#define GT_USER_INTERRUPT (1 << 0)