diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 75 |
1 files changed, 42 insertions, 33 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 14a3cf0b7213..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 | ||
1111 | static 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 | |||
1111 | static i915_reg_t g4x_aux_ctl_reg(struct drm_i915_private *dev_priv, | 1149 | static 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 | */ | ||
1175 | static 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 | |||
1195 | static i915_reg_t skl_aux_ctl_reg(struct drm_i915_private *dev_priv, | 1209 | static 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, | |||
1213 | static i915_reg_t skl_aux_data_reg(struct drm_i915_private *dev_priv, | 1224 | static 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, | |||
1253 | static void intel_aux_reg_init(struct intel_dp *intel_dp) | 1261 | static 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); |
@@ -3551,8 +3560,8 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp) | |||
3551 | /* Read the eDP Display control capabilities registers */ | 3560 | /* Read the eDP Display control capabilities registers */ |
3552 | if ((intel_dp->dpcd[DP_EDP_CONFIGURATION_CAP] & DP_DPCD_DISPLAY_CONTROL_CAPABLE) && | 3561 | if ((intel_dp->dpcd[DP_EDP_CONFIGURATION_CAP] & DP_DPCD_DISPLAY_CONTROL_CAPABLE) && |
3553 | drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV, | 3562 | drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV, |
3554 | intel_dp->edp_dpcd, sizeof(intel_dp->edp_dpcd) == | 3563 | intel_dp->edp_dpcd, sizeof(intel_dp->edp_dpcd)) == |
3555 | sizeof(intel_dp->edp_dpcd))) | 3564 | sizeof(intel_dp->edp_dpcd)) |
3556 | DRM_DEBUG_KMS("EDP DPCD : %*ph\n", (int) sizeof(intel_dp->edp_dpcd), | 3565 | DRM_DEBUG_KMS("EDP DPCD : %*ph\n", (int) sizeof(intel_dp->edp_dpcd), |
3557 | intel_dp->edp_dpcd); | 3566 | intel_dp->edp_dpcd); |
3558 | 3567 | ||