Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 716

kernel-2.6.18-238.el5.src.rpm


commit 48cb9aceed782a4e9c557f30429e65f845dd777d
Author: Alan Hourihane <alanh@tungstengraphics.com>
Date:   Tue Aug 8 15:05:54 2006 -0700

    Add support for Intel i965G chipsets.
    
    This is a patch prepared by Guangdeng Liao based off of Tungsten Graphics's
    final code drop.

---
 drivers/char/drm/drm_pciids.h |    4 	4 +	0 -	0 !
 drivers/char/drm/i915_dma.c   |   47 	35 +	12 -	0 !
 drivers/char/drm/i915_drm.h   |    6 	6 +	0 -	0 !
 drivers/char/drm/i915_drv.h   |   14 	8 +	6 -	0 !
 drivers/char/drm/i915_irq.c   |   18 	14 +	4 -	0 !
 5 files changed, 67 insertions(+), 22 deletions(-)

Index: linux-2.6.17/drivers/char/drm/i915_dma.c
===================================================================
--- linux-2.6.17.orig/drivers/char/drm/i915_dma.c	2006-08-10 11:43:30.000000000 +0200
+++ linux-2.6.17/drivers/char/drm/i915_dma.c	2006-08-10 11:50:44.000000000 +0200
@@ -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 *
 	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,24 +402,40 @@ static int i915_emit_box(drm_device_t * 
 		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);
Index: linux-2.6.17/drivers/char/drm/i915_drm.h
===================================================================
--- linux-2.6.17.orig/drivers/char/drm/i915_drm.h	2006-08-10 11:43:30.000000000 +0200
+++ linux-2.6.17/drivers/char/drm/i915_drm.h	2006-08-10 11:46:31.000000000 +0200
@@ -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
Index: linux-2.6.17/drivers/char/drm/i915_drv.h
===================================================================
--- linux-2.6.17.orig/drivers/char/drm/i915_drv.h	2006-08-10 11:43:30.000000000 +0200
+++ linux-2.6.17/drivers/char/drm/i915_drv.h	2006-08-10 11:50:44.000000000 +0200
@@ -137,14 +137,14 @@ extern void i915_mem_release(drm_device_
 #define I915_VERBOSE 0
 
 #define RING_LOCALS	unsigned int outring, ringmask, outcount; \
-                        volatile char *virt;
+			volatile char *virt;
 
 #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;		\
@@ -153,8 +153,8 @@ extern void i915_mem_release(drm_device_
 
 #define OUT_RING(n) do {					\
 	if (I915_VERBOSE) DRM_DEBUG("   OUT_RING %x\n", (int)(n));	\
-	*(volatile unsigned int *)(virt + outring) = n;		\
-        outcount++;						\
+	*(volatile unsigned int *)(virt + outring) = (n);		\
+	outcount++;						\
 	outring += 4;						\
 	outring &= ringmask;					\
 } while (0)
@@ -250,6 +250,8 @@ extern int i915_wait_ring(drm_device_t *
 #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)
Index: linux-2.6.17/drivers/char/drm/i915_irq.c
===================================================================
--- linux-2.6.17.orig/drivers/char/drm/i915_irq.c	2006-08-10 11:43:30.000000000 +0200
+++ linux-2.6.17/drivers/char/drm/i915_irq.c	2006-08-10 11:50:54.000000000 +0200
@@ -69,22 +69,32 @@ irqreturn_t i915_driver_irq_handler(DRM_
 
 static int i915_emit_irq(drm_device_t * dev)
 {
+
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	u32 ret;
 	RING_LOCALS;
 
 	i915_kernel_lost_context(dev);
 
 	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(2);
+	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 ret;
+	return dev_priv->counter;
+
+
 }
 
 static int i915_wait_irq(drm_device_t * dev, int irq_nr)
Index: linux-2.6.17/drivers/char/drm/drm_pciids.h
===================================================================
--- linux-2.6.17.orig/drivers/char/drm/drm_pciids.h	2006-06-18 03:49:35.000000000 +0200
+++ linux-2.6.17/drivers/char/drm/drm_pciids.h	2006-08-10 11:48:36.000000000 +0200
@@ -285,5 +285,9 @@
 	{0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0x8086, 0x27a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+	{0x8086, 0x2972, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+	{0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+	{0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+	{0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0, 0, 0}