drm/amdgpu: implement 2+1 PD support for Raven v3
Instead of falling back to 2 level and very limited address space use 2+1 PD support and 128TB + 512GB of virtual address space. v2: cleanup defines, rebase on top of level enum v3: fix inverted check in hardware setup Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-and-Tested-by: Chunming Zhou <david1.zhou@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
78f99c6d5c
commit
6a42fd6fbf
@ -540,6 +540,7 @@ struct amdgpu_mc {
|
|||||||
u64 private_aperture_end;
|
u64 private_aperture_end;
|
||||||
/* protects concurrent invalidation */
|
/* protects concurrent invalidation */
|
||||||
spinlock_t invalidate_lock;
|
spinlock_t invalidate_lock;
|
||||||
|
bool translate_further;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -70,6 +70,12 @@ struct amdgpu_bo_list_entry;
|
|||||||
/* PDE is handled as PTE for VEGA10 */
|
/* PDE is handled as PTE for VEGA10 */
|
||||||
#define AMDGPU_PDE_PTE (1ULL << 54)
|
#define AMDGPU_PDE_PTE (1ULL << 54)
|
||||||
|
|
||||||
|
/* PTE is handled as PDE for VEGA10 (Translate Further) */
|
||||||
|
#define AMDGPU_PTE_TF (1ULL << 56)
|
||||||
|
|
||||||
|
/* PDE Block Fragment Size for VEGA10 */
|
||||||
|
#define AMDGPU_PDE_BFS(a) ((uint64_t)a << 59)
|
||||||
|
|
||||||
/* VEGA10 only */
|
/* VEGA10 only */
|
||||||
#define AMDGPU_PTE_MTYPE(a) ((uint64_t)a << 57)
|
#define AMDGPU_PTE_MTYPE(a) ((uint64_t)a << 57)
|
||||||
#define AMDGPU_PTE_MTYPE_MASK AMDGPU_PTE_MTYPE(3ULL)
|
#define AMDGPU_PTE_MTYPE_MASK AMDGPU_PTE_MTYPE(3ULL)
|
||||||
|
@ -143,8 +143,15 @@ static void gfxhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
|
|||||||
WREG32_SOC15(GC, 0, mmVM_L2_CNTL2, tmp);
|
WREG32_SOC15(GC, 0, mmVM_L2_CNTL2, tmp);
|
||||||
|
|
||||||
tmp = mmVM_L2_CNTL3_DEFAULT;
|
tmp = mmVM_L2_CNTL3_DEFAULT;
|
||||||
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 9);
|
if (adev->mc.translate_further) {
|
||||||
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
|
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 12);
|
||||||
|
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3,
|
||||||
|
L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
|
||||||
|
} else {
|
||||||
|
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 9);
|
||||||
|
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3,
|
||||||
|
L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
|
||||||
|
}
|
||||||
WREG32_SOC15(GC, 0, mmVM_L2_CNTL3, tmp);
|
WREG32_SOC15(GC, 0, mmVM_L2_CNTL3, tmp);
|
||||||
|
|
||||||
tmp = mmVM_L2_CNTL4_DEFAULT;
|
tmp = mmVM_L2_CNTL4_DEFAULT;
|
||||||
@ -182,31 +189,40 @@ static void gfxhub_v1_0_disable_identity_aperture(struct amdgpu_device *adev)
|
|||||||
|
|
||||||
static void gfxhub_v1_0_setup_vmid_config(struct amdgpu_device *adev)
|
static void gfxhub_v1_0_setup_vmid_config(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned num_level, block_size;
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
num_level = adev->vm_manager.num_level;
|
||||||
|
block_size = adev->vm_manager.block_size;
|
||||||
|
if (adev->mc.translate_further)
|
||||||
|
num_level -= 1;
|
||||||
|
else
|
||||||
|
block_size -= 9;
|
||||||
|
|
||||||
for (i = 0; i <= 14; i++) {
|
for (i = 0; i <= 14; i++) {
|
||||||
tmp = RREG32_SOC15_OFFSET(GC, 0, mmVM_CONTEXT1_CNTL, i);
|
tmp = RREG32_SOC15_OFFSET(GC, 0, mmVM_CONTEXT1_CNTL, i);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1);
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH,
|
||||||
adev->vm_manager.num_level);
|
num_level);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT,
|
||||||
|
1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
PAGE_TABLE_BLOCK_SIZE,
|
PAGE_TABLE_BLOCK_SIZE,
|
||||||
adev->vm_manager.block_size - 9);
|
block_size);
|
||||||
/* Send no-retry XNACK on fault to suppress VM fault storm. */
|
/* Send no-retry XNACK on fault to suppress VM fault storm. */
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
|
RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
|
||||||
|
@ -476,6 +476,21 @@ static void gmc_v9_0_get_vm_pde(struct amdgpu_device *adev, int level,
|
|||||||
*addr = adev->vm_manager.vram_base_offset + *addr -
|
*addr = adev->vm_manager.vram_base_offset + *addr -
|
||||||
adev->mc.vram_start;
|
adev->mc.vram_start;
|
||||||
BUG_ON(*addr & 0xFFFF00000000003FULL);
|
BUG_ON(*addr & 0xFFFF00000000003FULL);
|
||||||
|
|
||||||
|
if (!adev->mc.translate_further)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (level == AMDGPU_VM_PDB1) {
|
||||||
|
/* Set the block fragment size */
|
||||||
|
if (!(*flags & AMDGPU_PDE_PTE))
|
||||||
|
*flags |= AMDGPU_PDE_BFS(0x9);
|
||||||
|
|
||||||
|
} else if (level == AMDGPU_VM_PDB0) {
|
||||||
|
if (*flags & AMDGPU_PDE_PTE)
|
||||||
|
*flags &= ~AMDGPU_PDE_PTE;
|
||||||
|
else
|
||||||
|
*flags |= AMDGPU_PTE_TF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct amdgpu_gart_funcs gmc_v9_0_gart_funcs = {
|
static const struct amdgpu_gart_funcs gmc_v9_0_gart_funcs = {
|
||||||
@ -773,11 +788,14 @@ static int gmc_v9_0_sw_init(void *handle)
|
|||||||
switch (adev->asic_type) {
|
switch (adev->asic_type) {
|
||||||
case CHIP_RAVEN:
|
case CHIP_RAVEN:
|
||||||
adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
|
adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
|
||||||
if (adev->rev_id == 0x0 || adev->rev_id == 0x1)
|
if (adev->rev_id == 0x0 || adev->rev_id == 0x1) {
|
||||||
amdgpu_vm_adjust_size(adev, 256 * 1024, 9, 3, 48);
|
amdgpu_vm_adjust_size(adev, 256 * 1024, 9, 3, 48);
|
||||||
else
|
} else {
|
||||||
/* vm_size is 64GB for legacy 2-level page support */
|
/* vm_size is 128TB + 512GB for legacy 3-level page support */
|
||||||
amdgpu_vm_adjust_size(adev, 64, 9, 1, 48);
|
amdgpu_vm_adjust_size(adev, 128 * 1024 + 512, 9, 2, 48);
|
||||||
|
adev->mc.translate_further =
|
||||||
|
adev->vm_manager.num_level > 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CHIP_VEGA10:
|
case CHIP_VEGA10:
|
||||||
/* XXX Don't know how to get VRAM type yet. */
|
/* XXX Don't know how to get VRAM type yet. */
|
||||||
|
@ -155,10 +155,15 @@ static void mmhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
|
|||||||
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
|
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
|
||||||
WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL2, tmp);
|
WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL2, tmp);
|
||||||
|
|
||||||
tmp = mmVM_L2_CNTL3_DEFAULT;
|
if (adev->mc.translate_further) {
|
||||||
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 9);
|
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 12);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
|
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3,
|
||||||
WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL3, tmp);
|
L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
|
||||||
|
} else {
|
||||||
|
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 9);
|
||||||
|
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3,
|
||||||
|
L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
|
||||||
|
}
|
||||||
|
|
||||||
tmp = mmVM_L2_CNTL4_DEFAULT;
|
tmp = mmVM_L2_CNTL4_DEFAULT;
|
||||||
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL4, VMC_TAP_PDE_REQUEST_PHYSICAL, 0);
|
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL4, VMC_TAP_PDE_REQUEST_PHYSICAL, 0);
|
||||||
@ -196,32 +201,40 @@ static void mmhub_v1_0_disable_identity_aperture(struct amdgpu_device *adev)
|
|||||||
|
|
||||||
static void mmhub_v1_0_setup_vmid_config(struct amdgpu_device *adev)
|
static void mmhub_v1_0_setup_vmid_config(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned num_level, block_size;
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
num_level = adev->vm_manager.num_level;
|
||||||
|
block_size = adev->vm_manager.block_size;
|
||||||
|
if (adev->mc.translate_further)
|
||||||
|
num_level -= 1;
|
||||||
|
else
|
||||||
|
block_size -= 9;
|
||||||
|
|
||||||
for (i = 0; i <= 14; i++) {
|
for (i = 0; i <= 14; i++) {
|
||||||
tmp = RREG32_SOC15_OFFSET(MMHUB, 0, mmVM_CONTEXT1_CNTL, i);
|
tmp = RREG32_SOC15_OFFSET(MMHUB, 0, mmVM_CONTEXT1_CNTL, i);
|
||||||
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1);
|
||||||
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH,
|
||||||
|
num_level);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
ENABLE_CONTEXT, 1);
|
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
PAGE_TABLE_DEPTH, adev->vm_manager.num_level);
|
DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT,
|
||||||
|
1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
PAGE_TABLE_BLOCK_SIZE,
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
block_size);
|
||||||
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
|
||||||
PAGE_TABLE_BLOCK_SIZE,
|
|
||||||
adev->vm_manager.block_size - 9);
|
|
||||||
/* Send no-retry XNACK on fault to suppress VM fault storm. */
|
/* Send no-retry XNACK on fault to suppress VM fault storm. */
|
||||||
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
|
||||||
RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
|
RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user