aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2006-03-19 03:45:26 -0500
committerDave Airlie <airlied@linux.ie>2006-03-19 03:45:26 -0500
commitee4621f011750a6eff9f56631e12ab7fd9503aaa (patch)
treea3d1291b3902ba2041464a0ef364d3acfb08dcac /drivers/char
parentd5ea702f1e8e3edeea6b673a58281bf99f3dbec5 (diff)
drm: Add general-purpose packet for manipulating scratch registers (r300)
From: Aapo Tahkola (via DRM CVS) Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/drm/r300_cmdbuf.c67
-rw-r--r--drivers/char/drm/radeon_drm.h4
-rw-r--r--drivers/char/drm/radeon_drv.h5
3 files changed, 75 insertions, 1 deletions
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
index 20b6cb39213d..b108c7f913b2 100644
--- a/drivers/char/drm/r300_cmdbuf.c
+++ b/drivers/char/drm/r300_cmdbuf.c
@@ -704,6 +704,64 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf)
704 buf->used = 0; 704 buf->used = 0;
705} 705}
706 706
707static int r300_scratch(drm_radeon_private_t *dev_priv,
708 drm_radeon_kcmd_buffer_t *cmdbuf,
709 drm_r300_cmd_header_t header)
710{
711 u32 *ref_age_base;
712 u32 i, buf_idx, h_pending;
713 RING_LOCALS;
714
715 if (cmdbuf->bufsz <
716 (sizeof(u64) + header.scratch.n_bufs * sizeof(buf_idx))) {
717 return DRM_ERR(EINVAL);
718 }
719
720 if (header.scratch.reg >= 5) {
721 return DRM_ERR(EINVAL);
722 }
723
724 dev_priv->scratch_ages[header.scratch.reg]++;
725
726 ref_age_base = *(u32 **)cmdbuf->buf;
727
728 cmdbuf->buf += sizeof(u64);
729 cmdbuf->bufsz -= sizeof(u64);
730
731 for (i=0; i < header.scratch.n_bufs; i++) {
732 buf_idx = *(u32 *)cmdbuf->buf;
733 buf_idx *= 2; /* 8 bytes per buf */
734
735 if (DRM_COPY_TO_USER(ref_age_base + buf_idx, &dev_priv->scratch_ages[header.scratch.reg], sizeof(u32))) {
736 return DRM_ERR(EINVAL);
737 }
738
739 if (DRM_COPY_FROM_USER(&h_pending, ref_age_base + buf_idx + 1, sizeof(u32))) {
740 return DRM_ERR(EINVAL);
741 }
742
743 if (h_pending == 0) {
744 return DRM_ERR(EINVAL);
745 }
746
747 h_pending--;
748
749 if (DRM_COPY_TO_USER(ref_age_base + buf_idx + 1, &h_pending, sizeof(u32))) {
750 return DRM_ERR(EINVAL);
751 }
752
753 cmdbuf->buf += sizeof(buf_idx);
754 cmdbuf->bufsz -= sizeof(buf_idx);
755 }
756
757 BEGIN_RING(2);
758 OUT_RING(CP_PACKET0(RADEON_SCRATCH_REG0 + header.scratch.reg * 4, 0));
759 OUT_RING(dev_priv->scratch_ages[header.scratch.reg]);
760 ADVANCE_RING();
761
762 return 0;
763}
764
707/** 765/**
708 * Parses and validates a user-supplied command buffer and emits appropriate 766 * Parses and validates a user-supplied command buffer and emits appropriate
709 * commands on the DMA ring buffer. 767 * commands on the DMA ring buffer.
@@ -841,6 +899,15 @@ int r300_do_cp_cmdbuf(drm_device_t *dev,
841 } 899 }
842 break; 900 break;
843 901
902 case R300_CMD_SCRATCH:
903 DRM_DEBUG("R300_CMD_SCRATCH\n");
904 ret = r300_scratch(dev_priv, cmdbuf, header);
905 if (ret) {
906 DRM_ERROR("r300_scratch failed\n");
907 goto cleanup;
908 }
909 break;
910
844 default: 911 default:
845 DRM_ERROR("bad cmd_type %i at %p\n", 912 DRM_ERROR("bad cmd_type %i at %p\n",
846 header.header.cmd_type, 913 header.header.cmd_type,
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
index bb63e6806fd1..c8e279e89c2e 100644
--- a/drivers/char/drm/radeon_drm.h
+++ b/drivers/char/drm/radeon_drm.h
@@ -222,6 +222,7 @@ typedef union {
222# define R300_WAIT_3D 0x2 222# define R300_WAIT_3D 0x2
223# define R300_WAIT_2D_CLEAN 0x3 223# define R300_WAIT_2D_CLEAN 0x3
224# define R300_WAIT_3D_CLEAN 0x4 224# define R300_WAIT_3D_CLEAN 0x4
225#define R300_CMD_SCRATCH 8
225 226
226typedef union { 227typedef union {
227 unsigned int u; 228 unsigned int u;
@@ -247,6 +248,9 @@ typedef union {
247 struct { 248 struct {
248 unsigned char cmd_type, flags, pad0, pad1; 249 unsigned char cmd_type, flags, pad0, pad1;
249 } wait; 250 } wait;
251 struct {
252 unsigned char cmd_type, reg, n_bufs, flags;
253 } scratch;
250} drm_r300_cmd_header_t; 254} drm_r300_cmd_header_t;
251 255
252#define RADEON_FRONT 0x1 256#define RADEON_FRONT 0x1
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index a0c198895a27..5cf555e4637b 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -92,9 +92,10 @@
92 * 1.21- Add support for card type getparam 92 * 1.21- Add support for card type getparam
93 * 1.22- Add support for texture cache flushes (R300_TX_CNTL) 93 * 1.22- Add support for texture cache flushes (R300_TX_CNTL)
94 * 1.23- Add new radeon memory map work from benh 94 * 1.23- Add new radeon memory map work from benh
95 * 1.24- Add general-purpose packet for manipulating scratch registers (r300)
95 */ 96 */
96#define DRIVER_MAJOR 1 97#define DRIVER_MAJOR 1
97#define DRIVER_MINOR 23 98#define DRIVER_MINOR 24
98#define DRIVER_PATCHLEVEL 0 99#define DRIVER_PATCHLEVEL 0
99 100
100/* 101/*
@@ -276,6 +277,8 @@ typedef struct drm_radeon_private {
276 unsigned long pcigart_offset; 277 unsigned long pcigart_offset;
277 drm_ati_pcigart_info gart_info; 278 drm_ati_pcigart_info gart_info;
278 279
280 u32 scratch_ages[5];
281
279 /* starting from here on, data is preserved accross an open */ 282 /* starting from here on, data is preserved accross an open */
280 uint32_t flags; /* see radeon_chip_flags */ 283 uint32_t flags; /* see radeon_chip_flags */
281} drm_radeon_private_t; 284} drm_radeon_private_t;