r300: Correctly translate the value for the R300_CMD_WAIT command.
authorOliver McFadden <z3ro.geek@gmail.com>
Sat, 29 Mar 2008 17:25:44 +0000 (17:25 +0000)
committerOliver McFadden <z3ro.geek@gmail.com>
Sat, 29 Mar 2008 17:31:39 +0000 (17:31 +0000)
Previously, the R300_CMD_WAIT command would write the passed directly to the
hardware. However this is incorrect because the R300_WAIT_* values used are
internal interface values that do not map directly to the hardware.

The new function I have added translates the R300_WAIT_* values into appropriate
values for the hardware before writing the register.

Thanks to John Bridgman for pointing this out. :-)

shared-core/r300_cmdbuf.c

index 1ae2e6779a0ee042bb5e4a1c19c46cc7bd0e767e..db5186c80b70e00c85e5f6434024939473794a40 100644 (file)
@@ -736,6 +736,32 @@ static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
        buf->used = 0;
 }
 
+static void r300_cmd_wait(drm_radeon_private_t * dev_priv,
+                         drm_r300_cmd_header_t header)
+{
+       RING_LOCALS;
+       u32 wait_until;
+
+       if (!header.wait.flags)
+               return;
+
+       wait_until = 0;
+
+       if (header.wait.flags & R300_WAIT_2D)
+               wait_until |= RADEON_WAIT_2D_IDLE;
+       if (header.wait.flags & R300_WAIT_3D)
+               wait_until |= RADEON_WAIT_3D_IDLE;
+       if (header.wait.flags & R300_WAIT_2D_CLEAN)
+               wait_until |= RADEON_WAIT_2D_IDLECLEAN;
+       if (header.wait.flags & R300_WAIT_3D_CLEAN)
+               wait_until |= RADEON_WAIT_3D_IDLECLEAN;
+
+       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,
                        drm_radeon_kcmd_buffer_t *cmdbuf,
                        drm_r300_cmd_header_t header)
@@ -962,19 +988,8 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
                        break;
 
                case R300_CMD_WAIT:
-                       /* simple enough, we can do it here */
                        DRM_DEBUG("R300_CMD_WAIT\n");
-                       if (header.wait.flags == 0)
-                               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();
-                       }
+                       r300_cmd_wait(dev_priv, header);
                        break;
 
                case R300_CMD_SCRATCH: