From 20f054e94e21baab2d1d66a15d250386d1fa6f84 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Thu, 27 Sep 2012 19:25:21 +0900 Subject: [PATCH] --- yaml --- r: 331774 b: refs/heads/master c: 2ab97921786f614bc9296722d8a2e2ce32d1760b h: refs/heads/master v: v3 --- [refs] | 2 +- .../drivers/gpu/drm/exynos/exynos_drm_plane.c | 56 ++++++++++++++++++- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 1cf0a591b955..df4e38be6e48 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 58f6aad7d93f7ce009d371aa5065b70d593d3b17 +refs/heads/master: 2ab97921786f614bc9296722d8a2e2ce32d1760b diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c index 8c3036dd512b..2a27b5678893 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/trunk/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;