Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c29b669c authored by Alan Hourihane's avatar Alan Hourihane Committed by Dave Airlie
Browse files

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: default avatarDave Airlie <airlied@linux.ie>
parent d000b486
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -287,5 +287,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}
+31 −10
Original line number Diff line number Diff line
@@ -31,6 +31,11 @@
#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,7 +352,7 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords)
	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;
@@ -395,6 +400,14 @@ static int i915_emit_box(drm_device_t * dev,
		return DRM_ERR(EINVAL);
	}

	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);
@@ -403,16 +416,24 @@ static int i915_emit_box(drm_device_t * dev,
		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);
+6 −0
Original line number Diff line number Diff line
@@ -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
+6 −4
Original line number Diff line number Diff line
@@ -146,9 +146,9 @@ extern void i915_mem_release(drm_device_t * dev,
#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;		\
@@ -157,7 +157,7 @@ extern void i915_mem_release(drm_device_t * dev,

#define OUT_RING(n) do {					\
	if (I915_VERBOSE) DRM_DEBUG("   OUT_RING %x\n", (int)(n));	\
	*(volatile unsigned int *)(virt + outring) = n;		\
	*(volatile unsigned int *)(virt + outring) = (n);	\
        outcount++;						\
	outring += 4;						\
	outring &= ringmask;					\
@@ -254,6 +254,8 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
#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)
+11 −5
Original line number Diff line number Diff line
@@ -71,21 +71,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
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;

	BEGIN_LP_RING(2);
	if (dev_priv->counter > 0x7FFFFFFFUL)
		dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;

	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)