diff options
author | Joonyoung Shim <jy0922.shim@samsung.com> | 2012-09-27 06:25:21 -0400 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2012-10-03 21:10:53 -0400 |
commit | 2ab97921786f614bc9296722d8a2e2ce32d1760b (patch) | |
tree | a2c864f34e4ea7c081d2b707ad00d56929cddf16 /drivers/gpu | |
parent | 58f6aad7d93f7ce009d371aa5065b70d593d3b17 (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.c | 56 |
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 | */ | ||
56 | static 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 | |||
35 | int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, | 71 | int 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; |