From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> On VLV both ports B and C can support either DP or eDP. Try to initialize eDP first on each port, and if that fails fall back to regular DP connector. intel_dp_init_typed() is now like the old intel_dp_init, except you pass in the connector type. If you pass DRM_MODE_CONNECTOR_Unknown, the code falls back to the old port/VBT based auto detection to determine the actual type. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71051 Tested-by: Robert Hooker <robert.hooker@xxxxxxxxxxxxx> Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/intel_ddi.c | 3 +- drivers/gpu/drm/i915/intel_display.c | 11 ++++-- drivers/gpu/drm/i915/intel_dp.c | 66 ++++++++++++++++++++++-------------- drivers/gpu/drm/i915/intel_drv.h | 5 ++- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 31f4fe2..dd2660c 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1356,7 +1356,8 @@ intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port) return NULL; intel_dig_port->dp.output_reg = DDI_BUF_CTL(port); - if (!intel_dp_init_connector(intel_dig_port, connector)) { + if (!intel_dp_init_connector(intel_dig_port, connector, + DRM_MODE_CONNECTOR_Unknown)) { kfree(connector); return NULL; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8f40ae3..16225eb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9984,15 +9984,20 @@ static void intel_setup_outputs(struct drm_device *dev) intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIB, PORT_B); if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED) - intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B); + if (!intel_dp_init_typed(dev, VLV_DISPLAY_BASE + DP_B, + PORT_B, DRM_MODE_CONNECTOR_eDP)) + intel_dp_init_typed(dev, VLV_DISPLAY_BASE + DP_B, + PORT_B, DRM_MODE_CONNECTOR_DisplayPort); } if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED) { intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC, PORT_C); if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED) - intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, - PORT_C); + if (!intel_dp_init_typed(dev, VLV_DISPLAY_BASE + DP_C, + PORT_C, DRM_MODE_CONNECTOR_eDP)) + intel_dp_init_typed(dev, VLV_DISPLAY_BASE + DP_C, + PORT_C, DRM_MODE_CONNECTOR_DisplayPort); } intel_dsi_init(dev); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index b3cc333..a97f186 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3540,7 +3540,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, - struct intel_connector *intel_connector) + struct intel_connector *intel_connector, + int type) { struct drm_connector *connector = &intel_connector->base; struct intel_dp *intel_dp = &intel_dig_port->dp; @@ -3549,33 +3550,32 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, struct drm_i915_private *dev_priv = dev->dev_private; enum port port = intel_dig_port->port; const char *name = NULL; - int type, error; + int error; /* Preserve the current hw state. */ intel_dp->DP = I915_READ(intel_dp->output_reg); intel_dp->attached_connector = intel_connector; - type = DRM_MODE_CONNECTOR_DisplayPort; - /* - * FIXME : We need to initialize built-in panels before external panels. - * For X0, DP_C is fixed as eDP. Revisit this as part of VLV eDP cleanup - */ - switch (port) { - case PORT_A: - type = DRM_MODE_CONNECTOR_eDP; - break; - case PORT_C: - if (IS_VALLEYVIEW(dev)) - type = DRM_MODE_CONNECTOR_eDP; - break; - case PORT_D: - if (HAS_PCH_SPLIT(dev) && intel_dpd_is_edp(dev)) + if (type == DRM_MODE_CONNECTOR_Unknown) { + type = DRM_MODE_CONNECTOR_DisplayPort; + + switch (port) { + case PORT_A: type = DRM_MODE_CONNECTOR_eDP; - break; - default: /* silence GCC warning */ - break; + break; + case PORT_D: + if (HAS_PCH_SPLIT(dev) && intel_dpd_is_edp(dev)) + type = DRM_MODE_CONNECTOR_eDP; + break; + default: /* silence GCC warning */ + break; + } } + if (WARN_ON(type != DRM_MODE_CONNECTOR_DisplayPort && + type != DRM_MODE_CONNECTOR_eDP)) + return false; + /* * For eDP we always set the encoder type to INTEL_OUTPUT_EDP, but * for DP the encoder type can be set by the caller to @@ -3598,7 +3598,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, ironlake_panel_vdd_work); intel_connector_attach_encoder(intel_connector, intel_encoder); - drm_sysfs_connector_add(connector); + error = drm_sysfs_connector_add(connector); + if (error) { + drm_connector_cleanup(connector); + return false; + } if (HAS_DDI(dev)) intel_connector->get_hw_state = intel_ddi_connector_get_hw_state; @@ -3680,8 +3684,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, return true; } -void -intel_dp_init(struct drm_device *dev, int output_reg, enum port port) +bool +intel_dp_init_typed(struct drm_device *dev, int output_reg, + enum port port, int type) { struct intel_digital_port *intel_dig_port; struct intel_encoder *intel_encoder; @@ -3690,12 +3695,12 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL); if (!intel_dig_port) - return; + return false; intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL); if (!intel_connector) { kfree(intel_dig_port); - return; + return false; } intel_encoder = &intel_dig_port->base; @@ -3727,9 +3732,18 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) intel_encoder->cloneable = false; intel_encoder->hot_plug = intel_dp_hot_plug; - if (!intel_dp_init_connector(intel_dig_port, intel_connector)) { + if (!intel_dp_init_connector(intel_dig_port, intel_connector, type)) { drm_encoder_cleanup(encoder); kfree(intel_dig_port); kfree(intel_connector); + return false; } + + return true; +} + +void +intel_dp_init(struct drm_device *dev, int output_reg, enum port port) +{ + intel_dp_init_typed(dev, output_reg, port, DRM_MODE_CONNECTOR_Unknown); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9d2624f..ff982d9 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -697,8 +697,11 @@ void intel_display_set_init_power(struct drm_device *dev, bool enable); /* intel_dp.c */ void intel_dp_init(struct drm_device *dev, int output_reg, enum port port); +bool intel_dp_init_typed(struct drm_device *dev, int output_reg, + enum port port, int type); bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, - struct intel_connector *intel_connector); + struct intel_connector *intel_connector, + int type); void intel_dp_start_link_train(struct intel_dp *intel_dp); void intel_dp_complete_link_train(struct intel_dp *intel_dp); void intel_dp_stop_link_train(struct intel_dp *intel_dp); -- 1.8.1.5 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx