diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index b6a9d45fc3c6..2f5106a488c5 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -140,9 +140,6 @@ struct intel_sdvo { | |||
140 | 140 | ||
141 | /* DDC bus used by this SDVO encoder */ | 141 | /* DDC bus used by this SDVO encoder */ |
142 | uint8_t ddc_bus; | 142 | uint8_t ddc_bus; |
143 | |||
144 | /* Input timings for adjusted_mode */ | ||
145 | struct intel_sdvo_dtd input_dtd; | ||
146 | }; | 143 | }; |
147 | 144 | ||
148 | struct intel_sdvo_connector { | 145 | struct intel_sdvo_connector { |
@@ -953,11 +950,15 @@ intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, | |||
953 | return true; | 950 | return true; |
954 | } | 951 | } |
955 | 952 | ||
953 | /* Asks the sdvo controller for the preferred input mode given the output mode. | ||
954 | * Unfortunately we have to set up the full output mode to do that. */ | ||
956 | static bool | 955 | static bool |
957 | intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, | 956 | intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, |
958 | struct drm_display_mode *mode, | 957 | struct drm_display_mode *mode, |
959 | struct drm_display_mode *adjusted_mode) | 958 | struct drm_display_mode *adjusted_mode) |
960 | { | 959 | { |
960 | struct intel_sdvo_dtd input_dtd; | ||
961 | |||
961 | /* Reset the input timing to the screen. Assume always input 0. */ | 962 | /* Reset the input timing to the screen. Assume always input 0. */ |
962 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 963 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
963 | return false; | 964 | return false; |
@@ -969,10 +970,10 @@ intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, | |||
969 | return false; | 970 | return false; |
970 | 971 | ||
971 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, | 972 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, |
972 | &intel_sdvo->input_dtd)) | 973 | &input_dtd)) |
973 | return false; | 974 | return false; |
974 | 975 | ||
975 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &intel_sdvo->input_dtd); | 976 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
976 | 977 | ||
977 | return true; | 978 | return true; |
978 | } | 979 | } |
@@ -993,17 +994,17 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
993 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) | 994 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) |
994 | return false; | 995 | return false; |
995 | 996 | ||
996 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, | 997 | (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, |
997 | mode, | 998 | mode, |
998 | adjusted_mode); | 999 | adjusted_mode); |
999 | } else if (intel_sdvo->is_lvds) { | 1000 | } else if (intel_sdvo->is_lvds) { |
1000 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, | 1001 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, |
1001 | intel_sdvo->sdvo_lvds_fixed_mode)) | 1002 | intel_sdvo->sdvo_lvds_fixed_mode)) |
1002 | return false; | 1003 | return false; |
1003 | 1004 | ||
1004 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, | 1005 | (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, |
1005 | mode, | 1006 | mode, |
1006 | adjusted_mode); | 1007 | adjusted_mode); |
1007 | } | 1008 | } |
1008 | 1009 | ||
1009 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | 1010 | /* Make the CRTC code factor in the SDVO pixel multiplier. The |
@@ -1057,7 +1058,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1057 | intel_sdvo->sdvo_lvds_fixed_mode); | 1058 | intel_sdvo->sdvo_lvds_fixed_mode); |
1058 | else | 1059 | else |
1059 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); | 1060 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
1060 | (void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd); | 1061 | if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd)) |
1062 | DRM_INFO("Setting output timings on %s failed\n", | ||
1063 | SDVO_NAME(intel_sdvo)); | ||
1061 | 1064 | ||
1062 | /* Set the input timing to the screen. Assume always input 0. */ | 1065 | /* Set the input timing to the screen. Assume always input 0. */ |
1063 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 1066 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
@@ -1079,7 +1082,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1079 | * adjusted_mode. | 1082 | * adjusted_mode. |
1080 | */ | 1083 | */ |
1081 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1084 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1082 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); | 1085 | if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) |
1086 | DRM_INFO("Setting input timings on %s failed\n", | ||
1087 | SDVO_NAME(intel_sdvo)); | ||
1083 | 1088 | ||
1084 | switch (pixel_multiplier) { | 1089 | switch (pixel_multiplier) { |
1085 | default: | 1090 | default: |
@@ -1376,7 +1381,7 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) | |||
1376 | 1381 | ||
1377 | /* add 30ms delay when the output type might be TV */ | 1382 | /* add 30ms delay when the output type might be TV */ |
1378 | if (intel_sdvo->caps.output_flags & SDVO_TV_MASK) | 1383 | if (intel_sdvo->caps.output_flags & SDVO_TV_MASK) |
1379 | mdelay(30); | 1384 | msleep(30); |
1380 | 1385 | ||
1381 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) | 1386 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) |
1382 | return connector_status_unknown; | 1387 | return connector_status_unknown; |
@@ -2521,6 +2526,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2521 | struct drm_i915_private *dev_priv = dev->dev_private; | 2526 | struct drm_i915_private *dev_priv = dev->dev_private; |
2522 | struct intel_encoder *intel_encoder; | 2527 | struct intel_encoder *intel_encoder; |
2523 | struct intel_sdvo *intel_sdvo; | 2528 | struct intel_sdvo *intel_sdvo; |
2529 | u32 hotplug_mask; | ||
2524 | int i; | 2530 | int i; |
2525 | 2531 | ||
2526 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); | 2532 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); |
@@ -2552,10 +2558,18 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2552 | } | 2558 | } |
2553 | } | 2559 | } |
2554 | 2560 | ||
2555 | if (intel_sdvo->is_sdvob) | 2561 | hotplug_mask = 0; |
2556 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; | 2562 | if (IS_G4X(dev)) { |
2557 | else | 2563 | hotplug_mask = intel_sdvo->is_sdvob ? |
2558 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | 2564 | SDVOB_HOTPLUG_INT_STATUS_G4X : SDVOC_HOTPLUG_INT_STATUS_G4X; |
2565 | } else if (IS_GEN4(dev)) { | ||
2566 | hotplug_mask = intel_sdvo->is_sdvob ? | ||
2567 | SDVOB_HOTPLUG_INT_STATUS_I965 : SDVOC_HOTPLUG_INT_STATUS_I965; | ||
2568 | } else { | ||
2569 | hotplug_mask = intel_sdvo->is_sdvob ? | ||
2570 | SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915; | ||
2571 | } | ||
2572 | dev_priv->hotplug_supported_mask |= hotplug_mask; | ||
2559 | 2573 | ||
2560 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); | 2574 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); |
2561 | 2575 | ||