diff options
author | Dave Airlie <airlied@linux.ie> | 2008-03-29 17:51:49 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2008-03-29 17:51:49 -0400 |
commit | 0c76be35194563f56e02fc1775d0fe29281e84d4 (patch) | |
tree | ce326ec271bb53323daf29f7098fb81ff6caae01 /drivers/char/drm/r300_cmdbuf.c | |
parent | af8be4e4b316df36a00c1e52a9970c253783b57e (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.c | 54 |
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 | ||
732 | static 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 | |||
732 | static int r300_scratch(drm_radeon_private_t *dev_priv, | 773 | static 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: |