The attached patches fix some issues with the vline handling in kms.

- 0001-drm-radeon-kms-r600-add-support-for-vline-relocs.patch
adds support for vline relocs for r6xx/r7xx hardware to the drm

- 0002-drm-radeon-kms-fix-some-bugs-in-vline-reloc.patch
Fixes some bugs in the vline handling for code in the drm for pre-r6xx chips

- 0001-kms-r600-add-support-for-vline-relocs.patch
Adds vline reloc support for r6xx/r6xx GPUs to xf86-video-ati for kms

Alex
From fc6f54267b9d4a4e41533c2ec72174acff4756eb Mon Sep 17 00:00:00 2001
From: Alex Deucher <alexdeuc...@gmail.com>
Date: Fri, 25 Sep 2009 16:35:11 -0400
Subject: [PATCH] drm/radeon/kms/r600: add support for vline relocs

Provides support for anti-tearing functionality
in the ddx.

Signed-off-by: Alex Deucher <alexdeuc...@gmail.com>
---
 drivers/gpu/drm/radeon/r500_reg.h   |    3 +
 drivers/gpu/drm/radeon/r600_cs.c    |  125 ++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/radeon/radeon_reg.h |    1 +
 3 files changed, 128 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h
index e1d5e03..868add6 100644
--- a/drivers/gpu/drm/radeon/r500_reg.h
+++ b/drivers/gpu/drm/radeon/r500_reg.h
@@ -445,6 +445,8 @@
 #define AVIVO_D1MODE_VBLANK_STATUS              0x6534
 #       define AVIVO_VBLANK_ACK                 (1 << 4)
 #define AVIVO_D1MODE_VLINE_START_END            0x6538
+#define AVIVO_D1MODE_VLINE_STATUS               0x653c
+#       define AVIVO_D1MODE_VLINE_STAT          (1 << 12)
 #define AVIVO_DxMODE_INT_MASK                   0x6540
 #       define AVIVO_D1MODE_INT_MASK            (1 << 0)
 #       define AVIVO_D2MODE_INT_MASK            (1 << 8)
@@ -502,6 +504,7 @@
 
 #define AVIVO_D2MODE_VBLANK_STATUS              0x6d34
 #define AVIVO_D2MODE_VLINE_START_END            0x6d38
+#define AVIVO_D2MODE_VLINE_STATUS               0x6d3c
 #define AVIVO_D2MODE_VIEWPORT_START             0x6d80
 #define AVIVO_D2MODE_VIEWPORT_SIZE              0x6d84
 #define AVIVO_D2MODE_EXT_OVERSCAN_LEFT_RIGHT    0x6d88
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index dd009da..20eb66d 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -177,13 +177,136 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p,
 	return 0;
 }
 
