]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
1fde528a59b65d545f9d62e468a52a6cc21d2f9c
[thirdparty/kernel/stable-queue.git] /
1 From bc9db5ad3253c8e17969bd802c47b73e63f125ab Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
3 Date: Fri, 11 Nov 2016 19:14:24 +0200
4 Subject: drm/i915: Assume non-DP++ port if dvo_port is HDMI and there's no AUX ch specified in the VBT
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 From: Ville Syrjälä <ville.syrjala@linux.intel.com>
10
11 commit bc9db5ad3253c8e17969bd802c47b73e63f125ab upstream.
12
13 My heuristic for detecting type 1 DVI DP++ adaptors based on the VBT
14 port information apparently didn't survive the reality of buggy VBTs.
15 In this particular case we have a machine with a natice HDMI port, but
16 the VBT tells us it's a DP++ port based on its capabilities.
17
18 The dvo_port information in VBT does claim that we're dealing with a
19 HDMI port though, but we have other machines which do the same even
20 when they actually have DP++ ports. So that piece of information alone
21 isn't sufficient to tell the two apart.
22
23 After staring at a bunch of VBTs from various machines, I have to
24 conclude that the only other semi-reliable clue we can use is the
25 presence of the AUX channel in the VBT. On this particular machine
26 AUX channel is specified as zero, whereas on some of the other machines
27 which listed the DP++ port as HDMI have a non-zero AUX channel.
28
29 I've also seen VBTs which have dvo_port a DP but have a zero AUX
30 channel. I believe those we need to treat as DP ports, so we'll limit
31 the AUX channel check to just the cases where dvo_port is HDMI.
32
33 If we encounter any more serious failures with this heuristic I think
34 we'll have to have to throw it out entirely. But that could mean that
35 there is a risk of type 1 DVI dongle users getting greeted by a
36 black screen, so I'd rather not go there unless absolutely necessary.
37
38 v2: Remove the duplicate PORT_A check (Daniel)
39 Fix some typos in the commit message
40
41 Cc: Daniel Otero <daniel.otero@outlook.com>
42 Tested-by: Daniel Otero <daniel.otero@outlook.com>
43 Fixes: d61992565bd3 ("drm/i915: Determine DP++ type 1 DVI adaptor presence based on VBT")
44 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97994
45 Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
46 Link: http://patchwork.freedesktop.org/patch/msgid/1478884464-14251-1-git-send-email-ville.syrjala@linux.intel.com
47 Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
48 (cherry picked from commit 7a17995a3dc8613f778a9e2fd20e870f17789544)
49 Signed-off-by: Jani Nikula <jani.nikula@intel.com>
50 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
51
52 ---
53 drivers/gpu/drm/i915/intel_bios.c | 30 ++++++++++++++++++++++--------
54 drivers/gpu/drm/i915/intel_vbt_defs.h | 3 ++-
55 2 files changed, 24 insertions(+), 9 deletions(-)
56
57 --- a/drivers/gpu/drm/i915/intel_bios.c
58 +++ b/drivers/gpu/drm/i915/intel_bios.c
59 @@ -1143,7 +1143,7 @@ static void parse_ddi_port(struct drm_i9
60 if (!child)
61 return;
62
63 - aux_channel = child->raw[25];
64 + aux_channel = child->common.aux_channel;
65 ddc_pin = child->common.ddc_pin;
66
67 is_dvi = child->common.device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING;
68 @@ -1673,7 +1673,8 @@ bool intel_bios_is_port_edp(struct drm_i
69 return false;
70 }
71
72 -bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum port port)
73 +static bool child_dev_is_dp_dual_mode(const union child_device_config *p_child,
74 + enum port port)
75 {
76 static const struct {
77 u16 dp, hdmi;
78 @@ -1687,22 +1688,35 @@ bool intel_bios_is_port_dp_dual_mode(str
79 [PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, },
80 [PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, },
81 };
82 - int i;
83
84 if (port == PORT_A || port >= ARRAY_SIZE(port_mapping))
85 return false;
86
87 - if (!dev_priv->vbt.child_dev_num)
88 + if ((p_child->common.device_type & DEVICE_TYPE_DP_DUAL_MODE_BITS) !=
89 + (DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS))
90 return false;
91
92 + if (p_child->common.dvo_port == port_mapping[port].dp)
93 + return true;
94 +
95 + /* Only accept a HDMI dvo_port as DP++ if it has an AUX channel */
96 + if (p_child->common.dvo_port == port_mapping[port].hdmi &&
97 + p_child->common.aux_channel != 0)
98 + return true;
99 +
100 + return false;
101 +}
102 +
103 +bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv,
104 + enum port port)
105 +{
106 + int i;
107 +
108 for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
109 const union child_device_config *p_child =
110 &dev_priv->vbt.child_dev[i];
111
112 - if ((p_child->common.dvo_port == port_mapping[port].dp ||
113 - p_child->common.dvo_port == port_mapping[port].hdmi) &&
114 - (p_child->common.device_type & DEVICE_TYPE_DP_DUAL_MODE_BITS) ==
115 - (DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS))
116 + if (child_dev_is_dp_dual_mode(p_child, port))
117 return true;
118 }
119
120 --- a/drivers/gpu/drm/i915/intel_vbt_defs.h
121 +++ b/drivers/gpu/drm/i915/intel_vbt_defs.h
122 @@ -280,7 +280,8 @@ struct common_child_dev_config {
123 u8 dp_support:1;
124 u8 tmds_support:1;
125 u8 support_reserved:5;
126 - u8 not_common3[12];
127 + u8 aux_channel;
128 + u8 not_common3[11];
129 u8 iboost_level;
130 } __packed;
131