diff options
author | Alan Hourihane <alanh@tungstengraphics.com> | 2006-08-12 02:29:24 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2006-09-21 15:32:32 -0400 |
commit | c29b669caae4ed1630ef479e54bdde126a0378ec (patch) | |
tree | 6a1b68ea33fd6bcfcf921494df35bc532aaac7ad /drivers | |
parent | d000b486ea1633380e6224c03e94227db46567ad (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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/drm/drm_pciids.h | 4 | ||||
-rw-r--r-- | drivers/char/drm/i915_dma.c | 41 | ||||
-rw-r--r-- | drivers/char/drm/i915_drm.h | 6 | ||||
-rw-r--r-- | drivers/char/drm/i915_drv.h | 10 | ||||
-rw-r--r-- | drivers/char/drm/i915_irq.c | 16 |
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 | |||
410 | static void i915_emit_breadcrumb(drm_device_t *dev) | 428 | static 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) | |||
71 | static int i915_emit_irq(drm_device_t * dev) | 71 | static 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 | ||
91 | static int i915_wait_irq(drm_device_t * dev, int irq_nr) | 97 | static int i915_wait_irq(drm_device_t * dev, int irq_nr) |