From mboxrd@z Thu Jan 1 00:00:00 1970 From: Damien Lespiau Subject: [PATCH] drm/i915: Set the digital port encoder personality during modeset Date: Fri, 29 Nov 2013 18:45:22 +0000 Message-ID: <1385750722-5114-2-git-send-email-damien.lespiau@intel.com> References: <1385750722-5114-1-git-send-email-damien.lespiau@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTP id 5C047FA2E1 for ; Fri, 29 Nov 2013 10:45:30 -0800 (PST) In-Reply-To: <1385750722-5114-1-git-send-email-damien.lespiau@intel.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces+gcfxdi-intel-gfx=m.gmane.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+gcfxdi-intel-gfx=m.gmane.org@lists.freedesktop.org To: intel-gfx@lists.freedesktop.org List-Id: intel-gfx@lists.freedesktop.org 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 --- 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