These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / gpu / drm / drm_crtc_helper.c
index ab00286..ef53475 100644 (file)
@@ -121,7 +121,7 @@ bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
                WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
        }
 
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+       drm_for_each_connector(connector, dev)
                if (connector->encoder == encoder)
                        return true;
        return false;
@@ -151,7 +151,7 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
        if (!oops_in_progress)
                WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
 
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+       drm_for_each_encoder(encoder, dev)
                if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
                        return true;
        return false;
@@ -163,16 +163,14 @@ drm_encoder_disable(struct drm_encoder *encoder)
 {
        const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
 
-       if (encoder->bridge)
-               encoder->bridge->funcs->disable(encoder->bridge);
+       drm_bridge_disable(encoder->bridge);
 
        if (encoder_funcs->disable)
                (*encoder_funcs->disable)(encoder);
        else
                (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
 
-       if (encoder->bridge)
-               encoder->bridge->funcs->post_disable(encoder->bridge);
+       drm_bridge_post_disable(encoder->bridge);
 }
 
 static void __drm_helper_disable_unused_functions(struct drm_device *dev)
@@ -182,7 +180,7 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev)
 
        drm_warn_on_modeset_not_all_locked(dev);
 
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+       drm_for_each_encoder(encoder, dev) {
                if (!drm_helper_encoder_in_use(encoder)) {
                        drm_encoder_disable(encoder);
                        /* disconnect encoder from any connector */
@@ -190,7 +188,7 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev)
                }
        }
 
