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>
This commit is contained in:
parent
4664c67b5d
commit
835aadbef3
3 changed files with 12 additions and 13 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Reference in a new issue