From: Paulo Zanoni <przanoni@gmail.com>
To: intel-gfx@lists.freedesktop.org
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Subject: [PATCH 2/2] drm/i915: Set the digital port encoder personality during modeset
Date: Tue, 3 Dec 2013 15:36:20 -0200 [thread overview]
Message-ID: <1386092180-12998-1-git-send-email-przanoni@gmail.com> (raw)
In-Reply-To: <CA+gsUGRZgg-Y5-tj5xhWVHW0=WFdvkVBxGaKZFLApssW=a-cwg@mail.gmail.com>
From: Damien Lespiau <damien.lespiau@intel.com>
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
Testcase: igt/kms_setmode/clone-exclusive-crtc
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68463
Tested-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_ddi.c | 96 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 93 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index c8382f5..879fbe8 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1442,18 +1442,108 @@ 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 (connectors > 1) {
+ DRM_DEBUG_KMS("Can't set modes for 2 connectors on the same DDI encoder\n");
+ 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);
--
1.8.3.1
next prev parent reply other threads:[~2013-12-03 17:36 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-29 20:31 Modeset without a detected monitor on DDI platforms v2.5 Damien Lespiau
2013-11-29 20:31 ` [PATCH 1/2] drm/i915: Introduce new intel_output_name() Damien Lespiau
2013-12-03 17:30 ` Paulo Zanoni
2013-11-29 20:31 ` [PATCH 2/2] drm/i915: Set the digital port encoder personality during modeset Damien Lespiau
2013-12-03 17:33 ` Paulo Zanoni
2013-12-03 17:36 ` Paulo Zanoni [this message]
2013-12-03 21:05 ` Daniel Vetter
2013-12-05 12:38 ` Paulo Zanoni
2013-12-05 12:48 ` Daniel Vetter
2014-01-07 16:54 ` Paulo Zanoni
2013-12-03 17:38 ` [PATCH IGT] tests/kms_setmode: avoid 2 connectors on the same encoder Paulo Zanoni
2013-12-09 20:52 ` Imre Deak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1386092180-12998-1-git-send-email-przanoni@gmail.com \
--to=przanoni@gmail.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=paulo.r.zanoni@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox