From patchwork Wed Apr 26 10:48:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jose Abreu X-Patchwork-Id: 9702233 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 A7DB4603F8 for ; Thu, 27 Apr 2017 00:08:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 98C9720373 for ; Thu, 27 Apr 2017 00:08:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8C18B285EA; Thu, 27 Apr 2017 00:08:02 +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 0754920373 for ; Thu, 27 Apr 2017 00:08:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 51D636E64E; Thu, 27 Apr 2017 00:07:21 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtprelay.synopsys.com (smtprelay4.synopsys.com [198.182.47.9]) by gabe.freedesktop.org (Postfix) with ESMTPS id A5916897C5 for ; Wed, 26 Apr 2017 10:49:30 +0000 (UTC) Received: from mailhost.synopsys.com (mailhost1.synopsys.com [10.12.238.239]) by smtprelay.synopsys.com (Postfix) with ESMTP id 6DAD724E1220; Wed, 26 Apr 2017 03:49:30 -0700 (PDT) Received: from mailhost.synopsys.com (localhost [127.0.0.1]) by mailhost.synopsys.com (Postfix) with ESMTP id 4DA61102; Wed, 26 Apr 2017 03:49:30 -0700 (PDT) Received: from joabreu-VirtualBox.internal.synopsys.com (joabreu-e7440.internal.synopsys.com [10.107.19.44]) by mailhost.synopsys.com (Postfix) with ESMTP id 709BFE9; Wed, 26 Apr 2017 03:49:28 -0700 (PDT) From: Jose Abreu To: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] drm: Introduce crtc->mode_valid() callback Date: Wed, 26 Apr 2017 11:48:34 +0100 Message-Id: <3e1dba0cd5fc053e56f1c9c94d0cb8789ecca4ae.1493203049.git.joabreu@synopsys.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: References: In-Reply-To: References: MIME-Version: 1.0 X-Mailman-Approved-At: Thu, 27 Apr 2017 00:07:00 +0000 Cc: Jose Abreu , Daniel Vetter , Alexey Brodkin , Carlos Palminha 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: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Some crtc's may have restrictions in the mode they can display. In this patch a new callback (crtc->mode_valid()) is introduced that is called at the same stage of connector->mode_valid() callback. This shall be implemented if the crtc has some sort of restriction so that we don't probe modes that will fail in the commit() stage. For example: A given crtc may be responsible to set a clock value. If the clock can not produce all the values for the available modes then this callback can be used to restrict the number of probbed modes to only the ones that can be displayed. If the crtc does not implement the callback then the behaviour will remain the same. Also, for a given set of crtcs that can be bound to the connector, if at least one can display the mode then the mode will be probbed. Signed-off-by: Jose Abreu Cc: Carlos Palminha Cc: Alexey Brodkin Cc: Ville Syrjälä Cc: Daniel Vetter Cc: Dave Airlie --- drivers/gpu/drm/drm_probe_helper.c | 44 ++++++++++++++++++++++++++++++++ include/drm/drm_modeset_helper_vtables.h | 26 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 1b0c14a..61eac30 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -80,6 +80,46 @@ return MODE_OK; } +static enum drm_mode_status drm_mode_validate_connector_crtc( + struct drm_connector *connector, + struct drm_display_mode *mode) +{ + const struct drm_crtc_helper_funcs *crtc_funcs = NULL; + enum drm_mode_status mode_status = MODE_ERROR; + struct drm_device *dev = connector->dev; + struct drm_encoder *encoder; + struct drm_crtc *crtc; + bool callback_found = false; + int i; + + for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { + encoder = drm_encoder_find(dev, connector->encoder_ids[i]); + + if (!encoder) + continue; + + drm_for_each_crtc(crtc, dev) { + crtc_funcs = crtc->helper_private; + + if (!drm_encoder_crtc_ok(encoder, crtc)) + continue; + if (!crtc_funcs || !crtc_funcs->mode_valid) + continue; + + /* MODE_OK=0 and default mode_status=MODE_ERROR=-1 + * so if at least one crtc accepts the mode we get + * MODE_OK */ + mode_status &= crtc_funcs->mode_valid(crtc, mode); + callback_found |= true; + } + } + + /* We can reach here without calling mode_valid if there is no + * registered crtc with this callback, lets return MODE_OK in this + * case */ + return callback_found ? mode_status : MODE_OK; +} + static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector) { struct drm_cmdline_mode *cmdline_mode; @@ -431,6 +471,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, if (mode->status == MODE_OK && connector_funcs->mode_valid) mode->status = connector_funcs->mode_valid(connector, mode); + + if (mode->status == MODE_OK) + mode->status = drm_mode_validate_connector_crtc( + connector, mode); } prune: diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index c01c328..59fffba 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -106,6 +106,32 @@ struct drm_crtc_helper_funcs { void (*commit)(struct drm_crtc *crtc); /** + * @mode_valid: + * + * This callback should be implemented if the crtc has some sort of + * restriction in the modes it can display. For example, a given crtc + * may be responsible to set a clock value. If the clock can not + * produce all the values for the available modes then this callback + * can be used to restrict the number of probbed modes to only the ones + * that can be displayed. + * + * This is directly called at the same stage of connector->mode_valid + * callback. + * + * NOTE: + * + * For a given set of crtc's in a drm_device, if at least one does not + * have the mode_valid callback, or, at least one returns MODE_OK then + * the mode will be probbed. + * + * RETURNS: + * + * drm_mode_status Enum + */ + enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc, + struct drm_display_mode *mode); + + /** * @mode_fixup: * * This callback is used to validate a mode. The parameter mode is the