diff mbox

drm/i915: Check VBT for port presence in addition to the strap on VLV/CHV

Message ID 1464945463-14364-1-git-send-email-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ville Syrjala June 3, 2016, 9:17 a.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Apparently some CHV boards failed to hook up the port presence straps
for HDMI ports as well (earlier we assumed this problem only affected
eDP ports). So let's check the VBT in addition to the strap, and if
either one claims that the port is present go ahead and register the
relevant connector.

While at it, change port D to register DP before HDMI as we do for ports
B and C since
commit 457c52d87e5d ("drm/i915: Only ignore eDP ports that are connected")

Also print a debug message when we register a HDMI connector to aid
in diagnosing missing/incorrect ports. We already had such a print for
DP/eDP.

v2: Improve the comment in the code a bit, note the port D change in
    the commit message

Cc: Radoslav Duda <radosd@radosd.com>
Tested-by: Radoslav Duda <radosd@radosd.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96321
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  1 +
 drivers/gpu/drm/i915/intel_bios.c    | 39 ++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_display.c | 30 ++++++++++++++++++---------
 drivers/gpu/drm/i915/intel_hdmi.c    |  3 +++
 4 files changed, 64 insertions(+), 9 deletions(-)

Comments

Chris Wilson June 3, 2016, 9:56 a.m. UTC | #1
On Fri, Jun 03, 2016 at 12:17:43PM +0300, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Apparently some CHV boards failed to hook up the port presence straps
> for HDMI ports as well (earlier we assumed this problem only affected
> eDP ports). So let's check the VBT in addition to the strap, and if
> either one claims that the port is present go ahead and register the
> relevant connector.
> 
> While at it, change port D to register DP before HDMI as we do for ports
> B and C since
> commit 457c52d87e5d ("drm/i915: Only ignore eDP ports that are connected")
> 
> Also print a debug message when we register a HDMI connector to aid
> in diagnosing missing/incorrect ports. We already had such a print for
> DP/eDP.
> 
> v2: Improve the comment in the code a bit, note the port D change in
>     the commit message
> 
> Cc: Radoslav Duda <radosd@radosd.com>
> Tested-by: Radoslav Duda <radosd@radosd.com>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96321
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  1 +
>  drivers/gpu/drm/i915/intel_bios.c    | 39 ++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_display.c | 30 ++++++++++++++++++---------
>  drivers/gpu/drm/i915/intel_hdmi.c    |  3 +++
>  4 files changed, 64 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 96d5034830f0..be9a6390b435 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3619,6 +3619,7 @@ int intel_bios_init(struct drm_i915_private *dev_priv);
>  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_present(struct drm_i915_private *dev_priv, enum port port);
>  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);
> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
> index 713a02db378a..da5ed4a850b9 100644
> --- a/drivers/gpu/drm/i915/intel_bios.c
> +++ b/drivers/gpu/drm/i915/intel_bios.c
> @@ -1570,6 +1570,45 @@ bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin)
>  }
>  
>  /**
> + * intel_bios_is_port_present - is the specified digital port present
> + * @dev_priv:	i915 device instance
> + * @port:	port to check
> + *
> + * Return true if the device in %port is present.
> + */
> +bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port)
> +{
> +	static const struct {
> +		u16 dp, hdmi;
> +	} port_mapping[] = {

		/* FIXME maybe deal with port A as well? */

> +		[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;
> +
> +	/* FIXME maybe deal with port A as well? */
> +	if (WARN_ON(port == PORT_A) || port >= ARRAY_SIZE(port_mapping))

if (WARN_ON(port >= ARRAY_SIZE() || !port_mapping[port]))

looks a bit more generic?

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
Ville Syrjala June 3, 2016, 10:06 a.m. UTC | #2
On Fri, Jun 03, 2016 at 10:56:24AM +0100, Chris Wilson wrote:
> On Fri, Jun 03, 2016 at 12:17:43PM +0300, ville.syrjala@linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Apparently some CHV boards failed to hook up the port presence straps
> > for HDMI ports as well (earlier we assumed this problem only affected
> > eDP ports). So let's check the VBT in addition to the strap, and if
> > either one claims that the port is present go ahead and register the
> > relevant connector.
> > 
> > While at it, change port D to register DP before HDMI as we do for ports
> > B and C since
> > commit 457c52d87e5d ("drm/i915: Only ignore eDP ports that are connected")
> > 
> > Also print a debug message when we register a HDMI connector to aid
> > in diagnosing missing/incorrect ports. We already had such a print for
> > DP/eDP.
> > 
> > v2: Improve the comment in the code a bit, note the port D change in
> >     the commit message
> > 
> > Cc: Radoslav Duda <radosd@radosd.com>
> > Tested-by: Radoslav Duda <radosd@radosd.com>
> > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96321
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h      |  1 +
> >  drivers/gpu/drm/i915/intel_bios.c    | 39 ++++++++++++++++++++++++++++++++++++
> >  drivers/gpu/drm/i915/intel_display.c | 30 ++++++++++++++++++---------
> >  drivers/gpu/drm/i915/intel_hdmi.c    |  3 +++
> >  4 files changed, 64 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 96d5034830f0..be9a6390b435 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -3619,6 +3619,7 @@ int intel_bios_init(struct drm_i915_private *dev_priv);
> >  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_present(struct drm_i915_private *dev_priv, enum port port);
> >  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);
> > diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
> > index 713a02db378a..da5ed4a850b9 100644
> > --- a/drivers/gpu/drm/i915/intel_bios.c
> > +++ b/drivers/gpu/drm/i915/intel_bios.c
> > @@ -1570,6 +1570,45 @@ bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin)
> >  }
> >  
> >  /**
> > + * intel_bios_is_port_present - is the specified digital port present
> > + * @dev_priv:	i915 device instance
> > + * @port:	port to check
> > + *
> > + * Return true if the device in %port is present.
> > + */
> > +bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port)
> > +{
> > +	static const struct {
> > +		u16 dp, hdmi;
> > +	} port_mapping[] = {
> 
> 		/* FIXME maybe deal with port A as well? */
> 
> > +		[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;
> > +
> > +	/* FIXME maybe deal with port A as well? */
> > +	if (WARN_ON(port == PORT_A) || port >= ARRAY_SIZE(port_mapping))
> 
> if (WARN_ON(port >= ARRAY_SIZE() || !port_mapping[port]))
> 
> looks a bit more generic?

Hmm. DVO_PORT_HDMIA==0, so if we'd start to handle port A here, we'd
have to make sure to use the dp port type for the null check. But yeah,
your idea here seem fairly sane to me. Though I'm thinking someone
should perhaps try to refactor all of these port type check functions
a bit. Would be nice if every one of them didn't have copy paste the
child dev walk. I think I'll leave these plans to simmer a bit, and
jump on them later if/when I'm bored.

> 
> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>

Thanks.

> -Chris
> 
> -- 
> Chris Wilson, Intel Open Source Technology Centre
Ville Syrjala June 3, 2016, 12:28 p.m. UTC | #3
On Fri, Jun 03, 2016 at 10:06:54AM -0000, Patchwork wrote:
> == Series Details ==
> 
> Series: drm/i915: Check VBT for port presence in addition to the strap on VLV/CHV
> URL   : https://patchwork.freedesktop.org/series/8211/
> State : warning
> 
> == Summary ==
> 
> Series 8211v1 drm/i915: Check VBT for port presence in addition to the strap on VLV/CHV
> http://patchwork.freedesktop.org/api/1.0/series/8211/revisions/1/mbox
> 
> Test core_auth:
>         Subgroup basic-auth:
>                 pass       -> DMESG-WARN (ro-skl-i7-6700hq)

all skl fails are
[   35.806452] [drm:intel_pipe_update_start [i915]] *ERROR* Potential atomic update failure on pipe A

https://bugs.freedesktop.org/show_bug.cgi?id=95632

> Test drv_module_reload_basic:
>                 pass       -> SKIP       (ro-hsw-i3-4010u)

Reloading i915.ko with
unbinding /sys/class/vtconsole/vtcon0/: (M) frame buffer device
module successfully unloaded
module successfully loaded again
Reloading i915.ko with inject_load_failure=1
unbinding /sys/class/vtconsole/vtcon0/: (M) frame buffer device
Reloading i915.ko with inject_load_failure=2
unbinding /sys/class/vtconsole/vtcon0/: (M) frame buffer device
Reloading i915.ko with inject_load_failure=3
unbinding /sys/class/vtconsole/vtcon0/: (M) frame buffer device
Reloading i915.ko with inject_load_failure=4
unbinding /sys/class/vtconsole/vtcon0/: (M) frame buffer device
Reloading i915.ko with
unbinding /sys/class/vtconsole/vtcon0/: (M) frame buffer device

rmmod: ERROR: Module i915 is in use
rmmod: ERROR: Module i915 is in use
rmmod: ERROR: Module i915 is in use
rmmod: ERROR: Module i915 is in use
rmmod: ERROR: Module i915 is in use

No clue what was using it. Not the first time I've seen this.

<snip>
> fi-bdw-i7-5557u  total:102  pass:93   dwarn:0   dfail:0   fail:0   skip:8  
> fi-hsw-i7-4770k  total:209  pass:187  dwarn:0   dfail:0   fail:3   skip:19 
> fi-skl-i5-6260u  total:209  pass:198  dwarn:0   dfail:0   fail:0   skip:11 
> fi-skl-i7-6700k  total:209  pass:184  dwarn:0   dfail:0   fail:0   skip:25 
> fi-snb-i7-2600   total:209  pass:167  dwarn:0   dfail:0   fail:3   skip:39 
> ro-bdw-i5-5250u  total:102  pass:93   dwarn:0   dfail:0   fail:0   skip:8  
> ro-bdw-i7-5600u  total:102  pass:75   dwarn:0   dfail:0   fail:0   skip:26 
> ro-byt-n2820     total:209  pass:169  dwarn:0   dfail:0   fail:3   skip:37 
> ro-hsw-i3-4010u  total:209  pass:185  dwarn:0   dfail:0   fail:0   skip:24 
> ro-hsw-i7-4770r  total:102  pass:82   dwarn:0   dfail:0   fail:0   skip:19 
> ro-ilk-i7-620lm  total:1    pass:0    dwarn:0   dfail:0   fail:0   skip:0  
> ro-ilk1-i5-650   total:204  pass:146  dwarn:0   dfail:0   fail:1   skip:57 
> ro-ivb-i7-3770   total:102  pass:75   dwarn:0   dfail:0   fail:0   skip:26 
> ro-ivb2-i7-3770  total:102  pass:79   dwarn:0   dfail:0   fail:0   skip:22 
> ro-skl-i7-6700hq total:204  pass:173  dwarn:10  dfail:0   fail:0   skip:21 
> ro-snb-i7-2620M  total:102  pass:72   dwarn:0   dfail:0   fail:0   skip:29 
> ro-bdw-i7-5557U failed to connect after reboot

So this bdw is indicates as having some other issues. But looking at the
visualization page I see that many other machines are failing to complete
the test run. It's a problem already in nightly, but it seems rather
strange to leave that out of this report. How can anyone be sure that
anything at all got tested if we just silently skip a significant portion
of the tests?

What's even more strange is that the bsw isn't listed anywhere. Looking
at the CI board it's only run 1 out of the last 5 runs. What's going on,
and why aren't these results telling us that something may be wrong on
that machine?

> 
> Results at /archive/results/CI_IGT_test/RO_Patchwork_1091/
> 
> 357b87b drm-intel-nightly: 2016y-06m-03d-08h-46m-18s UTC integration manifest
> 22fc11a drm/i915: Check VBT for port presence in addition to the strap on VLV/CHV
Marius Vlad June 3, 2016, 12:42 p.m. UTC | #4
On Fri, Jun 03, 2016 at 03:28:52PM +0300, Ville Syrjälä wrote:
> On Fri, Jun 03, 2016 at 10:06:54AM -0000, Patchwork wrote:
> > == Series Details ==
> > 
> > Series: drm/i915: Check VBT for port presence in addition to the strap on VLV/CHV
> > URL   : https://patchwork.freedesktop.org/series/8211/
> > State : warning
> > 
> > == Summary ==
> > 
> > Series 8211v1 drm/i915: Check VBT for port presence in addition to the strap on VLV/CHV
> > http://patchwork.freedesktop.org/api/1.0/series/8211/revisions/1/mbox
> > 
> > Test core_auth:
> >         Subgroup basic-auth:
> >                 pass       -> DMESG-WARN (ro-skl-i7-6700hq)
> 
> all skl fails are
> [   35.806452] [drm:intel_pipe_update_start [i915]] *ERROR* Potential atomic update failure on pipe A
> 
> https://bugs.freedesktop.org/show_bug.cgi?id=95632
> 
> > Test drv_module_reload_basic:
> >                 pass       -> SKIP       (ro-hsw-i3-4010u)
> 
> Reloading i915.ko with
> unbinding /sys/class/vtconsole/vtcon0/: (M) frame buffer device
> module successfully unloaded
> module successfully loaded again
> Reloading i915.ko with inject_load_failure=1
> unbinding /sys/class/vtconsole/vtcon0/: (M) frame buffer device
> Reloading i915.ko with inject_load_failure=2
> unbinding /sys/class/vtconsole/vtcon0/: (M) frame buffer device
> Reloading i915.ko with inject_load_failure=3
> unbinding /sys/class/vtconsole/vtcon0/: (M) frame buffer device
> Reloading i915.ko with inject_load_failure=4
> unbinding /sys/class/vtconsole/vtcon0/: (M) frame buffer device
> Reloading i915.ko with
> unbinding /sys/class/vtconsole/vtcon0/: (M) frame buffer device
> 
> rmmod: ERROR: Module i915 is in use
> rmmod: ERROR: Module i915 is in use
> rmmod: ERROR: Module i915 is in use
> rmmod: ERROR: Module i915 is in use
> rmmod: ERROR: Module i915 is in use
> 
> No clue what was using it. Not the first time I've seen this.
https://lists.freedesktop.org/archives/intel-gfx/2016-May/096264.html

Seen it myself a few times.
> 
> <snip>
> > fi-bdw-i7-5557u  total:102  pass:93   dwarn:0   dfail:0   fail:0   skip:8  
> > fi-hsw-i7-4770k  total:209  pass:187  dwarn:0   dfail:0   fail:3   skip:19 
> > fi-skl-i5-6260u  total:209  pass:198  dwarn:0   dfail:0   fail:0   skip:11 
> > fi-skl-i7-6700k  total:209  pass:184  dwarn:0   dfail:0   fail:0   skip:25 
> > fi-snb-i7-2600   total:209  pass:167  dwarn:0   dfail:0   fail:3   skip:39 
> > ro-bdw-i5-5250u  total:102  pass:93   dwarn:0   dfail:0   fail:0   skip:8  
> > ro-bdw-i7-5600u  total:102  pass:75   dwarn:0   dfail:0   fail:0   skip:26 
> > ro-byt-n2820     total:209  pass:169  dwarn:0   dfail:0   fail:3   skip:37 
> > ro-hsw-i3-4010u  total:209  pass:185  dwarn:0   dfail:0   fail:0   skip:24 
> > ro-hsw-i7-4770r  total:102  pass:82   dwarn:0   dfail:0   fail:0   skip:19 
> > ro-ilk-i7-620lm  total:1    pass:0    dwarn:0   dfail:0   fail:0   skip:0  
> > ro-ilk1-i5-650   total:204  pass:146  dwarn:0   dfail:0   fail:1   skip:57 
> > ro-ivb-i7-3770   total:102  pass:75   dwarn:0   dfail:0   fail:0   skip:26 
> > ro-ivb2-i7-3770  total:102  pass:79   dwarn:0   dfail:0   fail:0   skip:22 
> > ro-skl-i7-6700hq total:204  pass:173  dwarn:10  dfail:0   fail:0   skip:21 
> > ro-snb-i7-2620M  total:102  pass:72   dwarn:0   dfail:0   fail:0   skip:29 
> > ro-bdw-i7-5557U failed to connect after reboot
> 
> So this bdw is indicates as having some other issues. But looking at the
> visualization page I see that many other machines are failing to complete
> the test run. It's a problem already in nightly, but it seems rather
> strange to leave that out of this report. How can anyone be sure that
> anything at all got tested if we just silently skip a significant portion
> of the tests?
> 
> What's even more strange is that the bsw isn't listed anywhere. Looking
> at the CI board it's only run 1 out of the last 5 runs. What's going on,
> and why aren't these results telling us that something may be wrong on
> that machine?
> 
> > 
> > Results at /archive/results/CI_IGT_test/RO_Patchwork_1091/
> > 
> > 357b87b drm-intel-nightly: 2016y-06m-03d-08h-46m-18s UTC integration manifest
> > 22fc11a drm/i915: Check VBT for port presence in addition to the strap on VLV/CHV
> 
> -- 
> Ville Syrjälä
> Intel OTC
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Ville Syrjala June 7, 2016, 4:26 p.m. UTC | #5
On Fri, Jun 03, 2016 at 12:17:43PM +0300, ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> Apparently some CHV boards failed to hook up the port presence straps
> for HDMI ports as well (earlier we assumed this problem only affected
> eDP ports). So let's check the VBT in addition to the strap, and if
> either one claims that the port is present go ahead and register the
> relevant connector.
> 
> While at it, change port D to register DP before HDMI as we do for ports
> B and C since
> commit 457c52d87e5d ("drm/i915: Only ignore eDP ports that are connected")
> 
> Also print a debug message when we register a HDMI connector to aid
> in diagnosing missing/incorrect ports. We already had such a print for
> DP/eDP.
> 
> v2: Improve the comment in the code a bit, note the port D change in
>     the commit message
> 
> Cc: Radoslav Duda <radosd@radosd.com>
> Tested-by: Radoslav Duda <radosd@radosd.com>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96321
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---

Pushed to dinq. Thanks for the review.
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 96d5034830f0..be9a6390b435 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3619,6 +3619,7 @@  int intel_bios_init(struct drm_i915_private *dev_priv);
 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_present(struct drm_i915_private *dev_priv, enum port port);
 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);
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 713a02db378a..da5ed4a850b9 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -1570,6 +1570,45 @@  bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin)
 }
 
 /**
+ * intel_bios_is_port_present - is the specified digital port present
+ * @dev_priv:	i915 device instance
+ * @port:	port to check
+ *
+ * Return true if the device in %port is present.
+ */
+bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port)
+{
+	static const struct {
+		u16 dp, hdmi;
+	} port_mapping[] = {
+		[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;
+
+	/* FIXME maybe deal with port A as well? */
+	if (WARN_ON(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_TMDS_DVI_SIGNALING |
+						    DEVICE_TYPE_DISPLAYPORT_OUTPUT)))
+			return true;
+	}
+
+	return false;
+}
+
+/**
  * intel_bios_is_port_edp - is the device in given port eDP
  * @dev_priv:	i915 device instance
  * @port:	port to check
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 60cba1956c0d..6eceefb2ceb4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14702,7 +14702,7 @@  static void intel_setup_outputs(struct drm_device *dev)
 		if (I915_READ(PCH_DP_D) & DP_DETECTED)
 			intel_dp_init(dev, PCH_DP_D, PORT_D);
 	} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
-		bool has_edp;
+		bool has_edp, has_port;
 
 		/*
 		 * The DP_DETECTED bit is the latched state of the DDC
@@ -14712,25 +14712,37 @@  static void intel_setup_outputs(struct drm_device *dev)
 		 * Thus we can't rely on the DP_DETECTED bit alone to detect
 		 * eDP ports. Consult the VBT as well as DP_DETECTED to
 		 * detect eDP ports.
+		 *
+		 * Sadly the straps seem to be missing sometimes even for HDMI
+		 * ports (eg. on Voyo V3 - CHT x7-Z8700), so check both strap
+		 * and VBT for the presence of the port. Additionally we can't
+		 * trust the port type the VBT declares as we've seen at least
+		 * HDMI ports that the VBT claim are DP or eDP.
 		 */
 		has_edp = intel_dp_is_edp(dev, PORT_B);
