diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_atomic.c')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_atomic.c | 46 | 
1 files changed, 39 insertions, 7 deletions
| diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 5b192128cda2..1b22d8bfe142 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -84,6 +84,33 @@ static void commit_destroy(struct msm_commit *c)  	kfree(c);  } +static void msm_atomic_wait_for_commit_done(struct drm_device *dev, +		struct drm_atomic_state *old_state) +{ +	struct drm_crtc *crtc; +	struct msm_drm_private *priv = old_state->dev->dev_private; +	struct msm_kms *kms = priv->kms; +	int ncrtcs = old_state->dev->mode_config.num_crtc; +	int i; + +	for (i = 0; i < ncrtcs; i++) { +		crtc = old_state->crtcs[i]; + +		if (!crtc) +			continue; + +		if (!crtc->state->enable) +			continue; + +		/* Legacy cursor ioctls are completely unsynced, and userspace +		 * relies on that (by doing tons of cursor updates). */ +		if (old_state->legacy_cursor_update) +			continue; + +		kms->funcs->wait_for_crtc_commit_done(kms, crtc); +	} +} +  /* The (potentially) asynchronous part of the commit.  At this point   * nothing can fail short of armageddon.   */ @@ -115,7 +142,7 @@ static void complete_commit(struct msm_commit *c)  	 * not be critical path)  	 */ -	drm_atomic_helper_wait_for_vblanks(dev, state); +	msm_atomic_wait_for_commit_done(dev, state);  	drm_atomic_helper_cleanup_planes(dev, state); @@ -139,7 +166,6 @@ static void add_fb(struct msm_commit *c, struct drm_framebuffer *fb)  	c->fence = max(c->fence, msm_gem_fence(to_msm_bo(obj), MSM_PREP_READ));  } -  int msm_atomic_check(struct drm_device *dev,  		     struct drm_atomic_state *state)  { @@ -178,7 +204,7 @@ int msm_atomic_commit(struct drm_device *dev,  {  	int nplanes = dev->mode_config.num_total_plane;  	int ncrtcs = dev->mode_config.num_crtc; -	struct timespec timeout; +	ktime_t timeout;  	struct msm_commit *c;  	int i, ret; @@ -187,8 +213,10 @@ int msm_atomic_commit(struct drm_device *dev,  		return ret;  	c = commit_init(state); -	if (!c) -		return -ENOMEM; +	if (!c) { +		ret = -ENOMEM; +		goto error; +	}  	/*  	 * Figure out what crtcs we have: @@ -221,7 +249,7 @@ int msm_atomic_commit(struct drm_device *dev,  	ret = start_atomic(dev->dev_private, c->crtc_mask);  	if (ret) {  		kfree(c); -		return ret; +		goto error;  	}  	/* @@ -253,7 +281,7 @@ int msm_atomic_commit(struct drm_device *dev,  		return 0;  	} -	jiffies_to_timespec(jiffies + msecs_to_jiffies(1000), &timeout); +	timeout = ktime_add_ms(ktime_get(), 1000);  	ret = msm_wait_fence_interruptable(dev, c->fence, &timeout);  	if (ret) { @@ -265,4 +293,8 @@ int msm_atomic_commit(struct drm_device *dev,  	complete_commit(c);  	return 0; + +error: +	drm_atomic_helper_cleanup_planes(dev, state); +	return ret;  } | 
