OSDN Git Service

drm: Add drm_atomic_set_mode_for_crtc
authorDaniel Stone <daniels@collabora.com>
Tue, 26 May 2015 13:36:48 +0000 (14:36 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 26 May 2015 13:50:34 +0000 (15:50 +0200)
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.

v2: Do not touch active/mode_changed in CRTC state. Document return
    value. Remove stray drm_atomic_set_mode_prop_for_crtc declaration.

v3: Remove i915 changes, and leave it directly bashing crtc_state->mode
    for the meantime.

Signed-off-by: Daniel Stone <daniels@collabora.com>
Tested-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/drm_atomic.c
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/drm_crtc_helper.c
include/drm/drm_atomic.h

index 3134f50..e749287 100644 (file)
@@ -290,6 +290,42 @@ 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. Does
+ * not change any other state properties, including enable, active, or
+ * mode_changed.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure. Cannot return -EDEADLK.
+ */
+int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
+                                struct drm_display_mode *mode)
+{
+       /* Early return for no change. */
+       if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0)
+               return 0;
+
+       if (mode) {
+               drm_mode_copy(&state->mode, mode);
+               state->enable = true;
+               DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
+                                mode->name, state);
+       } else {
+               memset(&state->mode, 0, sizeof(state->mode));
+               state->enable = false;
+               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
index a64bacd..e69d484 100644 (file)
@@ -1607,7 +1607,10 @@ retry:
                WARN_ON(set->fb);
                WARN_ON(set->num_connectors);
 
-               crtc_state->enable = false;
+               ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
+               if (ret != 0)
+                       goto fail;
+
                crtc_state->active = false;
 
                ret = drm_atomic_set_crtc_for_plane(primary_state, NULL);
@@ -1622,9 +1625,11 @@ 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)
index 9297a61..393114d 100644 (file)
@@ -937,10 +937,11 @@ 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) {
index e89db0c..1e8c61f 100644 (file)
@@ -110,6 +110,9 @@ 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_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,