-		if (I915_READ(VLV_DP_B) & DP_DETECTED || has_edp)
+		has_port = intel_bios_is_port_present(dev_priv, PORT_B);
+		if (I915_READ(VLV_DP_B) & DP_DETECTED || has_port)
 			has_edp &= intel_dp_init(dev, VLV_DP_B, PORT_B);
-		if (I915_READ(VLV_HDMIB) & SDVO_DETECTED && !has_edp)
+		if ((I915_READ(VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp)
 			intel_hdmi_init(dev, VLV_HDMIB, PORT_B);
 
 		has_edp = intel_dp_is_edp(dev, PORT_C);
-		if (I915_READ(VLV_DP_C) & DP_DETECTED || has_edp)
+		has_port = intel_bios_is_port_present(dev_priv, PORT_C);
+		if (I915_READ(VLV_DP_C) & DP_DETECTED || has_port)
 			has_edp &= intel_dp_init(dev, VLV_DP_C, PORT_C);
-		if (I915_READ(VLV_HDMIC) & SDVO_DETECTED && !has_edp)
+		if ((I915_READ(VLV_HDMIC) & SDVO_DETECTED || has_port) && !has_edp)
 			intel_hdmi_init(dev, VLV_HDMIC, PORT_C);
 
 		if (IS_CHERRYVIEW(dev)) {
-			/* eDP not supported on port D, so don't check VBT */
-			if (I915_READ(CHV_HDMID) & SDVO_DETECTED)
-				intel_hdmi_init(dev, CHV_HDMID, PORT_D);
-			if (I915_READ(CHV_DP_D) & DP_DETECTED)
+			/*
+			 * eDP not supported on port D,
+			 * so no need to worry about it
+			 */
+			has_port = intel_bios_is_port_present(dev_priv, PORT_D);
+			if (I915_READ(CHV_DP_D) & DP_DETECTED || has_port)
 				intel_dp_init(dev, CHV_DP_D, PORT_D);
+			if (I915_READ(CHV_HDMID) & SDVO_DETECTED || has_port)
+				intel_hdmi_init(dev, CHV_HDMID, PORT_D);
 		}
 
 		intel_dsi_init(dev);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index eb455ea6ea92..ae153b6f093e 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1810,6 +1810,9 @@  void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 	enum port port = intel_dig_port->port;
 	uint8_t alternate_ddc_pin;
 
+	DRM_DEBUG_KMS("Adding HDMI connector on port %c\n",
+		      port_name(port));
+
 	if (WARN(intel_dig_port->max_lanes < 4,
 		 "Not enough lanes (%d) for HDMI on port %c\n",
 		 intel_dig_port->max_lanes, port_name(port)))