aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/r300_cmdbuf.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2008-03-29 17:51:49 -0400
committerDave Airlie <airlied@linux.ie>2008-03-29 17:51:49 -0400
commit0c76be35194563f56e02fc1775d0fe29281e84d4 (patch)
treece326ec271bb53323daf29f7098fb81ff6caae01 /drivers/char/drm/r300_cmdbuf.c
parentaf8be4e4b316df36a00c1e52a9970c253783b57e (diff)
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: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/char/drm/r300_cmdbuf.c')
-rw-r--r--drivers/char/drm/r300_cmdbuf.c54
1 files changed, 42 insertions, 12 deletions
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
index 0f4afc44245c..f535812e4057 100644
--- a/drivers/char/drm/r300_cmdbuf.c
+++ b/drivers/char/drm/r300_cmdbuf.c
@@ -729,6 +729,47 @@ static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
729 buf->used = 0; 729 buf->used = 0;
730} 730}
731 731
732static void r300_cmd_wait(drm_radeon_private_t * dev_priv,
733 drm_r300_cmd_header_t header)
734{
735 u32 wait_until;
736 RING_LOCALS;
737
738 if (!header.wait.flags)
739 return;
740
741 wait_until = 0;
742
743 switch(header.wait.flags) {
744 case R300_WAIT_2D:
745 wait_until = RADEON_WAIT_2D_IDLE;
746 break;
747 case R300_WAIT_3D:
748 wait_until = RADEON_WAIT_3D_IDLE;
749 break;
750 case R300_NEW_WAIT_2D_3D:
751 wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_3D_IDLE;
752 break;
753 case R300_NEW_WAIT_2D_2D_CLEAN:
754 wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN;
755 break;
756 case R300_NEW_WAIT_3D_3D_CLEAN:
757 wait_until = RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN;
758 break;
759 case R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN:
760 wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN;
761 wait_until |= RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN;
762 break;
763 default:
764 return;
765 }
766
767 BEGIN_RING(2);
768 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
769 OUT_RING(wait_until);
770 ADVANCE_RING();
771}
772
732static int r300_scratch(drm_radeon_private_t *dev_priv, 773static int r300_scratch(drm_radeon_private_t *dev_priv,
733 drm_radeon_kcmd_buffer_t *cmdbuf, 774 drm_radeon_kcmd_buffer_t *cmdbuf,
734 drm_r300_cmd_header_t header) 775 drm_r300_cmd_header_t header)
@@ -909,19 +950,8 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
909 break; 950 break;
910 951
911 case R300_CMD_WAIT: 952 case R300_CMD_WAIT:
912 /* simple enough, we can do it here */
913 DRM_DEBUG("R300_CMD_WAIT\n"); 953 DRM_DEBUG("R300_CMD_WAIT\n");
914 if (header.wait.flags == 0) 954 r300_cmd_wait(dev_priv, header);
915 break; /* nothing to do */
916
917 {
918 RING_LOCALS;
919
920 BEGIN_RING(2);
921 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
922 OUT_RING((header.wait.flags & 0xf) << 14);
923 ADVANCE_RING();
924 }
925 break; 955 break;
926 956
927 case R300_CMD_SCRATCH: 957 case R300_CMD_SCRATCH: