Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu:partially revert 1cfd8e237f0318e330190ac21d63c58ae6a1f66c

found RING0 test fail after S3 resume regression, which is
introduced by 1cfd8e237f0318e330190ac21d63c58ae6a1f66c

Because after suspend VRAM will be cleared, so driver must
unpin the GART table(resident in VRAM) during suspend so it
can be evicted to system ram and must correspondingly pin it
during resume so the GART table could be restored to VRAM.

Signed-off-by: Monk Liu <Monk.Liu@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Monk Liu and committed by
Alex Deucher
ce1b1b66 1bfcbad1

+94 -12
+73 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
··· 68 68 */ 69 69 int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) 70 70 { 71 - return amdgpu_bo_create_kernel(adev, adev->gart.table_size, PAGE_SIZE, 72 - AMDGPU_GEM_DOMAIN_VRAM, &adev->gart.robj, 73 - &adev->gart.table_addr, &adev->gart.ptr); 71 + int r; 72 + 73 + if (adev->gart.robj == NULL) { 74 + r = amdgpu_bo_create(adev, adev->gart.table_size, 75 + PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, 76 + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | 77 + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, 78 + NULL, NULL, 0, &adev->gart.robj); 79 + if (r) { 80 + return r; 81 + } 82 + } 83 + return 0; 84 + } 85 + 86 + /** 87 + * amdgpu_gart_table_vram_pin - pin gart page table in vram 88 + * 89 + * @adev: amdgpu_device pointer 90 + * 91 + * Pin the GART page table in vram so it will not be moved 92 + * by the memory manager (pcie r4xx, r5xx+). These asics require the 93 + * gart table to be in video memory. 94 + * Returns 0 for success, error for failure. 95 + */ 96 + int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev) 97 + { 98 + uint64_t gpu_addr; 99 + int r; 100 + 101 + r = amdgpu_bo_reserve(adev->gart.robj, false); 102 + if (unlikely(r != 0)) 103 + return r; 104 + r = amdgpu_bo_pin(adev->gart.robj, 105 + AMDGPU_GEM_DOMAIN_VRAM, &gpu_addr); 106 + if (r) { 107 + amdgpu_bo_unreserve(adev->gart.robj); 108 + return r; 109 + } 110 + r = amdgpu_bo_kmap(adev->gart.robj, &adev->gart.ptr); 111 + if (r) 112 + amdgpu_bo_unpin(adev->gart.robj); 113 + amdgpu_bo_unreserve(adev->gart.robj); 114 + adev->gart.table_addr = gpu_addr; 115 + return r; 116 + } 117 + 118 + /** 119 + * amdgpu_gart_table_vram_unpin - unpin gart page table in vram 120 + * 121 + * @adev: amdgpu_device pointer 122 + * 123 + * Unpin the GART page table in vram (pcie r4xx, r5xx+). 124 + * These asics require the gart table to be in video memory. 125 + */ 126 + void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev) 127 + { 128 + int r; 129 + 130 + if (adev->gart.robj == NULL) { 131 + return; 132 + } 133 + r = amdgpu_bo_reserve(adev->gart.robj, true); 134 + if (likely(r == 0)) { 135 + amdgpu_bo_kunmap(adev->gart.robj); 136 + amdgpu_bo_unpin(adev->gart.robj); 137 + amdgpu_bo_unreserve(adev->gart.robj); 138 + adev->gart.ptr = NULL; 139 + } 74 140 } 75 141 76 142 /** ··· 150 84 */ 151 85 void amdgpu_gart_table_vram_free(struct amdgpu_device *adev) 152 86 { 153 - amdgpu_bo_free_kernel(&adev->gart.robj, 154 - &adev->gart.table_addr, 155 - &adev->gart.ptr); 87 + if (adev->gart.robj == NULL) { 88 + return; 89 + } 90 + amdgpu_bo_unref(&adev->gart.robj); 156 91 } 157 92 158 93 /*
+2
drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h
··· 58 58 59 59 int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev); 60 60 void amdgpu_gart_table_vram_free(struct amdgpu_device *adev); 61 + int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev); 62 + void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev); 61 63 int amdgpu_gart_init(struct amdgpu_device *adev); 62 64 void amdgpu_gart_fini(struct amdgpu_device *adev); 63 65 int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
+5 -2
drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
··· 478 478 479 479 static int gmc_v6_0_gart_enable(struct amdgpu_device *adev) 480 480 { 481 - int i; 481 + int r, i; 482 482 u32 field; 483 483 484 484 if (adev->gart.robj == NULL) { 485 485 dev_err(adev->dev, "No VRAM object for PCIE GART.\n"); 486 486 return -EINVAL; 487 487 } 488 - 488 + r = amdgpu_gart_table_vram_pin(adev); 489 + if (r) 490 + return r; 489 491 /* Setup TLB control */ 490 492 WREG32(mmMC_VM_MX_L1_TLB_CNTL, 491 493 (0xA << 7) | ··· 614 612 WREG32(mmVM_L2_CNTL3, 615 613 VM_L2_CNTL3__L2_CACHE_BIGK_ASSOCIATIVITY_MASK | 616 614 (0UL << VM_L2_CNTL3__L2_CACHE_BIGK_FRAGMENT_SIZE__SHIFT)); 615 + amdgpu_gart_table_vram_unpin(adev); 617 616 } 618 617 619 618 static void gmc_v6_0_gart_fini(struct amdgpu_device *adev)
+5 -2
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
··· 582 582 */ 583 583 static int gmc_v7_0_gart_enable(struct amdgpu_device *adev) 584 584 { 585 - int i; 585 + int r, i; 586 586 u32 tmp, field; 587 587 588 588 if (adev->gart.robj == NULL) { 589 589 dev_err(adev->dev, "No VRAM object for PCIE GART.\n"); 590 590 return -EINVAL; 591 591 } 592 - 592 + r = amdgpu_gart_table_vram_pin(adev); 593 + if (r) 594 + return r; 593 595 /* Setup TLB control */ 594 596 tmp = RREG32(mmMC_VM_MX_L1_TLB_CNTL); 595 597 tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1); ··· 724 722 tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0); 725 723 WREG32(mmVM_L2_CNTL, tmp); 726 724 WREG32(mmVM_L2_CNTL2, 0); 725 + amdgpu_gart_table_vram_unpin(adev); 727 726 } 728 727 729 728 /**
+5 -2
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
··· 781 781 */ 782 782 static int gmc_v8_0_gart_enable(struct amdgpu_device *adev) 783 783 { 784 - int i; 784 + int r, i; 785 785 u32 tmp, field; 786 786 787 787 if (adev->gart.robj == NULL) { 788 788 dev_err(adev->dev, "No VRAM object for PCIE GART.\n"); 789 789 return -EINVAL; 790 790 } 791 - 791 + r = amdgpu_gart_table_vram_pin(adev); 792 + if (r) 793 + return r; 792 794 /* Setup TLB control */ 793 795 tmp = RREG32(mmMC_VM_MX_L1_TLB_CNTL); 794 796 tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1); ··· 940 938 tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0); 941 939 WREG32(mmVM_L2_CNTL, tmp); 942 940 WREG32(mmVM_L2_CNTL2, 0); 941 + amdgpu_gart_table_vram_unpin(adev); 943 942 } 944 943 945 944 /**
+4
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
··· 933 933 dev_err(adev->dev, "No VRAM object for PCIE GART.\n"); 934 934 return -EINVAL; 935 935 } 936 + r = amdgpu_gart_table_vram_pin(adev); 937 + if (r) 938 + return r; 936 939 937 940 switch (adev->asic_type) { 938 941 case CHIP_RAVEN: ··· 1013 1010 { 1014 1011 gfxhub_v1_0_gart_disable(adev); 1015 1012 mmhub_v1_0_gart_disable(adev); 1013 + amdgpu_gart_table_vram_unpin(adev); 1016 1014 } 1017 1015 1018 1016 static int gmc_v9_0_hw_fini(void *handle)