diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 71 |
1 files changed, 62 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1aac59e83bff..b4f02826676e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #define DP_LINK_CONFIGURATION_SIZE 9 | 43 | #define DP_LINK_CONFIGURATION_SIZE 9 |
44 | 44 | ||
45 | #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP) | 45 | #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP) |
46 | #define IS_PCH_eDP(dp_priv) ((dp_priv)->has_edp) | ||
46 | 47 | ||
47 | struct intel_dp_priv { | 48 | struct intel_dp_priv { |
48 | uint32_t output_reg; | 49 | uint32_t output_reg; |
@@ -56,6 +57,7 @@ struct intel_dp_priv { | |||
56 | struct intel_encoder *intel_encoder; | 57 | struct intel_encoder *intel_encoder; |
57 | struct i2c_adapter adapter; | 58 | struct i2c_adapter adapter; |
58 | struct i2c_algo_dp_aux_data algo; | 59 | struct i2c_algo_dp_aux_data algo; |
60 | bool has_edp; | ||
59 | }; | 61 | }; |
60 | 62 | ||
61 | static void | 63 | static void |
@@ -128,8 +130,9 @@ intel_dp_link_required(struct drm_device *dev, | |||
128 | struct intel_encoder *intel_encoder, int pixel_clock) | 130 | struct intel_encoder *intel_encoder, int pixel_clock) |
129 | { | 131 | { |
130 | struct drm_i915_private *dev_priv = dev->dev_private; | 132 | struct drm_i915_private *dev_priv = dev->dev_private; |
133 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
131 | 134 | ||
132 | if (IS_eDP(intel_encoder)) | 135 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) |
133 | return (pixel_clock * dev_priv->edp_bpp) / 8; | 136 | return (pixel_clock * dev_priv->edp_bpp) / 8; |
134 | else | 137 | else |
135 | return pixel_clock * 3; | 138 | return pixel_clock * 3; |
@@ -563,14 +566,14 @@ intel_reduce_ratio(uint32_t *num, uint32_t *den) | |||
563 | } | 566 | } |
564 | 567 | ||
565 | static void | 568 | static void |
566 | intel_dp_compute_m_n(int bytes_per_pixel, | 569 | intel_dp_compute_m_n(int bpp, |
567 | int nlanes, | 570 | int nlanes, |
568 | int pixel_clock, | 571 | int pixel_clock, |
569 | int link_clock, | 572 | int link_clock, |
570 | struct intel_dp_m_n *m_n) | 573 | struct intel_dp_m_n *m_n) |
571 | { | 574 | { |
572 | m_n->tu = 64; | 575 | m_n->tu = 64; |
573 | m_n->gmch_m = pixel_clock * bytes_per_pixel; | 576 | m_n->gmch_m = (pixel_clock * bpp) >> 3; |
574 | m_n->gmch_n = link_clock * nlanes; | 577 | m_n->gmch_n = link_clock * nlanes; |
575 | intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | 578 | intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
576 | m_n->link_m = pixel_clock; | 579 | m_n->link_m = pixel_clock; |
@@ -578,6 +581,28 @@ intel_dp_compute_m_n(int bytes_per_pixel, | |||
578 | intel_reduce_ratio(&m_n->link_m, &m_n->link_n); | 581 | intel_reduce_ratio(&m_n->link_m, &m_n->link_n); |
579 | } | 582 | } |
580 | 583 | ||
584 | bool intel_pch_has_edp(struct drm_crtc *crtc) | ||
585 | { | ||
586 | struct drm_device *dev = crtc->dev; | ||
587 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
588 | struct drm_encoder *encoder; | ||
589 | |||
590 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | ||
591 | struct intel_encoder *intel_encoder; | ||
592 | struct intel_dp_priv *dp_priv; | ||
593 | |||
594 | if (!encoder || encoder->crtc != crtc) | ||
595 | continue; | ||
596 | |||
597 | intel_encoder = enc_to_intel_encoder(encoder); | ||
598 | dp_priv = intel_encoder->dev_priv; | ||
599 | |||
600 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) | ||
601 | return dp_priv->has_edp; | ||
602 | } | ||
603 | return false; | ||
604 | } | ||
605 | |||
581 | void | 606 | void |
582 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | 607 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, |
583 | struct drm_display_mode *adjusted_mode) | 608 | struct drm_display_mode *adjusted_mode) |
@@ -587,7 +612,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
587 | struct drm_encoder *encoder; | 612 | struct drm_encoder *encoder; |
588 | struct drm_i915_private *dev_priv = dev->dev_private; | 613 | struct drm_i915_private *dev_priv = dev->dev_private; |
589 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 614 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
590 | int lane_count = 4; | 615 | int lane_count = 4, bpp = 24; |
591 | struct intel_dp_m_n m_n; | 616 | struct intel_dp_m_n m_n; |
592 | 617 | ||
593 | /* | 618 | /* |
@@ -605,6 +630,8 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
605 | 630 | ||
606 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { | 631 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { |
607 | lane_count = dp_priv->lane_count; | 632 | lane_count = dp_priv->lane_count; |
633 | if (IS_PCH_eDP(dp_priv)) | ||
634 | bpp = dev_priv->edp_bpp; | ||
608 | break; | 635 | break; |
609 | } | 636 | } |
610 | } | 637 | } |
@@ -614,7 +641,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
614 | * the number of bytes_per_pixel post-LUT, which we always | 641 | * the number of bytes_per_pixel post-LUT, which we always |
615 | * set up for 8-bits of R/G/B, or 3 bytes total. | 642 | * set up for 8-bits of R/G/B, or 3 bytes total. |
616 | */ | 643 | */ |
617 | intel_dp_compute_m_n(3, lane_count, | 644 | intel_dp_compute_m_n(bpp, lane_count, |
618 | mode->clock, adjusted_mode->clock, &m_n); | 645 | mode->clock, adjusted_mode->clock, &m_n); |
619 | 646 | ||
620 | if (HAS_PCH_SPLIT(dev)) { | 647 | if (HAS_PCH_SPLIT(dev)) { |
@@ -751,13 +778,13 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
751 | if (mode != DRM_MODE_DPMS_ON) { | 778 | if (mode != DRM_MODE_DPMS_ON) { |
752 | if (dp_reg & DP_PORT_EN) { | 779 | if (dp_reg & DP_PORT_EN) { |
753 | intel_dp_link_down(intel_encoder, dp_priv->DP); | 780 | intel_dp_link_down(intel_encoder, dp_priv->DP); |
754 | if (IS_eDP(intel_encoder)) | 781 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) |
755 | ironlake_edp_backlight_off(dev); | 782 | ironlake_edp_backlight_off(dev); |
756 | } | 783 | } |
757 | } else { | 784 | } else { |
758 | if (!(dp_reg & DP_PORT_EN)) { | 785 | if (!(dp_reg & DP_PORT_EN)) { |
759 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); | 786 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); |
760 | if (IS_eDP(intel_encoder)) | 787 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) |
761 | ironlake_edp_backlight_on(dev); | 788 | ironlake_edp_backlight_on(dev); |
762 | } | 789 | } |
763 | } | 790 | } |
@@ -1291,6 +1318,7 @@ static int intel_dp_get_modes(struct drm_connector *connector) | |||
1291 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1318 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
1292 | struct drm_device *dev = intel_encoder->enc.dev; | 1319 | struct drm_device *dev = intel_encoder->enc.dev; |
1293 | struct drm_i915_private *dev_priv = dev->dev_private; | 1320 | struct drm_i915_private *dev_priv = dev->dev_private; |
1321 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1294 | int ret; | 1322 | int ret; |
1295 | 1323 | ||
1296 | /* We should parse the EDID data and find out if it has an audio sink | 1324 | /* We should parse the EDID data and find out if it has an audio sink |
@@ -1301,7 +1329,7 @@ static int intel_dp_get_modes(struct drm_connector *connector) | |||
1301 | return ret; | 1329 | return ret; |
1302 | 1330 | ||
1303 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ | 1331 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ |
1304 | if (IS_eDP(intel_encoder)) { | 1332 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { |
1305 | if (dev_priv->panel_fixed_mode != NULL) { | 1333 | if (dev_priv->panel_fixed_mode != NULL) { |
1306 | struct drm_display_mode *mode; | 1334 | struct drm_display_mode *mode; |
1307 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); | 1335 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); |
@@ -1386,6 +1414,26 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc) | |||
1386 | return -1; | 1414 | return -1; |
1387 | } | 1415 | } |
1388 | 1416 | ||
1417 | /* check the VBT to see whether the eDP is on DP-D port */ | ||
1418 | static bool intel_dpd_is_edp(struct drm_device *dev) | ||
1419 | { | ||
1420 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1421 | struct child_device_config *p_child; | ||
1422 | int i; | ||
1423 | |||
1424 | if (!dev_priv->child_dev_num) | ||
1425 | return false; | ||
1426 | |||
1427 | for (i = 0; i < dev_priv->child_dev_num; i++) { | ||
1428 | p_child = dev_priv->child_dev + i; | ||
1429 | |||
1430 | if (p_child->dvo_port == PORT_IDPD && | ||
1431 | p_child->device_type == DEVICE_TYPE_eDP) | ||
1432 | return true; | ||
1433 | } | ||
1434 | return false; | ||
1435 | } | ||
1436 | |||
1389 | void | 1437 | void |
1390 | intel_dp_init(struct drm_device *dev, int output_reg) | 1438 | intel_dp_init(struct drm_device *dev, int output_reg) |
1391 | { | 1439 | { |
@@ -1431,6 +1479,11 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1431 | if (IS_eDP(intel_encoder)) | 1479 | if (IS_eDP(intel_encoder)) |
1432 | intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); | 1480 | intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); |
1433 | 1481 | ||
1482 | if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D)) { | ||
1483 | if (intel_dpd_is_edp(dev)) | ||
1484 | dp_priv->has_edp = true; | ||
1485 | } | ||
1486 | |||
1434 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1487 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
1435 | connector->interlace_allowed = true; | 1488 | connector->interlace_allowed = true; |
1436 | connector->doublescan_allowed = 0; | 1489 | connector->doublescan_allowed = 0; |
@@ -1479,7 +1532,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1479 | intel_encoder->ddc_bus = &dp_priv->adapter; | 1532 | intel_encoder->ddc_bus = &dp_priv->adapter; |
1480 | intel_encoder->hot_plug = intel_dp_hot_plug; | 1533 | intel_encoder->hot_plug = intel_dp_hot_plug; |
1481 | 1534 | ||
1482 | if (output_reg == DP_A) { | 1535 | if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) { |
1483 | /* initialize panel mode from VBT if available for eDP */ | 1536 | /* initialize panel mode from VBT if available for eDP */ |
1484 | if (dev_priv->lfp_lvds_vbt_mode) { | 1537 | if (dev_priv->lfp_lvds_vbt_mode) { |
1485 | dev_priv->panel_fixed_mode = | 1538 | dev_priv->panel_fixed_mode = |