Commit 09838c4e authored by Lyude Paul's avatar Lyude Paul
Browse files

drm/nouveau/kms: Search for encoders' connectors properly



While the way we find the associated connector for an encoder is just
fine for legacy modesetting, it's not correct for nv50+ since that uses
atomic modesetting. For reference, see the drm_encoder kdocs.

Fix this by removing nouveau_encoder_connector_get(), and replacing it
with nv04_encoder_get_connector(), nv50_outp_get_old_connector(), and
nv50_outp_get_new_connector().

v2:
* Don't line-wrap for_each_(old|new)_connector_in_state in
  nv50_outp_get_(old|new)_connector() - sravn
v3:
* Fix potential uninitialized usage of nv_connector (needs to be
  initialized to NULL at the start). Thanks kernel test robot!
v4:
* Actually fix uninitialized nv_connector usage in
  nv50_audio_component_get_eld(). The previous fix wouldn't have worked
  since we would have started out with nv_connector == NULL, but
  wouldn't clear it after a single drm_for_each_encoder() iteration.
  Thanks again Kernel bot!

Signed-off-by: default avatarLyude Paul <lyude@redhat.com>
Reviewed-by: default avatarBen Skeggs <bskeggs@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200826182456.322681-7-lyude@redhat.com
parent 254e7e3b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -419,7 +419,7 @@ static void nv04_dac_commit(struct drm_encoder *encoder)
	helper->dpms(encoder, DRM_MODE_DPMS_ON);

	NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n",
		 nouveau_encoder_connector_get(nv_encoder)->base.name,
		 nv04_encoder_get_connector(nv_encoder)->base.name,
		 nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
}

+4 −3
Original line number Diff line number Diff line
@@ -184,7 +184,8 @@ static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder,
				struct drm_display_mode *adjusted_mode)
{
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
	struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder);
	struct nouveau_connector *nv_connector =
		nv04_encoder_get_connector(nv_encoder);

	if (!nv_connector->native_mode ||
	    nv_connector->scaling_mode == DRM_MODE_SCALE_NONE ||
@@ -478,7 +479,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder)
	helper->dpms(encoder, DRM_MODE_DPMS_ON);

	NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n",
		 nouveau_encoder_connector_get(nv_encoder)->base.name,
		 nv04_encoder_get_connector(nv_encoder)->base.name,
		 nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
}

@@ -591,7 +592,7 @@ static void nv04_dfp_restore(struct drm_encoder *encoder)

	if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS) {
		struct nouveau_connector *connector =
			nouveau_encoder_connector_get(nv_encoder);
			nv04_encoder_get_connector(nv_encoder);

		if (connector && connector->native_mode)
			call_lvds_script(dev, nv_encoder->dcb, head,
+18 −0
Original line number Diff line number Diff line
@@ -35,6 +35,24 @@

#include <nvif/if0004.h>

struct nouveau_connector *
nv04_encoder_get_connector(struct nouveau_encoder *encoder)
{
	struct drm_device *dev = to_drm_encoder(encoder)->dev;
	struct drm_connector *connector;
	struct drm_connector_list_iter conn_iter;
	struct nouveau_connector *nv_connector = NULL;

	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter) {
		if (connector->encoder == to_drm_encoder(encoder))
			nv_connector = nouveau_connector(connector);
	}
	drm_connector_list_iter_end(&conn_iter);

	return nv_connector;
}

static void
nv04_display_fini(struct drm_device *dev, bool suspend)
{
+4 −0
Original line number Diff line number Diff line
@@ -6,6 +6,8 @@

#include "nouveau_display.h"

struct nouveau_encoder;

enum nv04_fp_display_regs {
	FP_DISPLAY_END,
	FP_TOTAL,
@@ -93,6 +95,8 @@ nv04_display(struct drm_device *dev)

/* nv04_display.c */
int nv04_display_create(struct drm_device *);
struct nouveau_connector *
nv04_encoder_get_connector(struct nouveau_encoder *nv_encoder);

/* nv04_crtc.c */
int nv04_crtc_create(struct drm_device *, int index);
+1 −1
Original line number Diff line number Diff line
@@ -172,7 +172,7 @@ static void nv04_tv_commit(struct drm_encoder *encoder)
	helper->dpms(encoder, DRM_MODE_DPMS_ON);

	NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n",
		 nouveau_encoder_connector_get(nv_encoder)->base.name,
		 nv04_encoder_get_connector(nv_encoder)->base.name,
		 nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
}

Loading