summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAapo Tahkola <aet@rasterburn.org>2006-03-06 20:08:50 +0000
committerAapo Tahkola <aet@rasterburn.org>2006-03-06 20:08:50 +0000
commitb3fdf9bb7acd023060e0dba07d3b439c3b64faef (patch)
treec8c57bc2b05aac1fc9b1632d3d991644f2e560fd
parent02f76f41b12e1465db4e4a48c0b81977a8bd3d8d (diff)
Add general-purpose packet for manipulating scratch registers (r300)
-rw-r--r--shared-core/r300_cmdbuf.c66
-rw-r--r--shared-core/radeon_drm.h4
-rw-r--r--shared-core/radeon_drv.h5
3 files changed, 74 insertions, 1 deletions
diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c
index 9af5c073..988734cf 100644
--- a/shared-core/r300_cmdbuf.c
+++ b/shared-core/r300_cmdbuf.c
@@ -702,6 +702,63 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf)
buf->used = 0;
}
+static __inline__ int r300_scratch(drm_radeon_private_t *dev_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf,
+ drm_r300_cmd_header_t header)
+{
+ u32 *ref_age_base;
+ u32 i, buf_idx, h_pending;
+ RING_LOCALS;
+
+ if (cmdbuf->bufsz < sizeof(u32 *) + header.scratch.n_bufs * sizeof(buf_idx) ) {
+ return DRM_ERR(EINVAL);
+ }
+
+ if (header.scratch.reg >= 5) {
+ return DRM_ERR(EINVAL);
+ }
+
+ dev_priv->scratch_ages[header.scratch.reg] ++;
+
+ ref_age_base = *((u32 **)cmdbuf->buf);
+
+ cmdbuf->buf += sizeof(u32 *);
+ cmdbuf->bufsz -= sizeof(u32 *);
+
+ for (i=0; i < header.scratch.n_bufs; i++) {
+ buf_idx = *((u32 *)cmdbuf->buf);
+ buf_idx *= 2; /* 8 bytes per buf */
+
+ if (DRM_COPY_TO_USER(ref_age_base + buf_idx, &dev_priv->scratch_ages[header.scratch.reg], sizeof(u32))) {
+ return DRM_ERR(EINVAL);
+ }
+
+ if (DRM_COPY_FROM_USER(&h_pending, ref_age_base + buf_idx + 1, sizeof(u32))) {
+ return DRM_ERR(EINVAL);
+ }
+
+ if (h_pending == 0) {
+ return DRM_ERR(EINVAL);
+ }
+
+ h_pending--;
+
+ if (DRM_COPY_TO_USER(ref_age_base + buf_idx + 1, &h_pending, sizeof(u32))) {
+ return DRM_ERR(EINVAL);
+ }
+
+ cmdbuf->buf += sizeof(buf_idx);
+ cmdbuf->bufsz -= sizeof(buf_idx);
+ }
+
+ BEGIN_RING(2);
+ OUT_RING( CP_PACKET0( RADEON_SCRATCH_REG0 + header.scratch.reg * 4, 0 ) );
+ OUT_RING( dev_priv->scratch_ages[header.scratch.reg] );
+ ADVANCE_RING();
+
+ return 0;
+}
+
/**
* Parses and validates a user-supplied command buffer and emits appropriate
* commands on the DMA ring buffer.
@@ -839,6 +896,15 @@ int r300_do_cp_cmdbuf(drm_device_t *dev,
}
break;
+ case R300_CMD_SCRATCH:
+ DRM_DEBUG("R300_CMD_SCRATCH\n");
+ ret = r300_scratch(dev_priv, cmdbuf, header);
+ if (ret) {
+ DRM_ERROR("r300_scratch failed\n");
+ goto cleanup;
+ }
+ break;
+
default:
DRM_ERROR("bad cmd_type %i at %p\n",
header.header.cmd_type,
diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h
index 62b82f22..601b22bb 100644
--- a/shared-core/radeon_drm.h
+++ b/shared-core/radeon_drm.h
@@ -222,6 +222,7 @@ typedef union {
# define R300_WAIT_3D 0x2
# define R300_WAIT_2D_CLEAN 0x3
# define R300_WAIT_3D_CLEAN 0x4
+#define R300_CMD_SCRATCH 8
typedef union {
unsigned int u;
@@ -247,6 +248,9 @@ typedef union {
struct {
unsigned char cmd_type, flags, pad0, pad1;
} wait;
+ struct {
+ unsigned char cmd_type, reg, n_bufs, flags;
+ } scratch;
} drm_r300_cmd_header_t;
#define RADEON_FRONT 0x1
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index 51d91578..af8c0a72 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -91,10 +91,11 @@
* 1.21- Add support for card type getparam
* 1.22- Add support for texture cache flushes (R300_TX_CNTL)
* 1.23- Add new radeon memory map work from benh
+ * 1.24- Add general-purpose packet for manipulating scratch registers (r300)
*/
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 23
+#define DRIVER_MINOR 24
#define DRIVER_PATCHLEVEL 0
enum radeon_family {
@@ -277,6 +278,8 @@ typedef struct drm_radeon_private {
/* starting from here on, data is preserved accross an open */
uint32_t flags; /* see radeon_chip_flags */
+ u32 scratch_ages[5];
+
} drm_radeon_private_t;
typedef struct drm_radeon_buf_priv {