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/char/drm/i915_dma.c | |
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/char/drm/i915_dma.c')
-rw-r--r-- | drivers/char/drm/i915_dma.c | 41 |
1 files changed, 31 insertions, 10 deletions
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); |