diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.h | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 433 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 112 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 4 |
8 files changed, 468 insertions, 168 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b05b44dd3bf6..5f3a259d95e9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -219,6 +219,7 @@ typedef struct drm_i915_private { | |||
219 | unsigned int lvds_vbt:1; | 219 | unsigned int lvds_vbt:1; |
220 | unsigned int int_crt_support:1; | 220 | unsigned int int_crt_support:1; |
221 | unsigned int lvds_use_ssc:1; | 221 | unsigned int lvds_use_ssc:1; |
222 | unsigned int edp_support:1; | ||
222 | int lvds_ssc_freq; | 223 | int lvds_ssc_freq; |
223 | 224 | ||
224 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ | 225 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ |
@@ -889,6 +890,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
889 | IS_I915GM(dev))) | 890 | IS_I915GM(dev))) |
890 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 891 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
891 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 892 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
893 | #define SUPPORTS_EDP(dev) (IS_IGDNG_M(dev)) | ||
892 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) | 894 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) |
893 | /* dsparb controlled by hw only */ | 895 | /* dsparb controlled by hw only */ |
894 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 896 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 4518a9489ed1..2955083aa471 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -1395,6 +1395,7 @@ | |||
1395 | #define TV_V_CHROMA_42 0x684a8 | 1395 | #define TV_V_CHROMA_42 0x684a8 |
1396 | 1396 | ||
1397 | /* Display Port */ | 1397 | /* Display Port */ |
1398 | #define DP_A 0x64000 /* eDP */ | ||
1398 | #define DP_B 0x64100 | 1399 | #define DP_B 0x64100 |
1399 | #define DP_C 0x64200 | 1400 | #define DP_C 0x64200 |
1400 | #define DP_D 0x64300 | 1401 | #define DP_D 0x64300 |
@@ -1437,9 +1438,17 @@ | |||
1437 | /* Mystic DPCD version 1.1 special mode */ | 1438 | /* Mystic DPCD version 1.1 special mode */ |
1438 | #define DP_ENHANCED_FRAMING (1 << 18) | 1439 | #define DP_ENHANCED_FRAMING (1 << 18) |
1439 | 1440 | ||
1441 | /* eDP */ | ||
1442 | #define DP_PLL_FREQ_270MHZ (0 << 16) | ||
1443 | #define DP_PLL_FREQ_160MHZ (1 << 16) | ||
1444 | #define DP_PLL_FREQ_MASK (3 << 16) | ||
1445 | |||
1440 | /** locked once port is enabled */ | 1446 | /** locked once port is enabled */ |
1441 | #define DP_PORT_REVERSAL (1 << 15) | 1447 | #define DP_PORT_REVERSAL (1 << 15) |
1442 | 1448 | ||
1449 | /* eDP */ | ||
1450 | #define DP_PLL_ENABLE (1 << 14) | ||
1451 | |||
1443 | /** sends the clock on lane 15 of the PEG for debug */ | 1452 | /** sends the clock on lane 15 of the PEG for debug */ |
1444 | #define DP_CLOCK_OUTPUT_ENABLE (1 << 13) | 1453 | #define DP_CLOCK_OUTPUT_ENABLE (1 << 13) |
1445 | 1454 | ||
@@ -1464,6 +1473,13 @@ | |||
1464 | * is 20 bytes in each direction, hence the 5 fixed | 1473 | * is 20 bytes in each direction, hence the 5 fixed |
1465 | * data registers | 1474 | * data registers |
1466 | */ | 1475 | */ |
1476 | #define DPA_AUX_CH_CTL 0x64010 | ||
1477 | #define DPA_AUX_CH_DATA1 0x64014 | ||
1478 | #define DPA_AUX_CH_DATA2 0x64018 | ||
1479 | #define DPA_AUX_CH_DATA3 0x6401c | ||
1480 | #define DPA_AUX_CH_DATA4 0x64020 | ||
1481 | #define DPA_AUX_CH_DATA5 0x64024 | ||
1482 | |||
1467 | #define DPB_AUX_CH_CTL 0x64110 | 1483 | #define DPB_AUX_CH_CTL 0x64110 |
1468 | #define DPB_AUX_CH_DATA1 0x64114 | 1484 | #define DPB_AUX_CH_DATA1 0x64114 |
1469 | #define DPB_AUX_CH_DATA2 0x64118 | 1485 | #define DPB_AUX_CH_DATA2 0x64118 |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 5c7a62a96ae7..300aee3296c2 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -296,6 +296,25 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
296 | } | 296 | } |
297 | return; | 297 | return; |
298 | } | 298 | } |
299 | |||
300 | static void | ||
301 | parse_driver_features(struct drm_i915_private *dev_priv, | ||
302 | struct bdb_header *bdb) | ||
303 | { | ||
304 | struct drm_device *dev = dev_priv->dev; | ||
305 | struct bdb_driver_features *driver; | ||
306 | |||
307 | /* set default for chips without eDP */ | ||
308 | if (!SUPPORTS_EDP(dev)) { | ||
309 | dev_priv->edp_support = 0; | ||
310 | return; | ||
311 | } | ||
312 | |||
313 | driver = find_section(bdb, BDB_DRIVER_FEATURES); | ||
314 | if (driver && driver->lvds_config == BDB_DRIVER_FEATURE_EDP) | ||
315 | dev_priv->edp_support = 1; | ||
316 | } | ||
317 | |||
299 | /** | 318 | /** |
300 | * intel_init_bios - initialize VBIOS settings & find VBT | 319 | * intel_init_bios - initialize VBIOS settings & find VBT |
301 | * @dev: DRM device | 320 | * @dev: DRM device |
@@ -346,6 +365,8 @@ intel_init_bios(struct drm_device *dev) | |||
346 | parse_lfp_panel_data(dev_priv, bdb); | 365 | parse_lfp_panel_data(dev_priv, bdb); |
347 | parse_sdvo_panel_data(dev_priv, bdb); | 366 | parse_sdvo_panel_data(dev_priv, bdb); |
348 | parse_sdvo_device_mapping(dev_priv, bdb); | 367 | parse_sdvo_device_mapping(dev_priv, bdb); |
368 | parse_driver_features(dev_priv, bdb); | ||
369 | |||
349 | pci_unmap_rom(pdev, bios); | 370 | pci_unmap_rom(pdev, bios); |
350 | 371 | ||
351 | return 0; | 372 | return 0; |
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index fe72e1c225d8..0f8e5f69ac7a 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h | |||
@@ -381,6 +381,51 @@ struct bdb_sdvo_lvds_options { | |||
381 | } __attribute__((packed)); | 381 | } __attribute__((packed)); |
382 | 382 | ||
383 | 383 | ||
384 | #define BDB_DRIVER_FEATURE_NO_LVDS 0 | ||
385 | #define BDB_DRIVER_FEATURE_INT_LVDS 1 | ||
386 | #define BDB_DRIVER_FEATURE_SDVO_LVDS 2 | ||
387 | #define BDB_DRIVER_FEATURE_EDP 3 | ||
388 | |||
389 | struct bdb_driver_features { | ||
390 | u8 boot_dev_algorithm:1; | ||
391 | u8 block_display_switch:1; | ||
392 | u8 allow_display_switch:1; | ||
393 | u8 hotplug_dvo:1; | ||
394 | u8 dual_view_zoom:1; | ||
395 | u8 int15h_hook:1; | ||
396 | u8 sprite_in_clone:1; | ||
397 | u8 primary_lfp_id:1; | ||
398 | |||
399 | u16 boot_mode_x; | ||
400 | u16 boot_mode_y; | ||
401 | u8 boot_mode_bpp; | ||
402 | u8 boot_mode_refresh; | ||
403 | |||
404 | u16 enable_lfp_primary:1; | ||
405 | u16 selective_mode_pruning:1; | ||
406 | u16 dual_frequency:1; | ||
407 | u16 render_clock_freq:1; /* 0: high freq; 1: low freq */ | ||
408 | u16 nt_clone_support:1; | ||
409 | u16 power_scheme_ui:1; /* 0: CUI; 1: 3rd party */ | ||
410 | u16 sprite_display_assign:1; /* 0: secondary; 1: primary */ | ||
411 | u16 cui_aspect_scaling:1; | ||
412 | u16 preserve_aspect_ratio:1; | ||
413 | u16 sdvo_device_power_down:1; | ||
414 | u16 crt_hotplug:1; | ||
415 | u16 lvds_config:2; | ||
416 | u16 tv_hotplug:1; | ||
417 | u16 hdmi_config:2; | ||
418 | |||
419 | u8 static_display:1; | ||
420 | u8 reserved2:7; | ||
421 | u16 legacy_crt_max_x; | ||
422 | u16 legacy_crt_max_y; | ||
423 | u8 legacy_crt_max_refresh; | ||
424 | |||
425 | u8 hdmi_termination; | ||
426 | u8 custom_vbt_version; | ||
427 | } __attribute__((packed)); | ||
428 | |||
384 | bool intel_init_bios(struct drm_device *dev); | 429 | bool intel_init_bios(struct drm_device *dev); |
385 | 430 | ||
386 | /* | 431 | /* |
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); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0715911cbd84..a6ff15ac548a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -40,6 +40,8 @@ | |||
40 | 40 | ||
41 | #define DP_LINK_CONFIGURATION_SIZE 9 | 41 | #define DP_LINK_CONFIGURATION_SIZE 9 |
42 | 42 | ||
43 | #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP) | ||
44 | |||
43 | struct intel_dp_priv { | 45 | struct intel_dp_priv { |
44 | uint32_t output_reg; | 46 | uint32_t output_reg; |
45 | uint32_t DP; | 47 | uint32_t DP; |
@@ -63,6 +65,19 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | |||
63 | static void | 65 | static void |
64 | intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); | 66 | intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); |
65 | 67 | ||
68 | void | ||
69 | intel_edp_link_config (struct intel_output *intel_output, | ||
70 | int *lane_num, int *link_bw) | ||
71 | { | ||
72 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
73 | |||
74 | *lane_num = dp_priv->lane_count; | ||
75 | if (dp_priv->link_bw == DP_LINK_BW_1_62) | ||
76 | *link_bw = 162000; | ||
77 | else if (dp_priv->link_bw == DP_LINK_BW_2_7) | ||
78 | *link_bw = 270000; | ||
79 | } | ||
80 | |||
66 | static int | 81 | static int |
67 | intel_dp_max_lane_count(struct intel_output *intel_output) | 82 | intel_dp_max_lane_count(struct intel_output *intel_output) |
68 | { | 83 | { |
@@ -206,9 +221,10 @@ intel_dp_aux_ch(struct intel_output *intel_output, | |||
206 | * and would like to run at 2MHz. So, take the | 221 | * and would like to run at 2MHz. So, take the |
207 | * hrawclk value and divide by 2 and use that | 222 | * hrawclk value and divide by 2 and use that |
208 | */ | 223 | */ |
209 | /* IGDNG: input clock fixed at 125Mhz, so aux_bit_clk always 62 */ | 224 | if (IS_eDP(intel_output)) |
210 | if (IS_IGDNG(dev)) | 225 | aux_clock_divider = 225; /* eDP input clock at 450Mhz */ |
211 | aux_clock_divider = 62; | 226 | else if (IS_IGDNG(dev)) |
227 | aux_clock_divider = 62; /* IGDNG: input clock fixed at 125Mhz */ | ||
212 | else | 228 | else |
213 | aux_clock_divider = intel_hrawclk(dev) / 2; | 229 | aux_clock_divider = intel_hrawclk(dev) / 2; |
214 | 230 | ||
@@ -579,8 +595,38 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
579 | 595 | ||
580 | if (intel_crtc->pipe == 1) | 596 | if (intel_crtc->pipe == 1) |
581 | dp_priv->DP |= DP_PIPEB_SELECT; | 597 | dp_priv->DP |= DP_PIPEB_SELECT; |
598 | |||
599 | if (IS_eDP(intel_output)) { | ||
600 | /* don't miss out required setting for eDP */ | ||
601 | dp_priv->DP |= DP_PLL_ENABLE; | ||
602 | if (adjusted_mode->clock < 200000) | ||
603 | dp_priv->DP |= DP_PLL_FREQ_160MHZ; | ||
604 | else | ||
605 | dp_priv->DP |= DP_PLL_FREQ_270MHZ; | ||
606 | } | ||
582 | } | 607 | } |
583 | 608 | ||
609 | static void igdng_edp_backlight_on (struct drm_device *dev) | ||
610 | { | ||
611 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
612 | u32 pp; | ||
613 | |||
614 | DRM_DEBUG("\n"); | ||
615 | pp = I915_READ(PCH_PP_CONTROL); | ||
616 | pp |= EDP_BLC_ENABLE; | ||
617 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
618 | } | ||
619 | |||
620 | static void igdng_edp_backlight_off (struct drm_device *dev) | ||
621 | { | ||
622 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
623 | u32 pp; | ||
624 | |||
625 | DRM_DEBUG("\n"); | ||
626 | pp = I915_READ(PCH_PP_CONTROL); | ||
627 | pp &= ~EDP_BLC_ENABLE; | ||
628 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
629 | } | ||
584 | 630 | ||
585 | static void | 631 | static void |
586 | intel_dp_dpms(struct drm_encoder *encoder, int mode) | 632 | intel_dp_dpms(struct drm_encoder *encoder, int mode) |
@@ -592,11 +638,17 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
592 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); | 638 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); |
593 | 639 | ||
594 | if (mode != DRM_MODE_DPMS_ON) { | 640 | if (mode != DRM_MODE_DPMS_ON) { |
595 | if (dp_reg & DP_PORT_EN) | 641 | if (dp_reg & DP_PORT_EN) { |
596 | intel_dp_link_down(intel_output, dp_priv->DP); | 642 | intel_dp_link_down(intel_output, dp_priv->DP); |
643 | if (IS_eDP(intel_output)) | ||
644 | igdng_edp_backlight_off(dev); | ||
645 | } | ||
597 | } else { | 646 | } else { |
598 | if (!(dp_reg & DP_PORT_EN)) | 647 | if (!(dp_reg & DP_PORT_EN)) { |
599 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); | 648 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); |
649 | if (IS_eDP(intel_output)) | ||
650 | igdng_edp_backlight_on(dev); | ||
651 | } | ||
600 | } | 652 | } |
601 | dp_priv->dpms_mode = mode; | 653 | dp_priv->dpms_mode = mode; |
602 | } | 654 | } |
@@ -958,12 +1010,23 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) | |||
958 | struct drm_i915_private *dev_priv = dev->dev_private; | 1010 | struct drm_i915_private *dev_priv = dev->dev_private; |
959 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 1011 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; |
960 | 1012 | ||
1013 | DRM_DEBUG("\n"); | ||
1014 | |||
1015 | if (IS_eDP(intel_output)) { | ||
1016 | DP &= ~DP_PLL_ENABLE; | ||
1017 | I915_WRITE(dp_priv->output_reg, DP); | ||
1018 | POSTING_READ(dp_priv->output_reg); | ||
1019 | udelay(100); | ||
1020 | } | ||
1021 | |||
961 | DP &= ~DP_LINK_TRAIN_MASK; | 1022 | DP &= ~DP_LINK_TRAIN_MASK; |
962 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); | 1023 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); |
963 | POSTING_READ(dp_priv->output_reg); | 1024 | POSTING_READ(dp_priv->output_reg); |
964 | 1025 | ||
965 | udelay(17000); | 1026 | udelay(17000); |
966 | 1027 | ||
1028 | if (IS_eDP(intel_output)) | ||
1029 | DP |= DP_LINK_TRAIN_OFF; | ||
967 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); | 1030 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); |
968 | POSTING_READ(dp_priv->output_reg); | 1031 | POSTING_READ(dp_priv->output_reg); |
969 | } | 1032 | } |
@@ -1089,11 +1152,27 @@ intel_dp_detect(struct drm_connector *connector) | |||
1089 | static int intel_dp_get_modes(struct drm_connector *connector) | 1152 | static int intel_dp_get_modes(struct drm_connector *connector) |
1090 | { | 1153 | { |
1091 | struct intel_output *intel_output = to_intel_output(connector); | 1154 | struct intel_output *intel_output = to_intel_output(connector); |
1155 | struct drm_device *dev = intel_output->base.dev; | ||
1156 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1157 | int ret; | ||
1092 | 1158 | ||
1093 | /* We should parse the EDID data and find out if it has an audio sink | 1159 | /* We should parse the EDID data and find out if it has an audio sink |
1094 | */ | 1160 | */ |
1095 | 1161 | ||
1096 | return intel_ddc_get_modes(intel_output); | 1162 | ret = intel_ddc_get_modes(intel_output); |
1163 | if (ret) | ||
1164 | return ret; | ||
1165 | |||
1166 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ | ||
1167 | if (IS_eDP(intel_output)) { | ||
1168 | if (dev_priv->panel_fixed_mode != NULL) { | ||
1169 | struct drm_display_mode *mode; | ||
1170 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); | ||
1171 | drm_mode_probed_add(connector, mode); | ||
1172 | return 1; | ||
1173 | } | ||
1174 | } | ||
1175 | return 0; | ||
1097 | } | 1176 | } |
1098 | 1177 | ||
1099 | static void | 1178 | static void |
@@ -1170,7 +1249,10 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1170 | DRM_MODE_CONNECTOR_DisplayPort); | 1249 | DRM_MODE_CONNECTOR_DisplayPort); |
1171 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); | 1250 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); |
1172 | 1251 | ||
1173 | intel_output->type = INTEL_OUTPUT_DISPLAYPORT; | 1252 | if (output_reg == DP_A) |
1253 | intel_output->type = INTEL_OUTPUT_EDP; | ||
1254 | else | ||
1255 | intel_output->type = INTEL_OUTPUT_DISPLAYPORT; | ||
1174 | 1256 | ||
1175 | connector->interlace_allowed = true; | 1257 | connector->interlace_allowed = true; |
1176 | connector->doublescan_allowed = 0; | 1258 | connector->doublescan_allowed = 0; |
@@ -1191,6 +1273,9 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1191 | 1273 | ||
1192 | /* Set up the DDC bus. */ | 1274 | /* Set up the DDC bus. */ |
1193 | switch (output_reg) { | 1275 | switch (output_reg) { |
1276 | case DP_A: | ||
1277 | name = "DPDDC-A"; | ||
1278 | break; | ||
1194 | case DP_B: | 1279 | case DP_B: |
1195 | case PCH_DP_B: | 1280 | case PCH_DP_B: |
1196 | name = "DPDDC-B"; | 1281 | name = "DPDDC-B"; |
@@ -1206,9 +1291,22 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1206 | } | 1291 | } |
1207 | 1292 | ||
1208 | intel_dp_i2c_init(intel_output, name); | 1293 | intel_dp_i2c_init(intel_output, name); |
1294 | |||
1209 | intel_output->ddc_bus = &dp_priv->adapter; | 1295 | intel_output->ddc_bus = &dp_priv->adapter; |
1210 | intel_output->hot_plug = intel_dp_hot_plug; | 1296 | intel_output->hot_plug = intel_dp_hot_plug; |
1211 | 1297 | ||
1298 | if (output_reg == DP_A) { | ||
1299 | /* initialize panel mode from VBT if available for eDP */ | ||
1300 | if (dev_priv->lfp_lvds_vbt_mode) { | ||
1301 | dev_priv->panel_fixed_mode = | ||
1302 | drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); | ||
1303 | if (dev_priv->panel_fixed_mode) { | ||
1304 | dev_priv->panel_fixed_mode->type |= | ||
1305 | DRM_MODE_TYPE_PREFERRED; | ||
1306 | } | ||
1307 | } | ||
1308 | } | ||
1309 | |||
1212 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written | 1310 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written |
1213 | * 0xd. Failure to do so will result in spurious interrupts being | 1311 | * 0xd. Failure to do so will result in spurious interrupts being |
1214 | * generated on the port when a cable is not attached. | 1312 | * generated on the port when a cable is not attached. |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 004541c935a8..d6f92ea1b553 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -55,6 +55,7 @@ | |||
55 | #define INTEL_OUTPUT_TVOUT 5 | 55 | #define INTEL_OUTPUT_TVOUT 5 |
56 | #define INTEL_OUTPUT_HDMI 6 | 56 | #define INTEL_OUTPUT_HDMI 6 |
57 | #define INTEL_OUTPUT_DISPLAYPORT 7 | 57 | #define INTEL_OUTPUT_DISPLAYPORT 7 |
58 | #define INTEL_OUTPUT_EDP 8 | ||
58 | 59 | ||
59 | #define INTEL_DVO_CHIP_NONE 0 | 60 | #define INTEL_DVO_CHIP_NONE 0 |
60 | #define INTEL_DVO_CHIP_LVDS 1 | 61 | #define INTEL_DVO_CHIP_LVDS 1 |
@@ -121,6 +122,8 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg); | |||
121 | void | 122 | void |
122 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | 123 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, |
123 | struct drm_display_mode *adjusted_mode); | 124 | struct drm_display_mode *adjusted_mode); |
125 | extern void intel_edp_link_config (struct intel_output *, int *, int *); | ||
126 | |||
124 | 127 | ||
125 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); | 128 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
126 | extern void intel_encoder_prepare (struct drm_encoder *encoder); | 129 | extern void intel_encoder_prepare (struct drm_encoder *encoder); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 43c7d9aa59ce..3f445a80c552 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -892,6 +892,10 @@ void intel_lvds_init(struct drm_device *dev) | |||
892 | if (IS_IGDNG(dev)) { | 892 | if (IS_IGDNG(dev)) { |
893 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) | 893 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) |
894 | return; | 894 | return; |
895 | if (dev_priv->edp_support) { | ||
896 | DRM_DEBUG("disable LVDS for eDP support\n"); | ||
897 | return; | ||
898 | } | ||
895 | gpio = PCH_GPIOC; | 899 | gpio = PCH_GPIOC; |
896 | } | 900 | } |
897 | 901 | ||