drm/exynos: update overlay via plane from crtc
authorJoonyoung Shim <jy0922.shim@samsung.com>
Wed, 27 Jun 2012 05:27:05 +0000 (14:27 +0900)
committerInki Dae <inki.dae@samsung.com>
Fri, 27 Jul 2012 02:13:53 +0000 (11:13 +0900)
There is no any reason to update overlay at crtc directly because the
crtc uses plane. Move its code to plane and call proper functions of
plane from crtc.

Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_crtc.h
drivers/gpu/drm/exynos/exynos_drm_encoder.c
drivers/gpu/drm/exynos/exynos_drm_encoder.h
drivers/gpu/drm/exynos/exynos_drm_plane.c
drivers/gpu/drm/exynos/exynos_drm_plane.h

index eaf6fb5..7f65842 100644 (file)
 #include "drm_crtc_helper.h"
 
 #include "exynos_drm_drv.h"
-#include "exynos_drm_crtc.h"
-#include "exynos_drm_fb.h"
 #include "exynos_drm_encoder.h"
-#include "exynos_drm_gem.h"
 #include "exynos_drm_plane.h"
 
 #define to_exynos_crtc(x)      container_of(x, struct exynos_drm_crtc,\
@@ -60,107 +57,6 @@ struct exynos_drm_crtc {
        unsigned int                    dpms;
 };
 
-static void exynos_drm_crtc_apply(struct drm_crtc *crtc)
-{
-       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
-       struct exynos_drm_overlay *overlay =
-               get_exynos_drm_overlay(exynos_crtc->plane);
-
-       exynos_drm_fn_encoder(crtc, overlay,
-                       exynos_drm_encoder_crtc_mode_set);
-       exynos_drm_fn_encoder(crtc, NULL, exynos_drm_encoder_crtc_commit);
-}
-
-int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay,
-                             struct drm_framebuffer *fb,
-                             struct drm_display_mode *mode,
-                             struct exynos_drm_crtc_pos *pos)
-{
-       struct exynos_drm_gem_buf *buffer;
-       unsigned int actual_w;
-       unsigned int actual_h;
-       int nr = exynos_drm_format_num_buffers(fb->pixel_format);
-       int i;
-
-       for (i = 0; i < nr; i++) {
-               buffer = exynos_drm_fb_buffer(fb, i);
-               if (!buffer) {
-                       DRM_LOG_KMS("buffer is null\n");
-                       return -EFAULT;
-               }
-
-               overlay->dma_addr[i] = buffer->dma_addr;
-               overlay->vaddr[i] = buffer->kvaddr;
-
-               DRM_DEBUG_KMS("buffer: %d, vaddr = 0x%lx, dma_addr = 0x%lx\n",
-                               i, (unsigned long)overlay->vaddr[i],
-                               (unsigned long)overlay->dma_addr[i]);
-       }
-
-       actual_w = min((mode->hdisplay - pos->crtc_x), pos->crtc_w);
-       actual_h = min((mode->vdisplay - pos->crtc_y), pos->crtc_h);
-
-       /* set drm framebuffer data. */
-       overlay->fb_x = pos->fb_x;
-       overlay->fb_y = pos->fb_y;
-       overlay->fb_width = fb->width;
-       overlay->fb_height = fb->height;
-       overlay->src_width = pos->src_w;
-       overlay->src_height = pos->src_h;
-       overlay->bpp = fb->bits_per_pixel;
-       overlay->pitch = fb->pitches[0];
-       overlay->pixel_format = fb->pixel_format;
-
-       /* set overlay range to be displayed. */
-       overlay->crtc_x = pos->crtc_x;
-       overlay->crtc_y = pos->crtc_y;
-       overlay->crtc_width = actual_w;
-       overlay->crtc_height = actual_h;
-
-       /* set drm mode data. */
-       overlay->mode_width = mode->hdisplay;
-       overlay->mode_height = mode->vdisplay;
-       overlay->refresh = mode->vrefresh;
-       overlay->scan_flag = mode->flags;
-
-       DRM_DEBUG_KMS("overlay : offset_x/y(%d,%d), width/height(%d,%d)",
-                       overlay->crtc_x, overlay->crtc_y,
-                       overlay->crtc_width, overlay->crtc_height);
-
-       return 0;
-}
-
-static int exynos_drm_crtc_update(struct drm_crtc *crtc)
-{
-       struct exynos_drm_crtc *exynos_crtc;
-       struct exynos_drm_overlay *overlay;
-       struct exynos_drm_crtc_pos pos;
-       struct drm_display_mode *mode = &crtc->mode;
-       struct drm_framebuffer *fb = crtc->fb;
-
-       if (!mode || !fb)
-               return -EINVAL;
-
-       exynos_crtc = to_exynos_crtc(crtc);
-       overlay = get_exynos_drm_overlay(exynos_crtc->plane);
-
-       memset(&pos, 0, sizeof(struct exynos_drm_crtc_pos));
-
-       /* it means the offset of framebuffer to be displayed. */
-       pos.fb_x = crtc->x;
-       pos.fb_y = crtc->y;
-
-       /* OSD position to be displayed. */
-       pos.crtc_x = 0;
-       pos.crtc_y = 0;
-       pos.crtc_w = fb->width - crtc->x;
-       pos.crtc_h = fb->height - crtc->y;
-       pos.src_w = pos.crtc_w;
-       pos.src_h = pos.crtc_h;
-
-       return exynos_drm_overlay_update(overlay, crtc->fb, mode, &pos);
-}
-
 static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
        struct drm_device *dev = crtc->dev;
