From c1fe75c9e42c8c598a7fb810ecc4f7be258e700c Mon Sep 17 00:00:00 2001 From: Piotr Redlewski Date: Fri, 10 Nov 2017 19:28:01 +0100 Subject: drm/amd/amdgpu: fix UVD mc offsets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Piotr Redlewski Signed-off-by: Alex Deucher --- 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(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h index 3553b92bf69a..845eea993f75 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h @@ -31,6 +31,10 @@ #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; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index 15771a53038e..b13ae34be1c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c @@ -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); diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index 3b29aaba783a..a4b0f1d842b7 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c @@ -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); diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 0c01825a8b9e..0e8b887cf03e 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -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); diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index 7b77339feb1a..6d4470626d25 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c @@ -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) { -- cgit v1.2.3