[Intel-gfx] [PATCH] drm/i915/ehl: Allow combo PHY A to drive a third external display

Ville Syrjälä ville.syrjala at linux.intel.com
Fri Jun 14 18:32:32 UTC 2019


On Fri, Jun 14, 2019 at 11:07:34AM -0700, Matt Roper wrote:
> EHL has a mux on combo PHY A that allows it to be driven either by an
> internal display (using DDI-A or DSI DPHY) or by an external display
> (using DDI-D).  This is a motherboard design decision that can not be
> changed on the fly.  Let's use the VBT child device settings to try to
> figure out our board's configuration and program the mux accordingly.
> 
> Cc: Clint Taylor <Clinton.A.Taylor at intel.com>
> Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h        |  1 +
>  drivers/gpu/drm/i915/intel_bios.c      | 24 ++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_bios.h      |  1 +
>  drivers/gpu/drm/i915/intel_combo_phy.c | 13 +++++++++++++
>  4 files changed, 39 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 368ee717580c..0ae0d85304b5 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -11121,6 +11121,7 @@ enum skl_power_gate {
>  #define _ICL_PHY_MISC_B		0x64C04
>  #define ICL_PHY_MISC(port)	_MMIO_PORT(port, _ICL_PHY_MISC_A, \
>  						 _ICL_PHY_MISC_B)
> +#define  ICL_PHY_MISC_MUX_DDID			(1 << 28)
>  #define  ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN	(1 << 23)
>  
>  /* Icelake Display Stream Compression Registers */
> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
> index d3d473934ea4..ac861852e843 100644
> --- a/drivers/gpu/drm/i915/intel_bios.c
> +++ b/drivers/gpu/drm/i915/intel_bios.c
> @@ -1667,6 +1667,9 @@ parse_general_definitions(struct drm_i915_private *dev_priv,
>  		if (!child->device_type)
>  			continue;
>  
> +		DRM_DEBUG_KMS("Found VBT child device with type 0x%x\n",
> +			      child->device_type);
> +
>  		/*
>  		 * Copy as much as we know (sizeof) and is available
>  		 * (child_dev_size) of the child device. Accessing the data must
> @@ -2259,3 +2262,24 @@ enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *dev_priv,
>  
>  	return aux_ch;
>  }
> +
> +/**
> + * intel_bios_has_internal_display - are any child devices marked 'internal?'
> + * @dev_priv:	i915 device instance
> + *
> + * Returns true if any of the child devices have a device type containing
> + * the %DEVICE_TYPE_INTERNAL_CONNECTOR bit.
> + */
> +bool intel_bios_has_internal_display(struct drm_i915_private *dev_priv)
> +{
> +	int i;
> +
> +	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
> +		struct child_device_config *child = &dev_priv->vbt.child_dev[i];
> +
> +		if (child->device_type & DEVICE_TYPE_INTERNAL_CONNECTOR)
> +			return true;
> +	}
> +
> +	return false;
> +}

This feels super fragile. No hw strap for this?

Is the VBT DVO port referring to DDI or PHY?

If it's referring to DDI then I think we could check
for child device being present on DDI D and no child
device on DDI A/DSI. Not sure which way we should go
if there's a conflict.

But if it's referring to the PHY then we're hosed because
we can't tell which DDI is driving DVO port A aka. PHY A.
I guess in that case we should check for an internal/DSI vs.
external connector on DVO port A?

Not sure how many places we have in the code which assumes
1:1 mapping between DDI:PHY. I think we really need to
introduce a new namespace for the PHY so that we aren't
super confused all the time which thing we're talking about.

> diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
> index 4e42cfaf61a7..df822a1efe55 100644
> --- a/drivers/gpu/drm/i915/intel_bios.h
> +++ b/drivers/gpu/drm/i915/intel_bios.h
> @@ -240,5 +240,6 @@ bool intel_bios_is_port_hpd_inverted(const struct drm_i915_private *i915,
>  bool intel_bios_is_lspcon_present(const struct drm_i915_private *i915,
>  				  enum port port);
>  enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *dev_priv, enum port port);
> +bool intel_bios_has_internal_display(struct drm_i915_private *dev_priv);
>  
>  #endif /* _INTEL_BIOS_H_ */
> diff --git a/drivers/gpu/drm/i915/intel_combo_phy.c b/drivers/gpu/drm/i915/intel_combo_phy.c
> index 841708da5a56..3bf3e41c5296 100644
> --- a/drivers/gpu/drm/i915/intel_combo_phy.c
> +++ b/drivers/gpu/drm/i915/intel_combo_phy.c
> @@ -273,7 +273,20 @@ static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
>  			continue;
>  		}
>  
> +		/*
> +		 * EHL's combo PHY A can be hooked up to either an external
> +		 * display (via DDI-D) or an internal display (via DDI-A or
> +		 * the DSI DPHY).  This is a motherboard design decision that
> +		 * can't be changed on the fly, so initialize the PHY's mux
> +		 * based on whether our VBT indicates the presence of any
> +		 * "internal" child devices.
> +		 */
>  		val = I915_READ(ICL_PHY_MISC(port));
> +		if (!IS_ICELAKE(dev_priv) && port == PORT_A &&
> +		    !intel_bios_has_internal_display(dev_priv))
> +			val |= ICL_PHY_MISC_MUX_DDID;
> +		else
> +			val &= ~ICL_PHY_MISC_MUX_DDID;
>  		val &= ~ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
>  		I915_WRITE(ICL_PHY_MISC(port), val);
>  
> -- 
> 2.14.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel


More information about the Intel-gfx mailing list