aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_sdvo.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c101
1 files changed, 44 insertions, 57 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 812fe7b06f87..701372e512a8 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -99,32 +99,13 @@ struct intel_sdvo {
99 */ 99 */
100 uint16_t hotplug_active; 100 uint16_t hotplug_active;
101 101
102 /**
103 * This is set if we're going to treat the device as TV-out.
104 *
105 * While we have these nice friendly flags for output types that ought
106 * to decide this for us, the S-Video output on our HDMI+S-Video card
107 * shows up as RGB1 (VGA).
108 */
109 bool is_tv;
110
111 enum port port; 102 enum port port;
112 103
113 /**
114 * This is set if we treat the device as HDMI, instead of DVI.
115 */
116 bool is_hdmi;
117 bool has_hdmi_monitor; 104 bool has_hdmi_monitor;
118 bool has_hdmi_audio; 105 bool has_hdmi_audio;
119 bool rgb_quant_range_selectable; 106 bool rgb_quant_range_selectable;
120 107
121 /** 108 /**
122 * This is set if we detect output of sdvo device as LVDS and
123 * have a valid fixed mode to use with the panel.
124 */
125 bool is_lvds;
126
127 /**
128 * This is sdvo fixed pannel mode pointer 109 * This is sdvo fixed pannel mode pointer
129 */ 110 */
130 struct drm_display_mode *sdvo_lvds_fixed_mode; 111 struct drm_display_mode *sdvo_lvds_fixed_mode;
@@ -172,6 +153,11 @@ struct intel_sdvo_connector {
172 153
173 /* this is to get the range of margin.*/ 154 /* this is to get the range of margin.*/
174 u32 max_hscan, max_vscan; 155 u32 max_hscan, max_vscan;
156
157 /**
158 * This is set if we treat the device as HDMI, instead of DVI.
159 */
160 bool is_hdmi;
175}; 161};
176 162
177struct intel_sdvo_connector_state { 163struct intel_sdvo_connector_state {
@@ -766,6 +752,7 @@ static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo,
766 752
767static bool 753static bool
768intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, 754intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
755 struct intel_sdvo_connector *intel_sdvo_connector,
769 uint16_t clock, 756 uint16_t clock,
770 uint16_t width, 757 uint16_t width,
771 uint16_t height) 758 uint16_t height)
@@ -778,7 +765,7 @@ intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
778 args.height = height; 765 args.height = height;
779 args.interlace = 0; 766 args.interlace = 0;
780 767
781 if (intel_sdvo->is_lvds && 768 if (IS_LVDS(intel_sdvo_connector) &&
782 (intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width || 769 (intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width ||
783 intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height)) 770 intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height))
784 args.scaled = 1; 771 args.scaled = 1;
@@ -1067,6 +1054,7 @@ intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,
1067 */ 1054 */
1068static bool 1055static bool
1069intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, 1056intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
1057 struct intel_sdvo_connector *intel_sdvo_connector,
1070 const struct drm_display_mode *mode, 1058 const struct drm_display_mode *mode,
1071 struct drm_display_mode *adjusted_mode) 1059 struct drm_display_mode *adjusted_mode)
1072{ 1060{
@@ -1077,6 +1065,7 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
1077 return false; 1065 return false;
1078 1066
1079 if (!intel_sdvo_create_preferred_input_timing(intel_sdvo, 1067 if (!intel_sdvo_create_preferred_input_timing(intel_sdvo,
1068 intel_sdvo_connector,
1080 mode->clock / 10, 1069 mode->clock / 10,
1081 mode->hdisplay, 1070 mode->hdisplay,
1082 mode->vdisplay)) 1071 mode->vdisplay))
@@ -1127,6 +1116,8 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1127 struct intel_sdvo *intel_sdvo = to_sdvo(encoder); 1116 struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
1128 struct intel_sdvo_connector_state *intel_sdvo_state = 1117 struct intel_sdvo_connector_state *intel_sdvo_state =
1129 to_intel_sdvo_connector_state(conn_state); 1118 to_intel_sdvo_connector_state(conn_state);
1119 struct intel_sdvo_connector *intel_sdvo_connector =
1120 to_intel_sdvo_connector(conn_state->connector);
1130 struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; 1121 struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
1131 struct drm_display_mode *mode = &pipe_config->base.mode; 1122 struct drm_display_mode *mode = &pipe_config->base.mode;
1132 1123
@@ -1142,20 +1133,22 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1142 * timings, even though this isn't really the right place in 1133 * timings, even though this isn't really the right place in
1143 * the sequence to do it. Oh well. 1134 * the sequence to do it. Oh well.
1144 */ 1135 */
1145 if (intel_sdvo->is_tv) { 1136 if (IS_TV(intel_sdvo_connector)) {
1146 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) 1137 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
1147 return false; 1138 return false;
1148 1139
1149 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, 1140 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
1141 intel_sdvo_connector,
1150 mode, 1142 mode,
1151 adjusted_mode); 1143 adjusted_mode);
1152 pipe_config->sdvo_tv_clock = true; 1144 pipe_config->sdvo_tv_clock = true;
1153 } else if (intel_sdvo->is_lvds) { 1145 } else if (IS_LVDS(intel_sdvo_connector)) {
1154 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, 1146 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
1155 intel_sdvo->sdvo_lvds_fixed_mode)) 1147 intel_sdvo->sdvo_lvds_fixed_mode))
1156 return false; 1148 return false;
1157 1149
1158 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, 1150 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
1151 intel_sdvo_connector,
1159 mode, 1152 mode,
1160 adjusted_mode); 1153 adjusted_mode);
1161 } 1154 }
@@ -1194,11 +1187,11 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1194 } 1187 }
1195 1188
1196 /* Clock computation needs to happen after pixel multiplier. */ 1189 /* Clock computation needs to happen after pixel multiplier. */
1197 if (intel_sdvo->is_tv) 1190 if (IS_TV(intel_sdvo_connector))
1198 i9xx_adjust_sdvo_tv_clock(pipe_config); 1191 i9xx_adjust_sdvo_tv_clock(pipe_config);
1199 1192
1200 /* Set user selected PAR to incoming mode's member */ 1193 /* Set user selected PAR to incoming mode's member */
1201 if (intel_sdvo->is_hdmi) 1194 if (intel_sdvo_connector->is_hdmi)
1202 adjusted_mode->picture_aspect_ratio = conn_state->picture_aspect_ratio; 1195 adjusted_mode->picture_aspect_ratio = conn_state->picture_aspect_ratio;
1203 1196
1204 return true; 1197 return true;
@@ -1275,6 +1268,8 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
1275 const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode; 1268 const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
1276 const struct intel_sdvo_connector_state *sdvo_state = 1269 const struct intel_sdvo_connector_state *sdvo_state =
1277 to_intel_sdvo_connector_state(conn_state); 1270 to_intel_sdvo_connector_state(conn_state);
1271 const struct intel_sdvo_connector *intel_sdvo_connector =
1272 to_intel_sdvo_connector(conn_state->connector);
1278 const struct drm_display_mode *mode = &crtc_state->base.mode; 1273 const struct drm_display_mode *mode = &crtc_state->base.mode;
1279 struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder); 1274 struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
1280 u32 sdvox; 1275 u32 sdvox;
@@ -1304,7 +1299,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
1304 return; 1299 return;
1305 1300
1306 /* lvds has a special fixed output timing. */ 1301 /* lvds has a special fixed output timing. */
1307 if (intel_sdvo->is_lvds) 1302 if (IS_LVDS(intel_sdvo_connector))
1308 intel_sdvo_get_dtd_from_mode(&output_dtd, 1303 intel_sdvo_get_dtd_from_mode(&output_dtd,
1309 intel_sdvo->sdvo_lvds_fixed_mode); 1304 intel_sdvo->sdvo_lvds_fixed_mode);
1310 else 1305 else
@@ -1325,13 +1320,13 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
1325 } else 1320 } else
1326 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI); 1321 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI);
1327 1322
1328 if (intel_sdvo->is_tv && 1323 if (IS_TV(intel_sdvo_connector) &&
1329 !intel_sdvo_set_tv_format(intel_sdvo, conn_state)) 1324 !intel_sdvo_set_tv_format(intel_sdvo, conn_state))
1330 return; 1325 return;
1331 1326
1332 intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); 1327 intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
1333 1328
1334 if (intel_sdvo->is_tv || intel_sdvo->is_lvds) 1329 if (IS_TV(intel_sdvo_connector) || IS_LVDS(intel_sdvo_connector))
1335 input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags; 1330 input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags;
1336 if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) 1331 if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd))
1337 DRM_INFO("Setting input timings on %s failed\n", 1332 DRM_INFO("Setting input timings on %s failed\n",
@@ -1630,6 +1625,8 @@ intel_sdvo_mode_valid(struct drm_connector *connector,
1630 struct drm_display_mode *mode) 1625 struct drm_display_mode *mode)
1631{ 1626{
1632 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); 1627 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
1628 struct intel_sdvo_connector *intel_sdvo_connector =
1629 to_intel_sdvo_connector(connector);
1633 int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; 1630 int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
1634 1631
1635 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 1632 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -1644,7 +1641,7 @@ intel_sdvo_mode_valid(struct drm_connector *connector,
1644 if (mode->clock > max_dotclk) 1641 if (mode->clock > max_dotclk)
1645 return MODE_CLOCK_HIGH; 1642 return MODE_CLOCK_HIGH;
1646 1643
1647 if (intel_sdvo->is_lvds) { 1644 if (IS_LVDS(intel_sdvo_connector)) {
1648 if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay) 1645 if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay)
1649 return MODE_PANEL; 1646 return MODE_PANEL;
1650 1647
@@ -1759,6 +1756,8 @@ static enum drm_connector_status
1759intel_sdvo_tmds_sink_detect(struct drm_connector *connector) 1756intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
1760{ 1757{
1761 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); 1758 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
1759 struct intel_sdvo_connector *intel_sdvo_connector =
1760 to_intel_sdvo_connector(connector);
1762 enum drm_connector_status status; 1761 enum drm_connector_status status;
1763 struct edid *edid; 1762 struct edid *edid;
1764 1763
@@ -1797,7 +1796,7 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
1797 /* DDC bus is shared, match EDID to connector type */ 1796 /* DDC bus is shared, match EDID to connector type */
1798 if (edid->input & DRM_EDID_INPUT_DIGITAL) { 1797 if (edid->input & DRM_EDID_INPUT_DIGITAL) {
1799 status = connector_status_connected; 1798 status = connector_status_connected;
1800 if (intel_sdvo->is_hdmi) { 1799 if (intel_sdvo_connector->is_hdmi) {
1801 intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); 1800 intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid);
1802 intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); 1801 intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid);
1803 intel_sdvo->rgb_quant_range_selectable = 1802 intel_sdvo->rgb_quant_range_selectable =
@@ -1875,17 +1874,6 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
1875 ret = connector_status_connected; 1874 ret = connector_status_connected;
1876 } 1875 }
1877 1876
1878 /* May update encoder flag for like clock for SDVO TV, etc.*/
1879 if (ret == connector_status_connected) {
1880 intel_sdvo->is_tv = false;
1881 intel_sdvo->is_lvds = false;
1882
1883 if (response & SDVO_TV_MASK)
1884 intel_sdvo->is_tv = true;
1885 if (response & SDVO_LVDS_MASK)
1886 intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL;
1887 }
1888
1889 return ret; 1877 return ret;
1890} 1878}
1891 1879
@@ -2054,16 +2042,6 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
2054 * arranged in priority order. 2042 * arranged in priority order.
2055 */ 2043 */
2056 intel_ddc_get_modes(connector, &intel_sdvo->ddc); 2044 intel_ddc_get_modes(connector, &intel_sdvo->ddc);
2057
2058 list_for_each_entry(newmode, &connector->probed_modes, head) {
2059 if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
2060 intel_sdvo->sdvo_lvds_fixed_mode =
2061 drm_mode_duplicate(connector->dev, newmode);
2062
2063 intel_sdvo->is_lvds = true;
2064 break;
2065 }
2066 }
2067} 2045}
2068 2046
2069static int intel_sdvo_get_modes(struct drm_connector *connector) 2047static int intel_sdvo_get_modes(struct drm_connector *connector)
@@ -2555,7 +2533,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
2555 if (INTEL_GEN(dev_priv) >= 4 && 2533 if (INTEL_GEN(dev_priv) >= 4 &&
2556 intel_sdvo_is_hdmi_connector(intel_sdvo, device)) { 2534 intel_sdvo_is_hdmi_connector(intel_sdvo, device)) {
2557 connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; 2535 connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
2558 intel_sdvo->is_hdmi = true; 2536 intel_sdvo_connector->is_hdmi = true;
2559 } 2537 }
2560 2538
2561 if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { 2539 if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
@@ -2563,7 +2541,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
2563 return false; 2541 return false;
2564 } 2542 }
2565 2543
2566 if (intel_sdvo->is_hdmi) 2544 if (intel_sdvo_connector->is_hdmi)
2567 intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector); 2545 intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector);
2568 2546
2569 return true; 2547 return true;
@@ -2591,8 +2569,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
2591 intel_sdvo->controlled_output |= type; 2569 intel_sdvo->controlled_output |= type;
2592 intel_sdvo_connector->output_flag = type; 2570 intel_sdvo_connector->output_flag = type;
2593 2571
2594 intel_sdvo->is_tv = true;
2595
2596 if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { 2572 if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
2597 kfree(intel_sdvo_connector); 2573 kfree(intel_sdvo_connector);
2598 return false; 2574 return false;
@@ -2654,6 +2630,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
2654 struct drm_connector *connector; 2630 struct drm_connector *connector;
2655 struct intel_connector *intel_connector; 2631 struct intel_connector *intel_connector;
2656 struct intel_sdvo_connector *intel_sdvo_connector; 2632 struct intel_sdvo_connector *intel_sdvo_connector;
2633 struct drm_display_mode *mode;
2657 2634
2658 DRM_DEBUG_KMS("initialising LVDS device %d\n", device); 2635 DRM_DEBUG_KMS("initialising LVDS device %d\n", device);
2659 2636
@@ -2682,6 +2659,19 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
2682 if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) 2659 if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
2683 goto err; 2660 goto err;
2684 2661
2662 intel_sdvo_get_lvds_modes(connector);
2663
2664 list_for_each_entry(mode, &connector->probed_modes, head) {
2665 if (mode->type & DRM_MODE_TYPE_PREFERRED) {
2666 intel_sdvo->sdvo_lvds_fixed_mode =
2667 drm_mode_duplicate(connector->dev, mode);
2668 break;
2669 }
2670 }
2671
2672 if (!intel_sdvo->sdvo_lvds_fixed_mode)
2673 goto err;
2674
2685 return true; 2675 return true;
2686 2676
2687err: 2677err:
@@ -2692,9 +2682,6 @@ err:
2692static bool 2682static bool
2693intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) 2683intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags)
2694{ 2684{
2695 intel_sdvo->is_tv = false;
2696 intel_sdvo->is_lvds = false;
2697
2698 /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ 2685 /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
2699 2686
2700 if (flags & SDVO_OUTPUT_TMDS0) 2687 if (flags & SDVO_OUTPUT_TMDS0)