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

Configure Feed

Select the types of activity you want to include in your feed.

drm/radeon: implement async vm_flush for the sDMA (v6)

Update the page table base address and flush the
VM TLB using the sDMA.

V2: update for 2 level PTs
V3: update vm flush
V4: update SH_MEM* regs
V5: switch back to old style VM TLB invalidate
V6: fix packet formatting

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

+70
+70
drivers/gpu/drm/radeon/cik.c
··· 3407 3407 radeon_ring_write(ring, 0x0); 3408 3408 } 3409 3409 3410 + /** 3411 + * cik_dma_vm_flush - cik vm flush using sDMA 3412 + * 3413 + * @rdev: radeon_device pointer 3414 + * 3415 + * Update the page table base and flush the VM TLB 3416 + * using sDMA (CIK). 3417 + */ 3418 + void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) 3419 + { 3420 + struct radeon_ring *ring = &rdev->ring[ridx]; 3421 + u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(1) | 3422 + SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */ 3423 + u32 ref_and_mask; 3424 + 3425 + if (vm == NULL) 3426 + return; 3427 + 3428 + if (ridx == R600_RING_TYPE_DMA_INDEX) 3429 + ref_and_mask = SDMA0; 3430 + else 3431 + ref_and_mask = SDMA1; 3432 + 3433 + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); 3434 + if (vm->id < 8) { 3435 + radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2); 3436 + } else { 3437 + radeon_ring_write(ring, (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2); 3438 + } 3439 + radeon_ring_write(ring, vm->pd_gpu_addr >> 12); 3440 + 3441 + /* update SH_MEM_* regs */ 3442 + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); 3443 + radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); 3444 + radeon_ring_write(ring, VMID(vm->id)); 3445 + 3446 + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); 3447 + radeon_ring_write(ring, SH_MEM_BASES >> 2); 3448 + radeon_ring_write(ring, 0); 3449 + 3450 + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); 3451 + radeon_ring_write(ring, SH_MEM_CONFIG >> 2); 3452 + radeon_ring_write(ring, 0); 3453 + 3454 + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); 3455 + radeon_ring_write(ring, SH_MEM_APE1_BASE >> 2); 3456 + radeon_ring_write(ring, 1); 3457 + 3458 + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); 3459 + radeon_ring_write(ring, SH_MEM_APE1_LIMIT >> 2); 3460 + radeon_ring_write(ring, 0); 3461 + 3462 + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); 3463 + radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); 3464 + radeon_ring_write(ring, VMID(0)); 3465 + 3466 + /* flush HDP */ 3467 + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits)); 3468 + radeon_ring_write(ring, GPU_HDP_FLUSH_DONE); 3469 + radeon_ring_write(ring, GPU_HDP_FLUSH_REQ); 3470 + radeon_ring_write(ring, ref_and_mask); /* REFERENCE */ 3471 + radeon_ring_write(ring, ref_and_mask); /* MASK */ 3472 + radeon_ring_write(ring, (4 << 16) | 10); /* RETRY_COUNT, POLL_INTERVAL */ 3473 + 3474 + /* flush TLB */ 3475 + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); 3476 + radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); 3477 + radeon_ring_write(ring, 1 << vm->id); 3478 + } 3479 + 3410 3480 /* 3411 3481 * RLC 3412 3482 * The RLC is a multi-purpose microengine that handles a