diff options
| -rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 64 |
1 files changed, 37 insertions, 27 deletions
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index c55c77043357..e38bc6769180 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -34,6 +34,16 @@ | |||
| 34 | #include "i915_drm.h" | 34 | #include "i915_drm.h" |
| 35 | #include "i915_drv.h" | 35 | #include "i915_drv.h" |
| 36 | 36 | ||
| 37 | struct intel_crt { | ||
| 38 | struct intel_encoder base; | ||
| 39 | }; | ||
| 40 | |||
| 41 | static struct intel_crt *intel_attached_crt(struct drm_connector *connector) | ||
| 42 | { | ||
| 43 | return container_of(intel_attached_encoder(connector), | ||
| 44 | struct intel_crt, base); | ||
| 45 | } | ||
| 46 | |||
| 37 | static void intel_crt_dpms(struct drm_encoder *encoder, int mode) | 47 | static void intel_crt_dpms(struct drm_encoder *encoder, int mode) |
| 38 | { | 48 | { |
| 39 | struct drm_device *dev = encoder->dev; | 49 | struct drm_device *dev = encoder->dev; |
| @@ -277,13 +287,12 @@ static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus) | |||
| 277 | return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1; | 287 | return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1; |
| 278 | } | 288 | } |
| 279 | 289 | ||
| 280 | static bool intel_crt_detect_ddc(struct drm_encoder *encoder) | 290 | static bool intel_crt_detect_ddc(struct intel_crt *crt) |
| 281 | { | 291 | { |
| 282 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); | 292 | struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; |
| 283 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | ||
| 284 | 293 | ||
| 285 | /* CRT should always be at 0, but check anyway */ | 294 | /* CRT should always be at 0, but check anyway */ |
| 286 | if (intel_encoder->type != INTEL_OUTPUT_ANALOG) | 295 | if (crt->base.type != INTEL_OUTPUT_ANALOG) |
| 287 | return false; | 296 | return false; |
| 288 | 297 | ||
| 289 | if (intel_crt_ddc_probe(dev_priv, dev_priv->crt_ddc_pin)) { | 298 | if (intel_crt_ddc_probe(dev_priv, dev_priv->crt_ddc_pin)) { |
| @@ -291,7 +300,7 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder) | |||
| 291 | return true; | 300 | return true; |
| 292 | } | 301 | } |
| 293 | 302 | ||
| 294 | if (intel_ddc_probe(intel_encoder, dev_priv->crt_ddc_pin)) { | 303 | if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) { |
| 295 | DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); | 304 | DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); |
| 296 | return true; | 305 | return true; |
| 297 | } | 306 | } |
| @@ -300,9 +309,9 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder) | |||
| 300 | } | 309 | } |
| 301 | 310 | ||
| 302 | static enum drm_connector_status | 311 | static enum drm_connector_status |
| 303 | intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder) | 312 | intel_crt_load_detect(struct drm_crtc *crtc, struct intel_crt *crt) |
| 304 | { | 313 | { |
| 305 | struct drm_encoder *encoder = &intel_encoder->base; | 314 | struct drm_encoder *encoder = &crt->base.base; |
| 306 | struct drm_device *dev = encoder->dev; | 315 | struct drm_device *dev = encoder->dev; |
| 307 | struct drm_i915_private *dev_priv = dev->dev_private; | 316 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 308 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 317 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| @@ -434,7 +443,7 @@ static enum drm_connector_status | |||
| 434 | intel_crt_detect(struct drm_connector *connector, bool force) | 443 | intel_crt_detect(struct drm_connector *connector, bool force) |
| 435 | { | 444 | { |
| 436 | struct drm_device *dev = connector->dev; | 445 | struct drm_device *dev = connector->dev; |
| 437 | struct intel_encoder *encoder = intel_attached_encoder(connector); | 446 | struct intel_crt *crt = intel_attached_crt(connector); |
| 438 | struct drm_crtc *crtc; | 447 | struct drm_crtc *crtc; |
| 439 | int dpms_mode; | 448 | int dpms_mode; |
| 440 | enum drm_connector_status status; | 449 | enum drm_connector_status status; |
| @@ -447,24 +456,25 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
| 447 | return connector_status_disconnected; | 456 | return connector_status_disconnected; |
| 448 | } | 457 | } |
| 449 | 458 | ||
| 450 | if (intel_crt_detect_ddc(&encoder->base)) | 459 | if (intel_crt_detect_ddc(crt)) |
| 451 | return connector_status_connected; | 460 | return connector_status_connected; |
| 452 | 461 | ||
| 453 | if (!force) | 462 | if (!force) |
| 454 | return connector->status; | 463 | return connector->status; |
| 455 | 464 | ||
| 456 | /* for pre-945g platforms use load detect */ | 465 | /* for pre-945g platforms use load detect */ |
| 457 | if (encoder->base.crtc && encoder->base.crtc->enabled) { | 466 | crtc = crt->base.base.crtc; |
| 458 | status = intel_crt_load_detect(encoder->base.crtc, encoder); | 467 | if (crtc && crtc->enabled) { |
| 468 | status = intel_crt_load_detect(crtc, crt); | ||
| 459 | } else { | 469 | } else { |
| 460 | crtc = intel_get_load_detect_pipe(encoder, connector, | 470 | crtc = intel_get_load_detect_pipe(&crt->base, connector, |
| 461 | NULL, &dpms_mode); | 471 | NULL, &dpms_mode); |
| 462 | if (crtc) { | 472 | if (crtc) { |
| 463 | if (intel_crt_detect_ddc(&encoder->base)) | 473 | if (intel_crt_detect_ddc(crt)) |
| 464 | status = connector_status_connected; | 474 | status = connector_status_connected; |
| 465 | else | 475 | else |
| 466 | status = intel_crt_load_detect(crtc, encoder); | 476 | status = intel_crt_load_detect(crtc, crt); |
| 467 | intel_release_load_detect_pipe(encoder, | 477 | intel_release_load_detect_pipe(&crt->base, |
| 468 | connector, dpms_mode); | 478 | connector, dpms_mode); |
| 469 | } else | 479 | } else |
| 470 | status = connector_status_unknown; | 480 | status = connector_status_unknown; |
| @@ -536,17 +546,17 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { | |||
| 536 | void intel_crt_init(struct drm_device *dev) | 546 | void intel_crt_init(struct drm_device *dev) |
| 537 | { | 547 | { |
| 538 | struct drm_connector *connector; | 548 | struct drm_connector *connector; |
| 539 | struct intel_encoder *intel_encoder; | 549 | struct intel_crt *crt; |
| 540 | struct intel_connector *intel_connector; | 550 | struct intel_connector *intel_connector; |
| 541 | struct drm_i915_private *dev_priv = dev->dev_private; | 551 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 542 | 552 | ||
| 543 | intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL); | 553 | crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL); |
| 544 | if (!intel_encoder) | 554 | if (!crt) |
| 545 | return; | 555 | return; |
| 546 | 556 | ||
| 547 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 557 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
| 548 | if (!intel_connector) { | 558 | if (!intel_connector) { |
| 549 | kfree(intel_encoder); | 559 | kfree(crt); |
| 550 | return; | 560 | return; |
| 551 | } | 561 | } |
| 552 | 562 | ||
| @@ -554,20 +564,20 @@ void intel_crt_init(struct drm_device *dev) | |||
| 554 | drm_connector_init(dev, &intel_connector->base, | 564 | drm_connector_init(dev, &intel_connector->base, |
| 555 | &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); | 565 | &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); |
| 556 | 566 | ||
| 557 | drm_encoder_init(dev, &intel_encoder->base, &intel_crt_enc_funcs, | 567 | drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs, |
| 558 | DRM_MODE_ENCODER_DAC); | 568 | DRM_MODE_ENCODER_DAC); |
| 559 | 569 | ||
| 560 | intel_connector_attach_encoder(intel_connector, intel_encoder); | 570 | intel_connector_attach_encoder(intel_connector, &crt->base); |
| 561 | 571 | ||
| 562 | intel_encoder->type = INTEL_OUTPUT_ANALOG; | 572 | crt->base.type = INTEL_OUTPUT_ANALOG; |
| 563 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 573 | crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT | |
| 564 | (1 << INTEL_ANALOG_CLONE_BIT) | | 574 | 1 << INTEL_ANALOG_CLONE_BIT | |
| 565 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | 575 | 1 << INTEL_SDVO_LVDS_CLONE_BIT); |
| 566 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 576 | crt->base.crtc_mask = (1 << 0) | (1 << 1); |
| 567 | connector->interlace_allowed = 1; | 577 | connector->interlace_allowed = 1; |
| 568 | connector->doublescan_allowed = 0; | 578 | connector->doublescan_allowed = 0; |
| 569 | 579 | ||
| 570 | drm_encoder_helper_add(&intel_encoder->base, &intel_crt_helper_funcs); | 580 | drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs); |
| 571 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); | 581 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); |
| 572 | 582 | ||
| 573 | drm_sysfs_connector_add(connector); | 583 | drm_sysfs_connector_add(connector); |