@@ -231,7 +127,7 @@ static void exynos_drm_crtc_commit(struct drm_crtc *crtc)
                                        exynos_drm_encoder_dpms_from_crtc);
        }
 
-       exynos_drm_fn_encoder(crtc, NULL, exynos_drm_encoder_crtc_commit);
+       exynos_plane_commit(exynos_crtc->plane);
 }
 
 static bool
@@ -251,8 +147,9 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
                          struct drm_framebuffer *old_fb)
 {
        struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
-       struct exynos_drm_overlay *overlay =
-               get_exynos_drm_overlay(exynos_crtc->plane);
+       struct drm_plane *plane = exynos_crtc->plane;
+       unsigned int crtc_w;
+       unsigned int crtc_h;
        int pipe = exynos_crtc->pipe;
        int ret;
 
@@ -264,11 +161,17 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
         */
        memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode));
 
-       ret = exynos_drm_crtc_update(crtc);
+       crtc_w = crtc->fb->width - x;
+       crtc_h = crtc->fb->height - y;
+
+       ret = exynos_plane_mode_set(plane, crtc, crtc->fb, 0, 0, crtc_w, crtc_h,
+                                   x, y, crtc_w, crtc_h);
        if (ret)
                return ret;
 
-       exynos_drm_fn_encoder(crtc, overlay, exynos_drm_encoder_crtc_mode_set);
+       plane->crtc = crtc;
+       plane->fb = crtc->fb;
+
        exynos_drm_fn_encoder(crtc, &pipe, exynos_drm_encoder_crtc_pipe);
 
        return 0;
@@ -277,17 +180,25 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
 static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
                                          struct drm_framebuffer *old_fb)
 {
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+       struct drm_plane *plane = exynos_crtc->plane;
+       unsigned int crtc_w;
+       unsigned int crtc_h;
        int ret;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       ret = exynos_drm_crtc_update(crtc);
+       crtc_w = crtc->fb->width - x;
+       crtc_h = crtc->fb->height - y;
+
+       ret = exynos_plane_mode_set(plane, crtc, crtc->fb, 0, 0, crtc_w, crtc_h,
+                                   x, y, crtc_w, crtc_h);
        if (ret)
                return ret;
 
-       exynos_drm_crtc_apply(crtc);
+       exynos_plane_commit(exynos_crtc->plane);
 
-       return ret;
+       return 0;
 }
 
 static void exynos_drm_crtc_load_lut(struct drm_crtc *crtc)
@@ -339,7 +250,8 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
                                &dev_priv->pageflip_event_list);
 
                crtc->fb = fb;
