[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-id: <1484895145-511-6-git-send-email-a.hajda@samsung.com>
Date: Fri, 20 Jan 2017 07:52:23 +0100
From: Andrzej Hajda <a.hajda@...sung.com>
To: Inki Dae <inki.dae@...sung.com>, dri-devel@...ts.freedesktop.org,
Krzysztof Kozlowski <krzk@...nel.org>
Cc: Andrzej Hajda <a.hajda@...sung.com>,
Bartlomiej Zolnierkiewicz <b.zolnierkie@...sung.com>,
Marek Szyprowski <m.szyprowski@...sung.com>,
Kyungmin Park <kyungmin.park@...sung.com>,
linux-kernel@...r.kernel.org, linux-samsung-soc@...r.kernel.org
Subject: [PATCH 5/7] drm/exynos/decon5433: add support for interlace modes
Some registers should be programmed differently in interlace mode.
Additionally IP does not signal stop state properly in interlaced
mode, so warning has been removed.
Signed-off-by: Andrzej Hajda <a.hajda@...sung.com>
---
drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 45 +++++++++++++++++++--------
include/video/exynos5433_decon.h | 1 +
2 files changed, 33 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 042d6ef..46434ba9 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -146,6 +146,7 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
{
struct decon_context *ctx = crtc->ctx;
struct drm_display_mode *m = &crtc->base.mode;
+ bool interlaced = false;
u32 val;
if (test_bit(BIT_SUSPENDED, &ctx->flags))
@@ -156,12 +157,16 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
m->crtc_hsync_end = m->crtc_htotal - 92;
m->crtc_vsync_start = m->crtc_vdisplay + 1;
m->crtc_vsync_end = m->crtc_vsync_start + 1;
+ if (m->flags & DRM_MODE_FLAG_INTERLACE)
+ interlaced = true;
}
decon_setup_trigger(ctx);
/* lcd on and use command if */
val = VIDOUT_LCD_ON;
+ if (interlaced)
+ val |= VIDOUT_INTERLACE_EN_F;
if (ctx->out_type & IFTYPE_I80) {
val |= VIDOUT_COMMAND_IF;
} else {
@@ -170,15 +175,21 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
writel(val, ctx->addr + DECON_VIDOUTCON0);
- val = VIDTCON2_LINEVAL(m->vdisplay - 1) |
- VIDTCON2_HOZVAL(m->hdisplay - 1);
+ if (interlaced)
+ val = VIDTCON2_LINEVAL(m->vdisplay / 2 - 1) |
+ VIDTCON2_HOZVAL(m->hdisplay - 1);
+ else
+ val = VIDTCON2_LINEVAL(m->vdisplay - 1) |
+ VIDTCON2_HOZVAL(m->hdisplay - 1);
writel(val, ctx->addr + DECON_VIDTCON2);
if (!(ctx->out_type & IFTYPE_I80)) {
- val = VIDTCON00_VBPD_F(
- m->crtc_vtotal - m->crtc_vsync_end - 1) |
- VIDTCON00_VFPD_F(
- m->crtc_vsync_start - m->crtc_vdisplay - 1);
+ int vbp = m->crtc_vtotal - m->crtc_vsync_end;
+ int vfp = m->crtc_vsync_start - m->crtc_vdisplay;
+
+ if (interlaced)
+ vbp = vbp / 2 - 1;
+ val = VIDTCON00_VBPD_F(vbp - 1) | VIDTCON00_VFPD_F(vfp - 1);
writel(val, ctx->addr + DECON_VIDTCON00);
val = VIDTCON01_VSPW_F(
@@ -293,12 +304,22 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
if (test_bit(BIT_SUSPENDED, &ctx->flags))
return;
- val = COORDINATE_X(state->crtc.x) | COORDINATE_Y(state->crtc.y);
- writel(val, ctx->addr + DECON_VIDOSDxA(win));
+ if (crtc->base.mode.flags & DRM_MODE_FLAG_INTERLACE) {
+ val = COORDINATE_X(state->crtc.x) |
+ COORDINATE_Y(state->crtc.y / 2);
+ writel(val, ctx->addr + DECON_VIDOSDxA(win));
+
+ val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) |
+ COORDINATE_Y((state->crtc.y + state->crtc.h) / 2 - 1);
+ writel(val, ctx->addr + DECON_VIDOSDxB(win));
+ } else {
+ val = COORDINATE_X(state->crtc.x) | COORDINATE_Y(state->crtc.y);
+ writel(val, ctx->addr + DECON_VIDOSDxA(win));
- val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) |
- COORDINATE_Y(state->crtc.y + state->crtc.h - 1);
- writel(val, ctx->addr + DECON_VIDOSDxB(win));
+ val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) |
+ COORDINATE_Y(state->crtc.y + state->crtc.h - 1);
+ writel(val, ctx->addr + DECON_VIDOSDxB(win));
+ }
val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
VIDOSD_Wx_ALPHA_B_F(0x0);
@@ -370,8 +391,6 @@ static void decon_swreset(struct decon_context *ctx)
udelay(10);
}
- WARN(tries == 0, "failed to disable DECON\n");
-
writel(VIDCON0_SWRESET, ctx->addr + DECON_VIDCON0);
for (tries = 2000; tries; --tries) {
if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_SWRESET)
diff --git a/include/video/exynos5433_decon.h b/include/video/exynos5433_decon.h
index 0098a52..b26511a 100644
--- a/include/video/exynos5433_decon.h
+++ b/include/video/exynos5433_decon.h
@@ -89,6 +89,7 @@
#define VIDCON0_ENVID_F (1 << 0)
/* VIDOUTCON0 */
+#define VIDOUT_INTERLACE_EN_F (1 << 28)
#define VIDOUT_LCD_ON (1 << 24)
#define VIDOUT_IF_F_MASK (0x3 << 20)
#define VIDOUT_RGB_IF (0x0 << 20)
--
2.7.4
Powered by blists - more mailing lists