From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alex Deucher Subject: Re: [PATCH] drm/radeon: never unpin UVD bo v2 Date: Fri, 12 Jul 2013 10:23:44 -0400 Message-ID: References: <1373614801-10172-1-git-send-email-deathsimple@vodafone.de> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Return-path: Received: from mail-vc0-f181.google.com (mail-vc0-f181.google.com [209.85.220.181]) by gabe.freedesktop.org (Postfix) with ESMTP id 3C04CE61A0 for ; Fri, 12 Jul 2013 07:23:45 -0700 (PDT) Received: by mail-vc0-f181.google.com with SMTP id lf11so7750212vcb.12 for ; Fri, 12 Jul 2013 07:23:44 -0700 (PDT) In-Reply-To: <1373614801-10172-1-git-send-email-deathsimple@vodafone.de> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org Errors-To: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org To: =?ISO-8859-1?Q?Christian_K=F6nig?= Cc: dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org On Fri, Jul 12, 2013 at 3:40 AM, Christian K=F6nig wrote: > From: Christian K=F6nig > > Changing the UVD BOs offset on suspend/resume doesn't work cause the VCPU > internally keeps pointers to it. Just keep it always pinned and save the > content manually. > > Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=3D66425 > > v2: fix compiler warning > > Signed-off-by: Christian K=F6nig > Cc: stable@vger.kernel.org I'll send this version to stable. I had to tweak it slightly for CIK for 3.11. Applied. Thanks, Alex > --- > drivers/gpu/drm/radeon/radeon.h | 3 +- > drivers/gpu/drm/radeon/radeon_fence.c | 2 +- > drivers/gpu/drm/radeon/radeon_uvd.c | 100 ++++++++++++++++-----------= ------ > drivers/gpu/drm/radeon/rv770.c | 2 +- > 4 files changed, 52 insertions(+), 55 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/rad= eon.h > index 9b7025d..7b7d23a 100644 > --- a/drivers/gpu/drm/radeon/radeon.h > +++ b/drivers/gpu/drm/radeon/radeon.h > @@ -1460,6 +1460,8 @@ struct radeon_uvd { > struct radeon_bo *vcpu_bo; > void *cpu_addr; > uint64_t gpu_addr; > + void *saved_bo; > + unsigned fw_size; > atomic_t handles[RADEON_MAX_UVD_HANDLES]; > struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; > struct delayed_work idle_work; > @@ -2054,7 +2056,6 @@ struct radeon_device { > const struct firmware *rlc_fw; /* r6/700 RLC firmware */ > const struct firmware *mc_fw; /* NI MC firmware */ > const struct firmware *ce_fw; /* SI CE firmware */ > - const struct firmware *uvd_fw; /* UVD firmware */ > const struct firmware *mec_fw; /* CIK MEC firmware */ > const struct firmware *sdma_fw; /* CIK SDMA firmware */ > const struct firmware *smc_fw; /* SMC firmware */ > diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/rade= on/radeon_fence.c > index ddb8f8e..7ddb0ef 100644 > --- a/drivers/gpu/drm/radeon/radeon_fence.c > +++ b/drivers/gpu/drm/radeon/radeon_fence.c > @@ -782,7 +782,7 @@ int radeon_fence_driver_start_ring(struct radeon_devi= ce *rdev, int ring) > > } else { > /* put fence directly behind firmware */ > - index =3D ALIGN(rdev->uvd_fw->size, 8); > + index =3D ALIGN(rdev->uvd.fw_size, 8); > rdev->fence_drv[ring].cpu_addr =3D rdev->uvd.cpu_= addr + index; > rdev->fence_drv[ring].gpu_addr =3D rdev->uvd.gpu_= addr + index; > } > diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon= /radeon_uvd.c > index 41efcec..43b083d 100644 > --- a/drivers/gpu/drm/radeon/radeon_uvd.c > +++ b/drivers/gpu/drm/radeon/radeon_uvd.c > @@ -57,6 +57,7 @@ static void radeon_uvd_idle_work_handler(struct work_st= ruct *work); > int radeon_uvd_init(struct radeon_device *rdev) > { > struct platform_device *pdev; > + const struct firmware *fw; > unsigned long bo_size; > const char *fw_name; > int i, r; > @@ -112,7 +113,7 @@ int radeon_uvd_init(struct radeon_device *rdev) > return -EINVAL; > } > > - r =3D request_firmware(&rdev->uvd_fw, fw_name, &pdev->dev); > + r =3D request_firmware(&fw, fw_name, &pdev->dev); > if (r) { > dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\= "\n", > fw_name); > @@ -122,7 +123,7 @@ int radeon_uvd_init(struct radeon_device *rdev) > > platform_device_unregister(pdev); > > - bo_size =3D RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) + > + bo_size =3D RADEON_GPU_PAGE_ALIGN(fw->size + 8) + > RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE; > r =3D radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, > RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcp= u_bo); > @@ -131,16 +132,35 @@ int radeon_uvd_init(struct radeon_device *rdev) > return r; > } > > - r =3D radeon_uvd_resume(rdev); > - if (r) > + r =3D radeon_bo_reserve(rdev->uvd.vcpu_bo, false); > + if (r) { > + radeon_bo_unref(&rdev->uvd.vcpu_bo); > + dev_err(rdev->dev, "(%d) failed to reserve UVD bo\n", r); > return r; > + } > > - memset(rdev->uvd.cpu_addr, 0, bo_size); > - memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size= ); > + r =3D radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM, > + &rdev->uvd.gpu_addr); > + if (r) { > + radeon_bo_unreserve(rdev->uvd.vcpu_bo); > + radeon_bo_unref(&rdev->uvd.vcpu_bo); > + dev_err(rdev->dev, "(%d) UVD bo pin failed\n", r); > + return r; > + } > > - r =3D radeon_uvd_suspend(rdev); > - if (r) > + r =3D radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr); > + if (r) { > + dev_err(rdev->dev, "(%d) UVD map failed\n", r); > return r; > + } > + > + radeon_bo_unreserve(rdev->uvd.vcpu_bo); > + > + rdev->uvd.fw_size =3D fw->size; > + memset(rdev->uvd.cpu_addr, 0, bo_size); > + memcpy(rdev->uvd.cpu_addr, fw->data, fw->size); > + > + release_firmware(fw); > > for (i =3D 0; i < RADEON_MAX_UVD_HANDLES; ++i) { > atomic_set(&rdev->uvd.handles[i], 0); > @@ -152,71 +172,47 @@ int radeon_uvd_init(struct radeon_device *rdev) > > void radeon_uvd_fini(struct radeon_device *rdev) > { > - radeon_uvd_suspend(rdev); > - radeon_bo_unref(&rdev->uvd.vcpu_bo); > -} > - > -int radeon_uvd_suspend(struct radeon_device *rdev) > -{ > int r; > > if (rdev->uvd.vcpu_bo =3D=3D NULL) > - return 0; > + return; > > r =3D radeon_bo_reserve(rdev->uvd.vcpu_bo, false); > if (!r) { > radeon_bo_kunmap(rdev->uvd.vcpu_bo); > radeon_bo_unpin(rdev->uvd.vcpu_bo); > - rdev->uvd.cpu_addr =3D NULL; > - if (!radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_C= PU, NULL)) { > - radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_= addr); > - } > radeon_bo_unreserve(rdev->uvd.vcpu_bo); > - > - if (rdev->uvd.cpu_addr) { > - radeon_fence_driver_start_ring(rdev, R600_RING_TY= PE_UVD_INDEX); > - } else { > - rdev->fence_drv[R600_RING_TYPE_UVD_INDEX].cpu_add= r =3D NULL; > - } > } > - return r; > + > + radeon_bo_unref(&rdev->uvd.vcpu_bo); > } > > -int radeon_uvd_resume(struct radeon_device *rdev) > +int radeon_uvd_suspend(struct radeon_device *rdev) > { > - int r; > + unsigned size; > > if (rdev->uvd.vcpu_bo =3D=3D NULL) > - return -EINVAL; > + return 0; > > - r =3D radeon_bo_reserve(rdev->uvd.vcpu_bo, false); > - if (r) { > - radeon_bo_unref(&rdev->uvd.vcpu_bo); > - dev_err(rdev->dev, "(%d) failed to reserve UVD bo\n", r); > - return r; > - } > + size =3D radeon_bo_size(rdev->uvd.vcpu_bo); > + rdev->uvd.saved_bo =3D kmalloc(size, GFP_KERNEL); > + memcpy(rdev->uvd.saved_bo, rdev->uvd.cpu_addr, size); > > - /* Have been pin in cpu unmap unpin */ > - radeon_bo_kunmap(rdev->uvd.vcpu_bo); > - radeon_bo_unpin(rdev->uvd.vcpu_bo); > + return 0; > +} > > - r =3D radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM, > - &rdev->uvd.gpu_addr); > - if (r) { > - radeon_bo_unreserve(rdev->uvd.vcpu_bo); > - radeon_bo_unref(&rdev->uvd.vcpu_bo); > - dev_err(rdev->dev, "(%d) UVD bo pin failed\n", r); > - return r; > - } > +int radeon_uvd_resume(struct radeon_device *rdev) > +{ > + if (rdev->uvd.vcpu_bo =3D=3D NULL) > + return -EINVAL; > > - r =3D radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr); > - if (r) { > - dev_err(rdev->dev, "(%d) UVD map failed\n", r); > - return r; > + if (rdev->uvd.saved_bo !=3D NULL) { > + unsigned size =3D radeon_bo_size(rdev->uvd.vcpu_bo); > + memcpy(rdev->uvd.cpu_addr, rdev->uvd.saved_bo, size); > + kfree(rdev->uvd.saved_bo); > + rdev->uvd.saved_bo =3D NULL; > } > > - radeon_bo_unreserve(rdev->uvd.vcpu_bo); > - > return 0; > } > > diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv77= 0.c > index 4a62ad2..30ea14e 100644 > --- a/drivers/gpu/drm/radeon/rv770.c > +++ b/drivers/gpu/drm/radeon/rv770.c > @@ -813,7 +813,7 @@ int rv770_uvd_resume(struct radeon_device *rdev) > > /* programm the VCPU memory controller bits 0-27 */ > addr =3D rdev->uvd.gpu_addr >> 3; > - size =3D RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3; > + size =3D RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3; > WREG32(UVD_VCPU_CACHE_OFFSET0, addr); > WREG32(UVD_VCPU_CACHE_SIZE0, size); > > -- > 1.7.9.5 >