diff options
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fence.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_uvd.c | 100 | ||||
-rw-r--r-- | 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/radeon.h index f4dcfdd5a28b..aad18e676826 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1145,6 +1145,8 @@ struct radeon_uvd { | |||
1145 | struct radeon_bo *vcpu_bo; | 1145 | struct radeon_bo *vcpu_bo; |
1146 | void *cpu_addr; | 1146 | void *cpu_addr; |
1147 | uint64_t gpu_addr; | 1147 | uint64_t gpu_addr; |
1148 | void *saved_bo; | ||
1149 | unsigned fw_size; | ||
1148 | atomic_t handles[RADEON_MAX_UVD_HANDLES]; | 1150 | atomic_t handles[RADEON_MAX_UVD_HANDLES]; |
1149 | struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; | 1151 | struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; |
1150 | struct delayed_work idle_work; | 1152 | struct delayed_work idle_work; |
@@ -1684,7 +1686,6 @@ struct radeon_device { | |||
1684 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ | 1686 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ |
1685 | const struct firmware *mc_fw; /* NI MC firmware */ | 1687 | const struct firmware *mc_fw; /* NI MC firmware */ |
1686 | const struct firmware *ce_fw; /* SI CE firmware */ | 1688 | const struct firmware *ce_fw; /* SI CE firmware */ |
1687 | const struct firmware *uvd_fw; /* UVD firmware */ | ||
1688 | struct r600_blit r600_blit; | 1689 | struct r600_blit r600_blit; |
1689 | struct r600_vram_scratch vram_scratch; | 1690 | struct r600_vram_scratch vram_scratch; |
1690 | int msi_enabled; /* msi enabled */ | 1691 | int msi_enabled; /* msi enabled */ |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index ddb8f8e04eb5..7ddb0efe2408 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 cad735dd02c6..1b3a91bf1a9d 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
@@ -55,6 +55,7 @@ static void radeon_uvd_idle_work_handler(struct work_struct *work); | |||
55 | int radeon_uvd_init(struct radeon_device *rdev) | 55 | int radeon_uvd_init(struct radeon_device *rdev) |
56 | { | 56 | { |
57 | struct platform_device *pdev; | 57 | struct platform_device *pdev; |
58 | const struct firmware *fw; | ||
58 | unsigned long bo_size; | 59 | unsigned long bo_size; |
59 | const char *fw_name; | 60 | const char *fw_name; |
60 | int i, r; | 61 | int i, r; |
@@ -104,7 +105,7 @@ int radeon_uvd_init(struct radeon_device *rdev) | |||
104 | return -EINVAL; | 105 | return -EINVAL; |
105 | } | 106 | } |
106 | 107 | ||
107 | r = request_firmware(&rdev->uvd_fw, fw_name, &pdev->dev); | 108 | r = request_firmware(&fw, fw_name, &pdev->dev); |
108 | if (r) { | 109 | if (r) { |
109 | dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n", | 110 | dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n", |
110 | fw_name); | 111 | fw_name); |
@@ -114,7 +115,7 @@ int radeon_uvd_init(struct radeon_device *rdev) | |||
114 | 115 | ||
115 | platform_device_unregister(pdev); | 116 | platform_device_unregister(pdev); |
116 | 117 | ||
117 | bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) + | 118 | bo_size = RADEON_GPU_PAGE_ALIGN(fw->size + 8) + |
118 | RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE; | 119 | RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE; |
119 | r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, | 120 | r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, |
120 | RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo); | 121 | RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo); |
@@ -123,16 +124,35 @@ int radeon_uvd_init(struct radeon_device *rdev) | |||
123 | return r; | 124 | return r; |
124 | } | 125 | } |
125 | 126 | ||
126 | r = radeon_uvd_resume(rdev); | 127 | r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false); |
127 | if (r) | 128 | if (r) { |
129 | radeon_bo_unref(&rdev->uvd.vcpu_bo); | ||
130 | dev_err(rdev->dev, "(%d) failed to reserve UVD bo\n", r); | ||
128 | return r; | 131 | return r; |
132 | } | ||
129 | 133 | ||
130 | memset(rdev->uvd.cpu_addr, 0, bo_size); | 134 | r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM, |
131 | memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); | 135 | &rdev->uvd.gpu_addr); |
136 | if (r) { | ||
137 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); | ||
138 | radeon_bo_unref(&rdev->uvd.vcpu_bo); | ||
139 | dev_err(rdev->dev, "(%d) UVD bo pin failed\n", r); | ||
140 | return r; | ||
141 | } | ||
132 | 142 | ||
133 | r = radeon_uvd_suspend(rdev); | 143 | r = radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr); |
134 | if (r) | 144 | if (r) { |
145 | dev_err(rdev->dev, "(%d) UVD map failed\n", r); | ||
135 | return r; | 146 | return r; |
147 | } | ||
148 | |||
149 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); | ||
150 | |||
151 | rdev->uvd.fw_size = fw->size; | ||
152 | memset(rdev->uvd.cpu_addr, 0, bo_size); | ||
153 | memcpy(rdev->uvd.cpu_addr, fw->data, fw->size); | ||
154 | |||
155 | release_firmware(fw); | ||
136 | 156 | ||
137 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { | 157 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { |
138 | atomic_set(&rdev->uvd.handles[i], 0); | 158 | atomic_set(&rdev->uvd.handles[i], 0); |
@@ -144,71 +164,47 @@ int radeon_uvd_init(struct radeon_device *rdev) | |||
144 | 164 | ||
145 | void radeon_uvd_fini(struct radeon_device *rdev) | 165 | void radeon_uvd_fini(struct radeon_device *rdev) |
146 | { | 166 | { |
147 | radeon_uvd_suspend(rdev); | ||
148 | radeon_bo_unref(&rdev->uvd.vcpu_bo); | ||
149 | } | ||
150 | |||
151 | int radeon_uvd_suspend(struct radeon_device *rdev) | ||
152 | { | ||
153 | int r; | 167 | int r; |
154 | 168 | ||
155 | if (rdev->uvd.vcpu_bo == NULL) | 169 | if (rdev->uvd.vcpu_bo == NULL) |
156 | return 0; | 170 | return; |
157 | 171 | ||
158 | r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false); | 172 | r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false); |
159 | if (!r) { | 173 | if (!r) { |
160 | radeon_bo_kunmap(rdev->uvd.vcpu_bo); | 174 | radeon_bo_kunmap(rdev->uvd.vcpu_bo); |
161 | radeon_bo_unpin(rdev->uvd.vcpu_bo); | 175 | radeon_bo_unpin(rdev->uvd.vcpu_bo); |
162 | rdev->uvd.cpu_addr = NULL; | ||
163 | if (!radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_CPU, NULL)) { | ||
164 | radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr); | ||
165 | } | ||
166 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); | 176 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); |
167 | |||
168 | if (rdev->uvd.cpu_addr) { | ||
169 | radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); | ||
170 | } else { | ||
171 | rdev->fence_drv[R600_RING_TYPE_UVD_INDEX].cpu_addr = NULL; | ||
172 | } | ||
173 | } | 177 | } |
174 | return r; | 178 | |
179 | radeon_bo_unref(&rdev->uvd.vcpu_bo); | ||
175 | } | 180 | } |
176 | 181 | ||
177 | int radeon_uvd_resume(struct radeon_device *rdev) | 182 | int radeon_uvd_suspend(struct radeon_device *rdev) |
178 | { | 183 | { |
179 | int r; | 184 | unsigned size; |
180 | 185 | ||
181 | if (rdev->uvd.vcpu_bo == NULL) | 186 | if (rdev->uvd.vcpu_bo == NULL) |
182 | return -EINVAL; | 187 | return 0; |
183 | 188 | ||
184 | r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false); | 189 | size = radeon_bo_size(rdev->uvd.vcpu_bo); |
185 | if (r) { | 190 | rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); |
186 | radeon_bo_unref(&rdev->uvd.vcpu_bo); | 191 | memcpy(rdev->uvd.saved_bo, rdev->uvd.cpu_addr, size); |
187 | dev_err(rdev->dev, "(%d) failed to reserve UVD bo\n", r); | ||
188 | return r; | ||
189 | } | ||
190 | 192 | ||
191 | /* Have been pin in cpu unmap unpin */ | 193 | return 0; |
192 | radeon_bo_kunmap(rdev->uvd.vcpu_bo); | 194 | } |
193 | radeon_bo_unpin(rdev->uvd.vcpu_bo); | ||
194 | 195 | ||
195 | r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM, | 196 | int radeon_uvd_resume(struct radeon_device *rdev) |
196 | &rdev->uvd.gpu_addr); | 197 | { |
197 | if (r) { | 198 | if (rdev->uvd.vcpu_bo == NULL) |
198 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); | 199 | return -EINVAL; |
199 | radeon_bo_unref(&rdev->uvd.vcpu_bo); | ||
200 | dev_err(rdev->dev, "(%d) UVD bo pin failed\n", r); | ||
201 | return r; | ||
202 | } | ||
203 | 200 | ||
204 | r = radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr); | 201 | if (rdev->uvd.saved_bo != NULL) { |
205 | if (r) { | 202 | unsigned size = radeon_bo_size(rdev->uvd.vcpu_bo); |
206 | dev_err(rdev->dev, "(%d) UVD map failed\n", r); | 203 | memcpy(rdev->uvd.cpu_addr, rdev->uvd.saved_bo, size); |
207 | return r; | 204 | kfree(rdev->uvd.saved_bo); |
205 | rdev->uvd.saved_bo = NULL; | ||
208 | } | 206 | } |
209 | 207 | ||
210 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); | ||
211 | |||
212 | return 0; | 208 | return 0; |
213 | } | 209 | } |
214 | 210 | ||
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 4a62ad2e5399..30ea14e8854c 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 | ||