| .. | .. |
|---|
| 20 | 20 | * OTHER DEALINGS IN THE SOFTWARE. |
|---|
| 21 | 21 | * |
|---|
| 22 | 22 | */ |
|---|
| 23 | + |
|---|
| 23 | 24 | #include <linux/firmware.h> |
|---|
| 24 | | -#include <drm/drmP.h> |
|---|
| 25 | +#include <linux/module.h> |
|---|
| 26 | +#include <linux/pci.h> |
|---|
| 27 | + |
|---|
| 25 | 28 | #include <drm/drm_cache.h> |
|---|
| 26 | 29 | #include "amdgpu.h" |
|---|
| 27 | 30 | #include "cikd.h" |
|---|
| .. | .. |
|---|
| 29 | 32 | #include "gmc_v7_0.h" |
|---|
| 30 | 33 | #include "amdgpu_ucode.h" |
|---|
| 31 | 34 | #include "amdgpu_amdkfd.h" |
|---|
| 35 | +#include "amdgpu_gem.h" |
|---|
| 32 | 36 | |
|---|
| 33 | 37 | #include "bif/bif_4_1_d.h" |
|---|
| 34 | 38 | #include "bif/bif_4_1_sh_mask.h" |
|---|
| .. | .. |
|---|
| 241 | 245 | u64 base = RREG32(mmMC_VM_FB_LOCATION) & 0xFFFF; |
|---|
| 242 | 246 | base <<= 24; |
|---|
| 243 | 247 | |
|---|
| 244 | | - amdgpu_device_vram_location(adev, &adev->gmc, base); |
|---|
| 245 | | - amdgpu_device_gart_location(adev, mc); |
|---|
| 248 | + amdgpu_gmc_vram_location(adev, mc, base); |
|---|
| 249 | + amdgpu_gmc_gart_location(adev, mc); |
|---|
| 246 | 250 | } |
|---|
| 247 | 251 | |
|---|
| 248 | 252 | /** |
|---|
| .. | .. |
|---|
| 377 | 381 | adev->gmc.aper_size = pci_resource_len(adev->pdev, 0); |
|---|
| 378 | 382 | |
|---|
| 379 | 383 | #ifdef CONFIG_X86_64 |
|---|
| 380 | | - if (adev->flags & AMD_IS_APU) { |
|---|
| 384 | + if (adev->flags & AMD_IS_APU && |
|---|
| 385 | + adev->gmc.real_vram_size > adev->gmc.aper_size) { |
|---|
| 381 | 386 | adev->gmc.aper_base = ((u64)RREG32(mmMC_VM_FB_OFFSET)) << 22; |
|---|
| 382 | 387 | adev->gmc.aper_size = adev->gmc.real_vram_size; |
|---|
| 383 | 388 | } |
|---|
| .. | .. |
|---|
| 414 | 419 | return 0; |
|---|
| 415 | 420 | } |
|---|
| 416 | 421 | |
|---|
| 422 | +/** |
|---|
| 423 | + * gmc_v7_0_flush_gpu_tlb_pasid - tlb flush via pasid |
|---|
| 424 | + * |
|---|
| 425 | + * @adev: amdgpu_device pointer |
|---|
| 426 | + * @pasid: pasid to be flush |
|---|
| 427 | + * |
|---|
| 428 | + * Flush the TLB for the requested pasid. |
|---|
| 429 | + */ |
|---|
| 430 | +static int gmc_v7_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev, |
|---|
| 431 | + uint16_t pasid, uint32_t flush_type, |
|---|
| 432 | + bool all_hub) |
|---|
| 433 | +{ |
|---|
| 434 | + int vmid; |
|---|
| 435 | + unsigned int tmp; |
|---|
| 436 | + |
|---|
| 437 | + if (amdgpu_in_reset(adev)) |
|---|
| 438 | + return -EIO; |
|---|
| 439 | + |
|---|
| 440 | + for (vmid = 1; vmid < 16; vmid++) { |
|---|
| 441 | + |
|---|
| 442 | + tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid); |
|---|
| 443 | + if ((tmp & ATC_VMID0_PASID_MAPPING__VALID_MASK) && |
|---|
| 444 | + (tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid) { |
|---|
| 445 | + WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid); |
|---|
| 446 | + RREG32(mmVM_INVALIDATE_RESPONSE); |
|---|
| 447 | + break; |
|---|
| 448 | + } |
|---|
| 449 | + } |
|---|
| 450 | + |
|---|
| 451 | + return 0; |
|---|
| 452 | +} |
|---|
| 453 | + |
|---|
| 417 | 454 | /* |
|---|
| 418 | 455 | * GART |
|---|
| 419 | 456 | * VMID 0 is the physical GPU addresses as used by the kernel. |
|---|
| .. | .. |
|---|
| 429 | 466 | * |
|---|
| 430 | 467 | * Flush the TLB for the requested page table (CIK). |
|---|
| 431 | 468 | */ |
|---|
| 432 | | -static void gmc_v7_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid) |
|---|
| 469 | +static void gmc_v7_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, |
|---|
| 470 | + uint32_t vmhub, uint32_t flush_type) |
|---|
| 433 | 471 | { |
|---|
| 434 | 472 | /* bits 0-15 are the VM contexts0-15 */ |
|---|
| 435 | 473 | WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid); |
|---|
| .. | .. |
|---|
| 458 | 496 | amdgpu_ring_emit_wreg(ring, mmIH_VMID_0_LUT + vmid, pasid); |
|---|
| 459 | 497 | } |
|---|
| 460 | 498 | |
|---|
| 461 | | -/** |
|---|
| 462 | | - * gmc_v7_0_set_pte_pde - update the page tables using MMIO |
|---|
| 463 | | - * |
|---|
| 464 | | - * @adev: amdgpu_device pointer |
|---|
| 465 | | - * @cpu_pt_addr: cpu address of the page table |
|---|
| 466 | | - * @gpu_page_idx: entry in the page table to update |
|---|
| 467 | | - * @addr: dst addr to write into pte/pde |
|---|
| 468 | | - * @flags: access flags |
|---|
| 469 | | - * |
|---|
| 470 | | - * Update the page tables using the CPU. |
|---|
| 471 | | - */ |
|---|
| 472 | | -static int gmc_v7_0_set_pte_pde(struct amdgpu_device *adev, void *cpu_pt_addr, |
|---|
| 473 | | - uint32_t gpu_page_idx, uint64_t addr, |
|---|
| 474 | | - uint64_t flags) |
|---|
| 475 | | -{ |
|---|
| 476 | | - void __iomem *ptr = (void *)cpu_pt_addr; |
|---|
| 477 | | - uint64_t value; |
|---|
| 478 | | - |
|---|
| 479 | | - value = addr & 0xFFFFFFFFFFFFF000ULL; |
|---|
| 480 | | - value |= flags; |
|---|
| 481 | | - writeq(value, ptr + (gpu_page_idx * 8)); |
|---|
| 482 | | - |
|---|
| 483 | | - return 0; |
|---|
| 484 | | -} |
|---|
| 485 | | - |
|---|
| 486 | | -static uint64_t gmc_v7_0_get_vm_pte_flags(struct amdgpu_device *adev, |
|---|
| 487 | | - uint32_t flags) |
|---|
| 488 | | -{ |
|---|
| 489 | | - uint64_t pte_flag = 0; |
|---|
| 490 | | - |
|---|
| 491 | | - if (flags & AMDGPU_VM_PAGE_READABLE) |
|---|
| 492 | | - pte_flag |= AMDGPU_PTE_READABLE; |
|---|
| 493 | | - if (flags & AMDGPU_VM_PAGE_WRITEABLE) |
|---|
| 494 | | - pte_flag |= AMDGPU_PTE_WRITEABLE; |
|---|
| 495 | | - if (flags & AMDGPU_VM_PAGE_PRT) |
|---|
| 496 | | - pte_flag |= AMDGPU_PTE_PRT; |
|---|
| 497 | | - |
|---|
| 498 | | - return pte_flag; |
|---|
| 499 | | -} |
|---|
| 500 | | - |
|---|
| 501 | 499 | static void gmc_v7_0_get_vm_pde(struct amdgpu_device *adev, int level, |
|---|
| 502 | 500 | uint64_t *addr, uint64_t *flags) |
|---|
| 503 | 501 | { |
|---|
| 504 | 502 | BUG_ON(*addr & 0xFFFFFF0000000FFFULL); |
|---|
| 503 | +} |
|---|
| 504 | + |
|---|
| 505 | +static void gmc_v7_0_get_vm_pte(struct amdgpu_device *adev, |
|---|
| 506 | + struct amdgpu_bo_va_mapping *mapping, |
|---|
| 507 | + uint64_t *flags) |
|---|
| 508 | +{ |
|---|
| 509 | + *flags &= ~AMDGPU_PTE_EXECUTABLE; |
|---|
| 510 | + *flags &= ~AMDGPU_PTE_PRT; |
|---|
| 505 | 511 | } |
|---|
| 506 | 512 | |
|---|
| 507 | 513 | /** |
|---|
| .. | .. |
|---|
| 601 | 607 | */ |
|---|
| 602 | 608 | static int gmc_v7_0_gart_enable(struct amdgpu_device *adev) |
|---|
| 603 | 609 | { |
|---|
| 610 | + uint64_t table_addr; |
|---|
| 604 | 611 | int r, i; |
|---|
| 605 | 612 | u32 tmp, field; |
|---|
| 606 | 613 | |
|---|
| 607 | | - if (adev->gart.robj == NULL) { |
|---|
| 614 | + if (adev->gart.bo == NULL) { |
|---|
| 608 | 615 | dev_err(adev->dev, "No VRAM object for PCIE GART.\n"); |
|---|
| 609 | 616 | return -EINVAL; |
|---|
| 610 | 617 | } |
|---|
| 611 | 618 | r = amdgpu_gart_table_vram_pin(adev); |
|---|
| 612 | 619 | if (r) |
|---|
| 613 | 620 | return r; |
|---|
| 621 | + |
|---|
| 622 | + table_addr = amdgpu_bo_gpu_offset(adev->gart.bo); |
|---|
| 623 | + |
|---|
| 614 | 624 | /* Setup TLB control */ |
|---|
| 615 | 625 | tmp = RREG32(mmMC_VM_MX_L1_TLB_CNTL); |
|---|
| 616 | 626 | tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1); |
|---|
| .. | .. |
|---|
| 642 | 652 | /* setup context0 */ |
|---|
| 643 | 653 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->gmc.gart_start >> 12); |
|---|
| 644 | 654 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->gmc.gart_end >> 12); |
|---|
| 645 | | - WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12); |
|---|
| 655 | + WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, table_addr >> 12); |
|---|
| 646 | 656 | WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, |
|---|
| 647 | 657 | (u32)(adev->dummy_page_addr >> 12)); |
|---|
| 648 | 658 | WREG32(mmVM_CONTEXT0_CNTL2, 0); |
|---|
| .. | .. |
|---|
| 666 | 676 | for (i = 1; i < 16; i++) { |
|---|
| 667 | 677 | if (i < 8) |
|---|
| 668 | 678 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + i, |
|---|
| 669 | | - adev->gart.table_addr >> 12); |
|---|
| 679 | + table_addr >> 12); |
|---|
| 670 | 680 | else |
|---|
| 671 | 681 | WREG32(mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + i - 8, |
|---|
| 672 | | - adev->gart.table_addr >> 12); |
|---|
| 682 | + table_addr >> 12); |
|---|
| 673 | 683 | } |
|---|
| 674 | 684 | |
|---|
| 675 | 685 | /* enable context1-15 */ |
|---|
| .. | .. |
|---|
| 693 | 703 | WREG32(mmCHUB_CONTROL, tmp); |
|---|
| 694 | 704 | } |
|---|
| 695 | 705 | |
|---|
| 696 | | - gmc_v7_0_flush_gpu_tlb(adev, 0); |
|---|
| 706 | + gmc_v7_0_flush_gpu_tlb(adev, 0, 0, 0); |
|---|
| 697 | 707 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", |
|---|
| 698 | 708 | (unsigned)(adev->gmc.gart_size >> 20), |
|---|
| 699 | | - (unsigned long long)adev->gart.table_addr); |
|---|
| 709 | + (unsigned long long)table_addr); |
|---|
| 700 | 710 | adev->gart.ready = true; |
|---|
| 701 | 711 | return 0; |
|---|
| 702 | 712 | } |
|---|
| .. | .. |
|---|
| 705 | 715 | { |
|---|
| 706 | 716 | int r; |
|---|
| 707 | 717 | |
|---|
| 708 | | - if (adev->gart.robj) { |
|---|
| 718 | + if (adev->gart.bo) { |
|---|
| 709 | 719 | WARN(1, "R600 PCIE GART already initialized\n"); |
|---|
| 710 | 720 | return 0; |
|---|
| 711 | 721 | } |
|---|
| .. | .. |
|---|
| 752 | 762 | * @adev: amdgpu_device pointer |
|---|
| 753 | 763 | * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value |
|---|
| 754 | 764 | * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value |
|---|
| 765 | + * @mc_client: VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT register value |
|---|
| 755 | 766 | * |
|---|
| 756 | 767 | * Print human readable fault information (CIK). |
|---|
| 757 | 768 | */ |
|---|
| .. | .. |
|---|
| 959 | 970 | unsigned size; |
|---|
| 960 | 971 | |
|---|
| 961 | 972 | if (REG_GET_FIELD(d1vga_control, D1VGA_CONTROL, D1VGA_MODE_ENABLE)) { |
|---|
| 962 | | - size = 9 * 1024 * 1024; /* reserve 8MB for vga emulator and 1 MB for FB */ |
|---|
| 973 | + size = AMDGPU_VBIOS_VGA_ALLOCATION; |
|---|
| 963 | 974 | } else { |
|---|
| 964 | 975 | u32 viewport = RREG32(mmVIEWPORT_SIZE); |
|---|
| 965 | 976 | size = (REG_GET_FIELD(viewport, VIEWPORT_SIZE, VIEWPORT_HEIGHT) * |
|---|
| 966 | 977 | REG_GET_FIELD(viewport, VIEWPORT_SIZE, VIEWPORT_WIDTH) * |
|---|
| 967 | 978 | 4); |
|---|
| 968 | 979 | } |
|---|
| 969 | | - /* return 0 if the pre-OS buffer uses up most of vram */ |
|---|
| 970 | | - if ((adev->gmc.real_vram_size - size) < (8 * 1024 * 1024)) |
|---|
| 971 | | - return 0; |
|---|
| 980 | + |
|---|
| 972 | 981 | return size; |
|---|
| 973 | 982 | } |
|---|
| 974 | 983 | |
|---|
| 975 | 984 | static int gmc_v7_0_sw_init(void *handle) |
|---|
| 976 | 985 | { |
|---|
| 977 | 986 | int r; |
|---|
| 978 | | - int dma_bits; |
|---|
| 979 | 987 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
|---|
| 988 | + |
|---|
| 989 | + adev->num_vmhubs = 1; |
|---|
| 980 | 990 | |
|---|
| 981 | 991 | if (adev->flags & AMD_IS_APU) { |
|---|
| 982 | 992 | adev->gmc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; |
|---|
| .. | .. |
|---|
| 986 | 996 | adev->gmc.vram_type = gmc_v7_0_convert_vram_type(tmp); |
|---|
| 987 | 997 | } |
|---|
| 988 | 998 | |
|---|
| 989 | | - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_PAGE_INV_FAULT, &adev->gmc.vm_fault); |
|---|
| 999 | + r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_PAGE_INV_FAULT, &adev->gmc.vm_fault); |
|---|
| 990 | 1000 | if (r) |
|---|
| 991 | 1001 | return r; |
|---|
| 992 | 1002 | |
|---|
| 993 | | - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_MEM_PROT_FAULT, &adev->gmc.vm_fault); |
|---|
| 1003 | + r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_MEM_PROT_FAULT, &adev->gmc.vm_fault); |
|---|
| 994 | 1004 | if (r) |
|---|
| 995 | 1005 | return r; |
|---|
| 996 | 1006 | |
|---|
| .. | .. |
|---|
| 1006 | 1016 | */ |
|---|
| 1007 | 1017 | adev->gmc.mc_mask = 0xffffffffffULL; /* 40 bit MC */ |
|---|
| 1008 | 1018 | |
|---|
| 1009 | | - /* set DMA mask + need_dma32 flags. |
|---|
| 1010 | | - * PCIE - can handle 40-bits. |
|---|
| 1011 | | - * IGP - can handle 40-bits |
|---|
| 1012 | | - * PCI - dma32 for legacy pci gart, 40 bits on newer asics |
|---|
| 1013 | | - */ |
|---|
| 1014 | | - adev->need_dma32 = false; |
|---|
| 1015 | | - dma_bits = adev->need_dma32 ? 32 : 40; |
|---|
| 1016 | | - r = pci_set_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits)); |
|---|
| 1019 | + r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40)); |
|---|
| 1017 | 1020 | if (r) { |
|---|
| 1018 | | - adev->need_dma32 = true; |
|---|
| 1019 | | - dma_bits = 32; |
|---|
| 1020 | | - pr_warn("amdgpu: No suitable DMA available\n"); |
|---|
| 1021 | + pr_warn("No suitable DMA available\n"); |
|---|
| 1022 | + return r; |
|---|
| 1021 | 1023 | } |
|---|
| 1022 | | - r = pci_set_consistent_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits)); |
|---|
| 1023 | | - if (r) { |
|---|
| 1024 | | - pci_set_consistent_dma_mask(adev->pdev, DMA_BIT_MASK(32)); |
|---|
| 1025 | | - pr_warn("amdgpu: No coherent DMA available\n"); |
|---|
| 1026 | | - } |
|---|
| 1027 | | - adev->need_swiotlb = drm_get_max_iomem() > ((u64)1 << dma_bits); |
|---|
| 1024 | + adev->need_swiotlb = drm_need_swiotlb(40); |
|---|
| 1028 | 1025 | |
|---|
| 1029 | 1026 | r = gmc_v7_0_init_microcode(adev); |
|---|
| 1030 | 1027 | if (r) { |
|---|
| .. | .. |
|---|
| 1036 | 1033 | if (r) |
|---|
| 1037 | 1034 | return r; |
|---|
| 1038 | 1035 | |
|---|
| 1039 | | - adev->gmc.stolen_size = gmc_v7_0_get_vbios_fb_size(adev); |
|---|
| 1036 | + amdgpu_gmc_get_vbios_allocations(adev); |
|---|
| 1040 | 1037 | |
|---|
| 1041 | 1038 | /* Memory manager */ |
|---|
| 1042 | 1039 | r = amdgpu_bo_init(adev); |
|---|
| .. | .. |
|---|
| 1053 | 1050 | * amdgpu graphics/compute will use VMIDs 1-7 |
|---|
| 1054 | 1051 | * amdkfd will use VMIDs 8-15 |
|---|
| 1055 | 1052 | */ |
|---|
| 1056 | | - adev->vm_manager.id_mgr[0].num_ids = AMDGPU_NUM_OF_VMIDS; |
|---|
| 1053 | + adev->vm_manager.first_kfd_vmid = 8; |
|---|
| 1057 | 1054 | amdgpu_vm_manager_init(adev); |
|---|
| 1058 | 1055 | |
|---|
| 1059 | 1056 | /* base offset of vram pages */ |
|---|
| .. | .. |
|---|
| 1368 | 1365 | |
|---|
| 1369 | 1366 | static const struct amdgpu_gmc_funcs gmc_v7_0_gmc_funcs = { |
|---|
| 1370 | 1367 | .flush_gpu_tlb = gmc_v7_0_flush_gpu_tlb, |
|---|
| 1368 | + .flush_gpu_tlb_pasid = gmc_v7_0_flush_gpu_tlb_pasid, |
|---|
| 1371 | 1369 | .emit_flush_gpu_tlb = gmc_v7_0_emit_flush_gpu_tlb, |
|---|
| 1372 | 1370 | .emit_pasid_mapping = gmc_v7_0_emit_pasid_mapping, |
|---|
| 1373 | | - .set_pte_pde = gmc_v7_0_set_pte_pde, |
|---|
| 1374 | 1371 | .set_prt = gmc_v7_0_set_prt, |
|---|
| 1375 | | - .get_vm_pte_flags = gmc_v7_0_get_vm_pte_flags, |
|---|
| 1376 | | - .get_vm_pde = gmc_v7_0_get_vm_pde |
|---|
| 1372 | + .get_vm_pde = gmc_v7_0_get_vm_pde, |
|---|
| 1373 | + .get_vm_pte = gmc_v7_0_get_vm_pte, |
|---|
| 1374 | + .get_vbios_fb_size = gmc_v7_0_get_vbios_fb_size, |
|---|
| 1377 | 1375 | }; |
|---|
| 1378 | 1376 | |
|---|
| 1379 | 1377 | static const struct amdgpu_irq_src_funcs gmc_v7_0_irq_funcs = { |
|---|
| .. | .. |
|---|
| 1383 | 1381 | |
|---|
| 1384 | 1382 | static void gmc_v7_0_set_gmc_funcs(struct amdgpu_device *adev) |
|---|
| 1385 | 1383 | { |
|---|
| 1386 | | - if (adev->gmc.gmc_funcs == NULL) |
|---|
| 1387 | | - adev->gmc.gmc_funcs = &gmc_v7_0_gmc_funcs; |
|---|
| 1384 | + adev->gmc.gmc_funcs = &gmc_v7_0_gmc_funcs; |
|---|
| 1388 | 1385 | } |
|---|
| 1389 | 1386 | |
|---|
| 1390 | 1387 | static void gmc_v7_0_set_irq_funcs(struct amdgpu_device *adev) |
|---|