[Intel-gfx] [PATCH] drm/i915: Set the digital port encoder personality during modeset
Damien Lespiau
damien.lespiau at intel.com
Fri Nov 29 19:45:22 CET 2013
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 at 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
More information about the Intel-gfx
mailing list