Rev 2351 | Rev 3243 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2351 | Rev 3031 | ||
---|---|---|---|
Line 29... | Line 29... | ||
29 | 29 | ||
30 | //#include |
30 | //#include |
31 | //#include |
31 | //#include |
32 | #include |
32 | #include |
33 | #include |
33 | #include |
34 | #include "drmP.h" |
- | |
35 | #include "drm.h" |
34 | #include |
36 | #include "drm_crtc.h" |
35 | #include |
37 | #include "drm_edid.h" |
36 | #include |
38 | #include "intel_drv.h" |
37 | #include "intel_drv.h" |
39 | #include "i915_drm.h" |
38 | #include |
40 | #include "i915_drv.h" |
39 | #include "i915_drv.h" |
Line 41... | Line 40... | ||
41 | //#include |
40 | //#include |
42 | 41 | ||
Line 63... | Line 62... | ||
63 | { |
62 | { |
64 | return container_of(intel_attached_encoder(connector), |
63 | return container_of(intel_attached_encoder(connector), |
65 | struct intel_lvds, base); |
64 | struct intel_lvds, base); |
66 | } |
65 | } |
Line -... | Line 66... | ||
- | 66 | ||
- | 67 | static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, |
|
- | 68 | enum pipe *pipe) |
|
- | 69 | { |
|
- | 70 | struct drm_device *dev = encoder->base.dev; |
|
- | 71 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 72 | u32 lvds_reg, tmp; |
|
- | 73 | ||
- | 74 | if (HAS_PCH_SPLIT(dev)) { |
|
- | 75 | lvds_reg = PCH_LVDS; |
|
- | 76 | } else { |
|
- | 77 | lvds_reg = LVDS; |
|
- | 78 | } |
|
- | 79 | ||
- | 80 | tmp = I915_READ(lvds_reg); |
|
- | 81 | ||
- | 82 | if (!(tmp & LVDS_PORT_EN)) |
|
- | 83 | return false; |
|
- | 84 | ||
- | 85 | if (HAS_PCH_CPT(dev)) |
|
- | 86 | *pipe = PORT_TO_PIPE_CPT(tmp); |
|
- | 87 | else |
|
- | 88 | *pipe = PORT_TO_PIPE(tmp); |
|
- | 89 | ||
- | 90 | return true; |
|
- | 91 | } |
|
67 | 92 | ||
68 | /** |
93 | /** |
69 | * Sets the power state for the panel. |
94 | * Sets the power state for the panel. |
70 | */ |
95 | */ |
71 | static void intel_lvds_enable(struct intel_lvds *intel_lvds) |
96 | static void intel_enable_lvds(struct intel_encoder *encoder) |
72 | { |
97 | { |
- | 98 | struct drm_device *dev = encoder->base.dev; |
|
- | 99 | struct intel_lvds *intel_lvds = to_intel_lvds(&encoder->base); |
|
73 | struct drm_device *dev = intel_lvds->base.base.dev; |
100 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
74 | struct drm_i915_private *dev_priv = dev->dev_private; |
101 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 75... | Line 102... | ||
75 | u32 ctl_reg, lvds_reg, stat_reg; |
102 | u32 ctl_reg, lvds_reg, stat_reg; |
76 | 103 | ||
Line 105... | Line 132... | ||
105 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); |
132 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); |
106 | POSTING_READ(lvds_reg); |
133 | POSTING_READ(lvds_reg); |
107 | if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) |
134 | if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) |
108 | DRM_ERROR("timed out waiting for panel to power on\n"); |
135 | DRM_ERROR("timed out waiting for panel to power on\n"); |
Line 109... | Line 136... | ||
109 | 136 | ||
110 | intel_panel_enable_backlight(dev); |
137 | intel_panel_enable_backlight(dev, intel_crtc->pipe); |
Line 111... | Line 138... | ||
111 | } |
138 | } |
112 | 139 | ||
113 | static void intel_lvds_disable(struct intel_lvds *intel_lvds) |
140 | static void intel_disable_lvds(struct intel_encoder *encoder) |
- | 141 | { |
|
114 | { |
142 | struct drm_device *dev = encoder->base.dev; |
115 | struct drm_device *dev = intel_lvds->base.base.dev; |
143 | struct intel_lvds *intel_lvds = to_intel_lvds(&encoder->base); |
Line 116... | Line 144... | ||
116 | struct drm_i915_private *dev_priv = dev->dev_private; |
144 | struct drm_i915_private *dev_priv = dev->dev_private; |
117 | u32 ctl_reg, lvds_reg, stat_reg; |
145 | u32 ctl_reg, lvds_reg, stat_reg; |
Line 139... | Line 167... | ||
139 | 167 | ||
140 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); |
168 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); |
141 | POSTING_READ(lvds_reg); |
169 | POSTING_READ(lvds_reg); |
Line 142... | Line -... | ||
142 | } |
- | |
143 | - | ||
144 | static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) |
- | |
145 | { |
- | |
146 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
- | |
147 | - | ||
148 | if (mode == DRM_MODE_DPMS_ON) |
- | |
149 | intel_lvds_enable(intel_lvds); |
- | |
150 | else |
- | |
151 | intel_lvds_disable(intel_lvds); |
- | |
152 | - | ||
153 | /* XXX: We never power down the LVDS pairs. */ |
- | |
154 | } |
170 | } |
155 | 171 | ||
156 | static int intel_lvds_mode_valid(struct drm_connector *connector, |
172 | static int intel_lvds_mode_valid(struct drm_connector *connector, |
157 | struct drm_display_mode *mode) |
173 | struct drm_display_mode *mode) |
158 | { |
174 | { |
Line 185... | Line 201... | ||
185 | mode->crtc_hblank_start = width + border; |
201 | mode->crtc_hblank_start = width + border; |
186 | mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width; |
202 | mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width; |
Line 187... | Line 203... | ||
187 | 203 | ||
188 | mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; |
204 | mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; |
- | 205 | mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; |
|
- | 206 | ||
189 | mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; |
207 | mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; |
Line 190... | Line 208... | ||
190 | } |
208 | } |
191 | 209 | ||
192 | static void |
210 | static void |
Line 206... | Line 224... | ||
206 | mode->crtc_vblank_start = height + border; |
224 | mode->crtc_vblank_start = height + border; |
207 | mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width; |
225 | mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width; |
Line 208... | Line 226... | ||
208 | 226 | ||
209 | mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; |
227 | mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; |
- | 228 | mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; |
|
- | 229 | ||
210 | mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; |
230 | mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; |
Line 211... | Line 231... | ||
211 | } |
231 | } |
212 | 232 | ||
213 | static inline u32 panel_fitter_scaling(u32 source, u32 target) |
233 | static inline u32 panel_fitter_scaling(u32 source, u32 target) |
Line 222... | Line 242... | ||
222 | u32 ratio = source * FACTOR / target; |
242 | u32 ratio = source * FACTOR / target; |
223 | return (FACTOR * ratio + FACTOR/2) / FACTOR; |
243 | return (FACTOR * ratio + FACTOR/2) / FACTOR; |
224 | } |
244 | } |
Line 225... | Line 245... | ||
225 | 245 | ||
226 | static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, |
246 | static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, |
227 | struct drm_display_mode *mode, |
247 | const struct drm_display_mode *mode, |
228 | struct drm_display_mode *adjusted_mode) |
248 | struct drm_display_mode *adjusted_mode) |
229 | { |
249 | { |
230 | struct drm_device *dev = encoder->dev; |
250 | struct drm_device *dev = encoder->dev; |
231 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
232 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
251 | struct drm_i915_private *dev_priv = dev->dev_private; |
233 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
252 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
234 | struct drm_encoder *tmp_encoder; |
253 | struct intel_crtc *intel_crtc = intel_lvds->base.new_crtc; |
235 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
254 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
Line 236... | Line 255... | ||
236 | int pipe; |
255 | int pipe; |
237 | 256 | ||
238 | /* Should never happen!! */ |
257 | /* Should never happen!! */ |
239 | if (INTEL_INFO(dev)->gen < 4 && intel_crtc->pipe == 0) { |
258 | if (INTEL_INFO(dev)->gen < 4 && intel_crtc->pipe == 0) { |
240 | DRM_ERROR("Can't support LVDS on pipe A\n"); |
259 | DRM_ERROR("Can't support LVDS on pipe A\n"); |
Line 241... | Line -... | ||
241 | return false; |
- | |
242 | } |
- | |
243 | 260 | return false; |
|
244 | /* Should never happen!! */ |
- | |
245 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { |
- | |
246 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { |
261 | } |
247 | DRM_ERROR("Can't enable LVDS and another " |
- | |
248 | "encoder on the same pipe\n"); |
- | |
Line 249... | Line 262... | ||
249 | return false; |
262 | |
250 | } |
263 | if (intel_encoder_check_is_cloned(&intel_lvds->base)) |
251 | } |
264 | return false; |
252 | 265 | ||
Line 281... | Line 294... | ||
281 | * Change the value here to see the borders for debugging |
294 | * Change the value here to see the borders for debugging |
282 | */ |
295 | */ |
283 | for_each_pipe(pipe) |
296 | for_each_pipe(pipe) |
284 | I915_WRITE(BCLRPAT(pipe), 0); |
297 | I915_WRITE(BCLRPAT(pipe), 0); |
Line -... | Line 298... | ||
- | 298 | ||
- | 299 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
|
285 | 300 | ||
286 | switch (intel_lvds->fitting_mode) { |
301 | switch (intel_lvds->fitting_mode) { |
287 | case DRM_MODE_SCALE_CENTER: |
302 | case DRM_MODE_SCALE_CENTER: |
288 | /* |
303 | /* |
289 | * For centered modes, we have to calculate border widths & |
304 | * For centered modes, we have to calculate border widths & |
Line 396... | Line 411... | ||
396 | */ |
411 | */ |
Line 397... | Line 412... | ||
397 | 412 | ||
398 | return true; |
413 | return true; |
Line 399... | Line -... | ||
399 | } |
- | |
400 | - | ||
401 | static void intel_lvds_prepare(struct drm_encoder *encoder) |
- | |
402 | { |
- | |
403 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
- | |
404 | - | ||
405 | /* |
- | |
406 | * Prior to Ironlake, we must disable the pipe if we want to adjust |
- | |
407 | * the panel fitter. However at all other times we can just reset |
- | |
408 | * the registers regardless. |
- | |
409 | */ |
- | |
410 | if (!HAS_PCH_SPLIT(encoder->dev) && intel_lvds->pfit_dirty) |
- | |
411 | intel_lvds_disable(intel_lvds); |
- | |
412 | } |
- | |
413 | - | ||
414 | static void intel_lvds_commit(struct drm_encoder *encoder) |
- | |
415 | { |
- | |
416 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
- | |
417 | - | ||
418 | /* Always do a full power on as we do not know what state |
- | |
419 | * we were left in. |
- | |
420 | */ |
- | |
421 | intel_lvds_enable(intel_lvds); |
- | |
422 | } |
414 | } |
423 | 415 | ||
424 | static void intel_lvds_mode_set(struct drm_encoder *encoder, |
416 | static void intel_lvds_mode_set(struct drm_encoder *encoder, |
425 | struct drm_display_mode *mode, |
417 | struct drm_display_mode *mode, |
426 | struct drm_display_mode *adjusted_mode) |
418 | struct drm_display_mode *adjusted_mode) |
Line 472... | Line 464... | ||
472 | return 1; |
464 | return 1; |
473 | } |
465 | } |
Line 474... | Line 466... | ||
474 | 466 | ||
475 | static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id) |
467 | static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id) |
476 | { |
468 | { |
477 | DRM_DEBUG_KMS("Skipping forced modeset for %s\n", id->ident); |
469 | DRM_INFO("Skipping forced modeset for %s\n", id->ident); |
478 | return 1; |
470 | return 1; |
Line 479... | Line 471... | ||
479 | } |
471 | } |
480 | 472 | ||
Line 533... | Line 525... | ||
533 | return NOTIFY_OK; |
525 | return NOTIFY_OK; |
Line 534... | Line 526... | ||
534 | 526 | ||
Line 535... | Line 527... | ||
535 | dev_priv->modeset_on_lid = 0; |
527 | dev_priv->modeset_on_lid = 0; |
536 | 528 | ||
537 | mutex_lock(&dev->mode_config.mutex); |
529 | mutex_lock(&dev->mode_config.mutex); |
Line 538... | Line 530... | ||
538 | drm_helper_resume_force_mode(dev); |
530 | intel_modeset_check_state(dev); |
539 | mutex_unlock(&dev->mode_config.mutex); |
531 | mutex_unlock(&dev->mode_config.mutex); |
540 | 532 | ||
Line 586... | Line 578... | ||
586 | if (crtc && crtc->enabled) { |
578 | if (crtc && crtc->enabled) { |
587 | /* |
579 | /* |
588 | * If the CRTC is enabled, the display will be changed |
580 | * If the CRTC is enabled, the display will be changed |
589 | * according to the new panel fitting mode. |
581 | * according to the new panel fitting mode. |
590 | */ |
582 | */ |
591 | drm_crtc_helper_set_mode(crtc, &crtc->mode, |
583 | intel_set_mode(crtc, &crtc->mode, |
592 | crtc->x, crtc->y, crtc->fb); |
584 | crtc->x, crtc->y, crtc->fb); |
593 | } |
585 | } |
594 | } |
586 | } |
Line 595... | Line 587... | ||
595 | 587 | ||
596 | return 0; |
588 | return 0; |
Line 597... | Line 589... | ||
597 | } |
589 | } |
598 | - | ||
599 | static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { |
590 | |
600 | .dpms = intel_lvds_dpms, |
- | |
601 | .mode_fixup = intel_lvds_mode_fixup, |
591 | static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { |
602 | .prepare = intel_lvds_prepare, |
592 | .mode_fixup = intel_lvds_mode_fixup, |
603 | .mode_set = intel_lvds_mode_set, |
593 | .mode_set = intel_lvds_mode_set, |
Line 604... | Line 594... | ||
604 | .commit = intel_lvds_commit, |
594 | .disable = intel_encoder_noop, |
605 | }; |
595 | }; |
606 | 596 | ||
607 | static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { |
597 | static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { |
608 | .get_modes = intel_lvds_get_modes, |
598 | .get_modes = intel_lvds_get_modes, |
Line 609... | Line 599... | ||
609 | .mode_valid = intel_lvds_mode_valid, |
599 | .mode_valid = intel_lvds_mode_valid, |
610 | .best_encoder = intel_best_encoder, |
600 | .best_encoder = intel_best_encoder, |
611 | }; |
601 | }; |
612 | 602 | ||
613 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { |
603 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { |
614 | .dpms = drm_helper_connector_dpms, |
604 | .dpms = intel_connector_dpms, |
615 | .detect = intel_lvds_detect, |
605 | .detect = intel_lvds_detect, |
Line 622... | Line 612... | ||
622 | .destroy = intel_encoder_destroy, |
612 | .destroy = intel_encoder_destroy, |
623 | }; |
613 | }; |
Line 624... | Line 614... | ||
624 | 614 | ||
625 | static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) |
615 | static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) |
626 | { |
616 | { |
627 | DRM_DEBUG_KMS("Skipping LVDS initialization for %s\n", id->ident); |
617 | DRM_INFO("Skipping LVDS initialization for %s\n", id->ident); |
628 | return 1; |
618 | return 1; |
Line 629... | Line 619... | ||
629 | } |
619 | } |
630 | 620 | ||
Line 739... | Line 729... | ||
739 | .matches = { |
729 | .matches = { |
740 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), |
730 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), |
741 | DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"), |
731 | DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"), |
742 | }, |
732 | }, |
743 | }, |
733 | }, |
- | 734 | { |
|
- | 735 | .callback = intel_no_lvds_dmi_callback, |
|
- | 736 | .ident = "Hewlett-Packard HP t5740e Thin Client", |
|
- | 737 | .matches = { |
|
- | 738 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), |
|
- | 739 | DMI_MATCH(DMI_PRODUCT_NAME, "HP t5740e Thin Client"), |
|
- | 740 | }, |
|
- | 741 | }, |
|
- | 742 | { |
|
- | 743 | .callback = intel_no_lvds_dmi_callback, |
|
- | 744 | .ident = "Hewlett-Packard t5745", |
|
- | 745 | .matches = { |
|
- | 746 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), |
|
- | 747 | DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"), |
|
- | 748 | }, |
|
- | 749 | }, |
|
- | 750 | { |
|
- | 751 | .callback = intel_no_lvds_dmi_callback, |
|
- | 752 | .ident = "Hewlett-Packard st5747", |
|
- | 753 | .matches = { |
|
- | 754 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), |
|
- | 755 | DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"), |
|
- | 756 | }, |
|
- | 757 | }, |
|
- | 758 | { |
|
- | 759 | .callback = intel_no_lvds_dmi_callback, |
|
- | 760 | .ident = "MSI Wind Box DC500", |
|
- | 761 | .matches = { |
|
- | 762 | DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), |
|
- | 763 | DMI_MATCH(DMI_BOARD_NAME, "MS-7469"), |
|
- | 764 | }, |
|
- | 765 | }, |
|
- | 766 | { |
|
- | 767 | .callback = intel_no_lvds_dmi_callback, |
|
- | 768 | .ident = "ZOTAC ZBOXSD-ID12/ID13", |
|
- | 769 | .matches = { |
|
- | 770 | DMI_MATCH(DMI_BOARD_VENDOR, "ZOTAC"), |
|
- | 771 | DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), |
|
- | 772 | }, |
|
- | 773 | }, |
|
- | 774 | { |
|
- | 775 | .callback = intel_no_lvds_dmi_callback, |
|
- | 776 | .ident = "Gigabyte GA-D525TUD", |
|
- | 777 | .matches = { |
|
- | 778 | DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), |
|
- | 779 | DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), |
|
- | 780 | }, |
|
- | 781 | }, |
|
- | 782 | { |
|
- | 783 | .callback = intel_no_lvds_dmi_callback, |
|
- | 784 | .ident = "Supermicro X7SPA-H", |
|
- | 785 | .matches = { |
|
- | 786 | DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"), |
|
- | 787 | DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"), |
|
- | 788 | }, |
|
- | 789 | }, |
|
Line 744... | Line 790... | ||
744 | 790 | ||
745 | { } /* terminating entry */ |
791 | { } /* terminating entry */ |
Line 746... | Line 792... | ||
746 | }; |
792 | }; |
Line 821... | Line 867... | ||
821 | */ |
867 | */ |
822 | if (child->device_type != DEVICE_TYPE_INT_LFP && |
868 | if (child->device_type != DEVICE_TYPE_INT_LFP && |
823 | child->device_type != DEVICE_TYPE_LFP) |
869 | child->device_type != DEVICE_TYPE_LFP) |
824 | continue; |
870 | continue; |
Line 825... | Line 871... | ||
825 | 871 | ||
826 | if (child->i2c_pin) |
872 | if (intel_gmbus_is_port_valid(child->i2c_pin)) |
Line 827... | Line 873... | ||
827 | *i2c_pin = child->i2c_pin; |
873 | *i2c_pin = child->i2c_pin; |
828 | 874 | ||
829 | /* However, we cannot trust the BIOS writers to populate |
875 | /* However, we cannot trust the BIOS writers to populate |
Line 844... | Line 890... | ||
844 | } |
890 | } |
Line 845... | Line 891... | ||
845 | 891 | ||
846 | return false; |
892 | return false; |
Line -... | Line 893... | ||
- | 893 | } |
|
- | 894 | ||
- | 895 | static bool intel_lvds_supported(struct drm_device *dev) |
|
- | 896 | { |
|
- | 897 | /* With the introduction of the PCH we gained a dedicated |
|
- | 898 | * LVDS presence pin, use it. */ |
|
- | 899 | if (HAS_PCH_SPLIT(dev)) |
|
- | 900 | return true; |
|
- | 901 | ||
- | 902 | /* Otherwise LVDS was only attached to mobile products, |
|
- | 903 | * except for the inglorious 830gm */ |
|
- | 904 | return IS_MOBILE(dev) && !IS_I830(dev); |
|
847 | } |
905 | } |
848 | 906 | ||
849 | /** |
907 | /** |
850 | * intel_lvds_init - setup LVDS connectors on this device |
908 | * intel_lvds_init - setup LVDS connectors on this device |
851 | * @dev: drm device |
909 | * @dev: drm device |
Line 865... | Line 923... | ||
865 | struct drm_crtc *crtc; |
923 | struct drm_crtc *crtc; |
866 | u32 lvds; |
924 | u32 lvds; |
867 | int pipe; |
925 | int pipe; |
868 | u8 pin; |
926 | u8 pin; |
Line -... | Line 927... | ||
- | 927 | ||
- | 928 | if (!intel_lvds_supported(dev)) |
|
- | 929 | return false; |
|
869 | 930 | ||
870 | /* Skip init on machines we know falsely report LVDS */ |
931 | /* Skip init on machines we know falsely report LVDS */ |
871 | // if (dmi_check_system(intel_no_lvds)) |
932 | // if (dmi_check_system(intel_no_lvds)) |
Line 872... | Line 933... | ||
872 | // return false; |
933 | // return false; |
Line 908... | Line 969... | ||
908 | DRM_MODE_CONNECTOR_LVDS); |
969 | DRM_MODE_CONNECTOR_LVDS); |
Line 909... | Line 970... | ||
909 | 970 | ||
910 | drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs, |
971 | drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs, |
Line -... | Line 972... | ||
- | 972 | DRM_MODE_ENCODER_LVDS); |
|
- | 973 | ||
- | 974 | intel_encoder->enable = intel_enable_lvds; |
|
- | 975 | intel_encoder->disable = intel_disable_lvds; |
|
- | 976 | intel_encoder->get_hw_state = intel_lvds_get_hw_state; |
|
911 | DRM_MODE_ENCODER_LVDS); |
977 | intel_connector->get_hw_state = intel_connector_get_hw_state; |
912 | 978 | ||
Line 913... | Line 979... | ||
913 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
979 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
914 | intel_encoder->type = INTEL_OUTPUT_LVDS; |
980 | intel_encoder->type = INTEL_OUTPUT_LVDS; |
915 | 981 | ||
- | 982 | intel_encoder->cloneable = false; |
|
- | 983 | if (HAS_PCH_SPLIT(dev)) |
|
916 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); |
984 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
917 | if (HAS_PCH_SPLIT(dev)) |
985 | else if (IS_GEN4(dev)) |
Line 918... | Line 986... | ||
918 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
986 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
919 | else |
987 | else |
Line 948... | Line 1016... | ||
948 | /* |
1016 | /* |
949 | * Attempt to get the fixed panel mode from DDC. Assume that the |
1017 | * Attempt to get the fixed panel mode from DDC. Assume that the |
950 | * preferred mode is the right one. |
1018 | * preferred mode is the right one. |
951 | */ |
1019 | */ |
952 | intel_lvds->edid = drm_get_edid(connector, |
1020 | intel_lvds->edid = drm_get_edid(connector, |
953 | &dev_priv->gmbus[pin].adapter); |
1021 | intel_gmbus_get_adapter(dev_priv, |
- | 1022 | pin)); |
|
954 | if (intel_lvds->edid) { |
1023 | if (intel_lvds->edid) { |
955 | if (drm_add_edid_modes(connector, |
1024 | if (drm_add_edid_modes(connector, |
956 | intel_lvds->edid)) { |
1025 | intel_lvds->edid)) { |
957 | drm_mode_connector_update_edid_property(connector, |
1026 | drm_mode_connector_update_edid_property(connector, |
958 | intel_lvds->edid); |
1027 | intel_lvds->edid); |
Line 1020... | Line 1089... | ||
1020 | /* If we still don't have a mode after all that, give up. */ |
1089 | /* If we still don't have a mode after all that, give up. */ |
1021 | if (!intel_lvds->fixed_mode) |
1090 | if (!intel_lvds->fixed_mode) |
1022 | goto failed; |
1091 | goto failed; |
Line 1023... | Line 1092... | ||
1023 | 1092 | ||
1024 | out: |
- | |
1025 | if (HAS_PCH_SPLIT(dev)) { |
- | |
1026 | u32 pwm; |
- | |
1027 | - | ||
1028 | pipe = (I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT) ? 1 : 0; |
- | |
1029 | - | ||
1030 | /* make sure PWM is enabled and locked to the LVDS pipe */ |
- | |
1031 | pwm = I915_READ(BLC_PWM_CPU_CTL2); |
- | |
1032 | if (pipe == 0 && (pwm & PWM_PIPE_B)) |
- | |
1033 | I915_WRITE(BLC_PWM_CPU_CTL2, pwm & ~PWM_ENABLE); |
- | |
1034 | if (pipe) |
- | |
1035 | pwm |= PWM_PIPE_B; |
- | |
1036 | else |
- | |
1037 | pwm &= ~PWM_PIPE_B; |
- | |
1038 | I915_WRITE(BLC_PWM_CPU_CTL2, pwm | PWM_ENABLE); |
- | |
1039 | - | ||
1040 | pwm = I915_READ(BLC_PWM_PCH_CTL1); |
- | |
1041 | pwm |= PWM_PCH_ENABLE; |
- | |
1042 | I915_WRITE(BLC_PWM_PCH_CTL1, pwm); |
1093 | out: |
1043 | /* |
1094 | /* |
1044 | * Unlock registers and just |
1095 | * Unlock registers and just |
1045 | * leave them unlocked |
1096 | * leave them unlocked |
- | 1097 | */ |
|
1046 | */ |
1098 | if (HAS_PCH_SPLIT(dev)) { |
1047 | I915_WRITE(PCH_PP_CONTROL, |
1099 | I915_WRITE(PCH_PP_CONTROL, |
1048 | I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); |
1100 | I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); |
1049 | } else { |
- | |
1050 | /* |
- | |
1051 | * Unlock registers and just |
- | |
1052 | * leave them unlocked |
- | |
1053 | */ |
1101 | } else { |
1054 | I915_WRITE(PP_CONTROL, |
1102 | I915_WRITE(PP_CONTROL, |
1055 | I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); |
1103 | I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); |
1056 | } |
1104 | } |
1057 | // dev_priv->lid_notifier.notifier_call = intel_lid_notify; |
1105 | // dev_priv->lid_notifier.notifier_call = intel_lid_notify; |