aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorJoonyoung Shim <jy0922.shim@samsung.com>2012-09-27 06:25:21 -0400
committerInki Dae <inki.dae@samsung.com>2012-10-03 21:10:53 -0400
commit2ab97921786f614bc9296722d8a2e2ce32d1760b (patch)
treea2c864f34e4ea7c081d2b707ad00d56929cddf16 /drivers/gpu
parent58f6aad7d93f7ce009d371aa5065b70d593d3b17 (diff)
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[] = {
32 DRM_FORMAT_NV12MT, 32 DRM_FORMAT_NV12MT,
33}; 33};
34 34
35/*
36 * This function is to get X or Y size shown via screen. This needs length and
37 * start position of CRTC.
38 *
39 * <--- length --->
40 * CRTC ----------------
41 * ^ start ^ end
42 *
43 * There are six cases from a to b.
44 *
45 * <----- SCREEN ----->
46 * 0 last
47 * ----------|------------------|----------
48 * CRTCs
49 * a -------
50 * b -------
51 * c --------------------------
52 * d --------
53 * e -------
54 * f -------
55 */
56static int exynos_plane_get_size(int start, unsigned length, unsigned last)
57{
58 int end = start + length;
59 int size = 0;
60
61 if (start <= 0) {
62 if (end > 0)
63 size = min_t(unsigned, end, last);
64 } else if (start <= last) {
65 size = min_t(unsigned, last - start, length);
66 }
67
68 return size;
69}
70
35int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, 71int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
36 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 72 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
37 unsigned int crtc_w, unsigned int crtc_h, 73 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,
64 (unsigned long)overlay->dma_addr[i]); 100 (unsigned long)overlay->dma_addr[i]);
65 } 101 }
66 102
67 actual_w = min((unsigned)(crtc->mode.hdisplay - crtc_x), crtc_w); 103 actual_w = exynos_plane_get_size(crtc_x, crtc_w, crtc->mode.hdisplay);
68 actual_h = min((unsigned)(crtc->mode.vdisplay - crtc_y), crtc_h); 104 actual_h = exynos_plane_get_size(crtc_y, crtc_h, crtc->mode.vdisplay);
105
106 if (crtc_x < 0) {
107 if (actual_w)
108 src_x -= crtc_x;
109 else
110 src_x += crtc_w;
111 crtc_x = 0;
112 }
113
114 if (crtc_y < 0) {
115 if (actual_h)
116 src_y -= crtc_y;
117 else
118 src_y += crtc_h;
119 crtc_y = 0;
120 }
69 121
70 /* set drm framebuffer data. */ 122 /* set drm framebuffer data. */
71 overlay->fb_x = src_x; 123 overlay->fb_x = src_x;