aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2013-08-05 08:10:55 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-08-07 17:37:15 -0400
commit4ad9c1c774c2af152283f510062094e768876f55 (patch)
treeaf8887721f494b5ac18374a34f1677c68a5ca628 /drivers/gpu
parent6fab3febf6d949b0a12b1e4e73db38e4a177a79e (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.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_uvd.c46
-rw-r--r--drivers/gpu/drm/radeon/rv770.c2
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
57int radeon_uvd_init(struct radeon_device *rdev) 57int 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
179int radeon_uvd_suspend(struct radeon_device *rdev) 174int 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
193int radeon_uvd_resume(struct radeon_device *rdev) 202int 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