Commit 0c76be35 authored by Dave Airlie's avatar Dave Airlie

drm/r300: fix bug in r300 userspace hardware wait emission

This interface was originally designed wrong, confusing bit-fields and
integers, major brown paper bag going back many years...

But userspace only ever used 4 values so fix the interface for new
users and fix the implementation to deal with the 4 values userspace
has ever emitted (0x1, 0x2, 0x3, 0x6).
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent af8be4e4
...@@ -729,6 +729,47 @@ static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf) ...@@ -729,6 +729,47 @@ static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
buf->used = 0; buf->used = 0;
} }
static void r300_cmd_wait(drm_radeon_private_t * dev_priv,
drm_r300_cmd_header_t header)
{
u32 wait_until;
RING_LOCALS;
if (!header.wait.flags)
return;
wait_until = 0;
switch(header.wait.flags) {
case R300_WAIT_2D:
wait_until = RADEON_WAIT_2D_IDLE;
break;
case R300_WAIT_3D:
wait_until = RADEON_WAIT_3D_IDLE;
break;
case R300_NEW_WAIT_2D_3D:
wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_3D_IDLE;
break;
case R300_NEW_WAIT_2D_2D_CLEAN:
wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN;
break;
case R300_NEW_WAIT_3D_3D_CLEAN:
wait_until = RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN;
break;
case R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN:
wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN;
wait_until |= RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN;
break;
default:
return;
}
BEGIN_RING(2);
OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
OUT_RING(wait_until);
ADVANCE_RING();
}
static int r300_scratch(drm_radeon_private_t *dev_priv, static int r300_scratch(drm_radeon_private_t *dev_priv,
drm_radeon_kcmd_buffer_t *cmdbuf, drm_radeon_kcmd_buffer_t *cmdbuf,
drm_r300_cmd_header_t header) drm_r300_cmd_header_t header)
...@@ -909,19 +950,8 @@ int r300_do_cp_cmdbuf(struct drm_device *dev, ...@@ -909,19 +950,8 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
break; break;
case R300_CMD_WAIT: case R300_CMD_WAIT:
/* simple enough, we can do it here */
DRM_DEBUG("R300_CMD_WAIT\n"); DRM_DEBUG("R300_CMD_WAIT\n");
if (header.wait.flags == 0) r300_cmd_wait(dev_priv, header);
break; /* nothing to do */
{
RING_LOCALS;
BEGIN_RING(2);
OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
OUT_RING((header.wait.flags & 0xf) << 14);
ADVANCE_RING();
}
break; break;
case R300_CMD_SCRATCH: case R300_CMD_SCRATCH:
......
...@@ -225,8 +225,20 @@ typedef union { ...@@ -225,8 +225,20 @@ typedef union {
#define R300_CMD_WAIT 7 #define R300_CMD_WAIT 7
# define R300_WAIT_2D 0x1 # define R300_WAIT_2D 0x1
# define R300_WAIT_3D 0x2 # define R300_WAIT_3D 0x2
/* these two defines are DOING IT WRONG - however
* we have userspace which relies on using these.
* The wait interface is backwards compat new
* code should use the NEW_WAIT defines below
* THESE ARE NOT BIT FIELDS
*/
# 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_NEW_WAIT_2D_3D 0x3
# define R300_NEW_WAIT_2D_2D_CLEAN 0x4
# define R300_NEW_WAIT_3D_3D_CLEAN 0x6
# define R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN 0x8
#define R300_CMD_SCRATCH 8 #define R300_CMD_SCRATCH 8
typedef union { typedef union {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment