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. Signed-off-by: Piotr Redlewski <predlewski at gmail.com> --- drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 5 ++++- drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | 5 ++++- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 5 ++++- drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 7 ++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index 15771a53038e..aa171464f203 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c @@ -560,10 +560,13 @@ static void uvd_v4_2_mc_resume(struct amdgpu_device *adev) { uint64_t addr; uint32_t size; + const struct common_firmware_header *hdr; /* 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; + hdr = (const struct common_firmware_header *)adev->uvd.fw->data; + size = (AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8) - + AMDGPU_UVD_FIRMWARE_OFFSET) >> 3; WREG32(mmUVD_VCPU_CACHE_OFFSET0, addr); WREG32(mmUVD_VCPU_CACHE_SIZE0, size); diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index 3b29aaba783a..7daf4e92aa8b 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c @@ -250,6 +250,7 @@ static void uvd_v5_0_mc_resume(struct amdgpu_device *adev) { uint64_t offset; uint32_t size; + const struct common_firmware_header *hdr; /* programm memory controller bits 0-27 */ WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, @@ -258,7 +259,9 @@ 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); + hdr = (const struct common_firmware_header *)adev->uvd.fw->data; + size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8) - + AMDGPU_UVD_FIRMWARE_OFFSET; WREG32(mmUVD_VCPU_CACHE_OFFSET0, offset >> 3); WREG32(mmUVD_VCPU_CACHE_SIZE0, size); diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 0c01825a8b9e..7c510aed7a1b 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -595,6 +595,7 @@ static void uvd_v6_0_mc_resume(struct amdgpu_device *adev) { uint64_t offset; uint32_t size; + const struct common_firmware_header *hdr; /* programm memory controller bits 0-27 */ WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, @@ -603,7 +604,9 @@ 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); + hdr = (const struct common_firmware_header *)adev->uvd.fw->data; + size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8) - + AMDGPU_UVD_FIRMWARE_OFFSET; WREG32(mmUVD_VCPU_CACHE_OFFSET0, offset >> 3); WREG32(mmUVD_VCPU_CACHE_SIZE0, size); diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index 7b77339feb1a..b015cfd5067d 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c @@ -616,8 +616,13 @@ 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; uint32_t offset; + const struct common_firmware_header *hdr; + + hdr = (const struct common_firmware_header *)adev->uvd.fw->data; + size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8) - + AMDGPU_UVD_FIRMWARE_OFFSET; if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, -- 2.15.0