aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_display.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c69
1 files changed, 31 insertions, 38 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 708b2d1c0037..907d20ef6d4d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -138,7 +138,7 @@ nouveau_user_framebuffer_create(struct drm_device *dev,
138{ 138{
139 struct nouveau_framebuffer *nouveau_fb; 139 struct nouveau_framebuffer *nouveau_fb;
140 struct drm_gem_object *gem; 140 struct drm_gem_object *gem;
141 int ret; 141 int ret = -ENOMEM;
142 142
143 gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); 143 gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
144 if (!gem) 144 if (!gem)
@@ -146,15 +146,19 @@ nouveau_user_framebuffer_create(struct drm_device *dev,
146 146
147 nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL); 147 nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL);
148 if (!nouveau_fb) 148 if (!nouveau_fb)
149 return ERR_PTR(-ENOMEM); 149 goto err_unref;
150 150
151 ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem)); 151 ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem));
152 if (ret) { 152 if (ret)
153 drm_gem_object_unreference(gem); 153 goto err;
154 return ERR_PTR(ret);
155 }
156 154
157 return &nouveau_fb->base; 155 return &nouveau_fb->base;
156
157err:
158 kfree(nouveau_fb);
159err_unref:
160 drm_gem_object_unreference(gem);
161 return ERR_PTR(ret);
158} 162}
159 163
160static const struct drm_mode_config_funcs nouveau_mode_config_funcs = { 164static const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
@@ -524,9 +528,12 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
524 struct nouveau_page_flip_state *s; 528 struct nouveau_page_flip_state *s;
525 struct nouveau_channel *chan = NULL; 529 struct nouveau_channel *chan = NULL;
526 struct nouveau_fence *fence; 530 struct nouveau_fence *fence;
527 struct list_head res; 531 struct ttm_validate_buffer resv[2] = {
528 struct ttm_validate_buffer res_val[2]; 532 { .bo = &old_bo->bo },
533 { .bo = &new_bo->bo },
534 };
529 struct ww_acquire_ctx ticket; 535 struct ww_acquire_ctx ticket;
536 LIST_HEAD(res);
530 int ret; 537 int ret;
531 538
532 if (!drm->channel) 539 if (!drm->channel)
@@ -545,27 +552,19 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
545 chan = drm->channel; 552 chan = drm->channel;
546 spin_unlock(&old_bo->bo.bdev->fence_lock); 553 spin_unlock(&old_bo->bo.bdev->fence_lock);
547 554
548 mutex_lock(&chan->cli->mutex);
549
550 if (new_bo != old_bo) { 555 if (new_bo != old_bo) {
551 ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM); 556 ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM);
552 if (likely(!ret)) { 557 if (ret)
553 res_val[0].bo = &old_bo->bo; 558 goto fail_free;
554 res_val[1].bo = &new_bo->bo;
555 INIT_LIST_HEAD(&res);
556 list_add_tail(&res_val[0].head, &res);
557 list_add_tail(&res_val[1].head, &res);
558 ret = ttm_eu_reserve_buffers(&ticket, &res);
559 if (ret)
560 nouveau_bo_unpin(new_bo);
561 }
562 } else
563 ret = ttm_bo_reserve(&new_bo->bo, false, false, false, 0);
564 559
565 if (ret) { 560 list_add(&resv[1].head, &res);
566 mutex_unlock(&chan->cli->mutex);
567 goto fail_free;
568 } 561 }
562 list_add(&resv[0].head, &res);
563
564 mutex_lock(&chan->cli->mutex);
565 ret = ttm_eu_reserve_buffers(&ticket, &res);
566 if (ret)
567 goto fail_unpin;
569 568
570 /* Initialize a page flip struct */ 569 /* Initialize a page flip struct */
571 *s = (struct nouveau_page_flip_state) 570 *s = (struct nouveau_page_flip_state)
@@ -576,10 +575,8 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
576 /* Emit a page flip */ 575 /* Emit a page flip */
577 if (nv_device(drm->device)->card_type >= NV_50) { 576 if (nv_device(drm->device)->card_type >= NV_50) {
578 ret = nv50_display_flip_next(crtc, fb, chan, 0); 577 ret = nv50_display_flip_next(crtc, fb, chan, 0);
579 if (ret) { 578 if (ret)
580 mutex_unlock(&chan->cli->mutex);
581 goto fail_unreserve; 579 goto fail_unreserve;
582 }
583 } 580 }
584 581
585 ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); 582 ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
@@ -590,22 +587,18 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
590 /* Update the crtc struct and cleanup */ 587 /* Update the crtc struct and cleanup */
591 crtc->fb = fb; 588 crtc->fb = fb;
592 589
593 if (old_bo != new_bo) { 590 ttm_eu_fence_buffer_objects(&ticket, &res, fence);
594 ttm_eu_fence_buffer_objects(&ticket, &res, fence); 591 if (old_bo != new_bo)
595 nouveau_bo_unpin(old_bo); 592 nouveau_bo_unpin(old_bo);
596 } else {
597 nouveau_bo_fence(new_bo, fence);
598 ttm_bo_unreserve(&new_bo->bo);
599 }
600 nouveau_fence_unref(&fence); 593 nouveau_fence_unref(&fence);
601 return 0; 594 return 0;
602 595
603fail_unreserve: 596fail_unreserve:
604 if (old_bo != new_bo) { 597 ttm_eu_backoff_reservation(&ticket, &res);
605 ttm_eu_backoff_reservation(&ticket, &res); 598fail_unpin:
599 mutex_unlock(&chan->cli->mutex);
600 if (old_bo != new_bo)
606 nouveau_bo_unpin(new_bo); 601 nouveau_bo_unpin(new_bo);
607 } else
608 ttm_bo_unreserve(&new_bo->bo);
609fail_free: 602fail_free:
610 kfree(s); 603 kfree(s);
611 return ret; 604 return ret;