aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-01-17 17:52:35 -0500
committerBen Skeggs <bskeggs@redhat.com>2010-01-17 18:56:27 -0500
commit58d65b84dee524b0a4a8b747b8eb8bbf2fb16d9d (patch)
treede9c4ef82d3c1a51d3fc0267b499e3dfcb02528a /drivers
parent134f248bea4bf5c3169b4950eb49c6651b09eb0e (diff)
drm/nv50: prevent accidently turning off encoders we're actually using
On most cards the DisplayPort connector is created with 2 encoders sharing a single SOR (for native DP, and for DVI-over-DP). The previous logic for turning off unused encoders didn't take into account that we could have multiple drm_encoders on a single hw encoder and ended up turning off encoders that were actually being used still. This patch fixes that issue. We probably want to look at something a bit better later on, and only expose one drm_encoder per hw encoder block. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_crtc.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
index 118d3285fd8c..40b7360841f8 100644
--- a/drivers/gpu/drm/nouveau/nv50_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
@@ -432,6 +432,7 @@ nv50_crtc_prepare(struct drm_crtc *crtc)
432 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 432 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
433 struct drm_device *dev = crtc->dev; 433 struct drm_device *dev = crtc->dev;
434 struct drm_encoder *encoder; 434 struct drm_encoder *encoder;
435 uint32_t dac = 0, sor = 0;
435 436
436 NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); 437 NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
437 438
@@ -439,9 +440,28 @@ nv50_crtc_prepare(struct drm_crtc *crtc)
439 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 440 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
440 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 441 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
441 442
442 if (drm_helper_encoder_in_use(encoder)) 443 if (!drm_helper_encoder_in_use(encoder))
443 continue; 444 continue;
444 445
446 if (nv_encoder->dcb->type == OUTPUT_ANALOG ||
447 nv_encoder->dcb->type == OUTPUT_TV)
448 dac |= (1 << nv_encoder->or);
449 else
450 sor |= (1 << nv_encoder->or);
451 }
452
453 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
454 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
455
456 if (nv_encoder->dcb->type == OUTPUT_ANALOG ||
457 nv_encoder->dcb->type == OUTPUT_TV) {
458 if (dac & (1 << nv_encoder->or))
459 continue;
460 } else {
461 if (sor & (1 << nv_encoder->or))
462 continue;
463 }
464
445 nv_encoder->disconnect(nv_encoder); 465 nv_encoder->disconnect(nv_encoder);
446 } 466 }
447 467