aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r300_cmdbuf.c
diff options
context:
space:
mode:
authorJerome Glisse <glisse@freedesktop.org>2008-08-12 19:46:31 -0400
committerDave Airlie <airlied@linux.ie>2008-08-24 16:34:58 -0400
commit54f961a628b737f66710eca0b0d95346645dd33e (patch)
tree9ba62d7e8d5818155330ef79cbf2d8b7302042a1 /drivers/gpu/drm/radeon/r300_cmdbuf.c
parent94ad374a0751f40d25e22e036c37f7263569d24c (diff)
radeon: fix some hard lockups on r3/4/500s
This patch should fix hard lockup and convert them in softlockup (ie you can ssh the box but the gpu is busted and we are waiting in loop for it to come back to reason). Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r300_cmdbuf.c')
-rw-r--r--drivers/gpu/drm/radeon/r300_cmdbuf.c117
1 files changed, 97 insertions, 20 deletions
diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c
index 702df45320f7..4b3bd6303daf 100644
--- a/drivers/gpu/drm/radeon/r300_cmdbuf.c
+++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c
@@ -136,6 +136,18 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
136 ADVANCE_RING(); 136 ADVANCE_RING();
137 } 137 }
138 138
139 /* flus cache and wait idle clean after cliprect change */
140 BEGIN_RING(2);
141 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
142 OUT_RING(R300_RB3D_DC_FLUSH);
143 ADVANCE_RING();
144 BEGIN_RING(2);
145 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
146 OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
147 ADVANCE_RING();
148 /* set flush flag */
149 dev_priv->track_flush |= RADEON_FLUSH_EMITED;
150
139 return 0; 151 return 0;
140} 152}
141 153
@@ -166,13 +178,13 @@ void r300_init_reg_flags(struct drm_device *dev)
166 ADD_RANGE(0x21DC, 1); 178 ADD_RANGE(0x21DC, 1);
167 ADD_RANGE(R300_VAP_UNKNOWN_221C, 1); 179 ADD_RANGE(R300_VAP_UNKNOWN_221C, 1);
168 ADD_RANGE(R300_VAP_CLIP_X_0, 4); 180 ADD_RANGE(R300_VAP_CLIP_X_0, 4);
169 ADD_RANGE(R300_VAP_PVS_WAITIDLE, 1); 181 ADD_RANGE(R300_VAP_PVS_STATE_FLUSH_REG, 1);
170 ADD_RANGE(R300_VAP_UNKNOWN_2288, 1); 182 ADD_RANGE(R300_VAP_UNKNOWN_2288, 1);
171 ADD_RANGE(R300_VAP_OUTPUT_VTX_FMT_0, 2); 183 ADD_RANGE(R300_VAP_OUTPUT_VTX_FMT_0, 2);
172 ADD_RANGE(R300_VAP_PVS_CNTL_1, 3); 184 ADD_RANGE(R300_VAP_PVS_CNTL_1, 3);
173 ADD_RANGE(R300_GB_ENABLE, 1); 185 ADD_RANGE(R300_GB_ENABLE, 1);
174 ADD_RANGE(R300_GB_MSPOS0, 5); 186 ADD_RANGE(R300_GB_MSPOS0, 5);
175 ADD_RANGE(R300_TX_CNTL, 1); 187 ADD_RANGE(R300_TX_INVALTAGS, 1);
176 ADD_RANGE(R300_TX_ENABLE, 1); 188 ADD_RANGE(R300_TX_ENABLE, 1);
177 ADD_RANGE(0x4200, 4); 189 ADD_RANGE(0x4200, 4);
178 ADD_RANGE(0x4214, 1); 190 ADD_RANGE(0x4214, 1);
@@ -388,15 +400,28 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv,
388 if (sz * 16 > cmdbuf->bufsz) 400 if (sz * 16 > cmdbuf->bufsz)
389 return -EINVAL; 401 return -EINVAL;
390 402
391 BEGIN_RING(5 + sz * 4); 403 /* VAP is very sensitive so we purge cache before we program it
392 /* Wait for VAP to come to senses.. */ 404 * and we also flush its state before & after */
393 /* there is no need to emit it multiple times, (only once before VAP is programmed, 405 BEGIN_RING(6);
394 but this optimization is for later */ 406 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
395 OUT_RING_REG(R300_VAP_PVS_WAITIDLE, 0); 407 OUT_RING(R300_RB3D_DC_FLUSH);
408 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
409 OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
410 OUT_RING(CP_PACKET0(R300_VAP_PVS_STATE_FLUSH_REG, 0));
411 OUT_RING(0);
412 ADVANCE_RING();
413 /* set flush flag */
414 dev_priv->track_flush |= RADEON_FLUSH_EMITED;
415
416 BEGIN_RING(3 + sz * 4);
396 OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr); 417 OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr);
397 OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1)); 418 OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1));
398 OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4); 419 OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4);
420 ADVANCE_RING();
399 421
422 BEGIN_RING(2);
423 OUT_RING(CP_PACKET0(R300_VAP_PVS_STATE_FLUSH_REG, 0));
424 OUT_RING(0);
400 ADVANCE_RING(); 425 ADVANCE_RING();
401 426
402 cmdbuf->buf += sz * 16; 427 cmdbuf->buf += sz * 16;
@@ -424,6 +449,15 @@ static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv,
424 OUT_RING_TABLE((int *)cmdbuf->buf, 8); 449 OUT_RING_TABLE((int *)cmdbuf->buf, 8);
425 ADVANCE_RING(); 450 ADVANCE_RING();
426 451
452 BEGIN_RING(4);
453 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
454 OUT_RING(R300_RB3D_DC_FLUSH);
455 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
456 OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
457 ADVANCE_RING();
458 /* set flush flag */
459 dev_priv->track_flush |= RADEON_FLUSH_EMITED;
460
427 cmdbuf->buf += 8 * 4; 461 cmdbuf->buf += 8 * 4;
428 cmdbuf->bufsz -= 8 * 4; 462 cmdbuf->bufsz -= 8 * 4;
429 463
@@ -613,11 +647,19 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
613 case RADEON_CNTL_BITBLT_MULTI: 647 case RADEON_CNTL_BITBLT_MULTI:
614 return r300_emit_bitblt_multi(dev_priv, cmdbuf); 648 return r300_emit_bitblt_multi(dev_priv, cmdbuf);
615 649
616 case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */ 650 case RADEON_CP_INDX_BUFFER:
651 /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
617 return r300_emit_indx_buffer(dev_priv, cmdbuf); 652 return r300_emit_indx_buffer(dev_priv, cmdbuf);
618 case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ 653 case RADEON_CP_3D_DRAW_IMMD_2:
619 case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ 654 /* triggers drawing using in-packet vertex data */
620 case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ 655 case RADEON_CP_3D_DRAW_VBUF_2:
656 /* triggers drawing of vertex buffers setup elsewhere */
657 case RADEON_CP_3D_DRAW_INDX_2:
658 /* triggers drawing using indices to vertex buffer */
659 /* whenever we send vertex we clear flush & purge */
660 dev_priv->track_flush &= ~(RADEON_FLUSH_EMITED |
661 RADEON_PURGE_EMITED);
662 break;
621 case RADEON_WAIT_FOR_IDLE: 663 case RADEON_WAIT_FOR_IDLE:
622 case RADEON_CP_NOP: 664 case RADEON_CP_NOP:
623 /* these packets are safe */ 665 /* these packets are safe */
@@ -713,17 +755,53 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv,
713 */ 755 */
714static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv) 756static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
715{ 757{
758 uint32_t cache_z, cache_3d, cache_2d;
716 RING_LOCALS; 759 RING_LOCALS;
760
761 cache_z = R300_ZC_FLUSH;
762 cache_2d = R300_RB2D_DC_FLUSH;
763 cache_3d = R300_RB3D_DC_FLUSH;
764 if (!(dev_priv->track_flush & RADEON_PURGE_EMITED)) {
765 /* we can purge, primitive where draw since last purge */
766 cache_z |= R300_ZC_FREE;
767 cache_2d |= R300_RB2D_DC_FREE;
768 cache_3d |= R300_RB3D_DC_FREE;
769 }
717 770
718 BEGIN_RING(6); 771 /* flush & purge zbuffer */
719 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); 772 BEGIN_RING(2);
720 OUT_RING(R300_RB3D_DSTCACHE_UNKNOWN_0A);
721 OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); 773 OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0));
722 OUT_RING(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE| 774 OUT_RING(cache_z);
723 R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); 775 ADVANCE_RING();
724 OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0)); 776 /* flush & purge 3d */
725 OUT_RING(0x0); 777 BEGIN_RING(2);
778 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
779 OUT_RING(cache_3d);
780 ADVANCE_RING();
781 /* flush & purge texture */
782 BEGIN_RING(2);
783 OUT_RING(CP_PACKET0(R300_TX_INVALTAGS, 0));
784 OUT_RING(0);
785 ADVANCE_RING();
786 /* FIXME: is this one really needed ? */
787 BEGIN_RING(2);
788 OUT_RING(CP_PACKET0(R300_RB3D_AARESOLVE_CTL, 0));
789 OUT_RING(0);
790 ADVANCE_RING();
791 BEGIN_RING(2);
792 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
793 OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
794 ADVANCE_RING();
795 /* flush & purge 2d through E2 as RB2D will trigger lockup */
796 BEGIN_RING(4);
797 OUT_RING(CP_PACKET0(R300_DSTCACHE_CTLSTAT, 0));
798 OUT_RING(cache_2d);
799 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
800 OUT_RING(RADEON_WAIT_2D_IDLECLEAN |
801 RADEON_WAIT_HOST_IDLECLEAN);
726 ADVANCE_RING(); 802 ADVANCE_RING();
803 /* set flush & purge flags */
804 dev_priv->track_flush |= RADEON_FLUSH_EMITED | RADEON_PURGE_EMITED;
727} 805}
728 806
729/** 807/**
@@ -905,8 +983,7 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
905 983
906 DRM_DEBUG("\n"); 984 DRM_DEBUG("\n");
907 985
908 /* See the comment above r300_emit_begin3d for why this call must be here, 986 /* pacify */
909 * and what the cleanup gotos are for. */
910 r300_pacify(dev_priv); 987 r300_pacify(dev_priv);
911 988
912 if (cmdbuf->nbox <= R300_SIMULTANEOUS_CLIPRECTS) { 989 if (cmdbuf->nbox <= R300_SIMULTANEOUS_CLIPRECTS) {