diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 135 |
1 files changed, 76 insertions, 59 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index 8e28270d1ea9..2c0ed9dd0c91 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -22,6 +22,7 @@ */ #include <linux/firmware.h> #include <drm/drmP.h> +#include <drm/drm_cache.h> #include "amdgpu.h" #include "gmc_v6_0.h" #include "amdgpu_ucode.h" @@ -36,7 +37,7 @@ #include "dce/dce_6_0_sh_mask.h" #include "si_enums.h" -static void gmc_v6_0_set_gart_funcs(struct amdgpu_device *adev); +static void gmc_v6_0_set_gmc_funcs(struct amdgpu_device *adev); static void gmc_v6_0_set_irq_funcs(struct amdgpu_device *adev); static int gmc_v6_0_wait_for_idle(void *handle); @@ -136,19 +137,19 @@ static int gmc_v6_0_init_microcode(struct amdgpu_device *adev) snprintf(fw_name, sizeof(fw_name), "radeon/si58_mc.bin"); else snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); - err = request_firmware(&adev->mc.fw, fw_name, adev->dev); + err = request_firmware(&adev->gmc.fw, fw_name, adev->dev); if (err) goto out; - err = amdgpu_ucode_validate(adev->mc.fw); + err = amdgpu_ucode_validate(adev->gmc.fw); out: if (err) { dev_err(adev->dev, "si_mc: Failed to load firmware \"%s\"\n", fw_name); - release_firmware(adev->mc.fw); - adev->mc.fw = NULL; + release_firmware(adev->gmc.fw); + adev->gmc.fw = NULL; } return err; } @@ -161,20 +162,20 @@ static int gmc_v6_0_mc_load_microcode(struct amdgpu_device *adev) int i, regs_size, ucode_size; const struct mc_firmware_header_v1_0 *hdr; - if (!adev->mc.fw) + if (!adev->gmc.fw) return -EINVAL; - hdr = (const struct mc_firmware_header_v1_0 *)adev->mc.fw->data; + hdr = (const struct mc_firmware_header_v1_0 *)adev->gmc.fw->data; amdgpu_ucode_print_mc_hdr(&hdr->header); - adev->mc.fw_version = le32_to_cpu(hdr->header.ucode_version); + adev->gmc.fw_version = le32_to_cpu(hdr->header.ucode_version); regs_size = le32_to_cpu(hdr->io_debug_size_bytes) / (4 * 2); new_io_mc_regs = (const __le32 *) - (adev->mc.fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes)); + (adev->gmc.fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes)); ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; new_fw_data = (const __le32 *) - (adev->mc.fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); + (adev->gmc.fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); running = RREG32(mmMC_SEQ_SUP_CNTL) & MC_SEQ_SUP_CNTL__RUN_MASK; @@ -217,12 +218,12 @@ static int gmc_v6_0_mc_load_microcode(struct amdgpu_device *adev) } static void gmc_v6_0_vram_gtt_location(struct amdgpu_device *adev, - struct amdgpu_mc *mc) + struct amdgpu_gmc *mc) { u64 base = RREG32(mmMC_VM_FB_LOCATION) & 0xFFFF; base <<= 24; - amdgpu_device_vram_location(adev, &adev->mc, base); + amdgpu_device_vram_location(adev, &adev->gmc, base); amdgpu_device_gart_location(adev, mc); } @@ -259,9 +260,9 @@ static void gmc_v6_0_mc_program(struct amdgpu_device *adev) } /* Update configuration */ WREG32(mmMC_VM_SYSTEM_APERTURE_LOW_ADDR, - adev->mc.vram_start >> 12); + adev->gmc.vram_start >> 12); WREG32(mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR, - adev->mc.vram_end >> 12); + adev->gmc.vram_end >> 12); WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, adev->vram_scratch.gpu_addr >> 12); WREG32(mmMC_VM_AGP_BASE, 0); @@ -319,56 +320,69 @@ static int gmc_v6_0_mc_init(struct amdgpu_device *adev) numchan = 16; break; } - adev->mc.vram_width = numchan * chansize; + adev->gmc.vram_width = numchan * chansize; /* size in MB on si */ - adev->mc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; - adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; + adev->gmc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; + adev->gmc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; if (!(adev->flags & AMD_IS_APU)) { r = amdgpu_device_resize_fb_bar(adev); if (r) return r; } - adev->mc.aper_base = pci_resource_start(adev->pdev, 0); - adev->mc.aper_size = pci_resource_len(adev->pdev, 0); - adev->mc.visible_vram_size = adev->mc.aper_size; + adev->gmc.aper_base = pci_resource_start(adev->pdev, 0); + adev->gmc.aper_size = pci_resource_len(adev->pdev, 0); + adev->gmc.visible_vram_size = adev->gmc.aper_size; /* set the gart size */ if (amdgpu_gart_size == -1) { switch (adev->asic_type) { case CHIP_HAINAN: /* no MM engines */ default: - adev->mc.gart_size = 256ULL << 20; + adev->gmc.gart_size = 256ULL << 20; break; case CHIP_VERDE: /* UVD, VCE do not support GPUVM */ case CHIP_TAHITI: /* UVD, VCE do not support GPUVM */ case CHIP_PITCAIRN: /* UVD, VCE do not support GPUVM */ case CHIP_OLAND: /* UVD, VCE do not support GPUVM */ - adev->mc.gart_size = 1024ULL << 20; + adev->gmc.gart_size = 1024ULL << 20; break; } } else { - adev->mc.gart_size = (u64)amdgpu_gart_size << 20; + adev->gmc.gart_size = (u64)amdgpu_gart_size << 20; } - gmc_v6_0_vram_gtt_location(adev, &adev->mc); + gmc_v6_0_vram_gtt_location(adev, &adev->gmc); return 0; } -static void gmc_v6_0_gart_flush_gpu_tlb(struct amdgpu_device *adev, - uint32_t vmid) +static void gmc_v6_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid) { - WREG32(mmHDP_MEM_COHERENCY_FLUSH_CNTL, 0); - WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid); } -static int gmc_v6_0_gart_set_pte_pde(struct amdgpu_device *adev, - void *cpu_pt_addr, - uint32_t gpu_page_idx, - uint64_t addr, - uint64_t flags) +static uint64_t gmc_v6_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring, + unsigned vmid, uint64_t pd_addr) +{ + uint32_t reg; + + /* write new base address */ + if (vmid < 8) + reg = mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vmid; + else + reg = mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + (vmid - 8); + amdgpu_ring_emit_wreg(ring, reg, pd_addr >> 12); + + /* bits 0-15 are the VM contexts0-15 */ + amdgpu_ring_emit_wreg(ring, mmVM_INVALIDATE_REQUEST, 1 << vmid); + + return pd_addr; +} + +static int gmc_v6_0_set_pte_pde(struct amdgpu_device *adev, void *cpu_pt_addr, + uint32_t gpu_page_idx, uint64_t addr, + uint64_t flags) { void __iomem *ptr = (void *)cpu_pt_addr; uint64_t value; @@ -432,9 +446,9 @@ static void gmc_v6_0_set_prt(struct amdgpu_device *adev, bool enable) { u32 tmp; - if (enable && !adev->mc.prt_warning) { + if (enable && !adev->gmc.prt_warning) { dev_warn(adev->dev, "Disabling VM faults because of PRT request!\n"); - adev->mc.prt_warning = true; + adev->gmc.prt_warning = true; } tmp = RREG32(mmVM_PRT_CNTL); @@ -454,7 +468,8 @@ static void gmc_v6_0_set_prt(struct amdgpu_device *adev, bool enable) if (enable) { uint32_t low = AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT; - uint32_t high = adev->vm_manager.max_pfn; + uint32_t high = adev->vm_manager.max_pfn - + (AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT); WREG32(mmVM_PRT_APERTURE0_LOW_ADDR, low); WREG32(mmVM_PRT_APERTURE1_LOW_ADDR, low); @@ -514,8 +529,8 @@ static int gmc_v6_0_gart_enable(struct amdgpu_device *adev) (field << VM_L2_CNTL3__BANK_SELECT__SHIFT) | (field << VM_L2_CNTL3__L2_CACHE_BIGK_FRAGMENT_SIZE__SHIFT)); /* setup context0 */ - 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_START_ADDR, adev->gmc.gart_start >> 12); + WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->gmc.gart_end >> 12); WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12); WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, (u32)(adev->dummy_page.addr >> 12)); @@ -560,9 +575,9 @@ static int gmc_v6_0_gart_enable(struct amdgpu_device *adev) else gmc_v6_0_set_fault_enable_default(adev, true); - gmc_v6_0_gart_flush_gpu_tlb(adev, 0); + gmc_v6_0_flush_gpu_tlb(adev, 0); dev_info(adev->dev, "PCIE GART of %uM enabled (table at 0x%016llX).\n", - (unsigned)(adev->mc.gart_size >> 20), + (unsigned)(adev->gmc.gart_size >> 20), (unsigned long long)adev->gart.table_addr); adev->gart.ready = true; return 0; @@ -794,7 +809,7 @@ static int gmc_v6_0_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - gmc_v6_0_set_gart_funcs(adev); + gmc_v6_0_set_gmc_funcs(adev); gmc_v6_0_set_irq_funcs(adev); return 0; @@ -805,7 +820,7 @@ static int gmc_v6_0_late_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) - return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); + return amdgpu_irq_get(adev, &adev->gmc.vm_fault, 0); else return 0; } @@ -817,26 +832,26 @@ static int gmc_v6_0_sw_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; if (adev->flags & AMD_IS_APU) { - adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; + adev->gmc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; } else { u32 tmp = RREG32(mmMC_SEQ_MISC0); tmp &= MC_SEQ_MISC0__MT__MASK; - adev->mc.vram_type = gmc_v6_0_convert_vram_type(tmp); + adev->gmc.vram_type = gmc_v6_0_convert_vram_type(tmp); } - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 146, &adev->mc.vm_fault); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 146, &adev->gmc.vm_fault); if (r) return r; - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 147, &adev->mc.vm_fault); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 147, &adev->gmc.vm_fault); if (r) return r; amdgpu_vm_adjust_size(adev, 64, 9, 1, 40); - adev->mc.mc_mask = 0xffffffffffULL; + adev->gmc.mc_mask = 0xffffffffffULL; - adev->mc.stolen_size = 256 * 1024; + adev->gmc.stolen_size = 256 * 1024; adev->need_dma32 = false; dma_bits = adev->need_dma32 ? 32 : 40; @@ -851,6 +866,7 @@ static int gmc_v6_0_sw_init(void *handle) pci_set_consistent_dma_mask(adev->pdev, DMA_BIT_MASK(32)); dev_warn(adev->dev, "amdgpu: No coherent DMA available.\n"); } + adev->need_swiotlb = drm_get_max_iomem() > ((u64)1 << dma_bits); r = gmc_v6_0_init_microcode(adev); if (r) { @@ -900,8 +916,8 @@ static int gmc_v6_0_sw_fini(void *handle) amdgpu_vm_manager_fini(adev); gmc_v6_0_gart_fini(adev); amdgpu_bo_fini(adev); - release_firmware(adev->mc.fw); - adev->mc.fw = NULL; + release_firmware(adev->gmc.fw); + adev->gmc.fw = NULL; return 0; } @@ -932,7 +948,7 @@ static int gmc_v6_0_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - amdgpu_irq_put(adev, &adev->mc.vm_fault, 0); + amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); gmc_v6_0_gart_disable(adev); return 0; @@ -1127,9 +1143,10 @@ static const struct amd_ip_funcs gmc_v6_0_ip_funcs = { .set_powergating_state = gmc_v6_0_set_powergating_state, }; -static const struct amdgpu_gart_funcs gmc_v6_0_gart_funcs = { - .flush_gpu_tlb = gmc_v6_0_gart_flush_gpu_tlb, - .set_pte_pde = gmc_v6_0_gart_set_pte_pde, +static const struct amdgpu_gmc_funcs gmc_v6_0_gmc_funcs = { + .flush_gpu_tlb = gmc_v6_0_flush_gpu_tlb, + .emit_flush_gpu_tlb = gmc_v6_0_emit_flush_gpu_tlb, + .set_pte_pde = gmc_v6_0_set_pte_pde, .set_prt = gmc_v6_0_set_prt, .get_vm_pde = gmc_v6_0_get_vm_pde, .get_vm_pte_flags = gmc_v6_0_get_vm_pte_flags @@ -1140,16 +1157,16 @@ static const struct amdgpu_irq_src_funcs gmc_v6_0_irq_funcs = { .process = gmc_v6_0_process_interrupt, }; -static void gmc_v6_0_set_gart_funcs(struct amdgpu_device *adev) +static void gmc_v6_0_set_gmc_funcs(struct amdgpu_device *adev) { - if (adev->gart.gart_funcs == NULL) - adev->gart.gart_funcs = &gmc_v6_0_gart_funcs; + if (adev->gmc.gmc_funcs == NULL) + adev->gmc.gmc_funcs = &gmc_v6_0_gmc_funcs; } static void gmc_v6_0_set_irq_funcs(struct amdgpu_device *adev) { - adev->mc.vm_fault.num_types = 1; - adev->mc.vm_fault.funcs = &gmc_v6_0_irq_funcs; + adev->gmc.vm_fault.num_types = 1; + adev->gmc.vm_fault.funcs = &gmc_v6_0_irq_funcs; } const struct amdgpu_ip_block_version gmc_v6_0_ip_block = |