-               ret = exynos_drm_crtc_update(crtc);
+               ret = exynos_drm_crtc_mode_set_base(crtc, crtc->x, crtc->y,
+                                                   NULL);
                if (ret) {
                        crtc->fb = old_fb;
                        drm_vblank_put(dev, exynos_crtc->pipe);
@@ -347,14 +259,6 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
 
                        goto out;
                }
-
-               /*
-                * the values related to a buffer of the drm framebuffer
-                * to be applied should be set at here. because these values
-                * first, are set to shadow registers and then to
-                * real registers at vsync front porch period.
-                */
-               exynos_drm_crtc_apply(crtc);
        }
 out:
        mutex_unlock(&dev->struct_mutex);
index b1c6e83..6bae8d8 100644 (file)
@@ -33,33 +33,4 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr);
 int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc);
 void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc);
 
-/*
- * Exynos specific crtc postion structure.
- *
- * @fb_x: offset x on a framebuffer to be displyed
- *     - the unit is screen coordinates.
- * @fb_y: offset y on a framebuffer to be displayed
- *     - the unit is screen coordinates.
- * @src_w: width of source area to be displayed from a framebuffer.
- * @src_h: height of source area to be displayed from a framebuffer.
- * @crtc_x: offset x on hardware screen.
- * @crtc_y: offset y on hardware screen.
- * @crtc_w: width of hardware screen.
- * @crtc_h: height of hardware screen.
- */
-struct exynos_drm_crtc_pos {
-       unsigned int fb_x;
-       unsigned int fb_y;
-       unsigned int src_w;
-       unsigned int src_h;
-       unsigned int crtc_x;
-       unsigned int crtc_y;
-       unsigned int crtc_w;
-       unsigned int crtc_h;
-};
-
-int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay,
-                             struct drm_framebuffer *fb,
-                             struct drm_display_mode *mode,
-                             struct exynos_drm_crtc_pos *pos);
 #endif
index 33f3c41..c25bd48 100644 (file)
@@ -323,30 +323,6 @@ void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data)
                manager_ops->disable_vblank(manager->dev);
 }
 
-void exynos_drm_encoder_crtc_plane_commit(struct drm_encoder *encoder,
-                                         void *data)
-{
-       struct exynos_drm_manager *manager =
-               to_exynos_encoder(encoder)->manager;
-       struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
-       int zpos = DEFAULT_ZPOS;
-
-       if (data)
-               zpos = *(int *)data;
-
-       if (overlay_ops && overlay_ops->commit)
-               overlay_ops->commit(manager->dev, zpos);
-}
-
-void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data)
-{
-       int zpos = DEFAULT_ZPOS;
-
-       DRM_DEBUG_KMS("%s\n", __FILE__);
-
-       exynos_drm_encoder_crtc_plane_commit(encoder, &zpos);
-}
-
 void exynos_drm_encoder_dpms_from_crtc(struct drm_encoder *encoder, void *data)
 {
        struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
@@ -393,44 +369,62 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data)
        }
 }
 
-void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data)
+void exynos_drm_encoder_crtc_pipe(struct drm_encoder *encoder, void *data)
+{
+       struct exynos_drm_manager *manager =
+               to_exynos_encoder(encoder)->manager;
+       int pipe = *(int *)data;
+
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+
+       /*
+        * when crtc is detached from encoder, this pipe is used
+        * to select manager operation
+        */
+       manager->pipe = pipe;
+}
+
+void exynos_drm_encoder_plane_mode_set(struct drm_encoder *encoder, void *data)
 {
        struct exynos_drm_manager *manager =
                to_exynos_encoder(encoder)->manager;
        struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
        struct exynos_drm_overlay *overlay = data;
 
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+
        if (overlay_ops && overlay_ops->mode_set)
                overlay_ops->mode_set(manager->dev, overlay);
 }
 
-void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data)
+void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data)
 {
        struct exynos_drm_manager *manager =
                to_exynos_encoder(encoder)->manager;
        struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
        int zpos = DEFAULT_ZPOS;
 
-       DRM_DEBUG_KMS("\n");
+       DRM_DEBUG_KMS("%s\n", __FILE__);
 
        if (data)
                zpos = *(int *)data;
 
-       if (overlay_ops && overlay_ops->disable)
-               overlay_ops->disable(manager->dev, zpos);
+       if (overlay_ops && overlay_ops->commit)
+               overlay_ops->commit(manager->dev, zpos);
 }
 
