aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_lvds.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_lvds.c')
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c115
1 files changed, 46 insertions, 69 deletions
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 0a2e60059fb3..6ec39a86ed06 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -41,12 +41,18 @@
41#include <linux/acpi.h> 41#include <linux/acpi.h>
42 42
43/* Private structure for the integrated LVDS support */ 43/* Private structure for the integrated LVDS support */
44struct intel_lvds_priv { 44struct intel_lvds {
45 struct intel_encoder base;
45 int fitting_mode; 46 int fitting_mode;
46 u32 pfit_control; 47 u32 pfit_control;
47 u32 pfit_pgm_ratios; 48 u32 pfit_pgm_ratios;
48}; 49};
49 50
51static struct intel_lvds *enc_to_intel_lvds(struct drm_encoder *encoder)
52{
53 return container_of(enc_to_intel_encoder(encoder), struct intel_lvds, base);
54}
55
50/** 56/**
51 * Sets the backlight level. 57 * Sets the backlight level.
52 * 58 *
@@ -90,7 +96,7 @@ static u32 intel_lvds_get_max_backlight(struct drm_device *dev)
90static void intel_lvds_set_power(struct drm_device *dev, bool on) 96static void intel_lvds_set_power(struct drm_device *dev, bool on)
91{ 97{
92 struct drm_i915_private *dev_priv = dev->dev_private; 98 struct drm_i915_private *dev_priv = dev->dev_private;
93 u32 pp_status, ctl_reg, status_reg, lvds_reg; 99 u32 ctl_reg, status_reg, lvds_reg;
94 100
95 if (HAS_PCH_SPLIT(dev)) { 101 if (HAS_PCH_SPLIT(dev)) {
96 ctl_reg = PCH_PP_CONTROL; 102 ctl_reg = PCH_PP_CONTROL;
@@ -108,9 +114,8 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on)
108 114
109 I915_WRITE(ctl_reg, I915_READ(ctl_reg) | 115 I915_WRITE(ctl_reg, I915_READ(ctl_reg) |
110 POWER_TARGET_ON); 116 POWER_TARGET_ON);
111 do { 117 if (wait_for(I915_READ(status_reg) & PP_ON, 1000, 0))
112 pp_status = I915_READ(status_reg); 118 DRM_ERROR("timed out waiting to enable LVDS pipe");
113 } while ((pp_status & PP_ON) == 0);
114 119
115 intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle); 120 intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle);
116 } else { 121 } else {
@@ -118,9 +123,8 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on)
118 123
119 I915_WRITE(ctl_reg, I915_READ(ctl_reg) & 124 I915_WRITE(ctl_reg, I915_READ(ctl_reg) &
120 ~POWER_TARGET_ON); 125 ~POWER_TARGET_ON);
121 do { 126 if (wait_for((I915_READ(status_reg) & PP_ON) == 0, 1000, 0))
122 pp_status = I915_READ(status_reg); 127 DRM_ERROR("timed out waiting for LVDS pipe to turn off");
123 } while (pp_status & PP_ON);
124 128
125 I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); 129 I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN);
126 POSTING_READ(lvds_reg); 130 POSTING_READ(lvds_reg);
@@ -219,9 +223,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
219 struct drm_device *dev = encoder->dev; 223 struct drm_device *dev = encoder->dev;
220 struct drm_i915_private *dev_priv = dev->dev_private; 224 struct drm_i915_private *dev_priv = dev->dev_private;
221 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); 225 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
226 struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder);
222 struct drm_encoder *tmp_encoder; 227 struct drm_encoder *tmp_encoder;
223 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
224 struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
225 u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; 228 u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
226 229
227 /* Should never happen!! */ 230 /* Should never happen!! */
@@ -241,26 +244,20 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
241 /* If we don't have a panel mode, there is nothing we can do */ 244 /* If we don't have a panel mode, there is nothing we can do */
242 if (dev_priv->panel_fixed_mode == NULL) 245 if (dev_priv->panel_fixed_mode == NULL)
243 return true; 246 return true;
247
244 /* 248 /*
245 * We have timings from the BIOS for the panel, put them in 249 * We have timings from the BIOS for the panel, put them in
246 * to the adjusted mode. The CRTC will be set up for this mode, 250 * to the adjusted mode. The CRTC will be set up for this mode,
247 * with the panel scaling set up to source from the H/VDisplay 251 * with the panel scaling set up to source from the H/VDisplay
248 * of the original mode. 252 * of the original mode.
249 */ 253 */
250 adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay; 254 intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode);
251 adjusted_mode->hsync_start = 255
252 dev_priv->panel_fixed_mode->hsync_start; 256 if (HAS_PCH_SPLIT(dev)) {
253 adjusted_mode->hsync_end = 257 intel_pch_panel_fitting(dev, intel_lvds->fitting_mode,
254 dev_priv->panel_fixed_mode->hsync_end; 258 mode, adjusted_mode);
255 adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal; 259 return true;
256 adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay; 260 }
257 adjusted_mode->vsync_start =
258 dev_priv->panel_fixed_mode->vsync_start;
259 adjusted_mode->vsync_end =
260 dev_priv->panel_fixed_mode->vsync_end;
261 adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal;
262 adjusted_mode->clock = dev_priv->panel_fixed_mode->clock;
263 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
264 261
265 /* Make sure pre-965s set dither correctly */ 262 /* Make sure pre-965s set dither correctly */
266 if (!IS_I965G(dev)) { 263 if (!IS_I965G(dev)) {
@@ -273,10 +270,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
273 adjusted_mode->vdisplay == mode->vdisplay) 270 adjusted_mode->vdisplay == mode->vdisplay)
274 goto out; 271 goto out;
275 272
276 /* full screen scale for now */
277 if (HAS_PCH_SPLIT(dev))
278 goto out;
279
280 /* 965+ wants fuzzy fitting */ 273 /* 965+ wants fuzzy fitting */
281 if (IS_I965G(dev)) 274 if (IS_I965G(dev))
282 pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | 275 pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
@@ -288,12 +281,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
288 * to register description and PRM. 281 * to register description and PRM.
289 * Change the value here to see the borders for debugging 282 * Change the value here to see the borders for debugging
290 */ 283 */
291 if (!HAS_PCH_SPLIT(dev)) { 284 I915_WRITE(BCLRPAT_A, 0);
292 I915_WRITE(BCLRPAT_A, 0); 285 I915_WRITE(BCLRPAT_B, 0);
293 I915_WRITE(BCLRPAT_B, 0);
294 }
295 286
296 switch (lvds_priv->fitting_mode) { 287 switch (intel_lvds->fitting_mode) {
297 case DRM_MODE_SCALE_CENTER: 288 case DRM_MODE_SCALE_CENTER:
298 /* 289 /*
299 * For centered modes, we have to calculate border widths & 290 * For centered modes, we have to calculate border widths &
@@ -378,8 +369,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
378 } 369 }
379 370
380out: 371out:
381 lvds_priv->pfit_control = pfit_control; 372 intel_lvds->pfit_control = pfit_control;
382 lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; 373 intel_lvds->pfit_pgm_ratios = pfit_pgm_ratios;
383 dev_priv->lvds_border_bits = border; 374 dev_priv->lvds_border_bits = border;
384 375
385 /* 376 /*
@@ -427,8 +418,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
427{ 418{
428 struct drm_device *dev = encoder->dev; 419 struct drm_device *dev = encoder->dev;
429 struct drm_i915_private *dev_priv = dev->dev_private; 420 struct drm_i915_private *dev_priv = dev->dev_private;
430 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); 421 struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder);
431 struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
432 422
433 /* 423 /*
434 * The LVDS pin pair will already have been turned on in the 424 * The LVDS pin pair will already have been turned on in the
@@ -444,8 +434,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
444 * screen. Should be enabled before the pipe is enabled, according to 434 * screen. Should be enabled before the pipe is enabled, according to
445 * register description and PRM. 435 * register description and PRM.
446 */ 436 */
447 I915_WRITE(PFIT_PGM_RATIOS, lvds_priv->pfit_pgm_ratios); 437 I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
448 I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control); 438 I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
449} 439}
450 440
451/** 441/**
@@ -455,7 +445,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
455 * connected and closed means disconnected. We also send hotplug events as 445 * connected and closed means disconnected. We also send hotplug events as
456 * needed, using lid status notification from the input layer. 446 * needed, using lid status notification from the input layer.
457 */ 447 */
458static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector) 448static enum drm_connector_status
449intel_lvds_detect(struct drm_connector *connector, bool force)
459{ 450{
460 struct drm_device *dev = connector->dev; 451 struct drm_device *dev = connector->dev;
461 enum drm_connector_status status = connector_status_connected; 452 enum drm_connector_status status = connector_status_connected;
@@ -550,7 +541,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
550 * the LID nofication event. 541 * the LID nofication event.
551 */ 542 */
552 if (connector) 543 if (connector)
553 connector->status = connector->funcs->detect(connector); 544 connector->status = connector->funcs->detect(connector,
545 false);
546
554 /* Don't force modeset on machines where it causes a GPU lockup */ 547 /* Don't force modeset on machines where it causes a GPU lockup */
555 if (dmi_check_system(intel_no_modeset_on_lid)) 548 if (dmi_check_system(intel_no_modeset_on_lid))
556 return NOTIFY_OK; 549 return NOTIFY_OK;
@@ -600,18 +593,17 @@ static int intel_lvds_set_property(struct drm_connector *connector,
600 connector->encoder) { 593 connector->encoder) {
601 struct drm_crtc *crtc = connector->encoder->crtc; 594 struct drm_crtc *crtc = connector->encoder->crtc;
602 struct drm_encoder *encoder = connector->encoder; 595 struct drm_encoder *encoder = connector->encoder;
603 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); 596 struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder);
604 struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
605 597
606 if (value == DRM_MODE_SCALE_NONE) { 598 if (value == DRM_MODE_SCALE_NONE) {
607 DRM_DEBUG_KMS("no scaling not supported\n"); 599 DRM_DEBUG_KMS("no scaling not supported\n");
608 return 0; 600 return 0;
609 } 601 }
610 if (lvds_priv->fitting_mode == value) { 602 if (intel_lvds->fitting_mode == value) {
611 /* the LVDS scaling property is not changed */ 603 /* the LVDS scaling property is not changed */
612 return 0; 604 return 0;
613 } 605 }
614 lvds_priv->fitting_mode = value; 606 intel_lvds->fitting_mode = value;
615 if (crtc && crtc->enabled) { 607 if (crtc && crtc->enabled) {
616 /* 608 /*
617 * If the CRTC is enabled, the display will be changed 609 * If the CRTC is enabled, the display will be changed
@@ -647,19 +639,8 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
647 .destroy = intel_lvds_destroy, 639 .destroy = intel_lvds_destroy,
648}; 640};
649 641
650
651static void intel_lvds_enc_destroy(struct drm_encoder *encoder)
652{
653 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
654
655 if (intel_encoder->ddc_bus)
656 intel_i2c_destroy(intel_encoder->ddc_bus);
657 drm_encoder_cleanup(encoder);
658 kfree(intel_encoder);
659}
660
661static const struct drm_encoder_funcs intel_lvds_enc_funcs = { 642static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
662 .destroy = intel_lvds_enc_destroy, 643 .destroy = intel_encoder_destroy,
663}; 644};
664 645
665static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) 646static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
@@ -843,13 +824,13 @@ static int lvds_is_present_in_vbt(struct drm_device *dev)
843void intel_lvds_init(struct drm_device *dev) 824void intel_lvds_init(struct drm_device *dev)
844{ 825{
845 struct drm_i915_private *dev_priv = dev->dev_private; 826 struct drm_i915_private *dev_priv = dev->dev_private;
827 struct intel_lvds *intel_lvds;
846 struct intel_encoder *intel_encoder; 828 struct intel_encoder *intel_encoder;
847 struct intel_connector *intel_connector; 829 struct intel_connector *intel_connector;
848 struct drm_connector *connector; 830 struct drm_connector *connector;
849 struct drm_encoder *encoder; 831 struct drm_encoder *encoder;
850 struct drm_display_mode *scan; /* *modes, *bios_mode; */ 832 struct drm_display_mode *scan; /* *modes, *bios_mode; */
851 struct drm_crtc *crtc; 833 struct drm_crtc *crtc;
852 struct intel_lvds_priv *lvds_priv;
853 u32 lvds; 834 u32 lvds;
854 int pipe, gpio = GPIOC; 835 int pipe, gpio = GPIOC;
855 836
@@ -872,20 +853,20 @@ void intel_lvds_init(struct drm_device *dev)
872 gpio = PCH_GPIOC; 853 gpio = PCH_GPIOC;
873 } 854 }
874 855
875 intel_encoder = kzalloc(sizeof(struct intel_encoder) + 856 intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL);
876 sizeof(struct intel_lvds_priv), GFP_KERNEL); 857 if (!intel_lvds) {
877 if (!intel_encoder) {
878 return; 858 return;
879 } 859 }
880 860
881 intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); 861 intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
882 if (!intel_connector) { 862 if (!intel_connector) {
883 kfree(intel_encoder); 863 kfree(intel_lvds);
884 return; 864 return;
885 } 865 }
886 866
887 connector = &intel_connector->base; 867 intel_encoder = &intel_lvds->base;
888 encoder = &intel_encoder->enc; 868 encoder = &intel_encoder->enc;
869 connector = &intel_connector->base;
889 drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, 870 drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs,
890 DRM_MODE_CONNECTOR_LVDS); 871 DRM_MODE_CONNECTOR_LVDS);
891 872
@@ -897,16 +878,12 @@ void intel_lvds_init(struct drm_device *dev)
897 878
898 intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); 879 intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
899 intel_encoder->crtc_mask = (1 << 1); 880 intel_encoder->crtc_mask = (1 << 1);
900 if (IS_I965G(dev))
901 intel_encoder->crtc_mask |= (1 << 0);
902 drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); 881 drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
903 drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); 882 drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
904 connector->display_info.subpixel_order = SubPixelHorizontalRGB; 883 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
905 connector->interlace_allowed = false; 884 connector->interlace_allowed = false;
906 connector->doublescan_allowed = false; 885 connector->doublescan_allowed = false;
907 886
908 lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1);
909 intel_encoder->dev_priv = lvds_priv;
910 /* create the scaling mode property */ 887 /* create the scaling mode property */
911 drm_mode_create_scaling_mode_property(dev); 888 drm_mode_create_scaling_mode_property(dev);
912 /* 889 /*
@@ -916,7 +893,7 @@ void intel_lvds_init(struct drm_device *dev)
916 drm_connector_attach_property(&intel_connector->base, 893 drm_connector_attach_property(&intel_connector->base,
917 dev->mode_config.scaling_mode_property, 894 dev->mode_config.scaling_mode_property,
918 DRM_MODE_SCALE_ASPECT); 895 DRM_MODE_SCALE_ASPECT);
919 lvds_priv->fitting_mode = DRM_MODE_SCALE_ASPECT; 896 intel_lvds->fitting_mode = DRM_MODE_SCALE_ASPECT;
920 /* 897 /*
921 * LVDS discovery: 898 * LVDS discovery:
922 * 1) check for EDID on DDC 899 * 1) check for EDID on DDC
@@ -1024,6 +1001,6 @@ failed:
1024 intel_i2c_destroy(intel_encoder->ddc_bus); 1001 intel_i2c_destroy(intel_encoder->ddc_bus);
1025 drm_connector_cleanup(connector); 1002 drm_connector_cleanup(connector);
1026 drm_encoder_cleanup(encoder); 1003 drm_encoder_cleanup(encoder);
1027 kfree(intel_encoder); 1004 kfree(intel_lvds);
1028 kfree(intel_connector); 1005 kfree(intel_connector);
1029} 1006}