Subversion Repositories Kolibri OS

Rev

Rev 6937 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6937 Rev 7144
1
/*
1
/*
2
 * Copyright © 2006-2007 Intel Corporation
2
 * Copyright © 2006-2007 Intel Corporation
3
 * Copyright (c) 2006 Dave Airlie 
3
 * Copyright (c) 2006 Dave Airlie 
4
 *
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * copy of this software and associated documentation files (the "Software"),
6
 * copy of this software and associated documentation files (the "Software"),
7
 * to deal in the Software without restriction, including without limitation
7
 * to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following conditions:
10
 * Software is furnished to do so, subject to the following conditions:
11
 *
11
 *
12
 * The above copyright notice and this permission notice (including the next
12
 * The above copyright notice and this permission notice (including the next
13
 * paragraph) shall be included in all copies or substantial portions of the
13
 * paragraph) shall be included in all copies or substantial portions of the
14
 * Software.
14
 * Software.
15
 *
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
22
 * DEALINGS IN THE SOFTWARE.
23
 *
23
 *
24
 * Authors:
24
 * Authors:
25
 *	Eric Anholt 
25
 *	Eric Anholt 
26
 *      Dave Airlie 
26
 *      Dave Airlie 
27
 *      Jesse Barnes 
27
 *      Jesse Barnes 
28
 */
28
 */
29
 
29
 
30
//#include 
30
//#include 
31
#include 
31
#include 
32
#include 
32
#include 
33
#include 
33
#include 
-
 
34
#include 
34
#include 
35
#include 
35
#include 
36
#include 
36
#include 
37
#include 
37
#include 
38
#include 
38
#include "intel_drv.h"
39
#include "intel_drv.h"
39
#include 
40
#include 
40
#include "i915_drv.h"
41
#include "i915_drv.h"
41
#include 
42
#include 
42
 
43
 
43
/* Private structure for the integrated LVDS support */
44
/* Private structure for the integrated LVDS support */
44
struct intel_lvds_connector {
45
struct intel_lvds_connector {
45
	struct intel_connector base;
46
	struct intel_connector base;
46
 
47
 
47
	struct notifier_block lid_notifier;
48
	struct notifier_block lid_notifier;
48
};
49
};
49
 
50
 
50
struct intel_lvds_encoder {
51
struct intel_lvds_encoder {
51
	struct intel_encoder base;
52
	struct intel_encoder base;
52
 
53
 
53
	bool is_dual_link;
54
	bool is_dual_link;
54
	i915_reg_t reg;
55
	i915_reg_t reg;
55
	u32 a3_power;
56
	u32 a3_power;
56
 
57
 
57
	struct intel_lvds_connector *attached_connector;
58
	struct intel_lvds_connector *attached_connector;
58
};
59
};
59
 
60
 
60
static struct intel_lvds_encoder *to_lvds_encoder(struct drm_encoder *encoder)
61
static struct intel_lvds_encoder *to_lvds_encoder(struct drm_encoder *encoder)
61
{
62
{
62
	return container_of(encoder, struct intel_lvds_encoder, base.base);
63
	return container_of(encoder, struct intel_lvds_encoder, base.base);
63
}
64
}
64
 
65
 
65
static struct intel_lvds_connector *to_lvds_connector(struct drm_connector *connector)
66
static struct intel_lvds_connector *to_lvds_connector(struct drm_connector *connector)
66
{
67
{
67
	return container_of(connector, struct intel_lvds_connector, base.base);
68
	return container_of(connector, struct intel_lvds_connector, base.base);
68
}
69
}
69
 
70
 
70
static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
71
static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
71
				    enum pipe *pipe)
72
				    enum pipe *pipe)
72
{
73
{
73
	struct drm_device *dev = encoder->base.dev;
74
	struct drm_device *dev = encoder->base.dev;
74
	struct drm_i915_private *dev_priv = dev->dev_private;
75
	struct drm_i915_private *dev_priv = dev->dev_private;
75
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
76
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
76
	enum intel_display_power_domain power_domain;
77
	enum intel_display_power_domain power_domain;
77
	u32 tmp;
78
	u32 tmp;
78
	bool ret;
79
	bool ret;
79
 
80
 
80
	power_domain = intel_display_port_power_domain(encoder);
81
	power_domain = intel_display_port_power_domain(encoder);
81
	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
82
	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
82
		return false;
83
		return false;
83
 
84
 
84
	ret = false;
85
	ret = false;
85
 
86
 
86
	tmp = I915_READ(lvds_encoder->reg);
87
	tmp = I915_READ(lvds_encoder->reg);
87
 
88
 
88
	if (!(tmp & LVDS_PORT_EN))
89
	if (!(tmp & LVDS_PORT_EN))
89
		goto out;
90
		goto out;
90
 
91
 
91
	if (HAS_PCH_CPT(dev))
92
	if (HAS_PCH_CPT(dev))
92
		*pipe = PORT_TO_PIPE_CPT(tmp);
93
		*pipe = PORT_TO_PIPE_CPT(tmp);
93
	else
94
	else
94
		*pipe = PORT_TO_PIPE(tmp);
95
		*pipe = PORT_TO_PIPE(tmp);
95
 
96
 
96
	ret = true;
97
	ret = true;
97
 
98
 
98
out:
99
out:
99
	intel_display_power_put(dev_priv, power_domain);
100
	intel_display_power_put(dev_priv, power_domain);
100
 
101
 
101
	return ret;
102
	return ret;
102
}
103
}
103
 
104
 
104
static void intel_lvds_get_config(struct intel_encoder *encoder,
105
static void intel_lvds_get_config(struct intel_encoder *encoder,
105
				  struct intel_crtc_state *pipe_config)
106
				  struct intel_crtc_state *pipe_config)
106
{
107
{
107
	struct drm_device *dev = encoder->base.dev;
108
	struct drm_device *dev = encoder->base.dev;
108
	struct drm_i915_private *dev_priv = dev->dev_private;
109
	struct drm_i915_private *dev_priv = dev->dev_private;
109
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
110
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
110
	u32 tmp, flags = 0;
111
	u32 tmp, flags = 0;
111
	int dotclock;
112
	int dotclock;
112
 
113
 
113
	tmp = I915_READ(lvds_encoder->reg);
114
	tmp = I915_READ(lvds_encoder->reg);
114
	if (tmp & LVDS_HSYNC_POLARITY)
115
	if (tmp & LVDS_HSYNC_POLARITY)
115
		flags |= DRM_MODE_FLAG_NHSYNC;
116
		flags |= DRM_MODE_FLAG_NHSYNC;
116
	else
117
	else
117
		flags |= DRM_MODE_FLAG_PHSYNC;
118
		flags |= DRM_MODE_FLAG_PHSYNC;
118
	if (tmp & LVDS_VSYNC_POLARITY)
119
	if (tmp & LVDS_VSYNC_POLARITY)
119
		flags |= DRM_MODE_FLAG_NVSYNC;
120
		flags |= DRM_MODE_FLAG_NVSYNC;
120
	else
121
	else
121
		flags |= DRM_MODE_FLAG_PVSYNC;
122
		flags |= DRM_MODE_FLAG_PVSYNC;
122
 
123
 
123
	pipe_config->base.adjusted_mode.flags |= flags;
124
	pipe_config->base.adjusted_mode.flags |= flags;
-
 
125
 
-
 
126
	if (INTEL_INFO(dev)->gen < 5)
-
 
127
		pipe_config->gmch_pfit.lvds_border_bits =
-
 
128
			tmp & LVDS_BORDER_ENABLE;
124
 
129
 
125
	/* gen2/3 store dither state in pfit control, needs to match */
130
	/* gen2/3 store dither state in pfit control, needs to match */
126
	if (INTEL_INFO(dev)->gen < 4) {
131
	if (INTEL_INFO(dev)->gen < 4) {
127
		tmp = I915_READ(PFIT_CONTROL);
132
		tmp = I915_READ(PFIT_CONTROL);
128
 
133
 
129
		pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE;
134
		pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE;
130
	}
135
	}
131
 
136
 
132
	dotclock = pipe_config->port_clock;
137
	dotclock = pipe_config->port_clock;
133
 
138
 
134
	if (HAS_PCH_SPLIT(dev_priv->dev))
139
	if (HAS_PCH_SPLIT(dev_priv->dev))
135
		ironlake_check_encoder_dotclock(pipe_config, dotclock);
140
		ironlake_check_encoder_dotclock(pipe_config, dotclock);
136
 
141
 
137
	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
142
	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
138
}
143
}
139
 
144
 
