]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/amdgpu:partially revert 1cfd8e237f0318e330190ac21d63c58ae6a1f66c
authorMonk Liu <Monk.Liu@amd.com>
Tue, 21 Nov 2017 05:29:14 +0000 (13:29 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 6 Dec 2017 17:48:15 +0000 (12:48 -0500)
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>
drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h
drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c

index 707f85825996d522cb54ecfc0073e7dc0eba725b..1f51897acc5b4d7bcf0b86fa7e2c53accff60d49 100644 (file)
  */
 int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
 {
-       return amdgpu_bo_create_kernel(adev, adev->gart.table_size, PAGE_SIZE,
-                                       AMDGPU_GEM_DOMAIN_VRAM, &adev->gart.robj,
-                                       &adev->gart.table_addr, &adev->gart.ptr);
+       int r;
+
+       if (adev->gart.robj == NULL) {
+               r = amdgpu_bo_create(adev, adev->gart.table_size,
+                                    PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
+                                    AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+                                    AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
+                                    NULL, NULL, 0, &adev->gart.robj);
+               if (r) {
+                       return r;
+               }
+       }
+       return 0;
+}
+
+/**
+ * amdgpu_gart_table_vram_pin - pin gart page table in vram
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Pin the GART page table in vram so it will not be moved
+ * by the memory manager (pcie r4xx, r5xx+).  These asics require the
+ * gart table to be in video memory.
+ * Returns 0 for success, error for failure.
+ */
+int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev)
+{
+       uint64_t gpu_addr;
+       int r;
+
+       r = amdgpu_bo_reserve(adev->gart.robj, false);
+       if (unlikely(r != 0))
+               return r;
+       r = amdgpu_bo_pin(adev->gart.robj,
+                               AMDGPU_GEM_DOMAIN_VRAM, &gpu_addr);
+       if (r) {
+               amdgpu_bo_unreserve(adev->gart.robj);
+               return r;
+       }
+       r = amdgpu_bo_kmap(adev->gart.robj, &adev->gart.ptr);
+       if (r)
+               amdgpu_bo_unpin(adev->gart.robj);
+       amdgpu_bo_unreserve(adev->gart.robj);
+       adev->gart.table_addr = gpu_addr;
+       return r;
+}
+
+/**
+ * amdgpu_gart_table_vram_unpin - unpin gart page table in vram
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Unpin the GART page table in vram (pcie r4xx, r5xx+).
+ * These asics require the gart table to be in video memory.
+ */
+void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev)
+{
+       int r;
+
+       if (adev->gart.robj == NULL) {
+               return;
+       }
+       r = amdgpu_bo_reserve(adev->gart.robj, true);
+       if (likely(r == 0)) {
+               amdgpu_bo_kunmap(adev->gart.robj);
+               amdgpu_bo_unpin(adev->gart.robj);
+               amdgpu_bo_unreserve(adev->gart.robj);
+               adev->gart.ptr = NULL;
+       }
 }
 
 /**
@@ -84,9 +150,10 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
  */
 void amdgpu_gart_table_vram_free(struct amdgpu_device *adev)
 {
-       amdgpu_bo_free_kernel(&adev->gart.robj,
-                               &adev->gart.table_addr,
-                               &adev->gart.ptr);
+       if (adev->gart.robj == NULL) {
+               return;
+       }
+       amdgpu_bo_unref(&adev->gart.robj);
 }
 
 /*
index 5eb1a6800f723a13fced94e2bda55a817e3bdb6d..d4a43302c2be56fedab92f155a84482fc3103ade 100644 (file)
@@ -58,6 +58,8 @@ struct amdgpu_gart {
 
 int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev);
 void amdgpu_gart_table_vram_free(struct amdgpu_device *adev);
+int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev);
+void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev);
 int amdgpu_gart_init(struct amdgpu_device *adev);
 void amdgpu_gart_fini(struct amdgpu_device *adev);
 int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
index 1e7f52f109b51e19d763942e1d8d939ca0645309..6098c773711ff248bbbb508c2259906de7d478c4 100644 (file)
@@ -478,14 +478,16 @@ static void gmc_v6_0_set_prt(struct amdgpu_device *adev, bool enable)
 
 static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
 {
-       int i;
+       int r, i;
        u32 field;
 
        if (adev->gart.robj == NULL) {
                dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
                return -EINVAL;
        }
-
+       r = amdgpu_gart_table_vram_pin(adev);
+       if (r)
+               return r;
        /* Setup TLB control */
        WREG32(mmMC_VM_MX_L1_TLB_CNTL,
               (0xA << 7) |
@@ -612,6 +614,7 @@ static void gmc_v6_0_gart_disable(struct amdgpu_device *adev)
        WREG32(mmVM_L2_CNTL3,
               VM_L2_CNTL3__L2_CACHE_BIGK_ASSOCIATIVITY_MASK |
               (0UL << VM_L2_CNTL3__L2_CACHE_BIGK_FRAGMENT_SIZE__SHIFT));
+       amdgpu_gart_table_vram_unpin(adev);
 }
 
 static void gmc_v6_0_gart_fini(struct amdgpu_device *adev)
