From patchwork Tue Jan 7 16:55:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paulo Zanoni X-Patchwork-Id: 3449271 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B36E19F2E9 for ; Tue, 7 Jan 2014 16:56:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6E5652010E for ; Tue, 7 Jan 2014 16:56:43 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 4A5602010C for ; Tue, 7 Jan 2014 16:56:42 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 33CA5FADDD for ; Tue, 7 Jan 2014 08:56:42 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-qe0-f43.google.com (mail-qe0-f43.google.com [209.85.128.43]) by gabe.freedesktop.org (Postfix) with ESMTP id CE07BFAD9E for ; Tue, 7 Jan 2014 08:56:22 -0800 (PST) Received: by mail-qe0-f43.google.com with SMTP id jy17so624164qeb.30 for ; Tue, 07 Jan 2014 08:56:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=RZvV08PCfF85B2yDStVAwqF6CXik61vL4gSFg91200c=; b=Us+G3oF2iOmMUHnZJVvQmKnBnZkbCyWS1No2/LdSQgMhHjjTzLMh3oskX35gyOPTM/ IskXjOqeFd+ExHKESCSfjLcDekYSKwb//iiGvDUCw749QrDZBqHYEBP9uzhcMpZ1LHyW sesUhroa1kmAK9em70cog1egtbNenUJOgJTzZalFYwSLzzxaIElm3z5TDXj8gFSdIMwH tpFJ7aL90TQ0HWEbofnFg9k8sWHk2JZXyH9M17JKWV1KyjiJgk3Fa2mM3WhoN66KTWfa WwHrOvA1HtNsf01rUPWS0oJ7vxoLW+ggvZKEXorukvgy9y1fAykhwMyr8h3uxsrH96QJ 4wvw== X-Received: by 10.49.59.83 with SMTP id x19mr3505610qeq.47.1389113782430; Tue, 07 Jan 2014 08:56:22 -0800 (PST) Received: from localhost.localdomain ([177.42.20.97]) by mx.google.com with ESMTPSA id f5sm41755949qas.11.2014.01.07.08.56.20 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 07 Jan 2014 08:56:21 -0800 (PST) From: Paulo Zanoni To: intel-gfx@lists.freedesktop.org Date: Tue, 7 Jan 2014 14:55:55 -0200 Message-Id: <1389113755-2021-3-git-send-email-przanoni@gmail.com> X-Mailer: git-send-email 1.8.4.2 In-Reply-To: <1389113755-2021-1-git-send-email-przanoni@gmail.com> References: <1389113755-2021-1-git-send-email-przanoni@gmail.com> Cc: Paulo Zanoni Subject: [Intel-gfx] [PATCH 3/3] drm/i915: Set the digital port encoder personality during modeset X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Damien Lespiau The ->detect() vfunc of connectors is usually responsible for setting the encoder type on intel_digital_ports when a hotplug event happens. However we sometimes want to force a modeset on a specific connector: - the user can ask the SETCRTC ioctl to use a connector that isn't marked as connected (because we never received a hotplug event for it). This can be also used in tests to do a modeset without the need of a plugged-in monitor. - the command line video= option can be used to force modesets, eg.: video=HDMI-A-1:1024x768e So, before we try to do anything with the DDI encoder as part of a modeset, we need to ensure that the personality of the encoder matches the selected connector. v2: Made by Paulo: - Return false if we have more than one connector - WARN in case it's not eDP/DP/HDMI - Don't break error strings in pieces - Change the "status == connected" message from DRM_ERROR to DRM_DEBUG_KMS - Don't store+use the old encoder->type at compute_config - Add bugzilla reference - Add testcase reference v3: Made by Paulo: - WARN in case "connectors > 1", since we have a patch that should catch this case earlier Testcase: igt/kms_setmode/clone-exclusive-crtc Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68463 Tested-by: Paulo Zanoni Signed-off-by: Damien Lespiau Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_ddi.c | 94 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 1488b28..4ec1665 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1512,18 +1512,106 @@ static void intel_ddi_destroy(struct drm_encoder *encoder) intel_dp_encoder_destroy(encoder); } +/* + * The ->detect() vfunc of connectors is usually responsible for setting the + * encoder type on intel_digital_ports when a hotplug event happens. + * + * However we sometimes want to force a modeset on a specific connector: + * - the user can ask the SETCRTC ioctl to use a connector that isn't marked + * as connected (because we never received a hotplug event for it). + * This can be also used in tests to do a modeset without the need of a + * plugged-in monitor. + * - the command line video= option can be used to force modesets, eg.: + * video=HDMI-A-1:1024x768e + * + * So, before we try to do anything with the DDI encoder as part of a modeset, + * we need to ensure that the personality of the encoder matches the selected + * connector. + */ +static bool +intel_ddi_ensure_encoder_type(struct intel_encoder *encoder) +{ + struct drm_device *dev = encoder->base.dev; + struct intel_connector *connector; + int connectors = 0; + + list_for_each_entry(connector, &dev->mode_config.connector_list, + base.head) { + int connector_type, old_encoder_type, new_encoder_type; + int port; + + if (connector->new_encoder != encoder) + continue; + + connectors++; + if (WARN_ON(connectors > 1)) + return false; + + connector_type = connector->base.connector_type; + old_encoder_type = encoder->type; + switch (connector_type) { + case DRM_MODE_CONNECTOR_HDMIA: + case DRM_MODE_CONNECTOR_HDMIB: + new_encoder_type = INTEL_OUTPUT_HDMI; + break; + case DRM_MODE_CONNECTOR_DisplayPort: + new_encoder_type = INTEL_OUTPUT_DISPLAYPORT; + break; + case DRM_MODE_CONNECTOR_eDP: + continue; + default: + WARN(1, "DRM connector type %d\n", connector_type); + continue; + } + + if (old_encoder_type == new_encoder_type) + continue; + + port = intel_ddi_get_encoder_port(encoder); + + if (old_encoder_type == INTEL_OUTPUT_EDP) { + DRM_ERROR("Can't change DDI %c personality to %s, it's an eDP DDI\n", + port_name(port), + intel_output_name(new_encoder_type)); + return false; + } + + if (connector->base.status == connector_status_connected) { + DRM_DEBUG_KMS("Can't change DDI %c personality to %s, it has a connected %s device\n", + port_name(port), + intel_output_name(new_encoder_type), + intel_output_name(old_encoder_type)); + return false; + } + + DRM_DEBUG_KMS("Changing DDI %c from %s to %s\n", + port_name(port), + intel_output_name(old_encoder_type), + intel_output_name(new_encoder_type)); + + encoder->type = new_encoder_type; + } + + return true; +} + static bool intel_ddi_compute_config(struct intel_encoder *encoder, struct intel_crtc_config *pipe_config) { - int type = encoder->type; int port = intel_ddi_get_encoder_port(encoder); + int ret; + + ret = intel_ddi_ensure_encoder_type(encoder); + if (!ret) + return false; - WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); + WARN(encoder->type == INTEL_OUTPUT_UNKNOWN, + "compute_config() on unknown output!\n"); if (port == PORT_A) pipe_config->cpu_transcoder = TRANSCODER_EDP; - if (type == INTEL_OUTPUT_HDMI) + if (encoder->type == INTEL_OUTPUT_HDMI) return intel_hdmi_compute_config(encoder, pipe_config); else return intel_dp_compute_config(encoder, pipe_config);