浏览代码

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>
Ben Skeggs 15 年之前
父节点
当前提交
835aadbef3
共有 3 个文件被更改,包括 12 次插入13 次删除
  1. 2 9
      drivers/gpu/drm/nouveau/nv50_crtc.c
  2. 5 2
      drivers/gpu/drm/nouveau/nv50_dac.c
  3. 5 2
      drivers/gpu/drm/nouveau/nv50_sor.c

+ 2 - 9
drivers/gpu/drm/nouveau/nv50_crtc.c

@@ -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

+ 5 - 2
drivers/gpu/drm/nouveau/nv50_dac.c

@@ -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;
 }

+ 5 - 2
drivers/gpu/drm/nouveau/nv50_sor.c

@@ -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;