aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@tungstengraphics.com>2006-08-12 02:29:24 -0400
committerDave Airlie <airlied@linux.ie>2006-09-21 15:32:32 -0400
commitc29b669caae4ed1630ef479e54bdde126a0378ec (patch)
tree6a1b68ea33fd6bcfcf921494df35bc532aaac7ad
parentd000b486ea1633380e6224c03e94227db46567ad (diff)
drm: Add support for Intel i965G chipsets.
This is a patch prepared by Guangdeng Liao based off of Tungsten Graphics's final code drop. From: Alan Hourihane <alanh@tungstengraphics.com> Signed-off-by: Dave Airlie <airlied@linux.ie>
-rw-r--r--drivers/char/drm/drm_pciids.h4
-rw-r--r--drivers/char/drm/i915_dma.c41
-rw-r--r--drivers/char/drm/i915_drm.h6
-rw-r--r--drivers/char/drm/i915_drv.h10
-rw-r--r--drivers/char/drm/i915_irq.c16
5 files changed, 58 insertions, 19 deletions
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index 8c16cde91133..beeeb0c61e4a 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -287,5 +287,9 @@
287 {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 287 {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
288 {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 288 {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
289 {0x8086, 0x27a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 289 {0x8086, 0x27a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
290 {0x8086, 0x2972, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
291 {0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
292 {0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
293 {0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
290 {0, 0, 0} 294 {0, 0, 0}
291 295
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index a94233bdbc0e..99e9d07409e4 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -31,6 +31,11 @@
31#include "i915_drm.h" 31#include "i915_drm.h"
32#include "i915_drv.h" 32#include "i915_drv.h"
33 33
34#define IS_I965G(dev) (dev->pdev->device == 0x2972 || \
35 dev->pdev->device == 0x2982 || \
36 dev->pdev->device == 0x2992 || \
37 dev->pdev->device == 0x29A2)
38
34/* Really want an OS-independent resettable timer. Would like to have 39/* Really want an OS-independent resettable timer. Would like to have
35 * this loop run for (eg) 3 sec, but have the timer reset every time 40 * this loop run for (eg) 3 sec, but have the timer reset every time
36 * the head pointer changes, so that EBUSY only happens if the ring 41 * the head pointer changes, so that EBUSY only happens if the ring
@@ -347,7 +352,7 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords)
347 if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) 352 if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8)
348 return DRM_ERR(EINVAL); 353 return DRM_ERR(EINVAL);
349 354
350 BEGIN_LP_RING(((dwords+1)&~1)); 355 BEGIN_LP_RING((dwords+1)&~1);
351 356
352 for (i = 0; i < dwords;) { 357 for (i = 0; i < dwords;) {
353 int cmd, sz; 358 int cmd, sz;
@@ -395,24 +400,40 @@ static int i915_emit_box(drm_device_t * dev,
395 return DRM_ERR(EINVAL); 400 return DRM_ERR(EINVAL);
396 } 401 }
397 402
398 BEGIN_LP_RING(6); 403 if (IS_I965G(dev)) {
399 OUT_RING(GFX_OP_DRAWRECT_INFO); 404 BEGIN_LP_RING(4);
400 OUT_RING(DR1); 405 OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
401 OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); 406 OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
402 OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); 407 OUT_RING(((box.x2 - 1) & 0xffff) ((box.y2 - 1) << 16));
403 OUT_RING(DR4); 408 OUT_RING(DR4);
404 OUT_RING(0); 409 ADVANCE_LP_RING();
405 ADVANCE_LP_RING(); 410 } else {
411 BEGIN_LP_RING(6);
412 OUT_RING(GFX_OP_DRAWRECT_INFO);
413 OUT_RING(DR1);
414 OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
415 OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
416 OUT_RING(DR4);
417 OUT_RING(0);
418 ADVANCE_LP_RING();
419 }
406 420
407 return 0; 421 return 0;
408} 422}
409 423
424/* XXX: Emitting the counter should really be moved to part of the IRQ
425 * emit. For now, do it in both places:
426 */
427
410static void i915_emit_breadcrumb(drm_device_t *dev) 428static void i915_emit_breadcrumb(drm_device_t *dev)
411{ 429{
412 drm_i915_private_t *dev_priv = dev->dev_private; 430 drm_i915_private_t *dev_priv = dev->dev_private;
413 RING_LOCALS; 431 RING_LOCALS;
414 432
415 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; 433 dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
434
435 if (dev_priv->counter > 0x7FFFFFFFUL)
436 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
416 437
417 BEGIN_LP_RING(4); 438 BEGIN_LP_RING(4);
418 OUT_RING(CMD_STORE_DWORD_IDX); 439 OUT_RING(CMD_STORE_DWORD_IDX);
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h
index 5aa3e0e3bb45..6af83e613f27 100644
--- a/drivers/char/drm/i915_drm.h
+++ b/drivers/char/drm/i915_drm.h
@@ -98,6 +98,12 @@ typedef struct _drm_i915_sarea {
98 int rotated_size; 98 int rotated_size;
99 int rotated_pitch; 99 int rotated_pitch;
100 int virtualX, virtualY; 100 int virtualX, virtualY;
101
102 unsigned int front_tiled;
103 unsigned int back_tiled;
104 unsigned int depth_tiled;
105 unsigned int rotated_tiled;
106 unsigned int rotated2_tiled;
101} drm_i915_sarea_t; 107} drm_i915_sarea_t;
102 108
103/* Flags for perf_boxes 109/* Flags for perf_boxes
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 2d565031c002..fdc2bf192714 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -146,9 +146,9 @@ extern void i915_mem_release(drm_device_t * dev,
146#define BEGIN_LP_RING(n) do { \ 146#define BEGIN_LP_RING(n) do { \
147 if (I915_VERBOSE) \ 147 if (I915_VERBOSE) \
148 DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \ 148 DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \
149 n, __FUNCTION__); \ 149 (n), __FUNCTION__); \
150 if (dev_priv->ring.space < n*4) \ 150 if (dev_priv->ring.space < (n)*4) \
151 i915_wait_ring(dev, n*4, __FUNCTION__); \ 151 i915_wait_ring(dev, (n)*4, __FUNCTION__); \
152 outcount = 0; \ 152 outcount = 0; \
153 outring = dev_priv->ring.tail; \ 153 outring = dev_priv->ring.tail; \
154 ringmask = dev_priv->ring.tail_mask; \ 154 ringmask = dev_priv->ring.tail_mask; \
@@ -157,7 +157,7 @@ extern void i915_mem_release(drm_device_t * dev,
157 157
158#define OUT_RING(n) do { \ 158#define OUT_RING(n) do { \
159 if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ 159 if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
160 *(volatile unsigned int *)(virt + outring) = n; \ 160 *(volatile unsigned int *)(virt + outring) = (n); \
161 outcount++; \ 161 outcount++; \
162 outring += 4; \ 162 outring += 4; \
163 outring &= ringmask; \ 163 outring &= ringmask; \
@@ -254,6 +254,8 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
254#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) 254#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
255#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) 255#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
256 256
257#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
258
257#define MI_BATCH_BUFFER ((0x30<<23)|1) 259#define MI_BATCH_BUFFER ((0x30<<23)|1)
258#define MI_BATCH_BUFFER_START (0x31<<23) 260#define MI_BATCH_BUFFER_START (0x31<<23)
259#define MI_BATCH_BUFFER_END (0xA<<23) 261#define MI_BATCH_BUFFER_END (0xA<<23)
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index cd96cfa430db..0d4a162aa385 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -71,21 +71,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
71static int i915_emit_irq(drm_device_t * dev) 71static int i915_emit_irq(drm_device_t * dev)
72{ 72{
73 drm_i915_private_t *dev_priv = dev->dev_private; 73 drm_i915_private_t *dev_priv = dev->dev_private;
74 u32 ret;
75 RING_LOCALS; 74 RING_LOCALS;
76 75
77 i915_kernel_lost_context(dev); 76 i915_kernel_lost_context(dev);
78 77
79 DRM_DEBUG("%s\n", __FUNCTION__); 78 DRM_DEBUG("%s\n", __FUNCTION__);
80 79
81 ret = dev_priv->counter; 80 dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
82 81
83 BEGIN_LP_RING(2); 82 if (dev_priv->counter > 0x7FFFFFFFUL)
83 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
84
85 BEGIN_LP_RING(6);
86 OUT_RING(CMD_STORE_DWORD_IDX);
87 OUT_RING(20);
88 OUT_RING(dev_priv->counter);
89 OUT_RING(0);
84 OUT_RING(0); 90 OUT_RING(0);
85 OUT_RING(GFX_OP_USER_INTERRUPT); 91 OUT_RING(GFX_OP_USER_INTERRUPT);
86 ADVANCE_LP_RING(); 92 ADVANCE_LP_RING();
87 93
88 return ret; 94 return dev_priv->counter;
89} 95}
90 96
91static int i915_wait_irq(drm_device_t * dev, int irq_nr) 97static int i915_wait_irq(drm_device_t * dev, int irq_nr)