diff options
Diffstat (limited to 'shared-core')
| -rw-r--r-- | shared-core/drm_pciids.txt | 4 | ||||
| -rw-r--r-- | shared-core/i915_dma.c | 46 | ||||
| -rw-r--r-- | shared-core/i915_drm.h | 6 | ||||
| -rw-r--r-- | shared-core/i915_drv.h | 10 | ||||
| -rw-r--r-- | shared-core/i915_irq.c | 32 | 
5 files changed, 71 insertions, 27 deletions
| diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt index e4415c16..9ef2c001 100644 --- a/shared-core/drm_pciids.txt +++ b/shared-core/drm_pciids.txt @@ -271,6 +271,10 @@  0x8086 0x2592 0 "Intel i915GM"  0x8086 0x2772 0 "Intel i945G"  0x8086 0x27A2 0 "Intel i945GM" +0x8086 0x2972 0 "Intel i946GZ" +0x8086 0x2982 0 "Intel i965G" +0x8086 0x2992 0 "Intel i965Q" +0x8086 0x29A2 0 "Intel i965G"  [imagine]  0x105d 0x2309 IMAGINE_128 "Imagine 128" diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index ae0f55a2..39f7b407 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -31,6 +31,12 @@  #include "i915_drm.h"  #include "i915_drv.h" +#define IS_I965G(dev)  (dev->pdev->device == 0x2972 || \ +                        dev->pdev->device == 0x2982 || \ +                        dev->pdev->device == 0x2992 || \ +                        dev->pdev->device == 0x29A2) + +  /* Really want an OS-independent resettable timer.  Would like to have   * this loop run for (eg) 3 sec, but have the timer reset every time   * the head pointer changes, so that EBUSY only happens if the ring @@ -347,14 +353,15 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords)  	if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8)  		return DRM_ERR(EINVAL); -	BEGIN_LP_RING(((dwords+1)&~1)); +	BEGIN_LP_RING((dwords+1)&~1);  	for (i = 0; i < dwords;) {  		int cmd, sz; -		if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) -			return DRM_ERR(EINVAL); +	     if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) { +			return DRM_ERR(EINVAL); +	      }  		if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)  			return DRM_ERR(EINVAL); @@ -395,25 +402,40 @@ static int i915_emit_box(drm_device_t * dev,  		return DRM_ERR(EINVAL);  	} -	BEGIN_LP_RING(6); -	OUT_RING(GFX_OP_DRAWRECT_INFO); -	OUT_RING(DR1); -	OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); -	OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); -	OUT_RING(DR4); -	OUT_RING(0); -	ADVANCE_LP_RING(); +       if (IS_I965G(dev)) { +               BEGIN_LP_RING(4); +               OUT_RING(GFX_OP_DRAWRECT_INFO_I965); +               OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); +               OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); +               OUT_RING(DR4); +               ADVANCE_LP_RING(); +       } else { +               BEGIN_LP_RING(6); +               OUT_RING(GFX_OP_DRAWRECT_INFO); +               OUT_RING(DR1); +               OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); +               OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); +               OUT_RING(DR4); +               OUT_RING(0); +               ADVANCE_LP_RING(); +       }  	return 0;  } +/* XXX: Emitting the counter should really be moved to part of the IRQ + * emit.  For now, do it in both places: + */  static void i915_emit_breadcrumb(drm_device_t *dev)  {  	drm_i915_private_t *dev_priv = dev->dev_private;  	RING_LOCALS; -	dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; +       dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; + +       if (dev_priv->counter > 0x7FFFFFFFUL) +               dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;  	BEGIN_LP_RING(4);  	OUT_RING(CMD_STORE_DWORD_IDX); diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index 999b567c..41acd4e6 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -98,6 +98,12 @@ typedef struct _drm_i915_sarea {  	int rotated_size;  	int rotated_pitch;          int virtualX, virtualY; + +        unsigned int front_tiled; +        unsigned int back_tiled; +        unsigned int depth_tiled; +        unsigned int rotated_tiled; +        unsigned int rotated2_tiled;  } drm_i915_sarea_t;  /* Flags for perf_boxes diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 0c3281d4..550e386f 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -146,9 +146,9 @@ extern void i915_mem_release(drm_device_t * dev,  #define BEGIN_LP_RING(n) do {				\  	if (I915_VERBOSE)				\  		DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n",	\ -			  n, __FUNCTION__);		\ -	if (dev_priv->ring.space < n*4)			\ -		i915_wait_ring(dev, n*4, __FUNCTION__);		\ +	                         (n), __FUNCTION__);           \ +       if (dev_priv->ring.space < (n)*4)                       \ +               i915_wait_ring(dev, (n)*4, __FUNCTION__);               \  	outcount = 0;					\  	outring = dev_priv->ring.tail;			\  	ringmask = dev_priv->ring.tail_mask;		\ @@ -157,7 +157,7 @@ extern void i915_mem_release(drm_device_t * dev,  #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;					\ @@ -254,6 +254,8 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);  #define GFX_OP_DESTBUFFER_VARS   ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)  #define GFX_OP_DRAWRECT_INFO     ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) +#define GFX_OP_DRAWRECT_INFO_I965  ((0x7900<<16)|0x2) +  #define MI_BATCH_BUFFER 	((0x30<<23)|1)  #define MI_BATCH_BUFFER_START 	(0x31<<23)  #define MI_BATCH_BUFFER_END 	(0xA<<23) diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index df4ce4e2..64d89a75 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -70,22 +70,32 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)  static int i915_emit_irq(drm_device_t * dev)  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	u32 ret; -	RING_LOCALS; +	 +       drm_i915_private_t *dev_priv = dev->dev_private; +       RING_LOCALS; -	i915_kernel_lost_context(dev); +       i915_kernel_lost_context(dev); -	DRM_DEBUG("%s\n", __FUNCTION__); +       DRM_DEBUG("%s\n", __FUNCTION__); -	ret = dev_priv->counter; +       dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; + +       if (dev_priv->counter > 0x7FFFFFFFUL) +               dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; + +       BEGIN_LP_RING(6); +       OUT_RING(CMD_STORE_DWORD_IDX); +       OUT_RING(20); +       OUT_RING(dev_priv->counter); + +       OUT_RING(0); +       OUT_RING(0); +       OUT_RING(GFX_OP_USER_INTERRUPT); +       ADVANCE_LP_RING(); + +       return dev_priv->counter; -	BEGIN_LP_RING(2); -	OUT_RING(0); -	OUT_RING(GFX_OP_USER_INTERRUPT); -	ADVANCE_LP_RING(); -	return ret;  }  static int i915_wait_irq(drm_device_t * dev, int irq_nr) | 
