Commit e618d306 authored by Roger He's avatar Roger He Committed by Alex Deucher

drm/amd/amdgpu: store fragment_size in vm_manager

adds fragment_size in the vm_manager structure and
implements hardware setup for it.
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarRoger He <Hongbo.He@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 27c7b9ae
...@@ -590,11 +590,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file ...@@ -590,11 +590,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
dev_info.virtual_address_offset = AMDGPU_VA_RESERVED_SIZE; dev_info.virtual_address_offset = AMDGPU_VA_RESERVED_SIZE;
dev_info.virtual_address_max = (uint64_t)adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE; dev_info.virtual_address_max = (uint64_t)adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE;
dev_info.virtual_address_alignment = max((int)PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE); dev_info.virtual_address_alignment = max((int)PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE);
dev_info.pte_fragment_size = dev_info.pte_fragment_size = (1 << adev->vm_manager.fragment_size) * AMDGPU_GPU_PAGE_SIZE;
(1 << AMDGPU_LOG2_PAGES_PER_FRAG(adev)) *
AMDGPU_GPU_PAGE_SIZE;
dev_info.gart_page_size = AMDGPU_GPU_PAGE_SIZE; dev_info.gart_page_size = AMDGPU_GPU_PAGE_SIZE;
dev_info.cu_active_number = adev->gfx.cu_info.number; dev_info.cu_active_number = adev->gfx.cu_info.number;
dev_info.cu_ao_mask = adev->gfx.cu_info.ao_cu_mask; dev_info.cu_ao_mask = adev->gfx.cu_info.ao_cu_mask;
dev_info.ce_ram_size = adev->gfx.ce_ram_size; dev_info.ce_ram_size = adev->gfx.ce_ram_size;
......
...@@ -1410,9 +1410,7 @@ static int amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params, ...@@ -1410,9 +1410,7 @@ static int amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params,
* Userspace can support this by aligning virtual base address and * Userspace can support this by aligning virtual base address and
* allocation size to the fragment size. * allocation size to the fragment size.
*/ */
unsigned pages_per_frag = params->adev->vm_manager.fragment_size;
/* SI and newer are optimized for 64KB */
unsigned pages_per_frag = AMDGPU_LOG2_PAGES_PER_FRAG(params->adev);
uint64_t frag_flags = AMDGPU_PTE_FRAG(pages_per_frag); uint64_t frag_flags = AMDGPU_PTE_FRAG(pages_per_frag);
uint64_t frag_align = 1 << pages_per_frag; uint64_t frag_align = 1 << pages_per_frag;
......
...@@ -50,11 +50,6 @@ struct amdgpu_bo_list_entry; ...@@ -50,11 +50,6 @@ struct amdgpu_bo_list_entry;
/* PTBs (Page Table Blocks) need to be aligned to 32K */ /* PTBs (Page Table Blocks) need to be aligned to 32K */
#define AMDGPU_VM_PTB_ALIGN_SIZE 32768 #define AMDGPU_VM_PTB_ALIGN_SIZE 32768
/* LOG2 number of continuous pages for the fragment field */
#define AMDGPU_LOG2_PAGES_PER_FRAG(adev) \
((adev)->asic_type < CHIP_VEGA10 ? 4 : \
(adev)->vm_manager.block_size)
#define AMDGPU_PTE_VALID (1ULL << 0) #define AMDGPU_PTE_VALID (1ULL << 0)
#define AMDGPU_PTE_SYSTEM (1ULL << 1) #define AMDGPU_PTE_SYSTEM (1ULL << 1)
#define AMDGPU_PTE_SNOOPED (1ULL << 2) #define AMDGPU_PTE_SNOOPED (1ULL << 2)
...@@ -200,6 +195,7 @@ struct amdgpu_vm_manager { ...@@ -200,6 +195,7 @@ struct amdgpu_vm_manager {
uint32_t num_level; uint32_t num_level;
uint64_t vm_size; uint64_t vm_size;
uint32_t block_size; uint32_t block_size;
uint32_t fragment_size;
/* vram base address for page table entry */ /* vram base address for page table entry */
u64 vram_base_offset; u64 vram_base_offset;
/* vm pte handling */ /* vm pte handling */
......
...@@ -124,7 +124,7 @@ static void gfxhub_v1_0_init_tlb_regs(struct amdgpu_device *adev) ...@@ -124,7 +124,7 @@ static void gfxhub_v1_0_init_tlb_regs(struct amdgpu_device *adev)
static void gfxhub_v1_0_init_cache_regs(struct amdgpu_device *adev) static void gfxhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
{ {
uint32_t tmp; uint32_t tmp, field;
/* Setup L2 cache */ /* Setup L2 cache */
tmp = RREG32_SOC15(GC, 0, mmVM_L2_CNTL); tmp = RREG32_SOC15(GC, 0, mmVM_L2_CNTL);
...@@ -143,8 +143,9 @@ static void gfxhub_v1_0_init_cache_regs(struct amdgpu_device *adev) ...@@ -143,8 +143,9 @@ static void gfxhub_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(GC, 0, mmVM_L2_CNTL2, tmp); WREG32_SOC15(GC, 0, mmVM_L2_CNTL2, tmp);
field = adev->vm_manager.fragment_size;
tmp = mmVM_L2_CNTL3_DEFAULT; tmp = mmVM_L2_CNTL3_DEFAULT;
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 9); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, field);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 6); 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);
......
...@@ -461,6 +461,7 @@ static void gmc_v6_0_set_prt(struct amdgpu_device *adev, bool enable) ...@@ -461,6 +461,7 @@ static void gmc_v6_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v6_0_gart_enable(struct amdgpu_device *adev) static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
{ {
int r, i; int r, i;
u32 field;
if (adev->gart.robj == NULL) { if (adev->gart.robj == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n"); dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
...@@ -488,10 +489,12 @@ static int gmc_v6_0_gart_enable(struct amdgpu_device *adev) ...@@ -488,10 +489,12 @@ static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
WREG32(mmVM_L2_CNTL2, WREG32(mmVM_L2_CNTL2,
VM_L2_CNTL2__INVALIDATE_ALL_L1_TLBS_MASK | VM_L2_CNTL2__INVALIDATE_ALL_L1_TLBS_MASK |
VM_L2_CNTL2__INVALIDATE_L2_CACHE_MASK); VM_L2_CNTL2__INVALIDATE_L2_CACHE_MASK);
field = adev->vm_manager.fragment_size;
WREG32(mmVM_L2_CNTL3, WREG32(mmVM_L2_CNTL3,
VM_L2_CNTL3__L2_CACHE_BIGK_ASSOCIATIVITY_MASK | VM_L2_CNTL3__L2_CACHE_BIGK_ASSOCIATIVITY_MASK |
(4UL << VM_L2_CNTL3__BANK_SELECT__SHIFT) | (field << VM_L2_CNTL3__BANK_SELECT__SHIFT) |
(4UL << VM_L2_CNTL3__L2_CACHE_BIGK_FRAGMENT_SIZE__SHIFT)); (field << VM_L2_CNTL3__L2_CACHE_BIGK_FRAGMENT_SIZE__SHIFT));
/* setup context0 */ /* setup context0 */
WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gart_start >> 12); WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gart_start >> 12);
WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gart_end >> 12); WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gart_end >> 12);
...@@ -812,6 +815,7 @@ static int gmc_v6_0_sw_init(void *handle) ...@@ -812,6 +815,7 @@ static int gmc_v6_0_sw_init(void *handle)
return r; return r;
amdgpu_vm_adjust_size(adev, 64); amdgpu_vm_adjust_size(adev, 64);
adev->vm_manager.fragment_size = 4;
adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18; adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18;
adev->mc.mc_mask = 0xffffffffffULL; adev->mc.mc_mask = 0xffffffffffULL;
......
...@@ -562,7 +562,7 @@ static void gmc_v7_0_set_prt(struct amdgpu_device *adev, bool enable) ...@@ -562,7 +562,7 @@ static void gmc_v7_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v7_0_gart_enable(struct amdgpu_device *adev) static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
{ {
int r, i; int r, i;
u32 tmp; u32 tmp, field;
if (adev->gart.robj == NULL) { if (adev->gart.robj == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n"); dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
...@@ -592,10 +592,12 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev) ...@@ -592,10 +592,12 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(0, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1); tmp = REG_SET_FIELD(0, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1);
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(mmVM_L2_CNTL2, tmp); WREG32(mmVM_L2_CNTL2, tmp);
field = adev->vm_manager.fragment_size;
tmp = RREG32(mmVM_L2_CNTL3); tmp = RREG32(mmVM_L2_CNTL3);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY, 1); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY, 1);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 4); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, field);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 4); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, field);
WREG32(mmVM_L2_CNTL3, tmp); WREG32(mmVM_L2_CNTL3, tmp);
/* setup context0 */ /* setup context0 */
WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gart_start >> 12); WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gart_start >> 12);
...@@ -949,6 +951,7 @@ static int gmc_v7_0_sw_init(void *handle) ...@@ -949,6 +951,7 @@ static int gmc_v7_0_sw_init(void *handle)
* Max GPUVM size for cayman and SI is 40 bits. * Max GPUVM size for cayman and SI is 40 bits.
*/ */
amdgpu_vm_adjust_size(adev, 64); amdgpu_vm_adjust_size(adev, 64);
adev->vm_manager.fragment_size = 4;
adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18; adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18;
/* Set the internal MC address mask /* Set the internal MC address mask
......
...@@ -762,7 +762,7 @@ static void gmc_v8_0_set_prt(struct amdgpu_device *adev, bool enable) ...@@ -762,7 +762,7 @@ static void gmc_v8_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v8_0_gart_enable(struct amdgpu_device *adev) static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
{ {
int r, i; int r, i;
u32 tmp; u32 tmp, field;
if (adev->gart.robj == NULL) { if (adev->gart.robj == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n"); dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
...@@ -793,10 +793,12 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev) ...@@ -793,10 +793,12 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1);
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(mmVM_L2_CNTL2, tmp); WREG32(mmVM_L2_CNTL2, tmp);
field = adev->vm_manager.fragment_size;
tmp = RREG32(mmVM_L2_CNTL3); tmp = RREG32(mmVM_L2_CNTL3);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY, 1); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY, 1);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 4); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, field);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 4); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, field);
WREG32(mmVM_L2_CNTL3, tmp); WREG32(mmVM_L2_CNTL3, tmp);
/* XXX: set to enable PTE/PDE in system memory */ /* XXX: set to enable PTE/PDE in system memory */
tmp = RREG32(mmVM_L2_CNTL4); tmp = RREG32(mmVM_L2_CNTL4);
...@@ -1047,6 +1049,7 @@ static int gmc_v8_0_sw_init(void *handle) ...@@ -1047,6 +1049,7 @@ static int gmc_v8_0_sw_init(void *handle)
* Max GPUVM size for cayman and SI is 40 bits. * Max GPUVM size for cayman and SI is 40 bits.
*/ */
amdgpu_vm_adjust_size(adev, 64); amdgpu_vm_adjust_size(adev, 64);
adev->vm_manager.fragment_size = 4;
adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18; adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18;
/* Set the internal MC address mask /* Set the internal MC address mask
......
...@@ -541,10 +541,12 @@ static int gmc_v9_0_sw_init(void *handle) ...@@ -541,10 +541,12 @@ static int gmc_v9_0_sw_init(void *handle)
adev->vm_manager.vm_size = 1U << 18; adev->vm_manager.vm_size = 1U << 18;
adev->vm_manager.block_size = 9; adev->vm_manager.block_size = 9;
adev->vm_manager.num_level = 3; adev->vm_manager.num_level = 3;
adev->vm_manager.fragment_size = 9;
} else { } else {
/* vm_size is 64GB for legacy 2-level page support*/ /* vm_size is 64GB for legacy 2-level page support*/
amdgpu_vm_adjust_size(adev, 64); amdgpu_vm_adjust_size(adev, 64);
adev->vm_manager.num_level = 1; adev->vm_manager.num_level = 1;
adev->vm_manager.fragment_size = 9;
} }
break; break;
case CHIP_VEGA10: case CHIP_VEGA10:
...@@ -558,14 +560,16 @@ static int gmc_v9_0_sw_init(void *handle) ...@@ -558,14 +560,16 @@ static int gmc_v9_0_sw_init(void *handle)
adev->vm_manager.vm_size = 1U << 18; adev->vm_manager.vm_size = 1U << 18;
adev->vm_manager.block_size = 9; adev->vm_manager.block_size = 9;
adev->vm_manager.num_level = 3; adev->vm_manager.num_level = 3;
adev->vm_manager.fragment_size = 9;
break; break;
default: default:
break; break;
} }
DRM_INFO("vm size is %llu GB, block size is %u-bit\n", DRM_INFO("vm size is %llu GB, block size is %u-bit,fragment size is %u-bit\n",
adev->vm_manager.vm_size, adev->vm_manager.vm_size,
adev->vm_manager.block_size); adev->vm_manager.block_size,
adev->vm_manager.fragment_size);
/* This interrupt is VMC page fault.*/ /* This interrupt is VMC page fault.*/
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_VMC, 0, r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_VMC, 0,
......
...@@ -138,7 +138,7 @@ static void mmhub_v1_0_init_tlb_regs(struct amdgpu_device *adev) ...@@ -138,7 +138,7 @@ static void mmhub_v1_0_init_tlb_regs(struct amdgpu_device *adev)
static void mmhub_v1_0_init_cache_regs(struct amdgpu_device *adev) static void mmhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
{ {
uint32_t tmp; uint32_t tmp, field;
/* Setup L2 cache */ /* Setup L2 cache */
tmp = RREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL); tmp = RREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL);
...@@ -157,8 +157,9 @@ static void mmhub_v1_0_init_cache_regs(struct amdgpu_device *adev) ...@@ -157,8 +157,9 @@ 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);
field = adev->vm_manager.fragment_size;
tmp = mmVM_L2_CNTL3_DEFAULT; tmp = mmVM_L2_CNTL3_DEFAULT;
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 9); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, field);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 6); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL3, tmp); WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL3, tmp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment