Rev 2342 | Rev 3120 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2342 | Rev 3031 | ||
---|---|---|---|
Line 24... | Line 24... | ||
24 | * Eric Anholt |
24 | * Eric Anholt |
25 | */ |
25 | */ |
Line 26... | Line 26... | ||
26 | 26 | ||
27 | #include |
27 | #include |
28 | #include |
28 | #include |
29 | #include "drmP.h" |
- | |
30 | #include "drm.h" |
29 | #include |
31 | #include "drm_crtc.h" |
30 | #include |
32 | #include "drm_crtc_helper.h" |
31 | #include |
33 | #include "drm_edid.h" |
32 | #include |
34 | #include "intel_drv.h" |
33 | #include "intel_drv.h" |
35 | #include "i915_drm.h" |
34 | #include |
Line 36... | Line 35... | ||
36 | #include "i915_drv.h" |
35 | #include "i915_drv.h" |
37 | 36 | ||
38 | /* Here's the desired hotplug mode */ |
37 | /* Here's the desired hotplug mode */ |
Line 44... | Line 43... | ||
44 | ADPA_CRT_HOTPLUG_ENABLE) |
43 | ADPA_CRT_HOTPLUG_ENABLE) |
Line 45... | Line 44... | ||
45 | 44 | ||
46 | struct intel_crt { |
45 | struct intel_crt { |
47 | struct intel_encoder base; |
46 | struct intel_encoder base; |
- | 47 | bool force_hotplug_required; |
|
48 | bool force_hotplug_required; |
48 | u32 adpa_reg; |
Line 49... | Line 49... | ||
49 | }; |
49 | }; |
50 | 50 | ||
51 | static struct intel_crt *intel_attached_crt(struct drm_connector *connector) |
51 | static struct intel_crt *intel_attached_crt(struct drm_connector *connector) |
52 | { |
52 | { |
53 | return container_of(intel_attached_encoder(connector), |
53 | return container_of(intel_attached_encoder(connector), |
Line 54... | Line 54... | ||
54 | struct intel_crt, base); |
54 | struct intel_crt, base); |
55 | } |
55 | } |
- | 56 | ||
- | 57 | static struct intel_crt *intel_encoder_to_crt(struct intel_encoder *encoder) |
|
- | 58 | { |
|
- | 59 | return container_of(encoder, struct intel_crt, base); |
|
- | 60 | } |
|
- | 61 | ||
56 | 62 | static bool intel_crt_get_hw_state(struct intel_encoder *encoder, |
|
57 | static void intel_crt_dpms(struct drm_encoder *encoder, int mode) |
63 | enum pipe *pipe) |
- | 64 | { |
|
58 | { |
65 | struct drm_device *dev = encoder->base.dev; |
Line -... | Line 66... | ||
- | 66 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 67 | struct intel_crt *crt = intel_encoder_to_crt(encoder); |
|
- | 68 | u32 tmp; |
|
- | 69 | ||
- | 70 | tmp = I915_READ(crt->adpa_reg); |
|
59 | struct drm_device *dev = encoder->dev; |
71 | |
60 | struct drm_i915_private *dev_priv = dev->dev_private; |
72 | if (!(tmp & ADPA_DAC_ENABLE)) |
61 | u32 temp, reg; |
73 | return false; |
- | 74 | ||
- | 75 | if (HAS_PCH_CPT(dev)) |
|
62 | 76 | *pipe = PORT_TO_PIPE_CPT(tmp); |
|
- | 77 | else |
|
- | 78 | *pipe = PORT_TO_PIPE(tmp); |
|
- | 79 | ||
- | 80 | return true; |
|
- | 81 | } |
|
- | 82 | ||
- | 83 | static void intel_disable_crt(struct intel_encoder *encoder) |
|
- | 84 | { |
|
- | 85 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
|
- | 86 | struct intel_crt *crt = intel_encoder_to_crt(encoder); |
|
- | 87 | u32 temp; |
|
- | 88 | ||
- | 89 | temp = I915_READ(crt->adpa_reg); |
|
- | 90 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); |
|
- | 91 | temp &= ~ADPA_DAC_ENABLE; |
|
- | 92 | I915_WRITE(crt->adpa_reg, temp); |
|
- | 93 | } |
|
- | 94 | ||
- | 95 | static void intel_enable_crt(struct intel_encoder *encoder) |
|
- | 96 | { |
|
- | 97 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
|
- | 98 | struct intel_crt *crt = intel_encoder_to_crt(encoder); |
|
- | 99 | u32 temp; |
|
- | 100 | ||
- | 101 | temp = I915_READ(crt->adpa_reg); |
|
- | 102 | temp |= ADPA_DAC_ENABLE; |
|
- | 103 | I915_WRITE(crt->adpa_reg, temp); |
|
- | 104 | } |
|
- | 105 | ||
- | 106 | /* Note: The caller is required to filter out dpms modes not supported by the |
|
- | 107 | * platform. */ |
|
- | 108 | static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) |
|
- | 109 | { |
|
Line 63... | Line 110... | ||
63 | if (HAS_PCH_SPLIT(dev)) |
110 | struct drm_device *dev = encoder->base.dev; |
64 | reg = PCH_ADPA; |
111 | struct drm_i915_private *dev_priv = dev->dev_private; |
65 | else |
112 | struct intel_crt *crt = intel_encoder_to_crt(encoder); |
Line 66... | Line 113... | ||
66 | reg = ADPA; |
113 | u32 temp; |
67 | 114 | ||
Line 82... | Line 129... | ||
82 | case DRM_MODE_DPMS_OFF: |
129 | case DRM_MODE_DPMS_OFF: |
83 | temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE; |
130 | temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE; |
84 | break; |
131 | break; |
85 | } |
132 | } |
Line 86... | Line 133... | ||
86 | 133 | ||
- | 134 | I915_WRITE(crt->adpa_reg, temp); |
|
- | 135 | } |
|
- | 136 | ||
- | 137 | static void intel_crt_dpms(struct drm_connector *connector, int mode) |
|
- | 138 | { |
|
- | 139 | struct drm_device *dev = connector->dev; |
|
- | 140 | struct intel_encoder *encoder = intel_attached_encoder(connector); |
|
- | 141 | struct drm_crtc *crtc; |
|
- | 142 | int old_dpms; |
|
- | 143 | ||
- | 144 | /* PCH platforms and VLV only support on/off. */ |
|
- | 145 | if (INTEL_INFO(dev)->gen < 5 && mode != DRM_MODE_DPMS_ON) |
|
- | 146 | mode = DRM_MODE_DPMS_OFF; |
|
- | 147 | ||
- | 148 | if (mode == connector->dpms) |
|
- | 149 | return; |
|
- | 150 | ||
- | 151 | old_dpms = connector->dpms; |
|
- | 152 | connector->dpms = mode; |
|
- | 153 | ||
- | 154 | /* Only need to change hw state when actually enabled */ |
|
- | 155 | crtc = encoder->base.crtc; |
|
- | 156 | if (!crtc) { |
|
- | 157 | encoder->connectors_active = false; |
|
- | 158 | return; |
|
- | 159 | } |
|
- | 160 | ||
- | 161 | /* We need the pipe to run for anything but OFF. */ |
|
- | 162 | if (mode == DRM_MODE_DPMS_OFF) |
|
- | 163 | encoder->connectors_active = false; |
|
- | 164 | else |
|
- | 165 | encoder->connectors_active = true; |
|
- | 166 | ||
- | 167 | if (mode < old_dpms) { |
|
- | 168 | /* From off to on, enable the pipe first. */ |
|
- | 169 | intel_crtc_update_dpms(crtc); |
|
- | 170 | ||
- | 171 | intel_crt_set_dpms(encoder, mode); |
|
- | 172 | } else { |
|
- | 173 | intel_crt_set_dpms(encoder, mode); |
|
- | 174 | ||
- | 175 | intel_crtc_update_dpms(crtc); |
|
- | 176 | } |
|
- | 177 | ||
87 | I915_WRITE(reg, temp); |
178 | intel_modeset_check_state(connector->dev); |
Line 88... | Line 179... | ||
88 | } |
179 | } |
89 | 180 | ||
90 | static int intel_crt_mode_valid(struct drm_connector *connector, |
181 | static int intel_crt_mode_valid(struct drm_connector *connector, |
Line 108... | Line 199... | ||
108 | 199 | ||
109 | return MODE_OK; |
200 | return MODE_OK; |
Line 110... | Line 201... | ||
110 | } |
201 | } |
111 | 202 | ||
112 | static bool intel_crt_mode_fixup(struct drm_encoder *encoder, |
203 | static bool intel_crt_mode_fixup(struct drm_encoder *encoder, |
113 | struct drm_display_mode *mode, |
204 | const struct drm_display_mode *mode, |
114 | struct drm_display_mode *adjusted_mode) |
205 | struct drm_display_mode *adjusted_mode) |
115 | { |
206 | { |
Line 121... | Line 212... | ||
121 | struct drm_display_mode *adjusted_mode) |
212 | struct drm_display_mode *adjusted_mode) |
122 | { |
213 | { |
Line 123... | Line 214... | ||
123 | 214 | ||
124 | struct drm_device *dev = encoder->dev; |
215 | struct drm_device *dev = encoder->dev; |
- | 216 | struct drm_crtc *crtc = encoder->crtc; |
|
- | 217 | struct intel_crt *crt = |
|
125 | struct drm_crtc *crtc = encoder->crtc; |
218 | intel_encoder_to_crt(to_intel_encoder(encoder)); |
126 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
219 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
127 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
128 | int dpll_md_reg; |
- | |
129 | u32 adpa, dpll_md; |
220 | struct drm_i915_private *dev_priv = dev->dev_private; |
130 | u32 adpa_reg; |
- | |
131 | - | ||
132 | dpll_md_reg = DPLL_MD(intel_crtc->pipe); |
- | |
133 | - | ||
134 | if (HAS_PCH_SPLIT(dev)) |
- | |
135 | adpa_reg = PCH_ADPA; |
- | |
136 | else |
- | |
137 | adpa_reg = ADPA; |
- | |
138 | - | ||
139 | /* |
- | |
140 | * Disable separate mode multiplier used when cloning SDVO to CRT |
- | |
141 | * XXX this needs to be adjusted when we really are cloning |
- | |
142 | */ |
- | |
143 | if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { |
- | |
144 | dpll_md = I915_READ(dpll_md_reg); |
- | |
145 | I915_WRITE(dpll_md_reg, |
- | |
146 | dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); |
- | |
Line 147... | Line 221... | ||
147 | } |
221 | u32 adpa; |
148 | 222 | ||
149 | adpa = ADPA_HOTPLUG_BITS; |
223 | adpa = ADPA_HOTPLUG_BITS; |
150 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
224 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
Line 161... | Line 235... | ||
161 | adpa |= ADPA_PIPE_B_SELECT; |
235 | adpa |= ADPA_PIPE_B_SELECT; |
Line 162... | Line 236... | ||
162 | 236 | ||
163 | if (!HAS_PCH_SPLIT(dev)) |
237 | if (!HAS_PCH_SPLIT(dev)) |
Line 164... | Line 238... | ||
164 | I915_WRITE(BCLRPAT(intel_crtc->pipe), 0); |
238 | I915_WRITE(BCLRPAT(intel_crtc->pipe), 0); |
165 | 239 | ||
Line 166... | Line 240... | ||
166 | I915_WRITE(adpa_reg, adpa); |
240 | I915_WRITE(crt->adpa_reg, adpa); |
167 | } |
241 | } |
168 | 242 | ||
Line 209... | Line 283... | ||
209 | DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret); |
283 | DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret); |
Line 210... | Line 284... | ||
210 | 284 | ||
211 | return ret; |
285 | return ret; |
Line -... | Line 286... | ||
- | 286 | } |
|
- | 287 | ||
- | 288 | static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) |
|
- | 289 | { |
|
- | 290 | struct drm_device *dev = connector->dev; |
|
- | 291 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 292 | u32 adpa; |
|
- | 293 | bool ret; |
|
- | 294 | u32 save_adpa; |
|
- | 295 | ||
- | 296 | save_adpa = adpa = I915_READ(ADPA); |
|
- | 297 | DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa); |
|
- | 298 | ||
- | 299 | adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER; |
|
- | 300 | ||
- | 301 | I915_WRITE(ADPA, adpa); |
|
- | 302 | ||
- | 303 | if (wait_for((I915_READ(ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, |
|
- | 304 | 1000)) { |
|
- | 305 | DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); |
|
- | 306 | I915_WRITE(ADPA, save_adpa); |
|
- | 307 | } |
|
- | 308 | ||
- | 309 | /* Check the status to see if both blue and green are on now */ |
|
- | 310 | adpa = I915_READ(ADPA); |
|
- | 311 | if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0) |
|
- | 312 | ret = true; |
|
- | 313 | else |
|
- | 314 | ret = false; |
|
- | 315 | ||
- | 316 | DRM_DEBUG_KMS("valleyview hotplug adpa=0x%x, result %d\n", adpa, ret); |
|
- | 317 | ||
- | 318 | /* FIXME: debug force function and remove */ |
|
- | 319 | ret = true; |
|
- | 320 | ||
- | 321 | return ret; |
|
212 | } |
322 | } |
213 | 323 | ||
214 | /** |
324 | /** |
215 | * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence. |
325 | * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence. |
216 | * |
326 | * |
Line 228... | Line 338... | ||
228 | int i, tries = 0; |
338 | int i, tries = 0; |
Line 229... | Line 339... | ||
229 | 339 | ||
230 | if (HAS_PCH_SPLIT(dev)) |
340 | if (HAS_PCH_SPLIT(dev)) |
Line -... | Line 341... | ||
- | 341 | return intel_ironlake_crt_detect_hotplug(connector); |
|
- | 342 | ||
- | 343 | if (IS_VALLEYVIEW(dev)) |
|
231 | return intel_ironlake_crt_detect_hotplug(connector); |
344 | return valleyview_crt_detect_hotplug(connector); |
232 | 345 | ||
233 | /* |
346 | /* |
234 | * On 4 series desktop, CRT detect sequence need to be done twice |
347 | * On 4 series desktop, CRT detect sequence need to be done twice |
Line 263... | Line 376... | ||
263 | I915_WRITE(PORT_HOTPLUG_EN, orig); |
376 | I915_WRITE(PORT_HOTPLUG_EN, orig); |
Line 264... | Line 377... | ||
264 | 377 | ||
265 | return ret; |
378 | return ret; |
Line -... | Line 379... | ||
- | 379 | } |
|
- | 380 | ||
- | 381 | static struct edid *intel_crt_get_edid(struct drm_connector *connector, |
|
- | 382 | struct i2c_adapter *i2c) |
|
- | 383 | { |
|
- | 384 | struct edid *edid; |
|
- | 385 | ||
- | 386 | edid = drm_get_edid(connector, i2c); |
|
- | 387 | ||
- | 388 | if (!edid && !intel_gmbus_is_forced_bit(i2c)) { |
|
- | 389 | DRM_DEBUG_KMS("CRT GMBUS EDID read failed, retry using GPIO bit-banging\n"); |
|
- | 390 | intel_gmbus_force_bit(i2c, true); |
|
- | 391 | edid = drm_get_edid(connector, i2c); |
|
- | 392 | intel_gmbus_force_bit(i2c, false); |
|
- | 393 | } |
|
- | 394 | ||
- | 395 | return edid; |
|
- | 396 | } |
|
- | 397 | ||
- | 398 | /* local version of intel_ddc_get_modes() to use intel_crt_get_edid() */ |
|
- | 399 | static int intel_crt_ddc_get_modes(struct drm_connector *connector, |
|
- | 400 | struct i2c_adapter *adapter) |
|
- | 401 | { |
|
- | 402 | struct edid *edid; |
|
- | 403 | ||
- | 404 | edid = intel_crt_get_edid(connector, adapter); |
|
- | 405 | if (!edid) |
|
- | 406 | return 0; |
|
- | 407 | ||
- | 408 | return intel_connector_update_modes(connector, edid); |
|
266 | } |
409 | } |
267 | 410 | ||
268 | static bool intel_crt_detect_ddc(struct drm_connector *connector) |
411 | static bool intel_crt_detect_ddc(struct drm_connector *connector) |
269 | { |
412 | { |
- | 413 | struct intel_crt *crt = intel_attached_crt(connector); |
|
- | 414 | struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; |
|
Line 270... | Line -... | ||
270 | struct intel_crt *crt = intel_attached_crt(connector); |
- | |
271 | struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; |
415 | struct edid *edid; |
272 | - | ||
Line 273... | Line 416... | ||
273 | /* CRT should always be at 0, but check anyway */ |
416 | struct i2c_adapter *i2c; |
- | 417 | ||
- | 418 | BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG); |
|
274 | if (crt->base.type != INTEL_OUTPUT_ANALOG) |
419 | |
275 | return false; |
420 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); |
Line 276... | Line -... | ||
276 | - | ||
277 | if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) { |
- | |
278 | struct edid *edid; |
421 | edid = intel_crt_get_edid(connector, i2c); |
279 | bool is_digital = false; |
422 | |
280 | 423 | if (edid) { |
|
281 | edid = drm_get_edid(connector, |
424 | bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; |
282 | &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); |
- | |
283 | /* |
- | |
284 | * This may be a DVI-I connector with a shared DDC |
425 | |
285 | * link between analog and digital outputs, so we |
- | |
286 | * have to check the EDID input spec of the attached device. |
- | |
287 | * |
- | |
288 | * On the other hand, what should we do if it is a broken EDID? |
- | |
289 | */ |
- | |
290 | if (edid != NULL) { |
- | |
291 | is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; |
426 | /* |
292 | connector->display_info.raw_edid = NULL; |
427 | * This may be a DVI-I connector with a shared DDC |
293 | kfree(edid); |
428 | * link between analog and digital outputs, so we |
294 | } |
- | |
295 | - | ||
296 | if (!is_digital) { |
429 | * have to check the EDID input spec of the attached device. |
- | 430 | */ |
|
- | 431 | if (!is_digital) { |
|
- | 432 | DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); |
|
- | 433 | return true; |
|
297 | DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); |
434 | } |
Line -... | Line 435... | ||
- | 435 | ||
- | 436 | DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n"); |
|
298 | return true; |
437 | } else { |
299 | } else { |
438 | DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [no valid EDID found]\n"); |
Line 300... | Line 439... | ||
300 | DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n"); |
439 | } |
301 | } |
440 | |
Line 427... | Line 566... | ||
427 | static enum drm_connector_status |
566 | static enum drm_connector_status |
428 | intel_crt_detect(struct drm_connector *connector, bool force) |
567 | intel_crt_detect(struct drm_connector *connector, bool force) |
429 | { |
568 | { |
430 | struct drm_device *dev = connector->dev; |
569 | struct drm_device *dev = connector->dev; |
431 | struct intel_crt *crt = intel_attached_crt(connector); |
570 | struct intel_crt *crt = intel_attached_crt(connector); |
432 | struct drm_crtc *crtc; |
- | |
433 | enum drm_connector_status status; |
571 | enum drm_connector_status status; |
- | 572 | struct intel_load_detect_pipe tmp; |
|
Line 434... | Line 573... | ||
434 | 573 | ||
- | 574 | if (I915_HAS_HOTPLUG(dev)) { |
|
- | 575 | /* We can not rely on the HPD pin always being correctly wired |
|
- | 576 | * up, for example many KVM do not pass it through, and so |
|
- | 577 | * only trust an assertion that the monitor is connected. |
|
435 | if (I915_HAS_HOTPLUG(dev)) { |
578 | */ |
436 | if (intel_crt_detect_hotplug(connector)) { |
579 | if (intel_crt_detect_hotplug(connector)) { |
437 | DRM_DEBUG_KMS("CRT detected via hotplug\n"); |
580 | DRM_DEBUG_KMS("CRT detected via hotplug\n"); |
438 | return connector_status_connected; |
581 | return connector_status_connected; |
439 | } else { |
582 | } else |
440 | DRM_DEBUG_KMS("CRT not detected via hotplug\n"); |
- | |
441 | return connector_status_disconnected; |
- | |
442 | } |
583 | DRM_DEBUG_KMS("CRT not detected via hotplug\n"); |
Line 443... | Line 584... | ||
443 | } |
584 | } |
444 | 585 | ||
Line -... | Line 586... | ||
- | 586 | if (intel_crt_detect_ddc(connector)) |
|
- | 587 | return connector_status_connected; |
|
- | 588 | ||
- | 589 | /* Load detection is broken on HPD capable machines. Whoever wants a |
|
- | 590 | * broken monitor (without edid) to work behind a broken kvm (that fails |
|
- | 591 | * to have the right resistors for HP detection) needs to fix this up. |
|
- | 592 | * For now just bail out. */ |
|
445 | if (intel_crt_detect_ddc(connector)) |
593 | if (I915_HAS_HOTPLUG(dev)) |
446 | return connector_status_connected; |
594 | return connector_status_disconnected; |
Line 447... | Line 595... | ||
447 | 595 | ||
448 | if (!force) |
- | |
449 | return connector->status; |
- | |
450 | - | ||
451 | /* for pre-945g platforms use load detect */ |
- | |
452 | crtc = crt->base.base.crtc; |
- | |
453 | if (crtc && crtc->enabled) { |
- | |
454 | status = intel_crt_load_detect(crt); |
596 | if (!force) |
455 | } else { |
- | |
456 | struct intel_load_detect_pipe tmp; |
597 | return connector->status; |
457 | 598 | ||
458 | if (intel_get_load_detect_pipe(&crt->base, connector, NULL, |
599 | /* for pre-945g platforms use load detect */ |
459 | &tmp)) { |
600 | if (intel_get_load_detect_pipe(connector, NULL, &tmp)) { |
460 | if (intel_crt_detect_ddc(connector)) |
601 | if (intel_crt_detect_ddc(connector)) |
461 | status = connector_status_connected; |
- | |
462 | else |
602 | status = connector_status_connected; |
463 | status = intel_crt_load_detect(crt); |
603 | else |
464 | intel_release_load_detect_pipe(&crt->base, connector, |
- | |
Line 465... | Line 604... | ||
465 | &tmp); |
604 | status = intel_crt_load_detect(crt); |
466 | } else |
605 | intel_release_load_detect_pipe(connector, &tmp); |
Line 467... | Line 606... | ||
467 | status = connector_status_unknown; |
606 | } else |
Line 480... | Line 619... | ||
480 | static int intel_crt_get_modes(struct drm_connector *connector) |
619 | static int intel_crt_get_modes(struct drm_connector *connector) |
481 | { |
620 | { |
482 | struct drm_device *dev = connector->dev; |
621 | struct drm_device *dev = connector->dev; |
483 | struct drm_i915_private *dev_priv = dev->dev_private; |
622 | struct drm_i915_private *dev_priv = dev->dev_private; |
484 | int ret; |
623 | int ret; |
- | 624 | struct i2c_adapter *i2c; |
|
Line 485... | Line 625... | ||
485 | 625 | ||
486 | ret = intel_ddc_get_modes(connector, |
626 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); |
487 | &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); |
627 | ret = intel_crt_ddc_get_modes(connector, i2c); |
488 | if (ret || !IS_G4X(dev)) |
628 | if (ret || !IS_G4X(dev)) |
Line 489... | Line 629... | ||
489 | return ret; |
629 | return ret; |
490 | 630 | ||
491 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ |
631 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ |
492 | return intel_ddc_get_modes(connector, |
632 | i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); |
Line 493... | Line 633... | ||
493 | &dev_priv->gmbus[GMBUS_PORT_DPB].adapter); |
633 | return intel_crt_ddc_get_modes(connector, i2c); |
494 | } |
634 | } |
495 | 635 | ||
Line 511... | Line 651... | ||
511 | 651 | ||
512 | /* |
652 | /* |
513 | * Routines for controlling stuff on the analog port |
653 | * Routines for controlling stuff on the analog port |
Line 514... | Line 654... | ||
514 | */ |
654 | */ |
515 | - | ||
516 | static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = { |
655 | |
517 | .dpms = intel_crt_dpms, |
- | |
518 | .mode_fixup = intel_crt_mode_fixup, |
- | |
519 | .prepare = intel_encoder_prepare, |
656 | static const struct drm_encoder_helper_funcs crt_encoder_funcs = { |
- | 657 | .mode_fixup = intel_crt_mode_fixup, |
|
520 | .commit = intel_encoder_commit, |
658 | .mode_set = intel_crt_mode_set, |
Line 521... | Line 659... | ||
521 | .mode_set = intel_crt_mode_set, |
659 | .disable = intel_encoder_noop, |
522 | }; |
660 | }; |
523 | 661 | ||
524 | static const struct drm_connector_funcs intel_crt_connector_funcs = { |
662 | static const struct drm_connector_funcs intel_crt_connector_funcs = { |
525 | .reset = intel_crt_reset, |
663 | .reset = intel_crt_reset, |
526 | .dpms = drm_helper_connector_dpms, |
664 | .dpms = intel_crt_dpms, |
527 | .detect = intel_crt_detect, |
665 | .detect = intel_crt_detect, |
528 | .fill_modes = drm_helper_probe_single_connector_modes, |
666 | .fill_modes = drm_helper_probe_single_connector_modes, |
Line 565... | Line 703... | ||
565 | DRM_MODE_ENCODER_DAC); |
703 | DRM_MODE_ENCODER_DAC); |
Line 566... | Line 704... | ||
566 | 704 | ||
Line 567... | Line 705... | ||
567 | intel_connector_attach_encoder(intel_connector, &crt->base); |
705 | intel_connector_attach_encoder(intel_connector, &crt->base); |
568 | 706 | ||
569 | crt->base.type = INTEL_OUTPUT_ANALOG; |
707 | crt->base.type = INTEL_OUTPUT_ANALOG; |
570 | crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT | |
708 | crt->base.cloneable = true; |
- | 709 | if (IS_HASWELL(dev) || IS_I830(dev)) |
|
571 | 1 << INTEL_ANALOG_CLONE_BIT | |
710 | crt->base.crtc_mask = (1 << 0); |
- | 711 | else |
|
- | 712 | crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
|
- | 713 | ||
- | 714 | if (IS_GEN2(dev)) |
|
572 | 1 << INTEL_SDVO_LVDS_CLONE_BIT); |
715 | connector->interlace_allowed = 0; |
573 | crt->base.crtc_mask = (1 << 0) | (1 << 1); |
716 | else |
Line -... | Line 717... | ||
- | 717 | connector->interlace_allowed = 1; |
|
- | 718 | connector->doublescan_allowed = 0; |
|
- | 719 | ||
- | 720 | if (HAS_PCH_SPLIT(dev)) |
|
- | 721 | crt->adpa_reg = PCH_ADPA; |
|
- | 722 | else if (IS_VALLEYVIEW(dev)) |
|
- | 723 | crt->adpa_reg = VLV_ADPA; |
|
- | 724 | else |
|
- | 725 | crt->adpa_reg = ADPA; |
|
- | 726 | ||
- | 727 | crt->base.disable = intel_disable_crt; |
|
- | 728 | crt->base.enable = intel_enable_crt; |
|
574 | connector->interlace_allowed = 1; |
729 | crt->base.get_hw_state = intel_crt_get_hw_state; |
575 | connector->doublescan_allowed = 0; |
730 | intel_connector->get_hw_state = intel_connector_get_hw_state; |
Line 576... | Line 731... | ||
576 | 731 | ||
Line 577... | Line 732... | ||
577 | drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs); |
732 | drm_encoder_helper_add(&crt->base.base, &crt_encoder_funcs); |