-void exynos_drm_encoder_crtc_pipe(struct drm_encoder *encoder, void *data)
+void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data)
 {
        struct exynos_drm_manager *manager =
                to_exynos_encoder(encoder)->manager;
-       int pipe = *(int *)data;
+       struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
+       int zpos = DEFAULT_ZPOS;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       /*
-        * when crtc is detached from encoder, this pipe is used
-        * to select manager operation
-        */
-       manager->pipe = pipe;
+       if (data)
+               zpos = *(int *)data;
+
+       if (overlay_ops && overlay_ops->disable)
+               overlay_ops->disable(manager->dev, zpos);
 }
index 14dab25..cabe3eb 100644 (file)
@@ -40,14 +40,12 @@ void exynos_drm_fn_encoder(struct drm_crtc *crtc, void *data,
                            void (*fn)(struct drm_encoder *, void *));
 void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data);
 void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data);
-void exynos_drm_encoder_crtc_plane_commit(struct drm_encoder *encoder,
-                                         void *data);
-void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data);
 void exynos_drm_encoder_dpms_from_crtc(struct drm_encoder *encoder,
                                        void *data);
 void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data);
-void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data);
-void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data);
 void exynos_drm_encoder_crtc_pipe(struct drm_encoder *encoder, void *data);
+void exynos_drm_encoder_plane_mode_set(struct drm_encoder *encoder, void *data);
+void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data);
+void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data);
 
 #endif
index 9ef5b8c..232e323 100644 (file)
@@ -13,8 +13,9 @@
 
 #include "exynos_drm.h"
 #include "exynos_drm_drv.h"
-#include "exynos_drm_crtc.h"
 #include "exynos_drm_encoder.h"
+#include "exynos_drm_fb.h"
+#include "exynos_drm_gem.h"
 
 #define to_exynos_plane(x)     container_of(x, struct exynos_plane, base)
 
@@ -32,6 +33,84 @@ static const uint32_t formats[] = {
        DRM_FORMAT_NV12MT,
 };
 
+int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
+                         struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+                         unsigned int crtc_w, unsigned int crtc_h,
+                         uint32_t src_x, uint32_t src_y,
+                         uint32_t src_w, uint32_t src_h)
+{
+       struct exynos_plane *exynos_plane = to_exynos_plane(plane);
+       struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
+       unsigned int actual_w;
+       unsigned int actual_h;
+       int nr;
+       int i;
+
+       DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+
+       nr = exynos_drm_format_num_buffers(fb->pixel_format);
+       for (i = 0; i < nr; i++) {
+               struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i);
+
+               if (!buffer) {
+                       DRM_LOG_KMS("buffer is null\n");
+                       return -EFAULT;
+               }
+
+               overlay->dma_addr[i] = buffer->dma_addr;
+               overlay->vaddr[i] = buffer->kvaddr;
+
+               DRM_DEBUG_KMS("buffer: %d, vaddr = 0x%lx, dma_addr = 0x%lx\n",
+                               i, (unsigned long)overlay->vaddr[i],
+                               (unsigned long)overlay->dma_addr[i]);
+       }
+
+       actual_w = min((unsigned)(crtc->mode.hdisplay - crtc_x), crtc_w);
+       actual_h = min((unsigned)(crtc->mode.vdisplay - crtc_y), crtc_h);
+
+       /* set drm framebuffer data. */
+       overlay->fb_x = src_x;
+       overlay->fb_y = src_y;
+       overlay->fb_width = fb->width;
+       overlay->fb_height = fb->height;
+       overlay->src_width = src_w;
+       overlay->src_height = src_h;
+       overlay->bpp = fb->bits_per_pixel;
+       overlay->pitch = fb->pitches[0];
+       overlay->pixel_format = fb->pixel_format;
+
+       /* set overlay range to be displayed. */
+       overlay->crtc_x = crtc_x;
+       overlay->crtc_y = crtc_y;
+       overlay->crtc_width = actual_w;
+       overlay->crtc_height = actual_h;
+
+       /* set drm mode data. */
+       overlay->mode_width = crtc->mode.hdisplay;
+       overlay->mode_height = crtc->mode.vdisplay;
+       overlay->refresh = crtc->mode.vrefresh;
+       overlay->scan_flag = crtc->mode.flags;
+
+       DRM_DEBUG_KMS("overlay : offset_x/y(%d,%d), width/height(%d,%d)",
+                       overlay->crtc_x, overlay->crtc_y,
+                       overlay->crtc_width, overlay->crtc_height);
+
+       exynos_drm_fn_encoder(crtc, overlay, exynos_drm_encoder_plane_mode_set);
+
+       return 0;
+}
+
+void exynos_plane_commit(struct drm_plane *plane)
+{
+       struct exynos_plane *exynos_plane = to_exynos_plane(plane);
+       struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
+
+       exynos_drm_fn_encoder(plane->crtc, &overlay->zpos,
+                       exynos_drm_encoder_plane_commit);
+
+       exynos_plane->enabled = true;
+}
+
 static int
 exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
                     struct drm_framebuffer *fb, int crtc_x, int crtc_y,
