diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-07-05 01:19:16 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-07-12 20:13:30 -0400 |
commit | 835aadbef3b762bc43eceddfec90c9a5a312d3c1 (patch) | |
tree | 1f79a03f0c690b51ab5ba9fcc970998d83d76667 | |
parent | 4664c67b5d054012562a74414ed3f8619912b3d1 (diff) |
drm/nv50: send evo "update" command after each disconnect
It turns out that the display engine signals an interrupt for disconnects
too. In order to make it easier to process the display interrupts
correctly, we want to ensure we only get one operation per interrupt
sequence - this is what this commit achieves.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_crtc.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_dac.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_sor.c | 7 |
3 files changed, 12 insertions, 13 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index fb3ed5d80aa6..5d11ea101666 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c | |||
@@ -449,7 +449,6 @@ nv50_crtc_prepare(struct drm_crtc *crtc) | |||
449 | static void | 449 | static void |
450 | nv50_crtc_commit(struct drm_crtc *crtc) | 450 | nv50_crtc_commit(struct drm_crtc *crtc) |
451 | { | 451 | { |
452 | struct drm_crtc *crtc2; | ||
453 | struct drm_device *dev = crtc->dev; | 452 | struct drm_device *dev = crtc->dev; |
454 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 453 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
455 | struct nouveau_channel *evo = dev_priv->evo; | 454 | struct nouveau_channel *evo = dev_priv->evo; |
@@ -460,20 +459,14 @@ nv50_crtc_commit(struct drm_crtc *crtc) | |||
460 | 459 | ||
461 | nv50_crtc_blank(nv_crtc, false); | 460 | nv50_crtc_blank(nv_crtc, false); |
462 | 461 | ||
463 | /* Explicitly blank all unused crtc's. */ | ||
464 | list_for_each_entry(crtc2, &dev->mode_config.crtc_list, head) { | ||
465 | if (!drm_helper_crtc_in_use(crtc2)) | ||
466 | nv50_crtc_blank(nouveau_crtc(crtc2), true); | ||
467 | } | ||
468 | |||
469 | ret = RING_SPACE(evo, 2); | 462 | ret = RING_SPACE(evo, 2); |
470 | if (ret) { | 463 | if (ret) { |
471 | NV_ERROR(dev, "no space while committing crtc\n"); | 464 | NV_ERROR(dev, "no space while committing crtc\n"); |
472 | return; | 465 | return; |
473 | } | 466 | } |
474 | BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); | 467 | BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); |
475 | OUT_RING(evo, 0); | 468 | OUT_RING (evo, 0); |
476 | FIRE_RING(evo); | 469 | FIRE_RING (evo); |
477 | } | 470 | } |
478 | 471 | ||
479 | static bool | 472 | static bool |
diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index 98d312623eda..71e0d5f21f93 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c | |||
@@ -47,16 +47,19 @@ nv50_dac_disconnect(struct drm_encoder *encoder) | |||
47 | 47 | ||
48 | if (!nv_encoder->crtc) | 48 | if (!nv_encoder->crtc) |
49 | return; | 49 | return; |
50 | nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true); | ||
50 | 51 | ||
51 | NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or); | 52 | NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or); |
52 | 53 | ||
53 | ret = RING_SPACE(evo, 2); | 54 | ret = RING_SPACE(evo, 4); |
54 | if (ret) { | 55 | if (ret) { |
55 | NV_ERROR(dev, "no space while disconnecting DAC\n"); | 56 | NV_ERROR(dev, "no space while disconnecting DAC\n"); |
56 | return; | 57 | return; |
57 | } | 58 | } |
58 | BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1); | 59 | BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1); |
59 | OUT_RING(evo, 0); | 60 | OUT_RING (evo, 0); |
61 | BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); | ||
62 | OUT_RING (evo, 0); | ||
60 | 63 | ||
61 | nv_encoder->crtc = NULL; | 64 | nv_encoder->crtc = NULL; |
62 | } | 65 | } |
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index 03cb021bf292..6461eaef6ec8 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c | |||
@@ -47,16 +47,19 @@ nv50_sor_disconnect(struct drm_encoder *encoder) | |||
47 | 47 | ||
48 | if (!nv_encoder->crtc) | 48 | if (!nv_encoder->crtc) |
49 | return; | 49 | return; |
50 | nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true); | ||
50 | 51 | ||
51 | NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or); | 52 | NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or); |
52 | 53 | ||
53 | ret = RING_SPACE(evo, 2); | 54 | ret = RING_SPACE(evo, 4); |
54 | if (ret) { | 55 | if (ret) { |
55 | NV_ERROR(dev, "no space while disconnecting SOR\n"); | 56 | NV_ERROR(dev, "no space while disconnecting SOR\n"); |
56 | return; | 57 | return; |
57 | } | 58 | } |
58 | BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); | 59 | BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); |
59 | OUT_RING(evo, 0); | 60 | OUT_RING (evo, 0); |
61 | BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); | ||
62 | OUT_RING (evo, 0); | ||
60 | 63 | ||
61 | nv_encoder->crtc = NULL; | 64 | nv_encoder->crtc = NULL; |
62 | nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; | 65 | nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; |