OSDN Git Service

drm/amd/amdgpu: fix UVD mc offsets
authorPiotr Redlewski <predlewski@gmail.com>
Fri, 10 Nov 2017 18:28:01 +0000 (19:28 +0100)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 6 Dec 2017 17:47:22 +0000 (12:47 -0500)
When UVD bo is created, its size is based on the information from firmware
header (ucode_size_bytes). The same value should be be used when programming
UVD mc controller offsets, otherwise it can happen that
(mmUVD_VCPU_CACHE_OFFSET2 + mmUVD_VCPU_CACHE_SIZE2) will point
AMDGPU_GPU_PAGE_SIZE bytes after the UVD bo end.

Second issue is that when programming the mmUVD_VCPU_CACHE_SIZE0 register,
AMDGPU_UVD_FIRMWARE_OFFSET should be taken into account. If it isn't,
(mmUVD_VCPU_CACHE_OFFSET2 + mmUVD_VCPU_CACHE_SIZE2) will always point
AMDGPU_UVD_FIRMWARE_OFFSET bytes after the UVD bo end.

v2: move firmware size calculation into macro definition
v3: align firmware size to the gpu page size

Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Piotr Redlewski <predlewski@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c

index 3553b92..845eea9 100644 (file)
 #define AMDGPU_UVD_SESSION_SIZE                (50*1024)
 #define AMDGPU_UVD_FIRMWARE_OFFSET     256
 
+#define AMDGPU_UVD_FIRMWARE_SIZE(adev)    \
+       (AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(((const struct common_firmware_header *)(adev)->uvd.fw->data)->ucode_size_bytes) + \
+                              8) - AMDGPU_UVD_FIRMWARE_OFFSET)
+
 struct amdgpu_uvd {
        struct amdgpu_bo        *vcpu_bo;
        void                    *cpu_addr;
index 15771a5..b13ae34 100644 (file)
@@ -563,7 +563,7 @@ static void uvd_v4_2_mc_resume(struct amdgpu_device *adev)
 
        /* programm the VCPU memory controller bits 0-27 */
        addr = (adev->uvd.gpu_addr + AMDGPU_UVD_FIRMWARE_OFFSET) >> 3;
-       size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4) >> 3;
+       size = AMDGPU_UVD_FIRMWARE_SIZE(adev) >> 3;
        WREG32(mmUVD_VCPU_CACHE_OFFSET0, addr);
        WREG32(mmUVD_VCPU_CACHE_SIZE0, size);
 
index 3b29aab..a4b0f1d 100644 (file)
@@ -258,7 +258,7 @@ static void uvd_v5_0_mc_resume(struct amdgpu_device *adev)
                        upper_32_bits(adev->uvd.gpu_addr));
 
        offset = AMDGPU_UVD_FIRMWARE_OFFSET;
-       size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4);
+       size = AMDGPU_UVD_FIRMWARE_SIZE(adev);
        WREG32(mmUVD_VCPU_CACHE_OFFSET0, offset >> 3);
        WREG32(mmUVD_VCPU_CACHE_SIZE0, size);
 
index 0c01825..0e8b887 100644 (file)
@@ -603,7 +603,7 @@ static void uvd_v6_0_mc_resume(struct amdgpu_device *adev)
                        upper_32_bits(adev->uvd.gpu_addr));
 
        offset = AMDGPU_UVD_FIRMWARE_OFFSET;
-       size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4);
+       size = AMDGPU_UVD_FIRMWARE_SIZE(adev);
        WREG32(mmUVD_VCPU_CACHE_OFFSET0, offset >> 3);
        WREG32(mmUVD_VCPU_CACHE_SIZE0, size);
 
index 7b77339..6d44706 100644 (file)
@@ -616,7 +616,7 @@ static int uvd_v7_0_resume(void *handle)
  */
 static void uvd_v7_0_mc_resume(struct amdgpu_device *adev)
 {
-       uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4);
+       uint32_t size = AMDGPU_UVD_FIRMWARE_SIZE(adev);
        uint32_t offset;
 
        if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {