Commit 81344372 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/disp: move DP link config into acquire



Aside from fixing MST->SST switching (KMS never turned off MST link config),
this should preserve existing behaviour for the moment, but provide a path
for the KMS driver to have more explicit control of the DP link, which has
been requested by Lyude.

More research into modeset/supervisor interactions is needed before we can
have fully explicit control from the KMS driver.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent a9f5d772
Loading
Loading
Loading
Loading
+4 −30
Original line number Diff line number Diff line
@@ -1014,7 +1014,7 @@ nv50_msto_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *st

	if (!mstm->links++) {
		/*XXX: MST audio. */
		nvif_outp_acquire_dp(&mstm->outp->outp, false);
		nvif_outp_acquire_dp(&mstm->outp->outp, mstm->outp->dp.dpcd, 0, 0, false, true);
	}

	if (mstm->outp->outp.or.link & 1)
@@ -1380,26 +1380,6 @@ nv50_mstm_remove(struct nv50_mstm *mstm)
	drm_dp_mst_topology_mgr_set_mst(&mstm->mgr, false);
}

static int
nv50_mstm_enable(struct nv50_mstm *mstm, int state)
{
	struct nouveau_encoder *outp = mstm->outp;
	struct {
		struct nv50_disp_mthd_v1 base;
		struct nv50_disp_sor_dp_mst_link_v0 mst;
	} args = {
		.base.version = 1,
		.base.method = NV50_DISP_MTHD_V1_SOR_DP_MST_LINK,
		.base.hasht = outp->dcb->hasht,
		.base.hashm = outp->dcb->hashm,
		.mst.state = state,
	};
	struct nouveau_drm *drm = nouveau_drm(outp->base.base.dev);
	struct nvif_object *disp = &drm->display->disp.object;

	return nvif_mthd(disp, 0, &args, sizeof(args));
}

int
nv50_mstm_detect(struct nouveau_encoder *outp)
{
@@ -1420,15 +1400,9 @@ nv50_mstm_detect(struct nouveau_encoder *outp)
		return ret;

	/* And start enabling */
	ret = nv50_mstm_enable(mstm, true);
	if (ret)
		return ret;

	ret = drm_dp_mst_topology_mgr_set_mst(&mstm->mgr, true);
	if (ret) {
		nv50_mstm_enable(mstm, false);
	if (ret)
		return ret;
	}

	mstm->is_mst = true;
	return 1;
@@ -1660,7 +1634,7 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *sta
		nvif_outp_acquire_lvds(&nv_encoder->outp, lvds_dual, lvds_8bpc);
		break;
	case DCB_OUTPUT_DP:
		nvif_outp_acquire_dp(&nv_encoder->outp, hda);
		nvif_outp_acquire_dp(&nv_encoder->outp, nv_encoder->dp.dpcd, 0, 0, hda, false);
		depth = nv50_dp_bpc_to_depth(asyh->or.bpc);

		if (nv_encoder->outp.or.link & 1)
@@ -1858,7 +1832,7 @@ nv50_pior_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *st
		break;
	case DCB_OUTPUT_DP:
		ctrl |= NVDEF(NV507D, PIOR_SET_CONTROL, PROTOCOL, EXT_TMDS_ENC);
		nvif_outp_acquire_dp(&nv_encoder->outp, false);
		nvif_outp_acquire_dp(&nv_encoder->outp, nv_encoder->dp.dpcd, 0, 0, false, false);
		break;
	default:
		BUG();
+0 −7
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ struct nv50_disp_scanoutpos_v0 {

struct nv50_disp_mthd_v1 {
	__u8  version;
#define NV50_DISP_MTHD_V1_SOR_DP_MST_LINK                                  0x25
#define NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI                                  0x26
	__u8  method;
	__u16 hasht;
@@ -36,12 +35,6 @@ struct nv50_disp_mthd_v1 {
	__u8  pad06[2];
};

struct nv50_disp_sor_dp_mst_link_v0 {
	__u8  version;
	__u8  state;
	__u8  pad02[6];
};

struct nv50_disp_sor_dp_mst_vcpi_v0 {
	__u8  version;
	__u8  pad01[1];
+5 −1
Original line number Diff line number Diff line
@@ -55,8 +55,12 @@ union nvif_outp_acquire_args {
				__u8 pad02[6];
			} lvds;
			struct {
				__u8 link_nr; /* 0 = highest possible. */
				__u8 link_bw; /* 0 = highest possible, DP BW code otherwise. */
				__u8 hda;
				__u8 pad01[7];
				__u8 mst;
				__u8 pad04[4];
				__u8 dpcd[16];
			} dp;
		};
	} v0;
+2 −1
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ int nvif_outp_acquire_rgb_crt(struct nvif_outp *);
int nvif_outp_acquire_tmds(struct nvif_outp *, int head,
			   bool hdmi, u8 max_ac_packet, u8 rekey, u8 scdc, bool hda);
int nvif_outp_acquire_lvds(struct nvif_outp *, bool dual, bool bpc8);
int nvif_outp_acquire_dp(struct nvif_outp *, bool hda);
int nvif_outp_acquire_dp(struct nvif_outp *, u8 dpcd[16],
			 int link_nr, int link_bw, bool hda, bool mst);
void nvif_outp_release(struct nvif_outp *);
int nvif_outp_infoframe(struct nvif_outp *, u8 type, struct nvif_outp_infoframe_v0 *, u32 size);
int nvif_outp_hda_eld(struct nvif_outp *, int head, void *data, u32 size);
+8 −2
Original line number Diff line number Diff line
@@ -84,16 +84,22 @@ nvif_outp_acquire(struct nvif_outp *outp, u8 proto, struct nvif_outp_acquire_v0
}

int
nvif_outp_acquire_dp(struct nvif_outp *outp,  bool hda)
nvif_outp_acquire_dp(struct nvif_outp *outp, u8 dpcd[16],
		     int link_nr, int link_bw, bool hda, bool mst)
{
	struct nvif_outp_acquire_v0 args;
	int ret;

	args.dp.link_nr = link_nr;
	args.dp.link_bw = link_bw;
	args.dp.hda = hda;
	args.dp.mst = mst;
	memcpy(args.dp.dpcd, dpcd, sizeof(args.dp.dpcd));

	ret = nvif_outp_acquire(outp, NVIF_OUTP_ACQUIRE_V0_DP, &args);
	NVIF_ERRON(ret, &outp->object,
		   "[ACQUIRE proto:DP hda:%d] or:%d link:%d", args.dp.hda, args.or, args.link);
		   "[ACQUIRE proto:DP link_nr:%d link_bw:%02x hda:%d mst:%d] or:%d link:%d",
		   args.dp.link_nr, args.dp.link_bw, args.dp.hda, args.dp.mst, args.or, args.link);
	return ret;
}

Loading