aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2016-10-11 13:52:45 -0400
committerJani Nikula <jani.nikula@intel.com>2016-10-28 08:20:54 -0400
commit198c5ee3c60169f8b64bcd330a34593be80699aa (patch)
tree86436b4007f352c50fd5473650d185d8aceec902
parent5e33791e1f27c3207e7b44071e7c94a487d1eb39 (diff)
drm/i915: Respect alternate_aux_channel for all DDI ports
The VBT provides the platform a way to mix and match the DDI ports vs. AUX channels. Currently we only trust the VBT for DDI E, which has no corresponding AUX channel of its own. However it is possible that some board might use some non-standard DDI vs. AUX port routing even for the other ports. Perhaps for signal routing reasons or something, So let's generalize this and trust the VBT for all ports. For now we'll limit this to DDI platforms, as we trust the VBT a bit more there anyway when it comes to the DDI ports. I've structured the code in a way that would allow us to easily expand this to other platforms as well, by simply filling in the ddi_port_info. v2: Drop whitespace changes, keep MISSING_CASE() for unknown aux ch assignment, include a commit message, include debug message during init Cc: stable@vger.kernel.org Cc: Maarten Maathuis <madman2003@gmail.com> Tested-by: Maarten Maathuis <madman2003@gmail.com> References: https://bugs.freedesktop.org/show_bug.cgi?id=97877 Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1476208368-5710-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Jim Bride <jim.bride@linux.intel.com> (cherry picked from commit 8f7ce038f1178057733b7e765bf9160a2f9be14b) Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c71
1 files changed, 40 insertions, 31 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index ee8aa95967de..3581b5a7f716 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1108,6 +1108,44 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
1108 return ret; 1108 return ret;
1109} 1109}
1110 1110
1111static enum port intel_aux_port(struct drm_i915_private *dev_priv,
1112 enum port port)
1113{
1114 const struct ddi_vbt_port_info *info =
1115 &dev_priv->vbt.ddi_port_info[port];
1116 enum port aux_port;
1117
1118 if (!info->alternate_aux_channel) {
1119 DRM_DEBUG_KMS("using AUX %c for port %c (platform default)\n",
1120 port_name(port), port_name(port));
1121 return port;
1122 }
1123
1124 switch (info->alternate_aux_channel) {
1125 case DP_AUX_A:
1126 aux_port = PORT_A;
1127 break;
1128 case DP_AUX_B:
1129 aux_port = PORT_B;
1130 break;
1131 case DP_AUX_C:
1132 aux_port = PORT_C;
1133 break;
1134 case DP_AUX_D:
1135 aux_port = PORT_D;
1136 break;
1137 default:
1138 MISSING_CASE(info->alternate_aux_channel);
1139 aux_port = PORT_A;
1140 break;
1141 }
1142
1143 DRM_DEBUG_KMS("using AUX %c for port %c (VBT)\n",
1144 port_name(aux_port), port_name(port));
1145
1146 return aux_port;
1147}
1148
1111static i915_reg_t g4x_aux_ctl_reg(struct drm_i915_private *dev_priv, 1149static i915_reg_t g4x_aux_ctl_reg(struct drm_i915_private *dev_priv,
1112 enum port port) 1150 enum port port)
1113{ 1151{
@@ -1168,36 +1206,9 @@ static i915_reg_t ilk_aux_data_reg(struct drm_i915_private *dev_priv,
1168 } 1206 }
1169} 1207}
1170 1208
1171/*
1172 * On SKL we don't have Aux for port E so we rely
1173 * on VBT to set a proper alternate aux channel.
1174 */
1175static enum port skl_porte_aux_port(struct drm_i915_private *dev_priv)
1176{
1177 const struct ddi_vbt_port_info *info =
1178 &dev_priv->vbt.ddi_port_info[PORT_E];
1179
1180 switch (info->alternate_aux_channel) {
1181 case DP_AUX_A:
1182 return PORT_A;
1183 case DP_AUX_B:
1184 return PORT_B;
1185 case DP_AUX_C:
1186 return PORT_C;
1187 case DP_AUX_D:
1188 return PORT_D;
1189 default:
1190 MISSING_CASE(info->alternate_aux_channel);
1191 return PORT_A;
1192 }
1193}
1194
1195static i915_reg_t skl_aux_ctl_reg(struct drm_i915_private *dev_priv, 1209static i915_reg_t skl_aux_ctl_reg(struct drm_i915_private *dev_priv,
1196 enum port port) 1210 enum port port)
1197{ 1211{
1198 if (port == PORT_E)
1199 port = skl_porte_aux_port(dev_priv);
1200
1201 switch (port) { 1212 switch (port) {
1202 case PORT_A: 1213 case PORT_A:
1203 case PORT_B: 1214 case PORT_B:
@@ -1213,9 +1224,6 @@ static i915_reg_t skl_aux_ctl_reg(struct drm_i915_private *dev_priv,
1213static i915_reg_t skl_aux_data_reg(struct drm_i915_private *dev_priv, 1224static i915_reg_t skl_aux_data_reg(struct drm_i915_private *dev_priv,
1214 enum port port, int index) 1225 enum port port, int index)
1215{ 1226{
1216 if (port == PORT_E)
1217 port = skl_porte_aux_port(dev_priv);
1218
1219 switch (port) { 1227 switch (port) {
1220 case PORT_A: 1228 case PORT_A:
1221 case PORT_B: 1229 case PORT_B:
@@ -1253,7 +1261,8 @@ static i915_reg_t intel_aux_data_reg(struct drm_i915_private *dev_priv,
1253static void intel_aux_reg_init(struct intel_dp *intel_dp) 1261static void intel_aux_reg_init(struct intel_dp *intel_dp)
1254{ 1262{
1255 struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); 1263 struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
1256 enum port port = dp_to_dig_port(intel_dp)->port; 1264 enum port port = intel_aux_port(dev_priv,
1265 dp_to_dig_port(intel_dp)->port);
1257 int i; 1266 int i;
1258 1267
1259 intel_dp->aux_ch_ctl_reg = intel_aux_ctl_reg(dev_priv, port); 1268 intel_dp->aux_ch_ctl_reg = intel_aux_ctl_reg(dev_priv, port);