drm/amd/amdgpu: fix UVD mc offsets
Subsystems (2)
PATCH v2 1/1 drm/amd/amdgpu: fix UVD mc offsets
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
--- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h | 4 ++++ drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 2 +- drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h +4 -0
@@ -31,6 +31,10 @@#define AMDGPU_UVD_SESSION_SIZE (50*1024)#define AMDGPU_UVD_FIRMWARE_OFFSET 256 +#define AMDGPU_UVD_FIRMWARE_SIZE (adev) \ + (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;
drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +1 -1
@@ -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);
drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +1 -1
@@ -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);
drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +1 -1
@@ -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);
drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +1 -1
@@ -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 ) {
Signature · 6 lines
2.15.0 _______________________________________________ amd-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/amd-gfx
A message that is not in the archive (sent off-list or not yet received): 20171110142649.4565-1-predlewski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Apperently I didn't test this patch enough - UVD boots, vdpauinfo reports correctly, but actual video playback performance is severly impacted. Version 3 of this patch is on the way.
Regards,
Piotr
Quoted 96 lines · Piotr Redlewski
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 pointAMDGPU_GPU_PAGE_SIZEbytes after the UVD bo end.Second issue is that when programming the
mmUVD_VCPU_CACHE_SIZE0register,AMDGPU_UVD_FIRMWARE_OFFSETshould be taken into account. If it isn't, (mmUVD_VCPU_CACHE_OFFSET2+mmUVD_VCPU_CACHE_SIZE2) will always pointAMDGPU_UVD_FIRMWARE_OFFSETbytes after the UVD bo end.v2: move firmware size calculation into macro definition
Signed-off-by Piotr Redlewski <[email protected]>--- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h | 4 ++++ drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 2 +- drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-)drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h +4
-0@@ -31,6 +31,10 @@#define AMDGPU_UVD_SESSION_SIZE (50*1024)#define AMDGPU_UVD_FIRMWARE_OFFSET 256 +#define AMDGPU_UVD_FIRMWARE_SIZE (adev) \ + (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;drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +1
-1@@ -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);drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +1
-1@@ -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);drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +1
-1@@ -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);drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +1
-1@@ -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 ) {Signature · 6 lines
2.15.0 _______________________________________________ amd-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx