Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Oct 2009 16:35:47 +0000 (UTC)
From:      Robert Noland <rnoland@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r198686 - in stable/7/sys: . conf contrib/pf dev/drm modules/drm/radeon
Message-ID:  <200910301635.n9UGZlB7051367@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rnoland
Date: Fri Oct 30 16:35:47 2009
New Revision: 198686
URL: http://svn.freebsd.org/changeset/base/198686

Log:
  MFC r196470-196471,197154-197155,197603-197606
  
  Sync radeon drm support
  
  This adds kernel support for r6/7xx 3D.

Added:
  stable/7/sys/dev/drm/r600_blit.c
     - copied, changed from r196470, head/sys/dev/drm/r600_blit.c
  stable/7/sys/dev/drm/radeon_cs.c
     - copied, changed from r196470, head/sys/dev/drm/radeon_cs.c
Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/conf/files
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/drm/drm_pciids.h
  stable/7/sys/dev/drm/r600_cp.c
  stable/7/sys/dev/drm/radeon_cp.c
  stable/7/sys/dev/drm/radeon_drm.h
  stable/7/sys/dev/drm/radeon_drv.h
  stable/7/sys/dev/drm/radeon_irq.c
  stable/7/sys/dev/drm/radeon_state.c
  stable/7/sys/modules/drm/radeon/Makefile

Modified: stable/7/sys/conf/files
==============================================================================
--- stable/7/sys/conf/files	Fri Oct 30 16:32:35 2009	(r198685)
+++ stable/7/sys/conf/files	Fri Oct 30 16:35:47 2009	(r198686)
@@ -757,8 +757,10 @@ dev/drm/r128_irq.c		optional r128drm
 dev/drm/r128_state.c		optional r128drm \
 	compile-with "${NORMAL_C} -finline-limit=13500"
 dev/drm/r300_cmdbuf.c		optional radeondrm
+dev/drm/r600_blit.c		optional radeondrm
 dev/drm/r600_cp.c		optional radeondrm
 dev/drm/radeon_cp.c		optional radeondrm
+dev/drm/radeon_cs.c		optional radeondrm
 dev/drm/radeon_drv.c		optional radeondrm
 dev/drm/radeon_irq.c		optional radeondrm
 dev/drm/radeon_mem.c		optional radeondrm

Modified: stable/7/sys/dev/drm/drm_pciids.h
==============================================================================
--- stable/7/sys/dev/drm/drm_pciids.h	Fri Oct 30 16:32:35 2009	(r198685)
+++ stable/7/sys/dev/drm/drm_pciids.h	Fri Oct 30 16:35:47 2009	(r198686)
@@ -338,6 +338,7 @@
 	{0x1002, 0x9440, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \
 	{0x1002, 0x9441, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4870 X2"}, \
 	{0x1002, 0x9442, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \
+	{0x1002, 0x9443, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4850 X2"}, \
 	{0x1002, 0x944C, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \
 	{0x1002, 0x9450, CHIP_RV770|RADEON_NEW_MEMMAP, "AMD FireStream 9270"}, \
 	{0x1002, 0x9452, CHIP_RV770|RADEON_NEW_MEMMAP, "AMD FireStream 9250"}, \

Copied and modified: stable/7/sys/dev/drm/r600_blit.c (from r196470, head/sys/dev/drm/r600_blit.c)
==============================================================================
--- head/sys/dev/drm/r600_blit.c	Sun Aug 23 14:55:57 2009	(r196470, copy source)
+++ stable/7/sys/dev/drm/r600_blit.c	Fri Oct 30 16:35:47 2009	(r198686)
@@ -1734,6 +1734,8 @@ r600_blit_copy(struct drm_device *dev,
 
 			if (!src_x && !dst_x) {
 				h = (cur_size / max_bytes);
+				if (h > 8192)
+					h = 8192;
 				if (h == 0)
 					h = 1;
 				else
@@ -1805,8 +1807,8 @@ r600_blit_copy(struct drm_device *dev,
 			vb += 12;
 			dev_priv->blit_vb->used += 12 * 4;
 
-			src_gpu_addr += cur_size;
-			dst_gpu_addr += cur_size;
+			src_gpu_addr += cur_size * h;
+			dst_gpu_addr += cur_size * h;
 			size_bytes -= cur_size * h;
 		}
 	} else {
@@ -1822,6 +1824,8 @@ r600_blit_copy(struct drm_device *dev,
 
 			if (!src_x && !dst_x) {
 				h = (cur_size / max_bytes);
+				if (h > 8192)
+					h = 8192;
 				if (h == 0)
 					h = 1;
 				else
@@ -1872,7 +1876,7 @@ r600_blit_copy(struct drm_device *dev,
 
 			/* dst */
 			set_render_target(dev_priv, COLOR_8_8_8_8,
-					  dst_x + cur_size, h,
+					  (dst_x + cur_size) / 4, h,
 					  dst_gpu_addr);
 
 			/* scissors */
@@ -1894,8 +1898,8 @@ r600_blit_copy(struct drm_device *dev,
 			vb += 12;
 			dev_priv->blit_vb->used += 12 * 4;
 
-			src_gpu_addr += cur_size;
-			dst_gpu_addr += cur_size;
+			src_gpu_addr += cur_size * h;
+			dst_gpu_addr += cur_size * h;
 			size_bytes -= cur_size * h;
 		}
 	}

Modified: stable/7/sys/dev/drm/r600_cp.c
==============================================================================
--- stable/7/sys/dev/drm/r600_cp.c	Fri Oct 30 16:32:35 2009	(r198685)
+++ stable/7/sys/dev/drm/r600_cp.c	Fri Oct 30 16:35:47 2009	(r198686)
@@ -1843,6 +1843,7 @@ int r600_do_init_cp(struct drm_device *d
 	 */
 	dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1;
 
+	dev_priv->do_boxes = 0;
 	dev_priv->cp_mode = init->cp_mode;
 
 	/* We don't support anything other than bus-mastering ring mode,
@@ -2100,6 +2101,8 @@ int r600_do_init_cp(struct drm_device *d
 	r600_do_engine_reset(dev);
 	r600_test_writeback(dev_priv);
 
+	r600_cs_init(dev);
+
 	return 0;
 }
 
@@ -2232,3 +2235,135 @@ int r600_cp_dispatch_indirect(struct drm
 
 	return 0;
 }
+
+void r600_cp_dispatch_swap(struct drm_device * dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+	int nbox = sarea_priv->nbox;
+	struct drm_clip_rect *pbox = sarea_priv->boxes;
+	int i, cpp, src_pitch, dst_pitch;
+	uint64_t src, dst;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	if (dev_priv->color_fmt == RADEON_COLOR_FORMAT_ARGB8888)
+		cpp = 4;
+	else
+		cpp = 2;
+
+	if (dev_priv->sarea_priv->pfCurrentPage == 0) {
+		src_pitch = dev_priv->back_pitch;
+		dst_pitch = dev_priv->front_pitch;
+		src = dev_priv->back_offset + dev_priv->fb_location;
+		dst = dev_priv->front_offset + dev_priv->fb_location;
+	} else {
+		src_pitch = dev_priv->front_pitch;
+		dst_pitch = dev_priv->back_pitch;
+		src = dev_priv->front_offset + dev_priv->fb_location;
+		dst = dev_priv->back_offset + dev_priv->fb_location;
+	}
+
+	if (r600_prepare_blit_copy(dev)) {
+		DRM_ERROR("unable to allocate vertex buffer for swap buffer\n");
+		return;
+	}
+	for (i = 0; i < nbox; i++) {
+		int x = pbox[i].x1;
+		int y = pbox[i].y1;
+		int w = pbox[i].x2 - x;
+		int h = pbox[i].y2 - y;
+
+		DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h);
+
+		r600_blit_swap(dev,
+			       src, dst,
+			       x, y, x, y, w, h,
+			       src_pitch, dst_pitch, cpp);
+	}
+	r600_done_blit_copy(dev);
+
+	/* Increment the frame counter.  The client-side 3D driver must
+	 * throttle the framerate by waiting for this value before
+	 * performing the swapbuffer ioctl.
+	 */
+	dev_priv->sarea_priv->last_frame++;
+
+	BEGIN_RING(3);
+	R600_FRAME_AGE(dev_priv->sarea_priv->last_frame);
+	ADVANCE_RING();
+}
+
+int r600_cp_dispatch_texture(struct drm_device * dev,
+			     struct drm_file *file_priv,
+			     drm_radeon_texture_t * tex,
+			     drm_radeon_tex_image_t * image)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	struct drm_buf *buf;
+	u32 *buffer;
+	const u8 __user *data;
+	int size, pass_size;
+	u64 src_offset, dst_offset;
+
+	if (!radeon_check_offset(dev_priv, tex->offset)) {
+		DRM_ERROR("Invalid destination offset\n");
+		return -EINVAL;
+	}
+
+	/* this might fail for zero-sized uploads - are those illegal? */
+	if (!radeon_check_offset(dev_priv, tex->offset + tex->height * tex->pitch - 1)) {
+		DRM_ERROR("Invalid final destination offset\n");
+		return -EINVAL;
+	}
+
+	size = tex->height * tex->pitch;
+
+	if (size == 0)
+		return 0;
+
+	dst_offset = tex->offset;
+
+	r600_prepare_blit_copy(dev);
+	do {
+		data = (const u8 __user *)image->data;
+		pass_size = size;
+
+		buf = radeon_freelist_get(dev);
+		if (!buf) {
+			DRM_DEBUG("EAGAIN\n");
+			if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image)))
+				return -EFAULT;
+			return -EAGAIN;
+		}
+
+		if (pass_size > buf->total)
+			pass_size = buf->total;
+
+		/* Dispatch the indirect buffer.
+		 */
+		buffer =
+		    (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
+
+		if (DRM_COPY_FROM_USER(buffer, data, pass_size)) {
+			DRM_ERROR("EFAULT on pad, %d bytes\n", pass_size);
+			return -EFAULT;
+		}
+
+		buf->file_priv = file_priv;
+		buf->used = pass_size;
+		src_offset = dev_priv->gart_buffers_offset + buf->offset;
+
+		r600_blit_copy(dev, src_offset, dst_offset, pass_size);
+
+		radeon_cp_discard_buffer(dev, buf);
+
+		/* Update the input parameters for next time */
+		image->data = (const u8 __user *)image->data + pass_size;
+		dst_offset += pass_size;
+		size -= pass_size;
+	} while (size > 0);
+	r600_done_blit_copy(dev);
+
+	return 0;
+}

Modified: stable/7/sys/dev/drm/radeon_cp.c
==============================================================================
--- stable/7/sys/dev/drm/radeon_cp.c	Fri Oct 30 16:32:35 2009	(r198685)
+++ stable/7/sys/dev/drm/radeon_cp.c	Fri Oct 30 16:35:47 2009	(r198686)
@@ -408,6 +408,15 @@ static void radeon_init_pipes(drm_radeon
 {
 	uint32_t gb_tile_config, gb_pipe_sel = 0;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) {
+		uint32_t z_pipe_sel = RADEON_READ(RV530_GB_PIPE_SELECT2);
+		if ((z_pipe_sel & 3) == 3)
+			dev_priv->num_z_pipes = 2;
+		else
+			dev_priv->num_z_pipes = 1;
+	} else
+		dev_priv->num_z_pipes = 1;
+
 	/* RS4xx/RS6xx/R4xx/R5xx */
 	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
 		gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
@@ -2060,6 +2069,8 @@ int radeon_driver_load(struct drm_device
 	else
 		dev_priv->flags |= RADEON_IS_PCI;
 
+	mtx_init(&dev_priv->cs.cs_mutex, "cs_mtx", NULL, MTX_DEF);
+
 	ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
 			 drm_get_resource_len(dev, 2), _DRM_REGISTERS,
 			 _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio);
@@ -2112,6 +2123,8 @@ int radeon_driver_unload(struct drm_devi
 
 	drm_rmmap(dev, dev_priv->mmio);
 
+	mtx_destroy(&dev_priv->cs.cs_mutex);
+
 	drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
 
 	dev->dev_private = NULL;
@@ -2126,9 +2139,9 @@ void radeon_commit_ring(drm_radeon_priva
 
 	/* check if the ring is padded out to 16-dword alignment */
 
-	tail_aligned = dev_priv->ring.tail & 0xf;
+	tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN - 1);
 	if (tail_aligned) {
-		int num_p2 = 16 - tail_aligned;
+		int num_p2 = RADEON_RING_ALIGN - tail_aligned;
 
 		ring = dev_priv->ring.start;
 		/* pad with some CP_PACKET2 */

Copied and modified: stable/7/sys/dev/drm/radeon_cs.c (from r196470, head/sys/dev/drm/radeon_cs.c)
==============================================================================
--- head/sys/dev/drm/radeon_cs.c	Sun Aug 23 14:55:57 2009	(r196470, copy source)
+++ stable/7/sys/dev/drm/radeon_cs.c	Fri Oct 30 16:35:47 2009	(r198686)
@@ -403,8 +403,8 @@ static inline int r600_cs_packet3(struct
 			DRM_ERROR("bad DRAW_INDEX\n");
 			break;
 		}
-		ib_chunk->kdata[offset_dw + 1] = (offset & 0xffffffff);
-		ib_chunk->kdata[offset_dw + 2] = (upper_32_bits(offset) & 0xff);
+		ib_chunk->kdata[offset_dw + 1] += (offset & 0xffffffff);
+		ib_chunk->kdata[offset_dw + 2] += (upper_32_bits(offset) & 0xff);
 		break;
 	case R600_IT_DRAW_INDEX_AUTO:
 		//DRM_INFO("R600_IT_DRAW_INDEX_AUTO\n");
@@ -433,8 +433,8 @@ static inline int r600_cs_packet3(struct
 				DRM_ERROR("bad WAIT_REG_MEM\n");
 				break;
 			}
-			ib_chunk->kdata[offset_dw + 2] = (offset & 0xffffffff);
-			ib_chunk->kdata[offset_dw + 3] = (upper_32_bits(offset) & 0xff);
+			ib_chunk->kdata[offset_dw + 2] += (offset & 0xffffffff);
+			ib_chunk->kdata[offset_dw + 3] += (upper_32_bits(offset) & 0xff);
 		}
 		if (ret)
 			DRM_ERROR("bad WAIT_REG_MEM\n");
@@ -469,7 +469,7 @@ static inline int r600_cs_packet3(struct
 				break;
 			}
 			ib_chunk->kdata[offset_dw + 2] += (offset & 0xffffffff);
-			ib_chunk->kdata[offset_dw + 3] |= (upper_32_bits(offset) & 0xff);
+			ib_chunk->kdata[offset_dw + 3] += (upper_32_bits(offset) & 0xff);
 		}
 		if (ret)
 			DRM_ERROR("bad EVENT_WRITE\n");
@@ -488,7 +488,7 @@ static inline int r600_cs_packet3(struct
 			break;
 		}
 		ib_chunk->kdata[offset_dw + 2] += (offset & 0xffffffff);
-		ib_chunk->kdata[offset_dw + 3] |= (upper_32_bits(offset) & 0xff);
+		ib_chunk->kdata[offset_dw + 3] += (upper_32_bits(offset) & 0xff);
 		break;
 	case R600_IT_SET_CONFIG_REG:
 		//DRM_INFO("R600_IT_SET_CONFIG_REG\n");
@@ -628,7 +628,7 @@ static inline int r600_cs_packet3(struct
 					if (ret)
 						break;
 					ib_chunk->kdata[offset_dw + (i * 7) + 0 + 2] += (offset & 0xffffffff);
-					ib_chunk->kdata[offset_dw + (i * 7) + 2 + 2] |= (upper_32_bits(offset) & 0xff);
+					ib_chunk->kdata[offset_dw + (i * 7) + 2 + 2] += (upper_32_bits(offset) & 0xff);
 					break;
 				}
 				if (ret)

Modified: stable/7/sys/dev/drm/radeon_drm.h
==============================================================================
--- stable/7/sys/dev/drm/radeon_drm.h	Fri Oct 30 16:32:35 2009	(r198685)
+++ stable/7/sys/dev/drm/radeon_drm.h	Fri Oct 30 16:35:47 2009	(r198686)
@@ -497,6 +497,8 @@ typedef struct {
 #define DRM_RADEON_SURF_ALLOC 0x1a
 #define DRM_RADEON_SURF_FREE  0x1b
 
+#define DRM_RADEON_CS         0x26
+
 #define DRM_IOCTL_RADEON_CP_INIT    DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
 #define DRM_IOCTL_RADEON_CP_START   DRM_IO(  DRM_COMMAND_BASE + DRM_RADEON_CP_START)
 #define DRM_IOCTL_RADEON_CP_STOP    DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_STOP, drm_radeon_cp_stop_t)
@@ -524,6 +526,7 @@ typedef struct {
 #define DRM_IOCTL_RADEON_SETPARAM   DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t)
 #define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
 #define DRM_IOCTL_RADEON_SURF_FREE  DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
+#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs)
 
 typedef struct drm_radeon_init {
 	enum {
@@ -685,6 +688,8 @@ typedef struct drm_radeon_indirect {
 #define RADEON_PARAM_VBLANK_CRTC           13   /* VBLANK CRTC */
 #define RADEON_PARAM_FB_LOCATION           14   /* FB location */
 #define RADEON_PARAM_NUM_GB_PIPES          15   /* num GB pipes */
+#define RADEON_PARAM_DEVICE_ID             16
+#define RADEON_PARAM_NUM_Z_PIPES           17   /* num Z pipes */
 
 typedef struct drm_radeon_getparam {
 	int param;
@@ -755,4 +760,23 @@ typedef struct drm_radeon_surface_free {
 #define	DRM_RADEON_VBLANK_CRTC1		1
 #define	DRM_RADEON_VBLANK_CRTC2		2
 
+/* New interface which obsolete all previous interface.
+ */
+#define RADEON_CHUNK_ID_RELOCS 0x01
+#define RADEON_CHUNK_ID_IB     0x02
+#define RADEON_CHUNK_ID_OLD 0xff
+
+struct drm_radeon_cs_chunk {
+	uint32_t chunk_id;
+	uint32_t length_dw;
+	uint64_t chunk_data;
+};
+
+struct drm_radeon_cs {
+	uint32_t        num_chunks;
+	uint32_t        cs_id;
+	uint64_t        chunks; /* this points to uint64_t * which point to
+				   cs chunks */
+};
+
 #endif

Modified: stable/7/sys/dev/drm/radeon_drv.h
==============================================================================
--- stable/7/sys/dev/drm/radeon_drv.h	Fri Oct 30 16:32:35 2009	(r198685)
+++ stable/7/sys/dev/drm/radeon_drv.h	Fri Oct 30 16:35:47 2009	(r198686)
@@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$");
 
 #define DRIVER_NAME		"radeon"
 #define DRIVER_DESC		"ATI Radeon"
-#define DRIVER_DATE		"20080528"
+#define DRIVER_DATE		"20080613"
 
 /* Interface history:
  *
@@ -102,9 +102,11 @@ __FBSDID("$FreeBSD$");
  * 1.27- Add support for IGP GART
  * 1.28- Add support for VBL on CRTC2
  * 1.29- R500 3D cmd buffer support
+ * 1.30- Add support for occlusion queries
+ * 1.31- Add support for num Z pipes from GET_PARAM
  */
 #define DRIVER_MAJOR		1
-#define DRIVER_MINOR		29
+#define DRIVER_MINOR		31
 #define DRIVER_PATCHLEVEL	0
 
 /*
@@ -141,15 +143,15 @@ enum radeon_family {
 	CHIP_R600,
 	CHIP_RV610,
 	CHIP_RV630,
+	CHIP_RV670,
 	CHIP_RV620,
 	CHIP_RV635,
-	CHIP_RV670,
 	CHIP_RS780,
 	CHIP_RS880,
 	CHIP_RV770,
-	CHIP_RV740,
 	CHIP_RV730,
 	CHIP_RV710,
+	CHIP_RV740,
 	CHIP_LAST,
 };
 
@@ -236,6 +238,46 @@ struct radeon_virt_surface {
 #define PCIGART_FILE_PRIV	((void *) -1L)
 };
 
+struct drm_radeon_kernel_chunk {
+	uint32_t chunk_id;
+	uint32_t length_dw;
+	uint32_t __user *chunk_data;
+	uint32_t *kdata;
+};
+
+struct drm_radeon_cs_parser {
+	struct drm_device *dev;
+	struct drm_file *file_priv;
+	uint32_t num_chunks;
+	struct drm_radeon_kernel_chunk *chunks;
+	int ib_index;
+	int reloc_index;
+	uint32_t card_offset;
+	void *ib;
+};
+
+/* command submission struct */
+struct drm_radeon_cs_priv {
+	struct mtx cs_mutex;
+	uint32_t id_wcnt;
+	uint32_t id_scnt;
+	uint32_t id_last_wcnt;
+	uint32_t id_last_scnt;
+
+	int (*parse)(struct drm_radeon_cs_parser *parser);
+	void (*id_emit)(struct drm_radeon_cs_parser *parser, uint32_t *id);
+	uint32_t (*id_last_get)(struct drm_device *dev);
+	/* this ib handling callback are for hidding memory manager drm
+	 * from memory manager less drm, free have to emit ib discard
+	 * sequence into the ring */
+	int (*ib_get)(struct drm_radeon_cs_parser *parser);
+	uint32_t (*ib_get_ptr)(struct drm_device *dev, void *ib);
+	void (*ib_free)(struct drm_radeon_cs_parser *parser, int error);
+	/* do a relocation either MM or non-MM */
+	int (*relocate)(struct drm_radeon_cs_parser *parser,
+			uint32_t *reloc, uint64_t *offset);
+};
+
 #define RADEON_FLUSH_EMITED	(1 << 0)
 #define RADEON_PURGE_EMITED	(1 << 1)
 
@@ -328,6 +370,7 @@ typedef struct drm_radeon_private {
 	unsigned long fb_aper_offset;
 
 	int num_gb_pipes;
+	int num_z_pipes;
 	int track_flush;
 	drm_local_map_t *mmio;
 
@@ -349,6 +392,12 @@ typedef struct drm_radeon_private {
 	int r700_sc_prim_fifo_size;
 	int r700_sc_hiz_tile_fifo_size;
 	int r700_sc_earlyz_tile_fifo_fize;
+	/* r6xx/r7xx drm blit vertex buffer */
+	struct drm_buf *blit_vb;
+
+	/* CS */
+	struct drm_radeon_cs_priv cs;
+	struct drm_buf *cs_buf;
 
 } drm_radeon_private_t;
 
@@ -379,10 +428,10 @@ extern void radeon_set_ring_head(drm_rad
 static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv,
 					  u64 off)
 {
-	u32 fb_start = dev_priv->fb_location;
-	u32 fb_end = fb_start + dev_priv->fb_size - 1;
-	u32 gart_start = dev_priv->gart_vm_start;
-	u32 gart_end = gart_start + dev_priv->gart_size - 1;
+	u64 fb_start = dev_priv->fb_location;
+	u64 fb_end = fb_start + dev_priv->fb_size - 1;
+	u64 gart_start = dev_priv->gart_vm_start;
+	u64 gart_end = gart_start + dev_priv->gart_size - 1;
 
 	return ((off >= fb_start && off <= fb_end) ||
 		(off >= gart_start && off <= gart_end));
@@ -476,6 +525,33 @@ extern int r600_cp_dispatch_indirect(str
 				     struct drm_buf *buf, int start, int end);
 extern int r600_page_table_init(struct drm_device *dev);
 extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info);
+extern void r600_cp_dispatch_swap(struct drm_device * dev);
+extern int r600_cp_dispatch_texture(struct drm_device * dev,
+				    struct drm_file *file_priv,
+				    drm_radeon_texture_t * tex,
+				    drm_radeon_tex_image_t * image);
+
+/* r600_blit.c */
+extern int
+r600_prepare_blit_copy(struct drm_device *dev);
+extern void
+r600_done_blit_copy(struct drm_device *dev);
+extern void
+r600_blit_copy(struct drm_device *dev,
+	       uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
+	       int size_bytes);
+extern void
+r600_blit_swap(struct drm_device *dev,
+	       uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
+	       int sx, int sy, int dx, int dy,
+	       int w, int h, int src_pitch, int dst_pitch, int cpp);
+
+/* radeon_state.c */
+extern void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf);
+
+/* radeon_cs.c */
+extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv);
+extern int r600_cs_init(struct drm_device *dev);
 
 /* Flags for stats.boxes
  */
@@ -685,6 +761,7 @@ extern void r600_page_table_cleanup(stru
 
 /* pipe config regs */
 #define R400_GB_PIPE_SELECT             0x402c
+#define RV530_GB_PIPE_SELECT2           0x4124
 #define R500_DYN_SCLK_PWMEM_PIPE        0x000d /* PLL */
 #define R300_GB_TILE_CONFIG             0x4018
 #       define R300_ENABLE_TILING       (1 << 0)
@@ -1827,26 +1904,38 @@ do {									\
  */
 
 #define RADEON_WAIT_UNTIL_2D_IDLE() do {				\
-	OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );			\
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)        \
+		OUT_RING( CP_PACKET0( R600_WAIT_UNTIL, 0 ) );           \
+	else                                                            \
+		OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );         \
 	OUT_RING( (RADEON_WAIT_2D_IDLECLEAN |				\
 		   RADEON_WAIT_HOST_IDLECLEAN) );			\
 } while (0)
 
 #define RADEON_WAIT_UNTIL_3D_IDLE() do {				\
-	OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );			\
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)        \
+		OUT_RING( CP_PACKET0( R600_WAIT_UNTIL, 0 ) );           \
+	else                                                            \
+		OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );         \
 	OUT_RING( (RADEON_WAIT_3D_IDLECLEAN |				\
 		   RADEON_WAIT_HOST_IDLECLEAN) );			\
 } while (0)
 
 #define RADEON_WAIT_UNTIL_IDLE() do {					\
-	OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );			\
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)        \
+		OUT_RING( CP_PACKET0( R600_WAIT_UNTIL, 0 ) );           \
+	else                                                            \
+		OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );         \
 	OUT_RING( (RADEON_WAIT_2D_IDLECLEAN |				\
 		   RADEON_WAIT_3D_IDLECLEAN |				\
 		   RADEON_WAIT_HOST_IDLECLEAN) );			\
 } while (0)
 
 #define RADEON_WAIT_UNTIL_PAGE_FLIPPED() do {				\
