On 08/17/2012 06:50 PM, Inki Dae wrote:
if old_crtc isn't same as encoder->crtc then it means that
user changed crtc id to another one so a plane to old_crtc
should be disabled so that current plane can be updated safely
and plane->crtc should be set to new crtc(encoder->crtc)

Signed-off-by: Inki Dae <inki....@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.p...@samsung.com>
---
  drivers/gpu/drm/exynos/exynos_drm_encoder.c |   59 +++++++++++++++++++++++++-
  1 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c 
b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index a562a94..7bcace8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -44,6 +44,7 @@
   * @dpms: store the encoder dpms value.
   */
  struct exynos_drm_encoder {
+       struct drm_crtc                 *old_crtc;
        struct drm_encoder              drm_encoder;
        struct exynos_drm_manager       *manager;
        int dpms;
@@ -106,22 +107,74 @@ exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
        return true;
  }
+static void disable_plane_to_crtc(struct drm_device *dev,
+                                               struct drm_crtc *old_crtc,
+                                               struct drm_crtc *new_crtc)
+{
+       struct drm_plane *plane;
+
+       /*
+        * if old_crtc isn't same as encoder->crtc then it means that
+        * user changed crtc id to another one so the plane to old_crtc
+        * should be disabled and plane->crtc should be set to new_crtc
+        * (encoder->crtc)
+        */
+       list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+               if (plane->crtc == old_crtc) {
+                       /*
+                        * do not change below call order.
+                        *
+                        * plane->funcs->disable_plane call checks
+                        * if encoder->crtc is same as plane->crtc and if same
+                        * then overlay_ops->disable callback will be called
+                        * to diasble current hw overlay so plane->crtc should
+                        * have new_crtc because new_crtc was set to
+                        * encoder->crtc in advance.
+                        */
+                       plane->crtc = new_crtc;
+                       plane->funcs->disable_plane(plane);
+               }
+       }
+}
+
  static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
                                         struct drm_display_mode *mode,
                                         struct drm_display_mode *adjusted_mode)
  {
        struct drm_device *dev = encoder->dev;
        struct drm_connector *connector;
-       struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
-       struct exynos_drm_manager_ops *manager_ops = manager->ops;
+       struct exynos_drm_manager *manager;
+       struct exynos_drm_manager_ops *manager_ops;
DRM_DEBUG_KMS("%s\n", __FILE__); list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               if (connector->encoder == encoder)
+               if (connector->encoder == encoder) {
+                       struct exynos_drm_encoder *exynos_encoder;
+
+                       exynos_encoder = to_exynos_encoder(encoder);

Does needs to do this in for statement?

+
+                       if (exynos_encoder->old_crtc != encoder->crtc &&
+                                       exynos_encoder->old_crtc) {
+
+                               /*
+                                * disable a plane to old crtc and change
+                                * crtc of the plane to new one.
+                                */
+                               disable_plane_to_crtc(dev,
+                                               exynos_encoder->old_crtc,
+                                               encoder->crtc);
+                       }
+
+                       manager = exynos_drm_get_manager(encoder);
+                       manager_ops = manager->ops;

Does needs to do this in for statement?


+
                        if (manager_ops && manager_ops->mode_set)
                                manager_ops->mode_set(manager->dev,
                                                        adjusted_mode);
+
+                       exynos_encoder->old_crtc = encoder->crtc;
+               }
        }
  }

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to