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.c133
1 files changed, 75 insertions, 58 deletions
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index f1a649990ea9..25bcedf386fd 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -68,7 +68,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector)
68/** 68/**
69 * Sets the power state for the panel. 69 * Sets the power state for the panel.
70 */ 70 */
71static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) 71static void intel_lvds_enable(struct intel_lvds *intel_lvds)
72{ 72{
73 struct drm_device *dev = intel_lvds->base.base.dev; 73 struct drm_device *dev = intel_lvds->base.base.dev;
74 struct drm_i915_private *dev_priv = dev->dev_private; 74 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -82,26 +82,61 @@ static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on)
82 lvds_reg = LVDS; 82 lvds_reg = LVDS;
83 } 83 }
84 84
85 if (on) { 85 I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
86 I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
87 I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
88 intel_panel_set_backlight(dev, dev_priv->backlight_level);
89 } else {
90 dev_priv->backlight_level = intel_panel_get_backlight(dev);
91
92 intel_panel_set_backlight(dev, 0);
93 I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
94 86
95 if (intel_lvds->pfit_control) { 87 if (intel_lvds->pfit_dirty) {
96 if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) 88 /*
97 DRM_ERROR("timed out waiting for panel to power off\n"); 89 * Enable automatic panel scaling so that non-native modes
98 I915_WRITE(PFIT_CONTROL, 0); 90 * fill the screen. The panel fitter should only be
99 intel_lvds->pfit_control = 0; 91 * adjusted whilst the pipe is disabled, according to
92 * register description and PRM.
93 */
94 DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
95 intel_lvds->pfit_control,
96 intel_lvds->pfit_pgm_ratios);
97 if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) {
98 DRM_ERROR("timed out waiting for panel to power off\n");
99 } else {
100 I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
101 I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
100 intel_lvds->pfit_dirty = false; 102 intel_lvds->pfit_dirty = false;
101 } 103 }
104 }
105
106 I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
107 POSTING_READ(lvds_reg);
108
109 intel_panel_set_backlight(dev, dev_priv->backlight_level);
110}
111
112static void intel_lvds_disable(struct intel_lvds *intel_lvds)
113{
114 struct drm_device *dev = intel_lvds->base.base.dev;
115 struct drm_i915_private *dev_priv = dev->dev_private;
116 u32 ctl_reg, lvds_reg;
117
118 if (HAS_PCH_SPLIT(dev)) {
119 ctl_reg = PCH_PP_CONTROL;
120 lvds_reg = PCH_LVDS;
121 } else {
122 ctl_reg = PP_CONTROL;
123 lvds_reg = LVDS;
124 }
125
126 dev_priv->backlight_level = intel_panel_get_backlight(dev);
127 intel_panel_set_backlight(dev, 0);
102 128
103 I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); 129 I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
130
131 if (intel_lvds->pfit_control) {
132 if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
133 DRM_ERROR("timed out waiting for panel to power off\n");
134
135 I915_WRITE(PFIT_CONTROL, 0);
136 intel_lvds->pfit_dirty = true;
104 } 137 }
138
139 I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN);
105 POSTING_READ(lvds_reg); 140 POSTING_READ(lvds_reg);
106} 141}
107 142
@@ -110,9 +145,9 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode)
110 struct intel_lvds *intel_lvds = to_intel_lvds(encoder); 145 struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
111 146
112 if (mode == DRM_MODE_DPMS_ON) 147 if (mode == DRM_MODE_DPMS_ON)
113 intel_lvds_set_power(intel_lvds, true); 148 intel_lvds_enable(intel_lvds);
114 else 149 else
115 intel_lvds_set_power(intel_lvds, false); 150 intel_lvds_disable(intel_lvds);
116 151
117 /* XXX: We never power down the LVDS pairs. */ 152 /* XXX: We never power down the LVDS pairs. */
118} 153}
@@ -411,43 +446,18 @@ static void intel_lvds_commit(struct drm_encoder *encoder)
411 /* Always do a full power on as we do not know what state 446 /* Always do a full power on as we do not know what state
412 * we were left in. 447 * we were left in.
413 */ 448 */
414 intel_lvds_set_power(intel_lvds, true); 449 intel_lvds_enable(intel_lvds);
415} 450}
416 451
417static void intel_lvds_mode_set(struct drm_encoder *encoder, 452static void intel_lvds_mode_set(struct drm_encoder *encoder,
418 struct drm_display_mode *mode, 453 struct drm_display_mode *mode,
419 struct drm_display_mode *adjusted_mode) 454 struct drm_display_mode *adjusted_mode)
420{ 455{
421 struct drm_device *dev = encoder->dev;
422 struct drm_i915_private *dev_priv = dev->dev_private;
423 struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
424
425 /* 456 /*
426 * The LVDS pin pair will already have been turned on in the 457 * The LVDS pin pair will already have been turned on in the
427 * intel_crtc_mode_set since it has a large impact on the DPLL 458 * intel_crtc_mode_set since it has a large impact on the DPLL
428 * settings. 459 * settings.
429 */ 460 */
430
431 if (HAS_PCH_SPLIT(dev))
432 return;
433
434 if (!intel_lvds->pfit_dirty)
435 return;
436
437 /*
438 * Enable automatic panel scaling so that non-native modes fill the
439 * screen. Should be enabled before the pipe is enabled, according to
440 * register description and PRM.
441 */
442 DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
443 intel_lvds->pfit_control,
444 intel_lvds->pfit_pgm_ratios);
445 if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
446 DRM_ERROR("timed out waiting for panel to power off\n");
447
448 I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
449 I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
450 intel_lvds->pfit_dirty = false;
451} 461}
452 462
453/** 463/**
@@ -481,11 +491,8 @@ static int intel_lvds_get_modes(struct drm_connector *connector)
481 struct drm_device *dev = connector->dev; 491 struct drm_device *dev = connector->dev;
482 struct drm_display_mode *mode; 492 struct drm_display_mode *mode;
483 493
484 if (intel_lvds->edid) { 494 if (intel_lvds->edid)
485 drm_mode_connector_update_edid_property(connector,
486 intel_lvds->edid);
487 return drm_add_edid_modes(connector, intel_lvds->edid); 495 return drm_add_edid_modes(connector, intel_lvds->edid);
488 }
489 496
490 mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode); 497 mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode);
491 if (mode == 0) 498 if (mode == 0)
@@ -840,7 +847,7 @@ static bool intel_lvds_ddc_probe(struct drm_device *dev, u8 pin)
840 * Create the connector, register the LVDS DDC bus, and try to figure out what 847 * Create the connector, register the LVDS DDC bus, and try to figure out what
841 * modes we can display on the LVDS panel (if present). 848 * modes we can display on the LVDS panel (if present).
842 */ 849 */
843void intel_lvds_init(struct drm_device *dev) 850bool intel_lvds_init(struct drm_device *dev)
844{ 851{
845 struct drm_i915_private *dev_priv = dev->dev_private; 852 struct drm_i915_private *dev_priv = dev->dev_private;
846 struct intel_lvds *intel_lvds; 853 struct intel_lvds *intel_lvds;
@@ -856,37 +863,37 @@ void intel_lvds_init(struct drm_device *dev)
856 863
857 /* Skip init on machines we know falsely report LVDS */ 864 /* Skip init on machines we know falsely report LVDS */
858 if (dmi_check_system(intel_no_lvds)) 865 if (dmi_check_system(intel_no_lvds))
859 return; 866 return false;
860 867
861 pin = GMBUS_PORT_PANEL; 868 pin = GMBUS_PORT_PANEL;
862 if (!lvds_is_present_in_vbt(dev, &pin)) { 869 if (!lvds_is_present_in_vbt(dev, &pin)) {
863 DRM_DEBUG_KMS("LVDS is not present in VBT\n"); 870 DRM_DEBUG_KMS("LVDS is not present in VBT\n");
864 return; 871 return false;
865 } 872 }
866 873
867 if (HAS_PCH_SPLIT(dev)) { 874 if (HAS_PCH_SPLIT(dev)) {
868 if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) 875 if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
869 return; 876 return false;
870 if (dev_priv->edp.support) { 877 if (dev_priv->edp.support) {
871 DRM_DEBUG_KMS("disable LVDS for eDP support\n"); 878 DRM_DEBUG_KMS("disable LVDS for eDP support\n");
872 return; 879 return false;
873 } 880 }
874 } 881 }
875 882
876 if (!intel_lvds_ddc_probe(dev, pin)) { 883 if (!intel_lvds_ddc_probe(dev, pin)) {
877 DRM_DEBUG_KMS("LVDS did not respond to DDC probe\n"); 884 DRM_DEBUG_KMS("LVDS did not respond to DDC probe\n");
878 return; 885 return false;
879 } 886 }
880 887
881 intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL); 888 intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL);
882 if (!intel_lvds) { 889 if (!intel_lvds) {
883 return; 890 return false;
884 } 891 }
885 892
886 intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); 893 intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
887 if (!intel_connector) { 894 if (!intel_connector) {
888 kfree(intel_lvds); 895 kfree(intel_lvds);
889 return; 896 return false;
890 } 897 }
891 898
892 if (!HAS_PCH_SPLIT(dev)) { 899 if (!HAS_PCH_SPLIT(dev)) {
@@ -939,7 +946,16 @@ void intel_lvds_init(struct drm_device *dev)
939 */ 946 */
940 intel_lvds->edid = drm_get_edid(connector, 947 intel_lvds->edid = drm_get_edid(connector,
941 &dev_priv->gmbus[pin].adapter); 948 &dev_priv->gmbus[pin].adapter);
942 949 if (intel_lvds->edid) {
950 if (drm_add_edid_modes(connector,
951 intel_lvds->edid)) {
952 drm_mode_connector_update_edid_property(connector,
953 intel_lvds->edid);
954 } else {
955 kfree(intel_lvds->edid);
956 intel_lvds->edid = NULL;
957 }
958 }
943 if (!intel_lvds->edid) { 959 if (!intel_lvds->edid) {
944 /* Didn't get an EDID, so 960 /* Didn't get an EDID, so
945 * Set wide sync ranges so we get all modes 961 * Set wide sync ranges so we get all modes
@@ -1020,7 +1036,7 @@ out:
1020 /* keep the LVDS connector */ 1036 /* keep the LVDS connector */
1021 dev_priv->int_lvds_connector = connector; 1037 dev_priv->int_lvds_connector = connector;
1022 drm_sysfs_connector_add(connector); 1038 drm_sysfs_connector_add(connector);
1023 return; 1039 return true;
1024 1040
1025failed: 1041failed:
1026 DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); 1042 DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
@@ -1028,4 +1044,5 @@ failed:
1028 drm_encoder_cleanup(encoder); 1044 drm_encoder_cleanup(encoder);
1029 kfree(intel_lvds); 1045 kfree(intel_lvds);
1030 kfree(intel_connector); 1046 kfree(intel_connector);
1047 return false;
1031} 1048}