140
static void intel_pre_enable_lvds(struct intel_encoder *encoder)
145
static void intel_pre_enable_lvds(struct intel_encoder *encoder)
141
{
146
{
142
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
147
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
143
	struct drm_device *dev = encoder->base.dev;
148
	struct drm_device *dev = encoder->base.dev;
144
	struct drm_i915_private *dev_priv = dev->dev_private;
149
	struct drm_i915_private *dev_priv = dev->dev_private;
145
	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
150
	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
146
	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
151
	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
147
	int pipe = crtc->pipe;
152
	int pipe = crtc->pipe;
148
	u32 temp;
153
	u32 temp;
149
 
154
 
150
	if (HAS_PCH_SPLIT(dev)) {
155
	if (HAS_PCH_SPLIT(dev)) {
151
		assert_fdi_rx_pll_disabled(dev_priv, pipe);
156
		assert_fdi_rx_pll_disabled(dev_priv, pipe);
152
		assert_shared_dpll_disabled(dev_priv,
157
		assert_shared_dpll_disabled(dev_priv,
153
					    intel_crtc_to_shared_dpll(crtc));
158
					    intel_crtc_to_shared_dpll(crtc));
154
	} else {
159
	} else {
155
		assert_pll_disabled(dev_priv, pipe);
160
		assert_pll_disabled(dev_priv, pipe);
156
	}
161
	}
157
 
162
 
158
	temp = I915_READ(lvds_encoder->reg);
163
	temp = I915_READ(lvds_encoder->reg);
159
	temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
164
	temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
160
 
165
 
161
	if (HAS_PCH_CPT(dev)) {
166
	if (HAS_PCH_CPT(dev)) {
162
		temp &= ~PORT_TRANS_SEL_MASK;
167
		temp &= ~PORT_TRANS_SEL_MASK;
163
		temp |= PORT_TRANS_SEL_CPT(pipe);
168
		temp |= PORT_TRANS_SEL_CPT(pipe);
164
	} else {
169
	} else {
165
		if (pipe == 1) {
170
		if (pipe == 1) {
166
			temp |= LVDS_PIPEB_SELECT;
171
			temp |= LVDS_PIPEB_SELECT;
167
		} else {
172
		} else {
168
			temp &= ~LVDS_PIPEB_SELECT;
173
			temp &= ~LVDS_PIPEB_SELECT;
169
		}
174
		}
170
	}
175
	}
171
 
176
 
172
	/* set the corresponsding LVDS_BORDER bit */
177
	/* set the corresponsding LVDS_BORDER bit */
173
	temp &= ~LVDS_BORDER_ENABLE;
178
	temp &= ~LVDS_BORDER_ENABLE;
174
	temp |= crtc->config->gmch_pfit.lvds_border_bits;
179
	temp |= crtc->config->gmch_pfit.lvds_border_bits;
175
	/* Set the B0-B3 data pairs corresponding to whether we're going to
180
	/* Set the B0-B3 data pairs corresponding to whether we're going to
176
	 * set the DPLLs for dual-channel mode or not.
181
	 * set the DPLLs for dual-channel mode or not.
177
	 */
182
	 */
178
	if (lvds_encoder->is_dual_link)
183
	if (lvds_encoder->is_dual_link)
179
		temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
184
		temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
180
	else
185
	else
181
		temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
186
		temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
182
 
187
 
183
	/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
188
	/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
184
	 * appropriately here, but we need to look more thoroughly into how
189
	 * appropriately here, but we need to look more thoroughly into how
185
	 * panels behave in the two modes. For now, let's just maintain the
190
	 * panels behave in the two modes. For now, let's just maintain the
186
	 * value we got from the BIOS.
191
	 * value we got from the BIOS.
187
	 */
192
	 */
188
	 temp &= ~LVDS_A3_POWER_MASK;
193
	 temp &= ~LVDS_A3_POWER_MASK;
189
	 temp |= lvds_encoder->a3_power;
194
	 temp |= lvds_encoder->a3_power;
190
 
195
 
191
	/* Set the dithering flag on LVDS as needed, note that there is no
196
	/* Set the dithering flag on LVDS as needed, note that there is no
192
	 * special lvds dither control bit on pch-split platforms, dithering is
197
	 * special lvds dither control bit on pch-split platforms, dithering is
193
	 * only controlled through the PIPECONF reg. */
198
	 * only controlled through the PIPECONF reg. */
194
	if (INTEL_INFO(dev)->gen == 4) {
199
	if (INTEL_INFO(dev)->gen == 4) {
195
		/* Bspec wording suggests that LVDS port dithering only exists
200
		/* Bspec wording suggests that LVDS port dithering only exists
196
		 * for 18bpp panels. */
201
		 * for 18bpp panels. */
197
		if (crtc->config->dither && crtc->config->pipe_bpp == 18)
202
		if (crtc->config->dither && crtc->config->pipe_bpp == 18)
198
			temp |= LVDS_ENABLE_DITHER;
203
			temp |= LVDS_ENABLE_DITHER;
199
		else
204
		else
200
			temp &= ~LVDS_ENABLE_DITHER;
205
			temp &= ~LVDS_ENABLE_DITHER;
201
	}
206
	}
202
	temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
207
	temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
203
	if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
208
	if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
204
		temp |= LVDS_HSYNC_POLARITY;
209
		temp |= LVDS_HSYNC_POLARITY;
205
	if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
210
	if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
206
		temp |= LVDS_VSYNC_POLARITY;
211
		temp |= LVDS_VSYNC_POLARITY;
207
 
212
 
208
	I915_WRITE(lvds_encoder->reg, temp);
213
	I915_WRITE(lvds_encoder->reg, temp);
209
}
214
}
210
 
215
 
211
/**
216
/**
212
 * Sets the power state for the panel.
217
 * Sets the power state for the panel.
213
 */
218
 */
214
static void intel_enable_lvds(struct intel_encoder *encoder)
219
static void intel_enable_lvds(struct intel_encoder *encoder)
215
{
220
{
216
	struct drm_device *dev = encoder->base.dev;
221
	struct drm_device *dev = encoder->base.dev;
217
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
222
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
218
	struct intel_connector *intel_connector =
223
	struct intel_connector *intel_connector =
219
		&lvds_encoder->attached_connector->base;
224
		&lvds_encoder->attached_connector->base;
220
	struct drm_i915_private *dev_priv = dev->dev_private;
225
	struct drm_i915_private *dev_priv = dev->dev_private;
221
	i915_reg_t ctl_reg, stat_reg;
226
	i915_reg_t ctl_reg, stat_reg;
222
 
227
 
223
	if (HAS_PCH_SPLIT(dev)) {
228
	if (HAS_PCH_SPLIT(dev)) {
224
		ctl_reg = PCH_PP_CONTROL;
229
		ctl_reg = PCH_PP_CONTROL;
225
		stat_reg = PCH_PP_STATUS;
230
		stat_reg = PCH_PP_STATUS;
226
	} else {
231
	} else {
227
		ctl_reg = PP_CONTROL;
232
		ctl_reg = PP_CONTROL;
228
		stat_reg = PP_STATUS;
233
		stat_reg = PP_STATUS;
229
	}
234
	}
230
 
235
 
231
	I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) | LVDS_PORT_EN);
236
	I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) | LVDS_PORT_EN);
232
 
237
 
233
	I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
238
	I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
234
	POSTING_READ(lvds_encoder->reg);
239
	POSTING_READ(lvds_encoder->reg);
235
	if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000))
240
	if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000))
236
		DRM_ERROR("timed out waiting for panel to power on\n");
241
		DRM_ERROR("timed out waiting for panel to power on\n");
237
 
242
 
238
	intel_panel_enable_backlight(intel_connector);
243
	intel_panel_enable_backlight(intel_connector);
239
}
244
}
240
 
245
 
241
static void intel_disable_lvds(struct intel_encoder *encoder)
246
static void intel_disable_lvds(struct intel_encoder *encoder)
242
{
247
{
243
	struct drm_device *dev = encoder->base.dev;
248
	struct drm_device *dev = encoder->base.dev;
244
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
249
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
245
	struct drm_i915_private *dev_priv = dev->dev_private;
250
	struct drm_i915_private *dev_priv = dev->dev_private;
246
	i915_reg_t ctl_reg, stat_reg;
251
	i915_reg_t ctl_reg, stat_reg;
247
 
252
 
248
	if (HAS_PCH_SPLIT(dev)) {
253
	if (HAS_PCH_SPLIT(dev)) {
249
		ctl_reg = PCH_PP_CONTROL;
254
		ctl_reg = PCH_PP_CONTROL;
250
		stat_reg = PCH_PP_STATUS;
255
		stat_reg = PCH_PP_STATUS;
251
	} else {
256
	} else {
252
		ctl_reg = PP_CONTROL;
257
		ctl_reg = PP_CONTROL;
253
		stat_reg = PP_STATUS;
258
		stat_reg = PP_STATUS;
254
	}
259
	}
255
 
260
 
256
	I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
261
	I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
257
	if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000))
262
	if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000))
258
		DRM_ERROR("timed out waiting for panel to power off\n");
263
		DRM_ERROR("timed out waiting for panel to power off\n");
259
 
264
 
260
	I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) & ~LVDS_PORT_EN);
265
	I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) & ~LVDS_PORT_EN);
261
	POSTING_READ(lvds_encoder->reg);
266
	POSTING_READ(lvds_encoder->reg);
262
}
267
}
263
 
268
 
264
static void gmch_disable_lvds(struct intel_encoder *encoder)
269
static void gmch_disable_lvds(struct intel_encoder *encoder)
265
{
270
{
266
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
271
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
267
	struct intel_connector *intel_connector =
272
	struct intel_connector *intel_connector =
268
		&lvds_encoder->attached_connector->base;
273
		&lvds_encoder->attached_connector->base;
269
 
274
 
270
	intel_panel_disable_backlight(intel_connector);
275
	intel_panel_disable_backlight(intel_connector);
271
 
276
 
272
	intel_disable_lvds(encoder);
277
	intel_disable_lvds(encoder);
273
}
278
}
274
 
279
 
275
static void pch_disable_lvds(struct intel_encoder *encoder)
280
static void pch_disable_lvds(struct intel_encoder *encoder)
276
{
281
{
277
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
282
	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
278
	struct intel_connector *intel_connector =
283
	struct intel_connector *intel_connector =
279
		&lvds_encoder->attached_connector->base;
284
		&lvds_encoder->attached_connector->base;
280
 
285
 
281
	intel_panel_disable_backlight(intel_connector);
286
	intel_panel_disable_backlight(intel_connector);
282
}
287
}
283
 
288
 
284
static void pch_post_disable_lvds(struct intel_encoder *encoder)
289
static void pch_post_disable_lvds(struct intel_encoder *encoder)
285
{
290
{
286
	intel_disable_lvds(encoder);
291
	intel_disable_lvds(encoder);
287
}
292
}
288
 
293
 
289
static enum drm_mode_status
294
static enum drm_mode_status
290
intel_lvds_mode_valid(struct drm_connector *connector,
295
intel_lvds_mode_valid(struct drm_connector *connector,
291
		      struct drm_display_mode *mode)
296
		      struct drm_display_mode *mode)
292
{
297
{
293
	struct intel_connector *intel_connector = to_intel_connector(connector);
298
	struct intel_connector *intel_connector = to_intel_connector(connector);
294
	struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
299
	struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
295
	int max_pixclk = to_i915(connector->dev)->max_dotclk_freq;
300
	int max_pixclk = to_i915(connector->dev)->max_dotclk_freq;
296
 
301
 
297
	if (mode->hdisplay > fixed_mode->hdisplay)
302
	if (mode->hdisplay > fixed_mode->hdisplay)
298
		return MODE_PANEL;
303
		return MODE_PANEL;
299
	if (mode->vdisplay > fixed_mode->vdisplay)
304
	if (mode->vdisplay > fixed_mode->vdisplay)
300
		return MODE_PANEL;
305
		return MODE_PANEL;
301
	if (fixed_mode->clock > max_pixclk)
306
	if (fixed_mode->clock > max_pixclk)
302
		return MODE_CLOCK_HIGH;
307
		return MODE_CLOCK_HIGH;
303
 
308
 
304
	return MODE_OK;
309
	return MODE_OK;
305
}
310
}
306
 
311
 
307
static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
312
static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
308
				      struct intel_crtc_state *pipe_config)
313
				      struct intel_crtc_state *pipe_config)
309
{
314
{
310
	struct drm_device *dev = intel_encoder->base.dev;
315
	struct drm_device *dev = intel_encoder->base.dev;
311
	struct intel_lvds_encoder *lvds_encoder =
316
	struct intel_lvds_encoder *lvds_encoder =
312
		to_lvds_encoder(&intel_encoder->base);
317
		to_lvds_encoder(&intel_encoder->base);
313
	struct intel_connector *intel_connector =
318
	struct intel_connector *intel_connector =
314
		&lvds_encoder->attached_connector->base;
319
		&lvds_encoder->attached_connector->base;
315
	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
320
	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
316
	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
321
	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
317
	unsigned int lvds_bpp;
322
	unsigned int lvds_bpp;
318
 
323
 
319
	/* Should never happen!! */
324
	/* Should never happen!! */
320
	if (INTEL_INFO(dev)->gen < 4 && intel_crtc->pipe == 0) {
325
	if (INTEL_INFO(dev)->gen < 4 && intel_crtc->pipe == 0) {
321
		DRM_ERROR("Can't support LVDS on pipe A\n");
326
		DRM_ERROR("Can't support LVDS on pipe A\n");
322
		return false;
327
		return false;
323
	}
328
	}
324
 
329
 
325
	if (lvds_encoder->a3_power == LVDS_A3_POWER_UP)
330
	if (lvds_encoder->a3_power == LVDS_A3_POWER_UP)
326
		lvds_bpp = 8*3;
331
		lvds_bpp = 8*3;
327
	else
332
	else
328
		lvds_bpp = 6*3;
333
		lvds_bpp = 6*3;
329
 
334
 
330
	if (lvds_bpp != pipe_config->pipe_bpp && !pipe_config->bw_constrained) {
335
	if (lvds_bpp != pipe_config->pipe_bpp && !pipe_config->bw_constrained) {
331
		DRM_DEBUG_KMS("forcing display bpp (was %d) to LVDS (%d)\n",
336
		DRM_DEBUG_KMS("forcing display bpp (was %d) to LVDS (%d)\n",
332
			      pipe_config->pipe_bpp, lvds_bpp);
337
			      pipe_config->pipe_bpp, lvds_bpp);
333
		pipe_config->pipe_bpp = lvds_bpp;
338
		pipe_config->pipe_bpp = lvds_bpp;
334
	}
339
	}
335
 
340
 
336
	/*
341
	/*
337
	 * We have timings from the BIOS for the panel, put them in
342
	 * We have timings from the BIOS for the panel, put them in
338
	 * to the adjusted mode.  The CRTC will be set up for this mode,
343
	 * to the adjusted mode.  The CRTC will be set up for this mode,
339
	 * with the panel scaling set up to source from the H/VDisplay
344
	 * with the panel scaling set up to source from the H/VDisplay
340
	 * of the original mode.
345
	 * of the original mode.
341
	 */
346
	 */
342
	intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
347
	intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
343
			       adjusted_mode);
348
			       adjusted_mode);
344
 
349
 
345
	if (HAS_PCH_SPLIT(dev)) {
350
	if (HAS_PCH_SPLIT(dev)) {
346
		pipe_config->has_pch_encoder = true;
351
		pipe_config->has_pch_encoder = true;
347
 
352
 
348
		intel_pch_panel_fitting(intel_crtc, pipe_config,
353
		intel_pch_panel_fitting(intel_crtc, pipe_config,
349
					intel_connector->panel.fitting_mode);
354
					intel_connector->panel.fitting_mode);
350
	} else {
355
	} else {
351
		intel_gmch_panel_fitting(intel_crtc, pipe_config,
356
		intel_gmch_panel_fitting(intel_crtc, pipe_config,
352
					 intel_connector->panel.fitting_mode);
357
					 intel_connector->panel.fitting_mode);
353
 
358
 
354
	}
359
	}
355
 
360
 
356
	/*
361
	/*
357
	 * XXX: It would be nice to support lower refresh rates on the
362
	 * XXX: It would be nice to support lower refresh rates on the
358
	 * panels to reduce power consumption, and perhaps match the
363
	 * panels to reduce power consumption, and perhaps match the
359
	 * user's requested refresh rate.
364
	 * user's requested refresh rate.
360
	 */
365
	 */
361
 
366
 
362
	return true;
367
	return true;
363
}
368
}
364
 
369
 
365
/**
370
/**
366
 * Detect the LVDS connection.
371
 * Detect the LVDS connection.
367
 *
372
 *
368
 * Since LVDS doesn't have hotlug, we use the lid as a proxy.  Open means
373
 * Since LVDS doesn't have hotlug, we use the lid as a proxy.  Open means
369
 * connected and closed means disconnected.  We also send hotplug events as
374
 * connected and closed means disconnected.  We also send hotplug events as
370
 * needed, using lid status notification from the input layer.
375
 * needed, using lid status notification from the input layer.
371
 */
376
 */
372
static enum drm_connector_status
377
static enum drm_connector_status
373
intel_lvds_detect(struct drm_connector *connector, bool force)
378
intel_lvds_detect(struct drm_connector *connector, bool force)
374
{
379
{
375
	struct drm_device *dev = connector->dev;
380
	struct drm_device *dev = connector->dev;
376
	enum drm_connector_status status;
381
	enum drm_connector_status status;
377
 
382
 
378
	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
383
	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
379
		      connector->base.id, connector->name);
384
		      connector->base.id, connector->name);
380
 
385
 
381
	status = intel_panel_detect(dev);
386
	status = intel_panel_detect(dev);
382
	if (status != connector_status_unknown)
387
	if (status != connector_status_unknown)
383
		return status;
388
		return status;
384
 
389
 
385
	return connector_status_connected;
390
	return connector_status_connected;
386
}
391
}
387
 
392
 
388
/**
393
/**
389
 * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
394
 * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
390
 */
395
 */
391
static int intel_lvds_get_modes(struct drm_connector *connector)
396
static int intel_lvds_get_modes(struct drm_connector *connector)
392
{
397
{
393
	struct intel_lvds_connector *lvds_connector = to_lvds_connector(connector);
398
	struct intel_lvds_connector *lvds_connector = to_lvds_connector(connector);
394
	struct drm_device *dev = connector->dev;
399
	struct drm_device *dev = connector->dev;
395
	struct drm_display_mode *mode;
400
	struct drm_display_mode *mode;
396
 
401
 
397
	/* use cached edid if we have one */
402
	/* use cached edid if we have one */
398
	if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
403
	if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
399
		return drm_add_edid_modes(connector, lvds_connector->base.edid);
404
		return drm_add_edid_modes(connector, lvds_connector->base.edid);
400
 
405
 
401
	mode = drm_mode_duplicate(dev, lvds_connector->base.panel.fixed_mode);
406
	mode = drm_mode_duplicate(dev, lvds_connector->base.panel.fixed_mode);
402
	if (mode == NULL)
407
	if (mode == NULL)
403
		return 0;
408
		return 0;
404
 
409
 
405
	drm_mode_probed_add(connector, mode);
410
	drm_mode_probed_add(connector, mode);
406
	return 1;
411
	return 1;
407
}
412
}
408
 
413
 
409
static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id)
414
static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id)
410
{
415
{
411
	DRM_INFO("Skipping forced modeset for %s\n", id->ident);
416
	DRM_INFO("Skipping forced modeset for %s\n", id->ident);
412
	return 1;
417
	return 1;
413
}
418
}
414
 
419
 
415
/* The GPU hangs up on these systems if modeset is performed on LID open */
420
/* The GPU hangs up on these systems if modeset is performed on LID open */
416
static const struct dmi_system_id intel_no_modeset_on_lid[] = {
421
static const struct dmi_system_id intel_no_modeset_on_lid[] = {
417
	{
422
	{
418
		.callback = intel_no_modeset_on_lid_dmi_callback,
423
		.callback = intel_no_modeset_on_lid_dmi_callback,
419
		.ident = "Toshiba Tecra A11",
424
		.ident = "Toshiba Tecra A11",
420
		.matches = {
425
		.matches = {
421
			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
426
			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
422
			DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"),
427
			DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"),
423
		},
428
		},
424
	},
429
	},
425
 
430
 
426
	{ }	/* terminating entry */
431
	{ }	/* terminating entry */
427
};
432
};
428
 
433
 
429
#if 0
434
#if 0
430
/*
435
/*
431
 * Lid events. Note the use of 'modeset':
436
 * Lid events. Note the use of 'modeset':
432
 *  - we set it to MODESET_ON_LID_OPEN on lid close,
437
 *  - we set it to MODESET_ON_LID_OPEN on lid close,
433
 *    and set it to MODESET_DONE on open
438
 *    and set it to MODESET_DONE on open
434
 *  - we use it as a "only once" bit (ie we ignore
439
 *  - we use it as a "only once" bit (ie we ignore
435
 *    duplicate events where it was already properly set)
440
 *    duplicate events where it was already properly set)
436
 *  - the suspend/resume paths will set it to
441
 *  - the suspend/resume paths will set it to
437
 *    MODESET_SUSPENDED and ignore the lid open event,
442
 *    MODESET_SUSPENDED and ignore the lid open event,
438
 *    because they restore the mode ("lid open").
443
 *    because they restore the mode ("lid open").
439
 */
444
 */
440
static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
445
static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
441
			    void *unused)
446
			    void *unused)
442
{
447
{
443
	struct intel_lvds_connector *lvds_connector =
448
	struct intel_lvds_connector *lvds_connector =
444
		container_of(nb, struct intel_lvds_connector, lid_notifier);
449
		container_of(nb, struct intel_lvds_connector, lid_notifier);
445
	struct drm_connector *connector = &lvds_connector->base.base;
450
	struct drm_connector *connector = &lvds_connector->base.base;
446
	struct drm_device *dev = connector->dev;
451
	struct drm_device *dev = connector->dev;
447
	struct drm_i915_private *dev_priv = dev->dev_private;
452
	struct drm_i915_private *dev_priv = dev->dev_private;
448
 
453
 
449
	if (dev->switch_power_state != DRM_SWITCH_POWER_ON)
454
	if (dev->switch_power_state != DRM_SWITCH_POWER_ON)
450
		return NOTIFY_OK;
455
		return NOTIFY_OK;
451
 
456
 
452
	mutex_lock(&dev_priv->modeset_restore_lock);
457
	mutex_lock(&dev_priv->modeset_restore_lock);
453
	if (dev_priv->modeset_restore == MODESET_SUSPENDED)
458
	if (dev_priv->modeset_restore == MODESET_SUSPENDED)
454
		goto exit;
459
		goto exit;
455
	/*
460
	/*
456
	 * check and update the status of LVDS connector after receiving
461
	 * check and update the status of LVDS connector after receiving
457
	 * the LID nofication event.
462
	 * the LID nofication event.
458
	 */
463
	 */
459
	connector->status = connector->funcs->detect(connector, false);
464
	connector->status = connector->funcs->detect(connector, false);
460
 
465
 
461
	/* Don't force modeset on machines where it causes a GPU lockup */
466
	/* Don't force modeset on machines where it causes a GPU lockup */
462
	if (dmi_check_system(intel_no_modeset_on_lid))
467
	if (dmi_check_system(intel_no_modeset_on_lid))
463
		goto exit;
468
		goto exit;
464
	if (!acpi_lid_open()) {
469
	if (!acpi_lid_open()) {
465
		/* do modeset on next lid open event */
470
		/* do modeset on next lid open event */
466
		dev_priv->modeset_restore = MODESET_ON_LID_OPEN;
471
		dev_priv->modeset_restore = MODESET_ON_LID_OPEN;
467
		goto exit;
472
		goto exit;
468
	}
473
	}
469
 
474
 
470
	if (dev_priv->modeset_restore == MODESET_DONE)
475
	if (dev_priv->modeset_restore == MODESET_DONE)
471
		goto exit;
476
		goto exit;
472
 
477
 
473
	/*
478
	/*
474
	 * Some old platform's BIOS love to wreak havoc while the lid is closed.
479
	 * Some old platform's BIOS love to wreak havoc while the lid is closed.
475
	 * We try to detect this here and undo any damage. The split for PCH
480
	 * We try to detect this here and undo any damage. The split for PCH
476
	 * platforms is rather conservative and a bit arbitrary expect that on
481
	 * platforms is rather conservative and a bit arbitrary expect that on
477
	 * those platforms VGA disabling requires actual legacy VGA I/O access,
482
	 * those platforms VGA disabling requires actual legacy VGA I/O access,
478
	 * and as part of the cleanup in the hw state restore we also redisable
483
	 * and as part of the cleanup in the hw state restore we also redisable
479
	 * the vga plane.
484
	 * the vga plane.
480
	 */
485
	 */
481
	if (!HAS_PCH_SPLIT(dev)) {
486
	if (!HAS_PCH_SPLIT(dev))
482
		drm_modeset_lock_all(dev);
-
 
483
		intel_display_resume(dev);
487
		intel_display_resume(dev);
484
		drm_modeset_unlock_all(dev);
-
 
485
	}
-
 
486
 
488
 
487
	dev_priv->modeset_restore = MODESET_DONE;
489
	dev_priv->modeset_restore = MODESET_DONE;
488
 
490
 
489
exit:
491
exit:
490
	mutex_unlock(&dev_priv->modeset_restore_lock);
492
	mutex_unlock(&dev_priv->modeset_restore_lock);
491
	return NOTIFY_OK;
493
	return NOTIFY_OK;
492
}
494
}
493
#endif
495
#endif
494
 
496
 
495
/**
497
/**
496
 * intel_lvds_destroy - unregister and free LVDS structures
498
 * intel_lvds_destroy - unregister and free LVDS structures
497
 * @connector: connector to free
499
 * @connector: connector to free
498
 *
500
 *
499
 * Unregister the DDC bus for this connector then free the driver private
501
 * Unregister the DDC bus for this connector then free the driver private
500
 * structure.
502
 * structure.
501
 */
503
 */
502
static void intel_lvds_destroy(struct drm_connector *connector)
504
static void intel_lvds_destroy(struct drm_connector *connector)
503
{
505
{
504
	struct intel_lvds_connector *lvds_connector =
506
	struct intel_lvds_connector *lvds_connector =
505
		to_lvds_connector(connector);
507
		to_lvds_connector(connector);
506
 
508
 
507
 
509
 
508
	if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
510
	if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
509
		kfree(lvds_connector->base.edid);
511
		kfree(lvds_connector->base.edid);
510
 
512
 
511
	intel_panel_fini(&lvds_connector->base.panel);
513
	intel_panel_fini(&lvds_connector->base.panel);
512
 
514
 
513
	drm_connector_cleanup(connector);
515
	drm_connector_cleanup(connector);
514
	kfree(connector);
516
	kfree(connector);
515
}
517
}
516
 
518
 
517
static int intel_lvds_set_property(struct drm_connector *connector,
519
static int intel_lvds_set_property(struct drm_connector *connector,
518
				   struct drm_property *property,
520
				   struct drm_property *property,
519
				   uint64_t value)
521
				   uint64_t value)
520
{
522
{
521
	struct intel_connector *intel_connector = to_intel_connector(connector);
523
	struct intel_connector *intel_connector = to_intel_connector(connector);
522
	struct drm_device *dev = connector->dev;
524
	struct drm_device *dev = connector->dev;
523
 
525
 
524
	if (property == dev->mode_config.scaling_mode_property) {
526
	if (property == dev->mode_config.scaling_mode_property) {
525
		struct drm_crtc *crtc;
527
		struct drm_crtc *crtc;
526
 
528
 
527
		if (value == DRM_MODE_SCALE_NONE) {
529
		if (value == DRM_MODE_SCALE_NONE) {
528
			DRM_DEBUG_KMS("no scaling not supported\n");
530
			DRM_DEBUG_KMS("no scaling not supported\n");
529
			return -EINVAL;
531
			return -EINVAL;
530
		}
532
		}
531
 
533
 
532
		if (intel_connector->panel.fitting_mode == value) {
534
		if (intel_connector->panel.fitting_mode == value) {
533
			/* the LVDS scaling property is not changed */
535
			/* the LVDS scaling property is not changed */
534
			return 0;
536
			return 0;
535
		}
537
		}
536
		intel_connector->panel.fitting_mode = value;
538
		intel_connector->panel.fitting_mode = value;
537
 
539
 
538
		crtc = intel_attached_encoder(connector)->base.crtc;
540
		crtc = intel_attached_encoder(connector)->base.crtc;
539
		if (crtc && crtc->state->enable) {
541
		if (crtc && crtc->state->enable) {
540
			/*
542
			/*
541
			 * If the CRTC is enabled, the display will be changed
543
			 * If the CRTC is enabled, the display will be changed
542
			 * according to the new panel fitting mode.
544
			 * according to the new panel fitting mode.
543
			 */
545
			 */
544
			intel_crtc_restore_mode(crtc);
546
			intel_crtc_restore_mode(crtc);
545
		}
547
		}
546
	}
548
	}
547
 
549
 
548
	return 0;
550
	return 0;
549
}
551
}
550
 
552
 
551
static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
553
static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
552
	.get_modes = intel_lvds_get_modes,
554
	.get_modes = intel_lvds_get_modes,
553
	.mode_valid = intel_lvds_mode_valid,
555
	.mode_valid = intel_lvds_mode_valid,
554
	.best_encoder = intel_best_encoder,
556
	.best_encoder = intel_best_encoder,
555
};
557
};
556
 
558
 
557
static const struct drm_connector_funcs intel_lvds_connector_funcs = {
559
static const struct drm_connector_funcs intel_lvds_connector_funcs = {
558
	.dpms = drm_atomic_helper_connector_dpms,
560
	.dpms = drm_atomic_helper_connector_dpms,
559
	.detect = intel_lvds_detect,
561
	.detect = intel_lvds_detect,
560
	.fill_modes = drm_helper_probe_single_connector_modes,
562
	.fill_modes = drm_helper_probe_single_connector_modes,
561
	.set_property = intel_lvds_set_property,
563
	.set_property = intel_lvds_set_property,
562
	.atomic_get_property = intel_connector_atomic_get_property,
564
	.atomic_get_property = intel_connector_atomic_get_property,
563
	.destroy = intel_lvds_destroy,
565
	.destroy = intel_lvds_destroy,
564
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
566
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
565
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
567
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
566
};
568
};
567
 
569
 
568
static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
570
static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
569
	.destroy = intel_encoder_destroy,
571
	.destroy = intel_encoder_destroy,
570
};
572
};
571
 
573
 
572
static int intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
574
static int intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
573
{
575
{
574
	DRM_INFO("Skipping LVDS initialization for %s\n", id->ident);
576
	DRM_INFO("Skipping LVDS initialization for %s\n", id->ident);
575
	return 1;
577
	return 1;
576
}
578
}
577
 
579
 
578
/* These systems claim to have LVDS, but really don't */
580
/* These systems claim to have LVDS, but really don't */
579
static const struct dmi_system_id intel_no_lvds[] = {
581
static const struct dmi_system_id intel_no_lvds[] = {
580
	{
582
	{
581
		.callback = intel_no_lvds_dmi_callback,
583
		.callback = intel_no_lvds_dmi_callback,
582
		.ident = "Apple Mac Mini (Core series)",
584
		.ident = "Apple Mac Mini (Core series)",
583
		.matches = {
585
		.matches = {
584
			DMI_MATCH(DMI_SYS_VENDOR, "Apple"),
586
			DMI_MATCH(DMI_SYS_VENDOR, "Apple"),
585
			DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
587
			DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
586
		},
588
		},
587
	},
589
	},
588
	{
590
	{
589
		.callback = intel_no_lvds_dmi_callback,
591
		.callback = intel_no_lvds_dmi_callback,
590
		.ident = "Apple Mac Mini (Core 2 series)",
592
		.ident = "Apple Mac Mini (Core 2 series)",
591
		.matches = {
593
		.matches = {
592
			DMI_MATCH(DMI_SYS_VENDOR, "Apple"),
594
			DMI_MATCH(DMI_SYS_VENDOR, "Apple"),
593
			DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"),
595
			DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"),
594
		},
596
		},
595
	},
597
	},
596
	{
598
	{
597
		.callback = intel_no_lvds_dmi_callback,
599
		.callback = intel_no_lvds_dmi_callback,
598
		.ident = "MSI IM-945GSE-A",
600
		.ident = "MSI IM-945GSE-A",
599
		.matches = {
601
		.matches = {
600
			DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
602
			DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
601
			DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"),
603
			DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"),
602
		},
604
		},
603
	},
605
	},
604
	{
606
	{
605
		.callback = intel_no_lvds_dmi_callback,
607
		.callback = intel_no_lvds_dmi_callback,
606
		.ident = "Dell Studio Hybrid",
608
		.ident = "Dell Studio Hybrid",
607
		.matches = {
609
		.matches = {
608
			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
610
			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
609
			DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"),
611
			DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"),
610
		},
612
		},
611
	},
613
	},
612
	{
614
	{
613
		.callback = intel_no_lvds_dmi_callback,
615
		.callback = intel_no_lvds_dmi_callback,
614
		.ident = "Dell OptiPlex FX170",
616
		.ident = "Dell OptiPlex FX170",
615
		.matches = {
617
		.matches = {
616
			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
618
			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
617
			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex FX170"),
619
			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex FX170"),
618
		},
620
		},
619
	},
621
	},
620
	{
622
	{
621
		.callback = intel_no_lvds_dmi_callback,
623
		.callback = intel_no_lvds_dmi_callback,
622
		.ident = "AOpen Mini PC",
624
		.ident = "AOpen Mini PC",
623
		.matches = {
625
		.matches = {
624
			DMI_MATCH(DMI_SYS_VENDOR, "AOpen"),
626
			DMI_MATCH(DMI_SYS_VENDOR, "AOpen"),
625
			DMI_MATCH(DMI_PRODUCT_NAME, "i965GMx-IF"),
627
			DMI_MATCH(DMI_PRODUCT_NAME, "i965GMx-IF"),
626
		},
628
		},
627
	},
629
	},
628
	{
630
	{
629
		.callback = intel_no_lvds_dmi_callback,
631
		.callback = intel_no_lvds_dmi_callback,
630
		.ident = "AOpen Mini PC MP915",
632
		.ident = "AOpen Mini PC MP915",
631
		.matches = {
633
		.matches = {
632
			DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
634
			DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
633
			DMI_MATCH(DMI_BOARD_NAME, "i915GMx-F"),
635
			DMI_MATCH(DMI_BOARD_NAME, "i915GMx-F"),
634
		},
636
		},
635
	},
637
	},
636
	{
638
	{
637
		.callback = intel_no_lvds_dmi_callback,
639
		.callback = intel_no_lvds_dmi_callback,
638
		.ident = "AOpen i915GMm-HFS",
640
		.ident = "AOpen i915GMm-HFS",
639
		.matches = {
641
		.matches = {
640
			DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
642
			DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
641
			DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
643
			DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
642
		},
644
		},
643
	},
645
	},
644
	{
646
	{
645
		.callback = intel_no_lvds_dmi_callback,
647
		.callback = intel_no_lvds_dmi_callback,
646
                .ident = "AOpen i45GMx-I",
648
                .ident = "AOpen i45GMx-I",
647
                .matches = {
649
                .matches = {
648
                        DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
650
                        DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
649
                        DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"),
651
                        DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"),
650
                },
652
                },
651
        },
653
        },
652
	{
654
	{
653
		.callback = intel_no_lvds_dmi_callback,
655
		.callback = intel_no_lvds_dmi_callback,
654
		.ident = "Aopen i945GTt-VFA",
656
		.ident = "Aopen i945GTt-VFA",
655
		.matches = {
657
		.matches = {
656
			DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
658
			DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
657
		},
659
		},
658
	},
660
	},
659
	{
661
	{
660
		.callback = intel_no_lvds_dmi_callback,
662
		.callback = intel_no_lvds_dmi_callback,
661
		.ident = "Clientron U800",
663
		.ident = "Clientron U800",
662
		.matches = {
664
		.matches = {
663
			DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
665
			DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
664
			DMI_MATCH(DMI_PRODUCT_NAME, "U800"),
666
			DMI_MATCH(DMI_PRODUCT_NAME, "U800"),
665
		},
667
		},
666
	},
668
	},
667
	{
669
	{
668
                .callback = intel_no_lvds_dmi_callback,
670
                .callback = intel_no_lvds_dmi_callback,
669
                .ident = "Clientron E830",
671
                .ident = "Clientron E830",
670
                .matches = {
672
                .matches = {
671
                        DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
673
                        DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
672
                        DMI_MATCH(DMI_PRODUCT_NAME, "E830"),
674
                        DMI_MATCH(DMI_PRODUCT_NAME, "E830"),
673
                },
675
                },
674
        },
676
        },
675
        {
677
        {
676
		.callback = intel_no_lvds_dmi_callback,
678
		.callback = intel_no_lvds_dmi_callback,
677
		.ident = "Asus EeeBox PC EB1007",
679
		.ident = "Asus EeeBox PC EB1007",
678
		.matches = {
680
		.matches = {
679
			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
681
			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
680
			DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"),
682
			DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"),
681
		},
683
		},
682
	},
684
	},
683
	{
685
	{
684
		.callback = intel_no_lvds_dmi_callback,
686
		.callback = intel_no_lvds_dmi_callback,
685
		.ident = "Asus AT5NM10T-I",
687
		.ident = "Asus AT5NM10T-I",
686
		.matches = {
688
		.matches = {
687
			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
689
			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
688
			DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"),
690
			DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"),
689
		},
691
		},
690
	},
692
	},
691
	{
693
	{
692
		.callback = intel_no_lvds_dmi_callback,
694
		.callback = intel_no_lvds_dmi_callback,
693
		.ident = "Hewlett-Packard HP t5740",
695
		.ident = "Hewlett-Packard HP t5740",
694
		.matches = {
696
		.matches = {
695
			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
697
			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
696
			DMI_MATCH(DMI_PRODUCT_NAME, " t5740"),
698
			DMI_MATCH(DMI_PRODUCT_NAME, " t5740"),
697
		},
699
		},
698
	},
700
	},
699
	{
701
	{
700
		.callback = intel_no_lvds_dmi_callback,
702
		.callback = intel_no_lvds_dmi_callback,
701
		.ident = "Hewlett-Packard t5745",
703
		.ident = "Hewlett-Packard t5745",
702
		.matches = {
704
		.matches = {
703
			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
705
			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
704
			DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"),
706
			DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"),
705
		},
707
		},
706
	},
708
	},
707
	{
709
	{
708
		.callback = intel_no_lvds_dmi_callback,
710
		.callback = intel_no_lvds_dmi_callback,
709
		.ident = "Hewlett-Packard st5747",
711
		.ident = "Hewlett-Packard st5747",
710
		.matches = {
712
		.matches = {
711
			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
713
			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
712
			DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"),
714
			DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"),
713
		},
715
		},
714
	},
716
	},
715
	{
717
	{
716
		.callback = intel_no_lvds_dmi_callback,
718
		.callback = intel_no_lvds_dmi_callback,
717
		.ident = "MSI Wind Box DC500",
719
		.ident = "MSI Wind Box DC500",
718
		.matches = {
720
		.matches = {
719
			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
721
			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
720
			DMI_MATCH(DMI_BOARD_NAME, "MS-7469"),
722
			DMI_MATCH(DMI_BOARD_NAME, "MS-7469"),
721
		},
723
		},
722
	},
724
	},
723
	{
725
	{
724
		.callback = intel_no_lvds_dmi_callback,
726
		.callback = intel_no_lvds_dmi_callback,
725
		.ident = "Gigabyte GA-D525TUD",
727
		.ident = "Gigabyte GA-D525TUD",
726
		.matches = {
728
		.matches = {
727
			DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
729
			DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
728
			DMI_MATCH(DMI_BOARD_NAME, "D525TUD"),
730
			DMI_MATCH(DMI_BOARD_NAME, "D525TUD"),
729
		},
731
		},
730
	},
732
	},
731
	{
733
	{
732
		.callback = intel_no_lvds_dmi_callback,
734
		.callback = intel_no_lvds_dmi_callback,
733
		.ident = "Supermicro X7SPA-H",
735
		.ident = "Supermicro X7SPA-H",
734
		.matches = {
736
		.matches = {
735
			DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
737
			DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
736
			DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"),
738
			DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"),
737
		},
739
		},
738
	},
740
	},
739
	{
741
	{
740
		.callback = intel_no_lvds_dmi_callback,
742
		.callback = intel_no_lvds_dmi_callback,
741
		.ident = "Fujitsu Esprimo Q900",
743
		.ident = "Fujitsu Esprimo Q900",
742
		.matches = {
744
		.matches = {
743
			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
745
			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
744
			DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Q900"),
746
			DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Q900"),
745
		},
747
		},
746
	},
748
	},
747
	{
749
	{
748
		.callback = intel_no_lvds_dmi_callback,
750
		.callback = intel_no_lvds_dmi_callback,
749
		.ident = "Intel D410PT",
751
		.ident = "Intel D410PT",
750
		.matches = {
752
		.matches = {
751
			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
753
			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
752
			DMI_MATCH(DMI_BOARD_NAME, "D410PT"),
754
			DMI_MATCH(DMI_BOARD_NAME, "D410PT"),
753
		},
755
		},
754
	},
756
	},
755
	{
757
	{
756
		.callback = intel_no_lvds_dmi_callback,
758
		.callback = intel_no_lvds_dmi_callback,
757
		.ident = "Intel D425KT",
759
		.ident = "Intel D425KT",
758
		.matches = {
760
		.matches = {
759
			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
761
			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
760
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "D425KT"),
762
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "D425KT"),
761
		},
763
		},
762
	},
764
	},
763
	{
765
	{
764
		.callback = intel_no_lvds_dmi_callback,
766
		.callback = intel_no_lvds_dmi_callback,
765
		.ident = "Intel D510MO",
767
		.ident = "Intel D510MO",
766
		.matches = {
768
		.matches = {
767
			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
769
			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
768
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "D510MO"),
770
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "D510MO"),
769
		},
771
		},
770
	},
772
	},
771
	{
773
	{
772
		.callback = intel_no_lvds_dmi_callback,
774
		.callback = intel_no_lvds_dmi_callback,
773
		.ident = "Intel D525MW",
775
		.ident = "Intel D525MW",
774
		.matches = {
776
		.matches = {
775
			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
777
			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
776
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
778
			DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
777
		},
779
		},
778
	},
780
	},
779
 
781
 
780
	{ }	/* terminating entry */
782
	{ }	/* terminating entry */
781
};
783
};
782
 
784
 
783
/*
785
/*
784
 * Enumerate the child dev array parsed from VBT to check whether
786
 * Enumerate the child dev array parsed from VBT to check whether
785
 * the LVDS is present.
787
 * the LVDS is present.
786
 * If it is present, return 1.
788
 * If it is present, return 1.
787
 * If it is not present, return false.
789
 * If it is not present, return false.
788
 * If no child dev is parsed from VBT, it assumes that the LVDS is present.
790
 * If no child dev is parsed from VBT, it assumes that the LVDS is present.
789
 */
791
 */
790
static bool lvds_is_present_in_vbt(struct drm_device *dev,
792
static bool lvds_is_present_in_vbt(struct drm_device *dev,
791
				   u8 *i2c_pin)
793
				   u8 *i2c_pin)
792
{
794
{
793
	struct drm_i915_private *dev_priv = dev->dev_private;
795
	struct drm_i915_private *dev_priv = dev->dev_private;
794
	int i;
796
	int i;
795
 
797
 
796
	if (!dev_priv->vbt.child_dev_num)
798
	if (!dev_priv->vbt.child_dev_num)
797
		return true;
799
		return true;
798
 
800
 
799
	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
801
	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
800
		union child_device_config *uchild = dev_priv->vbt.child_dev + i;
802
		union child_device_config *uchild = dev_priv->vbt.child_dev + i;
801
		struct old_child_dev_config *child = &uchild->old;
803
		struct old_child_dev_config *child = &uchild->old;
802
 
804
 
803
		/* If the device type is not LFP, continue.
805
		/* If the device type is not LFP, continue.
804
		 * We have to check both the new identifiers as well as the
806
		 * We have to check both the new identifiers as well as the
805
		 * old for compatibility with some BIOSes.
807
		 * old for compatibility with some BIOSes.
806
		 */
808
		 */
807
		if (child->device_type != DEVICE_TYPE_INT_LFP &&
809
		if (child->device_type != DEVICE_TYPE_INT_LFP &&
808
		    child->device_type != DEVICE_TYPE_LFP)
810
		    child->device_type != DEVICE_TYPE_LFP)
809
			continue;
811
			continue;
810
 
812
 
811
		if (intel_gmbus_is_valid_pin(dev_priv, child->i2c_pin))
813
		if (intel_gmbus_is_valid_pin(dev_priv, child->i2c_pin))
812
			*i2c_pin = child->i2c_pin;
814
			*i2c_pin = child->i2c_pin;
813
 
815
 
814
		/* However, we cannot trust the BIOS writers to populate
816
		/* However, we cannot trust the BIOS writers to populate
815
		 * the VBT correctly.  Since LVDS requires additional
817
		 * the VBT correctly.  Since LVDS requires additional
816
		 * information from AIM blocks, a non-zero addin offset is
818
		 * information from AIM blocks, a non-zero addin offset is
817
		 * a good indicator that the LVDS is actually present.
819
		 * a good indicator that the LVDS is actually present.
818
		 */
820
		 */
819
		if (child->addin_offset)
821
		if (child->addin_offset)
820
			return true;
822
			return true;
821
 
823
 
822
		/* But even then some BIOS writers perform some black magic
824
		/* But even then some BIOS writers perform some black magic
823
		 * and instantiate the device without reference to any
825
		 * and instantiate the device without reference to any
824
		 * additional data.  Trust that if the VBT was written into
826
		 * additional data.  Trust that if the VBT was written into
825
		 * the OpRegion then they have validated the LVDS's existence.
827
		 * the OpRegion then they have validated the LVDS's existence.
826
		 */
828
		 */
827
		if (dev_priv->opregion.vbt)
829
		if (dev_priv->opregion.vbt)
828
			return true;
830
			return true;
829
	}
831
	}
830
 
832
 
831
	return false;
833
	return false;
832
}
834
}
833
 
835
 
834
static int intel_dual_link_lvds_callback(const struct dmi_system_id *id)
836
static int intel_dual_link_lvds_callback(const struct dmi_system_id *id)
835
{
837
{
836
	DRM_INFO("Forcing lvds to dual link mode on %s\n", id->ident);
838
	DRM_INFO("Forcing lvds to dual link mode on %s\n", id->ident);
837
	return 1;
839
	return 1;
838
}
840
}
839
 
841
 
840
static const struct dmi_system_id intel_dual_link_lvds[] = {
842
static const struct dmi_system_id intel_dual_link_lvds[] = {
841
	{
843
	{
842
		.callback = intel_dual_link_lvds_callback,
844
		.callback = intel_dual_link_lvds_callback,
843
		.ident = "Apple MacBook Pro 15\" (2010)",
845
		.ident = "Apple MacBook Pro 15\" (2010)",
844
		.matches = {
846
		.matches = {
845
			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
847
			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
846
			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6,2"),
848
			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6,2"),
847
		},
849
		},
848
	},
850
	},
849
	{
851
	{
850
		.callback = intel_dual_link_lvds_callback,
852
		.callback = intel_dual_link_lvds_callback,
851
		.ident = "Apple MacBook Pro 15\" (2011)",
853
		.ident = "Apple MacBook Pro 15\" (2011)",
852
		.matches = {
854
		.matches = {
853
			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
855
			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
854
			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro8,2"),
856
			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro8,2"),
855
		},
857
		},
856
	},
858
	},
857
	{
859
	{
858
		.callback = intel_dual_link_lvds_callback,
860
		.callback = intel_dual_link_lvds_callback,
859
		.ident = "Apple MacBook Pro 15\" (2012)",
861
		.ident = "Apple MacBook Pro 15\" (2012)",
860
		.matches = {
862
		.matches = {
861
			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
863
			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
862
			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro9,1"),
864
			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro9,1"),
863
		},
865
		},
864
	},
866
	},
865
	{ }	/* terminating entry */
867
	{ }	/* terminating entry */
866
};
868
};
867
 
869
 
868
bool intel_is_dual_link_lvds(struct drm_device *dev)
870
bool intel_is_dual_link_lvds(struct drm_device *dev)
869
{
871
{
870
	struct intel_encoder *encoder;
872
	struct intel_encoder *encoder;
871
	struct intel_lvds_encoder *lvds_encoder;
873
	struct intel_lvds_encoder *lvds_encoder;
872
 
874
 
873
	for_each_intel_encoder(dev, encoder) {
875
	for_each_intel_encoder(dev, encoder) {
874
		if (encoder->type == INTEL_OUTPUT_LVDS) {
876
		if (encoder->type == INTEL_OUTPUT_LVDS) {
875
			lvds_encoder = to_lvds_encoder(&encoder->base);
877
			lvds_encoder = to_lvds_encoder(&encoder->base);
876
 
878
 
877
			return lvds_encoder->is_dual_link;
879
			return lvds_encoder->is_dual_link;
878
		}
880
		}
879
	}
881
	}
880
 
882
 
881
	return false;
883
	return false;
882
}
884
}
883
 
885
 
884
static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
886
static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
885
{
887
{
886
	struct drm_device *dev = lvds_encoder->base.base.dev;
888
	struct drm_device *dev = lvds_encoder->base.base.dev;
887
	unsigned int val;
889
	unsigned int val;
888
	struct drm_i915_private *dev_priv = dev->dev_private;
890
	struct drm_i915_private *dev_priv = dev->dev_private;
889
 
891
 
890
	/* use the module option value if specified */
892
	/* use the module option value if specified */
891
	if (i915.lvds_channel_mode > 0)
893
	if (i915.lvds_channel_mode > 0)
892
		return i915.lvds_channel_mode == 2;
894
		return i915.lvds_channel_mode == 2;
893
 
895
 
894
	/* single channel LVDS is limited to 112 MHz */
896
	/* single channel LVDS is limited to 112 MHz */
895
	if (lvds_encoder->attached_connector->base.panel.fixed_mode->clock
897
	if (lvds_encoder->attached_connector->base.panel.fixed_mode->clock
896
	    > 112999)
898
	    > 112999)
897
		return true;
899
		return true;
898
 
900
 
899
	if (dmi_check_system(intel_dual_link_lvds))
901
	if (dmi_check_system(intel_dual_link_lvds))
900
		return true;
902
		return true;
901
 
903
 
902
	/* BIOS should set the proper LVDS register value at boot, but
904
	/* BIOS should set the proper LVDS register value at boot, but
903
	 * in reality, it doesn't set the value when the lid is closed;
905
	 * in reality, it doesn't set the value when the lid is closed;
904
	 * we need to check "the value to be set" in VBT when LVDS
906
	 * we need to check "the value to be set" in VBT when LVDS
905
	 * register is uninitialized.
907
	 * register is uninitialized.
906
	 */
908
	 */
907
	val = I915_READ(lvds_encoder->reg);
909
	val = I915_READ(lvds_encoder->reg);
908
	if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED)))
910
	if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED)))
909
		val = dev_priv->vbt.bios_lvds_val;
911
		val = dev_priv->vbt.bios_lvds_val;
910
 
912
 
911
	return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
913
	return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
912
}
914
}
913
 
915
 
914
static bool intel_lvds_supported(struct drm_device *dev)
916
static bool intel_lvds_supported(struct drm_device *dev)
915
{
917
{
916
	/* With the introduction of the PCH we gained a dedicated
918
	/* With the introduction of the PCH we gained a dedicated
917
	 * LVDS presence pin, use it. */
919
	 * LVDS presence pin, use it. */
918
	if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
920
	if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
919
		return true;
921
		return true;
920
 
922
 
921
	/* Otherwise LVDS was only attached to mobile products,
923
	/* Otherwise LVDS was only attached to mobile products,
922
	 * except for the inglorious 830gm */
924
	 * except for the inglorious 830gm */
923
	if (INTEL_INFO(dev)->gen <= 4 && IS_MOBILE(dev) && !IS_I830(dev))
925
	if (INTEL_INFO(dev)->gen <= 4 && IS_MOBILE(dev) && !IS_I830(dev))
924
		return true;
926
		return true;
925
 
927
 
926
	return false;
928
	return false;
927
}
929
}
928
 
930
 
929
/**
931
/**
930
 * intel_lvds_init - setup LVDS connectors on this device
932
 * intel_lvds_init - setup LVDS connectors on this device
931
 * @dev: drm device
933
 * @dev: drm device
932
 *
934
 *
933
 * Create the connector, register the LVDS DDC bus, and try to figure out what
935
 * Create the connector, register the LVDS DDC bus, and try to figure out what
934
 * modes we can display on the LVDS panel (if present).
936
 * modes we can display on the LVDS panel (if present).
935
 */
937
 */
