[PATCH] drm/radeon: Always flush VM again on < CIK
Alex Deucher
alexdeucher at gmail.com
Fri Aug 8 06:34:58 PDT 2014
On Fri, Aug 8, 2014 at 9:31 AM, Alex Deucher <alexdeucher at gmail.com> wrote:
> On Fri, Aug 8, 2014 at 4:50 AM, Michel Dänzer <michel at daenzer.net> wrote:
>> On 08.08.2014 17:44, Christian König wrote:
>>>>>> On Thu, Aug 7, 2014 at 3:59 PM, Alex Deucher <alexdeucher at gmail.com>
>>>>>> wrote:
>>>>>>> We should be using PFP as much as possible. Does the attached
>>>>>>> patch help?
>>>> Unfortunately not.
>>>
>>> Maybe add a readback of the VM base addr pointer to make sure that the
>>> write has really reached the SBRM?
>>
>> I'm not sure what exactly you're thinking of, but I'm happy to test any
>> patches you guys come up with. :)
>>
>
> Maybe some variant of this patch?
Ignore that one. typo. Try this one instead.
Alex
-------------- next part --------------
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index dbd9d81..565201d 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -5007,6 +5007,7 @@ static void si_vm_decode_fault(struct radeon_device *rdev,
void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
{
struct radeon_ring *ring = &rdev->ring[ridx];
+ u32 reg;
if (vm == NULL)
return;
@@ -5017,15 +5018,23 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
WRITE_DATA_DST_SEL(0)));
if (vm->id < 8) {
- radeon_ring_write(ring,
- (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2);
+ reg = (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2;
} else {
- radeon_ring_write(ring,
- (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2);
+ reg = (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2;
}
+ radeon_ring_write(ring, reg);
radeon_ring_write(ring, 0);
radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
+ /* wait for the address change to go through */
+ radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
+ radeon_ring_write(ring, 3); /* == */
+ radeon_ring_write(ring, reg);
+ radeon_ring_write(ring, 0);
+ radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
+ radeon_ring_write(ring, 0x0fffffff);
+ radeon_ring_write(ring, 10);
+
/* flush hdp cache */
radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
@@ -5034,6 +5043,14 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
radeon_ring_write(ring, 0);
radeon_ring_write(ring, 0x1);
+ /* clear the response reg */
+ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+ radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
+ WRITE_DATA_DST_SEL(0)));
+ radeon_ring_write(ring, VM_INVALIDATE_RESPONSE >> 2);
+ radeon_ring_write(ring, 0);
+ radeon_ring_write(ring, 0);
+
/* bits 0-15 are the VM contexts0-15 */
radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
@@ -5042,6 +5059,15 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
radeon_ring_write(ring, 0);
radeon_ring_write(ring, 1 << vm->id);
+ /* wait for the invalidate */
+ radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
+ radeon_ring_write(ring, 3); /* == */
+ radeon_ring_write(ring, VM_INVALIDATE_RESPONSE >> 2);
+ radeon_ring_write(ring, 0);
+ radeon_ring_write(ring, 1 << vm->id);
+ radeon_ring_write(ring, 1 << vm->id);
+ radeon_ring_write(ring, 10);
+
/* sync PFP to ME, otherwise we might get invalid PFP reads */
radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
radeon_ring_write(ring, 0x0);
More information about the dri-devel
mailing list