From patchwork Tue Oct 18 08:29:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 9381633 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0B278607D0 for ; Tue, 18 Oct 2016 08:40:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ED053293FF for ; Tue, 18 Oct 2016 08:40:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DFAA02941C; Tue, 18 Oct 2016 08:40:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8CE282940E for ; Tue, 18 Oct 2016 08:40:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2512E6E670; Tue, 18 Oct 2016 08:39:59 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail.free-electrons.com (up.free-electrons.com [163.172.77.33]) by gabe.freedesktop.org (Postfix) with ESMTP id A4C946E66C for ; Tue, 18 Oct 2016 08:39:45 +0000 (UTC) Received: by mail.free-electrons.com (Postfix, from userid 110) id C0DC4228F6; Tue, 18 Oct 2016 10:29:42 +0200 (CEST) Received: from localhost (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 97A7B228F0; Tue, 18 Oct 2016 10:29:42 +0200 (CEST) From: Maxime Ripard To: Daniel Vetter , David Airlie Subject: [PATCH 5/5] drm/sun4i: Add support for the overscan profiles Date: Tue, 18 Oct 2016 10:29:38 +0200 Message-Id: X-Mailer: git-send-email 2.9.3 In-Reply-To: References: In-Reply-To: References: Cc: Thomas Petazzoni , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Hans de Goede , Chen-Yu Tsai , Laurent Pinchart , Maxime Ripard , linux-arm-kernel@lists.infradead.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Create overscan profiles reducing the displayed zone. For each TV standard (PAL and NTSC so far), we create 4 more reduced modes by steps of 5% that the user will be able to select. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_tv.c | 60 +++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c index f99886462cb8..9ee03ba086b6 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tv.c +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c @@ -301,27 +301,33 @@ static const struct tv_mode *sun4i_tv_find_tv_by_mode(const struct drm_display_m DRM_DEBUG_DRIVER("Comparing mode %s vs %s", mode->name, tv_mode->name); - if (!strcmp(mode->name, tv_mode->name)) + if (!strncmp(mode->name, tv_mode->name, strlen(tv_mode->name))) return tv_mode; } /* Then by number of lines */ for (i = 0; i < ARRAY_SIZE(tv_modes); i++) { const struct tv_mode *tv_mode = &tv_modes[i]; + int j; - DRM_DEBUG_DRIVER("Comparing mode %s vs %s (X: %d vs %d)", - mode->name, tv_mode->name, - mode->vdisplay, tv_mode->vdisplay); + for (j = 0; j < 20; j += 5) { + u32 vdisplay = tv_mode->vdisplay * (100 - j) / 100; - if (mode->vdisplay == tv_mode->vdisplay) - return tv_mode; + DRM_DEBUG_DRIVER("Comparing mode with %s (%d) (X: %d vs %d)", + tv_mode->name, j, + vdisplay, tv_mode->vdisplay); + + if (vdisplay == tv_mode->vdisplay) + return tv_mode; + } } return NULL; } static void sun4i_tv_mode_to_drm_mode(const struct tv_mode *tv_mode, - struct drm_display_mode *mode) + struct drm_display_mode *mode, + int overscan) { DRM_DEBUG_DRIVER("Creating mode %s\n", mode->name); @@ -329,12 +335,12 @@ static void sun4i_tv_mode_to_drm_mode(const struct tv_mode *tv_mode, mode->clock = 13500; mode->flags = DRM_MODE_FLAG_INTERLACE; - mode->hdisplay = tv_mode->hdisplay; + mode->hdisplay = tv_mode->hdisplay * (100 - overscan) / 100; mode->hsync_start = mode->hdisplay + tv_mode->hfront_porch; mode->hsync_end = mode->hsync_start + tv_mode->hsync_len; mode->htotal = mode->hsync_end + tv_mode->hback_porch; - mode->vdisplay = tv_mode->vdisplay; + mode->vdisplay = tv_mode->vdisplay * (100 - overscan) / 100; mode->vsync_start = mode->vdisplay + tv_mode->vfront_porch; mode->vsync_end = mode->vsync_start + tv_mode->vsync_len; mode->vtotal = mode->vsync_end + tv_mode->vback_porch; @@ -352,10 +358,10 @@ static int sun4i_tv_atomic_check(struct drm_encoder *encoder, return -EINVAL; state->display_x_size = tv_mode->hdisplay; - state->plane_x_offset = 0; + state->plane_x_offset = (tv_mode->hdisplay - mode->hdisplay) / 2; state->display_y_size = tv_mode->vdisplay; - state->plane_y_offset = 0; + state->plane_y_offset = (tv_mode->vdisplay - mode->vdisplay) / 2; return 0; } @@ -404,7 +410,7 @@ static void sun4i_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode tv_drm_mode = { 0 }; strcpy(tv_drm_mode.name, "TV"); - sun4i_tv_mode_to_drm_mode(tv_mode, &tv_drm_mode); + sun4i_tv_mode_to_drm_mode(tv_mode, &tv_drm_mode, 0); drm_mode_set_crtcinfo(&tv_drm_mode, CRTC_INTERLACE_HALVE_V); sun4i_tcon1_mode_set(tcon, &tv_drm_mode); @@ -526,22 +532,28 @@ static int sun4i_tv_comp_get_modes(struct drm_connector *connector) int i; for (i = 0; i < ARRAY_SIZE(tv_modes); i++) { - struct drm_display_mode *mode; const struct tv_mode *tv_mode = &tv_modes[i]; - - mode = drm_mode_create(connector->dev); - if (!mode) { - DRM_ERROR("Failed to create a new display mode\n"); - return 0; + int j; + + for (j = 0; j < 20; j += 5) { + struct drm_display_mode *mode = drm_mode_create(connector->dev); + if (!mode) { + DRM_ERROR("Failed to create a new display mode\n"); + return 0; + } + + if (j) + sprintf(mode->name, "%s%d", tv_mode->name, + j); + else + strcpy(mode->name, tv_mode->name); + + sun4i_tv_mode_to_drm_mode(tv_mode, mode, j); + drm_mode_probed_add(connector, mode); } - - strcpy(mode->name, tv_mode->name); - - sun4i_tv_mode_to_drm_mode(tv_mode, mode); - drm_mode_probed_add(connector, mode); } - return i; + return i * 4; } static int sun4i_tv_comp_mode_valid(struct drm_connector *connector,