diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 94 |
1 files changed, 49 insertions, 45 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 2628d5622449..317e058fb3cf 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -202,15 +202,14 @@ struct intel_sdvo_connector { | |||
202 | u32 cur_dot_crawl, max_dot_crawl; | 202 | u32 cur_dot_crawl, max_dot_crawl; |
203 | }; | 203 | }; |
204 | 204 | ||
205 | static struct intel_sdvo *to_intel_sdvo(struct drm_encoder *encoder) | 205 | static struct intel_sdvo *to_sdvo(struct intel_encoder *encoder) |
206 | { | 206 | { |
207 | return container_of(encoder, struct intel_sdvo, base.base); | 207 | return container_of(encoder, struct intel_sdvo, base); |
208 | } | 208 | } |
209 | 209 | ||
210 | static struct intel_sdvo *intel_attached_sdvo(struct drm_connector *connector) | 210 | static struct intel_sdvo *intel_attached_sdvo(struct drm_connector *connector) |
211 | { | 211 | { |
212 | return container_of(intel_attached_encoder(connector), | 212 | return to_sdvo(intel_attached_encoder(connector)); |
213 | struct intel_sdvo, base); | ||
214 | } | 213 | } |
215 | 214 | ||
216 | static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) | 215 | static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) |
@@ -539,7 +538,8 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, | |||
539 | &status)) | 538 | &status)) |
540 | goto log_fail; | 539 | goto log_fail; |
541 | 540 | ||
542 | while (status == SDVO_CMD_STATUS_PENDING && --retry) { | 541 | while ((status == SDVO_CMD_STATUS_PENDING || |
542 | status == SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED) && --retry) { | ||
543 | if (retry < 10) | 543 | if (retry < 10) |
544 | msleep(15); | 544 | msleep(15); |
545 | else | 545 | else |
@@ -964,30 +964,32 @@ static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, | |||
964 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, | 964 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, |
965 | const struct drm_display_mode *adjusted_mode) | 965 | const struct drm_display_mode *adjusted_mode) |
966 | { | 966 | { |
967 | struct dip_infoframe avi_if = { | 967 | uint8_t sdvo_data[HDMI_INFOFRAME_SIZE(AVI)]; |
968 | .type = DIP_TYPE_AVI, | 968 | struct drm_crtc *crtc = intel_sdvo->base.base.crtc; |
969 | .ver = DIP_VERSION_AVI, | 969 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
970 | .len = DIP_LEN_AVI, | 970 | union hdmi_infoframe frame; |
971 | }; | 971 | int ret; |
972 | uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; | 972 | ssize_t len; |
973 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_sdvo->base.base.crtc); | 973 | |
974 | ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, | ||
975 | adjusted_mode); | ||
976 | if (ret < 0) { | ||
977 | DRM_ERROR("couldn't fill AVI infoframe\n"); | ||
978 | return false; | ||
979 | } | ||
974 | 980 | ||
975 | if (intel_sdvo->rgb_quant_range_selectable) { | 981 | if (intel_sdvo->rgb_quant_range_selectable) { |
976 | if (intel_crtc->config.limited_color_range) | 982 | if (intel_crtc->config.limited_color_range) |
977 | avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED; | 983 | frame.avi.quantization_range = |
984 | HDMI_QUANTIZATION_RANGE_LIMITED; | ||
978 | else | 985 | else |
979 | avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL; | 986 | frame.avi.quantization_range = |
987 | HDMI_QUANTIZATION_RANGE_FULL; | ||
980 | } | 988 | } |
981 | 989 | ||
982 | avi_if.body.avi.VIC = drm_match_cea_mode(adjusted_mode); | 990 | len = hdmi_infoframe_pack(&frame, sdvo_data, sizeof(sdvo_data)); |
983 | 991 | if (len < 0) | |
984 | intel_dip_infoframe_csum(&avi_if); | 992 | return false; |
985 | |||
986 | /* sdvo spec says that the ecc is handled by the hw, and it looks like | ||
987 | * we must not send the ecc field, either. */ | ||
988 | memcpy(sdvo_data, &avi_if, 3); | ||
989 | sdvo_data[3] = avi_if.checksum; | ||
990 | memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); | ||
991 | 993 | ||
992 | return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, | 994 | return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, |
993 | SDVO_HBUF_TX_VSYNC, | 995 | SDVO_HBUF_TX_VSYNC, |
@@ -1084,7 +1086,7 @@ static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_config *pipe_config) | |||
1084 | static bool intel_sdvo_compute_config(struct intel_encoder *encoder, | 1086 | static bool intel_sdvo_compute_config(struct intel_encoder *encoder, |
1085 | struct intel_crtc_config *pipe_config) | 1087 | struct intel_crtc_config *pipe_config) |
1086 | { | 1088 | { |
1087 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); | 1089 | struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
1088 | struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; | 1090 | struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; |
1089 | struct drm_display_mode *mode = &pipe_config->requested_mode; | 1091 | struct drm_display_mode *mode = &pipe_config->requested_mode; |
1090 | 1092 | ||
@@ -1154,7 +1156,7 @@ static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder) | |||
1154 | struct drm_display_mode *adjusted_mode = | 1156 | struct drm_display_mode *adjusted_mode = |
1155 | &intel_crtc->config.adjusted_mode; | 1157 | &intel_crtc->config.adjusted_mode; |
1156 | struct drm_display_mode *mode = &intel_crtc->config.requested_mode; | 1158 | struct drm_display_mode *mode = &intel_crtc->config.requested_mode; |
1157 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&intel_encoder->base); | 1159 | struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder); |
1158 | u32 sdvox; | 1160 | u32 sdvox; |
1159 | struct intel_sdvo_in_out_map in_out; | 1161 | struct intel_sdvo_in_out_map in_out; |
1160 | struct intel_sdvo_dtd input_dtd, output_dtd; | 1162 | struct intel_sdvo_dtd input_dtd, output_dtd; |
@@ -1292,7 +1294,7 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, | |||
1292 | { | 1294 | { |
1293 | struct drm_device *dev = encoder->base.dev; | 1295 | struct drm_device *dev = encoder->base.dev; |
1294 | struct drm_i915_private *dev_priv = dev->dev_private; | 1296 | struct drm_i915_private *dev_priv = dev->dev_private; |
1295 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); | 1297 | struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
1296 | u16 active_outputs = 0; | 1298 | u16 active_outputs = 0; |
1297 | u32 tmp; | 1299 | u32 tmp; |
1298 | 1300 | ||
@@ -1315,7 +1317,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, | |||
1315 | { | 1317 | { |
1316 | struct drm_device *dev = encoder->base.dev; | 1318 | struct drm_device *dev = encoder->base.dev; |
1317 | struct drm_i915_private *dev_priv = dev->dev_private; | 1319 | struct drm_i915_private *dev_priv = dev->dev_private; |
1318 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); | 1320 | struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
1319 | struct intel_sdvo_dtd dtd; | 1321 | struct intel_sdvo_dtd dtd; |
1320 | int encoder_pixel_multiplier = 0; | 1322 | int encoder_pixel_multiplier = 0; |
1321 | u32 flags = 0, sdvox; | 1323 | u32 flags = 0, sdvox; |
@@ -1357,22 +1359,21 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, | |||
1357 | } | 1359 | } |
1358 | 1360 | ||
1359 | /* Cross check the port pixel multiplier with the sdvo encoder state. */ | 1361 | /* Cross check the port pixel multiplier with the sdvo encoder state. */ |
1360 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT, &val, 1); | 1362 | if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT, |
1361 | switch (val) { | 1363 | &val, 1)) { |
1362 | case SDVO_CLOCK_RATE_MULT_1X: | 1364 | switch (val) { |
1363 | encoder_pixel_multiplier = 1; | 1365 | case SDVO_CLOCK_RATE_MULT_1X: |
1364 | break; | 1366 | encoder_pixel_multiplier = 1; |
1365 | case SDVO_CLOCK_RATE_MULT_2X: | 1367 | break; |
1366 | encoder_pixel_multiplier = 2; | 1368 | case SDVO_CLOCK_RATE_MULT_2X: |
1367 | break; | 1369 | encoder_pixel_multiplier = 2; |
1368 | case SDVO_CLOCK_RATE_MULT_4X: | 1370 | break; |
1369 | encoder_pixel_multiplier = 4; | 1371 | case SDVO_CLOCK_RATE_MULT_4X: |
1370 | break; | 1372 | encoder_pixel_multiplier = 4; |
1373 | break; | ||
1374 | } | ||
1371 | } | 1375 | } |
1372 | 1376 | ||
1373 | if(HAS_PCH_SPLIT(dev)) | ||
1374 | return; /* no pixel multiplier readout support yet */ | ||
1375 | |||
1376 | WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier, | 1377 | WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier, |
1377 | "SDVO pixel multiplier mismatch, port: %i, encoder: %i\n", | 1378 | "SDVO pixel multiplier mismatch, port: %i, encoder: %i\n", |
1378 | pipe_config->pixel_multiplier, encoder_pixel_multiplier); | 1379 | pipe_config->pixel_multiplier, encoder_pixel_multiplier); |
@@ -1381,7 +1382,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, | |||
1381 | static void intel_disable_sdvo(struct intel_encoder *encoder) | 1382 | static void intel_disable_sdvo(struct intel_encoder *encoder) |
1382 | { | 1383 | { |
1383 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | 1384 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
1384 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); | 1385 | struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
1385 | u32 temp; | 1386 | u32 temp; |
1386 | 1387 | ||
1387 | intel_sdvo_set_active_outputs(intel_sdvo, 0); | 1388 | intel_sdvo_set_active_outputs(intel_sdvo, 0); |
@@ -1423,7 +1424,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder) | |||
1423 | { | 1424 | { |
1424 | struct drm_device *dev = encoder->base.dev; | 1425 | struct drm_device *dev = encoder->base.dev; |
1425 | struct drm_i915_private *dev_priv = dev->dev_private; | 1426 | struct drm_i915_private *dev_priv = dev->dev_private; |
1426 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); | 1427 | struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
1427 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | 1428 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
1428 | u32 temp; | 1429 | u32 temp; |
1429 | bool input1, input2; | 1430 | bool input1, input2; |
@@ -1584,7 +1585,7 @@ static uint16_t intel_sdvo_get_hotplug_support(struct intel_sdvo *intel_sdvo) | |||
1584 | 1585 | ||
1585 | static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder) | 1586 | static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder) |
1586 | { | 1587 | { |
1587 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); | 1588 | struct intel_sdvo *intel_sdvo = to_sdvo(encoder); |
1588 | 1589 | ||
1589 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, | 1590 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, |
1590 | &intel_sdvo->hotplug_active, 2); | 1591 | &intel_sdvo->hotplug_active, 2); |
@@ -1697,6 +1698,9 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) | |||
1697 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); | 1698 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1698 | enum drm_connector_status ret; | 1699 | enum drm_connector_status ret; |
1699 | 1700 | ||
1701 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", | ||
1702 | connector->base.id, drm_get_connector_name(connector)); | ||
1703 | |||
1700 | if (!intel_sdvo_get_value(intel_sdvo, | 1704 | if (!intel_sdvo_get_value(intel_sdvo, |
1701 | SDVO_CMD_GET_ATTACHED_DISPLAYS, | 1705 | SDVO_CMD_GET_ATTACHED_DISPLAYS, |
1702 | &response, 2)) | 1706 | &response, 2)) |
@@ -2188,7 +2192,7 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs | |||
2188 | 2192 | ||
2189 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) | 2193 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) |
2190 | { | 2194 | { |
2191 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); | 2195 | struct intel_sdvo *intel_sdvo = to_sdvo(to_intel_encoder(encoder)); |
2192 | 2196 | ||
2193 | if (intel_sdvo->sdvo_lvds_fixed_mode != NULL) | 2197 | if (intel_sdvo->sdvo_lvds_fixed_mode != NULL) |
2194 | drm_mode_destroy(encoder->dev, | 2198 | drm_mode_destroy(encoder->dev, |