aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/i915_dma.c
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 /drivers/char/drm/i915_dma.c
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>
Diffstat (limited to 'drivers/char/drm/i915_dma.c')
-rw-r--r--drivers/char/drm/i915_dma.c41
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
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);