[Intel-gfx] [PATCH] drm/i915: Reject modeset when the same digital port is used more than once
Daniel Vetter
daniel at ffwll.ch
Mon May 19 16:29:57 CEST 2014
On Mon, May 19, 2014 at 05:19:09PM +0300, ville.syrjala at linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
>
> On pre-HSW we have two encoders per digital port: one HDMI, one DP.
> However they are the same physical port in hardware and we can't enable
> both at the same time. Reject the modeset if the user attempts this.
>
> So far we've been saved by the fact that we never see both HDMI and DP
> connectors as connected. But if the user decides to force a mode anyway,
> all kinds of funny stuff might happen.
>
> Unfortunately we don't seem to have any way to inform userspace that
> such configurations are invalid except by returning an error from
> setcrtc. possible_clones only covers real cloning situations, and
> looking at the connector names doesn't work either since we don't
> always register both connectors for the same port. I suppose the
> only way to fix that would be to expose only a single encoder per
> digital port like we do on HSW+ but that would be a fairly large
> undertaking for little gain.
>
> kms_setmode hits this since it forces modes on non-connected VGA and
> HDMI connectors. Previosuly it just resulted in weirdness such as
> failed link training. With this patch it will now get an error back
> from the kernel and will die with an assert since it thinks that the
> configuration should be fine.
>
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
Do we have a bugzilla for this somewhere?
-Daniel
> ---
> drivers/gpu/drm/i915/intel_display.c | 44 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 44 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index a432348..13add38 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -9621,6 +9621,45 @@ static bool check_encoder_cloning(struct intel_crtc *crtc)
> return true;
> }
>
> +static bool check_digital_port_conflicts(struct drm_device *dev)
> +{
> + struct intel_connector *connector;
> + unsigned int used_ports = 0;
> +
> + /*
> + * Walk the connector list instead of the encoder
> + * list to detect the problem on ddi platforms
> + * where there's just one encoder per digital port.
> + */
> + list_for_each_entry(connector,
> + &dev->mode_config.connector_list, base.head) {
> + struct intel_encoder *encoder = connector->new_encoder;
> +
> + if (!encoder)
> + continue;
> +
> + WARN_ON(!encoder->new_crtc);
> +
> + switch (encoder->type) {
> + unsigned int port_mask;
> + case INTEL_OUTPUT_DISPLAYPORT:
> + case INTEL_OUTPUT_HDMI:
> + case INTEL_OUTPUT_EDP:
> + port_mask = 1 << enc_to_dig_port(&encoder->base)->port;
> +
> + /* the same port mustn't appear more than once */
> + if (used_ports & port_mask)
> + return false;
> +
> + used_ports |= port_mask;
> + default:
> + break;
> + }
> + }
> +
> + return true;
> +}
> +
> static struct intel_crtc_config *
> intel_modeset_pipe_config(struct drm_crtc *crtc,
> struct drm_framebuffer *fb,
> @@ -9637,6 +9676,11 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
> return ERR_PTR(-EINVAL);
> }
>
> + if (!check_digital_port_conflicts(dev)) {
> + DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
> if (!pipe_config)
> return ERR_PTR(-ENOMEM);
> --
> 1.8.5.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
More information about the Intel-gfx
mailing list