diff options
author | Dave Airlie <airlied@redhat.com> | 2011-07-14 01:45:23 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-07-14 01:45:23 -0400 |
commit | 5762a179b64cf37305d1d4d624e1b6ad9ee80602 (patch) | |
tree | 2e9225e382204ee8069bd10e2aeb0b27feaf4b87 /drivers/gpu/drm/i915/intel_dp.c | |
parent | cf056edbbe70393faa6edd2b7859a14467910946 (diff) | |
parent | 6e96e7757a0133a9a66fd9b86cd04b5e7b88122a (diff) |
Merge branch 'drm-intel-next' of ssh://master.kernel.org/pub/scm/linux/kernel/git/keithp/linux-2.6 into drm-core-next
* 'drm-intel-next' of ssh://master.kernel.org/pub/scm/linux/kernel/git/keithp/linux-2.6: (52 commits)
drm/i915: provide module parameter description
drm/i915: add module parameter compiler hints
drm/i915/bios: Avoid temporary allocation whilst searching for downclock
drm/i915: Cache GT fifo count for SandyBridge
i915: Fix opregion notifications
drm/i915: TVDAC_STATE_CHG does not indicate successful load-detect
drm/i915: Select correct pipe during TV detect
drm/i915/ringbuffer: Idling requires waiting for the ring to be empty
Revert "drm/i915: enable rc6 by default"
drm/i915: Clean up i915_driver_load failure path
drm/i915: Enable i915 frame buffer compression by default
drm/i915: Share the common work of disabling active FBC before updating
drm/i915: Perform intel_enable_fbc() from a delayed task
drm/i915: Disable FBC across page-flipping
drm/i915: Set persistent-mode for ILK/SNB framebuffer compression
drm/i915: Use of a CPU fence is mandatory to update FBC regions upon CPU writes
drm/i915: Remove vestigial pitch from post-gen2 FBC control routines
drm/i915: Replace direct calls to vfunc.disable_fbc with intel_disable_fbc()
drm/i915: Only export the generic intel_disable_fbc() interface
drm/i915: Enable GPU reset on Ivybridge.
...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 135 |
1 files changed, 100 insertions, 35 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 391b55f1cc74..f797fb58ba9c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -50,7 +50,6 @@ struct intel_dp { | |||
50 | bool has_audio; | 50 | bool has_audio; |
51 | int force_audio; | 51 | int force_audio; |
52 | uint32_t color_range; | 52 | uint32_t color_range; |
53 | int dpms_mode; | ||
54 | uint8_t link_bw; | 53 | uint8_t link_bw; |
55 | uint8_t lane_count; | 54 | uint8_t lane_count; |
56 | uint8_t dpcd[4]; | 55 | uint8_t dpcd[4]; |
@@ -138,8 +137,8 @@ intel_dp_max_lane_count(struct intel_dp *intel_dp) | |||
138 | { | 137 | { |
139 | int max_lane_count = 4; | 138 | int max_lane_count = 4; |
140 | 139 | ||
141 | if (intel_dp->dpcd[0] >= 0x11) { | 140 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) { |
142 | max_lane_count = intel_dp->dpcd[2] & 0x1f; | 141 | max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f; |
143 | switch (max_lane_count) { | 142 | switch (max_lane_count) { |
144 | case 1: case 2: case 4: | 143 | case 1: case 2: case 4: |
145 | break; | 144 | break; |
@@ -153,7 +152,7 @@ intel_dp_max_lane_count(struct intel_dp *intel_dp) | |||
153 | static int | 152 | static int |
154 | intel_dp_max_link_bw(struct intel_dp *intel_dp) | 153 | intel_dp_max_link_bw(struct intel_dp *intel_dp) |
155 | { | 154 | { |
156 | int max_link_bw = intel_dp->dpcd[1]; | 155 | int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE]; |
157 | 156 | ||
158 | switch (max_link_bw) { | 157 | switch (max_link_bw) { |
159 | case DP_LINK_BW_1_62: | 158 | case DP_LINK_BW_1_62: |
@@ -179,12 +178,14 @@ intel_dp_link_clock(uint8_t link_bw) | |||
179 | static int | 178 | static int |
180 | intel_dp_link_required(struct drm_device *dev, struct intel_dp *intel_dp, int pixel_clock) | 179 | intel_dp_link_required(struct drm_device *dev, struct intel_dp *intel_dp, int pixel_clock) |
181 | { | 180 | { |
182 | struct drm_i915_private *dev_priv = dev->dev_private; | 181 | struct drm_crtc *crtc = intel_dp->base.base.crtc; |
182 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
183 | int bpp = 24; | ||
183 | 184 | ||
184 | if (is_edp(intel_dp)) | 185 | if (intel_crtc) |
185 | return (pixel_clock * dev_priv->edp.bpp + 7) / 8; | 186 | bpp = intel_crtc->bpp; |
186 | else | 187 | |
187 | return pixel_clock * 3; | 188 | return (pixel_clock * bpp + 7) / 8; |
188 | } | 189 | } |
189 | 190 | ||
190 | static int | 191 | static int |
@@ -682,7 +683,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
682 | struct drm_encoder *encoder; | 683 | struct drm_encoder *encoder; |
683 | struct drm_i915_private *dev_priv = dev->dev_private; | 684 | struct drm_i915_private *dev_priv = dev->dev_private; |
684 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 685 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
685 | int lane_count = 4, bpp = 24; | 686 | int lane_count = 4; |
686 | struct intel_dp_m_n m_n; | 687 | struct intel_dp_m_n m_n; |
687 | int pipe = intel_crtc->pipe; | 688 | int pipe = intel_crtc->pipe; |
688 | 689 | ||
@@ -701,7 +702,6 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
701 | break; | 702 | break; |
702 | } else if (is_edp(intel_dp)) { | 703 | } else if (is_edp(intel_dp)) { |
703 | lane_count = dev_priv->edp.lanes; | 704 | lane_count = dev_priv->edp.lanes; |
704 | bpp = dev_priv->edp.bpp; | ||
705 | break; | 705 | break; |
706 | } | 706 | } |
707 | } | 707 | } |
@@ -711,7 +711,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
711 | * the number of bytes_per_pixel post-LUT, which we always | 711 | * the number of bytes_per_pixel post-LUT, which we always |
712 | * set up for 8-bits of R/G/B, or 3 bytes total. | 712 | * set up for 8-bits of R/G/B, or 3 bytes total. |
713 | */ | 713 | */ |
714 | intel_dp_compute_m_n(bpp, lane_count, | 714 | intel_dp_compute_m_n(intel_crtc->bpp, lane_count, |
715 | mode->clock, adjusted_mode->clock, &m_n); | 715 | mode->clock, adjusted_mode->clock, &m_n); |
716 | 716 | ||
717 | if (HAS_PCH_SPLIT(dev)) { | 717 | if (HAS_PCH_SPLIT(dev)) { |
@@ -774,7 +774,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
774 | /* | 774 | /* |
775 | * Check for DPCD version > 1.1 and enhanced framing support | 775 | * Check for DPCD version > 1.1 and enhanced framing support |
776 | */ | 776 | */ |
777 | if (intel_dp->dpcd[0] >= 0x11 && (intel_dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { | 777 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && |
778 | (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) { | ||
778 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | 779 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
779 | intel_dp->DP |= DP_ENHANCED_FRAMING; | 780 | intel_dp->DP |= DP_ENHANCED_FRAMING; |
780 | } | 781 | } |
@@ -942,11 +943,44 @@ static void ironlake_edp_pll_off(struct drm_encoder *encoder) | |||
942 | udelay(200); | 943 | udelay(200); |
943 | } | 944 | } |
944 | 945 | ||
946 | /* If the sink supports it, try to set the power state appropriately */ | ||
947 | static void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode) | ||
948 | { | ||
949 | int ret, i; | ||
950 | |||
951 | /* Should have a valid DPCD by this point */ | ||
952 | if (intel_dp->dpcd[DP_DPCD_REV] < 0x11) | ||
953 | return; | ||
954 | |||
955 | if (mode != DRM_MODE_DPMS_ON) { | ||
956 | ret = intel_dp_aux_native_write_1(intel_dp, DP_SET_POWER, | ||
957 | DP_SET_POWER_D3); | ||
958 | if (ret != 1) | ||
959 | DRM_DEBUG_DRIVER("failed to write sink power state\n"); | ||
960 | } else { | ||
961 | /* | ||
962 | * When turning on, we need to retry for 1ms to give the sink | ||
963 | * time to wake up. | ||
964 | */ | ||
965 | for (i = 0; i < 3; i++) { | ||
966 | ret = intel_dp_aux_native_write_1(intel_dp, | ||
967 | DP_SET_POWER, | ||
968 | DP_SET_POWER_D0); | ||
969 | if (ret == 1) | ||
970 | break; | ||
971 | msleep(1); | ||
972 | } | ||
973 | } | ||
974 | } | ||
975 | |||
945 | static void intel_dp_prepare(struct drm_encoder *encoder) | 976 | static void intel_dp_prepare(struct drm_encoder *encoder) |
946 | { | 977 | { |
947 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 978 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
948 | struct drm_device *dev = encoder->dev; | 979 | struct drm_device *dev = encoder->dev; |
949 | 980 | ||
981 | /* Wake up the sink first */ | ||
982 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | ||
983 | |||
950 | if (is_edp(intel_dp)) { | 984 | if (is_edp(intel_dp)) { |
951 | ironlake_edp_backlight_off(dev); | 985 | ironlake_edp_backlight_off(dev); |
952 | ironlake_edp_panel_off(dev); | 986 | ironlake_edp_panel_off(dev); |
@@ -990,6 +1024,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
990 | if (mode != DRM_MODE_DPMS_ON) { | 1024 | if (mode != DRM_MODE_DPMS_ON) { |
991 | if (is_edp(intel_dp)) | 1025 | if (is_edp(intel_dp)) |
992 | ironlake_edp_backlight_off(dev); | 1026 | ironlake_edp_backlight_off(dev); |
1027 | intel_dp_sink_dpms(intel_dp, mode); | ||
993 | intel_dp_link_down(intel_dp); | 1028 | intel_dp_link_down(intel_dp); |
994 | if (is_edp(intel_dp)) | 1029 | if (is_edp(intel_dp)) |
995 | ironlake_edp_panel_off(dev); | 1030 | ironlake_edp_panel_off(dev); |
@@ -998,6 +1033,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
998 | } else { | 1033 | } else { |
999 | if (is_edp(intel_dp)) | 1034 | if (is_edp(intel_dp)) |
1000 | ironlake_edp_panel_vdd_on(intel_dp); | 1035 | ironlake_edp_panel_vdd_on(intel_dp); |
1036 | intel_dp_sink_dpms(intel_dp, mode); | ||
1001 | if (!(dp_reg & DP_PORT_EN)) { | 1037 | if (!(dp_reg & DP_PORT_EN)) { |
1002 | intel_dp_start_link_train(intel_dp); | 1038 | intel_dp_start_link_train(intel_dp); |
1003 | if (is_edp(intel_dp)) { | 1039 | if (is_edp(intel_dp)) { |
@@ -1009,7 +1045,31 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
1009 | if (is_edp(intel_dp)) | 1045 | if (is_edp(intel_dp)) |
1010 | ironlake_edp_backlight_on(dev); | 1046 | ironlake_edp_backlight_on(dev); |
1011 | } | 1047 | } |
1012 | intel_dp->dpms_mode = mode; | 1048 | } |
1049 | |||
1050 | /* | ||
1051 | * Native read with retry for link status and receiver capability reads for | ||
1052 | * cases where the sink may still be asleep. | ||
1053 | */ | ||
1054 | static bool | ||
1055 | intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address, | ||
1056 | uint8_t *recv, int recv_bytes) | ||
1057 | { | ||
1058 | int ret, i; | ||
1059 | |||
1060 | /* | ||
1061 | * Sinks are *supposed* to come up within 1ms from an off state, | ||
1062 | * but we're also supposed to retry 3 times per the spec. | ||
1063 | */ | ||
1064 | for (i = 0; i < 3; i++) { | ||
1065 | ret = intel_dp_aux_native_read(intel_dp, address, recv, | ||
1066 | recv_bytes); | ||
1067 | if (ret == recv_bytes) | ||
1068 | return true; | ||
1069 | msleep(1); | ||
1070 | } | ||
1071 | |||
1072 | return false; | ||
1013 | } | 1073 | } |
1014 | 1074 | ||
1015 | /* | 1075 | /* |
@@ -1019,14 +1079,10 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
1019 | static bool | 1079 | static bool |
1020 | intel_dp_get_link_status(struct intel_dp *intel_dp) | 1080 | intel_dp_get_link_status(struct intel_dp *intel_dp) |
1021 | { | 1081 | { |
1022 | int ret; | 1082 | return intel_dp_aux_native_read_retry(intel_dp, |
1023 | 1083 | DP_LANE0_1_STATUS, | |
1024 | ret = intel_dp_aux_native_read(intel_dp, | 1084 | intel_dp->link_status, |
1025 | DP_LANE0_1_STATUS, | 1085 | DP_LINK_STATUS_SIZE); |
1026 | intel_dp->link_status, DP_LINK_STATUS_SIZE); | ||
1027 | if (ret != DP_LINK_STATUS_SIZE) | ||
1028 | return false; | ||
1029 | return true; | ||
1030 | } | 1086 | } |
1031 | 1087 | ||
1032 | static uint8_t | 1088 | static uint8_t |
@@ -1515,6 +1571,8 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1515 | static void | 1571 | static void |
1516 | intel_dp_check_link_status(struct intel_dp *intel_dp) | 1572 | intel_dp_check_link_status(struct intel_dp *intel_dp) |
1517 | { | 1573 | { |
1574 | int ret; | ||
1575 | |||
1518 | if (!intel_dp->base.base.crtc) | 1576 | if (!intel_dp->base.base.crtc) |
1519 | return; | 1577 | return; |
1520 | 1578 | ||
@@ -1523,6 +1581,15 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
1523 | return; | 1581 | return; |
1524 | } | 1582 | } |
1525 | 1583 | ||
1584 | /* Try to read receiver status if the link appears to be up */ | ||
1585 | ret = intel_dp_aux_native_read(intel_dp, | ||
1586 | 0x000, intel_dp->dpcd, | ||
1587 | sizeof (intel_dp->dpcd)); | ||
1588 | if (ret != sizeof(intel_dp->dpcd)) { | ||
1589 | intel_dp_link_down(intel_dp); | ||
1590 | return; | ||
1591 | } | ||
1592 | |||
1526 | if (!intel_channel_eq_ok(intel_dp)) { | 1593 | if (!intel_channel_eq_ok(intel_dp)) { |
1527 | intel_dp_start_link_train(intel_dp); | 1594 | intel_dp_start_link_train(intel_dp); |
1528 | intel_dp_complete_link_train(intel_dp); | 1595 | intel_dp_complete_link_train(intel_dp); |
@@ -1533,6 +1600,7 @@ static enum drm_connector_status | |||
1533 | ironlake_dp_detect(struct intel_dp *intel_dp) | 1600 | ironlake_dp_detect(struct intel_dp *intel_dp) |
1534 | { | 1601 | { |
1535 | enum drm_connector_status status; | 1602 | enum drm_connector_status status; |
1603 | bool ret; | ||
1536 | 1604 | ||
1537 | /* Can't disconnect eDP, but you can close the lid... */ | 1605 | /* Can't disconnect eDP, but you can close the lid... */ |
1538 | if (is_edp(intel_dp)) { | 1606 | if (is_edp(intel_dp)) { |
@@ -1543,13 +1611,11 @@ ironlake_dp_detect(struct intel_dp *intel_dp) | |||
1543 | } | 1611 | } |
1544 | 1612 | ||
1545 | status = connector_status_disconnected; | 1613 | status = connector_status_disconnected; |
1546 | if (intel_dp_aux_native_read(intel_dp, | 1614 | ret = intel_dp_aux_native_read_retry(intel_dp, |
1547 | 0x000, intel_dp->dpcd, | 1615 | 0x000, intel_dp->dpcd, |
1548 | sizeof (intel_dp->dpcd)) | 1616 | sizeof (intel_dp->dpcd)); |
1549 | == sizeof(intel_dp->dpcd)) { | 1617 | if (ret && intel_dp->dpcd[DP_DPCD_REV] != 0) |
1550 | if (intel_dp->dpcd[0] != 0) | 1618 | status = connector_status_connected; |
1551 | status = connector_status_connected; | ||
1552 | } | ||
1553 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], | 1619 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], |
1554 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); | 1620 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); |
1555 | return status; | 1621 | return status; |
@@ -1586,7 +1652,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
1586 | if (intel_dp_aux_native_read(intel_dp, 0x000, intel_dp->dpcd, | 1652 | if (intel_dp_aux_native_read(intel_dp, 0x000, intel_dp->dpcd, |
1587 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) | 1653 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) |
1588 | { | 1654 | { |
1589 | if (intel_dp->dpcd[0] != 0) | 1655 | if (intel_dp->dpcd[DP_DPCD_REV] != 0) |
1590 | status = connector_status_connected; | 1656 | status = connector_status_connected; |
1591 | } | 1657 | } |
1592 | 1658 | ||
@@ -1790,8 +1856,7 @@ intel_dp_hot_plug(struct intel_encoder *intel_encoder) | |||
1790 | { | 1856 | { |
1791 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); | 1857 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); |
1792 | 1858 | ||
1793 | if (intel_dp->dpms_mode == DRM_MODE_DPMS_ON) | 1859 | intel_dp_check_link_status(intel_dp); |
1794 | intel_dp_check_link_status(intel_dp); | ||
1795 | } | 1860 | } |
1796 | 1861 | ||
1797 | /* Return which DP Port should be selected for Transcoder DP control */ | 1862 | /* Return which DP Port should be selected for Transcoder DP control */ |
@@ -1859,7 +1924,6 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1859 | return; | 1924 | return; |
1860 | 1925 | ||
1861 | intel_dp->output_reg = output_reg; | 1926 | intel_dp->output_reg = output_reg; |
1862 | intel_dp->dpms_mode = -1; | ||
1863 | 1927 | ||
1864 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 1928 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1865 | if (!intel_connector) { | 1929 | if (!intel_connector) { |
@@ -1954,8 +2018,9 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1954 | sizeof(intel_dp->dpcd)); | 2018 | sizeof(intel_dp->dpcd)); |
1955 | ironlake_edp_panel_vdd_off(intel_dp); | 2019 | ironlake_edp_panel_vdd_off(intel_dp); |
1956 | if (ret == sizeof(intel_dp->dpcd)) { | 2020 | if (ret == sizeof(intel_dp->dpcd)) { |
1957 | if (intel_dp->dpcd[0] >= 0x11) | 2021 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) |
1958 | dev_priv->no_aux_handshake = intel_dp->dpcd[3] & | 2022 | dev_priv->no_aux_handshake = |
2023 | intel_dp->dpcd[DP_MAX_DOWNSPREAD] & | ||
1959 | DP_NO_AUX_HANDSHAKE_LINK_TRAINING; | 2024 | DP_NO_AUX_HANDSHAKE_LINK_TRAINING; |
1960 | } else { | 2025 | } else { |
1961 | /* if this fails, presume the device is a ghost */ | 2026 | /* if this fails, presume the device is a ghost */ |