/** * cik_sdma_vm_write_pages - update PTEs by writing them manually * * @ib: indirect buffer to fill with commands * @pe: addr of the page entry * @addr: dst addr to write into pe * @count: number of page entries to update * @incr: increase next addr by incr bytes * @flags: access flags * * Update PTEs by writing them manually using sDMA (CIK). */ static void cik_sdma_vm_write_pte(struct amdgpu_ib *ib, uint64_t pe, uint64_t addr, unsigned count, uint32_t incr, uint32_t flags) { uint64_t value; unsigned ndw; while (count) { ndw = count * 2; if (ndw > 0xFFFFE) ndw = 0xFFFFE; /* for non-physically contiguous pages (system) */ ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0); ib->ptr[ib->length_dw++] = pe; ib->ptr[ib->length_dw++] = upper_32_bits(pe); ib->ptr[ib->length_dw++] = ndw; for (; ndw > 0; ndw -= 2, --count, pe += 8) { if (flags & AMDGPU_PTE_SYSTEM) { value = amdgpu_vm_map_gart(ib->ring->adev, addr); value &= 0xFFFFFFFFFFFFF000ULL; } else if (flags & AMDGPU_PTE_VALID) { value = addr; } else { value = 0; } addr += incr; value |= flags; ib->ptr[ib->length_dw++] = value; ib->ptr[ib->length_dw++] = upper_32_bits(value); } } }
/** * cik_sdma_vm_write_pages - update PTEs by writing them manually * * @ib: indirect buffer to fill with commands * @pe: addr of the page entry * @addr: dst addr to write into pe * @count: number of page entries to update * @incr: increase next addr by incr bytes * @flags: access flags * * Update PTEs by writing them manually using sDMA (CIK). */ static void cik_sdma_vm_write_pte(struct amdgpu_ib *ib, const dma_addr_t *pages_addr, uint64_t pe, uint64_t addr, unsigned count, uint32_t incr, uint32_t flags) { uint64_t value; unsigned ndw; while (count) { ndw = count * 2; if (ndw > 0xFFFFE) ndw = 0xFFFFE; /* for non-physically contiguous pages (system) */ ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0); ib->ptr[ib->length_dw++] = pe; ib->ptr[ib->length_dw++] = upper_32_bits(pe); ib->ptr[ib->length_dw++] = ndw; for (; ndw > 0; ndw -= 2, --count, pe += 8) { value = amdgpu_vm_map_gart(pages_addr, addr); addr += incr; value |= flags; ib->ptr[ib->length_dw++] = value; ib->ptr[ib->length_dw++] = upper_32_bits(value); } } }
/** * amdgpu_vm_cpu_update - helper to update page tables via CPU * * @p: see amdgpu_vm_update_params definition * @bo: PD/PT to update * @pe: kmap addr of the page entry * @addr: dst addr to write into pe * @count: number of page entries to update * @incr: increase next addr by incr bytes * @flags: hw access flags * * Write count number of PT/PD entries directly. */ static int amdgpu_vm_cpu_update(struct amdgpu_vm_update_params *p, struct amdgpu_bo *bo, uint64_t pe, uint64_t addr, unsigned count, uint32_t incr, uint64_t flags) { unsigned int i; uint64_t value; pe += (unsigned long)amdgpu_bo_kptr(bo); trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags); for (i = 0; i < count; i++) { value = p->pages_addr ? amdgpu_vm_map_gart(p->pages_addr, addr) : addr; amdgpu_gmc_set_pte_pde(p->adev, (void *)(uintptr_t)pe, i, value, flags); addr += incr; } return 0; }