Skip to content

Commit

Permalink
drm/exynos: fix to calculate CRTC shown via screen
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Joonyoung Shim authored and Inki Dae committed Oct 4, 2012
1 parent 58f6aad commit 2ab9792
Showing 1 changed file with 54 additions and 2 deletions.
56 changes: 54 additions & 2 deletions drivers/gpu/drm/exynos/exynos_drm_plane.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 2ab9792

Please sign in to comment.