drm/nv50: send evo "update" command after each disconnect
authorBen Skeggs <bskeggs@redhat.com>
Mon, 5 Jul 2010 05:19:16 +0000 (15:19 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 13 Jul 2010 00:13:30 +0000 (10:13 +1000)
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>
drivers/gpu/drm/nouveau/nv50_crtc.c
drivers/gpu/drm/nouveau/nv50_dac.c
drivers/gpu/drm/nouveau/nv50_sor.c

index fb3ed5d80aa662c2f7a766d36881957528023951..5d11ea101666dc6eb3e39bfeeaee035f44c633c0 100644 (file)
@@ -449,7 +449,6 @@ nv50_crtc_prepare(struct drm_crtc *crtc)
 static void
 nv50_crtc_commit(struct drm_crtc *crtc)
 {
-       struct drm_crtc *crtc2;
        struct drm_device *dev = crtc->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_channel *evo = dev_priv->evo;
@@ -460,20 +459,14 @@ nv50_crtc_commit(struct drm_crtc *crtc)
 
        nv50_crtc_blank(nv_crtc, false);
 
-       /* Explicitly blank all unused crtc's. */
-       list_for_each_entry(crtc2, &dev->mode_config.crtc_list, head) {
-               if (!drm_helper_crtc_in_use(crtc2))
-                       nv50_crtc_blank(nouveau_crtc(crtc2), true);
-       }
-
        ret = RING_SPACE(evo, 2);
        if (ret) {
                NV_ERROR(dev, "no space while committing crtc\n");
                return;
        }
        BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
-       OUT_RING(evo, 0);
-       FIRE_RING(evo);
+       OUT_RING  (evo, 0);
+       FIRE_RING (evo);
 }
 
 static bool
index 98d312623edab2d61e4660a6e28b446f38ddb236..71e0d5f21f93e0ba2a572956442c36b2a5f0a971 100644 (file)
@@ -47,16 +47,19 @@ nv50_dac_disconnect(struct drm_encoder *encoder)
 
        if (!nv_encoder->crtc)
                return;
+       nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true);
 
        NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or);
 
-       ret = RING_SPACE(evo, 2);
+       ret = RING_SPACE(evo, 4);
        if (ret) {
                NV_ERROR(dev, "no space while disconnecting DAC\n");
                return;
        }
        BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1);
-       OUT_RING(evo, 0);
+       OUT_RING  (evo, 0);
+       BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+       OUT_RING  (evo, 0);
 
        nv_encoder->crtc = NULL;
 }
index 03cb021bf29276fa6016780e6111a30badf92238..6461eaef6ec8ffd59c39c807d1f2335c6821cf4b 100644 (file)
@@ -47,16 +47,19 @@ nv50_sor_disconnect(struct drm_encoder *encoder)
 
        if (!nv_encoder->crtc)
                return;
+       nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true);
 
        NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or);
 
-       ret = RING_SPACE(evo, 2);
+       ret = RING_SPACE(evo, 4);
        if (ret) {
                NV_ERROR(dev, "no space while disconnecting SOR\n");
                return;
        }
        BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
-       OUT_RING(evo, 0);
+       OUT_RING  (evo, 0);
+       BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
+       OUT_RING  (evo, 0);
 
        nv_encoder->crtc = NULL;
        nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;