-	OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );			\
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)        \
+		OUT_RING( CP_PACKET0( R600_WAIT_UNTIL, 0 ) );           \
+	else                                                            \
+		OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );         \
 	OUT_RING( RADEON_WAIT_CRTC_PFLIP );				\
 } while (0)
 
@@ -1961,14 +2050,17 @@ do {								\
 
 #define RING_LOCALS	int write, _nr, _align_nr; unsigned int mask; u32 *ring;
 
+#define RADEON_RING_ALIGN 16
+
 #define BEGIN_RING( n ) do {						\
 	if ( RADEON_VERBOSE ) {						\
 		DRM_INFO( "BEGIN_RING( %d )\n", (n));			\
 	}								\
-	_align_nr = (n + 0xf) & ~0xf;					\
-	if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) {	\
-                COMMIT_RING();						\
-		radeon_wait_ring( dev_priv, _align_nr * sizeof(u32));	\
+	_align_nr = RADEON_RING_ALIGN - ((dev_priv->ring.tail + n) & (RADEON_RING_ALIGN - 1)); \
+	_align_nr += n;							\
+	if ( dev_priv->ring.space <= (_align_nr) * sizeof(u32) ) {	\
+		COMMIT_RING();						\
+		radeon_wait_ring( dev_priv, (_align_nr) * sizeof(u32) ); \
 	}								\
 	_nr = n; dev_priv->ring.space -= (n) * sizeof(u32);		\
 	ring = dev_priv->ring.start;					\

Modified: stable/7/sys/dev/drm/radeon_irq.c
==============================================================================
--- stable/7/sys/dev/drm/radeon_irq.c	Fri Oct 30 16:32:35 2009	(r198685)
+++ stable/7/sys/dev/drm/radeon_irq.c	Fri Oct 30 16:35:47 2009	(r198686)
@@ -194,6 +194,9 @@ irqreturn_t radeon_driver_irq_handler(DR
 	u32 r500_disp_int;
 	u32 tmp;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return IRQ_NONE;
+
 	/* Only consider the bits we're interested in - others could be used
 	 * outside the DRM
 	 */
@@ -323,6 +326,9 @@ int radeon_irq_emit(struct drm_device *d
 	drm_radeon_irq_emit_t *emit = data;
 	int result;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return -EINVAL;
+
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
 	if (!dev_priv) {
@@ -363,6 +369,9 @@ void radeon_driver_irq_preinstall(struct
 	    (drm_radeon_private_t *) dev->dev_private;
 	u32 dummy;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return;
+
 	/* Disable *all* interrupts */
 	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
 		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
@@ -380,6 +389,9 @@ int radeon_driver_irq_postinstall(struct
 	atomic_set(&dev_priv->swi_emitted, 0);
 	DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return 0;
+
 	radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
 
 	return 0;
@@ -394,6 +406,9 @@ void radeon_driver_irq_uninstall(struct 
 
 	dev_priv->irq_enabled = 0;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return;
+
 	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
 		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
 	/* Disable *all* interrupts */

Modified: stable/7/sys/dev/drm/radeon_state.c
==============================================================================
--- stable/7/sys/dev/drm/radeon_state.c	Fri Oct 30 16:32:35 2009	(r198685)
+++ stable/7/sys/dev/drm/radeon_state.c	Fri Oct 30 16:35:47 2009	(r198686)
@@ -1541,7 +1541,7 @@ static void radeon_cp_dispatch_vertex(st
 	} while (i < nbox);
 }
 
-static void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_buf *buf)
+void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_buf *buf)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
@@ -2202,7 +2202,10 @@ static int radeon_cp_swap(struct drm_dev
 	if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
 		sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
 
-	radeon_cp_dispatch_swap(dev);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		r600_cp_dispatch_swap(dev);
+	else
+		radeon_cp_dispatch_swap(dev);
 	sarea_priv->ctx_owner = 0;
 
 	COMMIT_RING();
@@ -2399,7 +2402,10 @@ static int radeon_cp_texture(struct drm_
 	RING_SPACE_TEST_WITH_RETURN(dev_priv);
 	VB_AGE_TEST_WITH_RETURN(dev_priv);
 
-	ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		ret = r600_cp_dispatch_texture(dev, file_priv, tex, &image);
+	else
+		ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image);
 
 	return ret;
 }
@@ -3018,7 +3024,10 @@ static int radeon_cp_getparam(struct drm
 		value = GET_SCRATCH(dev_priv, 2);
 		break;
 	case RADEON_PARAM_IRQ_NR:
-		value = dev->irq;
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+			value = 0;
+		else
+			value = dev->irq;
 		break;
 	case RADEON_PARAM_GART_BASE:
 		value = dev_priv->gart_vm_start;
@@ -3072,6 +3081,9 @@ static int radeon_cp_getparam(struct drm
 	case RADEON_PARAM_NUM_GB_PIPES:
 		value = dev_priv->num_gb_pipes;
 		break;
+	case RADEON_PARAM_NUM_Z_PIPES:
+		value = dev_priv->num_z_pipes;
+		break;
 	default:
 		DRM_DEBUG("Invalid parameter %d\n", param->param);
 		return -EINVAL;
@@ -3156,6 +3168,14 @@ void radeon_driver_preclose(struct drm_d
 void radeon_driver_lastclose(struct drm_device *dev)
 {
 	radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private);
+	if (dev->dev_private) {
+		drm_radeon_private_t *dev_priv = dev->dev_private;
+
+		if (dev_priv->sarea_priv &&
+		    dev_priv->sarea_priv->pfCurrentPage != 0)
+			radeon_cp_dispatch_flip(dev);
+	}
+
 	radeon_do_release(dev);
 }
 
@@ -3216,7 +3236,8 @@ struct drm_ioctl_desc radeon_ioctls[] = 
 	DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH)
+	DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH)
 };
 
 int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);

Modified: stable/7/sys/modules/drm/radeon/Makefile
==============================================================================
--- stable/7/sys/modules/drm/radeon/Makefile	Fri Oct 30 16:32:35 2009	(r198685)
+++ stable/7/sys/modules/drm/radeon/Makefile	Fri Oct 30 16:35:47 2009	(r198686)
@@ -2,8 +2,8 @@
 
 .PATH:	${.CURDIR}/../../../dev/drm
 KMOD	= radeon
-SRCS	= r300_cmdbuf.c r600_cp.c radeon_cp.c radeon_drv.c radeon_irq.c \
-	radeon_mem.c radeon_state.c
+SRCS	= r300_cmdbuf.c r600_blit.c r600_cp.c radeon_cp.c radeon_cs.c \
+	radeon_drv.c radeon_irq.c radeon_mem.c radeon_state.c
 SRCS	+=device_if.h bus_if.h pci_if.h opt_drm.h
 
 .include <bsd.kmod.mk>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910301635.n9UGZlB7051367>