Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon: Sync ME and PFP after CP semaphore waits v4

Fixes lockups due to CP read GPUVM faults when running piglit on Cape
Verde.

v2 (chk): apply the fix to R600+ as well, on CIK only the GFX CP has
a PFP, add more comments to R600 code, enable flushing again
v3: (agd5f): only apply to 7xx+. r6xx does not have the packet.
v4: (agd5f): split flush change into a separate patch, fix formatting

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Tested-by: Michel Dänzer <michel.daenzer@amd.com>

authored by

Christian König and committed by
Alex Deucher
86302eea 73ef0e0d

+36
+17
drivers/gpu/drm/radeon/cik.c
··· 3920 3920 radeon_ring_write(ring, 0); 3921 3921 } 3922 3922 3923 + /** 3924 + * cik_semaphore_ring_emit - emit a semaphore on the CP ring 3925 + * 3926 + * @rdev: radeon_device pointer 3927 + * @ring: radeon ring buffer object 3928 + * @semaphore: radeon semaphore object 3929 + * @emit_wait: Is this a sempahore wait? 3930 + * 3931 + * Emits a semaphore signal/wait packet to the CP ring and prevents the PFP 3932 + * from running ahead of semaphore waits. 3933 + */ 3923 3934 bool cik_semaphore_ring_emit(struct radeon_device *rdev, 3924 3935 struct radeon_ring *ring, 3925 3936 struct radeon_semaphore *semaphore, ··· 3942 3931 radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); 3943 3932 radeon_ring_write(ring, lower_32_bits(addr)); 3944 3933 radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel); 3934 + 3935 + if (emit_wait && ring->idx == RADEON_RING_TYPE_GFX_INDEX) { 3936 + /* Prevent the PFP from running ahead of the semaphore wait */ 3937 + radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); 3938 + radeon_ring_write(ring, 0x0); 3939 + } 3945 3940 3946 3941 return true; 3947 3942 }
+18
drivers/gpu/drm/radeon/r600.c
··· 2753 2753 } 2754 2754 } 2755 2755 2756 + /** 2757 + * r600_semaphore_ring_emit - emit a semaphore on the CP ring 2758 + * 2759 + * @rdev: radeon_device pointer 2760 + * @ring: radeon ring buffer object 2761 + * @semaphore: radeon semaphore object 2762 + * @emit_wait: Is this a sempahore wait? 2763 + * 2764 + * Emits a semaphore signal/wait packet to the CP ring and prevents the PFP 2765 + * from running ahead of semaphore waits. 2766 + */ 2756 2767 bool r600_semaphore_ring_emit(struct radeon_device *rdev, 2757 2768 struct radeon_ring *ring, 2758 2769 struct radeon_semaphore *semaphore, ··· 2778 2767 radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); 2779 2768 radeon_ring_write(ring, lower_32_bits(addr)); 2780 2769 radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel); 2770 + 2771 + /* PFP_SYNC_ME packet only exists on 7xx+ */ 2772 + if (emit_wait && (rdev->family >= CHIP_RV770)) { 2773 + /* Prevent the PFP from running ahead of the semaphore wait */ 2774 + radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); 2775 + radeon_ring_write(ring, 0x0); 2776 + } 2781 2777 2782 2778 return true; 2783 2779 }
+1
drivers/gpu/drm/radeon/r600d.h
··· 1597 1597 */ 1598 1598 # define PACKET3_CP_DMA_CMD_SAIC (1 << 28) 1599 1599 # define PACKET3_CP_DMA_CMD_DAIC (1 << 29) 1600 + #define PACKET3_PFP_SYNC_ME 0x42 /* r7xx+ only */ 1600 1601 #define PACKET3_SURFACE_SYNC 0x43 1601 1602 # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) 1602 1603 # define PACKET3_FULL_CACHE_ENA (1 << 20) /* r7xx+ only */