public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
* Modeset without a detected monitor on DDI platforms
@ 2013-11-29 18:45 Damien Lespiau
  2013-11-29 18:45 ` [PATCH] drm/i915: Set the digital port encoder personality during modeset Damien Lespiau
  2013-11-29 19:36 ` [PATCH] drm/i915: don't set modes for 2 connectors on the same encoder Paulo Zanoni
  0 siblings, 2 replies; 3+ messages in thread
From: Damien Lespiau @ 2013-11-29 18:45 UTC (permalink / raw)
  To: intel-gfx

Here's a tentative patch that I unfortunately can't test on HSW because my dev
machine seems quite unhappy. The patch had limited testing on simulation
though.

The general problem is that intel_digital_port encoders personalities (ie
intel_encoder->type) are only set by ->detect() at the moment. It'd be nice to
be able to set it at modeset time so any path that forces a modeset with a
specific connector end up with a correct encoder type.

-- 
Damien

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH] drm/i915: Set the digital port encoder personality during modeset
  2013-11-29 18:45 Modeset without a detected monitor on DDI platforms Damien Lespiau
@ 2013-11-29 18:45 ` Damien Lespiau
  2013-11-29 19:36 ` [PATCH] drm/i915: don't set modes for 2 connectors on the same encoder Paulo Zanoni
  1 sibling, 0 replies; 3+ messages in thread
From: Damien Lespiau @ 2013-11-29 18:45 UTC (permalink / raw)
  To: intel-gfx

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 wasne
    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.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c     | 50 ++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_display.c |  2 ++
 drivers/gpu/drm/i915/intel_drv.h     |  1 +
 3 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index c8382f5..fe04a09 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -701,6 +701,56 @@ intel_ddi_calculate_wrpll(int clock /* in Hz */,
 		      clock, *p_out, *n2_out, *r2_out);
 }
 
+/*
+ * 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.
+ */
+void
+intel_ddi_ensure_encoder_type(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct intel_connector *connector;
+
+	if (!HAS_DDI(dev))
+		return;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list,
+			    base.head) {
+		int connector_type = connector->base.connector_type;
+
+		if (!connector->new_encoder)
+			continue;
+
+		if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+		    connector_type == DRM_MODE_CONNECTOR_HDMIB) {
+			connector->new_encoder->type = INTEL_OUTPUT_HDMI;
+			continue;
+		}
+
+		if (connector_type == DRM_MODE_CONNECTOR_eDP) {
+			connector->new_encoder->type = INTEL_OUTPUT_EDP;
+			continue;
+		}
+
+		if (connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
+			connector->new_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
+			continue;
+		}
+	}
+}
+
 bool intel_ddi_pll_mode_set(struct drm_crtc *crtc)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5dff7ca..dcd7a9c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9565,6 +9565,8 @@ static int __intel_set_mode(struct drm_crtc *crtc,
 	*saved_hwmode = crtc->hwmode;
 	*saved_mode = crtc->mode;
 
+	intel_ddi_ensure_encoder_type(crtc);
+
 	/* Hack: Because we don't (yet) support global modeset on multiple
 	 * crtcs, we don't keep track of the new mode for more than one crtc.
 	 * Hence simply check whether any bit is set in modeset_pipes in all the
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2b5bcb6..ebf6ba4 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -612,6 +612,7 @@ void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
 void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
 void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
 void intel_ddi_setup_hw_pll_state(struct drm_device *dev);
+void intel_ddi_ensure_encoder_type(struct drm_crtc *crtc);
 bool intel_ddi_pll_mode_set(struct drm_crtc *crtc);
 void intel_ddi_put_crtc_pll(struct drm_crtc *crtc);
 void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH] drm/i915: don't set modes for 2 connectors on the same encoder
  2013-11-29 18:45 Modeset without a detected monitor on DDI platforms Damien Lespiau
  2013-11-29 18:45 ` [PATCH] drm/i915: Set the digital port encoder personality during modeset Damien Lespiau
@ 2013-11-29 19:36 ` Paulo Zanoni
  1 sibling, 0 replies; 3+ messages in thread
From: Paulo Zanoni @ 2013-11-29 19:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

In some cases we have more than 1 connector associated to an encoder
(e.g., SDVO, Haswell DP/HDMI) and we can only set a mode for one of
these connectors. If we only allowed modesets for connected connectors
we would never need this patch, but since we do allow modeset for
disconnected connectors we may see user space trying to set modes on
the two connectors attached to the same encoder, so we need to forbid
that.

This problem can be reproduced by running the following
intel-gpu-tools test case:
  ./kms_setmode --run-subtest clone-exclusive-crtc

Thanks to Daniel Vetter for providing a version of this patch on
pastebin.

Credits-to: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

This is in addition to Damien's patch.

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9d14296..3f6037c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9912,17 +9912,21 @@ intel_modeset_stage_output_state(struct drm_device *dev,
 	/* Check for any encoders that needs to be disabled. */
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
 			    base.head) {
+		int num_connectors = 0;
 		list_for_each_entry(connector,
 				    &dev->mode_config.connector_list,
 				    base.head) {
 			if (connector->new_encoder == encoder) {
 				WARN_ON(!connector->new_encoder->new_crtc);
-
-				goto next_encoder;
+				num_connectors++;
 			}
 		}
-		encoder->new_crtc = NULL;
-next_encoder:
+
+		if (num_connectors == 0)
+			encoder->new_crtc = NULL;
+		else if (num_connectors > 1)
+			return -EINVAL;
+
 		/* Only now check for crtc changes so we don't miss encoders
 		 * that will be disabled. */
 		if (&encoder->new_crtc->base != encoder->base.crtc) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-11-29 19:37 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-29 18:45 Modeset without a detected monitor on DDI platforms Damien Lespiau
2013-11-29 18:45 ` [PATCH] drm/i915: Set the digital port encoder personality during modeset Damien Lespiau
2013-11-29 19:36 ` [PATCH] drm/i915: don't set modes for 2 connectors on the same encoder Paulo Zanoni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox