aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_crt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_crt.c')
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c124
1 files changed, 51 insertions, 73 deletions
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index e5051446c48e..759c2ef72eff 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -25,6 +25,7 @@
25 */ 25 */
26 26
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/slab.h>
28#include "drmP.h" 29#include "drmP.h"
29#include "drm.h" 30#include "drm.h"
30#include "drm_crtc.h" 31#include "drm_crtc.h"
@@ -39,7 +40,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
39 struct drm_i915_private *dev_priv = dev->dev_private; 40 struct drm_i915_private *dev_priv = dev->dev_private;
40 u32 temp, reg; 41 u32 temp, reg;
41 42
42 if (IS_IGDNG(dev)) 43 if (HAS_PCH_SPLIT(dev))
43 reg = PCH_ADPA; 44 reg = PCH_ADPA;
44 else 45 else
45 reg = ADPA; 46 reg = ADPA;
@@ -64,34 +65,6 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
64 } 65 }
65 66
66 I915_WRITE(reg, temp); 67 I915_WRITE(reg, temp);
67
68 if (IS_IGD(dev)) {
69 if (mode == DRM_MODE_DPMS_OFF) {
70 /* turn off DAC */
71 temp = I915_READ(PORT_HOTPLUG_EN);
72 temp &= ~CRT_EOS_INT_EN;
73 I915_WRITE(PORT_HOTPLUG_EN, temp);
74
75 temp = I915_READ(PORT_HOTPLUG_STAT);
76 if (temp & CRT_EOS_INT_STATUS)
77 I915_WRITE(PORT_HOTPLUG_STAT,
78 CRT_EOS_INT_STATUS);
79 } else {
80 /* turn on DAC. EOS interrupt must be enabled after DAC
81 * is enabled, so it sounds not good to enable it in
82 * i915_driver_irq_postinstall()
83 * wait 12.5ms after DAC is enabled
84 */
85 msleep(13);
86 temp = I915_READ(PORT_HOTPLUG_STAT);
87 if (temp & CRT_EOS_INT_STATUS)
88 I915_WRITE(PORT_HOTPLUG_STAT,
89 CRT_EOS_INT_STATUS);
90 temp = I915_READ(PORT_HOTPLUG_EN);
91 temp |= CRT_EOS_INT_EN;
92 I915_WRITE(PORT_HOTPLUG_EN, temp);
93 }
94 }
95} 68}
96 69
97static int intel_crt_mode_valid(struct drm_connector *connector, 70static int intel_crt_mode_valid(struct drm_connector *connector,
@@ -141,7 +114,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
141 else 114 else
142 dpll_md_reg = DPLL_B_MD; 115 dpll_md_reg = DPLL_B_MD;
143 116
144 if (IS_IGDNG(dev)) 117 if (HAS_PCH_SPLIT(dev))
145 adpa_reg = PCH_ADPA; 118 adpa_reg = PCH_ADPA;
146 else 119 else
147 adpa_reg = ADPA; 120 adpa_reg = ADPA;
@@ -150,7 +123,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
150 * Disable separate mode multiplier used when cloning SDVO to CRT 123 * Disable separate mode multiplier used when cloning SDVO to CRT
151 * XXX this needs to be adjusted when we really are cloning 124 * XXX this needs to be adjusted when we really are cloning
152 */ 125 */
153 if (IS_I965G(dev) && !IS_IGDNG(dev)) { 126 if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) {
154 dpll_md = I915_READ(dpll_md_reg); 127 dpll_md = I915_READ(dpll_md_reg);
155 I915_WRITE(dpll_md_reg, 128 I915_WRITE(dpll_md_reg,
156 dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); 129 dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
@@ -164,18 +137,18 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
164 137
165 if (intel_crtc->pipe == 0) { 138 if (intel_crtc->pipe == 0) {
166 adpa |= ADPA_PIPE_A_SELECT; 139 adpa |= ADPA_PIPE_A_SELECT;
167 if (!IS_IGDNG(dev)) 140 if (!HAS_PCH_SPLIT(dev))
168 I915_WRITE(BCLRPAT_A, 0); 141 I915_WRITE(BCLRPAT_A, 0);
169 } else { 142 } else {
170 adpa |= ADPA_PIPE_B_SELECT; 143 adpa |= ADPA_PIPE_B_SELECT;
171 if (!IS_IGDNG(dev)) 144 if (!HAS_PCH_SPLIT(dev))
172 I915_WRITE(BCLRPAT_B, 0); 145 I915_WRITE(BCLRPAT_B, 0);
173 } 146 }
174 147
175 I915_WRITE(adpa_reg, adpa); 148 I915_WRITE(adpa_reg, adpa);
176} 149}
177 150
178static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector) 151static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
179{ 152{
180 struct drm_device *dev = connector->dev; 153 struct drm_device *dev = connector->dev;
181 struct drm_i915_private *dev_priv = dev->dev_private; 154 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -185,6 +158,9 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
185 adpa = I915_READ(PCH_ADPA); 158 adpa = I915_READ(PCH_ADPA);
186 159
187 adpa &= ~ADPA_CRT_HOTPLUG_MASK; 160 adpa &= ~ADPA_CRT_HOTPLUG_MASK;
161 /* disable HPD first */
162 I915_WRITE(PCH_ADPA, adpa);
163 (void)I915_READ(PCH_ADPA);
188 164
189 adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | 165 adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 |
190 ADPA_CRT_HOTPLUG_WARMUP_10MS | 166 ADPA_CRT_HOTPLUG_WARMUP_10MS |
@@ -194,7 +170,7 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
194 ADPA_CRT_HOTPLUG_ENABLE | 170 ADPA_CRT_HOTPLUG_ENABLE |
195 ADPA_CRT_HOTPLUG_FORCE_TRIGGER); 171 ADPA_CRT_HOTPLUG_FORCE_TRIGGER);
196 172
197 DRM_DEBUG("pch crt adpa 0x%x", adpa); 173 DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa);
198 I915_WRITE(PCH_ADPA, adpa); 174 I915_WRITE(PCH_ADPA, adpa);
199 175
200 while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0) 176 while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0)
@@ -227,8 +203,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
227 u32 hotplug_en; 203 u32 hotplug_en;
228 int i, tries = 0; 204 int i, tries = 0;
229 205
230 if (IS_IGDNG(dev)) 206 if (HAS_PCH_SPLIT(dev))
231 return intel_igdng_crt_detect_hotplug(connector); 207 return intel_ironlake_crt_detect_hotplug(connector);
232 208
233 /* 209 /*
234 * On 4 series desktop, CRT detect sequence need to be done twice 210 * On 4 series desktop, CRT detect sequence need to be done twice
@@ -271,19 +247,19 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
271 247
272static bool intel_crt_detect_ddc(struct drm_connector *connector) 248static bool intel_crt_detect_ddc(struct drm_connector *connector)
273{ 249{
274 struct intel_output *intel_output = to_intel_output(connector); 250 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
275 251
276 /* CRT should always be at 0, but check anyway */ 252 /* CRT should always be at 0, but check anyway */
277 if (intel_output->type != INTEL_OUTPUT_ANALOG) 253 if (intel_encoder->type != INTEL_OUTPUT_ANALOG)
278 return false; 254 return false;
279 255
280 return intel_ddc_probe(intel_output); 256 return intel_ddc_probe(intel_encoder);
281} 257}
282 258
283static enum drm_connector_status 259static enum drm_connector_status
284intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output) 260intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
285{ 261{
286 struct drm_encoder *encoder = &intel_output->enc; 262 struct drm_encoder *encoder = &intel_encoder->enc;
287 struct drm_device *dev = encoder->dev; 263 struct drm_device *dev = encoder->dev;
288 struct drm_i915_private *dev_priv = dev->dev_private; 264 struct drm_i915_private *dev_priv = dev->dev_private;
289 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 265 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -411,8 +387,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
411static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) 387static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
412{ 388{
413 struct drm_device *dev = connector->dev; 389 struct drm_device *dev = connector->dev;
414 struct intel_output *intel_output = to_intel_output(connector); 390 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
415 struct drm_encoder *encoder = &intel_output->enc; 391 struct drm_encoder *encoder = &intel_encoder->enc;
416 struct drm_crtc *crtc; 392 struct drm_crtc *crtc;
417 int dpms_mode; 393 int dpms_mode;
418 enum drm_connector_status status; 394 enum drm_connector_status status;
@@ -429,13 +405,13 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
429 405
430 /* for pre-945g platforms use load detect */ 406 /* for pre-945g platforms use load detect */
431 if (encoder->crtc && encoder->crtc->enabled) { 407 if (encoder->crtc && encoder->crtc->enabled) {
432 status = intel_crt_load_detect(encoder->crtc, intel_output); 408 status = intel_crt_load_detect(encoder->crtc, intel_encoder);
433 } else { 409 } else {
434 crtc = intel_get_load_detect_pipe(intel_output, 410 crtc = intel_get_load_detect_pipe(intel_encoder,
435 NULL, &dpms_mode); 411 NULL, &dpms_mode);
436 if (crtc) { 412 if (crtc) {
437 status = intel_crt_load_detect(crtc, intel_output); 413 status = intel_crt_load_detect(crtc, intel_encoder);
438 intel_release_load_detect_pipe(intel_output, dpms_mode); 414 intel_release_load_detect_pipe(intel_encoder, dpms_mode);
439 } else 415 } else
440 status = connector_status_unknown; 416 status = connector_status_unknown;
441 } 417 }
@@ -445,9 +421,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
445 421
446static void intel_crt_destroy(struct drm_connector *connector) 422static void intel_crt_destroy(struct drm_connector *connector)
447{ 423{
448 struct intel_output *intel_output = to_intel_output(connector); 424 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
449 425
450 intel_i2c_destroy(intel_output->ddc_bus); 426 intel_i2c_destroy(intel_encoder->ddc_bus);
451 drm_sysfs_connector_remove(connector); 427 drm_sysfs_connector_remove(connector);
452 drm_connector_cleanup(connector); 428 drm_connector_cleanup(connector);
453 kfree(connector); 429 kfree(connector);
@@ -456,28 +432,28 @@ static void intel_crt_destroy(struct drm_connector *connector)
456static int intel_crt_get_modes(struct drm_connector *connector) 432static int intel_crt_get_modes(struct drm_connector *connector)
457{ 433{
458 int ret; 434 int ret;
459 struct intel_output *intel_output = to_intel_output(connector); 435 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
460 struct i2c_adapter *ddcbus; 436 struct i2c_adapter *ddcbus;
461 struct drm_device *dev = connector->dev; 437 struct drm_device *dev = connector->dev;
462 438
463 439
464 ret = intel_ddc_get_modes(intel_output); 440 ret = intel_ddc_get_modes(intel_encoder);
465 if (ret || !IS_G4X(dev)) 441 if (ret || !IS_G4X(dev))
466 goto end; 442 goto end;
467 443
468 ddcbus = intel_output->ddc_bus; 444 ddcbus = intel_encoder->ddc_bus;
469 /* Try to probe digital port for output in DVI-I -> VGA mode. */ 445 /* Try to probe digital port for output in DVI-I -> VGA mode. */
470 intel_output->ddc_bus = 446 intel_encoder->ddc_bus =
471 intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); 447 intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D");
472 448
473 if (!intel_output->ddc_bus) { 449 if (!intel_encoder->ddc_bus) {
474 intel_output->ddc_bus = ddcbus; 450 intel_encoder->ddc_bus = ddcbus;
475 dev_printk(KERN_ERR, &connector->dev->pdev->dev, 451 dev_printk(KERN_ERR, &connector->dev->pdev->dev,
476 "DDC bus registration failed for CRTDDC_D.\n"); 452 "DDC bus registration failed for CRTDDC_D.\n");
477 goto end; 453 goto end;
478 } 454 }
479 /* Try to get modes by GPIOD port */ 455 /* Try to get modes by GPIOD port */
480 ret = intel_ddc_get_modes(intel_output); 456 ret = intel_ddc_get_modes(intel_encoder);
481 intel_i2c_destroy(ddcbus); 457 intel_i2c_destroy(ddcbus);
482 458
483end: 459end:
@@ -530,50 +506,52 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
530void intel_crt_init(struct drm_device *dev) 506void intel_crt_init(struct drm_device *dev)
531{ 507{
532 struct drm_connector *connector; 508 struct drm_connector *connector;
533 struct intel_output *intel_output; 509 struct intel_encoder *intel_encoder;
534 struct drm_i915_private *dev_priv = dev->dev_private; 510 struct drm_i915_private *dev_priv = dev->dev_private;
535 u32 i2c_reg; 511 u32 i2c_reg;
536 512
537 intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); 513 intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL);
538 if (!intel_output) 514 if (!intel_encoder)
539 return; 515 return;
540 516
541 connector = &intel_output->base; 517 connector = &intel_encoder->base;
542 drm_connector_init(dev, &intel_output->base, 518 drm_connector_init(dev, &intel_encoder->base,
543 &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); 519 &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
544 520
545 drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs, 521 drm_encoder_init(dev, &intel_encoder->enc, &intel_crt_enc_funcs,
546 DRM_MODE_ENCODER_DAC); 522 DRM_MODE_ENCODER_DAC);
547 523
548 drm_mode_connector_attach_encoder(&intel_output->base, 524 drm_mode_connector_attach_encoder(&intel_encoder->base,
549 &intel_output->enc); 525 &intel_encoder->enc);
550 526
551 /* Set up the DDC bus. */ 527 /* Set up the DDC bus. */
552 if (IS_IGDNG(dev)) 528 if (HAS_PCH_SPLIT(dev))
553 i2c_reg = PCH_GPIOA; 529 i2c_reg = PCH_GPIOA;
554 else { 530 else {
555 i2c_reg = GPIOA; 531 i2c_reg = GPIOA;
556 /* Use VBT information for CRT DDC if available */ 532 /* Use VBT information for CRT DDC if available */
557 if (dev_priv->crt_ddc_bus != -1) 533 if (dev_priv->crt_ddc_bus != 0)
558 i2c_reg = dev_priv->crt_ddc_bus; 534 i2c_reg = dev_priv->crt_ddc_bus;
559 } 535 }
560 intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); 536 intel_encoder->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
561 if (!intel_output->ddc_bus) { 537 if (!intel_encoder->ddc_bus) {
562 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " 538 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
563 "failed.\n"); 539 "failed.\n");
564 return; 540 return;
565 } 541 }
566 542
567 intel_output->type = INTEL_OUTPUT_ANALOG; 543 intel_encoder->type = INTEL_OUTPUT_ANALOG;
568 intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | 544 intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
569 (1 << INTEL_ANALOG_CLONE_BIT) | 545 (1 << INTEL_ANALOG_CLONE_BIT) |
570 (1 << INTEL_SDVO_LVDS_CLONE_BIT); 546 (1 << INTEL_SDVO_LVDS_CLONE_BIT);
571 intel_output->crtc_mask = (1 << 0) | (1 << 1); 547 intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
572 connector->interlace_allowed = 0; 548 connector->interlace_allowed = 0;
573 connector->doublescan_allowed = 0; 549 connector->doublescan_allowed = 0;
574 550
575 drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs); 551 drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs);
576 drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); 552 drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
577 553
578 drm_sysfs_connector_add(connector); 554 drm_sysfs_connector_add(connector);
555
556 dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS;
579} 557}