Rev 4280 | Rev 5060 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4280 | Rev 4560 | ||
---|---|---|---|
Line 90... | Line 90... | ||
90 | struct intel_crtc_config *pipe_config) |
90 | struct intel_crtc_config *pipe_config) |
91 | { |
91 | { |
92 | struct drm_device *dev = encoder->base.dev; |
92 | struct drm_device *dev = encoder->base.dev; |
93 | struct drm_i915_private *dev_priv = dev->dev_private; |
93 | struct drm_i915_private *dev_priv = dev->dev_private; |
94 | u32 lvds_reg, tmp, flags = 0; |
94 | u32 lvds_reg, tmp, flags = 0; |
- | 95 | int dotclock; |
|
Line 95... | Line 96... | ||
95 | 96 | ||
96 | if (HAS_PCH_SPLIT(dev)) |
97 | if (HAS_PCH_SPLIT(dev)) |
97 | lvds_reg = PCH_LVDS; |
98 | lvds_reg = PCH_LVDS; |
98 | else |
99 | else |
Line 114... | Line 115... | ||
114 | if (INTEL_INFO(dev)->gen < 4) { |
115 | if (INTEL_INFO(dev)->gen < 4) { |
115 | tmp = I915_READ(PFIT_CONTROL); |
116 | tmp = I915_READ(PFIT_CONTROL); |
Line 116... | Line 117... | ||
116 | 117 | ||
117 | pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE; |
118 | pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE; |
- | 119 | } |
|
- | 120 | ||
- | 121 | dotclock = pipe_config->port_clock; |
|
- | 122 | ||
- | 123 | if (HAS_PCH_SPLIT(dev_priv->dev)) |
|
- | 124 | ironlake_check_encoder_dotclock(pipe_config, dotclock); |
|
- | 125 | ||
118 | } |
126 | pipe_config->adjusted_mode.crtc_clock = dotclock; |
Line 119... | Line 127... | ||
119 | } |
127 | } |
120 | 128 | ||
121 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
129 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
Line 196... | Line 204... | ||
196 | */ |
204 | */ |
197 | static void intel_enable_lvds(struct intel_encoder *encoder) |
205 | static void intel_enable_lvds(struct intel_encoder *encoder) |
198 | { |
206 | { |
199 | struct drm_device *dev = encoder->base.dev; |
207 | struct drm_device *dev = encoder->base.dev; |
200 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); |
208 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); |
201 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
209 | struct intel_connector *intel_connector = |
- | 210 | &lvds_encoder->attached_connector->base; |
|
202 | struct drm_i915_private *dev_priv = dev->dev_private; |
211 | struct drm_i915_private *dev_priv = dev->dev_private; |
203 | u32 ctl_reg, stat_reg; |
212 | u32 ctl_reg, stat_reg; |
Line 204... | Line 213... | ||
204 | 213 | ||
205 | if (HAS_PCH_SPLIT(dev)) { |
214 | if (HAS_PCH_SPLIT(dev)) { |
Line 215... | Line 224... | ||
215 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); |
224 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); |
216 | POSTING_READ(lvds_encoder->reg); |
225 | POSTING_READ(lvds_encoder->reg); |
217 | if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) |
226 | if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) |
218 | DRM_ERROR("timed out waiting for panel to power on\n"); |
227 | DRM_ERROR("timed out waiting for panel to power on\n"); |
Line 219... | Line 228... | ||
219 | 228 | ||
220 | intel_panel_enable_backlight(dev, intel_crtc->pipe); |
229 | intel_panel_enable_backlight(intel_connector); |
Line 221... | Line 230... | ||
221 | } |
230 | } |
222 | 231 | ||
223 | static void intel_disable_lvds(struct intel_encoder *encoder) |
232 | static void intel_disable_lvds(struct intel_encoder *encoder) |
224 | { |
233 | { |
- | 234 | struct drm_device *dev = encoder->base.dev; |
|
- | 235 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); |
|
225 | struct drm_device *dev = encoder->base.dev; |
236 | struct intel_connector *intel_connector = |
226 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); |
237 | &lvds_encoder->attached_connector->base; |
Line 227... | Line 238... | ||
227 | struct drm_i915_private *dev_priv = dev->dev_private; |
238 | struct drm_i915_private *dev_priv = dev->dev_private; |
228 | u32 ctl_reg, stat_reg; |
239 | u32 ctl_reg, stat_reg; |
Line 233... | Line 244... | ||
233 | } else { |
244 | } else { |
234 | ctl_reg = PP_CONTROL; |
245 | ctl_reg = PP_CONTROL; |
235 | stat_reg = PP_STATUS; |
246 | stat_reg = PP_STATUS; |
236 | } |
247 | } |
Line 237... | Line 248... | ||
237 | 248 | ||
Line 238... | Line 249... | ||
238 | intel_panel_disable_backlight(dev); |
249 | intel_panel_disable_backlight(intel_connector); |
239 | 250 | ||
240 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); |
251 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); |
Line 241... | Line 252... | ||
241 | if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000)) |
252 | if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000)) |
242 | DRM_ERROR("timed out waiting for panel to power off\n"); |
253 | DRM_ERROR("timed out waiting for panel to power off\n"); |
243 | 254 | ||
Line -... | Line 255... | ||
- | 255 | I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) & ~LVDS_PORT_EN); |
|
244 | I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) & ~LVDS_PORT_EN); |
256 | POSTING_READ(lvds_encoder->reg); |
245 | POSTING_READ(lvds_encoder->reg); |
257 | } |
246 | } |
258 | |
247 | 259 | static enum drm_mode_status |
|
248 | static int intel_lvds_mode_valid(struct drm_connector *connector, |
260 | intel_lvds_mode_valid(struct drm_connector *connector, |
Line 434... | Line 446... | ||
434 | } |
446 | } |
Line 435... | Line 447... | ||
435 | 447 | ||
436 | if (dev_priv->modeset_restore == MODESET_DONE) |
448 | if (dev_priv->modeset_restore == MODESET_DONE) |
Line -... | Line 449... | ||
- | 449 | goto exit; |
|
- | 450 | ||
- | 451 | /* |
|
- | 452 | * Some old platform's BIOS love to wreak havoc while the lid is closed. |
|
- | 453 | * We try to detect this here and undo any damage. The split for PCH |
|
- | 454 | * platforms is rather conservative and a bit arbitrary expect that on |
|
- | 455 | * those platforms VGA disabling requires actual legacy VGA I/O access, |
|
- | 456 | * and as part of the cleanup in the hw state restore we also redisable |
|
- | 457 | * the vga plane. |
|
437 | goto exit; |
458 | */ |
438 | 459 | if (!HAS_PCH_SPLIT(dev)) { |
|
439 | drm_modeset_lock_all(dev); |
460 | drm_modeset_lock_all(dev); |
- | 461 | intel_modeset_setup_hw_state(dev, true); |
|
Line 440... | Line 462... | ||
440 | intel_modeset_setup_hw_state(dev, true); |
462 | drm_modeset_unlock_all(dev); |
Line 441... | Line 463... | ||
441 | drm_modeset_unlock_all(dev); |
463 | } |
442 | 464 | ||
Line 464... | Line 486... | ||
464 | if (!IS_ERR_OR_NULL(lvds_connector->base.edid)) |
486 | if (!IS_ERR_OR_NULL(lvds_connector->base.edid)) |
465 | kfree(lvds_connector->base.edid); |
487 | kfree(lvds_connector->base.edid); |
Line 466... | Line 488... | ||
466 | 488 | ||
Line 467... | Line -... | ||
467 | intel_panel_fini(&lvds_connector->base.panel); |
- | |
468 | 489 | intel_panel_fini(&lvds_connector->base.panel); |
|
469 | drm_sysfs_connector_remove(connector); |
490 | |
470 | drm_connector_cleanup(connector); |
491 | drm_connector_cleanup(connector); |
Line 471... | Line 492... | ||
471 | kfree(connector); |
492 | kfree(connector); |
Line 732... | Line 753... | ||
732 | }, |
753 | }, |
Line 733... | Line 754... | ||
733 | 754 | ||
734 | { } /* terminating entry */ |
755 | { } /* terminating entry */ |
Line 735... | Line -... | ||
735 | }; |
- | |
736 | - | ||
737 | /** |
- | |
738 | * intel_find_lvds_downclock - find the reduced downclock for LVDS in EDID |
- | |
739 | * @dev: drm device |
- | |
740 | * @connector: LVDS connector |
- | |
741 | * |
- | |
742 | * Find the reduced downclock for LVDS in EDID. |
- | |
743 | */ |
- | |
744 | static void intel_find_lvds_downclock(struct drm_device *dev, |
- | |
745 | struct drm_display_mode *fixed_mode, |
- | |
746 | struct drm_connector *connector) |
- | |
747 | { |
- | |
748 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
749 | struct drm_display_mode *scan; |
- | |
750 | int temp_downclock; |
- | |
751 | - | ||
752 | temp_downclock = fixed_mode->clock; |
- | |
753 | list_for_each_entry(scan, &connector->probed_modes, head) { |
- | |
754 | /* |
- | |
755 | * If one mode has the same resolution with the fixed_panel |
- | |
756 | * mode while they have the different refresh rate, it means |
- | |
757 | * that the reduced downclock is found for the LVDS. In such |
- | |
758 | * case we can set the different FPx0/1 to dynamically select |
- | |
759 | * between low and high frequency. |
- | |
760 | */ |
- | |
761 | if (scan->hdisplay == fixed_mode->hdisplay && |
- | |
762 | scan->hsync_start == fixed_mode->hsync_start && |
- | |
763 | scan->hsync_end == fixed_mode->hsync_end && |
- | |
764 | scan->htotal == fixed_mode->htotal && |
- | |
765 | scan->vdisplay == fixed_mode->vdisplay && |
- | |
766 | scan->vsync_start == fixed_mode->vsync_start && |
- | |
767 | scan->vsync_end == fixed_mode->vsync_end && |
- | |
768 | scan->vtotal == fixed_mode->vtotal) { |
- | |
769 | if (scan->clock < temp_downclock) { |
- | |
770 | /* |
- | |
771 | * The downclock is already found. But we |
- | |
772 | * expect to find the lower downclock. |
- | |
773 | */ |
- | |
774 | temp_downclock = scan->clock; |
- | |
775 | } |
- | |
776 | } |
- | |
777 | } |
- | |
778 | if (temp_downclock < fixed_mode->clock && i915_lvds_downclock) { |
- | |
779 | /* We found the downclock for LVDS. */ |
- | |
780 | dev_priv->lvds_downclock_avail = 1; |
- | |
781 | dev_priv->lvds_downclock = temp_downclock; |
- | |
782 | DRM_DEBUG_KMS("LVDS downclock is found in EDID. " |
- | |
783 | "Normal clock %dKhz, downclock %dKhz\n", |
- | |
784 | fixed_mode->clock, temp_downclock); |
- | |
785 | } |
- | |
786 | } |
756 | }; |
787 | 757 | ||
788 | /* |
758 | /* |
789 | * Enumerate the child dev array parsed from VBT to check whether |
759 | * Enumerate the child dev array parsed from VBT to check whether |
790 | * the LVDS is present. |
760 | * the LVDS is present. |
Line 800... | Line 770... | ||
800 | 770 | ||
801 | if (!dev_priv->vbt.child_dev_num) |
771 | if (!dev_priv->vbt.child_dev_num) |
Line 802... | Line 772... | ||
802 | return true; |
772 | return true; |
803 | 773 | ||
- | 774 | for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { |
|
Line 804... | Line 775... | ||
804 | for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { |
775 | union child_device_config *uchild = dev_priv->vbt.child_dev + i; |
805 | struct child_device_config *child = dev_priv->vbt.child_dev + i; |
776 | struct old_child_dev_config *child = &uchild->old; |
806 | 777 | ||
807 | /* If the device type is not LFP, continue. |
778 | /* If the device type is not LFP, continue. |
Line 954... | Line 925... | ||
954 | DRM_DEBUG_KMS("disable LVDS for eDP support\n"); |
925 | DRM_DEBUG_KMS("disable LVDS for eDP support\n"); |
955 | return; |
926 | return; |
956 | } |
927 | } |
957 | } |
928 | } |
Line 958... | Line 929... | ||
958 | 929 | ||
959 | lvds_encoder = kzalloc(sizeof(struct intel_lvds_encoder), GFP_KERNEL); |
930 | lvds_encoder = kzalloc(sizeof(*lvds_encoder), GFP_KERNEL); |
960 | if (!lvds_encoder) |
931 | if (!lvds_encoder) |
Line 961... | Line 932... | ||
961 | return; |
932 | return; |
962 | 933 | ||
963 | lvds_connector = kzalloc(sizeof(struct intel_lvds_connector), GFP_KERNEL); |
934 | lvds_connector = kzalloc(sizeof(*lvds_connector), GFP_KERNEL); |
964 | if (!lvds_connector) { |
935 | if (!lvds_connector) { |
965 | kfree(lvds_encoder); |
936 | kfree(lvds_encoder); |
Line 1059... | Line 1030... | ||
1059 | DRM_DEBUG_KMS("using preferred mode from EDID: "); |
1030 | DRM_DEBUG_KMS("using preferred mode from EDID: "); |
1060 | drm_mode_debug_printmodeline(scan); |
1031 | drm_mode_debug_printmodeline(scan); |
Line 1061... | Line 1032... | ||
1061 | 1032 | ||
1062 | fixed_mode = drm_mode_duplicate(dev, scan); |
1033 | fixed_mode = drm_mode_duplicate(dev, scan); |
- | 1034 | if (fixed_mode) { |
|
1063 | if (fixed_mode) { |
1035 | intel_connector->panel.downclock_mode = |
1064 | intel_find_lvds_downclock(dev, fixed_mode, |
1036 | intel_find_panel_downclock(dev, |
- | 1037 | fixed_mode, connector); |
|
- | 1038 | if (intel_connector->panel.downclock_mode != |
|
- | 1039 | NULL && i915_lvds_downclock) { |
|
- | 1040 | /* We found the downclock for LVDS. */ |
|
- | 1041 | dev_priv->lvds_downclock_avail = true; |
|
- | 1042 | dev_priv->lvds_downclock = |
|
- | 1043 | intel_connector->panel. |
|
- | 1044 | downclock_mode->clock; |
|
- | 1045 | DRM_DEBUG_KMS("LVDS downclock is found" |
|
- | 1046 | " in EDID. Normal clock %dKhz, " |
|
- | 1047 | "downclock %dKhz\n", |
|
- | 1048 | fixed_mode->clock, |
|
- | 1049 | dev_priv->lvds_downclock); |
|
1065 | connector); |
1050 | } |
1066 | goto out; |
1051 | goto out; |
1067 | } |
1052 | } |
1068 | } |
1053 | } |