aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_display.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_display.c138
1 files changed, 29 insertions, 109 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 21125a9452b8..cdf2ab20166a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -138,52 +138,11 @@ static void amdgpu_unpin_work_func(struct work_struct *__work)
138 kfree(work); 138 kfree(work);
139} 139}
140 140
141 141int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
142static void amdgpu_flip_work_cleanup(struct amdgpu_flip_work *work) 142 struct drm_framebuffer *fb,
143{ 143 struct drm_pending_vblank_event *event,
144 int i; 144 uint32_t page_flip_flags, uint32_t target,
145 145 struct drm_modeset_acquire_ctx *ctx)
146 amdgpu_bo_unref(&work->old_abo);
147 dma_fence_put(work->excl);
148 for (i = 0; i < work->shared_count; ++i)
149 dma_fence_put(work->shared[i]);
150 kfree(work->shared);
151 kfree(work);
152}
153
154static void amdgpu_flip_cleanup_unreserve(struct amdgpu_flip_work *work,
155 struct amdgpu_bo *new_abo)
156{
157 amdgpu_bo_unreserve(new_abo);
158 amdgpu_flip_work_cleanup(work);
159}
160
161static void amdgpu_flip_cleanup_unpin(struct amdgpu_flip_work *work,
162 struct amdgpu_bo *new_abo)
163{
164 if (unlikely(amdgpu_bo_unpin(new_abo) != 0))
165 DRM_ERROR("failed to unpin new abo in error path\n");
166 amdgpu_flip_cleanup_unreserve(work, new_abo);
167}
168
169void amdgpu_crtc_cleanup_flip_ctx(struct amdgpu_flip_work *work,
170 struct amdgpu_bo *new_abo)
171{
172 if (unlikely(amdgpu_bo_reserve(new_abo, true) != 0)) {
173 DRM_ERROR("failed to reserve new abo in error path\n");
174 amdgpu_flip_work_cleanup(work);
175 return;
176 }
177 amdgpu_flip_cleanup_unpin(work, new_abo);
178}
179
180int amdgpu_crtc_prepare_flip(struct drm_crtc *crtc,
181 struct drm_framebuffer *fb,
182 struct drm_pending_vblank_event *event,
183 uint32_t page_flip_flags,
184 uint32_t target,
185 struct amdgpu_flip_work **work_p,
186 struct amdgpu_bo **new_abo_p)
187{ 146{
188 struct drm_device *dev = crtc->dev; 147 struct drm_device *dev = crtc->dev;
189 struct amdgpu_device *adev = dev->dev_private; 148 struct amdgpu_device *adev = dev->dev_private;
@@ -196,7 +155,7 @@ int amdgpu_crtc_prepare_flip(struct drm_crtc *crtc,
196 unsigned long flags; 155 unsigned long flags;
197 u64 tiling_flags; 156 u64 tiling_flags;
198 u64 base; 157 u64 base;
199 int r; 158 int i, r;
200 159
201 work = kzalloc(sizeof *work, GFP_KERNEL); 160 work = kzalloc(sizeof *work, GFP_KERNEL);
202 if (work == NULL) 161 if (work == NULL)
@@ -257,80 +216,41 @@ int amdgpu_crtc_prepare_flip(struct drm_crtc *crtc,
257 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 216 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
258 r = -EBUSY; 217 r = -EBUSY;
259 goto pflip_cleanup; 218 goto pflip_cleanup;
260
261 } 219 }
262 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
263
264 *work_p = work;
265 *new_abo_p = new_abo;
266
267 return 0;
268
269pflip_cleanup:
270 amdgpu_crtc_cleanup_flip_ctx(work, new_abo);
271 return r;
272
273unpin:
274 amdgpu_flip_cleanup_unpin(work, new_abo);
275 return r;
276
277unreserve:
278 amdgpu_flip_cleanup_unreserve(work, new_abo);
279 return r;
280 220
281cleanup:
282 amdgpu_flip_work_cleanup(work);
283 return r;
284
285}
286
287void amdgpu_crtc_submit_flip(struct drm_crtc *crtc,
288 struct drm_framebuffer *fb,
289 struct amdgpu_flip_work *work,
290 struct amdgpu_bo *new_abo)
291{
292 unsigned long flags;
293 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
294
295 spin_lock_irqsave(&crtc->dev->event_lock, flags);
296 amdgpu_crtc->pflip_status = AMDGPU_FLIP_PENDING; 221 amdgpu_crtc->pflip_status = AMDGPU_FLIP_PENDING;
297 amdgpu_crtc->pflip_works = work; 222 amdgpu_crtc->pflip_works = work;
298 223
224
225 DRM_DEBUG_DRIVER("crtc:%d[%p], pflip_stat:AMDGPU_FLIP_PENDING, work: %p,\n",
226 amdgpu_crtc->crtc_id, amdgpu_crtc, work);
299 /* update crtc fb */ 227 /* update crtc fb */
300 crtc->primary->fb = fb; 228 crtc->primary->fb = fb;
301 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 229 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
302
303 DRM_DEBUG_DRIVER(
304 "crtc:%d[%p], pflip_stat:AMDGPU_FLIP_PENDING, work: %p,\n",
305 amdgpu_crtc->crtc_id, amdgpu_crtc, work);
306
307 amdgpu_flip_work_func(&work->flip_work.work); 230 amdgpu_flip_work_func(&work->flip_work.work);
308} 231 return 0;
309
310int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
311 struct drm_framebuffer *fb,
312 struct drm_pending_vblank_event *event,
313 uint32_t page_flip_flags,
314 uint32_t target,
315 struct drm_modeset_acquire_ctx *ctx)
316{
317 struct amdgpu_bo *new_abo;
318 struct amdgpu_flip_work *work;
319 int r;
320 232
321 r = amdgpu_crtc_prepare_flip(crtc, 233pflip_cleanup:
322 fb, 234 if (unlikely(amdgpu_bo_reserve(new_abo, false) != 0)) {
323 event, 235 DRM_ERROR("failed to reserve new abo in error path\n");
324 page_flip_flags, 236 goto cleanup;
325 target, 237 }
326 &work, 238unpin:
327 &new_abo); 239 if (unlikely(amdgpu_bo_unpin(new_abo) != 0)) {
328 if (r) 240 DRM_ERROR("failed to unpin new abo in error path\n");
329 return r; 241 }
242unreserve:
243 amdgpu_bo_unreserve(new_abo);
330 244
331 amdgpu_crtc_submit_flip(crtc, fb, work, new_abo); 245cleanup:
246 amdgpu_bo_unref(&work->old_abo);
247 dma_fence_put(work->excl);
248 for (i = 0; i < work->shared_count; ++i)
249 dma_fence_put(work->shared[i]);
250 kfree(work->shared);
251 kfree(work);
332 252
333 return 0; 253 return r;
334} 254}
335 255
336int amdgpu_crtc_set_config(struct drm_mode_set *set, 256int amdgpu_crtc_set_config(struct drm_mode_set *set,