diff mbox

[09/11] drm: Add drm_atomic_set_mode_for_crtc

Message ID 1432298094-22239-10-git-send-email-daniels@collabora.com (mailing list archive)
State New, archived
Headers show

Commit Message

Daniel Stone May 22, 2015, 12:34 p.m. UTC
Add a new helper, to be used later for blob property management, that
sets the mode for a CRTC state, as well as updating the CRTC enable/active
state at the same time.

Signed-off-by: Daniel Stone <daniels@collabora.com>
Tested-by: Sean Paul <seanpaul@chromium.org>
---
 drivers/gpu/drm/drm_atomic.c         | 42 ++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_atomic_helper.c  | 24 ++++++---------------
 drivers/gpu/drm/drm_crtc_helper.c    |  6 +++---
 drivers/gpu/drm/i915/intel_display.c | 16 +++++++++-----
 include/drm/drm_atomic.h             |  6 ++++++
 5 files changed, 68 insertions(+), 26 deletions(-)

Comments

Daniel Vetter May 22, 2015, 2:26 p.m. UTC | #1
On Fri, May 22, 2015 at 01:34:52PM +0100, Daniel Stone wrote:
> Add a new helper, to be used later for blob property management, that
> sets the mode for a CRTC state, as well as updating the CRTC enable/active
> state at the same time.
> 
> Signed-off-by: Daniel Stone <daniels@collabora.com>
> Tested-by: Sean Paul <seanpaul@chromium.org>

A few small nits below.
-Daniel

