drm: Add general-purpose packet for manipulating scratch registers (r300)
From: Aapo Tahkola (via DRM CVS) Signed-off-by: Dave Airlie <airlied@linux.ie>
This commit is contained in:
@ -704,6 +704,64 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf)
|
|||||||
buf->used = 0;
|
buf->used = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static 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(u64) + 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(u64);
|
||||||
|
cmdbuf->bufsz -= sizeof(u64);
|
||||||
|
|
||||||
|
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
|
* Parses and validates a user-supplied command buffer and emits appropriate
|
||||||
* commands on the DMA ring buffer.
|
* commands on the DMA ring buffer.
|
||||||
@ -841,6 +899,15 @@ int r300_do_cp_cmdbuf(drm_device_t *dev,
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
DRM_ERROR("bad cmd_type %i at %p\n",
|
DRM_ERROR("bad cmd_type %i at %p\n",
|
||||||
header.header.cmd_type,
|
header.header.cmd_type,
|
||||||
|
@ -222,6 +222,7 @@ typedef union {
|
|||||||
# define R300_WAIT_3D 0x2
|
# define R300_WAIT_3D 0x2
|
||||||
# define R300_WAIT_2D_CLEAN 0x3
|
# define R300_WAIT_2D_CLEAN 0x3
|
||||||
# define R300_WAIT_3D_CLEAN 0x4
|
# define R300_WAIT_3D_CLEAN 0x4
|
||||||
|
#define R300_CMD_SCRATCH 8
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
unsigned int u;
|
unsigned int u;
|
||||||
@ -247,6 +248,9 @@ typedef union {
|
|||||||
struct {
|
struct {
|
||||||
unsigned char cmd_type, flags, pad0, pad1;
|
unsigned char cmd_type, flags, pad0, pad1;
|
||||||
} wait;
|
} wait;
|
||||||
|
struct {
|
||||||
|
unsigned char cmd_type, reg, n_bufs, flags;
|
||||||
|
} scratch;
|
||||||
} drm_r300_cmd_header_t;
|
} drm_r300_cmd_header_t;
|
||||||
|
|
||||||
#define RADEON_FRONT 0x1
|
#define RADEON_FRONT 0x1
|
||||||
|
@ -92,9 +92,10 @@
|
|||||||
* 1.21- Add support for card type getparam
|
* 1.21- Add support for card type getparam
|
||||||
* 1.22- Add support for texture cache flushes (R300_TX_CNTL)
|
* 1.22- Add support for texture cache flushes (R300_TX_CNTL)
|
||||||
* 1.23- Add new radeon memory map work from benh
|
* 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_MAJOR 1
|
||||||
#define DRIVER_MINOR 23
|
#define DRIVER_MINOR 24
|
||||||
#define DRIVER_PATCHLEVEL 0
|
#define DRIVER_PATCHLEVEL 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -276,6 +277,8 @@ typedef struct drm_radeon_private {
|
|||||||
unsigned long pcigart_offset;
|
unsigned long pcigart_offset;
|
||||||
drm_ati_pcigart_info gart_info;
|
drm_ati_pcigart_info gart_info;
|
||||||
|
|
||||||
|
u32 scratch_ages[5];
|
||||||
|
|
||||||
/* starting from here on, data is preserved accross an open */
|
/* starting from here on, data is preserved accross an open */
|
||||||
uint32_t flags; /* see radeon_chip_flags */
|
uint32_t flags; /* see radeon_chip_flags */
|
||||||
} drm_radeon_private_t;
|
} drm_radeon_private_t;
|
||||||
|
Reference in New Issue
Block a user