[Intel-gfx] [PATCH] drm/i915: Try to initialize eDP for both ports B and C on VLV

Jesse Barnes jbarnes at virtuousgeek.org
Thu Oct 31 18:18:00 CET 2013


On Thu, 31 Oct 2013 18:46:22 +0200
ville.syrjala at linux.intel.com wrote:

> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> 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 at canonical.com>
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> ---
>  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);

We're supposed to get this info from the VBT, but we don't have the new
spec yet.  If we get that, we can parse it out in intel_bios.c and use
it in intel_dp.c.

In cases where that may be unreliable, your approach might be fine,
though I suppose the typed init addition should be separate from the
"try both kinds" addition on VLV.

-- 
Jesse Barnes, Intel Open Source Technology Center



More information about the Intel-gfx mailing list