From 3799e9494117caf1e37f6ffad7433ee24360e50b Mon Sep 17 00:00:00 2001 From: John Sheu Date: Tue, 3 Jul 2012 23:55:24 -0700 Subject: [PATCH] drm/exynos: Allow overlays with sub-sized contents Overlays presently assume that the entire framebuffer is to be displayed; the src_w and src_h arguments to exynos_update_plane are ignored. Fix this. BUG=chrome-os-partner:9395 TEST=local build, run on ARM Change-Id: If9ecd7928bd9cbce1f73c7a9ac4ff825dfe690fd Signed-off-by: John Sheu Reviewed-on: https://gerrit.chromium.org/gerrit/26770 Reviewed-by: Akshu Agrawal Reviewed-by: Abhinav Kochhar --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 8 +++++--- drivers/gpu/drm/exynos/exynos_drm_crtc.h | 6 ++++++ drivers/gpu/drm/exynos/exynos_drm_drv.h | 3 ++- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 15 +++++++++------ drivers/gpu/drm/exynos/exynos_drm_plane.c | 4 ++++ 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index f0724756c9cf..86cba191f07a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -104,10 +104,10 @@ int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay, /* set drm framebuffer data. */ overlay->fb_x = pos->fb_x; overlay->fb_y = pos->fb_y; - overlay->fb_width = fb->width; - overlay->fb_height = fb->height; + overlay->fb_width = min(pos->fb_w, actual_w); + overlay->fb_height = min(pos->fb_h, actual_h); + overlay->fb_pitch = fb->pitches[0]; overlay->bpp = fb->bits_per_pixel; - overlay->pitch = fb->pitches[0]; overlay->pixel_format = fb->pixel_format; /* set overlay range to be displayed. */ @@ -148,6 +148,8 @@ static int exynos_drm_crtc_update(struct drm_crtc *crtc) /* it means the offset of framebuffer to be displayed. */ pos.fb_x = crtc->x; pos.fb_y = crtc->y; + pos.fb_w = fb->width; + pos.fb_h = fb->height; /* OSD position to be displayed. */ pos.crtc_x = 0; diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h index 25f72a62cb88..441e1921f437 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h @@ -42,6 +42,10 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc); * - the unit is screen coordinates. * @fb_y: offset y on a framebuffer to be displayed * - the unit is screen coordinates. + * @fb_w: width of a framebuffer to be displayed + * - the unit is screen coordinates. + * @fb_h: height of a framebuffer to be displayed + * - the unit is screen coordinates. * @crtc_x: offset x on hardware screen. * @crtc_y: offset y on hardware screen. * @crtc_w: width of hardware screen. @@ -50,6 +54,8 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc); struct exynos_drm_crtc_pos { unsigned int fb_x; unsigned int fb_y; + unsigned int fb_w; + unsigned int fb_h; unsigned int crtc_x; unsigned int crtc_y; unsigned int crtc_w; diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 28c9b689a655..9f2be046c20c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -81,6 +81,7 @@ struct exynos_drm_overlay_ops { * - the unit is screen coordinates. * @fb_width: width of a framebuffer. * @fb_height: height of a framebuffer. + * @fb_pitch: pitch of a framebuffer. * @crtc_x: offset x on hardware screen. * @crtc_y: offset y on hardware screen. * @crtc_width: window width to be displayed (hardware screen). @@ -112,6 +113,7 @@ struct exynos_drm_overlay { unsigned int fb_y; unsigned int fb_width; unsigned int fb_height; + unsigned int fb_pitch; unsigned int crtc_x; unsigned int crtc_y; unsigned int crtc_width; @@ -121,7 +123,6 @@ struct exynos_drm_overlay { unsigned int refresh; unsigned int scan_flag; unsigned int bpp; - unsigned int pitch; uint32_t pixel_format; dma_addr_t dma_addr[MAX_FB_BUFFER]; void __iomem *vaddr[MAX_FB_BUFFER]; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 863f02ec6ac5..b4b2d07cf5a4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -64,6 +64,7 @@ struct fimd_win_data { unsigned int ovl_height; unsigned int fb_width; unsigned int fb_height; + unsigned int fb_pitch; unsigned int bpp; dma_addr_t dma_addr; void __iomem *vaddr; @@ -317,9 +318,10 @@ static void fimd_win_mode_set(struct device *dev, return; offset = overlay->fb_x * (overlay->bpp >> 3); - offset += overlay->fb_y * overlay->pitch; + offset += overlay->fb_y * overlay->fb_pitch; - DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch); + DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", + offset, overlay->fb_pitch); win_data = &ctx->win_data[win]; @@ -329,12 +331,13 @@ static void fimd_win_mode_set(struct device *dev, win_data->ovl_height = overlay->crtc_height; win_data->fb_width = overlay->fb_width; win_data->fb_height = overlay->fb_height; + win_data->fb_pitch = overlay->fb_pitch; win_data->dma_addr = overlay->dma_addr[0] + offset; win_data->vaddr = overlay->vaddr[0] + offset; win_data->bpp = overlay->bpp; - win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) * - (overlay->bpp >> 3); - win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3); + win_data->buf_offsize = overlay->fb_pitch - + (overlay->fb_width * (overlay->bpp >> 3)); + win_data->line_size = overlay->fb_width * (overlay->bpp >> 3); DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n", win_data->offset_x, win_data->offset_y); @@ -464,7 +467,7 @@ static void fimd_win_commit(struct device *dev, int zpos) writel(val, ctx->regs + VIDWx_BUF_START(win, 0)); /* buffer end address */ - size = win_data->fb_width * win_data->ovl_height * (win_data->bpp >> 3); + size = win_data->fb_height * win_data->fb_pitch; val = (unsigned long)(win_data->dma_addr + size); writel(val, ctx->regs + VIDWx_BUF_END(win, 0)); diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index f92fe4c6174a..79813485e200 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -43,6 +43,8 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, struct exynos_drm_crtc_pos pos; unsigned int x = src_x >> 16; unsigned int y = src_y >> 16; + unsigned int w = src_w >> 16; + unsigned int h = src_h >> 16; int ret; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); @@ -55,6 +57,8 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, pos.fb_x = x; pos.fb_y = y; + pos.fb_w = w; + pos.fb_h = h; /* TODO: scale feature */ ret = exynos_drm_overlay_update(overlay, fb, &crtc->mode, &pos); -- 2.20.1