936
void intel_lvds_init(struct drm_device *dev)
938
void intel_lvds_init(struct drm_device *dev)
937
{
939
{
938
	struct drm_i915_private *dev_priv = dev->dev_private;
940
	struct drm_i915_private *dev_priv = dev->dev_private;
939
	struct intel_lvds_encoder *lvds_encoder;
941
	struct intel_lvds_encoder *lvds_encoder;
940
	struct intel_encoder *intel_encoder;
942
	struct intel_encoder *intel_encoder;
941
	struct intel_lvds_connector *lvds_connector;
943
	struct intel_lvds_connector *lvds_connector;
942
	struct intel_connector *intel_connector;
944
	struct intel_connector *intel_connector;
943
	struct drm_connector *connector;
945
	struct drm_connector *connector;
944
	struct drm_encoder *encoder;
946
	struct drm_encoder *encoder;
945
	struct drm_display_mode *scan; /* *modes, *bios_mode; */
947
	struct drm_display_mode *scan; /* *modes, *bios_mode; */
946
	struct drm_display_mode *fixed_mode = NULL;
948
	struct drm_display_mode *fixed_mode = NULL;
947
	struct drm_display_mode *downclock_mode = NULL;
949
	struct drm_display_mode *downclock_mode = NULL;
948
	struct edid *edid;
950
	struct edid *edid;
949
	struct drm_crtc *crtc;
951
	struct drm_crtc *crtc;
950
	i915_reg_t lvds_reg;
952
	i915_reg_t lvds_reg;
951
	u32 lvds;
953
	u32 lvds;
952
	int pipe;
954
	int pipe;
953
	u8 pin;
955
	u8 pin;
954
 
956
 
955
	/*
957
	/*
956
	 * Unlock registers and just leave them unlocked. Do this before
958
	 * Unlock registers and just leave them unlocked. Do this before
957
	 * checking quirk lists to avoid bogus WARNINGs.
959
	 * checking quirk lists to avoid bogus WARNINGs.
958
	 */
960
	 */
959
	if (HAS_PCH_SPLIT(dev)) {
961
	if (HAS_PCH_SPLIT(dev)) {
960
		I915_WRITE(PCH_PP_CONTROL,
962
		I915_WRITE(PCH_PP_CONTROL,
961
			   I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS);
963
			   I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS);
962
	} else if (INTEL_INFO(dev_priv)->gen < 5) {
964
	} else if (INTEL_INFO(dev_priv)->gen < 5) {
963
		I915_WRITE(PP_CONTROL,
965
		I915_WRITE(PP_CONTROL,
964
			   I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS);
966
			   I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS);
965
	}
967
	}
966
	if (!intel_lvds_supported(dev))
968
	if (!intel_lvds_supported(dev))
967
		return;
969
		return;
968
 
970
 
969
	/* Skip init on machines we know falsely report LVDS */
971
	/* Skip init on machines we know falsely report LVDS */
970
	if (dmi_check_system(intel_no_lvds))
972
	if (dmi_check_system(intel_no_lvds))
971
		return;
973
		return;
972
 
974
 
973
	if (HAS_PCH_SPLIT(dev))
975
	if (HAS_PCH_SPLIT(dev))
974
		lvds_reg = PCH_LVDS;
976
		lvds_reg = PCH_LVDS;
975
	else
977
	else
976
		lvds_reg = LVDS;
978
		lvds_reg = LVDS;
977
 
979
 
978
	lvds = I915_READ(lvds_reg);
980
	lvds = I915_READ(lvds_reg);
979
 
981
 
980
	if (HAS_PCH_SPLIT(dev)) {
982
	if (HAS_PCH_SPLIT(dev)) {
981
		if ((lvds & LVDS_DETECTED) == 0)
983
		if ((lvds & LVDS_DETECTED) == 0)
982
			return;
984
			return;
983
		if (dev_priv->vbt.edp_support) {
985
		if (dev_priv->vbt.edp_support) {
984
			DRM_DEBUG_KMS("disable LVDS for eDP support\n");
986
			DRM_DEBUG_KMS("disable LVDS for eDP support\n");
985
			return;
987
			return;
986
		}
988
		}
987
	}
989
	}
988
 
990
 
989
	pin = GMBUS_PIN_PANEL;
991
	pin = GMBUS_PIN_PANEL;
990
	if (!lvds_is_present_in_vbt(dev, &pin)) {
992
	if (!lvds_is_present_in_vbt(dev, &pin)) {
991
		if ((lvds & LVDS_PORT_EN) == 0) {
993
		if ((lvds & LVDS_PORT_EN) == 0) {
992
			DRM_DEBUG_KMS("LVDS is not present in VBT\n");
994
			DRM_DEBUG_KMS("LVDS is not present in VBT\n");
993
			return;
995
			return;
994
		}
996
		}
995
		DRM_DEBUG_KMS("LVDS is not present in VBT, but enabled anyway\n");
997
		DRM_DEBUG_KMS("LVDS is not present in VBT, but enabled anyway\n");
996
	}
998
	}
997
 
999
 
998
	 /* Set the Panel Power On/Off timings if uninitialized. */
1000
	 /* Set the Panel Power On/Off timings if uninitialized. */
999
	if (INTEL_INFO(dev_priv)->gen < 5 &&
1001
	if (INTEL_INFO(dev_priv)->gen < 5 &&
1000
	    I915_READ(PP_ON_DELAYS) == 0 && I915_READ(PP_OFF_DELAYS) == 0) {
1002
	    I915_READ(PP_ON_DELAYS) == 0 && I915_READ(PP_OFF_DELAYS) == 0) {
1001
		/* Set T2 to 40ms and T5 to 200ms */
1003
		/* Set T2 to 40ms and T5 to 200ms */
1002
		I915_WRITE(PP_ON_DELAYS, 0x019007d0);
1004
		I915_WRITE(PP_ON_DELAYS, 0x019007d0);
1003
 
1005
 
1004
		/* Set T3 to 35ms and Tx to 200ms */
1006
		/* Set T3 to 35ms and Tx to 200ms */
1005
		I915_WRITE(PP_OFF_DELAYS, 0x015e07d0);
1007
		I915_WRITE(PP_OFF_DELAYS, 0x015e07d0);
1006
 
1008
 
1007
		DRM_DEBUG_KMS("Panel power timings uninitialized, setting defaults\n");
1009
		DRM_DEBUG_KMS("Panel power timings uninitialized, setting defaults\n");
1008
	}
1010
	}
1009
 
1011
 
1010
	lvds_encoder = kzalloc(sizeof(*lvds_encoder), GFP_KERNEL);
1012
	lvds_encoder = kzalloc(sizeof(*lvds_encoder), GFP_KERNEL);
1011
	if (!lvds_encoder)
1013
	if (!lvds_encoder)
1012
		return;
1014
		return;
1013
 
1015
 
1014
	lvds_connector = kzalloc(sizeof(*lvds_connector), GFP_KERNEL);
1016
	lvds_connector = kzalloc(sizeof(*lvds_connector), GFP_KERNEL);
1015
	if (!lvds_connector) {
1017
	if (!lvds_connector) {
1016
		kfree(lvds_encoder);
1018
		kfree(lvds_encoder);
1017
		return;
1019
		return;
1018
	}
1020
	}
1019
 
1021
 
1020
	if (intel_connector_init(&lvds_connector->base) < 0) {
1022
	if (intel_connector_init(&lvds_connector->base) < 0) {
1021
		kfree(lvds_connector);
1023
		kfree(lvds_connector);
1022
		kfree(lvds_encoder);
1024
		kfree(lvds_encoder);
1023
		return;
1025
		return;
1024
	}
1026
	}
1025
 
1027
 
1026
	lvds_encoder->attached_connector = lvds_connector;
1028
	lvds_encoder->attached_connector = lvds_connector;
1027
 
1029
 
1028
	intel_encoder = &lvds_encoder->base;
1030
	intel_encoder = &lvds_encoder->base;
1029
	encoder = &intel_encoder->base;
1031
	encoder = &intel_encoder->base;
1030
	intel_connector = &lvds_connector->base;
1032
	intel_connector = &lvds_connector->base;
1031
	connector = &intel_connector->base;
1033
	connector = &intel_connector->base;
1032
	drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs,
1034
	drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs,
1033
			   DRM_MODE_CONNECTOR_LVDS);
1035
			   DRM_MODE_CONNECTOR_LVDS);
1034
 
1036
 
1035
	drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs,
1037
	drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs,
1036
			 DRM_MODE_ENCODER_LVDS, NULL);
1038
			 DRM_MODE_ENCODER_LVDS, NULL);
1037
 
1039
 
1038
	intel_encoder->enable = intel_enable_lvds;
1040
	intel_encoder->enable = intel_enable_lvds;
1039
	intel_encoder->pre_enable = intel_pre_enable_lvds;
1041
	intel_encoder->pre_enable = intel_pre_enable_lvds;
1040
	intel_encoder->compute_config = intel_lvds_compute_config;
1042
	intel_encoder->compute_config = intel_lvds_compute_config;
1041
	if (HAS_PCH_SPLIT(dev_priv)) {
1043
	if (HAS_PCH_SPLIT(dev_priv)) {
1042
		intel_encoder->disable = pch_disable_lvds;
1044
		intel_encoder->disable = pch_disable_lvds;
1043
		intel_encoder->post_disable = pch_post_disable_lvds;
1045
		intel_encoder->post_disable = pch_post_disable_lvds;
1044
	} else {
1046
	} else {
1045
		intel_encoder->disable = gmch_disable_lvds;
1047
		intel_encoder->disable = gmch_disable_lvds;
1046
	}
1048
	}
1047
	intel_encoder->get_hw_state = intel_lvds_get_hw_state;
1049
	intel_encoder->get_hw_state = intel_lvds_get_hw_state;
1048
	intel_encoder->get_config = intel_lvds_get_config;
1050
	intel_encoder->get_config = intel_lvds_get_config;
1049
	intel_connector->get_hw_state = intel_connector_get_hw_state;
1051
	intel_connector->get_hw_state = intel_connector_get_hw_state;
1050
	intel_connector->unregister = intel_connector_unregister;
1052
	intel_connector->unregister = intel_connector_unregister;
1051
 
1053
 
1052
	intel_connector_attach_encoder(intel_connector, intel_encoder);
1054
	intel_connector_attach_encoder(intel_connector, intel_encoder);
1053
	intel_encoder->type = INTEL_OUTPUT_LVDS;
1055
	intel_encoder->type = INTEL_OUTPUT_LVDS;
1054
 
1056
 
1055
	intel_encoder->cloneable = 0;
1057
	intel_encoder->cloneable = 0;
1056
	if (HAS_PCH_SPLIT(dev))
1058
	if (HAS_PCH_SPLIT(dev))
