xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/i915/display/intel_crt.c (revision 41ec02673d281bbb3d38e6c78504ce6e30c228c1)
1 /*	$NetBSD: intel_crt.c,v 1.2 2021/12/18 23:45:29 riastradh Exp $	*/
2 
3 /*
4  * Copyright © 2006-2007 Intel Corporation
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  *
25  * Authors:
26  *	Eric Anholt <eric@anholt.net>
27  */
28 
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: intel_crt.c,v 1.2 2021/12/18 23:45:29 riastradh Exp $");
31 
32 #include <linux/dmi.h>
33 #include <linux/i2c.h>
34 #include <linux/slab.h>
35 
36 #include <drm/drm_atomic_helper.h>
37 #include <drm/drm_crtc.h>
38 #include <drm/drm_edid.h>
39 #include <drm/drm_probe_helper.h>
40 #include <drm/i915_drm.h>
41 
42 #include "i915_drv.h"
43 #include "intel_connector.h"
44 #include "intel_crt.h"
45 #include "intel_ddi.h"
46 #include "intel_display_types.h"
47 #include "intel_fifo_underrun.h"
48 #include "intel_gmbus.h"
49 #include "intel_hotplug.h"
50 
51 /* Here's the desired hotplug mode */
52 #define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 |		\
53 			   ADPA_CRT_HOTPLUG_WARMUP_10MS |		\
54 			   ADPA_CRT_HOTPLUG_SAMPLE_4S |			\
55 			   ADPA_CRT_HOTPLUG_VOLTAGE_50 |		\
56 			   ADPA_CRT_HOTPLUG_VOLREF_325MV |		\
57 			   ADPA_CRT_HOTPLUG_ENABLE)
58 
59 struct intel_crt {
60 	struct intel_encoder base;
61 	/* DPMS state is stored in the connector, which we need in the
62 	 * encoder's enable/disable callbacks */
63 	struct intel_connector *connector;
64 	bool force_hotplug_required;
65 	i915_reg_t adpa_reg;
66 };
67 
intel_encoder_to_crt(struct intel_encoder * encoder)68 static struct intel_crt *intel_encoder_to_crt(struct intel_encoder *encoder)
69 {
70 	return container_of(encoder, struct intel_crt, base);
71 }
72 
intel_attached_crt(struct intel_connector * connector)73 static struct intel_crt *intel_attached_crt(struct intel_connector *connector)
74 {
75 	return intel_encoder_to_crt(intel_attached_encoder(connector));
76 }
77 
intel_crt_port_enabled(struct drm_i915_private * dev_priv,i915_reg_t adpa_reg,enum pipe * pipe)78 bool intel_crt_port_enabled(struct drm_i915_private *dev_priv,
79 			    i915_reg_t adpa_reg, enum pipe *pipe)
80 {
81 	u32 val;
82 
83 	val = I915_READ(adpa_reg);
84 
85 	/* asserts want to know the pipe even if the port is disabled */
86 	if (HAS_PCH_CPT(dev_priv))
87 		*pipe = (val & ADPA_PIPE_SEL_MASK_CPT) >> ADPA_PIPE_SEL_SHIFT_CPT;
88 	else
89 		*pipe = (val & ADPA_PIPE_SEL_MASK) >> ADPA_PIPE_SEL_SHIFT;
90 
91 	return val & ADPA_DAC_ENABLE;
92 }
93 
intel_crt_get_hw_state(struct intel_encoder * encoder,enum pipe * pipe)94 static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
95 				   enum pipe *pipe)
96 {
97 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
98 	struct intel_crt *crt = intel_encoder_to_crt(encoder);
99 	intel_wakeref_t wakeref;
100 	bool ret;
101 
102 	wakeref = intel_display_power_get_if_enabled(dev_priv,
103 						     encoder->power_domain);
104 	if (!wakeref)
105 		return false;
106 
107 	ret = intel_crt_port_enabled(dev_priv, crt->adpa_reg, pipe);
108 
109 	intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
110 
111 	return ret;
112 }
113 
intel_crt_get_flags(struct intel_encoder * encoder)114 static unsigned int intel_crt_get_flags(struct intel_encoder *encoder)
115 {
116 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
117 	struct intel_crt *crt = intel_encoder_to_crt(encoder);
118 	u32 tmp, flags = 0;
119 
120 	tmp = I915_READ(crt->adpa_reg);
121 
122 	if (tmp & ADPA_HSYNC_ACTIVE_HIGH)
123 		flags |= DRM_MODE_FLAG_PHSYNC;
124 	else
125 		flags |= DRM_MODE_FLAG_NHSYNC;
126 
127 	if (tmp & ADPA_VSYNC_ACTIVE_HIGH)
128 		flags |= DRM_MODE_FLAG_PVSYNC;
129 	else
130 		flags |= DRM_MODE_FLAG_NVSYNC;
131 
132 	return flags;
133 }
134 
intel_crt_get_config(struct intel_encoder * encoder,struct intel_crtc_state * pipe_config)135 static void intel_crt_get_config(struct intel_encoder *encoder,
136 				 struct intel_crtc_state *pipe_config)
137 {
138 	pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
139 
140 	pipe_config->hw.adjusted_mode.flags |= intel_crt_get_flags(encoder);
141 
142 	pipe_config->hw.adjusted_mode.crtc_clock = pipe_config->port_clock;
143 }
144 
hsw_crt_get_config(struct intel_encoder * encoder,struct intel_crtc_state * pipe_config)145 static void hsw_crt_get_config(struct intel_encoder *encoder,
146 			       struct intel_crtc_state *pipe_config)
147 {
148 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
149 
150 	intel_ddi_get_config(encoder, pipe_config);
151 
152 	pipe_config->hw.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
153 					      DRM_MODE_FLAG_NHSYNC |
154 					      DRM_MODE_FLAG_PVSYNC |
155 					      DRM_MODE_FLAG_NVSYNC);
156 	pipe_config->hw.adjusted_mode.flags |= intel_crt_get_flags(encoder);
157 
158 	pipe_config->hw.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv);
159 }
160 
161 /* Note: The caller is required to filter out dpms modes not supported by the
162  * platform. */
intel_crt_set_dpms(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,int mode)163 static void intel_crt_set_dpms(struct intel_encoder *encoder,
164 			       const struct intel_crtc_state *crtc_state,
165 			       int mode)
166 {
167 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
168 	struct intel_crt *crt = intel_encoder_to_crt(encoder);
169 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
170 	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
171 	u32 adpa;
172 
173 	if (INTEL_GEN(dev_priv) >= 5)
174 		adpa = ADPA_HOTPLUG_BITS;
175 	else
176 		adpa = 0;
177 
178 	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
179 		adpa |= ADPA_HSYNC_ACTIVE_HIGH;
180 	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
181 		adpa |= ADPA_VSYNC_ACTIVE_HIGH;
182 
183 	/* For CPT allow 3 pipe config, for others just use A or B */
184 	if (HAS_PCH_LPT(dev_priv))
185 		; /* Those bits don't exist here */
186 	else if (HAS_PCH_CPT(dev_priv))
187 		adpa |= ADPA_PIPE_SEL_CPT(crtc->pipe);
188 	else
189 		adpa |= ADPA_PIPE_SEL(crtc->pipe);
190 
191 	if (!HAS_PCH_SPLIT(dev_priv))
192 		I915_WRITE(BCLRPAT(crtc->pipe), 0);
193 
194 	switch (mode) {
195 	case DRM_MODE_DPMS_ON:
196 		adpa |= ADPA_DAC_ENABLE;
197 		break;
198 	case DRM_MODE_DPMS_STANDBY:
199 		adpa |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE;
200 		break;
201 	case DRM_MODE_DPMS_SUSPEND:
202 		adpa |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE;
203 		break;
204 	case DRM_MODE_DPMS_OFF:
205 		adpa |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
206 		break;
207 	}
208 
209 	I915_WRITE(crt->adpa_reg, adpa);
210 }
211 
intel_disable_crt(struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)212 static void intel_disable_crt(struct intel_encoder *encoder,
213 			      const struct intel_crtc_state *old_crtc_state,
214 			      const struct drm_connector_state *old_conn_state)
215 {
216 	intel_crt_set_dpms(encoder, old_crtc_state, DRM_MODE_DPMS_OFF);
217 }
218 
pch_disable_crt(struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)219 static void pch_disable_crt(struct intel_encoder *encoder,
220 			    const struct intel_crtc_state *old_crtc_state,
221 			    const struct drm_connector_state *old_conn_state)
222 {
223 }
224 
pch_post_disable_crt(struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)225 static void pch_post_disable_crt(struct intel_encoder *encoder,
226 				 const struct intel_crtc_state *old_crtc_state,
227 				 const struct drm_connector_state *old_conn_state)
228 {
229 	intel_disable_crt(encoder, old_crtc_state, old_conn_state);
230 }
231 
hsw_disable_crt(struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)232 static void hsw_disable_crt(struct intel_encoder *encoder,
233 			    const struct intel_crtc_state *old_crtc_state,
234 			    const struct drm_connector_state *old_conn_state)
235 {
236 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
237 
238 	WARN_ON(!old_crtc_state->has_pch_encoder);
239 
240 	intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
241 }
242 
hsw_post_disable_crt(struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)243 static void hsw_post_disable_crt(struct intel_encoder *encoder,
244 				 const struct intel_crtc_state *old_crtc_state,
245 				 const struct drm_connector_state *old_conn_state)
246 {
247 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
248 
249 	intel_crtc_vblank_off(old_crtc_state);
250 
251 	intel_disable_pipe(old_crtc_state);
252 
253 	intel_ddi_disable_transcoder_func(old_crtc_state);
254 
255 	ilk_pfit_disable(old_crtc_state);
256 
257 	intel_ddi_disable_pipe_clock(old_crtc_state);
258 
259 	pch_post_disable_crt(encoder, old_crtc_state, old_conn_state);
260 
261 	lpt_disable_pch_transcoder(dev_priv);
262 	lpt_disable_iclkip(dev_priv);
263 
264 	intel_ddi_fdi_post_disable(encoder, old_crtc_state, old_conn_state);
265 
266 	WARN_ON(!old_crtc_state->has_pch_encoder);
267 
268 	intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
269 }
270 
hsw_pre_pll_enable_crt(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)271 static void hsw_pre_pll_enable_crt(struct intel_encoder *encoder,
272 				   const struct intel_crtc_state *crtc_state,
273 				   const struct drm_connector_state *conn_state)
274 {
275 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
276 
277 	WARN_ON(!crtc_state->has_pch_encoder);
278 
279 	intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
280 }
281 
hsw_pre_enable_crt(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)282 static void hsw_pre_enable_crt(struct intel_encoder *encoder,
283 			       const struct intel_crtc_state *crtc_state,
284 			       const struct drm_connector_state *conn_state)
285 {
286 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
287 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
288 	enum pipe pipe = crtc->pipe;
289 
290 	WARN_ON(!crtc_state->has_pch_encoder);
291 
292 	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
293 
294 	hsw_fdi_link_train(encoder, crtc_state);
295 
296 	intel_ddi_enable_pipe_clock(crtc_state);
297 }
298 
hsw_enable_crt(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)299 static void hsw_enable_crt(struct intel_encoder *encoder,
300 			   const struct intel_crtc_state *crtc_state,
301 			   const struct drm_connector_state *conn_state)
302 {
303 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
304 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
305 	enum pipe pipe = crtc->pipe;
306 
307 	WARN_ON(!crtc_state->has_pch_encoder);
308 
309 	intel_crt_set_dpms(encoder, crtc_state, DRM_MODE_DPMS_ON);
310 
311 	intel_wait_for_vblank(dev_priv, pipe);
312 	intel_wait_for_vblank(dev_priv, pipe);
313 	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
314 	intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
315 }
316 
intel_enable_crt(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)317 static void intel_enable_crt(struct intel_encoder *encoder,
318 			     const struct intel_crtc_state *crtc_state,
319 			     const struct drm_connector_state *conn_state)
320 {
321 	intel_crt_set_dpms(encoder, crtc_state, DRM_MODE_DPMS_ON);
322 }
323 
324 static enum drm_mode_status
intel_crt_mode_valid(struct drm_connector * connector,struct drm_display_mode * mode)325 intel_crt_mode_valid(struct drm_connector *connector,
326 		     struct drm_display_mode *mode)
327 {
328 	struct drm_device *dev = connector->dev;
329 	struct drm_i915_private *dev_priv = to_i915(dev);
330 	int max_dotclk = dev_priv->max_dotclk_freq;
331 	int max_clock;
332 
333 	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
334 		return MODE_NO_DBLESCAN;
335 
336 	if (mode->clock < 25000)
337 		return MODE_CLOCK_LOW;
338 
339 	if (HAS_PCH_LPT(dev_priv))
340 		max_clock = 180000;
341 	else if (IS_VALLEYVIEW(dev_priv))
342 		/*
343 		 * 270 MHz due to current DPLL limits,
344 		 * DAC limit supposedly 355 MHz.
345 		 */
346 		max_clock = 270000;
347 	else if (IS_GEN_RANGE(dev_priv, 3, 4))
348 		max_clock = 400000;
349 	else
350 		max_clock = 350000;
351 	if (mode->clock > max_clock)
352 		return MODE_CLOCK_HIGH;
353 
354 	if (mode->clock > max_dotclk)
355 		return MODE_CLOCK_HIGH;
356 
357 	/* The FDI receiver on LPT only supports 8bpc and only has 2 lanes. */
358 	if (HAS_PCH_LPT(dev_priv) &&
359 	    ilk_get_lanes_required(mode->clock, 270000, 24) > 2)
360 		return MODE_CLOCK_HIGH;
361 
362 	/* HSW/BDW FDI limited to 4k */
363 	if (mode->hdisplay > 4096)
364 		return MODE_H_ILLEGAL;
365 
366 	return MODE_OK;
367 }
368 
intel_crt_compute_config(struct intel_encoder * encoder,struct intel_crtc_state * pipe_config,struct drm_connector_state * conn_state)369 static int intel_crt_compute_config(struct intel_encoder *encoder,
370 				    struct intel_crtc_state *pipe_config,
371 				    struct drm_connector_state *conn_state)
372 {
373 	struct drm_display_mode *adjusted_mode =
374 		&pipe_config->hw.adjusted_mode;
375 
376 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
377 		return -EINVAL;
378 
379 	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
380 
381 	return 0;
382 }
383 
pch_crt_compute_config(struct intel_encoder * encoder,struct intel_crtc_state * pipe_config,struct drm_connector_state * conn_state)384 static int pch_crt_compute_config(struct intel_encoder *encoder,
385 				  struct intel_crtc_state *pipe_config,
386 				  struct drm_connector_state *conn_state)
387 {
388 	struct drm_display_mode *adjusted_mode =
389 		&pipe_config->hw.adjusted_mode;
390 
391 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
392 		return -EINVAL;
393 
394 	pipe_config->has_pch_encoder = true;
395 	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
396 
397 	return 0;
398 }
399 
hsw_crt_compute_config(struct intel_encoder * encoder,struct intel_crtc_state * pipe_config,struct drm_connector_state * conn_state)400 static int hsw_crt_compute_config(struct intel_encoder *encoder,
401 				  struct intel_crtc_state *pipe_config,
402 				  struct drm_connector_state *conn_state)
403 {
404 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
405 	struct drm_display_mode *adjusted_mode =
406 		&pipe_config->hw.adjusted_mode;
407 
408 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
409 		return -EINVAL;
410 
411 	/* HSW/BDW FDI limited to 4k */
412 	if (adjusted_mode->crtc_hdisplay > 4096 ||
413 	    adjusted_mode->crtc_hblank_start > 4096)
414 		return -EINVAL;
415 
416 	pipe_config->has_pch_encoder = true;
417 	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
418 
419 	/* LPT FDI RX only supports 8bpc. */
420 	if (HAS_PCH_LPT(dev_priv)) {
421 		if (pipe_config->bw_constrained && pipe_config->pipe_bpp < 24) {
422 			DRM_DEBUG_KMS("LPT only supports 24bpp\n");
423 			return -EINVAL;
424 		}
425 
426 		pipe_config->pipe_bpp = 24;
427 	}
428 
429 	/* FDI must always be 2.7 GHz */
430 	pipe_config->port_clock = 135000 * 2;
431 
432 	return 0;
433 }
434 
ilk_crt_detect_hotplug(struct drm_connector * connector)435 static bool ilk_crt_detect_hotplug(struct drm_connector *connector)
436 {
437 	struct drm_device *dev = connector->dev;
438 	struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
439 	struct drm_i915_private *dev_priv = to_i915(dev);
440 	u32 adpa;
441 	bool ret;
442 
443 	/* The first time through, trigger an explicit detection cycle */
444 	if (crt->force_hotplug_required) {
445 		bool turn_off_dac = HAS_PCH_SPLIT(dev_priv);
446 		u32 save_adpa;
447 
448 		crt->force_hotplug_required = false;
449 
450 		save_adpa = adpa = I915_READ(crt->adpa_reg);
451 		DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa);
452 
453 		adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER;
454 		if (turn_off_dac)
455 			adpa &= ~ADPA_DAC_ENABLE;
456 
457 		I915_WRITE(crt->adpa_reg, adpa);
458 
459 		if (intel_de_wait_for_clear(dev_priv,
460 					    crt->adpa_reg,
461 					    ADPA_CRT_HOTPLUG_FORCE_TRIGGER,
462 					    1000))
463 			DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER");
464 
465 		if (turn_off_dac) {
466 			I915_WRITE(crt->adpa_reg, save_adpa);
467 			POSTING_READ(crt->adpa_reg);
468 		}
469 	}
470 
471 	/* Check the status to see if both blue and green are on now */
472 	adpa = I915_READ(crt->adpa_reg);
473 	if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0)
474 		ret = true;
475 	else
476 		ret = false;
477 	DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret);
478 
479 	return ret;
480 }
481 
valleyview_crt_detect_hotplug(struct drm_connector * connector)482 static bool valleyview_crt_detect_hotplug(struct drm_connector *connector)
483 {
484 	struct drm_device *dev = connector->dev;
485 	struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
486 	struct drm_i915_private *dev_priv = to_i915(dev);
487 	bool reenable_hpd;
488 	u32 adpa;
489 	bool ret;
490 	u32 save_adpa;
491 
492 	/*
493 	 * Doing a force trigger causes a hpd interrupt to get sent, which can
494 	 * get us stuck in a loop if we're polling:
495 	 *  - We enable power wells and reset the ADPA
496 	 *  - output_poll_exec does force probe on VGA, triggering a hpd
497 	 *  - HPD handler waits for poll to unlock dev->mode_config.mutex
498 	 *  - output_poll_exec shuts off the ADPA, unlocks
499 	 *    dev->mode_config.mutex
500 	 *  - HPD handler runs, resets ADPA and brings us back to the start
501 	 *
502 	 * Just disable HPD interrupts here to prevent this
503 	 */
504 	reenable_hpd = intel_hpd_disable(dev_priv, crt->base.hpd_pin);
505 
506 	save_adpa = adpa = I915_READ(crt->adpa_reg);
507 	DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa);
508 
509 	adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER;
510 
511 	I915_WRITE(crt->adpa_reg, adpa);
512 
513 	if (intel_de_wait_for_clear(dev_priv, crt->adpa_reg,
514 				    ADPA_CRT_HOTPLUG_FORCE_TRIGGER, 1000)) {
515 		DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER");
516 		I915_WRITE(crt->adpa_reg, save_adpa);
517 	}
518 
519 	/* Check the status to see if both blue and green are on now */
520 	adpa = I915_READ(crt->adpa_reg);
521 	if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0)
522 		ret = true;
523 	else
524 		ret = false;
525 
526 	DRM_DEBUG_KMS("valleyview hotplug adpa=0x%x, result %d\n", adpa, ret);
527 
528 	if (reenable_hpd)
529 		intel_hpd_enable(dev_priv, crt->base.hpd_pin);
530 
531 	return ret;
532 }
533 
intel_crt_detect_hotplug(struct drm_connector * connector)534 static bool intel_crt_detect_hotplug(struct drm_connector *connector)
535 {
536 	struct drm_device *dev = connector->dev;
537 	struct drm_i915_private *dev_priv = to_i915(dev);
538 	u32 stat;
539 	bool ret = false;
540 	int i, tries = 0;
541 
542 	if (HAS_PCH_SPLIT(dev_priv))
543 		return ilk_crt_detect_hotplug(connector);
544 
545 	if (IS_VALLEYVIEW(dev_priv))
546 		return valleyview_crt_detect_hotplug(connector);
547 
548 	/*
549 	 * On 4 series desktop, CRT detect sequence need to be done twice
550 	 * to get a reliable result.
551 	 */
552 
553 	if (IS_G45(dev_priv))
554 		tries = 2;
555 	else
556 		tries = 1;
557 
558 	for (i = 0; i < tries ; i++) {
559 		/* turn on the FORCE_DETECT */
560 		i915_hotplug_interrupt_update(dev_priv,
561 					      CRT_HOTPLUG_FORCE_DETECT,
562 					      CRT_HOTPLUG_FORCE_DETECT);
563 		/* wait for FORCE_DETECT to go off */
564 		if (intel_de_wait_for_clear(dev_priv, PORT_HOTPLUG_EN,
565 					    CRT_HOTPLUG_FORCE_DETECT, 1000))
566 			DRM_DEBUG_KMS("timed out waiting for FORCE_DETECT to go off");
567 	}
568 
569 	stat = I915_READ(PORT_HOTPLUG_STAT);
570 	if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE)
571 		ret = true;
572 
573 	/* clear the interrupt we just generated, if any */
574 	I915_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS);
575 
576 	i915_hotplug_interrupt_update(dev_priv, CRT_HOTPLUG_FORCE_DETECT, 0);
577 
578 	return ret;
579 }
580 
intel_crt_get_edid(struct drm_connector * connector,struct i2c_adapter * i2c)581 static struct edid *intel_crt_get_edid(struct drm_connector *connector,
582 				struct i2c_adapter *i2c)
583 {
584 	struct edid *edid;
585 
586 	edid = drm_get_edid(connector, i2c);
587 
588 	if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
589 		DRM_DEBUG_KMS("CRT GMBUS EDID read failed, retry using GPIO bit-banging\n");
590 		intel_gmbus_force_bit(i2c, true);
591 		edid = drm_get_edid(connector, i2c);
592 		intel_gmbus_force_bit(i2c, false);
593 	}
594 
595 	return edid;
596 }
597 
598 /* local version of intel_ddc_get_modes() to use intel_crt_get_edid() */
intel_crt_ddc_get_modes(struct drm_connector * connector,struct i2c_adapter * adapter)599 static int intel_crt_ddc_get_modes(struct drm_connector *connector,
600 				struct i2c_adapter *adapter)
601 {
602 	struct edid *edid;
603 	int ret;
604 
605 	edid = intel_crt_get_edid(connector, adapter);
606 	if (!edid)
607 		return 0;
608 
609 	ret = intel_connector_update_modes(connector, edid);
610 	kfree(edid);
611 
612 	return ret;
613 }
614 
intel_crt_detect_ddc(struct drm_connector * connector)615 static bool intel_crt_detect_ddc(struct drm_connector *connector)
616 {
617 	struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
618 	struct drm_i915_private *dev_priv = to_i915(crt->base.base.dev);
619 	struct edid *edid;
620 	struct i2c_adapter *i2c;
621 	bool ret = false;
622 
623 	BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG);
624 
625 	i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin);
626 	edid = intel_crt_get_edid(connector, i2c);
627 
628 	if (edid) {
629 		bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL;
630 
631 		/*
632 		 * This may be a DVI-I connector with a shared DDC
633 		 * link between analog and digital outputs, so we
634 		 * have to check the EDID input spec of the attached device.
635 		 */
636 		if (!is_digital) {
637 			DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
638 			ret = true;
639 		} else {
640 			DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n");
641 		}
642 	} else {
643 		DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [no valid EDID found]\n");
644 	}
645 
646 	kfree(edid);
647 
648 	return ret;
649 }
650 
651 static enum drm_connector_status
intel_crt_load_detect(struct intel_crt * crt,u32 pipe)652 intel_crt_load_detect(struct intel_crt *crt, u32 pipe)
653 {
654 	struct drm_device *dev = crt->base.base.dev;
655 	struct drm_i915_private *dev_priv = to_i915(dev);
656 	struct intel_uncore *uncore = &dev_priv->uncore;
657 	u32 save_bclrpat;
658 	u32 save_vtotal;
659 	u32 vtotal, vactive;
660 	u32 vsample;
661 	u32 vblank, vblank_start, vblank_end;
662 	u32 dsl;
663 	i915_reg_t bclrpat_reg, vtotal_reg,
664 		vblank_reg, vsync_reg, pipeconf_reg, pipe_dsl_reg;
665 	u8 st00;
666 	enum drm_connector_status status;
667 
668 	DRM_DEBUG_KMS("starting load-detect on CRT\n");
669 
670 	bclrpat_reg = BCLRPAT(pipe);
671 	vtotal_reg = VTOTAL(pipe);
672 	vblank_reg = VBLANK(pipe);
673 	vsync_reg = VSYNC(pipe);
674 	pipeconf_reg = PIPECONF(pipe);
675 	pipe_dsl_reg = PIPEDSL(pipe);
676 
677 	save_bclrpat = intel_uncore_read(uncore, bclrpat_reg);
678 	save_vtotal = intel_uncore_read(uncore, vtotal_reg);
679 	vblank = intel_uncore_read(uncore, vblank_reg);
680 
681 	vtotal = ((save_vtotal >> 16) & 0xfff) + 1;
682 	vactive = (save_vtotal & 0x7ff) + 1;
683 
684 	vblank_start = (vblank & 0xfff) + 1;
685 	vblank_end = ((vblank >> 16) & 0xfff) + 1;
686 
687 	/* Set the border color to purple. */
688 	intel_uncore_write(uncore, bclrpat_reg, 0x500050);
689 
690 	if (!IS_GEN(dev_priv, 2)) {
691 		u32 pipeconf = intel_uncore_read(uncore, pipeconf_reg);
692 		intel_uncore_write(uncore,
693 				   pipeconf_reg,
694 				   pipeconf | PIPECONF_FORCE_BORDER);
695 		intel_uncore_posting_read(uncore, pipeconf_reg);
696 		/* Wait for next Vblank to substitue
697 		 * border color for Color info */
698 		intel_wait_for_vblank(dev_priv, pipe);
699 		st00 = intel_uncore_read8(uncore, _VGA_MSR_WRITE);
700 		status = ((st00 & (1 << 4)) != 0) ?
701 			connector_status_connected :
702 			connector_status_disconnected;
703 
704 		intel_uncore_write(uncore, pipeconf_reg, pipeconf);
705 	} else {
706 		bool restore_vblank = false;
707 		int count, detect;
708 
709 		/*
710 		* If there isn't any border, add some.
711 		* Yes, this will flicker
712 		*/
713 		if (vblank_start <= vactive && vblank_end >= vtotal) {
714 			u32 vsync = I915_READ(vsync_reg);
715 			u32 vsync_start = (vsync & 0xffff) + 1;
716 
717 			vblank_start = vsync_start;
718 			intel_uncore_write(uncore,
719 					   vblank_reg,
720 					   (vblank_start - 1) |
721 					   ((vblank_end - 1) << 16));
722 			restore_vblank = true;
723 		}
724 		/* sample in the vertical border, selecting the larger one */
725 		if (vblank_start - vactive >= vtotal - vblank_end)
726 			vsample = (vblank_start + vactive) >> 1;
727 		else
728 			vsample = (vtotal + vblank_end) >> 1;
729 
730 		/*
731 		 * Wait for the border to be displayed
732 		 */
733 		while (intel_uncore_read(uncore, pipe_dsl_reg) >= vactive)
734 			;
735 		while ((dsl = intel_uncore_read(uncore, pipe_dsl_reg)) <=
736 		       vsample)
737 			;
738 		/*
739 		 * Watch ST00 for an entire scanline
740 		 */
741 		detect = 0;
742 		count = 0;
743 		do {
744 			count++;
745 			/* Read the ST00 VGA status register */
746 			st00 = intel_uncore_read8(uncore, _VGA_MSR_WRITE);
747 			if (st00 & (1 << 4))
748 				detect++;
749 		} while ((intel_uncore_read(uncore, pipe_dsl_reg) == dsl));
750 
751 		/* restore vblank if necessary */
752 		if (restore_vblank)
753 			intel_uncore_write(uncore, vblank_reg, vblank);
754 		/*
755 		 * If more than 3/4 of the scanline detected a monitor,
756 		 * then it is assumed to be present. This works even on i830,
757 		 * where there isn't any way to force the border color across
758 		 * the screen
759 		 */
760 		status = detect * 4 > count * 3 ?
761 			 connector_status_connected :
762 			 connector_status_disconnected;
763 	}
764 
765 	/* Restore previous settings */
766 	intel_uncore_write(uncore, bclrpat_reg, save_bclrpat);
767 
768 	return status;
769 }
770 
intel_spurious_crt_detect_dmi_callback(const struct dmi_system_id * id)771 static int intel_spurious_crt_detect_dmi_callback(const struct dmi_system_id *id)
772 {
773 	DRM_DEBUG_DRIVER("Skipping CRT detection for %s\n", id->ident);
774 	return 1;
775 }
776 
777 static const struct dmi_system_id intel_spurious_crt_detect[] = {
778 	{
779 		.callback = intel_spurious_crt_detect_dmi_callback,
780 		.ident = "ACER ZGB",
781 		.matches = {
782 			DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
783 			DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"),
784 		},
785 	},
786 	{
787 		.callback = intel_spurious_crt_detect_dmi_callback,
788 		.ident = "Intel DZ77BH-55K",
789 		.matches = {
790 			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
791 			DMI_MATCH(DMI_BOARD_NAME, "DZ77BH-55K"),
792 		},
793 	},
794 	{ }
795 };
796 
797 static int
intel_crt_detect(struct drm_connector * connector,struct drm_modeset_acquire_ctx * ctx,bool force)798 intel_crt_detect(struct drm_connector *connector,
799 		 struct drm_modeset_acquire_ctx *ctx,
800 		 bool force)
801 {
802 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
803 	struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
804 	struct intel_encoder *intel_encoder = &crt->base;
805 	intel_wakeref_t wakeref;
806 	int status, ret;
807 	struct intel_load_detect_pipe tmp;
808 
809 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
810 		      connector->base.id, connector->name,
811 		      force);
812 
813 	if (i915_modparams.load_detect_test) {
814 		wakeref = intel_display_power_get(dev_priv,
815 						  intel_encoder->power_domain);
816 		goto load_detect;
817 	}
818 
819 	/* Skip machines without VGA that falsely report hotplug events */
820 	if (dmi_check_system(intel_spurious_crt_detect))
821 		return connector_status_disconnected;
822 
823 	wakeref = intel_display_power_get(dev_priv,
824 					  intel_encoder->power_domain);
825 
826 	if (I915_HAS_HOTPLUG(dev_priv)) {
827 		/* We can not rely on the HPD pin always being correctly wired
828 		 * up, for example many KVM do not pass it through, and so
829 		 * only trust an assertion that the monitor is connected.
830 		 */
831 		if (intel_crt_detect_hotplug(connector)) {
832 			DRM_DEBUG_KMS("CRT detected via hotplug\n");
833 			status = connector_status_connected;
834 			goto out;
835 		} else
836 			DRM_DEBUG_KMS("CRT not detected via hotplug\n");
837 	}
838 
839 	if (intel_crt_detect_ddc(connector)) {
840 		status = connector_status_connected;
841 		goto out;
842 	}
843 
844 	/* Load detection is broken on HPD capable machines. Whoever wants a
845 	 * broken monitor (without edid) to work behind a broken kvm (that fails
846 	 * to have the right resistors for HP detection) needs to fix this up.
847 	 * For now just bail out. */
848 	if (I915_HAS_HOTPLUG(dev_priv)) {
849 		status = connector_status_disconnected;
850 		goto out;
851 	}
852 
853 load_detect:
854 	if (!force) {
855 		status = connector->status;
856 		goto out;
857 	}
858 
859 	/* for pre-945g platforms use load detect */
860 	ret = intel_get_load_detect_pipe(connector, &tmp, ctx);
861 	if (ret > 0) {
862 		if (intel_crt_detect_ddc(connector))
863 			status = connector_status_connected;
864 		else if (INTEL_GEN(dev_priv) < 4)
865 			status = intel_crt_load_detect(crt,
866 				to_intel_crtc(connector->state->crtc)->pipe);
867 		else if (i915_modparams.load_detect_test)
868 			status = connector_status_disconnected;
869 		else
870 			status = connector_status_unknown;
871 		intel_release_load_detect_pipe(connector, &tmp, ctx);
872 	} else if (ret == 0) {
873 		status = connector_status_unknown;
874 	} else {
875 		status = ret;
876 	}
877 
878 out:
879 	intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
880 
881 	/*
882 	 * Make sure the refs for power wells enabled during detect are
883 	 * dropped to avoid a new detect cycle triggered by HPD polling.
884 	 */
885 	intel_display_power_flush_work(dev_priv);
886 
887 	return status;
888 }
889 
intel_crt_get_modes(struct drm_connector * connector)890 static int intel_crt_get_modes(struct drm_connector *connector)
891 {
892 	struct drm_device *dev = connector->dev;
893 	struct drm_i915_private *dev_priv = to_i915(dev);
894 	struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
895 	struct intel_encoder *intel_encoder = &crt->base;
896 	intel_wakeref_t wakeref;
897 	struct i2c_adapter *i2c;
898 	int ret;
899 
900 	wakeref = intel_display_power_get(dev_priv,
901 					  intel_encoder->power_domain);
902 
903 	i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin);
904 	ret = intel_crt_ddc_get_modes(connector, i2c);
905 	if (ret || !IS_G4X(dev_priv))
906 		goto out;
907 
908 	/* Try to probe digital port for output in DVI-I -> VGA mode. */
909 	i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PIN_DPB);
910 	ret = intel_crt_ddc_get_modes(connector, i2c);
911 
912 out:
913 	intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
914 
915 	return ret;
916 }
917 
intel_crt_reset(struct drm_encoder * encoder)918 void intel_crt_reset(struct drm_encoder *encoder)
919 {
920 	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
921 	struct intel_crt *crt = intel_encoder_to_crt(to_intel_encoder(encoder));
922 
923 	if (INTEL_GEN(dev_priv) >= 5) {
924 		u32 adpa;
925 
926 		adpa = I915_READ(crt->adpa_reg);
927 		adpa &= ~ADPA_CRT_HOTPLUG_MASK;
928 		adpa |= ADPA_HOTPLUG_BITS;
929 		I915_WRITE(crt->adpa_reg, adpa);
930 		POSTING_READ(crt->adpa_reg);
931 
932 		DRM_DEBUG_KMS("crt adpa set to 0x%x\n", adpa);
933 		crt->force_hotplug_required = true;
934 	}
935 
936 }
937 
938 /*
939  * Routines for controlling stuff on the analog port
940  */
941 
942 static const struct drm_connector_funcs intel_crt_connector_funcs = {
943 	.fill_modes = drm_helper_probe_single_connector_modes,
944 	.late_register = intel_connector_register,
945 	.early_unregister = intel_connector_unregister,
946 	.destroy = intel_connector_destroy,
947 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
948 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
949 };
950 
951 static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = {
952 	.detect_ctx = intel_crt_detect,
953 	.mode_valid = intel_crt_mode_valid,
954 	.get_modes = intel_crt_get_modes,
955 };
956 
957 static const struct drm_encoder_funcs intel_crt_enc_funcs = {
958 	.reset = intel_crt_reset,
959 	.destroy = intel_encoder_destroy,
960 };
961 
intel_crt_init(struct drm_i915_private * dev_priv)962 void intel_crt_init(struct drm_i915_private *dev_priv)
963 {
964 	struct drm_connector *connector;
965 	struct intel_crt *crt;
966 	struct intel_connector *intel_connector;
967 	i915_reg_t adpa_reg;
968 	u32 adpa;
969 
970 	if (HAS_PCH_SPLIT(dev_priv))
971 		adpa_reg = PCH_ADPA;
972 	else if (IS_VALLEYVIEW(dev_priv))
973 		adpa_reg = VLV_ADPA;
974 	else
975 		adpa_reg = ADPA;
976 
977 	adpa = I915_READ(adpa_reg);
978 	if ((adpa & ADPA_DAC_ENABLE) == 0) {
979 		/*
980 		 * On some machines (some IVB at least) CRT can be
981 		 * fused off, but there's no known fuse bit to
982 		 * indicate that. On these machine the ADPA register
983 		 * works normally, except the DAC enable bit won't
984 		 * take. So the only way to tell is attempt to enable
985 		 * it and see what happens.
986 		 */
987 		I915_WRITE(adpa_reg, adpa | ADPA_DAC_ENABLE |
988 			   ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
989 		if ((I915_READ(adpa_reg) & ADPA_DAC_ENABLE) == 0)
990 			return;
991 		I915_WRITE(adpa_reg, adpa);
992 	}
993 
994 	crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL);
995 	if (!crt)
996 		return;
997 
998 	intel_connector = intel_connector_alloc();
999 	if (!intel_connector) {
1000 		kfree(crt);
1001 		return;
1002 	}
1003 
1004 	connector = &intel_connector->base;
1005 	crt->connector = intel_connector;
1006 	drm_connector_init(&dev_priv->drm, &intel_connector->base,
1007 			   &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
1008 
1009 	drm_encoder_init(&dev_priv->drm, &crt->base.base, &intel_crt_enc_funcs,
1010 			 DRM_MODE_ENCODER_DAC, "CRT");
1011 
1012 	intel_connector_attach_encoder(intel_connector, &crt->base);
1013 
1014 	crt->base.type = INTEL_OUTPUT_ANALOG;
1015 	crt->base.cloneable = (1 << INTEL_OUTPUT_DVO) | (1 << INTEL_OUTPUT_HDMI);
1016 	if (IS_I830(dev_priv))
1017 		crt->base.pipe_mask = BIT(PIPE_A);
1018 	else
1019 		crt->base.pipe_mask = ~0;
1020 
1021 	if (IS_GEN(dev_priv, 2))
1022 		connector->interlace_allowed = 0;
1023 	else
1024 		connector->interlace_allowed = 1;
1025 	connector->doublescan_allowed = 0;
1026 
1027 	crt->adpa_reg = adpa_reg;
1028 
1029 	crt->base.power_domain = POWER_DOMAIN_PORT_CRT;
1030 
1031 	if (I915_HAS_HOTPLUG(dev_priv) &&
1032 	    !dmi_check_system(intel_spurious_crt_detect)) {
1033 		crt->base.hpd_pin = HPD_CRT;
1034 		crt->base.hotplug = intel_encoder_hotplug;
1035 	}
1036 
1037 	if (HAS_DDI(dev_priv)) {
1038 		crt->base.port = PORT_E;
1039 		crt->base.get_config = hsw_crt_get_config;
1040 		crt->base.get_hw_state = intel_ddi_get_hw_state;
1041 		crt->base.compute_config = hsw_crt_compute_config;
1042 		crt->base.pre_pll_enable = hsw_pre_pll_enable_crt;
1043 		crt->base.pre_enable = hsw_pre_enable_crt;
1044 		crt->base.enable = hsw_enable_crt;
1045 		crt->base.disable = hsw_disable_crt;
1046 		crt->base.post_disable = hsw_post_disable_crt;
1047 	} else {
1048 		if (HAS_PCH_SPLIT(dev_priv)) {
1049 			crt->base.compute_config = pch_crt_compute_config;
1050 			crt->base.disable = pch_disable_crt;
1051 			crt->base.post_disable = pch_post_disable_crt;
1052 		} else {
1053 			crt->base.compute_config = intel_crt_compute_config;
1054 			crt->base.disable = intel_disable_crt;
1055 		}
1056 		crt->base.port = PORT_NONE;
1057 		crt->base.get_config = intel_crt_get_config;
1058 		crt->base.get_hw_state = intel_crt_get_hw_state;
1059 		crt->base.enable = intel_enable_crt;
1060 	}
1061 	intel_connector->get_hw_state = intel_connector_get_hw_state;
1062 
1063 	drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
1064 
1065 	if (!I915_HAS_HOTPLUG(dev_priv))
1066 		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1067 
1068 	/*
1069 	 * Configure the automatic hotplug detection stuff
1070 	 */
1071 	crt->force_hotplug_required = false;
1072 
1073 	/*
1074 	 * TODO: find a proper way to discover whether we need to set the the
1075 	 * polarity and link reversal bits or not, instead of relying on the
1076 	 * BIOS.
1077 	 */
1078 	if (HAS_PCH_LPT(dev_priv)) {
1079 		u32 fdi_config = FDI_RX_POLARITY_REVERSED_LPT |
1080 				 FDI_RX_LINK_REVERSAL_OVERRIDE;
1081 
1082 		dev_priv->fdi_rx_config = I915_READ(FDI_RX_CTL(PIPE_A)) & fdi_config;
1083 	}
1084 
1085 	intel_crt_reset(&crt->base.base);
1086 }
1087