Rev 3031 | Rev 3480 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3031 | Rev 3243 | ||
---|---|---|---|
Line 38... | Line 38... | ||
38 | #include |
38 | #include |
39 | #include "i915_drv.h" |
39 | #include "i915_drv.h" |
40 | //#include |
40 | //#include |
Line 41... | Line 41... | ||
41 | 41 | ||
42 | /* Private structure for the integrated LVDS support */ |
42 | /* Private structure for the integrated LVDS support */ |
43 | struct intel_lvds { |
43 | struct intel_lvds_connector { |
Line -... | Line 44... | ||
- | 44 | struct intel_connector base; |
|
- | 45 | ||
- | 46 | // struct notifier_block lid_notifier; |
|
- | 47 | }; |
|
44 | struct intel_encoder base; |
48 | |
Line 45... | Line -... | ||
45 | - | ||
46 | struct edid *edid; |
49 | struct intel_lvds_encoder { |
47 | 50 | struct intel_encoder base; |
|
48 | int fitting_mode; |
51 | |
Line 49... | Line 52... | ||
49 | u32 pfit_control; |
52 | u32 pfit_control; |
50 | u32 pfit_pgm_ratios; |
53 | u32 pfit_pgm_ratios; |
Line 51... | Line 54... | ||
51 | bool pfit_dirty; |
54 | bool pfit_dirty; |
52 | 55 | ||
53 | struct drm_display_mode *fixed_mode; |
56 | struct intel_lvds_connector *attached_connector; |
54 | }; |
57 | }; |
Line 55... | Line 58... | ||
55 | 58 | ||
56 | static struct intel_lvds *to_intel_lvds(struct drm_encoder *encoder) |
59 | static struct intel_lvds_encoder *to_lvds_encoder(struct drm_encoder *encoder) |
57 | { |
60 | { |
58 | return container_of(encoder, struct intel_lvds, base.base); |
- | |
59 | } |
61 | return container_of(encoder, struct intel_lvds_encoder, base.base); |
Line 60... | Line 62... | ||
60 | 62 | } |
|
61 | static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) |
63 | |
62 | { |
64 | static struct intel_lvds_connector *to_lvds_connector(struct drm_connector *connector) |
Line 94... | Line 96... | ||
94 | * Sets the power state for the panel. |
96 | * Sets the power state for the panel. |
95 | */ |
97 | */ |
96 | static void intel_enable_lvds(struct intel_encoder *encoder) |
98 | static void intel_enable_lvds(struct intel_encoder *encoder) |
97 | { |
99 | { |
98 | struct drm_device *dev = encoder->base.dev; |
100 | struct drm_device *dev = encoder->base.dev; |
99 | struct intel_lvds *intel_lvds = to_intel_lvds(&encoder->base); |
101 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); |
100 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
102 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); |
101 | struct drm_i915_private *dev_priv = dev->dev_private; |
103 | struct drm_i915_private *dev_priv = dev->dev_private; |
102 | u32 ctl_reg, lvds_reg, stat_reg; |
104 | u32 ctl_reg, lvds_reg, stat_reg; |
Line 103... | Line 105... | ||
103 | 105 | ||
Line 111... | Line 113... | ||
111 | stat_reg = PP_STATUS; |
113 | stat_reg = PP_STATUS; |
112 | } |
114 | } |
Line 113... | Line 115... | ||
113 | 115 | ||
Line 114... | Line 116... | ||
114 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); |
116 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); |
115 | 117 | ||
116 | if (intel_lvds->pfit_dirty) { |
118 | if (lvds_encoder->pfit_dirty) { |
117 | /* |
119 | /* |
118 | * Enable automatic panel scaling so that non-native modes |
120 | * Enable automatic panel scaling so that non-native modes |
119 | * fill the screen. The panel fitter should only be |
121 | * fill the screen. The panel fitter should only be |
120 | * adjusted whilst the pipe is disabled, according to |
122 | * adjusted whilst the pipe is disabled, according to |
121 | * register description and PRM. |
123 | * register description and PRM. |
122 | */ |
124 | */ |
123 | DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", |
125 | DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", |
Line 124... | Line 126... | ||
124 | intel_lvds->pfit_control, |
126 | lvds_encoder->pfit_control, |
125 | intel_lvds->pfit_pgm_ratios); |
127 | lvds_encoder->pfit_pgm_ratios); |
126 | 128 | ||
127 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); |
129 | I915_WRITE(PFIT_PGM_RATIOS, lvds_encoder->pfit_pgm_ratios); |
Line 128... | Line 130... | ||
128 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); |
130 | I915_WRITE(PFIT_CONTROL, lvds_encoder->pfit_control); |
129 | intel_lvds->pfit_dirty = false; |
131 | lvds_encoder->pfit_dirty = false; |
130 | } |
132 | } |
Line 138... | Line 140... | ||
138 | } |
140 | } |
Line 139... | Line 141... | ||
139 | 141 | ||
140 | static void intel_disable_lvds(struct intel_encoder *encoder) |
142 | static void intel_disable_lvds(struct intel_encoder *encoder) |
141 | { |
143 | { |
142 | struct drm_device *dev = encoder->base.dev; |
144 | struct drm_device *dev = encoder->base.dev; |
143 | struct intel_lvds *intel_lvds = to_intel_lvds(&encoder->base); |
145 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); |
144 | struct drm_i915_private *dev_priv = dev->dev_private; |
146 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 145... | Line 147... | ||
145 | u32 ctl_reg, lvds_reg, stat_reg; |
147 | u32 ctl_reg, lvds_reg, stat_reg; |
146 | 148 | ||
Line 158... | Line 160... | ||
158 | 160 | ||
159 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); |
161 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); |
160 | if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000)) |
162 | if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000)) |
Line 161... | Line 163... | ||
161 | DRM_ERROR("timed out waiting for panel to power off\n"); |
163 | DRM_ERROR("timed out waiting for panel to power off\n"); |
162 | 164 | ||
163 | if (intel_lvds->pfit_control) { |
165 | if (lvds_encoder->pfit_control) { |
164 | I915_WRITE(PFIT_CONTROL, 0); |
166 | I915_WRITE(PFIT_CONTROL, 0); |
Line 165... | Line 167... | ||
165 | intel_lvds->pfit_dirty = true; |
167 | lvds_encoder->pfit_dirty = true; |
166 | } |
168 | } |
167 | 169 | ||
Line 168... | Line 170... | ||
168 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); |
170 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); |
169 | POSTING_READ(lvds_reg); |
171 | POSTING_READ(lvds_reg); |
170 | } |
172 | } |
171 | 173 | ||
172 | static int intel_lvds_mode_valid(struct drm_connector *connector, |
174 | static int intel_lvds_mode_valid(struct drm_connector *connector, |
Line 173... | Line 175... | ||
173 | struct drm_display_mode *mode) |
175 | struct drm_display_mode *mode) |
174 | { |
176 | { |
175 | struct intel_lvds *intel_lvds = intel_attached_lvds(connector); |
177 | struct intel_connector *intel_connector = to_intel_connector(connector); |
176 | struct drm_display_mode *fixed_mode = intel_lvds->fixed_mode; |
178 | struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; |
Line 247... | Line 249... | ||
247 | const struct drm_display_mode *mode, |
249 | const struct drm_display_mode *mode, |
248 | struct drm_display_mode *adjusted_mode) |
250 | struct drm_display_mode *adjusted_mode) |
249 | { |
251 | { |
250 | struct drm_device *dev = encoder->dev; |
252 | struct drm_device *dev = encoder->dev; |
251 | struct drm_i915_private *dev_priv = dev->dev_private; |
253 | struct drm_i915_private *dev_priv = dev->dev_private; |
252 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
254 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); |
- | 255 | struct intel_connector *intel_connector = |
|
- | 256 | &lvds_encoder->attached_connector->base; |
|
253 | struct intel_crtc *intel_crtc = intel_lvds->base.new_crtc; |
257 | struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc; |
254 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
258 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
255 | int pipe; |
259 | int pipe; |
Line 256... | Line 260... | ||
256 | 260 | ||
257 | /* Should never happen!! */ |
261 | /* Should never happen!! */ |
258 | if (INTEL_INFO(dev)->gen < 4 && intel_crtc->pipe == 0) { |
262 | if (INTEL_INFO(dev)->gen < 4 && intel_crtc->pipe == 0) { |
259 | DRM_ERROR("Can't support LVDS on pipe A\n"); |
263 | DRM_ERROR("Can't support LVDS on pipe A\n"); |
260 | return false; |
264 | return false; |
Line 261... | Line 265... | ||
261 | } |
265 | } |
262 | 266 | ||
Line 263... | Line 267... | ||
263 | if (intel_encoder_check_is_cloned(&intel_lvds->base)) |
267 | if (intel_encoder_check_is_cloned(&lvds_encoder->base)) |
264 | return false; |
268 | return false; |
265 | 269 | ||
266 | /* |
270 | /* |
267 | * We have timings from the BIOS for the panel, put them in |
271 | * We have timings from the BIOS for the panel, put them in |
268 | * to the adjusted mode. The CRTC will be set up for this mode, |
272 | * to the adjusted mode. The CRTC will be set up for this mode, |
269 | * with the panel scaling set up to source from the H/VDisplay |
273 | * with the panel scaling set up to source from the H/VDisplay |
- | 274 | * of the original mode. |
|
Line 270... | Line 275... | ||
270 | * of the original mode. |
275 | */ |
271 | */ |
276 | intel_fixed_panel_mode(intel_connector->panel.fixed_mode, |
- | 277 | adjusted_mode); |
|
272 | intel_fixed_panel_mode(intel_lvds->fixed_mode, adjusted_mode); |
278 | |
273 | 279 | if (HAS_PCH_SPLIT(dev)) { |
|
274 | if (HAS_PCH_SPLIT(dev)) { |
280 | intel_pch_panel_fitting(dev, |
Line 275... | Line 281... | ||
275 | intel_pch_panel_fitting(dev, intel_lvds->fitting_mode, |
281 | intel_connector->panel.fitting_mode, |
Line 296... | Line 302... | ||
296 | for_each_pipe(pipe) |
302 | for_each_pipe(pipe) |
297 | I915_WRITE(BCLRPAT(pipe), 0); |
303 | I915_WRITE(BCLRPAT(pipe), 0); |
Line 298... | Line 304... | ||
298 | 304 | ||
Line 299... | Line 305... | ||
299 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
305 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
300 | 306 | ||
301 | switch (intel_lvds->fitting_mode) { |
307 | switch (intel_connector->panel.fitting_mode) { |
302 | case DRM_MODE_SCALE_CENTER: |
308 | case DRM_MODE_SCALE_CENTER: |
303 | /* |
309 | /* |
304 | * For centered modes, we have to calculate border widths & |
310 | * For centered modes, we have to calculate border widths & |
Line 394... | Line 400... | ||
394 | 400 | ||
395 | /* Make sure pre-965 set dither correctly */ |
401 | /* Make sure pre-965 set dither correctly */ |
396 | if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither) |
402 | if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither) |
Line 397... | Line 403... | ||
397 | pfit_control |= PANEL_8TO6_DITHER_ENABLE; |
403 | pfit_control |= PANEL_8TO6_DITHER_ENABLE; |
398 | 404 | ||
399 | if (pfit_control != intel_lvds->pfit_control || |
405 | if (pfit_control != lvds_encoder->pfit_control || |
400 | pfit_pgm_ratios != intel_lvds->pfit_pgm_ratios) { |
406 | pfit_pgm_ratios != lvds_encoder->pfit_pgm_ratios) { |
401 | intel_lvds->pfit_control = pfit_control; |
407 | lvds_encoder->pfit_control = pfit_control; |
402 | intel_lvds->pfit_pgm_ratios = pfit_pgm_ratios; |
408 | lvds_encoder->pfit_pgm_ratios = pfit_pgm_ratios; |
403 | intel_lvds->pfit_dirty = true; |
409 | lvds_encoder->pfit_dirty = true; |
Line 404... | Line 410... | ||
404 | } |
410 | } |
405 | dev_priv->lvds_border_bits = border; |
411 | dev_priv->lvds_border_bits = border; |
Line 447... | Line 453... | ||
447 | /** |
453 | /** |
448 | * Return the list of DDC modes if available, or the BIOS fixed mode otherwise. |
454 | * Return the list of DDC modes if available, or the BIOS fixed mode otherwise. |
449 | */ |
455 | */ |
450 | static int intel_lvds_get_modes(struct drm_connector *connector) |
456 | static int intel_lvds_get_modes(struct drm_connector *connector) |
451 | { |
457 | { |
452 | struct intel_lvds *intel_lvds = intel_attached_lvds(connector); |
458 | struct intel_lvds_connector *lvds_connector = to_lvds_connector(connector); |
453 | struct drm_device *dev = connector->dev; |
459 | struct drm_device *dev = connector->dev; |
454 | struct drm_display_mode *mode; |
460 | struct drm_display_mode *mode; |
Line -... | Line 461... | ||
- | 461 | ||
455 | 462 | /* use cached edid if we have one */ |
|
456 | if (intel_lvds->edid) |
463 | if (!IS_ERR_OR_NULL(lvds_connector->base.edid)) |
Line 457... | Line 464... | ||
457 | return drm_add_edid_modes(connector, intel_lvds->edid); |
464 | return drm_add_edid_modes(connector, lvds_connector->base.edid); |
458 | 465 | ||
459 | mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode); |
466 | mode = drm_mode_duplicate(dev, lvds_connector->base.panel.fixed_mode); |
Line 460... | Line 467... | ||
460 | if (mode == NULL) |
467 | if (mode == NULL) |
461 | return 0; |
468 | return 0; |
Line 495... | Line 502... | ||
495 | * zero, since they restore the mode ("lid open"). |
502 | * zero, since they restore the mode ("lid open"). |
496 | */ |
503 | */ |
497 | static int intel_lid_notify(struct notifier_block *nb, unsigned long val, |
504 | static int intel_lid_notify(struct notifier_block *nb, unsigned long val, |
498 | void *unused) |
505 | void *unused) |
499 | { |
506 | { |
500 | struct drm_i915_private *dev_priv = |
507 | struct intel_lvds_connector *lvds_connector = |
501 | container_of(nb, struct drm_i915_private, lid_notifier); |
508 | container_of(nb, struct intel_lvds_connector, lid_notifier); |
- | 509 | struct drm_connector *connector = &lvds_connector->base.base; |
|
502 | struct drm_device *dev = dev_priv->dev; |
510 | struct drm_device *dev = connector->dev; |
503 | struct drm_connector *connector = dev_priv->int_lvds_connector; |
511 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 504... | Line 512... | ||
504 | 512 | ||
505 | if (dev->switch_power_state != DRM_SWITCH_POWER_ON) |
513 | if (dev->switch_power_state != DRM_SWITCH_POWER_ON) |
Line 506... | Line 514... | ||
506 | return NOTIFY_OK; |
514 | return NOTIFY_OK; |
507 | 515 | ||
508 | /* |
516 | /* |
509 | * check and update the status of LVDS connector after receiving |
517 | * check and update the status of LVDS connector after receiving |
510 | * the LID nofication event. |
- | |
511 | */ |
518 | * the LID nofication event. |
512 | if (connector) |
- | |
Line 513... | Line 519... | ||
513 | connector->status = connector->funcs->detect(connector, |
519 | */ |
514 | false); |
520 | connector->status = connector->funcs->detect(connector, false); |
515 | 521 | ||
516 | /* Don't force modeset on machines where it causes a GPU lockup */ |
522 | /* Don't force modeset on machines where it causes a GPU lockup */ |
Line 525... | Line 531... | ||
525 | return NOTIFY_OK; |
531 | return NOTIFY_OK; |
Line 526... | Line 532... | ||
526 | 532 | ||
Line 527... | Line 533... | ||
527 | dev_priv->modeset_on_lid = 0; |
533 | dev_priv->modeset_on_lid = 0; |
528 | 534 | ||
529 | mutex_lock(&dev->mode_config.mutex); |
535 | mutex_lock(&dev->mode_config.mutex); |
Line 530... | Line 536... | ||
530 | intel_modeset_check_state(dev); |
536 | intel_modeset_setup_hw_state(dev, true); |
531 | mutex_unlock(&dev->mode_config.mutex); |
537 | mutex_unlock(&dev->mode_config.mutex); |
532 | 538 | ||
Line 541... | Line 547... | ||
541 | * Unregister the DDC bus for this connector then free the driver private |
547 | * Unregister the DDC bus for this connector then free the driver private |
542 | * structure. |
548 | * structure. |
543 | */ |
549 | */ |
544 | static void intel_lvds_destroy(struct drm_connector *connector) |
550 | static void intel_lvds_destroy(struct drm_connector *connector) |
545 | { |
551 | { |
546 | struct drm_device *dev = connector->dev; |
552 | struct intel_lvds_connector *lvds_connector = |
547 | struct drm_i915_private *dev_priv = dev->dev_private; |
553 | to_lvds_connector(connector); |
- | 554 | ||
Line -... | Line 555... | ||
- | 555 | ||
- | 556 | if (!IS_ERR_OR_NULL(lvds_connector->base.edid)) |
|
- | 557 | kfree(lvds_connector->base.edid); |
|
548 | 558 | ||
- | 559 | intel_panel_destroy_backlight(connector->dev); |
|
Line 549... | Line -... | ||
549 | intel_panel_destroy_backlight(dev); |
- | |
550 | - | ||
551 | // if (dev_priv->lid_notifier.notifier_call) |
560 | intel_panel_fini(&lvds_connector->base.panel); |
552 | // acpi_lid_notifier_unregister(&dev_priv->lid_notifier); |
561 | |
553 | drm_sysfs_connector_remove(connector); |
562 | drm_sysfs_connector_remove(connector); |
554 | drm_connector_cleanup(connector); |
563 | drm_connector_cleanup(connector); |
Line 555... | Line 564... | ||
555 | kfree(connector); |
564 | kfree(connector); |
556 | } |
565 | } |
557 | 566 | ||
558 | static int intel_lvds_set_property(struct drm_connector *connector, |
567 | static int intel_lvds_set_property(struct drm_connector *connector, |
559 | struct drm_property *property, |
568 | struct drm_property *property, |
560 | uint64_t value) |
569 | uint64_t value) |
Line 561... | Line 570... | ||
561 | { |
570 | { |
562 | struct intel_lvds *intel_lvds = intel_attached_lvds(connector); |
571 | struct intel_connector *intel_connector = to_intel_connector(connector); |
Line 563... | Line 572... | ||
563 | struct drm_device *dev = connector->dev; |
572 | struct drm_device *dev = connector->dev; |
564 | 573 | ||
565 | if (property == dev->mode_config.scaling_mode_property) { |
574 | if (property == dev->mode_config.scaling_mode_property) { |
566 | struct drm_crtc *crtc = intel_lvds->base.base.crtc; |
575 | struct drm_crtc *crtc; |
Line 567... | Line 576... | ||
567 | 576 | ||
568 | if (value == DRM_MODE_SCALE_NONE) { |
577 | if (value == DRM_MODE_SCALE_NONE) { |
569 | DRM_DEBUG_KMS("no scaling not supported\n"); |
578 | DRM_DEBUG_KMS("no scaling not supported\n"); |
570 | return -EINVAL; |
579 | return -EINVAL; |
571 | } |
580 | } |
- | 581 | ||
- | 582 | if (intel_connector->panel.fitting_mode == value) { |
|
572 | 583 | /* the LVDS scaling property is not changed */ |
|
573 | if (intel_lvds->fitting_mode == value) { |
584 | return 0; |
574 | /* the LVDS scaling property is not changed */ |
585 | } |
575 | return 0; |
586 | intel_connector->panel.fitting_mode = value; |
576 | } |
587 | |
Line 763... | Line 774... | ||
763 | DMI_MATCH(DMI_BOARD_NAME, "MS-7469"), |
774 | DMI_MATCH(DMI_BOARD_NAME, "MS-7469"), |
764 | }, |
775 | }, |
765 | }, |
776 | }, |
766 | { |
777 | { |
767 | .callback = intel_no_lvds_dmi_callback, |
778 | .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", |
779 | .ident = "Gigabyte GA-D525TUD", |
777 | .matches = { |
780 | .matches = { |
778 | DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), |
781 | DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), |
779 | DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), |
782 | DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), |
780 | }, |
783 | }, |
Line 912... | Line 915... | ||
912 | * modes we can display on the LVDS panel (if present). |
915 | * modes we can display on the LVDS panel (if present). |
913 | */ |
916 | */ |
914 | bool intel_lvds_init(struct drm_device *dev) |
917 | bool intel_lvds_init(struct drm_device *dev) |
915 | { |
918 | { |
916 | struct drm_i915_private *dev_priv = dev->dev_private; |
919 | struct drm_i915_private *dev_priv = dev->dev_private; |
917 | struct intel_lvds *intel_lvds; |
920 | struct intel_lvds_encoder *lvds_encoder; |
918 | struct intel_encoder *intel_encoder; |
921 | struct intel_encoder *intel_encoder; |
- | 922 | struct intel_lvds_connector *lvds_connector; |
|
919 | struct intel_connector *intel_connector; |
923 | struct intel_connector *intel_connector; |
920 | struct drm_connector *connector; |
924 | struct drm_connector *connector; |
921 | struct drm_encoder *encoder; |
925 | struct drm_encoder *encoder; |
922 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ |
926 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ |
- | 927 | struct drm_display_mode *fixed_mode = NULL; |
|
- | 928 | struct edid *edid; |
|
923 | struct drm_crtc *crtc; |
929 | struct drm_crtc *crtc; |
924 | u32 lvds; |
930 | u32 lvds; |
925 | int pipe; |
931 | int pipe; |
926 | u8 pin; |
932 | u8 pin; |
Line 945... | Line 951... | ||
945 | DRM_DEBUG_KMS("disable LVDS for eDP support\n"); |
951 | DRM_DEBUG_KMS("disable LVDS for eDP support\n"); |
946 | return false; |
952 | return false; |
947 | } |
953 | } |
948 | } |
954 | } |
Line 949... | Line 955... | ||
949 | 955 | ||
950 | intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL); |
956 | lvds_encoder = kzalloc(sizeof(struct intel_lvds_encoder), GFP_KERNEL); |
951 | if (!intel_lvds) { |
957 | if (!lvds_encoder) |
952 | return false; |
- | |
Line 953... | Line 958... | ||
953 | } |
958 | return false; |
954 | 959 | ||
955 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
960 | lvds_connector = kzalloc(sizeof(struct intel_lvds_connector), GFP_KERNEL); |
956 | if (!intel_connector) { |
961 | if (!lvds_connector) { |
957 | kfree(intel_lvds); |
962 | kfree(lvds_encoder); |
Line -... | Line 963... | ||
- | 963 | return false; |
|
- | 964 | } |
|
958 | return false; |
965 | |
959 | } |
966 | lvds_encoder->attached_connector = lvds_connector; |
960 | 967 | ||
Line 961... | Line 968... | ||
961 | if (!HAS_PCH_SPLIT(dev)) { |
968 | if (!HAS_PCH_SPLIT(dev)) { |
962 | intel_lvds->pfit_control = I915_READ(PFIT_CONTROL); |
969 | lvds_encoder->pfit_control = I915_READ(PFIT_CONTROL); |
- | 970 | } |
|
963 | } |
971 | |
964 | 972 | intel_encoder = &lvds_encoder->base; |
|
965 | intel_encoder = &intel_lvds->base; |
973 | encoder = &intel_encoder->base; |
Line 966... | Line 974... | ||
966 | encoder = &intel_encoder->base; |
974 | intel_connector = &lvds_connector->base; |
Line 993... | Line 1001... | ||
993 | connector->interlace_allowed = false; |
1001 | connector->interlace_allowed = false; |
994 | connector->doublescan_allowed = false; |
1002 | connector->doublescan_allowed = false; |
Line 995... | Line 1003... | ||
995 | 1003 | ||
996 | /* create the scaling mode property */ |
1004 | /* create the scaling mode property */ |
997 | drm_mode_create_scaling_mode_property(dev); |
- | |
998 | /* |
- | |
999 | * the initial panel fitting mode will be FULL_SCREEN. |
- | |
1000 | */ |
- | |
1001 | 1005 | drm_mode_create_scaling_mode_property(dev); |
|
1002 | drm_connector_attach_property(&intel_connector->base, |
1006 | drm_object_attach_property(&connector->base, |
1003 | dev->mode_config.scaling_mode_property, |
1007 | dev->mode_config.scaling_mode_property, |
1004 | DRM_MODE_SCALE_ASPECT); |
1008 | DRM_MODE_SCALE_ASPECT); |
1005 | intel_lvds->fitting_mode = DRM_MODE_SCALE_ASPECT; |
1009 | intel_connector->panel.fitting_mode = DRM_MODE_SCALE_ASPECT; |
1006 | /* |
1010 | /* |
1007 | * LVDS discovery: |
1011 | * LVDS discovery: |
1008 | * 1) check for EDID on DDC |
1012 | * 1) check for EDID on DDC |
1009 | * 2) check for VBT data |
1013 | * 2) check for VBT data |
Line 1015... | Line 1019... | ||
1015 | 1019 | ||
1016 | /* |
1020 | /* |
1017 | * Attempt to get the fixed panel mode from DDC. Assume that the |
1021 | * Attempt to get the fixed panel mode from DDC. Assume that the |
1018 | * preferred mode is the right one. |
1022 | * preferred mode is the right one. |
1019 | */ |
- | |
1020 | intel_lvds->edid = drm_get_edid(connector, |
1023 | */ |
1021 | intel_gmbus_get_adapter(dev_priv, |
- | |
1022 | pin)); |
1024 | edid = drm_get_edid(connector, intel_gmbus_get_adapter(dev_priv, pin)); |
1023 | if (intel_lvds->edid) { |
1025 | if (edid) { |
1024 | if (drm_add_edid_modes(connector, |
- | |
1025 | intel_lvds->edid)) { |
1026 | if (drm_add_edid_modes(connector, edid)) { |
1026 | drm_mode_connector_update_edid_property(connector, |
1027 | drm_mode_connector_update_edid_property(connector, |
1027 | intel_lvds->edid); |
1028 | edid); |
1028 | } else { |
1029 | } else { |
1029 | kfree(intel_lvds->edid); |
1030 | kfree(edid); |
1030 | intel_lvds->edid = NULL; |
1031 | edid = ERR_PTR(-EINVAL); |
- | 1032 | } |
|
- | 1033 | } else { |
|
1031 | } |
1034 | edid = ERR_PTR(-ENOENT); |
- | 1035 | } |
|
- | 1036 | lvds_connector->base.edid = edid; |
|
1032 | } |
1037 | |
1033 | if (!intel_lvds->edid) { |
1038 | if (IS_ERR_OR_NULL(edid)) { |
1034 | /* Didn't get an EDID, so |
1039 | /* Didn't get an EDID, so |
1035 | * Set wide sync ranges so we get all modes |
1040 | * Set wide sync ranges so we get all modes |
1036 | * handed to valid_mode for checking |
1041 | * handed to valid_mode for checking |
1037 | */ |
1042 | */ |
Line 1041... | Line 1046... | ||
1041 | connector->display_info.max_hfreq = 200; |
1046 | connector->display_info.max_hfreq = 200; |
1042 | } |
1047 | } |
Line 1043... | Line 1048... | ||
1043 | 1048 | ||
1044 | list_for_each_entry(scan, &connector->probed_modes, head) { |
1049 | list_for_each_entry(scan, &connector->probed_modes, head) { |
- | 1050 | if (scan->type & DRM_MODE_TYPE_PREFERRED) { |
|
1045 | if (scan->type & DRM_MODE_TYPE_PREFERRED) { |
1051 | DRM_DEBUG_KMS("using preferred mode from EDID: "); |
- | 1052 | drm_mode_debug_printmodeline(scan); |
|
1046 | intel_lvds->fixed_mode = |
1053 | |
1047 | drm_mode_duplicate(dev, scan); |
1054 | fixed_mode = drm_mode_duplicate(dev, scan); |
1048 | intel_find_lvds_downclock(dev, |
1055 | if (fixed_mode) { |
1049 | intel_lvds->fixed_mode, |
1056 | intel_find_lvds_downclock(dev, fixed_mode, |
1050 | connector); |
1057 | connector); |
1051 | goto out; |
1058 | goto out; |
1052 | } |
1059 | } |
- | 1060 | } |
|
Line 1053... | Line 1061... | ||
1053 | } |
1061 | } |
1054 | 1062 | ||
1055 | /* Failed to get EDID, what about VBT? */ |
1063 | /* Failed to get EDID, what about VBT? */ |
1056 | if (dev_priv->lfp_lvds_vbt_mode) { |
1064 | if (dev_priv->lfp_lvds_vbt_mode) { |
- | 1065 | DRM_DEBUG_KMS("using mode from VBT: "); |
|
1057 | intel_lvds->fixed_mode = |
1066 | drm_mode_debug_printmodeline(dev_priv->lfp_lvds_vbt_mode); |
1058 | drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); |
1067 | |
1059 | if (intel_lvds->fixed_mode) { |
1068 | fixed_mode = drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); |
1060 | intel_lvds->fixed_mode->type |= |
1069 | if (fixed_mode) { |
1061 | DRM_MODE_TYPE_PREFERRED; |
1070 | fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; |
1062 | goto out; |
1071 | goto out; |
Line 1063... | Line 1072... | ||
1063 | } |
1072 | } |
Line 1076... | Line 1085... | ||
1076 | lvds = I915_READ(LVDS); |
1085 | lvds = I915_READ(LVDS); |
1077 | pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; |
1086 | pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; |
1078 | crtc = intel_get_crtc_for_pipe(dev, pipe); |
1087 | crtc = intel_get_crtc_for_pipe(dev, pipe); |
Line 1079... | Line 1088... | ||
1079 | 1088 | ||
1080 | if (crtc && (lvds & LVDS_PORT_EN)) { |
1089 | if (crtc && (lvds & LVDS_PORT_EN)) { |
1081 | intel_lvds->fixed_mode = intel_crtc_mode_get(dev, crtc); |
1090 | fixed_mode = intel_crtc_mode_get(dev, crtc); |
- | 1091 | if (fixed_mode) { |
|
1082 | if (intel_lvds->fixed_mode) { |
1092 | DRM_DEBUG_KMS("using current (BIOS) mode: "); |
1083 | intel_lvds->fixed_mode->type |= |
1093 | drm_mode_debug_printmodeline(fixed_mode); |
1084 | DRM_MODE_TYPE_PREFERRED; |
1094 | fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; |
1085 | goto out; |
1095 | goto out; |
1086 | } |
1096 | } |
Line 1087... | Line 1097... | ||
1087 | } |
1097 | } |
1088 | 1098 | ||
1089 | /* If we still don't have a mode after all that, give up. */ |
1099 | /* If we still don't have a mode after all that, give up. */ |
Line 1090... | Line 1100... | ||
1090 | if (!intel_lvds->fixed_mode) |
1100 | if (!fixed_mode) |
1091 | goto failed; |
1101 | goto failed; |
1092 | 1102 | ||
Line 1105... | Line 1115... | ||
1105 | // dev_priv->lid_notifier.notifier_call = intel_lid_notify; |
1115 | // dev_priv->lid_notifier.notifier_call = intel_lid_notify; |
1106 | // if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) { |
1116 | // if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) { |
1107 | // DRM_DEBUG_KMS("lid notifier registration failed\n"); |
1117 | // DRM_DEBUG_KMS("lid notifier registration failed\n"); |
1108 | // dev_priv->lid_notifier.notifier_call = NULL; |
1118 | // dev_priv->lid_notifier.notifier_call = NULL; |
1109 | // } |
1119 | // } |
1110 | /* keep the LVDS connector */ |
- | |
1111 | dev_priv->int_lvds_connector = connector; |
- | |
1112 | drm_sysfs_connector_add(connector); |
1120 | drm_sysfs_connector_add(connector); |
Line -... | Line 1121... | ||
- | 1121 | ||
1113 | 1122 | intel_panel_init(&intel_connector->panel, fixed_mode); |
|
Line 1114... | Line 1123... | ||
1114 | intel_panel_setup_backlight(dev); |
1123 | intel_panel_setup_backlight(connector); |
Line 1115... | Line 1124... | ||
1115 | 1124 | ||
1116 | return true; |
1125 | return true; |
1117 | 1126 | ||
1118 | failed: |
1127 | failed: |
- | 1128 | DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); |
|
- | 1129 | drm_connector_cleanup(connector); |
|
1119 | DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); |
1130 | drm_encoder_cleanup(encoder); |
1120 | drm_connector_cleanup(connector); |
1131 | if (fixed_mode) |
1121 | drm_encoder_cleanup(encoder); |
1132 | drm_mode_destroy(dev, fixed_mode); |
1122 | kfree(intel_lvds); |
1133 | kfree(lvds_encoder); |