+/**
+ * r600_cs_packet_next_vline() - parse userspace VLINE packet
+ * @parser:		parser structure holding parsing context.
+ *
+ * Userspace sends a special sequence for VLINE waits.
+ * PACKET0 - VLINE_START_END + value
+ * PACKET3 - WAIT_REG_MEM poll vline status reg
+ * RELOC (P3) - crtc_id in reloc.
+ *
+ * This function parses this and relocates the VLINE START END
+ * and WAIT_REG_MEM packets to the correct crtc.
+ * It also detects a switched off crtc and nulls out the
+ * wait in that case.
+ */
+static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p)
+{
+	struct drm_mode_object *obj;
+	struct drm_crtc *crtc;
+	struct radeon_crtc *radeon_crtc;
+	struct radeon_cs_packet p3reloc, wait_reg_mem;
+	int crtc_id;
+	int r;
+	uint32_t header, h_idx, reg, wait_reg_mem_info;
+	volatile uint32_t *ib;
+
+	ib = p->ib->ptr;
+
+	/* parse the WAIT_REG_MEM */
+	r = r600_cs_packet_parse(p, &wait_reg_mem, p->idx);
+	if (r)
+		return r;
+
+	/* check its a WAIT_REG_MEM */
+	if (wait_reg_mem.type != PACKET_TYPE3 ||
+	    wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) {
+		DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n");
+		r = -EINVAL;
+		return r;
+	}
+
+	wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1);
+	/* bit 4 is reg (0) or mem (1) */
+	if (wait_reg_mem_info & 0x10) {
+		DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n");
+		r = -EINVAL;
+		return r;
+	}
+	/* waiting for value to be equal */
+	if ((wait_reg_mem_info & 0x7) != 0x3) {
+		DRM_ERROR("vline WAIT_REG_MEM function not equal\n");
+		r = -EINVAL;
+		return r;
+	}
+	if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != AVIVO_D1MODE_VLINE_STATUS) {
+		DRM_ERROR("vline WAIT_REG_MEM bad reg\n");
+		r = -EINVAL;
+		return r;
+	}
+
+	if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != AVIVO_D1MODE_VLINE_STAT) {
+		DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n");
+		r = -EINVAL;
+		return r;
+	}
+
+	/* jump over the NOP */
+	r = r600_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2);
+	if (r)
+		return r;
+
+	h_idx = p->idx - 2;
+	p->idx += wait_reg_mem.count + 2;
+	p->idx += p3reloc.count + 2;
+
+	header = radeon_get_ib_value(p, h_idx);
+	crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
+	reg = header >> 2;
+	mutex_lock(&p->rdev->ddev->mode_config.mutex);
+	obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
+	if (!obj) {
+		DRM_ERROR("cannot find crtc %d\n", crtc_id);
+		r = -EINVAL;
+		goto out;
+	}
+	crtc = obj_to_crtc(obj);
+	radeon_crtc = to_radeon_crtc(crtc);
+	crtc_id = radeon_crtc->crtc_id;
+
+	if (!crtc->enabled) {
+		/* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */
+		ib[h_idx + 2] = PACKET2(0);
+		ib[h_idx + 3] = PACKET2(0);
+		ib[h_idx + 4] = PACKET2(0);
+		ib[h_idx + 5] = PACKET2(0);
+		ib[h_idx + 6] = PACKET2(0);
+		ib[h_idx + 7] = PACKET2(0);
+		ib[h_idx + 8] = PACKET2(0);
+	} else if (crtc_id == 1) {
+		switch (reg) {
+		case AVIVO_D1MODE_VLINE_START_END:
+			header &= ~R600_CP_PACKET0_REG_MASK;
+			header |= AVIVO_D2MODE_VLINE_START_END >> 2;
+			break;
+		default:
+			DRM_ERROR("unknown crtc reloc\n");
+			r = -EINVAL;
+			goto out;
+		}
+		ib[h_idx] = header;
+		ib[h_idx + 4] = AVIVO_D2MODE_VLINE_STATUS >> 2;
+	}
+out:
+	mutex_unlock(&p->rdev->ddev->mode_config.mutex);
+	return r;
+}
+
 static int r600_packet0_check(struct radeon_cs_parser *p,
 				struct radeon_cs_packet *pkt,
 				unsigned idx, unsigned reg)
 {
+	int r;
+
 	switch (reg) {
 	case AVIVO_D1MODE_VLINE_START_END:
-	case AVIVO_D2MODE_VLINE_START_END:
+		r = r600_cs_packet_parse_vline(p);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+					idx, reg);
+			return r;
+		}
 		break;
 	default:
 		printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h
index 21da871..bfa1ab9 100644
--- a/drivers/gpu/drm/radeon/radeon_reg.h
+++ b/drivers/gpu/drm/radeon/radeon_reg.h
@@ -3333,6 +3333,7 @@
 #       define RADEON_CP_PACKET_MAX_DWORDS          (1 << 12)
 #       define RADEON_CP_PACKET0_REG_MASK           0x000007ff
 #       define R300_CP_PACKET0_REG_MASK             0x00001fff
+#       define R600_CP_PACKET0_REG_MASK             0x0000ffff
 #       define RADEON_CP_PACKET1_REG0_MASK          0x000007ff
 #       define RADEON_CP_PACKET1_REG1_MASK          0x003ff800
 
-- 
1.5.6.3

From adff3583f8b583ac8be66c04890361e2e77200d6 Mon Sep 17 00:00:00 2001
From: Alex Deucher <alexdeuc...@gmail.com>
Date: Fri, 25 Sep 2009 16:39:24 -0400
Subject: [PATCH] drm/radeon/kms: fix some bugs in vline reloc

- fix offset of NOP packet for parsing
- fix p->idx increments
- fix bad mask when updating crtc vline info

Signed-off-by: Alex Deucher <alexdeuc...@gmail.com>
---
 drivers/gpu/drm/radeon/r100.c |   11 +++++------
 1 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 9ab976d..d209914 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -968,13 +968,13 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
 	}
 
 	/* jump over the NOP */
-	r = r100_cs_packet_parse(p, &p3reloc, p->idx);
+	r = r100_cs_packet_parse(p, &p3reloc, p->idx + waitreloc.count + 2);
 	if (r)
 		return r;
 
 	h_idx = p->idx - 2;