@@ -39,35 +118,20 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
                     uint32_t src_x, uint32_t src_y,
                     uint32_t src_w, uint32_t src_h)
 {
-       struct exynos_plane *exynos_plane = to_exynos_plane(plane);
-       struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
-       struct exynos_drm_crtc_pos pos;
        int ret;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
-       memset(&pos, 0, sizeof(struct exynos_drm_crtc_pos));
-       pos.crtc_x = crtc_x;
-       pos.crtc_y = crtc_y;
-       pos.crtc_w = crtc_w;
-       pos.crtc_h = crtc_h;
-
-       /* considering 16.16 fixed point of source values */
-       pos.fb_x = src_x >> 16;
-       pos.fb_y = src_y >> 16;
-       pos.src_w = src_w >> 16;
-       pos.src_h = src_h >> 16;
-
-       ret = exynos_drm_overlay_update(overlay, fb, &crtc->mode, &pos);
+       ret = exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y,
+                       crtc_w, crtc_h, src_x >> 16, src_y >> 16,
+                       src_w >> 16, src_h >> 16);
        if (ret < 0)
                return ret;
 
-       exynos_drm_fn_encoder(crtc, overlay,
-                       exynos_drm_encoder_crtc_mode_set);
-       exynos_drm_fn_encoder(crtc, &overlay->zpos,
-                       exynos_drm_encoder_crtc_plane_commit);
+       plane->crtc = crtc;
+       plane->fb = crtc->fb;
 
-       exynos_plane->enabled = true;
+       exynos_plane_commit(plane);
 
        return 0;
 }
@@ -83,7 +147,7 @@ static int exynos_disable_plane(struct drm_plane *plane)
                return 0;
 
        exynos_drm_fn_encoder(plane->crtc, &overlay->zpos,
-                       exynos_drm_encoder_crtc_disable);
+                       exynos_drm_encoder_plane_disable);
 
        exynos_plane->enabled = false;
        exynos_plane->overlay.zpos = DEFAULT_ZPOS;
@@ -175,10 +239,3 @@ out:
        mutex_unlock(&dev->mode_config.mutex);
        return ret;
 }
-
-struct exynos_drm_overlay *get_exynos_drm_overlay(struct drm_plane *plane)
-{
-       struct exynos_plane *exynos_plane = to_exynos_plane(plane);
-
-       return &exynos_plane->overlay;
-}
index d052918..47fd555 100644 (file)
@@ -9,8 +9,13 @@
  *
  */
 
+int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
+                         struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+                         unsigned int crtc_w, unsigned int crtc_h,
+                         uint32_t src_x, uint32_t src_y,
+                         uint32_t src_w, uint32_t src_h);
+void exynos_plane_commit(struct drm_plane *plane);
 struct drm_plane *exynos_plane_init(struct drm_device *dev,
                                    unsigned int possible_crtcs, bool priv);
 int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
-struct exynos_drm_overlay *get_exynos_drm_overlay(struct drm_plane *plane);