* [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