[PATCH] drm/amd/amdgpu: fix UVD mc offsets

Piotr Redlewski predlewski at gmail.com
Fri Nov 10 14:50:51 UTC 2017


On Fri, Nov 10, 2017 at 12:55:09PM +0100, Christian König wrote:
> Am 10.11.2017 um 12:34 schrieb 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 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.
> 
> Good catch, a few notes inside.

Thanks for comments, I've already sent v2 of the patch.
> 
> > 
> > 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;
> 
> Coding style says reverse tree order. In other words longest line first.
> 
> >   	/* 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;
> 
> Instead of repeating the code multiple times please add a define for this
> into amdgpu_uvd.h. E.g. something like this:
> 
> #define AMDGPU_UVD_FIRMWARE_SIZE(adev)    \
>     (((const struct common_firmware_header
> *)(adev)->uvd.fw->data)->ucode_size_bytes + \
>     8 - AMDGPU_UVD_FIRMWARE_OFFSET)

I probably miss something, but this get me wondering - when calculating the size
of the UVD bo, firmware size is aligned to the page size. Is there a reason for
that? If not, maybe similar change could be done in amdgpu_uvd_sw_init.

Regards,
Piotr
> 
> Regards,
> Christian.
> 
> >   	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,
> 
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list