index d521862804ea4c91c154d59fbf3af975c242200d..8b460e9d44314822a6b9b4fd302351c847c64eed 100644 (file)
@@ -582,14 +582,16 @@ static void gmc_v7_0_set_prt(struct amdgpu_device *adev, bool enable)
  */
 static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
 {
-       int i;
+       int r, i;
        u32 tmp, field;
 
        if (adev->gart.robj == NULL) {
                dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
                return -EINVAL;
        }
-
+       r = amdgpu_gart_table_vram_pin(adev);
+       if (r)
+               return r;
        /* Setup TLB control */
        tmp = RREG32(mmMC_VM_MX_L1_TLB_CNTL);
        tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1);
@@ -722,6 +724,7 @@ static void gmc_v7_0_gart_disable(struct amdgpu_device *adev)
        tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0);
        WREG32(mmVM_L2_CNTL, tmp);
        WREG32(mmVM_L2_CNTL2, 0);
+       amdgpu_gart_table_vram_unpin(adev);
 }
 
 /**
index bd3f842cca00fb059d24762abf55f470142ee104..1fd7f9daab0a0fd7d4b5db7d87883d84dbd28635 100644 (file)
@@ -781,14 +781,16 @@ static void gmc_v8_0_set_prt(struct amdgpu_device *adev, bool enable)
  */
 static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
 {
-       int i;
+       int r, i;
        u32 tmp, field;
 
        if (adev->gart.robj == NULL) {
                dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
                return -EINVAL;
        }
-
+       r = amdgpu_gart_table_vram_pin(adev);
+       if (r)
+               return r;
        /* Setup TLB control */
        tmp = RREG32(mmMC_VM_MX_L1_TLB_CNTL);
        tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1);
@@ -938,6 +940,7 @@ static void gmc_v8_0_gart_disable(struct amdgpu_device *adev)
        tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0);
        WREG32(mmVM_L2_CNTL, tmp);
        WREG32(mmVM_L2_CNTL2, 0);
+       amdgpu_gart_table_vram_unpin(adev);
 }
 
 /**
index 8529005a50225e0b679854d4b4467b03317db00b..c30e08d9f30bda3c97f846aaeeabb2ac7608ee6e 100644 (file)
@@ -933,6 +933,9 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
                dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
                return -EINVAL;
        }
+       r = amdgpu_gart_table_vram_pin(adev);
+       if (r)
+               return r;
 
        switch (adev->asic_type) {
        case CHIP_RAVEN:
@@ -1010,6 +1013,7 @@ static void gmc_v9_0_gart_disable(struct amdgpu_device *adev)
 {
        gfxhub_v1_0_gart_disable(adev);
        mmhub_v1_0_gart_disable(adev);
+       amdgpu_gart_table_vram_unpin(adev);
 }
 
 static int gmc_v9_0_hw_fini(void *handle)