Message ID | 1459771308-4405-4-git-send-email-shashank.sharma@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, 04 Apr 2016, Shashank Sharma <shashank.sharma@intel.com> wrote: > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > MIME-Version: 1.0 > Content-Type: text/plain; charset=UTF-8 > Content-Transfer-Encoding: 8bit > > 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. > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > --- > drivers/gpu/drm/i915/i915_drv.h | 2 ++ > drivers/gpu/drm/i915/intel_bios.c | 32 ++++++++++++++++++++++++++++++++ > drivers/gpu/drm/i915/intel_dp.c | 5 +++++ > drivers/gpu/drm/i915/intel_drv.h | 1 + > drivers/gpu/drm/i915/intel_hdmi.c | 23 +++++++++++++++++++++-- > drivers/gpu/drm/i915/intel_vbt_defs.h | 3 +++ > 6 files changed, 64 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index f330a53..65bb83f 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -3373,6 +3373,8 @@ 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_dsi_present(struct drm_i915_private *dev_priv, enum port *port); > +bool intel_bios_is_dp_dual_mode(struct drm_i915_private *dev_priv, > + enum port port); > > /* intel_opregion.c */ > #ifdef CONFIG_ACPI > diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c > index 083003b..39c520a 100644 > --- a/drivers/gpu/drm/i915/intel_bios.c > +++ b/drivers/gpu/drm/i915/intel_bios.c > @@ -1550,6 +1550,38 @@ bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port) > return false; > } > > +bool intel_bios_is_dp_dual_mode(struct drm_i915_private *dev_priv, > + enum port port) > +{ > + const union child_device_config *p_child; > + int i; > + static const short port_mapping[] = { > + [PORT_B] = DVO_PORT_DPB, > + [PORT_C] = DVO_PORT_DPC, > + [PORT_D] = DVO_PORT_DPD, > + [PORT_E] = DVO_PORT_DPE, > + }; > + > + 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++) { > + p_child = &dev_priv->vbt.child_dev[i]; > + > + if (p_child->common.dvo_port == port_mapping[port] && > + (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 > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index 3ff8f1d..ba4da0c 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -5007,6 +5007,11 @@ bool intel_dp_is_edp(struct drm_device *dev, enum port port) > return intel_bios_is_port_edp(dev_priv, port); > } > > +bool intel_dp_is_dual_mode(struct drm_i915_private *dev_priv, enum port port) > +{ > + return intel_bios_is_dp_dual_mode(dev_priv, port); > +} Just use intel_bios_is_dp_dual_mode() where you need it. BR, Jani. > + > void > intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector) > { > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index ab514bd..26ef950 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -1276,6 +1276,7 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc); > bool intel_dp_compute_config(struct intel_encoder *encoder, > struct intel_crtc_state *pipe_config); > bool intel_dp_is_edp(struct drm_device *dev, enum port port); > +bool intel_dp_is_dual_mode(struct drm_i915_private *dev_priv, enum port port); > enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, > bool long_hpd); > void intel_edp_backlight_on(struct intel_dp *intel_dp); > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > index 3a93337..22b5a7e 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -1387,14 +1387,33 @@ 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); > > + /* > + * 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_NONE && has_edid && > + intel_dp_is_dual_mode(dev_priv, port)) { > + DRM_DEBUG_KMS("Assuming DP dual mode adaptor (as per VBT)\n"); > + type = DRM_DP_DUAL_MODE_TYPE1_DVI; > + } > + > if (type == DRM_DP_DUAL_MODE_NONE) > return; > > @@ -1440,7 +1459,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); > } > diff --git a/drivers/gpu/drm/i915/intel_vbt_defs.h b/drivers/gpu/drm/i915/intel_vbt_defs.h > index 749dcea..ebaecdb 100644 > --- a/drivers/gpu/drm/i915/intel_vbt_defs.h > +++ b/drivers/gpu/drm/i915/intel_vbt_defs.h > @@ -734,6 +734,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) > @@ -768,6 +769,8 @@ struct bdb_psr { > DEVICE_TYPE_DISPLAYPORT_OUTPUT | \ > DEVICE_TYPE_ANALOG_OUTPUT) > > +#define DEVICE_TYPE_DP_DUAL_MODE_BITS ~DEVICE_TYPE_NOT_HDMI_OUTPUT > + > /* define the DVO port for HDMI output type */ > #define DVO_B 1 > #define DVO_C 2
On Mon, May 02, 2016 at 05:33:49PM +0300, Jani Nikula wrote: > On Mon, 04 Apr 2016, Shashank Sharma <shashank.sharma@intel.com> wrote: > > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > > > MIME-Version: 1.0 > > Content-Type: text/plain; charset=UTF-8 > > Content-Transfer-Encoding: 8bit > > > > 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. > > > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > > --- > > drivers/gpu/drm/i915/i915_drv.h | 2 ++ > > drivers/gpu/drm/i915/intel_bios.c | 32 ++++++++++++++++++++++++++++++++ > > drivers/gpu/drm/i915/intel_dp.c | 5 +++++ > > drivers/gpu/drm/i915/intel_drv.h | 1 + > > drivers/gpu/drm/i915/intel_hdmi.c | 23 +++++++++++++++++++++-- > > drivers/gpu/drm/i915/intel_vbt_defs.h | 3 +++ > > 6 files changed, 64 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > > index f330a53..65bb83f 100644 > > --- a/drivers/gpu/drm/i915/i915_drv.h > > +++ b/drivers/gpu/drm/i915/i915_drv.h > > @@ -3373,6 +3373,8 @@ 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_dsi_present(struct drm_i915_private *dev_priv, enum port *port); > > +bool intel_bios_is_dp_dual_mode(struct drm_i915_private *dev_priv, > > + enum port port); > > > > /* intel_opregion.c */ > > #ifdef CONFIG_ACPI > > diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c > > index 083003b..39c520a 100644 > > --- a/drivers/gpu/drm/i915/intel_bios.c > > +++ b/drivers/gpu/drm/i915/intel_bios.c > > @@ -1550,6 +1550,38 @@ bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port) > > return false; > > } > > > > +bool intel_bios_is_dp_dual_mode(struct drm_i915_private *dev_priv, > > + enum port port) > > +{ > > + const union child_device_config *p_child; > > + int i; > > + static const short port_mapping[] = { > > + [PORT_B] = DVO_PORT_DPB, > > + [PORT_C] = DVO_PORT_DPC, > > + [PORT_D] = DVO_PORT_DPD, > > + [PORT_E] = DVO_PORT_DPE, > > + }; > > + > > + 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++) { > > + p_child = &dev_priv->vbt.child_dev[i]; > > + > > + if (p_child->common.dvo_port == port_mapping[port] && > > + (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 > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > > index 3ff8f1d..ba4da0c 100644 > > --- a/drivers/gpu/drm/i915/intel_dp.c > > +++ b/drivers/gpu/drm/i915/intel_dp.c > > @@ -5007,6 +5007,11 @@ bool intel_dp_is_edp(struct drm_device *dev, enum port port) > > return intel_bios_is_port_edp(dev_priv, port); > > } > > > > +bool intel_dp_is_dual_mode(struct drm_i915_private *dev_priv, enum port port) > > +{ > > + return intel_bios_is_dp_dual_mode(dev_priv, port); > > +} > > Just use intel_bios_is_dp_dual_mode() where you need it. That wasn't in my original patch, and the commit message lacks any information that the patch has been modified by someone else than the original author. Such things always need to be documented properly! Anyways, I should just repost my patches separately (with reviews comments addresses where appropriate) so that we can get the basic dual mode stuff in (to fix the 12bpc regressions).
Regards Shashank On 5/2/2016 8:09 PM, Ville Syrjälä wrote: > On Mon, May 02, 2016 at 05:33:49PM +0300, Jani Nikula wrote: >> On Mon, 04 Apr 2016, Shashank Sharma <shashank.sharma@intel.com> wrote: >>> From: Ville Syrjälä <ville.syrjala@linux.intel.com> >>> >>> MIME-Version: 1.0 >>> Content-Type: text/plain; charset=UTF-8 >>> Content-Transfer-Encoding: 8bit >>> >>> 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. >>> >>> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> >>> --- >>> drivers/gpu/drm/i915/i915_drv.h | 2 ++ >>> drivers/gpu/drm/i915/intel_bios.c | 32 ++++++++++++++++++++++++++++++++ >>> drivers/gpu/drm/i915/intel_dp.c | 5 +++++ >>> drivers/gpu/drm/i915/intel_drv.h | 1 + >>> drivers/gpu/drm/i915/intel_hdmi.c | 23 +++++++++++++++++++++-- >>> drivers/gpu/drm/i915/intel_vbt_defs.h | 3 +++ >>> 6 files changed, 64 insertions(+), 2 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h >>> index f330a53..65bb83f 100644 >>> --- a/drivers/gpu/drm/i915/i915_drv.h >>> +++ b/drivers/gpu/drm/i915/i915_drv.h >>> @@ -3373,6 +3373,8 @@ 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_dsi_present(struct drm_i915_private *dev_priv, enum port *port); >>> +bool intel_bios_is_dp_dual_mode(struct drm_i915_private *dev_priv, >>> + enum port port); >>> >>> /* intel_opregion.c */ >>> #ifdef CONFIG_ACPI >>> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c >>> index 083003b..39c520a 100644 >>> --- a/drivers/gpu/drm/i915/intel_bios.c >>> +++ b/drivers/gpu/drm/i915/intel_bios.c >>> @@ -1550,6 +1550,38 @@ bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port) >>> return false; >>> } >>> >>> +bool intel_bios_is_dp_dual_mode(struct drm_i915_private *dev_priv, >>> + enum port port) >>> +{ >>> + const union child_device_config *p_child; >>> + int i; >>> + static const short port_mapping[] = { >>> + [PORT_B] = DVO_PORT_DPB, >>> + [PORT_C] = DVO_PORT_DPC, >>> + [PORT_D] = DVO_PORT_DPD, >>> + [PORT_E] = DVO_PORT_DPE, >>> + }; >>> + >>> + 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++) { >>> + p_child = &dev_priv->vbt.child_dev[i]; >>> + >>> + if (p_child->common.dvo_port == port_mapping[port] && >>> + (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 >>> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c >>> index 3ff8f1d..ba4da0c 100644 >>> --- a/drivers/gpu/drm/i915/intel_dp.c >>> +++ b/drivers/gpu/drm/i915/intel_dp.c >>> @@ -5007,6 +5007,11 @@ bool intel_dp_is_edp(struct drm_device *dev, enum port port) >>> return intel_bios_is_port_edp(dev_priv, port); >>> } >>> >>> +bool intel_dp_is_dual_mode(struct drm_i915_private *dev_priv, enum port port) >>> +{ >>> + return intel_bios_is_dp_dual_mode(dev_priv, port); >>> +} >> >> Just use intel_bios_is_dp_dual_mode() where you need it. > > That wasn't in my original patch, and the commit message lacks any > information that the patch has been modified by someone else than the > original author. Such things always need to be documented properly! > > Anyways, I should just repost my patches separately (with reviews > comments addresses where appropriate) so that we can get the basic > dual mode stuff in (to fix the 12bpc regressions). > While porting this patch, I had to do some changes, and add wrapper functions due to recent changes in intel_bios.c and code movement to intel_vbt_def.h etc, but I couldn't remember now what was the exact reason. So yeah, having it in the commit message would have been a better idea.
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f330a53..65bb83f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3373,6 +3373,8 @@ 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_dsi_present(struct drm_i915_private *dev_priv, enum port *port); +bool intel_bios_is_dp_dual_mode(struct drm_i915_private *dev_priv, + enum port port); /* intel_opregion.c */ #ifdef CONFIG_ACPI diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 083003b..39c520a 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1550,6 +1550,38 @@ bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port) return false; } +bool intel_bios_is_dp_dual_mode(struct drm_i915_private *dev_priv, + enum port port) +{ + const union child_device_config *p_child; + int i; + static const short port_mapping[] = { + [PORT_B] = DVO_PORT_DPB, + [PORT_C] = DVO_PORT_DPC, + [PORT_D] = DVO_PORT_DPD, + [PORT_E] = DVO_PORT_DPE, + }; + + 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++) { + p_child = &dev_priv->vbt.child_dev[i]; + + if (p_child->common.dvo_port == port_mapping[port] && + (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 diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3ff8f1d..ba4da0c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5007,6 +5007,11 @@ bool intel_dp_is_edp(struct drm_device *dev, enum port port) return intel_bios_is_port_edp(dev_priv, port); } +bool intel_dp_is_dual_mode(struct drm_i915_private *dev_priv, enum port port) +{ + return intel_bios_is_dp_dual_mode(dev_priv, port); +} + void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ab514bd..26ef950 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1276,6 +1276,7 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc); bool intel_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config); bool intel_dp_is_edp(struct drm_device *dev, enum port port); +bool intel_dp_is_dual_mode(struct drm_i915_private *dev_priv, enum port port); enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd); void intel_edp_backlight_on(struct intel_dp *intel_dp); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 3a93337..22b5a7e 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1387,14 +1387,33 @@ 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); + /* + * 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_NONE && has_edid && + intel_dp_is_dual_mode(dev_priv, port)) { + DRM_DEBUG_KMS("Assuming DP dual mode adaptor (as per VBT)\n"); + type = DRM_DP_DUAL_MODE_TYPE1_DVI; + } + if (type == DRM_DP_DUAL_MODE_NONE) return; @@ -1440,7 +1459,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); } diff --git a/drivers/gpu/drm/i915/intel_vbt_defs.h b/drivers/gpu/drm/i915/intel_vbt_defs.h index 749dcea..ebaecdb 100644 --- a/drivers/gpu/drm/i915/intel_vbt_defs.h +++ b/drivers/gpu/drm/i915/intel_vbt_defs.h @@ -734,6 +734,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) @@ -768,6 +769,8 @@ struct bdb_psr { DEVICE_TYPE_DISPLAYPORT_OUTPUT | \ DEVICE_TYPE_ANALOG_OUTPUT) +#define DEVICE_TYPE_DP_DUAL_MODE_BITS ~DEVICE_TYPE_NOT_HDMI_OUTPUT + /* define the DVO port for HDMI output type */ #define DVO_B 1 #define DVO_C 2