diff options
author | Christian König <christian.koenig@amd.com> | 2013-08-05 08:10:55 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-08-07 17:37:15 -0400 |
commit | 4ad9c1c774c2af152283f510062094e768876f55 (patch) | |
tree | af8887721f494b5ac18374a34f1677c68a5ca628 /drivers/gpu | |
parent | 6fab3febf6d949b0a12b1e4e73db38e4a177a79e (diff) |
drm/radeon: only save UVD bo when we have open handles
Otherwise just reinitialize from scratch on resume,
and so make it more likely to succeed.
Signed-off-by: Christian König <christian.koenig@amd.com>
Cc: stable@vger.kernel.org
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fence.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_uvd.c | 46 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770.c | 2 |
5 files changed, 37 insertions, 17 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 5b587876c7f5..58136f20c060 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -6980,7 +6980,7 @@ int cik_uvd_resume(struct radeon_device *rdev) | |||
6980 | 6980 | ||
6981 | /* programm the VCPU memory controller bits 0-27 */ | 6981 | /* programm the VCPU memory controller bits 0-27 */ |
6982 | addr = rdev->uvd.gpu_addr >> 3; | 6982 | addr = rdev->uvd.gpu_addr >> 3; |
6983 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3; | 6983 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3; |
6984 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); | 6984 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); |
6985 | WREG32(UVD_VCPU_CACHE_SIZE0, size); | 6985 | WREG32(UVD_VCPU_CACHE_SIZE0, size); |
6986 | 6986 | ||
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 2f08219c39b6..76dbe8e9b5c8 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1468,7 +1468,6 @@ struct radeon_uvd { | |||
1468 | void *cpu_addr; | 1468 | void *cpu_addr; |
1469 | uint64_t gpu_addr; | 1469 | uint64_t gpu_addr; |
1470 | void *saved_bo; | 1470 | void *saved_bo; |
1471 | unsigned fw_size; | ||
1472 | atomic_t handles[RADEON_MAX_UVD_HANDLES]; | 1471 | atomic_t handles[RADEON_MAX_UVD_HANDLES]; |
1473 | struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; | 1472 | struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; |
1474 | struct delayed_work idle_work; | 1473 | struct delayed_work idle_work; |
@@ -2066,6 +2065,7 @@ struct radeon_device { | |||
2066 | const struct firmware *mec_fw; /* CIK MEC firmware */ | 2065 | const struct firmware *mec_fw; /* CIK MEC firmware */ |
2067 | const struct firmware *sdma_fw; /* CIK SDMA firmware */ | 2066 | const struct firmware *sdma_fw; /* CIK SDMA firmware */ |
2068 | const struct firmware *smc_fw; /* SMC firmware */ | 2067 | const struct firmware *smc_fw; /* SMC firmware */ |
2068 | const struct firmware *uvd_fw; /* UVD firmware */ | ||
2069 | struct r600_blit r600_blit; | 2069 | struct r600_blit r600_blit; |
2070 | struct r600_vram_scratch vram_scratch; | 2070 | struct r600_vram_scratch vram_scratch; |
2071 | int msi_enabled; /* msi enabled */ | 2071 | int msi_enabled; /* msi enabled */ |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 7ddb0efe2408..ddb8f8e04eb5 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_device *rdev, int ring) | |||
782 | 782 | ||
783 | } else { | 783 | } else { |
784 | /* put fence directly behind firmware */ | 784 | /* put fence directly behind firmware */ |
785 | index = ALIGN(rdev->uvd.fw_size, 8); | 785 | index = ALIGN(rdev->uvd_fw->size, 8); |
786 | rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index; | 786 | rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index; |
787 | rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index; | 787 | rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index; |
788 | } | 788 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 414fd145d20e..ca0d7358ed33 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
@@ -56,7 +56,6 @@ static void radeon_uvd_idle_work_handler(struct work_struct *work); | |||
56 | 56 | ||
57 | int radeon_uvd_init(struct radeon_device *rdev) | 57 | int radeon_uvd_init(struct radeon_device *rdev) |
58 | { | 58 | { |
59 | const struct firmware *fw; | ||
60 | unsigned long bo_size; | 59 | unsigned long bo_size; |
61 | const char *fw_name; | 60 | const char *fw_name; |
62 | int i, r; | 61 | int i, r; |
@@ -105,14 +104,14 @@ int radeon_uvd_init(struct radeon_device *rdev) | |||
105 | return -EINVAL; | 104 | return -EINVAL; |
106 | } | 105 | } |
107 | 106 | ||
108 | r = request_firmware(&fw, fw_name, rdev->dev); | 107 | r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev); |
109 | if (r) { | 108 | if (r) { |
110 | dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n", | 109 | dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n", |
111 | fw_name); | 110 | fw_name); |
112 | return r; | 111 | return r; |
113 | } | 112 | } |
114 | 113 | ||
115 | bo_size = RADEON_GPU_PAGE_ALIGN(fw->size + 8) + | 114 | bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) + |
116 | RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE; | 115 | RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE; |
117 | r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, | 116 | r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, |
118 | RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo); | 117 | RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo); |
@@ -145,12 +144,6 @@ int radeon_uvd_init(struct radeon_device *rdev) | |||
145 | 144 | ||
146 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); | 145 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); |
147 | 146 | ||
148 | rdev->uvd.fw_size = fw->size; | ||
149 | memset(rdev->uvd.cpu_addr, 0, bo_size); | ||
150 | memcpy(rdev->uvd.cpu_addr, fw->data, fw->size); | ||
151 | |||
152 | release_firmware(fw); | ||
153 | |||
154 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { | 147 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { |
155 | atomic_set(&rdev->uvd.handles[i], 0); | 148 | atomic_set(&rdev->uvd.handles[i], 0); |
156 | rdev->uvd.filp[i] = NULL; | 149 | rdev->uvd.filp[i] = NULL; |
@@ -174,33 +167,60 @@ void radeon_uvd_fini(struct radeon_device *rdev) | |||
174 | } | 167 | } |
175 | 168 | ||
176 | radeon_bo_unref(&rdev->uvd.vcpu_bo); | 169 | radeon_bo_unref(&rdev->uvd.vcpu_bo); |
170 | |||
171 | release_firmware(rdev->uvd_fw); | ||
177 | } | 172 | } |
178 | 173 | ||
179 | int radeon_uvd_suspend(struct radeon_device *rdev) | 174 | int radeon_uvd_suspend(struct radeon_device *rdev) |
180 | { | 175 | { |
181 | unsigned size; | 176 | unsigned size; |
177 | void *ptr; | ||
178 | int i; | ||
182 | 179 | ||
183 | if (rdev->uvd.vcpu_bo == NULL) | 180 | if (rdev->uvd.vcpu_bo == NULL) |
184 | return 0; | 181 | return 0; |
185 | 182 | ||
183 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) | ||
184 | if (atomic_read(&rdev->uvd.handles[i])) | ||
185 | break; | ||
186 | |||
187 | if (i == RADEON_MAX_UVD_HANDLES) | ||
188 | return 0; | ||
189 | |||
186 | size = radeon_bo_size(rdev->uvd.vcpu_bo); | 190 | size = radeon_bo_size(rdev->uvd.vcpu_bo); |
191 | size -= rdev->uvd_fw->size; | ||
192 | |||
193 | ptr = rdev->uvd.cpu_addr; | ||
194 | ptr += rdev->uvd_fw->size; | ||
195 | |||
187 | rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); | 196 | rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); |
188 | memcpy(rdev->uvd.saved_bo, rdev->uvd.cpu_addr, size); | 197 | memcpy(rdev->uvd.saved_bo, ptr, size); |
189 | 198 | ||
190 | return 0; | 199 | return 0; |
191 | } | 200 | } |
192 | 201 | ||
193 | int radeon_uvd_resume(struct radeon_device *rdev) | 202 | int radeon_uvd_resume(struct radeon_device *rdev) |
194 | { | 203 | { |
204 | unsigned size; | ||
205 | void *ptr; | ||
206 | |||
195 | if (rdev->uvd.vcpu_bo == NULL) | 207 | if (rdev->uvd.vcpu_bo == NULL) |
196 | return -EINVAL; | 208 | return -EINVAL; |
197 | 209 | ||
210 | memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); | ||
211 | |||
212 | size = radeon_bo_size(rdev->uvd.vcpu_bo); | ||
213 | size -= rdev->uvd_fw->size; | ||
214 | |||
215 | ptr = rdev->uvd.cpu_addr; | ||
216 | ptr += rdev->uvd_fw->size; | ||
217 | |||
198 | if (rdev->uvd.saved_bo != NULL) { | 218 | if (rdev->uvd.saved_bo != NULL) { |
199 | unsigned size = radeon_bo_size(rdev->uvd.vcpu_bo); | 219 | memcpy(ptr, rdev->uvd.saved_bo, size); |
200 | memcpy(rdev->uvd.cpu_addr, rdev->uvd.saved_bo, size); | ||
201 | kfree(rdev->uvd.saved_bo); | 220 | kfree(rdev->uvd.saved_bo); |
202 | rdev->uvd.saved_bo = NULL; | 221 | rdev->uvd.saved_bo = NULL; |
203 | } | 222 | } else |
223 | memset(ptr, 0, size); | ||
204 | 224 | ||
205 | return 0; | 225 | return 0; |
206 | } | 226 | } |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 3cc08a4d99d9..bcc68ec204ad 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) | |||
813 | 813 | ||
814 | /* programm the VCPU memory controller bits 0-27 */ | 814 | /* programm the VCPU memory controller bits 0-27 */ |
815 | addr = rdev->uvd.gpu_addr >> 3; | 815 | addr = rdev->uvd.gpu_addr >> 3; |
816 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3; | 816 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3; |
817 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); | 817 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); |
818 | WREG32(UVD_VCPU_CACHE_SIZE0, size); | 818 | WREG32(UVD_VCPU_CACHE_SIZE0, size); |
819 | 819 | ||