diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 96 |
1 files changed, 57 insertions, 39 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index df69aae99df4..3b045e0b114e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -75,11 +75,18 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, struct amdgpu_vmhub *hub; u32 tmp, reg, bits, i; + bits = VM_CONTEXT1_CNTL__RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | + VM_CONTEXT1_CNTL__DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | + VM_CONTEXT1_CNTL__PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | + VM_CONTEXT1_CNTL__VALID_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | + VM_CONTEXT1_CNTL__READ_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | + VM_CONTEXT1_CNTL__WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | + VM_CONTEXT1_CNTL__EXECUTE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK; + switch (state) { case AMDGPU_IRQ_STATE_DISABLE: /* MM HUB */ hub = &adev->vmhub[AMDGPU_MMHUB]; - bits = hub->get_vm_protection_bits(); for (i = 0; i< 16; i++) { reg = hub->vm_context0_cntl + i; tmp = RREG32(reg); @@ -89,7 +96,6 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, /* GFX HUB */ hub = &adev->vmhub[AMDGPU_GFXHUB]; - bits = hub->get_vm_protection_bits(); for (i = 0; i < 16; i++) { reg = hub->vm_context0_cntl + i; tmp = RREG32(reg); @@ -100,7 +106,6 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, case AMDGPU_IRQ_STATE_ENABLE: /* MM HUB */ hub = &adev->vmhub[AMDGPU_MMHUB]; - bits = hub->get_vm_protection_bits(); for (i = 0; i< 16; i++) { reg = hub->vm_context0_cntl + i; tmp = RREG32(reg); @@ -110,7 +115,6 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, /* GFX HUB */ hub = &adev->vmhub[AMDGPU_GFXHUB]; - bits = hub->get_vm_protection_bits(); for (i = 0; i < 16; i++) { reg = hub->vm_context0_cntl + i; tmp = RREG32(reg); @@ -129,8 +133,7 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) { - struct amdgpu_vmhub *gfxhub = &adev->vmhub[AMDGPU_GFXHUB]; - struct amdgpu_vmhub *mmhub = &adev->vmhub[AMDGPU_MMHUB]; + struct amdgpu_vmhub *hub = &adev->vmhub[entry->vm_id_src]; uint32_t status = 0; u64 addr; @@ -138,13 +141,8 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, addr |= ((u64)entry->src_data[1] & 0xf) << 44; if (!amdgpu_sriov_vf(adev)) { - if (entry->vm_id_src) { - status = RREG32(mmhub->vm_l2_pro_fault_status); - WREG32_P(mmhub->vm_l2_pro_fault_cntl, 1, ~1); - } else { - status = RREG32(gfxhub->vm_l2_pro_fault_status); - WREG32_P(gfxhub->vm_l2_pro_fault_cntl, 1, ~1); - } + status = RREG32(hub->vm_l2_pro_fault_status); + WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1); } if (printk_ratelimit()) { @@ -175,6 +173,25 @@ static void gmc_v9_0_set_irq_funcs(struct amdgpu_device *adev) adev->mc.vm_fault.funcs = &gmc_v9_0_irq_funcs; } +static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vm_id) +{ + u32 req = 0; + + /* invalidate using legacy mode on vm_id*/ + req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, + PER_VMID_INVALIDATE_REQ, 1 << vm_id); + req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, 0); + req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1); + req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1); + req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE1, 1); + req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE2, 1); + req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L1_PTES, 1); + req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, + CLEAR_PROTECTION_FAULT_STATUS_ADDR, 0); + + return req; +} + /* * GART * VMID 0 is the physical GPU addresses as used by the kernel. @@ -204,7 +221,7 @@ static void gmc_v9_0_gart_flush_gpu_tlb(struct amdgpu_device *adev, for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) { struct amdgpu_vmhub *hub = &adev->vmhub[i]; - u32 tmp = hub->get_invalidate_req(vmid); + u32 tmp = gmc_v9_0_get_invalidate_req(vmid); WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); @@ -337,30 +354,23 @@ static uint64_t gmc_v9_0_get_vm_pte_flags(struct amdgpu_device *adev, return pte_flag; } -static const struct amdgpu_gart_funcs gmc_v9_0_gart_funcs = { - .flush_gpu_tlb = gmc_v9_0_gart_flush_gpu_tlb, - .set_pte_pde = gmc_v9_0_gart_set_pte_pde, - .get_vm_pte_flags = gmc_v9_0_get_vm_pte_flags -}; - -static void gmc_v9_0_set_gart_funcs(struct amdgpu_device *adev) -{ - if (adev->gart.gart_funcs == NULL) - adev->gart.gart_funcs = &gmc_v9_0_gart_funcs; -} - static u64 gmc_v9_0_adjust_mc_addr(struct amdgpu_device *adev, u64 mc_addr) { return adev->vm_manager.vram_base_offset + mc_addr - adev->mc.vram_start; } -static const struct amdgpu_mc_funcs gmc_v9_0_mc_funcs = { +static const struct amdgpu_gart_funcs gmc_v9_0_gart_funcs = { + .flush_gpu_tlb = gmc_v9_0_gart_flush_gpu_tlb, + .set_pte_pde = gmc_v9_0_gart_set_pte_pde, + .get_vm_pte_flags = gmc_v9_0_get_vm_pte_flags, .adjust_mc_addr = gmc_v9_0_adjust_mc_addr, + .get_invalidate_req = gmc_v9_0_get_invalidate_req, }; -static void gmc_v9_0_set_mc_funcs(struct amdgpu_device *adev) +static void gmc_v9_0_set_gart_funcs(struct amdgpu_device *adev) { - adev->mc.mc_funcs = &gmc_v9_0_mc_funcs; + if (adev->gart.gart_funcs == NULL) + adev->gart.gart_funcs = &gmc_v9_0_gart_funcs; } static int gmc_v9_0_early_init(void *handle) @@ -368,7 +378,6 @@ static int gmc_v9_0_early_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; gmc_v9_0_set_gart_funcs(adev); - gmc_v9_0_set_mc_funcs(adev); gmc_v9_0_set_irq_funcs(adev); return 0; @@ -511,7 +520,12 @@ static int gmc_v9_0_vm_init(struct amdgpu_device *adev) * amdkfd will use VMIDs 8-15 */ adev->vm_manager.num_ids = AMDGPU_NUM_OF_VMIDS; - adev->vm_manager.num_level = 3; + + /* TODO: fix num_level for APU when updating vm size and block size */ + if (adev->flags & AMD_IS_APU) + adev->vm_manager.num_level = 1; + else + adev->vm_manager.num_level = 3; amdgpu_vm_manager_init(adev); /* base offset of vram pages */ @@ -543,9 +557,20 @@ static int gmc_v9_0_sw_init(void *handle) if (adev->flags & AMD_IS_APU) { adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; + amdgpu_vm_adjust_size(adev, 64); } else { /* XXX Don't know how to get VRAM type yet. */ adev->mc.vram_type = AMDGPU_VRAM_TYPE_HBM; + /* + * To fulfill 4-level page support, + * vm size is 256TB (48bit), maximum size of Vega10, + * block size 512 (9bit) + */ + adev->vm_manager.vm_size = 1U << 18; + adev->vm_manager.block_size = 9; + DRM_INFO("vm size is %llu GB, block size is %u-bit\n", + adev->vm_manager.vm_size, + adev->vm_manager.block_size); } /* This interrupt is VMC page fault.*/ @@ -557,14 +582,7 @@ static int gmc_v9_0_sw_init(void *handle) if (r) return r; - /* Because of four level VMPTs, vm size is at least 512GB. - * The maximum size is 256TB (48bit). - */ - if (amdgpu_vm_size < 512) { - DRM_WARN("VM size is at least 512GB!\n"); - amdgpu_vm_size = 512; - } - adev->vm_manager.max_pfn = (uint64_t)amdgpu_vm_size << 18; + adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18; /* Set the internal MC address mask * This is the max address of the GPU's |