diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_display.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 140 | 
1 files changed, 30 insertions, 110 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 96926a221bd5..cdf2ab20166a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -123,7 +123,7 @@ static void amdgpu_unpin_work_func(struct work_struct *__work)  	int r;  	/* unpin of the old buffer */ -	r = amdgpu_bo_reserve(work->old_abo, false); +	r = amdgpu_bo_reserve(work->old_abo, true);  	if (likely(r == 0)) {  		r = amdgpu_bo_unpin(work->old_abo);  		if (unlikely(r != 0)) { @@ -138,52 +138,11 @@ static void amdgpu_unpin_work_func(struct work_struct *__work)  	kfree(work);  } - -static void amdgpu_flip_work_cleanup(struct amdgpu_flip_work *work) -{ -	int i; - -	amdgpu_bo_unref(&work->old_abo); -	dma_fence_put(work->excl); -	for (i = 0; i < work->shared_count; ++i) -		dma_fence_put(work->shared[i]); -	kfree(work->shared); -	kfree(work); -} - -static void amdgpu_flip_cleanup_unreserve(struct amdgpu_flip_work *work, -					  struct amdgpu_bo *new_abo) -{ -	amdgpu_bo_unreserve(new_abo); -	amdgpu_flip_work_cleanup(work); -} - -static void amdgpu_flip_cleanup_unpin(struct amdgpu_flip_work *work, -				      struct amdgpu_bo *new_abo) -{ -	if (unlikely(amdgpu_bo_unpin(new_abo) != 0)) -		DRM_ERROR("failed to unpin new abo in error path\n"); -	amdgpu_flip_cleanup_unreserve(work, new_abo); -} - -void amdgpu_crtc_cleanup_flip_ctx(struct amdgpu_flip_work *work, -				  struct amdgpu_bo *new_abo) -{ -	if (unlikely(amdgpu_bo_reserve(new_abo, false) != 0)) { -		DRM_ERROR("failed to reserve new abo in error path\n"); -		amdgpu_flip_work_cleanup(work); -		return; -	} -	amdgpu_flip_cleanup_unpin(work, new_abo); -} - -int amdgpu_crtc_prepare_flip(struct drm_crtc *crtc, -			     struct drm_framebuffer *fb, -			     struct drm_pending_vblank_event *event, -			     uint32_t page_flip_flags, -			     uint32_t target, -			     struct amdgpu_flip_work **work_p, -			     struct amdgpu_bo **new_abo_p) +int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc, +				 struct drm_framebuffer *fb, +				 struct drm_pending_vblank_event *event, +				 uint32_t page_flip_flags, uint32_t target, +				 struct drm_modeset_acquire_ctx *ctx)  {  	struct drm_device *dev = crtc->dev;  	struct amdgpu_device *adev = dev->dev_private; @@ -196,7 +155,7 @@ int amdgpu_crtc_prepare_flip(struct drm_crtc *crtc,  	unsigned long flags;  	u64 tiling_flags;  	u64 base; -	int r; +	int i, r;  	work = kzalloc(sizeof *work, GFP_KERNEL);  	if (work == NULL) @@ -257,80 +216,41 @@ int amdgpu_crtc_prepare_flip(struct drm_crtc *crtc,  		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);  		r = -EBUSY;  		goto pflip_cleanup; -  	} -	spin_unlock_irqrestore(&crtc->dev->event_lock, flags); - -	*work_p = work; -	*new_abo_p = new_abo; - -	return 0; - -pflip_cleanup: -	amdgpu_crtc_cleanup_flip_ctx(work, new_abo); -	return r; - -unpin: -	amdgpu_flip_cleanup_unpin(work, new_abo); -	return r; - -unreserve: -	amdgpu_flip_cleanup_unreserve(work, new_abo); -	return r; -cleanup: -	amdgpu_flip_work_cleanup(work); -	return r; - -} - -void amdgpu_crtc_submit_flip(struct drm_crtc *crtc, -			     struct drm_framebuffer *fb, -			     struct amdgpu_flip_work *work, -			     struct amdgpu_bo *new_abo) -{ -	unsigned long flags; -	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); - -	spin_lock_irqsave(&crtc->dev->event_lock, flags);  	amdgpu_crtc->pflip_status = AMDGPU_FLIP_PENDING;  	amdgpu_crtc->pflip_works = work; + +	DRM_DEBUG_DRIVER("crtc:%d[%p], pflip_stat:AMDGPU_FLIP_PENDING, work: %p,\n", +					 amdgpu_crtc->crtc_id, amdgpu_crtc, work);  	/* update crtc fb */  	crtc->primary->fb = fb;  	spin_unlock_irqrestore(&crtc->dev->event_lock, flags); - -	DRM_DEBUG_DRIVER( -			"crtc:%d[%p], pflip_stat:AMDGPU_FLIP_PENDING, work: %p,\n", -			amdgpu_crtc->crtc_id, amdgpu_crtc, work); -  	amdgpu_flip_work_func(&work->flip_work.work); -} - -int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc, -				 struct drm_framebuffer *fb, -				 struct drm_pending_vblank_event *event, -				 uint32_t page_flip_flags, -				 uint32_t target, -				 struct drm_modeset_acquire_ctx *ctx) -{ -	struct amdgpu_bo *new_abo; -	struct amdgpu_flip_work *work; -	int r; +	return 0; -	r = amdgpu_crtc_prepare_flip(crtc, -				     fb, -				     event, -				     page_flip_flags, -				     target, -				     &work, -				     &new_abo); -	if (r) -		return r; +pflip_cleanup: +	if (unlikely(amdgpu_bo_reserve(new_abo, false) != 0)) { +		DRM_ERROR("failed to reserve new abo in error path\n"); +		goto cleanup; +	} +unpin: +	if (unlikely(amdgpu_bo_unpin(new_abo) != 0)) { +		DRM_ERROR("failed to unpin new abo in error path\n"); +	} +unreserve: +	amdgpu_bo_unreserve(new_abo); -	amdgpu_crtc_submit_flip(crtc, fb, work, new_abo); +cleanup: +	amdgpu_bo_unref(&work->old_abo); +	dma_fence_put(work->excl); +	for (i = 0; i < work->shared_count; ++i) +		dma_fence_put(work->shared[i]); +	kfree(work->shared); +	kfree(work); -	return 0; +	return r;  }  int amdgpu_crtc_set_config(struct drm_mode_set *set,  |