diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 89 |
1 files changed, 61 insertions, 28 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 093e914e8a4..ee73e428a84 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1061,8 +1061,9 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1061 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) | 1061 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) |
1062 | return false; | 1062 | return false; |
1063 | 1063 | ||
1064 | if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode)) | 1064 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, |
1065 | return false; | 1065 | mode, |
1066 | adjusted_mode); | ||
1066 | } else if (intel_sdvo->is_lvds) { | 1067 | } else if (intel_sdvo->is_lvds) { |
1067 | drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0); | 1068 | drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0); |
1068 | 1069 | ||
@@ -1070,8 +1071,9 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1070 | intel_sdvo->sdvo_lvds_fixed_mode)) | 1071 | intel_sdvo->sdvo_lvds_fixed_mode)) |
1071 | return false; | 1072 | return false; |
1072 | 1073 | ||
1073 | if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode)) | 1074 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, |
1074 | return false; | 1075 | mode, |
1076 | adjusted_mode); | ||
1075 | } | 1077 | } |
1076 | 1078 | ||
1077 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | 1079 | /* Make the CRTC code factor in the SDVO pixel multiplier. The |
@@ -1108,10 +1110,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1108 | in_out.in0 = intel_sdvo->attached_output; | 1110 | in_out.in0 = intel_sdvo->attached_output; |
1109 | in_out.in1 = 0; | 1111 | in_out.in1 = 0; |
1110 | 1112 | ||
1111 | if (!intel_sdvo_set_value(intel_sdvo, | 1113 | intel_sdvo_set_value(intel_sdvo, |
1112 | SDVO_CMD_SET_IN_OUT_MAP, | 1114 | SDVO_CMD_SET_IN_OUT_MAP, |
1113 | &in_out, sizeof(in_out))) | 1115 | &in_out, sizeof(in_out)); |
1114 | return; | ||
1115 | 1116 | ||
1116 | if (intel_sdvo->is_hdmi) { | 1117 | if (intel_sdvo->is_hdmi) { |
1117 | if (!intel_sdvo_set_avi_infoframe(intel_sdvo, mode)) | 1118 | if (!intel_sdvo_set_avi_infoframe(intel_sdvo, mode)) |
@@ -1122,11 +1123,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1122 | 1123 | ||
1123 | /* We have tried to get input timing in mode_fixup, and filled into | 1124 | /* We have tried to get input timing in mode_fixup, and filled into |
1124 | adjusted_mode */ | 1125 | adjusted_mode */ |
1125 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { | 1126 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1126 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1127 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) |
1127 | input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags; | 1128 | input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags; |
1128 | } else | ||
1129 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); | ||
1130 | 1129 | ||
1131 | /* If it's a TV, we already set the output timing in mode_fixup. | 1130 | /* If it's a TV, we already set the output timing in mode_fixup. |
1132 | * Otherwise, the output timing is equal to the input timing. | 1131 | * Otherwise, the output timing is equal to the input timing. |
@@ -1137,8 +1136,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1137 | intel_sdvo->attached_output)) | 1136 | intel_sdvo->attached_output)) |
1138 | return; | 1137 | return; |
1139 | 1138 | ||
1140 | if (!intel_sdvo_set_output_timing(intel_sdvo, &input_dtd)) | 1139 | (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); |
1141 | return; | ||
1142 | } | 1140 | } |
1143 | 1141 | ||
1144 | /* Set the input timing to the screen. Assume always input 0. */ | 1142 | /* Set the input timing to the screen. Assume always input 0. */ |
@@ -1165,8 +1163,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1165 | intel_sdvo_set_input_timing(encoder, &input_dtd); | 1163 | intel_sdvo_set_input_timing(encoder, &input_dtd); |
1166 | } | 1164 | } |
1167 | #else | 1165 | #else |
1168 | if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) | 1166 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); |
1169 | return; | ||
1170 | #endif | 1167 | #endif |
1171 | 1168 | ||
1172 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); | 1169 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); |
@@ -1420,7 +1417,7 @@ intel_analog_is_connected(struct drm_device *dev) | |||
1420 | if (!analog_connector) | 1417 | if (!analog_connector) |
1421 | return false; | 1418 | return false; |
1422 | 1419 | ||
1423 | if (analog_connector->funcs->detect(analog_connector) == | 1420 | if (analog_connector->funcs->detect(analog_connector, false) == |
1424 | connector_status_disconnected) | 1421 | connector_status_disconnected) |
1425 | return false; | 1422 | return false; |
1426 | 1423 | ||
@@ -1489,7 +1486,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1489 | return status; | 1486 | return status; |
1490 | } | 1487 | } |
1491 | 1488 | ||
1492 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) | 1489 | static enum drm_connector_status |
1490 | intel_sdvo_detect(struct drm_connector *connector, bool force) | ||
1493 | { | 1491 | { |
1494 | uint16_t response; | 1492 | uint16_t response; |
1495 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1493 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
@@ -1932,6 +1930,41 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | |||
1932 | .destroy = intel_sdvo_enc_destroy, | 1930 | .destroy = intel_sdvo_enc_destroy, |
1933 | }; | 1931 | }; |
1934 | 1932 | ||
1933 | static void | ||
1934 | intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo) | ||
1935 | { | ||
1936 | uint16_t mask = 0; | ||
1937 | unsigned int num_bits; | ||
1938 | |||
1939 | /* Make a mask of outputs less than or equal to our own priority in the | ||
1940 | * list. | ||
1941 | */ | ||
1942 | switch (sdvo->controlled_output) { | ||
1943 | case SDVO_OUTPUT_LVDS1: | ||
1944 | mask |= SDVO_OUTPUT_LVDS1; | ||
1945 | case SDVO_OUTPUT_LVDS0: | ||
1946 | mask |= SDVO_OUTPUT_LVDS0; | ||
1947 | case SDVO_OUTPUT_TMDS1: | ||
1948 | mask |= SDVO_OUTPUT_TMDS1; | ||
1949 | case SDVO_OUTPUT_TMDS0: | ||
1950 | mask |= SDVO_OUTPUT_TMDS0; | ||
1951 | case SDVO_OUTPUT_RGB1: | ||
1952 | mask |= SDVO_OUTPUT_RGB1; | ||
1953 | case SDVO_OUTPUT_RGB0: | ||
1954 | mask |= SDVO_OUTPUT_RGB0; | ||
1955 | break; | ||
1956 | } | ||
1957 | |||
1958 | /* Count bits to find what number we are in the priority list. */ | ||
1959 | mask &= sdvo->caps.output_flags; | ||
1960 | num_bits = hweight16(mask); | ||
1961 | /* If more than 3 outputs, default to DDC bus 3 for now. */ | ||
1962 | if (num_bits > 3) | ||
1963 | num_bits = 3; | ||
1964 | |||
1965 | /* Corresponds to SDVO_CONTROL_BUS_DDCx */ | ||
1966 | sdvo->ddc_bus = 1 << num_bits; | ||
1967 | } | ||
1935 | 1968 | ||
1936 | /** | 1969 | /** |
1937 | * Choose the appropriate DDC bus for control bus switch command for this | 1970 | * Choose the appropriate DDC bus for control bus switch command for this |
@@ -1951,7 +1984,10 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | |||
1951 | else | 1984 | else |
1952 | mapping = &(dev_priv->sdvo_mappings[1]); | 1985 | mapping = &(dev_priv->sdvo_mappings[1]); |
1953 | 1986 | ||
1954 | sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); | 1987 | if (mapping->initialized) |
1988 | sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); | ||
1989 | else | ||
1990 | intel_sdvo_guess_ddc_bus(sdvo); | ||
1955 | } | 1991 | } |
1956 | 1992 | ||
1957 | static bool | 1993 | static bool |
@@ -2134,8 +2170,7 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) | |||
2134 | return true; | 2170 | return true; |
2135 | 2171 | ||
2136 | err: | 2172 | err: |
2137 | intel_sdvo_destroy_enhance_property(connector); | 2173 | intel_sdvo_destroy(connector); |
2138 | kfree(intel_sdvo_connector); | ||
2139 | return false; | 2174 | return false; |
2140 | } | 2175 | } |
2141 | 2176 | ||
@@ -2207,8 +2242,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) | |||
2207 | return true; | 2242 | return true; |
2208 | 2243 | ||
2209 | err: | 2244 | err: |
2210 | intel_sdvo_destroy_enhance_property(connector); | 2245 | intel_sdvo_destroy(connector); |
2211 | kfree(intel_sdvo_connector); | ||
2212 | return false; | 2246 | return false; |
2213 | } | 2247 | } |
2214 | 2248 | ||
@@ -2486,11 +2520,10 @@ static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, | |||
2486 | uint16_t response; | 2520 | uint16_t response; |
2487 | } enhancements; | 2521 | } enhancements; |
2488 | 2522 | ||
2489 | if (!intel_sdvo_get_value(intel_sdvo, | 2523 | enhancements.response = 0; |
2490 | SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, | 2524 | intel_sdvo_get_value(intel_sdvo, |
2491 | &enhancements, sizeof(enhancements))) | 2525 | SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, |
2492 | return false; | 2526 | &enhancements, sizeof(enhancements)); |
2493 | |||
2494 | if (enhancements.response == 0) { | 2527 | if (enhancements.response == 0) { |
2495 | DRM_DEBUG_KMS("No enhancement is supported\n"); | 2528 | DRM_DEBUG_KMS("No enhancement is supported\n"); |
2496 | return true; | 2529 | return true; |