aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorJoonyoung Shim <jy0922.shim@samsung.com>2012-09-27 19:25:21 +0900
committerInki Dae <inki.dae@samsung.com>2012-10-04 10:10:53 +0900
commit2ab97921786f614bc9296722d8a2e2ce32d1760b (patch)
treea2c864f34e4ea7c081d2b707ad00d56929cddf16 /drivers/gpu
parentdrm/exynos: fix display power call issue. (diff)
downloadlinux-dev-2ab97921786f614bc9296722d8a2e2ce32d1760b.tar.xz
linux-dev-2ab97921786f614bc9296722d8a2e2ce32d1760b.zip
drm/exynos: fix to calculate CRTC shown via screen
This patch is to exactly calculate CRTC shown via screen for all cases. Refer exynos_plane_get_size() function for this. Also source position of fb is fixed when start position of CRTC is negative number. 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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 8c3036dd512b..2a27b5678893 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -32,6 +32,42 @@ static const uint32_t formats[] = {
DRM_FORMAT_NV12MT,
};
+/*
+ * This function is to get X or Y size shown via screen. This needs length and
+ * start position of CRTC.
+ *
+ * <--- length --->
+ * CRTC ----------------
+ * ^ start ^ end
+ *
+ * There are six cases from a to b.
+ *
+ * <----- SCREEN ----->
+ * 0 last
+ * ----------|------------------|----------
+ * CRTCs
+ * a -------
+ * b -------
+ * c --------------------------
+ * d --------
+ * e -------
+ * f -------
+ */
+static int exynos_plane_get_size(int start, unsigned length, unsigned last)
+{
+ int end = start + length;
+ int size = 0;
+
+ if (start <= 0) {
+ if (end > 0)
+ size = min_t(unsigned, end, last);
+ } else if (start <= last) {
+ size = min_t(unsigned, last - start, length);
+ }
+
+ return size;
+}
+
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,
@@ -64,8 +100,24 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
(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);
+ actual_w = exynos_plane_get_size(crtc_x, crtc_w, crtc->mode.hdisplay);
+ actual_h = exynos_plane_get_size(crtc_y, crtc_h, crtc->mode.vdisplay);
+
+ if (crtc_x < 0) {
+ if (actual_w)
+ src_x -= crtc_x;
+ else
+ src_x += crtc_w;
+ crtc_x = 0;
+ }
+
+ if (crtc_y < 0) {
+ if (actual_h)
+ src_y -= crtc_y;
+ else
+ src_y += crtc_h;
+ crtc_y = 0;
+ }
/* set drm framebuffer data. */
overlay->fb_x = src_x;