diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 433 |
1 files changed, 272 insertions, 161 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 34c50460eaa7..a9f1307d32d8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -34,6 +34,8 @@ | |||
34 | 34 | ||
35 | #include "drm_crtc_helper.h" | 35 | #include "drm_crtc_helper.h" |
36 | 36 | ||
37 | #define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) | ||
38 | |||
37 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); | 39 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); |
38 | static void intel_update_watermarks(struct drm_device *dev); | 40 | static void intel_update_watermarks(struct drm_device *dev); |
39 | 41 | ||
@@ -601,6 +603,23 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) | |||
601 | return false; | 603 | return false; |
602 | } | 604 | } |
603 | 605 | ||
606 | struct drm_connector * | ||
607 | intel_pipe_get_output (struct drm_crtc *crtc) | ||
608 | { | ||
609 | struct drm_device *dev = crtc->dev; | ||
610 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
611 | struct drm_connector *l_entry, *ret = NULL; | ||
612 | |||
613 | list_for_each_entry(l_entry, &mode_config->connector_list, head) { | ||
614 | if (l_entry->encoder && | ||
615 | l_entry->encoder->crtc == crtc) { | ||
616 | ret = l_entry; | ||
617 | break; | ||
618 | } | ||
619 | } | ||
620 | return ret; | ||
621 | } | ||
622 | |||
604 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) | 623 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) |
605 | /** | 624 | /** |
606 | * Returns whether the given set of divisors are valid for a given refclk with | 625 | * Returns whether the given set of divisors are valid for a given refclk with |
@@ -790,6 +809,10 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
790 | int err_most = 47; | 809 | int err_most = 47; |
791 | found = false; | 810 | found = false; |
792 | 811 | ||
812 | /* eDP has only 2 clock choice, no n/m/p setting */ | ||
813 | if (HAS_eDP) | ||
814 | return true; | ||
815 | |||
793 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) | 816 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) |
794 | return intel_find_pll_igdng_dp(limit, crtc, target, | 817 | return intel_find_pll_igdng_dp(limit, crtc, target, |
795 | refclk, best_clock); | 818 | refclk, best_clock); |
@@ -1052,6 +1075,67 @@ static void i915_disable_vga (struct drm_device *dev) | |||
1052 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | 1075 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); |
1053 | } | 1076 | } |
1054 | 1077 | ||
1078 | static void igdng_disable_pll_edp (struct drm_crtc *crtc) | ||
1079 | { | ||
1080 | struct drm_device *dev = crtc->dev; | ||
1081 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1082 | u32 dpa_ctl; | ||
1083 | |||
1084 | DRM_DEBUG("\n"); | ||
1085 | dpa_ctl = I915_READ(DP_A); | ||
1086 | dpa_ctl &= ~DP_PLL_ENABLE; | ||
1087 | I915_WRITE(DP_A, dpa_ctl); | ||
1088 | } | ||
1089 | |||
1090 | static void igdng_enable_pll_edp (struct drm_crtc *crtc) | ||
1091 | { | ||
1092 | struct drm_device *dev = crtc->dev; | ||
1093 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1094 | u32 dpa_ctl; | ||
1095 | |||
1096 | dpa_ctl = I915_READ(DP_A); | ||
1097 | dpa_ctl |= DP_PLL_ENABLE; | ||
1098 | I915_WRITE(DP_A, dpa_ctl); | ||
1099 | udelay(200); | ||
1100 | } | ||
1101 | |||
1102 | |||
1103 | static void igdng_set_pll_edp (struct drm_crtc *crtc, int clock) | ||
1104 | { | ||
1105 | struct drm_device *dev = crtc->dev; | ||
1106 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1107 | u32 dpa_ctl; | ||
1108 | |||
1109 | DRM_DEBUG("eDP PLL enable for clock %d\n", clock); | ||
1110 | dpa_ctl = I915_READ(DP_A); | ||
1111 | dpa_ctl &= ~DP_PLL_FREQ_MASK; | ||
1112 | |||
1113 | if (clock < 200000) { | ||
1114 | u32 temp; | ||
1115 | dpa_ctl |= DP_PLL_FREQ_160MHZ; | ||
1116 | /* workaround for 160Mhz: | ||
1117 | 1) program 0x4600c bits 15:0 = 0x8124 | ||
1118 | 2) program 0x46010 bit 0 = 1 | ||
1119 | 3) program 0x46034 bit 24 = 1 | ||
1120 | 4) program 0x64000 bit 14 = 1 | ||
1121 | */ | ||
1122 | temp = I915_READ(0x4600c); | ||
1123 | temp &= 0xffff0000; | ||
1124 | I915_WRITE(0x4600c, temp | 0x8124); | ||
1125 | |||
1126 | temp = I915_READ(0x46010); | ||
1127 | I915_WRITE(0x46010, temp | 1); | ||
1128 | |||
1129 | temp = I915_READ(0x46034); | ||
1130 | I915_WRITE(0x46034, temp | (1 << 24)); | ||
1131 | } else { | ||
1132 | dpa_ctl |= DP_PLL_FREQ_270MHZ; | ||
1133 | } | ||
1134 | I915_WRITE(DP_A, dpa_ctl); | ||
1135 | |||
1136 | udelay(500); | ||
1137 | } | ||
1138 | |||
1055 | static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | 1139 | static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) |
1056 | { | 1140 | { |
1057 | struct drm_device *dev = crtc->dev; | 1141 | struct drm_device *dev = crtc->dev; |
@@ -1093,27 +1177,32 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1093 | case DRM_MODE_DPMS_STANDBY: | 1177 | case DRM_MODE_DPMS_STANDBY: |
1094 | case DRM_MODE_DPMS_SUSPEND: | 1178 | case DRM_MODE_DPMS_SUSPEND: |
1095 | DRM_DEBUG("crtc %d dpms on\n", pipe); | 1179 | DRM_DEBUG("crtc %d dpms on\n", pipe); |
1096 | /* enable PCH DPLL */ | 1180 | if (HAS_eDP) { |
1097 | temp = I915_READ(pch_dpll_reg); | 1181 | /* enable eDP PLL */ |
1098 | if ((temp & DPLL_VCO_ENABLE) == 0) { | 1182 | igdng_enable_pll_edp(crtc); |
1099 | I915_WRITE(pch_dpll_reg, temp | DPLL_VCO_ENABLE); | 1183 | } else { |
1100 | I915_READ(pch_dpll_reg); | 1184 | /* enable PCH DPLL */ |
1101 | } | 1185 | temp = I915_READ(pch_dpll_reg); |
1102 | 1186 | if ((temp & DPLL_VCO_ENABLE) == 0) { | |
1103 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ | 1187 | I915_WRITE(pch_dpll_reg, temp | DPLL_VCO_ENABLE); |
1104 | temp = I915_READ(fdi_rx_reg); | 1188 | I915_READ(pch_dpll_reg); |
1105 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | | 1189 | } |
1106 | FDI_SEL_PCDCLK | | ||
1107 | FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ | ||
1108 | I915_READ(fdi_rx_reg); | ||
1109 | udelay(200); | ||
1110 | 1190 | ||
1111 | /* Enable CPU FDI TX PLL, always on for IGDNG */ | 1191 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ |
1112 | temp = I915_READ(fdi_tx_reg); | 1192 | temp = I915_READ(fdi_rx_reg); |
1113 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { | 1193 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | |
1114 | I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE); | 1194 | FDI_SEL_PCDCLK | |
1115 | I915_READ(fdi_tx_reg); | 1195 | FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ |
1116 | udelay(100); | 1196 | I915_READ(fdi_rx_reg); |
1197 | udelay(200); | ||
1198 | |||
1199 | /* Enable CPU FDI TX PLL, always on for IGDNG */ | ||
1200 | temp = I915_READ(fdi_tx_reg); | ||
1201 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { | ||
1202 | I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE); | ||
1203 | I915_READ(fdi_tx_reg); | ||
1204 | udelay(100); | ||
1205 | } | ||
1117 | } | 1206 | } |
1118 | 1207 | ||
1119 | /* Enable CPU pipe */ | 1208 | /* Enable CPU pipe */ |
@@ -1132,122 +1221,126 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1132 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); | 1221 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); |
1133 | } | 1222 | } |
1134 | 1223 | ||
1135 | /* enable CPU FDI TX and PCH FDI RX */ | 1224 | if (!HAS_eDP) { |
1136 | temp = I915_READ(fdi_tx_reg); | 1225 | /* enable CPU FDI TX and PCH FDI RX */ |
1137 | temp |= FDI_TX_ENABLE; | 1226 | temp = I915_READ(fdi_tx_reg); |
1138 | temp |= FDI_DP_PORT_WIDTH_X4; /* default */ | 1227 | temp |= FDI_TX_ENABLE; |
1139 | temp &= ~FDI_LINK_TRAIN_NONE; | 1228 | temp |= FDI_DP_PORT_WIDTH_X4; /* default */ |
1140 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1229 | temp &= ~FDI_LINK_TRAIN_NONE; |
1141 | I915_WRITE(fdi_tx_reg, temp); | 1230 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1142 | I915_READ(fdi_tx_reg); | 1231 | I915_WRITE(fdi_tx_reg, temp); |
1232 | I915_READ(fdi_tx_reg); | ||
1143 | 1233 | ||
1144 | temp = I915_READ(fdi_rx_reg); | 1234 | temp = I915_READ(fdi_rx_reg); |
1145 | temp &= ~FDI_LINK_TRAIN_NONE; | 1235 | temp &= ~FDI_LINK_TRAIN_NONE; |
1146 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1236 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1147 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENABLE); | 1237 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENABLE); |
1148 | I915_READ(fdi_rx_reg); | 1238 | I915_READ(fdi_rx_reg); |
1149 | 1239 | ||
1150 | udelay(150); | 1240 | udelay(150); |
1151 | 1241 | ||
1152 | /* Train FDI. */ | 1242 | /* Train FDI. */ |
1153 | /* umask FDI RX Interrupt symbol_lock and bit_lock bit | 1243 | /* umask FDI RX Interrupt symbol_lock and bit_lock bit |
1154 | for train result */ | 1244 | for train result */ |
1155 | temp = I915_READ(fdi_rx_imr_reg); | 1245 | temp = I915_READ(fdi_rx_imr_reg); |
1156 | temp &= ~FDI_RX_SYMBOL_LOCK; | 1246 | temp &= ~FDI_RX_SYMBOL_LOCK; |
1157 | temp &= ~FDI_RX_BIT_LOCK; | 1247 | temp &= ~FDI_RX_BIT_LOCK; |
1158 | I915_WRITE(fdi_rx_imr_reg, temp); | 1248 | I915_WRITE(fdi_rx_imr_reg, temp); |
1159 | I915_READ(fdi_rx_imr_reg); | 1249 | I915_READ(fdi_rx_imr_reg); |
1160 | udelay(150); | 1250 | udelay(150); |
1161 | 1251 | ||
1162 | temp = I915_READ(fdi_rx_iir_reg); | 1252 | temp = I915_READ(fdi_rx_iir_reg); |
1163 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1253 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1164 | 1254 | ||
1165 | if ((temp & FDI_RX_BIT_LOCK) == 0) { | 1255 | if ((temp & FDI_RX_BIT_LOCK) == 0) { |
1166 | for (j = 0; j < tries; j++) { | 1256 | for (j = 0; j < tries; j++) { |
1167 | temp = I915_READ(fdi_rx_iir_reg); | 1257 | temp = I915_READ(fdi_rx_iir_reg); |
1168 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1258 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1169 | if (temp & FDI_RX_BIT_LOCK) | 1259 | if (temp & FDI_RX_BIT_LOCK) |
1170 | break; | 1260 | break; |
1171 | udelay(200); | 1261 | udelay(200); |
1172 | } | 1262 | } |
1173 | if (j != tries) | 1263 | if (j != tries) |
1264 | I915_WRITE(fdi_rx_iir_reg, | ||
1265 | temp | FDI_RX_BIT_LOCK); | ||
1266 | else | ||
1267 | DRM_DEBUG("train 1 fail\n"); | ||
1268 | } else { | ||
1174 | I915_WRITE(fdi_rx_iir_reg, | 1269 | I915_WRITE(fdi_rx_iir_reg, |
1175 | temp | FDI_RX_BIT_LOCK); | 1270 | temp | FDI_RX_BIT_LOCK); |
1176 | else | 1271 | DRM_DEBUG("train 1 ok 2!\n"); |
1177 | DRM_DEBUG("train 1 fail\n"); | 1272 | } |
1178 | } else { | 1273 | temp = I915_READ(fdi_tx_reg); |
1179 | I915_WRITE(fdi_rx_iir_reg, | 1274 | temp &= ~FDI_LINK_TRAIN_NONE; |
1180 | temp | FDI_RX_BIT_LOCK); | 1275 | temp |= FDI_LINK_TRAIN_PATTERN_2; |
1181 | DRM_DEBUG("train 1 ok 2!\n"); | 1276 | I915_WRITE(fdi_tx_reg, temp); |
1182 | } | 1277 | |
1183 | temp = I915_READ(fdi_tx_reg); | 1278 | temp = I915_READ(fdi_rx_reg); |
1184 | temp &= ~FDI_LINK_TRAIN_NONE; | 1279 | temp &= ~FDI_LINK_TRAIN_NONE; |
1185 | temp |= FDI_LINK_TRAIN_PATTERN_2; | 1280 | temp |= FDI_LINK_TRAIN_PATTERN_2; |
1186 | I915_WRITE(fdi_tx_reg, temp); | 1281 | I915_WRITE(fdi_rx_reg, temp); |
1187 | |||
1188 | temp = I915_READ(fdi_rx_reg); | ||
1189 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1190 | temp |= FDI_LINK_TRAIN_PATTERN_2; | ||
1191 | I915_WRITE(fdi_rx_reg, temp); | ||
1192 | 1282 | ||
1193 | udelay(150); | 1283 | udelay(150); |
1194 | 1284 | ||
1195 | temp = I915_READ(fdi_rx_iir_reg); | 1285 | temp = I915_READ(fdi_rx_iir_reg); |
1196 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1286 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1197 | 1287 | ||
1198 | if ((temp & FDI_RX_SYMBOL_LOCK) == 0) { | 1288 | if ((temp & FDI_RX_SYMBOL_LOCK) == 0) { |
1199 | for (j = 0; j < tries; j++) { | 1289 | for (j = 0; j < tries; j++) { |
1200 | temp = I915_READ(fdi_rx_iir_reg); | 1290 | temp = I915_READ(fdi_rx_iir_reg); |
1201 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1291 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1202 | if (temp & FDI_RX_SYMBOL_LOCK) | 1292 | if (temp & FDI_RX_SYMBOL_LOCK) |
1203 | break; | 1293 | break; |
1204 | udelay(200); | 1294 | udelay(200); |
1205 | } | 1295 | } |
1206 | if (j != tries) { | 1296 | if (j != tries) { |
1297 | I915_WRITE(fdi_rx_iir_reg, | ||
1298 | temp | FDI_RX_SYMBOL_LOCK); | ||
1299 | DRM_DEBUG("train 2 ok 1!\n"); | ||
1300 | } else | ||
1301 | DRM_DEBUG("train 2 fail\n"); | ||
1302 | } else { | ||
1207 | I915_WRITE(fdi_rx_iir_reg, | 1303 | I915_WRITE(fdi_rx_iir_reg, |
1208 | temp | FDI_RX_SYMBOL_LOCK); | 1304 | temp | FDI_RX_SYMBOL_LOCK); |
1209 | DRM_DEBUG("train 2 ok 1!\n"); | 1305 | DRM_DEBUG("train 2 ok 2!\n"); |
1210 | } else | 1306 | } |
1211 | DRM_DEBUG("train 2 fail\n"); | 1307 | DRM_DEBUG("train done\n"); |
1212 | } else { | ||
1213 | I915_WRITE(fdi_rx_iir_reg, temp | FDI_RX_SYMBOL_LOCK); | ||
1214 | DRM_DEBUG("train 2 ok 2!\n"); | ||
1215 | } | ||
1216 | DRM_DEBUG("train done\n"); | ||
1217 | 1308 | ||
1218 | /* set transcoder timing */ | 1309 | /* set transcoder timing */ |
1219 | I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg)); | 1310 | I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg)); |
1220 | I915_WRITE(trans_hblank_reg, I915_READ(cpu_hblank_reg)); | 1311 | I915_WRITE(trans_hblank_reg, I915_READ(cpu_hblank_reg)); |
1221 | I915_WRITE(trans_hsync_reg, I915_READ(cpu_hsync_reg)); | 1312 | I915_WRITE(trans_hsync_reg, I915_READ(cpu_hsync_reg)); |
1222 | 1313 | ||
1223 | I915_WRITE(trans_vtot_reg, I915_READ(cpu_vtot_reg)); | 1314 | I915_WRITE(trans_vtot_reg, I915_READ(cpu_vtot_reg)); |
1224 | I915_WRITE(trans_vblank_reg, I915_READ(cpu_vblank_reg)); | 1315 | I915_WRITE(trans_vblank_reg, I915_READ(cpu_vblank_reg)); |
1225 | I915_WRITE(trans_vsync_reg, I915_READ(cpu_vsync_reg)); | 1316 | I915_WRITE(trans_vsync_reg, I915_READ(cpu_vsync_reg)); |
1226 | 1317 | ||
1227 | /* enable PCH transcoder */ | 1318 | /* enable PCH transcoder */ |
1228 | temp = I915_READ(transconf_reg); | 1319 | temp = I915_READ(transconf_reg); |
1229 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | 1320 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); |
1230 | I915_READ(transconf_reg); | 1321 | I915_READ(transconf_reg); |
1231 | 1322 | ||
1232 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) | 1323 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) |
1233 | ; | 1324 | ; |
1234 | 1325 | ||
1235 | /* enable normal */ | 1326 | /* enable normal */ |
1236 | 1327 | ||
1237 | temp = I915_READ(fdi_tx_reg); | 1328 | temp = I915_READ(fdi_tx_reg); |
1238 | temp &= ~FDI_LINK_TRAIN_NONE; | 1329 | temp &= ~FDI_LINK_TRAIN_NONE; |
1239 | I915_WRITE(fdi_tx_reg, temp | FDI_LINK_TRAIN_NONE | | 1330 | I915_WRITE(fdi_tx_reg, temp | FDI_LINK_TRAIN_NONE | |
1240 | FDI_TX_ENHANCE_FRAME_ENABLE); | 1331 | FDI_TX_ENHANCE_FRAME_ENABLE); |
1241 | I915_READ(fdi_tx_reg); | 1332 | I915_READ(fdi_tx_reg); |
1242 | 1333 | ||
1243 | temp = I915_READ(fdi_rx_reg); | 1334 | temp = I915_READ(fdi_rx_reg); |
1244 | temp &= ~FDI_LINK_TRAIN_NONE; | 1335 | temp &= ~FDI_LINK_TRAIN_NONE; |
1245 | I915_WRITE(fdi_rx_reg, temp | FDI_LINK_TRAIN_NONE | | 1336 | I915_WRITE(fdi_rx_reg, temp | FDI_LINK_TRAIN_NONE | |
1246 | FDI_RX_ENHANCE_FRAME_ENABLE); | 1337 | FDI_RX_ENHANCE_FRAME_ENABLE); |
1247 | I915_READ(fdi_rx_reg); | 1338 | I915_READ(fdi_rx_reg); |
1248 | 1339 | ||
1249 | /* wait one idle pattern time */ | 1340 | /* wait one idle pattern time */ |
1250 | udelay(100); | 1341 | udelay(100); |
1342 | |||
1343 | } | ||
1251 | 1344 | ||
1252 | intel_crtc_load_lut(crtc); | 1345 | intel_crtc_load_lut(crtc); |
1253 | 1346 | ||
@@ -1286,6 +1379,10 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1286 | } else | 1379 | } else |
1287 | DRM_DEBUG("crtc %d is disabled\n", pipe); | 1380 | DRM_DEBUG("crtc %d is disabled\n", pipe); |
1288 | 1381 | ||
1382 | if (HAS_eDP) { | ||
1383 | igdng_disable_pll_edp(crtc); | ||
1384 | } | ||
1385 | |||
1289 | /* disable CPU FDI tx and PCH FDI rx */ | 1386 | /* disable CPU FDI tx and PCH FDI rx */ |
1290 | temp = I915_READ(fdi_tx_reg); | 1387 | temp = I915_READ(fdi_tx_reg); |
1291 | I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_ENABLE); | 1388 | I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_ENABLE); |
@@ -2152,6 +2249,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2152 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; | 2249 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; |
2153 | bool ok, is_sdvo = false, is_dvo = false; | 2250 | bool ok, is_sdvo = false, is_dvo = false; |
2154 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; | 2251 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
2252 | bool is_edp = false; | ||
2155 | struct drm_mode_config *mode_config = &dev->mode_config; | 2253 | struct drm_mode_config *mode_config = &dev->mode_config; |
2156 | struct drm_connector *connector; | 2254 | struct drm_connector *connector; |
2157 | const intel_limit_t *limit; | 2255 | const intel_limit_t *limit; |
@@ -2199,6 +2297,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2199 | case INTEL_OUTPUT_DISPLAYPORT: | 2297 | case INTEL_OUTPUT_DISPLAYPORT: |
2200 | is_dp = true; | 2298 | is_dp = true; |
2201 | break; | 2299 | break; |
2300 | case INTEL_OUTPUT_EDP: | ||
2301 | is_edp = true; | ||
2302 | break; | ||
2202 | } | 2303 | } |
2203 | 2304 | ||
2204 | num_outputs++; | 2305 | num_outputs++; |
@@ -2251,16 +2352,27 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2251 | 2352 | ||
2252 | /* FDI link */ | 2353 | /* FDI link */ |
2253 | if (IS_IGDNG(dev)) { | 2354 | if (IS_IGDNG(dev)) { |
2254 | /* DP over FDI requires target mode clock | 2355 | int lane, link_bw; |
2255 | instead of link clock */ | 2356 | /* eDP doesn't require FDI link, so just set DP M/N |
2256 | if (is_dp) | 2357 | according to current link config */ |
2358 | if (is_edp) { | ||
2359 | struct drm_connector *edp; | ||
2257 | target_clock = mode->clock; | 2360 | target_clock = mode->clock; |
2258 | else | 2361 | edp = intel_pipe_get_output(crtc); |
2259 | target_clock = adjusted_mode->clock; | 2362 | intel_edp_link_config(to_intel_output(edp), |
2260 | igdng_compute_m_n(3, 4, /* lane num 4 */ | 2363 | &lane, &link_bw); |
2261 | target_clock, | 2364 | } else { |
2262 | 270000, /* lane clock */ | 2365 | /* DP over FDI requires target mode clock |
2263 | &m_n); | 2366 | instead of link clock */ |
2367 | if (is_dp) | ||
2368 | target_clock = mode->clock; | ||
2369 | else | ||
2370 | target_clock = adjusted_mode->clock; | ||
2371 | lane = 4; | ||
2372 | link_bw = 270000; | ||
2373 | } | ||
2374 | igdng_compute_m_n(3, lane, target_clock, | ||
2375 | link_bw, &m_n); | ||
2264 | } | 2376 | } |
2265 | 2377 | ||
2266 | if (IS_IGD(dev)) | 2378 | if (IS_IGD(dev)) |
@@ -2382,29 +2494,15 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2382 | dpll_reg = pch_dpll_reg; | 2494 | dpll_reg = pch_dpll_reg; |
2383 | } | 2495 | } |
2384 | 2496 | ||
2385 | if (dpll & DPLL_VCO_ENABLE) { | 2497 | if (is_edp) { |
2498 | igdng_disable_pll_edp(crtc); | ||
2499 | } else if ((dpll & DPLL_VCO_ENABLE)) { | ||
2386 | I915_WRITE(fp_reg, fp); | 2500 | I915_WRITE(fp_reg, fp); |
2387 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); | 2501 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); |
2388 | I915_READ(dpll_reg); | 2502 | I915_READ(dpll_reg); |
2389 | udelay(150); | 2503 | udelay(150); |
2390 | } | 2504 | } |
2391 | 2505 | ||
2392 | if (IS_IGDNG(dev)) { | ||
2393 | /* enable PCH clock reference source */ | ||
2394 | /* XXX need to change the setting for other outputs */ | ||
2395 | u32 temp; | ||
2396 | temp = I915_READ(PCH_DREF_CONTROL); | ||
2397 | temp &= ~DREF_NONSPREAD_SOURCE_MASK; | ||
2398 | temp |= DREF_NONSPREAD_CK505_ENABLE; | ||
2399 | temp &= ~DREF_SSC_SOURCE_MASK; | ||
2400 | temp |= DREF_SSC_SOURCE_ENABLE; | ||
2401 | temp &= ~DREF_SSC1_ENABLE; | ||
2402 | /* if no eDP, disable source output to CPU */ | ||
2403 | temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; | ||
2404 | temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; | ||
2405 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
2406 | } | ||
2407 | |||
2408 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. | 2506 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
2409 | * This is an exception to the general rule that mode_set doesn't turn | 2507 | * This is an exception to the general rule that mode_set doesn't turn |
2410 | * things on. | 2508 | * things on. |
@@ -2436,23 +2534,25 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2436 | if (is_dp) | 2534 | if (is_dp) |
2437 | intel_dp_set_m_n(crtc, mode, adjusted_mode); | 2535 | intel_dp_set_m_n(crtc, mode, adjusted_mode); |
2438 | 2536 | ||
2439 | I915_WRITE(fp_reg, fp); | 2537 | if (!is_edp) { |
2440 | I915_WRITE(dpll_reg, dpll); | 2538 | I915_WRITE(fp_reg, fp); |
2441 | I915_READ(dpll_reg); | ||
2442 | /* Wait for the clocks to stabilize. */ | ||
2443 | udelay(150); | ||
2444 | |||
2445 | if (IS_I965G(dev) && !IS_IGDNG(dev)) { | ||
2446 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | ||
2447 | I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | | ||
2448 | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); | ||
2449 | } else { | ||
2450 | /* write it again -- the BIOS does, after all */ | ||
2451 | I915_WRITE(dpll_reg, dpll); | 2539 | I915_WRITE(dpll_reg, dpll); |
2540 | I915_READ(dpll_reg); | ||
2541 | /* Wait for the clocks to stabilize. */ | ||
2542 | udelay(150); | ||
2543 | |||
2544 | if (IS_I965G(dev) && !IS_IGDNG(dev)) { | ||
2545 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | ||
2546 | I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | | ||
2547 | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); | ||
2548 | } else { | ||
2549 | /* write it again -- the BIOS does, after all */ | ||
2550 | I915_WRITE(dpll_reg, dpll); | ||
2551 | } | ||
2552 | I915_READ(dpll_reg); | ||
2553 | /* Wait for the clocks to stabilize. */ | ||
2554 | udelay(150); | ||
2452 | } | 2555 | } |
2453 | I915_READ(dpll_reg); | ||
2454 | /* Wait for the clocks to stabilize. */ | ||
2455 | udelay(150); | ||
2456 | 2556 | ||
2457 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | | 2557 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | |
2458 | ((adjusted_mode->crtc_htotal - 1) << 16)); | 2558 | ((adjusted_mode->crtc_htotal - 1) << 16)); |
@@ -2482,10 +2582,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2482 | I915_WRITE(link_m1_reg, m_n.link_m); | 2582 | I915_WRITE(link_m1_reg, m_n.link_m); |
2483 | I915_WRITE(link_n1_reg, m_n.link_n); | 2583 | I915_WRITE(link_n1_reg, m_n.link_n); |
2484 | 2584 | ||
2485 | /* enable FDI RX PLL too */ | 2585 | if (is_edp) { |
2486 | temp = I915_READ(fdi_rx_reg); | 2586 | igdng_set_pll_edp(crtc, adjusted_mode->clock); |
2487 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); | 2587 | } else { |
2488 | udelay(200); | 2588 | /* enable FDI RX PLL too */ |
2589 | temp = I915_READ(fdi_rx_reg); | ||
2590 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); | ||
2591 | udelay(200); | ||
2592 | } | ||
2489 | } | 2593 | } |
2490 | 2594 | ||
2491 | I915_WRITE(pipeconf_reg, pipeconf); | 2595 | I915_WRITE(pipeconf_reg, pipeconf); |
@@ -3083,6 +3187,9 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
3083 | if (IS_IGDNG(dev)) { | 3187 | if (IS_IGDNG(dev)) { |
3084 | int found; | 3188 | int found; |
3085 | 3189 | ||
3190 | if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED)) | ||
3191 | intel_dp_init(dev, DP_A); | ||
3192 | |||
3086 | if (I915_READ(HDMIB) & PORT_DETECTED) { | 3193 | if (I915_READ(HDMIB) & PORT_DETECTED) { |
3087 | /* check SDVOB */ | 3194 | /* check SDVOB */ |
3088 | /* found = intel_sdvo_init(dev, HDMIB); */ | 3195 | /* found = intel_sdvo_init(dev, HDMIB); */ |
@@ -3179,6 +3286,10 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
3179 | (1 << 1)); | 3286 | (1 << 1)); |
3180 | clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); | 3287 | clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); |
3181 | break; | 3288 | break; |
3289 | case INTEL_OUTPUT_EDP: | ||
3290 | crtc_mask = (1 << 1); | ||
3291 | clone_mask = (1 << INTEL_OUTPUT_EDP); | ||
3292 | break; | ||
3182 | } | 3293 | } |
3183 | encoder->possible_crtcs = crtc_mask; | 3294 | encoder->possible_crtcs = crtc_mask; |
3184 | encoder->possible_clones = intel_connector_clones(dev, clone_mask); | 3295 | encoder->possible_clones = intel_connector_clones(dev, clone_mask); |