Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58d65b84 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nv50: prevent accidently turning off encoders we're actually using



On most cards the DisplayPort connector is created with 2 encoders sharing
a single SOR (for native DP, and for DVI-over-DP).  The previous logic
for turning off unused encoders didn't take into account that we could
have multiple drm_encoders on a single hw encoder and ended up turning off
encoders that were actually being used still.

This patch fixes that issue.  We probably want to look at something a bit
better later on, and only expose one drm_encoder per hw encoder block.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 134f248b
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -432,6 +432,7 @@ nv50_crtc_prepare(struct drm_crtc *crtc)
	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
	struct drm_device *dev = crtc->dev;
	struct drm_encoder *encoder;
	uint32_t dac = 0, sor = 0;

	NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);

@@ -439,9 +440,28 @@ nv50_crtc_prepare(struct drm_crtc *crtc)
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);

		if (drm_helper_encoder_in_use(encoder))
		if (!drm_helper_encoder_in_use(encoder))
			continue;

		if (nv_encoder->dcb->type == OUTPUT_ANALOG ||
		    nv_encoder->dcb->type == OUTPUT_TV)
			dac |= (1 << nv_encoder->or);
		else
			sor |= (1 << nv_encoder->or);
	}

	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);

		if (nv_encoder->dcb->type == OUTPUT_ANALOG ||
		    nv_encoder->dcb->type == OUTPUT_TV) {
			if (dac & (1 << nv_encoder->or))
				continue;
		} else {
			if (sor & (1 << nv_encoder->or))
				continue;
		}

		nv_encoder->disconnect(nv_encoder);
	}