-       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+       drm_for_each_crtc(crtc, dev) {
                const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
                crtc->enabled = drm_helper_crtc_in_use(crtc);
                if (!crtc->enabled) {
@@ -232,7 +230,7 @@ drm_crtc_prepare_encoders(struct drm_device *dev)
        const struct drm_encoder_helper_funcs *encoder_funcs;
        struct drm_encoder *encoder;
 
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+       drm_for_each_encoder(encoder, dev) {
                encoder_funcs = encoder->helper_private;
                /* Disable unused encoders */
                if (encoder->crtc == NULL)
@@ -307,18 +305,16 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
         * adjust it according to limitations or connector properties, and also
         * a chance to reject the mode entirely.
         */
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+       drm_for_each_encoder(encoder, dev) {
 
                if (encoder->crtc != crtc)
                        continue;
 
-               if (encoder->bridge && encoder->bridge->funcs->mode_fixup) {
-                       ret = encoder->bridge->funcs->mode_fixup(
-                                       encoder->bridge, mode, adjusted_mode);
-                       if (!ret) {
-                               DRM_DEBUG_KMS("Bridge fixup failed\n");
-                               goto done;
-                       }
+               ret = drm_bridge_mode_fixup(encoder->bridge,
+                       mode, adjusted_mode);
+               if (!ret) {
+                       DRM_DEBUG_KMS("Bridge fixup failed\n");
+                       goto done;
                }
 
                encoder_funcs = encoder->helper_private;
@@ -338,20 +334,18 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
        crtc->hwmode = *adjusted_mode;
 
        /* Prepare the encoders and CRTCs before setting the mode. */
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+       drm_for_each_encoder(encoder, dev) {
 
                if (encoder->crtc != crtc)
                        continue;
 
-               if (encoder->bridge)
-                       encoder->bridge->funcs->disable(encoder->bridge);
+               drm_bridge_disable(encoder->bridge);
 
                encoder_funcs = encoder->helper_private;
                /* Disable the encoders as the first thing we do. */
                encoder_funcs->prepare(encoder);
 
-               if (encoder->bridge)
-                       encoder->bridge->funcs->post_disable(encoder->bridge);
+               drm_bridge_post_disable(encoder->bridge);
        }
 
        drm_crtc_prepare_encoders(dev);
@@ -365,7 +359,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
        if (!ret)
            goto done;
 
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+       drm_for_each_encoder(encoder, dev) {
 
                if (encoder->crtc != crtc)
                        continue;
@@ -376,27 +370,23 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
                encoder_funcs = encoder->helper_private;
                encoder_funcs->mode_set(encoder, mode, adjusted_mode);
 
-               if (encoder->bridge && encoder->bridge->funcs->mode_set)
-                       encoder->bridge->funcs->mode_set(encoder->bridge, mode,
-                                       adjusted_mode);
+               drm_bridge_mode_set(encoder->bridge, mode, adjusted_mode);
        }
 
        /* Now enable the clocks, plane, pipe, and connectors that we set up. */
        crtc_funcs->commit(crtc);
 
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+       drm_for_each_encoder(encoder, dev) {
 
                if (encoder->crtc != crtc)
                        continue;
 
-               if (encoder->bridge)
-                       encoder->bridge->funcs->pre_enable(encoder->bridge);
+               drm_bridge_pre_enable(encoder->bridge);
 
                encoder_funcs = encoder->helper_private;
                encoder_funcs->commit(encoder);
 
-               if (encoder->bridge)
-                       encoder->bridge->funcs->enable(encoder->bridge);
+               drm_bridge_enable(encoder->bridge);
        }
 
        /* Calculate and store various constants which
@@ -428,11 +418,11 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
        struct drm_encoder *encoder;
 
        /* Decouple all encoders and their attached connectors from this crtc */
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+       drm_for_each_encoder(encoder, dev) {
                if (encoder->crtc != crtc)
                        continue;
 
-               list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               drm_for_each_connector(connector, dev) {
                        if (connector->encoder != encoder)
                                continue;
 
@@ -529,12 +519,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
         * restored, not the drivers personal bookkeeping.
         */
        count = 0;
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+       drm_for_each_encoder(encoder, dev) {
                save_encoders[count++] = *encoder;
        }
 
        count = 0;
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+       drm_for_each_connector(connector, dev) {
                save_connectors[count++] = *connector;
        }
 
@@ -572,7 +562,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 
        /* a) traverse passed in connector list and get encoders for them */
        count = 0;
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+       drm_for_each_connector(connector, dev) {
                const struct drm_connector_helper_funcs *connector_funcs =
                        connector->helper_private;
                new_encoder = connector->encoder;
@@ -612,7 +602,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
        }
 
        count = 0;
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+       drm_for_each_connector(connector, dev) {
                if (!connector->encoder)
                        continue;
 
@@ -695,12 +685,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 fail:
        /* Restore all previous data. */
        count = 0;
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+       drm_for_each_encoder(encoder, dev) {
                *encoder = save_encoders[count++];
        }
 
        count = 0;
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+       drm_for_each_connector(connector, dev) {
                *connector = save_connectors[count++];
        }
 
@@ -722,7 +712,7 @@ static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
        struct drm_connector *connector;
        struct drm_device *dev = encoder->dev;
 
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+       drm_for_each_connector(connector, dev)
                if (connector->encoder == encoder)
                        if (connector->dpms < dpms)
                                dpms = connector->dpms;
@@ -735,23 +725,19 @@ static void drm_helper_encoder_dpms(struct drm_encoder *encoder, int mode)
        struct drm_bridge *bridge = encoder->bridge;
        const struct drm_encoder_helper_funcs *encoder_funcs;
 
-       if (bridge) {
-               if (mode == DRM_MODE_DPMS_ON)
-                       bridge->funcs->pre_enable(bridge);
-               else
-                       bridge->funcs->disable(bridge);
-       }
+       if (mode == DRM_MODE_DPMS_ON)
+               drm_bridge_pre_enable(bridge);
+       else
+               drm_bridge_disable(bridge);
 
        encoder_funcs = encoder->helper_private;
        if (encoder_funcs->dpms)
                encoder_funcs->dpms(encoder, mode);
 
-       if (bridge) {
-               if (mode == DRM_MODE_DPMS_ON)
-                       bridge->funcs->enable(bridge);
-               else
-                       bridge->funcs->post_disable(bridge);
-       }
+       if (mode == DRM_MODE_DPMS_ON)
+               drm_bridge_enable(bridge);
+       else
+               drm_bridge_post_disable(bridge);
 }
 
 static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
@@ -760,7 +746,7 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
        struct drm_connector *connector;
        struct drm_device *dev = crtc->dev;
 
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+       drm_for_each_connector(connector, dev)
                if (connector->encoder && connector->encoder->crtc == crtc)
                        if (connector->dpms < dpms)
                                dpms = connector->dpms;
@@ -776,15 +762,18 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
  * implementing the DPMS connector attribute. It computes the new desired DPMS
  * state for all encoders and crtcs in the output mesh and calls the ->dpms()
  * callback provided by the driver appropriately.
+ *
+ * Returns:
+ * Always returns 0.
  */
-void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
+int drm_helper_connector_dpms(struct drm_connector *connector, int mode)
 {
        struct drm_encoder *encoder = connector->encoder;
        struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
        int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF;
 
        if (mode == connector->dpms)
-               return;
+               return 0;
 
        old_dpms = connector->dpms;
        connector->dpms = mode;
@@ -816,7 +805,7 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
                }
        }
 
-       return;
+       return 0;
 }
 EXPORT_SYMBOL(drm_helper_connector_dpms);
 
@@ -876,7 +865,7 @@ void drm_helper_resume_force_mode(struct drm_device *dev)
        bool ret;
 
        drm_modeset_lock_all(dev);
-       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+       drm_for_each_crtc(crtc, dev) {
 
                if (!crtc->enabled)
                        continue;
@@ -890,7 +879,7 @@ void drm_helper_resume_force_mode(struct drm_device *dev)
 
                /* Turn off outputs that were already powered off */
                if (drm_helper_choose_crtc_dpms(crtc)) {
-                       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+                       drm_for_each_encoder(encoder, dev) {
 
                                if(encoder->crtc != crtc)
                                        continue;
@@ -941,42 +930,44 @@ int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mod
 
        if (crtc->funcs->atomic_duplicate_state)
                crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
-       else if (crtc->state)
-               crtc_state = kmemdup(crtc->state, sizeof(*crtc_state),
-                                    GFP_KERNEL);
-       else
-               crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
+       else {
+               if (!crtc->state)
+                       drm_atomic_helper_crtc_reset(crtc);
+
+               crtc_state = drm_atomic_helper_crtc_duplicate_state(crtc);
+       }
+
        if (!crtc_state)
                return -ENOMEM;
-       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) {
                ret = crtc_funcs->atomic_check(crtc, crtc_state);
-               if (ret) {
-                       kfree(crtc_state);
-
-                       return ret;
-               }
+               if (ret)
+                       goto out;
        }
 
        swap(crtc->state, crtc_state);
 
        crtc_funcs->mode_set_nofb(crtc);
 
+       ret = drm_helper_crtc_mode_set_base(crtc, x, y, old_fb);
+
+out:
        if (crtc_state) {
                if (crtc->funcs->atomic_destroy_state)
                        crtc->funcs->atomic_destroy_state(crtc, crtc_state);
                else
-                       kfree(crtc_state);
+                       drm_atomic_helper_crtc_destroy_state(crtc, crtc_state);
        }
 
-       return drm_helper_crtc_mode_set_base(crtc, x, y, old_fb);
+       return ret;
 }
 EXPORT_SYMBOL(drm_helper_crtc_mode_set);