diff options
author | Dave Airlie <airlied@redhat.com> | 2010-04-19 23:11:45 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-04-19 23:11:45 -0400 |
commit | 97921a5b03d40681b3aed620a5e719710336c6df (patch) | |
tree | 33d6badc2afb50e87cbd232549c7708596ac12a7 /drivers/gpu/drm/i915/intel_sdvo.c | |
parent | 01bf0b64579ead8a82e7cfc32ae44bc667e7ad0f (diff) | |
parent | e15831656778d032f3c7655949f8cc3997f2b04a (diff) |
Merge remote branch 'anholt/drm-intel-next' of /home/airlied/kernel/drm-next into drm-core-next
* 'anholt/drm-intel-next' of /home/airlied/kernel/drm-next: (48 commits)
agp/intel-gtt: kill previous_size assignments
agp/intel-gtt: kill intel_i830_tlbflush
agp/intel: split out gmch/gtt probe, part 1
agp/intel: kill mutli_gmch_chip
agp/intel: uncoditionally reconfigure driver on resume
agp/intel: split out the GTT support
agp/intel: introduce intel-agp.h header file
drm/i915: Don't touch PORT_HOTPLUG_EN in intel_dp_detect()
drm/i915/pch: Use minimal number of FDI lanes (v2)
drm/i915: Add the support of memory self-refresh on Ironlake
drm/i915: Move Pineview CxSR and watermark code into update_wm hook.
drm/i915: Only save/restore FBC on the platform that supports FBC
drm/i915: Fix the incorrect argument for SDVO SET_TV_format command
drm/i915: Add support of SDVO on Ibexpeak PCH
drm/i915: Don't enable pipe/plane/VCO early (wait for DPMS on).
drm/i915: do not read uninitialized ->dev_private
Revert "drm/i915: Use a dmi quirk to skip a broken SDVO TV output."
drm/i915: implement multifunction SDVO device support
drm/i915: remove unused intel_pipe_get_connector()
drm/i915: remove connector object in old output structure
...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 933 |
1 files changed, 465 insertions, 468 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 87d953664cb0..42ceb15da689 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -36,7 +36,18 @@ | |||
36 | #include "i915_drm.h" | 36 | #include "i915_drm.h" |
37 | #include "i915_drv.h" | 37 | #include "i915_drv.h" |
38 | #include "intel_sdvo_regs.h" | 38 | #include "intel_sdvo_regs.h" |
39 | #include <linux/dmi.h> | 39 | |
40 | #define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1) | ||
41 | #define SDVO_RGB_MASK (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1) | ||
42 | #define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1) | ||
43 | #define SDVO_TV_MASK (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_SVID0) | ||
44 | |||
45 | #define SDVO_OUTPUT_MASK (SDVO_TMDS_MASK | SDVO_RGB_MASK | SDVO_LVDS_MASK |\ | ||
46 | SDVO_TV_MASK) | ||
47 | |||
48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) | ||
49 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) | ||
50 | |||
40 | 51 | ||
41 | static char *tv_format_names[] = { | 52 | static char *tv_format_names[] = { |
42 | "NTSC_M" , "NTSC_J" , "NTSC_443", | 53 | "NTSC_M" , "NTSC_J" , "NTSC_443", |
@@ -86,12 +97,6 @@ struct intel_sdvo_priv { | |||
86 | /* This is for current tv format name */ | 97 | /* This is for current tv format name */ |
87 | char *tv_format_name; | 98 | char *tv_format_name; |
88 | 99 | ||
89 | /* This contains all current supported TV format */ | ||
90 | char *tv_format_supported[TV_FORMAT_NUM]; | ||
91 | int format_supported_num; | ||
92 | struct drm_property *tv_format_property; | ||
93 | struct drm_property *tv_format_name_property[TV_FORMAT_NUM]; | ||
94 | |||
95 | /** | 100 | /** |
96 | * This is set if we treat the device as HDMI, instead of DVI. | 101 | * This is set if we treat the device as HDMI, instead of DVI. |
97 | */ | 102 | */ |
@@ -112,12 +117,6 @@ struct intel_sdvo_priv { | |||
112 | */ | 117 | */ |
113 | struct drm_display_mode *sdvo_lvds_fixed_mode; | 118 | struct drm_display_mode *sdvo_lvds_fixed_mode; |
114 | 119 | ||
115 | /** | ||
116 | * Returned SDTV resolutions allowed for the current format, if the | ||
117 | * device reported it. | ||
118 | */ | ||
119 | struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; | ||
120 | |||
121 | /* | 120 | /* |
122 | * supported encoding mode, used to determine whether HDMI is | 121 | * supported encoding mode, used to determine whether HDMI is |
123 | * supported | 122 | * supported |
@@ -130,11 +129,24 @@ struct intel_sdvo_priv { | |||
130 | /* Mac mini hack -- use the same DDC as the analog connector */ | 129 | /* Mac mini hack -- use the same DDC as the analog connector */ |
131 | struct i2c_adapter *analog_ddc_bus; | 130 | struct i2c_adapter *analog_ddc_bus; |
132 | 131 | ||
133 | int save_sdvo_mult; | 132 | }; |
134 | u16 save_active_outputs; | 133 | |
135 | struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; | 134 | struct intel_sdvo_connector { |
136 | struct intel_sdvo_dtd save_output_dtd[16]; | 135 | /* Mark the type of connector */ |
137 | u32 save_SDVOX; | 136 | uint16_t output_flag; |
137 | |||
138 | /* This contains all current supported TV format */ | ||
139 | char *tv_format_supported[TV_FORMAT_NUM]; | ||
140 | int format_supported_num; | ||
141 | struct drm_property *tv_format_property; | ||
142 | struct drm_property *tv_format_name_property[TV_FORMAT_NUM]; | ||
143 | |||
144 | /** | ||
145 | * Returned SDTV resolutions allowed for the current format, if the | ||
146 | * device reported it. | ||
147 | */ | ||
148 | struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; | ||
149 | |||
138 | /* add the property for the SDVO-TV */ | 150 | /* add the property for the SDVO-TV */ |
139 | struct drm_property *left_property; | 151 | struct drm_property *left_property; |
140 | struct drm_property *right_property; | 152 | struct drm_property *right_property; |
@@ -162,7 +174,12 @@ struct intel_sdvo_priv { | |||
162 | }; | 174 | }; |
163 | 175 | ||
164 | static bool | 176 | static bool |
165 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags); | 177 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, |
178 | uint16_t flags); | ||
179 | static void | ||
180 | intel_sdvo_tv_create_property(struct drm_connector *connector, int type); | ||
181 | static void | ||
182 | intel_sdvo_create_enhance_property(struct drm_connector *connector); | ||
166 | 183 | ||
167 | /** | 184 | /** |
168 | * Writes the SDVOB or SDVOC with the given value, but always writes both | 185 | * Writes the SDVOB or SDVOC with the given value, but always writes both |
@@ -171,12 +188,18 @@ intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags); | |||
171 | */ | 188 | */ |
172 | static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) | 189 | static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) |
173 | { | 190 | { |
174 | struct drm_device *dev = intel_encoder->base.dev; | 191 | struct drm_device *dev = intel_encoder->enc.dev; |
175 | struct drm_i915_private *dev_priv = dev->dev_private; | 192 | struct drm_i915_private *dev_priv = dev->dev_private; |
176 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 193 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
177 | u32 bval = val, cval = val; | 194 | u32 bval = val, cval = val; |
178 | int i; | 195 | int i; |
179 | 196 | ||
197 | if (sdvo_priv->sdvo_reg == PCH_SDVOB) { | ||
198 | I915_WRITE(sdvo_priv->sdvo_reg, val); | ||
199 | I915_READ(sdvo_priv->sdvo_reg); | ||
200 | return; | ||
201 | } | ||
202 | |||
180 | if (sdvo_priv->sdvo_reg == SDVOB) { | 203 | if (sdvo_priv->sdvo_reg == SDVOB) { |
181 | cval = I915_READ(SDVOC); | 204 | cval = I915_READ(SDVOC); |
182 | } else { | 205 | } else { |
@@ -353,7 +376,8 @@ static const struct _sdvo_cmd_name { | |||
353 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), | 376 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), |
354 | }; | 377 | }; |
355 | 378 | ||
356 | #define SDVO_NAME(dev_priv) ((dev_priv)->sdvo_reg == SDVOB ? "SDVOB" : "SDVOC") | 379 | #define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) |
380 | #define SDVO_NAME(dev_priv) (IS_SDVOB((dev_priv)->sdvo_reg) ? "SDVOB" : "SDVOC") | ||
357 | #define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) | 381 | #define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) |
358 | 382 | ||
359 | static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, | 383 | static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, |
@@ -563,17 +587,6 @@ static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, b | |||
563 | return true; | 587 | return true; |
564 | } | 588 | } |
565 | 589 | ||
566 | static bool intel_sdvo_get_active_outputs(struct intel_encoder *intel_encoder, | ||
567 | u16 *outputs) | ||
568 | { | ||
569 | u8 status; | ||
570 | |||
571 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0); | ||
572 | status = intel_sdvo_read_response(intel_encoder, outputs, sizeof(*outputs)); | ||
573 | |||
574 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
575 | } | ||
576 | |||
577 | static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder, | 590 | static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder, |
578 | u16 outputs) | 591 | u16 outputs) |
579 | { | 592 | { |
@@ -646,40 +659,6 @@ static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder, | |||
646 | return (status == SDVO_CMD_STATUS_SUCCESS); | 659 | return (status == SDVO_CMD_STATUS_SUCCESS); |
647 | } | 660 | } |
648 | 661 | ||
649 | static bool intel_sdvo_get_timing(struct intel_encoder *intel_encoder, u8 cmd, | ||
650 | struct intel_sdvo_dtd *dtd) | ||
651 | { | ||
652 | u8 status; | ||
653 | |||
654 | intel_sdvo_write_cmd(intel_encoder, cmd, NULL, 0); | ||
655 | status = intel_sdvo_read_response(intel_encoder, &dtd->part1, | ||
656 | sizeof(dtd->part1)); | ||
657 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
658 | return false; | ||
659 | |||
660 | intel_sdvo_write_cmd(intel_encoder, cmd + 1, NULL, 0); | ||
661 | status = intel_sdvo_read_response(intel_encoder, &dtd->part2, | ||
662 | sizeof(dtd->part2)); | ||
663 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
664 | return false; | ||
665 | |||
666 | return true; | ||
667 | } | ||
668 | |||
669 | static bool intel_sdvo_get_input_timing(struct intel_encoder *intel_encoder, | ||
670 | struct intel_sdvo_dtd *dtd) | ||
671 | { | ||
672 | return intel_sdvo_get_timing(intel_encoder, | ||
673 | SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd); | ||
674 | } | ||
675 | |||
676 | static bool intel_sdvo_get_output_timing(struct intel_encoder *intel_encoder, | ||
677 | struct intel_sdvo_dtd *dtd) | ||
678 | { | ||
679 | return intel_sdvo_get_timing(intel_encoder, | ||
680 | SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd); | ||
681 | } | ||
682 | |||
683 | static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd, | 662 | static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd, |
684 | struct intel_sdvo_dtd *dtd) | 663 | struct intel_sdvo_dtd *dtd) |
685 | { | 664 | { |
@@ -767,23 +746,6 @@ static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_en | |||
767 | return false; | 746 | return false; |
768 | } | 747 | } |
769 | 748 | ||
770 | static int intel_sdvo_get_clock_rate_mult(struct intel_encoder *intel_encoder) | ||
771 | { | ||
772 | u8 response, status; | ||
773 | |||
774 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0); | ||
775 | status = intel_sdvo_read_response(intel_encoder, &response, 1); | ||
776 | |||
777 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
778 | DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n"); | ||
779 | return SDVO_CLOCK_RATE_MULT_1X; | ||
780 | } else { | ||
781 | DRM_DEBUG_KMS("Current clock rate multiplier: %d\n", response); | ||
782 | } | ||
783 | |||
784 | return response; | ||
785 | } | ||
786 | |||
787 | static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val) | 749 | static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val) |
788 | { | 750 | { |
789 | u8 status; | 751 | u8 status; |
@@ -1071,7 +1033,7 @@ static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder) | |||
1071 | memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? | 1033 | memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? |
1072 | sizeof(format) : sizeof(format_map)); | 1034 | sizeof(format) : sizeof(format_map)); |
1073 | 1035 | ||
1074 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format_map, | 1036 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format, |
1075 | sizeof(format)); | 1037 | sizeof(format)); |
1076 | 1038 | ||
1077 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | 1039 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
@@ -1101,7 +1063,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1101 | /* Set output timings */ | 1063 | /* Set output timings */ |
1102 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); | 1064 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
1103 | intel_sdvo_set_target_output(intel_encoder, | 1065 | intel_sdvo_set_target_output(intel_encoder, |
1104 | dev_priv->controlled_output); | 1066 | dev_priv->attached_output); |
1105 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); | 1067 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); |
1106 | 1068 | ||
1107 | /* Set the input timing to the screen. Assume always input 0. */ | 1069 | /* Set the input timing to the screen. Assume always input 0. */ |
@@ -1139,7 +1101,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1139 | dev_priv->sdvo_lvds_fixed_mode); | 1101 | dev_priv->sdvo_lvds_fixed_mode); |
1140 | 1102 | ||
1141 | intel_sdvo_set_target_output(intel_encoder, | 1103 | intel_sdvo_set_target_output(intel_encoder, |
1142 | dev_priv->controlled_output); | 1104 | dev_priv->attached_output); |
1143 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); | 1105 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); |
1144 | 1106 | ||
1145 | /* Set the input timing to the screen. Assume always input 0. */ | 1107 | /* Set the input timing to the screen. Assume always input 0. */ |
@@ -1204,7 +1166,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1204 | * channel on the motherboard. In a two-input device, the first input | 1166 | * channel on the motherboard. In a two-input device, the first input |
1205 | * will be SDVOB and the second SDVOC. | 1167 | * will be SDVOB and the second SDVOC. |
1206 | */ | 1168 | */ |
1207 | in_out.in0 = sdvo_priv->controlled_output; | 1169 | in_out.in0 = sdvo_priv->attached_output; |
1208 | in_out.in1 = 0; | 1170 | in_out.in1 = 0; |
1209 | 1171 | ||
1210 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP, | 1172 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP, |
@@ -1230,7 +1192,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1230 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { | 1192 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { |
1231 | /* Set the output timing to the screen */ | 1193 | /* Set the output timing to the screen */ |
1232 | intel_sdvo_set_target_output(intel_encoder, | 1194 | intel_sdvo_set_target_output(intel_encoder, |
1233 | sdvo_priv->controlled_output); | 1195 | sdvo_priv->attached_output); |
1234 | intel_sdvo_set_output_timing(intel_encoder, &input_dtd); | 1196 | intel_sdvo_set_output_timing(intel_encoder, &input_dtd); |
1235 | } | 1197 | } |
1236 | 1198 | ||
@@ -1352,107 +1314,16 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | |||
1352 | 1314 | ||
1353 | if (0) | 1315 | if (0) |
1354 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); | 1316 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); |
1355 | intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->controlled_output); | 1317 | intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->attached_output); |
1356 | } | 1318 | } |
1357 | return; | 1319 | return; |
1358 | } | 1320 | } |
1359 | 1321 | ||
1360 | static void intel_sdvo_save(struct drm_connector *connector) | ||
1361 | { | ||
1362 | struct drm_device *dev = connector->dev; | ||
1363 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1364 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
1365 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1366 | int o; | ||
1367 | |||
1368 | sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_encoder); | ||
1369 | intel_sdvo_get_active_outputs(intel_encoder, &sdvo_priv->save_active_outputs); | ||
1370 | |||
1371 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { | ||
1372 | intel_sdvo_set_target_input(intel_encoder, true, false); | ||
1373 | intel_sdvo_get_input_timing(intel_encoder, | ||
1374 | &sdvo_priv->save_input_dtd_1); | ||
1375 | } | ||
1376 | |||
1377 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { | ||
1378 | intel_sdvo_set_target_input(intel_encoder, false, true); | ||
1379 | intel_sdvo_get_input_timing(intel_encoder, | ||
1380 | &sdvo_priv->save_input_dtd_2); | ||
1381 | } | ||
1382 | |||
1383 | for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++) | ||
1384 | { | ||
1385 | u16 this_output = (1 << o); | ||
1386 | if (sdvo_priv->caps.output_flags & this_output) | ||
1387 | { | ||
1388 | intel_sdvo_set_target_output(intel_encoder, this_output); | ||
1389 | intel_sdvo_get_output_timing(intel_encoder, | ||
1390 | &sdvo_priv->save_output_dtd[o]); | ||
1391 | } | ||
1392 | } | ||
1393 | if (sdvo_priv->is_tv) { | ||
1394 | /* XXX: Save TV format/enhancements. */ | ||
1395 | } | ||
1396 | |||
1397 | sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->sdvo_reg); | ||
1398 | } | ||
1399 | |||
1400 | static void intel_sdvo_restore(struct drm_connector *connector) | ||
1401 | { | ||
1402 | struct drm_device *dev = connector->dev; | ||
1403 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
1404 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1405 | int o; | ||
1406 | int i; | ||
1407 | bool input1, input2; | ||
1408 | u8 status; | ||
1409 | |||
1410 | intel_sdvo_set_active_outputs(intel_encoder, 0); | ||
1411 | |||
1412 | for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++) | ||
1413 | { | ||
1414 | u16 this_output = (1 << o); | ||
1415 | if (sdvo_priv->caps.output_flags & this_output) { | ||
1416 | intel_sdvo_set_target_output(intel_encoder, this_output); | ||
1417 | intel_sdvo_set_output_timing(intel_encoder, &sdvo_priv->save_output_dtd[o]); | ||
1418 | } | ||
1419 | } | ||
1420 | |||
1421 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { | ||
1422 | intel_sdvo_set_target_input(intel_encoder, true, false); | ||
1423 | intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_1); | ||
1424 | } | ||
1425 | |||
1426 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { | ||
1427 | intel_sdvo_set_target_input(intel_encoder, false, true); | ||
1428 | intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_2); | ||
1429 | } | ||
1430 | |||
1431 | intel_sdvo_set_clock_rate_mult(intel_encoder, sdvo_priv->save_sdvo_mult); | ||
1432 | |||
1433 | if (sdvo_priv->is_tv) { | ||
1434 | /* XXX: Restore TV format/enhancements. */ | ||
1435 | } | ||
1436 | |||
1437 | intel_sdvo_write_sdvox(intel_encoder, sdvo_priv->save_SDVOX); | ||
1438 | |||
1439 | if (sdvo_priv->save_SDVOX & SDVO_ENABLE) | ||
1440 | { | ||
1441 | for (i = 0; i < 2; i++) | ||
1442 | intel_wait_for_vblank(dev); | ||
1443 | status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2); | ||
1444 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) | ||
1445 | DRM_DEBUG_KMS("First %s output reported failure to " | ||
1446 | "sync\n", SDVO_NAME(sdvo_priv)); | ||
1447 | } | ||
1448 | |||
1449 | intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->save_active_outputs); | ||
1450 | } | ||
1451 | |||
1452 | static int intel_sdvo_mode_valid(struct drm_connector *connector, | 1322 | static int intel_sdvo_mode_valid(struct drm_connector *connector, |
1453 | struct drm_display_mode *mode) | 1323 | struct drm_display_mode *mode) |
1454 | { | 1324 | { |
1455 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1325 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1326 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1456 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1327 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1457 | 1328 | ||
1458 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 1329 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
@@ -1490,6 +1361,8 @@ static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, str | |||
1490 | return true; | 1361 | return true; |
1491 | } | 1362 | } |
1492 | 1363 | ||
1364 | /* No use! */ | ||
1365 | #if 0 | ||
1493 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) | 1366 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) |
1494 | { | 1367 | { |
1495 | struct drm_connector *connector = NULL; | 1368 | struct drm_connector *connector = NULL; |
@@ -1560,6 +1433,7 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) | |||
1560 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); | 1433 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
1561 | intel_sdvo_read_response(intel_encoder, &response, 2); | 1434 | intel_sdvo_read_response(intel_encoder, &response, 2); |
1562 | } | 1435 | } |
1436 | #endif | ||
1563 | 1437 | ||
1564 | static bool | 1438 | static bool |
1565 | intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder) | 1439 | intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder) |
@@ -1598,12 +1472,17 @@ static struct drm_connector * | |||
1598 | intel_find_analog_connector(struct drm_device *dev) | 1472 | intel_find_analog_connector(struct drm_device *dev) |
1599 | { | 1473 | { |
1600 | struct drm_connector *connector; | 1474 | struct drm_connector *connector; |
1475 | struct drm_encoder *encoder; | ||
1601 | struct intel_encoder *intel_encoder; | 1476 | struct intel_encoder *intel_encoder; |
1602 | 1477 | ||
1603 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1478 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1604 | intel_encoder = to_intel_encoder(connector); | 1479 | intel_encoder = enc_to_intel_encoder(encoder); |
1605 | if (intel_encoder->type == INTEL_OUTPUT_ANALOG) | 1480 | if (intel_encoder->type == INTEL_OUTPUT_ANALOG) { |
1606 | return connector; | 1481 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
1482 | if (connector && encoder == intel_attached_encoder(connector)) | ||
1483 | return connector; | ||
1484 | } | ||
1485 | } | ||
1607 | } | 1486 | } |
1608 | return NULL; | 1487 | return NULL; |
1609 | } | 1488 | } |
@@ -1627,12 +1506,13 @@ intel_analog_is_connected(struct drm_device *dev) | |||
1627 | enum drm_connector_status | 1506 | enum drm_connector_status |
1628 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | 1507 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) |
1629 | { | 1508 | { |
1630 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1509 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1510 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1631 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1511 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1632 | enum drm_connector_status status = connector_status_connected; | 1512 | enum drm_connector_status status = connector_status_connected; |
1633 | struct edid *edid = NULL; | 1513 | struct edid *edid = NULL; |
1634 | 1514 | ||
1635 | edid = drm_get_edid(&intel_encoder->base, | 1515 | edid = drm_get_edid(connector, |
1636 | intel_encoder->ddc_bus); | 1516 | intel_encoder->ddc_bus); |
1637 | 1517 | ||
1638 | /* This is only applied to SDVO cards with multiple outputs */ | 1518 | /* This is only applied to SDVO cards with multiple outputs */ |
@@ -1646,7 +1526,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1646 | */ | 1526 | */ |
1647 | while(temp_ddc > 1) { | 1527 | while(temp_ddc > 1) { |
1648 | sdvo_priv->ddc_bus = temp_ddc; | 1528 | sdvo_priv->ddc_bus = temp_ddc; |
1649 | edid = drm_get_edid(&intel_encoder->base, | 1529 | edid = drm_get_edid(connector, |
1650 | intel_encoder->ddc_bus); | 1530 | intel_encoder->ddc_bus); |
1651 | if (edid) { | 1531 | if (edid) { |
1652 | /* | 1532 | /* |
@@ -1666,8 +1546,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1666 | */ | 1546 | */ |
1667 | if (edid == NULL && | 1547 | if (edid == NULL && |
1668 | sdvo_priv->analog_ddc_bus && | 1548 | sdvo_priv->analog_ddc_bus && |
1669 | !intel_analog_is_connected(intel_encoder->base.dev)) | 1549 | !intel_analog_is_connected(connector->dev)) |
1670 | edid = drm_get_edid(&intel_encoder->base, | 1550 | edid = drm_get_edid(connector, |
1671 | sdvo_priv->analog_ddc_bus); | 1551 | sdvo_priv->analog_ddc_bus); |
1672 | if (edid != NULL) { | 1552 | if (edid != NULL) { |
1673 | /* Don't report the output as connected if it's a DVI-I | 1553 | /* Don't report the output as connected if it's a DVI-I |
@@ -1682,7 +1562,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1682 | } | 1562 | } |
1683 | 1563 | ||
1684 | kfree(edid); | 1564 | kfree(edid); |
1685 | intel_encoder->base.display_info.raw_edid = NULL; | 1565 | connector->display_info.raw_edid = NULL; |
1686 | 1566 | ||
1687 | } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | 1567 | } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) |
1688 | status = connector_status_disconnected; | 1568 | status = connector_status_disconnected; |
@@ -1694,8 +1574,12 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1694 | { | 1574 | { |
1695 | uint16_t response; | 1575 | uint16_t response; |
1696 | u8 status; | 1576 | u8 status; |
1697 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1577 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1578 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1579 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
1698 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1580 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1581 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1582 | enum drm_connector_status ret; | ||
1699 | 1583 | ||
1700 | intel_sdvo_write_cmd(intel_encoder, | 1584 | intel_sdvo_write_cmd(intel_encoder, |
1701 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | 1585 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); |
@@ -1713,24 +1597,41 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1713 | if (response == 0) | 1597 | if (response == 0) |
1714 | return connector_status_disconnected; | 1598 | return connector_status_disconnected; |
1715 | 1599 | ||
1716 | if (intel_sdvo_multifunc_encoder(intel_encoder) && | 1600 | sdvo_priv->attached_output = response; |
1717 | sdvo_priv->attached_output != response) { | 1601 | |
1718 | if (sdvo_priv->controlled_output != response && | 1602 | if ((sdvo_connector->output_flag & response) == 0) |
1719 | intel_sdvo_output_setup(intel_encoder, response) != true) | 1603 | ret = connector_status_disconnected; |
1720 | return connector_status_unknown; | 1604 | else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) |
1721 | sdvo_priv->attached_output = response; | 1605 | ret = intel_sdvo_hdmi_sink_detect(connector, response); |
1606 | else | ||
1607 | ret = connector_status_connected; | ||
1608 | |||
1609 | /* May update encoder flag for like clock for SDVO TV, etc.*/ | ||
1610 | if (ret == connector_status_connected) { | ||
1611 | sdvo_priv->is_tv = false; | ||
1612 | sdvo_priv->is_lvds = false; | ||
1613 | intel_encoder->needs_tv_clock = false; | ||
1614 | |||
1615 | if (response & SDVO_TV_MASK) { | ||
1616 | sdvo_priv->is_tv = true; | ||
1617 | intel_encoder->needs_tv_clock = true; | ||
1618 | } | ||
1619 | if (response & SDVO_LVDS_MASK) | ||
1620 | sdvo_priv->is_lvds = true; | ||
1722 | } | 1621 | } |
1723 | return intel_sdvo_hdmi_sink_detect(connector, response); | 1622 | |
1623 | return ret; | ||
1724 | } | 1624 | } |
1725 | 1625 | ||
1726 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1626 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
1727 | { | 1627 | { |
1728 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1628 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1629 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1729 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1630 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1730 | int num_modes; | 1631 | int num_modes; |
1731 | 1632 | ||
1732 | /* set the bus switch and get the modes */ | 1633 | /* set the bus switch and get the modes */ |
1733 | num_modes = intel_ddc_get_modes(intel_encoder); | 1634 | num_modes = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); |
1734 | 1635 | ||
1735 | /* | 1636 | /* |
1736 | * Mac mini hack. On this device, the DVI-I connector shares one DDC | 1637 | * Mac mini hack. On this device, the DVI-I connector shares one DDC |
@@ -1740,17 +1641,10 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | |||
1740 | */ | 1641 | */ |
1741 | if (num_modes == 0 && | 1642 | if (num_modes == 0 && |
1742 | sdvo_priv->analog_ddc_bus && | 1643 | sdvo_priv->analog_ddc_bus && |
1743 | !intel_analog_is_connected(intel_encoder->base.dev)) { | 1644 | !intel_analog_is_connected(connector->dev)) { |
1744 | struct i2c_adapter *digital_ddc_bus; | ||
1745 | |||
1746 | /* Switch to the analog ddc bus and try that | 1645 | /* Switch to the analog ddc bus and try that |
1747 | */ | 1646 | */ |
1748 | digital_ddc_bus = intel_encoder->ddc_bus; | 1647 | (void) intel_ddc_get_modes(connector, sdvo_priv->analog_ddc_bus); |
1749 | intel_encoder->ddc_bus = sdvo_priv->analog_ddc_bus; | ||
1750 | |||
1751 | (void) intel_ddc_get_modes(intel_encoder); | ||
1752 | |||
1753 | intel_encoder->ddc_bus = digital_ddc_bus; | ||
1754 | } | 1648 | } |
1755 | } | 1649 | } |
1756 | 1650 | ||
@@ -1821,8 +1715,9 @@ struct drm_display_mode sdvo_tv_modes[] = { | |||
1821 | 1715 | ||
1822 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | 1716 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) |
1823 | { | 1717 | { |
1824 | struct intel_encoder *output = to_intel_encoder(connector); | 1718 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1825 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1719 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
1720 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1826 | struct intel_sdvo_sdtv_resolution_request tv_res; | 1721 | struct intel_sdvo_sdtv_resolution_request tv_res; |
1827 | uint32_t reply = 0, format_map = 0; | 1722 | uint32_t reply = 0, format_map = 0; |
1828 | int i; | 1723 | int i; |
@@ -1842,11 +1737,11 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1842 | sizeof(format_map) ? sizeof(format_map) : | 1737 | sizeof(format_map) ? sizeof(format_map) : |
1843 | sizeof(struct intel_sdvo_sdtv_resolution_request)); | 1738 | sizeof(struct intel_sdvo_sdtv_resolution_request)); |
1844 | 1739 | ||
1845 | intel_sdvo_set_target_output(output, sdvo_priv->controlled_output); | 1740 | intel_sdvo_set_target_output(intel_encoder, sdvo_priv->attached_output); |
1846 | 1741 | ||
1847 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, | 1742 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, |
1848 | &tv_res, sizeof(tv_res)); | 1743 | &tv_res, sizeof(tv_res)); |
1849 | status = intel_sdvo_read_response(output, &reply, 3); | 1744 | status = intel_sdvo_read_response(intel_encoder, &reply, 3); |
1850 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1745 | if (status != SDVO_CMD_STATUS_SUCCESS) |
1851 | return; | 1746 | return; |
1852 | 1747 | ||
@@ -1863,7 +1758,8 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1863 | 1758 | ||
1864 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1759 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
1865 | { | 1760 | { |
1866 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1761 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1762 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1867 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1763 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1868 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1764 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1869 | struct drm_display_mode *newmode; | 1765 | struct drm_display_mode *newmode; |
@@ -1873,7 +1769,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1873 | * Assume that the preferred modes are | 1769 | * Assume that the preferred modes are |
1874 | * arranged in priority order. | 1770 | * arranged in priority order. |
1875 | */ | 1771 | */ |
1876 | intel_ddc_get_modes(intel_encoder); | 1772 | intel_ddc_get_modes(connector, intel_encoder->ddc_bus); |
1877 | if (list_empty(&connector->probed_modes) == false) | 1773 | if (list_empty(&connector->probed_modes) == false) |
1878 | goto end; | 1774 | goto end; |
1879 | 1775 | ||
@@ -1902,12 +1798,12 @@ end: | |||
1902 | 1798 | ||
1903 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1799 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
1904 | { | 1800 | { |
1905 | struct intel_encoder *output = to_intel_encoder(connector); | 1801 | struct intel_connector *intel_connector = to_intel_connector(connector); |
1906 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1802 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; |
1907 | 1803 | ||
1908 | if (sdvo_priv->is_tv) | 1804 | if (IS_TV(sdvo_connector)) |
1909 | intel_sdvo_get_tv_modes(connector); | 1805 | intel_sdvo_get_tv_modes(connector); |
1910 | else if (sdvo_priv->is_lvds == true) | 1806 | else if (IS_LVDS(sdvo_connector)) |
1911 | intel_sdvo_get_lvds_modes(connector); | 1807 | intel_sdvo_get_lvds_modes(connector); |
1912 | else | 1808 | else |
1913 | intel_sdvo_get_ddc_modes(connector); | 1809 | intel_sdvo_get_ddc_modes(connector); |
@@ -1920,11 +1816,11 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) | |||
1920 | static | 1816 | static |
1921 | void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | 1817 | void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) |
1922 | { | 1818 | { |
1923 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1819 | struct intel_connector *intel_connector = to_intel_connector(connector); |
1924 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1820 | struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv; |
1925 | struct drm_device *dev = connector->dev; | 1821 | struct drm_device *dev = connector->dev; |
1926 | 1822 | ||
1927 | if (sdvo_priv->is_tv) { | 1823 | if (IS_TV(sdvo_priv)) { |
1928 | if (sdvo_priv->left_property) | 1824 | if (sdvo_priv->left_property) |
1929 | drm_property_destroy(dev, sdvo_priv->left_property); | 1825 | drm_property_destroy(dev, sdvo_priv->left_property); |
1930 | if (sdvo_priv->right_property) | 1826 | if (sdvo_priv->right_property) |
@@ -1937,8 +1833,6 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | |||
1937 | drm_property_destroy(dev, sdvo_priv->hpos_property); | 1833 | drm_property_destroy(dev, sdvo_priv->hpos_property); |
1938 | if (sdvo_priv->vpos_property) | 1834 | if (sdvo_priv->vpos_property) |
1939 | drm_property_destroy(dev, sdvo_priv->vpos_property); | 1835 | drm_property_destroy(dev, sdvo_priv->vpos_property); |
1940 | } | ||
1941 | if (sdvo_priv->is_tv) { | ||
1942 | if (sdvo_priv->saturation_property) | 1836 | if (sdvo_priv->saturation_property) |
1943 | drm_property_destroy(dev, | 1837 | drm_property_destroy(dev, |
1944 | sdvo_priv->saturation_property); | 1838 | sdvo_priv->saturation_property); |
@@ -1948,7 +1842,7 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | |||
1948 | if (sdvo_priv->hue_property) | 1842 | if (sdvo_priv->hue_property) |
1949 | drm_property_destroy(dev, sdvo_priv->hue_property); | 1843 | drm_property_destroy(dev, sdvo_priv->hue_property); |
1950 | } | 1844 | } |
1951 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { | 1845 | if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) { |
1952 | if (sdvo_priv->brightness_property) | 1846 | if (sdvo_priv->brightness_property) |
1953 | drm_property_destroy(dev, | 1847 | drm_property_destroy(dev, |
1954 | sdvo_priv->brightness_property); | 1848 | sdvo_priv->brightness_property); |
@@ -1958,31 +1852,17 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | |||
1958 | 1852 | ||
1959 | static void intel_sdvo_destroy(struct drm_connector *connector) | 1853 | static void intel_sdvo_destroy(struct drm_connector *connector) |
1960 | { | 1854 | { |
1961 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1855 | struct intel_connector *intel_connector = to_intel_connector(connector); |
1962 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1856 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; |
1963 | 1857 | ||
1964 | if (intel_encoder->i2c_bus) | 1858 | if (sdvo_connector->tv_format_property) |
1965 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
1966 | if (intel_encoder->ddc_bus) | ||
1967 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
1968 | if (sdvo_priv->analog_ddc_bus) | ||
1969 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | ||
1970 | |||
1971 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | ||
1972 | drm_mode_destroy(connector->dev, | ||
1973 | sdvo_priv->sdvo_lvds_fixed_mode); | ||
1974 | |||
1975 | if (sdvo_priv->tv_format_property) | ||
1976 | drm_property_destroy(connector->dev, | 1859 | drm_property_destroy(connector->dev, |
1977 | sdvo_priv->tv_format_property); | 1860 | sdvo_connector->tv_format_property); |
1978 | |||
1979 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) | ||
1980 | intel_sdvo_destroy_enhance_property(connector); | ||
1981 | 1861 | ||
1862 | intel_sdvo_destroy_enhance_property(connector); | ||
1982 | drm_sysfs_connector_remove(connector); | 1863 | drm_sysfs_connector_remove(connector); |
1983 | drm_connector_cleanup(connector); | 1864 | drm_connector_cleanup(connector); |
1984 | 1865 | kfree(connector); | |
1985 | kfree(intel_encoder); | ||
1986 | } | 1866 | } |
1987 | 1867 | ||
1988 | static int | 1868 | static int |
@@ -1990,9 +1870,11 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1990 | struct drm_property *property, | 1870 | struct drm_property *property, |
1991 | uint64_t val) | 1871 | uint64_t val) |
1992 | { | 1872 | { |
1993 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1873 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1874 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1994 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1875 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1995 | struct drm_encoder *encoder = &intel_encoder->enc; | 1876 | struct intel_connector *intel_connector = to_intel_connector(connector); |
1877 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1996 | struct drm_crtc *crtc = encoder->crtc; | 1878 | struct drm_crtc *crtc = encoder->crtc; |
1997 | int ret = 0; | 1879 | int ret = 0; |
1998 | bool changed = false; | 1880 | bool changed = false; |
@@ -2003,101 +1885,101 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
2003 | if (ret < 0) | 1885 | if (ret < 0) |
2004 | goto out; | 1886 | goto out; |
2005 | 1887 | ||
2006 | if (property == sdvo_priv->tv_format_property) { | 1888 | if (property == sdvo_connector->tv_format_property) { |
2007 | if (val >= TV_FORMAT_NUM) { | 1889 | if (val >= TV_FORMAT_NUM) { |
2008 | ret = -EINVAL; | 1890 | ret = -EINVAL; |
2009 | goto out; | 1891 | goto out; |
2010 | } | 1892 | } |
2011 | if (sdvo_priv->tv_format_name == | 1893 | if (sdvo_priv->tv_format_name == |
2012 | sdvo_priv->tv_format_supported[val]) | 1894 | sdvo_connector->tv_format_supported[val]) |
2013 | goto out; | 1895 | goto out; |
2014 | 1896 | ||
2015 | sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[val]; | 1897 | sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[val]; |
2016 | changed = true; | 1898 | changed = true; |
2017 | } | 1899 | } |
2018 | 1900 | ||
2019 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { | 1901 | if (IS_TV(sdvo_connector) || IS_LVDS(sdvo_connector)) { |
2020 | cmd = 0; | 1902 | cmd = 0; |
2021 | temp_value = val; | 1903 | temp_value = val; |
2022 | if (sdvo_priv->left_property == property) { | 1904 | if (sdvo_connector->left_property == property) { |
2023 | drm_connector_property_set_value(connector, | 1905 | drm_connector_property_set_value(connector, |
2024 | sdvo_priv->right_property, val); | 1906 | sdvo_connector->right_property, val); |
2025 | if (sdvo_priv->left_margin == temp_value) | 1907 | if (sdvo_connector->left_margin == temp_value) |
2026 | goto out; | 1908 | goto out; |
2027 | 1909 | ||
2028 | sdvo_priv->left_margin = temp_value; | 1910 | sdvo_connector->left_margin = temp_value; |
2029 | sdvo_priv->right_margin = temp_value; | 1911 | sdvo_connector->right_margin = temp_value; |
2030 | temp_value = sdvo_priv->max_hscan - | 1912 | temp_value = sdvo_connector->max_hscan - |
2031 | sdvo_priv->left_margin; | 1913 | sdvo_connector->left_margin; |
2032 | cmd = SDVO_CMD_SET_OVERSCAN_H; | 1914 | cmd = SDVO_CMD_SET_OVERSCAN_H; |
2033 | } else if (sdvo_priv->right_property == property) { | 1915 | } else if (sdvo_connector->right_property == property) { |
2034 | drm_connector_property_set_value(connector, | 1916 | drm_connector_property_set_value(connector, |
2035 | sdvo_priv->left_property, val); | 1917 | sdvo_connector->left_property, val); |
2036 | if (sdvo_priv->right_margin == temp_value) | 1918 | if (sdvo_connector->right_margin == temp_value) |
2037 | goto out; | 1919 | goto out; |
2038 | 1920 | ||
2039 | sdvo_priv->left_margin = temp_value; | 1921 | sdvo_connector->left_margin = temp_value; |
2040 | sdvo_priv->right_margin = temp_value; | 1922 | sdvo_connector->right_margin = temp_value; |
2041 | temp_value = sdvo_priv->max_hscan - | 1923 | temp_value = sdvo_connector->max_hscan - |
2042 | sdvo_priv->left_margin; | 1924 | sdvo_connector->left_margin; |
2043 | cmd = SDVO_CMD_SET_OVERSCAN_H; | 1925 | cmd = SDVO_CMD_SET_OVERSCAN_H; |
2044 | } else if (sdvo_priv->top_property == property) { | 1926 | } else if (sdvo_connector->top_property == property) { |
2045 | drm_connector_property_set_value(connector, | 1927 | drm_connector_property_set_value(connector, |
2046 | sdvo_priv->bottom_property, val); | 1928 | sdvo_connector->bottom_property, val); |
2047 | if (sdvo_priv->top_margin == temp_value) | 1929 | if (sdvo_connector->top_margin == temp_value) |
2048 | goto out; | 1930 | goto out; |
2049 | 1931 | ||
2050 | sdvo_priv->top_margin = temp_value; | 1932 | sdvo_connector->top_margin = temp_value; |
2051 | sdvo_priv->bottom_margin = temp_value; | 1933 | sdvo_connector->bottom_margin = temp_value; |
2052 | temp_value = sdvo_priv->max_vscan - | 1934 | temp_value = sdvo_connector->max_vscan - |
2053 | sdvo_priv->top_margin; | 1935 | sdvo_connector->top_margin; |
2054 | cmd = SDVO_CMD_SET_OVERSCAN_V; | 1936 | cmd = SDVO_CMD_SET_OVERSCAN_V; |
2055 | } else if (sdvo_priv->bottom_property == property) { | 1937 | } else if (sdvo_connector->bottom_property == property) { |
2056 | drm_connector_property_set_value(connector, | 1938 | drm_connector_property_set_value(connector, |
2057 | sdvo_priv->top_property, val); | 1939 | sdvo_connector->top_property, val); |
2058 | if (sdvo_priv->bottom_margin == temp_value) | 1940 | if (sdvo_connector->bottom_margin == temp_value) |
2059 | goto out; | 1941 | goto out; |
2060 | sdvo_priv->top_margin = temp_value; | 1942 | sdvo_connector->top_margin = temp_value; |
2061 | sdvo_priv->bottom_margin = temp_value; | 1943 | sdvo_connector->bottom_margin = temp_value; |
2062 | temp_value = sdvo_priv->max_vscan - | 1944 | temp_value = sdvo_connector->max_vscan - |
2063 | sdvo_priv->top_margin; | 1945 | sdvo_connector->top_margin; |
2064 | cmd = SDVO_CMD_SET_OVERSCAN_V; | 1946 | cmd = SDVO_CMD_SET_OVERSCAN_V; |
2065 | } else if (sdvo_priv->hpos_property == property) { | 1947 | } else if (sdvo_connector->hpos_property == property) { |
2066 | if (sdvo_priv->cur_hpos == temp_value) | 1948 | if (sdvo_connector->cur_hpos == temp_value) |
2067 | goto out; | 1949 | goto out; |
2068 | 1950 | ||
2069 | cmd = SDVO_CMD_SET_POSITION_H; | 1951 | cmd = SDVO_CMD_SET_POSITION_H; |
2070 | sdvo_priv->cur_hpos = temp_value; | 1952 | sdvo_connector->cur_hpos = temp_value; |
2071 | } else if (sdvo_priv->vpos_property == property) { | 1953 | } else if (sdvo_connector->vpos_property == property) { |
2072 | if (sdvo_priv->cur_vpos == temp_value) | 1954 | if (sdvo_connector->cur_vpos == temp_value) |
2073 | goto out; | 1955 | goto out; |
2074 | 1956 | ||
2075 | cmd = SDVO_CMD_SET_POSITION_V; | 1957 | cmd = SDVO_CMD_SET_POSITION_V; |
2076 | sdvo_priv->cur_vpos = temp_value; | 1958 | sdvo_connector->cur_vpos = temp_value; |
2077 | } else if (sdvo_priv->saturation_property == property) { | 1959 | } else if (sdvo_connector->saturation_property == property) { |
2078 | if (sdvo_priv->cur_saturation == temp_value) | 1960 | if (sdvo_connector->cur_saturation == temp_value) |
2079 | goto out; | 1961 | goto out; |
2080 | 1962 | ||
2081 | cmd = SDVO_CMD_SET_SATURATION; | 1963 | cmd = SDVO_CMD_SET_SATURATION; |
2082 | sdvo_priv->cur_saturation = temp_value; | 1964 | sdvo_connector->cur_saturation = temp_value; |
2083 | } else if (sdvo_priv->contrast_property == property) { | 1965 | } else if (sdvo_connector->contrast_property == property) { |
2084 | if (sdvo_priv->cur_contrast == temp_value) | 1966 | if (sdvo_connector->cur_contrast == temp_value) |
2085 | goto out; | 1967 | goto out; |
2086 | 1968 | ||
2087 | cmd = SDVO_CMD_SET_CONTRAST; | 1969 | cmd = SDVO_CMD_SET_CONTRAST; |
2088 | sdvo_priv->cur_contrast = temp_value; | 1970 | sdvo_connector->cur_contrast = temp_value; |
2089 | } else if (sdvo_priv->hue_property == property) { | 1971 | } else if (sdvo_connector->hue_property == property) { |
2090 | if (sdvo_priv->cur_hue == temp_value) | 1972 | if (sdvo_connector->cur_hue == temp_value) |
2091 | goto out; | 1973 | goto out; |
2092 | 1974 | ||
2093 | cmd = SDVO_CMD_SET_HUE; | 1975 | cmd = SDVO_CMD_SET_HUE; |
2094 | sdvo_priv->cur_hue = temp_value; | 1976 | sdvo_connector->cur_hue = temp_value; |
2095 | } else if (sdvo_priv->brightness_property == property) { | 1977 | } else if (sdvo_connector->brightness_property == property) { |
2096 | if (sdvo_priv->cur_brightness == temp_value) | 1978 | if (sdvo_connector->cur_brightness == temp_value) |
2097 | goto out; | 1979 | goto out; |
2098 | 1980 | ||
2099 | cmd = SDVO_CMD_SET_BRIGHTNESS; | 1981 | cmd = SDVO_CMD_SET_BRIGHTNESS; |
2100 | sdvo_priv->cur_brightness = temp_value; | 1982 | sdvo_connector->cur_brightness = temp_value; |
2101 | } | 1983 | } |
2102 | if (cmd) { | 1984 | if (cmd) { |
2103 | intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2); | 1985 | intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2); |
@@ -2127,8 +2009,6 @@ static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | |||
2127 | 2009 | ||
2128 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | 2010 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { |
2129 | .dpms = drm_helper_connector_dpms, | 2011 | .dpms = drm_helper_connector_dpms, |
2130 | .save = intel_sdvo_save, | ||
2131 | .restore = intel_sdvo_restore, | ||
2132 | .detect = intel_sdvo_detect, | 2012 | .detect = intel_sdvo_detect, |
2133 | .fill_modes = drm_helper_probe_single_connector_modes, | 2013 | .fill_modes = drm_helper_probe_single_connector_modes, |
2134 | .set_property = intel_sdvo_set_property, | 2014 | .set_property = intel_sdvo_set_property, |
@@ -2138,12 +2018,27 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | |||
2138 | static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = { | 2018 | static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = { |
2139 | .get_modes = intel_sdvo_get_modes, | 2019 | .get_modes = intel_sdvo_get_modes, |
2140 | .mode_valid = intel_sdvo_mode_valid, | 2020 | .mode_valid = intel_sdvo_mode_valid, |
2141 | .best_encoder = intel_best_encoder, | 2021 | .best_encoder = intel_attached_encoder, |
2142 | }; | 2022 | }; |
2143 | 2023 | ||
2144 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) | 2024 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) |
2145 | { | 2025 | { |
2026 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
2027 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2028 | |||
2029 | if (intel_encoder->i2c_bus) | ||
2030 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
2031 | if (intel_encoder->ddc_bus) | ||
2032 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
2033 | if (sdvo_priv->analog_ddc_bus) | ||
2034 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | ||
2035 | |||
2036 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | ||
2037 | drm_mode_destroy(encoder->dev, | ||
2038 | sdvo_priv->sdvo_lvds_fixed_mode); | ||
2039 | |||
2146 | drm_encoder_cleanup(encoder); | 2040 | drm_encoder_cleanup(encoder); |
2041 | kfree(intel_encoder); | ||
2147 | } | 2042 | } |
2148 | 2043 | ||
2149 | static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | 2044 | static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { |
@@ -2196,12 +2091,15 @@ intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv) | |||
2196 | } | 2091 | } |
2197 | 2092 | ||
2198 | static bool | 2093 | static bool |
2199 | intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output) | 2094 | intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output, int device) |
2200 | { | 2095 | { |
2201 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 2096 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; |
2202 | uint8_t status; | 2097 | uint8_t status; |
2203 | 2098 | ||
2204 | intel_sdvo_set_target_output(output, sdvo_priv->controlled_output); | 2099 | if (device == 0) |
2100 | intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS0); | ||
2101 | else | ||
2102 | intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS1); | ||
2205 | 2103 | ||
2206 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0); | 2104 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0); |
2207 | status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1); | 2105 | status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1); |
@@ -2214,15 +2112,13 @@ static struct intel_encoder * | |||
2214 | intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan) | 2112 | intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan) |
2215 | { | 2113 | { |
2216 | struct drm_device *dev = chan->drm_dev; | 2114 | struct drm_device *dev = chan->drm_dev; |
2217 | struct drm_connector *connector; | 2115 | struct drm_encoder *encoder; |
2218 | struct intel_encoder *intel_encoder = NULL; | 2116 | struct intel_encoder *intel_encoder = NULL; |
2219 | 2117 | ||
2220 | list_for_each_entry(connector, | 2118 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
2221 | &dev->mode_config.connector_list, head) { | 2119 | intel_encoder = enc_to_intel_encoder(encoder); |
2222 | if (to_intel_encoder(connector)->ddc_bus == &chan->adapter) { | 2120 | if (intel_encoder->ddc_bus == &chan->adapter) |
2223 | intel_encoder = to_intel_encoder(connector); | ||
2224 | break; | 2121 | break; |
2225 | } | ||
2226 | } | 2122 | } |
2227 | return intel_encoder; | 2123 | return intel_encoder; |
2228 | } | 2124 | } |
@@ -2259,7 +2155,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) | |||
2259 | struct drm_i915_private *dev_priv = dev->dev_private; | 2155 | struct drm_i915_private *dev_priv = dev->dev_private; |
2260 | struct sdvo_device_mapping *my_mapping, *other_mapping; | 2156 | struct sdvo_device_mapping *my_mapping, *other_mapping; |
2261 | 2157 | ||
2262 | if (sdvo_reg == SDVOB) { | 2158 | if (IS_SDVOB(sdvo_reg)) { |
2263 | my_mapping = &dev_priv->sdvo_mappings[0]; | 2159 | my_mapping = &dev_priv->sdvo_mappings[0]; |
2264 | other_mapping = &dev_priv->sdvo_mappings[1]; | 2160 | other_mapping = &dev_priv->sdvo_mappings[1]; |
2265 | } else { | 2161 | } else { |
@@ -2284,120 +2180,235 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) | |||
2284 | /* No SDVO device info is found for another DVO port, | 2180 | /* No SDVO device info is found for another DVO port, |
2285 | * so use mapping assumption we had before BIOS parsing. | 2181 | * so use mapping assumption we had before BIOS parsing. |
2286 | */ | 2182 | */ |
2287 | if (sdvo_reg == SDVOB) | 2183 | if (IS_SDVOB(sdvo_reg)) |
2288 | return 0x70; | 2184 | return 0x70; |
2289 | else | 2185 | else |
2290 | return 0x72; | 2186 | return 0x72; |
2291 | } | 2187 | } |
2292 | 2188 | ||
2293 | static int intel_sdvo_bad_tv_callback(const struct dmi_system_id *id) | 2189 | static bool |
2190 | intel_sdvo_connector_alloc (struct intel_connector **ret) | ||
2294 | { | 2191 | { |
2295 | DRM_DEBUG_KMS("Ignoring bad SDVO TV connector for %s\n", id->ident); | 2192 | struct intel_connector *intel_connector; |
2296 | return 1; | 2193 | struct intel_sdvo_connector *sdvo_connector; |
2194 | |||
2195 | *ret = kzalloc(sizeof(*intel_connector) + | ||
2196 | sizeof(*sdvo_connector), GFP_KERNEL); | ||
2197 | if (!*ret) | ||
2198 | return false; | ||
2199 | |||
2200 | intel_connector = *ret; | ||
2201 | sdvo_connector = (struct intel_sdvo_connector *)(intel_connector + 1); | ||
2202 | intel_connector->dev_priv = sdvo_connector; | ||
2203 | |||
2204 | return true; | ||
2297 | } | 2205 | } |
2298 | 2206 | ||
2299 | static struct dmi_system_id intel_sdvo_bad_tv[] = { | 2207 | static void |
2300 | { | 2208 | intel_sdvo_connector_create (struct drm_encoder *encoder, |
2301 | .callback = intel_sdvo_bad_tv_callback, | 2209 | struct drm_connector *connector) |
2302 | .ident = "IntelG45/ICH10R/DME1737", | 2210 | { |
2303 | .matches = { | 2211 | drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs, |
2304 | DMI_MATCH(DMI_SYS_VENDOR, "IBM CORPORATION"), | 2212 | connector->connector_type); |
2305 | DMI_MATCH(DMI_PRODUCT_NAME, "4800784"), | ||
2306 | }, | ||
2307 | }, | ||
2308 | 2213 | ||
2309 | { } /* terminating entry */ | 2214 | drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs); |
2310 | }; | 2215 | |
2216 | connector->interlace_allowed = 0; | ||
2217 | connector->doublescan_allowed = 0; | ||
2218 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | ||
2219 | |||
2220 | drm_mode_connector_attach_encoder(connector, encoder); | ||
2221 | drm_sysfs_connector_add(connector); | ||
2222 | } | ||
2311 | 2223 | ||
2312 | static bool | 2224 | static bool |
2313 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags) | 2225 | intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device) |
2314 | { | 2226 | { |
2315 | struct drm_connector *connector = &intel_encoder->base; | ||
2316 | struct drm_encoder *encoder = &intel_encoder->enc; | 2227 | struct drm_encoder *encoder = &intel_encoder->enc; |
2317 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 2228 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
2318 | bool ret = true, registered = false; | 2229 | struct drm_connector *connector; |
2230 | struct intel_connector *intel_connector; | ||
2231 | struct intel_sdvo_connector *sdvo_connector; | ||
2232 | |||
2233 | if (!intel_sdvo_connector_alloc(&intel_connector)) | ||
2234 | return false; | ||
2235 | |||
2236 | sdvo_connector = intel_connector->dev_priv; | ||
2237 | |||
2238 | if (device == 0) { | ||
2239 | sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS0; | ||
2240 | sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; | ||
2241 | } else if (device == 1) { | ||
2242 | sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS1; | ||
2243 | sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; | ||
2244 | } | ||
2245 | |||
2246 | connector = &intel_connector->base; | ||
2247 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; | ||
2248 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; | ||
2249 | |||
2250 | if (intel_sdvo_get_supp_encode(intel_encoder, &sdvo_priv->encode) | ||
2251 | && intel_sdvo_get_digital_encoding_mode(intel_encoder, device) | ||
2252 | && sdvo_priv->is_hdmi) { | ||
2253 | /* enable hdmi encoding mode if supported */ | ||
2254 | intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI); | ||
2255 | intel_sdvo_set_colorimetry(intel_encoder, | ||
2256 | SDVO_COLORIMETRY_RGB256); | ||
2257 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | ||
2258 | } | ||
2259 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
2260 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
2261 | |||
2262 | intel_sdvo_connector_create(encoder, connector); | ||
2263 | |||
2264 | return true; | ||
2265 | } | ||
2266 | |||
2267 | static bool | ||
2268 | intel_sdvo_tv_init(struct intel_encoder *intel_encoder, int type) | ||
2269 | { | ||
2270 | struct drm_encoder *encoder = &intel_encoder->enc; | ||
2271 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2272 | struct drm_connector *connector; | ||
2273 | struct intel_connector *intel_connector; | ||
2274 | struct intel_sdvo_connector *sdvo_connector; | ||
2275 | |||
2276 | if (!intel_sdvo_connector_alloc(&intel_connector)) | ||
2277 | return false; | ||
2278 | |||
2279 | connector = &intel_connector->base; | ||
2280 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
2281 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
2282 | sdvo_connector = intel_connector->dev_priv; | ||
2283 | |||
2284 | sdvo_priv->controlled_output |= type; | ||
2285 | sdvo_connector->output_flag = type; | ||
2286 | |||
2287 | sdvo_priv->is_tv = true; | ||
2288 | intel_encoder->needs_tv_clock = true; | ||
2289 | intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | ||
2290 | |||
2291 | intel_sdvo_connector_create(encoder, connector); | ||
2292 | |||
2293 | intel_sdvo_tv_create_property(connector, type); | ||
2294 | |||
2295 | intel_sdvo_create_enhance_property(connector); | ||
2296 | |||
2297 | return true; | ||
2298 | } | ||
2299 | |||
2300 | static bool | ||
2301 | intel_sdvo_analog_init(struct intel_encoder *intel_encoder, int device) | ||
2302 | { | ||
2303 | struct drm_encoder *encoder = &intel_encoder->enc; | ||
2304 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2305 | struct drm_connector *connector; | ||
2306 | struct intel_connector *intel_connector; | ||
2307 | struct intel_sdvo_connector *sdvo_connector; | ||
2308 | |||
2309 | if (!intel_sdvo_connector_alloc(&intel_connector)) | ||
2310 | return false; | ||
2311 | |||
2312 | connector = &intel_connector->base; | ||
2313 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | ||
2314 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | ||
2315 | sdvo_connector = intel_connector->dev_priv; | ||
2316 | |||
2317 | if (device == 0) { | ||
2318 | sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB0; | ||
2319 | sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; | ||
2320 | } else if (device == 1) { | ||
2321 | sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB1; | ||
2322 | sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; | ||
2323 | } | ||
2324 | |||
2325 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
2326 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
2327 | |||
2328 | intel_sdvo_connector_create(encoder, connector); | ||
2329 | return true; | ||
2330 | } | ||
2331 | |||
2332 | static bool | ||
2333 | intel_sdvo_lvds_init(struct intel_encoder *intel_encoder, int device) | ||
2334 | { | ||
2335 | struct drm_encoder *encoder = &intel_encoder->enc; | ||
2336 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2337 | struct drm_connector *connector; | ||
2338 | struct intel_connector *intel_connector; | ||
2339 | struct intel_sdvo_connector *sdvo_connector; | ||
2340 | |||
2341 | if (!intel_sdvo_connector_alloc(&intel_connector)) | ||
2342 | return false; | ||
2343 | |||
2344 | connector = &intel_connector->base; | ||
2345 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | ||
2346 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
2347 | sdvo_connector = intel_connector->dev_priv; | ||
2348 | |||
2349 | sdvo_priv->is_lvds = true; | ||
2350 | |||
2351 | if (device == 0) { | ||
2352 | sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS0; | ||
2353 | sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; | ||
2354 | } else if (device == 1) { | ||
2355 | sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS1; | ||
2356 | sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; | ||
2357 | } | ||
2358 | |||
2359 | intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2360 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
2361 | |||
2362 | intel_sdvo_connector_create(encoder, connector); | ||
2363 | intel_sdvo_create_enhance_property(connector); | ||
2364 | return true; | ||
2365 | } | ||
2366 | |||
2367 | static bool | ||
2368 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags) | ||
2369 | { | ||
2370 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2319 | 2371 | ||
2320 | sdvo_priv->is_tv = false; | 2372 | sdvo_priv->is_tv = false; |
2321 | intel_encoder->needs_tv_clock = false; | 2373 | intel_encoder->needs_tv_clock = false; |
2322 | sdvo_priv->is_lvds = false; | 2374 | sdvo_priv->is_lvds = false; |
2323 | 2375 | ||
2324 | if (device_is_registered(&connector->kdev)) { | 2376 | /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ |
2325 | drm_sysfs_connector_remove(connector); | ||
2326 | registered = true; | ||
2327 | } | ||
2328 | 2377 | ||
2329 | if (flags & | 2378 | if (flags & SDVO_OUTPUT_TMDS0) |
2330 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | 2379 | if (!intel_sdvo_dvi_init(intel_encoder, 0)) |
2331 | if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) | 2380 | return false; |
2332 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0; | 2381 | |
2333 | else | 2382 | if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) |
2334 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1; | 2383 | if (!intel_sdvo_dvi_init(intel_encoder, 1)) |
2335 | 2384 | return false; | |
2336 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; | 2385 | |
2337 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; | 2386 | /* TV has no XXX1 function block */ |
2338 | 2387 | if (flags & SDVO_OUTPUT_SVID0) | |
2339 | if (intel_sdvo_get_supp_encode(intel_encoder, | 2388 | if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_SVID0)) |
2340 | &sdvo_priv->encode) && | 2389 | return false; |
2341 | intel_sdvo_get_digital_encoding_mode(intel_encoder) && | 2390 | |
2342 | sdvo_priv->is_hdmi) { | 2391 | if (flags & SDVO_OUTPUT_CVBS0) |
2343 | /* enable hdmi encoding mode if supported */ | 2392 | if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_CVBS0)) |
2344 | intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI); | 2393 | return false; |
2345 | intel_sdvo_set_colorimetry(intel_encoder, | ||
2346 | SDVO_COLORIMETRY_RGB256); | ||
2347 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | ||
2348 | intel_encoder->clone_mask = | ||
2349 | (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
2350 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
2351 | } | ||
2352 | } else if ((flags & SDVO_OUTPUT_SVID0) && | ||
2353 | !dmi_check_system(intel_sdvo_bad_tv)) { | ||
2354 | |||
2355 | sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; | ||
2356 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
2357 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
2358 | sdvo_priv->is_tv = true; | ||
2359 | intel_encoder->needs_tv_clock = true; | ||
2360 | intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | ||
2361 | } else if (flags & SDVO_OUTPUT_RGB0) { | ||
2362 | |||
2363 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; | ||
2364 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | ||
2365 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | ||
2366 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
2367 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
2368 | } else if (flags & SDVO_OUTPUT_RGB1) { | ||
2369 | |||
2370 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; | ||
2371 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | ||
2372 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | ||
2373 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
2374 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
2375 | } else if (flags & SDVO_OUTPUT_CVBS0) { | ||
2376 | |||
2377 | sdvo_priv->controlled_output = SDVO_OUTPUT_CVBS0; | ||
2378 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
2379 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
2380 | sdvo_priv->is_tv = true; | ||
2381 | intel_encoder->needs_tv_clock = true; | ||
2382 | intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | ||
2383 | } else if (flags & SDVO_OUTPUT_LVDS0) { | ||
2384 | |||
2385 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; | ||
2386 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | ||
2387 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
2388 | sdvo_priv->is_lvds = true; | ||
2389 | intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2390 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
2391 | } else if (flags & SDVO_OUTPUT_LVDS1) { | ||
2392 | |||
2393 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; | ||
2394 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | ||
2395 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
2396 | sdvo_priv->is_lvds = true; | ||
2397 | intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2398 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
2399 | } else { | ||
2400 | 2394 | ||
2395 | if (flags & SDVO_OUTPUT_RGB0) | ||
2396 | if (!intel_sdvo_analog_init(intel_encoder, 0)) | ||
2397 | return false; | ||
2398 | |||
2399 | if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) | ||
2400 | if (!intel_sdvo_analog_init(intel_encoder, 1)) | ||
2401 | return false; | ||
2402 | |||
2403 | if (flags & SDVO_OUTPUT_LVDS0) | ||
2404 | if (!intel_sdvo_lvds_init(intel_encoder, 0)) | ||
2405 | return false; | ||
2406 | |||
2407 | if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) | ||
2408 | if (!intel_sdvo_lvds_init(intel_encoder, 1)) | ||
2409 | return false; | ||
2410 | |||
2411 | if ((flags & SDVO_OUTPUT_MASK) == 0) { | ||
2401 | unsigned char bytes[2]; | 2412 | unsigned char bytes[2]; |
2402 | 2413 | ||
2403 | sdvo_priv->controlled_output = 0; | 2414 | sdvo_priv->controlled_output = 0; |
@@ -2405,28 +2416,25 @@ intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags) | |||
2405 | DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", | 2416 | DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", |
2406 | SDVO_NAME(sdvo_priv), | 2417 | SDVO_NAME(sdvo_priv), |
2407 | bytes[0], bytes[1]); | 2418 | bytes[0], bytes[1]); |
2408 | ret = false; | 2419 | return false; |
2409 | } | 2420 | } |
2410 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 2421 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
2411 | 2422 | ||
2412 | if (ret && registered) | 2423 | return true; |
2413 | ret = drm_sysfs_connector_add(connector) == 0 ? true : false; | ||
2414 | |||
2415 | |||
2416 | return ret; | ||
2417 | |||
2418 | } | 2424 | } |
2419 | 2425 | ||
2420 | static void intel_sdvo_tv_create_property(struct drm_connector *connector) | 2426 | static void intel_sdvo_tv_create_property(struct drm_connector *connector, int type) |
2421 | { | 2427 | { |
2422 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 2428 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
2429 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
2423 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 2430 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
2431 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
2432 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
2424 | struct intel_sdvo_tv_format format; | 2433 | struct intel_sdvo_tv_format format; |
2425 | uint32_t format_map, i; | 2434 | uint32_t format_map, i; |
2426 | uint8_t status; | 2435 | uint8_t status; |
2427 | 2436 | ||
2428 | intel_sdvo_set_target_output(intel_encoder, | 2437 | intel_sdvo_set_target_output(intel_encoder, type); |
2429 | sdvo_priv->controlled_output); | ||
2430 | 2438 | ||
2431 | intel_sdvo_write_cmd(intel_encoder, | 2439 | intel_sdvo_write_cmd(intel_encoder, |
2432 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); | 2440 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); |
@@ -2441,35 +2449,37 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector) | |||
2441 | if (format_map == 0) | 2449 | if (format_map == 0) |
2442 | return; | 2450 | return; |
2443 | 2451 | ||
2444 | sdvo_priv->format_supported_num = 0; | 2452 | sdvo_connector->format_supported_num = 0; |
2445 | for (i = 0 ; i < TV_FORMAT_NUM; i++) | 2453 | for (i = 0 ; i < TV_FORMAT_NUM; i++) |
2446 | if (format_map & (1 << i)) { | 2454 | if (format_map & (1 << i)) { |
2447 | sdvo_priv->tv_format_supported | 2455 | sdvo_connector->tv_format_supported |
2448 | [sdvo_priv->format_supported_num++] = | 2456 | [sdvo_connector->format_supported_num++] = |
2449 | tv_format_names[i]; | 2457 | tv_format_names[i]; |
2450 | } | 2458 | } |
2451 | 2459 | ||
2452 | 2460 | ||
2453 | sdvo_priv->tv_format_property = | 2461 | sdvo_connector->tv_format_property = |
2454 | drm_property_create( | 2462 | drm_property_create( |
2455 | connector->dev, DRM_MODE_PROP_ENUM, | 2463 | connector->dev, DRM_MODE_PROP_ENUM, |
2456 | "mode", sdvo_priv->format_supported_num); | 2464 | "mode", sdvo_connector->format_supported_num); |
2457 | 2465 | ||
2458 | for (i = 0; i < sdvo_priv->format_supported_num; i++) | 2466 | for (i = 0; i < sdvo_connector->format_supported_num; i++) |
2459 | drm_property_add_enum( | 2467 | drm_property_add_enum( |
2460 | sdvo_priv->tv_format_property, i, | 2468 | sdvo_connector->tv_format_property, i, |
2461 | i, sdvo_priv->tv_format_supported[i]); | 2469 | i, sdvo_connector->tv_format_supported[i]); |
2462 | 2470 | ||
2463 | sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[0]; | 2471 | sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[0]; |
2464 | drm_connector_attach_property( | 2472 | drm_connector_attach_property( |
2465 | connector, sdvo_priv->tv_format_property, 0); | 2473 | connector, sdvo_connector->tv_format_property, 0); |
2466 | 2474 | ||
2467 | } | 2475 | } |
2468 | 2476 | ||
2469 | static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | 2477 | static void intel_sdvo_create_enhance_property(struct drm_connector *connector) |
2470 | { | 2478 | { |
2471 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 2479 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
2472 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 2480 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
2481 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
2482 | struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv; | ||
2473 | struct intel_sdvo_enhancements_reply sdvo_data; | 2483 | struct intel_sdvo_enhancements_reply sdvo_data; |
2474 | struct drm_device *dev = connector->dev; | 2484 | struct drm_device *dev = connector->dev; |
2475 | uint8_t status; | 2485 | uint8_t status; |
@@ -2488,7 +2498,7 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2488 | DRM_DEBUG_KMS("No enhancement is supported\n"); | 2498 | DRM_DEBUG_KMS("No enhancement is supported\n"); |
2489 | return; | 2499 | return; |
2490 | } | 2500 | } |
2491 | if (sdvo_priv->is_tv) { | 2501 | if (IS_TV(sdvo_priv)) { |
2492 | /* when horizontal overscan is supported, Add the left/right | 2502 | /* when horizontal overscan is supported, Add the left/right |
2493 | * property | 2503 | * property |
2494 | */ | 2504 | */ |
@@ -2636,8 +2646,6 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2636 | "default %d, current %d\n", | 2646 | "default %d, current %d\n", |
2637 | data_value[0], data_value[1], response); | 2647 | data_value[0], data_value[1], response); |
2638 | } | 2648 | } |
2639 | } | ||
2640 | if (sdvo_priv->is_tv) { | ||
2641 | if (sdvo_data.saturation) { | 2649 | if (sdvo_data.saturation) { |
2642 | intel_sdvo_write_cmd(intel_encoder, | 2650 | intel_sdvo_write_cmd(intel_encoder, |
2643 | SDVO_CMD_GET_MAX_SATURATION, NULL, 0); | 2651 | SDVO_CMD_GET_MAX_SATURATION, NULL, 0); |
@@ -2733,7 +2741,7 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2733 | data_value[0], data_value[1], response); | 2741 | data_value[0], data_value[1], response); |
2734 | } | 2742 | } |
2735 | } | 2743 | } |
2736 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { | 2744 | if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) { |
2737 | if (sdvo_data.brightness) { | 2745 | if (sdvo_data.brightness) { |
2738 | intel_sdvo_write_cmd(intel_encoder, | 2746 | intel_sdvo_write_cmd(intel_encoder, |
2739 | SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); | 2747 | SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); |
@@ -2773,12 +2781,11 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2773 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | 2781 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) |
2774 | { | 2782 | { |
2775 | struct drm_i915_private *dev_priv = dev->dev_private; | 2783 | struct drm_i915_private *dev_priv = dev->dev_private; |
2776 | struct drm_connector *connector; | ||
2777 | struct intel_encoder *intel_encoder; | 2784 | struct intel_encoder *intel_encoder; |
2778 | struct intel_sdvo_priv *sdvo_priv; | 2785 | struct intel_sdvo_priv *sdvo_priv; |
2779 | |||
2780 | u8 ch[0x40]; | 2786 | u8 ch[0x40]; |
2781 | int i; | 2787 | int i; |
2788 | u32 i2c_reg, ddc_reg, analog_ddc_reg; | ||
2782 | 2789 | ||
2783 | intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 2790 | intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); |
2784 | if (!intel_encoder) { | 2791 | if (!intel_encoder) { |
@@ -2791,11 +2798,21 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2791 | intel_encoder->dev_priv = sdvo_priv; | 2798 | intel_encoder->dev_priv = sdvo_priv; |
2792 | intel_encoder->type = INTEL_OUTPUT_SDVO; | 2799 | intel_encoder->type = INTEL_OUTPUT_SDVO; |
2793 | 2800 | ||
2801 | if (HAS_PCH_SPLIT(dev)) { | ||
2802 | i2c_reg = PCH_GPIOE; | ||
2803 | ddc_reg = PCH_GPIOE; | ||
2804 | analog_ddc_reg = PCH_GPIOA; | ||
2805 | } else { | ||
2806 | i2c_reg = GPIOE; | ||
2807 | ddc_reg = GPIOE; | ||
2808 | analog_ddc_reg = GPIOA; | ||
2809 | } | ||
2810 | |||
2794 | /* setup the DDC bus. */ | 2811 | /* setup the DDC bus. */ |
2795 | if (sdvo_reg == SDVOB) | 2812 | if (IS_SDVOB(sdvo_reg)) |
2796 | intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); | 2813 | intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOB"); |
2797 | else | 2814 | else |
2798 | intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); | 2815 | intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOC"); |
2799 | 2816 | ||
2800 | if (!intel_encoder->i2c_bus) | 2817 | if (!intel_encoder->i2c_bus) |
2801 | goto err_inteloutput; | 2818 | goto err_inteloutput; |
@@ -2809,20 +2826,20 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2809 | for (i = 0; i < 0x40; i++) { | 2826 | for (i = 0; i < 0x40; i++) { |
2810 | if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { | 2827 | if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { |
2811 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", | 2828 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", |
2812 | sdvo_reg == SDVOB ? 'B' : 'C'); | 2829 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2813 | goto err_i2c; | 2830 | goto err_i2c; |
2814 | } | 2831 | } |
2815 | } | 2832 | } |
2816 | 2833 | ||
2817 | /* setup the DDC bus. */ | 2834 | /* setup the DDC bus. */ |
2818 | if (sdvo_reg == SDVOB) { | 2835 | if (IS_SDVOB(sdvo_reg)) { |
2819 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); | 2836 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); |
2820 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, | 2837 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
2821 | "SDVOB/VGA DDC BUS"); | 2838 | "SDVOB/VGA DDC BUS"); |
2822 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; | 2839 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; |
2823 | } else { | 2840 | } else { |
2824 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); | 2841 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); |
2825 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, | 2842 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
2826 | "SDVOC/VGA DDC BUS"); | 2843 | "SDVOC/VGA DDC BUS"); |
2827 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | 2844 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; |
2828 | } | 2845 | } |
@@ -2833,40 +2850,20 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2833 | /* Wrap with our custom algo which switches to DDC mode */ | 2850 | /* Wrap with our custom algo which switches to DDC mode */ |
2834 | intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; | 2851 | intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; |
2835 | 2852 | ||
2853 | /* encoder type will be decided later */ | ||
2854 | drm_encoder_init(dev, &intel_encoder->enc, &intel_sdvo_enc_funcs, 0); | ||
2855 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); | ||
2856 | |||
2836 | /* In default case sdvo lvds is false */ | 2857 | /* In default case sdvo lvds is false */ |
2837 | intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps); | 2858 | intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps); |
2838 | 2859 | ||
2839 | if (intel_sdvo_output_setup(intel_encoder, | 2860 | if (intel_sdvo_output_setup(intel_encoder, |
2840 | sdvo_priv->caps.output_flags) != true) { | 2861 | sdvo_priv->caps.output_flags) != true) { |
2841 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", | 2862 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", |
2842 | sdvo_reg == SDVOB ? 'B' : 'C'); | 2863 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2843 | goto err_i2c; | 2864 | goto err_i2c; |
2844 | } | 2865 | } |
2845 | 2866 | ||
2846 | |||
2847 | connector = &intel_encoder->base; | ||
2848 | drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, | ||
2849 | connector->connector_type); | ||
2850 | |||
2851 | drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs); | ||
2852 | connector->interlace_allowed = 0; | ||
2853 | connector->doublescan_allowed = 0; | ||
2854 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | ||
2855 | |||
2856 | drm_encoder_init(dev, &intel_encoder->enc, | ||
2857 | &intel_sdvo_enc_funcs, intel_encoder->enc.encoder_type); | ||
2858 | |||
2859 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); | ||
2860 | |||
2861 | drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); | ||
2862 | if (sdvo_priv->is_tv) | ||
2863 | intel_sdvo_tv_create_property(connector); | ||
2864 | |||
2865 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) | ||
2866 | intel_sdvo_create_enhance_property(connector); | ||
2867 | |||
2868 | drm_sysfs_connector_add(connector); | ||
2869 | |||
2870 | intel_sdvo_select_ddc_bus(sdvo_priv); | 2867 | intel_sdvo_select_ddc_bus(sdvo_priv); |
2871 | 2868 | ||
2872 | /* Set the input timing to the screen. Assume always input 0. */ | 2869 | /* Set the input timing to the screen. Assume always input 0. */ |