1057
		intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
1059
		intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
1058
	else if (IS_GEN4(dev))
1060
	else if (IS_GEN4(dev))
1059
		intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
1061
		intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
1060
	else
1062
	else
1061
		intel_encoder->crtc_mask = (1 << 1);
1063
		intel_encoder->crtc_mask = (1 << 1);
1062
 
1064
 
1063
	drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
1065
	drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
1064
	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1066
	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1065
	connector->interlace_allowed = false;
1067
	connector->interlace_allowed = false;
1066
	connector->doublescan_allowed = false;
1068
	connector->doublescan_allowed = false;
1067
 
1069
 
1068
	lvds_encoder->reg = lvds_reg;
1070
	lvds_encoder->reg = lvds_reg;
1069
 
1071
 
1070
	/* create the scaling mode property */
1072
	/* create the scaling mode property */
1071
	drm_mode_create_scaling_mode_property(dev);
1073
	drm_mode_create_scaling_mode_property(dev);
1072
	drm_object_attach_property(&connector->base,
1074
	drm_object_attach_property(&connector->base,
1073
				      dev->mode_config.scaling_mode_property,
1075
				      dev->mode_config.scaling_mode_property,
1074
				      DRM_MODE_SCALE_ASPECT);
1076
				      DRM_MODE_SCALE_ASPECT);
1075
	intel_connector->panel.fitting_mode = DRM_MODE_SCALE_ASPECT;
1077
	intel_connector->panel.fitting_mode = DRM_MODE_SCALE_ASPECT;
1076
	/*
1078
	/*
1077
	 * LVDS discovery:
1079
	 * LVDS discovery:
1078
	 * 1) check for EDID on DDC
1080
	 * 1) check for EDID on DDC
1079
	 * 2) check for VBT data
1081
	 * 2) check for VBT data
1080
	 * 3) check to see if LVDS is already on
1082
	 * 3) check to see if LVDS is already on
1081
	 *    if none of the above, no panel
1083
	 *    if none of the above, no panel
1082
	 * 4) make sure lid is open
1084
	 * 4) make sure lid is open
1083
	 *    if closed, act like it's not there for now
1085
	 *    if closed, act like it's not there for now
1084
	 */
1086
	 */
1085
 
1087
 
1086
	/*
1088
	/*
1087
	 * Attempt to get the fixed panel mode from DDC.  Assume that the
1089
	 * Attempt to get the fixed panel mode from DDC.  Assume that the
1088
	 * preferred mode is the right one.
1090
	 * preferred mode is the right one.
1089
	 */
1091
	 */
1090
	mutex_lock(&dev->mode_config.mutex);
1092
	mutex_lock(&dev->mode_config.mutex);
1091
	edid = drm_get_edid(connector, intel_gmbus_get_adapter(dev_priv, pin));
1093
	edid = drm_get_edid(connector, intel_gmbus_get_adapter(dev_priv, pin));
1092
	if (edid) {
1094
	if (edid) {
1093
		if (drm_add_edid_modes(connector, edid)) {
1095
		if (drm_add_edid_modes(connector, edid)) {
1094
			drm_mode_connector_update_edid_property(connector,
1096
			drm_mode_connector_update_edid_property(connector,
1095
								edid);
1097
								edid);
1096
		} else {
1098
		} else {
1097
			kfree(edid);
1099
			kfree(edid);
1098
			edid = ERR_PTR(-EINVAL);
1100
			edid = ERR_PTR(-EINVAL);
1099
		}
1101
		}
1100
	} else {
1102
	} else {
1101
		edid = ERR_PTR(-ENOENT);
1103
		edid = ERR_PTR(-ENOENT);
1102
	}
1104
	}
1103
	lvds_connector->base.edid = edid;
1105
	lvds_connector->base.edid = edid;
1104
 
1106
 
1105
	if (IS_ERR_OR_NULL(edid)) {
1107
	if (IS_ERR_OR_NULL(edid)) {
1106
		/* Didn't get an EDID, so
1108
		/* Didn't get an EDID, so
1107
		 * Set wide sync ranges so we get all modes
1109
		 * Set wide sync ranges so we get all modes
1108
		 * handed to valid_mode for checking
1110
		 * handed to valid_mode for checking
1109
		 */
1111
		 */
1110
		connector->display_info.min_vfreq = 0;
1112
		connector->display_info.min_vfreq = 0;
1111
		connector->display_info.max_vfreq = 200;
1113
		connector->display_info.max_vfreq = 200;
1112
		connector->display_info.min_hfreq = 0;
1114
		connector->display_info.min_hfreq = 0;
1113
		connector->display_info.max_hfreq = 200;
1115
		connector->display_info.max_hfreq = 200;
1114
	}
1116
	}
1115
 
1117
 
1116
	list_for_each_entry(scan, &connector->probed_modes, head) {
1118
	list_for_each_entry(scan, &connector->probed_modes, head) {
1117
		if (scan->type & DRM_MODE_TYPE_PREFERRED) {
1119
		if (scan->type & DRM_MODE_TYPE_PREFERRED) {
1118
			DRM_DEBUG_KMS("using preferred mode from EDID: ");
1120
			DRM_DEBUG_KMS("using preferred mode from EDID: ");
1119
			drm_mode_debug_printmodeline(scan);
1121
			drm_mode_debug_printmodeline(scan);
1120
 
1122
 
1121
			fixed_mode = drm_mode_duplicate(dev, scan);
1123
			fixed_mode = drm_mode_duplicate(dev, scan);
1122
			if (fixed_mode)
1124
			if (fixed_mode)
1123
				goto out;
1125
				goto out;
1124
		}
1126
		}
1125
	}
1127
	}
1126
 
1128
 
1127
	/* Failed to get EDID, what about VBT? */
1129
	/* Failed to get EDID, what about VBT? */
1128
	if (dev_priv->vbt.lfp_lvds_vbt_mode) {
1130
	if (dev_priv->vbt.lfp_lvds_vbt_mode) {
1129
		DRM_DEBUG_KMS("using mode from VBT: ");
1131
		DRM_DEBUG_KMS("using mode from VBT: ");
1130
		drm_mode_debug_printmodeline(dev_priv->vbt.lfp_lvds_vbt_mode);
1132
		drm_mode_debug_printmodeline(dev_priv->vbt.lfp_lvds_vbt_mode);
1131
 
1133
 
1132
		fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode);
1134
		fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode);
1133
		if (fixed_mode) {
1135
		if (fixed_mode) {
1134
			fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
1136
			fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
1135
			goto out;
1137
			goto out;
1136
		}
1138
		}
1137
	}
1139
	}
1138
 
1140
 
1139
	/*
1141
	/*
1140
	 * If we didn't get EDID, try checking if the panel is already turned
1142
	 * If we didn't get EDID, try checking if the panel is already turned
1141
	 * on.  If so, assume that whatever is currently programmed is the
1143
	 * on.  If so, assume that whatever is currently programmed is the
1142
	 * correct mode.
1144
	 * correct mode.
1143
	 */
1145
	 */
1144
 
1146
 
1145
	/* Ironlake: FIXME if still fail, not try pipe mode now */
1147
	/* Ironlake: FIXME if still fail, not try pipe mode now */
1146
	if (HAS_PCH_SPLIT(dev))
1148
	if (HAS_PCH_SPLIT(dev))
1147
		goto failed;
1149
		goto failed;
1148
 
1150
 
1149
	pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
1151
	pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
1150
	crtc = intel_get_crtc_for_pipe(dev, pipe);
1152
	crtc = intel_get_crtc_for_pipe(dev, pipe);
1151
 
1153
 
1152
	if (crtc && (lvds & LVDS_PORT_EN)) {
1154
	if (crtc && (lvds & LVDS_PORT_EN)) {
1153
		fixed_mode = intel_crtc_mode_get(dev, crtc);
1155
		fixed_mode = intel_crtc_mode_get(dev, crtc);
1154
		if (fixed_mode) {
1156
		if (fixed_mode) {
1155
			DRM_DEBUG_KMS("using current (BIOS) mode: ");
1157
			DRM_DEBUG_KMS("using current (BIOS) mode: ");
1156
			drm_mode_debug_printmodeline(fixed_mode);
1158
			drm_mode_debug_printmodeline(fixed_mode);
1157
			fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
1159
			fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
1158
			goto out;
1160
			goto out;
1159
		}
1161
		}
1160
	}
1162
	}
1161
 
1163
 
1162
	/* If we still don't have a mode after all that, give up. */
1164
	/* If we still don't have a mode after all that, give up. */
1163
	if (!fixed_mode)
1165
	if (!fixed_mode)
1164
		goto failed;
1166
		goto failed;
1165
 
1167
 
1166
out:
1168
out:
1167
	mutex_unlock(&dev->mode_config.mutex);
1169
	mutex_unlock(&dev->mode_config.mutex);
1168
 
1170
 
1169
	intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
1171
	intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
1170
 
1172
 
1171
	lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder);
1173
	lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder);
1172
	DRM_DEBUG_KMS("detected %s-link lvds configuration\n",
1174
	DRM_DEBUG_KMS("detected %s-link lvds configuration\n",
1173
		      lvds_encoder->is_dual_link ? "dual" : "single");
1175
		      lvds_encoder->is_dual_link ? "dual" : "single");
1174
 
1176
 
1175
	lvds_encoder->a3_power = lvds & LVDS_A3_POWER_MASK;
1177
	lvds_encoder->a3_power = lvds & LVDS_A3_POWER_MASK;
1176
 
1178
 
1177
	drm_connector_register(connector);
1179
	drm_connector_register(connector);
1178
 
1180
 
1179
	intel_panel_setup_backlight(connector, INVALID_PIPE);
1181
	intel_panel_setup_backlight(connector, INVALID_PIPE);
1180
 
1182
 
1181
	return;
1183
	return;
1182
 
1184
 
1183
failed:
1185
failed:
1184
	mutex_unlock(&dev->mode_config.mutex);
1186
	mutex_unlock(&dev->mode_config.mutex);
1185
 
1187
 
1186
	DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
1188
	DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
1187
	drm_connector_cleanup(connector);
1189
	drm_connector_cleanup(connector);
1188
	drm_encoder_cleanup(encoder);
1190
	drm_encoder_cleanup(encoder);
1189
	kfree(lvds_encoder);
1191
	kfree(lvds_encoder);
1190
	kfree(lvds_connector);
1192
	kfree(lvds_connector);
1191
	return;
1193
	return;
1192
}
1194
}