-	p->idx += waitreloc.count;
-	p->idx += p3reloc.count;
+	p->idx += waitreloc.count + 2;
+	p->idx += p3reloc.count + 2;
 
 	header = radeon_get_ib_value(p, h_idx);
 	crtc_id = radeon_get_ib_value(p, h_idx + 5);
@@ -992,17 +992,16 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
 
 	if (!crtc->enabled) {
 		/* if the CRTC isn't enabled - we need to nop out the wait until */
-		
 		ib[h_idx + 2] = PACKET2(0);
 		ib[h_idx + 3] = PACKET2(0);
 	} else if (crtc_id == 1) {
 		switch (reg) {
 		case AVIVO_D1MODE_VLINE_START_END:
-			header &= R300_CP_PACKET0_REG_MASK;
+			header &= ~R300_CP_PACKET0_REG_MASK;
 			header |= AVIVO_D2MODE_VLINE_START_END >> 2;
 			break;
 		case RADEON_CRTC_GUI_TRIG_VLINE:
-			header &= R300_CP_PACKET0_REG_MASK;
+			header &= ~R300_CP_PACKET0_REG_MASK;
 			header |= RADEON_CRTC2_GUI_TRIG_VLINE >> 2;
 			break;
 		default:
-- 
1.5.6.3

From 0380a9cf98d34e88dd81370ade5525680ec89c02 Mon Sep 17 00:00:00 2001
From: Alex Deucher <alexdeuc...@gmail.com>
Date: Fri, 25 Sep 2009 16:46:43 -0400
Subject: [PATCH] kms/r600: add support for vline relocs

Signed-off-by: Alex Deucher <alexdeuc...@gmail.com>
---
 src/r6xx_accel.c |   37 +++++++++++++++++++++++++++++--------
 1 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c
index f5e6bce..8377ae5 100644
--- a/src/r6xx_accel.c
+++ b/src/r6xx_accel.c
@@ -318,12 +318,6 @@ void cp_wait_vline_sync(ScrnInfoPtr pScrn, drmBufPtr ib, PixmapPtr pPix,
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     uint32_t offset;
 
-    //XXX FIXME
-#if defined(XF86DRM_MODE)
-    if (info->cs)
-	return;
-#endif
-
     if (!crtc)
         return;
 
@@ -333,7 +327,10 @@ void cp_wait_vline_sync(ScrnInfoPtr pScrn, drmBufPtr ib, PixmapPtr pPix,
     if (!crtc->enabled)
         return;
 
-    {
+    if (info->cs) {
+        if (pPix != pScrn->pScreen->GetScreenPixmap(pScrn->pScreen))
+	    return;
+    } else {
 #ifdef USE_EXA
 	if (info->useEXA)
 	    offset = exaGetPixmapOffset(pPix);
@@ -352,10 +349,34 @@ void cp_wait_vline_sync(ScrnInfoPtr pScrn, drmBufPtr ib, PixmapPtr pPix,
     if (start > crtc->mode.VDisplay)
         return;
 
+#if defined(XF86DRM_MODE)
+    if (info->cs) {
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+	BEGIN_BATCH(11);
+	/* set the VLINE range */
+	EREG(ib, AVIVO_D1MODE_VLINE_START_END, /* this is just a marker */
+	     (start << AVIVO_D1MODE_VLINE_START_SHIFT) |
+	     (stop << AVIVO_D1MODE_VLINE_END_SHIFT));
+
+	/* tell the CP to poll the VLINE state register */
+	PACK3(ib, IT_WAIT_REG_MEM, 6);
+	E32(ib, IT_WAIT_REG | IT_WAIT_EQ);
+	E32(ib, IT_WAIT_ADDR(AVIVO_D1MODE_VLINE_STATUS));
+	E32(ib, 0);
+	E32(ib, 0);                          // Ref value
+	E32(ib, AVIVO_D1MODE_VLINE_STAT);    // Mask
+	E32(ib, 10);                         // Wait interval
+	/* add crtc reloc */
+	PACK3(ib, IT_NOP, 1);
+	E32(ib, drmmode_crtc->mode_crtc->crtc_id);
+	END_BATCH();
+    } else
+#endif
     {
 	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 
-	BEGIN_BATCH(10);
+	BEGIN_BATCH(9);
 	/* set the VLINE range */
 	EREG(ib, AVIVO_D1MODE_VLINE_START_END + radeon_crtc->crtc_offset,
 	     (start << AVIVO_D1MODE_VLINE_START_SHIFT) |
-- 
1.5.6.3

------------------------------------------------------------------------------
Come build with us! The BlackBerry&reg; Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9&#45;12, 2009. Register now&#33;
http://p.sf.net/sfu/devconf
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to