diff options
author | Aapo Tahkola <aet@rasterburn.org> | 2006-03-06 20:08:50 +0000 |
---|---|---|
committer | Aapo Tahkola <aet@rasterburn.org> | 2006-03-06 20:08:50 +0000 |
commit | b3fdf9bb7acd023060e0dba07d3b439c3b64faef (patch) | |
tree | c8c57bc2b05aac1fc9b1632d3d991644f2e560fd | |
parent | 02f76f41b12e1465db4e4a48c0b81977a8bd3d8d (diff) |
Add general-purpose packet for manipulating scratch registers (r300)
-rw-r--r-- | shared-core/r300_cmdbuf.c | 66 | ||||
-rw-r--r-- | shared-core/radeon_drm.h | 4 | ||||
-rw-r--r-- | shared-core/radeon_drv.h | 5 |
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 { |