aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_display.c41
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c131
3 files changed, 154 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6ffabab3bb60..790fef32afef 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1001,6 +1001,7 @@ extern void i8xx_disable_fbc(struct drm_device *dev);
1001extern void g4x_disable_fbc(struct drm_device *dev); 1001extern void g4x_disable_fbc(struct drm_device *dev);
1002 1002
1003extern void intel_detect_pch (struct drm_device *dev); 1003extern void intel_detect_pch (struct drm_device *dev);
1004extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
1004 1005
1005/** 1006/**
1006 * Lock test for when it's just for synchronization of ring access. 1007 * Lock test for when it's just for synchronization of ring access.
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 606924ef65a6..1a7c7ac66efd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1893,6 +1893,39 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
1893 /* wait one idle pattern time */ 1893 /* wait one idle pattern time */
1894 udelay(100); 1894 udelay(100);
1895 1895
1896 /* For PCH DP, enable TRANS_DP_CTL */
1897 if (HAS_PCH_CPT(dev) &&
1898 intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
1899 int trans_dp_ctl = (pipe == 0) ? TRANS_DP_CTL_A : TRANS_DP_CTL_B;
1900 int reg;
1901
1902 reg = I915_READ(trans_dp_ctl);
1903 reg &= ~TRANS_DP_PORT_SEL_MASK;
1904 reg = TRANS_DP_OUTPUT_ENABLE |
1905 TRANS_DP_ENH_FRAMING |
1906 TRANS_DP_VSYNC_ACTIVE_HIGH |
1907 TRANS_DP_HSYNC_ACTIVE_HIGH;
1908
1909 switch (intel_trans_dp_port_sel(crtc)) {
1910 case PCH_DP_B:
1911 reg |= TRANS_DP_PORT_SEL_B;
1912 break;
1913 case PCH_DP_C:
1914 reg |= TRANS_DP_PORT_SEL_C;
1915 break;
1916 case PCH_DP_D:
1917 reg |= TRANS_DP_PORT_SEL_D;
1918 break;
1919 default:
1920 DRM_DEBUG_KMS("Wrong PCH DP port return. Guess port B\n");
1921 reg |= TRANS_DP_PORT_SEL_B;
1922 break;
1923 }
1924
1925 I915_WRITE(trans_dp_ctl, reg);
1926 POSTING_READ(trans_dp_ctl);
1927 }
1928
1896 /* enable PCH transcoder */ 1929 /* enable PCH transcoder */
1897 temp = I915_READ(transconf_reg); 1930 temp = I915_READ(transconf_reg);
1898 /* 1931 /*
@@ -2030,6 +2063,14 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
2030 udelay(100); 2063 udelay(100);
2031 2064
2032 if (HAS_PCH_CPT(dev)) { 2065 if (HAS_PCH_CPT(dev)) {
2066 /* disable TRANS_DP_CTL */
2067 int trans_dp_ctl = (pipe == 0) ? TRANS_DP_CTL_A : TRANS_DP_CTL_B;
2068 int reg;
2069
2070 reg = I915_READ(trans_dp_ctl);
2071 reg &= ~(TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK);
2072 I915_WRITE(trans_dp_ctl, reg);
2073 POSTING_READ(trans_dp_ctl);
2033 2074
2034 /* disable DPLL_SEL */ 2075 /* disable DPLL_SEL */
2035 temp = I915_READ(PCH_DPLL_SEL); 2076 temp = I915_READ(PCH_DPLL_SEL);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 8f2dd65abaca..a0e18b01612e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -221,19 +221,27 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder,
221 uint32_t ctl; 221 uint32_t ctl;
222 uint32_t status; 222 uint32_t status;
223 uint32_t aux_clock_divider; 223 uint32_t aux_clock_divider;
224 int try; 224 int try, precharge;
225 225
226 /* The clock divider is based off the hrawclk, 226 /* The clock divider is based off the hrawclk,
227 * and would like to run at 2MHz. So, take the 227 * and would like to run at 2MHz. So, take the
228 * hrawclk value and divide by 2 and use that 228 * hrawclk value and divide by 2 and use that
229 */ 229 */
230 if (IS_eDP(intel_encoder)) 230 if (IS_eDP(intel_encoder)) {
231 aux_clock_divider = 225; /* eDP input clock at 450Mhz */ 231 if (IS_GEN6(dev))
232 else if (HAS_PCH_SPLIT(dev)) 232 aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */
233 else
234 aux_clock_divider = 225; /* eDP input clock at 450Mhz */
235 } else if (HAS_PCH_SPLIT(dev))
233 aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */ 236 aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */
234 else 237 else
235 aux_clock_divider = intel_hrawclk(dev) / 2; 238 aux_clock_divider = intel_hrawclk(dev) / 2;
236 239
240 if (IS_GEN6(dev))
241 precharge = 3;
242 else
243 precharge = 5;
244
237 /* Must try at least 3 times according to DP spec */ 245 /* Must try at least 3 times according to DP spec */
238 for (try = 0; try < 5; try++) { 246 for (try = 0; try < 5; try++) {
239 /* Load the send data into the aux channel data registers */ 247 /* Load the send data into the aux channel data registers */
@@ -246,7 +254,7 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder,
246 ctl = (DP_AUX_CH_CTL_SEND_BUSY | 254 ctl = (DP_AUX_CH_CTL_SEND_BUSY |
247 DP_AUX_CH_CTL_TIME_OUT_400us | 255 DP_AUX_CH_CTL_TIME_OUT_400us |
248 (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | 256 (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
249 (5 << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | 257 (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
250 (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | 258 (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) |
251 DP_AUX_CH_CTL_DONE | 259 DP_AUX_CH_CTL_DONE |
252 DP_AUX_CH_CTL_TIME_OUT_ERROR | 260 DP_AUX_CH_CTL_TIME_OUT_ERROR |
@@ -623,17 +631,22 @@ static void
623intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, 631intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
624 struct drm_display_mode *adjusted_mode) 632 struct drm_display_mode *adjusted_mode)
625{ 633{
634 struct drm_device *dev = encoder->dev;
626 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); 635 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
627 struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; 636 struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
628 struct drm_crtc *crtc = intel_encoder->enc.crtc; 637 struct drm_crtc *crtc = intel_encoder->enc.crtc;
629 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 638 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
630 639
631 dp_priv->DP = (DP_LINK_TRAIN_OFF | 640 dp_priv->DP = (DP_VOLTAGE_0_4 |
632 DP_VOLTAGE_0_4 |
633 DP_PRE_EMPHASIS_0 | 641 DP_PRE_EMPHASIS_0 |
634 DP_SYNC_VS_HIGH | 642 DP_SYNC_VS_HIGH |
635 DP_SYNC_HS_HIGH); 643 DP_SYNC_HS_HIGH);
636 644
645 if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
646 dp_priv->DP |= DP_LINK_TRAIN_OFF_CPT;
647 else
648 dp_priv->DP |= DP_LINK_TRAIN_OFF;
649
637 switch (dp_priv->lane_count) { 650 switch (dp_priv->lane_count) {
638 case 1: 651 case 1:
639 dp_priv->DP |= DP_PORT_WIDTH_1; 652 dp_priv->DP |= DP_PORT_WIDTH_1;
@@ -661,7 +674,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
661 dp_priv->DP |= DP_ENHANCED_FRAMING; 674 dp_priv->DP |= DP_ENHANCED_FRAMING;
662 } 675 }
663 676
664 if (intel_crtc->pipe == 1) 677 /* CPT DP's pipe select is decided in TRANS_DP_CTL */
678 if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev))
665 dp_priv->DP |= DP_PIPEB_SELECT; 679 dp_priv->DP |= DP_PIPEB_SELECT;
666 680
667 if (IS_eDP(intel_encoder)) { 681 if (IS_eDP(intel_encoder)) {
@@ -875,6 +889,25 @@ intel_dp_signal_levels(uint8_t train_set, int lane_count)
875 return signal_levels; 889 return signal_levels;
876} 890}
877 891
892/* Gen6's DP voltage swing and pre-emphasis control */
893static uint32_t
894intel_gen6_edp_signal_levels(uint8_t train_set)
895{
896 switch (train_set & (DP_TRAIN_VOLTAGE_SWING_MASK|DP_TRAIN_PRE_EMPHASIS_MASK)) {
897 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0:
898 return EDP_LINK_TRAIN_400MV_0DB_SNB_B;
899 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6:
900 return EDP_LINK_TRAIN_400MV_6DB_SNB_B;
901 case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5:
902 return EDP_LINK_TRAIN_600MV_3_5DB_SNB_B;
903 case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0:
904 return EDP_LINK_TRAIN_800MV_0DB_SNB_B;
905 default:
906 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level\n");
907 return EDP_LINK_TRAIN_400MV_0DB_SNB_B;
908 }
909}
910
878static uint8_t 911static uint8_t
879intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], 912intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
880 int lane) 913 int lane)
@@ -968,23 +1001,38 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
968 bool channel_eq = false; 1001 bool channel_eq = false;
969 bool first = true; 1002 bool first = true;
970 int tries; 1003 int tries;
1004 u32 reg;
971 1005
972 /* Write the link configuration data */ 1006 /* Write the link configuration data */
973 intel_dp_aux_native_write(intel_encoder, 0x100, 1007 intel_dp_aux_native_write(intel_encoder, 0x100,
974 link_configuration, DP_LINK_CONFIGURATION_SIZE); 1008 link_configuration, DP_LINK_CONFIGURATION_SIZE);
975 1009
976 DP |= DP_PORT_EN; 1010 DP |= DP_PORT_EN;
977 DP &= ~DP_LINK_TRAIN_MASK; 1011 if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
1012 DP &= ~DP_LINK_TRAIN_MASK_CPT;
1013 else
1014 DP &= ~DP_LINK_TRAIN_MASK;
978 memset(train_set, 0, 4); 1015 memset(train_set, 0, 4);
979 voltage = 0xff; 1016 voltage = 0xff;
980 tries = 0; 1017 tries = 0;
981 clock_recovery = false; 1018 clock_recovery = false;
982 for (;;) { 1019 for (;;) {
983 /* Use train_set[0] to set the voltage and pre emphasis values */ 1020 /* Use train_set[0] to set the voltage and pre emphasis values */
984 uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); 1021 uint32_t signal_levels;
985 DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; 1022 if (IS_GEN6(dev) && IS_eDP(intel_encoder)) {
1023 signal_levels = intel_gen6_edp_signal_levels(train_set[0]);
1024 DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
1025 } else {
1026 signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count);
1027 DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
1028 }
986 1029
987 if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_1, 1030 if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
1031 reg = DP | DP_LINK_TRAIN_PAT_1_CPT;
1032 else
1033 reg = DP | DP_LINK_TRAIN_PAT_1;
1034
1035 if (!intel_dp_set_link_train(intel_encoder, reg,
988 DP_TRAINING_PATTERN_1, train_set, first)) 1036 DP_TRAINING_PATTERN_1, train_set, first))
989 break; 1037 break;
990 first = false; 1038 first = false;
@@ -1024,11 +1072,23 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
1024 channel_eq = false; 1072 channel_eq = false;
1025 for (;;) { 1073 for (;;) {
1026 /* Use train_set[0] to set the voltage and pre emphasis values */ 1074 /* Use train_set[0] to set the voltage and pre emphasis values */
1027 uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); 1075 uint32_t signal_levels;
1028 DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; 1076
1077 if (IS_GEN6(dev) && IS_eDP(intel_encoder)) {
1078 signal_levels = intel_gen6_edp_signal_levels(train_set[0]);
1079 DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
1080 } else {
1081 signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count);
1082 DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
1083 }
1084
1085 if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
1086 reg = DP | DP_LINK_TRAIN_PAT_2_CPT;
1087 else
1088 reg = DP | DP_LINK_TRAIN_PAT_2;
1029 1089
1030 /* channel eq pattern */ 1090 /* channel eq pattern */
1031 if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_2, 1091 if (!intel_dp_set_link_train(intel_encoder, reg,
1032 DP_TRAINING_PATTERN_2, train_set, 1092 DP_TRAINING_PATTERN_2, train_set,
1033 false)) 1093 false))
1034 break; 1094 break;
@@ -1051,7 +1111,12 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
1051 ++tries; 1111 ++tries;
1052 } 1112 }
1053 1113
1054 I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF); 1114 if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder))
1115 reg = DP | DP_LINK_TRAIN_OFF_CPT;
1116 else
1117 reg = DP | DP_LINK_TRAIN_OFF;
1118
1119 I915_WRITE(dp_priv->output_reg, reg);
1055 POSTING_READ(dp_priv->output_reg); 1120 POSTING_READ(dp_priv->output_reg);
1056 intel_dp_aux_native_write_1(intel_encoder, 1121 intel_dp_aux_native_write_1(intel_encoder,
1057 DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); 1122 DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE);
@@ -1073,9 +1138,15 @@ intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP)
1073 udelay(100); 1138 udelay(100);
1074 } 1139 }
1075 1140
1076 DP &= ~DP_LINK_TRAIN_MASK; 1141 if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) {
1077 I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); 1142 DP &= ~DP_LINK_TRAIN_MASK_CPT;
1078 POSTING_READ(dp_priv->output_reg); 1143 I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT);
1144 POSTING_READ(dp_priv->output_reg);
1145 } else {
1146 DP &= ~DP_LINK_TRAIN_MASK;
1147 I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE);
1148 POSTING_READ(dp_priv->output_reg);
1149 }
1079 1150
1080 udelay(17000); 1151 udelay(17000);
1081 1152
@@ -1268,6 +1339,28 @@ intel_dp_hot_plug(struct intel_encoder *intel_encoder)
1268 intel_dp_check_link_status(intel_encoder); 1339 intel_dp_check_link_status(intel_encoder);
1269} 1340}
1270 1341
1342/* Return which DP Port should be selected for Transcoder DP control */
1343int
1344intel_trans_dp_port_sel (struct drm_crtc *crtc)
1345{
1346 struct drm_device *dev = crtc->dev;
1347 struct drm_mode_config *mode_config = &dev->mode_config;
1348 struct drm_encoder *encoder;
1349 struct intel_encoder *intel_encoder = NULL;
1350
1351 list_for_each_entry(encoder, &mode_config->encoder_list, head) {
1352 if (!encoder || encoder->crtc != crtc)
1353 continue;
1354
1355 intel_encoder = enc_to_intel_encoder(encoder);
1356 if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
1357 struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
1358 return dp_priv->output_reg;
1359 }
1360 }
1361 return -1;
1362}
1363
1271void 1364void
1272intel_dp_init(struct drm_device *dev, int output_reg) 1365intel_dp_init(struct drm_device *dev, int output_reg)
1273{ 1366{