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.c111
1 files changed, 27 insertions, 84 deletions
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index b66806a37d37..6a1accd83aec 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -139,75 +139,6 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode)
139 /* XXX: We never power down the LVDS pairs. */ 139 /* XXX: We never power down the LVDS pairs. */
140} 140}
141 141
142static void intel_lvds_save(struct drm_connector *connector)
143{
144 struct drm_device *dev = connector->dev;
145 struct drm_i915_private *dev_priv = dev->dev_private;
146 u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg;
147 u32 pwm_ctl_reg;
148
149 if (HAS_PCH_SPLIT(dev)) {
150 pp_on_reg = PCH_PP_ON_DELAYS;
151 pp_off_reg = PCH_PP_OFF_DELAYS;
152 pp_ctl_reg = PCH_PP_CONTROL;
153 pp_div_reg = PCH_PP_DIVISOR;
154 pwm_ctl_reg = BLC_PWM_CPU_CTL;
155 } else {
156 pp_on_reg = PP_ON_DELAYS;
157 pp_off_reg = PP_OFF_DELAYS;
158 pp_ctl_reg = PP_CONTROL;
159 pp_div_reg = PP_DIVISOR;
160 pwm_ctl_reg = BLC_PWM_CTL;
161 }
162
163 dev_priv->savePP_ON = I915_READ(pp_on_reg);
164 dev_priv->savePP_OFF = I915_READ(pp_off_reg);
165 dev_priv->savePP_CONTROL = I915_READ(pp_ctl_reg);
166 dev_priv->savePP_DIVISOR = I915_READ(pp_div_reg);
167 dev_priv->saveBLC_PWM_CTL = I915_READ(pwm_ctl_reg);
168 dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
169 BACKLIGHT_DUTY_CYCLE_MASK);
170
171 /*
172 * If the light is off at server startup, just make it full brightness
173 */
174 if (dev_priv->backlight_duty_cycle == 0)
175 dev_priv->backlight_duty_cycle =
176 intel_lvds_get_max_backlight(dev);
177}
178
179static void intel_lvds_restore(struct drm_connector *connector)
180{
181 struct drm_device *dev = connector->dev;
182 struct drm_i915_private *dev_priv = dev->dev_private;
183 u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg;
184 u32 pwm_ctl_reg;
185
186 if (HAS_PCH_SPLIT(dev)) {
187 pp_on_reg = PCH_PP_ON_DELAYS;
188 pp_off_reg = PCH_PP_OFF_DELAYS;
189 pp_ctl_reg = PCH_PP_CONTROL;
190 pp_div_reg = PCH_PP_DIVISOR;
191 pwm_ctl_reg = BLC_PWM_CPU_CTL;
192 } else {
193 pp_on_reg = PP_ON_DELAYS;
194 pp_off_reg = PP_OFF_DELAYS;
195 pp_ctl_reg = PP_CONTROL;
196 pp_div_reg = PP_DIVISOR;
197 pwm_ctl_reg = BLC_PWM_CTL;
198 }
199
200 I915_WRITE(pwm_ctl_reg, dev_priv->saveBLC_PWM_CTL);
201 I915_WRITE(pp_on_reg, dev_priv->savePP_ON);
202 I915_WRITE(pp_off_reg, dev_priv->savePP_OFF);
203 I915_WRITE(pp_div_reg, dev_priv->savePP_DIVISOR);
204 I915_WRITE(pp_ctl_reg, dev_priv->savePP_CONTROL);
205 if (dev_priv->savePP_CONTROL & POWER_TARGET_ON)
206 intel_lvds_set_power(dev, true);
207 else
208 intel_lvds_set_power(dev, false);
209}
210
211static int intel_lvds_mode_valid(struct drm_connector *connector, 142static int intel_lvds_mode_valid(struct drm_connector *connector,
212 struct drm_display_mode *mode) 143 struct drm_display_mode *mode)
213{ 144{
@@ -635,12 +566,13 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect
635static int intel_lvds_get_modes(struct drm_connector *connector) 566static int intel_lvds_get_modes(struct drm_connector *connector)
636{ 567{
637 struct drm_device *dev = connector->dev; 568 struct drm_device *dev = connector->dev;
638 struct intel_encoder *intel_encoder = to_intel_encoder(connector); 569 struct drm_encoder *encoder = intel_attached_encoder(connector);
570 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
639 struct drm_i915_private *dev_priv = dev->dev_private; 571 struct drm_i915_private *dev_priv = dev->dev_private;
640 int ret = 0; 572 int ret = 0;
641 573
642 if (dev_priv->lvds_edid_good) { 574 if (dev_priv->lvds_edid_good) {
643 ret = intel_ddc_get_modes(intel_encoder); 575 ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
644 576
645 if (ret) 577 if (ret)
646 return ret; 578 return ret;
@@ -717,11 +649,8 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
717static void intel_lvds_destroy(struct drm_connector *connector) 649static void intel_lvds_destroy(struct drm_connector *connector)
718{ 650{
719 struct drm_device *dev = connector->dev; 651 struct drm_device *dev = connector->dev;
720 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
721 struct drm_i915_private *dev_priv = dev->dev_private; 652 struct drm_i915_private *dev_priv = dev->dev_private;
722 653
723 if (intel_encoder->ddc_bus)
724 intel_i2c_destroy(intel_encoder->ddc_bus);
725 if (dev_priv->lid_notifier.notifier_call) 654 if (dev_priv->lid_notifier.notifier_call)
726 acpi_lid_notifier_unregister(&dev_priv->lid_notifier); 655 acpi_lid_notifier_unregister(&dev_priv->lid_notifier);
727 drm_sysfs_connector_remove(connector); 656 drm_sysfs_connector_remove(connector);
@@ -734,13 +663,14 @@ static int intel_lvds_set_property(struct drm_connector *connector,
734 uint64_t value) 663 uint64_t value)
735{ 664{
736 struct drm_device *dev = connector->dev; 665 struct drm_device *dev = connector->dev;
737 struct intel_encoder *intel_encoder =
738 to_intel_encoder(connector);
739 666
740 if (property == dev->mode_config.scaling_mode_property && 667 if (property == dev->mode_config.scaling_mode_property &&
741 connector->encoder) { 668 connector->encoder) {
742 struct drm_crtc *crtc = connector->encoder->crtc; 669 struct drm_crtc *crtc = connector->encoder->crtc;
670 struct drm_encoder *encoder = connector->encoder;
671 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
743 struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; 672 struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
673
744 if (value == DRM_MODE_SCALE_NONE) { 674 if (value == DRM_MODE_SCALE_NONE) {
745 DRM_DEBUG_KMS("no scaling not supported\n"); 675 DRM_DEBUG_KMS("no scaling not supported\n");
746 return 0; 676 return 0;
@@ -774,13 +704,11 @@ static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
774static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { 704static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
775 .get_modes = intel_lvds_get_modes, 705 .get_modes = intel_lvds_get_modes,
776 .mode_valid = intel_lvds_mode_valid, 706 .mode_valid = intel_lvds_mode_valid,
777 .best_encoder = intel_best_encoder, 707 .best_encoder = intel_attached_encoder,
778}; 708};
779 709
780static const struct drm_connector_funcs intel_lvds_connector_funcs = { 710static const struct drm_connector_funcs intel_lvds_connector_funcs = {
781 .dpms = drm_helper_connector_dpms, 711 .dpms = drm_helper_connector_dpms,
782 .save = intel_lvds_save,
783 .restore = intel_lvds_restore,
784 .detect = intel_lvds_detect, 712 .detect = intel_lvds_detect,
785 .fill_modes = drm_helper_probe_single_connector_modes, 713 .fill_modes = drm_helper_probe_single_connector_modes,
786 .set_property = intel_lvds_set_property, 714 .set_property = intel_lvds_set_property,
@@ -790,7 +718,12 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
790 718
791static void intel_lvds_enc_destroy(struct drm_encoder *encoder) 719static void intel_lvds_enc_destroy(struct drm_encoder *encoder)
792{ 720{
721 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
722
723 if (intel_encoder->ddc_bus)
724 intel_i2c_destroy(intel_encoder->ddc_bus);
793 drm_encoder_cleanup(encoder); 725 drm_encoder_cleanup(encoder);
726 kfree(intel_encoder);
794} 727}
795 728
796static const struct drm_encoder_funcs intel_lvds_enc_funcs = { 729static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
@@ -979,6 +912,7 @@ void intel_lvds_init(struct drm_device *dev)
979{ 912{
980 struct drm_i915_private *dev_priv = dev->dev_private; 913 struct drm_i915_private *dev_priv = dev->dev_private;
981 struct intel_encoder *intel_encoder; 914 struct intel_encoder *intel_encoder;
915 struct intel_connector *intel_connector;
982 struct drm_connector *connector; 916 struct drm_connector *connector;
983 struct drm_encoder *encoder; 917 struct drm_encoder *encoder;
984 struct drm_display_mode *scan; /* *modes, *bios_mode; */ 918 struct drm_display_mode *scan; /* *modes, *bios_mode; */
@@ -1012,19 +946,27 @@ void intel_lvds_init(struct drm_device *dev)
1012 return; 946 return;
1013 } 947 }
1014 948
1015 connector = &intel_encoder->base; 949 intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
950 if (!intel_connector) {
951 kfree(intel_encoder);
952 return;
953 }
954
955 connector = &intel_connector->base;
1016 encoder = &intel_encoder->enc; 956 encoder = &intel_encoder->enc;
1017 drm_connector_init(dev, &intel_encoder->base, &intel_lvds_connector_funcs, 957 drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs,
1018 DRM_MODE_CONNECTOR_LVDS); 958 DRM_MODE_CONNECTOR_LVDS);
1019 959
1020 drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs, 960 drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs,
1021 DRM_MODE_ENCODER_LVDS); 961 DRM_MODE_ENCODER_LVDS);
1022 962
1023 drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); 963 drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc);
1024 intel_encoder->type = INTEL_OUTPUT_LVDS; 964 intel_encoder->type = INTEL_OUTPUT_LVDS;
1025 965
1026 intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); 966 intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
1027 intel_encoder->crtc_mask = (1 << 1); 967 intel_encoder->crtc_mask = (1 << 1);
968 if (IS_I965G(dev))
969 intel_encoder->crtc_mask |= (1 << 0);
1028 drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); 970 drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
1029 drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); 971 drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
1030 connector->display_info.subpixel_order = SubPixelHorizontalRGB; 972 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
@@ -1039,7 +981,7 @@ void intel_lvds_init(struct drm_device *dev)
1039 * the initial panel fitting mode will be FULL_SCREEN. 981 * the initial panel fitting mode will be FULL_SCREEN.
1040 */ 982 */
1041 983
1042 drm_connector_attach_property(&intel_encoder->base, 984 drm_connector_attach_property(&intel_connector->base,
1043 dev->mode_config.scaling_mode_property, 985 dev->mode_config.scaling_mode_property,
1044 DRM_MODE_SCALE_FULLSCREEN); 986 DRM_MODE_SCALE_FULLSCREEN);
1045 lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; 987 lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN;
@@ -1067,7 +1009,7 @@ void intel_lvds_init(struct drm_device *dev)
1067 */ 1009 */
1068 dev_priv->lvds_edid_good = true; 1010 dev_priv->lvds_edid_good = true;
1069 1011
1070 if (!intel_ddc_get_modes(intel_encoder)) 1012 if (!intel_ddc_get_modes(connector, intel_encoder->ddc_bus))
1071 dev_priv->lvds_edid_good = false; 1013 dev_priv->lvds_edid_good = false;
1072 1014
1073 list_for_each_entry(scan, &connector->probed_modes, head) { 1015 list_for_each_entry(scan, &connector->probed_modes, head) {
@@ -1151,4 +1093,5 @@ failed:
1151 drm_connector_cleanup(connector); 1093 drm_connector_cleanup(connector);
1152 drm_encoder_cleanup(encoder); 1094 drm_encoder_cleanup(encoder);
1153 kfree(intel_encoder); 1095 kfree(intel_encoder);
1096 kfree(intel_connector);
1154} 1097}