Merge branch 'spi/merge' of git://git.secretlab.ca/git/linux-2.6
[pandora-kernel.git] / drivers / gpu / drm / i915 / intel_crt.c
1 /*
2  * Copyright © 2006-2007 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *      Eric Anholt <eric@anholt.net>
25  */
26
27 #include <linux/i2c.h>
28 #include <linux/slab.h>
29 #include "drmP.h"
30 #include "drm.h"
31 #include "drm_crtc.h"
32 #include "drm_crtc_helper.h"
33 #include "drm_edid.h"
34 #include "intel_drv.h"
35 #include "i915_drm.h"
36 #include "i915_drv.h"
37
38 /* Here's the desired hotplug mode */
39 #define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 |                \
40                            ADPA_CRT_HOTPLUG_WARMUP_10MS |               \
41                            ADPA_CRT_HOTPLUG_SAMPLE_4S |                 \
42                            ADPA_CRT_HOTPLUG_VOLTAGE_50 |                \
43                            ADPA_CRT_HOTPLUG_VOLREF_325MV |              \
44                            ADPA_CRT_HOTPLUG_ENABLE)
45
46 struct intel_crt {
47         struct intel_encoder base;
48         bool force_hotplug_required;
49 };
50
51 static struct intel_crt *intel_attached_crt(struct drm_connector *connector)
52 {
53         return container_of(intel_attached_encoder(connector),
54                             struct intel_crt, base);
55 }
56
57 static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
58 {
59         struct drm_device *dev = encoder->dev;
60         struct drm_i915_private *dev_priv = dev->dev_private;
61         u32 temp, reg;
62
63         if (HAS_PCH_SPLIT(dev))
64                 reg = PCH_ADPA;
65         else
66                 reg = ADPA;
67
68         temp = I915_READ(reg);
69         temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
70         temp &= ~ADPA_DAC_ENABLE;
71
72         switch(mode) {
73         case DRM_MODE_DPMS_ON:
74                 temp |= ADPA_DAC_ENABLE;
75                 break;
76         case DRM_MODE_DPMS_STANDBY:
77                 temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE;
78                 break;
79         case DRM_MODE_DPMS_SUSPEND:
80                 temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE;
81                 break;
82         case DRM_MODE_DPMS_OFF:
83                 temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
84                 break;
85         }
86
87         I915_WRITE(reg, temp);
88 }
89
90 static int intel_crt_mode_valid(struct drm_connector *connector,
91                                 struct drm_display_mode *mode)
92 {
93         struct drm_device *dev = connector->dev;
94
95         int max_clock = 0;
96         if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
97                 return MODE_NO_DBLESCAN;
98
99         if (mode->clock < 25000)
100                 return MODE_CLOCK_LOW;
101
102         if (IS_GEN2(dev))
103                 max_clock = 350000;
104         else
105                 max_clock = 400000;
106         if (mode->clock > max_clock)
107                 return MODE_CLOCK_HIGH;
108
109         return MODE_OK;
110 }
111
112 static bool intel_crt_mode_fixup(struct drm_encoder *encoder,
113                                  struct drm_display_mode *mode,
114                                  struct drm_display_mode *adjusted_mode)
115 {
116         return true;
117 }
118
119 static void intel_crt_mode_set(struct drm_encoder *encoder,
120                                struct drm_display_mode *mode,
121                                struct drm_display_mode *adjusted_mode)
122 {
123
124         struct drm_device *dev = encoder->dev;
125         struct drm_crtc *crtc = encoder->crtc;
126         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
127         struct drm_i915_private *dev_priv = dev->dev_private;
128         int dpll_md_reg;
129         u32 adpa, dpll_md;
130         u32 adpa_reg;
131
132         if (intel_crtc->pipe == 0)
133                 dpll_md_reg = DPLL_A_MD;
134         else
135                 dpll_md_reg = DPLL_B_MD;
136
137         if (HAS_PCH_SPLIT(dev))
138                 adpa_reg = PCH_ADPA;
139         else
140                 adpa_reg = ADPA;
141
142         /*
143          * Disable separate mode multiplier used when cloning SDVO to CRT
144          * XXX this needs to be adjusted when we really are cloning
145          */
146         if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) {
147                 dpll_md = I915_READ(dpll_md_reg);
148                 I915_WRITE(dpll_md_reg,
149                            dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
150         }
151
152         adpa = ADPA_HOTPLUG_BITS;
153         if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
154                 adpa |= ADPA_HSYNC_ACTIVE_HIGH;
155         if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
156                 adpa |= ADPA_VSYNC_ACTIVE_HIGH;
157
158         if (intel_crtc->pipe == 0) {
159                 if (HAS_PCH_CPT(dev))
160                         adpa |= PORT_TRANS_A_SEL_CPT;
161                 else
162                         adpa |= ADPA_PIPE_A_SELECT;
163                 if (!HAS_PCH_SPLIT(dev))
164                         I915_WRITE(BCLRPAT_A, 0);
165         } else {
166                 if (HAS_PCH_CPT(dev))
167                         adpa |= PORT_TRANS_B_SEL_CPT;
168                 else
169                         adpa |= ADPA_PIPE_B_SELECT;
170                 if (!HAS_PCH_SPLIT(dev))
171                         I915_WRITE(BCLRPAT_B, 0);
172         }
173
174         I915_WRITE(adpa_reg, adpa);
175 }
176
177 static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
178 {
179         struct drm_device *dev = connector->dev;
180         struct intel_crt *crt = intel_attached_crt(connector);
181         struct drm_i915_private *dev_priv = dev->dev_private;
182         u32 adpa;
183         bool ret;
184
185         /* The first time through, trigger an explicit detection cycle */
186         if (crt->force_hotplug_required) {
187                 bool turn_off_dac = HAS_PCH_SPLIT(dev);
188                 u32 save_adpa;
189
190                 crt->force_hotplug_required = 0;
191
192                 save_adpa = adpa = I915_READ(PCH_ADPA);
193                 DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa);
194
195                 adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER;
196                 if (turn_off_dac)
197                         adpa &= ~ADPA_DAC_ENABLE;
198
199                 I915_WRITE(PCH_ADPA, adpa);
200
201                 if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0,
202                              1000))
203                         DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER");
204
205                 if (turn_off_dac) {
206                         I915_WRITE(PCH_ADPA, save_adpa);
207                         POSTING_READ(PCH_ADPA);
208                 }
209         }
210
211         /* Check the status to see if both blue and green are on now */
212         adpa = I915_READ(PCH_ADPA);
213         if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0)
214                 ret = true;
215         else
216                 ret = false;
217         DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret);
218
219         return ret;
220 }
221
222 /**
223  * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
224  *
225  * Not for i915G/i915GM
226  *
227  * \return true if CRT is connected.
228  * \return false if CRT is disconnected.
229  */
230 static bool intel_crt_detect_hotplug(struct drm_connector *connector)
231 {
232         struct drm_device *dev = connector->dev;
233         struct drm_i915_private *dev_priv = dev->dev_private;
234         u32 hotplug_en, orig, stat;
235         bool ret = false;
236         int i, tries = 0;
237
238         if (HAS_PCH_SPLIT(dev))
239                 return intel_ironlake_crt_detect_hotplug(connector);
240
241         /*
242          * On 4 series desktop, CRT detect sequence need to be done twice
243          * to get a reliable result.
244          */
245
246         if (IS_G4X(dev) && !IS_GM45(dev))
247                 tries = 2;
248         else
249                 tries = 1;
250         hotplug_en = orig = I915_READ(PORT_HOTPLUG_EN);
251         hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
252
253         for (i = 0; i < tries ; i++) {
254                 /* turn on the FORCE_DETECT */
255                 I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
256                 /* wait for FORCE_DETECT to go off */
257                 if (wait_for((I915_READ(PORT_HOTPLUG_EN) &
258                               CRT_HOTPLUG_FORCE_DETECT) == 0,
259                              1000))
260                         DRM_DEBUG_KMS("timed out waiting for FORCE_DETECT to go off");
261         }
262
263         stat = I915_READ(PORT_HOTPLUG_STAT);
264         if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE)
265                 ret = true;
266
267         /* clear the interrupt we just generated, if any */
268         I915_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS);
269
270         /* and put the bits back */
271         I915_WRITE(PORT_HOTPLUG_EN, orig);
272
273         return ret;
274 }
275
276 static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus)
277 {
278         u8 buf;
279         struct i2c_msg msgs[] = {
280                 {
281                         .addr = 0xA0,
282                         .flags = 0,
283                         .len = 1,
284                         .buf = &buf,
285                 },
286         };
287         /* DDC monitor detect: Does it ACK a write to 0xA0? */
288         return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1;
289 }
290
291 static bool intel_crt_detect_ddc(struct drm_connector *connector)
292 {
293         struct intel_crt *crt = intel_attached_crt(connector);
294         struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private;
295
296         /* CRT should always be at 0, but check anyway */
297         if (crt->base.type != INTEL_OUTPUT_ANALOG)
298                 return false;
299
300         if (intel_crt_ddc_probe(dev_priv, dev_priv->crt_ddc_pin)) {
301                 DRM_DEBUG_KMS("CRT detected via DDC:0xa0\n");
302                 return true;
303         }
304
305         if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) {
306                 struct edid *edid;
307                 bool is_digital = false;
308
309                 edid = drm_get_edid(connector,
310                         &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
311                 /*
312                  * This may be a DVI-I connector with a shared DDC
313                  * link between analog and digital outputs, so we
314                  * have to check the EDID input spec of the attached device.
315                  */
316                 if (edid != NULL) {
317                         is_digital = edid->input & DRM_EDID_INPUT_DIGITAL;
318                         connector->display_info.raw_edid = NULL;
319                         kfree(edid);
320                 }
321
322                 if (!is_digital) {
323                         DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
324                         return true;
325                 }
326         }
327
328         return false;
329 }
330
331 static enum drm_connector_status
332 intel_crt_load_detect(struct drm_crtc *crtc, struct intel_crt *crt)
333 {
334         struct drm_encoder *encoder = &crt->base.base;
335         struct drm_device *dev = encoder->dev;
336         struct drm_i915_private *dev_priv = dev->dev_private;
337         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
338         uint32_t pipe = intel_crtc->pipe;
339         uint32_t save_bclrpat;
340         uint32_t save_vtotal;
341         uint32_t vtotal, vactive;
342         uint32_t vsample;
343         uint32_t vblank, vblank_start, vblank_end;
344         uint32_t dsl;
345         uint32_t bclrpat_reg;
346         uint32_t vtotal_reg;
347         uint32_t vblank_reg;
348         uint32_t vsync_reg;
349         uint32_t pipeconf_reg;
350         uint32_t pipe_dsl_reg;
351         uint8_t st00;
352         enum drm_connector_status status;
353
354         DRM_DEBUG_KMS("starting load-detect on CRT\n");
355
356         if (pipe == 0) {
357                 bclrpat_reg = BCLRPAT_A;
358                 vtotal_reg = VTOTAL_A;
359                 vblank_reg = VBLANK_A;
360                 vsync_reg = VSYNC_A;
361                 pipeconf_reg = PIPEACONF;
362                 pipe_dsl_reg = PIPEADSL;
363         } else {
364                 bclrpat_reg = BCLRPAT_B;
365                 vtotal_reg = VTOTAL_B;
366                 vblank_reg = VBLANK_B;
367                 vsync_reg = VSYNC_B;
368                 pipeconf_reg = PIPEBCONF;
369                 pipe_dsl_reg = PIPEBDSL;
370         }
371
372         save_bclrpat = I915_READ(bclrpat_reg);
373         save_vtotal = I915_READ(vtotal_reg);
374         vblank = I915_READ(vblank_reg);
375
376         vtotal = ((save_vtotal >> 16) & 0xfff) + 1;
377         vactive = (save_vtotal & 0x7ff) + 1;
378
379         vblank_start = (vblank & 0xfff) + 1;
380         vblank_end = ((vblank >> 16) & 0xfff) + 1;
381
382         /* Set the border color to purple. */
383         I915_WRITE(bclrpat_reg, 0x500050);
384
385         if (!IS_GEN2(dev)) {
386                 uint32_t pipeconf = I915_READ(pipeconf_reg);
387                 I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
388                 POSTING_READ(pipeconf_reg);
389                 /* Wait for next Vblank to substitue
390                  * border color for Color info */
391                 intel_wait_for_vblank(dev, pipe);
392                 st00 = I915_READ8(VGA_MSR_WRITE);
393                 status = ((st00 & (1 << 4)) != 0) ?
394                         connector_status_connected :
395                         connector_status_disconnected;
396
397                 I915_WRITE(pipeconf_reg, pipeconf);
398         } else {
399                 bool restore_vblank = false;
400                 int count, detect;
401
402                 /*
403                 * If there isn't any border, add some.
404                 * Yes, this will flicker
405                 */
406                 if (vblank_start <= vactive && vblank_end >= vtotal) {
407                         uint32_t vsync = I915_READ(vsync_reg);
408                         uint32_t vsync_start = (vsync & 0xffff) + 1;
409
410                         vblank_start = vsync_start;
411                         I915_WRITE(vblank_reg,
412                                    (vblank_start - 1) |
413                                    ((vblank_end - 1) << 16));
414                         restore_vblank = true;
415                 }
416                 /* sample in the vertical border, selecting the larger one */
417                 if (vblank_start - vactive >= vtotal - vblank_end)
418                         vsample = (vblank_start + vactive) >> 1;
419                 else
420                         vsample = (vtotal + vblank_end) >> 1;
421
422                 /*
423                  * Wait for the border to be displayed
424                  */
425                 while (I915_READ(pipe_dsl_reg) >= vactive)
426                         ;
427                 while ((dsl = I915_READ(pipe_dsl_reg)) <= vsample)
428                         ;
429                 /*
430                  * Watch ST00 for an entire scanline
431                  */
432                 detect = 0;
433                 count = 0;
434                 do {
435                         count++;
436                         /* Read the ST00 VGA status register */
437                         st00 = I915_READ8(VGA_MSR_WRITE);
438                         if (st00 & (1 << 4))
439                                 detect++;
440                 } while ((I915_READ(pipe_dsl_reg) == dsl));
441
442                 /* restore vblank if necessary */
443                 if (restore_vblank)
444                         I915_WRITE(vblank_reg, vblank);
445                 /*
446                  * If more than 3/4 of the scanline detected a monitor,
447                  * then it is assumed to be present. This works even on i830,
448                  * where there isn't any way to force the border color across
449                  * the screen
450                  */
451                 status = detect * 4 > count * 3 ?
452                          connector_status_connected :
453                          connector_status_disconnected;
454         }
455
456         /* Restore previous settings */
457         I915_WRITE(bclrpat_reg, save_bclrpat);
458
459         return status;
460 }
461
462 static enum drm_connector_status
463 intel_crt_detect(struct drm_connector *connector, bool force)
464 {
465         struct drm_device *dev = connector->dev;
466         struct intel_crt *crt = intel_attached_crt(connector);
467         struct drm_crtc *crtc;
468         int dpms_mode;
469         enum drm_connector_status status;
470
471         if (I915_HAS_HOTPLUG(dev)) {
472                 if (intel_crt_detect_hotplug(connector)) {
473                         DRM_DEBUG_KMS("CRT detected via hotplug\n");
474                         return connector_status_connected;
475                 } else {
476                         DRM_DEBUG_KMS("CRT not detected via hotplug\n");
477                         return connector_status_disconnected;
478                 }
479         }
480
481         if (intel_crt_detect_ddc(connector))
482                 return connector_status_connected;
483
484         if (!force)
485                 return connector->status;
486
487         /* for pre-945g platforms use load detect */
488         crtc = crt->base.base.crtc;
489         if (crtc && crtc->enabled) {
490                 status = intel_crt_load_detect(crtc, crt);
491         } else {
492                 crtc = intel_get_load_detect_pipe(&crt->base, connector,
493                                                   NULL, &dpms_mode);
494                 if (crtc) {
495                         if (intel_crt_detect_ddc(connector))
496                                 status = connector_status_connected;
497                         else
498                                 status = intel_crt_load_detect(crtc, crt);
499                         intel_release_load_detect_pipe(&crt->base,
500                                                        connector, dpms_mode);
501                 } else
502                         status = connector_status_unknown;
503         }
504
505         return status;
506 }
507
508 static void intel_crt_destroy(struct drm_connector *connector)
509 {
510         drm_sysfs_connector_remove(connector);
511         drm_connector_cleanup(connector);
512         kfree(connector);
513 }
514
515 static int intel_crt_get_modes(struct drm_connector *connector)
516 {
517         struct drm_device *dev = connector->dev;
518         struct drm_i915_private *dev_priv = dev->dev_private;
519         int ret;
520
521         ret = intel_ddc_get_modes(connector,
522                                  &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
523         if (ret || !IS_G4X(dev))
524                 return ret;
525
526         /* Try to probe digital port for output in DVI-I -> VGA mode. */
527         return intel_ddc_get_modes(connector,
528                                    &dev_priv->gmbus[GMBUS_PORT_DPB].adapter);
529 }
530
531 static int intel_crt_set_property(struct drm_connector *connector,
532                                   struct drm_property *property,
533                                   uint64_t value)
534 {
535         return 0;
536 }
537
538 static void intel_crt_reset(struct drm_connector *connector)
539 {
540         struct drm_device *dev = connector->dev;
541         struct intel_crt *crt = intel_attached_crt(connector);
542
543         if (HAS_PCH_SPLIT(dev))
544                 crt->force_hotplug_required = 1;
545 }
546
547 /*
548  * Routines for controlling stuff on the analog port
549  */
550
551 static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = {
552         .dpms = intel_crt_dpms,
553         .mode_fixup = intel_crt_mode_fixup,
554         .prepare = intel_encoder_prepare,
555         .commit = intel_encoder_commit,
556         .mode_set = intel_crt_mode_set,
557 };
558
559 static const struct drm_connector_funcs intel_crt_connector_funcs = {
560         .reset = intel_crt_reset,
561         .dpms = drm_helper_connector_dpms,
562         .detect = intel_crt_detect,
563         .fill_modes = drm_helper_probe_single_connector_modes,
564         .destroy = intel_crt_destroy,
565         .set_property = intel_crt_set_property,
566 };
567
568 static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = {
569         .mode_valid = intel_crt_mode_valid,
570         .get_modes = intel_crt_get_modes,
571         .best_encoder = intel_best_encoder,
572 };
573
574 static const struct drm_encoder_funcs intel_crt_enc_funcs = {
575         .destroy = intel_encoder_destroy,
576 };
577
578 void intel_crt_init(struct drm_device *dev)
579 {
580         struct drm_connector *connector;
581         struct intel_crt *crt;
582         struct intel_connector *intel_connector;
583         struct drm_i915_private *dev_priv = dev->dev_private;
584
585         crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL);
586         if (!crt)
587                 return;
588
589         intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
590         if (!intel_connector) {
591                 kfree(crt);
592                 return;
593         }
594
595         connector = &intel_connector->base;
596         drm_connector_init(dev, &intel_connector->base,
597                            &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
598
599         drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs,
600                          DRM_MODE_ENCODER_DAC);
601
602         intel_connector_attach_encoder(intel_connector, &crt->base);
603
604         crt->base.type = INTEL_OUTPUT_ANALOG;
605         crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT |
606                                 1 << INTEL_ANALOG_CLONE_BIT |
607                                 1 << INTEL_SDVO_LVDS_CLONE_BIT);
608         crt->base.crtc_mask = (1 << 0) | (1 << 1);
609         connector->interlace_allowed = 1;
610         connector->doublescan_allowed = 0;
611
612         drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs);
613         drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
614
615         drm_sysfs_connector_add(connector);
616
617         if (I915_HAS_HOTPLUG(dev))
618                 connector->polled = DRM_CONNECTOR_POLL_HPD;
619         else
620                 connector->polled = DRM_CONNECTOR_POLL_CONNECT;
621
622         /*
623          * Configure the automatic hotplug detection stuff
624          */
625         crt->force_hotplug_required = 0;
626         if (HAS_PCH_SPLIT(dev)) {
627                 u32 adpa;
628
629                 adpa = I915_READ(PCH_ADPA);
630                 adpa &= ~ADPA_CRT_HOTPLUG_MASK;
631                 adpa |= ADPA_HOTPLUG_BITS;
632                 I915_WRITE(PCH_ADPA, adpa);
633                 POSTING_READ(PCH_ADPA);
634
635                 DRM_DEBUG_KMS("pch crt adpa set to 0x%x\n", adpa);
636                 crt->force_hotplug_required = 1;
637         }
638
639         dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS;
640 }