drm/amdgpu: add vram check function for GMC
authorXiaojian Du <Xiaojian.Du@amd.com>
Mon, 17 Jan 2022 04:44:51 +0000 (12:44 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 20 Jan 2022 03:31:51 +0000 (22:31 -0500)
This patch will add vram check function for GMC block.
It will write pattern data to the vram and then read back from the vram,
so that to verify the work status of vram.
This patch  will cover gmc v6/7/8/9/10.

Signed-off-by: Xiaojian Du <Xiaojian.Du@amd.com>
Reviewed-by: Huang Rui <ray.huang@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
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 a0a9abd23a7b1854b98a7bf5a74478f87c8d4ee9..cbe30ccf6162c4f4fbc2b9f5966dda787e73d373 100644 (file)
@@ -822,3 +822,49 @@ void amdgpu_gmc_get_reserved_allocation(struct amdgpu_device *adev)
                break;
        }
 }
+
+int amdgpu_gmc_vram_checking(struct amdgpu_device *adev)
+{
+       struct amdgpu_bo *vram_bo;
+       uint64_t vram_gpu;
+       void *vram_ptr;
+
+       int ret, size = 0x100000;
+       uint8_t cptr[10];
+
+       ret = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
+                               AMDGPU_GEM_DOMAIN_VRAM,
+                               &vram_bo,
+                               &vram_gpu,
+                               &vram_ptr);
+       if (ret)
+               return ret;
+
+       memset(vram_ptr, 0x86, size);
+       memset(cptr, 0x86, 10);
+
+       /**
+        * Check the start, the mid, and the end of the memory if the content of
+        * each byte is the pattern "0x86". If yes, we suppose the vram bo is
+        * workable.
+        *
+        * Note: If check the each byte of whole 1M bo, it will cost too many
+        * seconds, so here, we just pick up three parts for emulation.
+        */
+       ret = memcmp(vram_ptr, cptr, 10);
+       if (ret)
+               return ret;
+
+       ret = memcmp(vram_ptr + (size / 2), cptr, 10);
+       if (ret)
+               return ret;
+
+       ret = memcmp(vram_ptr + size - 10, cptr, 10);
+       if (ret)
+               return ret;
+
+       amdgpu_bo_free_kernel(&vram_bo, &vram_gpu,
+                       &vram_ptr);
+
+       return 0;
+}
index 0001631cfedb770a12ebfa6a48a7eb7973caff86..a5e8e0e089707a83430831dd9a491556bc3af3f2 100644 (file)
@@ -336,4 +336,5 @@ void amdgpu_gmc_init_pdb0(struct amdgpu_device *adev);
 uint64_t amdgpu_gmc_vram_mc2pa(struct amdgpu_device *adev, uint64_t mc_addr);
 uint64_t amdgpu_gmc_vram_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo);
 uint64_t amdgpu_gmc_vram_cpu_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo);
+int amdgpu_gmc_vram_checking(struct amdgpu_device *adev);
 #endif
index 4f8d356f8432843af0e32963ef7cdc716a975518..bb9a11bc644b93bc22036ce57a312bbde23f677f 100644 (file)
@@ -1057,6 +1057,12 @@ static int gmc_v10_0_hw_init(void *handle)
        if (r)
                return r;
 
+       if (amdgpu_emu_mode == 1) {
+               r = amdgpu_gmc_vram_checking(adev);
+               if (r)
+                       return r;
+       }
+
        if (adev->umc.funcs && adev->umc.funcs->init_registers)
                adev->umc.funcs->init_registers(adev);
 
index cd6c38e083d0d28d2f1e408337dac0a58e24e6e9..84f0debe8264d54b053a5661915f55c1fa924e4b 100644 (file)
@@ -922,7 +922,10 @@ static int gmc_v6_0_hw_init(void *handle)
        if (r)
                return r;
 
-       return r;
+       if (amdgpu_emu_mode == 1)
+               return amdgpu_gmc_vram_checking(adev);
+       else
+               return r;
 }
 
 static int gmc_v6_0_hw_fini(void *handle)
index ab8adbff9e2d0e4c5fed21465c506e646686f66b..8800a18b0cf69025fc7395717a5bff2025e6d1bb 100644 (file)
@@ -1111,7 +1111,10 @@ static int gmc_v7_0_hw_init(void *handle)
        if (r)
                return r;
 
-       return r;
+       if (amdgpu_emu_mode == 1)
+               return amdgpu_gmc_vram_checking(adev);
+       else
+               return r;
 }
 
 static int gmc_v7_0_hw_fini(void *handle)
index 054733838292c319e602e01ad31066105c6adf57..1c10fa5d0db7bd77c4719bd8ea4923173a86562b 100644 (file)
@@ -1242,7 +1242,10 @@ static int gmc_v8_0_hw_init(void *handle)
        if (r)
                return r;
 
-       return r;
+       if (amdgpu_emu_mode == 1)
+               return amdgpu_gmc_vram_checking(adev);
+       else
+               return r;
 }
 
 static int gmc_v8_0_hw_fini(void *handle)
index c76ffd1a70cde48e62916ffaaa4b0a9689aff9c4..6866e0311b4987f4560be59bd98875a041d031d6 100644 (file)
@@ -1815,7 +1815,7 @@ static int gmc_v9_0_hw_init(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        bool value;
-       int i;
+       int i, r;
 
        /* The sequence of these two function calls matters.*/
        gmc_v9_0_init_golden_registers(adev);
@@ -1850,7 +1850,14 @@ static int gmc_v9_0_hw_init(void *handle)
        if (adev->umc.funcs && adev->umc.funcs->init_registers)
                adev->umc.funcs->init_registers(adev);
 
-       return gmc_v9_0_gart_enable(adev);
+       r = gmc_v9_0_gart_enable(adev);
+       if (r)
+               return r;
+
+       if (amdgpu_emu_mode == 1)
+               return amdgpu_gmc_vram_checking(adev);
+       else
+               return r;
 }
 
 /**