FAILED: patch "[PATCH] drm/i915: Determine DP++ type 1 DVI adaptor presence based on" failed to apply to 4.6-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 4.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
55d7f30ee1096474cb5bdbca46b60f23ce8b1f83Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <[email protected]>
Date: Wed, 4 May 2016 14:45:22 +0300
Subject: [PATCH] drm/i915: Determine DP++ type 1 DVI adaptor presence based on
VBT
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
DP dual mode type 1 DVI adaptors aren't required to implement any registers, so it's a bit hard to detect them. The best way would be to check the state of the CONFIG1 pin, but we have no way to do that. So as a last resort, check the VBT to see if the HDMI port is in fact a dual mode capable DP port.
v2: Deal with VBT code reorganization
Deal with DRM_DP_DUAL_MODE_UNKNOWN
Reduce DEVICE_TYPE_DP_DUAL_MODE_BITS a bit Accept both DP and HDMI dvo_port in VBT as my BSW at least declare its DP port as HDMI :(
v3: Ignore DEVICE_TYPE_NOT_HDMI_OUTPUT (Shashank)
drivers/gpu/drm/i915/i915_drv.h +1 -0
@@ -3482,6 +3482,7 @@ bool intel_bios_is_valid_vbt(const void *buf, size_t size);bool intel_bios_is_tv_present (struct drm_i915_private *dev_priv);bool intel_bios_is_lvds_present (struct drm_i915_private *dev_priv,u8 *i2c_pin);bool intel_bios_is_port_edp (struct drm_i915_private *dev_priv,enum port port); +bool intel_bios_is_port_dp_dual_mode (struct drm_i915_private *dev_priv,enum port port);bool intel_bios_is_dsi_present (struct drm_i915_private *dev_priv,enum port *port);bool intel_bios_is_port_hpd_inverted (struct drm_i915_private *dev_priv,enum port port);
drivers/gpu/drm/i915/intel_bios.c +36 -0
@@ -1578,6 +1578,42 @@ bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port)return false; } +bool intel_bios_is_port_dp_dual_mode (struct drm_i915_private *dev_priv,enum port port) +{ +static const struct { +u16 dp, hdmi; + } port_mapping[] = { +/* +* Buggy VBTs may declare DP ports as having +* HDMI type dvo_port :( So let's check both. +*/ + [PORT_B ] = {DVO_PORT_DPB ,DVO_PORT_HDMIB , }, + [PORT_C ] = {DVO_PORT_DPC ,DVO_PORT_HDMIC , }, + [PORT_D ] = {DVO_PORT_DPD ,DVO_PORT_HDMID , }, + [PORT_E ] = {DVO_PORT_DPE ,DVO_PORT_HDMIE , }, + }; +int i; + +if (port ==PORT_A || port >=ARRAY_SIZE (port_mapping)) +return false; + +if (!dev_priv->vbt.child_dev_num) +return false; + +for (i =0 ; i < dev_priv->vbt.child_dev_num; i++) { +const union child_device_config *p_child = + &dev_priv->vbt.child_dev[i]; + +if ((p_child->common.dvo_port == port_mapping[port].dp || + p_child->common.dvo_port == port_mapping[port].hdmi) && + (p_child->common.device_type &DEVICE_TYPE_DP_DUAL_MODE_BITS ) == + (DEVICE_TYPE_DP_DUAL_MODE &DEVICE_TYPE_DP_DUAL_MODE_BITS )) +return true; + } + +return false; +} +/** * intel_bios_is_dsi_present - is DSI present in VBT * @dev_priv: i915 device instance
drivers/gpu/drm/i915/intel_hdmi.c +26 -4
@@ -1392,16 +1392,38 @@ intel_hdmi_unset_edid(struct drm_connector *connector) }static void -intel_hdmi_dp_dual_mode_detect (struct drm_connector *connector) +intel_hdmi_dp_dual_mode_detect (struct drm_connector *connector,bool has_edid) {struct drm_i915_private *dev_priv =to_i915 (connector->dev);struct intel_hdmi *hdmi =intel_attached_hdmi (connector); +enum port port =hdmi_to_dig_port (hdmi)->port;struct i2c_adapter *adapter =intel_gmbus_get_adapter (dev_priv, hdmi->ddc_bus);enum drm_dp_dual_mode_type type =drm_dp_dual_mode_detect (adapter); -if (type ==DRM_DP_DUAL_MODE_NONE || - type ==DRM_DP_DUAL_MODE_UNKNOWN ) +/* +* Type 1 DVI adaptors are not required to implement any +* registers, so we can't always detect their presence. +* Ideally we should be able to check the state of the +* CONFIG1 pin, but no such luck on our hardware. +* +* The only method left to us is to check the VBT to see +* if the port is a dual mode capable DP port. But let's +* only do that when we sucesfully read the EDID, to avoid +* confusing log messages about DP dual mode adaptors when +* there's nothing connected to the port. +*/ +if (type ==DRM_DP_DUAL_MODE_UNKNOWN ) { +if (has_edid && +intel_bios_is_port_dp_dual_mode (dev_priv, port)) { +DRM_DEBUG_KMS ("Assuming DP dual mode adaptor presence based on VBT\n" ); + type =DRM_DP_DUAL_MODE_TYPE1_DVI ; + }else { + type =DRM_DP_DUAL_MODE_NONE ; + } + } + +if (type ==DRM_DP_DUAL_MODE_NONE )return ; hdmi->dp_dual_mode.type = type;
@@ -1428,7 +1450,7 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)intel_gmbus_get_adapter (dev_priv, intel_hdmi->ddc_bus)); -intel_hdmi_dp_dual_mode_detect (connector); +intel_hdmi_dp_dual_mode_detect (connector, edid !=NULL );intel_display_power_put (dev_priv,POWER_DOMAIN_GMBUS ); }
drivers/gpu/drm/i915/intel_vbt_defs.h +12 -0
@@ -740,6 +740,7 @@ struct bdb_psr {#define DEVICE_TYPE_INT_TV 0x1009#define DEVICE_TYPE_HDMI 0x60D2#define DEVICE_TYPE_DP 0x68C6 +#define DEVICE_TYPE_DP_DUAL_MODE 0x60D6#define DEVICE_TYPE_eDP 0x78C6#define DEVICE_TYPE_CLASS_EXTENSION (1 << 15)
@@ -774,6 +775,17 @@ struct bdb_psr { DEVICE_TYPE_DISPLAYPORT_OUTPUT | \ DEVICE_TYPE_ANALOG_OUTPUT) +#define DEVICE_TYPE_DP_DUAL_MODE_BITS \ + (DEVICE_TYPE_INTERNAL_CONNECTOR | \ + DEVICE_TYPE_MIPI_OUTPUT | \ + DEVICE_TYPE_COMPOSITE_OUTPUT | \ + DEVICE_TYPE_LVDS_SINGALING | \ + DEVICE_TYPE_TMDS_DVI_SIGNALING | \ + DEVICE_TYPE_VIDEO_SIGNALING | \ + DEVICE_TYPE_DISPLAYPORT_OUTPUT | \ + DEVICE_TYPE_DIGITAL_OUTPUT | \ + DEVICE_TYPE_ANALOG_OUTPUT) +/* define the DVO port for HDMI output type */ #define DVO_B 1#define DVO_C 2