> ---
>  drivers/gpu/drm/drm_atomic.c         | 42 ++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_atomic_helper.c  | 24 ++++++---------------
>  drivers/gpu/drm/drm_crtc_helper.c    |  6 +++---
>  drivers/gpu/drm/i915/intel_display.c | 16 +++++++++-----
>  include/drm/drm_atomic.h             |  6 ++++++
>  5 files changed, 68 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 3134f50..67c251f 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -290,6 +290,48 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state,
>  EXPORT_SYMBOL(drm_atomic_get_crtc_state);
>  
>  /**
> + * drm_atomic_set_mode_for_crtc - set mode for CRTC
> + * @state: the CRTC whose incoming state to update
> + * @mode: kernel-internal mode to use for the CRTC, or NULL to disable
> + *
> + * Set a mode (originating from the kernel) on the desired CRTC state, and
> + * update the CRTC state's enable and mode_changed parameters as necessary.
> + * If disabling, it will also set active to false.

Kerneldoc for return values is missing. Fairly important since many atomic
functions can return -EDEADLK, but this one doesn (even not when all the
patches are applied).

> + */
> +int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
> +				 struct drm_display_mode *mode)
> +{
> +	/* Early return for no change. */
> +	if (!mode && !state->enable)
> +		return 0;
> +	if (mode && state->enable &&
> +	    memcmp(&state->mode, mode, sizeof(*mode)) == 0)
> +		return 0;
> +
> +	state->mode_changed = true;

Layering violation: ->mode_changed is purely something for the benefit of
drivers/helpers and not something the core manadates. Hence this should
get removed imo.

> +
> +	if (mode) {
> +		drm_mode_copy(&state->mode, mode);
> +		state->enable = true;
> +	} else {
> +		memset(&state->mode, 0, sizeof(state->mode));
> +		state->enable = false;
> +		state->active = false;
> +	}
> +
> +	if (state->enable)
> +		DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
> +				 mode->name, state);
> +	else
> +		DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
> +				 state);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_atomic_set_mode_for_crtc);
> +
> +
> +/**
>   * drm_atomic_crtc_set_property - set property on CRTC
>   * @crtc: the drm CRTC to set a property on
>   * @state: the state object to update with the new property value
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index a64bacd..70ce243 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -369,20 +369,6 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
>  	struct drm_connector_state *connector_state;
>  	int i, ret;
>  
> -	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> -		if (!drm_mode_equal(&crtc->state->mode, &crtc_state->mode)) {
> -			DRM_DEBUG_ATOMIC("[CRTC:%d] mode changed\n",
> -					 crtc->base.id);
> -			crtc_state->mode_changed = true;
> -		}
> -
> -		if (crtc->state->enable != crtc_state->enable) {
> -			DRM_DEBUG_ATOMIC("[CRTC:%d] enable changed\n",
> -					 crtc->base.id);
> -			crtc_state->mode_changed = true;
> -		}
> -	}

Ofc then this hunk here needs to stay.

> -
>  	for_each_connector_in_state(state, connector, connector_state, i) {
>  		/*
>  		 * This only sets crtc->mode_changed for routing changes,
> @@ -1607,8 +1593,9 @@ retry:
>  		WARN_ON(set->fb);
>  		WARN_ON(set->num_connectors);
>  
> -		crtc_state->enable = false;
> -		crtc_state->active = false;
> +		ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
> +		if (ret != 0)
> +			goto fail;
>  
>  		ret = drm_atomic_set_crtc_for_plane(primary_state, NULL);
>  		if (ret != 0)
> @@ -1622,9 +1609,10 @@ retry:
>  	WARN_ON(!set->fb);
>  	WARN_ON(!set->num_connectors);
>  
> -	crtc_state->enable = true;
> +	ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode);
> +	if (ret != 0)
> +		goto fail;
>  	crtc_state->active = true;
> -	drm_mode_copy(&crtc_state->mode, set->mode);
>  
>  	ret = drm_atomic_set_crtc_for_plane(primary_state, crtc);
>  	if (ret != 0)
> diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
> index 9297a61..cc77a4f 100644
> --- a/drivers/gpu/drm/drm_crtc_helper.c
> +++ b/drivers/gpu/drm/drm_crtc_helper.c
> @@ -937,10 +937,10 @@ int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mod
>  			crtc_state->crtc = crtc;
>  	}
>  
> -	crtc_state->enable = true;
>  	crtc_state->planes_changed = true;
> -	crtc_state->mode_changed = true;
> -	drm_mode_copy(&crtc_state->mode, mode);
> +	ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
> +	if (ret)
> +		goto out;
>  	drm_mode_copy(&crtc_state->adjusted_mode, adjusted_mode);
>  
>  	if (crtc_funcs->atomic_check) {
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 240092a..7e31972 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -9896,7 +9896,9 @@ retry:
>  	if (ret)
>  		goto fail;
>  
> -	drm_mode_copy(&crtc_state->base.mode, mode);
> +	ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode);
> +	if (ret)
> +		goto fail;
>  
>  	if (intel_set_mode(crtc, state)) {
>  		DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
> @@ -12494,8 +12496,11 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
>  
>  		crtc_state->base.enable = intel_crtc->new_enabled;
>  
> -		if (&intel_crtc->base == crtc)
> -			drm_mode_copy(&crtc_state->base.mode, &crtc->mode);
> +		if (&intel_crtc->base == crtc) {
> +			ret = drm_atomic_set_mode_for_crtc(&crtc_state->base,
> +							   &crtc->mode);
> +			WARN_ON(ret);
> +		}
>  	}
>  
>  	intel_modeset_setup_plane_state(state, crtc, &crtc->mode,
> @@ -12633,8 +12638,9 @@ intel_modeset_stage_output_state(struct drm_device *dev,
>  	if (IS_ERR(crtc_state))
>  		return PTR_ERR(crtc_state);
>  
> -	if (set->mode)
> -		drm_mode_copy(&crtc_state->mode, set->mode);
> +	ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode);
> +	if (ret)
> +		return ret;
>  
>  	if (set->num_connectors)
>  		crtc_state->active = true;
> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> index e89db0c..55f4604 100644
> --- a/include/drm/drm_atomic.h
> +++ b/include/drm/drm_atomic.h
> @@ -110,6 +110,12 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
>  }
>  
>  int __must_check
> +drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
> +			     struct drm_display_mode *mode);
> +int __must_check
> +drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
> +				  struct drm_property_blob *blob);
> +int __must_check
>  drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
>  			      struct drm_crtc *crtc);
>  void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
> -- 
> 2.4.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
diff mbox

Patch

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 3134f50..67c251f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -290,6 +290,48 @@  drm_atomic_get_crtc_state(struct drm_atomic_state *state,
 EXPORT_SYMBOL(drm_atomic_get_crtc_state);
 
 /**
+ * drm_atomic_set_mode_for_crtc - set mode for CRTC
+ * @state: the CRTC whose incoming state to update
+ * @mode: kernel-internal mode to use for the CRTC, or NULL to disable
+ *
+ * Set a mode (originating from the kernel) on the desired CRTC state, and
+ * update the CRTC state's enable and mode_changed parameters as necessary.
+ * If disabling, it will also set active to false.
+ */
+int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
+				 struct drm_display_mode *mode)
+{
+	/* Early return for no change. */
+	if (!mode && !state->enable)
+		return 0;
+	if (mode && state->enable &&
+	    memcmp(&state->mode, mode, sizeof(*mode)) == 0)
+		return 0;
+
+	state->mode_changed = true;
+
+	if (mode) {
+		drm_mode_copy(&state->mode, mode);
+		state->enable = true;
+	} else {
+		memset(&state->mode, 0, sizeof(state->mode));
+		state->enable = false;
+		state->active = false;
+	}
+
+	if (state->enable)
+		DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
+				 mode->name, state);
+	else
+		DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
+				 state);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_atomic_set_mode_for_crtc);
+
+
+/**
  * drm_atomic_crtc_set_property - set property on CRTC
  * @crtc: the drm CRTC to set a property on
  * @state: the state object to update with the new property value
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index a64bacd..70ce243 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -369,20 +369,6 @@  drm_atomic_helper_check_modeset(struct drm_device *dev,
 	struct drm_connector_state *connector_state;
 	int i, ret;
 
-	for_each_crtc_in_state(state, crtc, crtc_state, i) {
-		if (!drm_mode_equal(&crtc->state->mode, &crtc_state->mode)) {
-			DRM_DEBUG_ATOMIC("[CRTC:%d] mode changed\n",
-					 crtc->base.id);
-			crtc_state->mode_changed = true;
-		}
-
-		if (crtc->state->enable != crtc_state->enable) {
-			DRM_DEBUG_ATOMIC("[CRTC:%d] enable changed\n",
-					 crtc->base.id);
-			crtc_state->mode_changed = true;
-		}
-	}
-
 	for_each_connector_in_state(state, connector, connector_state, i) {
 		/*
 		 * This only sets crtc->mode_changed for routing changes,
@@ -1607,8 +1593,9 @@  retry:
 		WARN_ON(set->fb);
 		WARN_ON(set->num_connectors);
 
-		crtc_state->enable = false;
-		crtc_state->active = false;
+		ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
+		if (ret != 0)
+			goto fail;
 
 		ret = drm_atomic_set_crtc_for_plane(primary_state, NULL);
 		if (ret != 0)
@@ -1622,9 +1609,10 @@  retry:
 	WARN_ON(!set->fb);
 	WARN_ON(!set->num_connectors);
 
-	crtc_state->enable = true;
+	ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode);
+	if (ret != 0)
+		goto fail;
 	crtc_state->active = true;
-	drm_mode_copy(&crtc_state->mode, set->mode);
 
 	ret = drm_atomic_set_crtc_for_plane(primary_state, crtc);
 	if (ret != 0)
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 9297a61..cc77a4f 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -937,10 +937,10 @@  int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mod
 			crtc_state->crtc = crtc;
 	}
 
-	crtc_state->enable = true;
 	crtc_state->planes_changed = true;
-	crtc_state->mode_changed = true;
-	drm_mode_copy(&crtc_state->mode, mode);
+	ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
+	if (ret)
+		goto out;
 	drm_mode_copy(&crtc_state->adjusted_mode, adjusted_mode);
 
 	if (crtc_funcs->atomic_check) {
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 240092a..7e31972 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9896,7 +9896,9 @@  retry:
 	if (ret)
 		goto fail;
 
-	drm_mode_copy(&crtc_state->base.mode, mode);
+	ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode);
+	if (ret)
+		goto fail;
 
 	if (intel_set_mode(crtc, state)) {
 		DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
@@ -12494,8 +12496,11 @@  void intel_crtc_restore_mode(struct drm_crtc *crtc)
 
 		crtc_state->base.enable = intel_crtc->new_enabled;
 
-		if (&intel_crtc->base == crtc)
-			drm_mode_copy(&crtc_state->base.mode, &crtc->mode);
+		if (&intel_crtc->base == crtc) {
+			ret = drm_atomic_set_mode_for_crtc(&crtc_state->base,
+							   &crtc->mode);
+			WARN_ON(ret);
+		}
 	}
 
 	intel_modeset_setup_plane_state(state, crtc, &crtc->mode,
@@ -12633,8 +12638,9 @@  intel_modeset_stage_output_state(struct drm_device *dev,
 	if (IS_ERR(crtc_state))
 		return PTR_ERR(crtc_state);
 
-	if (set->mode)
-		drm_mode_copy(&crtc_state->mode, set->mode);
+	ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode);
+	if (ret)
+		return ret;
 
 	if (set->num_connectors)
 		crtc_state->active = true;
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index e89db0c..55f4604 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -110,6 +110,12 @@  drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
 }
 
 int __must_check
+drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
+			     struct drm_display_mode *mode);
+int __must_check
+drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
+				  struct drm_property_blob *blob);
+int __must_check
 drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
 			      struct drm_crtc *crtc);
 void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,