提交 835aadbe 编写于 作者: B Ben Skeggs

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: NBen Skeggs <bskeggs@redhat.com>
上级 4664c67b
...@@ -449,7 +449,6 @@ nv50_crtc_prepare(struct drm_crtc *crtc) ...@@ -449,7 +449,6 @@ nv50_crtc_prepare(struct drm_crtc *crtc)
static void static void
nv50_crtc_commit(struct drm_crtc *crtc) nv50_crtc_commit(struct drm_crtc *crtc)
{ {
struct drm_crtc *crtc2;
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_channel *evo = dev_priv->evo; struct nouveau_channel *evo = dev_priv->evo;
...@@ -460,20 +459,14 @@ nv50_crtc_commit(struct drm_crtc *crtc) ...@@ -460,20 +459,14 @@ nv50_crtc_commit(struct drm_crtc *crtc)
nv50_crtc_blank(nv_crtc, false); 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); ret = RING_SPACE(evo, 2);
if (ret) { if (ret) {
NV_ERROR(dev, "no space while committing crtc\n"); NV_ERROR(dev, "no space while committing crtc\n");
return; return;
} }
BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
OUT_RING(evo, 0); OUT_RING (evo, 0);
FIRE_RING(evo); FIRE_RING (evo);
} }
static bool static bool
......
...@@ -47,16 +47,19 @@ nv50_dac_disconnect(struct drm_encoder *encoder) ...@@ -47,16 +47,19 @@ nv50_dac_disconnect(struct drm_encoder *encoder)
if (!nv_encoder->crtc) if (!nv_encoder->crtc)
return; return;
nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true);
NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or); NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or);
ret = RING_SPACE(evo, 2); ret = RING_SPACE(evo, 4);
if (ret) { if (ret) {
NV_ERROR(dev, "no space while disconnecting DAC\n"); NV_ERROR(dev, "no space while disconnecting DAC\n");
return; return;
} }
BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1); 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; nv_encoder->crtc = NULL;
} }
......
...@@ -47,16 +47,19 @@ nv50_sor_disconnect(struct drm_encoder *encoder) ...@@ -47,16 +47,19 @@ nv50_sor_disconnect(struct drm_encoder *encoder)
if (!nv_encoder->crtc) if (!nv_encoder->crtc)
return; return;
nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true);
NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or); NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or);
ret = RING_SPACE(evo, 2); ret = RING_SPACE(evo, 4);
if (ret) { if (ret) {
NV_ERROR(dev, "no space while disconnecting SOR\n"); NV_ERROR(dev, "no space while disconnecting SOR\n");
return; return;
} }
BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); 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->crtc = NULL;
nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册